Skip to content

Commit

Permalink
Merge branch 'GPII-3083'
Browse files Browse the repository at this point in the history
* GPII-3083: (50 commits)
  GPII-3083: Added handlebars as a dev dependency to improve reliability of using handlebars in browser fixtures.
  GPII-3083:  Cleaned up remaining message key examples.
  GPII-3038: Updated remaining overly generic <Object> references in JSDocs.
  GPII-3083: Tweaked environment detection based on errors requiring individual files from Node.js.
  GPII-3083 Standardised message key namespacing in code and docs.
  GPII-3083: Fixed duplicate Chrome Testem runs.
  GPII-3083: Refined and extended JSDoc typedefs.
  GPII-3080: Added JSDoc typedefs for several object types.
  GPII-3083: Added JSDoc typedef for AJV errors.
  GPII-3083: Cleaned up schema-validated and schema-validated model docs.
  Removed "fluid.get" check around schemaValidationResults.
  GPII-3083: Downgraded nyc dependency to avoid empty coverage reports.
  GPII-3083: Added "testem" as a direct (dev) dependency.  Updated dependencies to pick up newer versions.
  GPII-3083: Removed lingering instances of "typeof require" pattern.  Standardised "Ajv" name to match browser global case.
  GPII-3083: Replace lingering instances of "FSL" throughout.
  GPII-3083: Refactored "node vs. web" check for cross-environment scripts.
  GPII-3083: Disallowed "additionalProperties" in GSS schemas.
  GPII-3083: Updated kettle middleware to add a configurable status code when a validation error occurs.
  GPII-3083: Removed crufty comment.
  GPII-3083: Added default rules to kettle validation request handler in case some reuses that grade in their own work withour our options wiring.
  ...
  • Loading branch information
amb26 committed May 7, 2019
2 parents 9cef446 + 7ea9bc7 commit d181a1a
Show file tree
Hide file tree
Showing 114 changed files with 5,833 additions and 10,354 deletions.
2 changes: 1 addition & 1 deletion .eslintrc-md.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@
"plugins": [
"markdown"
]
}
}
4 changes: 2 additions & 2 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"extends": "eslint-config-fluid"
}
"extends": "eslint-config-fluid"
}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ pids
*.pid
*.seed

# npm package lock file
package-lock.json

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

Expand Down
1 change: 0 additions & 1 deletion .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,3 @@ vagrant_destroy:
- vagrant destroy -f
- "rm -fr ../.vagrant-$CI_COMMIT_SHA"
when: always

6 changes: 6 additions & 0 deletions .nycrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"reporter": ["html", "text-summary"],
"report-dir": "reports",
"temp-directory": "coverage",
"include": [ "./src/**/*.js", "./index.js"]
}
2 changes: 1 addition & 1 deletion .vagrant.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ test_job:
script: # One line per command to execute
# Required to avoid problems installing esparse
- "npm config set bin-links false --global"
- "do.ps1 -c 'v: && npm install && npm test'"
- "do.ps1 -c 'v: && npm install && npm test'"
58 changes: 10 additions & 48 deletions Gruntfile.js
Original file line number Diff line number Diff line change
@@ -1,56 +1,18 @@
/* eslint-env node */
"use strict";

