Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "lob/lob-php",
"version": "4.2.8",
"version": "4.3.0",
"description": "The Lob API is organized around REST. Our API is designed to have predictable, resource-oriented URLs and uses HTTP response codes to indicate any API errors.",
"keywords": [
"openapitools",
Expand Down
42 changes: 37 additions & 5 deletions lib/Model/BankAccount.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ class BankAccount implements ModelInterface, ArrayAccess, \JsonSerializable
'date_created' => '\DateTime',
'date_modified' => '\DateTime',
'deleted' => 'bool',
'object' => 'string'
'object' => 'string',
'microdeposit_type' => 'string'
];

/**
Expand All @@ -97,7 +98,8 @@ class BankAccount implements ModelInterface, ArrayAccess, \JsonSerializable
'date_created' => 'date-time',
'date_modified' => 'date-time',
'deleted' => null,
'object' => null
'object' => null,
'microdeposit_type' => null
];

/**
Expand Down Expand Up @@ -140,7 +142,8 @@ public static function openAPIFormats()
'date_created' => 'date_created',
'date_modified' => 'date_modified',
'deleted' => 'deleted',
'object' => 'object'
'object' => 'object',
'microdeposit_type' => 'microdeposit_type'
];

/**
Expand All @@ -162,7 +165,8 @@ public static function openAPIFormats()
'date_created' => 'setDateCreated',
'date_modified' => 'setDateModified',
'deleted' => 'setDeleted',
'object' => 'setObject'
'object' => 'setObject',
'microdeposit_type' => 'setMicrodepositType'
];

/**
Expand All @@ -184,7 +188,8 @@ public static function openAPIFormats()
'date_created' => 'getDateCreated',
'date_modified' => 'getDateModified',
'deleted' => 'getDeleted',
'object' => 'getObject'
'object' => 'getObject',
'microdeposit_type' => 'getMicrodepositType'
];

/**
Expand Down Expand Up @@ -286,6 +291,7 @@ public function __construct(array $data = null)
$this->container['date_modified'] = $data['date_modified'] ?? null;
$this->container['deleted'] = $data['deleted'] ?? null;
$this->container['object'] = $data['object'] ?? null;
$this->container['microdeposit_type'] = $data['microdeposit_type'] ?? null;
}

/**
Expand Down Expand Up @@ -836,6 +842,32 @@ public function setObject($object)

return $this;
}


/**
* Gets microdeposit_type
*
* @return string|null
*/
public function getMicrodepositType()
{
return $this->container['microdeposit_type'];
}

/**
* Sets microdeposit_type
*
* @param string|null $microdeposit_type The type of microdeposit verification required. Present when verified is false; null once the account is verified. Use this to determine which field to submit to the verify endpoint: amounts or descriptor_code.
*
* @return self
*/
public function setMicrodepositType($microdeposit_type)
{
$this->container['microdeposit_type'] = $microdeposit_type;

return $this;
}

/**
* Returns true if offset exists. False otherwise.
*
Expand Down
72 changes: 57 additions & 15 deletions lib/Model/BankAccountVerify.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ class BankAccountVerify implements ModelInterface, ArrayAccess, \JsonSerializabl
* @var string[]
*/
protected static $openAPITypes = [
'amounts' => 'int[]'
'amounts' => 'int[]',
'descriptor_code' => 'string'
];

/**
Expand All @@ -71,7 +72,8 @@ class BankAccountVerify implements ModelInterface, ArrayAccess, \JsonSerializabl
* @psalm-var array<string, string|null>
*/
protected static $openAPIFormats = [
'amounts' => null
'amounts' => null,
'descriptor_code' => null
];

/**
Expand Down Expand Up @@ -101,7 +103,8 @@ public static function openAPIFormats()
* @var string[]
*/
protected static $attributeMap = [
'amounts' => 'amounts'
'amounts' => 'amounts',
'descriptor_code' => 'descriptor_code'
];

