all repos

onasty @ 08f207c

a one-time notes service

onasty/e2e/apiv1_notes_test.go (view raw)

Olexandr Smirnov Olexandr Smirnov
ss2316544@gmail.com
refactor: don't pass note password in url (#167)..., 10 months ago
1
package e2e_test
2
3
import (
4
	"net/http"
5
	"net/http/httptest"
6
	"time"
7
8
	"github.com/gofrs/uuid/v5"
9
)
10
11
type (
12
	apiv1NoteCreateRequest struct {
13
		Content              string    `json:"content"`
14
		Slug                 string    `json:"slug"`
15
		Password             string    `json:"password"`
16
		BurnBeforeExpiration bool      `json:"burn_before_expiration"`
17
		ExpiresAt            time.Time `json:"expires_at"`
18
	}
19
	apiv1NoteCreateResponse struct {
20
		Slug string `json:"slug"`
21
	}
22
)
23
24
func (e *AppTestSuite) TestNoteV1_Create() {
25
	tests := []struct {
26
		name   string
27
		inp    apiv1NoteCreateRequest
28
		assert func(*httptest.ResponseRecorder, apiv1NoteCreateRequest)
29
	}{
30
		{
31
			name: "empty request",
32
			inp:  apiv1NoteCreateRequest{}, //nolint:exhaustruct
33
			assert: func(r *httptest.ResponseRecorder, _ apiv1NoteCreateRequest) {
34
				e.Equal(r.Code, http.StatusBadRequest)
35
			},
36
		},
37
		{
38
			name: "content only",
39
			inp:  apiv1NoteCreateRequest{Content: e.uuid()}, //nolint:exhaustruct
40
			assert: func(r *httptest.ResponseRecorder, _ apiv1NoteCreateRequest) {
41
				e.Equal(r.Code, http.StatusCreated)
42
43
				var body apiv1NoteCreateResponse
44
				e.readBodyAndUnjsonify(r.Body, &body)
45
46
				_, err := uuid.FromString(body.Slug)
47
				e.require.NoError(err)
48
49
				dbNote := e.getNoteBySlug(body.Slug)
50
				e.NotEmpty(dbNote)
51
			},
52
		},
53
		{
54
			name: "set slug",
55
			inp: apiv1NoteCreateRequest{ //nolint:exhaustruct
56
				Slug:    e.uuid() + "fuker",
57
				Content: e.uuid(),
58
			},
59
			assert: func(r *httptest.ResponseRecorder, inp apiv1NoteCreateRequest) {
60
				e.Equal(r.Code, http.StatusCreated)
61
62
				var body apiv1NoteCreateResponse
63
				e.readBodyAndUnjsonify(r.Body, &body)
64
65
				dbNote := e.getNoteBySlug(inp.Slug)
66
				e.NotEmpty(dbNote)
67
			},
68
		},
69
		{
70
			name: "set password",
71
			inp: apiv1NoteCreateRequest{ //nolint:exhaustruct
72
				Content:  e.uuid(),
73
				Password: e.uuid(),
74
			},
75
			assert: func(r *httptest.ResponseRecorder, _ apiv1NoteCreateRequest) {
76
				e.Equal(r.Code, http.StatusCreated)
77
			},
78
		},
79
		{
80
			name: "all possible fields",
81
			inp: apiv1NoteCreateRequest{ //nolint:exhaustruct
82
				Content:              e.uuid(),
83
				BurnBeforeExpiration: true,
84
				ExpiresAt:            time.Now().Add(time.Hour),
85
			},
86
			assert: func(r *httptest.ResponseRecorder, inp apiv1NoteCreateRequest) {
87
				e.Equal(r.Code, http.StatusCreated)
88
89
				var body apiv1NoteCreateResponse
90
				e.readBodyAndUnjsonify(r.Body, &body)
91
92
				dbNote := e.getNoteBySlug(body.Slug)
93
				e.NotEmpty(dbNote)
94
95
				e.Equal(dbNote.Content, inp.Content)
96
				e.Equal(dbNote.BurnBeforeExpiration, inp.BurnBeforeExpiration)
97
				e.Equal(dbNote.ExpiresAt.Unix(), inp.ExpiresAt.Unix())
98
			},
99
		},
100
	}
101
102
	for _, tt := range tests {
103
		httpResp := e.httpRequest(http.MethodPost, "/api/v1/note", e.jsonify(tt.inp))
104
		tt.assert(httpResp, tt.inp)
105
	}
106
}
107
108
type apiv1NoteGetResponse struct {
109
	Content   string     `json:"content"`
110
	ReadAt    *time.Time `json:"read_at"`
111
	CreatedAt time.Time  `json:"created_at"`
112
	ExpiresAt time.Time  `json:"expires_at"`
113
}
114
115
func (e *AppTestSuite) TestNoteV1_Get() {
116
	content := e.uuid()
117
	httpResp := e.httpRequest(
118
		http.MethodPost,
119
		"/api/v1/note",
120
		e.jsonify(apiv1NoteCreateRequest{ //nolint:exhaustruct
121
			Content: content,
122
		}),
123
	)
124
	e.Equal(http.StatusCreated, httpResp.Code)
125
126
	var bodyCreated apiv1NoteCreateResponse
127
	e.readBodyAndUnjsonify(httpResp.Body, &bodyCreated)
128
129
	httpResp = e.httpRequest(http.MethodGet, "/api/v1/note/"+bodyCreated.Slug, nil)
130
	e.Equal(httpResp.Code, http.StatusOK)
131
132
	var body apiv1NoteGetResponse
133
	e.readBodyAndUnjsonify(httpResp.Body, &body)
134
135
	e.Equal(content, body.Content)
136
137
	dbNote := e.getNoteBySlug(bodyCreated.Slug)
138
	e.Equal(dbNote.Content, "")
139
	e.Equal(dbNote.ReadAt.IsZero(), false)
140
}
141
142
type apiv1NoteGetWithPasswordRequest struct {
143
	Password string `json:"password"`
144
}
145
146
func (e *AppTestSuite) TestNoteV1_GetWithPassword() {
147
	content := e.uuid()
148
	passwd := e.uuid()
149
	httpResp := e.httpRequest(
150
		http.MethodPost,
151
		"/api/v1/note",
152
		e.jsonify(apiv1NoteCreateRequest{ //nolint:exhaustruct
153
			Content:  content,
154
			Password: passwd,
155
		}),
156
	)
157
	e.Equal(http.StatusCreated, httpResp.Code)
158
159
	var bodyCreated apiv1NoteCreateResponse
160
	e.readBodyAndUnjsonify(httpResp.Body, &bodyCreated)
161
162
	httpResp = e.httpRequest(
163
		http.MethodPost,
164
		"/api/v1/note/"+bodyCreated.Slug+"/view",
165
		e.jsonify(apiv1NoteGetWithPasswordRequest{
166
			Password: passwd,
167
		}),
168
	)
169
	e.Equal(httpResp.Code, http.StatusOK)
170
171
	var body apiv1NoteGetResponse
172
	e.readBodyAndUnjsonify(httpResp.Body, &body)
173
174
	e.Equal(content, body.Content)
175
176
	dbNote := e.getNoteBySlug(bodyCreated.Slug)
177
	e.Equal(dbNote.Content, "")
178
	e.Equal(dbNote.ReadAt.IsZero(), false)
179
}
180
181
func (e *AppTestSuite) TestNoteV1_GetWithPassword_wrongNoPassword() {
182
	content := e.uuid()
183
	passwd := e.uuid()
184
	httpResp := e.httpRequest(
185
		http.MethodPost,
186
		"/api/v1/note",
187
		e.jsonify(apiv1NoteCreateRequest{ //nolint:exhaustruct
188
			Content:  content,
189
			Password: passwd,
190
		}),
191
	)
192
	e.Equal(http.StatusCreated, httpResp.Code)
193
194
	var bodyCreated apiv1NoteCreateResponse
195
	e.readBodyAndUnjsonify(httpResp.Body, &bodyCreated)
196
197
	httpResp = e.httpRequest(http.MethodGet, "/api/v1/note/"+bodyCreated.Slug, nil)
198
	e.Equal(httpResp.Code, http.StatusNotFound)
199
}
200
201
func (e *AppTestSuite) TestNoteV1_GetWithPassword_wrong() {
202
	content := e.uuid()
203
	httpResp := e.httpRequest(
204
		http.MethodPost,
205
		"/api/v1/note",
206
		e.jsonify(apiv1NoteCreateRequest{ //nolint:exhaustruct
207
			Content:  content,
208
			Password: e.uuid(),
209
		}),
210
	)
211
	e.Equal(http.StatusCreated, httpResp.Code)
212
213
	var bodyCreated apiv1NoteCreateResponse
214
	e.readBodyAndUnjsonify(httpResp.Body, &bodyCreated)
215
216
	httpResp = e.httpRequest(
217
		http.MethodPost,
218
		"/api/v1/note/"+bodyCreated.Slug+"/view",
219
		e.jsonify(apiv1NoteGetWithPasswordRequest{
220
			Password: e.uuid(),
221
		}),
222
	)
223
	e.Equal(httpResp.Code, http.StatusNotFound)
224
}
225
226
type apiv1NoteMetadataResponse struct {
227
	CreatedAt   time.Time `json:"created_at"`
228
	HasPassword bool      `json:"has_password"`
229
}
230
231
func (e *AppTestSuite) TestNoteV1_GetMetadata() {
232
	// create note
233
	httpResp := e.httpRequest(
234
		http.MethodPost,
235
		"/api/v1/note",
236
		e.jsonify(apiv1NoteCreateRequest{Content: "content"}), //nolint:exhaustruct
237
	)
238
	e.Equal(http.StatusCreated, httpResp.Code)
239
240
	var bodyCreated apiv1NoteCreateResponse
241
	e.readBodyAndUnjsonify(httpResp.Body, &bodyCreated)
242
243
	// get metadata
244
	metaResp := e.httpRequest(http.MethodGet, "/api/v1/note/"+bodyCreated.Slug+"/meta", []byte{})
245
	e.Equal(metaResp.Code, http.StatusOK)
246
247
	var metadata apiv1NoteMetadataResponse
248
	e.readBodyAndUnjsonify(metaResp.Body, &metadata)
249
250
	e.False(metadata.HasPassword)
251
	e.NotEmpty(metadata.CreatedAt)
252
}
253
254
func (e *AppTestSuite) TestNoteV1_GetMetadata_withPassword() {
255
	// create note
256
	httpResp := e.httpRequest(
257
		http.MethodPost,
258
		"/api/v1/note",
259
		e.jsonify(apiv1NoteCreateRequest{ //nolint:exhaustruct
260
			Content:  "content",
261
			Password: "pass",
262
		}),
263
	)
264
	e.Equal(http.StatusCreated, httpResp.Code)
265
266
	var bodyCreated apiv1NoteCreateResponse
267
	e.readBodyAndUnjsonify(httpResp.Body, &bodyCreated)
268
269
	// get metadata
270
	metaResp := e.httpRequest(http.MethodGet, "/api/v1/note/"+bodyCreated.Slug+"/meta", []byte{})
271
	e.Equal(http.StatusOK, metaResp.Code)
272
273
	var metadata apiv1NoteMetadataResponse
274
	e.readBodyAndUnjsonify(metaResp.Body, &metadata)
275
276
	e.True(metadata.HasPassword)
277
	e.NotEmpty(metadata.CreatedAt)
278
}
279
280
func (e *AppTestSuite) TestNoteV1_GetMetadata_notFound() {
281
	metaResp := e.httpRequest(http.MethodGet, "/api/v1/note/"+e.uuid()+"/meta", []byte{})
282
	e.Equal(http.StatusNotFound, metaResp.Code)
283
}
284
285
func (e *AppTestSuite) TestNoteV1_GetMetadata_readNote() {
286
	// create note
287
	createdResp := e.httpRequest(
288
		http.MethodPost,
289
		"/api/v1/note",
290
		e.jsonify(apiv1NoteCreateRequest{Content: "content"}), //nolint:exhaustruct
291
	)
292
	e.Equal(http.StatusCreated, createdResp.Code)
293
294
	var bodyCreated apiv1NoteCreateResponse
295
	e.readBodyAndUnjsonify(createdResp.Body, &bodyCreated)
296
297
	// read note
298
	readResp := e.httpRequest(http.MethodGet, "/api/v1/note/"+bodyCreated.Slug, nil)
299
	e.Equal(http.StatusOK, readResp.Code)
300
301
	// get metadata
302
	metaResp := e.httpRequest(http.MethodGet, "/api/v1/note/"+e.uuid()+"/meta", nil)
303
	e.Equal(http.StatusNotFound, metaResp.Code)
304
}