Skip to content

Commit 03a8c8d

Browse files
feat: update accounts API and integration tests (#451)
- Changed `Draft` and `IsDraft` properties in `OnboardEntityRequest` to nullable booleans (`bool?`). - Added `[JsonExtensionData]` to `OnboardSubEntityRequest` for handling dynamic JSON properties. - Introduced `Draft` status to the `OnboardingStatus` enum. - Updated test cases in `AccountsClientTest`: - Modified response field names and values. - Added checks for `Id` and updated `custom_field_1`. - Enhanced `AccountsIntegrationTest` with new test cases (`ShouldCreateCompanyV2`, `ShouldCreateCompanyV3`). - Added helper methods for generating random data: - `RandomString`, `RandomDigits`, `RandomBusinessRegistrationNumber`, and `RandomIdentifier`. - Introduced `CustomClientFactory` to manage HTTP client with schema version headers.
1 parent 55d2875 commit 03a8c8d

File tree

7 files changed

+221
-61
lines changed

7 files changed

+221
-61
lines changed

src/CheckoutSdk/Accounts/Entities/Common/Company/EntityRoles.cs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,19 @@ namespace Checkout.Accounts.Entities.Common.Company
44
{
55
public enum EntityRoles
66
{
7-
[EnumMember(Value = "ubo")] Ubo,
8-
[EnumMember(Value = "legal_representative")] LegalRepresentative,
9-
[EnumMember(Value = "authorised_signatory")] AuthorisedSignatory,
10-
[EnumMember(Value = "control_person")] ControlPerson,
7+
[EnumMember(Value = "ubo")]
8+
Ubo,
9+
10+
[EnumMember(Value = "authorised_signatory")]
11+
AuthorisedSignatory,
12+
13+
[EnumMember(Value = "director")]
14+
Director,
15+
16+
[EnumMember(Value = "control_person")]
17+
ControlPerson,
18+
19+
[EnumMember(Value = "legal_representative")]
20+
LegalRepresentative,
1121
}
1222
}

src/CheckoutSdk/Accounts/Entities/Request/OnboardEntityRequest.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ public class OnboardEntityRequest
1919

2020
public ProcessingDetails ProcessingDetails { get; set; }
2121

22-
public bool Draft { get; set; }
23-
public bool IsDraft { get; set; }
22+
public bool? Draft { get; set; }
23+
24+
public bool? IsDraft { get; set; }
2425

2526
public Individual Individual { get; set; }
2627

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
using Newtonsoft.Json;
12
using System.Collections.Generic;
23

34
namespace Checkout.Accounts.Entities.Request
45
{
56
public class OnboardSubEntityRequest
67
{
8+
[JsonExtensionData]
79
public IDictionary<string, object> Request { get; set; }
810
}
911
}

src/CheckoutSdk/Accounts/Entities/Response/OnboardingStatus.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ namespace Checkout.Accounts.Entities.Response
44
{
55
public enum OnboardingStatus
66
{
7+
[EnumMember(Value = "draft")]
8+
Draft,
9+
710
[EnumMember(Value = "active")]
811
Active,
912

test/CheckoutSdkTest/Accounts/AccountsClientTest.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ private async Task ShouldReinviteSubEntityMember()
7878
{
7979
Response = new Dictionary<string, object>
8080
{
81-
{ "custom_field_1", "value_1" },
82-
{ "custom_field_2", 12345 }
81+
{ "Id", "sub_entity_id" },
82+
{ "custom_field_1", 12345 }
8383
}
8484
};
8585

@@ -100,10 +100,10 @@ private async Task ShouldReinviteSubEntityMember()
100100

101101
response.ShouldNotBeNull();
102102
response.Response.ShouldNotBeNull();
103+
response.Response.ContainsKey("Id").ShouldBeTrue();
104+
response.Response["Id"].ShouldBe("sub_entity_id");
103105
response.Response.ContainsKey("custom_field_1").ShouldBeTrue();
104-
response.Response["custom_field_1"].ShouldBe("value_1");
105-
response.Response.ContainsKey("custom_field_2").ShouldBeTrue();
106-
response.Response["custom_field_2"].ShouldBe(12345);
106+
response.Response["custom_field_1"].ShouldBe(12345);
107107
}
108108

109109
[Fact]

test/CheckoutSdkTest/Accounts/AccountsIntegrationTest.cs

Lines changed: 146 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -6,34 +6,29 @@
66
using Checkout.Common;
77
using Checkout.Instruments;
88
using Shouldly;
9-
using System;
109
using System.Collections.Generic;
11-
using System.Linq;
1210
using System.Net;
1311
using System.Net.Mime;
14-
using System.Reflection.Metadata;
1512
using System.Threading.Tasks;
1613
using Xunit;
1714

1815
namespace Checkout.Accounts
1916
{
2017
public class AccountsIntegrationTest : SandboxTestFixture
2118
{
22-
private static readonly Random Random = new Random();
23-
2419
public AccountsIntegrationTest() : base(PlatformType.DefaultOAuth)
2520
{
2621
}
2722

28-
[Fact(Skip = "beta")]
23+
[Fact]
2924
public async Task ShouldCreateHostedOnboardingInvitationRequest()
3025
{
3126
string randomReference = RandomString(15);
3227
var entityRequest = new OnboardEntityRequest
3328
{
3429
Reference = randomReference,
35-
IsDraft = false,
36-
ContactDetails = new ContactDetails { Invitee = new Invitee { Email = "[email protected]" } }
30+
IsDraft = true,
31+
ContactDetails = new ContactDetails { Invitee = new Invitee { Email = GenerateRandomEmail() } }
3732
};
3833

3934
var response = await DefaultApi.AccountsClient().CreateEntity(entityRequest);
@@ -44,62 +39,170 @@ public async Task ShouldCreateHostedOnboardingInvitationRequest()
4439
}
4540

4641
[Fact]
47-
public async Task ShouldCreateCompany()
42+
public async Task ShouldCreateCompanyV2()
4843
{
4944
string randomReference = RandomString(15);
50-
var entityRequest = new OnboardEntityRequest
45+
var request = new OnboardEntityRequest
5146
{
5247
Reference = randomReference,
53-
Draft = true,
54-
Profile =
55-
new Profile
56-
{
57-
Urls = new List<string> { "http://example.com" },
58-
Mccs = new List<string> { "4814" },
59-
HoldingCurrencies = new List<Currency> { Currency.GBP }
60-
},
61-
ContactDetails =
62-
new ContactDetails
48+
Company =
49+
new Company
6350
{
64-
Phone = new Phone { CountryCode = "GI", Number = "656453654" },
65-
EmailAddresses = new EmailAddresses { Primary = null },
66-
Invitee = new Invitee { Email = null }
51+
LegalName = "Company " + RandomString(3),
52+
TradingName = "Trading " + RandomString(3),
53+
PrincipalAddress = GetAddress(),
54+
RegisteredAddress = GetAddress(),
55+
Representatives =
56+
new List<Representative>
57+
{
58+
new Representative
59+
{
60+
FirstName = RandomString(5),
61+
LastName = RandomString(5),
62+
Address = GetAddress(),
63+
Roles = new List<EntityRoles> { EntityRoles.Ubo },
64+
DateOfBirth = new DateOfBirth { Day = 1, Month = 1, Year = 1980 },
65+
},
66+
},
67+
BusinessRegistrationNumber = RandomBusinessRegistrationNumber(),
68+
DateOfIncorporation = new DateOfIncorporation { Day = 1, Month = 1, Year = 2001 },
69+
6770
},
71+
ContactDetails = new ContactDetails
72+
{
73+
Phone = new Phone { CountryCode = "GB", Number = RandomDigits(9) },
74+
EmailAddresses = new EmailAddresses { Primary = GenerateRandomEmail() },
75+
Invitee = new Invitee { Email = GenerateRandomEmail() }
76+
},
77+
Profile = new Profile
78+
{
79+
Urls = new List<string> { "http://example.com" },
80+
Mccs = new List<string> { "4814" },
81+
DefaultHoldingCurrency = Currency.GBP,
82+
HoldingCurrencies = new List<Currency> { Currency.GBP }
83+
},
84+
IsDraft = true
85+
};
86+
87+
var api = CheckoutSdk.Builder().OAuth()
88+
.ClientCredentials(
89+
System.Environment.GetEnvironmentVariable("CHECKOUT_DEFAULT_OAUTH_CLIENT_ID"),
90+
System.Environment.GetEnvironmentVariable("CHECKOUT_DEFAULT_OAUTH_CLIENT_SECRET"))
91+
.Scopes(OAuthScope.Accounts)
92+
.Environment(Environment.Sandbox)
93+
.HttpClientFactory(new CustomClientFactory("2.0"))
94+
.Build();
95+
96+
var response = await api.AccountsClient().CreateEntity(request);
97+
98+
response.ShouldNotBeNull();
99+
response.Id.ShouldNotBeNullOrEmpty();
100+
response.Reference.ShouldBe(randomReference);
101+
}
102+
103+
[Fact(Skip = "temporarily unavailable")]
104+
public async Task ShouldCreateCompanyV3()
105+
{
106+
string randomReference = RandomString(15);
107+
var request = new OnboardEntityRequest
108+
{
109+
Reference = randomReference,
68110
Company =
69111
new Company
70112
{
71-
LegalName = "string",
72-
TradingName = "string",
73-
BusinessRegistrationNumber = "AC123456",
113+
LegalName = "Company " + RandomString(3),
114+
TradingName = "Trading " + RandomString(3),
115+
BusinessRegistrationNumber = RandomBusinessRegistrationNumber(),
74116
DateOfIncorporation = new DateOfIncorporation { Day = 1, Month = 1, Year = 2001 },
75117
PrincipalAddress = GetAddress(),
76118
RegisteredAddress = GetAddress(),
77-
BusinessType = BusinessType.IndividualOrSoleProprietorship
78-
},
79-
ProcessingDetails =
80-
new ProcessingDetails
81-
{
82-
SettlementCountry = "GB",
83-
TargetCountries = new List<string> { "GB" },
84-
Currency = Currency.GBP
119+
Representatives =
120+
new List<Representative>
121+
{
122+
new Representative
123+
{
124+
Company = new Company
125+
{
126+
LegalName = "Company " + RandomString(3),
127+
TradingName = "Trading " + RandomString(3),
128+
RegisteredAddress = GetAddress()
129+
},
130+
OwnershipPercentage = 100,
131+
},
132+
new Representative
133+
{
134+
Individual = new Individual
135+
{
136+
FirstName = "FirstName " + RandomString(3),
137+
LastName = "LastName " + RandomString(3),
138+
DateOfBirth = new DateOfBirth { Day = 1, Month = 1, Year = 1980 },
139+
PlaceOfBirth = new PlaceOfBirth { Country = CountryCode.GB},
140+
Address = GetAddress(),
141+
EmailAddress = GenerateRandomEmail(),
142+
},
143+
Roles = new List<EntityRoles> { EntityRoles.AuthorisedSignatory, EntityRoles.Director },
144+
Documents = new Documents
145+
{
146+
IdentityVerification = new IdentityVerification()
147+
{
148+
Type = IdentityVerificationType.Passport,
149+
Front = "file_bonwzndueqrlwvv3kfcokug5iu"
150+
}
151+
},
152+
},
153+
},
154+
BusinessType = BusinessType.PublicLimitedCompany
85155
},
86-
Documents = new Documents
156+
Profile = new Profile
157+
{
158+
Urls = new List<string> { "http://example.com" },
159+
Mccs = new List<string> { "4814" },
160+
DefaultHoldingCurrency = Currency.GBP,
161+
HoldingCurrencies = new List<Currency> { Currency.GBP }
162+
},
163+
ContactDetails = new ContactDetails
164+
{
165+
Phone = new Phone { CountryCode = "GB", Number = RandomDigits(9) },
166+
EmailAddresses = new EmailAddresses { Primary = GenerateRandomEmail() },
167+
Invitee = new Invitee { Email = GenerateRandomEmail() }
168+
},
169+
Documents = new Documents()
87170
{
88171
ArticlesOfAssociation =
89172
new ArticlesOfAssociation()
90173
{
91174
Type = ArticlesOfAssociationType.ArticlesOfAssociation,
92-
Front = "stringstringstringstringstrings"
175+
Front = "file_aacb27em7gmj6e7dhxabazucqi"
93176
},
94-
ShareholderStructure = new ShareholderStructure()
95-
{
96-
Type = ShareholderStructureType.CertifiedShareholderStructure,
97-
Front = "stringstringstringstringstrings"
98-
},
99-
}
177+
ShareholderStructure =
178+
new ShareholderStructure()
179+
{
180+
Type = ShareholderStructureType.CertifiedShareholderStructure,
181+
Front = "file_bpme2tii3lsgshx4ghj3i4672q"
182+
},
183+
},
184+
ProcessingDetails = new ProcessingDetails
185+
{
186+
SettlementCountry = "GB",
187+
TargetCountries = new List<string> { "GB" },
188+
AnnualProcessingVolume = 0,
189+
AverageTransactionValue = 0,
190+
HighestTransactionValue = 0,
191+
Currency = Currency.GBP
192+
},
193+
IsDraft = false
100194
};
101195

102-
var response = await DefaultApi.AccountsClient().CreateEntity(entityRequest);
196+
var api = CheckoutSdk.Builder().OAuth()
197+
.ClientCredentials(
198+
System.Environment.GetEnvironmentVariable("CHECKOUT_DEFAULT_OAUTH_CLIENT_ID"),
199+
System.Environment.GetEnvironmentVariable("CHECKOUT_DEFAULT_OAUTH_CLIENT_SECRET"))
200+
.Scopes(OAuthScope.Accounts)
201+
.Environment(Environment.Sandbox)
202+
.HttpClientFactory(new CustomClientFactory("3.0"))
203+
.Build();
204+
205+
var response = await api.AccountsClient().CreateEntity(request);
103206

104207
response.ShouldNotBeNull();
105208
response.Id.ShouldNotBeNullOrEmpty();
@@ -412,13 +515,6 @@ private async Task ShouldCreateAndRetrievePaymentInstrumentCompany()
412515
queryResponse.Data.ShouldNotBeNull();
413516
}
414517

415-
private static string RandomString(int length)
416-
{
417-
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
418-
return new string(Enumerable.Repeat(chars, length)
419-
.Select(s => s[Random.Next(s.Length)]).ToArray());
420-
}
421-
422518
private static ContactDetails BuildContactDetails()
423519
{
424520
return new ContactDetails

0 commit comments

Comments
 (0)