|
|
|
|
@@ -2,14 +2,17 @@ package homeassistant
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"bytes"
|
|
|
|
|
"errors"
|
|
|
|
|
"log/slog"
|
|
|
|
|
"net/http"
|
|
|
|
|
"net/http/httptest"
|
|
|
|
|
"strings"
|
|
|
|
|
"testing"
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
"github.com/spf13/viper"
|
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
|
"github.com/stretchr/testify/mock"
|
|
|
|
|
"github.com/t-liu93/home-automation-backend/util/ticktickutil"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
@@ -18,26 +21,26 @@ var (
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type MockTicktickUtil struct {
|
|
|
|
|
// Mock methods for testing
|
|
|
|
|
mock.Mock
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (m *MockTicktickUtil) HandleAuthCode(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
// Mock implementation
|
|
|
|
|
m.Called(w, r)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (m *MockTicktickUtil) GetTasks(projectId string) []ticktickutil.Task {
|
|
|
|
|
// Mock implementation
|
|
|
|
|
return []ticktickutil.Task{}
|
|
|
|
|
args := m.Called(projectId)
|
|
|
|
|
return args.Get(0).([]ticktickutil.Task)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (m *MockTicktickUtil) HasDuplicateTask(projectId string, taskTitle string) bool {
|
|
|
|
|
// Mock implementation
|
|
|
|
|
return false
|
|
|
|
|
func (m *MockTicktickUtil) HasDuplicateTask(projectId string, taskTitile string) bool {
|
|
|
|
|
args := m.Called(projectId, taskTitile)
|
|
|
|
|
return args.Bool(0)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (m *MockTicktickUtil) CreateTask(task ticktickutil.Task) error {
|
|
|
|
|
// Mock implementation
|
|
|
|
|
return nil
|
|
|
|
|
args := m.Called(task)
|
|
|
|
|
return args.Error(0)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func SetupTearDown(t *testing.T) (func(), *HomeAssistant) {
|
|
|
|
|
@@ -47,6 +50,7 @@ func SetupTearDown(t *testing.T) (func(), *HomeAssistant) {
|
|
|
|
|
|
|
|
|
|
return func() {
|
|
|
|
|
loggertearDown()
|
|
|
|
|
viper.Reset()
|
|
|
|
|
}, ha
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -172,3 +176,105 @@ func TestHandleLocationRecorderMsgRequestErr(t *testing.T) {
|
|
|
|
|
assert.Equal(t, http.StatusInternalServerError, w.Code)
|
|
|
|
|
assert.Contains(t, loggerText.String(), "homeassistant.handleLocationRecorderMsg: Error sending request to location recorder")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestHandleTicktickMsgCreateActionTask(t *testing.T) {
|
|
|
|
|
teardown, _ := SetupTearDown(t)
|
|
|
|
|
defer teardown()
|
|
|
|
|
const expectedProjectId = "test_project_id"
|
|
|
|
|
const dueHour = 12
|
|
|
|
|
due := time.Now().Add(time.Hour * time.Duration(dueHour))
|
|
|
|
|
dueNextMidnight := time.Date(due.Year(), due.Month(), due.Day(), 0, 0, 0, 0, time.Local).AddDate(0, 0, 1)
|
|
|
|
|
dueTicktick := dueNextMidnight.UTC().Format(ticktickutil.DateTimeLayout)
|
|
|
|
|
|
|
|
|
|
requestBody := `{"target": "ticktick", "action": "create_action_task", "content": "{'title': 'test', 'action': 'test_action', 'due_hour': 12}"}`
|
|
|
|
|
req := httptest.NewRequest(http.MethodPost, "/homeassistant/publish", strings.NewReader(requestBody))
|
|
|
|
|
w := httptest.NewRecorder()
|
|
|
|
|
|
|
|
|
|
mockTicktick := &MockTicktickUtil{}
|
|
|
|
|
mockTicktick.On("CreateTask", mock.Anything).Return(nil)
|
|
|
|
|
ha := NewHomeAssistant(mockTicktick)
|
|
|
|
|
viper.Set("homeassistant.actionTaskProjectId", expectedProjectId)
|
|
|
|
|
ha.HandleHaMessage(w, req)
|
|
|
|
|
expectedTask := ticktickutil.Task{
|
|
|
|
|
Title: "test_action",
|
|
|
|
|
DueDate: dueTicktick,
|
|
|
|
|
ProjectId: expectedProjectId,
|
|
|
|
|
}
|
|
|
|
|
mockTicktick.AssertCalled(t, "CreateTask", expectedTask)
|
|
|
|
|
mockTicktick.AssertNumberOfCalls(t, "CreateTask", 1)
|
|
|
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
|
|
|
assert.Empty(t, loggerText.String())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestHandleTicktickMsgUnknownAction(t *testing.T) {
|
|
|
|
|
teardown, ha := SetupTearDown(t)
|
|
|
|
|
defer teardown()
|
|
|
|
|
|
|
|
|
|
requestBody := `{"target": "ticktick", "action": "unknown_action", "content": ""}`
|
|
|
|
|
req := httptest.NewRequest(http.MethodPost, "/homeassistant/publish", strings.NewReader(requestBody))
|
|
|
|
|
w := httptest.NewRecorder()
|
|
|
|
|
|
|
|
|
|
ha.HandleHaMessage(w, req)
|
|
|
|
|
assert.Equal(t, http.StatusInternalServerError, w.Code)
|
|
|
|
|
assert.Contains(t, loggerText.String(), "homeassistant.handleTicktickMsg: Unknown action")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestHandleTicktickMsgProjectIdUnset(t *testing.T) {
|
|
|
|
|
teardown, ha := SetupTearDown(t)
|
|
|
|
|
defer teardown()
|
|
|
|
|
|
|
|
|
|
requestBody := `{"target": "ticktick", "action": "create_action_task", "content": "{'title': 'test', 'action': 'test_action', 'due_hour': 12}"}`
|
|
|
|
|
req := httptest.NewRequest(http.MethodPost, "/homeassistant/publish", strings.NewReader(requestBody))
|
|
|
|
|
w := httptest.NewRecorder()
|
|
|
|
|
|
|
|
|
|
ha.HandleHaMessage(w, req)
|
|
|
|
|
assert.Equal(t, http.StatusInternalServerError, w.Code)
|
|
|
|
|
assert.Contains(t, loggerText.String(), "homeassistant.createActionTask: actionTaskProjectId not found in config file")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestHandleTicktickMsgJsonError(t *testing.T) {
|
|
|
|
|
teardown, ha := SetupTearDown(t)
|
|
|
|
|
defer teardown()
|
|
|
|
|
|
|
|
|
|
invalidRequestBody := ` { "target": "ticktick", "action": "create_action_task", "content": "{'title': 'tes, 'action': 'test_action', 'due_hour': 12}"}`
|
|
|
|
|
req := httptest.NewRequest(http.MethodPost, "/homeassistant/publish", strings.NewReader(invalidRequestBody))
|
|
|
|
|
w := httptest.NewRecorder()
|
|
|
|
|
viper.Set("homeassistant.actionTaskProjectId", "some project id")
|
|
|
|
|
ha.HandleHaMessage(w, req)
|
|
|
|
|
assert.Equal(t, http.StatusInternalServerError, w.Code)
|
|
|
|
|
assert.Contains(t, loggerText.String(), "homeassistant.createActionTask: Error unmarshalling")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestHandleTicktickMsgTicktickUtilErr(t *testing.T) {
|
|
|
|
|
teardown, _ := SetupTearDown(t)
|
|
|
|
|
defer teardown()
|
|
|
|
|
|
|
|
|
|
requestBody := `{"target": "ticktick", "action": "create_action_task", "content": "{'title': 'test', 'action': 'test_action', 'due_hour': 12}"}`
|
|
|
|
|
req := httptest.NewRequest(http.MethodPost, "/homeassistant/publish", strings.NewReader(requestBody))
|
|
|
|
|
w := httptest.NewRecorder()
|
|
|
|
|
mockedTicktickUtil := &MockTicktickUtil{}
|
|
|
|
|
viper.Set("homeassistant.actionTaskProjectId", "some project id")
|
|
|
|
|
|
|
|
|
|
mockedTicktickUtil.On("CreateTask", mock.Anything).Return(errors.New("some error"))
|
|
|
|
|
|
|
|
|
|
ha := NewHomeAssistant(mockedTicktickUtil)
|
|
|
|
|
|
|
|
|
|
ha.HandleHaMessage(w, req)
|
|
|
|
|
|
|
|
|
|
mockedTicktickUtil.AssertCalled(t, "CreateTask", mock.Anything)
|
|
|
|
|
assert.Equal(t, http.StatusInternalServerError, w.Code)
|
|
|
|
|
assert.Contains(t, loggerText.String(), "homeassistant.createActionTask: Error creating task")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestHandleHaMessageUnknownTarget(t *testing.T) {
|
|
|
|
|
teardown, ha := SetupTearDown(t)
|
|
|
|
|
defer teardown()
|
|
|
|
|
|
|
|
|
|
requestBody := `{"target": "unknown_target", "action": "record", "content": ""}`
|
|
|
|
|
req := httptest.NewRequest(http.MethodPost, "/homeassistant/publish", strings.NewReader(requestBody))
|
|
|
|
|
w := httptest.NewRecorder()
|
|
|
|
|
|
|
|
|
|
ha.HandleHaMessage(w, req)
|
|
|
|
|
assert.Equal(t, http.StatusInternalServerError, w.Code)
|
|
|
|
|
assert.Contains(t, loggerText.String(), "homeassistant.HandleHaMessage: Unknown target")
|
|
|
|
|
}
|
|
|
|
|
|