55 lines
2.1 KiB
Go
55 lines
2.1 KiB
Go
package service
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
"time"
|
|
|
|
"git.apinb.com/heqiapp/platforms/backend/iot-client/internal/config"
|
|
)
|
|
|
|
func TestDispatchPreservesIdempotency(t *testing.T) {
|
|
calls := 0
|
|
upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
calls++
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusAccepted)
|
|
_, _ = w.Write([]byte(`{"status":"dispatched","packet_number":9}`))
|
|
}))
|
|
defer upstream.Close()
|
|
srv := New(config.Config{HTTP: config.HTTP{InternalToken: "token"}, Upstream: config.Upstream{IoTServerURL: upstream.URL, Token: "token"}})
|
|
cmd := Command{Identity: "one", IdempotencyKey: "same", DeviceID: "1234567890123456", Action: "close_valve", ExpiresAt: time.Now().Add(time.Minute)}
|
|
status, packet, err := srv.dispatch(context.Background(), cmd)
|
|
if err != nil || status != "dispatched" || packet != 9 || calls != 1 {
|
|
t.Fatalf("status=%s packet=%d calls=%d err=%v", status, packet, calls, err)
|
|
}
|
|
}
|
|
|
|
func TestCommandsDoesNotDispatchDuplicateIdempotencyKey(t *testing.T) {
|
|
calls := 0
|
|
upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
calls++
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusAccepted)
|
|
_, _ = w.Write([]byte(`{"status":"dispatched","packet_number":9}`))
|
|
}))
|
|
defer upstream.Close()
|
|
srv := New(config.Config{HTTP: config.HTTP{InternalToken: "token"}, Upstream: config.Upstream{IoTServerURL: upstream.URL, Token: "token"}})
|
|
body := []byte(`{"identity":"one","idempotency_key":"same","device_id":"1234567890123456","action":"close_valve","expires_at":"2099-01-01T00:00:00Z"}`)
|
|
for range 2 {
|
|
request := httptest.NewRequest(http.MethodPost, "/v1/device-commands", bytes.NewReader(body))
|
|
request.Header.Set("X-Heqi-Iot-Token", "token")
|
|
response := httptest.NewRecorder()
|
|
srv.commands(response, request)
|
|
if response.Code != http.StatusAccepted && response.Code != http.StatusOK {
|
|
t.Fatalf("unexpected status %d: %s", response.Code, response.Body.String())
|
|
}
|
|
}
|
|
if calls != 1 {
|
|
t.Fatalf("duplicate command dispatched %d times", calls)
|
|
}
|
|
}
|