Skip to content

Commit

Permalink
feat(commons): Add text.isValidAutocomplete method
Browse files Browse the repository at this point in the history
  • Loading branch information
WilcoFiers committed Jul 12, 2018
1 parent e6189ce commit 8d44fe4
Show file tree
Hide file tree
Showing 4 changed files with 244 additions and 175 deletions.
104 changes: 2 additions & 102 deletions lib/checks/forms/autocomplete-valid.js
Original file line number Diff line number Diff line change
@@ -1,102 +1,2 @@
let {
standaloneTerms = [],
qualifiedTerms = [],
qualifiers = [],
locations = [],
looseTyped = false
} =
options || {};

qualifiers = qualifiers.concat(['home', 'work', 'mobile', 'fax', 'pager']);
locations = locations.concat(['billing', 'shipping']);
standaloneTerms = standaloneTerms.concat([
'name',
'honorific-prefix',
'given-name',
'additional-name',
'family-name',
'honorific-suffix',
'nickname',
'username',
'new-password',
'current-password',
'organization-title',
'organization',
'street-address',
'address-line1',
'address-line2',
'address-line3',
'address-level4',
'address-level3',
'address-level2',
'address-level1',
'country',
'country-name',
'postal-code',
'cc-name',
'cc-given-name',
'cc-additional-name',
'cc-family-name',
'cc-number',
'cc-exp',
'cc-exp-month',
'cc-exp-year',
'cc-csc',
'cc-type',
'transaction-currency',
'transaction-amount',
'language',
'bday',
'bday-day',
'bday-month',
'bday-year',
'sex',
'url',
'photo'
]);

qualifiedTerms = qualifiedTerms.concat([
'tel',
'tel-country-code',
'tel-national',
'tel-area-code',
'tel-local',
'tel-local-prefix',
'tel-local-suffix',
'tel-extension',
'email',
'impp'
]);

const autocomplete = node.getAttribute('autocomplete');
const autocompleteTerms = autocomplete.split(/\s+/g).map(term => {
return term.toLowerCase();
});

if (!looseTyped) {
if (
autocompleteTerms[0].length > 8 &&
autocompleteTerms[0].substr(0, 8) === 'section-'
) {
autocompleteTerms.shift();
}

if (locations.includes(autocompleteTerms[0])) {
autocompleteTerms.shift();
}

if (qualifiers.includes(autocompleteTerms[0])) {
autocompleteTerms.shift();
// only quantifiers allowed at this point
standaloneTerms = [];
}

if (autocompleteTerms.length !== 1) {
return false;
}
}

const purposeTerm = autocompleteTerms[autocompleteTerms.length - 1];
return (
standaloneTerms.includes(purposeTerm) || qualifiedTerms.includes(purposeTerm)
);
const autocomplete = node.getAttribute('autocomplete') || '';
return axe.commons.text.isValidAutocomplete(autocomplete, options);
118 changes: 118 additions & 0 deletions lib/commons/text/is-valid-autocomplete.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/* global text */
const autocomplete = {
stateTerms: ['on', 'off'],
standaloneTerms: [
'name',
'honorific-prefix',
'given-name',
'additional-name',
'family-name',
'honorific-suffix',
'nickname',
'username',
'new-password',
'current-password',
'organization-title',
'organization',
'street-address',
'address-line1',
'address-line2',
'address-line3',
'address-level4',
'address-level3',
'address-level2',
'address-level1',
'country',
'country-name',
'postal-code',
'cc-name',
'cc-given-name',
'cc-additional-name',
'cc-family-name',
'cc-number',
'cc-exp',
'cc-exp-month',
'cc-exp-year',
'cc-csc',
'cc-type',
'transaction-currency',
'transaction-amount',
'language',
'bday',
'bday-day',
'bday-month',
'bday-year',
'sex',
'url',
'photo'
],
qualifiers: ['home', 'work', 'mobile', 'fax', 'pager'],
qualifiedTerms: [
'tel',
'tel-country-code',
'tel-national',
'tel-area-code',
'tel-local',
'tel-local-prefix',
'tel-local-suffix',
'tel-extension',
'email',
'impp'
],
locations: ['billing', 'shipping']
};
text.autocomplete = autocomplete;

