// 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, "