Skip to content

Commit 0f6c063

Browse files
committed
Add tests for all routes
1 parent 296ba02 commit 0f6c063

11 files changed

Lines changed: 868 additions & 0 deletions
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package routes
2+
3+
import (
4+
"context"
5+
"errors"
6+
"testing"
7+
8+
"github.com/f1monkey/spellchecker-web/internal/spellchecker"
9+
"github.com/stretchr/testify/require"
10+
"github.com/swaggest/usecase/status"
11+
)
12+
13+
type testAliasDeleter struct {
14+
err error
15+
}
16+
17+
func (f *testAliasDeleter) DeleteAlias(alias string) error {
18+
return f.err
19+
}
20+
21+
func Test_AliasDelete(t *testing.T) {
22+
t.Parallel()
23+
24+
tests := []struct {
25+
name string
26+
deleter *testAliasDeleter
27+
input AliasDeleteRequest
28+
wantErr bool
29+
wantCode status.Code
30+
}{
31+
{
32+
name: "success",
33+
deleter: &testAliasDeleter{err: nil},
34+
input: AliasDeleteRequest{Alias: "eng"},
35+
wantErr: false,
36+
wantCode: status.OK,
37+
},
38+
{
39+
name: "alias not found",
40+
deleter: &testAliasDeleter{err: spellchecker.ErrAliasNotFound},
41+
input: AliasDeleteRequest{Alias: "xx"},
42+
wantErr: true,
43+
wantCode: status.NotFound,
44+
},
45+
{
46+
name: "internal error",
47+
deleter: &testAliasDeleter{err: errors.New("boom")},
48+
input: AliasDeleteRequest{Alias: "eng"},
49+
wantErr: true,
50+
wantCode: status.Internal,
51+
},
52+
}
53+
54+
for _, tt := range tests {
55+
t.Run(tt.name, func(t *testing.T) {
56+
t.Parallel()
57+
58+
interactor := aliasDelete(tt.deleter)
59+
60+
var out Empty
61+
err := interactor.Interact(context.Background(), tt.input, &out)
62+
63+
if tt.wantErr {
64+
require.Error(t, err)
65+
require.True(t, err.(isErr).Is(tt.wantCode))
66+
} else {
67+
require.NoError(t, err)
68+
}
69+
})
70+
}
71+
}

internal/routes/alias_get_test.go

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package routes
2+
3+
import (
4+
"context"
5+
"errors"
6+
"testing"
7+
8+
"github.com/f1monkey/spellchecker-web/internal/spellchecker"
9+
"github.com/stretchr/testify/require"
10+
"github.com/swaggest/usecase/status"
11+
)
12+
13+
type testAliasGetter struct {
14+
code string
15+
err error
16+
}
17+
18+
func (f *testAliasGetter) GetCodeByAlias(alias string) (string, error) {
19+
return f.code, f.err
20+
}
21+
22+
func Test_AliasGet(t *testing.T) {
23+
t.Parallel()
24+
25+
tests := []struct {
26+
name string
27+
getter *testAliasGetter
28+
input AliasGetRequest
29+
wantErr bool
30+
wantCode status.Code
31+
wantDict string
32+
}{
33+
{
34+
name: "success",
35+
getter: &testAliasGetter{code: "en", err: nil},
36+
input: AliasGetRequest{Alias: "eng"},
37+
wantErr: false,
38+
wantCode: status.OK,
39+
wantDict: "en",
40+
},
41+
{
42+
name: "not found",
43+
getter: &testAliasGetter{code: "", err: spellchecker.ErrNotFound},
44+
input: AliasGetRequest{Alias: "xx"},
45+
wantErr: true,
46+
wantCode: status.NotFound,
47+
},
48+
{
49+
name: "internal error",
50+
getter: &testAliasGetter{code: "", err: errors.New("boom")},
51+
input: AliasGetRequest{Alias: "eng"},
52+
wantErr: true,
53+
wantCode: status.Internal,
54+
},
55+
}
56+
57+
for _, tt := range tests {
58+
t.Run(tt.name, func(t *testing.T) {
59+
t.Parallel()
60+
61+
interactor := aliasGet(tt.getter)
62+
63+
var out AliasGetResponse
64+
err := interactor.Interact(context.Background(), tt.input, &out)
65+
66+
if tt.wantErr {
67+
require.Error(t, err)
68+
require.True(t, err.(isErr).Is(tt.wantCode))
69+
} else {
70+
require.NoError(t, err)
71+
require.Equal(t, tt.wantDict, out.Dictionary)
72+
}
73+
})
74+
}
75+
}

internal/routes/alias_list_test.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package routes
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
"github.com/f1monkey/spellchecker-web/internal/spellchecker"
8+
"github.com/stretchr/testify/require"
9+
)
10+
11+
type testAliasLister struct {
12+
items []spellchecker.ListItem
13+
}
14+
15+
func (f *testAliasLister) ListAliases() []spellchecker.ListItem {
16+
return f.items
17+
}
18+
19+
func Test_AliasList(t *testing.T) {
20+
t.Parallel()
21+
22+
tests := []struct {
23+
name string
24+
lister *testAliasLister
25+
wantItems []ListItem
26+
}{
27+
{
28+
name: "empty list",
29+
lister: &testAliasLister{items: []spellchecker.ListItem{}},
30+
wantItems: []ListItem{},
31+
},
32+
{
33+
name: "single item",
34+
lister: &testAliasLister{items: []spellchecker.ListItem{
35+
{Code: "en", Aliases: []string{"eng", "english"}},
36+
}},
37+
wantItems: []ListItem{
38+
{Code: "en", Aliases: []string{"eng", "english"}},
39+
},
40+
},
41+
{
42+
name: "multiple items",
43+
lister: &testAliasLister{items: []spellchecker.ListItem{
44+
{Code: "en", Aliases: []string{"eng"}},
45+
{Code: "fr", Aliases: []string{"fra", "french"}},
46+
}},
47+
wantItems: []ListItem{
48+
{Code: "en", Aliases: []string{"eng"}},
49+
{Code: "fr", Aliases: []string{"fra", "french"}},
50+
},
51+
},
52+
}
53+
54+
for _, tt := range tests {
55+
t.Run(tt.name, func(t *testing.T) {
56+
t.Parallel()
57+
58+
interactor := aliasList(tt.lister)
59+
60+
var out AliasListResponse
61+
err := interactor.Interact(context.Background(), Empty{}, &out)
62+
63+
require.NoError(t, err)
64+
require.Equal(t, tt.wantItems, out.Items)
65+
})
66+
}
67+
}

