diff --git a/README.md b/README.md index 28adf275..634335a6 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ This repository is being development under a task order of the Agile Blanket Pur - AWS_REGION - AWS_BUCKET_NAME - SUDS_API_URL - - To point at mocks, update this to be `http://localhost:${PORT}/mocks` + - To use the moxai dependency and point at the mock API, update this to be `http://localhost:${PORT}/mocks`. - Dotenv: - [Dotenv](https://www.npmjs.com/package/dotenv) is used which can load environment variables from a .env file into process.env @@ -74,6 +74,10 @@ Refer to application package and dependency trackers for additional dependency i - [VersionEye](https://www.versioneye.com/user/projects/58a669e7b4d2a20055fcb84c) - [Bithound](https://www.bithound.io/github/nci-ats/fs-middlelayer-api/feat%2Fswagger-ui/dependencies/npm) +The Moxai package is a dependency for testing and was built specifically for this project. Moxai was published as an [independent package](https://www.npmjs.com/package/moxai) that can be used with any Express application. This application uses the moxai package as a placeholder mock API. The /mocks/basic.json file maintains the API endpoint schema. + +The controllers/index.js file has random control number generation logic that should be removed when the mock API is replaced with the Basic API. + ## Point of Contact and Notifications You can report issues and submit questions by opening a new [Issue](https://help.github.com/articles/creating-an-issue/) in GitHub. You can [Watch](https://help.github.com/articles/watching-repositories/) this repo to receive notifications from GitHub when a new issue is posted, when an existing issue’s status is updated, and when a pull request is created. diff --git a/docs/ci-cd.md b/docs/ci-cd.md index cb10cb22..e0a5f188 100644 --- a/docs/ci-cd.md +++ b/docs/ci-cd.md @@ -1,8 +1,8 @@ # Travis CI -Travis is configured using the `.travis.yml` file created in the core repository. +[Travis CI](https://docs.travis-ci.com/) (continuous integration) is configured using the `.travis.yml` file created in the core repository. -Travis CI is configured to build on each commit or on each pull request. +Travis is triggered to build with every commit and pull request creation or merge. The build process includes the following steps: @@ -12,4 +12,4 @@ The build process includes the following steps: 2. `npm run lint` 3. `istanbul cover ./node_modules/mocha/bin/_mocha --report lcovonly -- -R spec --recursive` 4. `codecov` -3. If the build is successful, Travis automatically deploys the build to Heroku. An `api_key` in `.travis.yml` directs the deployment to `fs-epermit-dev`. +3. A successful build on a PR merge triggers a branch-dependent deployment to cloud.gov or Heroku. An `api_key` in `.travis.yml` directs the deployment to `fs-epermit-dev`. diff --git a/docs/code-quality.md b/docs/code-quality.md new file mode 100644 index 00000000..c2d2f84c --- /dev/null +++ b/docs/code-quality.md @@ -0,0 +1,31 @@ +# Code Quality and Coverage + +We are using the following packages for maintaining code quality and coverage. + +## Code Quality + +### ESLint + +[ESLint](https://www.npmjs.com/package/eslint) is a pluggable linting utility for JavaScript. The linting configuration and rules are provided in the `.eslintrc.json` file. Use `npm run lint` to run ESLint. + +### MarkdownLint + +[MarkdownLint](https://www.npmjs.com/package/markdownlint) is a static analysis tool with a library of rules to enforce standards and consistency for Markdown files. +The linting configuration and rules are provided in the `.markdownlint.json` file. +Use `npm run lint:md` to run MarkdownLint. + +### JSDoc + +[JSDoc](https://www.npmjs.com/package/jsdoc) is an API documentation generator for JavaScript. +JSDoc documentation is available in the `/docs/code` folder and accessed via `/docs/code`. Use `npm run doc` to run JSDoc. + +## Code Coverage + +### Codecov + +We use [Istanbul](https://www.npmjs.com/package/istanbul) to run the Mocha test cases. [Codecov](https://www.npmjs.com/package/codecov) makes the Instanbul test coverage report available to Travis CI. +Using `npm run coverage` runs the `istanbul cover ./node_modules/mocha/bin/_mocha -- --recursive` command. This command runs the tests and creates the report in `/coverage`. The coverage indicates the percentage of code covered by unit testing. + +### Code Climate + +[Code Climate](https://www.npmjs.com/package/codeclimate) is another tool for generating [unit test coverage reports](https://codeclimate.com/github/nci-ats/fs-middlelayer-api/code). Code Climate is configured in the `.codecov.yml` file. diff --git a/docs/epermit_api_architecture.pdf b/docs/epermit_api_architecture.pdf new file mode 100644 index 00000000..66b27cf7 Binary files /dev/null and b/docs/epermit_api_architecture.pdf differ diff --git a/docs/permit-creation.md b/docs/permit-creation.md index ec18dda5..8b0caeb3 100644 --- a/docs/permit-creation.md +++ b/docs/permit-creation.md @@ -3,11 +3,11 @@ These steps define the process for creating a new permit type using Example Permit. 1. Create Swagger Documentation. - 1. Go to `src/api.json` and add the new `GET`, `PUT`, and `POST` route for the new Example Permit as shown below: + 1. Go to the `src/api.json` Swagger document file and add the new `GET`, `PUT`, and `POST` route for the new Example Permit as shown below: `/permits/applications/special-uses/commercial/example-permit/` - 2. Add the relevant application form fields for these routes.
+ 2. Create the GET endpoint for the new permit with the relevant application form fields in the Swagger document.
Example `GET` in `api.json`: /permits/applications/special-uses/commercial/example-permit{controlNumber}/: { @@ -26,18 +26,19 @@ These steps define the process for creating a new permit type using Example Perm Intake options include: - `middleLayer/` - - From the application table in middleLayer database, column name + - From the application table in middleLayer database, column name `` - `addresses/` - - From Basic API response, addresses array + - From Basic API response JSON; using the first element of the `addresses` array, `` is the key of the key value pair - `holders/` - - From Basic API response, holders array + - From Basic API response JSON; using the first element of the `holders` array, `` is the key of the key value pair - `phones/` - - From Basic API response, phones array + - From Basic API response JSON; using the first element of the `phones` array, `` is the key of the key value pair - `` - From Basic API response, not in any array - 3. Example `POST` in `api.json`: + 3. Create the POST endpoint for the new permit with the relevant application form fields.
+ Example `POST` in `api.json`: "/permits/applications/special-uses/commercial/example-permit/": { "post": { @@ -73,7 +74,8 @@ These steps define the process for creating a new permit type using Example Perm "required": ["region","forest","district"...] } - 4. Example `POST` in `validation.json`: + 4. The `validation.json` is a schema file for validating submitted data through `POST` routes.
+ Example `POST` in `validation.json`: "district": { "default":"", @@ -113,7 +115,9 @@ These steps define the process for creating a new permit type using Example Perm }, - - `fromIntake` indicates whether the field will be directly populated with user input. If set to `false`, `madeOf` must be provided, giving the fields, or strings used to populate this field. + - `fromIntake` indicates whether the field will be directly populated with user input. If set to `false`, the API will populate this field using the strings and fields provided under `madeOf`. + + - `store` describes where this field should be stored, either in the middlelayer DB or in the basic API. It can list multiple places to store this field Files: - `maxSize` is measured in megabytes @@ -128,7 +132,7 @@ These steps define the process for creating a new permit type using Example Perm If the store contains one of the `basic` type options, `basicField` attribute must be included. This is the name of the field used to submit this data to the Basic API. 2. Extend the schema, if necessary. - 1. If there are any new form fields not supported by the current middle-layer database, they can be added in the application table. To do this, go to `dba/migrations/ 02-create-applications.js` and update the sequelize migration script as needed. Also, update `src/models/applications.js` to include the new database fields. + 1. If there are any new form fields not supported by the current middle-layer database, they can be added in the application table. To do this, go to `dba/migrations/ 02-create-applications.js` and update the sequelize migration script as needed. Also, update `src/models/applications.js` to include the new database fields. This applies only if you are recreating the applications table. Please refer to the [Sequelize migrations documentation](http://docs.sequelizejs.com/en/latest/docs/migrations/) for information on altering an existing table. 2. If there are routing changes, update `src/controllers/index.js`. 3. If there are validation changes, update `src/controllers/validation.js`. 4. If there are any changes on how the files are to be stored, update `src/controllers/store.js`. diff --git a/docs/testing.md b/docs/testing.md index c3f5947b..f4f3f821 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -11,12 +11,12 @@ These two files contain unit testing test cases: - `test/controllers-test.js` - `test/functions-test.js` -## API Tests +## API Tests (Integration Tests) API tests run the test case against the API routes. These three files contain the API testing test cases: -- `test/authetnication.js` +- `test/authentication.js` - `test/noncommercial.js` - `test/outfitters.js` diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 1ab9f93f..0ae40748 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1,6 +1,6 @@ { "name": "fs-middlelayer-api", - "version": "0.0.12", + "version": "0.0.13", "dependencies": { "abbrev": { "version": "1.0.9", @@ -74,6 +74,70 @@ "from": "append-field@>=0.1.0 <0.2.0", "resolved": "https://registry.npmjs.org/append-field/-/append-field-0.1.0.tgz" }, + "archiver": { + "version": "0.21.0", + "from": "archiver@>=0.21.0 <0.22.0", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-0.21.0.tgz", + "dependencies": { + "async": { + "version": "1.5.2", + "from": "async@~1.5.0", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz" + }, + "glob": { + "version": "6.0.4", + "from": "glob@>=6.0.0 <6.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz" + }, + "lodash": { + "version": "3.10.1", + "from": "lodash@>=3.10.0 <3.11.0", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz" + }, + "readable-stream": { + "version": "2.0.6", + "from": "readable-stream@>=2.0.0 <2.1.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz" + }, + "string_decoder": { + "version": "0.10.31", + "from": "string_decoder@~0.10.x", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" + } + } + }, + "archiver-utils": { + "version": "0.3.0", + "from": "archiver-utils@>=0.3.0 <0.4.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-0.3.0.tgz", + "dependencies": { + "glob": { + "version": "6.0.4", + "from": "glob@~6.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz" + }, + "lodash": { + "version": "3.10.1", + "from": "lodash@~3.10.0", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz" + }, + "normalize-path": { + "version": "2.0.1", + "from": "normalize-path@>=2.0.0 <2.1.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.0.1.tgz" + }, + "readable-stream": { + "version": "2.0.6", + "from": "readable-stream@~2.0.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz" + }, + "string_decoder": { + "version": "0.10.31", + "from": "string_decoder@~0.10.x", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" + } + } + }, "archy": { "version": "1.0.0", "from": "archy@>=1.0.0 <2.0.0", @@ -183,6 +247,43 @@ "from": "asynckit@>=0.4.0 <0.5.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" }, + "aws-s3-zipper": { + "version": "1.0.1", + "from": "aws-s3-zipper@latest", + "resolved": "https://registry.npmjs.org/aws-s3-zipper/-/aws-s3-zipper-1.0.1.tgz", + "dependencies": { + "async": { + "version": "1.5.2", + "from": "async@>=1.5.0 <1.6.0", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz" + }, + "aws-sdk": { + "version": "2.2.48", + "from": "aws-sdk@>=2.2.0 <2.3.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.2.48.tgz" + }, + "lodash": { + "version": "3.5.0", + "from": "lodash@>=3.5.0 <3.6.0", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.5.0.tgz" + }, + "sax": { + "version": "1.1.5", + "from": "sax@1.1.5", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.1.5.tgz" + }, + "xml2js": { + "version": "0.4.15", + "from": "xml2js@0.4.15", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.15.tgz" + }, + "xmlbuilder": { + "version": "2.6.2", + "from": "xmlbuilder@2.6.2", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-2.6.2.tgz" + } + } + }, "aws-sdk": { "version": "2.45.0", "from": "aws-sdk@>=2.32.0 <3.0.0", @@ -207,8 +308,7 @@ "balanced-match": { "version": "0.4.2", "from": "balanced-match@>=0.4.1 <0.5.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", - "dev": true + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz" }, "base64-js": { "version": "1.2.0", @@ -246,19 +346,16 @@ "version": "1.1.2", "from": "bl@>=1.1.2 <1.2.0", "resolved": "https://registry.npmjs.org/bl/-/bl-1.1.2.tgz", - "dev": true, "dependencies": { "readable-stream": { "version": "2.0.6", "from": "readable-stream@>=2.0.5 <2.1.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", - "dev": true + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz" }, "string_decoder": { "version": "0.10.31", "from": "string_decoder@>=0.10.0 <0.11.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "dev": true + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" } } }, @@ -280,8 +377,7 @@ "brace-expansion": { "version": "1.1.7", "from": "brace-expansion@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz", - "dev": true + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz" }, "braces": { "version": "1.8.5", @@ -300,6 +396,11 @@ "from": "buffer@4.9.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz" }, + "buffer-crc32": { + "version": "0.2.13", + "from": "buffer-crc32@>=0.2.1 <0.3.0", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz" + }, "buffer-equal-constant-time": { "version": "1.0.1", "from": "buffer-equal-constant-time@1.0.1", @@ -556,11 +657,32 @@ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", "dev": true }, + "compress-commons": { + "version": "0.4.2", + "from": "compress-commons@>=0.4.0 <0.5.0", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-0.4.2.tgz", + "dependencies": { + "normalize-path": { + "version": "2.0.1", + "from": "normalize-path@~2.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.0.1.tgz" + }, + "readable-stream": { + "version": "2.0.6", + "from": "readable-stream@~2.0.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz" + }, + "string_decoder": { + "version": "0.10.31", + "from": "string_decoder@~0.10.x", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" + } + } + }, "concat-map": { "version": "0.0.1", "from": "concat-map@0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "dev": true + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" }, "concat-stream": { "version": "1.6.0", @@ -626,6 +748,23 @@ "from": "cors@>=2.8.1 <3.0.0", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.3.tgz" }, + "crc32-stream": { + "version": "0.4.0", + "from": "crc32-stream@>=0.4.0 <0.5.0", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-0.4.0.tgz", + "dependencies": { + "readable-stream": { + "version": "2.0.6", + "from": "readable-stream@~2.0.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz" + }, + "string_decoder": { + "version": "0.10.31", + "from": "string_decoder@~0.10.x", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" + } + } + }, "cross-env": { "version": "3.2.4", "from": "cross-env@>=3.1.2 <4.0.0", @@ -1007,7 +1146,7 @@ }, "escape-string-regexp": { "version": "1.0.5", - "from": "escape-string-regexp@>=1.0.5 <1.1.0", + "from": "escape-string-regexp@>=1.0.2 <2.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" }, "escodegen": { @@ -1198,6 +1337,11 @@ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "dev": true }, + "fd-slicer": { + "version": "1.0.1", + "from": "fd-slicer@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz" + }, "figures": { "version": "1.7.0", "from": "figures@>=1.3.5 <2.0.0", @@ -1256,6 +1400,11 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", "dev": true }, + "findit2": { + "version": "2.2.3", + "from": "findit2@>=2.2.3 <2.3.0", + "resolved": "https://registry.npmjs.org/findit2/-/findit2-2.2.3.tgz" + }, "findup-sync": { "version": "0.4.3", "from": "findup-sync@>=0.4.0 <0.5.0", @@ -1803,8 +1952,7 @@ "inflight": { "version": "1.0.6", "from": "inflight@>=1.0.4 <2.0.0", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "dev": true + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" }, "inherits": { "version": "2.0.3", @@ -2232,6 +2380,28 @@ "dev": true, "optional": true }, + "lazystream": { + "version": "0.1.0", + "from": "lazystream@>=0.1.0 <0.2.0", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-0.1.0.tgz", + "dependencies": { + "isarray": { + "version": "0.0.1", + "from": "isarray@0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" + }, + "readable-stream": { + "version": "1.0.34", + "from": "readable-stream@>=1.0.2 <1.1.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz" + }, + "string_decoder": { + "version": "0.10.31", + "from": "string_decoder@>=0.10.0 <0.11.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" + } + } + }, "lcid": { "version": "1.0.0", "from": "lcid@>=1.0.0 <2.0.0", @@ -2561,8 +2731,7 @@ "minimatch": { "version": "3.0.3", "from": "minimatch@>=3.0.2 <4.0.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz", - "dev": true + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz" }, "minimist": { "version": "0.0.8", @@ -2665,8 +2834,7 @@ "natives": { "version": "1.1.0", "from": "natives@>=1.1.0 <2.0.0", - "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.0.tgz", - "dev": true + "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.0.tgz" }, "natural-compare": { "version": "1.4.0", @@ -2690,6 +2858,11 @@ "from": "nocache@2.0.0", "resolved": "https://registry.npmjs.org/nocache/-/nocache-2.0.0.tgz" }, + "node-int64": { + "version": "0.4.0", + "from": "node-int64@>=0.4.0 <0.5.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz" + }, "nopt": { "version": "3.0.6", "from": "nopt@>=3.0.0 <4.0.0", @@ -2755,8 +2928,7 @@ "once": { "version": "1.4.0", "from": "once@>=1.3.0 <2.0.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "dev": true + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz" }, "onetime": { "version": "1.1.0", @@ -2871,8 +3043,7 @@ "path-is-absolute": { "version": "1.0.1", "from": "path-is-absolute@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "dev": true + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" }, "path-is-inside": { "version": "1.0.2", @@ -2920,6 +3091,11 @@ "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", "dev": true }, + "pend": { + "version": "1.2.0", + "from": "pend@>=1.2.0 <1.3.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz" + }, "performance-now": { "version": "0.2.0", "from": "performance-now@>=0.2.0 <0.3.0", @@ -3333,6 +3509,48 @@ "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", "dev": true }, + "s3": { + "version": "4.4.0", + "from": "s3@latest", + "resolved": "https://registry.npmjs.org/s3/-/s3-4.4.0.tgz", + "dependencies": { + "aws-sdk": { + "version": "2.0.31", + "from": "aws-sdk@>=2.0.31 <2.1.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.0.31.tgz" + }, + "graceful-fs": { + "version": "3.0.11", + "from": "graceful-fs@>=3.0.5 <3.1.0", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.11.tgz" + }, + "mime": { + "version": "1.2.11", + "from": "mime@>=1.2.11 <1.3.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz" + }, + "rimraf": { + "version": "2.2.8", + "from": "rimraf@>=2.2.8 <2.3.0", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz" + }, + "sax": { + "version": "0.4.2", + "from": "sax@0.4.2", + "resolved": "https://registry.npmjs.org/sax/-/sax-0.4.2.tgz" + }, + "xml2js": { + "version": "0.2.6", + "from": "xml2js@0.2.6", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.2.6.tgz" + }, + "xmlbuilder": { + "version": "0.4.2", + "from": "xmlbuilder@0.4.2", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-0.4.2.tgz" + } + } + }, "safe-buffer": { "version": "5.0.1", "from": "safe-buffer@>=5.0.1 <6.0.0", @@ -3559,6 +3777,11 @@ "from": "streamsearch@0.1.2", "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz" }, + "streamsink": { + "version": "1.2.0", + "from": "streamsink@>=1.2.0 <1.3.0", + "resolved": "https://registry.npmjs.org/streamsink/-/streamsink-1.2.0.tgz" + }, "string_decoder": { "version": "1.0.0", "from": "string_decoder@>=1.0.0 <1.1.0", @@ -3641,6 +3864,18 @@ "from": "taffydb@2.6.2", "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz" }, + "tar-stream": { + "version": "1.3.2", + "from": "tar-stream@>=1.3.1 <1.4.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.3.2.tgz", + "dependencies": { + "end-of-stream": { + "version": "1.4.0", + "from": "end-of-stream@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.0.tgz" + } + } + }, "temp": { "version": "0.5.1", "from": "temp@>=0.5.1 <0.6.0", @@ -4021,8 +4256,7 @@ "wrappy": { "version": "1.0.2", "from": "wrappy@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "dev": true + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" }, "write": { "version": "0.2.1", @@ -4047,7 +4281,7 @@ }, "xtend": { "version": "4.0.1", - "from": "xtend@>=4.0.0 <5.0.0", + "from": "xtend@>=4.0.1 <5.0.0", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" }, "y18n": { @@ -4081,6 +4315,28 @@ "dev": true } } + }, + "zip-stream": { + "version": "0.8.0", + "from": "zip-stream@>=0.8.0 <0.9.0", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-0.8.0.tgz", + "dependencies": { + "lodash": { + "version": "3.10.1", + "from": "lodash@~3.10.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz" + }, + "readable-stream": { + "version": "2.0.6", + "from": "readable-stream@~2.0.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz" + }, + "string_decoder": { + "version": "0.10.31", + "from": "string_decoder@~0.10.x", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" + } + } } } } diff --git a/package.json b/package.json index bb9a8687..1cd59291 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fs-middlelayer-api", - "version": "0.0.12", + "version": "0.0.13", "description": "US Forest Service ePermit Middlelayer API", "engines": { "node": "6.9.x", @@ -10,6 +10,7 @@ "scripts": { "start": "node src/index.js", "test": "mocha test --recursive", + "test:mock": "npm --mock=Y run test", "coverage": "istanbul cover ./node_modules/mocha/bin/_mocha -- --recursive", "lint": "npm-run-all -c -s lint:es lint:es:out lint:md", "lint:es": "eslint . -f stylish || exit 0", @@ -52,6 +53,7 @@ "istanbul": "^0.4.5", "markdownlint-cli": "^0.2.0", "mocha": "^3.2.0", + "mock-aws": "^1.2.3", "npm-run-all": "^4.0.2", "sequelize-cli": "^2.6.0", "supertest": "^3.0.0", @@ -59,6 +61,7 @@ }, "dependencies": { "async": "^2.2.0", + "aws-s3-zipper": "^1.0.1", "aws-sdk": "^2.32.0", "bcrypt-nodejs": "0.0.3", "body-parser": "^1.17.1", diff --git a/src/api.json b/src/api.json index 37c3eb67..a223a561 100644 --- a/src/api.json +++ b/src/api.json @@ -1,8 +1,9 @@ { "swagger": "2.0", + "basePath":"/", "info": { "description": "This page is for developers. We built this site entirely off the APIs below and we want to share them with you.", - "version": "0.0.12", + "version": "0.0.13", "title": "API Documentation for Developers" }, "tags": [ @@ -66,49 +67,49 @@ "/permits/applications/special-uses/noncommercial/{controlNumber}/": { "get": { "x-mockOutput":"test/data/basicGET.json", - "x-getTemplate":{ - "controlNumber":{"default":"", "intake":"accinstCn"}, - "region": {"default":"", "intake":"middleLayer/region"}, - "forest": {"default":"", "intake":"middleLayer/forest"}, - "district": {"default":"", "intake":"middleLayer/district"}, - "authorizingOfficerName": {"default":"", "intake":"authOfficerName"}, - "authorizingOfficerTitle": {"default":"", "intake":"authOfficerTitle"}, - "adminOrg": {"default":"", "intake":"adminOrg"}, - "applicantInfo": { - "contactControlNumber":{"default":"", "intake":"addresses/contCn"}, - "firstName": {"default":"", "intake":"holders/firstName"}, - "lastName": {"default":"", "intake":"holders/lastName"}, - "dayPhone": { - "areaCode": {"default":0, "intake":"phones/areaCode"}, - "number": {"default":0, "intake":"phones/phoneNumber"}, - "extension": {"default":"", "intake":"phones/extension"}, - "phoneType": {"default":"", "intake":"phones/phoneNumberType"} - }, - "eveningPhone": { - "areaCode": {"default":0, "intake":"phones/areaCode"}, - "number": {"default":0, "intake":"phones/phoneNumber"}, - "extension": {"default":"", "intake":"phones/extension"}, - "phoneType": {"default":"", "intake":"phones/phoneNumberType"} - }, - "emailAddress": {"default":"", "intake":"addresses/email"}, - "mailingAddress": {"default":"", "intake":"addresses/address1"}, - "mailingAddress2": {"default":"", "intake":"addresses/address2"}, - "mailingCity": {"default":"", "intake":"addresses/cityName"}, - "mailingState": {"default":"", "intake":"addresses/stateCode"}, - "mailingZIP": {"default":"", "intake":"addresses/postalCode"}, - "organizationName": {"default":"", "intake":"addresses/contName"}, - "website": {"default":"", "intake":"middleLayer/website"}, - "orgType": {"default":"", "intake":"holders/orgType"} - }, - "noncommercialFields": { - "activityDescription": {"default":"", "intake":"middleLayer/activityDescription"}, - "locationDescription": {"default":"", "intake":"middleLayer/locationDescription"}, - "startDateTime": {"default":"", "intake":"middleLayer/startDatetime"}, - "endDateTime": {"default":"", "intake":"middleLayer/endDatetime"}, - "numberParticipants": {"default":0, "intake":"middleLayer/numberParticipants"} - } - }, - "tags": [ + "x-getTemplate":{ + "controlNumber":{"default":"", "intake":"accinstCn"}, + "region": {"default":"", "intake":"middleLayer/region"}, + "forest": {"default":"", "intake":"middleLayer/forest"}, + "district": {"default":"", "intake":"middleLayer/district"}, + "authorizingOfficerName": {"default":"", "intake":"authOfficerName"}, + "authorizingOfficerTitle": {"default":"", "intake":"authOfficerTitle"}, + "adminOrg": {"default":"", "intake":"adminOrg"}, + "applicantInfo": { + "contactControlNumber":{"default":"", "intake":"addresses/contCn"}, + "firstName": {"default":"", "intake":"holders/firstName"}, + "lastName": {"default":"", "intake":"holders/lastName"}, + "dayPhone": { + "areaCode": {"default":0, "intake":"phones/areaCode"}, + "number": {"default":0, "intake":"phones/phoneNumber"}, + "extension": {"default":"", "intake":"phones/extension"}, + "phoneType": {"default":"", "intake":"phones/phoneNumberType"} + }, + "eveningPhone": { + "areaCode": {"default":0, "intake":"phones/areaCode"}, + "number": {"default":0, "intake":"phones/phoneNumber"}, + "extension": {"default":"", "intake":"phones/extension"}, + "phoneType": {"default":"", "intake":"phones/phoneNumberType"} + }, + "emailAddress": {"default":"", "intake":"addresses/email"}, + "mailingAddress": {"default":"", "intake":"addresses/address1"}, + "mailingAddress2": {"default":"", "intake":"addresses/address2"}, + "mailingCity": {"default":"", "intake":"addresses/cityName"}, + "mailingState": {"default":"", "intake":"addresses/stateCode"}, + "mailingZIP": {"default":"", "intake":"addresses/postalCode"}, + "organizationName": {"default":"", "intake":"addresses/contName"}, + "website": {"default":"", "intake":"middleLayer/website"}, + "orgType": {"default":"", "intake":"holders/orgType"} + }, + "noncommercialFields": { + "activityDescription": {"default":"", "intake":"middleLayer/activityDescription"}, + "locationDescription": {"default":"", "intake":"middleLayer/locationDescription"}, + "startDateTime": {"default":"", "intake":"middleLayer/startDatetime"}, + "endDateTime": {"default":"", "intake":"middleLayer/endDatetime"}, + "numberParticipants": {"default":0, "intake":"middleLayer/numberParticipants"} + } + }, + "tags": [ "Noncommercial Permit" ], "summary": "Find noncommercial permit by ID", @@ -158,8 +159,8 @@ "/permits/applications/special-uses/noncommercial/": { "post": { "x-validation":{ - "$ref":"validation.json#noncommercialApplication" - }, + "$ref":"controllers/validation.json#noncommercialApplication" + }, "tags": [ "Noncommercial Permit" ], @@ -305,6 +306,58 @@ } } }, + "/permits/applications/special-uses/commercial/temp-outfitters/{controlNumber}/files/": { + "get": { + "tags": [ + "Outfitter and Guide Permit" + ], + "summary": "Get files in zip format of Outfitter and Guide Permit", + "description": "", + "consumes": [ + "application/json" + ], + "produces": [ + "application/zip" + ], + "parameters": [ + { + "name": "controlNumber", + "in": "path", + "description": "Control Number of temp-outfitter permit", + "required": true, + "type": "integer", + "format": "int64" + }, + { + "name": "x-access-token", + "in": "header", + "description": "access token", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "type": "file" + } + }, + "400": { + "description": "Invalid controlNumber supplied" + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Permit not found" + } + } + } + }, "/permits/applications/special-uses/commercial/temp-outfitters/{controlNumber}/files/{fileName}": { "get": { "tags": [ @@ -372,7 +425,7 @@ "/permits/applications/special-uses/commercial/temp-outfitters/": { "post": { "x-validation":{ - "$ref":"validation.json#tempOutfitterApplication" + "$ref":"controllers/validation.json#tempOutfitterApplication" }, "tags": [ "Outfitter and Guide Permit" @@ -385,15 +438,13 @@ "produces": [ "application/json" ], - "parameters": [ + "parameters": [ { "in": "formData", "name": "body", "description": "temp-outfitter permit information", - "required": true, - "schema": { - "$ref": "#/definitions/tempOutfitterPermit" - } + "type":"string", + "required": true }, { "in": "formData", @@ -461,12 +512,12 @@ "lastName": { "type": "string" }, "dayPhone": { "$ref": "#/definitions/phoneNumber" }, "eveningPhone": { "$ref": "#/definitions/phoneNumber" }, - "emailAddress": { "type": "string", "pattern":"^(([^<>()\\[\\]\\\\.,;:\\s@\"]+(\\.[^<>()\\[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$"}, + "emailAddress": { "type": "string" }, "mailingAddress": { "type": "string" }, "mailingAddress2": { "type": "string" }, "mailingCity": { "type": "string" }, - "mailingState": { "type": "string" ,"pattern":"^(A[EKLPRSZ]|C[AOT]|D[CE]|F[LM]|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEHINOPST]|N[CDEHVJMY]|O[HKR]|P[ARW]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$"}, - "mailingZIP": { "type": "string", "pattern":"^[0-9]{5}$|^[0-9]{9}$"}, + "mailingState": { "type": "string" }, + "mailingZIP": { "type": "string" }, "organizationName": { "type": "string"}, "website":{"type": "string"}, "orgType":{ @@ -481,12 +532,8 @@ "Local Government or Agency", "Nonprofit" ] - } + } }, - "required": ["firstName","lastName","dayPhone","emailAddress","mailingAddress","mailingCity","mailingZIP","mailingState"], - "dependencies":{ - "organizationName":["orgType"] - }, "xml": { "name": "applicantInfoNoncommercial" } @@ -502,9 +549,9 @@ "mailingAddress": { "type": "string" }, "mailingAddress2": { "type": "string" }, "mailingCity": { "type": "string" }, - "mailingState": { "type": "string", "pattern":"^(A[EKLPRSZ]|C[AOT]|D[CE]|F[LM]|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEHINOPST]|N[CDEHVJMY]|O[HKR]|P[ARW]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$" }, - "mailingZIP": { "type": "string", "pattern":"^[0-9]{5}$|^[0-9]{9}$" }, - "organizationName": { "type": "string"}, + "mailingState": { "type": "string" }, + "mailingZIP": { "type": "string" }, + "organizationName": { "type": "string" }, "website":{"type": "string"}, "orgType":{ "type":"string", @@ -518,7 +565,7 @@ "Local Government or Agency", "Nonprofit" ] - } + } }, "required": ["firstName","lastName","dayPhone","emailAddress","mailingAddress","mailingCity","mailingZIP","mailingState","orgType"], "xml": { @@ -536,7 +583,7 @@ "required": ["areaCode","number","phoneType"], "xml": { "name": "phoneNumber" - } + } }, "noncommercialFields": { "type": "object", @@ -550,7 +597,7 @@ "required": ["activityDescription","locationDescription","startDateTime","endDateTime","numberParticipants"], "xml": { "name": "noncommercialFields" - } + } }, "tempOutfitterFields": { "type": "object", @@ -563,27 +610,18 @@ "clientCharges": { "type": "string"}, "experienceList": { "type": "string"} }, - "allOf":[ - {"required":["activityDescription", "clientCharges"]}, - { - "x-anyOf": [ - { "required": ["advertisingURL"] }, - { "required": ["advertisingDescription"] } - ] - } - ], "xml": { "name": "tempOutfitterFields" - } + } }, "noncommercialPermit": { "type": "object", "properties": { - "region": { "type" : "string", "pattern":"^[0-9]{2}$" }, - "forest": { "type" : "string", "pattern":"^[0-9]{2}$" }, - "district": { "type" : "string", "pattern":"^[0-9]{2}$" }, - "authorizingOfficerName": { "type" : "string"}, - "authorizingOfficerTitle": { "type" : "string"}, + "region": { "type" : "string" }, + "forest": { "type" : "string" }, + "district": { "type" : "string" }, + "authorizingOfficerName": { "type" : "string" }, + "authorizingOfficerTitle": { "type" : "string" }, "applicantInfo": { "$ref": "#/definitions/applicantInfoNoncommercial" }, @@ -635,9 +673,9 @@ "tempOutfitterPermit": { "type": "object", "properties": { - "region": { "type" : "string", "pattern":"^[0-9]{2}$" }, - "forest": { "type" : "string", "pattern":"^[0-9]{2}$" }, - "district": { "type" : "string", "pattern":"^[0-9]{2}$" }, + "region": { "type" : "string" }, + "forest": { "type" : "string" }, + "district": { "type" : "string" }, "authorizingOfficerName": { "type" : "string"}, "authorizingOfficerTitle": { "type" : "string"}, "applicantInfo": { diff --git a/src/controllers/auth/index.js b/src/controllers/auth/index.js index da464924..1b161695 100644 --- a/src/controllers/auth/index.js +++ b/src/controllers/auth/index.js @@ -21,6 +21,7 @@ const bcrypt = require('bcrypt-nodejs'); const models = include('src/models'); const jwt = require('jsonwebtoken'); +const uuidV4 = require('uuid/v4'); const JWT_SECRET_KEY = process.env.JWT_SECRET_KEY; //******************************************************************* @@ -80,10 +81,20 @@ const serialize = function(req, res, next) { */ const generate = function(req, res, next) { + const claims = { + expiresIn: 120 * 60, + notBefore: 0, + jwtid: uuidV4(), + issuer: 'fs-epermit-api', + subject: 'permit applications', + audience: 'fs-epermit-api-intake-users' + }; + req.token = jwt.sign({ id: req.user.id, role: req.user.role - }, JWT_SECRET_KEY, { expiresIn: 120 * 60 }); + }, JWT_SECRET_KEY, claims); + next(); }; diff --git a/src/controllers/auth/token.js b/src/controllers/auth/token.js index fbe55d86..7c03574d 100644 --- a/src/controllers/auth/token.js +++ b/src/controllers/auth/token.js @@ -35,7 +35,13 @@ const token = function(req, res, next){ if (token) { - jwt.verify(token, JWT_SECRET_KEY, function(err, decoded) { + const claims = { + issuer: 'fs-epermit-api', + subject: 'permit applications', + audience: 'fs-epermit-api-intake-users' + }; + + jwt.verify(token, JWT_SECRET_KEY, claims, function(err, decoded) { if (err) { error.sendError(req, res, 401, 'Failed to authenticate token.'); } diff --git a/src/controllers/db.js b/src/controllers/db.js index 42f04edf..e2514e0f 100644 --- a/src/controllers/db.js +++ b/src/controllers/db.js @@ -159,7 +159,7 @@ function getFieldsToStore(schema, fieldsToStore, path, saveLocation){ case 'properties': getFieldsToStore(schema.properties, fieldsToStore, `${path}`, saveLocation); break; - default: + default: { const store = schema[key].store; let storeInMiddle = false; if (store && schema[key].type !== 'file'){ @@ -184,6 +184,7 @@ function getFieldsToStore(schema, fieldsToStore, path, saveLocation){ } break; } + } }); } diff --git a/src/controllers/index.js b/src/controllers/index.js index d9175e51..f76d99c1 100644 --- a/src/controllers/index.js +++ b/src/controllers/index.js @@ -65,7 +65,7 @@ function apiSchemaData(apiSchema, reqPath){ if (apiSchema) { for (const k in apiSchema.paths) { - + const ms = matchstick(k, 'template'); ms.match(reqPath); @@ -200,52 +200,85 @@ const getControlNumber = function(req, res, reqData){ 'opp': 'operatingPlan' }; - let basicData = {}; - getBasicRes(reqData.matches.controlNumber) - .then((appData)=>{ - basicData = appData; + const reqPath = `/${req.params[0]}`; + + if (reqPath.indexOf('/files') !== -1) { + let controlNumber = reqData.matches.controlNumber; + controlNumber = controlNumber.substr(0, controlNumber.length - 6); + + db.getApplication(controlNumber, function(err, appl, fileData){ + + if (err) { + return error.sendError(req, res, 500, 'unable to process request.'); + } + + else if (fileData){ - let jsonData = {}; + store.getFilesZip(controlNumber, fileData, res, function(err){ - const controlNumber = reqData.matches.controlNumber; + if (err){ + error.sendError(req, res, 404, 'file not found'); + } - const jsonResponse = {}; + }); + + } + else { + error.sendError(req, res, 404, 'file not found'); + } + + }); + } + else { - const cnData = basicData; // TODO: remove - used for mocks + let basicData = {}; + getBasicRes(reqData.matches.controlNumber) + .then((appData)=>{ + basicData = appData; - if (basicData){ + let jsonData = {}; - db.getApplication(controlNumber, function(err, appl, fileData){ - if (err){ - return error.sendError(req, res, 500, 'unable to process request.'); - } - else { - - if(!appl){ - return error.sendError(req, res, 404, 'file not found.'); - } - else if (fileData){ - fileData.forEach(function(file){ - const fileType = fileTypes[file.fileType]; - appl[fileType] = file.fileName; - }); + const controlNumber = reqData.matches.controlNumber; + + const jsonResponse = {}; + + const cnData = basicData; // TODO: remove - used for mocks + + if (basicData){ + + db.getApplication(controlNumber, function(err, appl, fileData){ + if (err){ + return error.sendError(req, res, 500, 'unable to process request.'); } - jsonData = get.copyGenericInfo(cnData, appl, jsonData, pathData['x-getTemplate']); - jsonData.controlNumber = controlNumber;// TODO: remove - used for mocks + else { + + if (!appl){ + return error.sendError(req, res, 404, 'file not found.'); + } + else if (fileData){ + fileData.forEach(function(file){ + const fileType = fileTypes[file.fileType]; + appl[fileType] = file.fileName; + }); + } + jsonData = get.copyGenericInfo(cnData, appl, jsonData, pathData['x-getTemplate']); + jsonData.controlNumber = controlNumber;// TODO: remove - used for mocks - jsonResponse.status = 'success'; - const toReturn = Object.assign({}, jsonResponse, jsonData); + jsonResponse.status = 'success'; + const toReturn = Object.assign({}, jsonResponse, jsonData); - res.json(toReturn); - } - }); - } - }) - .catch((err)=>{ - console.error(err); - return error.sendError(req, res, 500, 'unable to process request.'); - }); + res.json(toReturn); + } + }); + } + }) + .catch((err)=>{ + console.error(err); + return error.sendError(req, res, 500, 'unable to process request.'); + }); + + } }; diff --git a/src/controllers/store.js b/src/controllers/store.js index 6ecdc53e..7eca4341 100644 --- a/src/controllers/store.js +++ b/src/controllers/store.js @@ -15,12 +15,12 @@ // required modules const config = require('./storeConfig.js'); +const s3zipper = require ('aws-s3-zipper'); //************************************************************* // AWS -const AWS_BUCKET_NAME = process.env.AWS_BUCKET_NAME; -const s3 = config.getStoreObject(); +const AWS = config.getStoreObject(); //************************************************************* @@ -30,8 +30,10 @@ const s3 = config.getStoreObject(); * @param {Function} callback - function to call after uploading */ function uploadFile(fileInfo, callback){ + const s3 = new AWS.S3(); + const params = { - Bucket: AWS_BUCKET_NAME, + Bucket: config.bucketName, Key: fileInfo.keyname, Body: fileInfo.buffer, ACL: 'private' @@ -42,7 +44,7 @@ function uploadFile(fileInfo, callback){ console.error(err); return callback(err, null); } - else { + else { return callback(null, data); } }); @@ -55,11 +57,11 @@ function uploadFile(fileInfo, callback){ * @param {Function} callback - function to call after file has been retreived, or error returned */ function getFile(controlNumber, fileName, callback){ - + const s3 = new AWS.S3(); const filePath = `${controlNumber}/${fileName}`; const getParams = { - Bucket: AWS_BUCKET_NAME, + Bucket: config.bucketName, Key: filePath }; @@ -76,5 +78,82 @@ function getFile(controlNumber, fileName, callback){ }); } +/** + * Retreives file from S3 + * @param {Number} controlNumber - controlNumber of application files is associated with + * @param {Array} dbFiles - database file objects associated with that controlNumber. + * @param {Object} res - response object + * @param {Function} callback - function to call after files have been retreived, or error returned + */ +function getFilesZip(controlNumber, dbFiles, res, callback){ + + const zipper = new s3zipper(config.getStoreConfig()); + + const filePath = `${controlNumber}`; + + const storeFiles = []; + const fileNames = []; + + dbFiles.forEach((dbFile)=>{ + fileNames.push(dbFile.filePath); + }); + + zipper.getFiles({ + folderName: filePath + }, + function (err, fileResult) { + if (err){ + console.error(err); + return callback(err); + } + else { + + if (fileResult.files.length === 0 ){ + return callback('files not found'); + } + else { + + fileResult.files.forEach((storeFile)=>{ + + storeFiles.push(storeFile.Key); + + }); + + zipper.filterOutFiles = function(file){ + if (fileNames.indexOf(file.Key) >= 0){ + return file; + } + else { + return null; + } + }; + + res.set('Content-Type', 'application/zip'); + res.set('Content-Disposition', 'attachment; filename=' + controlNumber + '.zip'); + + zipper.streamZipDataTo({ + folderName: filePath, + pipe: res, + recursive: true + }, + function (err, result) { + if (err){ + console.error(err); + return callback(err); + } + else { + return callback(null); + } + } + ); + + } + + } +}); + +} + module.exports.getFile = getFile; module.exports.uploadFile = uploadFile; +module.exports.getFilesZip = getFilesZip; diff --git a/src/controllers/storeConfig.js b/src/controllers/storeConfig.js index 261db4f5..23cd09f1 100644 --- a/src/controllers/storeConfig.js +++ b/src/controllers/storeConfig.js @@ -22,6 +22,7 @@ const AWS = require('aws-sdk'); const AWS_ACCESS_KEY_ID = process.env.AWS_ACCESS_KEY_ID; const AWS_SECRET_ACCESS_KEY = process.env.AWS_SECRET_ACCESS_KEY; const AWS_REGION = process.env.AWS_REGION; +const AWS_BUCKET_NAME = process.env.AWS_BUCKET_NAME; AWS.config.update({ accessKeyId: AWS_ACCESS_KEY_ID, @@ -29,9 +30,20 @@ AWS.config.update({ region: AWS_REGION }); +function getStoreConfig(){ + const config = { + accessKeyId: AWS_ACCESS_KEY_ID, + secretAccessKey: AWS_SECRET_ACCESS_KEY, + region: AWS_REGION, + bucket: AWS_BUCKET_NAME + }; + return config; +} + function getStoreObject(){ - const s3 = new AWS.S3(); - return s3; + return AWS; } module.exports.getStoreObject = getStoreObject; +module.exports.getStoreConfig = getStoreConfig; +module.exports.bucketName = AWS_BUCKET_NAME; diff --git a/src/controllers/validation.js b/src/controllers/validation.js index 75d232cb..a095befa 100644 --- a/src/controllers/validation.js +++ b/src/controllers/validation.js @@ -344,7 +344,7 @@ function handleAnyOfError(errorTracking, result, counter){ * @return {Object} schemas - fullSchema is the full validation schemas for all permit types. schemaToUse is the validation schema for this route */ function getValidationSchema(pathData){ - const fileToGet = `src/controllers/${pathData['x-validation'].$ref.split('#')[0]}`; + const fileToGet = `src/${pathData['x-validation'].$ref.split('#')[0]}`; const schemaToGet = pathData['x-validation'].$ref.split('#')[1]; const applicationSchema = include(fileToGet); return { diff --git a/test/controllers-test.js b/test/controllers-test.js index d3c154f7..2fee968e 100644 --- a/test/controllers-test.js +++ b/test/controllers-test.js @@ -37,11 +37,11 @@ describe('API Controllers: build error message', function(){ })) ) .to.be.equal('Applicant Info/First Name is a required field.'); - + }); it('should return \'First Name is a required field. Last Name is a required field.\'', function(){ - + expect( specialUses.validate.generateErrorMesage(errorFactory.create( { 'errorArray[]':2, @@ -52,11 +52,11 @@ describe('API Controllers: build error message', function(){ })) ) .to.be.equal('Applicant Info/First Name is a required field. Applicant Info/Last Name is a required field.'); - + }); it('should return \'First Name is expected to be of type \'string\'.\'', function(){ - + expect( specialUses.validate.generateErrorMesage(errorFactory.create( { 'errorArray[]':1, @@ -66,11 +66,11 @@ describe('API Controllers: build error message', function(){ })) ) .to.be.equal('Applicant Info/First Name is expected to be type \'string\'.'); - + }); it('should return \'Mailing Zip must be 5 or 9 digits.\'', function(){ - + expect( specialUses.validate.generateErrorMesage(errorFactory.create( { 'errorArray[]':1, @@ -79,11 +79,11 @@ describe('API Controllers: build error message', function(){ })) ) .to.be.equal('Applicant Info/Mailing Zip must be 5 or 9 digits.'); - + }); it('should return \'First Name with some enum message.\'', function(){ - + expect( specialUses.validate.generateErrorMesage(errorFactory.create( { 'errorArray[]':1, @@ -93,11 +93,11 @@ describe('API Controllers: build error message', function(){ })) ) .to.be.equal('Applicant Info/First Name with some enum message.'); - + }); it('should return \'Having Applicant Info/First Name requires that Applicant Info/Last Name be provided.\'', function(){ - + expect( specialUses.validate.generateErrorMesage(errorFactory.create( { 'errorArray[]':1, @@ -107,9 +107,86 @@ describe('API Controllers: build error message', function(){ })) ) .to.be.equal('Having Applicant Info/First Name requires that Applicant Info/Last Name be provided.'); - + }); - + + it('should return \'Either Temp Outfitter Fields/Advertising URL or Temp Outfitter Fields/Advertising Description is a required field.\'', function(){ + + expect( specialUses.validate.generateErrorMesage(errorFactory.create( + { + 'errorArray[]':1, + 'errorArray[0].errorType':'anyOf', + 'errorArray[0].anyOfFields':[ + 'tempOutfitterFields.advertisingURL', + 'tempOutfitterFields.advertisingDescription' + ] + })) + ) + .to.be.equal('Either Temp Outfitter Fields/Advertising URL or Temp Outfitter Fields/Advertising Description is a required field.'); + + }); + + it('should return \'Applicant Info/First Name is too long, must be 255 chracters or shorter\'', function(){ + + expect( specialUses.validate.generateErrorMesage(errorFactory.create( + { + 'errorArray[]':1, + 'errorArray[0].field':'applicantInfo.firstName', + 'errorArray[0].errorType':'length', + 'errorArray[0].expectedFieldType':255 + })) + ) + .to.be.equal('Applicant Info/First Name is too long, must be 255 chracters or shorter'); + + }); + + it('should return \'Insurance Certificate cannot be larger than 10 MB.\'', function(){ + + expect( specialUses.validate.generateErrorMesage(errorFactory.create( + { + 'errorArray[]':1, + 'errorArray[0].field':'insuranceCertificate', + 'errorArray[0].errorType':'invalidSizeLarge', + 'errorArray[0].expectedFieldType':'10' + })) + ) + .to.be.equal('Insurance Certificate cannot be larger than 10 MB.'); + + }); + + it('should return \'Insurance Certificate cannot be an empty file.\'', function(){ + + expect( specialUses.validate.generateErrorMesage(errorFactory.create( + { + 'errorArray[]':1, + 'errorArray[0].field':'insuranceCertificate', + 'errorArray[0].errorType':'invalidSizeSmall', + 'errorArray[0].expectedFieldType':'0' + })) + ) + .to.be.equal('Insurance Certificate cannot be an empty file.'); + + }); + + it('should return \'Insurance Certificate must be one of the following mime types: application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/msword, text/rtf, application/pdf.\'', function(){ + + expect( specialUses.validate.generateErrorMesage(errorFactory.create( + { + 'errorArray[]':1, + 'errorArray[0].field':'insuranceCertificate', + 'errorArray[0].errorType':'invalidMime', + 'errorArray[0].expectedFieldType':[ + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'application/msword', + 'text/rtf', + 'application/pdf' + ] + })) + ) + .to.be.equal('Insurance Certificate must be one of the following mime types: application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/msword, text/rtf, application/pdf.'); + + }); + }); //******************************************************************* diff --git a/test/data/testObjects.json b/test/data/testObjects.json new file mode 100644 index 00000000..0b032ed0 --- /dev/null +++ b/test/data/testObjects.json @@ -0,0 +1,1205 @@ +{ + "outfitters":{ + "pathData":{ + "x-validation": { + "$ref":"controllers/validation.json#tempOutfitterApplication" + }, + "tags": [ + "Outfitter and Guide Permit" + ], + "summary": "Submit a new temp-outfitter permit", + "description": "", + "consumes": [ + "multipart/form-data" + ], + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "formData", + "name": "body", + "description": "temp-outfitter permit information", + "required": true, + "schema": { + "$ref": "#/definitions/tempOutfitterPermit" + } + }, + { + "in": "formData", + "name": "guideDocumentation", + "description": "temp-outfitter guideDocumentation file upload", + "type": "file" + }, + { + "in": "formData", + "name": "acknowledgementOfRiskForm", + "description": "temp-outfitter acknowledgementOfRiskForm file upload", + "type": "file" + }, + { + "in": "formData", + "name": "insuranceCertificate", + "description": "temp-outfitter insuranceCertificate file upload", + "required": true, + "type": "file" + }, + { + "in": "formData", + "name": "goodStandingEvidence", + "description": "temp-outfitter goodStandingEvidence file upload", + "required": true, + "type": "file" + }, + { + "in": "formData", + "name": "operatingPlan", + "description": "temp-outfitter operatingPlan file upload", + "required": true, + "type": "file" + }, + { + "name": "x-access-token", + "in": "header", + "description": "access token", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "Success" + }, + "400": { + "description": "Invalid input" + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + } + } + }, + "derefSchema":{ + "id": "http://json-schema.org/tempOutfitterApplication#", + "type": "object", + "allOf": [ + { + "type": "object", + "properties": { + "region": { + "default": "", + "fromIntake": true, + "pattern": "^[0-9]{2}$", + "store": [ + "middleLayer:region" + ], + "type": "string" + }, + "forest": { + "default": "", + "fromIntake": true, + "pattern": "^[0-9]{2}$", + "store": [ + "middleLayer:forest" + ], + "type": "string" + }, + "district": { + "default": "", + "fromIntake": true, + "pattern": "^[0-9]{2}$", + "store": [ + "middleLayer:district" + ], + "type": "string" + }, + "securityId": { + "basicField": "securityId", + "default": "", + "fromIntake": false, + "madeOf": [ + "region", + "forest", + "district" + ], + "store": [ + "basic:/application", + "basic:/contact/address", + "basic:/contact/phone" + ], + "type": "string" + }, + "managingID": { + "basicField": "managingOrg", + "default": "", + "fromIntake": false, + "madeOf": [ + "region", + "forest", + "district" + ], + "store": [ + "basic:/application" + ], + "type": "string" + }, + "adminOrg": { + "basicField": "adminOrg", + "default": "", + "fromIntake": false, + "madeOf": [ + "region", + "forest", + "district" + ], + "store": [ + "basic:/application" + ], + "type": "string" + }, + "ePermitID": { + "basicField": "ePermitID", + "default": "", + "fromIntake": false, + "madeOf": [ + "region", + "forest", + "00000" + ], + "store": [ + "basic:/application" + ], + "type": "string" + }, + "acres": { + "basicField": "acres", + "default": 0, + "fromIntake": false, + "store": [ + "basic:/application" + ], + "type": "integer" + }, + "contCN": { + "basicField": "contact", + "default": "", + "fromIntake": false, + "store": [ + "basic:/contact/phone", + "basic:/contact/address", + "basic:/contact/person" + ], + "type": "string" + } + }, + "required": [ + "region", + "forest", + "district" + ] + }, + { + "properties": { + "applicantInfo": { + "type": "object", + "allOf": [ + { + "type": "object", + "properties": { + "firstName": { + "basicField": "firstName", + "default": "", + "fromIntake": true, + "maxLength": 255, + "store": [ + "basic:/contact/person" + ], + "type": "string" + }, + "lastName": { + "basicField": "lastName", + "default": "", + "fromIntake": true, + "maxLength": 255, + "store": [ + "basic:/contact/person" + ], + "type": "string" + }, + "dayPhone": { + "type": "object", + "properties": { + "areaCode": { + "basicField": "areaCode", + "default": 0, + "fromIntake": true, + "format": "areaCodeFormat", + "store": [ + "basic:/contact/phone" + ], + "type": "integer" + }, + "number": { + "basicField": "phoneNumber", + "default": 0, + "fromIntake": true, + "format": "phoneNumberFormat", + "store": [ + "basic:/contact/phone" + ], + "type": "integer" + }, + "extension": { + "basicField": "extension", + "default": "", + "fromIntake": true, + "pattern": "[\\d]+", + "store": [ + "basic:/contact/phone" + ], + "type": "string" + }, + "phoneType": { + "basicField": "phoneNumberType", + "default": "", + "fromIntake": true, + "store": [ + "basic:/contact/phone" + ], + "type": "string" + } + }, + "required": [ + "areaCode", + "number", + "phoneType" + ] + }, + "eveningPhone": { + "type": "object", + "properties": { + "areaCode": { + "basicField": "areaCode", + "default": 0, + "fromIntake": true, + "format": "areaCodeFormat", + "store": [ + "basic:/contact/phone" + ], + "type": "integer" + }, + "number": { + "basicField": "phoneNumber", + "default": 0, + "fromIntake": true, + "format": "phoneNumberFormat", + "store": [ + "basic:/contact/phone" + ], + "type": "integer" + }, + "extension": { + "basicField": "extension", + "default": "", + "fromIntake": true, + "pattern": "[\\d]+", + "store": [ + "basic:/contact/phone" + ], + "type": "string" + }, + "phoneType": { + "basicField": "phoneNumberType", + "default": "", + "fromIntake": true, + "store": [ + "basic:/contact/phone" + ], + "type": "string" + } + }, + "required": [ + "areaCode", + "number", + "phoneType" + ] + }, + "emailAddress": { + "basicField": "email", + "default": "", + "fromIntake": true, + "pattern": "^(([^<>()\\[\\]\\\\.,;:\\s@\"]+(\\.[^<>()\\[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$", + "store": [ + "basic:/contact/address" + ], + "type": "string" + }, + "mailingAddress": { + "basicField": "address1", + "default": "", + "fromIntake": true, + "store": [ + "basic:/contact/address" + ], + "type": "string" + }, + "mailingAddress2": { + "basicField": "address2", + "default": "", + "fromIntake": true, + "store": [ + "basic:/contact/address" + ], + "type": "string" + }, + "mailingCity": { + "basicField": "cityName", + "default": "", + "fromIntake": true, + "store": [ + "basic:/contact/address" + ], + "type": "string" + }, + "mailingState": { + "basicField": "stateCode", + "default": "", + "fromIntake": true, + "pattern": "^(A[EKLPRSZ]|C[AOT]|D[CE]|F[LM]|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEHINOPST]|N[CDEHVJMY]|O[HKR]|P[ARW]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$", + "store": [ + "basic:/contact/address" + ], + "type": "string" + }, + "mailingZIP": { + "basicField": "postalCode", + "default": "", + "fromIntake": true, + "pattern": "^[0-9]{5}$|^[0-9]{9}$", + "store": [ + "basic:/contact/address" + ], + "type": "string" + }, + "website": { + "default": "", + "fromIntake": true, + "store": [ + "middleLayer:website" + ], + "type": "string" + } + }, + "required": [ + "firstName", + "lastName", + "dayPhone", + "emailAddress", + "mailingAddress", + "mailingCity", + "mailingZIP", + "mailingState" + ] + }, + { + "properties": { + "organizationName": { + "basicField": "contName", + "default": "", + "fromIntake": true, + "store": [ + "basic:/contact/organization" + ], + "type": "string" + }, + "orgType": { + "description": "Organization Type", + "enum": [ + "Individual", + "Corporation", + "Limited Liability Company", + "Partnership or Association", + "State Government or Agency", + "Local Government or Agency", + "Nonprofit" + ], + "fromIntake": true, + "store": [ + "basic:/contact/organization" + ], + "type": "string" + } + }, + "required": [ + "orgType" + ] + } + ] + }, + "type": { + "type": "string", + "default": "tempOutfitters", + "enum": [ + "noncommercial", + "tempOutfitters" + ] + }, + "tempOutfitterFields": { + "type": "object", + "properties": { + "individualIsCitizen": { + "default": false, + "fromIntake": true, + "store": [ + "middleLayer:individualIsCitizen" + ], + "type": "boolean" + }, + "smallBusiness": { + "default": false, + "fromIntake": true, + "store": [ + "middleLayer:smallBusiness" + ], + "type": "boolean" + }, + "activityDescription": { + "basicField": "purpose", + "default": "", + "fromIntake": true, + "store": [ + "middleLayer:activityDescription", + "basic:/application" + ], + "type": "string" + }, + "advertisingURL": { + "default": "", + "fromIntake": true, + "store": [ + "middleLayer:advertisingURL" + ], + "type": "string" + }, + "advertisingDescription": { + "default": "", + "fromIntake": true, + "store": [ + "middleLayer:advertisingDescription" + ], + "type": "string" + }, + "clientCharges": { + "default": "", + "fromIntake": true, + "store": [ + "middleLayer:clientCharges" + ], + "type": "string" + }, + "experienceList": { + "default": "", + "fromIntake": true, + "store": [ + "middleLayer:experienceList" + ], + "type": "string" + }, + "guideDocumentation": { + "filetypecode": "gud", + "maxSize": 25, + "requiredFile": false, + "store": [ + "middleLayer:guideDocumentation" + ], + "type": "file", + "validExtensions": [ + "pdf", + "doc", + "docx", + "rtf" + ] + }, + "acknowledgementOfRiskForm": { + "filetypecode": "arf", + "maxSize": 10, + "requirequiredFilered": false, + "store": [ + "middleLayer:acknowledgementOfRiskForm" + ], + "type": "file", + "validExtensions": [ + "pdf", + "doc", + "docx", + "rtf" + ] + }, + "insuranceCertificate": { + "filetypecode": "inc", + "maxSize": 10, + "requiredFile": true, + "store": [ + "middleLayer:insuranceCertificate" + ], + "type": "file", + "validExtensions": [ + "pdf", + "doc", + "docx", + "rtf" + ] + }, + "goodStandingEvidence": { + "filetypecode": "gse", + "maxSize": 10, + "requiredFile": true, + "store": [ + "middleLayer:acknowledgementOfRiskForm" + ], + "type": "file", + "validExtensions": [ + "pdf", + "doc", + "docx", + "rtf" + ] + }, + "operatingPlan": { + "filetypecode": "opp", + "maxSize": 10, + "requiredFile": true, + "store": [ + "middleLayer:operatingPlan" + ], + "type": "file", + "validExtensions": [ + "pdf", + "doc", + "docx", + "rtf" + ] + }, + "formName": { + "basicField": "formName", + "default": "FS-2700-4I", + "store": [ + "middleLayer:formName", + "basic:/application" + ], + "type": "string" + } + }, + "allOf": [ + { + "required": [ + "activityDescription", + "clientCharges" + ] + }, + { + "anyOf": [ + { + "required": [ + "advertisingURL" + ] + }, + { + "required": [ + "advertisingDescription" + ] + } + ] + } + ] + } + }, + "required": [ + "applicantInfo", + "type", + "tempOutfitterFields" + ] + } + ] + } + }, + "noncommercial":{ + "pathData":{ + "x-validation": { + "$ref":"controllers/validation.json#noncommercialApplication" + }, + "tags": [ + "Noncommercial Permit" + ], + "summary": "Submit a new noncommercial permit", + "description": "", + "operationId": "createPermit", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "body", + "name": "body", + "description": "noncommercial permit information", + "required": true, + "schema": { + "$ref": "#/definitions/noncommercialPermit" + } + }, + { + "name": "x-access-token", + "in": "header", + "description": "access token", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "Success" + }, + "400": { + "description": "Invalid input" + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + } + } + }, + "derefSchema":{ + "id": "http://json-schema.org/noncommercialPermit#", + "type": "object", + "allOf": [ + { + "type": "object", + "properties": { + "region": { + "default": "", + "fromIntake": true, + "pattern": "^[0-9]{2}$", + "store": [ + "middleLayer:region" + ], + "type": "string" + }, + "forest": { + "default": "", + "fromIntake": true, + "pattern": "^[0-9]{2}$", + "store": [ + "middleLayer:forest" + ], + "type": "string" + }, + "district": { + "default": "", + "fromIntake": true, + "pattern": "^[0-9]{2}$", + "store": [ + "middleLayer:district" + ], + "type": "string" + }, + "securityId": { + "basicField": "securityId", + "default": "", + "fromIntake": false, + "madeOf": [ + "region", + "forest", + "district" + ], + "store": [ + "basic:/application", + "basic:/contact/address", + "basic:/contact/phone" + ], + "type": "string" + }, + "managingID": { + "basicField": "managingOrg", + "default": "", + "fromIntake": false, + "madeOf": [ + "region", + "forest", + "district" + ], + "store": [ + "basic:/application" + ], + "type": "string" + }, + "adminOrg": { + "basicField": "adminOrg", + "default": "", + "fromIntake": false, + "madeOf": [ + "region", + "forest", + "district" + ], + "store": [ + "basic:/application" + ], + "type": "string" + }, + "ePermitID": { + "basicField": "ePermitID", + "default": "", + "fromIntake": false, + "madeOf": [ + "region", + "forest", + "00000" + ], + "store": [ + "basic:/application" + ], + "type": "string" + }, + "acres": { + "basicField": "acres", + "default": 0, + "fromIntake": false, + "store": [ + "basic:/application" + ], + "type": "integer" + }, + "contCN": { + "basicField": "contact", + "default": "", + "fromIntake": false, + "store": [ + "basic:/contact/phone", + "basic:/contact/address", + "basic:/contact/person" + ], + "type": "string" + } + }, + "required": [ + "region", + "forest", + "district" + ] + }, + { + "properties": { + "applicantInfo": { + "type": "object", + "allOf": [ + { + "type": "object", + "properties": { + "firstName": { + "basicField": "firstName", + "default": "", + "fromIntake": true, + "maxLength": 255, + "store": [ + "basic:/contact/person" + ], + "type": "string" + }, + "lastName": { + "basicField": "lastName", + "default": "", + "fromIntake": true, + "maxLength": 255, + "store": [ + "basic:/contact/person" + ], + "type": "string" + }, + "dayPhone": { + "type": "object", + "properties": { + "areaCode": { + "basicField": "areaCode", + "default": 0, + "fromIntake": true, + "format": "areaCodeFormat", + "store": [ + "basic:/contact/phone" + ], + "type": "integer" + }, + "number": { + "basicField": "phoneNumber", + "default": 0, + "fromIntake": true, + "format": "phoneNumberFormat", + "store": [ + "basic:/contact/phone" + ], + "type": "integer" + }, + "extension": { + "basicField": "extension", + "default": "", + "fromIntake": true, + "pattern": "[\\d]+", + "store": [ + "basic:/contact/phone" + ], + "type": "string" + }, + "phoneType": { + "basicField": "phoneNumberType", + "default": "", + "fromIntake": true, + "store": [ + "basic:/contact/phone" + ], + "type": "string" + } + }, + "required": [ + "areaCode", + "number", + "phoneType" + ] + }, + "eveningPhone": { + "type": "object", + "properties": { + "areaCode": { + "basicField": "areaCode", + "default": 0, + "fromIntake": true, + "format": "areaCodeFormat", + "store": [ + "basic:/contact/phone" + ], + "type": "integer" + }, + "number": { + "basicField": "phoneNumber", + "default": 0, + "fromIntake": true, + "format": "phoneNumberFormat", + "store": [ + "basic:/contact/phone" + ], + "type": "integer" + }, + "extension": { + "basicField": "extension", + "default": "", + "fromIntake": true, + "pattern": "[\\d]+", + "store": [ + "basic:/contact/phone" + ], + "type": "string" + }, + "phoneType": { + "basicField": "phoneNumberType", + "default": "", + "fromIntake": true, + "store": [ + "basic:/contact/phone" + ], + "type": "string" + } + }, + "required": [ + "areaCode", + "number", + "phoneType" + ] + }, + "emailAddress": { + "basicField": "email", + "default": "", + "fromIntake": true, + "pattern": "^(([^<>()\\[\\]\\\\.,;:\\s@\"]+(\\.[^<>()\\[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$", + "store": [ + "basic:/contact/address" + ], + "type": "string" + }, + "mailingAddress": { + "basicField": "address1", + "default": "", + "fromIntake": true, + "store": [ + "basic:/contact/address" + ], + "type": "string" + }, + "mailingAddress2": { + "basicField": "address2", + "default": "", + "fromIntake": true, + "store": [ + "basic:/contact/address" + ], + "type": "string" + }, + "mailingCity": { + "basicField": "cityName", + "default": "", + "fromIntake": true, + "store": [ + "basic:/contact/address" + ], + "type": "string" + }, + "mailingState": { + "basicField": "stateCode", + "default": "", + "fromIntake": true, + "pattern": "^(A[EKLPRSZ]|C[AOT]|D[CE]|F[LM]|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEHINOPST]|N[CDEHVJMY]|O[HKR]|P[ARW]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$", + "store": [ + "basic:/contact/address" + ], + "type": "string" + }, + "mailingZIP": { + "basicField": "postalCode", + "default": "", + "fromIntake": true, + "pattern": "^[0-9]{5}$|^[0-9]{9}$", + "store": [ + "basic:/contact/address" + ], + "type": "string" + }, + "website": { + "default": "", + "fromIntake": true, + "store": [ + "middleLayer:website" + ], + "type": "string" + } + }, + "required": [ + "firstName", + "lastName", + "dayPhone", + "emailAddress", + "mailingAddress", + "mailingCity", + "mailingZIP", + "mailingState" + ] + }, + { + "properties": { + "organizationName": { + "basicField": "contName", + "default": "", + "fromIntake": true, + "store": [ + "basic:/contact/organization" + ], + "type": "string" + }, + "orgType": { + "basicField": "orgType", + "default": "", + "description": "Organization Type", + "enum": [ + "Individual", + "Corporation", + "Limited Liability Company", + "Partnership or Association", + "State Government or Agency", + "Local Government or Agency", + "Nonprofit" + ], + "fromIntake": true, + "store": [ + "basic:/contact/organization" + ], + "type": "string" + } + }, + "dependencies": { + "organizationName": [ + "orgType" + ] + } + } + ] + }, + "type": { + "default": "noncommercial", + "enum": [ + "noncommercial", + "tempOutfitters" + ], + "fromIntake": true, + "type": "string" + }, + "noncommercialFields": { + "type": "object", + "properties": { + "activityDescription": { + "default": "", + "fromIntake": true, + "store": [ + "middleLayer:activityDescription" + ], + "type": "string" + }, + "locationDescription": { + "default": "", + "fromIntake": true, + "store": [ + "middleLayer:locationDescription" + ], + "type": "string" + }, + "startDateTime": { + "default": "", + "fromIntake": true, + "pattern": "^(19|20)\\d\\d-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T(0\\d|1\\d|2[0-3]):(0\\d|1\\d|2[0-3]):(0\\d|1\\d|2[0-3])Z$", + "store": [ + "middleLayer:startDatetime" + ], + "type": "string" + }, + "endDateTime": { + "default": "", + "fromIntake": true, + "pattern": "^(19|20)\\d\\d-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T(0\\d|1\\d|2[0-3]):(0\\d|1\\d|2[0-3]):(0\\d|1\\d|2[0-3])Z$", + "store": [ + "middleLayer:endDatetime" + ], + "type": "string" + }, + "numberParticipants": { + "default": 0, + "fromIntake": true, + "store": [ + "middleLayer:numberParticipants" + ], + "type": "integer" + }, + "formName": { + "basicField": "formName", + "default": "FS-2700-3b", + "store": [ + "middleLayer:formName", + "basic:/application" + ], + "type": "string" + } + }, + "required": [ + "activityDescription", + "locationDescription", + "startDateTime", + "endDateTime", + "numberParticipants" + ] + } + }, + "required": [ + "applicantInfo", + "type", + "noncommercialFields" + ] + } + ] + } + }, + "file":{ + "validationConstraints":{ + "insuranceCertificate": { + "filetypecode": "inc", + "maxSize": 1, + "requiredFile": true, + "store": [ + "middleLayer:insuranceCertificate" + ], + "type": "file", + "validExtensions": [ + "pdf", + "doc", + "docx", + "rtf" + ] + } + }, + "uploadFile_empty":[ + { + "fieldname": "insuranceCertificate", + "originalname": "test_insuranceCertificate.docx", + "encoding": "7bit", + "mimetype": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + "buffer": { + "type": "Buffer", + "data": [] + }, + "size": 0 + } + ], + "uploadFile_20MB":[ + { + "fieldname": "insuranceCertificate", + "originalname": "test_insuranceCertificate.docx", + "encoding": "7bit", + "mimetype": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + "buffer": { + "type": "Buffer", + "data": [] + }, + "size": 2000000 + } + ], + "uploadFile_invalid_mime":[ + { + "fieldname": "insuranceCertificate", + "originalname": "test_insuranceCertificate.docx", + "encoding": "7bit", + "mimetype": "text/plain", + "buffer": { + "type": "Buffer", + "data": [] + }, + "size": 15 + } + ] + }, + "mockS3Get":{ + "AcceptRanges": "bytes", + "LastModified": "2017-05-09T12:25:00.000Z", + "ContentLength": 13, + "ETag": "\"fa7d7e650b2cec68f302b31ba28235d8\"", + "ContentType": "application/octet-stream", + "Metadata": {}, + "Body": { + "type": "Buffer", + "data": [ + 37, + 80, + 68, + 70, + 45, + 49, + 46, + 51, + 13, + 37, + 226, + 227, + 207 + ] + } + } +} \ No newline at end of file diff --git a/test/noncommercial.js b/test/noncommercial.js index 328c5acf..284a035e 100644 --- a/test/noncommercial.js +++ b/test/noncommercial.js @@ -36,337 +36,7 @@ const noncommercialFactory = factory.factory(noncommercialInput); //******************************************************************* -describe('noncommercial POST: validate required fields present', function(){ - - let token; - - before(function(done) { - - util.getToken(function(t){ - - token = t; - return done(); - - }); - - }); - - describe('body fields', function(){ - - it('should return valid json with a 400 status code for noncommercial POST request without a body', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Region is a required field. Forest is a required field. District is a required field. Applicant Info is a required field. Applicant Info/First Name is a required field. Applicant Info/Last Name is a required field. Applicant Info/Day Phone is a required field. Applicant Info/Day Phone/Area Code is a required field. Applicant Info/Day Phone/Number is a required field. Applicant Info/Day Phone/Phone Type is a required field. Applicant Info/Email Address is a required field. Applicant Info/Mailing Address is a required field. Applicant Info/Mailing City is a required field. Applicant Info/Mailing Zip is a required field. Applicant Info/Mailing State is a required field. Type is a required field. Noncommercial Fields is a required field. Noncommercial Fields/Activity Description is a required field. Noncommercial Fields/Location Description is a required field. Noncommercial Fields/Start Date Time is a required field. Noncommercial Fields/End Date Time is a required field. Noncommercial Fields/Number Participants is a required field.'); - - }) - .expect(400, done); - - }); - - it('should return valid json with a 400 status code for noncommercial POST request without an applicantInfo object', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({applicantInfo : undefined})) - .expect('Content-Type', /json/) - .expect(function(res){ - expect(res.body.message).to.equal('Applicant Info is a required field. Applicant Info/First Name is a required field. Applicant Info/Last Name is a required field. Applicant Info/Day Phone is a required field. Applicant Info/Day Phone/Area Code is a required field. Applicant Info/Day Phone/Number is a required field. Applicant Info/Day Phone/Phone Type is a required field. Applicant Info/Email Address is a required field. Applicant Info/Mailing Address is a required field. Applicant Info/Mailing City is a required field. Applicant Info/Mailing Zip is a required field. Applicant Info/Mailing State is a required field.'); - - }) - .expect(400, done); - - }); - - it('should return valid json with a 400 status code for noncommercial POST request without a noncommercialFields object', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({noncommercialFields : undefined})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Noncommercial Fields is a required field. Noncommercial Fields/Activity Description is a required field. Noncommercial Fields/Location Description is a required field. Noncommercial Fields/Start Date Time is a required field. Noncommercial Fields/End Date Time is a required field. Noncommercial Fields/Number Participants is a required field.'); - - }) - .expect(400, done); - - }); - - }); - - describe('applicantInfo fields', function(){ - - it('should return valid json with a 400 status code for noncommercial POST request without a firstName', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'applicantInfo.firstName':undefined})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/First Name is a required field.'); - - }) - .expect(400, done); - - }); - - it('should return valid json with a 400 status code for noncommercial POST request without a lastName', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'applicantInfo.lastName':undefined})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Last Name is a required field.'); - - }) - .expect(400, done); - - }); - - it('should return valid json with a 400 status code for noncommercial POST request without a dayphone', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'applicantInfo.dayPhone':undefined})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Day Phone is a required field. Applicant Info/Day Phone/Area Code is a required field. Applicant Info/Day Phone/Number is a required field. Applicant Info/Day Phone/Phone Type is a required field.'); - - }) - .expect(400, done); - - }); - - it('should return valid json with a 400 status code for noncommercial POST request without a dayPhone/areaCode', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'applicantInfo.dayPhone.areaCode':undefined})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Day Phone/Area Code is a required field.'); - - }) - .expect(400, done); - - }); - - it('should return valid json with a 400 status code for noncommercial POST request without a dayPhone/number', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'applicantInfo.dayPhone.number':undefined})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Day Phone/Number is a required field.'); - - }) - .expect(400, done); - - }); - - it('should return valid json with a 400 status code for noncommercial POST request without a dayPhone/phoneType', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'applicantInfo.dayPhone.phoneType':undefined})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Day Phone/Phone Type is a required field.'); - - }) - .expect(400, done); - - }); - - it('should return valid json with a 400 status code for noncommercial POST request without an emailAddress', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'applicantInfo.emailAddress':undefined})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Email Address is a required field.'); - - }) - .expect(400, done); - - }); - - it('should return valid json with a 400 status code for noncommercial POST request without a mailingAddress', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'applicantInfo.mailingAddress':undefined})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Mailing Address is a required field.'); - - }) - .expect(400, done); - - }); - - it('should return valid json with a 400 status code for noncommercial POST request without a mailingCity', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'applicantInfo.mailingCity':undefined})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Mailing City is a required field.'); - - }) - .expect(400, done); - - }); - - it('should return valid json with a 400 status code for noncommercial POST request without a mailingState', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'applicantInfo.mailingState':undefined})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Mailing State is a required field.'); - - }) - .expect(400, done); - - }); - - it('should return valid json with a 400 status code for noncommercial POST request without a mailingZIP', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'applicantInfo.mailingZIP':undefined})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Mailing Zip is a required field.'); - - }) - .expect(400, done); - - }); - }); - - describe('noncommercial fields', function(){ - - it('should return valid json with a 400 status code for noncommercial POST request without an activityDescription', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'noncommercialFields.activityDescription':undefined})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Noncommercial Fields/Activity Description is a required field.'); - - }) - .expect(400, done); - - }); - - it('should return valid json with a 400 status code for noncommercial POST request without a locationDescription', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'noncommercialFields.locationDescription':undefined})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Noncommercial Fields/Location Description is a required field.'); - - }) - .expect(400, done); - - }); - - it('should return valid json with a 400 status code for noncommercial POST request without a startDateTime', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'noncommercialFields.startDateTime':undefined})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Noncommercial Fields/Start Date Time is a required field.'); - - }) - .expect(400, done); - - }); - - it('should return valid json with a 400 status code for noncommercial POST request without a endDateTime', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'noncommercialFields.endDateTime':undefined})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Noncommercial Fields/End Date Time is a required field.'); - - }) - .expect(400, done); - - }); - - it('should return valid json with a 400 status code for noncommercial POST request without a numberParticipants', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'noncommercialFields.numberParticipants':undefined})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Noncommercial Fields/Number Participants is a required field.'); - - }) - .expect(400, done); - - }); - - }); - -}); - -describe('API Routes: permits/special-uses/noncommercial', function(){ +describe('Integration tests - noncommercial', function(){ let token; let postControlNumber; @@ -382,619 +52,43 @@ describe('API Routes: permits/special-uses/noncommercial', function(){ }); - it('should return valid json for noncommercial POST request (controlNumber to be used in GET)', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create()) - .expect('Content-Type', /json/) - .expect(function(res){ - postControlNumber = res.body.controlNumber; - }) - .expect(200, done); - - }); - - it('should return valid json for noncommercial GET request for id', function(done) { - - request(server) - .get(`${testURL}${postControlNumber}/`) - .set('x-access-token', token) - .expect('Content-Type', /json/) - .expect(200, done); - - }); - - it('should return valid json for noncommercial POST request', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create()) - .expect('Content-Type', /json/) - .expect(200, done); - - }); - -}); - -describe('noncommercial POST: field type validated', function(){ - - let token; - - before(function(done) { - - util.getToken(function(t){ - - token = t; - return done(); - - }); - - }); - - describe('noncommercial POST: required fields are type validated', function(){ - - it('should return valid json for invalid type, firstName', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'applicantInfo.firstName':1})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/First Name is expected to be type \'string\'.'); - - }) - .expect(400, done); - - }); - - it('should return valid json for invalid type, lastName', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'applicantInfo.lastName':1})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Last Name is expected to be type \'string\'.'); - - }) - .expect(400, done); - - }); - - it('should return valid json for invalid type, dayPhone.areaCode', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'applicantInfo.dayPhone.areaCode':'123'})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Day Phone/Area Code is expected to be type \'integer\'.'); - - }) - .expect(400, done); - - }); - - it('should return valid json for invalid type, dayPhone.number', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'applicantInfo.dayPhone.number':'456789'})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Day Phone/Number is expected to be type \'integer\'.'); - - }) - .expect(400, done); - - }); - - it('should return valid json for invalid type, dayPhone.phoneType', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'applicantInfo.dayPhone.phoneType':1})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Day Phone/Phone Type is expected to be type \'string\'.'); - - }) - .expect(400, done); - - }); - - it('should return valid json for invalid type, emailAddress', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'applicantInfo.emailAddress':1})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Email Address is expected to be type \'string\'.'); - - }) - .expect(400, done); - - }); - - it('should return valid json for invalid type, mailingAddress', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'applicantInfo.mailingAddress':1})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Mailing Address is expected to be type \'string\'.'); - - }) - .expect(400, done); - - }); - - it('should return valid json for invalid type, mailingCity', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'applicantInfo.mailingCity':1})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Mailing City is expected to be type \'string\'.'); - - }) - .expect(400, done); - - }); - - it('should return valid json for invalid type, mailingState', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'applicantInfo.mailingState':1})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Mailing State is expected to be type \'string\'.'); - - }) - .expect(400, done); - - }); - - it('should return valid json for invalid type, mailingZIP', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'applicantInfo.mailingZIP':12345})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Mailing Zip is expected to be type \'string\'.'); - - }) - .expect(400, done); - - }); - - it('should return valid json for invalid type, activityDescription', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'noncommercialFields.activityDescription':1})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Noncommercial Fields/Activity Description is expected to be type \'string\'.'); - - }) - .expect(400, done); - - }); - - it('should return valid json for invalid type, locationDescription', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'noncommercialFields.locationDescription':1})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Noncommercial Fields/Location Description is expected to be type \'string\'.'); - - }) - .expect(400, done); - - }); - - it('should return valid json for invalid type, startDateTime', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'noncommercialFields.startDateTime':1})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Noncommercial Fields/Start Date Time is expected to be type \'string\'.'); - - }) - .expect(400, done); - - }); - - it('should return valid json for invalid type, endDateTime', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'noncommercialFields.endDateTime':1})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Noncommercial Fields/End Date Time is expected to be type \'string\'.'); - - }) - .expect(400, done); - - }); - - it('should return valid json for invalid type, numberParticipants', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'noncommercialFields.numberParticipants':'15'})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Noncommercial Fields/Number Participants is expected to be type \'integer\'.'); - - }) - .expect(400, done); - - }); - - }); - - describe('noncommercial POST: non-required fields are type validated', function(){ - - it('should return valid json for invalid type, dayPhone.extension', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'applicantInfo.dayPhone.extension':1})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Day Phone/Extension is expected to be type \'string\'.'); - - }) - .expect(400, done); - - }); - - }); - -}); - -describe('noncommercial POST: format validated', function(){ - - let token; - - before(function(done) { - - util.getToken(function(t){ - - token = t; - return done(); - - }); - - }); - - describe('noncommercial POST: fields with a specific format are validated', function(){ - - it('should return valid json for invalid format, areaCode', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'applicantInfo.dayPhone.areaCode':1})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Day Phone/Area Code must be 3 digits.'); - - }) - .expect(400, done); - - }); - - it('should return valid json for invalid format, number', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'applicantInfo.dayPhone.number':456789})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Day Phone/Number must be 7 digits.'); - - }) - .expect(400, done); - - }); - - }); - - it('should return valid json for invalid format, mailingState', function(done) { + it('should return valid json with a 400 status code for noncommercial POST request without an applicantInfo object', function(done) { request(server) .post(testURL) .set('x-access-token', token) - .send(noncommercialFactory.create({'applicantInfo.mailingState':'ORE'})) + .send(noncommercialFactory.create({applicantInfo : undefined})) .expect('Content-Type', /json/) .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Mailing State must be 2 letters.'); + expect(res.body.message).to.equal('Applicant Info is a required field. Applicant Info/First Name is a required field. Applicant Info/Last Name is a required field. Applicant Info/Day Phone is a required field. Applicant Info/Day Phone/Area Code is a required field. Applicant Info/Day Phone/Number is a required field. Applicant Info/Day Phone/Phone Type is a required field. Applicant Info/Email Address is a required field. Applicant Info/Mailing Address is a required field. Applicant Info/Mailing City is a required field. Applicant Info/Mailing Zip is a required field. Applicant Info/Mailing State is a required field.'); }) .expect(400, done); }); - it('should return valid json for invalid format, mailingZIP', function(done) { + it('should return valid json for noncommercial POST request (controlNumber to be used in GET)', function(done) { request(server) .post(testURL) .set('x-access-token', token) - .send(noncommercialFactory.create({'applicantInfo.mailingZIP':'123456'})) + .send(noncommercialFactory.create()) .expect('Content-Type', /json/) .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Mailing Zip must be 5 or 9 digits.'); - + postControlNumber = res.body.controlNumber; }) - .expect(400, done); - - }); - - it('should return valid json for valid format, mailingZIP', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'applicantInfo.mailingZIP':'123456789'})) - .expect('Content-Type', /json/) .expect(200, done); }); - - it('should return valid json for invalid format, region', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'region':'156'})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Region must be 2 digits.'); - - }) - .expect(400, done); - - }); - - it('should return valid json for invalid format, forest', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'forest':'156'})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Forest must be 2 digits.'); - - }) - .expect(400, done); - - }); - - it('should return valid json for invalid format, district', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'district':'156'})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('District must be 2 digits.'); - - }) - .expect(400, done); - - }); - - it('should return valid json for invalid format, startDateTime', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'noncommercialFields.startDateTime':'01-12-2012'})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Noncommercial Fields/Start Date Time must be in format \'YYYY-MM-DDThh:mm:ssZ\'.'); - - }) - .expect(400, done); - - }); - - it('should return valid json for invalid format, endDateTime', function(done) { + + it('should return valid json for noncommercial GET request for id', function(done) { request(server) - .post(testURL) + .get(`${testURL}${postControlNumber}/`) .set('x-access-token', token) - .send(noncommercialFactory.create({'noncommercialFields.endDateTime':'01-12-2012'})) .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Noncommercial Fields/End Date Time must be in format \'YYYY-MM-DDThh:mm:ssZ\'.'); - - }) - .expect(400, done); - - }); - -}); - -describe('noncommercial POST: enum validated', function(){ - - let token; - - before(function(done) { - - util.getToken(function(t){ - - token = t; - return done(); - - }); - - }); - - describe('noncommercial POST: fields with enumuration are validated', function(){ - - it('should return valid json for invalid option, type', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'type':'invalid'})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Type is not one of enum values: noncommercial,tempOutfitters.'); - - }) - .expect(400, done); - - }); - - it('should return valid json for invalid option, orgType', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'applicantInfo.orgType':'invalid'})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Org Type is not one of enum values: Individual,Corporation,Limited Liability Company,Partnership or Association,State Government or Agency,Local Government or Agency,Nonprofit.'); - - }) - .expect(400, done); - - }); - - }); - -}); - -describe('noncommercial POST: pattern validated', function(){ - - let token; - - before(function(done) { - - util.getToken(function(t){ - - token = t; - return done(); - - }); - - }); - - describe('noncommercial POST: fields with a regex pattern are validated', function(){ - - it('should return valid json for invalid pattern, emailAddress', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'applicantInfo.emailAddress':'invalid'})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Email Address must be in format \'email@email.service\'.'); - - }) - .expect(400, done); - - }); - }); -}); - -describe('noncommercial POST: dependency validated', function(){ - - let token; - - before(function(done) { - - util.getToken(function(t){ - - token = t; - return done(); + .expect(200, done); - }); - }); - describe('noncommercial POST: fields with a dependency are validated', function(){ - - it('should return valid json for organizationName being provided but not orgType', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .send(noncommercialFactory.create({'applicantInfo.organizationName':'theOrg'})) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Having Applicant Info/Organization Name requires that Applicant Info/Org Type be provided.'); - - }) - .expect(400, done); - - }); - }); }); diff --git a/test/outfitters.js b/test/outfitters.js index b0078418..92a60265 100644 --- a/test/outfitters.js +++ b/test/outfitters.js @@ -17,949 +17,45 @@ const include = require('include')(__dirname); //******************************************************************* +const AWS = require('mock-aws'); const request = require('supertest'); const server = include('src/index.js'); const util = include('test/utility.js'); const factory = require('unionized'); const tempOutfitterInput = include('test/data/testInputTempOutfitters.json'); +const tempOutfitterObjects = include('test/data/testObjects.json'); const testURL = '/permits/applications/special-uses/commercial/temp-outfitters/'; const chai = require('chai'); const expect = chai.expect; -//******************************************************************* -//Mock Input - -const tempOutfitterFactory = factory.factory(tempOutfitterInput); - -const binaryParser = function (res, cb) { - res.setEncoding("binary"); - res.data = ""; - res.on("data", function (chunk) { - res.data += chunk; - }); - res.on("end", function () { - cb(null, new Buffer(res.data, "binary")); - }); -}; - -//******************************************************************* - -describe('tempOutfitters POST: validate required fields present', function(){ - - let token; - - before(function(done) { - - util.getToken(function(t){ - - token = t; - return done(); - - }); - - }); - - describe('body fields', function(){ - - it('should return valid json with a 400 status code for tempOutfitters POST request without a body', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Region is a required field. Forest is a required field. District is a required field. Applicant Info is a required field. Applicant Info/First Name is a required field. Applicant Info/Last Name is a required field. Applicant Info/Day Phone is a required field. Applicant Info/Day Phone/Area Code is a required field. Applicant Info/Day Phone/Number is a required field. Applicant Info/Day Phone/Phone Type is a required field. Applicant Info/Email Address is a required field. Applicant Info/Mailing Address is a required field. Applicant Info/Mailing City is a required field. Applicant Info/Mailing Zip is a required field. Applicant Info/Mailing State is a required field. Applicant Info/Org Type is a required field. Type is a required field. Temp Outfitter Fields is a required field. Temp Outfitter Fields/Activity Description is a required field. Temp Outfitter Fields/Client Charges is a required field.'); - - }) - .expect(400, done); - - }); - - it('should return valid json with a 400 status code for tempOutfitters POST request without an applicantInfo object', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create({applicantInfo : undefined}))) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info is a required field. Applicant Info/First Name is a required field. Applicant Info/Last Name is a required field. Applicant Info/Day Phone is a required field. Applicant Info/Day Phone/Area Code is a required field. Applicant Info/Day Phone/Number is a required field. Applicant Info/Day Phone/Phone Type is a required field. Applicant Info/Email Address is a required field. Applicant Info/Mailing Address is a required field. Applicant Info/Mailing City is a required field. Applicant Info/Mailing Zip is a required field. Applicant Info/Mailing State is a required field. Applicant Info/Org Type is a required field.'); - - }) - .expect(400, done); - - }); - - it('should return valid json with a 400 status code for tempOutfitters POST request without a tempOutfitterFields object', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create({tempOutfitterFields : undefined}))) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Temp Outfitter Fields is a required field. Temp Outfitter Fields/Activity Description is a required field. Temp Outfitter Fields/Client Charges is a required field.'); - - }) - .expect(400, done); - - }); - - }); - - describe('applicantInfo fields', function(){ - - it('should return valid json with a 400 status code for tempOutfitters POST request without a firstName', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create({'applicantInfo.firstName':undefined}))) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/First Name is a required field.'); - - }) - .expect(400, done); - - }); - - it('should return valid json with a 400 status code for tempOutfitters POST request without a lastName', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create({'applicantInfo.lastName':undefined}))) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Last Name is a required field.'); - - }) - .expect(400, done); - - }); - - it('should return valid json with a 400 status code for tempOutfitters POST request without a dayPhone', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create({'applicantInfo.dayPhone':undefined}))) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Day Phone is a required field. Applicant Info/Day Phone/Area Code is a required field. Applicant Info/Day Phone/Number is a required field. Applicant Info/Day Phone/Phone Type is a required field.'); - - }) - .expect(400, done); - - }); - - it('should return valid json with a 400 status code for tempOutfitters POST request without a dayPhone/areaCode', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create({'applicantInfo.dayPhone.areaCode':undefined}))) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Day Phone/Area Code is a required field.'); - - }) - .expect(400, done); - - }); - - it('should return valid json with a 400 status code for tempOutfitters POST request without a dayPhone/number', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create({'applicantInfo.dayPhone.number':undefined}))) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Day Phone/Number is a required field.'); - - }) - .expect(400, done); - - }); - - it('should return valid json with a 400 status code for tempOutfitters POST request without a dayPhone/phoneType', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create({'applicantInfo.dayPhone.phoneType':undefined}))) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Day Phone/Phone Type is a required field.'); - - }) - .expect(400, done); - - }); - - it('should return valid json with a 400 status code for tempOutfitters POST request without an emailAddress', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create({'applicantInfo.emailAddress':undefined}))) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Email Address is a required field.'); - - }) - .expect(400, done); - - }); - - it('should return valid json with a 400 status code for tempOutfitters POST request without a mailingAddress', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create({'applicantInfo.mailingAddress':undefined}))) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Mailing Address is a required field.'); - - }) - .expect(400, done); - - }); - - it('should return valid json with a 400 status code for tempOutfitters POST request without a mailingCity', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create({'applicantInfo.mailingCity':undefined}))) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Mailing City is a required field.'); - - }) - .expect(400, done); - - }); - - it('should return valid json with a 400 status code for tempOutfitters POST request without a mailingState', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create({'applicantInfo.mailingState':undefined}))) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Mailing State is a required field.'); - - }) - .expect(400, done); - - }); - - it('should return valid json with a 400 status code for tempOutfitters POST request without a mailingZIP', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create({'applicantInfo.mailingZIP':undefined}))) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx').expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Mailing Zip is a required field.'); - - }) - .expect(400, done); - - }); - - it('should return valid json with a 400 status code for tempOutfitters POST request without an orgType', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create({'applicantInfo.orgType':undefined}))) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Org Type is a required field.'); - - }) - .expect(400, done); - - }); - - }); - - describe('validate required fields present: tempOutfitters fields', function(){ - - it('should return valid json with a 400 status code for tempOutfitters POST request without an activityDescription', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create({'tempOutfitterFields.activityDescription':undefined}))) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Temp Outfitter Fields/Activity Description is a required field.'); - - }) - .expect(400, done); - - }); - - it('should return valid json with a 400 status code for tempOutfitters POST request without either advertisingURL or advertisingDescription', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create( - { - 'tempOutfitterFields.advertisingURL':undefined, - 'tempOutfitterFields.advertisingDescription':undefined - } - ))) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Either Temp Outfitter Fields/Advertising URL or Temp Outfitter Fields/Advertising Description is a required field.'); - }) - .expect(400, done); - }); - - }); - -}); - -describe('API Routes: permits/special-uses/commercial/outfitters', function() { - - let token; - let postControlNumber; - - before(function(done) { - - util.getToken(function(t){ - - token = t; - return done(); - - }); - - }); - - it('should return valid json for tempOutfitters POST (controlNumber to be used in GET)', function(done) { - - this.timeout(5000); - - request(server) - .post('/permits/applications/special-uses/commercial/temp-outfitters/') - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create())) - .attach('insuranceCertificate', './test/data/test_file.doc') - .attach('goodStandingEvidence', './test/data/test_file.docx') - .attach('operatingPlan', './test/data/test_file.pdf') - .expect('Content-Type', /json/) - .expect(function(res){ - postControlNumber = res.body.controlNumber; - }) - .expect(200, done); - - }); - - it('should return valid json for tempOutfitters GET request for id', function(done) { - - request(server) - .get(`${testURL}${postControlNumber}/`) - .set('x-access-token', token) - .expect('Content-Type', /json/) - .expect(200, done); - - }); - - it('should return valid json for tempOutfitters POST request', function(done) { - - request(server) - .post(testURL) - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create())) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(200, done); - - }); - -}); - -describe('tempOutfitters POST: field type validated', function(){ - - let token; - - before(function(done) { - - util.getToken(function(t){ - - token = t; - return done(); - - }); - - }); - - describe('tempOutfitters POST: required fields are type validated', function(){ - - it('should return valid json for invalid type, firstName', function(done) { - - request(server) - .post('/permits/applications/special-uses/commercial/temp-outfitters/') - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create({'applicantInfo.firstName':1}))) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/First Name is expected to be type \'string\'.'); - - }) - .expect(400, done); - - }); - - it('should return valid json for invalid type, lastName', function(done) { - - request(server) - .post('/permits/applications/special-uses/commercial/temp-outfitters/') - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create({'applicantInfo.lastName':1}))) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Last Name is expected to be type \'string\'.'); - - }) - .expect(400, done); - - }); - - it('should return valid json for invalid type, areaCode', function(done) { - - request(server) - .post('/permits/applications/special-uses/commercial/temp-outfitters/') - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create({'applicantInfo.dayPhone.areaCode':'123'}))) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Day Phone/Area Code is expected to be type \'integer\'.'); - - }) - .expect(400, done); - - }); - - it('should return valid json for invalid type, number', function(done) { - - request(server) - .post('/permits/applications/special-uses/commercial/temp-outfitters/') - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create({'applicantInfo.dayPhone.number':'123'}))) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Day Phone/Number is expected to be type \'integer\'.'); - - }) - .expect(400, done); - - }); - - it('should return valid json for invalid type, phoneType', function(done) { - - request(server) - .post('/permits/applications/special-uses/commercial/temp-outfitters/') - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create({'applicantInfo.dayPhone.phoneType':1}))) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Day Phone/Phone Type is expected to be type \'string\'.'); - - }) - .expect(400, done); - - }); - - it('should return valid json for invalid type, emailAddress', function(done) { - - request(server) - .post('/permits/applications/special-uses/commercial/temp-outfitters/') - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create({'applicantInfo.emailAddress':1}))) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Email Address is expected to be type \'string\'.'); - - }) - .expect(400, done); - - }); - - it('should return valid json for invalid type, mailingAddress', function(done) { - - request(server) - .post('/permits/applications/special-uses/commercial/temp-outfitters/') - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create({'applicantInfo.mailingAddress':1}))) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Mailing Address is expected to be type \'string\'.'); - - }) - .expect(400, done); - - }); - - it('should return valid json for invalid type, mailingCity', function(done) { - - request(server) - .post('/permits/applications/special-uses/commercial/temp-outfitters/') - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create({'applicantInfo.mailingCity':1}))) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Mailing City is expected to be type \'string\'.'); - - }) - .expect(400, done); - - }); - - it('should return valid json for invalid type, mailingState', function(done) { - - request(server) - .post('/permits/applications/special-uses/commercial/temp-outfitters/') - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create({'applicantInfo.mailingState':1}))) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Mailing State is expected to be type \'string\'.'); - - }) - .expect(400, done); - - }); - - it('should return valid json for invalid type, mailingZIP', function(done) { - - request(server) - .post('/permits/applications/special-uses/commercial/temp-outfitters/') - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create({'applicantInfo.mailingZIP':12345}))) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Mailing Zip is expected to be type \'string\'.'); - - }) - .expect(400, done); - - }); - - it('should return valid json for invalid type, activityDescription', function(done) { - - request(server) - .post('/permits/applications/special-uses/commercial/temp-outfitters/') - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create({'tempOutfitterFields.activityDescription':1}))) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Temp Outfitter Fields/Activity Description is expected to be type \'string\'.'); - - }) - .expect(400, done); - - }); - - }); - - describe('tempOutfitters POST: non-required fields are type validated', function(){ - - it('should return valid json for invalid type, extension', function(done) { - - request(server) - .post('/permits/applications/special-uses/commercial/temp-outfitters/') - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create({'applicantInfo.dayPhone.extension':1}))) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Day Phone/Extension is expected to be type \'string\'.'); - - }) - .expect(400, done); - - }); - - }); - -}); - -describe('tempOutfitters POST: format validated', function(){ - - let token; - - before(function(done) { - - util.getToken(function(t){ - - token = t; - return done(); - - }); - - }); - - describe('tempOutfitters POST: fields with a specific format are validated', function(){ - - it('should return valid json for invalid format, areaCode', function(done) { - - request(server) - .post('/permits/applications/special-uses/commercial/temp-outfitters/') - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create({'applicantInfo.dayPhone.areaCode':1234}))) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Day Phone/Area Code must be 3 digits.'); - - }) - .expect(400, done); - - }); - - it('should return valid json for invalid format, number', function(done) { - - request(server) - .post('/permits/applications/special-uses/commercial/temp-outfitters/') - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create({'applicantInfo.dayPhone.number':45678901}))) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Day Phone/Number must be 7 digits.'); - - }) - .expect(400, done); - - }); - - }); - - it('should return valid json for invalid format, mailingState', function(done) { - - request(server) - .post('/permits/applications/special-uses/commercial/temp-outfitters/') - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create({'applicantInfo.mailingState':'ORE'}))) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Mailing State must be 2 letters.'); - - }) - .expect(400, done); - - }); - - it('should return valid json for invalid format, mailingZIP', function(done) { - - request(server) - .post('/permits/applications/special-uses/commercial/temp-outfitters/') - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create({'applicantInfo.mailingZIP':'1234'}))) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Mailing Zip must be 5 or 9 digits.'); - - }) - .expect(400, done); - - }); - - it('should return valid json for valid format, mailingZIP', function(done) { - - request(server) - .post('/permits/applications/special-uses/commercial/temp-outfitters/') - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create({'applicantInfo.mailingZIP':'123456789'}))) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(200, done); - - }); - - it('should return valid json for invalid format, region', function(done) { - - request(server) - .post('/permits/applications/special-uses/commercial/temp-outfitters/') - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create({'region':'123'}))) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Region must be 2 digits.'); - - }) - .expect(400, done); - - }); - - it('should return valid json for invalid format, forest', function(done) { +const specialUses = {}; - request(server) - .post('/permits/applications/special-uses/commercial/temp-outfitters/') - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create({'forest':'123'}))) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(function(res){ +specialUses.validate = require('../src/controllers/validation.js'); - expect(res.body.message).to.equal('Forest must be 2 digits.'); +//******************************************************************* +//Mock Input - }) - .expect(400, done); +const tempOutfitterFactory = factory.factory(tempOutfitterInput); +const binaryParser = function (res, cb) { + res.setEncoding('binary'); + res.data = ''; + res.on('data', function (chunk) { + res.data += chunk; }); - - it('should return valid json for invalid format, district', function(done) { - - request(server) - .post('/permits/applications/special-uses/commercial/temp-outfitters/') - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create({'district':'123'}))) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('District must be 2 digits.'); - - }) - .expect(400, done); - + res.on('end', function () { + cb(null, new Buffer(res.data, 'binary')); }); +}; -}); - -describe('tempOutfitters POST: enum validated', function(){ +//******************************************************************* +describe('API Routes: permits/special-uses/commercial/outfitters', function() { + let token; + let postControlNumber; before(function(done) { @@ -971,93 +67,36 @@ describe('tempOutfitters POST: enum validated', function(){ }); }); - - describe('tempOutfitters POST: fields with enumuration are validated', function(){ - - it('should return valid json for invalid option, orgType', function(done) { - - request(server) - .post('/permits/applications/special-uses/commercial/temp-outfitters/') - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create({'applicantInfo.orgType':'invalid'}))) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Org Type is not one of enum values: Individual,Corporation,Limited Liability Company,Partnership or Association,State Government or Agency,Local Government or Agency,Nonprofit.'); - - }) - .expect(400, done); - - }); - it('should return valid json for invalid option, type', function(done) { - - request(server) - .post('/permits/applications/special-uses/commercial/temp-outfitters/') - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create({'type':'invalid'}))) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Type is not one of enum values: noncommercial,tempOutfitters.'); - - }) - .expect(400, done); + it('should return valid json for tempOutfitters POST (controlNumber to be used in GET)', function(done) { + + this.timeout(5000); - }); + request(server) + .post(testURL) + .set('x-access-token', token) + .field('body', JSON.stringify(tempOutfitterFactory.create())) + .attach('insuranceCertificate', './test/data/test_file.doc') + .attach('goodStandingEvidence', './test/data/test_file.docx') + .attach('operatingPlan', './test/data/test_file.pdf') + .expect('Content-Type', /json/) + .expect(function(res){ + postControlNumber = res.body.controlNumber; + }) + .expect(200, done); }); - -}); - -describe('tempOutfitters POST: pattern validated', function(){ - - let token; - - before(function(done) { - - util.getToken(function(t){ - - token = t; - return done(); - - }); - }); - - describe('tempOutfitters POST: fields with a regex pattern are validated', function(){ - - it('should return valid json for invalid pattern, emailAddress', function(done) { - - request(server) - .post('/permits/applications/special-uses/commercial/temp-outfitters/') - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create({'applicantInfo.emailAddress':'invalid'}))) - .attach('guideDocumentation', './test/data/test_guideDocumentation.docx') - .attach('acknowledgementOfRiskForm', './test/data/test_acknowledgementOfRiskForm.docx') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Applicant Info/Email Address must be in format \'email@email.service\'.'); + it('should return valid json for tempOutfitters GET request for id', function(done) { - }) - .expect(400, done); + request(server) + .get(`${testURL}${postControlNumber}/`) + .set('x-access-token', token) + .expect('Content-Type', /json/) + .expect(200, done); - }); }); + }); describe('tempOutfitters POST: file validated', function(){ @@ -1077,6 +116,25 @@ describe('tempOutfitters POST: file validated', function(){ describe('tempOutfitters POST: required files checks', function(){ + it('should return errors for file that is too large', function(){ + expect ( + specialUses.validate.validateFile(tempOutfitterObjects.file.uploadFile_20MB, tempOutfitterObjects.file.validationConstraints, 'insuranceCertificate').length + ) + .to.be.equal(1); + }); + it('should return errors for file that is too small', function(){ + expect ( + specialUses.validate.validateFile(tempOutfitterObjects.file.uploadFile_empty, tempOutfitterObjects.file.validationConstraints, 'insuranceCertificate').length + ) + .to.be.equal(1); + }); + it('should return errors for file that is the wrong mime type', function(){ + expect ( + specialUses.validate.validateFile(tempOutfitterObjects.file.uploadFile_invalid_mime, tempOutfitterObjects.file.validationConstraints, 'insuranceCertificate').length + ) + .to.be.equal(1); + }); + it('should return valid json missing single required file', function(done) { request(server) @@ -1114,97 +172,6 @@ describe('tempOutfitters POST: file validated', function(){ }); - it('should return valid json missing all files', function(done) { - - request(server) - .post('/permits/applications/special-uses/commercial/temp-outfitters/') - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create())) - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Insurance Certificate is a required file. Good Standing Evidence is a required file. Operating Plan is a required file.'); - - }) - .expect(400, done); - - }); - - it('should return valid json with error messages for an invalid file (size of 0 bytes)', function(done) { - - request(server) - .post('/permits/applications/special-uses/commercial/temp-outfitters/') - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create())) - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_file0bytes.docx') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Operating Plan cannot be an empty file.'); - - }) - .expect(400, done); - - }); - - it('should return valid json with error messages for an invalid file (size over 10 MB)', function(done) { - - request(server) - .post('/permits/applications/special-uses/commercial/temp-outfitters/') - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create())) - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_file_16mb.pdf') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Operating Plan cannot be larger than 10 MB.'); - - }) - .expect(400, done); - - }); - - it('should return valid json when guideDocumentation file uploaded of size 16 MB (size limit 25 MB)', function(done) { - - this.timeout(60000); - - request(server) - .post('/permits/applications/special-uses/commercial/temp-outfitters/') - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create())) - .attach('guideDocumentation', './test/data/test_file_16mb.pdf') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(200, done); - - }); - - it('should return valid json with error message when guideDocumentation file uploaded of size 32 MB (size limit 25 MB)', function(done) { - - request(server) - .post('/permits/applications/special-uses/commercial/temp-outfitters/') - .set('x-access-token', token) - .field('body', JSON.stringify(tempOutfitterFactory.create())) - .attach('guideDocumentation', './test/data/test_file_32mb.pdf') - .attach('insuranceCertificate', './test/data/test_insuranceCertificate.docx') - .attach('goodStandingEvidence', './test/data/test_goodStandingEvidence.docx') - .attach('operatingPlan', './test/data/test_operatingPlan.docx') - .expect('Content-Type', /json/) - .expect(function(res){ - - expect(res.body.message).to.equal('Guide Documentation cannot be larger than 25 MB.'); - - }) - .expect(400, done); - - }); - it('should return valid json with error messages for an invalid file (invalid extension)', function(done) { request(server) @@ -1298,7 +265,14 @@ describe('tempOutfitters GET: files validated', function(){ .get(`${testURL}${postControlNumber}/files/${postFileName}`) .set('x-access-token', token) .expect(200) - .expect('Content-Type', 'application/pdf') + .expect(function(res){ + if (res.headers['Content-Type'] === 'application/pdf; charset=utf-8' || res.headers['Content-Type'] === 'application/pdf'){ + return true; + } + else { + return false; + } + }) .buffer() .parse(binaryParser) .end(function(err, res) { @@ -1313,5 +287,73 @@ describe('tempOutfitters GET: files validated', function(){ }); }); +describe('tempOutfitters GET: zip file validated', function(){ + + let token; + + let postControlNumber; + + before(function(done) { + + if (process.env.npm_config_mock === 'Y'){ + AWS.restore('S3'); + } + + util.getToken(function(t){ + + token = t; + return done(); + + }); + + }); + + after(function(done){ + if (process.env.npm_config_mock === 'Y'){ + AWS.mock('S3', 'getObject', tempOutfitterObjects.mockS3Get); + } + + return done(); + }); + + describe('tempOutfitters GET/POST: post a new application with files, get that application, get files zipped ', function(){ + + it('should return valid json when application submitted with three required files', function(done) { + + this.timeout(5000); + + request(server) + .post('/permits/applications/special-uses/commercial/temp-outfitters/') + .set('x-access-token', token) + .field('body', JSON.stringify(tempOutfitterFactory.create())) + .attach('insuranceCertificate', './test/data/test_file.doc') + .attach('goodStandingEvidence', './test/data/test_file.docx') + .attach('operatingPlan', './test/data/test_file.pdf') + .expect('Content-Type', /json/) + .expect(function(res){ + postControlNumber = res.body.controlNumber; + }) + .expect(200, done); + + }); + + it('should return valid zip when getting outfitters files using the controlNumber returned from POST', function(done) { + request(server) + .get(`${testURL}${postControlNumber}/files/`) + .set('x-access-token', token) + .expect(200) + .expect('Content-Type', 'application/zip') + .buffer() + .parse(binaryParser) + .end(function(err, res) { + if (err) + return done(err); + + expect(200, done); + done(); + }); + }); + }); +}); diff --git a/test/validation-test.js b/test/validation-test.js new file mode 100644 index 00000000..be65cd81 --- /dev/null +++ b/test/validation-test.js @@ -0,0 +1,418 @@ +/* + + ___ ___ ___ _ _ _ ___ ___ + | __/ __| ___| _ \___ _ _ _ __ (_) |_ /_\ | _ \_ _| + | _|\__ \ / -_) _/ -_) '_| ' \| | _| / _ \| _/| | + |_| |___/ \___|_| \___|_| |_|_|_|_|\__| /_/ \_\_| |___| + +*/ + +//******************************************************************* + +'use strict'; + +//******************************************************************* + +const AWS = require('mock-aws'); +const chai = require('chai'); +const expect = chai.expect; + +const specialUses = {}; + +specialUses.validate = require('../src/controllers/validation.js'); + +const testObjects = require('./data/testObjects.json'); +const outfittersObjects = testObjects.outfitters; +const noncommercialObjects = testObjects.noncommercial; + +const factory = require('unionized'); +const testTempOutfittersBody = require('./data/testInputTempOutfitters.json'); +const testNoncommercialBody = require('./data/testInputNoncommercial.json'); +const tempOutfitterFactory = factory.factory(testTempOutfittersBody); +const noncommercialFactory = factory.factory(testNoncommercialBody); + +before(function(){ + if (process.env.npm_config_mock === 'Y'){ + AWS.mock('S3', 'putObject', { ETag: '"82e8674bebaea2797c28872c9a38ad43"' }); + AWS.mock('S3', 'getObject', testObjects.mockS3Get); + } +}); + +after(function(){ + if (process.env.npm_config_mock === 'Y'){ + AWS.restore(); + } +}); + +describe('outfitters validation ', function(){ + describe('ensure field is present', function(){ + it('should report issues when no body is provided', function(){ + expect ( + specialUses.validate.validateBody({}, outfittersObjects.pathData, outfittersObjects.derefSchema).errorArray.length + ) + .to.be.equal(20); + }); + it('should report issues when no applicantInfo object is provided', function(){ + expect ( + specialUses.validate.validateBody(tempOutfitterFactory.create({applicantInfo : undefined}), outfittersObjects.pathData, outfittersObjects.derefSchema).errorArray.length + ) + .to.be.equal(13); + }); + it('should report issues when no tempOutfitterFields object is provided', function(){ + expect ( + specialUses.validate.validateBody(tempOutfitterFactory.create({tempOutfitterFields : undefined}), outfittersObjects.pathData, outfittersObjects.derefSchema).errorArray.length + ) + .to.be.equal(3); + }); + it('should report issues when no applicantInfo/org type is provided', function(){ + expect ( + specialUses.validate.validateBody(tempOutfitterFactory.create({'applicantInfo.orgType' : undefined}), outfittersObjects.pathData, outfittersObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when no tempOutfitterFields/activity description is provided', function(){ + expect ( + specialUses.validate.validateBody(tempOutfitterFactory.create({'tempOutfitterFields.activityDescription' : undefined}), outfittersObjects.pathData, outfittersObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when no tempOutfitterFields/client charges is provided', function(){ + expect ( + specialUses.validate.validateBody(tempOutfitterFactory.create({'tempOutfitterFields.clientCharges' : undefined}), outfittersObjects.pathData, outfittersObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when no tempOutfitterFields/client charges is provided', function(){ + expect ( + specialUses.validate.validateBody(tempOutfitterFactory.create({'tempOutfitterFields.clientCharges' : undefined}), outfittersObjects.pathData, outfittersObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when neither tempOutfitterFields/advertising url nor tempOutfitterFields/advertising description is provided', function(){ + expect ( + specialUses.validate.validateBody(tempOutfitterFactory.create({'tempOutfitterFields.advertisingURL' : undefined, 'tempOutfitterFields.advertisingDescription' : undefined}), outfittersObjects.pathData, outfittersObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + }); + describe('ensure fields are the right type', function(){ + it('should report issues when when the wrong type of tempOutfitterFields/activity description is provided', function(){ + expect ( + specialUses.validate.validateBody(tempOutfitterFactory.create({'tempOutfitterFields.activityDescription' : 123}), outfittersObjects.pathData, outfittersObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when when the wrong type of tempOutfitterFields/client charges is provided', function(){ + expect ( + specialUses.validate.validateBody(tempOutfitterFactory.create({'tempOutfitterFields.clientCharges' : 500}), outfittersObjects.pathData, outfittersObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + }); +}); + +describe('noncommercial validation', function(){ + describe('ensure field is present', function(){ + it('should report issues when no region is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({region : undefined}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when no forest is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({forest : undefined}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when no district is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({district : undefined}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when no first name is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'applicantInfo.firstName' : undefined}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when no last name is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'applicantInfo.lastName' : undefined}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when no day phone is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'applicantInfo.dayPhone' : undefined}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(4); + }); + it('should report issues when no day phone/area code is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'applicantInfo.dayPhone.areaCode' : undefined}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when no day phone/number is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'applicantInfo.dayPhone.number' : undefined}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when no day phone/phone type is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'applicantInfo.dayPhone.phoneType' : undefined}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when no email address is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'applicantInfo.emailAddress' : undefined}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when no mailing address is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'applicantInfo.mailingAddress' : undefined}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when no mailing city is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'applicantInfo.mailingCity' : undefined}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when no mailing state is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'applicantInfo.mailingState' : undefined}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when no mailing zip is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'applicantInfo.mailingZIP' : undefined}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when no type is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'type' : undefined}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when no noncommcialFields object is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({noncommercialFields : undefined}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(6); + }); + it('should report issues when no noncommcialFields/activity description is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'noncommercialFields.activityDescription' : undefined}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when no noncommcialFields/location description is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'noncommercialFields.locationDescription' : undefined}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when no noncommcialFields/start date time is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'noncommercialFields.startDateTime' : undefined}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when no noncommcialFields/end date time is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'noncommercialFields.endDateTime' : undefined}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when no noncommcialFields/number participants is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'noncommercialFields.numberParticipants' : undefined}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + }); + describe('ensure fields are the right type', function(){ + it('should report issues when the wrong type of applicantInfo/first name is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'applicantInfo.firstName' : 123}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when the wrong type of applicantInfo/last name is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'applicantInfo.lastName' : 123}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when the wrong type of applicantInfo/day phone/area code is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'applicantInfo.dayPhone.areaCode' : '123'}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when the wrong type of applicantInfo/day phone/number is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'applicantInfo.dayPhone.number' : '123'}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when the wrong type of applicantInfo/day phone/phone type is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'applicantInfo.dayPhone.phoneType' : 1}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when the wrong type of applicantInfo/day phone/extension is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'applicantInfo.dayPhone.extension' : 1}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when the wrong type of applicantInfo/email address is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'applicantInfo.emailAddress' : 123}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when the wrong type of applicantInfo/mailing address is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'applicantInfo.mailingAddress' : 123}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when the wrong type of applicantInfo/mailing city is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'applicantInfo.mailingCity' : 123}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when the wrong type of applicantInfo/mailing state is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'applicantInfo.mailingState' : 123}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when the wrong type of applicantInfo/mailing zip is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'applicantInfo.mailingZIP' : 123}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when the wrong type of noncommcialFields/activity description is provided', function(){ + expect ( + specialUses.validate.validateBody(tempOutfitterFactory.create({'tempOutfitterFields.activityDescription' : 123}), outfittersObjects.pathData, outfittersObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + }); + describe('ensure fields are the right format', function(){ + + it('should report issues when the wrong format of applicantInfo/day phone/area code is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'applicantInfo.dayPhone.areaCode' : 12}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when the wrong format of applicantInfo/day phone/number is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'applicantInfo.dayPhone.areaCode' : 12}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when the wrong format of applicantInfo/mailing state is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'applicantInfo.mailingState' : 'ORE'}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when the wrong format of applicantInfo/mailing zip is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'applicantInfo.mailingZIP' : '123456'}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should not report issues when the right format of applicantInfo/mailing zip is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'applicantInfo.mailingZIP' : '123456789'}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(0); + }); + it('should report issues when the wrong format of region is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'region' : '123'}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when the wrong format of forest is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'forest' : '123'}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when the wrong format of district is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'district' : '123'}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when the wrong format of noncommercialFields/start date time is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'noncommercialFields.startDateTime' : '01-12-2012'}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues when the wrong format of noncommercialFields/end date time is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'noncommercialFields.endDateTime' : '01-12-2012'}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + }); + describe('ensure fields follow their pattern', function(){ + it('should report issues for invalid pattern for email address is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'applicantInfo.emailAddress' : 'invalid'}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + }); + describe('ensure fields with enumuration are validated', function(){ + it('should report issues for invalid option for type is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'type' : 'invalid'}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + it('should report issues for invalid option for applicant info/org type is provided', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'applicantInfo.orgType' : 'invalid'}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + }); + describe('ensure fields with a dependency are checked', function(){ + it('should report issues for orgName', function(){ + expect ( + specialUses.validate.validateBody(noncommercialFactory.create({'applicantInfo.organizationName' : 'theOrg'}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + }); + describe('ensure fields is right length', function(){ + it('should report issues for invalid length', function(){ + expect ( + specialUses.validate.getFieldValidationErrors(noncommercialFactory.create({'applicantInfo.firstName' : 'Josdfsdfsdfsdasdasdhnaaaaaaaaaaaaasasasasasaasaaaaasahbsdbahsdbhasdbasbdbahsdbasbdbashdbashjdbashdbahsdbahsdbahsdbashdbahsdbhasdbashdbahjsdbhasbdahsbdhasbdhabsdhjabsdhjasbdhjasbdhjasbdjhasbdjahsbdahsbdahsdbahsdbahjsbdhjasbdahsdbasbdahsdbahsbdahsdbjhasbdahsbdhjasdbahbdbdbb'}), noncommercialObjects.pathData, noncommercialObjects.derefSchema).errorArray.length + ) + .to.be.equal(1); + }); + }); +});