Skip to content

Commit 8f8f4b9

Browse files
Merge pull request #101 from notion-dotnet/feature/79-add-support-to-update-a-block
Add support to update a block 💖
2 parents a1d801f + 52fa7a2 commit 8f8f4b9

18 files changed

+203
-7
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,9 @@ var complexFiler = new CompoundFilter(
103103
- [x] Retrieve a page
104104
- [x] Create a page
105105
- [x] Update page
106-
- [ ] Blocks
106+
- [x] Blocks
107107
- [x] Retrieve a block
108-
- [ ] Update a block
108+
- [x] Update a block
109109
- [x] Retrieve block children
110110
- [x] Append block children
111111
- [x] Users

Src/Notion.Client/Api/ApiEndpoints.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public static class UsersApiUrls
2020
public static class BlocksApiUrls
2121
{
2222
public static string Retrieve(string blockId) => $"/v1/blocks/{blockId}";
23+
public static string Update(string blockId) => $"/v1/blocks/{blockId}";
2324
public static string RetrieveChildren(string blockId) => $"/v1/blocks/{blockId}/children";
2425
public static string AppendChildren(string blockId) => $"/v1/blocks/{blockId}/children";
2526
}

Src/Notion.Client/Api/Blocks/BlocksClient.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public async Task<Block> AppendChildrenAsync(string blockId, BlocksAppendChildre
4848
return await _client.PatchAsync<Block>(url, body);
4949
}
5050

51-
public async Task<Block> Retrieve(string blockId)
51+
public async Task<Block> RetrieveAsync(string blockId)
5252
{
5353
if (string.IsNullOrWhiteSpace(blockId))
5454
{
@@ -59,5 +59,17 @@ public async Task<Block> Retrieve(string blockId)
5959

6060
return await _client.GetAsync<Block>(url);
6161
}
62+
63+
public async Task<Block> UpdateAsync(string blockId, IUpdateBlock updateBlock)
64+
{
65+
if (string.IsNullOrWhiteSpace(blockId))
66+
{
67+
throw new ArgumentNullException(nameof(blockId));
68+
}
69+
70+
var url = BlocksApiUrls.Update(blockId);
71+
72+
return await _client.PatchAsync<Block>(url, updateBlock);
73+
}
6274
}
6375
}

Src/Notion.Client/Api/Blocks/IBlocksClient.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,15 @@ public interface IBlocksClient
99
/// </summary>
1010
/// <param name="blockId"></param>
1111
/// <returns>Block</returns>
12-
Task<Block> Retrieve(string blockId);
12+
Task<Block> RetrieveAsync(string blockId);
13+
14+
/// <summary>
15+
/// Updates the content for the specified block_id based on the block type.
16+
/// </summary>
17+
/// <param name="blockId"></param>
18+
/// <param name="updateBlock"></param>
19+
/// <returns>Block</returns>
20+
Task<Block> UpdateAsync(string blockId, IUpdateBlock updateBlock);
1321

