// SPDX-License-Identifier: AGPL-3.0-or-later
package web
import (
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"bnema.dev/ermite/internal/domain"
"bnema.dev/ermite/internal/ports"
"bnema.dev/ermite/internal/ports/mocks"
)
const testPendingID = "aaaaaaaaaaaaaaaaaaaaaaaaaa"
func testPendingIssue(t testing.TB) domain.PendingIssue {
t.Helper()
id, err := domain.NewPendingIssueID()
require.NoError(t, err)
title, err := domain.ParseIssueTitle(" crash")
require.NoError(t, err)
body, err := domain.ParseIssueBody("**not bold** [x](javascript:alert(1))
\n" + strings.Repeat("long line ", 60))
require.NoError(t, err)
return domain.PendingIssue{ID: id, Repo: repoName(t, "alpha"), Title: title, Body: body, Author: "Eve ", CreatedAt: time.Now().Add(-3 * time.Hour)}
}
func moderationServer(t *testing.T, inbox ports.InboxService, mod ports.IssueModerationService) *Server {
t.Helper()
return newTestServer(t, Config{
Repos: reposServing(t, publicRepo(t, "alpha")), Browse: homeBrowse(t), Inbox: inbox, Moderation: mod,
Sessions: newSessions(t, "tok"), Limiter: &countingLimiter{},
})
}
func TestInboxShowsPendingIssuesAsPlainTextFirst(t *testing.T) {
t.Parallel()
p := testPendingIssue(t)
ov := inboxOverview(t)
ov.Pending = []domain.PendingIssue{p, {ID: p.ID, Repo: repoName(t, "beta"), Title: p.Title, CreatedAt: time.Now()}}
ov.Counts.Pending = 2
svc := mocks.NewInboxService(t)
svc.EXPECT().Overview(mock.Anything, mock.Anything, domain.RepoName{}).Return(ov, nil)
srv := moderationServer(t, svc, mocks.NewIssueModerationService(t))
rec := inboxGet(srv, "/-/inbox", true)
require.Equal(t, 200, rec.Code)
body := rec.Body.String()
assert.Contains(t, body, "2 awaiting moderation")
assert.Less(t, strings.Index(body, `id="inbox-pending"`), strings.Index(body, `id="inbox-mrs"`), "first section")
assert.Contains(t, body, "<script>alert(1)</script> crash")
assert.NotContains(t, body, "