master
Raw Download raw file
  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}