Skip to content

121 is working towards an open source platform that allows safe, fast and fair humanitarian cash based aid programs using blockchain.

License

Notifications You must be signed in to change notification settings

RubenGeo/121-platform

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

121 platform

121 is an open source platform for Cash based Aid built with Digital Account & Local/Global Financial service partners. -- Learn more about the platform: https://www.121.global/


License Releases


Status

Interfaces Build Status
PA-App Build Status
AW-App Build Status
HO-Portal Build Status
Services Build Status
121-service Build Status
PA-accounts-service Build Status

Documentation

The documentation of the 121 platform can be found on the Wiki of this repository on GitHub: https://github.com/global-121/121-platform/wiki


Getting Started

To set up a local development-environment:

With these tools in place you can checkout the code and start setting up:

git clone https://github.com/global-121/121-platform.git

Setup Services

Follow the "Getting started / installation"-section in the services/README-file.

Start Services

To start all services, after setup, from the root of this repository, run:

npm run start:services

To see the status/logs of all Docker-containers, run from the services/-folder:

docker-compose logs -f <container-name>

To verify the successful installation and setup of services, access their Swagger UI:

URL or run:
121-service http://localhost:3000/docs/ npm rum open:121-service
PA-accounts-service http://localhost:3001/docs/ npm rum open:pa-accounts

Setup Interfaces

Install dependencies for all the interfaces at once, run:

npm run install:interfaces

Or to install 1 specific interface's dependencies, run: (where <interface-name> is one of pa, aw, ho)

npm run install:<interface-name>

