From cf838df994bbb5d0678ccff284878e1ca89f34d5 Mon Sep 17 00:00:00 2001 From: roost-io Date: Tue, 31 Mar 2026 08:28:59 +0000 Subject: [PATCH] Functional (using Source code) (Java) generated by RoostGPT Using AI Model gpt-4.1 --- .../.roost/knowledge.json | 632 ++++++++++++++++++ .../gherkin_AccountController.feature | 48 ++ .../gherkin_AppController.feature | 73 ++ .../gherkin_AuthController.feature | 71 ++ .../gherkin_IndexController.feature | 61 ++ .../gherkin_RegisterController.feature | 68 ++ .../gherkin_TransactController.feature | 188 ++++++ .../test_docs/README.md | 28 + .../test_docs/api_flows.md | 251 +++++++ .../test_docs/business_use_cases.md | 259 +++++++ .../test_docs/test_coverage.md | 182 +++++ 11 files changed, 1861 insertions(+) create mode 100644 Online-Banking-App-Spring-Boot/.roost/knowledge.json create mode 100644 Online-Banking-App-Spring-Boot/gherkin_scenarios/gherkin_AccountController.feature create mode 100644 Online-Banking-App-Spring-Boot/gherkin_scenarios/gherkin_AppController.feature create mode 100644 Online-Banking-App-Spring-Boot/gherkin_scenarios/gherkin_AuthController.feature create mode 100644 Online-Banking-App-Spring-Boot/gherkin_scenarios/gherkin_IndexController.feature create mode 100644 Online-Banking-App-Spring-Boot/gherkin_scenarios/gherkin_RegisterController.feature create mode 100644 Online-Banking-App-Spring-Boot/gherkin_scenarios/gherkin_TransactController.feature create mode 100644 Online-Banking-App-Spring-Boot/test_docs/README.md create mode 100644 Online-Banking-App-Spring-Boot/test_docs/api_flows.md create mode 100644 Online-Banking-App-Spring-Boot/test_docs/business_use_cases.md create mode 100644 Online-Banking-App-Spring-Boot/test_docs/test_coverage.md diff --git a/Online-Banking-App-Spring-Boot/.roost/knowledge.json b/Online-Banking-App-Spring-Boot/.roost/knowledge.json new file mode 100644 index 0000000..4253700 --- /dev/null +++ b/Online-Banking-App-Spring-Boot/.roost/knowledge.json @@ -0,0 +1,632 @@ +{ + "endpoints": [ + { + "controller": "AccountController", + "basePath": "/account", + "endpoints": [ + { + "method": "POST", + "path": "/account/create_account", + "handler": "createAccount", + "parameters": [ + { + "in": "body", + "type": "object", + "required": true, + "schema": { + "account_name": "string", + "account_type": "string" + } + }, + { + "in": "session", + "name": "user" + } + ], + "responses": { + "200": { + "description": "User's accounts", + "content": "application/json" + }, + "400": { + "description": "Account name cannot be Empty!" + }, + "401": { + "description": "You must login first." + } + } + } + ] + }, + { + "controller": "AppController", + "basePath": "/app", + "endpoints": [ + { + "method": "GET", + "path": "/app/dashboard", + "handler": "getDashboard", + "parameters": [ + { + "in": "session", + "name": "user" + } + ], + "responses": { + "200": { + "description": "User dashboard data (accounts, total balance)", + "content": "application/json" + }, + "401": { + "description": "Unauthorized if not logged in" + } + } + }, + { + "method": "GET", + "path": "/app/payment_history", + "handler": "getPaymentHistory", + "parameters": [ + { + "in": "session", + "name": "user" + } + ], + "responses": { + "200": { + "description": "Payment history as JSON", + "content": "application/json" + }, + "401": { + "description": "Unauthorized if not logged in" + } + } + }, + { + "method": "GET", + "path": "/app/transaction_history", + "handler": "getTransactiontHistory", + "parameters": [ + { + "in": "session", + "name": "user" + } + ], + "responses": { + "200": { + "description": "Transaction history as JSON", + "content": "application/json" + }, + "401": { + "description": "Unauthorized if not logged in" + } + } + }, + { + "method": "POST", + "path": "/app/account_transaction_history", + "handler": "getAccountTransactiontHistory", + "parameters": [ + { + "in": "body", + "type": "object", + "required": true, + "schema": { + "account_id": "string" + } + }, + { + "in": "session", + "name": "user" + } + ], + "responses": { + "200": { + "description": "Transaction history for the specified account", + "content": "application/json" + }, + "401": { + "description": "Unauthorized if not logged in" + } + } + } + ] + }, + { + "controller": "AuthController", + "basePath": "", + "endpoints": [ + { + "method": "POST", + "path": "/login", + "handler": "login", + "parameters": [ + { + "in": "body", + "type": "object", + "required": true, + "schema": { + "email": "string", + "password": "string" + } + } + ], + "responses": { + "200": { + "description": "Authentication confirmed, returns access_token (JWT)", + "content": "application/json" + }, + "400": { + "description": "Username or Password Cannot Be Empty." + }, + "401": { + "description": "Incorrect Username or Password" + }, + "403": { + "description": "Account verification required." + }, + "500": { + "description": "Something went wrong" + } + } + }, + { + "method": "GET", + "path": "/logout", + "handler": "logout", + "parameters": [ + { + "in": "session", + "name": "user" + } + ], + "responses": { + "200": { + "description": "Logged out successfully." + } + } + } + ] + }, + { + "controller": "IndexController", + "basePath": "", + "endpoints": [ + { + "method": "GET", + "path": "/", + "handler": "getIndex", + "parameters": [], + "responses": { + "200": { + "description": "Welcome message: Merhaba, Spring Boot JSON örnegi!", + "content": "text/plain" + } + } + }, + { + "method": "GET", + "path": "/verify", + "handler": "getVerify", + "parameters": [ + { + "in": "query", + "name": "token", + "type": "string", + "required": true + }, + { + "in": "query", + "name": "code", + "type": "string", + "required": true + } + ], + "responses": { + "200": { + "description": "Verification success.", + "content": "application/json" + }, + "400": { + "description": "This session has expire." + } + } + } + ] + }, + { + "controller": "RegisterController", + "basePath": "", + "endpoints": [ + { + "method": "POST", + "path": "/register", + "handler": "registerUser", + "parameters": [ + { + "in": "body", + "type": "object", + "required": true, + "schema": { + "$ref": "#/components/schemas/User" + } + }, + { + "in": "query", + "name": "confirm_password", + "type": "string", + "required": true + } + ], + "responses": { + "200": { + "description": "Registration success. Please check your email and verify your account.", + "content": "application/json" + }, + "400": { + "description": "Validation errors or password mismatch." + } + } + } + ] + }, + { + "controller": "TransactController", + "basePath": "/transact", + "endpoints": [ + { + "method": "POST", + "path": "/transact/deposit", + "handler": "deposit", + "parameters": [ + { + "in": "body", + "type": "object", + "required": true, + "schema": { + "deposit_amount": "string", + "account_id": "string" + } + }, + { + "in": "session", + "name": "user" + } + ], + "responses": { + "200": { + "description": "Amount deposited and updated accounts list", + "content": "application/json" + }, + "400": { + "description": "Deposit amount and account ID cannot be empty or zero" + }, + "401": { + "description": "Unauthorized if not logged in" + } + } + }, + { + "method": "POST", + "path": "/transact/transfer", + "handler": "transfer (transfer)", + "parameters": [ + { + "in": "body", + "type": "object", + "required": true, + "schema": { + "$ref": "#/components/schemas/TransferRequest" + } + }, + { + "in": "session", + "name": "user" + } + ], + "responses": { + "200": { + "description": "Transfer completed and updated accounts list", + "content": "application/json" + }, + "400": { + "description": "Invalid fields, zero/negative values, insufficient funds, or transfer between same account" + }, + "401": { + "description": "Unauthorized if not logged in" + } + } + }, + { + "method": "POST", + "path": "/transact/withdraw", + "handler": "transfer (withdraw)", + "parameters": [ + { + "in": "body", + "type": "object", + "required": true, + "schema": { + "withdrawal_amount": "string", + "account_id": "string" + } + }, + { + "in": "session", + "name": "user" + } + ], + "responses": { + "200": { + "description": "Withdrawal successful and updated accounts list", + "content": "application/json" + }, + "400": { + "description": "Invalid input, zero/negative values, or insufficient funds" + }, + "401": { + "description": "Unauthorized if not logged in" + } + } + }, + { + "method": "POST", + "path": "/transact/payment", + "handler": "transfer (payment)", + "parameters": [ + { + "in": "body", + "type": "object", + "required": true, + "schema": { + "$ref": "#/components/schemas/PaymentRequest" + } + }, + { + "in": "session", + "name": "user" + } + ], + "responses": { + "200": { + "description": "Payment processed and updated accounts list", + "content": "application/json" + }, + "400": { + "description": "Invalid data or insufficient funds" + }, + "401": { + "description": "Unauthorized if not logged in" + } + } + } + ] + } + ], + "models": [ + { + "name": "Account", + "type": "Entity", + "fields": [ + { + "name": "account_id", + "type": "int" + }, + { + "name": "user_id", + "type": "int" + }, + { + "name": "account_number", + "type": "String" + }, + { + "name": "account_name", + "type": "String" + }, + { + "name": "account_type", + "type": "String" + }, + { + "name": "balance", + "type": "BigDecimal" + }, + { + "name": "create_at", + "type": "LocalDateTime" + }, + { + "name": "updated_at", + "type": "LocalDateTime" + } + ] + }, + { + "name": "Payment", + "type": "Entity", + "fields": [ + { + "name": "payment_id", + "type": "int" + }, + { + "name": "account_id", + "type": "int" + }, + { + "name": "beneficiary", + "type": "String" + }, + { + "name": "beneficiary_acc_no", + "type": "String" + }, + { + "name": "amount", + "type": "double" + }, + { + "name": "reference_no", + "type": "String" + }, + { + "name": "status", + "type": "String" + }, + { + "name": "reason_code", + "type": "String" + }, + { + "name": "created_at", + "type": "LocalDateTime" + } + ] + }, + { + "name": "PaymentHistory", + "type": "Entity (View)", + "fields": [ + { + "name": "payment_id", + "type": "int" + }, + { + "name": "account_id", + "type": "int" + }, + { + "name": "beneficiary", + "type": "String" + }, + { + "name": "beneficiary_acc_no", + "type": "String" + }, + { + "name": "amount", + "type": "double" + }, + { + "name": "reference_no", + "type": "String" + }, + { + "name": "status", + "type": "String" + }, + { + "name": "reason_code", + "type": "String" + }, + { + "name": "created_at", + "type": "LocalDateTime" + } + ] + }, + { + "name": "PaymentRequest", + "type": "DTO", + "fields": [ + { + "name": "beneficiary", + "type": "String" + }, + { + "name": "account_number", + "type": "String" + }, + { + "name": "account_id", + "type": "String" + }, + { + "name": "reference", + "type": "String" + }, + { + "name": "payment_amount", + "type": "String" + } + ] + } + ], + "dependencies": [], + "businessFlows": [], + "language": "java", + "buildTool": "maven", + "framework": "spring-boot", + "projectStructure": [ + "[DIR] .mvn/", + " [DIR] wrapper/", + " [FILE] maven-wrapper.jar", + " [FILE] maven-wrapper.properties", + "[DIR] src/", + " [DIR] main/", + " [DIR] java/", + " [DIR] com/", + " [DIR] beko/", + " [DIR] DemoBank_v1/", + " [DIR] config/", + " [FILE] AppConfig.java", + " [FILE] MailConfig.java", + " [DIR] controller_advisor/", + " [FILE] AdvisorController.java", + " [DIR] controllers/", + " [FILE] AccountController.java", + " [FILE] AppController.java", + " [FILE] AuthController.java", + " [FILE] IndexController.java", + " [FILE] RegisterController.java", + " [FILE] TransactController.java", + " [DIR] exception/", + " [FILE] CustomError.java", + " [FILE] GlobalExceptionHandler.java", + " [DIR] helpers/", + " [DIR] authorization/", + " [FILE] JwtService.java", + " [FILE] GenAccountNumber.java", + " [FILE] HTML.java", + " [FILE] Token.java", + " [DIR] interceptors/", + " [FILE] AppInterceptor.java", + " [DIR] mailMessenger/", + " [FILE] MailMessenger.java", + " [DIR] models/", + " [FILE] Account.java", + " [FILE] Payment.java", + " [FILE] PaymentHistory.java", + " [FILE] PaymentRequest.java", + " [FILE] Transact.java", + " [FILE] TransactionHistory.java", + " [FILE] TransferRequest.java", + " [FILE] User.java", + " [DIR] repository/", + " [FILE] AccountRepository.java", + " [FILE] PaymentHistoryRepository.java", + " [FILE] PaymentRepository.java", + " [FILE] TransactHistoryRepository.java", + " [FILE] TransactRepository.java", + " [FILE] UserRepository.java", + " [FILE] DemoBankV1Application.java", + " [DIR] resources/", + " [FILE] application.properties", + " [DIR] webapp/", + " [DIR] WEB-INF/", + " [DIR] jsp/", + " [FILE] index.jsp", + " [DIR] test/", + " [DIR] java/", + " [DIR] com/", + " [DIR] beko/", + " [DIR] DemoBank_v1/", + " [FILE] DemoBankV1ApplicationTests.java", + "[FILE] .gitignore", + "[FILE] mvnw", + "[FILE] mvnw.cmd", + "[FILE] pom.xml", + "[FILE] README.md" + ] +} \ No newline at end of file diff --git a/Online-Banking-App-Spring-Boot/gherkin_scenarios/gherkin_AccountController.feature b/Online-Banking-App-Spring-Boot/gherkin_scenarios/gherkin_AccountController.feature new file mode 100644 index 0000000..bc3e64c --- /dev/null +++ b/Online-Banking-App-Spring-Boot/gherkin_scenarios/gherkin_AccountController.feature @@ -0,0 +1,48 @@ +Feature: Account Creation via AccountController + + As an authenticated user + I want to create new accounts using the AccountController + So that I can manage my finances + + Background: + Given the API endpoint is "/account/create_account" + And the request method is POST + + @smoke + Scenario: Successfully create a new account with valid details + Given I am a logged-in user with a valid session + And the request body contains: + | account_name | account_type | + | "Personal Fund" | "Savings" | + When I send the POST request to "/account/create_account" + Then the response status should be 200 + And the response should contain a list of Account objects + And each Account object should have fields: + | account_id | + | user_id | + | account_number | + | account_name | + | account_type | + | balance | + | create_at | + | updated_at | + + @regression + Scenario: Fail to create account with missing account_name + Given I am a logged-in user with a valid session + And the request body contains: + | account_name | account_type | + | "" | "Savings" | + When I send the POST request to "/account/create_account" + Then the response status should be 400 + And the response should contain the message "Account name cannot be Empty!" + + @regression + Scenario: Fail to create account when user is not authenticated + Given I am not logged in and have no valid session + And the request body contains: + | account_name | account_type | + | "Personal Fund" | "Savings" | + When I send the POST request to "/account/create_account" + Then the response status should be 401 + And the response should contain the message "You must login first." \ No newline at end of file diff --git a/Online-Banking-App-Spring-Boot/gherkin_scenarios/gherkin_AppController.feature b/Online-Banking-App-Spring-Boot/gherkin_scenarios/gherkin_AppController.feature new file mode 100644 index 0000000..da9c204 --- /dev/null +++ b/Online-Banking-App-Spring-Boot/gherkin_scenarios/gherkin_AppController.feature @@ -0,0 +1,73 @@ +Feature: App Dashboard and History API Endpoints + + Background: + Given the API base URL is set + And a user exists in the system + + @smoke + Scenario: Successfully fetch dashboard data as logged-in user + Given I am logged in as a valid user + When I send a GET request to "/app/dashboard" + Then the response status should be 200 + And the response should contain "accounts" + And the response should contain "total_balance" + + @regression + Scenario: Attempt to fetch dashboard data without logging in + Given I am not logged in + When I send a GET request to "/app/dashboard" + Then the response status should be 401 + And the response should contain "Unauthorized" + + @smoke + Scenario: Successfully fetch payment history as logged-in user + Given I am logged in as a valid user + When I send a GET request to "/app/payment_history" + Then the response status should be 200 + And the response should contain "payment_history" as JSON + + @regression + Scenario: Attempt to fetch payment history without logging in + Given I am not logged in + When I send a GET request to "/app/payment_history" + Then the response status should be 401 + And the response should contain "Unauthorized" + + @smoke + Scenario: Successfully fetch transaction history as logged-in user + Given I am logged in as a valid user + When I send a GET request to "/app/transaction_history" + Then the response status should be 200 + And the response should contain "transaction_history" as JSON + + @regression + Scenario: Attempt to fetch transaction history without logging in + Given I am not logged in + When I send a GET request to "/app/transaction_history" + Then the response status should be 401 + And the response should contain "Unauthorized" + + @smoke + Scenario: Successfully fetch account transaction history with valid account ID as logged-in user + Given I am logged in as a valid user + And I have a valid account ID "12345" + When I send a POST request to "/app/account_transaction_history" with body: + | account_id | 12345 | + Then the response status should be 200 + And the response should contain "history" for account "12345" + + @regression + Scenario: Attempt to fetch account transaction history without logging in + Given I am not logged in + And I have a valid account ID "12345" + When I send a POST request to "/app/account_transaction_history" with body: + | account_id | 12345 | + Then the response status should be 401 + And the response should contain "Unauthorized" + + @regression + Scenario: Attempt to fetch account transaction history with missing account ID as logged-in user + Given I am logged in as a valid user + When I send a POST request to "/app/account_transaction_history" with empty body + Then the response status should not be 200 + And the response should indicate "account_id" is required \ No newline at end of file diff --git a/Online-Banking-App-Spring-Boot/gherkin_scenarios/gherkin_AuthController.feature b/Online-Banking-App-Spring-Boot/gherkin_scenarios/gherkin_AuthController.feature new file mode 100644 index 0000000..0739acf --- /dev/null +++ b/Online-Banking-App-Spring-Boot/gherkin_scenarios/gherkin_AuthController.feature @@ -0,0 +1,71 @@ +Feature: AuthController Authentication Endpoints + + Background: + Given the API base URL is "/" + And the user data is as follows: + | email | password | verified | correct_password | + | user@example.com | secret123 | true | secret123 | + | unverified@example.com | secret321 | false | secret321 | + + @smoke + Scenario: Successful login with valid credentials + When I send a POST request to "/login" with body: + | email | password | + | user@example.com | secret123 | + Then the response status should be 200 + And the response should contain JSON field "access_token" + + @regression + Scenario: Login fails when email is missing + When I send a POST request to "/login" with body: + | password | + | secret123 | + Then the response status should be 400 + And the response should contain an error message "Missing required field: email" + + @regression + Scenario: Login fails when password is missing + When I send a POST request to "/login" with body: + | email | + | user@example.com | + Then the response status should be 400 + And the response should contain an error message "Missing required field: password" + + @regression + Scenario: Login fails with incorrect credentials + When I send a POST request to "/login" with body: + | email | password | + | user@example.com | wrongpass | + Then the response status should be 401 + And the response should contain an error message "Invalid email or password" + + @regression + Scenario: Login fails when account verification is required + When I send a POST request to "/login" with body: + | email | password | + | unverified@example.com | secret321 | + Then the response status should be 403 + And the response should contain an error message "Account verification required" + + @regression + Scenario: Login fails due to server error + Given the authentication service is unavailable + When I send a POST request to "/login" with body: + | email | password | + | user@example.com | secret123 | + Then the response status should be 500 + And the response should contain an error message "Internal server error" + + @smoke + Scenario: Successful logout for logged-in user + Given the user "user@example.com" is logged in with a valid session + When I send a GET request to "/logout" + Then the response status should be 200 + And the response should contain a success message "Logout successful" + + @regression + Scenario: Logout fails for not logged-in user + Given no user is logged in + When I send a GET request to "/logout" + Then the response status should be 401 + And the response should contain an error message "Authentication required" \ No newline at end of file diff --git a/Online-Banking-App-Spring-Boot/gherkin_scenarios/gherkin_IndexController.feature b/Online-Banking-App-Spring-Boot/gherkin_scenarios/gherkin_IndexController.feature new file mode 100644 index 0000000..0c7ef72 --- /dev/null +++ b/Online-Banking-App-Spring-Boot/gherkin_scenarios/gherkin_IndexController.feature @@ -0,0 +1,61 @@ +Feature: IndexController API Functional Tests + + Background: + Given the API base URL is "https://api.example.com" + And all requests include header "Accept: application/json" + + @smoke @regression + Scenario: GET / returns welcome text (happy path) + When I send a GET request to "/" + Then the response status code should be 200 + And the response content type should be "text/plain" + And the response body should be equal to "Welcome to Example API!" + + @smoke @regression + Scenario: GET /verify returns verification success for valid token and code (happy path) + Given I have a valid token "abc123xyz" and code "456789" + When I send a GET request to "/verify?token=abc123xyz&code=456789" + Then the response status code should be 200 + And the response content type should be "application/json" + And the response body should be valid JSON + And the response JSON should contain: + | key | value | + | verified | true | + | user_id | 42 | + | message | "Verification successful." | + + @regression + Scenario: GET /verify returns error for missing token + When I send a GET request to "/verify?code=456789" + Then the response status code should be 400 + And the response content type should be "text/plain" + And the response body should be equal to "This session has expire." + + @regression + Scenario: GET /verify returns error for missing code + When I send a GET request to "/verify?token=abc123xyz" + Then the response status code should be 400 + And the response content type should be "text/plain" + And the response body should be equal to "This session has expire." + + @regression + Scenario: GET /verify returns error for invalid token + When I send a GET request to "/verify?token=invalidToken&code=456789" + Then the response status code should be 400 + And the response content type should be "text/plain" + And the response body should be equal to "This session has expire." + + @regression + Scenario: GET /verify returns error for invalid code + When I send a GET request to "/verify?token=abc123xyz&code=wrongCode" + Then the response status code should be 400 + And the response content type should be "text/plain" + And the response body should be equal to "This session has expire." + + @regression + Scenario: GET /verify returns error for expired session + Given the token "expiredToken" and code "456789" belong to an expired session + When I send a GET request to "/verify?token=expiredToken&code=456789" + Then the response status code should be 400 + And the response content type should be "text/plain" + And the response body should be equal to "This session has expire." \ No newline at end of file diff --git a/Online-Banking-App-Spring-Boot/gherkin_scenarios/gherkin_RegisterController.feature b/Online-Banking-App-Spring-Boot/gherkin_scenarios/gherkin_RegisterController.feature new file mode 100644 index 0000000..2aff4f0 --- /dev/null +++ b/Online-Banking-App-Spring-Boot/gherkin_scenarios/gherkin_RegisterController.feature @@ -0,0 +1,68 @@ +Feature: User Registration via POST /register + As a new user + I want to be able to register an account + So that I can access protected features + + Background: + Given the API endpoint "/register" is available + And the following request headers are set: + | Content-Type | application/json | + + @smoke + Scenario: Successfully register with valid details and matching confirm_password + Given the request body is: + """ + { + "name": "Alice Johnson", + "email": "alice.johnson@example.com", + "password": "S3cureP@ssword" + } + """ + And the query parameter "confirm_password" is set to "S3cureP@ssword" + When I POST to "/register" + Then the response status code should be 200 + And the response should include a user id and welcome message + + @regression + Scenario: Registration fails with missing required fields + Given the request body is: + """ + { + "email": "bob.smith@example.com", + "password": "Pa$$word123" + } + """ + And the query parameter "confirm_password" is set to "Pa$$word123" + When I POST to "/register" + Then the response status code should be 400 + And the response body should contain "name is required" + + @regression + Scenario: Registration fails when password and confirm_password do not match + Given the request body is: + """ + { + "name": "Charlie Lee", + "email": "charlie.lee@example.com", + "password": "StrongPass1" + } + """ + And the query parameter "confirm_password" is set to "DifferentPass1" + When I POST to "/register" + Then the response status code should be 400 + And the response body should contain "Password and confirm_password do not match" + + @regression + Scenario: Registration fails with invalid email format + Given the request body is: + """ + { + "name": "Diana Miller", + "email": "diana.miller[at]example", + "password": "ValidP@ss123" + } + """ + And the query parameter "confirm_password" is set to "ValidP@ss123" + When I POST to "/register" + Then the response status code should be 400 + And the response body should contain "email must be a valid email address" \ No newline at end of file diff --git a/Online-Banking-App-Spring-Boot/gherkin_scenarios/gherkin_TransactController.feature b/Online-Banking-App-Spring-Boot/gherkin_scenarios/gherkin_TransactController.feature new file mode 100644 index 0000000..78bf82e --- /dev/null +++ b/Online-Banking-App-Spring-Boot/gherkin_scenarios/gherkin_TransactController.feature @@ -0,0 +1,188 @@ +Feature: TransactController API Endpoints Functional Testing + + Background: + Given the API base URL is "https://api.example.com" + And I have valid user credentials as "user1" with password "password123" + + @smoke + Scenario: Successful deposit to an account + Given I am authorized as "user1" + When I POST to "/transact/deposit" with body: + | deposit_amount | 500 | + | account_id | ACC123456 | + Then the response status should be 200 + And the response body should contain: + | message | Deposit successful | + | account_id | ACC123456 | + | deposit_amount | 500 | + + @regression + Scenario: Deposit with invalid amount (missing deposit_amount) + Given I am authorized as "user1" + When I POST to "/transact/deposit" with body: + | account_id | ACC123456 | + Then the response status should be 400 + And the response body should contain "deposit_amount is required" + + @regression + Scenario: Deposit with non-numeric deposit_amount + Given I am authorized as "user1" + When I POST to "/transact/deposit" with body: + | deposit_amount | fifty | + | account_id | ACC123456 | + Then the response status should be 400 + And the response body should contain "deposit_amount must be a number" + + @regression + Scenario: Deposit when unauthorized + Given I am not authorized + When I POST to "/transact/deposit" with body: + | deposit_amount | 500 | + | account_id | ACC123456 | + Then the response status should be 401 + And the response body should contain "Unauthorized" + + @smoke + Scenario: Successful withdrawal from an account + Given I am authorized as "user1" + And account "ACC123456" has a balance of 1000 + When I POST to "/transact/withdraw" with body: + | withdrawal_amount | 250 | + | account_id | ACC123456 | + Then the response status should be 200 + And the response body should contain: + | message | Withdrawal successful | + | account_id | ACC123456 | + | withdrawn_amount | 250 | + + @regression + Scenario: Withdrawal with insufficient funds + Given I am authorized as "user1" + And account "ACC123456" has a balance of 100 + When I POST to "/transact/withdraw" with body: + | withdrawal_amount | 200 | + | account_id | ACC123456 | + Then the response status should be 400 + And the response body should contain "Insufficient funds" + + @regression + Scenario: Withdrawal with invalid account_id (missing) + Given I am authorized as "user1" + When I POST to "/transact/withdraw" with body: + | withdrawal_amount | 100 | + Then the response status should be 400 + And the response body should contain "account_id is required" + + @regression + Scenario: Withdrawal when unauthorized + Given I am not authorized + When I POST to "/transact/withdraw" with body: + | withdrawal_amount | 100 | + | account_id | ACC123456 | + Then the response status should be 401 + And the response body should contain "Unauthorized" + + @smoke + Scenario: Successful transfer between accounts + Given I am authorized as "user1" + And account "ACC123456" has a balance of 2000 + When I POST to "/transact/transfer" with body: + | source_account_id | ACC123456 | + | destination_account_id | ACC654321 | + | transfer_amount | 300 | + Then the response status should be 200 + And the response body should contain: + | message | Transfer successful | + | source_account_id | ACC123456 | + | destination_account_id | ACC654321 | + | transferred_amount | 300 | + + @regression + Scenario: Transfer to same account fails + Given I am authorized as "user1" + When I POST to "/transact/transfer" with body: + | source_account_id | ACC123456 | + | destination_account_id | ACC123456 | + | transfer_amount | 100 | + Then the response status should be 400 + And the response body should contain "Source and destination accounts must be different" + + @regression + Scenario: Transfer with insufficient funds + Given I am authorized as "user1" + And account "ACC123456" has a balance of 50 + When I POST to "/transact/transfer" with body: + | source_account_id | ACC123456 | + | destination_account_id | ACC654321 | + | transfer_amount | 100 | + Then the response status should be 400 + And the response body should contain "Insufficient funds" + + @regression + Scenario: Transfer with missing fields + Given I am authorized as "user1" + When I POST to "/transact/transfer" with body: + | source_account_id | ACC123456 | + | transfer_amount | 100 | + Then the response status should be 400 + And the response body should contain "destination_account_id is required" + + @regression + Scenario: Transfer when unauthorized + Given I am not authorized + When I POST to "/transact/transfer" with body: + | source_account_id | ACC123456 | + | destination_account_id | ACC654321 | + | transfer_amount | 100 | + Then the response status should be 401 + And the response body should contain "Unauthorized" + + @smoke + Scenario: Successful payment from an account + Given I am authorized as "user1" + And account "ACC123456" has a balance of 1000 + When I POST to "/transact/payment" with body: + | payer_account_id | ACC123456 | + | payee | VendorXYZ | + | amount | 150 | + | reference | INV-9001 | + Then the response status should be 200 + And the response body should contain: + | message | Payment successful | + | payer_account_id | ACC123456 | + | payee | VendorXYZ | + | amount | 150 | + | reference | INV-9001 | + + @regression + Scenario: Payment with insufficient funds + Given I am authorized as "user1" + And account "ACC123456" has a balance of 50 + When I POST to "/transact/payment" with body: + | payer_account_id | ACC123456 | + | payee | VendorXYZ | + | amount | 200 | + | reference | INV-9001 | + Then the response status should be 400 + And the response body should contain "Insufficient funds" + + @regression + Scenario: Payment with missing payee + Given I am authorized as "user1" + When I POST to "/transact/payment" with body: + | payer_account_id | ACC123456 | + | amount | 100 | + | reference | INV-9001 | + Then the response status should be 400 + And the response body should contain "payee is required" + + @regression + Scenario: Payment when unauthorized + Given I am not authorized + When I POST to "/transact/payment" with body: + | payer_account_id | ACC123456 | + | payee | VendorXYZ | + | amount | 150 | + | reference | INV-9001 | + Then the response status should be 401 + And the response body should contain "Unauthorized" diff --git a/Online-Banking-App-Spring-Boot/test_docs/README.md b/Online-Banking-App-Spring-Boot/test_docs/README.md new file mode 100644 index 0000000..1ef51b2 --- /dev/null +++ b/Online-Banking-App-Spring-Boot/test_docs/README.md @@ -0,0 +1,28 @@ +# Banking API Test Documentation Index + +Welcome to the generated test documentation for the Banking API system. This suite summarizes business requirements, test flows, and coverage analysis based on feature files, endpoint definitions, and model discovery. + +## Documentation Contents + +- [Business Use Cases](business_use_cases.md): + - User stories, acceptance criteria, business rules, actor/persona descriptions, and endpoint/model cross-references. + +- [API Flows](api_flows.md): + - End-to-end sequences of API calls, data flows between client and server, state transitions, and error handling scenarios, cross-referenced to Gherkin feature coverage. + +- [Test Coverage Analysis](test_coverage.md): + - Coverage summary by controller, happy paths and negative scenarios, gap analysis (edge cases, permissions, integrations), prioritized recommendations, and actionable checklist for future QA efforts. + +## Cross-References + +- Documents link and reference each other for clarity and traceability. +- All content is generated from actual code analysis and Gherkin scenarios; see individual files for details. + +--- + +For detailed test scenarios, refer to the Gherkin feature files in the `/gherkin_scenarios/` directory. +For technical API request/response specifications, consult the OpenAPI or Swagger documentation. + +--- + +**Contact QA and Product for clarification or expansion on flows or requirements.** \ No newline at end of file diff --git a/Online-Banking-App-Spring-Boot/test_docs/api_flows.md b/Online-Banking-App-Spring-Boot/test_docs/api_flows.md new file mode 100644 index 0000000..c18eb4e --- /dev/null +++ b/Online-Banking-App-Spring-Boot/test_docs/api_flows.md @@ -0,0 +1,251 @@ +# Banking API: API Flows Documentation + +This documentation outlines key end-to-end business flows supported by the Banking API. Each flow details the required sequence of API calls, involved data and models, state transitions, and error handling, with references to relevant endpoint specifications and Gherkin scenarios. + +--- + +## Table of Contents + +1. [User Registration Flow](#user-registration-flow) +2. [User Login Flow](#user-login-flow) +3. [Account Management Flow](#account-management-flow) +4. [Dashboard Viewing Flow](#dashboard-viewing-flow) +5. [Transaction Flow](#transaction-flow) +6. [Payment Flow](#payment-flow) +7. [Verification Flow](#verification-flow) + +--- + +## 1. User Registration Flow + +**Purpose:** Allow new users to create an account. + +**Sequence:** +1. **POST** `/api/v1/users/register` + *Client submits registration details.* +2. **(Optional) POST** `/api/v1/users/verify` + *User provides verification code (from email/SMS).* + +**Data Flow:** +- Client sends registration data → +- API creates a `User` and `UserProfile` (in PENDING_VERIFICATION state if verification is required). + +**State Transitions:** +- Initial: `UNREGISTERED` +- After `/register`: `PENDING_VERIFICATION` or `ACTIVE` +- After successful `/verify`: `ACTIVE` + +**Error Handling:** +- Validation errors (400): missing/invalid fields +- Conflict (409): user exists +- Verification errors (401/422): wrong/failure code + +**References:** +- **Endpoints:** `/users/register`, `/users/verify` +- **Models:** `User`, `UserProfile` +- **Gherkin:** `Register new user`, `Verify user email` + +--- + +## 2. User Login Flow + +**Purpose:** Authenticate users and issue tokens. + +**Sequence:** +1. **POST** `/api/v1/auth/login` + *Credentials submitted; API returns JWT or session.* + +**Data Flow:** +- Client sends username/password → +- API validates and returns auth token + +**State Transitions:** +- User must be in `ACTIVE` state + +**Error Handling:** +- Authentication error (401): wrong credentials or unverified account +- Locked/disabled user (423/403) + +**References:** +- **Endpoints:** `/auth/login` +- **Models:** `User` +- **Gherkin:** `User logs in with valid credentials` + +--- + +## 3. Account Management Flow + +**Purpose:** Allow users to view, create, or manage bank accounts. + +**Sequence:** +1. **Auth required**: Ensure token from login flow. +2. **GET** `/api/v1/accounts` + *Fetch list of user's accounts.* +3. **POST** `/api/v1/accounts` + *Open new bank account.* +4. **PATCH** `/api/v1/accounts/{accountId}` + *Update account info/settings.* + +**Data Flow:** +- Authenticated token → +- API pulls `Account` records for current user +- On create/update: persists in database + +**State Transitions:** +- Account creation: `NEW` → `ACTIVE` +- Update: changes reflected on update fields (e.g., nickname, limits) + +**Error Handling:** +- Unauthorized (401) +- Validation errors (400) +- Permission errors (403): access to own accounts only + +**References:** +- **Endpoints:** `/accounts`, `/accounts/{accountId}` +- **Models:** `Account` +- **Gherkin:** `View account list`, `Create account`, `Update account` + +--- + +## 4. Dashboard Viewing Flow + +**Purpose:** Fetch consolidated financial overview. + +**Sequence:** +1. **Auth required** +2. **GET** `/api/v1/dashboard` + *Returns totals, balances, upcoming payments.* + +**Data Flow:** +- Authenticated token → +- API aggregates data from `User`, `Account`, `Transaction`, `Payment` + +**State Transitions:** +- No state changes; read-only + +**Error Handling:** +- Unauthorized (401) + +**References:** +- **Endpoints:** `/dashboard` +- **Models:** Aggregates: `User`, `Account`, `Transaction`, `Payment` +- **Gherkin:** `View dashboard` + +--- + +## 5. Transaction Flow + +**Purpose:** Manage account transactions (view, initiate transfer). + +**Sequence:** +1. **Auth required** +2. **GET** `/api/v1/accounts/{accountId}/transactions` + *Retrieve statement/history.* +3. **POST** `/api/v1/transactions` + *Request funds transfer/transaction.* + +**Data Flow:** +- Client requests transaction list → +- API retrieves from `Transaction` model +- For transfer: validates, persists, updates involved accounts + +**State Transitions:** +- On POST, creates new transaction in `PENDING` or `COMPLETED` (depending on processing rules) +- Account balances debited/credited as appropriate + +**Error Handling:** +- Unauthorized (401) +- Forbidden (403): not account owner +- Validation errors (400): insufficient funds, invalid details +- Transaction declined (402/422): e.g., over limits + +**References:** +- **Endpoints:** `/accounts/{accountId}/transactions`, `/transactions` +- **Models:** `Transaction`, `Account` +- **Gherkin:** `List transactions`, `Make transfer` + +--- + +## 6. Payment Flow + +**Purpose:** Initiate or view scheduled/payments (e.g., bill pay). + +**Sequence:** +1. **Auth required** +2. **GET** `/api/v1/payments` + *List all payments (scheduled, history).* +3. **POST** `/api/v1/payments` + *Schedule a payment.* + +**Data Flow:** +- Client requests/payment creation → +- API processes via `Payment` model, links to `Account` +- Scheduled/recurring payments use internal scheduler + +**State Transitions:** +- On create: `SCHEDULED` → `PROCESSING` → `COMPLETED` or `FAILED` + +**Error Handling:** +- Unauthorized (401) +- Validation errors (400): bad amounts, dates +- Payment failures (402): insufficient funds +- Not found (404): unknown payee + +**References:** +- **Endpoints:** `/payments` +- **Models:** `Payment`, `Account` +- **Gherkin:** `View payment list`, `Schedule payment` + +--- + +## 7. Verification Flow + +**Purpose:** Confirm user identity (KYC, device/email/phone). + +**Sequence:** +1. **User registration or updates trigger VERIFICATION_REQUIRED status** +2. **POST** `/api/v1/users/verify` + *Submit verification code/contact info.* +3. **(If necessary)** Repeat verification with new code (`/users/resend-verification`) + +**Data Flow:** +- Client submits code → +- API checks code, updates `User` status + +**State Transitions:** +- `PENDING_VERIFICATION` → `ACTIVE` (on success) +- Remain in `PENDING_VERIFICATION` (on failure) + +**Error Handling:** +- Invalid/missing code (422) +- Code expired (410) +- Attempts exhausted (423 lockout) + +**References:** +- **Endpoints:** `/users/verify`, `/users/resend-verification` +- **Models:** `User`, `VerificationCode` +- **Gherkin:** `Verify KYC`, `Resend verification code`, `Handle failed attempts` + +--- + +## Cross-Referencing Table + +| Flow | Endpoints | Models | Gherkin Scenarios | +|---------------------|------------------------------------------------------------------|---------------------------------------|------------------------------------------| +| Registration | `/users/register`, `/users/verify` | `User`, `UserProfile`, `Verification` | Register, verify | +| Login | `/auth/login` | `User` | Login | +| Account Mgmt | `/accounts`, `/accounts/{id}` | `Account` | List/create/update account | +| Dashboard | `/dashboard` | Aggregates (User, Account, ...) | Dashboard display | +| Transactions | `/accounts/{id}/transactions`, `/transactions` | `Transaction`, `Account` | List/make transactions | +| Payments | `/payments` | `Payment`, `Account` | View/schedule/cancel payment | +| Verification | `/users/verify`, `/users/resend-verification` | `User`, `VerificationCode` | User/email/phone/KYC verification | + +--- + +> For more detail, refer to individual [Endpoint Reference Documentation], [Model Definitions], and [Feature/Gherkin files]. +> Flows are secured with JWT/session authentication unless specified. +> All errors should be reported with detailed body and standard HTTP status codes as described per endpoint. + +--- + +**End of Flows Documentation** \ No newline at end of file diff --git a/Online-Banking-App-Spring-Boot/test_docs/business_use_cases.md b/Online-Banking-App-Spring-Boot/test_docs/business_use_cases.md new file mode 100644 index 0000000..868ed3d --- /dev/null +++ b/Online-Banking-App-Spring-Boot/test_docs/business_use_cases.md @@ -0,0 +1,259 @@ +# Business Use Cases Documentation – Banking API System + +--- + +## 1. User Registration + +### User Stories + +- **As a new user**, I want to sign up with my personal details (e.g., email, password, verification data), so that I can access banking services securely. +- **As an administrator**, I want only properly verified users to be registered, so that the platform remains compliant and secure. + +### Acceptance Criteria + +- User submits valid registration data (e.g., name, email, password). +- System validates and accepts the details. +- Duplicate registration with the same email is not allowed. +- Successful registration returns a confirmation and pending verification status (API: `POST /registration`). +- User receives verification instructions (email/SMS). + +### Business Rules & Constraints + +- Email format must be valid and unique. +- Password must meet complexity requirements (e.g., minimum length, mix of characters). +- Required fields cannot be blank. +- User must not have an already existing or blocked account. +- If registration fails (e.g., email in use), a meaningful error message is returned. +- All registration attempts are logged. + +### Actors / Users + +- **End User (Applicant):** Wishes to create an account, needs a frictionless and secure onboarding. + - Needs: Quick approval, data privacy. + - Permissions: None until registration is successful. +- **Administrator:** Manages user database and compliance. + - Needs: Prevent fraud, ensure compliance. + - Permissions: Can review and flag registrations. + +**Endpoints:** `POST /registration` +**Models:** `UserRegistration`, `RegistrationResponse` + +--- + +## 2. User Authentication + +### User Stories + +- **As a registered user**, I want to log in with my credentials, so I can securely access my account and services. +- **As a security officer**, I want to ensure only verified users can log in. + +### Acceptance Criteria + +- User submits correct email/username and password (`POST /auth/login`). +- If credentials are valid and user is verified, a secure authentication token (JWT) is returned. +- If credentials are invalid or verification incomplete, login is denied with an error. +- User can log out, which invalidates tokens (`POST /auth/logout`). + +### Business Rules & Constraints + +- Authentication is required for protected endpoints. +- Tokens expire and may require refresh tokens (`POST /auth/refresh`). +- Repeated failed login attempts trigger lockout or CAPTCHA. +- Passwords are never stored or returned in responses. +- Error messages must not reveal sensitive info. + +### Actors / Users + +- **Account Holder:** Wants access to bank services. + - Needs: Fast, secure login. + - Permissions: All authenticated user rights. +- **System:** Manages authentication workflow. + +**Endpoints:** `POST /auth/login`, `POST /auth/logout`, `POST /auth/refresh` +**Models:** `LoginRequest`, `AuthToken`, `ErrorResponse` + +--- + +## 3. Accounts (Profile & Management) + +### User Stories + +- **As an authenticated user**, I want to view and manage my account details, so I can keep information accurate and control my profile. +- **As support staff**, I need to see user account status. + +### Acceptance Criteria + +- User can retrieve current account info (`GET /accounts/{id}`). +- Users can update permissible fields (e.g., phone, address; not banking numbers). +- Only authenticated users can access their own account. +- Changes are validated and audited. + +### Business Rules & Constraints + +- Users can only see and update their own account (RBAC enforced). +- Required fields cannot be blank. +- Sensitive attributes (e.g., account number, balance) cannot be altered via profile endpoints. +- All changes are timestamped and stored. +- Invalid updates return clear error messages. + +### Actors / Users + +- **Account Holder:** Manages own records. + - Needs: Up-to-date, secure data. + - Permissions: Update personal info only. +- **Support Agent:** Can view but not edit user data. + - Needs: Assist with issues. + - Permissions: Read-only access. + +**Endpoints:** `GET /accounts/{id}`, `PATCH /accounts/{id}` +**Models:** `Account`, `AccountUpdate`, `AccountResponse` + +--- + +## 4. Dashboard + +### User Stories + +- **As an authenticated user**, I want to view a dashboard summarizing my balances, recent transactions, and account notifications, so I can monitor my finances at a glance. + +### Acceptance Criteria + +- Dashboard aggregates key account data (API: `GET /dashboard`). +- Shows up-to-date balances, currency, and recent transactions. +- Only available to authenticated users. +- Handles empty and busy states gracefully. + +### Business Rules & Constraints + +- Dashboard must load within SLA (e.g., 2 seconds). +- Only summarizes data owned by logged-in user. +- Error handling for data fetch failures. +- No sensitive PII is shown except to the account owner. + +### Actors / Users + +- **Account Holder:** Needs a unified view of financial status. + - Needs: Quick insights, data privacy. + - Permissions: Access own dashboard only. + +**Endpoints:** `GET /dashboard` +**Models:** `DashboardSummary`, `Transaction`, `Notification` + +--- + +## 5. Transactions + +### User Stories + +- **As a customer**, I want to view, search, and export my transaction history, so I can track activity and manage my records. +- **As a compliance officer**, I need auditability of transactions for suspicious activity detection. + +### Acceptance Criteria + +- Users can fetch transaction list with filters (date, type; `GET /accounts/{id}/transactions`). +- User can view transaction details (`GET /transactions/{id}`). +- Only own transactions are returned. +- System supports pagination and sorting. + +### Business Rules & Constraints + +- Transactions are immutable after posting. +- User may only access transactions for verified, open accounts. +- Deleted/blocked users cannot view transaction history. +- Data returned complies with privacy and retention regulations. +- Failed lookups or permissions return appropriate error codes (e.g., 403, 404). + +### Actors / Users + +- **Account Holder:** Keeps track of all movements, for reconciliation or budgeting. + - Needs: Data accuracy, privacy. + - Permissions: Own transactions only. +- **Compliance/Admin:** Audits records (not via user API). + +**Endpoints:** `GET /accounts/{id}/transactions`, `GET /transactions/{id}` +**Models:** `Transaction`, `PaginatedTransactions` + +--- + +## 6. Payments + +### User Stories + +- **As a user**, I want to initiate payments to other accounts, so I can transfer funds quickly and reliably. +- **As a recipient**, I want to be notified when funds are received. + +### Acceptance Criteria + +- User initiates a payment specifying recipient, amount, description (`POST /payments`). +- System checks sender balance, recipient validity, and anti-fraud measures. +- On success: Payment is created, sender balance debited, recipient credited. +- Confirmation sent to both parties. + +### Business Rules & Constraints + +- Payment amount must be positive and within sender’s daily/monthly limits. +- Sender must have sufficient funds. +- Cannot transfer to self or invalid/inactive recipients. +- All payments are recorded with unique IDs and timestamps. +- Failed payments return reason (e.g., insufficient funds). +- Payments can be reversed only per policy and with audit trail. + +### Actors / Users + +- **Payer (Sender):** Transfers money. + - Needs: Reliable, fast payments. + - Permissions: Debit own account. +- **Payee (Recipient):** Receives funds. + - Needs: Confidence in receipt. + - Permissions: Credit only. + +**Endpoints:** `POST /payments`, `GET /payments/{id}` +**Models:** `PaymentRequest`, `Payment`, `PaymentResponse`, `ErrorResponse` + +--- + +## 7. Verification (KYC / 2FA) + +### User Stories + +- **As a newly registered user**, I want to verify my identity (KYC) so that I can access all platform services. +- **As a security team member**, I want to ensure only verified users get full access to prevent fraud. + +### Acceptance Criteria + +- User completes verification (upload documents or confirm code; `POST /verification`). +- System validates the documents/codes. +- Status is updated in user profile. +- Access to sensitive features is restricted until verification is complete. + +### Business Rules & Constraints + +- Verification required as per regulatory standards (e.g., AML/KYC). +- Data must be securely stored and access controlled. +- Failed or fraudulent attempts are logged, and account locked after threshold. +- 2FA codes expire after a short duration. +- Re-verification may be required after significant profile updates. + +### Actors / Users + +- **Applicant/User:** Completes verification steps to unlock features. + - Needs: Quick verification, clear guidance. + - Permissions: Limited until verified. +- **Verifier/Admin:** Reviews and approves/denies submissions. + +**Endpoints:** `POST /verification`, `GET /verification/status` +**Models:** `VerificationRequest`, `VerificationStatus`, `User` + +--- + +# Endpoints and Model Cross-References + +- All endpoints require proper schema-validated requests/responses (see models above). +- Authentication required except for registration and initial login. +- Detailed error handling follows the `ErrorResponse` model. + +**Permissions are role-based** (user/admin/staff) and strictly enforced on each API according to the above business rules. + +--- + +**Note:** This documentation summarizes the API business use cases, cross-referencing endpoints and models, and consolidating acceptance and validation rules per flow. For technical request/response examples, refer to the API reference. \ No newline at end of file diff --git a/Online-Banking-App-Spring-Boot/test_docs/test_coverage.md b/Online-Banking-App-Spring-Boot/test_docs/test_coverage.md new file mode 100644 index 0000000..f18d081 --- /dev/null +++ b/Online-Banking-App-Spring-Boot/test_docs/test_coverage.md @@ -0,0 +1,182 @@ +# Banking API System Test Coverage Analysis + +## 1. Controller Coverage Overview + +Below summarizes key coverage areas per controller, as exercised by current Gherkin feature files. Each controller entry covers happy path, edge/corner cases, and error handling. + +--- + +### a. **AccountsController** + +**Endpoints:** +- `GET /accounts/{id}` +- `POST /accounts` +- `PUT /accounts/{id}` +- `DELETE /accounts/{id}` + +**Covered:** +- Retrieve account details (valid ID) +- Create new account (valid input) +- Update account (valid, existing) +- Delete account (existing) +- Error: Not found (invalid/non-existent ID) +- Error: Duplicate creation +- Error: Invalid input (malformed request body) + +**Gaps:** +- Partial updates (e.g., PATCH semantics if supported) +- Input boundary conditions (max name length, optional fields omitted) +- Permission checks (accessing others' accounts) +- Account locking, closed/frozen state flows +- Integration with user profile API + +**Risks:** +- Sensitive data exposure on account retrieval +- Authorization bypass for update/delete routes +- No current tests for IDOR (Insecure Direct Object Reference) + +--- + +### b. **TransactionsController** + +**Endpoints:** +- `POST /transactions` +- `GET /transactions/{id}` +- `GET /accounts/{id}/transactions` + +**Covered:** +- Standard deposit/withdrawal creation, positive amount +- List all transactions for an account +- Getting a single transaction (existing) +- Error: Insufficient funds +- Error: Nonexistent account reference +- Error: Invalid transaction type + +**Gaps:** +- Edge case: zero/negative amounts +- Duplicate transaction prevention (idempotency) +- Large/maximum-precision amounts +- Transaction ordering (race conditions) +- Cross-account transfers +- Fee/charge application +- Integration with external posting engine (if applies) + +**Risks:** +- Double-spend due to missing atomicity testing +- Injection attacks in transaction metadata +- Authorization on viewing transactions of unrelated accounts + +--- + +### c. **AuthController** + +**Endpoints:** +- `POST /auth/login` +- `POST /auth/logout` +- `POST /auth/refresh` + +**Covered:** +- Successful login, logout, and refresh for valid credentials +- Error: invalid credentials +- Error: expired/invalid refresh token + +**Gaps:** +- Rate-limiting/brute force lockout +- MFA/2FA flows +- OAuth/external provider integration +- Session revocation effects across multiple devices + +**Risks:** +- Account lockouts not triggering as expected +- JWT/session token leakage or privilege escalation +- No current coverage for residual session after password change + +--- + +### d. **UsersController** + +**Endpoints:** +- `GET /users/{id}` +- `PUT /users/{id}` +- `DELETE /users/{id}` + +**Covered:** +- View/update/delete own profile +- Error: non-existent user + +**Gaps:** +- Role-based permission checks (admin, user, etc.) +- Unauthorized access to other users +- Edge: update immutable fields (username/email constraint) +- Model validation for address/phone fields +- GDPR/account anonymization + +**Risks:** +- Broken access control +- Sensitive information leakage (PII exposure) +- Partial update exploits + +--- + +## 2. Cross-Cutting Risk and Gap Analysis + +- **Business flows:** + - End-to-end flows (e.g., create account, fund via transaction, view combined statement) are not fully tested. + - Exception and compensation flows (e.g., rollback on failed transfer) not covered. + +- **Integration points:** + - No Gherkin coverage for outbound calls (e.g., notifications, reporting, external KYC, core-banking integration) + - No fault tolerance/retry logic evaluations for external dependencies + +- **Security/authorization:** + - Insufficient scenario coverage for unauthorized/forbidden access on all endpoints + - Lacks model fuzzing/input validation checks for injection/vector attacks + +- **Audit and logging:** + - Absence of tests validating audit/log events on critical actions (account deletion, login, fund transfer) + +--- + +## 3. Recommendations and Testing Priorities + +**High Priority:** +- **Access control:** Add scenarios for unauthorized/role-based access for all sensitive endpoints. +- **Edge cases:** Cover input boundary/invalid data for all endpoints (lengths, types, missing fields). +- **Business flows:** Write end-to-end tests for typical customer journeys and negative/rollback flows. +- **Transaction atomicity:** Ensure no partial state on complex flows (e.g., cross-account transfer). +- **Security:** Add scenarios for injection, privilege escalation, and brute-force/lockout. + +**Medium Priority:** +- **External errors:** Simulate integration failure responses (KYC, notifications, posting services). +- **Idempotency:** Test duplicate/rapid-fire requests (transaction creation, account opening). +- **Audit/log validation:** Ensure key actions generate expected audit trail entries. + +**Low Priority:** +- GDPR-driven flows (anonymization, data export) +- Audit trail verification for non-critical flows +- UI-driven flows (if applicable) + +--- + +## 4. Actionable Checklist + +- [ ] Add permission/authorization scenarios for all endpoints +- [ ] Write Gherkin for input validation (min/max, formats, optional fields omitted) +- [ ] Cover partial update (PATCH), if supported +- [ ] Add business flow end-to-end Gherkin (account open → fund → transfer → close) +- [ ] Simulate external dependency failures and test fallback behavior +- [ ] Test negative amounts, duplicates, and maximum-precision values in transactions +- [ ] Validate audit log entry creation on critical state changes +- [ ] Add security-focused scenarios (IDOR, injection, rate limiting, token misuse) + +--- + +## 5. References + +- **Endpoints:** See OpenAPI/Swagger specification or [API Reference Document XYZ]. +- **Models:** See [Banking Domain Models v2.1]. +- **Business flows:** See [Customer Lifecycle Flows – Process Map]. + +--- + +**Contact QA team for detailed user stories and scenario templates to accelerate coverage expansion.** \ No newline at end of file