package rest_test import ( "bytes" "encoding/gob" "encoding/json" "io" "net/http" "testing" "gitea.dwysokinski.me/Kichiyaki/notificationarr/internal/domain" "github.com/stretchr/testify/assert" "gitea.dwysokinski.me/Kichiyaki/notificationarr/internal/rest" "gitea.dwysokinski.me/Kichiyaki/notificationarr/internal/rest/internal/mock" "github.com/go-chi/chi/v5" ) func TestWebhookHandler_Sonarr(t *testing.T) { t.Parallel() tests := []struct { name string setup func(svc *mock.FakeSonarrService) body io.Reader expectedStatus int target any expectedResponse any }{ { name: "OK: event type=Download", setup: func(svc *mock.FakeSonarrService) { svc.ProcessReturns(nil) }, body: func() *bytes.Buffer { var buf bytes.Buffer _ = json.NewEncoder(&buf).Encode(rest.SonarrWebhookRequest{ EventType: "Download", Series: rest.SonarrSeries{ ID: 1, Title: "Series 1", }, Episodes: []rest.SonarrEpisode{ { ID: 1, EpisodeNumber: 1, SeasonNumber: 1, Title: "Ep 1", }, }, }) return &buf }(), expectedStatus: http.StatusNoContent, }, { name: "ERR: only JSON is accepted", setup: func(svc *mock.FakeSonarrService) {}, body: func() *bytes.Buffer { var buf bytes.Buffer _ = gob.NewEncoder(&buf).Encode(rest.SonarrWebhookRequest{ EventType: "Download", Series: rest.SonarrSeries{ ID: 1, Title: "Series 1", }, Episodes: []rest.SonarrEpisode{ { ID: 1, EpisodeNumber: 1, SeasonNumber: 1, Title: "Ep 1", }, }, }) return &buf }(), expectedStatus: http.StatusBadRequest, target: &rest.ErrorResponse{}, expectedResponse: &rest.ErrorResponse{ Error: rest.APIError{ Code: domain.ErrorCodeValidation.String(), Message: "invalid request body", }, }, }, { name: "ERR: unsupported event type", setup: func(svc *mock.FakeSonarrService) {}, body: func() *bytes.Buffer { var buf bytes.Buffer _ = json.NewEncoder(&buf).Encode(rest.SonarrWebhookRequest{ EventType: "xxxx", }) return &buf }(), expectedStatus: http.StatusBadRequest, target: &rest.ErrorResponse{}, expectedResponse: &rest.ErrorResponse{ Error: rest.APIError{ Code: domain.ErrUnsupportedSonarrEventType.Code().String(), Message: domain.ErrUnsupportedSonarrEventType.Message(), }, }, }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() svc := mock.FakeSonarrService{} if tt.setup != nil { tt.setup(&svc) } router := chi.NewRouter() rest.NewWebhookHandler(&svc).Register(router) resp := doRequest(router, http.MethodPost, "/webhook/sonarr", tt.body) defer assert.NoError(t, resp.Body.Close()) if tt.target != nil && tt.expectedResponse != nil { assertJSONResponse(t, resp, tt.expectedStatus, tt.expectedResponse, tt.target) } else { assert.Equal(t, tt.expectedStatus, resp.StatusCode) } }) } }