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
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package com.plaid.client.request;

import com.plaid.client.internal.gson.RequiredField;
import com.plaid.client.request.common.BasePublicRequest;
import com.plaid.client.request.common.Product;
import java.util.ArrayList;
import java.util.Arrays;

import static com.plaid.client.internal.Util.notEmpty;
import static com.plaid.client.internal.Util.notNull;

/**
Expand All @@ -11,10 +16,24 @@
*/
public final class InstitutionsGetByIdRequest extends BasePublicRequest {
private String institutionId;
private Options options;

public InstitutionsGetByIdRequest(String institutionId) {
notNull(institutionId, "institutionId");

this.institutionId = institutionId;
}

public InstitutionsGetByIdRequest withIncludeInstitutionData(boolean includeInstitutionData) {
this.options = new Options(includeInstitutionData);
return this;
}

private static class Options {
private boolean includeInstitutionData;

private Options(boolean includeInstitutionData) {
this.includeInstitutionData = includeInstitutionData;
}
}
}
16 changes: 16 additions & 0 deletions src/main/java/com/plaid/client/request/InstitutionsGetRequest.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.plaid.client.request;

import com.plaid.client.request.common.BaseClientRequest;
import java.util.List;

import static com.plaid.client.internal.Util.isBetween;
import static com.plaid.client.internal.Util.notNull;

