test: 💍 add missing auth navigation and setup initial tests

This commit is contained in:
Randall Morey committed 2020-11-13 17:10:56 -05:00
1 parent 4495a84692
commit d84d427ff5
8 files changed
+397 -3

No files matched your search

@@ -0,0 +1,17 @@
import Controller from '@ember/controller';
export default class ScopesScopeAuthenticateController extends Controller {
// =attributes
/**
* Moves the global scope to index 0.
* @type {Array}
*/
get sortedScopes() {
return [
...this.model.scopes.filter((scope) => scope.id === 'global'),
...this.model.scopes.filter((scope) => scope.id !== 'global'),
]
}
}
+13
View File
@@ -10,6 +10,19 @@
<header.nav>
{{outlet "header-nav"}}
</header.nav>
<header.utilities as |utilities|>
<utilities.dropdown
@text={{this.session.data.authenticated.username}}
as |dropdown|
>
<dropdown.button
{{on "click" (route-action "invalidateSession")}}
>
{{t 'actions.deauthenticate'}}
</dropdown.button>
</utilities.dropdown>
</header.utilities>
{{/if}}
</Rose::Header>
@@ -1 +1,57 @@
{{outlet}}
{{page-title (t "actions.authenticate")}}
<Rose::Layout::Centered>
<Rose::Layout::Page as |page|>
<page.header>
<h2>{{t "actions.authenticate"}}</h2>
<p>{{t "auth.descriptions.authenticating-with-org" name=@model.scope.displayName}}</p>
</page.header>
<page.navigation>
<Rose::Dropdown
@text={{t "actions.choose-different-org"}}
@icon="user-organization"
as |dropdown|>
<dropdown.link @route="scopes.scope.authenticate" @model="global">
{{t "titles.global"}}
</dropdown.link>
{{#each this.sortedScopes as |scope|}}
<dropdown.link @route="scopes.scope.authenticate" @model={{scope.id}}>
{{scope.displayName}}
</dropdown.link>
{{/each}}
</Rose::Dropdown>
<Rose::Separator />
<Rose::Nav::Tabs as |nav|>
{{#each @model.authMethods as |authMethod|}}
<nav.link @route="scopes.scope.authenticate.method" @model={{authMethod.id}}>
{{t (concat "resources.auth-method.types." authMethod.type)}}
</nav.link>
{{/each}}
</Rose::Nav::Tabs>
</page.navigation>
<page.body>
{{#if @model.authMethods}}
{{outlet}}
{{/if}}
{{#unless @model.authMethods}}
<Rose::Layout::Centered>
<Rose::Message
@title={{t "resources.auth-method.messages.none.title"}}
@icon="alert-circle-outline"
as |message|>
<message.description>
{{t "resources.auth-method.messages.none.description"}}
</message.description>
</Rose::Message>
</Rose::Layout::Centered>
{{/unless}}
</page.body>
</Rose::Layout::Page>
</Rose::Layout::Centered>
@@ -1 +1,12 @@
{{outlet}}
{{#unless @model}}
<Rose::Layout::Centered>
<Rose::Message
@title={{t "resources.auth-method.messages.none.title"}}
@icon="alert-circle-outline"
as |message|>
<message.description>
{{t "resources.auth-method.messages.none.description"}}
</message.description>
</Rose::Message>
</Rose::Layout::Centered>
{{/unless}}
+1 -1
View File
@@ -6,7 +6,7 @@ import { Response } from 'miragejs';
export default function() {
if (!config.isElectron) {
if (!config.isElectron && !Ember.testing) {
class MockIPC {
invoke(method, payload) {
console.log('MockIPC:', method, payload);
@@ -0,0 +1,152 @@
import { module, test } from 'qunit';
import {
visit,
currentURL,
fillIn,
click,
find,
findAll,
getRootElement
//setupOnerror,
} from '@ember/test-helpers';
import { setupApplicationTest } from 'ember-qunit';
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
import { Response } from 'miragejs';
//import a11yAudit from 'ember-a11y-testing/test-support/audit';
import {
currentSession,
authenticateSession,
invalidateSession,
} from 'ember-simple-auth/test-support';
module('Acceptance | authentication', function(hooks) {
setupApplicationTest(hooks);
setupMirage(hooks);
let mockIPC;
let messageHandler;
const instances = {
scopes: {
global: null,
org: null,
project: null
},
authMethods: {
global: null,
org: null
},
hostCatalog: null,
target: null
};
const stubs = {
global: null,
org: null
};
const urls = {
index: '/',
origin: '/origin',
scopes: {
global: null,
org: null,
},
authenticate: {
global: null,
methods: {
global: null,
}
},
targets: null
};
const setDefaultOrigin = (test) => {
const origin = window.location.origin;
const session = test.owner.lookup('service:session');
session.set('data.origin', origin);
};
hooks.beforeEach(function () {
invalidateSession();
// create scopes
instances.scopes.global = this.server.create('scope', { id: 'global' });
stubs.global = { id: 'global', type: 'global' };
instances.scopes.org = this.server.create(
'scope',
{ type: 'org', scope: stubs.global }
);
stubs.org = { id: instances.scopes.org.id, type: 'org' };
instances.scopes.project = this.server.create(
'scope',
{ type: 'project', scope: stubs.org }
);
stubs.project = { id: instances.scopes.project.id, type: 'project' };
// create other resources
instances.authMethods.global = this.server.create('auth-method', { scope: instances.scopes.global });
instances.authMethods.org = this.server.create('auth-method', { scope: instances.scopes.org });
instances.hostCatalog = this.server.create('host-catalog', { scope: instances.scopes.project }, 'withChildren');
instances.target = this.server.create('target', { scope: instances.scopes.project }, 'withRandomHostSets');
urls.scopes.global = `/scopes/${instances.scopes.global.id}`;
urls.scopes.org = `/scopes/${instances.scopes.org.id}`;
urls.authenticate.global = `${urls.scopes.global}/authenticate`;
urls.authenticate.methods.global = `${urls.authenticate.global}/${instances.authMethods.global.id}`;
class MockIPC {
origin = null;
invoke(method, payload) {
return this[method](payload);
}
getOrigin() {
return this.origin;
}
setOrigin(origin) {
this.origin = origin;
return this.origin;
}
}
mockIPC = new MockIPC();
messageHandler = async function (event) {
if (event.origin !== window.location.origin) return;
const { method, payload } = event.data;
if (method) {
const response =
await mockIPC.invoke(method, payload);
event.ports[0].postMessage(response);
}
};
window.addEventListener('message', messageHandler);
setDefaultOrigin(this);
});
hooks.afterEach(function () {
window.removeEventListener('message', messageHandler);
});
test('visiting index while unauthenticated redirects to global authenticate method', async function (assert) {
assert.expect(2);
await visit(urls.index);
//await a11yAudit();
assert.notOk(currentSession().isAuthenticated);
assert.equal(currentURL(), urls.authenticate.methods.global);
});
test('visiting authenticate route when there no methods shows a message', async function (assert) {
assert.expect(2);
instances.authMethods.global.destroy();
await visit(urls.authenticate.global);
//await a11yAudit();
assert.equal(currentURL(), urls.authenticate.global);
assert.ok(find('.rose-message'));
});
});
+133
View File
@@ -0,0 +1,133 @@
import { module, test } from 'qunit';
import {
visit,
currentURL,
fillIn,
click,
find,
findAll,
getRootElement
//setupOnerror,
} from '@ember/test-helpers';
import { setupApplicationTest } from 'ember-qunit';
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
import { Response } from 'miragejs';
//import a11yAudit from 'ember-a11y-testing/test-support/audit';
import {
currentSession,
authenticateSession,
invalidateSession,
} from 'ember-simple-auth/test-support';
module('Acceptance | authentication', function(hooks) {
setupApplicationTest(hooks);
setupMirage(hooks);
let mockIPC;
let messageHandler;
const instances = {
scopes: {
global: null,
org: null,
project: null
},
authMethods: {
global: null,
org: null
},
hostCatalog: null,
target: null
};
const stubs = {
global: null,
org: null
};
const urls = {
index: '/',
origin: '/origin',
scopes: {
global: null,
org: null,
},
authenticate: {
global: null,
org: null
},
targets: null
};
hooks.beforeEach(function () {
invalidateSession();
// create scopes
instances.scopes.global = this.server.create('scope', { id: 'global' });
stubs.global = { id: 'global', type: 'global' };
instances.scopes.org = this.server.create(
'scope',
{ type: 'org', scope: stubs.global }
);
stubs.org = { id: instances.scopes.org.id, type: 'org' };
instances.scopes.project = this.server.create(
'scope',
{ type: 'project', scope: stubs.org }
);
stubs.project = { id: instances.scopes.project.id, type: 'project' };
// create other resources
instances.authMethods.global = this.server.create('auth-method', { scope: instances.scopes.global });
instances.authMethods.org = this.server.create('auth-method', { scope: instances.scopes.org });
instances.hostCatalog = this.server.create('host-catalog', { scope: instances.scopes.project }, 'withChildren');
instances.target = this.server.create('target', { scope: instances.scopes.project }, 'withRandomHostSets');
urls.scopes.global = `/scopes/${instances.scopes.global.id}`;
urls.scopes.org = `/scopes/${instances.scopes.org.id}`;
urls.authenticate.global = `${urls.scopes.global}/authenticate/${instances.authMethods.global.id}`;
urls.authenticate.org = `${urls.scopes.global}/authenticate/${instances.authMethods.org.id}`;
class MockIPC {
origin = null;
invoke(method, payload) {
return this[method](payload);
}
getOrigin() {
return this.origin;
}
setOrigin(origin) {
this.origin = origin;
return this.origin;
}
}
mockIPC = new MockIPC();
messageHandler = async function (event) {
if (event.origin !== window.location.origin) return;
const { method, payload } = event.data;
if (method) {
const response =
await mockIPC.invoke(method, payload);
event.ports[0].postMessage(response);
}
};
window.addEventListener('message', messageHandler);
});
hooks.afterEach(function () {
window.removeEventListener('message', messageHandler);
});
test('visiting index without an origin specified redirects to origin route', async function (assert) {
assert.expect(2);
await visit(urls.index);
//await a11yAudit();
assert.notOk(mockIPC.origin);
assert.equal(currentURL(), urls.origin);
});
});
@@ -0,0 +1,12 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module('Unit | Controller | scopes/scope/authenticate', function(hooks) {
setupTest(hooks);
// TODO: Replace this with your real tests.
test('it exists', function(assert) {
let controller = this.owner.lookup('controller:scopes/scope/authenticate');
assert.ok(controller);
});
});