Skip to content

Commit 8d55a64

Browse files
authored
feat: Subscriptions (#83)
* feat: Subscriptions
1 parent 775d60b commit 8d55a64

13 files changed

+726
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Threading.Tasks;
4+
using Xunit;
5+
6+
namespace Pipedrive.Tests.Integration.Clients
7+
{
8+
public class SubscriptionsClientTests
9+
{
10+
public class TheGetByDealIdMethod
11+
{
12+
[IntegrationTest]
13+
public async Task CanRetrieveSubscription()
14+
{
15+
var pipedrive = Helper.GetAuthenticatedClient();
16+
17+
var subscription = await pipedrive.Subscription.GetByDealId(540);
18+
19+
Assert.False(subscription.Infinite);
20+
Assert.True(subscription.IsActive);
21+
}
22+
}
23+
24+
public class TheGetMethod
25+
{
26+
[IntegrationTest]
27+
public async Task CanRetrieveSubscription()
28+
{
29+
var pipedrive = Helper.GetAuthenticatedClient();
30+
31+
var subscription = await pipedrive.Subscription.Get(1);
32+
33+
Assert.True(subscription.IsActive);
34+
}
35+
}
36+
37+
public class TheGetPaymentsMethod
38+
{
39+
[IntegrationTest]
40+
public async Task CanRetrievePayments()
41+
{
42+
var pipedrive = Helper.GetAuthenticatedClient();
43+
44+
var payments = await pipedrive.Subscription.GetPayments(1);
45+
46+
Assert.Equal(3, payments.Count);
47+
}
48+
}
49+
50+
public class TheCreateRecurringMethod
51+
{
52+
[IntegrationTest]
53+
public async Task CanCreateInfinite()
54+
{
55+
var pipedrive = Helper.GetAuthenticatedClient();
56+
var fixture = pipedrive.Subscription;
57+
58+
var newRecurringSubscription = new NewRecurringSubscription()
59+
{
60+
DealId = 1,
61+
Description = "a subscription",
62+
Currency = "EUR",
63+
CadenceType = "monthly",
64+
CycleAmount = 200,
65+
Infinite = true,
66+
StartDate = DateTime.UtcNow.AddDays(3).Date,
67+
Payments = new List<NewPayment>()
68+
{
69+
new NewPayment() { Amount = 200, Description = "my payment", DueAt = DateTime.Now }
70+
}
71+
};
72+
73+
var subscription = await fixture.CreateRecurring(newRecurringSubscription);
74+
Assert.NotNull(subscription);
75+
76+
var retrieved = await fixture.Get(subscription.Id);
77+
Assert.NotNull(retrieved);
78+
Assert.True(newRecurringSubscription.Infinite);
79+
Assert.Equal(DateTime.UtcNow.AddDays(3).Date, subscription.StartDate);
80+
81+
// Cleanup
82+
await fixture.Delete(subscription.Id);
83+
}
84+
85+
[IntegrationTest]
86+
public async Task CanCreateLimited()
87+
{
88+
var pipedrive = Helper.GetAuthenticatedClient();
89+
var fixture = pipedrive.Subscription;
90+
91+
var newRecurringSubscription = new NewRecurringSubscription()
92+
{
93+
DealId = 1,
94+
Description = "a subscription",
95+
Currency = "EUR",
96+
CadenceType = "monthly",
97+
CycleAmount = 200,
98+
CyclesCount = 12,
99+
StartDate = DateTime.UtcNow.AddDays(3).Date,
100+
Payments = new List<NewPayment>()
101+
{
102+
new NewPayment() { Amount = 400, Description = "my payment", DueAt = DateTime.Now }
103+
}
104+
};
105+
106+
var subscription = await fixture.CreateRecurring(newRecurringSubscription);
107+
Assert.NotNull(subscription);
108+
109+
var retrieved = await fixture.Get(subscription.Id);
110+
Assert.NotNull(retrieved);
111+
Assert.False(subscription.Infinite);
112+
Assert.Equal(12, subscription.CyclesCount);
113+
Assert.Equal(DateTime.UtcNow.AddDays(3).Date, subscription.StartDate);
114+
115+
// Cleanup
116+
await fixture.Delete(subscription.Id);
117+
}
118+
}
119+
120+
public class TheCreateInstallmentMethod
121+
{
122+
[IntegrationTest]
123+
public async Task CanCreate()
124+
{
125+
var pipedrive = Helper.GetAuthenticatedClient();
126+
var fixture = pipedrive.Subscription;
127+
128+
var newInstallmentSubscription = new NewInstallmentSubscription()
129+
{
130+
DealId = 1,
131+
Currency = "EUR",
132+
Payments = new List<NewPayment>()
133+
{
134+
new NewPayment() { Amount = 200, Description = "my payment", DueAt = DateTime.Now }
135+
}
136+
};
137+
138+
var subscription = await fixture.CreateInstallment(newInstallmentSubscription);
139+
Assert.NotNull(subscription);
140+
141+
var retrieved = await fixture.Get(subscription.Id);
142+
Assert.NotNull(retrieved);
143+
Assert.Equal(1, newInstallmentSubscription.DealId);
144+
145+
// Cleanup
146+
await fixture.Delete(subscription.Id);
147+
}
148+
}
149+
150+
public class TheCancelRecurringMethod
151+
{
152+
[IntegrationTest]
153+
public async Task CanCancel()
154+
{
155+
var pipedrive = Helper.GetAuthenticatedClient();
156+
var fixture = pipedrive.Subscription;
157+
158+
var newSubscription = new NewRecurringSubscription()
159+
{
160+
DealId = 1,
161+
Description = "a subscription",
162+
Currency = "EUR",
163+
CadenceType = "monthly",
164+
CycleAmount = 200,
165+
Infinite = true,
166+
StartDate = DateTime.UtcNow.AddDays(3).Date,
167+
Payments = new List<NewPayment>()
168+
{
169+
new NewPayment() { Amount = 200, Description = "my payment", DueAt = DateTime.Now }
170+
}
171+
};
172+
173+
var subscription = await fixture.CreateRecurring(newSubscription);
174+
175+
var createdSubscription = await fixture.Get(subscription.Id);
176+
177+
Assert.NotNull(createdSubscription);
178+
179+
await fixture.CancelRecurring(createdSubscription.Id, new CancelRecurringSubscription() { EndDate = DateTime.UtcNow.AddDays(6).Date });
180+
181+
var cancelledSubscription = await fixture.Get(createdSubscription.Id);
182+
183+
Assert.Equal("canceled", cancelledSubscription.FinalStatus);
184+
}
185+
}
186+
187+
public class TheDeleteMethod
188+
{
189+
[IntegrationTest]
190+
public async Task CanDelete()
191+
{
192+
var pipedrive = Helper.GetAuthenticatedClient();
193+
var fixture = pipedrive.Subscription;
194+
195+
var newSubscription = new NewInstallmentSubscription()
196+
{
197+
DealId = 1,
198+
Currency = "EUR",
199+
Payments = new List<NewPayment>()
200+
{
201+
new NewPayment() { Amount = 200, Description = "my payment", DueAt = DateTime.Now }
202+
}
203+
};
204+
var subscription = await fixture.CreateInstallment(newSubscription);
205+
206+
var createdSubscription = await fixture.Get(subscription.Id);
207+
208+
Assert.NotNull(createdSubscription);
209+
210+
await fixture.Delete(createdSubscription.Id);
211+
212+
var deletedSubscription = await fixture.Get(createdSubscription.Id);
213+
214+
Assert.False(deletedSubscription.IsActive);
215+
}
216+
}
217+
}
218+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
using System;
2+
using System.Threading.Tasks;
3+
using NSubstitute;
4+
using Xunit;
5+
6+
namespace Pipedrive.Tests.Clients
7+
{
8+
public class SubscriptionsClientTests
9+
{
10+
public class TheCtor
11+
{
12+
[Fact]
13+
public void EnsuresNonNullArguments()
14+
{
15+
Assert.Throws<ArgumentNullException>(() => new SubscriptionsClient(null));
16+
}
17+
}
18+
19+
public class TheGetByDealIdMethod
20+
{
21+
[Fact]
22+
public async Task RequestsCorrectUrl()
23+
{
24+
var connection = Substitute.For<IApiConnection>();
25+
var client = new SubscriptionsClient(connection);
26+
27+
await client.GetByDealId(123);
28+
29+
Received.InOrder(async () =>
30+
{
31+
await connection.Get<Subscription>(
32+
Arg.Is<Uri>(u => u.ToString() == "subscriptions/find/123"));
33+
});
34+
}
35+
}
36+
37+
public class TheGetMethod
38+
{
39+
[Fact]
40+
public async Task RequestsCorrectUrl()
41+
{
42+
var connection = Substitute.For<IApiConnection>();
43+
var client = new SubscriptionsClient(connection);
44+
45+
await client.Get(123);
46+
47+
Received.InOrder(async () =>
48+
{
49+
await connection.Get<Subscription>(Arg.Is<Uri>(u => u.ToString() == "subscriptions/123"));
50+
});
51+
}
52+
}
53+
54+
public class TheGetPaymentsMethod
55+
{
56+
[Fact]
57+
public async Task RequestsCorrectUrl()
58+
{
59+
var connection = Substitute.For<IApiConnection>();
60+
var client = new SubscriptionsClient(connection);
61+
62+
await client.GetPayments(123);
63+
64+
Received.InOrder(async () =>
65+
{
66+
await connection.GetAll<Payment>(Arg.Is<Uri>(u => u.ToString() == "subscriptions/123/payments"));
67+
});
68+
}
69+
}
70+
71+
public class TheCreateRecurringMethod
72+
{
73+
[Fact]
74+
public async Task EnsuresNonNullArguments()
75+
{
76+
var client = new SubscriptionsClient(Substitute.For<IApiConnection>());
77+
78+
await Assert.ThrowsAsync<ArgumentNullException>(() => client.CreateRecurring(null));
79+
}
80+
81+
[Fact]
82+
public void PostsToTheCorrectUrl()
83+
{
84+
var connection = Substitute.For<IApiConnection>();
85+
var client = new SubscriptionsClient(connection);
86+
87+
var newSubscription = new NewRecurringSubscription() { DealId = 1, Currency = "EUR", CadenceType = "monthly", CycleAmount = 100, StartDate = DateTime.UtcNow };
88+
client.CreateRecurring(newSubscription);
89+
90+
connection.Received().Post<Subscription>(Arg.Is<Uri>(u => u.ToString() == "subscriptions/recurring"),
91+
Arg.Is<NewRecurringSubscription>(d => d.DealId == 1 && d.Currency == "EUR" && d.CadenceType == "monthly" && d.CycleAmount == 100));
92+
}
93+
}
94+
95+
public class TheCreateInstallmentMethod
96+
{
97+
[Fact]
98+
public async Task EnsuresNonNullArguments()
99+
{
100+
var client = new SubscriptionsClient(Substitute.For<IApiConnection>());
101+
102+
await Assert.ThrowsAsync<ArgumentNullException>(() => client.CreateInstallment(null));
103+
}
104+
105+
[Fact]
106+
public void PostsToTheCorrectUrl()
107+
{
108+
var connection = Substitute.For<IApiConnection>();
109+
var client = new SubscriptionsClient(connection);
110+
111+
var newSubscription = new NewInstallmentSubscription() { DealId = 1, Currency = "EUR" };
112+
client.CreateInstallment(newSubscription);
113+
114+
connection.Received().Post<Subscription>(Arg.Is<Uri>(u => u.ToString() == "subscriptions/installment"),
115+
Arg.Is<NewInstallmentSubscription>(d => d.DealId == 1 && d.Currency == "EUR"));
116+
}
117+
}
118+
119+
public class TheCancelRecurringMethod
120+
{
121+
[Fact]
122+
public void CancelsCorrectUrl()
123+
{
124+
var connection = Substitute.For<IApiConnection>();
125+
var client = new SubscriptionsClient(connection);
126+
127+
client.CancelRecurring(123, new CancelRecurringSubscription() { EndDate = DateTime.UtcNow.AddDays(4).Date });
128+
129+
connection.Received().Put<Subscription>(Arg.Is<Uri>(u => u.ToString() == "subscriptions/recurring/123/cancel"),
130+
Arg.Is<CancelRecurringSubscription>(d => d.EndDate == DateTime.UtcNow.AddDays(4).Date));
131+
}
132+
}
133+
134+
public class TheDeleteMethod
135+
{
136+
[Fact]
137+
public void DeletesCorrectUrl()
138+
{
139+
var connection = Substitute.For<IApiConnection>();
140+
var client = new SubscriptionsClient(connection);
141+
142+
client.Delete(123);
143+
144+
connection.Received().Delete(Arg.Is<Uri>(u => u.ToString() == "subscriptions/123"));
145+
}
146+
}
147+
}
148+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using System.Collections.Generic;
2+
using System.Threading.Tasks;
3+
4+
namespace Pipedrive
5+
{
6+
/// <summary>
7+
/// A client for Pipedrive's Subscription API.
8+
/// </summary>
9+
/// <remarks>
10+
/// See the <a href="https://developers.pipedrive.com/docs/api/v1/Subscriptions">Subscription API documentation</a> for more information.
11+
public interface ISubscriptionsClient
12+
{
13+
Task<Subscription> GetByDealId(long dealId);
14+
15+
Task<Subscription> Get(long id);
16+
17+
Task<IReadOnlyList<Payment>> GetPayments(long id);
18+
19+
Task<Subscription> CreateRecurring(NewRecurringSubscription data);
20+
21+
Task<Subscription> CreateInstallment(NewInstallmentSubscription data);
22+
23+
Task<Subscription> CancelRecurring(long id, CancelRecurringSubscription data);
24+
25+
Task Delete(long id);
26+
}
27+
}

0 commit comments

Comments
 (0)