/**
Expand All @@ -110,7 +113,8 @@ public static function openAPIFormats()
* @var string[]
*/
protected static $setters = [
'amounts' => 'setAmounts'
'amounts' => 'setAmounts',
'descriptor_code' => 'setDescriptorCode'
];

/**
Expand All @@ -119,7 +123,8 @@ public static function openAPIFormats()
* @var string[]
*/
protected static $getters = [
'amounts' => 'getAmounts'
'amounts' => 'getAmounts',
'descriptor_code' => 'getDescriptorCode'
];

/**
Expand Down Expand Up @@ -180,6 +185,7 @@ public function getModelName()
public function __construct(array $data = null)
{
$this->container['amounts'] = $data['amounts'] ?? null;
$this->container['descriptor_code'] = $data['descriptor_code'] ?? null;
}

/**
Expand All @@ -192,19 +198,26 @@ public function listInvalidProperties()
$invalidProperties = [];

if (!method_exists($this, 'getId') || (!empty($this->getId()) && strpos($this->getId(), "fakeId") === False)) {
if ($this->container['amounts'] === null) {
$invalidProperties[] = "'amounts' can't be null";
}
}
if (!method_exists($this, 'getId') || (!empty($this->getId()) && strpos($this->getId(), "fakeId") === False)) {
if ((count($this->container['amounts']) > 2)) {
$invalidProperties[] = "invalid value for 'amounts', number of items must be less than or equal to 2.";
$hasAmounts = $this->container['amounts'] !== null;
$hasDescriptorCode = $this->container['descriptor_code'] !== null;

if (!$hasAmounts && !$hasDescriptorCode) {
$invalidProperties[] = "one of 'amounts' or 'descriptor_code' must be provided";
}

if ((count($this->container['amounts']) < 2)) {
$invalidProperties[] = "invalid value for 'amounts', number of items must be greater than or equal to 2.";
if ($hasAmounts && $hasDescriptorCode) {
$invalidProperties[] = "only one of 'amounts' or 'descriptor_code' may be provided";
}

if ($hasAmounts) {
if ((count($this->container['amounts']) > 2)) {
$invalidProperties[] = "invalid value for 'amounts', number of items must be less than or equal to 2.";
}

if ((count($this->container['amounts']) < 2)) {
$invalidProperties[] = "invalid value for 'amounts', number of items must be greater than or equal to 2.";
}
}
}
return $invalidProperties;
}
Expand Down Expand Up @@ -253,14 +266,43 @@ public function setAmounts($amounts)
$this->container['amounts'] = [];
if ($amounts) {
foreach ($amounts as $point) {

$deserializedData = (int) $point;
array_push($this->container['amounts'], $deserializedData);
}
}

return $this;
}

/**
* Gets descriptor_code
*
* @return string|null
*/
public function getDescriptorCode()
{
return $this->container['descriptor_code'];
}

