@@ -967,6 +967,196 @@ describe('ContentClient', () => {
967967 } ) ;
968968 } ) ;
969969
970+ describe ( 'getEditURL' , ( ) => {
971+ let client ;
972+
973+ function getHlxConfig ( ) {
974+ return {
975+ ...hlxConfigGoogle ,
976+ rso : {
977+ owner : 'owner' ,
978+ site : 'repo' ,
979+ ref : 'main' ,
980+ } ,
981+ } ;
982+ }
983+
984+ const helixAdminToken = 'test-token' ;
985+ /** @type {SecretsManagerClient } */
986+ let secretsManagerClient ;
987+ let sendStub ;
988+
989+ beforeEach ( async ( ) => {
990+ secretsManagerClient = new SecretsManagerClient ( ) ;
991+ sendStub = sinon . stub ( secretsManagerClient , 'send' ) ;
992+ sendStub . resolves ( { SecretString : JSON . stringify ( { helix_admin_token : helixAdminToken } ) } ) ;
993+
994+ client = await ContentClient . createFrom (
995+ context ,
996+ { ...siteConfigGoogleDrive , getHlxConfig } ,
997+ secretsManagerClient ,
998+ ) ;
999+ } ) ;
1000+
1001+ it ( 'should return the edit URL on success' , async ( ) => {
1002+ const path = '/example/path' ;
1003+ const mockResponse = {
1004+ edit : { url : 'https://drive.google.com/document/d/abc123/edit' } ,
1005+ } ;
1006+
1007+ nock ( 'https://admin.hlx.page' , {
1008+ reqheaders : {
1009+ authorization : `token ${ helixAdminToken } ` ,
1010+ } ,
1011+ } )
1012+ . get ( '/status/owner/repo/main/example/path?editUrl=auto' )
1013+ . reply ( 200 , mockResponse ) ;
1014+
1015+ expect ( sendStub ) . to . have . been . calledWithMatch (
1016+ {
1017+ input : {
1018+ SecretId : resolveCustomerSecretsName ( baseUrl , context ) ,
1019+ } ,
1020+ } ,
1021+ ) ;
1022+ const result = await client . getEditURL ( path ) ;
1023+
1024+ expect ( result ) . to . equal ( 'https://drive.google.com/document/d/abc123/edit' ) ;
1025+ } ) ;
1026+
1027+ it ( 'should handle undefined edit URL in response' , async ( ) => {
1028+ const path = '/example-path' ;
1029+ const mockResponse = {
1030+ edit : null ,
1031+ } ;
1032+
1033+ nock ( 'https://admin.hlx.page' )
1034+ . get ( '/status/owner/repo/main/example-path?editUrl=auto' )
1035+ . reply ( 200 , mockResponse ) ;
1036+
1037+ const result = await client . getEditURL ( path ) ;
1038+
1039+ expect ( result ) . to . be . undefined ;
1040+ } ) ;
1041+
1042+ it ( 'should handle empty response object' , async ( ) => {
1043+ const path = '/example-path' ;
1044+
1045+ nock ( 'https://admin.hlx.page' )
1046+ . get ( '/status/owner/repo/main/example-path?editUrl=auto' )
1047+ . reply ( 200 , { } ) ;
1048+
1049+ const result = await client . getEditURL ( path ) ;
1050+
1051+ expect ( result ) . to . be . undefined ;
1052+ } ) ;
1053+
1054+ it ( 'should remove leading slashes from path in API call' , async ( ) => {
1055+ const path = '///multiple/leading/slashes' ;
1056+ const mockResponse = {
1057+ edit : { url : 'https://sharepoint.com/document/edit' } ,
1058+ } ;
1059+
1060+ const scope = nock ( 'https://admin.hlx.page' )
1061+ . get ( '/status/owner/repo/main/multiple/leading/slashes?editUrl=auto' )
1062+ . reply ( 200 , mockResponse ) ;
1063+
1064+ await client . getEditURL ( path ) ;
1065+
1066+ expect ( scope . isDone ( ) ) . to . be . true ;
1067+ } ) ;
1068+
1069+ it ( 'should include editUrl=auto query parameter' , async ( ) => {
1070+ const path = '/test-path' ;
1071+ const mockResponse = {
1072+ edit : { url : 'https://onedrive.com/document/edit' } ,
1073+ } ;
1074+
1075+ const scope = nock ( 'https://admin.hlx.page' )
1076+ . get ( ( uri ) => uri . includes ( 'editUrl=auto' ) )
1077+ . reply ( 200 , mockResponse ) ;
1078+
1079+ await client . getEditURL ( path ) ;
1080+
1081+ expect ( scope . isDone ( ) ) . to . be . true ;
1082+ } ) ;
1083+
1084+ it ( 'should throw an error on HTTP failure' , async ( ) => {
1085+ const path = '/example-path' ;
1086+
1087+ nock ( 'https://admin.hlx.page' )
1088+ . get ( '/status/owner/repo/main/example-path?editUrl=auto' )
1089+ . reply ( 404 , { message : 'Not Found' } ) ;
1090+
1091+ try {
1092+ await client . getEditURL ( path ) ;
1093+ expect . fail ( 'Should have thrown an error' ) ;
1094+ } catch ( err ) {
1095+ expect ( err . message ) . to . equal ( 'Failed to fetch document path for /example-path: {"message":"Not Found"}' ) ;
1096+ }
1097+ } ) ;
1098+
1099+ it ( 'should throw an error on network failure' , async ( ) => {
1100+ const path = '/example-path' ;
1101+
1102+ nock ( 'https://admin.hlx.page' )
1103+ . get ( '/status/owner/repo/main/example-path?editUrl=auto' )
1104+ . replyWithError ( 'Network error' ) ;
1105+
1106+ try {
1107+ await client . getEditURL ( path ) ;
1108+ expect . fail ( 'Should have thrown an error' ) ;
1109+ } catch ( err ) {
1110+ expect ( err . message ) . to . include ( 'Network error' ) ;
1111+ }
1112+ } ) ;
1113+
1114+ it ( 'should handle OneDrive edit URLs' , async ( ) => {
1115+ const path = '/onedrive-document' ;
1116+ const mockResponse = {
1117+ edit : { url : 'https://adobe.sharepoint.com/:w:/r/sites/test/_layouts/15/Doc.aspx?sourcedoc=123' } ,
1118+ } ;
1119+
1120+ nock ( 'https://admin.hlx.page' )
1121+ . get ( '/status/owner/repo/main/onedrive-document?editUrl=auto' )
1122+ . reply ( 200 , mockResponse ) ;
1123+
1124+ const result = await client . getEditURL ( path ) ;
1125+
1126+ expect ( result ) . to . equal ( 'https://adobe.sharepoint.com/:w:/r/sites/test/_layouts/15/Doc.aspx?sourcedoc=123' ) ;
1127+ } ) ;
1128+
1129+ it ( 'should handle Google Drive edit URLs' , async ( ) => {
1130+ const path = '/gdrive-document' ;
1131+ const mockResponse = {
1132+ edit : { url : 'https://docs.google.com/document/d/1abc_DEF-xyz/edit' } ,
1133+ } ;
1134+
1135+ nock ( 'https://admin.hlx.page' )
1136+ . get ( '/status/owner/repo/main/gdrive-document?editUrl=auto' )
1137+ . reply ( 200 , mockResponse ) ;
1138+
1139+ const result = await client . getEditURL ( path ) ;
1140+
1141+ expect ( result ) . to . equal ( 'https://docs.google.com/document/d/1abc_DEF-xyz/edit' ) ;
1142+ } ) ;
1143+
1144+ it ( 'should handle paths ending with /' , async ( ) => {
1145+ const path = '/example-path/' ;
1146+ const mockResponse = {
1147+ edit : { url : 'https://drive.google.com/document/d/test/edit' } ,
1148+ } ;
1149+
1150+ nock ( 'https://admin.hlx.page' )
1151+ . get ( '/status/owner/repo/main/example-path/?editUrl=auto' )
1152+ . reply ( 200 , mockResponse ) ;
1153+
1154+ const result = await client . getEditURL ( path ) ;
1155+
1156+ expect ( result ) . to . equal ( 'https://drive.google.com/document/d/test/edit' ) ;
1157+ } ) ;
1158+ } ) ;
1159+
9701160 describe ( 'updateImageAltText' , ( ) => {
9711161 let client ;
9721162 let mockDocument ;
0 commit comments