package contract import ( "encoding/json" "testing" "github.com/google/uuid" "github.com/stretchr/testify/require" ) func TestUpdateCategoryRequestTellsNullFromOmitted(t *testing.T) { parentID := uuid.New() tests := []struct { name string body string wantParentID *uuid.UUID wantClear bool wantClearFee bool wantFee *float64 wantNameIsSet bool }{ {name: "omitted leaves parent unchanged", body: `{"name":"Food"}`, wantNameIsSet: true}, {name: "null detaches the parent", body: `{"parent_id":null}`, wantClear: true}, {name: "empty string detaches the parent", body: `{"name":"Food","parent_id":""}`, wantClear: true, wantNameIsSet: true}, {name: "uuid sets the parent", body: `{"parent_id":"` + parentID.String() + `"}`, wantParentID: &parentID}, {name: "null removes the owner fee override", body: `{"owner_fee_percent":null}`, wantClearFee: true}, {name: "number sets the owner fee", body: `{"owner_fee_percent":35}`, wantFee: func() *float64 { v := 35.0; return &v }()}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { var req UpdateCategoryRequest require.NoError(t, json.Unmarshal([]byte(tt.body), &req)) require.Equal(t, tt.wantParentID, req.ParentID) require.Equal(t, tt.wantClear, req.ClearParentID) require.Equal(t, tt.wantClearFee, req.ClearOwnerFeePercent) require.Equal(t, tt.wantFee, req.OwnerFeePercent) require.Equal(t, tt.wantNameIsSet, req.Name != nil) }) } } func TestUpdateCategoryRequestRejectsInvalidParentID(t *testing.T) { var req UpdateCategoryRequest require.Error(t, json.Unmarshal([]byte(`{"parent_id":"not-a-uuid"}`), &req)) }