package transcoder import ( "reflect" "strconv" "testing" model "galaxy/model/order" "github.com/google/uuid" ) func TestUserGamesCommandPayloadRoundTrip(t *testing.T) { t.Parallel() source := &model.UserGamesCommand{ GameID: uuid.MustParse("11111111-2222-3333-4444-555555555555"), Commands: []model.DecodableCommand{ &model.CommandRaceVote{CommandMeta: commandMeta("cmd-01", model.CommandTypeRaceVote, nil, nil), Acceptor: "race-a"}, &model.CommandShipGroupSend{CommandMeta: commandMeta("cmd-02", model.CommandTypeShipGroupSend, nil, nil), ID: "group-1", Destination: 7}, }, } payload, err := UserGamesCommandToPayload(source) if err != nil { t.Fatalf("encode user games command: %v", err) } decoded, err := PayloadToUserGamesCommand(payload) if err != nil { t.Fatalf("decode user games command: %v", err) } if !reflect.DeepEqual(source, decoded) { t.Fatalf("round-trip mismatch\nsource: %#v\ndecoded:%#v", source, decoded) } } func TestUserGamesOrderPayloadRoundTrip(t *testing.T) { t.Parallel() source := &model.UserGamesOrder{ GameID: uuid.MustParse("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"), UpdatedAt: 12345, Commands: []model.DecodableCommand{ &model.CommandPlanetRename{CommandMeta: commandMeta("cmd-1", model.CommandTypePlanetRename, nil, nil), Number: 5, Name: "alpha"}, }, } payload, err := UserGamesOrderToPayload(source) if err != nil { t.Fatalf("encode user games order: %v", err) } decoded, err := PayloadToUserGamesOrder(payload) if err != nil { t.Fatalf("decode user games order: %v", err) } if !reflect.DeepEqual(source, decoded) { t.Fatalf("round-trip mismatch\nsource: %#v\ndecoded:%#v", source, decoded) } } func TestUserGamesCommandRejectsNilAndEmpty(t *testing.T) { t.Parallel() if _, err := UserGamesCommandToPayload(nil); err == nil { t.Fatalf("expected error encoding nil user games command") } if _, err := PayloadToUserGamesCommand(nil); err == nil { t.Fatalf("expected error decoding empty user games command") } if _, err := UserGamesOrderToPayload(nil); err == nil { t.Fatalf("expected error encoding nil user games order") } if _, err := PayloadToUserGamesOrder(nil); err == nil { t.Fatalf("expected error decoding empty user games order") } if _, err := UserGamesOrderGetToPayload(nil); err == nil { t.Fatalf("expected error encoding nil user games order get") } if _, err := PayloadToUserGamesOrderGet(nil); err == nil { t.Fatalf("expected error decoding empty user games order get") } if _, _, err := PayloadToUserGamesOrderGetResponse(nil); err == nil { t.Fatalf("expected error decoding empty user games order get response") } } func TestUserGamesOrderResponsePayloadRoundTrip(t *testing.T) { t.Parallel() applied := true rejected := false errCode := 7 source := &model.UserGamesOrder{ GameID: uuid.MustParse("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"), UpdatedAt: 99, Commands: []model.DecodableCommand{ &model.CommandPlanetRename{ CommandMeta: commandMeta("cmd-1", model.CommandTypePlanetRename, &applied, nil), Number: 5, Name: "alpha", }, &model.CommandPlanetRename{ CommandMeta: commandMeta("cmd-2", model.CommandTypePlanetRename, &rejected, &errCode), Number: 6, Name: "beta", }, }, } payload, err := UserGamesOrderResponseToPayload(source) if err != nil { t.Fatalf("encode user games order response: %v", err) } decoded, err := PayloadToUserGamesOrderResponse(payload) if err != nil { t.Fatalf("decode user games order response: %v", err) } if !reflect.DeepEqual(source, decoded) { t.Fatalf("round-trip mismatch\nsource: %#v\ndecoded:%#v", source, decoded) } } func TestUserGamesOrderResponseEmptyPayload(t *testing.T) { t.Parallel() payload, err := UserGamesOrderResponseToPayload(nil) if err != nil { t.Fatalf("encode empty user games order response: %v", err) } if len(payload) == 0 { t.Fatal("empty envelope payload must be non-zero length") } decoded, err := PayloadToUserGamesOrderResponse(payload) if err != nil { t.Fatalf("decode empty user games order response: %v", err) } if decoded != nil { t.Fatalf("empty envelope must decode to nil, got %#v", decoded) } } func TestUserGamesOrderGetPayloadRoundTrip(t *testing.T) { t.Parallel() source := &model.UserGamesOrderGet{ GameID: uuid.MustParse("11111111-2222-3333-4444-555555555555"), Turn: 7, } payload, err := UserGamesOrderGetToPayload(source) if err != nil { t.Fatalf("encode user games order get: %v", err) } decoded, err := PayloadToUserGamesOrderGet(payload) if err != nil { t.Fatalf("decode user games order get: %v", err) } if !reflect.DeepEqual(source, decoded) { t.Fatalf("round-trip mismatch\nsource: %#v\ndecoded:%#v", source, decoded) } } func TestUserGamesOrderGetRejectsNegativeTurn(t *testing.T) { t.Parallel() if _, err := UserGamesOrderGetToPayload(&model.UserGamesOrderGet{ GameID: uuid.MustParse("11111111-2222-3333-4444-555555555555"), Turn: -1, }); err == nil { t.Fatalf("expected error encoding negative turn") } } func TestUserGamesOrderGetResponseRoundTrip(t *testing.T) { t.Parallel() applied := true stored := &model.UserGamesOrder{ GameID: uuid.MustParse("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"), UpdatedAt: 1234, Commands: []model.DecodableCommand{ &model.CommandPlanetRename{ CommandMeta: commandMeta("cmd-1", model.CommandTypePlanetRename, &applied, nil), Number: 5, Name: "stored", }, }, } payload, err := UserGamesOrderGetResponseToPayload(stored, true) if err != nil { t.Fatalf("encode user games order get response: %v", err) } decoded, found, err := PayloadToUserGamesOrderGetResponse(payload) if err != nil { t.Fatalf("decode user games order get response: %v", err) } if !found { t.Fatal("expected found=true round-trip") } if !reflect.DeepEqual(stored, decoded) { t.Fatalf("round-trip mismatch\nsource: %#v\ndecoded:%#v", stored, decoded) } } func TestUserGamesOrderGetResponseNotFound(t *testing.T) { t.Parallel() payload, err := UserGamesOrderGetResponseToPayload(nil, false) if err != nil { t.Fatalf("encode not-found response: %v", err) } decoded, found, err := PayloadToUserGamesOrderGetResponse(payload) if err != nil { t.Fatalf("decode not-found response: %v", err) } if found { t.Fatal("expected found=false") } if decoded != nil { t.Fatalf("expected nil order, got %#v", decoded) } } func TestInt64ToInt(t *testing.T) { t.Parallel() value, err := int64ToInt(123, "field") if err != nil { t.Fatalf("unexpected error: %v", err) } if value != 123 { t.Fatalf("unexpected int value: %d", value) } if strconv.IntSize == 32 { maxInt := int(^uint(0) >> 1) _, err = int64ToInt(int64(maxInt)+1, "field") if err == nil { t.Fatal("expected overflow error") } } } func commandMeta(id string, cmdType model.CommandType, applied *bool, errCode *int) model.CommandMeta { return model.CommandMeta{ CmdType: cmdType, CmdID: id, CmdApplied: applied, CmdErrCode: errCode, } }