text.isValidAutocomplete = function isValidAutocomplete(
autocomplete,
{
looseTyped = false,
stateTerms = [],
locations = [],
qualifiers = [],
standaloneTerms = [],
qualifiedTerms = []
} = {}
) {
/*eslint max-statements: ["error", 21] */
autocomplete = autocomplete.toLowerCase();
stateTerms = stateTerms.concat(text.autocomplete.stateTerms);
if (stateTerms.includes(autocomplete)) {
return true;
}

qualifiers = qualifiers.concat(text.autocomplete.qualifiers);
locations = locations.concat(text.autocomplete.locations);
standaloneTerms = standaloneTerms.concat(text.autocomplete.standaloneTerms);
qualifiedTerms = qualifiedTerms.concat(text.autocomplete.qualifiedTerms);

const autocompleteTerms = autocomplete.split(/\s+/g);
if (!looseTyped) {
if (
autocompleteTerms[0].length > 8 &&
autocompleteTerms[0].substr(0, 8) === 'section-'
) {
autocompleteTerms.shift();
}

if (locations.includes(autocompleteTerms[0])) {
autocompleteTerms.shift();
}

if (qualifiers.includes(autocompleteTerms[0])) {
autocompleteTerms.shift();
// only quantifiers allowed at this point
standaloneTerms = [];
}

if (autocompleteTerms.length !== 1) {
return false;
}
}

const purposeTerm = autocompleteTerms[autocompleteTerms.length - 1];
return (
standaloneTerms.includes(purposeTerm) ||
qualifiedTerms.includes(purposeTerm)
);
};
109 changes: 36 additions & 73 deletions test/checks/forms/autocomplete-valid.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,94 +11,57 @@ describe('autocomplete-valid', function() {
qualifiedTerms: ['qualified-term']
};

var _isValidAutocomplete;
beforeEach(function() {
axe._tree = undefined;
_isValidAutocomplete = axe.commons.text.isValidAutocomplete;
});

afterEach(function() {
axe.commons.text.isValidAutocomplete = _isValidAutocomplete;
fixture.innerHTML = '';
checkContext.reset();
});

function autocompleteCheckParams(arg, opt) {
return checkSetup(
'<input autocomplete="' + arg + '" id="target" />',
opt || options
);
}

it('returns true the only term is a valid autocomplete term', function() {
var params = autocompleteCheckParams('standalone-term');
assert.isTrue(evaluate.apply(checkContext, params));
});

it('returns false the only term is an invalid autocomplete term', function() {
var params = autocompleteCheckParams('bad-term');
assert.isFalse(evaluate.apply(checkContext, params));
});

it('returns true if section-* is used as the first term', function() {
var params = autocompleteCheckParams('section-foo standalone-term');
assert.isTrue(evaluate.apply(checkContext, params));
});

it('returns true if `shipping` or `billing` is used as the first term', function() {
var params1 = autocompleteCheckParams('shipping standalone-term');
assert.isTrue(evaluate.apply(checkContext, params1));

var params2 = autocompleteCheckParams('billing standalone-term');
assert.isTrue(evaluate.apply(checkContext, params2));
it('passes autocomplete attribute to text.isValidAutocomplete', function() {
var params = checkSetup('<input autocomplete="foo" id="target" />');
var called = false;
axe.commons.text.isValidAutocomplete = function(arg1) {
assert.equal(arg1, 'foo');
called = true;
};
evaluate.apply(checkContext, params);
assert.isTrue(called);
});

it('returns true if section-* is used before `shipping` or `billing`', function() {
var params = autocompleteCheckParams(
'section-foo shipping standalone-term'
it('passes options to text.isValidAutocomplete', function() {
var options = { foo: 'bar' };
var params = checkSetup(
'<input autocomplete="foo" id="target" />',
options
);
assert.isTrue(evaluate.apply(checkContext, params));
var called = false;
axe.commons.text.isValidAutocomplete = function(_, arg2) {
assert.equal(arg2, options);
called = true;
};
evaluate.apply(checkContext, params);
assert.isTrue(called);
});

it('returns false if `shipping` or `billing` is used before section-*', function() {
var params = autocompleteCheckParams(
'shipping section-foo standalone-term'
it('returns the outcome of text.isValidAutocomplete', function() {
var params1 = checkSetup(
'<input autocomplete="badvalue" id="target" />',
options
);
assert.isFalse(evaluate.apply(checkContext, params));
});
assert.isFalse(_isValidAutocomplete('badvalue'));
assert.isFalse(evaluate.apply(checkContext, params1));

it('returns true if "home", "work", "mobile", "fax" or "pager" is used before aqualifier', function() {
['home', 'work', 'mobile', 'fax', 'pager'].forEach(function(qualifier) {
var params = autocompleteCheckParams(qualifier + ' qualified-term');
assert.isTrue(
evaluate.apply(checkContext, params),
'failed for ' + qualifier
);
});
});

it('returns false if "home", "work", "mobile", "fax" or "pager" is used before an inappropriate term', function() {
['home', 'work', 'mobile', 'fax', 'pager'].forEach(function(qualifier) {
var params = autocompleteCheckParams(qualifier + ' standalone-term');
assert.isFalse(
evaluate.apply(checkContext, params),
'failed for ' + qualifier
);
});
});

describe('options.strictMode:false', function() {
it('returns true if the last term is a valid autocomplete term', function() {
var params = autocompleteCheckParams('do not care! valid-term', {
looseTyped: true,
standaloneTerms: ['valid-term']
});
assert.isTrue(evaluate.apply(checkContext, params));
});

it('returns false if the last term is an invalid autocomplete term', function() {
var params = autocompleteCheckParams('shipping invalid', {
looseTyped: true,
standaloneTerms: ['valid-term']
});
assert.isFalse(evaluate.apply(checkContext, params));
});
var params2 = checkSetup(
'<input autocomplete="email" id="target" />',
options
);
assert.isTrue(_isValidAutocomplete('email'));
assert.isTrue(evaluate.apply(checkContext, params2));
});
});
Loading

0 comments on commit 8d44fe4

Please sign in to comment.