-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Test helpers #8
Comments
Hi Tom No I hadn't - but now you mention it I think I probably should. I'm a bit tied up right now but will try to make a bit of time out to check out Ember Simple Auth and see how it was done there. Will keep you posted (and obviously any other thoughts you might have are more than welcome). thanks, and best rgds, Steve F. |
Hi team:
Note: At this point, it looks works. When open http://www.sample.com:4200/help, it redirect to keycloak login page and a user is able to log in. Issue was start at: when I update the environment.js, set as follows: When open the site like www.sample.com:4200/test/#/help, it redirects to keycloak login page. But the keycloak login page return error: "Invalid parameter: redirect_uri". The failure was caused by the redirect URL was set as: http://www.sample.com:4200#help. Please help to take look and fix the issue. Thanks. |
Oops, above comment should be in a new issue. Please ignore the previous comment. I create a new issue for it. |
We're converting our app to Keycloak and have tried this Ember addon. It worked out of the box! But all our tests are a mess. We need a way to mock authentication. @sbflynn I can work on this. Do you have any specific approach in mind or should I come up with something on my own? |
Any Updates on this? |
I've ended up making a stub of the Keycloak service. It mimics all the original methods so that it can be used in the app normally. And it also has a simple auth store. You can erase the token and the app should gracefully log out next time it attempts using the token. I can make a PR but I would like to validate the approach with addon maintainers before I spend time on it. |
@lolmaus That sounds great. Do you have this Stub in a Git Repository so I might have a look at it? |
Alright I've figured it out myself, I just literally stubbed every method and every variable that the session uses. From what I can tell so far updateToken() is the only function that needs a little bit more magic than just an empty function. keycloak-stub.js import Service from '@ember/service';
export default Service.extend({
tokenParsed: '1234',
given_name: 'Name',
token: '1234',
roles: 'bla',
keycloak: Object.freeze([{ token: '1234' }]),
get headers() {},
hasResourceRole(resource, role) {},
installKeycloak(parameters) {},
initKeycloak() {},
hasRealmRole(role) {},
_parseRedirectUrl(router, transition) {},
loadUserProfile() {},
login(redirectUri) {},
logout(redirectUri) {},
checkTransition(transition) {},
updateToken() {
return new Promise((resolve, reject) => { resolve() })
}
}) And then imported it import keycloakStub from '../helpers/keycloak-stub'; and added it in my acceptance test module beforeEach() function like this: this.owner.register('service:keycloak-session', keycloakStub); Keep in mind this does not really authenticate the user, it just bypasses all the functions. It's a good enough workaround for the Mixins in Acceptance tests atm. |
@lolmaus @lolmaus, @Robin481 Rough plan is a future 1.0 is going to be 'Octane' aligned. As a quick straw poll - what versions of Ember are you focussed on ? Any thoughts welcome. |
@sbflynn Thanks for answering! |
I have taken a first go at this - in the addon-test-support folder there is now a MockKeycloakSessionService class and a MockKeycloak class. The service mock extends the 'real' KeycloakSessionService class - it overrides a single method (installKeycloak()) to install a mock Keycloak Adapter instead of a 'real' Keycloak Adapter instance. The mock service can then be used in tests in exactly the way you suggested (example usage the add-on tests). The bad news is that at the moment that only works for the latest (Ember 3.8+) version - it still needs to be back ported to earlier versions. BTW the upgrade path, when you get there, should be straight forward as the service methods and the mixins remain unchanged. The latest version now deprecates the route mixin in favour of using the new RouteInfo Metadata API to trigger token update checks - but the route mixin will work just fine unchanged. |
@sbflynn Very cool, thanks a lot for your effort. |
Looks like I'm late for the party. 😔 In my implementation, I defined a simple token store: export const AUTH_TOKEN = 'The most important thing is listening the recording of the music. It makes them gain a musical sense and gets to the point of the fast progress.'; // just a random string
interface AuthStore {
token: string | null;
authenticate(token?: string): void;
invalidate(): void;
}
export const AUTH_STORE: AuthStore = {
token: null,
authenticate(token = AUTH_TOKEN) {
this.token = token;
},
invalidate() {
this.token = null;
}
}; It's used in a mock service: export class KeycloakSessionStubService extends Service {
@service
router!: RouterService;
get authenticated() {
return !!this.token;
}
get token() {
// @ts-ignore
return AUTH_STORE.token;
}
async checkTransition() {
if (!this.authenticated) {
return this.router.transitionTo('unauthenticated');
} else {
return;
}
}
installKeycloak() {}
initKeycloak() {}
async updateToken() {}
isStub = true;
} And we use this to register the mock: export default function setupKeycloackStub(hooks: TestHooks) {
hooks.beforeEach( function() {
this.owner.register('service:keycloak-session', KeycloakSessionStubService);
assert('Keycloak-session service registration failed! Called the hook too late?', this.owner.lookup('service:keycloak-session').isStub);
AUTH_STORE.invalidate();
});
} We also hack into Mirage so that it passes the token with every request. Our backend does not have public endpoints, so we don't need to check for authorization in every route handler. import { AUTH_TOKEN } from './setup-keycloak-stub';
import { assert } from '@ember/debug';
import RouteHandler from 'ember-cli-mirage/route-handler';
export default function setupMirageAuth(hooks) {
hooks.beforeEach(function() {
this.__originalMirageRouteHandlerHandle__ = RouteHandler.prototype.handle;
RouteHandler.prototype.handle = function(request) {
assert('Unauthorized request', request.requestHeaders.authorization === `Bearer ${AUTH_TOKEN}`);
return this
._getMirageResponseForRequest(request)
.then((mirageResponse) => this.serialize(mirageResponse, request))
.then((serializedMirageResponse) => serializedMirageResponse.toRackResponse());
};
});
hooks.afterEach(function() {
RouteHandler.prototype.handle = this.__originalMirageRouteHandlerHandle__;
delete this.__originalMirageRouteHandlerHandle__;
});
} Note how the same token is used both in Mirage and in the mock service. The mock keeps functioning, checking for a valid token for every request. But it has all the Keycloak complexity removed. In tests, I can do This lets me test basic situations without delving into how Keycloak actually works. @sbflynn What do you think? And is there any documentation/guidelines for your implementation? |
Not too late at all - party hardly started 🙂 I like your mirage setup and the shared token - definitely should add these in some form or other. I think that the token should be structured more like a real auth2 response so as to better test the addon itself. I have, so far, stubbed the wrapped keycloak adapter rather than the service - so as to make tests a realistic as possible. Always need better docs ! Best rgds Steve F. |
Woah, just noticed the changes in the |
Note that now the addon is depending on Mirage, which might not be desirable for every app. I think it would be OK if Mirage imports were moved to a separate file. |
Good catch - I think you are right about separating the mirage stuff from the rest - should do the trick - will play with it later today. |
Hi there!
Do you have plans to add any test helpers to allow accessing authenticated routes in acceptance tests? In Ember Simple Auth, they provide a mechanism that lets you call authenticate directly with the token information, allowing you to "authenticate" and carry on with the test. It would be great if Ember Keycloak Auth could offer similar functionality. In lieu of that, do you have any workaround for "authenticating" in a test environment?
Cheers, and thanks for the great addon!
The text was updated successfully, but these errors were encountered: