// SPDX-License-Identifier: AGPL-3.0-or-later package app import ( "crypto/sha256" "encoding/base64" "html" "math/bits" "net/url" "regexp" "strconv" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "bnema.dev/ermite/internal/domain" "bnema.dev/ermite/internal/ports" ) var ( reFormAttr = func(name string) *regexp.Regexp { return regexp.MustCompile(`data-` + name + `="([^"]*)"`) } reFormField = func(name string) *regexp.Regexp { return regexp.MustCompile(`= difficulty { return strconv.Itoa(n) } } t.Fatal("no solution") return "" } // formValues reads the challenge out of the HTML of the public form and // solves it. func formValues(t *testing.T, body string) url.Values { t.Helper() get := func(re *regexp.Regexp) string { m := re.FindStringSubmatch(body) require.Len(t, m, 2, "the form carries %s", re) return html.UnescapeString(m[1]) } diff, err := strconv.Atoi(get(reFormAttr("difficulty"))) require.NoError(t, err) require.Equal(t, testPoW, diff, "the test difficulty") return url.Values{ "token": {get(reFormField("token"))}, "form_token": {get(reFormField("form_token"))}, "solution": {solvePoW(t, get(reFormAttr("nonce")), diff)}, } } // The public issue form end to end: a visitor solves the proof of work and // submits, the owner sees the issue awaiting moderation in the inbox and // approves it, and a rejection with a ban shuts the same address out. func TestWebPublicIssueFormEndToEnd(t *testing.T) { h := newHarnessWith(t, harnessOpts{}, func(o *options) { o.issuePoW = testPoW }) cli := &cliHarness{harness: h, url: h.srv.URL} _, err := h.forge.Repos.Create(h.ctx, domain.Root(), createParams(h, "proj", domain.VisibilityPublic)) require.NoError(t, err) b := browser{h} token := cli.signIn(t) pub := domain.IssuesPublic _, err = h.forge.Repos.Update(h.ctx, domain.Root(), h.name("proj"), ports.UpdateRepoParams{Issues: &pub}) require.NoError(t, err) site := map[string]string{"Origin": publicOrigin} // The visitor reads the list and finds the button. list := b.get("/proj/issues", nil) require.Equal(t, 200, list.status, list.body) assert.Contains(t, list.body, `href="/proj/issues/new"`) // The form, with a challenge, never stored. form := b.get("/proj/issues/new", nil) require.Equal(t, 200, form.status, form.body) assert.Equal(t, "no-store", form.hdr.Get("Cache-Control")) assert.Contains(t, form.body, "