master
1package main
2
3import (
4 "bytes"
5 "encoding/json"
6 "fmt"
7 "net/http"
8 "net/http/httptest"
9 "testing"
10
11 "github.com/stretchr/testify/assert"
12)
13
14type mockDB struct{}
15type errorDB struct{}
16
17func (db *mockDB) GetVisits() (v []Visit, err error) {
18 return []Visit{Visit{ID: "a"}, Visit{ID: "b"}}, nil
19}
20func (db *errorDB) GetVisits() (v []Visit, err error) {
21 return nil, fmt.Errorf("test error")
22}
23
24func (db *mockDB) GetVisit(visitID string) (v *Visit, err error) {
25 if len(visitID) != 0 {
26 if visitID == "exampleNotFound" {
27 return nil, fmt.Errorf("visit ID [%s] not found", visitID)
28 }
29 return &Visit{ID: visitID}, nil
30 } else {
31 return nil, fmt.Errorf("no visit id providied")
32 }
33}
34func (db *errorDB) GetVisit(visitID string) (v *Visit, err error) {
35 return nil, fmt.Errorf("test error")
36}
37
38func (db *mockDB) CreateVisit(v Visit) (vl []Visit, err error) {
39 if len(v.ID) == 0 {
40 return nil, fmt.Errorf("visit id required, none providied")
41 }
42 return append([]Visit{Visit{ID: "a"}, Visit{ID: "b"}}, v), nil
43}
44func (db *errorDB) CreateVisit(v Visit) (vl []Visit, err error) {
45 return nil, fmt.Errorf("test error")
46}
47
48func (db *mockDB) CancelVisit(visitID string) (vl []Visit, err error) {
49 vl = []Visit{Visit{ID: "a"}}
50 if len(visitID) == 0 {
51 return vl, fmt.Errorf("visit id required, none providied")
52 }
53 b := vl[:0]
54 for _, x := range vl {
55 if x.ID != visitID {
56 b = append(b, x)
57 }
58 }
59 return b, nil
60}
61func (db *errorDB) CancelVisit(visitID string) (vl []Visit, err error) {
62 return nil, fmt.Errorf("test error")
63}
64
65var basepath string = "http://domain.example/"
66
67func Test_VisitList(t *testing.T) {
68 r := assert.New(t)
69
70 gettests := []struct {
71 db datasource
72 path string
73 code int
74 out []Visit
75 }{
76 {&mockDB{}, basepath + "visits", http.StatusOK, []Visit{Visit{ID: "a"}, Visit{ID: "b"}}},
77 {&errorDB{}, basepath + "visits", http.StatusInternalServerError, nil},
78 }
79
80 for _, ti := range gettests {
81 visitDB = ti.db
82 req, err := http.NewRequest("GET", ti.path, nil)
83 r.NoError(err)
84
85 res := httptest.NewRecorder()
86 VisitList().ServeHTTP(res, req)
87
88 r.Equal(ti.code, res.Code)
89
90 if res.Code == http.StatusOK {
91 var visits []Visit
92 dec := json.NewDecoder(res.Body)
93 err = dec.Decode(&visits)
94 r.NoError(err)
95
96 for i, v := range ti.out {
97 r.Equal(v.ID, visits[i].ID)
98 }
99 }
100 }
101
102}
103func Test_VisitDetails(t *testing.T) {
104 r := assert.New(t)
105
106 // initialize router and mock database
107 visitDB = &mockDB{}
108
109 gettests := []struct {
110 path string
111 code int
112 item interface{}
113 }{
114 {basepath + "visits/", http.StatusNotFound, nil},
115 {basepath + "visits/AAAA", http.StatusOK, Visit{ID: "AAAA"}},
116 {basepath + "visits/aaaa", http.StatusOK, Visit{ID: "aaaa"}},
117 {basepath + "visits/1111", http.StatusOK, Visit{ID: "1111"}},
118 {basepath + "visits/-", http.StatusNotFound, nil},
119 {basepath + "visits/_", http.StatusNotFound, nil},
120 {basepath + "visits/~", http.StatusNotFound, nil},
121 {basepath + "visits/exampleNotFound", http.StatusNotFound, nil},
122 }
123
124 for _, ti := range gettests {
125 req, err := http.NewRequest("GET", ti.path, nil)
126 r.NoError(err)
127
128 res := httptest.NewRecorder()
129 VisitrApp().ServeHTTP(res, req)
130
131 r.Equal(ti.code, res.Code)
132
133 if res.Code == http.StatusOK {
134 var visit Visit
135 dec := json.NewDecoder(res.Body)
136 err = dec.Decode(&visit)
137 r.NoError(err)
138
139 v, ok := ti.item.(Visit)
140 r.True(ok)
141
142 r.Equal(v.ID, visit.ID)
143 }
144 }
145
146}
147
148func Test_VisitCreate(t *testing.T) {
149 r := assert.New(t)
150
151 // initialize router and mock database
152 visitDB = &mockDB{}
153
154 goodVisit, _ := json.Marshal(Visit{ID: "c"})
155 emptyVisit, _ := json.Marshal(Visit{})
156 postTests := []struct {
157 path string
158 visit []byte
159 code int
160 out []Visit
161 }{
162 {
163 path: basepath + "visits",
164 visit: goodVisit,
165 code: http.StatusCreated,
166 out: []Visit{Visit{ID: "a"}, Visit{ID: "b"}, Visit{ID: "c"}},
167 },
168 {
169 path: basepath + "visits",
170 visit: emptyVisit,
171 code: http.StatusBadRequest,
172 out: nil,
173 },
174 {
175 path: basepath + "visits",
176 visit: []byte("bad bytes"),
177 code: http.StatusBadRequest,
178 out: nil,
179 },
180 }
181
182 for _, ti := range postTests {
183 req, err := http.NewRequest("POST", ti.path, bytes.NewBuffer(ti.visit))
184 r.NoError(err)
185
186 res := httptest.NewRecorder()
187 VisitCreate().ServeHTTP(res, req)
188
189 r.Equal(ti.code, res.Code)
190
191 if res.Code == http.StatusCreated {
192 var visits []Visit
193 dec := json.NewDecoder(res.Body)
194 err = dec.Decode(&visits)
195 r.NoError(err)
196
197 for i, v := range ti.out {
198 r.Equal(v.ID, visits[i].ID)
199 }
200 }
201 }
202}
203
204func Test_VisitCancel(t *testing.T) {
205 r := assert.New(t)
206
207 // initialize router and mock database
208 visitDB = &mockDB{}
209
210 postTests := []struct {
211 path string
212 code int
213 item interface{}
214 }{
215 {basepath + "visits/b", http.StatusOK, []Visit{Visit{ID: "a"}}},
216 {basepath + "visits/a", http.StatusOK, []Visit{Visit{ID: "a"}}},
217 {basepath + "visits", http.StatusNotFound, nil},
218 }
219
220 for _, ti := range postTests {
221 req, err := http.NewRequest("DELETE", ti.path, nil)
222 r.NoError(err)
223
224 res := httptest.NewRecorder()
225 VisitrApp().ServeHTTP(res, req)
226
227 r.Equal(ti.code, res.Code)
228
229 if res.Code == http.StatusOK {
230 var visits []Visit
231 dec := json.NewDecoder(res.Body)
232 err = dec.Decode(&visits)
233 r.NoError(err)
234
235 vl, ok := ti.item.([]Visit)
236 r.True(ok)
237
238 for i, v := range visits {
239 r.Equal(vl[i].ID, v.ID)
240 }
241 }
242 }
243
244}