-
Notifications
You must be signed in to change notification settings - Fork 13
/
main_test.go
129 lines (114 loc) · 3.58 KB
/
main_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package main
import (
"bytes"
"net/http"
"net/http/httptest"
"testing"
"github.com/Stratoscale/swagger/example/auth"
"github.com/Stratoscale/swagger/example/models"
"github.com/Stratoscale/swagger/example/restapi"
"github.com/Stratoscale/swagger/example/restapi/operations/pet"
"github.com/go-openapi/swag"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
)
const target = "http://petstore.org/api"
// mocks contains on the restapi.Config dependencies that should be mocked
type mocks struct {
pet restapi.MockPetAPI
store restapi.MockStoreAPI
}
func (m *mocks) assertExpectations(t *testing.T) {
m.pet.AssertExpectations(t)
m.store.AssertExpectations(t)
}
func TestHTTPHandler(t *testing.T) {
t.Parallel()
// declare the test cases
tests := []struct {
// name for test case
name string
// req is the request that will be tested
req *http.Request
// cookie that will be added to the request
cookie string
// prepare mocks before running the test
prepare func(*testing.T, *mocks)
// wantCode is the expected response status code
wantCode int
// wantBody is the expected response body
wantBody []byte
}{
{
name: "get pet by anonymous should be unauthorized",
req: httptest.NewRequest(http.MethodGet, target+"/pets/1", nil),
wantCode: http.StatusUnauthorized,
},
{
name: "get pet by a member",
req: httptest.NewRequest(http.MethodGet, target+"/pets/1", nil),
cookie: `{"id":1,"role":"member"}`,
prepare: func(t *testing.T, m *mocks) {
m.pet.On("PetGet", mock.Anything, mock.Anything).
Return(&pet.PetGetOK{Payload: &models.Pet{ID: 1, Name: swag.String("kitty")}}).
Once()
},
wantCode: http.StatusOK,
wantBody: []byte(`{"id":1,"name":"kitty"}`),
},
{
name: "pet create by anonymous should be unauthorized",
req: httptest.NewRequest(http.MethodPost, target+"/pets", bytes.NewBufferString(`{"name":"kitty"}`)),
wantCode: http.StatusUnauthorized,
},
{
name: "pet create by a member should be forbidden",
req: httptest.NewRequest(http.MethodPost, target+"/pets", bytes.NewBufferString(`{"name":"kitty"}`)),
cookie: `{"id":1,"role":"member"}`,
wantCode: http.StatusForbidden,
},
{
name: "pet create by an admin",
req: httptest.NewRequest(http.MethodPost, target+"/pets", bytes.NewBufferString(`{"name":"kitty"}`)),
cookie: `{"id":1,"role":"admin"}`,
prepare: func(t *testing.T, m *mocks) {
m.pet.On("PetCreate", mock.Anything, mock.Anything).
Return(&pet.PetCreateCreated{Payload: &models.Pet{ID: 1, Name: swag.String("kitty")}}).
Once()
},
wantCode: http.StatusCreated,
wantBody: []byte(`{"id":1,"name":"kitty"}`),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var (
resp = httptest.NewRecorder()
mocks mocks
)
h, err := restapi.Handler(restapi.Config{
PetAPI: &mocks.pet,
StoreAPI: &mocks.store,
AuthToken: auth.Token,
Authorizer: auth.Request,
Logger: t.Logf,
})
require.Nil(t, err)
tt.req.Header.Set("Content-Type", "application/json")
tt.req.Header.Set("Cookie", tt.cookie)
// prepare mocks
if tt.prepare != nil {
tt.prepare(t, &mocks)
}
h.ServeHTTP(resp, tt.req)
t.Logf("Got response for request %s %s: %d %s", tt.req.Method, tt.req.URL, resp.Code, resp.Body.String())
// assert the response expectations
assert.Equal(t, tt.wantCode, resp.Code)
if tt.wantBody != nil {
assert.JSONEq(t, string(tt.wantBody), resp.Body.String())
}
mocks.assertExpectations(t)
})
}
}