Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ codeunit 9101 "SharePoint Client Impl."
Request.Add('Title', ListTitle);

SharePointHttpContent.FromJson(Request);
SharePointHttpContent.SetRequestDigest(GetRequestDigest(SharePointUriBuilder.GetHost()));
SharePointHttpContent.SetRequestDigest(GetRequestDigest(SharePointUriBuilder.GetSiteUrl()));

SharePointRequestHelper.SetAuthorization(Authorization);
SharePointOperationResponse := SharePointRequestHelper.Post(SharePointUriBuilder, SharePointHttpContent);
Expand Down Expand Up @@ -399,7 +399,7 @@ codeunit 9101 "SharePoint Client Impl."
Request.Add('Title', ListItemTitle);

SharePointHttpContent.FromJson(Request);
SharePointHttpContent.SetRequestDigest(GetRequestDigest(SharePointUriBuilder.GetHost()));
SharePointHttpContent.SetRequestDigest(GetRequestDigest(SharePointUriBuilder.GetSiteUrl()));

SharePointRequestHelper.SetAuthorization(Authorization);
SharePointOperationResponse := SharePointRequestHelper.Post(SharePointUriBuilder, SharePointHttpContent);
Expand Down Expand Up @@ -427,7 +427,7 @@ codeunit 9101 "SharePoint Client Impl."
Request.Add('Title', ListItemTitle);

SharePointHttpContent.FromJson(Request);
SharePointHttpContent.SetRequestDigest(GetRequestDigest(SharePointUriBuilder.GetHost()));
SharePointHttpContent.SetRequestDigest(GetRequestDigest(SharePointUriBuilder.GetSiteUrl()));

SharePointRequestHelper.SetAuthorization(Authorization);
SharePointOperationResponse := SharePointRequestHelper.Post(SharePointUriBuilder, SharePointHttpContent);
Expand Down Expand Up @@ -640,7 +640,7 @@ codeunit 9101 "SharePoint Client Impl."
Request.Add('ServerRelativeUrl', ServerRelativeUrl);

SharePointHttpContent.FromJson(Request);
SharePointHttpContent.SetRequestDigest(GetRequestDigest(SharePointUriBuilder.GetHost()));
SharePointHttpContent.SetRequestDigest(GetRequestDigest(SharePointUriBuilder.GetSiteUrl()));

SharePointRequestHelper.SetAuthorization(Authorization);
SharePointOperationResponse := SharePointRequestHelper.Post(SharePointUriBuilder, SharePointHttpContent);
Expand Down Expand Up @@ -786,7 +786,7 @@ codeunit 9101 "SharePoint Client Impl."

SharePointHttpContent.GetContent().ReadAs(Txt);

SharePointHttpContent.SetRequestDigest(GetRequestDigest(SharePointUriBuilder.GetHost()));
SharePointHttpContent.SetRequestDigest(GetRequestDigest(SharePointUriBuilder.GetSiteUrl()));
SharePointHttpContent.SetXHttpMethod('MERGE');
SharePointHttpContent.SetIfMatch('*');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ codeunit 9110 "SharePoint Uri Builder"
exit(NewUri.GetHost());
end;

procedure GetSiteUrl(): Text
begin
exit(ServerName.TrimStart('/').TrimEnd('/'));
end;

