Skip to content

Commit b42d243

Browse files
committed
Add ManagementWebhooks tests
1 parent ba4a7a0 commit b42d243

8 files changed

Lines changed: 386 additions & 0 deletions
Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
using System.Text.Json;
2+
using Adyen.Core.Options;
3+
using Adyen.ManagementWebhooks.Extensions;
4+
using Adyen.ManagementWebhooks.Handlers;
5+
using Adyen.ManagementWebhooks.Models;
6+
using Microsoft.Extensions.DependencyInjection;
7+
using Microsoft.Extensions.Hosting;
8+
using Microsoft.VisualStudio.TestTools.UnitTesting;
9+
10+
namespace Adyen.Test.ManagementWebhooks
11+
{
12+
[TestClass]
13+
public class ManagementWebhooksTest
14+
{
15+
private readonly IManagementWebhooksHandler _managementWebhooksHandler;
16+
17+
public ManagementWebhooksTest()
18+
{
19+
IHost host = Host.CreateDefaultBuilder()
20+
.ConfigureManagementWebhooks((context, services, config) =>
21+
{
22+
services.AddManagementWebhooksHandler();
23+
})
24+
.Build();
25+
26+
_managementWebhooksHandler = host.Services.GetRequiredService<IManagementWebhooksHandler>();
27+
}
28+
29+
[TestMethod]
30+
public void Given_Deserialize_When_Event_Is_Merchant_Created()
31+
{
32+
// Arrange
33+
string json = TestUtilities.GetTestFileContent("mocks/managementwebhooks/merchant.created.json");
34+
35+
// Act
36+
var r = _managementWebhooksHandler.DeserializeMerchantCreatedNotificationRequest(json);
37+
38+
// Assert
39+
Assert.IsNotNull(r);
40+
Assert.AreEqual("test", r.Environment);
41+
Assert.AreEqual(MerchantCreatedNotificationRequest.TypeEnum.MerchantCreated, r.Type);
42+
Assert.AreEqual(DateTimeOffset.Parse("2022-08-12T10:50:01+02:00"), r.CreatedAt);
43+
44+
Assert.IsNotNull(r.Data);
45+
Assert.AreEqual("YOUR_COMPANY_ID", r.Data.CompanyId);
46+
Assert.AreEqual("MC3224X22322535GH8D537TJR", r.Data.MerchantId);
47+
Assert.AreEqual("PreActive", r.Data.Status);
48+
49+
Assert.IsNotNull(r.Data.Capabilities);
50+
Assert.IsTrue(r.Data.Capabilities.ContainsKey("sendToTransferInstrument"));
51+
var capability = r.Data.Capabilities["sendToTransferInstrument"];
52+
Assert.IsTrue(capability.Requested);
53+
Assert.AreEqual("notApplicable", capability.RequestedLevel);
54+
}
55+
56+
[TestMethod]
57+
public void Given_Deserialize_When_Event_Is_PaymentMethod_Created()
58+
{
59+
// Arrange
60+
string json = TestUtilities.GetTestFileContent("mocks/managementwebhooks/paymentMethod.created.json");
61+
62+
// Act
63+
var r = _managementWebhooksHandler.DeserializePaymentMethodCreatedNotificationRequest(json);
64+
65+
// Assert
66+
Assert.IsNotNull(r);
67+
Assert.AreEqual("test", r.Environment);
68+
Assert.AreEqual(PaymentMethodCreatedNotificationRequest.TypeEnum.PaymentMethodCreated, r.Type);
69+
Assert.AreEqual(DateTimeOffset.Parse("2022-01-24T14:59:11+01:00"), r.CreatedAt);
70+
71+
Assert.IsNotNull(r.Data);
72+
Assert.AreEqual("PM3224R223224K5FH4M2K9B86", r.Data.Id);
73+
Assert.AreEqual("MERCHANT_ACCOUNT", r.Data.MerchantId);
74+
Assert.AreEqual(MidServiceNotificationData.StatusEnum.Success, r.Data.Status);
75+
Assert.AreEqual("ST322LJ223223K5F4SQNR9XL5", r.Data.StoreId);
76+
Assert.AreEqual("visa", r.Data.Type);
77+
}
78+
79+
[TestMethod]
80+
public void Given_Deserialize_When_Event_Is_Merchant_Created_With_Unknown_Attribute()
81+
{
82+
// Arrange
83+
string json = TestUtilities.GetTestFileContent("mocks/managementwebhooks/merchant.created.unknown.attribute.json");
84+
85+
// Act
86+
var r = _managementWebhooksHandler.DeserializeMerchantCreatedNotificationRequest(json);
87+
88+
// Assert
89+
Assert.IsNotNull(r);
90+
Assert.AreEqual("test", r.Environment);
91+
Assert.AreEqual(MerchantCreatedNotificationRequest.TypeEnum.MerchantCreated, r.Type);
92+
Assert.AreEqual("YOUR_COMPANY_ID", r.Data.CompanyId);
93+
Assert.AreEqual("MC3224X22322535GH8D537TJR", r.Data.MerchantId);
94+
}
95+
96+
[TestMethod]
97+
public void Given_Deserialize_When_Event_Is_PaymentMethod_Created_With_Unknown_Status_Enum()
98+
{
99+
// Arrange
100+
string json = TestUtilities.GetTestFileContent("mocks/managementwebhooks/paymentMethod.created.unknown.status.enum.json");
101+
102+
// Act
103+
var r = _managementWebhooksHandler.DeserializePaymentMethodCreatedNotificationRequest(json);
104+
105+
// Assert
106+
Assert.IsNotNull(r);
107+
Assert.AreEqual("test", r.Environment);
108+
Assert.AreEqual(PaymentMethodCreatedNotificationRequest.TypeEnum.PaymentMethodCreated, r.Type);
109+
Assert.AreEqual("PM3224R223224K5FH4M2K9B86", r.Data.Id);
110+
Assert.AreEqual("unknown-future-status", r.Data.Status.Value);
111+
}
112+
113+
[TestMethod]
114+
public void Given_Deserialize_When_Event_Is_Merchant_Created_With_Multiple_Capabilities()
115+
{
116+
// Arrange
117+
string json = TestUtilities.GetTestFileContent("mocks/managementwebhooks/merchant.created.multiple.capabilities.json");
118+
119+
// Act
120+
var r = _managementWebhooksHandler.DeserializeMerchantCreatedNotificationRequest(json);
121+
122+
// Assert
123+
Assert.IsNotNull(r);
124+
Assert.AreEqual(3, r.Data.Capabilities.Count);
125+
126+
Assert.IsTrue(r.Data.Capabilities.ContainsKey("sendToTransferInstrument"));
127+
var sendToTransferInstrument = r.Data.Capabilities["sendToTransferInstrument"];
128+
Assert.IsTrue(sendToTransferInstrument.Requested);
129+
Assert.AreEqual("notApplicable", sendToTransferInstrument.RequestedLevel);
130+
Assert.IsNull(sendToTransferInstrument.Allowed);
131+
Assert.IsNull(sendToTransferInstrument.VerificationStatus);
132+
133+
Assert.IsTrue(r.Data.Capabilities.ContainsKey("receivePayments"));
134+
var receivePayments = r.Data.Capabilities["receivePayments"];
135+
Assert.IsTrue(receivePayments.Requested);
136+
Assert.AreEqual("notApplicable", receivePayments.RequestedLevel);
137+
Assert.IsTrue(receivePayments.Allowed);
138+
Assert.AreEqual("valid", receivePayments.VerificationStatus);
139+
140+
Assert.IsTrue(r.Data.Capabilities.ContainsKey("receiveFromPlatformPayments"));
141+
var receiveFromPlatformPayments = r.Data.Capabilities["receiveFromPlatformPayments"];
142+
Assert.IsFalse(receiveFromPlatformPayments.Requested);
143+
Assert.AreEqual("low", receiveFromPlatformPayments.RequestedLevel);
144+
Assert.IsNull(receiveFromPlatformPayments.Allowed);
145+
}
146+
147+
[TestMethod]
148+
public void Given_Deserialize_When_Event_Is_Merchant_Updated_With_Capability_Having_Only_Required_Fields()
149+
{
150+
// Arrange
151+
string json = TestUtilities.GetTestFileContent("mocks/managementwebhooks/merchant.updated.capability.required.fields.only.json");
152+
153+
// Act
154+
var r = _managementWebhooksHandler.DeserializeMerchantUpdatedNotificationRequest(json);
155+
156+
// Assert
157+
Assert.IsNotNull(r);
158+
Assert.AreEqual(1, r.Data.Capabilities.Count);
159+
160+
Assert.IsTrue(r.Data.Capabilities.ContainsKey("receivePayments"));
161+
var receivePayments = r.Data.Capabilities["receivePayments"];
162+
Assert.IsTrue(receivePayments.Requested);
163+
Assert.AreEqual("notApplicable", receivePayments.RequestedLevel);
164+
165+
Assert.IsNull(receivePayments.Allowed);
166+
Assert.IsNull(receivePayments.AllowedLevel);
167+
Assert.IsNull(receivePayments.Capability);
168+
Assert.IsNull(receivePayments.Problems);
169+
Assert.IsNull(receivePayments.VerificationDeadline);
170+
Assert.IsNull(receivePayments.VerificationStatus);
171+
Assert.IsNull(r.Data.LegalEntityId);
172+
}
173+
174+
[TestMethod]
175+
public void Given_Deserialize_When_Required_Fields_Are_Missing_Then_Throws_ArgumentException()
176+
{
177+
// Arrange
178+
string json = @"{ ""type"": ""merchant.created"" }"; // No data, no environment (which are required)!
179+
180+
// Act & Assert
181+
Assert.ThrowsException<ArgumentException>(() =>
182+
{
183+
_managementWebhooksHandler.DeserializeMerchantCreatedNotificationRequest(json);
184+
});
185+
}
186+
187+
[TestMethod]
188+
public void Given_Deserialize_When_Json_Is_Invalid_Then_Throws_JsonException()
189+
{
190+
// Arrange
191+
string json = "{ invalid,.json; }";
192+
193+
// Act & Assert
194+
Assert.ThrowsException<JsonException>(() =>
195+
{
196+
_managementWebhooksHandler.DeserializeMerchantCreatedNotificationRequest(json);
197+
});
198+
}
199+
200+
[TestMethod]
201+
public void Given_IsValidHmacSignature_When_Hmac_Key_Is_Not_Configured_Then_Throws_InvalidOperationException()
202+
{
203+
// Arrange - handler built without HMAC key
204+
IHost host = Host.CreateDefaultBuilder()
205+
.ConfigureManagementWebhooks((context, services, config) =>
206+
{
207+
services.AddManagementWebhooksHandler();
208+
})
209+
.Build();
210+
var handler = host.Services.GetRequiredService<IManagementWebhooksHandler>();
211+
212+
// Act & Assert
213+
Assert.ThrowsException<InvalidOperationException>(() =>
214+
{
215+
handler.IsValidHmacSignature("{}", "some-signature");
216+
});
217+
}
218+
219+
[TestMethod]
220+
public void Given_IsValidHmacSignature_When_Hmac_Signature_Is_Invalid_Then_Returns_False()
221+
{
222+
// Arrange - key must be a valid 64-char hex string
223+
IHost host = Host.CreateDefaultBuilder()
224+
.ConfigureManagementWebhooks((context, services, config) =>
225+
{
226+
config.ConfigureAdyenOptions(options =>
227+
{
228+
options.AdyenHmacKey = "0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20";
229+
});
230+
services.AddManagementWebhooksHandler();
231+
})
232+
.Build();
233+
var handler = host.Services.GetRequiredService<IManagementWebhooksHandler>();
234+
235+
// Act
236+
bool isValid = handler.IsValidHmacSignature("{ \"test\": \"value\" }", "invalid-hmac-signature");
237+
238+
// Assert
239+
Assert.IsFalse(isValid);
240+
}
241+
242+
[TestMethod]
243+
public void Given_Deserialize_When_Event_Is_Merchant_Updated()
244+
{
245+
// Arrange
246+
string json = TestUtilities.GetTestFileContent("mocks/managementwebhooks/merchant.updated.json");
247+
248+
// Act
249+
var r = _managementWebhooksHandler.DeserializeMerchantUpdatedNotificationRequest(json);
250+
251+
// Assert
252+
Assert.IsNotNull(r);
253+
Assert.AreEqual("test", r.Environment);
254+
Assert.AreEqual(MerchantUpdatedNotificationRequest.TypeEnum.MerchantUpdated, r.Type);
255+
Assert.AreEqual(DateTimeOffset.Parse("2022-09-20T13:42:31+02:00"), r.CreatedAt);
256+
257+
Assert.IsNotNull(r.Data);
258+
Assert.AreEqual("YOUR_MERCHANT_ID", r.Data.MerchantId);
259+
Assert.AreEqual("PreActive", r.Data.Status);
260+
Assert.AreEqual("LE322KH223222F5GNNW694PZN", r.Data.LegalEntityId);
261+
262+
Assert.IsNotNull(r.Data.Capabilities);
263+
Assert.IsTrue(r.Data.Capabilities.ContainsKey("receivePayments"));
264+
var capability = r.Data.Capabilities["receivePayments"];
265+
Assert.IsTrue(capability.Allowed);
266+
Assert.IsTrue(capability.Requested);
267+
Assert.AreEqual("notApplicable", capability.RequestedLevel);
268+
}
269+
}
270+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"type": "merchant.created",
3+
"environment": "test",
4+
"createdAt": "2022-08-12T10:50:01+02:00",
5+
"data": {
6+
"capabilities": {
7+
"sendToTransferInstrument": {
8+
"requested": true,
9+
"requestedLevel": "notApplicable"
10+
}
11+
},
12+
"companyId": "YOUR_COMPANY_ID",
13+
"merchantId": "MC3224X22322535GH8D537TJR",
14+
"status": "PreActive"
15+
}
16+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"type": "merchant.created",
3+
"environment": "test",
4+
"createdAt": "2022-08-12T10:50:01+02:00",
5+
"data": {
6+
"capabilities": {
7+
"sendToTransferInstrument": {
8+
"requested": true,
9+
"requestedLevel": "notApplicable"
10+
},
11+
"receivePayments": {
12+
"allowed": true,
13+
"requested": true,
14+
"requestedLevel": "notApplicable",
15+
"verificationStatus": "valid"
16+
},
17+
"receiveFromPlatformPayments": {
18+
"requested": false,
19+
"requestedLevel": "low"
20+
}
21+
},
22+
"companyId": "YOUR_COMPANY_ID",
23+
"merchantId": "MC3224X22322535GH8D537TJR",
24+
"status": "PreActive"
25+
}
26+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"type": "merchant.created",
3+
"environment": "test",
4+
"createdAt": "2022-08-12T10:50:01+02:00",
5+
"unknownAttribute": "some-value-that-does-not-exist-in-the-model",
6+
"data": {
7+
"capabilities": {
8+
"sendToTransferInstrument": {
9+
"requested": true,
10+
"requestedLevel": "notApplicable"
11+
}
12+
},
13+
"companyId": "YOUR_COMPANY_ID",
14+
"merchantId": "MC3224X22322535GH8D537TJR",
15+
"status": "PreActive"
16+
}
17+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"type": "merchant.updated",
3+
"environment": "test",
4+
"createdAt": "2022-09-20T13:42:31+02:00",
5+
"data": {
6+
"capabilities": {
7+
"receivePayments": {
8+
"requested": true,
9+
"requestedLevel": "notApplicable"
10+
}
11+
},
12+
"merchantId": "YOUR_MERCHANT_ID",
13+
"status": "PreActive"
14+
}
15+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"type": "merchant.updated",
3+
"environment": "test",
4+
"createdAt": "2022-09-20T13:42:31+02:00",
5+
"data": {
6+
"capabilities": {
7+
"receivePayments": {
8+
"allowed": true,
9+
"requested": true,
10+
"requestedLevel": "notApplicable",
11+
"verificationStatus": "valid"
12+
}
13+
},
14+
"legalEntityId": "LE322KH223222F5GNNW694PZN",
15+
"merchantId": "YOUR_MERCHANT_ID",
16+
"status": "PreActive"
17+
}
18+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"createdAt": "2022-01-24T14:59:11+01:00",
3+
"data": {
4+
"id": "PM3224R223224K5FH4M2K9B86",
5+
"merchantId": "MERCHANT_ACCOUNT",
6+
"status": "success",
7+
"storeId": "ST322LJ223223K5F4SQNR9XL5",
8+
"type": "visa"
9+
},
10+
"environment": "test",
11+
"type": "paymentMethod.created"
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"createdAt": "2022-01-24T14:59:11+01:00",
3+
"data": {
4+
"id": "PM3224R223224K5FH4M2K9B86",
5+
"merchantId": "MERCHANT_ACCOUNT",
6+
"status": "unknown-future-status",
7+
"storeId": "ST322LJ223223K5F4SQNR9XL5",
8+
"type": "visa"
9+
},
10+
"environment": "test",
11+
"type": "paymentMethod.created"
12+
}

0 commit comments

Comments
 (0)