Or from each of the individual interface directories(interfaces/*) run:

npm install

Start Interfaces

To start all interfaces at once, from the root of this repository, run:

npm run start:interfaces

To start an individual interface in development mode:

  • Run: (where <interface-name> is one of pa, aw, ho)

    npm run start:<interface-name>
    
  • Or explore the specific options as defined in each interface's own package.json or README.md.

All individual Angular applications, when started will be available via:

URL or run:
PA-App http://localhost:8008 npm run open:pa
AW-App http://localhost:8080 npm run open:aw
HO-Portal http://localhost:8888 npm run open:ho

Local development

Recommended code-editor/IDE tools/extensions

To help with some types if files/tasks we've listed them here:

  • Workspace recommendations for VS Code When you open the root-folder of this repository in VSCode and go to: "Extensions" and use the filter: "Recommended";
    A list should be shown and each extension can be installed individually.

    Generic highlights:

    Interfaces / front-end highlights:

    • i18n Ally - To work with translations in the HTML-templates and component TS-files

Common problems with Local Environment set-up

Swagger-UI not accessible

If the Swagger-UI is not accessible after installing Docker and setting up the services, you can take the following steps to debug:

  1. docker-compose ps to list running containers and their status
  2. docker-compose logs -f <container-name> to check their logs/console output (or leave out the <container-name> to get ALL output)

Docker related issues

If there are issues with Docker commands, it could be due to permissions. Prefix your commands with sudo docker....

Database related errors

If the errors are related to not being able to access/connect to the database then reset/recreate the database by:

  • Setting dropSchema: true in ormconfig.ts of the specific service.
  • Restarting that service will reset/recreate its database(-schema)

Updating/adding Node.js dependencies

When new Node.js dependencies are added to the services since it is last build on you local machine, you can:

  • Verify if everything is installed properly:

    docker-compose exec <container-name> npm ls
    
  • If that produces errors or reports missing dependencies, try to build the service from a clean slate with:

    npm run install:services -- --no-cache <container-name>
    

    Or similarly:

    npm run start:services -- --force-recreate <container-name>
    

Testing

  • Scenarios of end-to-end/integration-tests for the whole platform are described in /features.
  • Each component has its own individual tests:
    • Unit-tests and UI-tests for all interfaces; Run with npm test in each interfaces/*-folder.
    • Unit-tests and integration-tests for all services; Run with npm test in each services/*-folder.

Unit Tests

Why?

There are a few reasons why we write unit tests cases:

  • Unit tests are written to ensure the integrity the functional level aspect of the code written. It helps us identify mistakes, unnecessary code and also when there is room for improvement to make the code more intuitive and efficient.
  • We also write unit test cases to clearly state what the method is supposed to do, so it is smoother for new joiners to be onboarded
  • It helps us achieve recommended devOps protocols for maintaining code base while working within teams.

Maintenance with future changes

How are Unit Tests affected when we make changes within the code in future?

  • We should aim to write and update unit tests along side the current development, so that our tests are up to date and also reflect the changes done. Helps us stay in track
  • Unit tests in this case differ from manual or automated UI testing. While UI may not exhibit any changes on the surface it is possible code itself might be declaring new variables or making new method calls upon modifications, all of those need to be tested and the new test-scenario or spec-file should be committed together with the feature change.

Our testing framework(s)

We are using jasmine for executing unit tests within interfaces and jest within services. However, while writing the unit test cases, the writing style and testing paradigm do not differ since jest is based on jasmine to begin with.

Key points for writing tests

Keep the following points in mind while writing test cases:

  • We should follow a practice to write to tests for all methods except the ones which are private.

  • Every method which contains an async call, can be tested by returning a promise that can be spied and stubbed to verify the UI behavior.

  • We should aim to write a complementary test for each method written on the file

  • Verify class declarations and modifications through methods, boolean variables, string variables, etc.

  • Monitor changes within the HTML template(values of attributes, content of buttons) and verify through test cases

  • Create "it ("should...." scenarios for conditional code as well (e.g. if/else blocks)

  • NOTE: It isn't necessary to test all the variables and all method calls, however a highlight of what the method is supposed to accomplish should be reflected within the test cases.

  • Use the "fit" and "fdescribe" to execute only the unit test cases that you are currently working on. Make sure not to commit these commands.

  • Testing class variables and objects, when they are being defined or constructed

  • There are several methods which serve the purpose of defining class wide variables, which we should also test and verify. One of the typical examples of one such method is ngOnInit

it('ngOnInit: should set up variables', () => {
  expect(component.isLoggedIn).toBeDefined(); // check for class variables to be defined
  expect(component.someValye).toBeTruthy(); // check for a variable to be TRUE
  expect(component.someValye).toBeFalsy(); // check for a variable to be FALSE
});

The methods written as toBeTruthy are called matchers, they help us compare the expected values, their types, whether a method was called, the arguments of the methods and also their existence. There are various methods provided by the testing module. We can find a detailed list of those methods and their usage here: https://jasmine.github.io/api/3.5/matchers.html

A short introduction tutorial, to start off writing test cases can be found at: https://jasmine.github.io/tutorials/your_first_suite

Testing method callbacks and changes
  • In order to test for methods to have been called, or been called with certain arguments use spy and toHaveBeenCalled/ toHaveBeenCalledWith matchers.
// Code
public doLogin(event: Event) {
  event.preventDefault();
  // ...rest of the actual method.
}

// Test
it('some_method: should call another fn', () => {
  spyOn(event, "preventDefault"); // Monitor the said method
  component.doLogin(event); // call some_method
  expect(event.preventDefault).toHaveBeenCalled(); // check for the monitored method to have been called
});
Testing conditional statements
  • Make separate it blocks for different conditions.
it("Test when xyz === 'some-value'", () => {});
it("Test when xyz !== 'some-value'", () => {});
Testing Async methods (i.e. methods which make an API call)
  • Make a Spy for the specific async call which returns a Promise object. For example a method containing a call routine this.programsService.changePassword can be spied using following
let spy = spyOn(component.programsService, 'changePassword').and.returnValue(
  Promise.resolve(true),
);
  • Based on the changes / executions upon the completion of the async request, we should aim to test the changes and modifications.
// block to test what happens after the async calls:
spy.calls.mostRecent().returnValue.then(() => {
  // Here goes expectations and changes
});
  • Make sure the done() method is used to account for the async calls and fake async stubs/spies.
it('XYZ', (done) => {
  // spies and stubs

  spy.calls.mostRecent().returnValue.then(() => {
    // tests
    done(); // to complete the tests
  });
});
Testing HTML elements
  • By using the defaultEl and the monitoring the changes within the HTML pages. However, the testing here does not bring a lot of productivity in terms of what we get out of it. So, we can choose to discard this aspect of testing.
  • HTML elements are tested by matching the string values, which is not very intuitive with i18n modules in use

Releases

See notable changes and the currently release version in the CHANGELOG.

Release Checklist

This is how we create and publish a new release of the 121-platform.
(See the glossary for definitions of some terms.)

  • Define the date/time of the release. (Notify the dev-team for a code-freeze.)
  • Define what code gets released. ("Is the current master-branch working?")
  • Define the version(-number) for the upcoming release.
  • Update the CHANGELOG with the date + version.
    • Commit changes to master-branch on GitHub.
  • Create a release-branch ("release/<version>") from current master-branch and push this branch to GitHub
  • "Draft a release" on GitHub
    • Add the version to create a new tag
    • Select the new release/<version>-branch
    • Set the title of the release to version. Add a short description and/or link to relevant other documents (if applicable)
    • Publish the release on GitHub

Patch/Hotfix Checklist

This follows the same process as a regular release + deployment. With some small changes.

  • Code does not need to be frozen. (As there is no active development on the release-branch)

Manual approach

  • Checkout the release/<version>-branch that needs the hotfix.
  • Create a new local branch (e.g. release/<v0.x.1>) and make the changes
  • Push this branch directly to the main/upstream repository, not to a personal fork.
  • Create a new release (see above) and publish it.
    The publish-command will invoke the webhook(s), which trigger an automated deploy for environments on that same minor version.
  • Add the hotfix-release to the CHANGELOG
  • After the hotfix-release, apply the same fix to the master-branch in a regular PR (by creating a PR from the hotfix-branch to master-branch)

GitHub web-interface-only approach

  • Browse to the specific file that needs a fix on GitHub, click "edit" and make the changes
    The URL will look like: https://github.com/global-121/121-platform/edit/release/v1.0.0/<path-to-file>
  • Select "Create a new branch for this commit and start a pull request" from the "commit changes"-box
  • Use release/v1.0.1 as the branch-name by clicking "Propose changes"
    This branch will now be created and is available to use for a new release
  • Add the hotfix-release to the CHANGELOG and commit to the same release/v1.0.1 branch.
  • Create a new release (see above) and publish it.
    The publish-command will invoke the webhook(s), which trigger an automated deploy for environments on that same minor version.
  • After the hotfix-release, apply the fixes to the master-branch by merging the PR created.

Deployment

To "test" environment

  • Merged PR's to 'master' branch are automatically deployed to the test-server. (via webhook, see: /tools#GitHub-webhook)
    • To skip deployment after a PR is merged, add [SKIP CD] to the title of the PR before merging. (For example when only updating documentation)
  • Make sure to update the environment-settings as soon as possible, preferably before the merge+deploy.

To "production" environment

On initial deployment (only)

On next deployments

  • Decide on what version to deploy
  • Check for any changes/additions/removals in the CHANGELOG
  • Prepare the environment accordingly (in all .env-files)
    • Build the platform (by running the deploy script):
      Run: sudo ./tools/deploy.sh <target-branch>, where <target-branch> is for example: release/v1.1.0

Glossary

Term Definition (we use)
version A 'number' specified in the SemVer-format: 1.1.0
tag A specific commit or point-in-time on the git-timeline; named after a version, i.e. v1.1.0
release A fixed 'state of the code-base', published on GitHub
deployment An action performed to get (released) code running on an environment
environment A machine that can run code (with specified settings); i.e. a server or VM, or your local machine

License

Released under the Apache 2.0 License. See LICENSE.

About

121 is working towards an open source platform that allows safe, fast and fair humanitarian cash based aid programs using blockchain.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • TypeScript 76.8%
  • HTML 11.1%
  • Gherkin 6.2%
  • SCSS 2.7%
  • JavaScript 2.0%
  • Shell 1.1%
  • Other 0.1%