@@ -244,6 +244,11 @@ define(function (require, exports, module) {
244244 }
245245 }
246246
247+ async function verifyIsPaidSubscriber ( expected , _testDescription ) {
248+ const isPaidSub = await EntitlementsExports . isPaidSubscriber ( ) ;
249+ expect ( isPaidSub ) . toBe ( expected ) ;
250+ }
251+
247252 async function verifyRawEntitlements ( expected , _testDescription ) {
248253 const rawEntitlements = await EntitlementsExports . getRawEntitlements ( ) ;
249254
@@ -395,6 +400,7 @@ define(function (require, exports, module) {
395400 // Verify entitlements API consistency for logged out state
396401 await verifyIsInProTrialEntitlement ( false , "no trial for logged out user with expired trial" ) ;
397402 await verifyTrialRemainingDaysEntitlement ( 0 , "no trial days remaining" ) ;
403+ await verifyIsPaidSubscriber ( false , "logged out user should not be a paid subscriber" ) ;
398404
399405 // Perform login
400406 await performFullLoginFlow ( ) ;
@@ -403,6 +409,7 @@ define(function (require, exports, module) {
403409 // Verify entitlements API consistency for logged in pro user
404410 await verifyIsInProTrialEntitlement ( false , "pro user should not be in trial" ) ;
405411 await verifyPlanEntitlements ( { isSubscriber : true , paidSubscriber : true } , "pro user should have paid subscriber plan" ) ;
412+ await verifyIsPaidSubscriber ( true , "pro user should be a paid subscriber" ) ;
406413
407414 // Check profile popup shows pro status (not trial)
408415 const $profileButton = testWindow . $ ( "#user-profile-button" ) ;
@@ -426,6 +433,7 @@ define(function (require, exports, module) {
426433 // Verify entitlements API consistency after logout
427434 await verifyRawEntitlements ( null , "no raw entitlements when logged out" ) ;
428435 await verifyIsInProTrialEntitlement ( false , "no trial after logout" ) ;
436+ await verifyIsPaidSubscriber ( false , "logged out pro user should not be a paid subscriber (no server entitlements)" ) ;
429437 } ) ;
430438
431439 it ( "should show trial branding for user without pro subscription (active trial)" , async function ( ) {
@@ -452,6 +460,7 @@ define(function (require, exports, module) {
452460 // Verify entitlements API consistency for logged in trial user
453461 await verifyIsInProTrialEntitlement ( true , "user should still be in trial after login" ) ;
454462 await verifyPlanEntitlements ( { isSubscriber : true , paidSubscriber : false } , "trial user should have isSubscriber true but paidSubscriber false" ) ;
463+ await verifyIsPaidSubscriber ( false , "trial user should not be a paid subscriber" ) ;
455464
456465 // Check profile popup shows trial status
457466 const $profileButton = testWindow . $ ( "#user-profile-button" ) ;
@@ -472,6 +481,7 @@ define(function (require, exports, module) {
472481 // Verify entitlements API consistency after logout (trial still active)
473482 await verifyIsInProTrialEntitlement ( true , "trial should persist after logout" ) ;
474483 await verifyRawEntitlements ( null , "no raw entitlements when logged out" ) ;
484+ await verifyIsPaidSubscriber ( false , "logged out trial user should not be a paid subscriber" ) ;
475485
476486 // Check profile popup still shows trial status
477487 $profileButton . trigger ( 'click' ) ;
@@ -496,6 +506,9 @@ define(function (require, exports, module) {
496506 // Verify pro branding appears
497507 await verifyProBranding ( true , "Pro branding to appear for pro user" ) ;
498508
509+ // Verify entitlements API consistency for logged in pro user with trial
510+ await verifyIsPaidSubscriber ( true , "pro user with trial should be a paid subscriber" ) ;
511+
499512 // Check profile popup shows pro status (not trial text)
500513 const $profileButton = testWindow . $ ( "#user-profile-button" ) ;
501514 $profileButton . trigger ( 'click' ) ;
@@ -513,6 +526,7 @@ define(function (require, exports, module) {
513526
514527 // Verify pro branding remains due to trial (even though subscription is gone)
515528 await verifyProBranding ( true , "Pro branding should remain after logout as trial user" ) ;
529+ await verifyIsPaidSubscriber ( false , "logged out user should not be a paid subscriber (no server entitlements)" ) ;
516530 $profileButton . trigger ( 'click' ) ;
517531 await popupToAppear ( SIGNIN_POPUP ) ;
518532 await verifyProfilePopupContent ( VIEW_TRIAL_DAYS_LEFT ,
@@ -538,6 +552,7 @@ define(function (require, exports, module) {
538552 await verifyIsInProTrialEntitlement ( false , "no trial for user with expired trial" ) ;
539553 await verifyTrialRemainingDaysEntitlement ( 0 , "no trial days remaining for expired trial" ) ;
540554 await verifyLiveEditEntitlement ( { activated : false } , "live edit deactivated for expired trial" ) ;
555+ await verifyIsPaidSubscriber ( false , "logged out free user should not be a paid subscriber" ) ;
541556
542557 // Perform login
543558 await performFullLoginFlow ( ) ;
@@ -550,6 +565,7 @@ define(function (require, exports, module) {
550565 "free plan for logged in user with expired trial" ) ;
551566 await verifyIsInProTrialEntitlement ( false , "still no trial after login" ) ;
552567 await verifyLiveEditEntitlement ( { activated : false } , "live edit still deactivated after login" ) ;
568+ await verifyIsPaidSubscriber ( false , "logged in free user should not be a paid subscriber" ) ;
553569
554570 // Check profile popup shows free plan status
555571 const $profileButton = testWindow . $ ( "#user-profile-button" ) ;
@@ -570,6 +586,7 @@ define(function (require, exports, module) {
570586 // Verify entitlements API consistency after logout
571587 await verifyRawEntitlements ( null , "no raw entitlements when logged out" ) ;
572588 await verifyIsInProTrialEntitlement ( false , "no trial after logout" ) ;
589+ await verifyIsPaidSubscriber ( false , "logged out free user should not be a paid subscriber" ) ;
573590
574591 // Check profile popup still shows free plan status as trial expired
575592 $profileButton . trigger ( 'click' ) ;
@@ -598,6 +615,7 @@ define(function (require, exports, module) {
598615 await verifyTrialRemainingDaysEntitlement ( 0 , "no trial days remaining" ) ;
599616 await verifyRawEntitlements ( null , "no raw entitlements when logged out" ) ;
600617 await verifyLiveEditEntitlement ( { activated : false } , "live edit deactivated with no trial" ) ;
618+ await verifyIsPaidSubscriber ( false , "logged out user with expired entitlements should not be a paid subscriber" ) ;
601619
602620 // Perform login
603621 await performFullLoginFlow ( ) ;
@@ -615,6 +633,7 @@ define(function (require, exports, module) {
615633 subscribeURL : testWindow . brackets . config . purchase_url ,
616634 upgradeToPlan : testWindow . brackets . config . main_pro_plan
617635 } , "live edit deactivated with fallback URLs for expired entitlements" ) ;
636+ await verifyIsPaidSubscriber ( false , "logged in user with expired entitlements should not be a paid subscriber" ) ;
618637
619638 // Check profile popup shows free plan status
620639 const $profileButton = testWindow . $ ( "#user-profile-button" ) ;
@@ -635,6 +654,7 @@ define(function (require, exports, module) {
635654 // Verify entitlements API consistency after logout
636655 await verifyRawEntitlements ( null , "no raw entitlements when logged out" ) ;
637656 await verifyIsInProTrialEntitlement ( false , "no trial after logout" ) ;
657+ await verifyIsPaidSubscriber ( false , "logged out user with expired entitlements should not be a paid subscriber" ) ;
638658
639659 // Check profile popup (signed out state)
640660 $profileButton . trigger ( 'click' ) ;
@@ -663,6 +683,7 @@ define(function (require, exports, module) {
663683 await verifyTrialRemainingDaysEntitlement ( 10 , "should have 10 trial days remaining" ) ;
664684 await verifyRawEntitlements ( null , "no raw entitlements when logged out" ) ;
665685 await verifyLiveEditEntitlement ( { activated : true } , "live edit activated via trial" ) ;
686+ await verifyIsPaidSubscriber ( false , "logged out trial user should not be a paid subscriber" ) ;
666687
667688 // Perform login
668689 await performFullLoginFlow ( ) ;
@@ -676,6 +697,7 @@ define(function (require, exports, module) {
676697 await verifyIsInProTrialEntitlement ( true , "user should still be in trial after login" ) ;
677698 await verifyTrialRemainingDaysEntitlement ( 10 , "trial days should remain 10 after login" ) ;
678699 await verifyLiveEditEntitlement ( { activated : true } , "live edit should be activated via trial override" ) ;
700+ await verifyIsPaidSubscriber ( false , "logged in trial user should not be a paid subscriber (expired entitlements)" ) ;
679701
680702 // Check profile popup shows trial status (not expired server entitlements)
681703 const $profileButton = testWindow . $ ( "#user-profile-button" ) ;
@@ -698,6 +720,7 @@ define(function (require, exports, module) {
698720 await verifyTrialRemainingDaysEntitlement ( 10 , "trial days should persist after logout" ) ;
699721 await verifyRawEntitlements ( null , "no raw entitlements when logged out" ) ;
700722 await verifyLiveEditEntitlement ( { activated : true } , "live edit still activated via trial after logout" ) ;
723+ await verifyIsPaidSubscriber ( false , "logged out trial user should not be a paid subscriber" ) ;
701724
702725 // Check profile popup still shows trial status
703726 $profileButton . trigger ( 'click' ) ;
@@ -752,6 +775,47 @@ define(function (require, exports, module) {
752775 }
753776 } ) ;
754777
778+ it ( "should test isPaidSubscriber API across different user states" , async function ( ) {
779+ console . log ( "isPaidSubscriber: Testing API across different user states" ) ;
780+
781+ try {
782+ // Test 1: Logged out user should not be a paid subscriber
783+ await cleanupTrialState ( ) ;
784+ expect ( LoginServiceExports . LoginService . isLoggedIn ( ) ) . toBe ( false ) ;
785+ await verifyIsPaidSubscriber ( false , "logged out user should not be a paid subscriber" ) ;
786+
787+ // Test 2: Free user (no subscription) should not be a paid subscriber
788+ setupProUserMock ( false ) ;
789+ await performFullLoginFlow ( ) ;
790+ expect ( LoginServiceExports . LoginService . isLoggedIn ( ) ) . toBe ( true ) ;
791+ await verifyIsPaidSubscriber ( false , "free user should not be a paid subscriber" ) ;
792+ await performFullLogoutFlow ( ) ;
793+
794+ // Test 3: Trial user (no paid subscription) should not be a paid subscriber
795+ setupProUserMock ( false ) ;
796+ await setupTrialState ( 10 ) ;
797+ await performFullLoginFlow ( ) ;
798+ expect ( LoginServiceExports . LoginService . isLoggedIn ( ) ) . toBe ( true ) ;
799+ await verifyIsPaidSubscriber ( false , "trial user should not be a paid subscriber" ) ;
800+ await performFullLogoutFlow ( ) ;
801+ await cleanupTrialState ( ) ;
802+
803+ // Test 4: Pro user with paid subscription should be a paid subscriber
804+ setupProUserMock ( true ) ;
805+ await performFullLoginFlow ( ) ;
806+ expect ( LoginServiceExports . LoginService . isLoggedIn ( ) ) . toBe ( true ) ;
807+ await verifyIsPaidSubscriber ( true , "pro user should be a paid subscriber" ) ;
808+
809+ // Test 5: After logout, should not be a paid subscriber (no server entitlements)
810+ await performFullLogoutFlow ( ) ;
811+ expect ( LoginServiceExports . LoginService . isLoggedIn ( ) ) . toBe ( false ) ;
812+ await verifyIsPaidSubscriber ( false , "logged out pro user should not be a paid subscriber" ) ;
813+
814+ } finally {
815+ await cleanupTrialState ( ) ;
816+ }
817+ } ) ;
818+
755819 if ( Phoenix . isNativeApp ) {
756820 it ( "should show device-licensed Pro branding and popup when not logged in" , async function ( ) {
757821 console . log ( "llgT: Starting device license Pro branding test" ) ;
@@ -797,6 +861,7 @@ define(function (require, exports, module) {
797861 ) ;
798862 await verifyIsInProTrialEntitlement ( false , "device license is not a trial" ) ;
799863 await verifyLiveEditEntitlement ( { activated : true } , "live edit activated via device license" ) ;
864+ await verifyIsPaidSubscriber ( false , "educational device license should not be a paid subscriber (not logged in)" ) ;
800865
801866 // Verify raw entitlements are present (not null)
802867 const rawEntitlements = await EntitlementsExports . getRawEntitlements ( ) ;
0 commit comments