1422
Task<PaginatedList<Block>> RetrieveChildrenAsync(string blockId, BlocksRetrieveChildrenParameters parameters = null);
1523
Task<Block> AppendChildrenAsync(string blockId, BlocksAppendChildrenParameters parameters = null);
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using Newtonsoft.Json;
2+
3+
namespace Notion.Client
4+
{
5+
public class BulletedListItemUpdateBlock : IUpdateBlock
6+
{
7+
[JsonProperty("bulleted_list_item")]
8+
public TextContentUpdate BulletedListItem { get; set; }
9+
}
10+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using Newtonsoft.Json;
2+
3+
namespace Notion.Client
4+
{
5+
public class HeadingOneUpdateBlock : IUpdateBlock
6+
{
7+
[JsonProperty("heading_1")]
8+
public TextContentUpdate Heading_1 { get; set; }
9+
}
10+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using Newtonsoft.Json;
2+
3+
namespace Notion.Client
4+
{
5+
public class HeadingThreeeUpdateBlock : IUpdateBlock
6+
{
7+
[JsonProperty("heading_3")]
8+
public TextContentUpdate Heading_3 { get; set; }
9+
}
10+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using Newtonsoft.Json;
2+
3+
namespace Notion.Client
4+
{
5+
public class HeadingTwoUpdateBlock : IUpdateBlock
6+
{
7+
[JsonProperty("heading_2")]
8+
public TextContentUpdate Heading_2 { get; set; }
9+
}
10+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace Notion.Client
2+
{
3+
public interface IUpdateBlock
4+
{
5+
}
6+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using Newtonsoft.Json;
2+
3+
namespace Notion.Client
4+
{
5+
public class NumberedListItemUpdateBlock : IUpdateBlock
6+
{
7+
[JsonProperty("numbered_list_item")]
8+
public TextContentUpdate NumberedListItem { get; set; }
9+
}
10+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace Notion.Client
2+
{
3+
public class ParagraphUpdateBlock : IUpdateBlock
4+
{
5+
public TextContentUpdate Paragraph { get; set; }
6+
}
7+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
using System.Collections.Generic;
2+
3+
namespace Notion.Client
4+
{
5+
public class TextContentUpdate
6+
{
7+
public IEnumerable<RichTextBaseInput> Text { get; set; }
8+
}
9+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using System.Collections.Generic;
2+
using Newtonsoft.Json;
3+
4+
namespace Notion.Client
5+
{
6+
public class ToDoUpdateBlock : IUpdateBlock
7+
{
8+
[JsonProperty("to_do")]
9+
public Info ToDo { get; set; }
10+
11+
public class Info
12+
{
13+
public IEnumerable<RichTextBaseInput> Text { get; set; }
14+
15+
[JsonProperty("checked")]
16+
public bool IsChecked { get; set; }
17+
}
18+
}
19+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace Notion.Client
2+
{
3+
public class ToggleUpdateBlock : IUpdateBlock
4+
{
5+
public TextContentUpdate Toggle { get; set; }
6+
}
7+
}

Test/Notion.UnitTests/BlocksClientTests.cs

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,51 @@ public async Task RetrieveAsync()
7575
.WithBody(jsonData)
7676
);
7777

78-
var block = await _client.Retrieve(blockId);
78+
var block = await _client.RetrieveAsync(blockId);
79+
80+
block.Id.Should().Be(blockId);
81+
block.HasChildren.Should().BeFalse();
82+
block.Type.Should().Be(BlockType.ToDo);
83+
84+
var todoBlock = ((ToDoBlock)block);
85+
todoBlock.ToDo.Text.Should().ContainSingle();
86+
todoBlock.ToDo.Text.First().Should().BeAssignableTo<RichTextText>();
87+
((RichTextText)todoBlock.ToDo.Text.First()).Text.Content.Should().Be("Lacinato kale");
88+
}
89+
90+
[Fact]
91+
public async Task UpdateAsync()
92+
{
93+
string blockId = "9bc30ad4-9373-46a5-84ab-0a7845ee52e6";
94+
var path = ApiEndpoints.BlocksApiUrls.Update(blockId);
95+
var jsonData = await File.ReadAllTextAsync("data/blocks/UpdateBlockResponse.json");
96+
97+
Server.Given(CreatePatchRequestBuilder(path))
98+
.RespondWith(
99+
Response.Create()
100+
.WithStatusCode(200)
101+
.WithBody(jsonData)
102+
);
103+
104+
var updateBlock = new ToDoUpdateBlock
105+
{
106+
ToDo = new ToDoUpdateBlock.Info
107+
{
108+
Text = new List<RichTextBaseInput>()
109+
{
110+
new RichTextTextInput
111+
{
112+
Text = new Text
113+
{
114+
Content = "Lacinato kale"
115+
},
116+
}
117+
},
118+
IsChecked = true
119+
}
120+
};
121+
122+
var block = await _client.UpdateAsync(blockId, updateBlock);
79123

80124
block.Id.Should().Be(blockId);
81125
block.HasChildren.Should().BeFalse();

Test/Notion.UnitTests/Notion.UnitTests.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
<None Update="data\blocks\RetrieveBlockResponse.json">
3131
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
3232
</None>
33+
<None Update="data\blocks\UpdateBlockResponse.json">
34+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
35+
</None>
3336
<None Update="data\databases\CreateDatabaseResponse.json">
3437
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
3538
</None>
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"object": "block",
3+
"id": "9bc30ad4-9373-46a5-84ab-0a7845ee52e6",
4+
"created_time": "2021-03-16T16:31:00.000Z",
5+
"last_edited_time": "2021-03-16T16:32:00.000Z",
6+
"has_children": false,
7+
"type": "to_do",
8+
"to_do": {
9+
"text": [
10+
{
11+
"type": "text",
12+
"text": {
13+
"content": "Lacinato kale",
14+
"link": null
15+
},
16+
"annotations": {
17+
"bold": false,
18+
"italic": false,
19+
"strikethrough": false,
20+
"underline": false,
21+
"code": false,
22+
"color": "default"
23+
},
24+
"plain_text": "Lacinato kale",
25+
"href": null
26+
}
27+
],
28+
"checked": false
29+
}
30+
}

docs/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,9 @@ var complexFiler = new CompoundFilter(
7373
- [x] Retrieve a page
7474
- [x] Create a page
7575
- [x] Update page
76-
- [ ] Blocks
76+
- [x] Blocks
7777
- [x] Retrieve a block
78-
- [ ] Update a block
78+
- [x] Update a block
7979
- [x] Retrieve block children
8080
- [x] Append block children
8181
- [x] Users

0 commit comments

Comments
 (0)