refactor: version cursor - don't allow for nullable values
This commit is contained in:
parent
74c5d842ce
commit
7f614877c5
|
@ -50,18 +50,19 @@ func (a listVersionsParamsApplier) apply(q *bun.SelectQuery) *bun.SelectQuery {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, s := range a.params.Sort() {
|
for _, s := range a.params.Sort() {
|
||||||
codeCursor := a.params.Cursor().Code()
|
cursorZero := a.params.Cursor().IsZero()
|
||||||
|
cursorCode := a.params.Cursor().Code()
|
||||||
|
|
||||||
switch s {
|
switch s {
|
||||||
case domain.VersionSortCodeASC:
|
case domain.VersionSortCodeASC:
|
||||||
if codeCursor.Valid {
|
if !cursorZero {
|
||||||
q = q.Where("version.code >= ?", codeCursor.Value)
|
q = q.Where("version.code >= ?", cursorCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
q = q.Order("version.code ASC")
|
q = q.Order("version.code ASC")
|
||||||
case domain.VersionSortCodeDESC:
|
case domain.VersionSortCodeDESC:
|
||||||
if codeCursor.Valid {
|
if !cursorZero {
|
||||||
q = q.Where("version.code <= ?", codeCursor.Value)
|
q = q.Where("version.code <= ?", cursorCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
q = q.Order("version.code DESC")
|
q = q.Order("version.code DESC")
|
||||||
|
|
|
@ -80,10 +80,7 @@ func testVersionRepository(t *testing.T, newRepos func(t *testing.T) repositorie
|
||||||
require.Greater(t, len(res.Versions()), 2)
|
require.Greater(t, len(res.Versions()), 2)
|
||||||
|
|
||||||
require.NoError(t, params.SetCursor(domaintest.NewVersionCursor(t, func(cfg *domaintest.VersionCursorConfig) {
|
require.NoError(t, params.SetCursor(domaintest.NewVersionCursor(t, func(cfg *domaintest.VersionCursorConfig) {
|
||||||
cfg.Code = domain.NullString{
|
cfg.Code = res.Versions()[1].Code()
|
||||||
Value: res.Versions()[1].Code(),
|
|
||||||
Valid: true,
|
|
||||||
}
|
|
||||||
})))
|
})))
|
||||||
|
|
||||||
return params
|
return params
|
||||||
|
@ -95,7 +92,7 @@ func testVersionRepository(t *testing.T, newRepos func(t *testing.T) repositorie
|
||||||
return cmp.Compare(a.Code(), b.Code())
|
return cmp.Compare(a.Code(), b.Code())
|
||||||
}))
|
}))
|
||||||
for _, v := range res.Versions() {
|
for _, v := range res.Versions() {
|
||||||
assert.GreaterOrEqual(t, v.Code(), params.Cursor().Code().Value, v.Code())
|
assert.GreaterOrEqual(t, v.Code(), params.Cursor().Code(), v.Code())
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
assertError: func(t *testing.T, err error) {
|
assertError: func(t *testing.T, err error) {
|
||||||
|
@ -116,10 +113,7 @@ func testVersionRepository(t *testing.T, newRepos func(t *testing.T) repositorie
|
||||||
require.Greater(t, len(res.Versions()), 2)
|
require.Greater(t, len(res.Versions()), 2)
|
||||||
|
|
||||||
require.NoError(t, params.SetCursor(domaintest.NewVersionCursor(t, func(cfg *domaintest.VersionCursorConfig) {
|
require.NoError(t, params.SetCursor(domaintest.NewVersionCursor(t, func(cfg *domaintest.VersionCursorConfig) {
|
||||||
cfg.Code = domain.NullString{
|
cfg.Code = res.Versions()[1].Code()
|
||||||
Value: res.Versions()[1].Code(),
|
|
||||||
Valid: true,
|
|
||||||
}
|
|
||||||
})))
|
})))
|
||||||
|
|
||||||
return params
|
return params
|
||||||
|
@ -131,7 +125,7 @@ func testVersionRepository(t *testing.T, newRepos func(t *testing.T) repositorie
|
||||||
return cmp.Compare(a.Code(), b.Code()) * -1
|
return cmp.Compare(a.Code(), b.Code()) * -1
|
||||||
}))
|
}))
|
||||||
for _, v := range res.Versions() {
|
for _, v := range res.Versions() {
|
||||||
assert.LessOrEqual(t, v.Code(), params.Cursor().Code().Value, v.Code())
|
assert.LessOrEqual(t, v.Code(), params.Cursor().Code(), v.Code())
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
assertError: func(t *testing.T, err error) {
|
assertError: func(t *testing.T, err error) {
|
||||||
|
|
|
@ -7,17 +7,14 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type VersionCursorConfig struct {
|
type VersionCursorConfig struct {
|
||||||
Code domain.NullString
|
Code string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewVersionCursor(tb TestingTB, opts ...func(cfg *VersionCursorConfig)) domain.VersionCursor {
|
func NewVersionCursor(tb TestingTB, opts ...func(cfg *VersionCursorConfig)) domain.VersionCursor {
|
||||||
tb.Helper()
|
tb.Helper()
|
||||||
|
|
||||||
cfg := &VersionCursorConfig{
|
cfg := &VersionCursorConfig{
|
||||||
Code: domain.NullString{
|
Code: RandVersionCode(),
|
||||||
Value: RandVersionCode(),
|
|
||||||
Valid: true,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
|
|
|
@ -108,17 +108,13 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
type VersionCursor struct {
|
type VersionCursor struct {
|
||||||
code NullString
|
code string
|
||||||
}
|
}
|
||||||
|
|
||||||
const versionCursorModelName = "VersionCursor"
|
const versionCursorModelName = "VersionCursor"
|
||||||
|
|
||||||
func NewVersionCursor(code NullString) (VersionCursor, error) {
|
func NewVersionCursor(code string) (VersionCursor, error) {
|
||||||
if !code.Valid {
|
if err := validateVersionCode(code); err != nil {
|
||||||
return VersionCursor{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := validateVersionCode(code.Value); err != nil {
|
|
||||||
return VersionCursor{}, ValidationError{
|
return VersionCursor{}, ValidationError{
|
||||||
Model: versionCursorModelName,
|
Model: versionCursorModelName,
|
||||||
Field: "code",
|
Field: "code",
|
||||||
|
@ -152,10 +148,7 @@ func decodeVersionCursor(encoded string) (VersionCursor, error) {
|
||||||
return VersionCursor{}, ErrInvalidCursor
|
return VersionCursor{}, ErrInvalidCursor
|
||||||
}
|
}
|
||||||
|
|
||||||
vc, err := NewVersionCursor(NullString{
|
vc, err := NewVersionCursor(code)
|
||||||
Value: code,
|
|
||||||
Valid: true,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return VersionCursor{}, ErrInvalidCursor
|
return VersionCursor{}, ErrInvalidCursor
|
||||||
}
|
}
|
||||||
|
@ -163,12 +156,12 @@ func decodeVersionCursor(encoded string) (VersionCursor, error) {
|
||||||
return vc, nil
|
return vc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vc VersionCursor) Code() NullString {
|
func (vc VersionCursor) Code() string {
|
||||||
return vc.code
|
return vc.code
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vc VersionCursor) IsZero() bool {
|
func (vc VersionCursor) IsZero() bool {
|
||||||
return !vc.code.Valid
|
return vc == VersionCursor{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vc VersionCursor) Encode() string {
|
func (vc VersionCursor) Encode() string {
|
||||||
|
@ -176,7 +169,7 @@ func (vc VersionCursor) Encode() string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
return base64.StdEncoding.EncodeToString([]byte("code=" + vc.code.Value))
|
return base64.StdEncoding.EncodeToString([]byte("code=" + vc.code))
|
||||||
}
|
}
|
||||||
|
|
||||||
type ListVersionsParams struct {
|
type ListVersionsParams struct {
|
||||||
|
@ -287,10 +280,7 @@ func NewListVersionsResult(versions Versions, next Version) (ListVersionsResult,
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(versions) > 0 {
|
if len(versions) > 0 {
|
||||||
res.self, err = NewVersionCursor(NullString{
|
res.self, err = NewVersionCursor(versions[0].Code())
|
||||||
Value: versions[0].Code(),
|
|
||||||
Valid: true,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ListVersionsResult{}, ValidationError{
|
return ListVersionsResult{}, ValidationError{
|
||||||
Model: listVersionsResultModelName,
|
Model: listVersionsResultModelName,
|
||||||
|
@ -300,15 +290,14 @@ func NewListVersionsResult(versions Versions, next Version) (ListVersionsResult,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res.next, err = NewVersionCursor(NullString{
|
if !next.IsZero() {
|
||||||
Value: next.Code(),
|
res.next, err = NewVersionCursor(next.Code())
|
||||||
Valid: !next.IsZero(),
|
if err != nil {
|
||||||
})
|
return ListVersionsResult{}, ValidationError{
|
||||||
if err != nil {
|
Model: listVersionsResultModelName,
|
||||||
return ListVersionsResult{}, ValidationError{
|
Field: "next",
|
||||||
Model: listVersionsResultModelName,
|
Err: err,
|
||||||
Field: "next",
|
}
|
||||||
Err: err,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ func TestNewVersionCursor(t *testing.T) {
|
||||||
validVersionCursor := domaintest.NewVersionCursor(t)
|
validVersionCursor := domaintest.NewVersionCursor(t)
|
||||||
|
|
||||||
type args struct {
|
type args struct {
|
||||||
code domain.NullString
|
code string
|
||||||
}
|
}
|
||||||
|
|
||||||
type test struct {
|
type test struct {
|
||||||
|
@ -34,23 +34,13 @@ func TestNewVersionCursor(t *testing.T) {
|
||||||
},
|
},
|
||||||
expectedErr: nil,
|
expectedErr: nil,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "OK: nil code",
|
|
||||||
args: args{
|
|
||||||
code: domain.NullString{},
|
|
||||||
},
|
|
||||||
expectedErr: nil,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, versionCodeTest := range newVersionCodeValidationTests() {
|
for _, versionCodeTest := range newVersionCodeValidationTests() {
|
||||||
tests = append(tests, test{
|
tests = append(tests, test{
|
||||||
name: versionCodeTest.name,
|
name: versionCodeTest.name,
|
||||||
args: args{
|
args: args{
|
||||||
code: domain.NullString{
|
code: versionCodeTest.code,
|
||||||
Value: versionCodeTest.code,
|
|
||||||
Valid: true,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
expectedErr: domain.ValidationError{
|
expectedErr: domain.ValidationError{
|
||||||
Model: "VersionCursor",
|
Model: "VersionCursor",
|
||||||
|
@ -72,11 +62,7 @@ func TestNewVersionCursor(t *testing.T) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
assert.Equal(t, tt.args.code, vc.Code())
|
assert.Equal(t, tt.args.code, vc.Code())
|
||||||
if tt.args.code.Valid {
|
assert.NotEmpty(t, vc.Encode())
|
||||||
assert.NotEmpty(t, vc.Encode())
|
|
||||||
} else {
|
|
||||||
assert.Empty(t, vc.Encode())
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -231,7 +217,6 @@ func TestListVersionsParams_SetEncodedCursor(t *testing.T) {
|
||||||
fmt.Println(tt.expectedErr.Error())
|
fmt.Println(tt.expectedErr.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
assert.True(t, params.Cursor().Code().Valid)
|
|
||||||
assert.Equal(t, tt.expectedCursor.Code(), params.Cursor().Code())
|
assert.Equal(t, tt.expectedCursor.Code(), params.Cursor().Code())
|
||||||
assert.Equal(t, tt.args.cursor, params.Cursor().Encode())
|
assert.Equal(t, tt.args.cursor, params.Cursor().Encode())
|
||||||
})
|
})
|
||||||
|
@ -319,10 +304,8 @@ func TestNewListVersionsResult(t *testing.T) {
|
||||||
res, err := domain.NewListVersionsResult(versions, next)
|
res, err := domain.NewListVersionsResult(versions, next)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, versions, res.Versions())
|
assert.Equal(t, versions, res.Versions())
|
||||||
assert.True(t, res.Self().Code().Valid)
|
assert.Equal(t, versions[0].Code(), res.Self().Code())
|
||||||
assert.Equal(t, versions[0].Code(), res.Self().Code().Value)
|
assert.Equal(t, next.Code(), res.Next().Code())
|
||||||
assert.True(t, res.Next().Code().Valid)
|
|
||||||
assert.Equal(t, next.Code(), res.Next().Code().Value)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("OK: without next", func(t *testing.T) {
|
t.Run("OK: without next", func(t *testing.T) {
|
||||||
|
@ -331,8 +314,7 @@ func TestNewListVersionsResult(t *testing.T) {
|
||||||
res, err := domain.NewListVersionsResult(versions, domain.Version{})
|
res, err := domain.NewListVersionsResult(versions, domain.Version{})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, versions, res.Versions())
|
assert.Equal(t, versions, res.Versions())
|
||||||
assert.True(t, res.Self().Code().Valid)
|
assert.Equal(t, versions[0].Code(), res.Self().Code())
|
||||||
assert.Equal(t, versions[0].Code(), res.Self().Code().Value)
|
|
||||||
assert.True(t, res.Next().IsZero())
|
assert.True(t, res.Next().IsZero())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue