-
Notifications
You must be signed in to change notification settings - Fork 27
Expand file tree
/
Copy pathanonymous_temp_expiration_test.go
More file actions
152 lines (131 loc) · 4.87 KB
/
Copy pathanonymous_temp_expiration_test.go
File metadata and controls
152 lines (131 loc) · 4.87 KB
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package httpapi
import (
"context"
"net/http"
"strconv"
"testing"
"time"
"scrumboy/internal/store"
"scrumboy/internal/version"
)
func TestAnonymousMode_DeleteProjectRoute_Returns404(t *testing.T) {
ts, _, cleanup := newTestHTTPServer(t, "anonymous")
defer cleanup()
client := ts.Client()
resp, _ := doJSON(t, client, http.MethodDelete, ts.URL+"/api/projects/1", nil, nil)
if resp.StatusCode != http.StatusNotFound {
t.Fatalf("expected 404 for DELETE /api/projects/{id} in anonymous mode, got %d", resp.StatusCode)
}
}
func TestExpiredAnonymousTempBoard_BoardGET_Returns404(t *testing.T) {
ts, sqlDB, cleanup := newTestHTTPServer(t, "anonymous")
defer cleanup()
st := store.New(sqlDB, nil)
p, err := st.CreateAnonymousBoard(context.Background())
if err != nil {
t.Fatalf("CreateAnonymousBoard: %v", err)
}
pastMs := time.Now().UTC().Add(-24 * time.Hour).UnixMilli()
if _, err := sqlDB.Exec(`UPDATE projects SET expires_at = ? WHERE id = ?`, pastMs, p.ID); err != nil {
t.Fatalf("expire project: %v", err)
}
client := ts.Client()
resp, body := doJSON(t, client, http.MethodGet, ts.URL+"/api/board/"+p.Slug, nil, nil)
if resp.StatusCode != http.StatusNotFound {
t.Fatalf("expected 404 for expired board GET, got %d body=%s", resp.StatusCode, string(body))
}
}
func TestExpiredAnonymousTempBoard_TodoCreate_Returns404(t *testing.T) {
ts, sqlDB, cleanup := newTestHTTPServer(t, "anonymous")
defer cleanup()
st := store.New(sqlDB, nil)
p, err := st.CreateAnonymousBoard(context.Background())
if err != nil {
t.Fatalf("CreateAnonymousBoard: %v", err)
}
pastMs := time.Now().UTC().Add(-24 * time.Hour).UnixMilli()
if _, err := sqlDB.Exec(`UPDATE projects SET expires_at = ? WHERE id = ?`, pastMs, p.ID); err != nil {
t.Fatalf("expire project: %v", err)
}
client := ts.Client()
resp, body := doJSON(t, client, http.MethodPost, ts.URL+"/api/board/"+p.Slug+"/todos", map[string]any{
"title": "late",
"columnKey": "backlog",
}, nil)
if resp.StatusCode != http.StatusNotFound {
t.Fatalf("expected 404 for todo create on expired board, got %d body=%s", resp.StatusCode, string(body))
}
}
func TestAnonymousMode_ImportReplace_Forbidden(t *testing.T) {
ts, _, cleanup := newTestHTTPServer(t, "anonymous")
defer cleanup()
client := ts.Client()
data := store.ExportData{
Version: version.ExportFormatVersion,
Scope: "single",
Projects: []store.ProjectExport{
{Slug: "imp", Name: "Import"},
},
}
resp, body := doJSON(t, client, http.MethodPost, ts.URL+"/api/backup/import", map[string]any{
"data": data,
"importMode": "replace",
"confirmation": "REPLACE",
}, nil)
if resp.StatusCode != http.StatusBadRequest {
t.Fatalf("expected 400 for replace import in anonymous mode, got %d body=%s", resp.StatusCode, string(body))
}
}
func TestAnonymousMode_PatchRename_ExpiredBoard_Returns404(t *testing.T) {
ts, sqlDB, cleanup := newTestHTTPServer(t, "anonymous")
defer cleanup()
st := store.New(sqlDB, nil)
p, err := st.CreateAnonymousBoard(context.Background())
if err != nil {
t.Fatalf("CreateAnonymousBoard: %v", err)
}
pastMs := time.Now().UTC().Add(-24 * time.Hour).UnixMilli()
if _, err := sqlDB.Exec(`UPDATE projects SET expires_at = ? WHERE id = ?`, pastMs, p.ID); err != nil {
t.Fatalf("expire project: %v", err)
}
client := ts.Client()
resp, _ := doJSON(t, client, http.MethodPatch, ts.URL+"/api/projects/"+strconv.FormatInt(p.ID, 10), map[string]any{
"name": "Too Late",
}, nil)
if resp.StatusCode != http.StatusNotFound {
t.Fatalf("expected 404 for PATCH rename on expired board, got %d", resp.StatusCode)
}
}
func TestAnonymousMode_PatchRename_DurableProject_Returns404(t *testing.T) {
ts, sqlDB, cleanup := newTestHTTPServer(t, "anonymous")
defer cleanup()
st := store.New(sqlDB, nil)
p, err := st.CreateProject(context.Background(), "Durable")
if err != nil {
t.Fatalf("CreateProject: %v", err)
}
client := ts.Client()
resp, _ := doJSON(t, client, http.MethodPatch, ts.URL+"/api/projects/"+strconv.FormatInt(p.ID, 10), map[string]any{
"name": "Nope",
}, nil)
if resp.StatusCode != http.StatusNotFound {
t.Fatalf("expected 404 for PATCH on durable project in anonymous mode, got %d", resp.StatusCode)
}
}
func TestAnonymousMode_PatchRename_ImageRejected(t *testing.T) {
ts, sqlDB, cleanup := newTestHTTPServer(t, "anonymous")
defer cleanup()
st := store.New(sqlDB, nil)
p, err := st.CreateAnonymousBoard(context.Background())
if err != nil {
t.Fatalf("CreateAnonymousBoard: %v", err)
}
client := ts.Client()
resp, _ := doJSON(t, client, http.MethodPatch, ts.URL+"/api/projects/"+strconv.FormatInt(p.ID, 10), map[string]any{
"image": "data:image/png;base64,aaaa",
}, nil)
// Anonymous mode has no session; image PATCH requires auth (route is open only for rename on active anon temps).
if resp.StatusCode != http.StatusUnauthorized {
t.Fatalf("expected 401 for image PATCH in anonymous mode, got %d", resp.StatusCode)
}
}