Add initial MQTT scrubber service scaffold
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
package parser
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"mqqt-scrubber/internal/model"
|
||||
)
|
||||
|
||||
type fixtureCase struct {
|
||||
Name string `json:"name"`
|
||||
Topic string `json:"topic"`
|
||||
Payload string `json:"payload"`
|
||||
ReceivedAt string `json:"received_at"`
|
||||
ExpectedMeasurement string `json:"expected_measurement"`
|
||||
ExpectedTimestamp string `json:"expected_timestamp"`
|
||||
ExpectedTags map[string]string `json:"expected_tags"`
|
||||
ExpectedFields map[string]any `json:"expected_fields"`
|
||||
}
|
||||
|
||||
func TestParseTasmotaFixtures(t *testing.T) {
|
||||
contents, err := os.ReadFile("testdata/tasmota_samples.json")
|
||||
if err != nil {
|
||||
t.Fatalf("read fixture file: %v", err)
|
||||
}
|
||||
|
||||
var fixtures []fixtureCase
|
||||
if err := json.Unmarshal(contents, &fixtures); err != nil {
|
||||
t.Fatalf("parse fixture file: %v", err)
|
||||
}
|
||||
|
||||
for _, fixture := range fixtures {
|
||||
t.Run(fixture.Name, func(t *testing.T) {
|
||||
receivedAt, err := time.Parse(time.RFC3339, fixture.ReceivedAt)
|
||||
if err != nil {
|
||||
t.Fatalf("parse receivedAt: %v", err)
|
||||
}
|
||||
|
||||
expectedTimestamp, err := time.Parse(time.RFC3339, fixture.ExpectedTimestamp)
|
||||
if err != nil {
|
||||
t.Fatalf("parse expected timestamp: %v", err)
|
||||
}
|
||||
|
||||
records, err := ParseTasmota(model.RawMessage{
|
||||
Topic: fixture.Topic,
|
||||
Payload: []byte(fixture.Payload),
|
||||
ReceivedAt: receivedAt,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("ParseTasmota returned error: %v", err)
|
||||
}
|
||||
|
||||
if len(records) != 1 {
|
||||
t.Fatalf("expected 1 record, got %d", len(records))
|
||||
}
|
||||
|
||||
record := records[0]
|
||||
if record.Measurement != fixture.ExpectedMeasurement {
|
||||
t.Fatalf("unexpected measurement: got %s want %s", record.Measurement, fixture.ExpectedMeasurement)
|
||||
}
|
||||
|
||||
if !record.Timestamp.Equal(expectedTimestamp) {
|
||||
t.Fatalf("unexpected timestamp: got %s want %s", record.Timestamp.Format(time.RFC3339), expectedTimestamp.Format(time.RFC3339))
|
||||
}
|
||||
|
||||
for key, value := range fixture.ExpectedTags {
|
||||
if record.Tags[key] != value {
|
||||
t.Fatalf("unexpected tag %s: got %q want %q", key, record.Tags[key], value)
|
||||
}
|
||||
}
|
||||
|
||||
for key, value := range fixture.ExpectedFields {
|
||||
fieldValue, ok := record.Fields[key]
|
||||
if !ok {
|
||||
t.Fatalf("expected field %s to be present", key)
|
||||
}
|
||||
|
||||
if !fieldEquals(fieldValue, value) {
|
||||
t.Fatalf("unexpected field %s: got %#v want %#v", key, fieldValue, value)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func fieldEquals(got any, want any) bool {
|
||||
switch typedWant := want.(type) {
|
||||
case float64:
|
||||
typedGot, ok := got.(float64)
|
||||
return ok && typedGot == typedWant
|
||||
case string:
|
||||
typedGot, ok := got.(string)
|
||||
return ok && typedGot == typedWant
|
||||
case bool:
|
||||
typedGot, ok := got.(bool)
|
||||
return ok && typedGot == typedWant
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user