diff --git a/ui/app/components/toggle.js b/ui/app/components/toggle.js
index f8c3bb496..e4becf153 100644
--- a/ui/app/components/toggle.js
+++ b/ui/app/components/toggle.js
@@ -5,5 +5,9 @@ export default Component.extend({
classNames: ['toggle'],
classNameBindings: ['isDisabled:is-disabled', 'isActive:is-active'],
+ 'data-test-label': true,
+
+ isActive: false,
+ isDisabled: false,
onToggle() {},
});
diff --git a/ui/app/templates/components/toggle.hbs b/ui/app/templates/components/toggle.hbs
index d0c46f69e..dbcf208df 100644
--- a/ui/app/templates/components/toggle.hbs
+++ b/ui/app/templates/components/toggle.hbs
@@ -1,8 +1,9 @@
-
+
{{yield}}
diff --git a/ui/tests/integration/toggle-test.js b/ui/tests/integration/toggle-test.js
new file mode 100644
index 000000000..e4ff27f3f
--- /dev/null
+++ b/ui/tests/integration/toggle-test.js
@@ -0,0 +1,89 @@
+import { find, settled } from '@ember/test-helpers';
+import { module, test } from 'qunit';
+import { setupRenderingTest } from 'ember-qunit';
+import hbs from 'htmlbars-inline-precompile';
+import sinon from 'sinon';
+import { create } from 'ember-cli-page-object';
+import togglePageObject from 'nomad-ui/tests/pages/components/toggle';
+
+const Toggle = create(togglePageObject());
+
+module('Integration | Component | toggle', function(hooks) {
+ setupRenderingTest(hooks);
+
+ const commonProperties = () => ({
+ isActive: false,
+ isDisabled: false,
+ label: 'Label',
+ onToggle: sinon.spy(),
+ });
+
+ const commonTemplate = hbs`
+ {{#toggle
+ isActive=isActive
+ isDisabled=isDisabled
+ onToggle=onToggle}}
+ {{label}}
+ {{/toggle}}
+ `;
+
+ test('presents as a label with an inner checkbox and display span, and text', async function(assert) {
+ const props = commonProperties();
+ this.setProperties(props);
+ await this.render(commonTemplate);
+
+ assert.equal(Toggle.label, props.label, `Label should be ${props.label}`);
+ assert.ok(Toggle.isPresent);
+ assert.notOk(Toggle.isActive);
+ assert.ok(find('[data-test-toggler]'));
+ assert.equal(
+ find('[data-test-input]').tagName.toLowerCase(),
+ 'input',
+ 'The input is a real HTML input'
+ );
+ assert.equal(
+ find('[data-test-input]').getAttribute('type'),
+ 'checkbox',
+ 'The input type is checkbox'
+ );
+ });
+
+ test('the isActive property dictates the active state and class', async function(assert) {
+ const props = commonProperties();
+ this.setProperties(props);
+ await this.render(commonTemplate);
+
+ assert.notOk(Toggle.isActive);
+ assert.notOk(Toggle.hasActiveClass);
+
+ this.set('isActive', true);
+ await settled();
+
+ assert.ok(Toggle.isActive);
+ assert.ok(Toggle.hasActiveClass);
+ });
+
+ test('the isDisabled property dictates the disabled state and class', async function(assert) {
+ const props = commonProperties();
+ this.setProperties(props);
+ await this.render(commonTemplate);
+
+ assert.notOk(Toggle.isDisabled);
+ assert.notOk(Toggle.hasDisabledClass);
+
+ this.set('isDisabled', true);
+ await settled();
+
+ assert.ok(Toggle.isDisabled);
+ assert.ok(Toggle.hasDisabledClass);
+ });
+
+ test('toggling the input calls the onToggle action', async function(assert) {
+ const props = commonProperties();
+ this.setProperties(props);
+ await this.render(commonTemplate);
+
+ await Toggle.toggle();
+ assert.equal(props.onToggle.callCount, 1);
+ });
+});
diff --git a/ui/tests/pages/components/toggle.js b/ui/tests/pages/components/toggle.js
new file mode 100644
index 000000000..a4f1f6e3f
--- /dev/null
+++ b/ui/tests/pages/components/toggle.js
@@ -0,0 +1,16 @@
+import { attribute, property, clickable, hasClass, isPresent, text } from 'ember-cli-page-object';
+
+export default scope => ({
+ scope,
+
+ isPresent: isPresent(),
+ isDisabled: attribute('disabled', '[data-test-input]'),
+ isActive: property('checked', '[data-test-input]'),
+
+ hasDisabledClass: hasClass('is-disabled', '[data-test-label]'),
+ hasActiveClass: hasClass('is-active', '[data-test-label]'),
+
+ label: text('[data-test-label]'),
+
+ toggle: clickable('[data-test-input]'),
+});