refactor: 💡 rewrite OIDC polling for ember pollster

This commit is contained in:
Randall Morey committed 2022-01-02 22:36:53 -05:00
1 parent a3bb788716
commit 28de23b517
2 files changed
+44 -91

No files matched your search

@@ -1,39 +1,20 @@
import Route from '@ember/routing/route';
import { getOwner } from '@ember/application';
import { inject as service } from '@ember/service';
import { task, timeout } from 'ember-concurrency';
import { action } from '@ember/object';
import runEvery from 'ember-pollster/decorators/route/run-every';
import { notifyError } from 'core/decorators/notify';
import config from '../../../../../config/environment';
const POLL_TIMEOUT_SECONDS = config.oidcPollingTimeoutSeconds;
export default class ScopesScopeAuthenticateMethodOidcRoute extends Route {
// =services
@service session;
// =attributes
/**
* A simple Ember Concurrency-based polling task that refreshes the route
* every POLL_TIMEOUT_SECONDS seconds. This is necessary to display changes
* to session `status` that may occur.
*
* NOTE: tasks are sort of attributes and sort of methods, but they are not
* language-level constructs. Thus we annotate this task as if it
* is an attribute.
* @type {Task}
*/
@task(function * () {
while(!this.session.isAuthenticated) {
yield timeout(POLL_TIMEOUT_SECONDS * 1000);
yield this.refresh();
}
/* eslint-disable-next-line prettier/prettier */
}).drop() poller;
// =methods
model() {
@@ -46,25 +27,9 @@ export default class ScopesScopeAuthenticateMethodOidcRoute extends Route {
return oidc.attemptFetchToken({ scope, authMethod });
}
/**
* If authenticated, redirects to index for further processing.
*/
redirect() {
if (this.session.isAuthenticated) this.replaceWith('index');
}
/**
* When this route is activated (entered), begin polling for changes.
*/
activate() {
this.poller.perform();
}
/**
* When this route is deactivated (exited), stop polling for changes.
*/
deactivate() {
this.poller.cancelAll();
@runEvery(POLL_TIMEOUT_SECONDS * 1000)
poller() {
this.refresh();
}
/**
@@ -78,5 +43,4 @@ export default class ScopesScopeAuthenticateMethodOidcRoute extends Route {
// rethrow the error to activate the notifyError decorator
throw e;
}
}
@@ -9,7 +9,6 @@ import {
getRootElement,
//setupOnerror,
} from '@ember/test-helpers';
import { run, later } from '@ember/runloop';
import { setupApplicationTest } from 'ember-qunit';
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
import { Response } from 'miragejs';
@@ -162,20 +161,17 @@ module('Acceptance | authentication', function (hooks) {
await visit(urls.authenticate.methods.global);
await fillIn('[name="identification"]', 'test');
await fillIn('[name="password"]', 'test');
later(async () => {
run.cancelTimers();
assert.ok(currentSession().isAuthenticated);
await click('.rose-header-utilities .rose-dropdown summary');
assert.equal(
find(
'.rose-header-utilities .rose-dropdown-content button'
).textContent.trim(),
'Deauthenticate'
);
await click('.rose-header-utilities .rose-dropdown-content button');
assert.notOk(currentSession().isAuthenticated);
}, 750);
await click('[type="submit"]');
assert.ok(currentSession().isAuthenticated);
await click('.rose-header-utilities .rose-dropdown summary');
assert.equal(
find(
'.rose-header-utilities .rose-dropdown-content button'
).textContent.trim(),
'Deauthenticate'
);
await click('.rose-header-utilities .rose-dropdown-content button');
assert.notOk(currentSession().isAuthenticated);
});
test('401 responses result in deauthentication', async function (assert) {
@@ -183,21 +179,18 @@ module('Acceptance | authentication', function (hooks) {
await visit(urls.authenticate.methods.global);
await fillIn('[name="identification"]', 'test');
await fillIn('[name="password"]', 'test');
later(async () => {
run.cancelTimers();
assert.ok(
currentSession().isAuthenticated,
'Session begins authenticated, before encountering 401'
);
assert.ok(currentURL(), urls.targets);
this.server.get('/sessions', () => new Response(401));
await visit(urls.sessions);
assert.notOk(
currentSession().isAuthenticated,
'Session is unauthenticated, after encountering 401'
);
}, 750);
await click('[type="submit"]');
assert.ok(
currentSession().isAuthenticated,
'Session begins authenticated, before encountering 401'
);
assert.ok(currentURL(), urls.targets);
this.server.get('/sessions', () => new Response(401));
await visit(urls.sessions);
assert.notOk(
currentSession().isAuthenticated,
'Session is unauthenticated, after encountering 401'
);
});
test('color theme is applied from session data', async function (assert) {
@@ -208,29 +201,25 @@ module('Acceptance | authentication', function (hooks) {
type: instances.scopes.global.type,
},
});
later(async () => {
run.cancelTimers();
// system default
assert.notOk(currentSession().get('data.theme'));
assert.notOk(getRootElement().classList.contains('rose-theme-light'));
assert.notOk(getRootElement().classList.contains('rose-theme-dark'));
// toggle light mode
await click('[name="theme"][value="light"]');
assert.equal(currentSession().get('data.theme'), 'light');
assert.ok(getRootElement().classList.contains('rose-theme-light'));
assert.notOk(getRootElement().classList.contains('rose-theme-dark'));
// toggle dark mode
await click('[name="theme"][value="dark"]');
assert.equal(currentSession().get('data.theme'), 'dark');
assert.notOk(getRootElement().classList.contains('rose-theme-light'));
assert.ok(getRootElement().classList.contains('rose-theme-dark'));
// toggle system default
await click('[name="theme"][value=""]');
assert.notOk(currentSession().get('data.theme'));
assert.notOk(getRootElement().classList.contains('rose-theme-light'));
assert.notOk(getRootElement().classList.contains('rose-theme-dark'));
}, 750);
await visit(urls.scopes.org);
// system default
assert.notOk(currentSession().get('data.theme'));
assert.notOk(getRootElement().classList.contains('rose-theme-light'));
assert.notOk(getRootElement().classList.contains('rose-theme-dark'));
// toggle light mode
await click('[name="theme"][value="light"]');
assert.equal(currentSession().get('data.theme'), 'light');
assert.ok(getRootElement().classList.contains('rose-theme-light'));
assert.notOk(getRootElement().classList.contains('rose-theme-dark'));
// toggle dark mode
await click('[name="theme"][value="dark"]');
assert.equal(currentSession().get('data.theme'), 'dark');
assert.notOk(getRootElement().classList.contains('rose-theme-light'));
assert.ok(getRootElement().classList.contains('rose-theme-dark'));
// toggle system default
await click('[name="theme"][value=""]');
assert.notOk(currentSession().get('data.theme'));
assert.notOk(getRootElement().classList.contains('rose-theme-light'));
assert.notOk(getRootElement().classList.contains('rose-theme-dark'));
});
});