diff --git a/addons/api/.editorconfig b/addons/api/.editorconfig
index c35a00240..41302d1b0 100644
--- a/addons/api/.editorconfig
+++ b/addons/api/.editorconfig
@@ -12,8 +12,5 @@ insert_final_newline = true
indent_style = space
indent_size = 2
-[*.hbs]
-insert_final_newline = false
-
[*.{diff,md}]
trim_trailing_whitespace = false
diff --git a/addons/api/.eslintrc.js b/addons/api/.eslintrc.js
index 49fb14100..114c6817f 100644
--- a/addons/api/.eslintrc.js
+++ b/addons/api/.eslintrc.js
@@ -56,5 +56,10 @@ module.exports = {
plugins: ['node'],
extends: ['plugin:node/recommended'],
},
+ {
+ // Test files:
+ files: ['tests/**/*-test.{js,ts}'],
+ extends: ['plugin:qunit/recommended'],
+ },
],
};
diff --git a/addons/api/package.json b/addons/api/package.json
index 9ed30927e..17434703b 100644
--- a/addons/api/package.json
+++ b/addons/api/package.json
@@ -66,6 +66,7 @@
"eslint-plugin-ember": "^10.5.4",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^4.0.0",
+ "eslint-plugin-qunit": "^6.2.0",
"loader.js": "^4.7.0",
"npm-run-all": "^4.1.5",
"prettier": "^2.4.0",
@@ -73,7 +74,7 @@
"qunit-dom": "^2.0.0"
},
"engines": {
- "node": ">=10 <=15"
+ "node": ">=12 <=17"
},
"ember": {
"edition": "octane"
diff --git a/addons/api/tests/unit/models/base-test.js b/addons/api/tests/unit/models/base-test.js
index 228f47782..8e320cfdf 100644
--- a/addons/api/tests/unit/models/base-test.js
+++ b/addons/api/tests/unit/models/base-test.js
@@ -47,7 +47,7 @@ module('Unit | Model | base', function (hooks) {
assert.notEqual(model.scopeID, scope.id);
model.scopeModel = scope;
assert.equal(model.scopeID, scope.id);
- assert.equal(model.scope.isOrg, true);
+ assert.true(model.scope.isOrg);
});
test('it has a displayName attribute', function (assert) {
@@ -78,18 +78,18 @@ module('Unit | Model | base', function (hooks) {
},
});
const model = store.peekRecord('user', '1');
- assert.equal(model.canSave, false);
- assert.equal(model.cannotSave, true);
+ assert.false(model.canSave);
+ assert.true(model.cannotSave);
// Should be able to save if dirty
model.name = 'User';
- assert.equal(model.hasDirtyAttributes, true);
- assert.equal(model.canSave, true);
- assert.equal(model.cannotSave, false);
+ assert.true(model.hasDirtyAttributes);
+ assert.true(model.canSave);
+ assert.false(model.cannotSave);
// Should not be able to save while currently saving
model.transitionTo('updated.inFlight');
- assert.equal(model.isSaving, true);
- assert.equal(model.canSave, false);
- assert.equal(model.cannotSave, true);
+ assert.true(model.isSaving);
+ assert.false(model.canSave);
+ assert.true(model.cannotSave);
model.transitionTo('loaded');
});
diff --git a/addons/api/tests/unit/services/storage-test.js b/addons/api/tests/unit/services/storage-test.js
index 61702c765..5b955dc21 100644
--- a/addons/api/tests/unit/services/storage-test.js
+++ b/addons/api/tests/unit/services/storage-test.js
@@ -30,7 +30,7 @@ module('Unit | Service | storage', function (hooks) {
assert.equal(service.getItem('foo'), 'bar');
});
- test("it's in-memory storage is implicitly refreshed for every test case", function (assert) {
+ test("it's in-memory storage is implicitly refreshed for every test case, and thus values from previous runs are not present", function (assert) {
assert.expect(1);
const service = this.owner.lookup('service:storage');
assert.notOk(service.getItem('foo'));
diff --git a/addons/auth/.editorconfig b/addons/auth/.editorconfig
index c35a00240..41302d1b0 100644
--- a/addons/auth/.editorconfig
+++ b/addons/auth/.editorconfig
@@ -12,8 +12,5 @@ insert_final_newline = true
indent_style = space
indent_size = 2
-[*.hbs]
-insert_final_newline = false
-
[*.{diff,md}]
trim_trailing_whitespace = false
diff --git a/addons/auth/.eslintrc.js b/addons/auth/.eslintrc.js
index 49fb14100..114c6817f 100644
--- a/addons/auth/.eslintrc.js
+++ b/addons/auth/.eslintrc.js
@@ -56,5 +56,10 @@ module.exports = {
plugins: ['node'],
extends: ['plugin:node/recommended'],
},
+ {
+ // Test files:
+ files: ['tests/**/*-test.{js,ts}'],
+ extends: ['plugin:qunit/recommended'],
+ },
],
};
diff --git a/addons/auth/package.json b/addons/auth/package.json
index 462c1a970..531137952 100644
--- a/addons/auth/package.json
+++ b/addons/auth/package.json
@@ -58,6 +58,7 @@
"eslint-plugin-ember": "^10.5.4",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^4.0.0",
+ "eslint-plugin-qunit": "^6.2.0",
"loader.js": "^4.7.0",
"npm-run-all": "^4.1.5",
"prettier": "^2.4.0",
@@ -65,7 +66,7 @@
"qunit-dom": "^2.0.0"
},
"engines": {
- "node": ">=10 <=15"
+ "node": ">=12 <=17"
},
"ember": {
"edition": "octane"
diff --git a/addons/core/.editorconfig b/addons/core/.editorconfig
index c35a00240..41302d1b0 100644
--- a/addons/core/.editorconfig
+++ b/addons/core/.editorconfig
@@ -12,8 +12,5 @@ insert_final_newline = true
indent_style = space
indent_size = 2
-[*.hbs]
-insert_final_newline = false
-
[*.{diff,md}]
trim_trailing_whitespace = false
diff --git a/addons/core/.eslintrc.js b/addons/core/.eslintrc.js
index 49fb14100..114c6817f 100644
--- a/addons/core/.eslintrc.js
+++ b/addons/core/.eslintrc.js
@@ -56,5 +56,10 @@ module.exports = {
plugins: ['node'],
extends: ['plugin:node/recommended'],
},
+ {
+ // Test files:
+ files: ['tests/**/*-test.{js,ts}'],
+ extends: ['plugin:qunit/recommended'],
+ },
],
};
diff --git a/addons/core/package.json b/addons/core/package.json
index 199973f38..03c494d89 100644
--- a/addons/core/package.json
+++ b/addons/core/package.json
@@ -72,6 +72,7 @@
"eslint-plugin-ember": "^10.5.4",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^4.0.0",
+ "eslint-plugin-qunit": "^6.2.0",
"faker": "^5.5.3",
"loader.js": "^4.7.0",
"npm-run-all": "^4.1.5",
@@ -80,7 +81,7 @@
"qunit-dom": "^2.0.0"
},
"engines": {
- "node": ">=10 <=15"
+ "node": ">=12 <=17"
},
"ember": {
"edition": "octane"
diff --git a/addons/rose/.editorconfig b/addons/rose/.editorconfig
index c35a00240..41302d1b0 100644
--- a/addons/rose/.editorconfig
+++ b/addons/rose/.editorconfig
@@ -12,8 +12,5 @@ insert_final_newline = true
indent_style = space
indent_size = 2
-[*.hbs]
-insert_final_newline = false
-
[*.{diff,md}]
trim_trailing_whitespace = false
diff --git a/addons/rose/.eslintrc.js b/addons/rose/.eslintrc.js
index bdb867ae9..46de42474 100644
--- a/addons/rose/.eslintrc.js
+++ b/addons/rose/.eslintrc.js
@@ -58,5 +58,10 @@ module.exports = {
plugins: ['node'],
extends: ['plugin:node/recommended'],
},
+ {
+ // Test files:
+ files: ['tests/**/*-test.{js,ts}'],
+ extends: ['plugin:qunit/recommended'],
+ },
],
};
diff --git a/addons/rose/package.json b/addons/rose/package.json
index 7c654b351..b84a76425 100644
--- a/addons/rose/package.json
+++ b/addons/rose/package.json
@@ -81,6 +81,7 @@
"eslint-plugin-ember": "^10.5.4",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^4.0.0",
+ "eslint-plugin-qunit": "^6.2.0",
"loader.js": "^4.7.0",
"npm-run-all": "^4.1.5",
"prettier": "^2.4.0",
@@ -92,7 +93,7 @@
"sass-lint": "^1.13.1"
},
"engines": {
- "node": ">=10 <=15"
+ "node": ">=12 <=17"
},
"ember": {
"edition": "octane"
diff --git a/addons/rose/tests/integration/components/rose/badge-test.js b/addons/rose/tests/integration/components/rose/badge-test.js
index 56810d21b..96ff69f08 100644
--- a/addons/rose/tests/integration/components/rose/badge-test.js
+++ b/addons/rose/tests/integration/components/rose/badge-test.js
@@ -22,6 +22,7 @@ module('Integration | Component | rose/badge', function (hooks) {
});
test('it styles content using @style', async function (assert) {
+ assert.expect(14);
let styles = [
'outline',
'dark',
diff --git a/addons/rose/tests/integration/components/rose/button-test.js b/addons/rose/tests/integration/components/rose/button-test.js
index 90cc10589..e5a685be5 100644
--- a/addons/rose/tests/integration/components/rose/button-test.js
+++ b/addons/rose/tests/integration/components/rose/button-test.js
@@ -23,7 +23,7 @@ module('Integration | Component | rose/button', function (hooks) {
test('it is disabled when @disabled={{true}}', async function (assert) {
await render(hbs``);
- assert.equal(find('button').disabled, true);
+ assert.true(find('button').disabled);
});
test('it adds a style class', async function (assert) {
diff --git a/addons/rose/tests/integration/components/rose/dropdown/button-test.js b/addons/rose/tests/integration/components/rose/dropdown/button-test.js
index b0bd48eb5..92129e5a7 100644
--- a/addons/rose/tests/integration/components/rose/dropdown/button-test.js
+++ b/addons/rose/tests/integration/components/rose/dropdown/button-test.js
@@ -23,7 +23,7 @@ module('Integration | Component | rose/dropdown/button', function (hooks) {
test('it is disabled when @disabled={{true}}', async function (assert) {
await render(hbs``);
- assert.equal(find('button').disabled, true);
+ assert.true(find('button').disabled);
});
test('it adds a style class', async function (assert) {
diff --git a/addons/rose/tests/integration/components/rose/form/checkbox-test.js b/addons/rose/tests/integration/components/rose/form/checkbox-test.js
index 594704918..cd131f0b1 100644
--- a/addons/rose/tests/integration/components/rose/form/checkbox-test.js
+++ b/addons/rose/tests/integration/components/rose/form/checkbox-test.js
@@ -60,17 +60,17 @@ module('Integration | Component | rose/form/checkbox', function (hooks) {
test('it is not checked by default', async function (assert) {
await render(hbs``);
- assert.equal(find('input').checked, false);
+ assert.false(find('input').checked);
});
test('it is not disabled by default', async function (assert) {
await render(hbs``);
- assert.equal(find('input').disabled, false);
+ assert.false(find('input').disabled);
});
test('it is checked when @checked={{true}}', async function (assert) {
await render(hbs``);
- assert.equal(find('input').checked, true);
+ assert.true(find('input').checked);
});
test('it marks error when @error={{true}}', async function (assert) {
@@ -80,6 +80,6 @@ module('Integration | Component | rose/form/checkbox', function (hooks) {
test('it is disabled when @disabled={{true}}', async function (assert) {
await render(hbs``);
- assert.equal(find('input').disabled, true);
+ assert.true(find('input').disabled);
});
});
diff --git a/addons/rose/tests/integration/components/rose/form/radio/group-test.js b/addons/rose/tests/integration/components/rose/form/radio/group-test.js
index dfd2e4bce..4354004e7 100644
--- a/addons/rose/tests/integration/components/rose/form/radio/group-test.js
+++ b/addons/rose/tests/integration/components/rose/form/radio/group-test.js
@@ -43,13 +43,13 @@ module('Integration | Component | rose/form/radio/group', function (hooks) {
`);
- assert.equal(findAll('[type="radio"]')[0].checked, false);
- assert.equal(findAll('[type="radio"]')[1].checked, true);
+ assert.false(findAll('[type="radio"]')[0].checked);
+ assert.true(findAll('[type="radio"]')[1].checked);
await click(findAll('[type="radio"]')[0]);
- assert.equal(findAll('[type="radio"]')[0].checked, true);
- assert.equal(findAll('[type="radio"]')[1].checked, false);
+ assert.true(findAll('[type="radio"]')[0].checked);
+ assert.false(findAll('[type="radio"]')[1].checked);
});
test('it reflects active radiofield value in @selectedValue and triggers a @changed function', async function (assert) {
@@ -100,19 +100,19 @@ module('Integration | Component | rose/form/radio/group', function (hooks) {
`);
- assert.equal(findAll('[type="radio"]')[0].checked, false);
- assert.equal(findAll('[type="radio"]')[1].checked, false);
+ assert.false(findAll('[type="radio"]')[0].checked);
+ assert.false(findAll('[type="radio"]')[1].checked);
this.set('selectedValue', 'flamingo');
- assert.equal(findAll('[type="radio"]')[0].checked, false);
- assert.equal(findAll('[type="radio"]')[1].checked, true);
+ assert.false(findAll('[type="radio"]')[0].checked);
+ assert.true(findAll('[type="radio"]')[1].checked);
this.set('selectedValue', 'pegion');
- assert.equal(findAll('[type="radio"]')[0].checked, true);
- assert.equal(findAll('[type="radio"]')[1].checked, false);
+ assert.true(findAll('[type="radio"]')[0].checked);
+ assert.false(findAll('[type="radio"]')[1].checked);
this.set('selectedValue', 'dog');
- assert.equal(findAll('[type="radio"]')[0].checked, false);
- assert.equal(findAll('[type="radio"]')[1].checked, false);
+ assert.false(findAll('[type="radio"]')[0].checked);
+ assert.false(findAll('[type="radio"]')[1].checked);
});
});
diff --git a/addons/rose/tests/integration/components/rose/form/radio/radio-test.js b/addons/rose/tests/integration/components/rose/form/radio/radio-test.js
index 56c8caebc..af0be8d54 100644
--- a/addons/rose/tests/integration/components/rose/form/radio/radio-test.js
+++ b/addons/rose/tests/integration/components/rose/form/radio/radio-test.js
@@ -28,25 +28,25 @@ module('Integration | Component | rose/form/radio/radio', function (hooks) {
await render(
hbs``
);
- assert.equal(await find('input').checked, true);
+ assert.true(await find('input').checked);
});
test('it is not checked when @value and @selectedValue values are different', async function (assert) {
await render(hbs``);
- assert.equal(await find('input').checked, false);
+ assert.false(await find('input').checked);
await render(hbs``);
- assert.equal(await find('input').checked, false);
+ assert.false(await find('input').checked);
await render(
hbs``
);
- assert.equal(await find('input').checked, false);
+ assert.false(await find('input').checked);
});
test('it is not disabled by default', async function (assert) {
await render(hbs``);
- assert.equal(await find('input').disabled, false);
+ assert.false(await find('input').disabled);
});
test('it is not in error state by default', async function (assert) {
@@ -56,7 +56,7 @@ module('Integration | Component | rose/form/radio/radio', function (hooks) {
test('it is disabled when @disabled={{true}}', async function (assert) {
await render(hbs``);
- assert.equal(await find('input').disabled, true);
+ assert.true(await find('input').disabled);
});
test('it is in error state when @error={{true}}', async function (assert) {
diff --git a/addons/rose/tests/integration/modifiers/on-click-outside-test.js b/addons/rose/tests/integration/modifiers/on-click-outside-test.js
index 7318ef423..294134263 100644
--- a/addons/rose/tests/integration/modifiers/on-click-outside-test.js
+++ b/addons/rose/tests/integration/modifiers/on-click-outside-test.js
@@ -7,6 +7,7 @@ module('Integration | Modifier | on-click-outside', function (hooks) {
setupRenderingTest(hooks);
test('it fires event when an outside element is clicked', async function (assert) {
+ assert.expect(2);
this.set('clickedOutside', (element, event) => {
assert.ok(element);
assert.equal(event.target.id, 'outside');
diff --git a/package.json b/package.json
index cef044455..275cf5d0a 100755
--- a/package.json
+++ b/package.json
@@ -89,6 +89,6 @@
}
},
"engines": {
- "node": ">=10 <=15"
+ "node": ">=12 <=17"
}
}
diff --git a/ui/admin/.editorconfig b/ui/admin/.editorconfig
index c35a00240..41302d1b0 100644
--- a/ui/admin/.editorconfig
+++ b/ui/admin/.editorconfig
@@ -12,8 +12,5 @@ insert_final_newline = true
indent_style = space
indent_size = 2
-[*.hbs]
-insert_final_newline = false
-
[*.{diff,md}]
trim_trailing_whitespace = false
diff --git a/ui/admin/.eslintrc.js b/ui/admin/.eslintrc.js
index 5062441ff..c926d2400 100644
--- a/ui/admin/.eslintrc.js
+++ b/ui/admin/.eslintrc.js
@@ -55,5 +55,10 @@ module.exports = {
'node/no-unpublished-require': 'off',
},
},
+ {
+ // Test files:
+ files: ['tests/**/*-test.{js,ts}'],
+ extends: ['plugin:qunit/recommended'],
+ },
],
};
diff --git a/ui/admin/package.json b/ui/admin/package.json
index 9ff71681b..61d9ff33c 100644
--- a/ui/admin/package.json
+++ b/ui/admin/package.json
@@ -51,7 +51,7 @@
"ember-a11y-testing": "^4.2.0",
"ember-auto-import": "^1.12.0",
"ember-breadcrumbs": "^0.2.3",
- "ember-cli": "~3.28.0",
+ "ember-cli": "~3.28.3",
"ember-cli-app-version": "^5.0.0",
"ember-cli-babel": "^7.26.6",
"ember-cli-code-coverage": "^1.0.3",
@@ -82,6 +82,7 @@
"eslint-plugin-ember": "^10.5.4",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^4.0.0",
+ "eslint-plugin-qunit": "^6.2.0",
"faker": "^5.5.3",
"loader.js": "^4.7.0",
"npm-run-all": "^4.1.5",
@@ -94,7 +95,7 @@
"sinon": "^11.1.2"
},
"engines": {
- "node": ">=10 <=15"
+ "node": ">=12 <=17"
},
"ember": {
"edition": "octane"
diff --git a/ui/admin/tests/acceptance/accounts/create-test.js b/ui/admin/tests/acceptance/accounts/create-test.js
index e68e69695..e852a5b64 100644
--- a/ui/admin/tests/acceptance/accounts/create-test.js
+++ b/ui/admin/tests/acceptance/accounts/create-test.js
@@ -150,12 +150,12 @@ module('Acceptance | accounts | create', function (hooks) {
await fillIn('[name="name"]', 'new account');
await click('form [type="submit"]');
await a11yAudit();
- assert.ok(
- find('[role="alert"]').textContent.trim(),
+ assert.equal(
+ find('.rose-notification-body').textContent.trim(),
'The request was invalid.',
'Displays primary error message.'
);
- assert.ok(
+ assert.equal(
find('.rose-form-error-message').textContent.trim(),
'Name is required.',
'Displays field-level errors.'
diff --git a/ui/admin/tests/acceptance/accounts/delete-test.js b/ui/admin/tests/acceptance/accounts/delete-test.js
index 8b78b1834..da71a395a 100644
--- a/ui/admin/tests/acceptance/accounts/delete-test.js
+++ b/ui/admin/tests/acceptance/accounts/delete-test.js
@@ -93,8 +93,8 @@ module('Acceptance | accounts | delete', function (hooks) {
await visit(urls.account);
await click('.rose-layout-page-actions .rose-dropdown-button-danger');
await a11yAudit();
- assert.ok(
- find('[role="alert"]').textContent.trim(),
+ assert.equal(
+ find('.rose-notification-body').textContent.trim(),
'Oops.',
'Displays primary error message.'
);
diff --git a/ui/admin/tests/acceptance/accounts/set-password-test.js b/ui/admin/tests/acceptance/accounts/set-password-test.js
index 89f9ce3e7..67939ab83 100644
--- a/ui/admin/tests/acceptance/accounts/set-password-test.js
+++ b/ui/admin/tests/acceptance/accounts/set-password-test.js
@@ -100,13 +100,13 @@ module('Acceptance | accounts | set password', function (hooks) {
// NOTE: since set password is a tabbed route with easy navigation away
// from the form, and the form does not directly operate on a model instance,
// a "cancel" flow doesn't make much sense. Disabling for now.
- // test('can cancel setting new password', async function (assert) {
- // assert.expect(1);
- // await visit(urls.setPassword);
- // await fillIn('[name="password"]', 'update password');
- // await click('form button:not([type="submit"])');
- // assert.notOk(find('[name="password"]').textContent.trim());
- // });
+ test.skip('can cancel setting new password', async function (assert) {
+ assert.expect(1);
+ await visit(urls.setPassword);
+ await fillIn('[name="password"]', 'update password');
+ await click('form button:not([type="submit"])');
+ assert.notOk(find('[name="password"]').textContent.trim());
+ });
test('errors are displayed when setting password fails', async function (assert) {
assert.expect(1);
diff --git a/ui/admin/tests/acceptance/accounts/update-test.js b/ui/admin/tests/acceptance/accounts/update-test.js
index 163b7ac9e..139beeccf 100644
--- a/ui/admin/tests/acceptance/accounts/update-test.js
+++ b/ui/admin/tests/acceptance/accounts/update-test.js
@@ -103,8 +103,8 @@ module('Acceptance | accounts | update', function (hooks) {
await fillIn('[name="name"]', 'save account');
await click('form [type="submit"]');
await a11yAudit();
- assert.ok(
- find('[role="alert"]').textContent.trim(),
+ assert.equal(
+ find('.rose-notification-body').textContent.trim(),
'Oops.',
'Displays primary error message.'
);
@@ -136,12 +136,12 @@ module('Acceptance | accounts | update', function (hooks) {
await fillIn('[name="name"]', 'existing account');
await click('form [type="submit"]');
await a11yAudit();
- assert.ok(
- find('[role="alert"]').textContent.trim(),
+ assert.equal(
+ find('.rose-notification-body').textContent.trim(),
'The request was invalid.',
'Displays primary error message.'
);
- assert.ok(
+ assert.equal(
find('.rose-form-error-message').textContent.trim(),
'Name is required.',
'Displays field-level errors.'
diff --git a/ui/admin/tests/acceptance/auth-methods/delete-test.js b/ui/admin/tests/acceptance/auth-methods/delete-test.js
index f80721f37..d2f32c18e 100644
--- a/ui/admin/tests/acceptance/auth-methods/delete-test.js
+++ b/ui/admin/tests/acceptance/auth-methods/delete-test.js
@@ -72,8 +72,8 @@ module('Acceptance | auth methods | delete', function (hooks) {
await visit(urls.authMethod);
await click('.rose-layout-page-actions .rose-dropdown-button-danger');
await a11yAudit();
- assert.ok(
- find('[role="alert"]').textContent.trim(),
+ assert.equal(
+ find('.rose-notification-body').textContent.trim(),
'Oops.',
'Displays primary error message.'
);
diff --git a/ui/admin/tests/acceptance/auth-methods/oidc-test.js b/ui/admin/tests/acceptance/auth-methods/oidc-test.js
index 3bc1f226b..ab37b1d62 100644
--- a/ui/admin/tests/acceptance/auth-methods/oidc-test.js
+++ b/ui/admin/tests/acceptance/auth-methods/oidc-test.js
@@ -102,38 +102,38 @@ module('Acceptance | auth methods | oidc', function (hooks) {
});
// FIXME: How to mock just one request routed to /auth-methods and let everything else passthrough?
- // test('errors are displayed when state update fails', async function (assert) {
- // assert.expect(2);
- // this.server.post('/auth-methods/:idMethod', (_, request) => {
- // // Only respond to state update with error
- // if (request.params.idMethod.match(/(change-state)/i)) {
- // return new Response(
- // 400,
- // {},
- // {
- // status: 400,
- // code: 'error',
- // message: 'Sorry!',
- // }
- // );
- // }
- // return request;
- // });
- // const newState = 'inactive';
- // await visit(urls.authMethod);
- // await click('.rose-layout-page-actions .rose-dropdown-trigger');
- // await click(`.rose-dropdown[open] input[value="${newState}"]`);
- // // debugger;
- // const authMethod = this.server.db.authMethods.find(instances.authMethod.id);
- // assert.notEqual(
- // newState,
- // authMethod.attributes.state,
- // 'Auth method state is not be updated.'
- // );
- // assert.ok(
- // find('[role="alert"]').textContent.trim(),
- // 'Sorry!',
- // 'Displays error message.'
- // );
- // });
+ test.skip('errors are displayed when state update fails', async function (assert) {
+ assert.expect(2);
+ this.server.post('/auth-methods/:idMethod', (_, request) => {
+ // Only respond to state update with error
+ if (request.params.idMethod.match(/(change-state)/i)) {
+ return new Response(
+ 400,
+ {},
+ {
+ status: 400,
+ code: 'error',
+ message: 'Sorry!',
+ }
+ );
+ }
+ return request;
+ });
+ const newState = 'inactive';
+ await visit(urls.authMethod);
+ await click('.rose-layout-page-actions .rose-dropdown-trigger');
+ await click(`.rose-dropdown[open] input[value="${newState}"]`);
+ // debugger;
+ const authMethod = this.server.db.authMethods.find(instances.authMethod.id);
+ assert.notEqual(
+ newState,
+ authMethod.attributes.state,
+ 'Auth method state is not be updated.'
+ );
+ assert.ok(
+ find('.rose-notification-body').textContent.trim(),
+ 'Sorry!',
+ 'Displays error message.'
+ );
+ });
});
diff --git a/ui/admin/tests/acceptance/auth-methods/update-test.js b/ui/admin/tests/acceptance/auth-methods/update-test.js
index 8060e4382..859b0ae57 100644
--- a/ui/admin/tests/acceptance/auth-methods/update-test.js
+++ b/ui/admin/tests/acceptance/auth-methods/update-test.js
@@ -102,50 +102,12 @@ module('Acceptance | auth methods | update', function (hooks) {
await fillIn('[name="name"]', 'existing auth method');
await click('form [type="submit"]');
await a11yAudit();
- assert.ok(
- find('[role="alert"]').textContent.trim(),
+ assert.equal(
+ find('.rose-notification-body').textContent.trim(),
'The request was invalid.',
'Displays primary error message.'
);
- assert.ok(
- find('.rose-form-error-message').textContent.trim(),
- 'Name is required.',
- 'Displays field-level errors.'
- );
- });
-
- test('saving an existing auth method with invalid fields displays error messages', async function (assert) {
- assert.expect(2);
- this.server.patch('/auth-methods/:id', () => {
- return new Response(
- 400,
- {},
- {
- status: 400,
- code: 'invalid_argument',
- message: 'The request was invalid.',
- details: {
- request_fields: [
- {
- name: 'name',
- description: 'Name is required.',
- },
- ],
- },
- }
- );
- });
- await visit(urls.authMethod);
- await click('form [type="button"]', 'Activate edit mode');
- await fillIn('[name="name"]', 'existing auth method');
- await click('form [type="submit"]');
- await a11yAudit();
- assert.ok(
- find('[role="alert"]').textContent.trim(),
- 'The request was invalid.',
- 'Displays primary error message.'
- );
- assert.ok(
+ assert.equal(
find('.rose-form-error-message').textContent.trim(),
'Name is required.',
'Displays field-level errors.'
diff --git a/ui/admin/tests/acceptance/authentication-test.js b/ui/admin/tests/acceptance/authentication-test.js
index f42540f4f..3c1cedd48 100644
--- a/ui/admin/tests/acceptance/authentication-test.js
+++ b/ui/admin/tests/acceptance/authentication-test.js
@@ -5,7 +5,7 @@ import {
fillIn,
click,
find,
- //findAll,
+ findAll,
getRootElement,
//setupOnerror,
} from '@ember/test-helpers';
@@ -300,23 +300,23 @@ module('Acceptance | authentication', function (hooks) {
// This test is disabled because it is no longer relevant. On deauth,
// the page is reloaded. If the user was viewing a route requiring
// authentication, they will be redirected accordingly.
- // test('deauthentication redirects to first global authenticate method', async function (assert) {
- // assert.expect(3);
- // await visit(authMethodAuthenticateURL);
- // await fillIn('[name="identification"]', 'test');
- // await fillIn('[name="password"]', 'test');
- // await click('[type="submit"]');
- // assert.ok(currentSession().isAuthenticated);
- // // Open header utilities dropdown
- // await click('.rose-header-utilities .rose-dropdown summary');
- // // Find and click on last element in dropdown - should be deauthenticate button
- // const menu = findAll(
- // '.rose-header-utilities .rose-dropdown .rose-dropdown-content button'
- // );
- // await click(menu[menu.length - 1]);
- // assert.notOk(currentSession().isAuthenticated);
- // assert.equal(currentURL(), authMethodGlobalAuthenticateURL);
- // });
+ test.skip('deauthentication redirects to first global authenticate method', async function (assert) {
+ assert.expect(3);
+ await visit(authMethodAuthenticateURL);
+ await fillIn('[name="identification"]', 'test');
+ await fillIn('[name="password"]', 'test');
+ await click('[type="submit"]');
+ assert.ok(currentSession().isAuthenticated);
+ // Open header utilities dropdown
+ await click('.rose-header-utilities .rose-dropdown summary');
+ // Find and click on last element in dropdown - should be deauthenticate button
+ const menu = findAll(
+ '.rose-header-utilities .rose-dropdown .rose-dropdown-content button'
+ );
+ await click(menu[menu.length - 1]);
+ assert.notOk(currentSession().isAuthenticated);
+ assert.equal(currentURL(), authMethodGlobalAuthenticateURL);
+ });
test('401 responses result in deauthentication', async function (assert) {
assert.expect(2);
diff --git a/ui/admin/tests/acceptance/groups/create-test.js b/ui/admin/tests/acceptance/groups/create-test.js
index 815e4a760..d3cc5fffb 100644
--- a/ui/admin/tests/acceptance/groups/create-test.js
+++ b/ui/admin/tests/acceptance/groups/create-test.js
@@ -109,12 +109,12 @@ module('Acceptance | groups | create', function (hooks) {
await visit(urls.newGroup);
await fillIn('[name="name"]', 'group name');
await click('[type="submit"]');
- assert.ok(
- find('[role="alert"]').textContent.trim(),
+ assert.equal(
+ find('.rose-notification-body').textContent.trim(),
'The request was invalid.',
'Displays primary error message.'
);
- assert.ok(
+ assert.equal(
find('.rose-form-error-message').textContent.trim(),
'Name is required.',
'Displays field-level errors.'
diff --git a/ui/admin/tests/acceptance/groups/delete-test.js b/ui/admin/tests/acceptance/groups/delete-test.js
index c1dec7fdb..58f7498b1 100644
--- a/ui/admin/tests/acceptance/groups/delete-test.js
+++ b/ui/admin/tests/acceptance/groups/delete-test.js
@@ -76,8 +76,8 @@ module('Acceptance | groups | delete', function (hooks) {
});
await visit(urls.group);
await click('.rose-layout-page-actions .rose-dropdown-button-danger');
- assert.ok(
- find('[role="alert"]').textContent.trim(),
+ assert.equal(
+ find('.rose-notification-body').textContent.trim(),
'Oops.',
'Displays primary error message.'
);
diff --git a/ui/admin/tests/acceptance/groups/update-test.js b/ui/admin/tests/acceptance/groups/update-test.js
index 6d39cefbe..696a88e48 100644
--- a/ui/admin/tests/acceptance/groups/update-test.js
+++ b/ui/admin/tests/acceptance/groups/update-test.js
@@ -95,12 +95,12 @@ module('Acceptance | groups | update', function (hooks) {
await click('form [type="button"]', 'Activate edit mode');
await fillIn('[name="name"]', 'random string');
await click('[type="submit"]');
- assert.ok(
- find('[role="alert"]').textContent.trim(),
+ assert.equal(
+ find('.rose-notification-body').textContent.trim(),
'The request was invalid.',
'Displays primary error message.'
);
- assert.ok(
+ assert.equal(
find('.rose-form-error-message').textContent.trim(),
'Name is required.',
'Displays field-level errors.'
diff --git a/ui/admin/tests/acceptance/roles/delete-test.js b/ui/admin/tests/acceptance/roles/delete-test.js
index a965ff63a..ba0363e1d 100644
--- a/ui/admin/tests/acceptance/roles/delete-test.js
+++ b/ui/admin/tests/acceptance/roles/delete-test.js
@@ -88,8 +88,8 @@ module('Acceptance | roles | delete', function (hooks) {
});
await visit(urls.role);
await click('.rose-layout-page-actions .rose-dropdown-button-danger');
- assert.ok(
- find('[role="alert"]').textContent.trim(),
+ assert.equal(
+ find('.rose-notification-body').textContent.trim(),
'Oops.',
'Displays primary error message.'
);
diff --git a/ui/admin/tests/acceptance/roles/update-test.js b/ui/admin/tests/acceptance/roles/update-test.js
index 21737c705..aca161a54 100644
--- a/ui/admin/tests/acceptance/roles/update-test.js
+++ b/ui/admin/tests/acceptance/roles/update-test.js
@@ -107,12 +107,12 @@ module('Acceptance | roles | update', function (hooks) {
await click('form [type="button"]', 'Activate edit mode');
await fillIn('[name="name"]', 'random string');
await click('[type="submit"]');
- assert.ok(
- find('[role="alert"]').textContent.trim(),
+ assert.equal(
+ find('.rose-notification-body').textContent.trim(),
'The request was invalid.',
'Displays primary error message.'
);
- assert.ok(
+ assert.equal(
find('.rose-form-error-message').textContent.trim(),
'Name is required.',
'Displays field-level errors.'
diff --git a/ui/admin/tests/acceptance/users/create-test.js b/ui/admin/tests/acceptance/users/create-test.js
index b69a1f3df..12261e9f5 100644
--- a/ui/admin/tests/acceptance/users/create-test.js
+++ b/ui/admin/tests/acceptance/users/create-test.js
@@ -97,12 +97,12 @@ module('Acceptance | users | create', function (hooks) {
await visit(newUserURL);
await fillIn('[name="name"]', 'User name');
await click('[type="submit"]');
- assert.ok(
- find('[role="alert"]').textContent.trim(),
+ assert.equal(
+ find('.rose-notification-body').textContent.trim(),
'The request was invalid.',
'Displays primary error message.'
);
- assert.ok(
+ assert.equal(
find('.rose-form-error-message').textContent.trim(),
'Name is required.',
'Displays field-level errors.'
diff --git a/ui/admin/tests/acceptance/users/delete-test.js b/ui/admin/tests/acceptance/users/delete-test.js
index 14b5371fc..2146278f6 100644
--- a/ui/admin/tests/acceptance/users/delete-test.js
+++ b/ui/admin/tests/acceptance/users/delete-test.js
@@ -77,8 +77,8 @@ module('Acceptance | users | delete', function (hooks) {
});
await visit(userURL);
await click('.rose-layout-page-actions .rose-dropdown-button-danger');
- assert.ok(
- find('[role="alert"]').textContent.trim(),
+ assert.equal(
+ find('.rose-notification-body').textContent.trim(),
'Oops.',
'Displays primary error message.'
);
diff --git a/ui/admin/tests/acceptance/users/update-test.js b/ui/admin/tests/acceptance/users/update-test.js
index 931a58641..f7f448156 100644
--- a/ui/admin/tests/acceptance/users/update-test.js
+++ b/ui/admin/tests/acceptance/users/update-test.js
@@ -96,12 +96,12 @@ module('Acceptance | users | update', function (hooks) {
await click('form [type="button"]', 'Activate edit mode');
await fillIn('[name="name"]', 'User name');
await click('[type="submit"]');
- assert.ok(
- find('[role="alert"]').textContent.trim(),
+ assert.equal(
+ find('.rose-notification-body').textContent.trim(),
'The request was invalid.',
'Displays primary error message.'
);
- assert.ok(
+ assert.equal(
find('.rose-form-error-message').textContent.trim(),
'Name is required.',
'Displays field-level errors.'
diff --git a/ui/desktop/.editorconfig b/ui/desktop/.editorconfig
index c35a00240..41302d1b0 100644
--- a/ui/desktop/.editorconfig
+++ b/ui/desktop/.editorconfig
@@ -12,8 +12,5 @@ insert_final_newline = true
indent_style = space
indent_size = 2
-[*.hbs]
-insert_final_newline = false
-
[*.{diff,md}]
trim_trailing_whitespace = false
diff --git a/ui/desktop/.eslintrc.js b/ui/desktop/.eslintrc.js
index 6d20176b1..44c31c752 100644
--- a/ui/desktop/.eslintrc.js
+++ b/ui/desktop/.eslintrc.js
@@ -56,5 +56,10 @@ module.exports = {
'node/no-unpublished-require': 'off',
},
},
+ {
+ // Test files:
+ files: ['tests/**/*-test.{js,ts}'],
+ extends: ['plugin:qunit/recommended'],
+ },
],
};
diff --git a/ui/desktop/package.json b/ui/desktop/package.json
index 590e92035..c3980a942 100755
--- a/ui/desktop/package.json
+++ b/ui/desktop/package.json
@@ -72,7 +72,7 @@
"ember-a11y-testing": "^4.2.0",
"ember-auto-import": "^1.12.0",
"ember-autofocus-modifier": "^2.0.0",
- "ember-cli": "~3.28.0",
+ "ember-cli": "~3.28.3",
"ember-cli-app-version": "^5.0.0",
"ember-cli-babel": "^7.26.6",
"ember-cli-code-coverage": "^1.0.3",
@@ -103,6 +103,7 @@
"eslint-plugin-ember": "^10.5.4",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^4.0.0",
+ "eslint-plugin-qunit": "^6.2.0",
"faker": "^5.5.3",
"loader.js": "^4.7.0",
"npm-run-all": "^4.1.5",
@@ -117,7 +118,7 @@
"stylelint-config-sass-guidelines": "^8.0.0"
},
"engines": {
- "node": ">=10 <=15"
+ "node": ">=12 <=17"
},
"ember": {
"edition": "octane"
diff --git a/ui/desktop/tests/unit/services/ipc-test.js b/ui/desktop/tests/unit/services/ipc-test.js
index d193074c5..2e3ab6ae3 100644
--- a/ui/desktop/tests/unit/services/ipc-test.js
+++ b/ui/desktop/tests/unit/services/ipc-test.js
@@ -73,7 +73,7 @@ module('Unit | Service | ipc', function (hooks) {
});
});
- test('IPCRequests reject if receiving an Error instance, where the rejection value is the parsed JSON Error message', async (assert) => {
+ test('IPCRequests reject if receiving an Error instance, where the rejection value is the parsed JSON Error message', async function (assert) {
assert.expect(1);
const stringifiedPayload = JSON.stringify({
foo: 'bar',
diff --git a/yarn.lock b/yarn.lock
index 462c131b0..660c765b2 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -9959,6 +9959,103 @@ ember-cli@~3.28.0:
workerpool "^6.1.4"
yam "^1.0.0"
+ember-cli@~3.28.3:
+ version "3.28.3"
+ resolved "https://registry.yarnpkg.com/ember-cli/-/ember-cli-3.28.3.tgz#3384c3fb018b58111e30efed15a2f6a9b66b84c3"
+ integrity sha512-DddAQAddbyaOU4NAjTt8g+FoCCK/F00kbj9pcHO1lfAUpIUS9JPBoWxxZ3qO08mUNXi50pdQSPVVRWzN7mNz2g==
+ dependencies:
+ "@babel/core" "^7.13.8"
+ "@babel/plugin-transform-modules-amd" "^7.12.1"
+ amd-name-resolver "^1.3.1"
+ babel-plugin-module-resolver "^4.1.0"
+ bower-config "^1.4.3"
+ bower-endpoint-parser "0.2.2"
+ broccoli "^3.5.1"
+ broccoli-amd-funnel "^2.0.1"
+ broccoli-babel-transpiler "^7.8.0"
+ broccoli-builder "^0.18.14"
+ broccoli-concat "^4.2.5"
+ broccoli-config-loader "^1.0.1"
+ broccoli-config-replace "^1.1.2"
+ broccoli-debug "^0.6.5"
+ broccoli-funnel "^3.0.5"
+ broccoli-funnel-reducer "^1.0.0"
+ broccoli-merge-trees "^3.0.2"
+ broccoli-middleware "^2.1.1"
+ broccoli-slow-trees "^3.1.0"
+ broccoli-source "^3.0.0"
+ broccoli-stew "^3.0.0"
+ calculate-cache-key-for-tree "^2.0.0"
+ capture-exit "^2.0.0"
+ chalk "^4.1.0"
+ ci-info "^2.0.0"
+ clean-base-url "^1.0.0"
+ compression "^1.7.4"
+ configstore "^5.0.1"
+ console-ui "^3.1.2"
+ core-object "^3.1.5"
+ dag-map "^2.0.2"
+ diff "^5.0.0"
+ ember-cli-is-package-missing "^1.0.0"
+ ember-cli-lodash-subset "^2.0.1"
+ ember-cli-normalize-entity-name "^1.0.0"
+ ember-cli-preprocess-registry "^3.3.0"
+ ember-cli-string-utils "^1.1.0"
+ ember-source-channel-url "^3.0.0"
+ ensure-posix-path "^1.1.1"
+ execa "^5.0.0"
+ exit "^0.1.2"
+ express "^4.17.1"
+ filesize "^6.1.0"
+ find-up "^5.0.0"
+ find-yarn-workspace-root "^2.0.0"
+ fixturify-project "^2.1.1"
+ fs-extra "^9.1.0"
+ fs-tree-diff "^2.0.1"
+ get-caller-file "^2.0.5"
+ git-repo-info "^2.1.1"
+ glob "^7.1.6"
+ heimdalljs "^0.2.6"
+ heimdalljs-fs-monitor "^1.1.0"
+ heimdalljs-graph "^1.0.0"
+ heimdalljs-logger "^0.1.10"
+ http-proxy "^1.18.1"
+ inflection "^1.12.0"
+ is-git-url "^1.0.0"
+ is-language-code "^2.0.0"
+ isbinaryfile "^4.0.6"
+ js-yaml "^3.14.0"
+ json-stable-stringify "^1.0.1"
+ leek "0.0.24"
+ lodash.template "^4.5.0"
+ markdown-it "^12.0.4"
+ markdown-it-terminal "0.2.1"
+ minimatch "^3.0.4"
+ morgan "^1.10.0"
+ nopt "^3.0.6"
+ npm-package-arg "^8.1.1"
+ p-defer "^3.0.0"
+ portfinder "^1.0.28"
+ promise-map-series "^0.3.0"
+ promise.hash.helper "^1.0.7"
+ quick-temp "^0.1.8"
+ resolve "^1.20.0"
+ resolve-package-path "^3.1.0"
+ sane "^4.1.0"
+ semver "^7.3.4"
+ silent-error "^1.1.1"
+ sort-package-json "^1.49.0"
+ symlink-or-copy "^1.3.1"
+ temp "0.9.4"
+ testem "^3.2.0"
+ tiny-lr "^2.0.0"
+ tree-sync "^2.1.0"
+ uuid "^8.3.2"
+ walk-sync "^2.2.0"
+ watch-detector "^1.0.0"
+ workerpool "^6.1.4"
+ yam "^1.0.0"
+
ember-compatibility-helpers@^1.1.1, ember-compatibility-helpers@^1.1.2, ember-compatibility-helpers@^1.2.0, ember-compatibility-helpers@^1.2.1, ember-compatibility-helpers@^1.2.4:
version "1.2.5"
resolved "https://registry.yarnpkg.com/ember-compatibility-helpers/-/ember-compatibility-helpers-1.2.5.tgz#b8363b1d5b8725afa9a4fe2b2986ac28626c6f23"
@@ -10965,6 +11062,14 @@ eslint-plugin-prettier@^4.0.0:
dependencies:
prettier-linter-helpers "^1.0.0"
+eslint-plugin-qunit@^6.2.0:
+ version "6.2.0"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-qunit/-/eslint-plugin-qunit-6.2.0.tgz#f4efda29da99523e560848d9592c39c0590c308d"
+ integrity sha512-KvPmkIC2MHpfRxs/r8WUeeGkG6y+3qwSi2AZIBtjcM/YG6Z3k0GxW5Hbu3l7X0TDhljVCeBb9Q5puUkHzl83Mw==
+ dependencies:
+ eslint-utils "^3.0.0"
+ requireindex "^1.2.0"
+
eslint-scope@^4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848"