@@ -30,14 +30,15 @@ define(function (require, exports, module) {
3030 LoginService ,
3131 ProDialogs ,
3232 originalAppConfig ,
33+ originalFetch ,
3334 mockNow = 1000000000000 ; // Fixed timestamp for consistent testing
3435
3536 beforeAll ( async function ( ) {
3637 testWindow = await SpecRunnerUtils . createTestWindowAndRun ( ) ;
3738
3839 // Access modules from test window
39- LoginService = testWindow . _test_login_exports ;
40- ProDialogs = testWindow . _test_login_exports . ProDialogs ;
40+ LoginService = testWindow . _test_promo_login_exports ;
41+ ProDialogs = testWindow . _test_promo_login_exports . ProDialogs ;
4142
4243 // Debug: Check what's available in the exports
4344 console . log ( 'Debug: Available exports:' , Object . keys ( LoginService ) ) ;
@@ -52,6 +53,12 @@ define(function (require, exports, module) {
5253 throw new Error ( 'setDateNowFn not available in test exports' ) ;
5354 }
5455
56+ // Set up fetch mocking for pro dialogs
57+ if ( testWindow . _test_pro_dlg_login_exports && testWindow . _test_pro_dlg_login_exports . setFetchFn ) {
58+ // Store reference for later restoration
59+ originalFetch = testWindow . fetch ;
60+ }
61+
5562 // Store original config and mock AppConfig for tests
5663 originalAppConfig = testWindow . AppConfig ;
5764 testWindow . AppConfig = {
@@ -66,9 +73,15 @@ define(function (require, exports, module) {
6673 testWindow . AppConfig = originalAppConfig ;
6774 }
6875
76+ // Restore original fetch if it was mocked
77+ if ( originalFetch && testWindow . _test_pro_dlg_login_exports && testWindow . _test_pro_dlg_login_exports . setFetchFn ) {
78+ testWindow . _test_pro_dlg_login_exports . setFetchFn ( originalFetch ) ;
79+ }
80+
6981 testWindow = null ;
7082 LoginService = null ;
7183 ProDialogs = null ;
84+ originalFetch = null ;
7285 await SpecRunnerUtils . closeTestWindow ( ) ;
7386 } , 30000 ) ;
7487
@@ -248,7 +261,7 @@ define(function (require, exports, module) {
248261
249262 describe ( "Trial Expiration" , function ( ) {
250263
251- it ( "should show promo ended dialog when trial expires (not logged in)" , async function ( ) {
264+ async function setupExpiredTrialAndActivate ( ) {
252265 const expiredTrial = {
253266 proVersion : "3.1.0" , // Same version as current to trigger ended dialog
254267 endDate : mockNow - LoginService . TRIAL_CONSTANTS . MS_PER_DAY , // Expired yesterday
@@ -269,30 +282,67 @@ define(function (require, exports, module) {
269282 expect ( updatedTrialData . proVersion ) . toBe ( "3.1.0" ) ; // Should preserve original version
270283 expect ( updatedTrialData . endDate ) . toBe ( expiredTrial . endDate ) ; // Should preserve end date
271284
272- // Wait for modal dialog and verify it's the "ended" dialog
285+ return { expiredTrial, updatedTrialData } ;
286+ }
287+
288+ it ( "should show local promo ended dialog when trial expires (offline/fetch fails)" , async function ( ) {
289+ // Mock fetch to fail (network error)
290+ if ( testWindow . _test_pro_dlg_login_exports && testWindow . _test_pro_dlg_login_exports . setFetchFn ) {
291+ testWindow . _test_pro_dlg_login_exports . setFetchFn ( ( ) => {
292+ return Promise . reject ( new Error ( 'Network error' ) ) ;
293+ } ) ;
294+ }
295+
296+ // Set up expired trial and activate
297+ await setupExpiredTrialAndActivate ( ) ;
298+
299+ // Wait for modal dialog and verify it's the local "ended" dialog
273300 await testWindow . __PR . waitForModalDialog ( ".modal" ) ;
274301 const modalContent = testWindow . $ ( '.modal' ) ;
275302 expect ( modalContent . length ) . toBeGreaterThan ( 0 ) ;
276303
277- // Check if it's the "ended" dialog (different text than upgrade )
304+ // Verify it's the local dialog (has text content, no iframe )
278305 const dialogText = modalContent . text ( ) ;
279306 expect ( dialogText ) . toContain ( 'Phoenix Pro' ) ;
280307 expect ( dialogText ) . toContain ( 'Trial has ended' ) ;
281308
282- // Close the dialog, so here trial expiration has 2 dialogs, either an offline dialog or online depends
283- // on config. we just close em blindly. depending on config of
284- // `${brackets.config.promotions_url}app/config.json`. here we just close both blindly;
285- try {
286- //
287- testWindow . __PR . clickDialogButtonID ( "secondaryButton" ) ;
288- } catch ( e ) {
289- // ignored
290- }
291- try {
292- testWindow . __PR . clickDialogButtonID ( testWindow . __PR . Dialogs . DIALOG_BTN_CANCEL ) ;
293- } catch ( e ) {
294- // ignored
309+ // Verify NO iframe present (local dialog)
310+ const iframes = modalContent . find ( 'iframe' ) ;
311+ expect ( iframes . length ) . toBe ( 0 ) ;
312+
313+ // Close local dialog - simpler button structure
314+ testWindow . __PR . clickDialogButtonID ( "secondaryButton" ) ;
315+ await testWindow . __PR . waitForModalDialogClosed ( ".modal" ) ;
316+ } ) ;
317+
318+ it ( "should show remote promo ended dialog when trial expires (online)" , async function ( ) {
319+ // Mock fetch to succeed with remote config
320+ if ( testWindow . _test_pro_dlg_login_exports && testWindow . _test_pro_dlg_login_exports . setFetchFn ) {
321+ testWindow . _test_pro_dlg_login_exports . setFetchFn ( ( ) => {
322+ return Promise . resolve ( {
323+ ok : true ,
324+ json : ( ) => Promise . resolve ( {
325+ upsell_after_trial_url : "https://phcode.io" ,
326+ upsell_purchase_url : "https://phcode.dev/pricing"
327+ } )
328+ } ) ;
329+ } ) ;
295330 }
331+
332+ // Set up expired trial and activate
333+ await setupExpiredTrialAndActivate ( ) ;
334+
335+ // Wait for modal dialog and verify it's the remote dialog
336+ await testWindow . __PR . waitForModalDialog ( ".modal" ) ;
337+ const modalContent = testWindow . $ ( '.modal' ) ;
338+ expect ( modalContent . length ) . toBeGreaterThan ( 0 ) ;
339+
340+ // Verify it's the remote dialog (contains iframe)
341+ const iframes = modalContent . find ( 'iframe' ) ;
342+ expect ( iframes . length ) . toBeGreaterThan ( 0 ) ;
343+
344+ // Close remote dialog - may have complex button structure
345+ testWindow . __PR . clickDialogButtonID ( testWindow . __PR . Dialogs . DIALOG_BTN_CANCEL ) ;
296346 await testWindow . __PR . waitForModalDialogClosed ( ".modal" ) ;
297347 } ) ;
298348
0 commit comments