mirror of
https://github.com/alibaba/open-code-review.git
synced 2026-08-21 14:44:56 +00:00
Some checks are pending
CI / test (push) Waiting to run
CI / cross-compile (amd64, darwin) (push) Waiting to run
CI / cross-compile (amd64, windows) (push) Waiting to run
CI / cross-compile (arm64, windows) (push) Waiting to run
CI / cross-compile (arm64, darwin) (push) Waiting to run
CI / cross-compile (arm64, linux) (push) Waiting to run
CodeQL Advanced / Analyze (go) (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
* feat(viewer): add review comment tag filters * fix(viewer): normalize filter chip state values Use the same empty-string fallback when updating filter-chip active state as when handling clicks, preventing filters without a value attribute from appearing inactive after selection. Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * fix(viewer): improve comment tag filter controls * fix(viewer): support combined comment filters * fix(viewer): simplify active filter chip ring --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
104 lines
3.6 KiB
Go
104 lines
3.6 KiB
Go
// SPDX-License-Identifier: Apache-2.0
|
|
// Copyright 2026 alibaba/open-code-review Contributors
|
|
|
|
package viewer
|
|
|
|
import (
|
|
"net"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// TestStartServer_SessionsRootError forces os.UserHomeDir to fail by clearing
|
|
// HOME so StartServer returns before binding a socket.
|
|
func TestStartServer_SessionsRootError(t *testing.T) {
|
|
t.Setenv("HOME", "")
|
|
// On unix os.UserHomeDir errors when HOME is empty.
|
|
if _, err := SessionsRoot(); err == nil {
|
|
t.Skip("home dir resolvable despite empty HOME; platform-specific")
|
|
}
|
|
if err := StartServer("127.0.0.1:0"); err == nil {
|
|
t.Fatal("expected StartServer to fail when sessions root cannot resolve")
|
|
}
|
|
}
|
|
|
|
// TestStartServer_AddrInUse runs the full setup path (routes, host guard,
|
|
// security headers, server construction) and then fails fast on ListenAndServe
|
|
// because the port is already bound — no goroutine leak.
|
|
func TestStartServer_AddrInUse(t *testing.T) {
|
|
ln, err := net.Listen("tcp", "127.0.0.1:0")
|
|
if err != nil {
|
|
t.Fatalf("reserve port: %v", err)
|
|
}
|
|
defer ln.Close()
|
|
|
|
err = StartServer(ln.Addr().String())
|
|
if err == nil {
|
|
t.Fatal("expected StartServer to fail binding an in-use address")
|
|
}
|
|
}
|
|
|
|
// TestParseTemplate_SessionWithComments renders session.html with review
|
|
// comments spanning several severities and categories so the template helpers
|
|
// (severityCounts, categoryCounts, severityClass, categoryClass,
|
|
// groupCommentsByFile, and the normalization helpers) execute.
|
|
func TestParseTemplate_SessionWithComments(t *testing.T) {
|
|
tmpl, err := parseTemplate("session.html")
|
|
if err != nil {
|
|
t.Fatalf("parseTemplate: %v", err)
|
|
}
|
|
|
|
comments := []*ReviewComment{
|
|
{FilePath: "a.go", Content: "c1", Category: "bug", Severity: "critical", StartLine: 1, EndLine: 2},
|
|
{FilePath: "a.go", Content: "c2", Category: "security", Severity: "high"},
|
|
{FilePath: "b.go", Content: "c3", Category: "performance", Severity: "medium"},
|
|
{FilePath: "b.go", Content: "c4", Category: "docs", Severity: "low"},
|
|
}
|
|
vs := &ViewSession{
|
|
Summary: SessionSummary{SessionID: "s", CWD: "/p"},
|
|
Comments: comments,
|
|
Files: []*FileGroup{
|
|
{FilePath: "a.go", Tasks: map[TaskType][]*TaskCard{
|
|
MainTask: {{RequestNo: 1, ResponseContent: "ok", DurationMs: 1500, PromptTokens: 1200, CompletionTokens: 2_000_000}},
|
|
}},
|
|
},
|
|
}
|
|
|
|
rr := httptest.NewRecorder()
|
|
if err := tmpl.Execute(rr, sessionPageData{EncodedRepo: "r", RepoName: "R", Session: vs}); err != nil {
|
|
t.Fatalf("execute session.html with comments: %v", err)
|
|
}
|
|
if !strings.Contains(rr.Body.String(), "Review Comments") {
|
|
t.Error("rendered page missing Review Comments section")
|
|
}
|
|
body := rr.Body.String()
|
|
for _, want := range []string{
|
|
`<span class="comment-filter-label">Severity:</span>`,
|
|
`<span class="comment-filter-label">Category:</span>`,
|
|
`data-filter-kind="severity" data-filter-value="all"`,
|
|
`data-filter-kind="category" data-filter-value="all"`,
|
|
`data-filter-kind="severity" data-filter-value="critical"`,
|
|
`data-filter-kind="category" data-filter-value="bug"`,
|
|
`data-filter-kind="category" data-filter-value="other"`,
|
|
`data-comment-card data-category="bug" data-severity="critical"`,
|
|
`data-comment-card data-category="other" data-severity="low"`,
|
|
`data-comment-filter-empty`,
|
|
} {
|
|
if !strings.Contains(body, want) {
|
|
t.Errorf("rendered page missing %q", want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestCategoryCounts_NormalizesUnknownCategories(t *testing.T) {
|
|
counts := categoryCounts([]*ReviewComment{
|
|
{Category: "bug"},
|
|
{Category: "MAINTAINABILITY"},
|
|
{Category: ""},
|
|
{Category: "not-a-category"},
|
|
})
|
|
if counts.Bug != 1 || counts.Maintainability != 1 || counts.Other != 2 {
|
|
t.Fatalf("unexpected category counts: %+v", counts)
|
|
}
|
|
}
|