Skip to content

Commit a0fbdfa

Browse files
committed
Implemented UserPinPolicyAsync region replication with tests. Refining request/response models.
1 parent 1af5356 commit a0fbdfa

6 files changed

Lines changed: 86 additions & 16 deletions

File tree

Source/Pinata.Client.Tests/IntegrationTests/AllTests.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ public async Task pinning_pinJson_as_object()
8080
var body = new { hello = "world" };
8181
var r = await this.client.Pinning.PinJsonToIpfsAsync(body);
8282
}
83+
8384
[Test]
8485
public async Task pinning_pinJson_as_object_with_options()
8586
{
@@ -106,7 +107,9 @@ public async Task pinning_pinJson_as_object_with_options()
106107
[Test]
107108
public async Task pinning_set_userPinPolicy()
108109
{
109-
110+
var policy = new PinPolicy();
111+
policy.AddOrUpdateRegion("FRA1", 1);
112+
var r = await this.client.Pinning.UserPinPolicyAsync(policy);
110113
}
111114
}
112115
}

Source/Pinata.Client.Tests/PinningTests.cs

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public async Task pin_json_content()
2626
{
2727
this.server.RespondWithJsonTestFile();
2828

29-
var content = "{\"hello\":\"world\"}";
29+
var content = @"{""hello"":""world""}";
3030

3131
var r = await this.client.Pinning.PinJsonToIpfsAsync(content);
3232

@@ -42,7 +42,7 @@ public async Task pin_json_content_with_options()
4242
{
4343
this.server.RespondWithJsonTestFile();
4444

45-
var content = "{\"hello\":\"world\"}";
45+
var content = @"{""hello"":""world""}";
4646

4747
var opts = new PinataOptions
4848
{
@@ -61,7 +61,7 @@ public async Task pin_json_content_with_options()
6161

6262
var r = await this.client.Pinning.PinJsonToIpfsAsync(content, meta, opts);
6363

64-
var expectedBody = "{\"pinataContent\":{\"hello\":\"world\"},\"pinataOptions\":{\"cidVersion\":1,\"customPinPolicy\":{\"regions\":[{\"id\":\"FRA1\",\"desiredReplicationCount\":1}]}},\"pinataMetadata\":{\"name\":\"hello\",\"keyvalues\":{\"someKey\":\"someValue\"}}}";
64+
var expectedBody = @"{""pinataContent"":{""hello"":""world""},""pinataOptions"":{""cidVersion"":1,""customPinPolicy"":{""regions"":[{""id"":""FRA1"",""desiredReplicationCount"":1}]}},""pinataMetadata"":{""name"":""hello"",""keyvalues"":{""someKey"":""someValue""}}}";
6565

6666
this.server.ShouldHaveCalledPath("/pinning/pinJSONToIPFS")
6767
.WithVerb(Post)
@@ -79,7 +79,7 @@ public async Task pin_json_object()
7979

8080
var r = await this.client.Pinning.PinJsonToIpfsAsync(body);
8181

82-
var expectedBody = "{\"pinataOptions\":null,\"pinataMetadata\":null,\"pinataContent\":{\"hello\":\"world\"}}";
82+
var expectedBody = @"{""pinataOptions"":null,""pinataMetadata"":null,""pinataContent"":{""hello"":""world""}}";
8383

8484
this.server.ShouldHaveCalledPath("/pinning/pinJSONToIPFS")
8585
.WithVerb(Post)
@@ -110,12 +110,31 @@ public async Task pin_json_object_with_options()
110110
};
111111
var r = await this.client.Pinning.PinJsonToIpfsAsync(body, meta, opts);
112112

113-
var expectedBody = "{\"pinataOptions\":{\"cidVersion\":1,\"customPinPolicy\":{\"regions\":[{\"id\":\"FRA1\",\"desiredReplicationCount\":1}]}},\"pinataMetadata\":{\"name\":\"hello\",\"keyvalues\":{\"someKey\":\"someValue\"}},\"pinataContent\":{\"hello\":\"world\"}}";
113+
var expectedBody = @"{""pinataOptions"":{""cidVersion"":1,""customPinPolicy"":{""regions"":[{""id"":""FRA1"",""desiredReplicationCount"":1}]}},""pinataMetadata"":{""name"":""hello"",""keyvalues"":{""someKey"":""someValue""}},""pinataContent"":{""hello"":""world""}}";
114114
this.server.ShouldHaveCalledPath("/pinning/pinJSONToIPFS")
115115
.WithVerb(Post)
116116
.WithExactBody(expectedBody);
117117

118118
await Verify(r);
119119
}
120+
121+
[Test]
122+
public async Task new_user_pin_policy()
123+
{
124+
this.server.RespondWithJsonTestFile();
125+
126+
var policy = new PinPolicy();
127+
policy.AddOrUpdateRegion("FRA1", 1);
128+
129+
var r = await this.client.Pinning.UserPinPolicyAsync(policy);
130+
131+
var expectedBody = @"{""newPinPolicy"":{""regions"":[{""id"":""FRA1"",""desiredReplicationCount"":1}]},""migratePreviousPins"":false}";
132+
133+
this.server.ShouldHaveCalledPath("/pinning/userPinPolicy")
134+
.WithVerb(Put)
135+
.WithExactBody(expectedBody);
136+
137+
await Verify(r);
138+
}
120139
}
121140
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"result":"success"}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
Result: 'success',
3+
IsSuccess: true
4+
}

