1package cef
2
3import (
4 "context"
5 "testing"
6
7 "github.com/stretchr/testify/mock"
8 "github.com/stretchr/testify/require"
9
10 "github.com/bnema/dumber/internal/application/port"
11 portmocks "github.com/bnema/dumber/internal/application/port/mocks"
12)
13
14type closeablePopupWebViewStub struct {
15 *portmocks.MockWebView
16 closed bool
17}
18
19func (s *closeablePopupWebViewStub) AddCloseCallback(func()) {}
20func (s *closeablePopupWebViewStub) AddNavigationCallback(func(string)) {}
21func (s *closeablePopupWebViewStub) Close() { s.closed = true }
22
23func TestHandleSyntheticPopupOpen_ReplaysQueuedNavigation(t *testing.T) {
24 popupWV := portmocks.NewMockWebView(t)
25 popupWV.EXPECT().IsDestroyed().Return(false).Once()
26 popupWV.EXPECT().LoadURI(mock.Anything, "https://example.com/callback").Return(nil).Once()
27
28 parentWV := &WebView{
29 ctx: context.Background(),
30 id: port.WebViewID(17),
31 callbacks: &port.WebViewCallbacks{
32 OnCreate: func(req port.PopupRequest) port.WebView {
33 require.Empty(t, req.TargetURI)
34 require.Equal(t, "_blank", req.FrameName)
35 require.True(t, req.IsUserGesture)
36 require.True(t, req.NoJavaScriptAccess)
37 require.Equal(t, port.WebViewID(17), req.ParentViewID)
38 return popupWV
39 },
40 },
41 }
42
43 parentWV.handleSyntheticPopupNavigate("popup-1", "https://example.com/callback")
44 parentWV.handleSyntheticPopupOpen("", "_blank", "popup-1", true, true)
45}
46
47func TestHandleSyntheticPopupNavigate_LoadsMappedPopup(t *testing.T) {
48 popupWV := portmocks.NewMockWebView(t)
49 popupWV.EXPECT().IsDestroyed().Return(false).Once()
50 popupWV.EXPECT().LoadURI(mock.Anything, "https://example.com/finish").Return(nil).Once()
51
52 parentWV := &WebView{
53 ctx: context.Background(),
54 id: port.WebViewID(23),
55 callbacks: &port.WebViewCallbacks{
56 OnCreate: func(req port.PopupRequest) port.WebView {
57 require.Equal(t, "https://example.com/start", req.TargetURI)
58 require.Equal(t, "auth-popup", req.FrameName)
59 require.False(t, req.NoJavaScriptAccess)
60 return popupWV
61 },
62 },
63 }
64
65 parentWV.handleSyntheticPopupOpen("https://example.com/start", "auth-popup", "popup-2", true, false)
66 parentWV.handleSyntheticPopupNavigate("popup-2", "https://example.com/finish")
67}
68
69func TestHandleSyntheticPopupOpen_CleansUpStateWhenPopupIsBlocked(t *testing.T) {
70 parentWV := &WebView{
71 ctx: context.Background(),
72 id: port.WebViewID(28),
73 callbacks: &port.WebViewCallbacks{
74 OnCreate: func(port.PopupRequest) port.WebView {
75 return nil
76 },
77 },
78 }
79
80 parentWV.handleSyntheticPopupNavigate("popup-blocked", "https://example.com/blocked")
81 parentWV.handleSyntheticPopupOpen("https://example.com/blocked", "_blank", "popup-blocked", true, false)
82
83 require.Empty(t, parentWV.syntheticPopups)
84}
85
86func TestHandleSyntheticPopupClose_ClosesMappedPopup(t *testing.T) {
87 popupWV := &closeablePopupWebViewStub{MockWebView: portmocks.NewMockWebView(t)}
88 parentWV := &WebView{
89 ctx: context.Background(),
90 id: port.WebViewID(29),
91 syntheticPopups: map[string]*syntheticPopupState{
92 "popup-3": {WebView: popupWV},
93 },
94 }
95
96 parentWV.handleSyntheticPopupClose("popup-3")
97
98 require.True(t, popupWV.closed)
99 require.Empty(t, parentWV.syntheticPopups)
100}