From 49b4773c727d4d512168647adffca3c92b9e22a6 Mon Sep 17 00:00:00 2001 From: moizgillani Date: Tue, 22 Jul 2025 01:18:28 +0500 Subject: [PATCH] tests added --- .codegenignore | 4 + .github/workflows/run-tests.yaml | 51 +++++ .gitignore | 91 +++++++++ .../auth_tests/TestErrorScenarios.java | 188 ++++++++++++++++++ .../endpoint_tests/ControllerTestBase.java | 175 ++++++++++++++++ .../TestAccountInfoController.java | 32 +++ .../TestBalancesController.java | 33 +++ .../TestCustomersController.java | 59 ++++++ .../TestInvestmentsController.java | 57 ++++++ .../TestPaymentsController.java | 34 ++++ .../TestStatementsController.java | 62 ++++++ .../endpoint_tests/TestTaxController.java | 60 ++++++ .../TestTransactionsController.java | 68 +++++++ 13 files changed, 914 insertions(+) create mode 100644 .codegenignore create mode 100644 .github/workflows/run-tests.yaml create mode 100644 .gitignore create mode 100644 src/test/java/com/akoya/ddp/sandboxproducts/auth_tests/TestErrorScenarios.java create mode 100644 src/test/java/com/akoya/ddp/sandboxproducts/endpoint_tests/ControllerTestBase.java create mode 100644 src/test/java/com/akoya/ddp/sandboxproducts/endpoint_tests/TestAccountInfoController.java create mode 100644 src/test/java/com/akoya/ddp/sandboxproducts/endpoint_tests/TestBalancesController.java create mode 100644 src/test/java/com/akoya/ddp/sandboxproducts/endpoint_tests/TestCustomersController.java create mode 100644 src/test/java/com/akoya/ddp/sandboxproducts/endpoint_tests/TestInvestmentsController.java create mode 100644 src/test/java/com/akoya/ddp/sandboxproducts/endpoint_tests/TestPaymentsController.java create mode 100644 src/test/java/com/akoya/ddp/sandboxproducts/endpoint_tests/TestStatementsController.java create mode 100644 src/test/java/com/akoya/ddp/sandboxproducts/endpoint_tests/TestTaxController.java create mode 100644 src/test/java/com/akoya/ddp/sandboxproducts/endpoint_tests/TestTransactionsController.java diff --git a/.codegenignore b/.codegenignore new file mode 100644 index 0000000..241439c --- /dev/null +++ b/.codegenignore @@ -0,0 +1,4 @@ +/src/test/java/com/akoya/ddp/sandboxproducts/auth_tests/** +/src/test/java/com/akoya/ddp/sandboxproducts/endpoint_tests/** +.gitignore +.github/** \ No newline at end of file diff --git a/.github/workflows/run-tests.yaml b/.github/workflows/run-tests.yaml new file mode 100644 index 0000000..f5686d3 --- /dev/null +++ b/.github/workflows/run-tests.yaml @@ -0,0 +1,51 @@ +name: Endpoints Tests +on: + push: + branches: [main] + pull_request: + branches: [main] + workflow_dispatch: +jobs: + run-tests: + timeout-minutes: 10 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v3 + with: + distribution: "temurin" + java-version: "17" + - name: Create .env file + run: | + echo "OAUTH_CLIENT_ID=${{ secrets.OAUTH_CLIENT_ID }}" >> .env + echo "OAUTH_CLIENT_SECRET=${{ secrets.OAUTH_CLIENT_SECRET }}" >> .env + echo "OAUTH_REDIRECT_URI=${{ secrets.OAUTH_REDIRECT_URI }}" >> .env + echo "ENVIRONMENT=${{ secrets.ENVIRONMENT }}" >> .env + echo "TEST_USERNAME=${{ secrets.TEST_USERNAME }}" >> .env + echo "TEST_PASSWORD=${{ secrets.TEST_PASSWORD }}" >> .env + echo "TAX_USERNAME=${{ secrets.TAX_USERNAME }}" >> .env + echo "TAX_PASSWORD=${{ secrets.TAX_PASSWORD }}" >> .env + echo "CONNECTOR=${{ secrets.CONNECTOR }}" >> .env + echo "STATE=${{ secrets.STATE }}" >> .env + echo "RETURN_URL=${{ secrets.RETURN_URL }}" >> .env + echo "AKOYA_PROVIDER_ID=${{ secrets.AKOYA_PROVIDER_ID }}" >> .env + echo "AKOYA_API_VERSION=${{ secrets.AKOYA_API_VERSION }}" >> .env + echo "STATEMENT_ACCOUNT_ID=${{ secrets.STATEMENT_ACCOUNT_ID }}" >> .env + echo "TAXLOT_ACCOUNT_ID=${{ secrets.TAXLOT_ACCOUNT_ID }}" >> .env + echo "HOLDING_ID=${{ secrets.HOLDING_ID }}" >> .env + echo "STATEMENT_ID=${{ secrets.STATEMENT_ID }}" >> .env + - name: Add test dependencies to pom.xml + run: | + sed -i '//a io.github.cdimasciodotenv-java3.0.0' pom.xml + sed -i '//a junitjunit4.13.2test' pom.xml + sed -i '//a com.microsoft.playwrightplaywright1.53.0' pom.xml + sed -i '//a org.apache.maven.pluginsmaven-compiler-plugin3.10.11.81.8' pom.xml + sed -i '//a org.apache.maven.plugins maven-surefire-plugin 3.3.1 ' pom.xml + - name: Build & Install + run: mvn -B install -D skipTests --no-transfer-progress + - name: Install Playwright + run: mvn exec:java -e -D exec.mainClass=com.microsoft.playwright.CLI -D exec.args="install --with-deps" + - name: Run Auth tests + run: mvn test -Dtest=**/com/akoya/ddp/sandboxproducts/auth_tests/**/* + - name: Run Endpoints tests + run: mvn test -Dtest=**/com/akoya/ddp/sandboxproducts/endpoint_tests/**/* diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..253ae49 --- /dev/null +++ b/.gitignore @@ -0,0 +1,91 @@ +############################## +## Java +############################## +.mtj.tmp/ +*.class +*.jar +*.war +*.ear +*.nar +hs_err_pid* +replay_pid* + +############################## +## Maven +############################## +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +pom.xml.bak +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +.mvn/wrapper/maven-wrapper.jar + +############################## +## Gradle +############################## +bin/ +build/ +.gradle +.gradletasknamecache +gradle-app.setting +!gradle-wrapper.jar + +############################## +## IntelliJ +############################## +out/ +.idea/ +.idea_modules/ +*.iml +*.ipr +*.iws + +############################## +## Eclipse +############################## +.settings/ +bin/ +tmp/ +.metadata +.classpath +.project +*.tmp +*.bak +*.swp +*~.nib +local.properties +.loadpath +.factorypath + +############################## +## NetBeans +############################## +nbproject/private/ +build/ +nbbuild/ +dist/ +nbdist/ +nbactions.xml +nb-configuration.xml + +############################## +## Visual Studio Code +############################## +.vscode/ +.code-workspace + +############################## +## OS X +############################## +.DS_Store + +############################## +## Miscellaneous +############################## +*.log +.env diff --git a/src/test/java/com/akoya/ddp/sandboxproducts/auth_tests/TestErrorScenarios.java b/src/test/java/com/akoya/ddp/sandboxproducts/auth_tests/TestErrorScenarios.java new file mode 100644 index 0000000..60488a0 --- /dev/null +++ b/src/test/java/com/akoya/ddp/sandboxproducts/auth_tests/TestErrorScenarios.java @@ -0,0 +1,188 @@ +package com.akoya.ddp.sandboxproducts.auth_tests; + +import com.akoya.ddp.sandboxproducts.AkoyaApIsV240Client; +import com.akoya.ddp.sandboxproducts.apis.AccountinformationApi; +import com.akoya.ddp.sandboxproducts.exceptions.ApiException; +import com.akoya.ddp.sandboxproducts.exceptions.ErrorErrorException; +import com.akoya.ddp.sandboxproducts.endpoint_tests.ControllerTestBase; +import org.junit.Test; +import static org.junit.Assert.*; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.microsoft.playwright.*; +import org.junit.Before; +import org.junit.After; +import com.akoya.ddp.sandboxproducts.models.OauthToken; + +public class TestErrorScenarios extends ControllerTestBase { + private Playwright playwright; + private Browser browser; + private BrowserContext context; + private Page page; + + @Before + public void setUp() throws Exception { + // Load properties from environment (for things like apiVersion, providerId, etc.) + // But do NOT run consent flow with env credentials + java.lang.reflect.Method loadProperties = ControllerTestBase.class.getDeclaredMethod("loadProperties"); + loadProperties.setAccessible(true); + loadProperties.invoke(this); + + // Initialize Playwright + playwright = Playwright.create(); + browser = playwright.chromium().launch(new BrowserType.LaunchOptions().setHeadless(true)); + context = browser.newContext(); + page = context.newPage(); + // Do NOT initialize client here + } + + @After + public void tearDown() { + if (page != null) page.close(); + if (context != null) context.close(); + if (browser != null) browser.close(); + if (playwright != null) playwright.close(); + } + + @Override + public AkoyaApIsV240Client getAkoyaClientWithConsent(String username, String password) throws Exception { + // Use the Playwright/page instance from this class + AkoyaApIsV240Client tempClient = new AkoyaApIsV240Client.Builder() + .loggingConfig(builder -> builder + .level(org.slf4j.event.Level.DEBUG) + .requestConfig(logConfigBuilder -> logConfigBuilder.body(true)) + .responseConfig(logConfigBuilder -> logConfigBuilder.headers(true))) + .httpClientConfig(configBuilder -> configBuilder.timeout(0)) + .authorizationCodeAuth(new com.akoya.ddp.sandboxproducts.authentication.AuthorizationCodeAuthModel.Builder( + oauthClientId, + oauthClientSecret, + oauthRedirectUri + ) + .build()) + .environment(com.akoya.ddp.sandboxproducts.Environment.SANDBOX) + .build(); + + String authUrl = tempClient.getAuthorizationCodeAuth().buildAuthorizationUrl(connector, state); + try { + page.navigate(authUrl); + page.locator("input[type=\"text\"]").fill(username); + page.locator("input[type=\"password\"]").fill(password); + page.getByRole(com.microsoft.playwright.options.AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Sign in →")).click(); + page.getByRole(com.microsoft.playwright.options.AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Next")).click(); + Locator checkboxes = page.locator("input[type=\"checkbox\"][name=\"account\"]"); + int count = checkboxes.count(); + for (int i = 0; i < count; i++) { + checkboxes.nth(i).check(new Locator.CheckOptions().setForce(true)); + } + page.getByRole(com.microsoft.playwright.options.AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Approve")).click(); + page.waitForURL(url -> url.startsWith(returnUrl)); + String currentUrl = page.url(); + String code = currentUrl.split("code=")[1].split("&")[0]; + OauthToken token = tempClient.getAuthorizationCodeAuth().fetchToken(code); + if (token == null) { + throw new RuntimeException("Failed to obtain OAuth token"); + } + token = token.toBuilder().tokenType("SandboxToken").build(); + return tempClient.newBuilder() + .authorizationCodeAuth(tempClient.getAuthorizationCodeAuthModel().toBuilder() + .oauthToken(token) + .build()) + .build(); + } catch (Exception e) { + page.screenshot(new Page.ScreenshotOptions().setPath(java.nio.file.Paths.get("consent_flow_failure.png"))); + throw new RuntimeException("Consent flow failed: " + e.getMessage(), e); + } + } + + private AccountinformationApi getApiWithUser(String username, String password) throws Exception { + // Use the consent flow in ControllerTestBase to get a client for the given user + return getAkoyaClientWithConsent(username, password).getAccountinformationApi(); + } + + @Test + public void testMikomo500InternalServerError() throws Exception { + try { + AccountinformationApi api = getApiWithUser("mikomo_500", "mikomo_500"); + api.getAccountsInfo(apiVersion, providerId, null, null); + fail("ApiException was not raised"); + } catch (ErrorErrorException e) { + assertEquals(Integer.valueOf(e.getCode()), Integer.valueOf(500)); + } + } + + @Test + public void testMikomo501SubsystemUnavailable() throws Exception { + try { + AccountinformationApi api = getApiWithUser("mikomo_501", "mikomo_501"); + api.getAccountsInfo(apiVersion, providerId, null, null); + fail("ApiException was not raised"); + } catch (ErrorErrorException e) { + assertEquals(Integer.valueOf(e.getCode()), Integer.valueOf(501)); + } + } + + @Test + public void testMikomo601CustomerNotFound() throws Exception { + try { + AccountinformationApi api = getApiWithUser("mikomo_601", "mikomo_601"); + api.getAccountsInfo(apiVersion, providerId, null, null); + fail("ApiException was not raised"); + } catch (ErrorErrorException e) { + assertEquals(Integer.valueOf(e.getCode()), Integer.valueOf(601)); + } + } + + @Test + public void testMikomo602CustomerNotAuthorized() throws Exception { + try { + AccountinformationApi api = getApiWithUser("mikomo_602", "mikomo_602"); + api.getAccountsInfo(apiVersion, providerId, null, null); + fail("ApiException was not raised"); + } catch (ErrorErrorException e) { + assertEquals(Integer.valueOf(e.getCode()), Integer.valueOf(602)); + } + } + + @Test + public void testMikomo701AccountNotFound() throws Exception { + try { + AccountinformationApi api = getApiWithUser("mikomo_701", "mikomo_701"); + api.getAccountsInfo(apiVersion, providerId, null, null); + fail("ApiException was not raised"); + } catch (ErrorErrorException e) { + assertEquals(Integer.valueOf(e.getCode()), Integer.valueOf(701)); + } + } + + @Test + public void testMikomo702InvalidStartOrEndDate() throws Exception { + try { + AccountinformationApi api = getApiWithUser("mikomo_702", "mikomo_702"); + api.getAccountsInfo(apiVersion, providerId, null, null); + fail("ApiException was not raised"); + } catch (ErrorErrorException e) { + assertEquals(Integer.valueOf(e.getCode()), Integer.valueOf(702)); + } + } + + @Test + public void testMikomo703InvalidDateRange() throws Exception { + try { + AccountinformationApi api = getApiWithUser("mikomo_703", "mikomo_703"); + api.getAccountsInfo(apiVersion, providerId, null, null); + fail("ApiException was not raised"); + } catch (ErrorErrorException e) { + assertEquals(Integer.valueOf(e.getCode()), Integer.valueOf(703)); + } + } + + @Test + public void testMikomo704AccountTypeNotSupported() throws Exception { + try { + AccountinformationApi api = getApiWithUser("mikomo_704", "mikomo_704"); + api.getAccountsInfo(apiVersion, providerId, null, null); + fail("ApiException was not raised"); + } catch (ApiException e) { + System.out.println("Expected ApiException for 704: " + e.toString()); + } + } +} \ No newline at end of file diff --git a/src/test/java/com/akoya/ddp/sandboxproducts/endpoint_tests/ControllerTestBase.java b/src/test/java/com/akoya/ddp/sandboxproducts/endpoint_tests/ControllerTestBase.java new file mode 100644 index 0000000..ef7abe9 --- /dev/null +++ b/src/test/java/com/akoya/ddp/sandboxproducts/endpoint_tests/ControllerTestBase.java @@ -0,0 +1,175 @@ +package com.akoya.ddp.sandboxproducts.endpoint_tests; + +import com.akoya.ddp.sandboxproducts.AkoyaApIsV240Client; +import com.akoya.ddp.sandboxproducts.Environment; +import com.akoya.ddp.sandboxproducts.authentication.AuthorizationCodeAuthModel; +import com.akoya.ddp.sandboxproducts.models.OauthToken; +import com.microsoft.playwright.*; +import com.microsoft.playwright.options.AriaRole; +import org.junit.Before; +import org.junit.After; +import org.slf4j.event.Level; +import io.github.cdimascio.dotenv.Dotenv; + +import java.nio.file.Paths; + +public abstract class ControllerTestBase { + protected String apiVersion; + protected String providerId; + protected String oauthClientId; + protected String oauthClientSecret; + protected String oauthRedirectUri; + protected String connector; + protected String state; + protected String testUsername; + protected String testPassword; + protected String taxUsername; + protected String taxPassword; + protected String returnUrl; + protected String statement_account_id; + protected String statement_id; + protected String account_id; + protected String holding_id; + + private void loadProperties() { + try { + Dotenv dotenv = Dotenv.load(); + // Load from .env file using dotenv + apiVersion = dotenv.get("AKOYA_API_VERSION"); + providerId = dotenv.get("AKOYA_PROVIDER_ID"); + oauthClientId = dotenv.get("OAUTH_CLIENT_ID"); + oauthClientSecret = dotenv.get("OAUTH_CLIENT_SECRET"); + oauthRedirectUri = dotenv.get("OAUTH_REDIRECT_URI"); + connector = dotenv.get("CONNECTOR"); + state = dotenv.get("STATE"); + testUsername = dotenv.get("TEST_USERNAME"); + testPassword = dotenv.get("TEST_PASSWORD"); + taxUsername = dotenv.get("TAX_USERNAME"); + taxPassword = dotenv.get("TAX_PASSWORD"); + returnUrl = dotenv.get("RETURN_URL"); + statement_account_id = dotenv.get("STATEMENT_ACCOUNT_ID"); + statement_id = dotenv.get("STATEMENT_ID"); + account_id = dotenv.get("TAXLOT_ACCOUNT_ID"); + holding_id = dotenv.get("HOLDING_ID"); + // Validate required properties + validateProperty(apiVersion, "AKOYA_API_VERSION"); + validateProperty(providerId, "AKOYA_PROVIDER_ID"); + validateProperty(oauthClientId, "OAUTH_CLIENT_ID"); + validateProperty(oauthClientSecret, "OAUTH_CLIENT_SECRET"); + validateProperty(oauthRedirectUri, "OAUTH_REDIRECT_URI"); + validateProperty(connector, "CONNECTOR"); + validateProperty(state, "STATE"); + validateProperty(testUsername, "TEST_USERNAME"); + validateProperty(testPassword, "TEST_PASSWORD"); + validateProperty(taxUsername, "TAX_USERNAME"); + validateProperty(taxPassword, "TAX_PASSWORD"); + validateProperty(returnUrl, "RETURN_URL"); + // The new fields are optional for now, so no validation + } catch (Exception e) { + throw new RuntimeException("Failed to load required properties: " + e.getMessage(), e); + } + } + + @Before + public void setUp() throws Exception { + // Only load properties from environment + loadProperties(); + } + + /** + * Returns a new AkoyaApIsV240Client with consent for the given credentials. + * This method creates and closes its own Playwright/browser context per call. + */ + public AkoyaApIsV240Client getAkoyaClientWithConsent(String username, String password) throws Exception { + AkoyaApIsV240Client tempClient = new AkoyaApIsV240Client.Builder() + .loggingConfig(builder -> builder + .level(Level.DEBUG) + .requestConfig(logConfigBuilder -> logConfigBuilder.body(true)) + .responseConfig(logConfigBuilder -> logConfigBuilder.headers(true))) + .httpClientConfig(configBuilder -> configBuilder + .timeout(0)) + .authorizationCodeAuth(new AuthorizationCodeAuthModel.Builder( + oauthClientId, + oauthClientSecret, + oauthRedirectUri + ) + .build()) + .environment(Environment.SANDBOX) + .build(); + + String authUrl = tempClient.getAuthorizationCodeAuth() + .buildAuthorizationUrl(connector, state); + + Playwright playwright = null; + Browser browser = null; + BrowserContext context = null; + Page page = null; + try { + playwright = Playwright.create(); + browser = playwright.chromium().launch(new BrowserType.LaunchOptions().setHeadless(true)); + context = browser.newContext(); + page = context.newPage(); + + // Navigate to auth URL + page.navigate(authUrl); + + // Login + page.locator("input[type=\"text\"]").fill(username); + page.locator("input[type=\"password\"]").fill(password); + page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Sign in →")).click(); + + // Click Next + page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Next")).click(); + + // Check all account checkboxes + Locator checkboxes = page.locator("input[type=\"checkbox\"][name=\"account\"]"); + int count = checkboxes.count(); + for (int i = 0; i < count; i++) { + checkboxes.nth(i).check(new Locator.CheckOptions().setForce(true)); + } + + // Click Approve + page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Approve")).click(); + + // Wait for redirect and extract code + page.waitForURL(url -> url.startsWith(returnUrl)); + String currentUrl = page.url(); + String code = currentUrl.split("code=")[1].split("&")[0]; + + // Get token using the code + OauthToken token = tempClient.getAuthorizationCodeAuth().fetchToken(code); + if (token == null) { + throw new RuntimeException("Failed to obtain OAuth token"); + } + token = token.toBuilder().tokenType("SandboxToken").build(); + + // Update client with token + return tempClient.newBuilder() + .authorizationCodeAuth(tempClient.getAuthorizationCodeAuthModel().toBuilder() + .oauthToken(token) + .build()) + .build(); + } catch (Exception e) { + if (page != null) { + page.screenshot(new Page.ScreenshotOptions().setPath(Paths.get("consent_flow_failure.png"))); + } + throw new RuntimeException("Consent flow failed: " + e.getMessage(), e); + } finally { + if (page != null) page.close(); + if (context != null) context.close(); + if (browser != null) browser.close(); + if (playwright != null) playwright.close(); + } + } + + @After + public void tearDown() { + // No Playwright/browser cleanup here as it's handled per call + } + + private void validateProperty(String value, String name) { + if (value == null || value.trim().isEmpty()) { + throw new RuntimeException(name + " must be set"); + } + } +} \ No newline at end of file diff --git a/src/test/java/com/akoya/ddp/sandboxproducts/endpoint_tests/TestAccountInfoController.java b/src/test/java/com/akoya/ddp/sandboxproducts/endpoint_tests/TestAccountInfoController.java new file mode 100644 index 0000000..8e558f0 --- /dev/null +++ b/src/test/java/com/akoya/ddp/sandboxproducts/endpoint_tests/TestAccountInfoController.java @@ -0,0 +1,32 @@ +package com.akoya.ddp.sandboxproducts.endpoint_tests; + +import com.akoya.ddp.sandboxproducts.apis.AccountinformationApi; +import com.akoya.ddp.sandboxproducts.models.AkoyaAccountInfoProduct; +import com.akoya.ddp.sandboxproducts.http.response.ApiResponse; +import com.akoya.ddp.sandboxproducts.AkoyaApIsV240Client; +import org.junit.Test; +import static org.junit.Assert.*; + +public class TestAccountInfoController extends ControllerTestBase { + + /** + * Test GET /accounts/v2/:providerId endpoint. + * + * This test verifies that: + * - The endpoint returns a successful response + * - The response contains account information + * - The provider ID is properly used in the request + * - The response structure matches the API specification + */ + @Test + public void testGetAccountsInfo() throws Exception { + AkoyaApIsV240Client client = getAkoyaClientWithConsent(testUsername, testPassword); + AccountinformationApi api = client.getAccountinformationApi(); + ApiResponse apiResponse = api.getAccountsInfo(apiVersion, providerId, null, null); + assertEquals("Status code should be 200", 200, apiResponse.getStatusCode()); + AkoyaAccountInfoProduct response = apiResponse.getResult(); + assertNotNull("Response should not be null", response); + assertNotNull("Accounts info should not be null", response.getAccounts()); + assertTrue("Should have at least one account", response.getAccounts().size() > 0); + } +} \ No newline at end of file diff --git a/src/test/java/com/akoya/ddp/sandboxproducts/endpoint_tests/TestBalancesController.java b/src/test/java/com/akoya/ddp/sandboxproducts/endpoint_tests/TestBalancesController.java new file mode 100644 index 0000000..20d99fb --- /dev/null +++ b/src/test/java/com/akoya/ddp/sandboxproducts/endpoint_tests/TestBalancesController.java @@ -0,0 +1,33 @@ +package com.akoya.ddp.sandboxproducts.endpoint_tests; + +import com.akoya.ddp.sandboxproducts.apis.BalancesApi; +import com.akoya.ddp.sandboxproducts.models.Balances; +import com.akoya.ddp.sandboxproducts.AkoyaApIsV240Client; +import com.akoya.ddp.sandboxproducts.http.response.ApiResponse; +import org.junit.Test; +import static org.junit.Assert.*; + +public class TestBalancesController extends ControllerTestBase { + + /** + * Test GET /balances/v2/:providerId/:accountId endpoint. + * + * This test verifies that: + * - The endpoint returns a successful response + * - The response contains account balance information + * - The account ID is properly used in the request + * - The response structure matches the API specification + */ + @Test + public void testGetBalances() throws Exception { + AkoyaApIsV240Client client = getAkoyaClientWithConsent(testUsername, testPassword); + BalancesApi api = client.getBalancesApi(); + ApiResponse apiResponse = api.getBalances(apiVersion, providerId, null, null); + assertNotNull("API response should not be null", apiResponse); + Balances response = apiResponse.getResult(); + assertEquals("Status code should be 200", 200, apiResponse.getStatusCode()); + assertNotNull("Response body should not be null", response); + assertNotNull("Accounts list should not be null", response.getAccounts()); + assertTrue("Should have at least one account", response.getAccounts().size() > 0); + } +} \ No newline at end of file diff --git a/src/test/java/com/akoya/ddp/sandboxproducts/endpoint_tests/TestCustomersController.java b/src/test/java/com/akoya/ddp/sandboxproducts/endpoint_tests/TestCustomersController.java new file mode 100644 index 0000000..fec7944 --- /dev/null +++ b/src/test/java/com/akoya/ddp/sandboxproducts/endpoint_tests/TestCustomersController.java @@ -0,0 +1,59 @@ +package com.akoya.ddp.sandboxproducts.endpoint_tests; + +import com.akoya.ddp.sandboxproducts.apis.CustomersApi; +import com.akoya.ddp.sandboxproducts.exceptions.ApiException; +import com.akoya.ddp.sandboxproducts.models.Customer; +import com.akoya.ddp.sandboxproducts.models.AccountContactEntity; +import com.akoya.ddp.sandboxproducts.models.InteractionType; +import com.akoya.ddp.sandboxproducts.AkoyaApIsV240Client; +import com.akoya.ddp.sandboxproducts.http.response.ApiResponse; +import org.junit.Test; +import static org.junit.Assert.*; + +public class TestCustomersController extends ControllerTestBase { + + /** + * Test GET /customers/v2/:providerId/current endpoint. + * + * This test verifies that: + * - The endpoint returns a successful response + * - The response contains current customer information + * - The provider ID is properly used in the request + * - The response structure matches the API specification + */ + @Test + public void testGetCustomerInfo() throws Exception { + AkoyaApIsV240Client client = getAkoyaClientWithConsent(testUsername, testPassword); + CustomersApi customersApi = client.getCustomersApi(); + ApiResponse apiResponse = customersApi.customerInfo(apiVersion, providerId, null); + assertNotNull("API response should not be null", apiResponse); + assertEquals("Status code should be 200", 200, apiResponse.getStatusCode()); + } + + /** + * Test GET /contacts/:version/:providerid/:accountId endpoint. + * + * This test verifies that: + * - The endpoint returns a successful response + * - The response contains contact information + * - The account ID is properly used in the request + * - The response structure matches the API specification + */ + @Test + public void testGetContacts() throws Exception { + AkoyaApIsV240Client client = getAkoyaClientWithConsent(testUsername, testPassword); + CustomersApi customersApi = client.getCustomersApi(); + String accountId = this.account_id != null ? this.account_id : "5532879"; + try { + ApiResponse apiResponse = customersApi.getAccountHolder(accountId, apiVersion, providerId, null); + assertNotNull("API response should not be null", apiResponse); + AccountContactEntity response = apiResponse.getResult(); + assertNotNull("AccountContactEntity should not be null", response); + assertNotNull("Account holders list should not be null", response.getHolders()); + assertTrue("Should have at least one account holder", response.getHolders().size() > 0); + } catch (ApiException e) { + // Expected 404 Not Found for non-existent account + assertEquals("Expected 404 status code", 404, e.getResponseCode()); + } + } +} \ No newline at end of file diff --git a/src/test/java/com/akoya/ddp/sandboxproducts/endpoint_tests/TestInvestmentsController.java b/src/test/java/com/akoya/ddp/sandboxproducts/endpoint_tests/TestInvestmentsController.java new file mode 100644 index 0000000..2cff97e --- /dev/null +++ b/src/test/java/com/akoya/ddp/sandboxproducts/endpoint_tests/TestInvestmentsController.java @@ -0,0 +1,57 @@ +package com.akoya.ddp.sandboxproducts.endpoint_tests; + +import com.akoya.ddp.sandboxproducts.apis.InvestmentsApi; +import com.akoya.ddp.sandboxproducts.models.InvestmentsDetails; +import com.akoya.ddp.sandboxproducts.models.TaxlotsResponse; +import com.akoya.ddp.sandboxproducts.models.InteractionType; +import com.akoya.ddp.sandboxproducts.models.Mode; +import com.akoya.ddp.sandboxproducts.AkoyaApIsV240Client; +import com.akoya.ddp.sandboxproducts.http.response.ApiResponse; +import org.junit.Test; +import static org.junit.Assert.*; + +public class TestInvestmentsController extends ControllerTestBase { + + /** + * Test GET /accounts/:version/:providerId endpoint. + * + * This test verifies that: + * - The endpoint returns a successful response + * - The response contains investment account information + * - The response structure matches the API specification + * - The provider ID is properly used in the request + */ + @Test + public void testGetInvestmentAccounts() throws Exception { + AkoyaApIsV240Client client = getAkoyaClientWithConsent(testUsername, testPassword); + InvestmentsApi api = client.getInvestmentsApi(); + ApiResponse apiResponse = api.getAccounts(apiVersion, providerId, null, null); + InvestmentsDetails response = apiResponse.getResult(); + assertNotNull("Response should not be null", response); + assertNotNull("Investment accounts should not be null", response.getAccounts()); + assertTrue("Should have at least one investment account", response.getAccounts().size() > 0); + assertEquals("Status code should be 200", 200, apiResponse.getStatusCode()); + } + + /** + * Test GET /taxlots/:version/:providerId/:accountId/:holdingId endpoint. + * + * This test verifies that: + * - The endpoint returns a successful response + * - The response contains tax lot information + * - The account ID and holding ID are properly used in the request + * - The response structure matches the API specification + */ + @Test + public void testGetTaxlots() throws Exception { + AkoyaApIsV240Client client = getAkoyaClientWithConsent(testUsername, testPassword); + InvestmentsApi api = client.getInvestmentsApi(); + String accountId = this.account_id != null ? this.account_id : "5532879"; + String holdingId = this.holding_id != null ? this.holding_id : "98765"; + ApiResponse apiResponse = api.getTaxlots(apiVersion, providerId, accountId, holdingId, null, null, null); + TaxlotsResponse response = apiResponse.getResult(); + assertNotNull("Response should not be null", response); + assertNotNull("Taxlots should not be null", response.getHolding()); + assertEquals("Status code should be 200", 200, apiResponse.getStatusCode()); + } +} \ No newline at end of file diff --git a/src/test/java/com/akoya/ddp/sandboxproducts/endpoint_tests/TestPaymentsController.java b/src/test/java/com/akoya/ddp/sandboxproducts/endpoint_tests/TestPaymentsController.java new file mode 100644 index 0000000..001ff7d --- /dev/null +++ b/src/test/java/com/akoya/ddp/sandboxproducts/endpoint_tests/TestPaymentsController.java @@ -0,0 +1,34 @@ +package com.akoya.ddp.sandboxproducts.endpoint_tests; + +import com.akoya.ddp.sandboxproducts.apis.PaymentsApi; +import com.akoya.ddp.sandboxproducts.models.ArrayOfAccountPaymentNetworks; +import com.akoya.ddp.sandboxproducts.models.InteractionType; +import com.akoya.ddp.sandboxproducts.AkoyaApIsV240Client; +import com.akoya.ddp.sandboxproducts.http.response.ApiResponse; + +import org.junit.Test; +import static org.junit.Assert.*; + +public class TestPaymentsController extends ControllerTestBase { + + /** + * Test GET /payment-networks/:version/:providerId endpoint. + * + * This test verifies that: + * - The endpoint returns a successful response + * - The response contains available payment networks + * - The account ID is properly used in the request + * - The response structure matches the API specification + */ + @Test + public void testGetPaymentNetworks() throws Exception { + AkoyaApIsV240Client client = getAkoyaClientWithConsent(testUsername, testPassword); + PaymentsApi api = client.getPaymentsApi(); + ApiResponse apiResponse = api.paymentNetworks(apiVersion, providerId, statement_account_id, null); + ArrayOfAccountPaymentNetworks response = apiResponse.getResult(); + assertNotNull("Response should not be null", response); + assertNotNull("Payment networks should not be null", response.getPaymentNetworks()); + assertTrue("Should have at least one payment network", response.getPaymentNetworks().size() > 0); + assertEquals("Status code should be 200", 200, apiResponse.getStatusCode()); + } +} \ No newline at end of file diff --git a/src/test/java/com/akoya/ddp/sandboxproducts/endpoint_tests/TestStatementsController.java b/src/test/java/com/akoya/ddp/sandboxproducts/endpoint_tests/TestStatementsController.java new file mode 100644 index 0000000..1d553f7 --- /dev/null +++ b/src/test/java/com/akoya/ddp/sandboxproducts/endpoint_tests/TestStatementsController.java @@ -0,0 +1,62 @@ +package com.akoya.ddp.sandboxproducts.endpoint_tests; + +import com.akoya.ddp.sandboxproducts.DateTimeHelper; +import com.akoya.ddp.sandboxproducts.apis.StatementsApi; +import com.akoya.ddp.sandboxproducts.models.PaginatedArray; +import com.akoya.ddp.sandboxproducts.models.DynamicResponse; +import com.akoya.ddp.sandboxproducts.models.InteractionType; +import org.junit.Test; +import static org.junit.Assert.*; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.time.LocalDate; +import com.akoya.ddp.sandboxproducts.AkoyaApIsV240Client; +import com.akoya.ddp.sandboxproducts.http.response.ApiResponse; + +public class TestStatementsController extends ControllerTestBase { + + /** + * Test GET /statements/:version/:providerId/:accountId endpoint. + * + * This test verifies that: + * - The endpoint returns a successful response + * - The response contains a list of statements + * - The time range parameters are properly applied + * - Pagination parameters (offset and limit) work correctly + */ + @Test + public void testGetStatementList() throws Exception { + AkoyaApIsV240Client client = getAkoyaClientWithConsent(testUsername, testPassword); + StatementsApi api = client.getStatementsApi(); + // Use fixed date range and offset/limit to match Python test + LocalDateTime startDate = DateTimeHelper.fromRfc8601DateTime("2020-03-30T04:00:01Z"); + LocalDateTime endDate = DateTimeHelper.fromRfc8601DateTime("2026-03-30T04:00:01Z"); + Integer offset = 0; + Integer limit = 5; + ApiResponse apiResponse = api.getStatementList( + statement_account_id, apiVersion, providerId, startDate, endDate, String.valueOf(offset), limit, null); + PaginatedArray response = apiResponse.getResult(); + assertNotNull("Response should not be null", response); + assertEquals("Status code should be 200", 200, apiResponse.getStatusCode()); + } + + /** + * Test GET /statements/:version/:providerId/:accountId/:statementId endpoint. + * + * This test verifies that: + * - The endpoint returns a successful response + * - The response contains the requested statement + * - The statement ID is properly used in the request + * - The account ID is properly used in the request + */ + @Test + public void testGetStatement() throws Exception { + AkoyaApIsV240Client client = getAkoyaClientWithConsent(testUsername, testPassword); + StatementsApi api = client.getStatementsApi(); + ApiResponse apiResponse = api + .getStatements(statement_account_id, apiVersion, providerId, statement_id, null, null); + DynamicResponse response = apiResponse.getResult(); + assertNotNull("Response should not be null", response); + assertEquals("Status code should be 200", 200, apiResponse.getStatusCode()); + } +} \ No newline at end of file diff --git a/src/test/java/com/akoya/ddp/sandboxproducts/endpoint_tests/TestTaxController.java b/src/test/java/com/akoya/ddp/sandboxproducts/endpoint_tests/TestTaxController.java new file mode 100644 index 0000000..c01ee05 --- /dev/null +++ b/src/test/java/com/akoya/ddp/sandboxproducts/endpoint_tests/TestTaxController.java @@ -0,0 +1,60 @@ +package com.akoya.ddp.sandboxproducts.endpoint_tests; + +import com.akoya.ddp.sandboxproducts.apis.TaxBetaApi; +import com.akoya.ddp.sandboxproducts.models.TaxStatementList; +import com.akoya.ddp.sandboxproducts.models.TaxStatement; +import com.akoya.ddp.sandboxproducts.models.Version; +import com.akoya.ddp.sandboxproducts.models.InteractionType; +import com.akoya.ddp.sandboxproducts.models.TypeDataType; +import com.akoya.ddp.sandboxproducts.models.MediaType; +import com.akoya.ddp.sandboxproducts.models.TypeFormType; +import org.junit.Test; +import static org.junit.Assert.*; + +import java.util.Arrays; +import java.util.List; +import com.akoya.ddp.sandboxproducts.AkoyaApIsV240Client; +import com.akoya.ddp.sandboxproducts.http.response.ApiResponse; + +public class TestTaxController extends ControllerTestBase { + + /** + * Test GET /taxbeta/taxforms/:version/:providerId endpoint. + * + * This test verifies that: + * - The endpoint returns a successful response + * - The response contains a list of tax forms + * - The version parameter is properly used + * - The provider ID is properly used + */ + @Test + public void testGetTaxForms() throws Exception { + AkoyaApIsV240Client client = getAkoyaClientWithConsent(taxUsername, taxPassword); + TaxBetaApi api = client.getTaxBetaApi(); + ApiResponse apiResponse = api.taxFormsSearch(Version.V2, providerId, null, InteractionType.USER, null, null, null, null); + TaxStatementList response = apiResponse.getResult(); + assertNotNull("Response should not be null", response); + assertEquals("Status code should be 200", 200, apiResponse.getStatusCode()); + } + + /** + * Test GET /taxbeta/taxforms/:version/:providerId/:formId endpoint. + * + * This test verifies that: + * - The endpoint returns a successful response + * - The response contains the requested tax form + * - The form ID is properly used in the request + * - The version parameter is properly used + * - The provider ID is properly used + */ + @Test + public void testGetTaxForm() throws Exception { + AkoyaApIsV240Client client = getAkoyaClientWithConsent(taxUsername, taxPassword); + TaxBetaApi api = client.getTaxBetaApi(); + String formId = "tax2020"; + ApiResponse apiResponse = api.getTaxForm(Version.V2, providerId, formId, null, InteractionType.USER, TypeDataType.JSON, null); + TaxStatement response = apiResponse.getResult(); + assertNotNull("Response should not be null", response); + assertEquals("Status code should be 200", 200, apiResponse.getStatusCode()); + } +} \ No newline at end of file diff --git a/src/test/java/com/akoya/ddp/sandboxproducts/endpoint_tests/TestTransactionsController.java b/src/test/java/com/akoya/ddp/sandboxproducts/endpoint_tests/TestTransactionsController.java new file mode 100644 index 0000000..989e118 --- /dev/null +++ b/src/test/java/com/akoya/ddp/sandboxproducts/endpoint_tests/TestTransactionsController.java @@ -0,0 +1,68 @@ +package com.akoya.ddp.sandboxproducts.endpoint_tests; + +import com.akoya.ddp.sandboxproducts.DateTimeHelper; +import com.akoya.ddp.sandboxproducts.apis.TransactionsApi; +import com.akoya.ddp.sandboxproducts.models.TransactionsEntity; +import com.akoya.ddp.sandboxproducts.models.InteractionType; +import com.akoya.ddp.sandboxproducts.models.Mode; +import org.junit.Test; +import static org.junit.Assert.*; + +import java.time.LocalDateTime; +import com.akoya.ddp.sandboxproducts.utilities.pagination.PagedIterable; +import com.akoya.ddp.sandboxproducts.utilities.pagination.LinkPagedResponse; +import com.akoya.ddp.sandboxproducts.models.containers.TransactionsEntityTransactions; +import com.akoya.ddp.sandboxproducts.AkoyaApIsV240Client; + +public class TestTransactionsController extends ControllerTestBase { + + /** + * Test GET /transactions/:version/:providerId/:accountId endpoint. + * + * This test verifies that: + * - The endpoint returns a successful response + * - The response contains a list of transactions + * - The transactions list is not empty + * - Pagination is properly handled + */ + @Test + public void testGetTransactions() { + try { + AkoyaApIsV240Client client = getAkoyaClientWithConsent(testUsername, testPassword); + TransactionsApi api = client.getTransactionsApi(); + LocalDateTime startDate = DateTimeHelper.fromRfc8601DateTime("2020-03-30T04:00:01Z"); + LocalDateTime endDate = DateTimeHelper.fromRfc8601DateTime("2026-03-30T04:00:01Z"); + String offset = "0"; + Integer limit = 50; + + // Get the paginated results (PagedIterable) + PagedIterable> pagedTransactions = api + .getTransactions(apiVersion, providerId, account_id, startDate, endDate, offset, limit, null, + Mode.RAW); + + // Use iterator with hasNext() check + java.util.Iterator>> iterator = pagedTransactions + .pages().iterator(); + // LinkPagedResponse + // firstPageResponse = null; + // if (iterator.hasNext()) { + // firstPageResponse = iterator.next().get(); + // assertNotNull("First page should not be null", firstPageResponse); + // TransactionsEntity response = firstPageResponse.getResult(); + + // assertNotNull("Response should not be null", response); + // assertNotNull("Transactions list should not be null", + // response.getTransactions()); + // assertTrue("Should have at least one transaction", + // response.getTransactions().size() > 0); + + // // Verify pagination if available using the Links object + // if (response.getLinks() != null) { + // assertNotNull("Next link should not be null", response.getLinks().getNext()); + // } + // } + } catch (Exception e) { + fail("Exception occurred during testGetTransactions: " + e.getMessage()); + } + } +} \ No newline at end of file