Files
chorus/portal/web/web_test.go
T

123 lines
4.2 KiB
Go

package web
import (
"bytes"
"io/fs"
"strings"
"testing"
"time"
"git.ilapage.cn/OPC/chorus/internal/core/model"
)
func TestLoginUsesAccountOnly(t *testing.T) {
renderer, err := NewRenderer()
if err != nil {
t.Fatal(err)
}
var page bytes.Buffer
if err := renderer.Render(&page, "login", Page{CSRFToken: "synthetic", ReturnTo: "/"}); err != nil {
t.Fatal(err)
}
html := page.String()
for _, required := range []string{`for="account">账号`, `id="account"`, `name="account"`, `type="text"`, `autocomplete="username"`, `账号或密码不正确`} {
if !strings.Contains(html, required) {
t.Errorf("login page is missing %s", required)
}
}
for _, forbidden := range []string{`id="email"`, `name="email"`, `type="email"`, `邮箱或密码不正确`} {
if strings.Contains(html, forbidden) {
t.Errorf("login page still contains %s", forbidden)
}
}
static, err := Static()
if err != nil {
t.Fatal(err)
}
script, err := fs.ReadFile(static, "app.js")
if err != nil {
t.Fatal(err)
}
for _, required := range []string{`querySelector("#account")`, `account: account.value`} {
if !strings.Contains(string(script), required) {
t.Errorf("login script is missing %s", required)
}
}
if strings.Contains(string(script), `email: email.value`) {
t.Error("login script still submits email")
}
}
func TestGenerationDurationUsesTerminalAndLiveBoundaries(t *testing.T) {
created := time.Date(2026, 8, 25, 9, 0, 0, 0, time.UTC)
completed := created.Add(2*time.Minute + 30*time.Second)
terminal := model.Generation{Status: model.StatusSucceeded, CreatedAt: created, CompletedAt: &completed}
if got := generationDuration(terminal, completed.Add(time.Hour), false); got != "2分30秒" {
t.Fatalf("terminal duration = %q", got)
}
pending := model.Generation{Status: model.StatusPending, CreatedAt: created}
if got := generationDuration(pending, created.Add(9*time.Second), true); got != "已等待 9秒" {
t.Fatalf("pending duration = %q", got)
}
invalid := model.Generation{Status: model.StatusSucceeded, CreatedAt: completed, CompletedAt: &created}
if got := generationDuration(invalid, completed, true); got != "时间异常" {
t.Fatalf("invalid duration = %q", got)
}
}
func TestOutputMetadataUsesAvailableFields(t *testing.T) {
mimeType, size, width, height := "image/png", uint64(1536), uint32(1024), uint32(768)
output := model.GenerationOutput{MIMEType: &mimeType, SizeBytes: &size, Width: &width, Height: &height}
if got := outputMetadata(output); got != "PNG · 1024 x 768 · 1.5 KB" {
t.Fatalf("metadata = %q", got)
}
if got := outputMetadata(model.GenerationOutput{}); got != "图片结果" {
t.Fatalf("fallback metadata = %q", got)
}
}
func TestAppRendersHistoryDurationMarkup(t *testing.T) {
renderer, err := NewRenderer()
if err != nil {
t.Fatal(err)
}
created := time.Now().Add(-10 * time.Second)
completed := created.Add(5 * time.Second)
var page bytes.Buffer
data := Page{History: []model.Generation{{ID: 3, Status: model.StatusSucceeded, Kind: model.KindImage, UserPrompt: "test", CreatedAt: created, CompletedAt: &completed}}, MaxPromptBytes: 1000, MaxImages: 3}
if err := renderer.Render(&page, "app", data); err != nil {
t.Fatal(err)
}
html := page.String()
for _, expected := range []string{`aria-label="图片"`, `data-duration-context="history"`, `>5秒</span>`, `class="relative-time"`} {
if !strings.Contains(html, expected) {
t.Errorf("history markup is missing %s", expected)
}
}
}
func TestAppDisablesUnavailableImageGenerateRoute(t *testing.T) {
renderer, err := NewRenderer()
if err != nil {
t.Fatal(err)
}
var page bytes.Buffer
data := Page{CSRFToken: "synthetic", MaxPromptBytes: 1000, MaxImages: 3, ImageEditAvailable: true}
if err := renderer.Render(&page, "app", data); err != nil {
t.Fatal(err)
}
html := page.String()
for _, required := range []string{
`name="image-generate-available" content="false"`,
`data-mode="generate" x-on:click="setGenerate" x-bind:aria-pressed="generatePressed" aria-disabled="true"`,
`id="generation-mode" type="hidden" value="edit"`,
`当前文生图暂不可用,请使用图片编辑。`,
`<span>开始图片编辑</span>`,
} {
if !strings.Contains(html, required) {
t.Errorf("app page is missing %s", required)
}
}
}