package component
import (
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/bnema/dumber/internal/application/port"
)
func TestJSDialogOriginLabel(t *testing.T) {
assert.Equal(t, "example.com", jsDialogOriginLabel("https://example.com/a?b=c"))
assert.Equal(t, "example.com:8080", jsDialogOriginLabel("http://example.com:8080/"))
assert.Equal(t, "This page", jsDialogOriginLabel(""))
assert.Equal(t, "This page", jsDialogOriginLabel("not a url"))
assert.Equal(t, "file:", jsDialogOriginLabel("file:///tmp/x.html"))
long := jsDialogOriginLabel("https://" + strings.Repeat("a", 500) + ".example.com/")
assert.LessOrEqual(t, len([]rune(long)), jsDialogMaxHostChars+1)
}
func TestJSDialogOriginLabelOpaqueSchemes(t *testing.T) {
cases := map[string]string{
"blob:https://example.com/3f1c-uuid": "example.com",
"blob:http://sub.example.com:8080/uuid": "sub.example.com:8080",
"filesystem:https://example.com/temporary/file.txt": "example.com",
"blob:null/uuid": "blob:",
"blob:": "blob:",
"data:text/html,x": "data:",
"javascript:alert(1)": "javascript:",
}
for in, want := range cases {
assert.Equal(t, want, jsDialogOriginLabel(in), in)
}
}
func TestJSDialogOriginLabelKeepsRegistrableDomain(t *testing.T) {
// A long attacker-controlled prefix must not push the real domain out.
label := jsDialogOriginLabel("https://" + strings.Repeat("paypal.com.", 20) + "evil.test/")
assert.True(t, strings.HasPrefix(label, "…"))
assert.True(t, strings.HasSuffix(label, "evil.test"))
}
func TestBuildJSDialogContentCapsPageText(t *testing.T) {
huge := strings.Repeat("x", jsDialogMaxTextRunes*3)
c := buildJSDialogContent(port.JSDialogRequest{Type: port.JSDialogAlert, Message: huge})
assert.LessOrEqual(t, len([]rune(c.Body)), jsDialogMaxTextRunes+1)
}
func TestBuildJSDialogContentBeforeUnloadUsesFixedText(t *testing.T) {
c := buildJSDialogContent(port.JSDialogRequest{Type: port.JSDialogBeforeUnload, Origin: "https://example.com", Message: "page text"})
assert.Contains(t, c.Body, jsDialogBeforeUnloadText)
assert.NotContains(t, c.Body, "page text")
}
func TestBuildJSDialogContent(t *testing.T) {
origin := "https://example.com/x"
alert := buildJSDialogContent(port.JSDialogRequest{Type: port.JSDialogAlert, Origin: origin, Message: "hi"})
assert.Equal(t, "example.com says:", alert.Heading)
assert.Equal(t, "hi", alert.Body, "message must stay plain text")
assert.Equal(t, "OK", alert.OKLabel)
assert.Empty(t, alert.CancelLabel)
assert.False(t, alert.ShowInput)
confirm := buildJSDialogContent(port.JSDialogRequest{Type: port.JSDialogConfirm, Origin: origin})
assert.Equal(t, "Cancel", confirm.CancelLabel)
assert.False(t, confirm.ShowInput)
prompt := buildJSDialogContent(port.JSDialogRequest{Type: port.JSDialogPrompt, Origin: origin})
assert.True(t, prompt.ShowInput)
assert.Equal(t, "Cancel", prompt.CancelLabel)
leave := buildJSDialogContent(port.JSDialogRequest{Type: port.JSDialogBeforeUnload, Origin: origin})
assert.Equal(t, "Leave page?", leave.Heading)
assert.Equal(t, "Leave", leave.OKLabel)
assert.Equal(t, "Stay", leave.CancelLabel)
assert.Contains(t, leave.Body, "example.com")
reload := buildJSDialogContent(port.JSDialogRequest{Type: port.JSDialogBeforeUnload, Origin: origin, IsReload: true, Message: "x"})
assert.Equal(t, "Reload page?", reload.Heading)
}