Repository navigation
Expand file tree
/
Copy pathevents_test.go
More file actions
113 lines (105 loc) · 4.26 KB
/
Copy pathevents_test.go
File metadata and controls
113 lines (105 loc) · 4.26 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
package main
import (
"context"
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"
)
type fakeChangeEventStore struct {
latest int64
events []changeEvent
cancel context.CancelFunc
deny bool
}
func (s *fakeChangeEventStore) latestID(context.Context) (int64, error) { return s.latest, nil }
func (s *fakeChangeEventStore) canReadDataset(context.Context, string, string) (bool, error) {
return !s.deny, nil
}
func (s *fakeChangeEventStore) eventsAfter(context.Context, int64, string, string, string, int) ([]changeEvent, error) {
if s.cancel != nil {
s.cancel()
}
return s.events, nil
}
func TestChangeEventsRequireSheetbaseSession(t *testing.T) {
auth := &authService{events: &fakeChangeEventStore{}}
res := httptest.NewRecorder()
handleChangeEvents(auth, res, httptest.NewRequest(http.MethodGet, "/internal/events?scope=workspace", nil))
if res.Code != http.StatusUnauthorized {
t.Fatalf("status = %d, want 401", res.Code)
}
}
func TestUIHandlerStreamsEventsThroughResponseLogger(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
store := &fakeChangeEventStore{cancel: cancel}
auth := &authService{events: store, jwtSecret: defaultJWTSecret, sessions: map[string]sessionRecord{}}
cookie := httptest.NewRecorder()
auth.setSession(cookie, "00000000-0000-0000-0000-000000000010")
handler, err := newUIHandler("http://127.0.0.1:3000", auth)
if err != nil {
t.Fatal(err)
}
req := httptest.NewRequest(http.MethodGet, "/internal/events?scope=workspace", nil).WithContext(ctx)
req.AddCookie(cookie.Result().Cookies()[0])
res := httptest.NewRecorder()
done := make(chan struct{})
go func() { handler.ServeHTTP(res, req); close(done) }()
select {
case <-done:
case <-time.After(2 * time.Second):
t.Fatal("event stream did not stop")
}
if res.Code != http.StatusOK || !strings.Contains(res.Body.String(), "event: ready") {
t.Fatalf("status/body = %d %q", res.Code, res.Body.String())
}
}
func TestChangeEventsSendReadyAndReplayChange(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
store := &fakeChangeEventStore{latest: 4, events: []changeEvent{{ID: 5, Scope: "dataset", Kind: "row_update", SheetFormID: "00000000-0000-0000-0000-000000000001", RowID: "00000000-0000-0000-0000-000000000002"}}, cancel: cancel}
auth := &authService{events: store, jwtSecret: defaultJWTSecret, sessions: map[string]sessionRecord{}}
cookie := httptest.NewRecorder()
auth.setSession(cookie, "00000000-0000-0000-0000-000000000010")
req := httptest.NewRequest(http.MethodGet, "/internal/events?dataset=00000000-0000-0000-0000-000000000001", nil).WithContext(ctx)
req.Header.Set("Last-Event-ID", "4")
req.AddCookie(cookie.Result().Cookies()[0])
res := httptest.NewRecorder()
done := make(chan struct{})
go func() { handleChangeEvents(auth, res, req); close(done) }()
select {
case <-done:
case <-time.After(2 * time.Second):
t.Fatal("event stream did not stop")
}
body := res.Body.String()
for _, want := range []string{"event: ready", "id: 5", "event: change", `"kind":"row_update"`} {
if !strings.Contains(body, want) {
t.Fatalf("stream missing %q:\n%s", want, body)
}
}
}
func TestChangeEventsRejectInvalidDataset(t *testing.T) {
auth := &authService{events: &fakeChangeEventStore{}, jwtSecret: defaultJWTSecret, sessions: map[string]sessionRecord{}}
cookie := httptest.NewRecorder()
auth.setSession(cookie, "00000000-0000-0000-0000-000000000010")
req := httptest.NewRequest(http.MethodGet, "/internal/events?dataset=not-a-uuid", nil)
req.AddCookie(cookie.Result().Cookies()[0])
res := httptest.NewRecorder()
handleChangeEvents(auth, res, req)
if res.Code != http.StatusBadRequest {
t.Fatalf("status = %d, want 400", res.Code)
}
}
func TestChangeEventsRejectDatasetWithoutPermission(t *testing.T) {
auth := &authService{events: &fakeChangeEventStore{deny: true}, jwtSecret: defaultJWTSecret, sessions: map[string]sessionRecord{}}
cookie := httptest.NewRecorder()
auth.setSession(cookie, "00000000-0000-0000-0000-000000000010")
req := httptest.NewRequest(http.MethodGet, "/internal/events?dataset=00000000-0000-0000-0000-000000000001", nil)
req.AddCookie(cookie.Result().Cookies()[0])
res := httptest.NewRecorder()
handleChangeEvents(auth, res, req)
if res.Code != http.StatusForbidden {
t.Fatalf("status = %d, want 403", res.Code)
}
}