← NodeJS Teams

Testing Services

Binci

We use binci to containerize our services using Docker. Binci is very similar to Docker-compose. We can use this to test our services locally and will always run the test suites before opening a PR.

Pre-requisites

binci.yml

binci is configured via the binci.yml file, located at the root of the project. You can check the official docs for more information but the following are areas of interest for now.

  • env contains all of the environment variables required by the application to run

  • expose details the ports that will be made available for the host to access the service

  • taskslists all of the available binci commands

  • services this lists all the services that will be stood up for your application to run locally, such as vault, redis or postgres depending on the requirements. The services listed here will not diect traffic to another environment such as UAT etc. It is all for local development.

Common commands

  • binci install installs dependencies by running pnpm install

  • binci build builds the project by running pnpm build

  • You can chain commands also: binci install build

  • binci dev runs the application locally for you to test

  • binci test runs the unit tests and e2e tests by running pnpm test

  • binci test:watch will rerun the tests after making changes, similar to nodemon

  • binci test:unit will run the unit tests

  • binci test:unit:watch will rerun the unit tests after making changes

  • binci test:e2e will run the end to end tests

  • binci test:e2e:watch will rerun the end to end tests after making changes

  • binci test:integration will run the integration tests

  • binci test:integration:watch will rerun the integration tests after making changes

Local Testing

After running binci dev your service is now running locally for you to test via cURL or Postman etc.

Your test may have some requirements in order to be successful, such as eauth token, ConsumerJWT, x-forwarded-for, referrer and/or origin headers etc.

  • Get eauth token. The eauth -> x-bannoenterprise0 token is a fallback method that we use since our services are designed to only ever be called if x-bannoenterprise0 or x-bannoconsumer0 are present. This passes auth checks and node-api-gateway calls the service.

  • To get a ConsumerJWT token, the steps are similar to getting eauth but instead of logging into uat.banno.com, you would log into devbank.banno-uat.com using your test user and get the token from Chrome dev tools. Note: A ConsumerJWT is not suitable for any enterprise endpoint testing.

  • For x-forwarded-for you can set it to your ip. We need to set this as it is usually set by the nginx load balancer and we call node-api-gateway

  • For origin and referrer headers, make sure the url is correct. See Example #2 below

Examples

  1. The below example is going to hit the /a/consumer-login/api/institutions/:institutionId/users/:userId/2fa/methodsendpoint in node-consumer-login-proxy:

    curl -v
    -X PUT
    -d ‘{“authMethods”:[{“authMethod”:“push”,“enabled”:true}]}’
    -H ‘Content-Type: application/json’
    -H “cookie: eauth=$eauth”
    -H “x-forwarded-for: $ip”
    http://localhost:8080/a/consumer-login/api/institutions/<institution_id>/users/user_id/2fa/methods

  2. The below is an example of a non-banno enterprise/platform (mobile/online) route, showing the use of ConsumerJwt, Referrer and Origin. This example is going to hit the v0/oob/enrollments/authy endpoint in node-consumer-login-proxy:

    curl -v
    -H ‘origin: http://localhost:8080’
    -H ‘referer: http://localhost:8080/login’
    -H ‘Content-Type: application/json’
    -H “cookie: ConsumerJwt=$ConsumerJwt”
    http://localhost:8080/v0/oob/enrollments/authy

In the terminal running the service, the logs will be more verbose for this request including InternalApiRequest, VaultRetrieval, DecodedJwt, AuthyGetEnrollment, and SuccessResponse and a 200 OK HTTP response from your cURL command along with a body containing the user enrollments, including "validDeliveryMethods":["call","sms","authy"]}, which is valid for this test.

Troubleshooting

Please update this as you encounter/resolve issues testing a service locally

  • Logs showErrorResponse: The request body was invalid. cURL response shows HTTP/1.1 401 Unauthorized

    Check the x-forwarded-for header is set

  • Logs showHttpError: Internal Server Error. cURL response shows HTTP/1.1 401 Unauthorized

    Check the eauth token has not expired

  • Node binding issues Sometimes native modules for mac os x can cause “node binding” issues because binci is running as a docker container (linux)

  • sh: can't open '/tmp/binci.sh': No such file or directory

    Add the following to your ~/.bashrc or ~/.zshrc and relaunch your shell:

    export BINCI_TMP=/tmp/rancher-desktop (or some other directory)