Source/Pinata.Client/Models/Response.cs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,17 @@ namespace Pinata.Client.Models
55
{
66
public class Response : Json
77
{
8+
[JsonProperty("message")]
9+
public string Message { get; set; }
10+
811
public string Error { get; set; }
9-
public bool IsSuccess => string.IsNullOrWhiteSpace(this.Error);
12+
13+
public virtual bool IsSuccess => string.IsNullOrWhiteSpace(this.Error);
1014
}
1115

1216

1317
public partial class TestAuthenticationResponse : Response
1418
{
15-
[JsonProperty("message")]
16-
public string Message { get; set; }
1719
}
1820

1921
public partial class UserPinnedDataTotalResponse : Response
@@ -39,7 +41,6 @@ public partial class UserPinnedDataTotalResponse : Response
3941

4042
public class UnpinResponse : Response
4143
{
42-
public bool IsSuccess => string.IsNullOrWhiteSpace(this.Error);
4344
}
4445

4546
public partial class PinJsonToIpfsResponse : Response
@@ -53,4 +54,13 @@ public partial class PinJsonToIpfsResponse : Response
5354
[JsonProperty("Timestamp")]
5455
public DateTimeOffset Timestamp { get; set; }
5556
}
57+
58+
public class UserPinPolicyResponse : Response
59+
{
60+
public string Result { get; set; }
61+
62+
public override bool IsSuccess => this.Result == "success" &&
63+
string.IsNullOrWhiteSpace(this.Error);
64+
}
65+
5666
}

Source/Pinata.Client/PinataClient.Pinning.cs

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,34 @@ public class PinataMetadata : Json
6969

