@@ -363,7 +363,7 @@ describe('server', () => {
363363
364364 it ( 'should throw when getting invalid mount' , done => {
365365 reconfigureServer ( { publicServerURL : 'blabla:/some' } ) . catch ( error => {
366- expect ( error ) . toEqual ( 'publicServerURL should be a valid HTTPS URL starting with https://' ) ;
366+ expect ( error ) . toEqual ( 'The option publicServerURL must be a valid URL starting with http:// or https://. ' ) ;
367367 done ( ) ;
368368 } ) ;
369369 } ) ;
@@ -685,4 +685,171 @@ describe('server', () => {
685685 } )
686686 . catch ( done . fail ) ;
687687 } ) ;
688+
689+ describe ( 'publicServerURL' , ( ) => {
690+ it ( 'should load publicServerURL' , async ( ) => {
691+ await reconfigureServer ( {
692+ publicServerURL : ( ) => 'https://example.com/1' ,
693+ } ) ;
694+
695+ await new Parse . Object ( 'TestObject' ) . save ( ) ;
696+
697+ const config = Config . get ( Parse . applicationId ) ;
698+ expect ( config . publicServerURL ) . toEqual ( 'https://example.com/1' ) ;
699+ } ) ;
700+
701+ it ( 'should load publicServerURL from Promise' , async ( ) => {
702+ await reconfigureServer ( {
703+ publicServerURL : ( ) => Promise . resolve ( 'https://example.com/1' ) ,
704+ } ) ;
705+
706+ await new Parse . Object ( 'TestObject' ) . save ( ) ;
707+
708+ const config = Config . get ( Parse . applicationId ) ;
709+ expect ( config . publicServerURL ) . toEqual ( 'https://example.com/1' ) ;
710+ } ) ;
711+
712+ it ( 'should handle publicServerURL function throwing error' , async ( ) => {
713+ const errorMessage = 'Failed to get public server URL' ;
714+ await reconfigureServer ( {
715+ publicServerURL : ( ) => {
716+ throw new Error ( errorMessage ) ;
717+ } ,
718+ } ) ;
719+
720+ // The error should occur when trying to save an object (which triggers loadKeys in middleware)
721+ await expectAsync (
722+ new Parse . Object ( 'TestObject' ) . save ( )
723+ ) . toBeRejected ( ) ;
724+ } ) ;
725+
726+ it ( 'should handle publicServerURL Promise rejection' , async ( ) => {
727+ const errorMessage = 'Async fetch of public server URL failed' ;
728+ await reconfigureServer ( {
729+ publicServerURL : ( ) => Promise . reject ( new Error ( errorMessage ) ) ,
730+ } ) ;
731+
732+ // The error should occur when trying to save an object (which triggers loadKeys in middleware)
733+ await expectAsync (
734+ new Parse . Object ( 'TestObject' ) . save ( )
735+ ) . toBeRejected ( ) ;
736+ } ) ;
737+
738+ it ( 'executes publicServerURL function on every config access' , async ( ) => {
739+ let counter = 0 ;
740+ await reconfigureServer ( {
741+ publicServerURL : ( ) => {
742+ counter ++ ;
743+ return `https://example.com/${ counter } ` ;
744+ } ,
745+ } ) ;
746+
747+ // First request - should call the function
748+ await new Parse . Object ( 'TestObject' ) . save ( ) ;
749+ const config1 = Config . get ( Parse . applicationId ) ;
750+ expect ( config1 . publicServerURL ) . toEqual ( 'https://example.com/1' ) ;
751+ expect ( counter ) . toEqual ( 1 ) ;
752+
753+ // Second request - should call the function again
754+ await new Parse . Object ( 'TestObject' ) . save ( ) ;
755+ const config2 = Config . get ( Parse . applicationId ) ;
756+ expect ( config2 . publicServerURL ) . toEqual ( 'https://example.com/2' ) ;
757+ expect ( counter ) . toEqual ( 2 ) ;
758+
759+ // Third request - should call the function again
760+ await new Parse . Object ( 'TestObject' ) . save ( ) ;
761+ const config3 = Config . get ( Parse . applicationId ) ;
762+ expect ( config3 . publicServerURL ) . toEqual ( 'https://example.com/3' ) ;
763+ expect ( counter ) . toEqual ( 3 ) ;
764+ } ) ;
765+
766+ it ( 'executes publicServerURL function on every password reset email' , async ( ) => {
767+ let counter = 0 ;
768+ const emailCalls = [ ] ;
769+
770+ const emailAdapter = MockEmailAdapterWithOptions ( {
771+ sendPasswordResetEmail : ( { link } ) => {
772+ emailCalls . push ( link ) ;
773+ return Promise . resolve ( ) ;
774+ } ,
775+ } ) ;
776+
777+ await reconfigureServer ( {
778+ appName : 'test-app' ,
779+ publicServerURL : ( ) => {
780+ counter ++ ;
781+ return `https://example.com/${ counter } ` ;
782+ } ,
783+ emailAdapter,
784+ } ) ;
785+
786+ // Create a user
787+ const user = new Parse . User ( ) ;
788+ user . setUsername ( 'user' ) ;
789+ user . setPassword ( 'pass' ) ;
790+ user . setEmail ( 'user@example.com' ) ;
791+ await user . signUp ( ) ;
792+
793+ // Should use first publicServerURL
794+ const counterBefore1 = counter ;
795+ await Parse . User . requestPasswordReset ( 'user@example.com' ) ;
796+ await jasmine . timeout ( ) ;
797+ expect ( emailCalls . length ) . toEqual ( 1 ) ;
798+ expect ( emailCalls [ 0 ] ) . toContain ( `https://example.com/${ counterBefore1 + 1 } ` ) ;
799+ expect ( counter ) . toBeGreaterThanOrEqual ( 2 ) ;
800+
801+ // Should use updated publicServerURL
802+ const counterBefore2 = counter ;
803+ await Parse . User . requestPasswordReset ( 'user@example.com' ) ;
804+ await jasmine . timeout ( ) ;
805+ expect ( emailCalls . length ) . toEqual ( 2 ) ;
806+ expect ( emailCalls [ 1 ] ) . toContain ( `https://example.com/${ counterBefore2 + 1 } ` ) ;
807+ expect ( counterBefore2 ) . toBeGreaterThan ( counterBefore1 ) ;
808+ } ) ;
809+
810+ it ( 'executes publicServerURL function on every verification email' , async ( ) => {
811+ let counter = 0 ;
812+ const emailCalls = [ ] ;
813+
814+ const emailAdapter = MockEmailAdapterWithOptions ( {
815+ sendVerificationEmail : ( { link } ) => {
816+ emailCalls . push ( link ) ;
817+ return Promise . resolve ( ) ;
818+ } ,
819+ } ) ;
820+
821+ await reconfigureServer ( {
822+ appName : 'test-app' ,
823+ verifyUserEmails : true ,
824+ publicServerURL : ( ) => {
825+ counter ++ ;
826+ return `https://example.com/${ counter } ` ;
827+ } ,
828+ emailAdapter,
829+ } ) ;
830+
831+ // Should trigger verification email with first publicServerURL
832+ const counterBefore1 = counter ;
833+ const user1 = new Parse . User ( ) ;
834+ user1 . setUsername ( 'user1' ) ;
835+ user1 . setPassword ( 'pass1' ) ;
836+ user1 . setEmail ( 'user1@example.com' ) ;
837+ await user1 . signUp ( ) ;
838+ await jasmine . timeout ( ) ;
839+ expect ( emailCalls . length ) . toEqual ( 1 ) ;
840+ expect ( emailCalls [ 0 ] ) . toContain ( `https://example.com/${ counterBefore1 + 1 } ` ) ;
841+
842+ // Should trigger verification email with updated publicServerURL
843+ const counterBefore2 = counter ;
844+ const user2 = new Parse . User ( ) ;
845+ user2 . setUsername ( 'user2' ) ;
846+ user2 . setPassword ( 'pass2' ) ;
847+ user2 . setEmail ( 'user2@example.com' ) ;
848+ await user2 . signUp ( ) ;
849+ await jasmine . timeout ( ) ;
850+ expect ( emailCalls . length ) . toEqual ( 2 ) ;
851+ expect ( emailCalls [ 1 ] ) . toContain ( `https://example.com/${ counterBefore2 + 1 } ` ) ;
852+ expect ( counterBefore2 ) . toBeGreaterThan ( counterBefore1 ) ;
853+ } ) ;
854+ } ) ;
688855} ) ;
0 commit comments