package web import ( "context" "io" "net/http" "net/url" "sync" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/shcizo/package-updater/internal/master/model" "github.com/shcizo/package-updater/internal/master/poller" ) // fakePoller records the services it was asked to check and answers err. type fakePoller struct { mu sync.Mutex err error calls []int64 } func (f *fakePoller) PollService(_ context.Context, id int64) error { f.mu.Lock() defer f.mu.Unlock() f.calls = append(f.calls, id) return f.err } func (f *fakePoller) called() []int64 { f.mu.Lock() defer f.mu.Unlock() return append([]int64(nil), f.calls...) } func TestPollService(t *testing.T) { tests := []struct { name string id string err error wantStatus int wantLocation string wantBody string wantCalls []int64 }{ {name: "redirects to the service page", id: "1", wantStatus: http.StatusSeeOther, wantLocation: "/services/1", wantCalls: []int64{1}}, {name: "unknown service is 404", id: "1", err: model.ErrNotFound, wantStatus: http.StatusNotFound, wantCalls: []int64{1}}, {name: "invalid id is 400", id: "abc", wantStatus: http.StatusBadRequest}, {name: "not polled is 409 with the reason", id: "1", err: &poller.NotPolledError{Reason: model.ReasonNoTag}, wantStatus: http.StatusConflict, wantBody: "Cannot check: follows no tag.", wantCalls: []int64{1}}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { fp := &fakePoller{err: tt.err} srv, _, _, _, _ := newTestEnvFull(t, func(*Config) {}, fp) resp, err := noRedirectClient().PostForm(srv.URL+"/services/"+tt.id+"/poll", url.Values{"csrf_token": {"csrf"}}) require.NoError(t, err) defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) assert.Equal(t, tt.wantStatus, resp.StatusCode) assert.Equal(t, tt.wantLocation, resp.Header.Get("Location")) assert.Contains(t, string(body), tt.wantBody) assert.Equal(t, tt.wantCalls, fp.called()) }) } } func TestServicePage_CheckNowForm(t *testing.T) { srv, store, _, _, _ := newTestEnv(t) store.services[0].ActualDigest = "sha256:" + "a" _, body := get(t, srv, "/services/1") assert.Contains(t, body, `action="/services/1/poll"`) assert.Contains(t, body, ``) assert.NotContains(t, body, "Check unavailable") } func TestServicePage_CheckNowDisabledWhenNotPolled(t *testing.T) { srv, _, _, _, _ := newTestEnv(t) _, body := get(t, srv, "/services/2") // follows no tag assert.Contains(t, body, ``) assert.Contains(t, body, "Check unavailable: follows no tag.") }