|
- package bridge
-
- import (
- "encoding/json"
- "testing"
- "time"
-
- "github.com/AFASystems/presence/internal/pkg/common/appcontext"
- "github.com/AFASystems/presence/internal/pkg/model"
- )
-
- // TestHelper provides utility functions for testing
- type TestHelper struct {
- t *testing.T
- appState *appcontext.AppState
- }
-
- // NewTestHelper creates a new test helper instance
- func NewTestHelper(t *testing.T) *TestHelper {
- return &TestHelper{
- t: t,
- appState: appcontext.NewAppState(),
- }
- }
-
- // GetAppState returns the appState instance
- func (th *TestHelper) GetAppState() *appcontext.AppState {
- return th.appState
- }
-
- // AddTestBeacon adds a beacon with the given MAC and ID to the lookup
- func (th *TestHelper) AddTestBeacon(mac, id string) {
- th.appState.AddBeaconToLookup(mac, id)
- }
-
- // CreateRawReading creates a test RawReading with default values
- func (th *TestHelper) CreateRawReading(mac string, rssi int) model.RawReading {
- return model.RawReading{
- Timestamp: time.Now().Format(time.RFC3339),
- Type: "BLE",
- MAC: mac,
- RSSI: rssi,
- RawData: "0201060302A0",
- }
- }
-
- // CreateRawReadingWithCustomData creates a test RawReading with custom raw data
- func (th *TestHelper) CreateRawReadingWithCustomData(mac string, rssi int, rawData string) model.RawReading {
- return model.RawReading{
- Timestamp: time.Now().Format(time.RFC3339),
- Type: "BLE",
- MAC: mac,
- RSSI: rssi,
- RawData: rawData,
- }
- }
-
- // CreateGatewayReading creates a Gateway type reading
- func (th *TestHelper) CreateGatewayReading(mac string) model.RawReading {
- return model.RawReading{
- Timestamp: time.Now().Format(time.RFC3339),
- Type: "Gateway",
- MAC: mac,
- RSSI: -50,
- RawData: "020106",
- }
- }
-
- // MarshalReadings marshals a slice of readings to JSON
- func (th *TestHelper) MarshalReadings(readings []model.RawReading) []byte {
- data, err := json.Marshal(readings)
- if err != nil {
- th.t.Fatalf("Failed to marshal readings: %v", err)
- }
- return data
- }
-
- // CreateMQTTMessage creates a complete MQTT message with readings
- func (th *TestHelper) CreateMQTTMessage(topic string, readings []model.RawReading) (string, []byte) {
- data := th.MarshalReadings(readings)
- return topic, data
- }
-
- // AssertBeaconAdvertisement asserts that a beacon advertisement matches expected values
- func (th *TestHelper) AssertBeaconAdvertisement(adv model.BeaconAdvertisement, expectedID, expectedHostname, expectedMAC string, expectedRSSI int64) {
- if adv.ID != expectedID {
- th.t.Errorf("Expected ID '%s', got '%s'", expectedID, adv.ID)
- }
-
- if adv.Hostname != expectedHostname {
- th.t.Errorf("Expected hostname '%s', got '%s'", expectedHostname, adv.Hostname)
- }
-
- if adv.MAC != expectedMAC {
- th.t.Errorf("Expected MAC '%s', got '%s'", expectedMAC, adv.MAC)
- }
-
- if adv.RSSI != expectedRSSI {
- th.t.Errorf("Expected RSSI %d, got %d", expectedRSSI, adv.RSSI)
- }
- }
-
- // GenerateTestMAC generates a test MAC address from an index
- func GenerateTestMAC(index int) string {
- return "AA:BB:CC:DD:" + toHex(index>>8) + ":" + toHex(index&0xFF)
- }
-
- // GenerateTestID generates a test beacon ID from an index
- func GenerateTestID(index int) string {
- return "test-beacon-" + toHex(index)
- }
-
- // toHex converts a number to a 2-digit hex string
- func toHex(n int) string {
- return formatInt(n, 16)
- }
-
- // Helper function to format int as hex string
- func formatInt(n, base int) string {
- const digits = "0123456789ABCDEF"
- if n == 0 {
- return "00"
- }
-
- result := ""
- for n > 0 {
- remainder := n % base
- result = string(digits[remainder]) + result
- n = n / base
- }
-
- // Pad to 2 digits
- for len(result) < 2 {
- result = "0" + result
- }
-
- return result
- }
-
- // CreateMockMessage creates a mock MQTT message for testing
- type MockMessage struct {
- topic string
- payload []byte
- }
-
- // NewMockMessage creates a new mock message
- func NewMockMessage(topic string, payload []byte) *MockMessage {
- return &MockMessage{
- topic: topic,
- payload: payload,
- }
- }
-
- // Topic returns the message topic
- func (m *MockMessage) Topic() string {
- return m.topic
- }
-
- // Payload returns the message payload
- func (m *MockMessage) Payload() []byte {
- return m.payload
- }
-
- // Asserted returns a flag (not used in mock)
- func (m *MockMessage) Asserted() bool {
- return false
- }
-
- // Duplicate returns a flag (not used in mock)
- func (m *MockMessage) Duplicate() bool {
- return false
- }
-
- // QoS returns the QoS level (not used in mock)
- func (m *MockMessage) QoS() byte {
- return 0
- }
-
- // Retained returns retained flag (not used in mock)
- func (m *MockMessage) Retained() bool {
- return false
- }
-
- // MessageID returns message ID (not used in mock)
- func (m *MockMessage) MessageID() uint16 {
- return 0
- }
-
- // SetupTestBeacons configures the appState with a standard set of test beacons
- func SetupTestBeacons(appState *appcontext.AppState) {
- beacons := []struct {
- mac string
- id string
- }{
- {"AA:BB:CC:DD:EE:FF", "beacon-1"},
- {"11:22:33:44:55:66", "beacon-2"},
- {"77:88:99:AA:BB:CC", "beacon-3"},
- {"DD:EE:FF:00:11:22", "beacon-4"},
- }
-
- for _, b := range beacons {
- appState.AddBeaconToLookup(b.mac, b.id)
- }
- }
-
- // CreateTestReadings creates a slice of test readings
- func CreateTestReadings(count int) []model.RawReading {
- readings := make([]model.RawReading, count)
- for i := 0; i < count; i++ {
- readings[i] = model.RawReading{
- Timestamp: time.Now().Format(time.RFC3339),
- Type: "BLE",
- MAC: GenerateTestMAC(i),
- RSSI: -60 - i,
- RawData: "0201060302A0",
- }
- }
- return readings
- }
-
- // CleanupTestState cleans up the appState lookup
- func CleanupTestState(appState *appcontext.AppState) {
- appState.CleanLookup()
- }
-
- // AssertKafkaMessageCount asserts that the mock writer received the expected number of messages
- func AssertKafkaMessageCount(t *testing.T, writer *MockKafkaWriter, expected int) {
- if len(writer.Messages) != expected {
- t.Errorf("Expected %d Kafka message(s), got %d", expected, len(writer.Messages))
- }
- }
-
- // AssertNoKafkaMessages asserts that no messages were written to Kafka
- func AssertNoKafkaMessages(t *testing.T, writer *MockKafkaWriter) {
- AssertKafkaMessageCount(t, writer, 0)
- }
|