diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index b6e07e5..37ce16f 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -90,9 +90,9 @@ jobs:
try-scenario:
- ember-lts-3.24
- ember-lts-3.28
- # - ember-release
- # - ember-beta
- # - ember-canary
+ - ember-release
+ - ember-beta
+ - ember-canary
- ember-classic
- ember-default-with-jquery
- embroider-safe
diff --git a/.jshintrc b/.jshintrc
deleted file mode 100644
index d421faa..0000000
--- a/.jshintrc
+++ /dev/null
@@ -1,32 +0,0 @@
-{
- "predef": [
- "document",
- "window",
- "-Promise"
- ],
- "browser": true,
- "boss": true,
- "curly": true,
- "debug": false,
- "devel": true,
- "eqeqeq": true,
- "evil": true,
- "forin": false,
- "immed": false,
- "laxbreak": false,
- "newcap": true,
- "noarg": true,
- "noempty": false,
- "nonew": false,
- "nomen": false,
- "onevar": false,
- "plusplus": false,
- "regexp": false,
- "undef": true,
- "sub": true,
- "strict": false,
- "white": false,
- "eqnull": true,
- "esversion": 6,
- "unused": true
-}
diff --git a/README.md b/README.md
index 19ad5f2..0a7c0a4 100644
--- a/README.md
+++ b/README.md
@@ -28,10 +28,10 @@ ember install ember-credit-cards
Usage (Components)
------------------------------------------------------------------------------
-### credit-card-form
+### CreditCardForm
Full credit card form with validations and formatting.
-Attributes:
+Arguments:
* number
* name
* month
@@ -41,47 +41,47 @@ Attributes:
* zipcodeRequired
Events:
+ * onUpdate
* onValidate
Example:
-``` html
-//templates/credit-cards/new.hbs
-
-
- {{ credit-card-form
- number=attrs.number
- name=attrs.name
- month=attrs.month
- year=attrs.year
- cvc=attrs.cvc
- onValidate=(mut disabled)
- }}
-
-
-
- Save
-
-
+``` hbs
+
+
+
+
+
+
+ Save
+
```
-### input-credit-card-number
+### ` `
Formats credit card number on entry. Discards non-numeric and extra characters. Parses sets number attribute.
Attributes:
* number
-### input-credit-card-cvc
+### ` `
Formats cvc number on entry. Discards non-numeric and extra characters. Parses sets cvc attribute.
Attributes:
* cvc
-### input-credit-card-expiration
+### ` `
Validates and formats expiration date. Discards non-numeric and extra characters. Parses and sets month, year attributes.
@@ -90,7 +90,7 @@ Attributes:
* year
-### input-credit-card-zipcode
+### ` `
Validates and formats zip code. Discards non-numeric and extra characters. Sets zipcode attribute.
@@ -175,26 +175,23 @@ validations.validateZipcode('94611-24'); //=> false
## Custom Labels
-
You can provide custom labels for localization.
-``` html
-
- {{
- credit-card-form
- number=ccNumber
- name=ccName
- month=ccMonth
- year=ccYear
- cvc=ccCvc
- numberLabel=(t 'credit-card-form.number')
- securityCodeLabel=(t 'credit-card-form.security-code')
- nameOnCardLabel=(t 'credit-card-form.name-on-card')
- expirationLabel=(t 'credit-card-form.expiration')
- zipCodeLabel=(t 'credit-card-form.zip-code')
- on-validate='ccValidate'
- }}
-
+``` hbs
+
```
Contributing
diff --git a/addon/components/credit-card-form.hbs b/addon/components/credit-card-form.hbs
new file mode 100644
index 0000000..22ca59f
--- /dev/null
+++ b/addon/components/credit-card-form.hbs
@@ -0,0 +1,56 @@
+
diff --git a/addon/components/credit-card-form.js b/addon/components/credit-card-form.js
index 690ed96..bbe1d72 100644
--- a/addon/components/credit-card-form.js
+++ b/addon/components/credit-card-form.js
@@ -1,81 +1,59 @@
-/* eslint-disable ember/require-tagless-components */
-/* eslint-disable ember/no-classic-components */
-/* eslint-disable ember/no-classic-classes */
-/* eslint-disable ember/no-observers */
-
-import { and } from '@ember/object/computed';
-import Component from '@ember/component';
-import { computed, observer } from '@ember/object';
+import Component from '@glimmer/component';
+import { action } from '@ember/object';
import Validations from 'ember-credit-cards/utils/validations';
import Cards from 'ember-credit-cards/utils/cards';
-export default Component.extend({
- tagName: 'form',
- classNames: ['credit-card-form'],
- classNameBindings: ['isValid'],
- name: null,
- number: null,
- month: null,
- year: null,
- cvc: null,
- zipcode: null,
- zipcodeRequired: false,
- onValidate() {},
-
- isValid: and(
- 'nameValid',
- 'numberValid',
- 'expirationValid',
- 'cvcValid',
- 'zipcodeValid'
- ),
-
- becameValid: observer('isValid', function () {
- this.onValidate(this.isValid);
- }),
-
- nameValid: computed('name', function () {
- var name = this.name;
+export default class CreditCardFormComponent extends Component {
+ get isValid() {
+ return (
+ this.nameValid &&
+ this.numberValid &&
+ this.expirationValid &&
+ this.cvcValid &&
+ this.zipcodeValid
+ );
+ }
+
+ get nameValid() {
+ var name = this.args.name;
if (name) {
return true;
}
return false;
- }),
-
- numberValid: computed('number', function () {
- var number = this.number;
+ }
- return Validations.validateNumber(number);
- }),
+ get numberValid() {
+ return Validations.validateNumber(this.args.number);
+ }
- expirationValid: computed('month', 'year', function () {
- var month = this.month;
- var year = this.year;
+ get expirationValid() {
+ var month = this.args.month;
+ var year = this.args.year;
return Validations.validateExpiration(month, year);
- }),
+ }
- cvcValid: computed('cvc', 'type', function () {
- var cvc = this.cvc;
+ get cvcValid() {
+ var cvc = this.args.cvc;
var type = this.type;
return Validations.validateCVC(cvc, type);
- }),
+ }
- zipcodeValid: computed('zipcodeRequired', 'zipcode', function () {
- if (this.zipcodeRequired) {
- var zip = this.zipcode;
+ get zipcodeValid() {
+ if (this.args.zipcodeRequired) {
+ var zip = this.args.zipcode;
return Validations.validateZipcode(zip);
}
return true;
- }),
+ }
- type: computed('number', function () {
- var number = this.number;
+ get type() {
+ var number = this.args.number;
var card = Cards.fromNumber(number);
if (card) {
@@ -83,5 +61,15 @@ export default Component.extend({
} else {
return '';
}
- }),
-});
+ }
+
+ @action
+ setValue(key, value) {
+ this.args.onUpdate(key, value);
+ this._onValidate();
+ }
+
+ _onValidate() {
+ (this.args.onValidate || (() => {}))(this.isValid);
+ }
+}
diff --git a/addon/components/input-credit-card-cvc.hbs b/addon/components/input-credit-card-cvc.hbs
new file mode 100644
index 0000000..2404d5f
--- /dev/null
+++ b/addon/components/input-credit-card-cvc.hbs
@@ -0,0 +1,8 @@
+
diff --git a/addon/components/input-credit-card-cvc.js b/addon/components/input-credit-card-cvc.js
index bd8027e..1fd9c16 100644
--- a/addon/components/input-credit-card-cvc.js
+++ b/addon/components/input-credit-card-cvc.js
@@ -1,42 +1,37 @@
-/* eslint-disable ember/no-classic-classes */
-import TextField from '@ember/component/text-field';
-import { computed } from '@ember/object';
+import Component from '@glimmer/component';
+import { action } from '@ember/object';
import hasTextSelected from 'ember-credit-cards/utils/has-text-selected';
+import formatters from 'ember-credit-cards/utils/formatters';
import isDigitKeypress from 'ember-credit-cards/utils/is-digit-keypress';
import isWhitelistKeypress from 'ember-credit-cards/utils/is-whitelist-keypress';
-export default TextField.extend({
- classNames: ['input-credit-card-cvc'],
- autocomplete: 'cc-csc',
- placeholder: '•••',
- label: 'Expiration',
- type: 'tel',
+function inputValid(value) {
+ return value.length <= 4;
+}
- keyPress: function (e) {
+export default class InputCreditCardCvcComponent extends Component {
+ get cvc() {
+ return formatters.formatCvc(this.args.cvc);
+ }
+
+ set cvc(value) {
+ this.args.onUpdate(value);
+ }
+
+ @action
+ keyPress(e) {
var digit = String.fromCharCode(e.which);
if (!isDigitKeypress(e)) {
return false;
}
- if (hasTextSelected(this.element)) {
+ if (hasTextSelected(e.target)) {
return true;
}
- var value = this.element.value + digit;
-
- return isWhitelistKeypress(e) || value.length <= 4;
- },
-
- value: computed('cvc', {
- get() {
- return this.cvc;
- },
- set(propertyName, newValue) {
- var number = newValue.replace(/\D/g, '').slice(0, 4);
- this.set('cvc', newValue);
+ var value = (this.args.cvc || '') + digit;
- return number;
- },
- }),
-});
+ return isWhitelistKeypress(e) || inputValid(value);
+ }
+}
diff --git a/addon/components/input-credit-card-expiration.hbs b/addon/components/input-credit-card-expiration.hbs
new file mode 100644
index 0000000..5a02507
--- /dev/null
+++ b/addon/components/input-credit-card-expiration.hbs
@@ -0,0 +1,10 @@
+
diff --git a/addon/components/input-credit-card-expiration.js b/addon/components/input-credit-card-expiration.js
index 69a1cb9..7674d42 100644
--- a/addon/components/input-credit-card-expiration.js
+++ b/addon/components/input-credit-card-expiration.js
@@ -1,6 +1,6 @@
-/* eslint-disable ember/no-classic-classes */
-import TextField from '@ember/component/text-field';
-import { computed } from '@ember/object';
+import Component from '@glimmer/component';
+import { action } from '@ember/object';
+import { tracked } from '@glimmer/tracking';
import formatters from 'ember-credit-cards/utils/formatters';
import hasTextSelected from 'ember-credit-cards/utils/has-text-selected';
import isDigitKeypress from 'ember-credit-cards/utils/is-digit-keypress';
@@ -36,46 +36,45 @@ function parseInput(value) {
return [mon, year];
}
-export default TextField.extend({
- classNames: ['input-credit-card-expiration'],
- month: null,
- year: null,
- placeholder: '•• / ••',
- autocomplete: 'cc-exp',
- type: 'tel',
- required: true,
+export default class InputCreditCardExpirationComponent extends Component {
+ @tracked
+ _value;
- keyPress: function (e) {
+ constructor() {
+ super(...arguments);
+ this._value = formatters.formatExpiration(this.args.month, this.args.year);
+ }
+
+ get value() {
+ return this._value;
+ }
+
+ set value(value) {
+ var isBackspace = this._value.length - 1 === value.length;
+ var parsed = parseInput(value);
+
+ var month = parsed[0];
+ var year = parsed[1];
+
+ this._value = formatters.formatExpiration(month, year, isBackspace);
+
+ this.args.onUpdateMonth(month);
+ this.args.onUpdateYear(year);
+ }
+
+ @action
+ keyPress(e) {
var digit = String.fromCharCode(e.which);
if (!isDigitKeypress(e)) {
return false;
}
- if (hasTextSelected(this.element)) {
+ if (hasTextSelected(e.target)) {
return true;
}
- var value = this.element.value + digit;
+ var value = this._value + digit;
return inputValid(value);
- },
-
- value: computed('month', 'year', {
- get() {
- return formatters.formatExpiration(this.month, this.year);
- },
- set(key, value) {
- var parsed = parseInput(value);
-
- var month = parsed[0];
- var year = parsed[1];
-
- this.setProperties({
- month: month,
- year: year,
- });
-
- return formatters.formatExpiration(month, year);
- },
- }),
-});
+ }
+}
diff --git a/addon/components/input-credit-card-number.hbs b/addon/components/input-credit-card-number.hbs
new file mode 100644
index 0000000..6ac1adb
--- /dev/null
+++ b/addon/components/input-credit-card-number.hbs
@@ -0,0 +1,10 @@
+
diff --git a/addon/components/input-credit-card-number.js b/addon/components/input-credit-card-number.js
index ac40e33..c7710cb 100644
--- a/addon/components/input-credit-card-number.js
+++ b/addon/components/input-credit-card-number.js
@@ -1,6 +1,5 @@
-/* eslint-disable ember/no-classic-classes */
-import TextField from '@ember/component/text-field';
-import { computed } from '@ember/object';
+import Component from '@glimmer/component';
+import { action } from '@ember/object';
import hasTextSelected from 'ember-credit-cards/utils/has-text-selected';
import formatters from 'ember-credit-cards/utils/formatters';
import cards from 'ember-credit-cards/utils/cards';
@@ -20,34 +19,27 @@ function inputValid(value) {
}
}
-export default TextField.extend({
- classNames: ['input-credit-card-number'],
- placeholder: '•••• •••• •••• ••••',
- autocomplete: 'cc-number',
- type: 'tel',
- required: true,
+export default class InputCreditCardNumberComponent extends Component {
+ get number() {
+ return formatters.formatNumber(this.args.number);
+ }
+
+ set number(value) {
+ this.args.onUpdate(value);
+ }
- keyPress: function (e) {
+ @action
+ keyPress(e) {
if (!isDigitKeypress(e)) {
return false;
}
- if (hasTextSelected(this.element)) {
+ if (hasTextSelected(e.target)) {
return true;
}
var digit = String.fromCharCode(e.which);
- var value = this.element.value + digit;
+ var value = this.args.number + digit;
return inputValid(value);
- },
-
- value: computed('number', {
- get() {
- return formatters.formatNumber(this.number);
- },
- set(key, value) {
- this.set('number', value);
- return formatters.formatNumber(value);
- },
- }),
-});
+ }
+}
diff --git a/addon/components/input-credit-card-zipcode.hbs b/addon/components/input-credit-card-zipcode.hbs
new file mode 100644
index 0000000..98ad798
--- /dev/null
+++ b/addon/components/input-credit-card-zipcode.hbs
@@ -0,0 +1,9 @@
+
diff --git a/addon/components/input-credit-card-zipcode.js b/addon/components/input-credit-card-zipcode.js
index 9eff831..df4878a 100644
--- a/addon/components/input-credit-card-zipcode.js
+++ b/addon/components/input-credit-card-zipcode.js
@@ -1,38 +1,35 @@
-/* eslint-disable ember/no-classic-classes */
-import TextField from '@ember/component/text-field';
-import { computed } from '@ember/object';
+import Component from '@glimmer/component';
+import { action } from '@ember/object';
import hasTextSelected from 'ember-credit-cards/utils/has-text-selected';
import formatters from 'ember-credit-cards/utils/formatters';
import isDigitKeypress from 'ember-credit-cards/utils/is-digit-keypress';
-export default TextField.extend({
- type: 'tel',
- classNames: ['input-credit-card-zipcode'],
- autocomplete: 'none',
- autocorrect: 'off',
+function inputValid(value) {
+ return value.length <= 10;
+}
- keyPress: function (e) {
+export default class InputCreditCardZipcodeComponent extends Component {
+ get zipcode() {
+ return formatters.formatZipcode(this.args.zipcode);
+ }
+
+ set zipcode(value) {
+ this.args.onUpdate(value);
+ }
+
+ @action
+ keyPress(e) {
var digit = String.fromCharCode(e.which);
if (!isDigitKeypress(e)) {
return false;
}
- if (hasTextSelected(this.element)) {
+ if (hasTextSelected(e.target)) {
return true;
}
- var value = this.element.value + digit;
- return value.length <= 10;
- },
-
- value: computed('zipcode', {
- get() {
- return formatters.formatZipcode(this.zipcode);
- },
- set(key, value) {
- this.set('zipcode', value);
- return formatters.formatZipcode(value);
- },
- }),
-});
+ var value = this._zipcode + digit;
+ return inputValid(value);
+ }
+}
diff --git a/addon/utils/formatters.js b/addon/utils/formatters.js
index 5e9ea16..ebb734a 100644
--- a/addon/utils/formatters.js
+++ b/addon/utils/formatters.js
@@ -37,7 +37,7 @@ function formatNumber(num) {
}
}
-function formatExpiration(mon, year) {
+function formatExpiration(mon, year, isBackspace) {
var sep = '';
mon = mon || '';
@@ -47,13 +47,21 @@ function formatExpiration(mon, year) {
mon = '0' + mon;
}
- if (mon.length === 2) {
- sep = ' / ';
+ if (year !== '' || !isBackspace) {
+ if (mon.length === 2) {
+ sep = ' / ';
+ }
}
return mon + sep + year;
}
+function formatCvc(value) {
+ if (value) {
+ return value.toString().replace(/\D/g, '').slice(0, 4);
+ }
+}
+
function formatZipcode(zip) {
zip = zip || '';
@@ -71,5 +79,6 @@ function formatZipcode(zip) {
export default {
formatNumber: formatNumber,
formatExpiration: formatExpiration,
+ formatCvc: formatCvc,
formatZipcode: formatZipcode,
};
diff --git a/addon/utils/is-whitelist-keypress.js b/addon/utils/is-whitelist-keypress.js
index 6004be3..b83fa25 100644
--- a/addon/utils/is-whitelist-keypress.js
+++ b/addon/utils/is-whitelist-keypress.js
@@ -1,6 +1,10 @@
-import { A } from '@ember/array';
-
-const validKeyCodes = A([9, 8, 46, 27, 13]);
+const validKeyCodes = [
+ 9, // Tab
+ 8, // Backspace
+ 46, // Delete
+ 27, // Escape
+ 13, // Enter
+];
export default function isDigitKeypress(e) {
var keyCode = e.keyCode || e.which;
diff --git a/config/ember-try.js b/config/ember-try.js
index 2612023..fd1aa7f 100644
--- a/config/ember-try.js
+++ b/config/ember-try.js
@@ -28,6 +28,10 @@ module.exports = async function () {
devDependencies: {
'ember-source': await getChannelURL('release'),
},
+ dependencies: {
+ 'ember-auto-import': '^2.2.4',
+ webpack: '^5.64.4',
+ },
},
},
{
@@ -36,6 +40,10 @@ module.exports = async function () {
devDependencies: {
'ember-source': await getChannelURL('beta'),
},
+ dependencies: {
+ 'ember-auto-import': '^2.2.4',
+ webpack: '^5.64.4',
+ },
},
},
{
@@ -44,6 +52,10 @@ module.exports = async function () {
devDependencies: {
'ember-source': await getChannelURL('canary'),
},
+ dependencies: {
+ 'ember-auto-import': '^2.2.4',
+ webpack: '^5.64.4',
+ },
},
},
{
diff --git a/tests/.jshintrc b/tests/.jshintrc
deleted file mode 100644
index d2bd113..0000000
--- a/tests/.jshintrc
+++ /dev/null
@@ -1,52 +0,0 @@
-{
- "predef": [
- "document",
- "window",
- "location",
- "setTimeout",
- "$",
- "-Promise",
- "define",
- "console",
- "visit",
- "exists",
- "fillIn",
- "click",
- "keyEvent",
- "triggerEvent",
- "find",
- "findWithAssert",
- "wait",
- "DS",
- "andThen",
- "currentURL",
- "currentPath",
- "currentRouteName"
- ],
- "node": false,
- "browser": false,
- "boss": true,
- "curly": true,
- "debug": false,
- "devel": false,
- "eqeqeq": true,
- "evil": true,
- "forin": false,
- "immed": false,
- "laxbreak": false,
- "newcap": true,
- "noarg": true,
- "noempty": false,
- "nonew": false,
- "nomen": false,
- "onevar": false,
- "plusplus": false,
- "regexp": false,
- "undef": true,
- "sub": true,
- "strict": false,
- "white": false,
- "eqnull": true,
- "esversion": 6,
- "unused": true
-}
diff --git a/tests/dummy/app/controllers/application.js b/tests/dummy/app/controllers/application.js
new file mode 100644
index 0000000..e20e8fc
--- /dev/null
+++ b/tests/dummy/app/controllers/application.js
@@ -0,0 +1,25 @@
+import Controller from '@ember/controller';
+import { tracked } from '@glimmer/tracking';
+import { action } from '@ember/object';
+
+export default class ApplicationController extends Controller {
+ @tracked
+ name;
+
+ @tracked
+ number;
+
+ @tracked
+ cvc;
+
+ @tracked
+ month;
+
+ @tracked
+ year;
+
+ @action
+ setValue(key, value) {
+ this[key] = value;
+ }
+}
diff --git a/tests/dummy/app/index.html b/tests/dummy/app/index.html
index 53ed12f..141e718 100644
--- a/tests/dummy/app/index.html
+++ b/tests/dummy/app/index.html
@@ -11,6 +11,7 @@
+
{{content-for "head-footer"}}
diff --git a/tests/dummy/app/templates/application.hbs b/tests/dummy/app/templates/application.hbs
index fb1e016..6cfcae2 100644
--- a/tests/dummy/app/templates/application.hbs
+++ b/tests/dummy/app/templates/application.hbs
@@ -21,13 +21,21 @@
-
+
+ {{this.name}}
require zip code.
-
diff --git a/tests/integration/components/credit-card-form-test.js b/tests/integration/components/credit-card-form-test.js
index 16323df..fa02764 100644
--- a/tests/integration/components/credit-card-form-test.js
+++ b/tests/integration/components/credit-card-form-test.js
@@ -3,13 +3,27 @@ import { setupRenderingTest } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
import { render } from '@ember/test-helpers';
-module('credit-card-form', function (hooks) {
+module('Integration | Component | credit-card-form', function (hooks) {
setupRenderingTest(hooks);
test('it should format Card labels correctly with default values', async function (assert) {
assert.expect(5);
- await render(hbs`{{credit-card-form zipcodeRequired=true}}`);
+ this.set('setValue', () => {});
+
+ await render(
+ hbs`
+
+ `
+ );
assert.equal(
this.element.querySelector('.cc-number .control-label').innerHTML,
@@ -41,11 +55,24 @@ module('credit-card-form', function (hooks) {
);
});
- // tests for custom label
-
test('it should format Card Number label correctly with custom numberLabel provided', async function (assert) {
await render(
- hbs`{{credit-card-form zipcodeRequired=true numberLabel="Kaartnummer" securityCodeLabel="Veiligheidscode" nameOnCardLabel="Naam op Kaart" expirationLabel="Vervalt op" zipCodeLabel="postcode"}}`
+ hbs`
+
+ `
);
assert.equal(
diff --git a/tests/integration/components/input-credit-card-cvc-test.js b/tests/integration/components/input-credit-card-cvc-test.js
index f07be3e..f872ffb 100644
--- a/tests/integration/components/input-credit-card-cvc-test.js
+++ b/tests/integration/components/input-credit-card-cvc-test.js
@@ -3,7 +3,7 @@ import { setupRenderingTest } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
import { render } from '@ember/test-helpers';
-module('input-credit-card-cvc', function (hooks) {
+module('Integration | Component | input-credit-card-cvc', function (hooks) {
setupRenderingTest(hooks);
test('it renders', async function (assert) {
@@ -11,7 +11,9 @@ module('input-credit-card-cvc', function (hooks) {
this.set('cvc', 300);
- await render(hbs`{{input-credit-card-cvc cvc=cvc class="form-control"}}`);
+ await render(
+ hbs` `
+ );
assert.equal(this.element.querySelector('.form-control').value, '300');
});
diff --git a/tests/integration/components/input-credit-card-expiration-test.js b/tests/integration/components/input-credit-card-expiration-test.js
index e0b7590..d03cc37 100644
--- a/tests/integration/components/input-credit-card-expiration-test.js
+++ b/tests/integration/components/input-credit-card-expiration-test.js
@@ -3,58 +3,138 @@ import { setupRenderingTest } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
import { render, typeIn } from '@ember/test-helpers';
-module('input-credit-card-expiration', function (hooks) {
- setupRenderingTest(hooks);
+module(
+ 'Integration | Component | input-credit-card-expiration',
+ function (hooks) {
+ setupRenderingTest(hooks);
- test('it renders', async function (assert) {
- assert.expect(1);
+ test('it renders', async function (assert) {
+ assert.expect(1);
- this.set('month', 10);
- this.set('year', 2019);
+ this.set('month', 10);
+ this.set('year', 2019);
+ this.set('setMonth', (month) => {
+ this.set('month', month);
+ });
+ this.set('setYear', (year) => {
+ this.set('year', year);
+ });
- await render(hbs`{{input-credit-card-expiration month=month year=year }}`);
+ await render(
+ hbs`
+
+ `
+ );
- assert.equal(this.element.querySelector('input').value, '102019');
- });
+ assert.equal(this.element.querySelector('input').value, '102019');
+ });
- test('should format month shorthand correctly', async function (assert) {
- assert.expect(1);
+ test('should format month shorthand correctly', async function (assert) {
+ assert.expect(1);
- await render(hbs`{{input-credit-card-expiration}}`);
+ this.set('setMonth', (month) => {
+ this.set('month', month);
+ });
+ this.set('setYear', (year) => {
+ this.set('year', year);
+ });
- await typeIn('input', '4');
+ await render(
+ hbs`
+
+ `
+ );
- assert.equal(this.element.querySelector('input').value, '04 / ');
- });
+ await typeIn('input', '4');
- test('should format forward slash shorthand correctly', async function (assert) {
- assert.expect(1);
- this.set('month', 8);
- await render(hbs`{{input-credit-card-expiration month=month}}`);
- await typeIn('input', '/');
+ assert.equal(this.element.querySelector('input').value, '04 / ');
+ });
- assert.equal(this.element.querySelector('input').value, '08 / ');
- });
+ test('should format forward slash shorthand correctly', async function (assert) {
+ assert.expect(1);
+ this.set('month', 8);
+ this.set('setMonth', (month) => {
+ this.set('month', month);
+ });
+ this.set('setYear', (year) => {
+ this.set('year', year);
+ });
- test('should only allow numbers', async function (assert) {
- assert.expect(3);
- this.set('month', '');
- this.set('year', '');
- await render(hbs`{{input-credit-card-expiration month=month year=year}}`);
- await typeIn('input', '4');
- assert.equal(this.element.querySelector('input').value, '04 / ');
- await typeIn('input', 'd');
+ await render(
+ hbs`
+
+ `
+ );
+ await typeIn('input', '/');
- assert.equal(this.month, '04');
- assert.equal(this.year, '');
- });
+ assert.equal(this.element.querySelector('input').value, '08 / ');
+ });
- test('should only allow six numbers', async function (assert) {
- assert.expect(1);
- this.set('month', '4');
- this.set('year', '2019');
- await render(hbs`{{input-credit-card-expiration month=month year=year}}`);
+ test('should only allow numbers', async function (assert) {
+ assert.expect(3);
+ this.set('month', '');
+ this.set('year', '');
+ this.set('setMonth', (month) => {
+ this.set('month', month);
+ });
+ this.set('setYear', (year) => {
+ this.set('year', year);
+ });
+ await render(
+ hbs`
+
+ `
+ );
+ await typeIn('input', '4');
+ assert.equal(this.element.querySelector('input').value, '04 / ');
+ await typeIn('input', 'd');
- assert.equal(this.element.querySelector('input').value, '04 / 2019');
- });
-});
+ assert.equal(this.month, '04');
+ assert.equal(this.year, '');
+ });
+
+ test('should only allow six numbers', async function (assert) {
+ assert.expect(1);
+ this.set('month', '4');
+ this.set('year', '2019');
+ this.set('setMonth', (month) => {
+ this.set('month', month);
+ });
+ this.set('setYear', (year) => {
+ this.set('year', year);
+ });
+ await render(
+ hbs`
+
+ `
+ );
+
+ assert.equal(this.element.querySelector('input').value, '04 / 2019');
+ });
+ }
+);
diff --git a/tests/integration/components/input-credit-card-number-test.js b/tests/integration/components/input-credit-card-number-test.js
index 6a5cc8d..45720c0 100644
--- a/tests/integration/components/input-credit-card-number-test.js
+++ b/tests/integration/components/input-credit-card-number-test.js
@@ -3,13 +3,18 @@ import { setupRenderingTest } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
import { render, typeIn } from '@ember/test-helpers';
-module('input-credit-card-number', function (hooks) {
+module('Integration | Component | input-credit-card-number', function (hooks) {
setupRenderingTest(hooks);
test('it should format cc number correctly', async function (assert) {
assert.expect(2);
this.set('number', '42424');
- await render(hbs`{{input-credit-card-number number=number}}`);
+ this.set('onUpdate', (value) => {
+ this.set('number', value);
+ });
+ await render(
+ hbs` `
+ );
assert.equal(this.element.querySelector('input').value, '4242 4');
await typeIn('input', '5');
assert.equal(this.element.querySelector('input').value, '4242 45');
diff --git a/tests/integration/components/input-credit-card-zipcode-test.js b/tests/integration/components/input-credit-card-zipcode-test.js
index 6bfbf1d..976ed29 100644
--- a/tests/integration/components/input-credit-card-zipcode-test.js
+++ b/tests/integration/components/input-credit-card-zipcode-test.js
@@ -3,13 +3,15 @@ import { setupRenderingTest } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
import { render } from '@ember/test-helpers';
-module('input-credit-card-zipcode', function (hooks) {
+module('Integration | Component | input-credit-card-zipcode', function (hooks) {
setupRenderingTest(hooks);
test('should accept 9 digits ', async function (assert) {
assert.expect(1);
this.set('zipcode', '946062370');
- await render(hbs`{{input-credit-card-zipcode zipcode=zipcode}}`);
+ await render(hbs`
+
+ `);
assert.equal(this.element.querySelector('input').value, '94606-2370');
});
});
diff --git a/tests/unit/utils/cards-test.js b/tests/unit/utils/cards-test.js
index 1179197..709b2a0 100644
--- a/tests/unit/utils/cards-test.js
+++ b/tests/unit/utils/cards-test.js
@@ -1,7 +1,7 @@
import cards from 'ember-credit-cards/utils/cards';
import { module, test } from 'qunit';
-module('cards', function () {
+module('Unit | Utility | cards', function () {
test('should return Visa that begins with 40', function (assert) {
assert.equal(cards.cardType('4012121212121212'), 'visa');
});
diff --git a/tests/unit/utils/formatters-test.js b/tests/unit/utils/formatters-test.js
index 42bec29..2913b7a 100644
--- a/tests/unit/utils/formatters-test.js
+++ b/tests/unit/utils/formatters-test.js
@@ -1,7 +1,7 @@
import formatters from 'ember-credit-cards/utils/formatters';
import { module, test } from 'qunit';
-module('formatters', function () {
+module('Unit | Utility | formatters', function () {
module('formatExpiration', function () {
test('it should format incomplete date', function (assert) {
var result = formatters.formatExpiration('2');
@@ -12,6 +12,11 @@ module('formatters', function () {
var result = formatters.formatExpiration('12', '2010');
assert.equal(result, '12 / 2010');
});
+
+ test('it should handle backspace', function (assert) {
+ var result = formatters.formatExpiration('12', '', true);
+ assert.equal(result, '12');
+ });
});
module('formatNumber', function () {
diff --git a/tests/unit/utils/validations-test.js b/tests/unit/utils/validations-test.js
index 3e15989..618da7c 100644
--- a/tests/unit/utils/validations-test.js
+++ b/tests/unit/utils/validations-test.js
@@ -1,7 +1,7 @@
import validations from 'ember-credit-cards/utils/validations';
import { module, test } from 'qunit';
-module('validations', function () {
+module('Unit | Utility | validations', function () {
test('Validating a card number', function (assert) {
var validate = validations.validateNumber;