Skip to content

Commit 91e5a71

Browse files
committed
feat(api): add sessions events listing to store
1 parent 996e8f2 commit 91e5a71

File tree

10 files changed

+641
-69
lines changed

10 files changed

+641
-69
lines changed

api/routes/routes.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ func NewRouter(service services.Service, opts ...Option) *echo.Echo {
132132

133133
publicAPI.GET(GetSessionsURL, routesmiddleware.Authorize(gateway.Handler(handler.GetSessionList)))
134134
publicAPI.GET(GetSessionURL, routesmiddleware.Authorize(gateway.Handler(handler.GetSession)))
135+
publicAPI.GET(ListEventsSessionsURL, routesmiddleware.Authorize(gateway.Handler(handler.ListEventsSession)))
135136

136137
publicAPI.GET(GetStatsURL, routesmiddleware.Authorize(gateway.Handler(handler.GetStats)))
137138
publicAPI.GET(GetSystemInfoURL, gateway.Handler(handler.GetSystemInfo))

api/routes/session.go

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,14 @@ import (
1313
)
1414

1515
const (
16-
GetSessionsURL = "/sessions"
17-
GetSessionURL = "/sessions/:uid"
18-
UpdateSessionURL = "/sessions/:uid"
19-
CreateSessionURL = "/sessions"
20-
FinishSessionURL = "/sessions/:uid/finish"
21-
KeepAliveSessionURL = "/sessions/:uid/keepalive"
22-
EventsSessionsURL = "/sessions/:uid/events"
16+
GetSessionsURL = "/sessions"
17+
GetSessionURL = "/sessions/:uid"
18+
UpdateSessionURL = "/sessions/:uid"
19+
CreateSessionURL = "/sessions"
20+
FinishSessionURL = "/sessions/:uid/finish"
21+
KeepAliveSessionURL = "/sessions/:uid/keepalive"
22+
EventsSessionsURL = "/sessions/:uid/events"
23+
ListEventsSessionsURL = "/sessions/:uid/events"
2324
)
2425

2526
const (
@@ -164,7 +165,7 @@ func (h *Handler) EventSession(c gateway.Context) error {
164165
return err
165166
}
166167

167-
if err := h.service.EventSession(c.Ctx(), models.UID(req.UID), &models.SessionEvent{
168+
if err := h.service.SaveEventSession(c.Ctx(), models.UID(req.UID), &models.SessionEvent{
168169
Session: req.UID,
169170
Type: models.SessionEventType(r.Type),
170171
Timestamp: r.Timestamp,
@@ -175,3 +176,31 @@ func (h *Handler) EventSession(c gateway.Context) error {
175176
}
176177
}
177178
}
179+
180+
func (h *Handler) ListEventsSession(c gateway.Context) error {
181+
req := new(requests.SessionListEvents)
182+
183+
if err := c.Bind(req); err != nil {
184+
return err
185+
}
186+
187+
req.Paginator.Normalize()
188+
req.Sorter.Normalize()
189+
190+
if err := req.Filters.Unmarshal(); err != nil {
191+
return err
192+
}
193+
194+
if err := c.Validate(req); err != nil {
195+
return err
196+
}
197+
198+
events, counter, err := h.service.ListEventsSession(c.Ctx(), models.UID(req.UID), req.Paginator, req.Filters, req.Sorter)
199+
if err != nil {
200+
return err
201+
}
202+
203+
c.Response().Header().Set("X-Total-Count", strconv.Itoa(counter))
204+
205+
return c.JSON(http.StatusOK, events)
206+
}

api/routes/session_test.go

Lines changed: 196 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import (
77
"io"
88
"net/http"
99
"net/http/httptest"
10+
"net/url"
11+
"strconv"
1012
"strings"
1113
"testing"
1214

@@ -399,7 +401,7 @@ func TestEventSession(t *testing.T) {
399401

400402
webSocketUpgraderMock.On("Upgrade", gomock.Anything, gomock.Anything).Return(conn, nil).Once()
401403

402-
mock.On("EventSession", gomock.Anything, models.UID(uid), gomock.Anything).
404+
mock.On("SaveEventSession", gomock.Anything, models.UID(uid), gomock.Anything).
403405
Return(errors.New("not able record")).Once()
404406
},
405407
expected: http.StatusInternalServerError,
@@ -422,7 +424,7 @@ func TestEventSession(t *testing.T) {
422424

423425
webSocketUpgraderMock.On("Upgrade", gomock.Anything, gomock.Anything).Return(conn, nil).Once()
424426

425-
mock.On("EventSession", gomock.Anything, models.UID(uid),
427+
mock.On("SaveEventSession", gomock.Anything, models.UID(uid),
426428
gomock.Anything).Return(nil).Once()
427429

428430
conn.On("ReadJSON", gomock.Anything).Return(&websocket.CloseError{
@@ -468,3 +470,195 @@ func TestEventSession(t *testing.T) {
468470
})
469471
}
470472
}
473+
474+
func TestListEventsSession(t *testing.T) {
475+
mock := new(mocks.Service)
476+
477+
cases := []struct {
478+
title string
479+
req *requests.SessionListEvents
480+
requiredMocks func()
481+
expectedStatus int
482+
expectedCounter string
483+
expectedBody string
484+
}{
485+
{
486+
title: "fails to list session's events when input data is invalid",
487+
req: &requests.SessionListEvents{
488+
UID: "",
489+
Paginator: query.Paginator{},
490+
Sorter: query.Sorter{},
491+
Filters: query.Filters{},
492+
},
493+
requiredMocks: func() {},
494+
expectedStatus: http.StatusBadRequest,
495+
expectedCounter: "",
496+
expectedBody: "",
497+
},
498+
{
499+
title: "fails to list session's events when cannot validate input params",
500+
req: &requests.SessionListEvents{
501+
UID: "",
502+
Paginator: query.Paginator{Page: 1, PerPage: 10},
503+
Sorter: query.Sorter{By: "name", Order: "asc"},
504+
Filters: query.Filters{},
505+
},
506+
requiredMocks: func() {},
507+
expectedStatus: http.StatusBadRequest,
508+
expectedCounter: "",
509+
expectedBody: "",
510+
},
511+
{
512+
title: "fails to list session's events when service fails because session doesn't exist",
513+
req: &requests.SessionListEvents{
514+
UID: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
515+
Paginator: query.Paginator{Page: 1, PerPage: 10},
516+
Sorter: query.Sorter{By: "name", Order: "asc"},
517+
Filters: query.Filters{},
518+
},
519+
requiredMocks: func() {
520+
mock.
521+
On("ListEventsSession",
522+
gomock.Anything,
523+
models.UID("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
524+
gomock.Anything,
525+
gomock.Anything,
526+
gomock.Anything,
527+
).
528+
Return(nil, 0, svc.ErrSessionNotFound).
529+
Once()
530+
},
531+
expectedStatus: http.StatusNotFound,
532+
expectedCounter: "",
533+
expectedBody: "",
534+
},
535+
{
536+
title: "fails to list session's events when service fails",
537+
req: &requests.SessionListEvents{
538+
UID: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
539+
Paginator: query.Paginator{Page: 1, PerPage: 10},
540+
Sorter: query.Sorter{By: "name", Order: "asc"},
541+
Filters: query.Filters{},
542+
},
543+
requiredMocks: func() {
544+
mock.
545+
On("ListEventsSession",
546+
gomock.Anything,
547+
models.UID("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
548+
gomock.Anything,
549+
gomock.Anything,
550+
gomock.Anything,
551+
).
552+
Return(nil, 0, errors.New("")).
553+
Once()
554+
},
555+
expectedStatus: http.StatusInternalServerError,
556+
expectedCounter: "",
557+
expectedBody: "",
558+
},
559+
{
560+
title: "success to list session's events when it is empty",
561+
req: &requests.SessionListEvents{
562+
UID: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
563+
Paginator: query.Paginator{Page: 1, PerPage: 10},
564+
Sorter: query.Sorter{By: "name", Order: "asc"},
565+
Filters: query.Filters{},
566+
},
567+
requiredMocks: func() {
568+
mock.
569+
On("ListEventsSession",
570+
gomock.Anything,
571+
models.UID("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
572+
gomock.Anything,
573+
gomock.Anything,
574+
gomock.Anything,
575+
).
576+
Return([]models.SessionEvent{}, 0, nil).
577+
Once()
578+
},
579+
expectedStatus: http.StatusOK,
580+
expectedCounter: "0",
581+
expectedBody: `[]` + "\n",
582+
},
583+
{
584+
title: "success to list session's events with one item",
585+
req: &requests.SessionListEvents{
586+
UID: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
587+
Paginator: query.Paginator{Page: 1, PerPage: 10},
588+
Sorter: query.Sorter{By: "name", Order: "asc"},
589+
Filters: query.Filters{},
590+
},
591+
requiredMocks: func() {
592+
mock.
593+
On("ListEventsSession",
594+
gomock.Anything,
595+
models.UID("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
596+
gomock.Anything,
597+
gomock.Anything,
598+
gomock.Anything,
599+
).
600+
Return([]models.SessionEvent{
601+
{},
602+
}, 1, nil).
603+
Once()
604+
},
605+
expectedStatus: http.StatusOK,
606+
expectedCounter: "1",
607+
expectedBody: `[{"session":"","type":"","timestamp":"0001-01-01T00:00:00Z","data":null,"seat":0}]` + "\n",
608+
},
609+
{
610+
title: "success to list session's events with more than one item",
611+
req: &requests.SessionListEvents{
612+
UID: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
613+
Paginator: query.Paginator{Page: 1, PerPage: 10},
614+
Sorter: query.Sorter{By: "name", Order: "asc"},
615+
Filters: query.Filters{},
616+
},
617+
requiredMocks: func() {
618+
mock.
619+
On("ListEventsSession",
620+
gomock.Anything,
621+
models.UID("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
622+
gomock.Anything,
623+
gomock.Anything,
624+
gomock.Anything,
625+
).
626+
Return([]models.SessionEvent{
627+
{},
628+
{},
629+
}, 2, nil).
630+
Once()
631+
},
632+
expectedStatus: http.StatusOK,
633+
expectedCounter: "2",
634+
expectedBody: `[{"session":"","type":"","timestamp":"0001-01-01T00:00:00Z","data":null,"seat":0},{"session":"","type":"","timestamp":"0001-01-01T00:00:00Z","data":null,"seat":0}]` + "\n",
635+
},
636+
}
637+
638+
for _, tc := range cases {
639+
t.Run(tc.title, func(t *testing.T) {
640+
tc.requiredMocks()
641+
642+
urlVal := &url.Values{}
643+
urlVal.Set("page", strconv.Itoa(tc.req.Page))
644+
urlVal.Set("per_page", strconv.Itoa(tc.req.PerPage))
645+
urlVal.Set("sort_by", tc.req.By)
646+
urlVal.Set("order_by", tc.req.Order)
647+
648+
req := httptest.NewRequest(http.MethodGet, fmt.Sprintf("/api/sessions/%s/events?"+urlVal.Encode(), tc.req.UID), nil)
649+
req.Header.Set("Content-Type", "application/json")
650+
req.Header.Set("X-Role", authorizer.RoleOwner.String())
651+
652+
rec := httptest.NewRecorder()
653+
654+
e := NewRouter(mock)
655+
e.ServeHTTP(rec, req)
656+
657+
assert.Equal(t, tc.expectedStatus, rec.Result().StatusCode)
658+
assert.Equal(t, tc.expectedCounter, rec.Header().Get("X-Total-Count"))
659+
assert.Equal(t, tc.expectedBody, rec.Body.String())
660+
})
661+
}
662+
663+
mock.AssertExpectations(t)
664+
}

api/services/mocks/services.go

Lines changed: 56 additions & 19 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)