/**
* Request for the /institutions/get endpoint.
Expand All @@ -12,6 +14,7 @@
public final class InstitutionsGetRequest extends BaseClientRequest {
private Integer count;
private Integer offset;
private Options options;

public InstitutionsGetRequest(Integer count, Integer offset) {
isBetween(count, 1, 500, "count");
Expand All @@ -20,4 +23,17 @@ public InstitutionsGetRequest(Integer count, Integer offset) {
this.count = count;
this.offset = offset;
}

public InstitutionsGetRequest withIncludeInstitutionData(boolean includeInstitutionData) {
this.options = new Options(includeInstitutionData);
return this;
}

private static class Options {
private boolean includeInstitutionData;

private Options(boolean includeInstitutionData) {
this.includeInstitutionData = includeInstitutionData;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,18 @@
public final class InstitutionsSearchRequest extends BasePublicRequest {
private String query;
private RequiredField<List<Product>> products = RequiredField.empty();

private Options options;

public InstitutionsSearchRequest(String query) {
notNull(query, "query");
this.query = query;
}

public InstitutionsSearchRequest withIncludeInstitutionData(boolean includeInstitutionData) {
this.options = new Options(includeInstitutionData);
return this;
}

public InstitutionsSearchRequest withProducts(Product... products) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we add a .withIncludeInstitutionData(boolean) instead of creating more constructors?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes will do

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uh. I'm not a big fan of object mutation here. Can we either make it a static factory method (ie. static method that always returns a new object)?

notEmpty(products, "product");
if (!this.products.isPresent()) {
Expand All @@ -35,4 +40,12 @@ public InstitutionsSearchRequest withProducts(Product... products) {
return this;
}

private static class Options {
private boolean includeInstitutionData;

private Options(boolean includeInstitutionData) {
this.includeInstitutionData = includeInstitutionData;
}
}

}
16 changes: 16 additions & 0 deletions src/main/java/com/plaid/client/response/Institution.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,22 @@ public String getType() {
private String name;
private List<Product> products;

private String url;
private String logo;
private String primaryColor;

public String getUrl() {
return url;
}

public String getLogo() {
return logo;
}

public String getPrimaryColor() {
return primaryColor;
}

public List<Credential> getCredentials() {
return credentials;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public void testAccountsBalanceGetSuccess() throws Exception {

// sandbox should return expected accounts
List<Account> accounts = response.body().getAccounts();
assertEquals(5, accounts.size());
assertEquals(7, accounts.size());
assertAccount(accounts.get(0), "depository", "checking", 100d, 110d, null, "Plaid Checking", "0000", "Plaid Gold Standard 0% Interest Checking");
assertAccount(accounts.get(1), "depository", "savings", 200d, 210d, null, "Plaid Saving", "1111", "Plaid Silver Standard 0.1% Interest Saving");
assertAccount(accounts.get(2), "depository", "cd", null, 1000d, null, "Plaid CD", "2222", "Plaid Bronze Standard 0.2% Interest CD");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public void testAccountsGetSuccess() throws Exception {

// sandbox should return expected accounts
List<Account> accounts = response.body().getAccounts();
assertEquals(5, accounts.size());
assertEquals(7, accounts.size());
assertAccount(accounts.get(0), "depository", "checking", 100d,
110d, null, "Plaid Checking",
"0000", "Plaid Gold Standard 0% Interest Checking");
Expand Down
13 changes: 11 additions & 2 deletions src/test/java/com/plaid/client/integration/AssetReportGetTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,17 @@ public void testAssetReportGetSuccess() throws Exception {
assertNotNull(respBody.getReport());

// An Asset Report with Insights should include a name (when available).
assertNotNull(respBody.getReport().getItems().get(0).getAccounts().get(0).getTransactions()
.get(0).getName());
assertTrue(containsTransactionWithName(respBody.getReport()));
}

private boolean containsTransactionWithName(AssetReportGetResponse.AssetReport assetReport) {
List<AssetReportGetResponse.Account> accounts = assetReport.getItems().get(0).getAccounts();
for (AssetReportGetResponse.Account account : accounts) {
if (account.getTransactions().size() > 0) {
return account.getTransactions().get(0).getName() != null;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please confirm that a "" transaction name should return true.

Also, I can't see this method being used anywhere, what is it meant for?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah it was to prevent some flakiness but yes "" should return true, a report without insights will not have the name key

}
}
return false;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public void testAllAccountsSuccess() throws Exception {
.execute();

assertSuccessResponse(response);
assertEquals(5, response.body().getAccounts().size());
assertEquals(7, response.body().getAccounts().size());
assertNotNull(response.body().getItem());

for (AuthGetResponse.NumberACH numberACH : response.body().getNumbers().getACH()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
public class InstitutionsGetByIdTest extends AbstractIntegrationTest {
@Test
public void testSuccess() throws Exception {
Response<InstitutionsGetByIdResponse> response = client().service().institutionsGetById(new InstitutionsGetByIdRequest(TARTAN_BANK_INSTITUTION_ID))
Response<InstitutionsGetByIdResponse> response = client().service().
institutionsGetById(new InstitutionsGetByIdRequest(TARTAN_BANK_INSTITUTION_ID))
.execute();

assertSuccessResponse(response);
Expand All @@ -27,12 +28,65 @@ public void testSuccess() throws Exception {
assertNotNull(c.getType());
assertNotNull(c.getName());
}
assertIsValidInstitution(institution);
}

@Test
public void testSuccessWithIncludeInstitutionDataTrue() throws Exception {
Response<InstitutionsGetByIdResponse> response =
client().service().institutionsGetById(
new InstitutionsGetByIdRequest(TARTAN_BANK_INSTITUTION_ID).withIncludeInstitutionData(true))
.execute();

assertSuccessResponse(response);

Institution institution = response.body().getInstitution();
assertFalse(institution.getCredentials().isEmpty());
for (Institution.Credential c : institution.getCredentials()) {
assertNotNull(c.getLabel());
assertNotNull(c.getType());
assertNotNull(c.getName());
}

assertIsValidInstitution(institution);

assertEquals("https://www.plaid.com/", institution.getUrl());
assertEquals("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", institution.getLogo());
assertEquals("#174e7c", institution.getPrimaryColor());
}

@Test
public void testSuccessWithIncludeInstitutionDataFalse() throws Exception {
Response<InstitutionsGetByIdResponse> response = client().service().
institutionsGetById(new InstitutionsGetByIdRequest(TARTAN_BANK_INSTITUTION_ID).
withIncludeInstitutionData(false))
.execute();

assertSuccessResponse(response);

Institution institution = response.body().getInstitution();
assertFalse(institution.getCredentials().isEmpty());
for (Institution.Credential c : institution.getCredentials()) {
assertNotNull(c.getLabel());
assertNotNull(c.getType());
assertNotNull(c.getName());
}

assertIsValidInstitution(institution);

assertEquals(null, institution.getUrl());
assertEquals(null, institution.getLogo());
assertEquals(null, institution.getPrimaryColor());
}

private void assertIsValidInstitution(Institution institution) {
assertTrue(institution.hasMfa());
assertEquals(TARTAN_BANK_INSTITUTION_ID, institution.getInstitutionId());
assertEquals(Arrays.asList("code", "list", "questions", "selections"), institution.getMfa());
assertEquals("Tartan Bank", institution.getName());
assertEquals(Arrays.asList(Product.ASSETS, Product.AUTH, Product.BALANCE, Product.TRANSACTIONS, Product.CREDIT_DETAILS, Product.INCOME, Product.IDENTITY),
institution.getProducts());
assertEquals(Arrays.asList(Product.ASSETS, Product.AUTH, Product.BALANCE,
Product.TRANSACTIONS, Product.CREDIT_DETAILS, Product.INCOME, Product.IDENTITY),
institution.getProducts());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,29 @@ public void testSuccess() throws Exception {
assertEquals(3, response.body().getInstitutions().size());
}

@Test
public void testSuccessWithIncludesInstitutionDataTrue() throws Exception {
Response<InstitutionsGetResponse> response =
client().service().institutionsGet(new InstitutionsGetRequest(3, 0).withIncludeInstitutionData(true)).execute();

assertSuccessResponse(response);

// check number returned
assertEquals(3, response.body().getInstitutions().size());
}

@Test
public void testSuccessWithIncludesInstitutionDataFalse() throws Exception {
Response<InstitutionsGetResponse> response =
client().service().institutionsGet(new InstitutionsGetRequest(3, 0).withIncludeInstitutionData(false)).execute();

assertSuccessResponse(response);

// check number returned
assertEquals(3, response.body().getInstitutions().size());
}


@Test
public void testRequestValidation() throws Exception {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
import org.junit.Test;
import retrofit2.Response;

import static junit.framework.TestCase.assertNull;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

public class InstitutionsSearchTest extends AbstractIntegrationTest {
@Test
Expand All @@ -17,12 +19,38 @@ public void testSuccess() throws Exception {
assertSuccessResponse(response);
}

@Test
public void testSuccessWithIncludeInstitutionDataTrue() throws Exception {
Response<InstitutionsSearchResponse> response =
client().service().institutionsSearch(new InstitutionsSearchRequest("t").withIncludeInstitutionData(true)).execute();

assertSuccessResponse(response);

InstitutionsSearchResponse institutionsSearchResponse = response.body();
assertNotNull(institutionsSearchResponse.getInstitutions().get(0).getUrl());
assertNotNull(institutionsSearchResponse.getInstitutions().get(0).getPrimaryColor());
}

@Test
public void testSuccessWithIncludeInstitutionDataFalse() throws Exception {
Response<InstitutionsSearchResponse> response =
client().service().institutionsSearch(new InstitutionsSearchRequest("t").withIncludeInstitutionData(false)).execute();

assertSuccessResponse(response);

InstitutionsSearchResponse institutionsSearchResponse = response.body();

assertNull(institutionsSearchResponse.getInstitutions().get(0).getUrl());
assertNull(institutionsSearchResponse.getInstitutions().get(0).getPrimaryColor());
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two tests look to me like a missed opportunity to reflect what difference setting true vs false means for the result object.
Update if you have time.

@Test
public void testNoResults() throws Exception {
Response<InstitutionsSearchResponse> response =
client().service().institutionsSearch(new InstitutionsSearchRequest("zebra")).execute();

assertSuccessResponse(response);
assertEquals(0, response.body().getInstitutions().size());

}
}