procedure AddQueryParameter(ParameterName: Text; ParameterValue: Text)
begin
QueryParameters.Add(ParameterName, ParameterValue);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ codeunit 132973 "SharePoint Test Library"
{
EventSubscriberInstance = Manual;

var
LastContextInfoRequestUri: Text;

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SharePoint Request Helper", 'OnBeforeSendRequest', '', false, false)]
local procedure RunOnBeforeSendRequest(HttpRequestMessage: HttpRequestMessage; var SharePointOperationResponse: Codeunit "SharePoint Operation Response"; var IsHandled: Boolean; Method: Text)
var
Expand All @@ -33,6 +36,7 @@ codeunit 132973 "SharePoint Test Library"
Uri := LocalUri.UnescapeDataString(Uri);

if Uri.EndsWith('/_api/contextinfo/') then begin
LastContextInfoRequestUri := Uri;
GetContextDigestTestResponse(SharePointOperationResponse, BaseUrl, ParentUrl);
exit;
end;
Expand Down Expand Up @@ -109,6 +113,15 @@ codeunit 132973 "SharePoint Test Library"
Error('No matching test response for %1', Uri);
end;

/// <summary>
/// Returns the full request URI of the last "_api/contextinfo" request digest call that was intercepted by this test library.
/// </summary>
/// <returns>The full, unescaped request URI, or an empty string if no request digest call has been made yet.</returns>
procedure GetLastContextInfoRequestUri(): Text
begin
exit(LastContextInfoRequestUri);
end;

local procedure GetContextDigestTestResponse(var SharePointOperationResponse: Codeunit "SharePoint Operation Response"; BaseUrl: Text; ParentUrl: Text)
var
HttpHeaders: HttpHeaders;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,45 @@ codeunit 132970 "SharePoint Client Test"
Assert.IsTrue(TempSharePointFolder.OdataId.EndsWith('_api/Web/GetFolderByServerRelativePath(decodedurl=''' + ParentUrl + '/Lists/Test Documents/Attachments/TestSubfolder'')'), StrSubstNo('Different %1 value expected', TempSharePointFolder.FieldCaption("OdataId")));
Assert.AreEqual('SP.Folder', TempSharePointFolder.OdataType, StrSubstNo('Different %1 value expected', TempSharePointFolder.FieldCaption("OdataType")));
Assert.IsTrue(TempSharePointFolder."Server Relative Url".EndsWith('/Lists/Test Documents/Attachments/TestSubfolder'), StrSubstNo('Different %1 value expected', TempSharePointFolder.FieldCaption("Server Relative Url")));

// [THEN] The request digest ("_api/contextinfo") call was made against the site-scoped URL, not the tenant root
Assert.AreEqual('https://' + BaseUrl + '/_api/contextinfo/', SharePointTestLibrary.GetLastContextInfoRequestUri(), 'Request digest should be requested from the site-scoped URL, not the tenant root.');
end;

[Test]
procedure TestCreateListRequestDigestUsesSiteScopedUrl()
var
TempSharePointList: Record "SharePoint List" temporary;
IsSuccess: Boolean;
begin
// [Scenario] CreateList requests the digest from the site-scoped URL, not the tenant root, so it works under Sites.Selected
Initialize();

// [WHEN] CreateList is called for a site-scoped account (BaseUrl contains a "/sites/<site>" segment)
IsSuccess := SharePointClient.CreateList('Test Sample List Title', 'Test Sample List Description', TempSharePointList);
Assert.AreEqual(true, IsSuccess, 'Successfull operation expected');

// [THEN] The request digest ("_api/contextinfo") call was made against the site-scoped URL, not the tenant root
Assert.AreEqual('https://' + BaseUrl + '/_api/contextinfo/', SharePointTestLibrary.GetLastContextInfoRequestUri(), 'Request digest should be requested from the site-scoped URL, not the tenant root.');
end;

[Test]
procedure TestCreateListItemRequestDigestUsesSiteScopedUrl()
var
TempSharePointListItem: Record "SharePoint List Item" temporary;
Guid: Guid;
IsSuccess: Boolean;
begin
// [Scenario] CreateListItem requests the digest from the site-scoped URL, not the tenant root, so it works under Sites.Selected
Initialize();
Evaluate(Guid, '{854D7F21-1C6A-43AB-A081-20404894B449}');

// [WHEN] CreateListItem is called for a site-scoped account (BaseUrl contains a "/sites/<site>" segment)
IsSuccess := SharePointClient.CreateListItem(Guid, 'SP.Data.My_x0020_Test_x0020_DocumentsListItem', 'Test List Item', TempSharePointListItem);
Assert.AreEqual(true, IsSuccess, 'Successfull operation expected');

// [THEN] The request digest ("_api/contextinfo") call was made against the site-scoped URL, not the tenant root
Assert.AreEqual('https://' + BaseUrl + '/_api/contextinfo/', SharePointTestLibrary.GetLastContextInfoRequestUri(), 'Request digest should be requested from the site-scoped URL, not the tenant root.');
end;

[Test]
Expand Down
Loading