/**
* Sets descriptor_code
*
* @param string|null $descriptor_code The 6-character code (beginning with SM) from the bank statement descriptor of the single $0.01 microdeposit. Required when microdeposit_type is descriptor_code.
*
* @return self
*/
public function setDescriptorCode($descriptor_code)
{
if (!method_exists($this, 'getId') || (!empty($this->getId()) && strpos($this->getId(), "fakeId") === False)) {
if (!is_null($descriptor_code) && !preg_match("/^SM[a-zA-Z0-9]{4}$/", $descriptor_code)) {
throw new \InvalidArgumentException('invalid value for $descriptor_code when calling BankAccountVerify., must conform to the pattern /^SM[a-zA-Z0-9]{4}$/.');
}
}
$this->container['descriptor_code'] = $descriptor_code;

return $this;
}
/**
* Returns true if offset exists. False otherwise.
*
Expand Down
27 changes: 27 additions & 0 deletions test/Integration/BankAccountsApiSpecTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -360,4 +360,31 @@ public function testDelete404()
$this->expectExceptionMessageMatches("/bank account not found/");
$badDeletion = self::$bankApi->delete("bank_NONEXISTENT");
}

public function testVerifyWithDescriptorCode200()
{
try {
$createdBankAccount = self::$bankApi->create(self::$writableBankAcc);
$descriptorVerify = new BankAccountVerify();
$descriptorVerify->setDescriptorCode("SM11AA");
$verifiedBankAccount = self::$bankApi->verify($createdBankAccount->getId(), $descriptorVerify);
$this->assertMatchesRegularExpression("/bank_/", $verifiedBankAccount->getId());
array_push($this->idsForCleanup, $createdBankAccount->getId());
} catch (\Exception $e) {
throw new \Exception($e->getMessage());
}
}

public function testBankAccountHasMicrodepositType()
{
try {
$createdBankAccount = self::$bankApi->create(self::$writableBankAcc);
$retrievedBankAccount = self::$bankApi->get($createdBankAccount->getId());
$this->assertNotNull($retrievedBankAccount->getMicrodepositType());
$this->assertContains($retrievedBankAccount->getMicrodepositType(), ["amounts", "descriptor_code"]);
array_push($this->idsForCleanup, $createdBankAccount->getId());
} catch (\Exception $e) {
throw new \Exception($e->getMessage());
}
}
}
81 changes: 81 additions & 0 deletions test/Unit/BankAccountsApiUnitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -836,4 +836,85 @@ public function testVerifyFailStatusCode()
echo 'Caught exception: ', $instantiationError->getMessage(), "\n";
}
}

/**
* @group unit
* @group bankAccounts
*/
public function testVerifyWithDescriptorCode()
{
$guzzleMock = new MockHandler();
$handlerStack = HandlerStack::create($guzzleMock);
$client = new Client(['handler' => $handlerStack]);
$config = new Configuration();
$config->setApiKey('basic', 'Totally Fake Key');
$bankAccountsApi = new BankAccountsApi($config, $client);

$guzzleMock->append(new Response(200, [], self::$mockBankAccountResponse));
try {
$verify = new BankAccountVerify(array("descriptor_code" => "SM11AA"));
$happyPath = $bankAccountsApi->verify(self::$mockBankId, $verify);
$this->assertEquals($happyPath->getId(), self::$mockBankId);
} catch (Exception $retrieveError) {
echo 'Caught exception: ', $retrieveError->getMessage(), "\n";
}
}

/**
* @group unit
* @group bankAccounts
*/
public function testVerifyFailBothAmountsAndDescriptorCode()
{
$verify = new BankAccountVerify(array("amounts" => [1, 2], "descriptor_code" => "SM11AA"));
$invalidProps = $verify->listInvalidProperties();
$this->assertNotEmpty($invalidProps);
$this->assertStringContainsString("only one of", $invalidProps[0]);
$this->assertFalse($verify->valid());
}

/**
* @group unit
* @group bankAccounts
*/
public function testVerifyFailNeitherAmountsNorDescriptorCode()
{
$verify = new BankAccountVerify();
$invalidProps = $verify->listInvalidProperties();
$this->assertNotEmpty($invalidProps);
$this->assertStringContainsString("one of 'amounts' or 'descriptor_code' must be provided", $invalidProps[0]);
}

/**
* @group unit
* @group bankAccounts
*/
public function testVerifyFailInvalidDescriptorCodePattern()
{
try {
$this->expectException(\InvalidArgumentException::class);
$verify = new BankAccountVerify();
$verify->setDescriptorCode("INVALID");
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
}

/**
* @group unit
* @group bankAccounts
*/
public function testBankAccountHasMicrodepositType()
{
$account = new BankAccount();
$account->setId(self::$mockBankId);
$account->setMicrodepositType("amounts");
$this->assertEquals("amounts", $account->getMicrodepositType());

$account->setMicrodepositType("descriptor_code");
$this->assertEquals("descriptor_code", $account->getMicrodepositType());

$account->setMicrodepositType(null);
$this->assertNull($account->getMicrodepositType());
}
}
Loading