module.exports = function (grunt) {
grunt.initConfig({
eslint: {
js: {
src: ["./src/**/*.js", "./tests/**/*.js", "./*.js"]
},
md: {
options: {
configFile: ".eslintrc-md.json"
},
src: ["./*.md", "./src/docs/**/*.md"]
}
},
jsonlint: {
src: ["./src/**/*.json", "tests/**/*.json", "./*.json"]
},
json5lint: {
src: ["./src/**/*.json5", "tests/**/*.json5", "./*.json5"]
},
mdjsonlint: {
src: ["./*.md", "./**/*.md", "!./node_modules/**"]
},
markdownlint: {
full: {
options: {
config: {
// See https://github.com/DavidAnson/markdownlint#rules--aliases for rule names and meanings.
"no-emphasis-as-header": false, // We use this far too often in fairly legitimate contexts i.e. for a line of actual emphasis that we should discuss
"no-duplicate-header": false, // We use duplicate nested headers, as in section 1 and 2 both have the same sub-section name.
"no-trailing-punctuation": false, // This catches headings that are questions, which seems wrong.
"first-header-h1": false, // Docpad takes care of this for us.
"first-line-h1": false, // Docpad also takes care of this for us.
"header-style": {style: "atx"}, // Although we use a mix, in discussion with various team members, we agreed to try this for now.
"no-inline-html": false, // Obviously we need HTML
"line-length": false,
"ol-prefix": {style: "ordered"} // 1. 2. 3. etc
}
},
src: ["./*.md", "src/docs/**/*.md"]
lintAll: {
sources: {
md: [ "./*.md","./docs/*.md"],
js: ["./src/**/*.js", "./tests/**/*.js", "./*.js"],
json: ["./src/**/*.json", "./tests/**/*.json", "./*.json"],
json5: ["./src/**/*.json5", "./tests/**/*.json5", "./*.json5"],
other: ["./.*"]
}
},
mdlint: ["./*.md", "src/docs/**/*.md"]
}
});

grunt.loadNpmTasks("grunt-jsonlint");
grunt.loadNpmTasks("fluid-grunt-json5lint");
grunt.loadNpmTasks("fluid-grunt-eslint");
grunt.loadNpmTasks("grunt-markdownlint");
grunt.loadNpmTasks("gpii-grunt-mdjson-lint");

grunt.registerTask("lint", "Apply eslint, jsonlint, json5lint, and markdownlint", ["eslint:js", "jsonlint", "markdownlint", "eslint:md", "mdjsonlint"]);
grunt.loadNpmTasks("gpii-grunt-lint-all");
grunt.registerTask("lint", "Perform all standard lint checks.", ["lint-all"]);
};

70 changes: 47 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,48 +7,72 @@ JSON Schema standard includes rules about what fields are required, what type an
and many other complex rules that allow you to do things like limit the length of a text field, or require between one
and three entries in an array.

This package provides a series of [Fluid components](https://github.com/fluid-project/infusion-docs/blob/master/src/documents/UnderstandingInfusionComponents.md)
to help add the power of [JSON Schemas](http://json-schema.org) to your project.

This package is intended to help with three key use cases:

1. Validating arbitrary JSON data and reporting problems to the end user. See the [validator documentation](./docs/validator.md) and [parser documentation](./docs/parser.md) for more details.
2. Rejecting invalid data sent to a REST endpoint (presumably via a POST or PUT request). See the [middleware documentation](./docs/schemaValidationMiddleware.md) for more details.
3. Adding appropriate headers to JSON responses so that it is clear what JSON Schema they adhere to. See the [handler documentation](https://github.com/GPII/gpii-express/blob/master/docs/handler.md) for more details.
This package provides a series of [Fluid
components](https://github.com/fluid-project/infusion-docs/blob/master/src/documents/UnderstandingInfusionComponents.md)
and static functions that are intended to help with two general use cases:

1. Defining the fields and values that are allowed in JSON using [GSS](./docs/gss.md), a variant of the underlying JSON
Schema language.
2. Validating JSON data against a GSS Schema and reporting errors to the user. See the [validator
documentation](./docs/validator.md) for more details.

Although you can reuse the above in various additional ways, this package provides components and functions to assist
with the following specific use cases:

1. (In both Node and a browser) Defining the information a [schema-validated
component](./docs/schemaValidatedComponent.md) requires to start up and preventing its creation if material is missing
or incorrect.
2. (In both Node and a browser) Defining what is allowed in the
[model](https://docs.fluidproject.org/infusion/development/ChangeApplier.html) of a [schema-validated
modelComponent](./docs/schemaValidatedModelComponent.md), and automatically (re)validating the model when changes are
made.
3. (In Node) Rejecting invalid data sent to a REST endpoint (presumably via a POST or PUT request) served up by either
gpii-express or kettle. See the [middleware documentation](./docs/schemaValidationMiddleware.md) for more details.
4. (In a browser) Associating model material with HTML DOM elements, and displaying validation errors in context using
the ["error binder"](./docs/errorBinder.md).

## Running the tests

### Running the Tests in a Virtual Machine

The preferred way to run the tests is to create a virtual machine and run the tests in that supported and
pre-configured environment. To run the tests in a virtual machine, you will need to have VirtualBox, Vagrant, and the
Vagrant CI Plugin installed. See the [QI development environment requirements](https://github.com/GPII/qi-development-environments/#requirements) for more details.
The preferred way to run the tests is to create a virtual machine and run the tests in that supported and pre-configured
environment. To run the tests in a virtual machine, you will need to have VirtualBox, Vagrant, and the Vagrant CI
Plugin installed. See the [QI development environment
requirements](https://github.com/GPII/qi-development-environments/#requirements) for more details.

Once you have satisfied the requirements, you can run the tests using the following commands from the root of the
Once you have satisfied the requirements, you can run the tests using commands like the following from the root of the
repository:

1. `vagrant up`
2. `vagrant ci test`
```bash
vagrant up
vagrant ci test
```

If you would like to remove the VM, use the command `vagrant destroy` from the root of the repository.

### Running the Tests on a Local Machine

Before you can successfully run the tests on a local machine, you will need to have the following installed:
You can run the tests on a local machine using commands like the following from the root of the repository:

* `node` (4.x or 6.x)
* `npm` (3.x)
* [Chrome](https://www.google.com/chrome/)
* [`chromedriver`](https://sites.google.com/a/chromium.org/chromedriver/)
```bash
npm install
npm test
```

Once you have these installed, you can run the tests using commands like:
### Running the Browser Tests without Instrumentation

1. `npm install`
2. `npm test`
By default, the browser tests are run against instrumented code so that we can prepare a code coverage report at the end
of each test run. If you need to troubleshoot a problem with the browser tests, you can also run the tests against the
raw source code by hosting the content in a standalone web server and then opening the tests in a browser. For example,
if you have python installed, you can use the command `python -m SimpleHTTPServer` from the root of the repository, and
then open
[http://localhost:8000/tests/browser-fixtures/all-tests.html](http://localhost:8000/tests/browser-fixtures/all-tests.html)
in a browser.

## Using these components in a browser

This package depends on [AJV](https://github.com/epoberezkin/ajv). AJV can be used on the client-side, but must first
be bundled using `browserify`. The AJV package takes care of this automatically when it's installed, the required
client-side bundle can be found in `./node_modules/ajv/dist/ajv.bundle.js` once you've installed this package's
dependencies.
dependencies. The remaining client-side dependencies depend on which parts of this package you're using. See the HTML
browser test fixtures in `./tests/static/` for examples.
48 changes: 13 additions & 35 deletions docs/errorBinder.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,64 +28,42 @@ grades like 'templateFormControl`.

## Requirements

The `errorBinder` component requires both `gpii-binder` and `gpii-handlebars`.
In addition to the validator and other material from this package, the `errorBinder` component also requires both
`gpii-binder` and `gpii-handlebars`.

## Component options


| Option | Type | Description |
| ------------------ | -------- | ----------- |
| `selectors.fieldError` | `Selector` | The selector representing the view that will display our error summary. |
| `templates.inlineError` | `String` | The filename/id of the template that will be used to produce the inline error output. |

| `templateKeys.inlineError` | `String` | The filename/id of the template that will be used to produce the inline error output. |

# `gpii.schemas.client.errorAwareForm`
## `gpii.schemas.client.errorAwareForm`

This is an extended version of the `templateFormControl` grade provided by the `gpii-handlebars` package.
It passes on validation errors returned by the server to an instance of the `errorBinder`, which displays
the errors next to each field. It also displays a summary of all errors.
It validates the model whenever it changes, and displays the errors next to each field. It also displays a summary of
all errors.

## Component options
### Component options

Here are the unique options you will likely want to customize when using the `errorAwareForm` component.

| Option | Type | Description |
| ------------------ | -------- | ----------- |
| `templates.error` | `String` | The filename/id of the template that will be used to produce the error summary. |
| `templateKeys.error` | `String` | The filename/id of the template that will be used to produce the error summary. |
| `rules` | `Object` | The [model transformation rules](https://wiki.fluidproject.org/display/docs/fluid.model.transformWithRules) that control what information is passed to the server on form submit, and how the response is handled. See the `ajaxCapable` documentation in the `gpii-handlebars` package for details. |

| `rules.modelToRequestPayload` | `Object` | The [model transformation rules](https://wiki.fluidproject.org/display/docs/fluid.model.transformWithRules) that control what information is submitted by the form are also used in validating the form data. |

See the `templateFormControl`documentation in the [`gpii-handlebars`](https://github.com/GPII/gpii-handlebars) package
for more details about supported options.

### Invokers

# `gpii.schemas.client.errorAwareForm.clientSideValidation`

This is an extended version of the `errorAwareForm` grade that adds client-side validation. It validates the model
content before submitting and prevents form submission if there are any errors.

## Component options

| Option | Type | Description |
| ------------------ | -------- | ----------- |
| `rules.modelToRequestPayload` | `Object` | The [model transformation rules](https://wiki.fluidproject.org/display/docs/fluid.model.transformWithRules) that control what information is submitted by the form are also used in validating the form data. |

## Invokers
#### `{gpii.schemas.client.errorAwareForm.clientSideValidation}.submitForm(event)`

### `{gpii.schemas.client.errorAwareForm.clientSideValidation}.submitForm(event)`
* `event {Object}`: The [jQuery event object](http://api.jquery.com/Types/#Event) passed to us by the DOM elements we're bound to.
* `event {Object}`: The [jQuery event object](http://api.jquery.com/Types/#Event) passed to us by the DOM elements we're
bound to.
* Returns: Nothing.

A gatekeeper function that only allows the form to be submitted if client-side validation succeeds. For details on
binding this to your own elements, see the `templateFormControl` documentation in the `gpii-handlebars` package.

### `{gpii.schemas.client.errorAwareForm.clientSideValidation}.validateContent()`
* Returns: Nothing.

Validate client-side model content and display any errors. It expects to validate the same transformed model data the
form transmits (see the `rules.modelToRequestPayload` option above).

# `gpii.schemas.client.errorAwareForm.clientSideValidation.realTime`

This is an extended version of the `clientSideValidation` grade that listens for all model changes, revalidates the
model and updates the onscreen error messages in real time.
Loading

0 comments on commit d181a1a

Please sign in to comment.