Files

146 lines
3.9 KiB
Go

package webassets
import (
"io"
"strings"
"testing"
)
func TestFileSystemServesEmbeddedIndex(t *testing.T) {
file, err := FileSystem().Open("index.html")
if err != nil {
t.Fatalf("open embedded index.html: %v", err)
}
_ = file.Close()
}
func TestStaticAssetsIncludeMobileRecordLayout(t *testing.T) {
css, err := readAsset("styles.css")
if err != nil {
t.Fatalf("read styles.css: %v", err)
}
if !contains(string(css), "@media (max-width: 560px)") || !contains(string(css), "content: attr(data-label)") {
t.Fatalf("styles.css missing mobile record layout rules")
}
app, err := readAsset("app.js")
if err != nil {
t.Fatalf("read app.js: %v", err)
}
if !contains(string(app), `data-label="脱敏 IP"`) {
t.Fatalf("app.js missing mobile record data labels")
}
}
func TestStaticAssetsUseFixedDurationChoices(t *testing.T) {
html, err := readAsset("index.html")
if err != nil {
t.Fatalf("read index.html: %v", err)
}
if !contains(html, `name="durationSeconds" type="radio" value="15"`) ||
!contains(html, `name="durationSeconds" type="radio" value="30"`) {
t.Fatalf("index.html missing fixed 15s/30s duration choices")
}
if contains(html, `id="durationSeconds" name="durationSeconds" type="number"`) {
t.Fatalf("index.html should not expose free-form duration number input")
}
}
func TestStaticAssetsIncludeCopyableClientCommand(t *testing.T) {
html, err := readAsset("index.html")
if err != nil {
t.Fatalf("read index.html: %v", err)
}
if !contains(html, `id="cliCommand"`) || !contains(html, `id="copyCommandButton"`) {
t.Fatalf("index.html missing copyable CLI command controls")
}
app, err := readAsset("app.js")
if err != nil {
t.Fatalf("read app.js: %v", err)
}
if !contains(app, "updateClientCommand") ||
!contains(app, "navigator.clipboard.writeText") ||
!contains(app, "curl -fsSL") ||
!contains(app, "/downloads/netstable-linux-") ||
!contains(app, ".tar.gz") ||
!contains(app, "tar -xz -C") ||
!contains(app, "uname -m") {
t.Fatalf("app.js missing generated one-click download and test command behavior")
}
}
func TestStaticAssetsIncludeQueueWaitingBehavior(t *testing.T) {
app, err := readAsset("app.js")
if err != nil {
t.Fatalf("read app.js: %v", err)
}
if !contains(app, "waitForBrowserQueue") ||
!contains(app, "queuePosition") ||
!contains(app, "当前排第") ||
!contains(app, "排队中") {
t.Fatalf("app.js missing queue waiting behavior")
}
}
func TestStaticAssetsIncludeManualCancelBehavior(t *testing.T) {
html, err := readAsset("index.html")
if err != nil {
t.Fatalf("read index.html: %v", err)
}
if !contains(html, `id="stopButton"`) {
t.Fatalf("index.html missing manual stop control")
}
app, err := readAsset("app.js")
if err != nil {
t.Fatalf("read app.js: %v", err)
}
if !contains(app, "cancelUrl") ||
!contains(app, "cancelCurrentSession") ||
!contains(app, "beforeunload") ||
!contains(app, "navigator.sendBeacon") {
t.Fatalf("app.js missing manual/unload cancel behavior")
}
}
func TestStaticAssetsPersistPartialBrowserStop(t *testing.T) {
app, err := readAsset("app.js")
if err != nil {
t.Fatalf("read app.js: %v", err)
}
if !contains(app, "completeCurrentSession") ||
!contains(app, "session.completeUrl") ||
!contains(app, "state.samples.length") ||
!contains(app, "已保存已完成样本") {
t.Fatalf("app.js missing partial browser stop persistence behavior")
}
}
func TestStaticAssetsLabelTransferSamplesAsInstantaneous(t *testing.T) {
app, err := readAsset("app.js")
if err != nil {
t.Fatalf("read app.js: %v", err)
}
if !contains(app, "瞬时") {
t.Fatalf("app.js missing instantaneous transfer sample label")
}
}
func contains(text, pattern string) bool {
return strings.Contains(text, pattern)
}
func readAsset(path string) (string, error) {
file, err := FileSystem().Open(path)
if err != nil {
return "", err
}
defer file.Close()
data, err := io.ReadAll(file)
if err != nil {
return "", err
}
return string(data), nil
}