internal/routes/alias_set_test.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package routes
2+
3+
import (
4+
"context"
5+
"errors"
6+
"testing"
7+
8+
"github.com/f1monkey/spellchecker-web/internal/spellchecker"
9+
"github.com/stretchr/testify/require"
10+
"github.com/swaggest/usecase/status"
11+
)
12+
13+
type testAliasSetter struct {
14+
err error
15+
}
16+
17+
func (f *testAliasSetter) SetAlias(alias string, code string) error {
18+
return f.err
19+
}
20+
21+
func Test_AliasSet(t *testing.T) {
22+
t.Parallel()
23+
24+
tests := []struct {
25+
name string
26+
setter *testAliasSetter
27+
input AliasSetRequest
28+
wantErr bool
29+
wantCode status.Code
30+
}{
31+
{
32+
name: "success",
33+
setter: &testAliasSetter{err: nil},
34+
input: AliasSetRequest{Alias: "eng", Dictionary: "en"},
35+
wantErr: false,
36+
wantCode: status.OK,
37+
},
38+
{
39+
name: "alias not found",
40+
setter: &testAliasSetter{err: spellchecker.ErrAliasNotFound},
41+
input: AliasSetRequest{Alias: "xx", Dictionary: "en"},
42+
wantErr: true,
43+
wantCode: status.NotFound,
44+
},
45+
{
46+
name: "internal error",
47+
setter: &testAliasSetter{err: errors.New("boom")},
48+
input: AliasSetRequest{Alias: "eng", Dictionary: "en"},
49+
wantErr: true,
50+
wantCode: status.Internal,
51+
},
52+
}
53+
54+
for _, tt := range tests {
55+
t.Run(tt.name, func(t *testing.T) {
56+
t.Parallel()
57+
58+
interactor := aliasSet(tt.setter)
59+
60+
var out Empty
61+
err := interactor.Interact(context.Background(), tt.input, &out)
62+
63+
if tt.wantErr {
64+
require.Error(t, err)
65+
require.True(t, err.(isErr).Is(tt.wantCode))
66+
} else {
67+
require.NoError(t, err)
68+
}
69+
})
70+
}
71+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package routes
2+
3+
import (
4+
"context"
5+
"errors"
6+
"testing"
7+
8+
f1mspellchecker "github.com/f1monkey/spellchecker"
9+
"github.com/f1monkey/spellchecker-web/internal/spellchecker"
10+
"github.com/stretchr/testify/require"
11+
"github.com/swaggest/usecase/status"
12+
)
13+
14+
type testRegistryAdder struct {
15+
err error
16+
}
17+
18+
func (f *testRegistryAdder) Add(code string, options spellchecker.Options) (*f1mspellchecker.Spellchecker, error) {
19+
return nil, f.err
20+
}
21+
22+
func Test_DictionaryCreate(t *testing.T) {
23+
t.Parallel()
24+
25+
tests := []struct {
26+
name string
27+
adder *testRegistryAdder
28+
input DictionaryCreateRequest
29+
wantErr bool
30+
wantCode status.Code
31+
}{
32+
{
33+
name: "success",
34+
adder: &testRegistryAdder{
35+
err: nil,
36+
},
37+
input: DictionaryCreateRequest{
38+
Code: "en",
39+
Alphabet: "abcdefghijklmnopqrstuvwxyz",
40+
MaxErrors: 2,
41+
},
42+
wantErr: false,
43+
wantCode: status.OK,
44+
},
45+
{
46+
name: "already exists",
47+
adder: &testRegistryAdder{
48+
err: spellchecker.ErrAlreadyExists,
49+
},
50+
input: DictionaryCreateRequest{
51+
Code: "en",
52+
Alphabet: "abcdefghijklmnopqrstuvwxyz",
53+
MaxErrors: 2,
54+
},
55+
wantErr: true,
56+
wantCode: status.AlreadyExists,
57+
},
58+
{
59+
name: "internal error",
60+
adder: &testRegistryAdder{
61+
err: errors.New("boom"),
62+
},
63+
input: DictionaryCreateRequest{
64+
Code: "fr",
65+
Alphabet: "abcdefghijklmnopqrstuvwxyz",
66+
MaxErrors: 2,
67+
},
68+
wantErr: true,
69+
wantCode: status.Internal,
70+
},
71+
}
72+
73+
for _, tt := range tests {
74+
t.Run(tt.name, func(t *testing.T) {
75+
t.Parallel()
76+
77+
interactor := dictionaryCreate(tt.adder)
78+
79+
var out Empty
80+
err := interactor.Interact(context.Background(), tt.input, &out)
81+
82+
if tt.wantErr {
83+
require.Error(t, err)
84+
require.True(t, err.(isErr).Is(tt.wantCode))
85+
} else {
86+
require.NoError(t, err)
87+
}
88+
})
89+
}
90+
}

0 commit comments

Comments
 (0)