Prevent being able to submit a create form with empty values

This commit is contained in:
John Cowen 2018-06-11 12:50:58 +01:00
parent 59ce55227c
commit e37136ecae
12 changed files with 66 additions and 10 deletions

View File

@ -13,6 +13,8 @@ export default Route.extend(WithAclActions, {
}, },
model: function(params) { model: function(params) {
this.item = get(this, 'repo').create(); this.item = get(this, 'repo').create();
// TODO: Why didn't I have to do this for KV's?
set(this.item, 'Name', '');
set(this.item, 'Datacenter', this.modelFor('dc').dc.Name); set(this.item, 'Datacenter', this.modelFor('dc').dc.Name);
return hash({ return hash({
create: true, create: true,

View File

@ -26,12 +26,13 @@
</fieldset> </fieldset>
<div> <div>
{{#if create }} {{#if create }}
<button type="submit" {{ action "create" item}} disabled={{if item.isInvalid 'disabled'}}>Save</button> {{! we only need to check for an empty name here as ember munges autofocus, once we have autofocus back revisit this}}
<button type="submit" {{ action "create" item}} disabled={{if (or item.isPristine item.isInvalid (eq item.Name '')) 'disabled'}}>Save</button>
{{ else }} {{ else }}
<button type="submit" {{ action "update" item}} disabled={{if item.isInvalid 'disabled'}}>Save</button> <button type="submit" {{ action "update" item}} disabled={{if item.isInvalid 'disabled'}}>Save</button>
{{/if}} {{/if}}
<button type="reset" {{ action "cancel" item}}>Cancel</button> <button type="reset" {{ action "cancel" item}}>Cancel</button>
{{# if (and item.ID (not-eq item.ID 'anonymous')) }} {{# if (and (not create) (not-eq item.ID 'anonymous')) }}
{{#confirmation-dialog message='Are you sure you want to delete this ACL token?'}} {{#confirmation-dialog message='Are you sure you want to delete this ACL token?'}}
{{#block-slot 'action' as |confirm|}} {{#block-slot 'action' as |confirm|}}
<button type="button" class="type-delete" {{action confirm 'delete' item parent}}>Delete</button> <button type="button" class="type-delete" {{action confirm 'delete' item parent}}>Delete</button>

View File

@ -24,8 +24,10 @@
</div> </div>
{{/if}} {{/if}}
</fieldset> </fieldset>
{{!TODO This has a <div> around it in acls, remove or add for consistency }}
{{#if create }} {{#if create }}
<button type="submit" {{ action "create" item parent}} disabled={{if item.isInvalid 'disabled'}}>Save</button> {{! we only need to check for an empty keyname here as ember munges autofocus, once we have autofocus back revisit this}}
<button type="submit" {{ action "create" item parent}} disabled={{if (or item.isPristine item.isInvalid (eq (left-trim item.Key parent.Key) '')) 'disabled'}}>Save</button>
{{ else }} {{ else }}
<button type="submit" {{ action "update" item parent}} disabled={{if item.isInvalid 'disabled'}}>Save</button> <button type="submit" {{ action "update" item parent}} disabled={{if item.isInvalid 'disabled'}}>Save</button>
<button type="reset" {{ action "cancel" item parent}}>Cancel changes</button> <button type="reset" {{ action "cancel" item parent}}>Cancel changes</button>

View File

@ -2,5 +2,4 @@ import { validatePresence, validateLength } from 'ember-changeset-validations/va
export default { export default {
Name: [validatePresence(true), validateLength({ min: 1 })], Name: [validatePresence(true), validateLength({ min: 1 })],
Type: validatePresence(true), Type: validatePresence(true),
ID: validateLength({ min: 1 }),
}; };

View File

@ -11,6 +11,7 @@ Feature: dc / acls / update: ACL Update
dc: datacenter dc: datacenter
acl: key acl: key
--- ---
Then the url should be /datacenter/acls/key
Then I type with yaml Then I type with yaml
--- ---
name: [Name] name: [Name]

View File

@ -11,6 +11,7 @@ Feature: dc / kvs / update: KV Update
dc: datacenter dc: datacenter
kv: [Name] kv: [Name]
--- ---
Then the url should be /datacenter/kv/[Name]/edit
Then I type with yaml Then I type with yaml
--- ---
value: [Value] value: [Value]

View File

@ -0,0 +1,10 @@
import steps from './steps';
// step definitions that are shared between features should be moved to the
// tests/acceptance/steps/steps.js file
export default function(assert) {
return steps(assert).then('I should find a file', function() {
assert.ok(true, this.step);
});
}

View File

@ -0,0 +1,24 @@
@setupApplicationTest
Feature: submit blank
In order to prevent form's being saved without values
As a user
I shouldn't be able to submit a blank form
Scenario: Visiting a blank form for [Model]
Given 1 datacenter model with the value "datacenter"
When I visit the [Model] page for yaml
---
dc: datacenter
---
Then the url should be /datacenter/[Slug]/create
And I submit
Then the url should be /datacenter/[Slug]/create
Where:
------------------
| Model | Slug |
| kv | kv |
| acl | acls |
------------------
@ignore
Scenario: The button is disabled
Then ok

View File

@ -44,9 +44,22 @@ export function visitable(path, encoder = encodeURIComponent) {
let executionContext = getExecutionContext(this); let executionContext = getExecutionContext(this);
return executionContext.runAsync(context => { return executionContext.runAsync(context => {
let params = assign({}, dynamicSegmentsAndQueryParams); var params;
let fullPath = fillInDynamicSegments(path, params, encoder); let fullPath = (function _try(paths) {
const path = paths.shift();
params = assign({}, dynamicSegmentsAndQueryParams);
var fullPath;
try {
fullPath = fillInDynamicSegments(path, params, encoder);
} catch (e) {
if (paths.length > 0) {
fullPath = _try(paths);
} else {
throw e;
}
}
return fullPath;
})(typeof path === 'string' ? [path] : path.slice(0));
fullPath = appendQueryParams(fullPath, params); fullPath = appendQueryParams(fullPath, params);
return context.visit(fullPath); return context.visit(fullPath);

View File

@ -1,7 +1,8 @@
import { create, visitable, clickable, triggerable } from 'ember-cli-page-object'; import { create, clickable, triggerable } from 'ember-cli-page-object';
import { visitable } from 'consul-ui/tests/lib/page-object/visitable';
export default create({ export default create({
visit: visitable('/:dc/acls/:acl'), visit: visitable(['/:dc/acls/:acl', '/:dc/acls/create']),
// fillIn: fillable('input, textarea, [contenteditable]'), // fillIn: fillable('input, textarea, [contenteditable]'),
name: triggerable('keypress', '[name="name"]'), name: triggerable('keypress', '[name="name"]'),
submit: clickable('[type=submit]'), submit: clickable('[type=submit]'),

View File

@ -2,7 +2,7 @@ import { create, clickable } from 'ember-cli-page-object';
import { visitable } from 'consul-ui/tests/lib/page-object/visitable'; import { visitable } from 'consul-ui/tests/lib/page-object/visitable';
export default create({ export default create({
visit: visitable('/:dc/kv/:kv/edit', str => str), visit: visitable(['/:dc/kv/:kv/edit', '/:dc/kv/create'], str => str),
// fillIn: fillable('input, textarea, [contenteditable]'), // fillIn: fillable('input, textarea, [contenteditable]'),
// name: triggerable('keypress', '[name="additional"]'), // name: triggerable('keypress', '[name="additional"]'),
submit: clickable('[type=submit]'), submit: clickable('[type=submit]'),

View File

@ -65,6 +65,8 @@ export default function(assert) {
['I visit the $name page for yaml\n$yaml', 'I visit the $name page for json\n$json'], ['I visit the $name page for yaml\n$yaml', 'I visit the $name page for json\n$json'],
function(name, data) { function(name, data) {
currentPage = pages[name]; currentPage = pages[name];
// TODO: Consider putting an assertion here for testing the current url
// do I absolutely definitely need that all the time?
return pages[name].visit(data); return pages[name].visit(data);
} }
) )