Skip to content

Commit

Permalink
Merge pull request #241 from NickPhura/ACRFD-55
Browse files Browse the repository at this point in the history
ACRFD-55: Tests + Misc Cleanup
  • Loading branch information
NickPhura authored Oct 28, 2019
2 parents b4c9c9a + 190a7dc commit 0a45299
Show file tree
Hide file tree
Showing 13 changed files with 229 additions and 269 deletions.
5 changes: 5 additions & 0 deletions .huskyrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"hooks": {
"pre-commit": "lint-staged"
}
}
7 changes: 7 additions & 0 deletions .lintstagedrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"*.js": [
"eslint --fix",
"prettier --write --loglevel warn",
"git add"
]
}
39 changes: 16 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ Useful Note: The handler function for each route is specified by the `operationI

Recommend reviewing the [Open API Specification](https://swagger.io/docs/specification/about/) before making any changes to the `swagger.yaml` file.

- Updates to the swagger may require updates to the mock handlers in the test files. See section on API testing below.

# Logging

A centralized logger has been created (see `api/helpers/logger.js`).
Expand Down Expand Up @@ -128,23 +130,23 @@ log.debug('Useful for logging objects and other developer data', JSON.stringify(

## Info

### Technolgies used
This project contains two kinds of unit tests. Regular unit tests and API unit tests, which require some special considerations and setup, as detailed in the API Testing section below.

[Jasmine](https://jasmine.github.io/), [Karma](https://karma-runner.github.io/latest/index.html), [Protractor](http://www.protractortest.org/)
### Technolgies used

## Initial Setup
[Jest](jasmine), [SuperTest](https://www.npmjs.com/package/supertest), [Nock](https://www.npmjs.com/package/nock), [Mongodb-Memory-Server](https://www.npmjs.com/package/mongodb-memory-server)

1) Start server and create database by running `npm start` in root
## Run Tests

2) Add Admin user to users collection
* Run the unit and api tests.
* Note: the `package.json` `tests` command sets the `UPLOAD_DIRECTORY` environment variable, the command for which may be OS specific and therefore may need adjusting depending on your machines OS.

``
db.users.insert({ "username": #{username}, "password": #{password}, roles: [['sysadmin'],['public']] })
``
```
npm run tests
```

3) Seed local database as described in [seed README](seed/README.md)

## API Testing
## API Tests

This project is using [jest](http://jestjs.io/) as a testing framework. You can run tests with
`yarn test` or `jest`. Running either command with the `--watch` flag will re-run the tests every time a file is changed.
Expand Down Expand Up @@ -234,19 +236,10 @@ This project uses [Keycloak](https://www.keycloak.org/) to handle authentication

Required environment variables:
```
TTLS_API_ENDPOINT="<see below>"
WEBADE_AUTH_ENDPOINT="<see below>"
WEBADE_USERNAME="<see below>"
WEBADE_PASSWORD="<see below>"
```
_Note: Get the values for TTLS_API_ENDPOINT, WEBADE_AUTH_ENDPOINT, WEBADE_USERNAME and WEBADE_PASSWORD, at [Openshift](https://console.pathfinder.gov.bc.ca:8443/console/projects) &rarr; Natural Resource Public Review and Comment (dev) project &rarr; Applications &rarr; Pods &rarr; prc-api pod &rarr; Environment._

2. Before starting the local Admin project, in file `src/app/services/keycloak.service.ts`, around line 17, change code to:
```
case 'http://localhost:4200':
// Local
this.keycloakEnabled = true;
break;
TTLS_API_ENDPOINT="<see OpenShift api deployment variables>"
WEBADE_AUTH_ENDPOINT="<see OpenShift api deployment variables>"
WEBADE_USERNAME="<see OpenShift api deployment variables>"
WEBADE_PASSWORD="<see OpenShift ttls-api-test secret>"
```

# VSCode Extensions
Expand Down
28 changes: 22 additions & 6 deletions api/helpers/ttlsUtils.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ var _ = require('lodash');

describe('TTLSUtils', () => {
const webADENock = {
domain: 'https://api.nrs.gov.bc.ca',
domain: 'https://t1api.nrs.gov.bc.ca',
path: '/oauth2/v1/oauth/token?grant_type=client_credentials&disableDeveloperFilter=true&scope=TTLS.*',
headers: {
reqheaders: {
Expand Down Expand Up @@ -58,7 +58,7 @@ describe('TTLSUtils', () => {
const accessToken = 'ACCESS_TOKEN';
const fileNumber = '99999';

const fileSearchPath = '/ttls-api/v1/landUseApplications?fileNumber=99999';
const fileSearchPath = '/ttls-api/v1/landUseApplications?fileNumber=99999&pageNumber=1&pageRowCount=100';
const ttlsApiResponse = {
'@type': 'LandUseApplicationResources',
links: [
Expand Down Expand Up @@ -102,6 +102,12 @@ describe('TTLSUtils', () => {
code: 'GS',
description: 'DISPOSITION IN GOOD STANDING'
},
reasonCode: {
'@type': 'ReasonCodeResource',
links: [],
code: 'C',
description: 'AMENDMENT APPROVED - APPLICATION'
},
landUseTypeCode: {
'@type': 'LandUseTypeCodeResource',
links: [],
Expand Down Expand Up @@ -158,12 +164,13 @@ describe('TTLSUtils', () => {
});
});

it('returns an application with the expected tenure status, stage, and location attrs', done => {
it('returns an application with the expected tenure status, reason, stage, and location attrs', done => {
TTLSUtils.getApplicationByFilenumber(accessToken, fileNumber).then(response => {
expect(response.length).toEqual(1);
let firstApplication = response[0];

expect(firstApplication.TENURE_STATUS).toEqual('DISPOSITION IN GOOD STANDING');
expect(firstApplication.TENURE_REASON).toEqual('AMENDMENT APPROVED - APPLICATION');
expect(firstApplication.TENURE_STAGE).toEqual('TENURE');
expect(firstApplication.TENURE_LOCATION).toEqual('Over the River and through the woods');

Expand Down Expand Up @@ -211,7 +218,7 @@ describe('TTLSUtils', () => {
}
};

const landUseAppSearchPath = '/ttls-api/v1/landUseApplications/666666';
const landUseAppSearchPath = '/ttls-api/v1/landUseApplications/666666?pageNumber=1&pageRowCount=100';
const ttlsApiResponse = {
'@type': 'LandUseApplicationResource',
links: [
Expand Down Expand Up @@ -246,6 +253,12 @@ describe('TTLSUtils', () => {
code: 'AC',
description: 'DISPOSITION IN GOOD STANDING'
},
reasonCode: {
'@type': 'ReasonCodeResource',
links: [],
code: 'C',
description: 'AMENDMENT APPROVED - APPLICATION'
},
landUseTypeCode: {
'@type': 'LandUseTypeCodeResource',
links: [],
Expand Down Expand Up @@ -329,6 +342,7 @@ describe('TTLSUtils', () => {
let firstApplication = response;

expect(firstApplication.TENURE_STATUS).toEqual('DISPOSITION IN GOOD STANDING');
expect(firstApplication.TENURE_REASON).toEqual('AMENDMENT APPROVED - APPLICATION');
expect(firstApplication.TENURE_STAGE).toEqual('TENURE');
expect(firstApplication.TENURE_LOCATION).toEqual('Over the River and through the woods');

Expand Down Expand Up @@ -424,8 +438,10 @@ describe('TTLSUtils', () => {
const firstParcel = application.parcels[0];
const geometry = firstParcel.geometry;
expect(geometry).not.toBeNull();
expect(geometry.type).toEqual('Polygon');
expect(geometry.coordinates).toBeDefined();
expect(geometry.type).toEqual('GeometryCollection');
expect(geometry.geometries).toBeDefined();
expect(geometry.geometries[0].type).toEqual('Polygon');
expect(geometry.geometries[0].coordinates).toBeDefined();

done();
});
Expand Down
19 changes: 16 additions & 3 deletions api/test/application.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ const mongoose = require('mongoose');
const request = require('supertest');
// const nock = require('nock');
// const tantalisResponse = require('./fixtures/tantalis_response.json');
const fieldNames = ['description', 'tantalisID'];
const _ = require('lodash');
const TTLSUtils = require('../helpers/ttlsUtils');

Expand All @@ -14,7 +13,13 @@ require('../helpers/models/application');
require('../helpers/models/feature');
const Application = mongoose.model('Application');
const Feature = mongoose.model('Feature');

/*************************************
Mock Route Handlers + Helper Methods
*************************************/

const idirUsername = 'idir/i_am_a_bot';
const fieldNames = ['description', 'tantalisID'];

function paramsWithAppId(req) {
let params = test_helper.buildParams({ appId: req.params.id });
Expand Down Expand Up @@ -68,6 +73,10 @@ app.put('/api/application/:id/unpublish', function(req, res) {
return applicationController.protectedUnPublish(paramsWithAppId(req), res);
});

/*************************************
General Test Data + Helper Methods
*************************************/

const applicationsData = [
{ description: 'SPECIAL', name: 'Special Application', tags: [['public'], ['sysadmin']], isDeleted: false },
{ description: 'VANILLA', name: 'Vanilla Ice Cream', tags: [['public']], isDeleted: false },
Expand All @@ -88,6 +97,10 @@ function setupApplications(applicationsData) {
});
}

/*************************************
Tests
*************************************/

describe('GET /application', () => {
test('returns a list of non-deleted, public and sysadmin Applications', done => {
setupApplications(applicationsData).then(documents => {
Expand Down Expand Up @@ -336,7 +349,7 @@ describe('POST /application', () => {
});
});

test('defaults to sysadmin for tags and review tags', done => {
test('defaults to sysadmin for tags', done => {
request(app)
.post('/api/application')
.send(applicationObj)
Expand Down Expand Up @@ -505,7 +518,7 @@ describe('POST /application', () => {

describe('when the login call fails', () => {
let loginPromise = new Promise(function(resolve, reject) {
reject({ statusCode: 503, message: 'Ooh boy something went wrong' });
reject({ code: 503, message: 'Ooh boy something went wrong' });
});

beforeEach(() => {
Expand Down
88 changes: 14 additions & 74 deletions api/test/comment.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,17 @@ const mongoose = require('mongoose');
const commentFactory = require('./factories/comment_factory').factory;
const commentPeriodFactory = require('./factories/comment_period_factory').factory;
const request = require('supertest');

const fieldNames = ['comment', 'name'];

const _ = require('lodash');

const commentController = require('../controllers/comment.js');
require('../helpers/models/comment');
const Comment = mongoose.model('Comment');

/*************************************
Mock Route Handlers + Helper Methods
*************************************/
const fieldNames = ['comment', 'name'];

function paramsWithCommentId(req) {
let params = test_helper.buildParams({ CommentId: req.params.id });
return test_helper.createSwaggerParams(fieldNames, params);
Expand Down Expand Up @@ -61,6 +63,10 @@ app.put('/api/comment/:id/unpublish', function(req, res) {
return commentController.protectedUnPublish(paramsWithCommentId(req), res);
});

/*************************************
General Test Data + Helper Methods
*************************************/

const commentsData = [
{
name: 'Special Comment',
Expand All @@ -86,6 +92,10 @@ function setupComments(commentsData) {
});
}

/*************************************
Tests
*************************************/

describe('GET /Comment', () => {
test('returns a list of non-deleted, public and sysadmin Comments', done => {
setupComments(commentsData).then(documents => {
Expand Down Expand Up @@ -278,7 +288,7 @@ describe('POST /public/comment', () => {
});

describe('tags', () => {
test('defaults to sysadmin for tags and review tags', done => {
test('defaults to sysadmin for tags', done => {
let commentObj = {
name: 'Victoria',
comment: 'Victoria is a great place'
Expand All @@ -294,9 +304,6 @@ describe('POST /public/comment', () => {

expect(comment.tags.length).toEqual(1);
expect(comment.tags[0]).toEqual(expect.arrayContaining(['sysadmin']));

expect(comment.review.tags.length).toEqual(1);
expect(comment.review.tags[0]).toEqual(expect.arrayContaining(['sysadmin']));
done();
});
});
Expand Down Expand Up @@ -393,73 +400,6 @@ describe('PUT /comment/:id', () => {
});
});

describe('review tags', () => {
test('sets sysadmin and public tags when commentStatus is "Accepted" ', done => {
let updateData = {
review: {},
commentStatus: 'Accepted'
};
let uri = '/api/comment/' + existingComment._id;
request(app)
.put(uri, updateData)
.send(updateData)
.then(response => {
Comment.findById(existingComment._id).exec(function(error, updatedComment) {
expect(updatedComment).not.toBeNull();
expect(updatedComment.review).not.toBeNull();
let reviewTags = updatedComment.review.tags;
expect(reviewTags.length).toEqual(2);
expect(reviewTags[0]).toEqual(expect.arrayContaining(['sysadmin']));
expect(reviewTags[1]).toEqual(expect.arrayContaining(['public']));
done();
});
});
});

test('sets sysadmin tags when commentStatus is "Pending" ', done => {
let updateData = {
review: {},
commentStatus: 'Pending'
};

let uri = '/api/comment/' + existingComment._id;
request(app)
.put(uri, updateData)
.send(updateData)
.then(response => {
Comment.findById(existingComment._id).exec(function(error, updatedComment) {
expect(updatedComment).not.toBeNull();
expect(updatedComment.review).not.toBeNull();
let reviewTags = updatedComment.review.tags;
expect(reviewTags.length).toEqual(1);
expect(reviewTags[0]).toEqual(expect.arrayContaining(['sysadmin']));
done();
});
});
});
test('sets sysadmin tags when commentStatus is "Rejected" ', done => {
let updateData = {
review: {},
commentStatus: 'Rejected'
};

let uri = '/api/comment/' + existingComment._id;
request(app)
.put(uri, updateData)
.send(updateData)
.then(response => {
Comment.findById(existingComment._id).exec(function(error, updatedComment) {
expect(updatedComment).not.toBeNull();
expect(updatedComment.review).not.toBeNull();
let reviewTags = updatedComment.review.tags;
expect(reviewTags.length).toEqual(1);
expect(reviewTags[0]).toEqual(expect.arrayContaining(['sysadmin']));
done();
});
});
});
});

describe('comment author tags', () => {
test('sets sysadmin tags when commentAuthor requestedAnonymous ', done => {
let updateData = {
Expand Down
Loading

0 comments on commit 0a45299

Please sign in to comment.