diff --git a/Src/Notion.Client/Api/ApiEndpoints.cs b/Src/Notion.Client/Api/ApiEndpoints.cs index ed531c0b..886abf78 100644 --- a/Src/Notion.Client/Api/ApiEndpoints.cs +++ b/Src/Notion.Client/Api/ApiEndpoints.cs @@ -27,6 +27,7 @@ public static class PagesApiUrls { public static string Create() => $"/v1/pages"; public static string Retrieve(string pageId) => $"/v1/pages/{pageId}"; + public static string Update(string pageId) => $"/v1/pages/{pageId}"; public static string UpdateProperties(string pageId) => $"/v1/pages/{pageId}"; } diff --git a/Src/Notion.Client/Api/Pages/IPagesClient.cs b/Src/Notion.Client/Api/Pages/IPagesClient.cs index fe179ff2..932d3fe9 100644 --- a/Src/Notion.Client/Api/Pages/IPagesClient.cs +++ b/Src/Notion.Client/Api/Pages/IPagesClient.cs @@ -12,5 +12,14 @@ Task UpdatePropertiesAsync( string pageId, IDictionary updatedProperties ); + + /// + /// Updates page property values for the specified page. + /// Properties that are not set via the properties parameter will remain unchanged. + /// + /// + /// + /// Updated page. + Task UpdateAsync(string pageId, PagesUpdateParameters pagesUpdateParameters); } } diff --git a/Src/Notion.Client/Api/Pages/PagesClient.cs b/Src/Notion.Client/Api/Pages/PagesClient.cs index ecf3a5f6..2b7adf76 100644 --- a/Src/Notion.Client/Api/Pages/PagesClient.cs +++ b/Src/Notion.Client/Api/Pages/PagesClient.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Threading.Tasks; using static Notion.Client.ApiEndpoints; @@ -24,6 +25,15 @@ public async Task RetrieveAsync(string pageId) return await _client.GetAsync(url); } + public async Task UpdateAsync(string pageId, PagesUpdateParameters pagesUpdateParameters) + { + var url = PagesApiUrls.Update(pageId); + var body = (IPagesUpdateBodyParameters)pagesUpdateParameters; + + return await _client.PatchAsync(url, body); + } + + [Obsolete("This method is obsolute. Use UpdateAsync instead. This API will be removed in future release")] public async Task UpdatePropertiesAsync( string pageId, IDictionary updatedProperties) diff --git a/Src/Notion.Client/Api/Pages/RequestParams/IPagesUpdateBodyParameters.cs b/Src/Notion.Client/Api/Pages/RequestParams/IPagesUpdateBodyParameters.cs new file mode 100644 index 00000000..12a8cc12 --- /dev/null +++ b/Src/Notion.Client/Api/Pages/RequestParams/IPagesUpdateBodyParameters.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace Notion.Client +{ + public interface IPagesUpdateBodyParameters + { + bool Archived { get; set; } + IDictionary Properties { get; set; } + } +} diff --git a/Src/Notion.Client/Api/Pages/RequestParams/PagesUpdateParameters.cs b/Src/Notion.Client/Api/Pages/RequestParams/PagesUpdateParameters.cs new file mode 100644 index 00000000..db35d093 --- /dev/null +++ b/Src/Notion.Client/Api/Pages/RequestParams/PagesUpdateParameters.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace Notion.Client +{ + public class PagesUpdateParameters : IPagesUpdateBodyParameters + { + public bool Archived { get; set; } + public IDictionary Properties { get; set; } + } +} diff --git a/Test/Notion.UnitTests/Notion.UnitTests.csproj b/Test/Notion.UnitTests/Notion.UnitTests.csproj index 006a8b84..87f6a000 100644 --- a/Test/Notion.UnitTests/Notion.UnitTests.csproj +++ b/Test/Notion.UnitTests/Notion.UnitTests.csproj @@ -36,6 +36,9 @@ Always + + Always + Always diff --git a/Test/Notion.UnitTests/PagesClientTests.cs b/Test/Notion.UnitTests/PagesClientTests.cs index e95e3feb..04957bef 100644 --- a/Test/Notion.UnitTests/PagesClientTests.cs +++ b/Test/Notion.UnitTests/PagesClientTests.cs @@ -125,5 +125,70 @@ public async Task PageObjectShouldHaveUrlProperty() page.Url.Should().Be("https://www.notion.so/Avocado-251d2b5f268c4de2afe9c71ff92ca95c"); } + + [Fact] + public async Task UpdatePageAsync() + { + var pageId = "251d2b5f-268c-4de2-afe9-c71ff92ca95c"; + var path = ApiEndpoints.PagesApiUrls.UpdateProperties(pageId); + + var jsonData = await File.ReadAllTextAsync("data/pages/UpdatePagePropertiesResponse.json"); + + Server.Given(CreatePatchRequestBuilder(path)) + .RespondWith( + Response.Create() + .WithStatusCode(200) + .WithBody(jsonData) + ); + + var pagesUpdateParameters = new PagesUpdateParameters + { + Properties = new Dictionary() + { + { "In stock", new CheckboxPropertyValue() { Checkbox = true } } + } + }; + + var page = await _client.UpdateAsync(pageId, pagesUpdateParameters); + + page.Id.Should().Be(pageId); + page.IsArchived.Should().BeFalse(); + page.Properties.Should().HaveCount(2); + var updatedProperty = page.Properties.First(x => x.Key == "In stock"); + ((CheckboxPropertyValue)updatedProperty.Value).Checkbox.Should().BeTrue(); + } + + [Fact] + public async Task ArchivePageAsync() + { + var pageId = "251d2b5f-268c-4de2-afe9-c71ff92ca95c"; + var path = ApiEndpoints.PagesApiUrls.UpdateProperties(pageId); + + var jsonData = await File.ReadAllTextAsync("data/pages/ArchivePageResponse.json"); + + Server.Given(CreatePatchRequestBuilder(path)) + .RespondWith( + Response.Create() + .WithStatusCode(200) + .WithBody(jsonData) + ); + + var pagesUpdateParameters = new PagesUpdateParameters + { + Archived = true, + Properties = new Dictionary() + { + { "In stock", new CheckboxPropertyValue() { Checkbox = true } } + } + }; + + var page = await _client.UpdateAsync(pageId, pagesUpdateParameters); + + page.Id.Should().Be(pageId); + page.IsArchived.Should().BeTrue(); + page.Properties.Should().HaveCount(2); + var updatedProperty = page.Properties.First(x => x.Key == "In stock"); + ((CheckboxPropertyValue)updatedProperty.Value).Checkbox.Should().BeTrue(); + } } } diff --git a/Test/Notion.UnitTests/data/pages/ArchivePageResponse.json b/Test/Notion.UnitTests/data/pages/ArchivePageResponse.json new file mode 100644 index 00000000..2f9af7c6 --- /dev/null +++ b/Test/Notion.UnitTests/data/pages/ArchivePageResponse.json @@ -0,0 +1,38 @@ +{ + "object": "page", + "id": "251d2b5f-268c-4de2-afe9-c71ff92ca95c", + "created_time": "2020-03-17T19:10:04.968Z", + "last_edited_time": "2020-03-17T21:49:37.913Z", + "archived": true, + "url": "https://www.notion.so/Test-251d2b5f268c4de2afe9c71ff92ca95c", + "properties": { + "In stock": { + "id": "{>U;", + "type": "checkbox", + "checkbox": true + }, + "Name": { + "id": "title", + "type": "title", + "title": [ + { + "type": "text", + "text": { + "content": "Test", + "link": null + }, + "annotations": { + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "code": false, + "color": "default" + }, + "plain_text": "Test", + "href": null + } + ] + } + } +} \ No newline at end of file