package clientupdate import ( "context" "fmt" "testing" "queryorchestration/internal/client" "queryorchestration/internal/database/repository" "queryorchestration/internal/serviceconfig" "queryorchestration/internal/serviceconfig/queue/clientsync" queuemock "queryorchestration/mocks/queue" "github.com/aws/aws-sdk-go-v2/service/sqs" "github.com/pashagolub/pgxmock/v3" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" ) type Config struct { serviceconfig.BaseConfig clientsync.ClientSyncConfig } func TestUpdate(t *testing.T) { ctx := context.Background() pool, err := pgxmock.NewPool() require.NoError(t, err) cfg := &Config{} cfg.DBPool = pool cfg.DBQueries = repository.New(pool) svc := New(cfg, &Services{ Client: client.New(cfg), }) c := client.Client{ ID: "huhu", Name: "example_name", CanSync: false, } update := Update{} pool.ExpectQuery("name: GetClient :one").WithArgs(c.ID). WillReturnRows( pgxmock.NewRows([]string{"id", "name", "canSync"}). AddRow(c.ID, c.Name, c.CanSync), ) err = svc.Update(ctx, c.ID, &update) assert.Error(t, err) c.CanSync = false update.CanSync = &c.CanSync pool.ExpectQuery("name: GetClient :one").WithArgs(c.ID). WillReturnRows( pgxmock.NewRows([]string{"id", "name", "canSync"}). AddRow(c.ID, c.Name, c.CanSync), ) err = svc.Update(ctx, c.ID, &update) assert.Error(t, err) c.Name = "updated_name" update.Name = &c.Name pool.ExpectQuery("name: GetClient :one").WithArgs(c.ID). WillReturnRows( pgxmock.NewRows([]string{"id", "name", "canSync"}). AddRow(c.ID, c.Name, c.CanSync), ) pool.ExpectExec("name: UpdateClient :exec").WithArgs(*update.Name, c.ID). WillReturnResult(pgxmock.NewResult("", 1)) err = svc.Update(ctx, c.ID, &update) assert.Error(t, err) } func TestNormalizeUpdateParams(t *testing.T) { svc := Service{} err := svc.normalizeUpdateParams("huhu", nil, nil) assert.Error(t, err) current := &client.Client{ ID: "hi", Name: "client", } update := &Update{} err = svc.normalizeUpdateParams(current.ID, current, update) assert.Error(t, err) n := "updated_client" cs := true update = &Update{ Name: &n, CanSync: &cs, } err = svc.normalizeUpdateParams(current.ID, current, update) require.NoError(t, err) n = "updated_client" cs = true assert.EqualExportedValues(t, Update{ Name: &n, CanSync: &cs, }, *update) update = &Update{ Name: ¤t.Name, CanSync: ¤t.CanSync, } err = svc.normalizeUpdateParams(current.ID, current, update) assert.Error(t, err) } func TestSubmitUpdate(t *testing.T) { ctx := context.Background() pool, err := pgxmock.NewPool() require.NoError(t, err) cfg := &Config{} cfg.DBPool = pool cfg.DBQueries = repository.New(pool) svc := New(cfg, &Services{}) c := client.Client{ ID: "hello", Name: "example_name", CanSync: false, } update := Update{} pool.ExpectBegin() pool.ExpectCommit() err = svc.submitUpdate(ctx, c.ID, &update) require.NoError(t, err) c.CanSync = true update.CanSync = &c.CanSync pool.ExpectBegin() pool.ExpectExec("name: AddClientCanSync :exec").WithArgs(*update.CanSync, c.ID). WillReturnResult(pgxmock.NewResult("", 1)) pool.ExpectCommit() err = svc.submitUpdate(ctx, c.ID, &update) require.NoError(t, err) c.Name = "updated_name" update.Name = &c.Name update.CanSync = nil pool.ExpectBegin() pool.ExpectExec("name: UpdateClient :exec").WithArgs(*update.Name, c.ID). WillReturnResult(pgxmock.NewResult("", 1)) pool.ExpectCommit() err = svc.submitUpdate(ctx, c.ID, &update) require.NoError(t, err) } func TestInformUpdate(t *testing.T) { ctx := context.Background() cfg := &Config{} mockSQS := queuemock.NewMockSQSClient(t) cfg.QueueClient = mockSQS svc := New(cfg, &Services{}) id := "HIELO" t.Run("no cansync", func(t *testing.T) { update := Update{} err := svc.informUpdate(ctx, id, &update) require.NoError(t, err) }) t.Run("false cansync", func(t *testing.T) { cansync := false update := Update{ CanSync: &cansync, } err := svc.informUpdate(ctx, id, &update) require.NoError(t, err) }) t.Run("true cansync", func(t *testing.T) { cansync := true update := Update{ CanSync: &cansync, } mockSQS.EXPECT(). SendMessage( mock.Anything, mock.MatchedBy(func(in *sqs.SendMessageInput) bool { return *in.QueueUrl == cfg.ClientSyncURL && *in.MessageBody == fmt.Sprintf("{\"id\":\"%s\"}", id) }), mock.Anything, ). Return(&sqs.SendMessageOutput{}, nil) err := svc.informUpdate(ctx, id, &update) require.NoError(t, err) }) }