Add test structure
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -32,4 +32,6 @@ __pycache__/
|
|||||||
.pytest_cache/
|
.pytest_cache/
|
||||||
config.yaml
|
config.yaml
|
||||||
bin/
|
bin/
|
||||||
*.db
|
*.db
|
||||||
|
|
||||||
|
cover.html
|
||||||
@@ -103,8 +103,7 @@ func serve(cmd *cobra.Command, args []string) {
|
|||||||
|
|
||||||
router.HandleFunc("/poo/latest", pooRecorder.HandleNotifyLatestPoo).Methods("GET")
|
router.HandleFunc("/poo/latest", pooRecorder.HandleNotifyLatestPoo).Methods("GET")
|
||||||
router.HandleFunc("/poo/record", pooRecorder.HandleRecordPoo).Methods("POST")
|
router.HandleFunc("/poo/record", pooRecorder.HandleRecordPoo).Methods("POST")
|
||||||
|
router.HandleFunc("/homeassistant/publish", homeassistant.HandleHaMessage).Methods("POST")
|
||||||
router.HandleFunc("/homeassistant/publish", homeassistant.DefaultHandler.HandleHaMessage).Methods("POST")
|
|
||||||
|
|
||||||
router.HandleFunc("/location/record", locationRecorder.HandleRecordLocation).Methods("POST")
|
router.HandleFunc("/location/record", locationRecorder.HandleRecordLocation).Methods("POST")
|
||||||
|
|
||||||
|
|||||||
@@ -23,19 +23,7 @@ type actionTask struct {
|
|||||||
DueHour int `json:"due_hour"`
|
DueHour int `json:"due_hour"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type HaMessageHandler struct {
|
func HandleHaMessage(w http.ResponseWriter, r *http.Request) {
|
||||||
PooRecorderHandler func(message haMessage)
|
|
||||||
LocationRecorderHandler func(message haMessage)
|
|
||||||
TicktickHandler func(message haMessage)
|
|
||||||
}
|
|
||||||
|
|
||||||
var DefaultHandler = HaMessageHandler{
|
|
||||||
PooRecorderHandler: handlePooRecorderMsg,
|
|
||||||
LocationRecorderHandler: handleLocationRecorderMsg,
|
|
||||||
TicktickHandler: handleTicktickMsg,
|
|
||||||
}
|
|
||||||
|
|
||||||
func (handler HaMessageHandler) HandleHaMessage(w http.ResponseWriter, r *http.Request) {
|
|
||||||
var message haMessage
|
var message haMessage
|
||||||
decoder := json.NewDecoder(r.Body)
|
decoder := json.NewDecoder(r.Body)
|
||||||
decoder.DisallowUnknownFields()
|
decoder.DisallowUnknownFields()
|
||||||
@@ -48,11 +36,14 @@ func (handler HaMessageHandler) HandleHaMessage(w http.ResponseWriter, r *http.R
|
|||||||
|
|
||||||
switch message.Target {
|
switch message.Target {
|
||||||
case "poo_recorder":
|
case "poo_recorder":
|
||||||
handler.PooRecorderHandler(message)
|
handlePooRecorderMsg(message)
|
||||||
case "location_recorder":
|
case "location_recorder":
|
||||||
handler.LocationRecorderHandler(message)
|
handleLocationRecorderMsg(message)
|
||||||
case "ticktick":
|
case "ticktick":
|
||||||
handler.TicktickHandler(message)
|
handleTicktickMsg(message)
|
||||||
|
default:
|
||||||
|
slog.Warn(fmt.Sprintln("HandleHaMessage Unknown target", message.Target))
|
||||||
|
http.Error(w, "Unknown target", http.StatusBadRequest)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,7 +82,7 @@ func handleTicktickMsg(message haMessage) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleGetLatestPoo() {
|
func handleGetLatestPoo() bool {
|
||||||
client := &http.Client{
|
client := &http.Client{
|
||||||
Timeout: time.Second * 1,
|
Timeout: time.Second * 1,
|
||||||
}
|
}
|
||||||
@@ -99,7 +90,10 @@ func handleGetLatestPoo() {
|
|||||||
_, err := client.Get("http://localhost:" + port + "/poo/latest")
|
_, err := client.Get("http://localhost:" + port + "/poo/latest")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Warn(fmt.Sprintln("handleGetLatestPoo Error sending request to poo recorder", err))
|
slog.Warn(fmt.Sprintln("handleGetLatestPoo Error sending request to poo recorder", err))
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func createActionTask(message haMessage) {
|
func createActionTask(message haMessage) {
|
||||||
|
|||||||
@@ -1,65 +1,46 @@
|
|||||||
package homeassistant
|
package homeassistant
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"bytes"
|
||||||
"math/rand/v2"
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/mock"
|
"github.com/spf13/viper"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MockedHaHandler struct {
|
var (
|
||||||
mock.Mock
|
loggerText = new(bytes.Buffer)
|
||||||
|
)
|
||||||
|
|
||||||
|
func LoggerSetupTeardown(t *testing.T) func() {
|
||||||
|
logger := slog.New(slog.NewTextHandler(loggerText, nil))
|
||||||
|
defaultLogger := slog.Default()
|
||||||
|
slog.SetDefault(logger)
|
||||||
|
|
||||||
|
return func() {
|
||||||
|
slog.SetDefault(defaultLogger)
|
||||||
|
loggerText.Reset()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MockedHaHandler) handlePooRecorderMsg(message haMessage) {
|
func TestHandlePooRecorderMsgGetLatest(t *testing.T) {
|
||||||
m.Called(message)
|
teardown := LoggerSetupTeardown(t)
|
||||||
}
|
defer teardown()
|
||||||
|
|
||||||
func (m *MockedHaHandler) handleLocationRecorderMsg(message haMessage) {
|
|
||||||
m.Called(message)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MockedHaHandler) handleTicktickMsg(message haMessage) {
|
|
||||||
m.Called(message)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHandleHaMessagePooRecorder(t *testing.T) {
|
|
||||||
requestBody := `{"target": "poo_recorder", "action": "get_latest", "content": ""}`
|
requestBody := `{"target": "poo_recorder", "action": "get_latest", "content": ""}`
|
||||||
req := httptest.NewRequest(http.MethodPost, "/homeassistant/publish", strings.NewReader(requestBody))
|
req := httptest.NewRequest(http.MethodPost, "/homeassistant/publish", strings.NewReader(requestBody))
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
assert.Equal(t, "/poo/latest", r.URL.Path)
|
||||||
|
}))
|
||||||
|
defer server.Close()
|
||||||
|
port := strings.Split(server.URL, ":")[2]
|
||||||
|
viper.Set("port", port)
|
||||||
|
|
||||||
testObj := new(MockedHaHandler)
|
HandleHaMessage(w, req)
|
||||||
mockedHandler := HaMessageHandler{
|
assert.Equal(t, http.StatusOK, w.Code)
|
||||||
PooRecorderHandler: testObj.handlePooRecorderMsg,
|
assert.Empty(t, loggerText.String())
|
||||||
LocationRecorderHandler: testObj.handleLocationRecorderMsg,
|
|
||||||
TicktickHandler: testObj.handleTicktickMsg,
|
|
||||||
}
|
|
||||||
testObj.On("handlePooRecorderMsg", haMessage{Target: "poo_recorder", Action: "get_latest"}).Return()
|
|
||||||
mockedHandler.HandleHaMessage(w, req)
|
|
||||||
testObj.AssertCalled(t, "handlePooRecorderMsg", haMessage{Target: "poo_recorder", Action: "get_latest"})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHandleHaMessageLocationRecorder(t *testing.T) {
|
|
||||||
expectedLatitude := rand.Float64() * 359
|
|
||||||
expectedLongitude := rand.Float64() * 359
|
|
||||||
expectedAltitude := rand.Float64() * 10000
|
|
||||||
requestBody := fmt.Sprintf(`{"target": "location_recorder", "action": "record",
|
|
||||||
"content": "{'Person': 'Tom', 'latitude': %f, 'longitude': %f, 'altitude': %f}"}`, expectedLatitude, expectedLongitude, expectedAltitude)
|
|
||||||
req := httptest.NewRequest(http.MethodPost, "/homeassistant/publish", strings.NewReader(requestBody))
|
|
||||||
w := httptest.NewRecorder()
|
|
||||||
testobj := new(MockedHaHandler)
|
|
||||||
mockedHandler := HaMessageHandler{
|
|
||||||
PooRecorderHandler: testobj.handlePooRecorderMsg,
|
|
||||||
LocationRecorderHandler: testobj.handleLocationRecorderMsg,
|
|
||||||
TicktickHandler: testobj.handleTicktickMsg,
|
|
||||||
}
|
|
||||||
testobj.On("handleLocationRecorderMsg", haMessage{Target: "location_recorder", Action: "record",
|
|
||||||
Content: fmt.Sprintf("{'Person': 'Tom', 'latitude': %f, 'longitude': %f, 'altitude': %f}", expectedLatitude, expectedLongitude, expectedAltitude)}).Return()
|
|
||||||
mockedHandler.HandleHaMessage(w, req)
|
|
||||||
testobj.AssertCalled(t, "handleLocationRecorderMsg", haMessage{Target: "location_recorder", Action: "record",
|
|
||||||
Content: fmt.Sprintf("{'Person': 'Tom', 'latitude': %f, 'longitude': %f, 'altitude': %f}", expectedLatitude, expectedLongitude, expectedAltitude)})
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user