Skip to content

Commit

Permalink
feat: update accounts API and integration tests
Browse files Browse the repository at this point in the history
- 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.
  • Loading branch information
armando-rodriguez-cko committed Feb 5, 2025
1 parent 55d2875 commit 72be1aa
Show file tree
Hide file tree
Showing 7 changed files with 221 additions and 61 deletions.
18 changes: 14 additions & 4 deletions src/CheckoutSdk/Accounts/Entities/Common/Company/EntityRoles.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,19 @@ namespace Checkout.Accounts.Entities.Common.Company
{
public enum EntityRoles
{
[EnumMember(Value = "ubo")] Ubo,
[EnumMember(Value = "legal_representative")] LegalRepresentative,
[EnumMember(Value = "authorised_signatory")] AuthorisedSignatory,
[EnumMember(Value = "control_person")] ControlPerson,
[EnumMember(Value = "ubo")]
Ubo,

[EnumMember(Value = "authorised_signatory")]
AuthorisedSignatory,

[EnumMember(Value = "director")]
Director,

[EnumMember(Value = "control_person")]
ControlPerson,

[EnumMember(Value = "legal_representative")]
LegalRepresentative,
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ public class OnboardEntityRequest

public ProcessingDetails ProcessingDetails { get; set; }

public bool Draft { get; set; }
public bool IsDraft { get; set; }
public bool? Draft { get; set; }

public bool? IsDraft { get; set; }

public Individual Individual { get; set; }

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
using Newtonsoft.Json;
using System.Collections.Generic;

namespace Checkout.Accounts.Entities.Request
{
public class OnboardSubEntityRequest
{
[JsonExtensionData]
public IDictionary<string, object> Request { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ namespace Checkout.Accounts.Entities.Response
{
public enum OnboardingStatus
{
[EnumMember(Value = "draft")]
Draft,

[EnumMember(Value = "active")]
Active,

Expand Down
10 changes: 5 additions & 5 deletions test/CheckoutSdkTest/Accounts/AccountsClientTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ private async Task ShouldReinviteSubEntityMember()
{
Response = new Dictionary<string, object>
{
{ "custom_field_1", "value_1" },
{ "custom_field_2", 12345 }
{ "Id", "sub_entity_id" },
{ "custom_field_1", 12345 }
}
};

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

response.ShouldNotBeNull();
response.Response.ShouldNotBeNull();
response.Response.ContainsKey("Id").ShouldBeTrue();
response.Response["Id"].ShouldBe("sub_entity_id");
response.Response.ContainsKey("custom_field_1").ShouldBeTrue();
response.Response["custom_field_1"].ShouldBe("value_1");
response.Response.ContainsKey("custom_field_2").ShouldBeTrue();
response.Response["custom_field_2"].ShouldBe(12345);
response.Response["custom_field_1"].ShouldBe(12345);
}

[Fact]
Expand Down
196 changes: 146 additions & 50 deletions test/CheckoutSdkTest/Accounts/AccountsIntegrationTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,29 @@
using Checkout.Common;
using Checkout.Instruments;
using Shouldly;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Mime;
using System.Reflection.Metadata;
using System.Threading.Tasks;
using Xunit;

namespace Checkout.Accounts
{
public class AccountsIntegrationTest : SandboxTestFixture
{
private static readonly Random Random = new Random();

public AccountsIntegrationTest() : base(PlatformType.DefaultOAuth)
{
}

[Fact(Skip = "beta")]
[Fact]
public async Task ShouldCreateHostedOnboardingInvitationRequest()
{
string randomReference = RandomString(15);
var entityRequest = new OnboardEntityRequest
{
Reference = randomReference,
IsDraft = false,
ContactDetails = new ContactDetails { Invitee = new Invitee { Email = "[email protected]" } }
IsDraft = true,
ContactDetails = new ContactDetails { Invitee = new Invitee { Email = GenerateRandomEmail() } }
};

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

[Fact]
public async Task ShouldCreateCompany()
public async Task ShouldCreateCompanyV2()
{
string randomReference = RandomString(15);
var entityRequest = new OnboardEntityRequest
var request = new OnboardEntityRequest
{
Reference = randomReference,
Draft = true,
Profile =
new Profile
{
Urls = new List<string> { "http://example.com" },
Mccs = new List<string> { "4814" },
HoldingCurrencies = new List<Currency> { Currency.GBP }
},
ContactDetails =
new ContactDetails
Company =
new Company
{
Phone = new Phone { CountryCode = "GI", Number = "656453654" },
EmailAddresses = new EmailAddresses { Primary = null },
Invitee = new Invitee { Email = null }
LegalName = "Company " + RandomString(3),
TradingName = "Trading " + RandomString(3),
PrincipalAddress = GetAddress(),
RegisteredAddress = GetAddress(),
Representatives =
new List<Representative>
{
new Representative
{
FirstName = RandomString(5),
LastName = RandomString(5),
Address = GetAddress(),
Roles = new List<EntityRoles> { EntityRoles.Ubo },
DateOfBirth = new DateOfBirth { Day = 1, Month = 1, Year = 1980 },
},
},
BusinessRegistrationNumber = RandomBusinessRegistrationNumber(),
DateOfIncorporation = new DateOfIncorporation { Day = 1, Month = 1, Year = 2001 },

},
ContactDetails = new ContactDetails
{
Phone = new Phone { CountryCode = "GB", Number = RandomDigits(9) },
EmailAddresses = new EmailAddresses { Primary = GenerateRandomEmail() },
Invitee = new Invitee { Email = GenerateRandomEmail() }
},
Profile = new Profile
{
Urls = new List<string> { "http://example.com" },
Mccs = new List<string> { "4814" },
DefaultHoldingCurrency = Currency.GBP,
HoldingCurrencies = new List<Currency> { Currency.GBP }
},
IsDraft = true
};

var api = CheckoutSdk.Builder().OAuth()
.ClientCredentials(
System.Environment.GetEnvironmentVariable("CHECKOUT_DEFAULT_OAUTH_CLIENT_ID"),
System.Environment.GetEnvironmentVariable("CHECKOUT_DEFAULT_OAUTH_CLIENT_SECRET"))
.Scopes(OAuthScope.Accounts)
.Environment(Environment.Sandbox)
.HttpClientFactory(new CustomClientFactory("2.0"))
.Build();

var response = await api.AccountsClient().CreateEntity(request);

response.ShouldNotBeNull();
response.Id.ShouldNotBeNullOrEmpty();
response.Reference.ShouldBe(randomReference);
}

[Fact(Skip = "temporarily unavailable")]
public async Task ShouldCreateCompanyV3()
{
string randomReference = RandomString(15);
var request = new OnboardEntityRequest
{
Reference = randomReference,
Company =
new Company
{
LegalName = "string",
TradingName = "string",
BusinessRegistrationNumber = "AC123456",
LegalName = "Company " + RandomString(3),
TradingName = "Trading " + RandomString(3),
BusinessRegistrationNumber = RandomBusinessRegistrationNumber(),
DateOfIncorporation = new DateOfIncorporation { Day = 1, Month = 1, Year = 2001 },
PrincipalAddress = GetAddress(),
RegisteredAddress = GetAddress(),
BusinessType = BusinessType.IndividualOrSoleProprietorship
},
ProcessingDetails =
new ProcessingDetails
{
SettlementCountry = "GB",
TargetCountries = new List<string> { "GB" },
Currency = Currency.GBP
Representatives =
new List<Representative>
{
new Representative
{
Company = new Company
{
LegalName = "Company " + RandomString(3),
TradingName = "Trading " + RandomString(3),
RegisteredAddress = GetAddress()
},
OwnershipPercentage = 100,
},
new Representative
{
Individual = new Individual
{
FirstName = "FirstName " + RandomString(3),
LastName = "LastName " + RandomString(3),
DateOfBirth = new DateOfBirth { Day = 1, Month = 1, Year = 1980 },
PlaceOfBirth = new PlaceOfBirth { Country = CountryCode.GB},
Address = GetAddress(),
EmailAddress = GenerateRandomEmail(),
},
Roles = new List<EntityRoles> { EntityRoles.AuthorisedSignatory, EntityRoles.Director },
Documents = new Documents
{
IdentityVerification = new IdentityVerification()
{
Type = IdentityVerificationType.Passport,
Front = "file_bonwzndueqrlwvv3kfcokug5iu"
}
},
},
},
BusinessType = BusinessType.PublicLimitedCompany
},
Documents = new Documents
Profile = new Profile
{
Urls = new List<string> { "http://example.com" },
Mccs = new List<string> { "4814" },
DefaultHoldingCurrency = Currency.GBP,
HoldingCurrencies = new List<Currency> { Currency.GBP }
},
ContactDetails = new ContactDetails
{
Phone = new Phone { CountryCode = "GB", Number = RandomDigits(9) },
EmailAddresses = new EmailAddresses { Primary = GenerateRandomEmail() },
Invitee = new Invitee { Email = GenerateRandomEmail() }
},
Documents = new Documents()
{
ArticlesOfAssociation =
new ArticlesOfAssociation()
{
Type = ArticlesOfAssociationType.ArticlesOfAssociation,
Front = "stringstringstringstringstrings"
Front = "file_aacb27em7gmj6e7dhxabazucqi"
},
ShareholderStructure = new ShareholderStructure()
{
Type = ShareholderStructureType.CertifiedShareholderStructure,
Front = "stringstringstringstringstrings"
},
}
ShareholderStructure =
new ShareholderStructure()
{
Type = ShareholderStructureType.CertifiedShareholderStructure,
Front = "file_bpme2tii3lsgshx4ghj3i4672q"
},
},
ProcessingDetails = new ProcessingDetails
{
SettlementCountry = "GB",
TargetCountries = new List<string> { "GB" },
AnnualProcessingVolume = 0,
AverageTransactionValue = 0,
HighestTransactionValue = 0,
Currency = Currency.GBP
},
IsDraft = false
};

var response = await DefaultApi.AccountsClient().CreateEntity(entityRequest);
var api = CheckoutSdk.Builder().OAuth()
.ClientCredentials(
System.Environment.GetEnvironmentVariable("CHECKOUT_DEFAULT_OAUTH_CLIENT_ID"),
System.Environment.GetEnvironmentVariable("CHECKOUT_DEFAULT_OAUTH_CLIENT_SECRET"))
.Scopes(OAuthScope.Accounts)
.Environment(Environment.Sandbox)
.HttpClientFactory(new CustomClientFactory("3.0"))
.Build();

var response = await api.AccountsClient().CreateEntity(request);

response.ShouldNotBeNull();
response.Id.ShouldNotBeNullOrEmpty();
Expand Down Expand Up @@ -412,13 +515,6 @@ private async Task ShouldCreateAndRetrievePaymentInstrumentCompany()
queryResponse.Data.ShouldNotBeNull();
}

private static string RandomString(int length)
{
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
return new string(Enumerable.Repeat(chars, length)
.Select(s => s[Random.Next(s.Length)]).ToArray());
}

private static ContactDetails BuildContactDetails()
{
return new ContactDetails
Expand Down
Loading

0 comments on commit 72be1aa

Please sign in to comment.