7070
public interface IPinningEndpoint
7171
{
72+
/// <summary>
73+
/// This endpoint allows the sender to unpin content they previously uploaded to Pinata's IPFS nodes
74+
/// </summary>
7275
Task<IFlurlResponse> UnpinAsync(string hashToUnpin, CancellationToken cancellationToken = default);
76+
77+
/// <summary>
78+
/// This endpoint allows the sender to add and pin any JSON object they wish to Pinata's IPFS nodes. This endpoint is specifically optimized to only handle JSON content.
79+
/// </summary>
80+
/// <param name="jsonContent">Any valid JSON string</param>
81+
/// <param name="pinataMetadata">Metadata associated with the JSON file</param>
82+
/// <param name="pinataOptions">Custom replication policy for this file</param>
83+
/// <returns></returns>
7384
Task<PinJsonToIpfsResponse> PinJsonToIpfsAsync(string jsonContent, PinataMetadata pinataMetadata = null, PinataOptions pinataOptions = null, CancellationToken cancellationToken = default);
85+
86+
/// <summary>
87+
/// This endpoint allows the sender to add and pin any JSON object they wish to Pinata's IPFS nodes. This endpoint is specifically optimized to only handle JSON content.
88+
/// </summary>
89+
/// <param name="pinataContent">Any C# object that will be serialized to JSON</param>
90+
/// <param name="pinataMetadata">Metadata associated with the JSON file</param>
91+
/// <param name="pinataOptions">Custom replication policy for this file</param>
92+
/// <returns></returns>
7493
Task<PinJsonToIpfsResponse> PinJsonToIpfsAsync(object pinataContent, PinataMetadata pinataMetadata = null, PinataOptions pinataOptions = null, CancellationToken cancellationToken = default);
7594

95+
/// <summary>
96+
/// This endpoint allows the sender to change the pin policy their account.
97+
/// Following a successful call of this endpoint, the new pin policy provided will be utilized for every new piece of content pinned to IPFS via Pinata.
98+
/// </summary>
99+
Task<UserPinPolicyResponse> UserPinPolicyAsync(PinPolicy newPinPolicy, bool migratePreviousPins = false, CancellationToken cancellationToken = default);
76100
}
77101

78102
public partial class PinataClient : IPinningEndpoint
@@ -89,9 +113,7 @@ Task<IFlurlResponse> IPinningEndpoint.UnpinAsync(string hashToUnpin, Cancellatio
89113
.DeleteAsync(cancellationToken);
90114
}
91115

92-
Task<PinJsonToIpfsResponse> IPinningEndpoint.PinJsonToIpfsAsync(string jsonContent,
93-
PinataMetadata pinataMetadata = null,
94-
PinataOptions pinataOptions = null, CancellationToken cancellationToken = default)
116+
Task<PinJsonToIpfsResponse> IPinningEndpoint.PinJsonToIpfsAsync(string jsonContent, PinataMetadata pinataMetadata = null, PinataOptions pinataOptions = null, CancellationToken cancellationToken = default)
95117
{
96118
string body = jsonContent;
97119

@@ -124,9 +146,7 @@ Task<PinJsonToIpfsResponse> IPinningEndpoint.PinJsonToIpfsAsync(string jsonConte
124146
.ReceiveJson<PinJsonToIpfsResponse>();
125147
}
126148

127-
Task<PinJsonToIpfsResponse> IPinningEndpoint.PinJsonToIpfsAsync(object pinataContent,
128-
PinataMetadata pinataMetadata = null,
129-
PinataOptions pinataOptions = null, CancellationToken cancellationToken = default)
149+
Task<PinJsonToIpfsResponse> IPinningEndpoint.PinJsonToIpfsAsync(object pinataContent, PinataMetadata pinataMetadata = null, PinataOptions pinataOptions = null, CancellationToken cancellationToken = default)
130150
{
131151
return this.PinningEndpoint
132152
.WithClient(this)
@@ -139,5 +159,18 @@ Task<PinJsonToIpfsResponse> IPinningEndpoint.PinJsonToIpfsAsync(object pinataCon
139159
}, cancellationToken)
140160
.ReceiveJson<PinJsonToIpfsResponse>();
141161
}
162+
163+
public Task<UserPinPolicyResponse> UserPinPolicyAsync(PinPolicy newPinPolicy, bool migratePreviousPins = false, CancellationToken cancellationToken = default)
164+
{
165+
return this.PinningEndpoint
166+
.WithClient(this)
167+
.AppendPathSegment("userPinPolicy")
168+
.PutJsonAsync(new
169+
{
170+
newPinPolicy,
171+
migratePreviousPins
172+
}, cancellationToken)
173+
.ReceiveJson<UserPinPolicyResponse>();
174+
}
142175
}
143176
}

0 commit comments

Comments
 (0)