package adapter_test import ( "cmp" "context" "slices" "testing" "gitea.dwysokinski.me/twhelp/corev3/internal/domain" "gitea.dwysokinski.me/twhelp/corev3/internal/domain/domaintest" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func testVersionRepository(t *testing.T, newRepos func(t *testing.T) repositories) { t.Helper() ctx := context.Background() t.Run("List", func(t *testing.T) { t.Parallel() repos := newRepos(t) tests := []struct { name string params func(t *testing.T) domain.ListVersionsParams assertResult func(t *testing.T, params domain.ListVersionsParams, res domain.ListVersionsResult) assertError func(t *testing.T, err error) }{ { name: "OK: default params", params: func(t *testing.T) domain.ListVersionsParams { t.Helper() return domain.NewListVersionsParams() }, assertResult: func(t *testing.T, params domain.ListVersionsParams, res domain.ListVersionsResult) { t.Helper() assert.NotEmpty(t, res.Versions()) assert.True(t, slices.IsSortedFunc(res.Versions(), func(a, b domain.Version) int { return cmp.Compare(a.Code(), b.Code()) })) assert.True(t, res.Next().IsZero()) }, assertError: func(t *testing.T, err error) { t.Helper() require.NoError(t, err) }, }, { name: "OK: sort=[code DESC]", params: func(t *testing.T) domain.ListVersionsParams { t.Helper() params := domain.NewListVersionsParams() require.NoError(t, params.SetSort([]domain.VersionSort{domain.VersionSortCodeDESC})) return params }, assertResult: func(t *testing.T, params domain.ListVersionsParams, res domain.ListVersionsResult) { t.Helper() assert.NotEmpty(t, res.Versions()) assert.True(t, slices.IsSortedFunc(res.Versions(), func(a, b domain.Version) int { return cmp.Compare(a.Code(), b.Code()) * -1 })) }, assertError: func(t *testing.T, err error) { t.Helper() require.NoError(t, err) }, }, { name: "OK: cursor sort=[code ASC]", params: func(t *testing.T) domain.ListVersionsParams { t.Helper() params := domain.NewListVersionsParams() require.NoError(t, params.SetSort([]domain.VersionSort{domain.VersionSortCodeASC})) res, err := repos.version.List(ctx, params) require.NoError(t, err) require.Greater(t, len(res.Versions()), 2) require.NoError(t, params.SetCursor(domaintest.NewVersionCursor(t, func(cfg *domaintest.VersionCursorConfig) { cfg.Code = res.Versions()[1].Code() }))) return params }, assertResult: func(t *testing.T, params domain.ListVersionsParams, res domain.ListVersionsResult) { t.Helper() assert.NotEmpty(t, res.Versions()) assert.True(t, slices.IsSortedFunc(res.Versions(), func(a, b domain.Version) int { return cmp.Compare(a.Code(), b.Code()) })) for _, v := range res.Versions() { assert.GreaterOrEqual(t, v.Code(), params.Cursor().Code(), v.Code()) } }, assertError: func(t *testing.T, err error) { t.Helper() require.NoError(t, err) }, }, { name: "OK: cursor sort=[code DESC]", params: func(t *testing.T) domain.ListVersionsParams { t.Helper() params := domain.NewListVersionsParams() require.NoError(t, params.SetSort([]domain.VersionSort{domain.VersionSortCodeDESC})) res, err := repos.version.List(ctx, params) require.NoError(t, err) require.Greater(t, len(res.Versions()), 2) require.NoError(t, params.SetCursor(domaintest.NewVersionCursor(t, func(cfg *domaintest.VersionCursorConfig) { cfg.Code = res.Versions()[1].Code() }))) return params }, assertResult: func(t *testing.T, params domain.ListVersionsParams, res domain.ListVersionsResult) { t.Helper() assert.NotEmpty(t, res.Versions()) assert.True(t, slices.IsSortedFunc(res.Versions(), func(a, b domain.Version) int { return cmp.Compare(a.Code(), b.Code()) * -1 })) for _, v := range res.Versions() { assert.LessOrEqual(t, v.Code(), params.Cursor().Code(), v.Code()) } }, assertError: func(t *testing.T, err error) { t.Helper() require.NoError(t, err) }, }, { name: "OK: codes limit=1", params: func(t *testing.T) domain.ListVersionsParams { t.Helper() params := domain.NewListVersionsParams() require.NoError(t, params.SetLimit(1)) res, err := repos.version.List(ctx, params) require.NoError(t, err) require.NotEmpty(t, res) require.NoError(t, params.SetCodes([]string{res.Versions()[0].Code()})) return params }, assertResult: func(t *testing.T, params domain.ListVersionsParams, res domain.ListVersionsResult) { t.Helper() versions := res.Versions() codes := params.Codes() assert.Len(t, versions, len(codes)) for _, v := range versions { assert.Contains(t, codes, v.Code()) } }, assertError: func(t *testing.T, err error) { t.Helper() require.NoError(t, err) }, }, { name: "OK: limit=5", params: func(t *testing.T) domain.ListVersionsParams { t.Helper() params := domain.NewListVersionsParams() require.NoError(t, params.SetLimit(5)) return params }, assertResult: func(t *testing.T, params domain.ListVersionsParams, res domain.ListVersionsResult) { t.Helper() assert.Len(t, res.Versions(), params.Limit()) assert.False(t, res.Next().IsZero()) }, assertError: func(t *testing.T, err error) { t.Helper() require.NoError(t, err) }, }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() params := tt.params(t) res, err := repos.version.List(ctx, params) tt.assertError(t, err) tt.assertResult(t, params, res) }) } }) }