diff --git a/__tests__/Api/BankAccountsApiTest.java b/__tests__/Api/BankAccountsApiTest.java index 895eb87e..77b0cb76 100755 --- a/__tests__/Api/BankAccountsApiTest.java +++ b/__tests__/Api/BankAccountsApiTest.java @@ -128,10 +128,10 @@ public void bankAccountGetTestCatchesExceptionWithResponseBody() throws ApiExcep @Test(enabled=false, groups={"Unit", "Verify", "Bank Account", "Valid"}) public void bankAccountVerifyTest() throws ApiException { BankAccountsApi bankAccountsApiMock = mock(BankAccountsApi.class); - BankAccount FakeBankAccount = new BankAccount(); + BankAccount FakeBankAccount = new BankAccount(); BankAccountVerify bankAccountVerify = new BankAccountVerify(); List amounts = new ArrayList(); - + FakeBankAccount.setId("bank_fakeId"); amounts.add(1); amounts.add(2); @@ -139,9 +139,39 @@ public void bankAccountVerifyTest() throws ApiException { when(bankAccountsApiMock.verify("bank_fakeId", bankAccountVerify)).thenReturn(FakeBankAccount); BankAccount response = bankAccountsApiMock.verify("bank_fakeId", bankAccountVerify); - + Assert.assertEquals(FakeBankAccount.getId(), response.getId()); } + + @Test(enabled=true, groups={"Unit", "Verify", "Bank Account", "Valid"}) + public void bankAccountVerifyWithDescriptorCodeTest() throws ApiException { + BankAccountsApi bankAccountsApiMock = mock(BankAccountsApi.class); + BankAccount fakeBankAccount = new BankAccount(); + BankAccountVerify bankAccountVerify = new BankAccountVerify(); + + fakeBankAccount.setId("bank_fakeId"); + bankAccountVerify.setDescriptorCode("SM11AA"); + + when(bankAccountsApiMock.verify("bank_fakeId", bankAccountVerify)).thenReturn(fakeBankAccount); + BankAccount response = bankAccountsApiMock.verify("bank_fakeId", bankAccountVerify); + + Assert.assertEquals(fakeBankAccount.getId(), response.getId()); + } + + @Test(enabled=true, groups={"Unit", "Bank Account", "Valid"}) + public void bankAccountHasMicrodepositTypeTest() throws ApiException { + BankAccount account = new BankAccount(); + account.setId("bank_fakeId"); + + account.setMicrodepositType("amounts"); + Assert.assertEquals(account.getMicrodepositType(), "amounts"); + + account.setMicrodepositType("descriptor_code"); + Assert.assertEquals(account.getMicrodepositType(), "descriptor_code"); + + account.setMicrodepositType(null); + Assert.assertNull(account.getMicrodepositType()); + } @Test(enabled=true, groups={"Unit", "List", "Bank Account", "Valid"}) public void bankAccountsListTest() throws ApiException { diff --git a/__tests__/Integration/BankAccountsApiSpecTest.java b/__tests__/Integration/BankAccountsApiSpecTest.java index 387f960d..ee4e0e03 100755 --- a/__tests__/Integration/BankAccountsApiSpecTest.java +++ b/__tests__/Integration/BankAccountsApiSpecTest.java @@ -128,6 +128,42 @@ public void bankAccountVerifyTest() throws ApiException { createdBankAccounts.add(response); } + @Test( + enabled=true, + groups={"Integration", "Verify", "Bank Account", "Valid"} + ) + public void bankAccountVerifyWithDescriptorCodeTest() throws ApiException { + BankAccount created = validApi.create(BankAccountWritableList.get(0)); + createdBankAccounts.add(created); + + BankAccountVerify bv = new BankAccountVerify(); + bv.setDescriptorCode("SM11AA"); + + BankAccount response = validApi.verify(created.getId(), bv); + + Assert.assertNotNull(response); + Assert.assertNotNull(response.getId()); + Assert.assertEquals(response.getId(), created.getId()); + } + + @Test( + enabled=true, + groups={"Integration", "Get", "Bank Account", "Valid"} + ) + public void bankAccountHasMicrodepositTypeTest() throws ApiException { + BankAccount created = validApi.create(BankAccountWritableList.get(0)); + createdBankAccounts.add(created); + + BankAccount retrieved = validApi.get(created.getId()); + + Assert.assertNotNull(retrieved); + String mdType = retrieved.getMicrodepositType(); + Assert.assertTrue( + mdType == null || mdType.equals("amounts") || mdType.equals("descriptor_code"), + "microdeposit_type should be 'amounts', 'descriptor_code', or null but was: " + mdType + ); + } + @Test( enabled=true, expectedExceptions={ApiException.class}, diff --git a/__tests__/Model/BankAccountTest.java b/__tests__/Model/BankAccountTest.java index 4d5054e3..7a682c77 100755 --- a/__tests__/Model/BankAccountTest.java +++ b/__tests__/Model/BankAccountTest.java @@ -33,6 +33,8 @@ public Object[][] bankAccountDpMethod() { {"deleted", false}, {"deleted", true}, {"object", BankAccount.ObjectEnum.BANK_ACCOUNT}, + {"microdeposit_type", "amounts"}, + {"microdeposit_type", "descriptor_code"}, }; } @@ -125,6 +127,12 @@ public void bankAccountTestWithProvidedValue(String prop, Object val) throws Exc Assert.assertEquals(rec.getObject(), castedVal); break; } + case "microdeposit_type": { + String castedVal = (String)val; + rec.setMicrodepositType(castedVal); + Assert.assertEquals(rec.getMicrodepositType(), castedVal); + break; + } default: throw new Exception("Wrong prop name: " + prop); } diff --git a/__tests__/Model/BankAccountVerifyTest.java b/__tests__/Model/BankAccountVerifyTest.java index b726c3e9..ba568237 100755 --- a/__tests__/Model/BankAccountVerifyTest.java +++ b/__tests__/Model/BankAccountVerifyTest.java @@ -10,7 +10,7 @@ public class BankAccountVerifyTest { @Test(enabled=true) - public void bankAccountVerifyTest() { + public void bankAccountVerifyWithAmountsTest() { BankAccountVerify rec = new BankAccountVerify(); List amounts = new ArrayList(); @@ -18,5 +18,45 @@ public void bankAccountVerifyTest() { amounts.add(2); rec.setAmounts(amounts); Assert.assertEquals(rec.getAmounts(), amounts); + Assert.assertNull(rec.getDescriptorCode()); + Assert.assertTrue(rec.isValid()); + } + + @Test(enabled=true) + public void bankAccountVerifyWithDescriptorCodeTest() { + BankAccountVerify rec = new BankAccountVerify(); + rec.setDescriptorCode("SM11AA"); + Assert.assertEquals(rec.getDescriptorCode(), "SM11AA"); + Assert.assertNull(rec.getAmounts()); + Assert.assertTrue(rec.isValid()); + } + + @Test(enabled=true) + public void bankAccountVerifyInvalidWhenNeitherSetTest() { + BankAccountVerify rec = new BankAccountVerify(); + Assert.assertFalse(rec.isValid()); + } + + @Test(enabled=true) + public void bankAccountVerifyInvalidWhenBothSetTest() { + BankAccountVerify rec = new BankAccountVerify(); + List amounts = new ArrayList(); + amounts.add(1); + amounts.add(2); + rec.setAmounts(amounts); + rec.setDescriptorCode("SM11AA"); + Assert.assertFalse(rec.isValid()); + } + + @Test(enabled=true, expectedExceptions = {IllegalArgumentException.class}) + public void bankAccountVerifyInvalidDescriptorCodePatternTest() { + BankAccountVerify rec = new BankAccountVerify(); + rec.setDescriptorCode("INVALID"); + } + + @Test(enabled=true, expectedExceptions = {IllegalArgumentException.class}) + public void bankAccountVerifyDescriptorCodeTooShortTest() { + BankAccountVerify rec = new BankAccountVerify(); + rec.setDescriptorCode("SM1"); } } diff --git a/pom.xml b/pom.xml index 05839b41..28aadfda 100755 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ com.lob lob-java jar - 13.4.8-SNAPSHOT + 13.5.0-SNAPSHOT ${project.groupId}:${project.artifactId} Parent pom for the Lob API Java Wrapper https://github.com/lob/lob-java @@ -64,7 +64,6 @@ org.sonatype.plugins nexus-staging-maven-plugin 1.7.0 - true ossrh https://oss.sonatype.org/ diff --git a/src/main/java/com/lob/model/BankAccount.java b/src/main/java/com/lob/model/BankAccount.java index be7dcb35..266a9749 100644 --- a/src/main/java/com/lob/model/BankAccount.java +++ b/src/main/java/com/lob/model/BankAccount.java @@ -403,21 +403,37 @@ public ObjectEnum read(final JsonReader jsonReader) throws IOException { public static final String SERIALIZED_NAME_OBJECT = "object"; @SerializedName(SERIALIZED_NAME_OBJECT) - + private ObjectEnum _object = ObjectEnum.BANK_ACCOUNT; /** * Get _object * @return _object **/ - + @javax.annotation.Nonnull - + @ApiModelProperty(required = true, value = "") - + public ObjectEnum getObject() { return _object; } + + public static final String SERIALIZED_NAME_MICRODEPOSIT_TYPE = "microdeposit_type"; + + @SerializedName(SERIALIZED_NAME_MICRODEPOSIT_TYPE) + private String microdepositType; + + /** + * 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 microdepositType + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "The type of microdeposit verification required. Present when verified is false; null once the account is verified.") + public String getMicrodepositType() { + return microdepositType; + } @@ -632,6 +648,10 @@ public void setObject(ObjectEnum _object) { this._object = _object; } + public void setMicrodepositType(String microdepositType) { + this.microdepositType = microdepositType; + } + @Override @@ -656,7 +676,8 @@ public boolean equals(Object o) { Objects.equals(this.dateCreated, bankAccount.dateCreated) && Objects.equals(this.dateModified, bankAccount.dateModified) && Objects.equals(this.deleted, bankAccount.deleted) && - Objects.equals(this._object, bankAccount._object); + Objects.equals(this._object, bankAccount._object) && + Objects.equals(this.microdepositType, bankAccount.microdepositType); } private static boolean equalsNullable(JsonNullable a, JsonNullable b) { @@ -665,7 +686,7 @@ private static boolean equalsNullable(JsonNullable a, JsonNullable b) @Override public int hashCode() { - return Objects.hash(description, routingNumber, accountNumber, accountType, signatory, metadata, id, signatureUrl, bankName, verified, dateCreated, dateModified, deleted, _object); + return Objects.hash(description, routingNumber, accountNumber, accountType, signatory, metadata, id, signatureUrl, bankName, verified, dateCreated, dateModified, deleted, _object, microdepositType); } private static int hashCodeNullable(JsonNullable a) { @@ -693,6 +714,7 @@ public String toString() { sb.append(" dateModified: ").append(toIndentedString(dateModified)).append("\n"); sb.append(" deleted: ").append(toIndentedString(deleted)).append("\n"); sb.append(" _object: ").append(toIndentedString(_object)).append("\n"); + sb.append(" microdepositType: ").append(toIndentedString(microdepositType)).append("\n"); sb.append("}"); return sb.toString(); } @@ -713,6 +735,7 @@ public Map toMap() { localMap.put("date_modified", dateModified); localMap.put("deleted", deleted); localMap.put("object", _object); + localMap.put("microdeposit_type", microdepositType); return localMap; } diff --git a/src/main/java/com/lob/model/BankAccountVerify.java b/src/main/java/com/lob/model/BankAccountVerify.java index 357fff72..a5268bc5 100644 --- a/src/main/java/com/lob/model/BankAccountVerify.java +++ b/src/main/java/com/lob/model/BankAccountVerify.java @@ -45,26 +45,41 @@ public List getAmounts() { return this.amounts; } - - /* - public BankAccountVerify amounts(List amounts) { - - this.amounts = amounts; - return this; - } - */ - public BankAccountVerify addAmountsItem(Integer amountsItem) { + if (this.amounts == null) { + this.amounts = new ArrayList(); + } this.amounts.add(amountsItem); return this; } - public void setAmounts(List amounts) { this.amounts = amounts; } + public static final String SERIALIZED_NAME_DESCRIPTOR_CODE = "descriptor_code"; + private static final java.util.regex.Pattern DESCRIPTOR_CODE_PATTERN = + java.util.regex.Pattern.compile("^SM[a-zA-Z0-9]{4}$"); + + @SerializedName(SERIALIZED_NAME_DESCRIPTOR_CODE) + private String descriptorCode; + + public String getDescriptorCode() { + return this.descriptorCode; + } + + public void setDescriptorCode(String descriptorCode) { + if (descriptorCode != null && !DESCRIPTOR_CODE_PATTERN.matcher(descriptorCode).matches()) { + throw new IllegalArgumentException("Invalid descriptor_code: must match ^SM[a-zA-Z0-9]{4}$"); + } + this.descriptorCode = descriptorCode; + } + public boolean isValid() { + boolean hasAmounts = amounts != null && !amounts.isEmpty(); + boolean hasDescriptorCode = descriptorCode != null && !descriptorCode.isEmpty(); + return hasAmounts ^ hasDescriptorCode; + } @Override public boolean equals(Object o) { @@ -75,12 +90,13 @@ public boolean equals(Object o) { return false; } BankAccountVerify bankAccountVerify = (BankAccountVerify) o; - return Objects.equals(this.amounts, bankAccountVerify.amounts); + return Objects.equals(this.amounts, bankAccountVerify.amounts) && + Objects.equals(this.descriptorCode, bankAccountVerify.descriptorCode); } @Override public int hashCode() { - return Objects.hash(amounts); + return Objects.hash(amounts, descriptorCode); } @Override @@ -88,6 +104,7 @@ public String toString() { StringBuilder sb = new StringBuilder(); sb.append("{\n"); sb.append(" amounts: ").append(toIndentedString(amounts)).append("\n"); + sb.append(" descriptorCode: ").append(toIndentedString(descriptorCode)).append("\n"); sb.append("}"); return sb.toString(); } @@ -95,6 +112,7 @@ public String toString() { public Map toMap() { Map localMap = new HashMap(); localMap.put("amounts", amounts); + localMap.put("descriptor_code", descriptorCode); return localMap; }