package tests import ( "encoding/binary" "testing" "time" "github.com/jfraeys/fetch_ml/internal/api" ) func TestProtocolSerialization(t *testing.T) { // Test success packet successPacket := api.NewSuccessPacket("Operation completed successfully") data, err := successPacket.Serialize() if err != nil { t.Fatalf("Failed to serialize success packet: %v", err) } // Verify packet type if len(data) < 1 || data[0] != api.PacketTypeSuccess { t.Errorf("Expected packet type %d, got %d", api.PacketTypeSuccess, data[0]) } // Verify timestamp is present (9 bytes minimum: 1 type + 8 timestamp) if len(data) < 9 { t.Errorf("Expected at least 9 bytes, got %d", len(data)) } // Test error packet errorPacket := api.NewErrorPacket(api.ErrorCodeAuthenticationFailed, "Auth failed", "Invalid API key") data, err = errorPacket.Serialize() if err != nil { t.Fatalf("Failed to serialize error packet: %v", err) } if len(data) < 1 || data[0] != api.PacketTypeError { t.Errorf("Expected packet type %d, got %d", api.PacketTypeError, data[0]) } // Test progress packet progressPacket := api.NewProgressPacket(api.ProgressTypePercentage, 75, 100, "Processing...") data, err = progressPacket.Serialize() if err != nil { t.Fatalf("Failed to serialize progress packet: %v", err) } if len(data) < 1 || data[0] != api.PacketTypeProgress { t.Errorf("Expected packet type %d, got %d", api.PacketTypeProgress, data[0]) } // Test status packet statusPacket := api.NewStatusPacket(`{"workers":1,"queued":0}`) data, err = statusPacket.Serialize() if err != nil { t.Fatalf("Failed to serialize status packet: %v", err) } if len(data) < 1 || data[0] != api.PacketTypeStatus { t.Errorf("Expected packet type %d, got %d", api.PacketTypeStatus, data[0]) } } func TestErrorMessageMapping(t *testing.T) { tests := map[byte]string{ api.ErrorCodeUnknownError: "Unknown error occurred", api.ErrorCodeAuthenticationFailed: "Authentication failed", api.ErrorCodeJobNotFound: "Job not found", api.ErrorCodeServerOverloaded: "Server is overloaded", } for code, expected := range tests { actual := api.GetErrorMessage(code) if actual != expected { t.Errorf("Expected error message '%s' for code %d, got '%s'", expected, code, actual) } } } func TestLogLevelMapping(t *testing.T) { tests := map[byte]string{ api.LogLevelDebug: "DEBUG", api.LogLevelInfo: "INFO", api.LogLevelWarn: "WARN", api.LogLevelError: "ERROR", } for level, expected := range tests { actual := api.GetLogLevelName(level) if actual != expected { t.Errorf("Expected log level '%s' for level %d, got '%s'", expected, level, actual) } } } func TestTimestampConsistency(t *testing.T) { before := time.Now().Unix() packet := api.NewSuccessPacket("Test message") data, err := packet.Serialize() if err != nil { t.Fatalf("Failed to serialize: %v", err) } after := time.Now().Unix() // Extract timestamp (bytes 1-8, big-endian) if len(data) < 9 { t.Fatalf("Packet too short: %d bytes", len(data)) } timestamp := binary.BigEndian.Uint64(data[1:9]) if timestamp < uint64(before) || timestamp > uint64(after) { t.Errorf("Timestamp %d not in expected range [%d, %d]", timestamp, before, after) } }