-
Notifications
You must be signed in to change notification settings - Fork 1
Testing Guards
Authentication in this application is currently being performed by passport
which provides authentication middleware to protect certain API routes from access by unauthenticated users.
Generally, it is not desireable for tests to be interacting with authentication sources. Therefore, the canActivate
method in passport is typically stubbed out to prevent this, like so:
beforeEach(function () {
stub(AuthGuard('saml').prototype, 'canActivate');
});
afterEach(function () {
AuthGuard('saml').prototype.canActivate.restore();
});
Additionally, implementations of the CanActivate interface must have a canActivate
method, which, in turn recieves an ExecutionContext as it's only parameter.
ExecutionContext
contains metadata about the handler the guard is bound to, the current HTTP request and other parts of the application that may be used to determine whether a guard should allow or deny access. In certain cases(for example, when only performing authentication), the specifics of ExecutionContext
may be irrelevant, and a simple object literal can be provided to canActivate
in testing.
strictEqual(myGuard.canActivate({} as ExecutionContext), true);
For other guards that may need to examine parts of the HTTP request (for example for access control etc.) a stub ExecutionContext
may be used in testing. This can be done like so:
const context: Partial<ExecutionContext> = {
switchToHttp: stub().returns({
getRequest: stub(),
getResponse: stub(),
getNext: stub(),
} as HttpArgumetsHost),
};
strictEqual(myGuard.canActivate(context as ExecutionContext), true);
From there, the switchToHttp().getRequest()
can be used within the guard to obtain access to parts of the application(such as the current HTTP request) like so:
const request = context.switchToHttp().getRequest();
const user = request.user;
See https://docs.nestjs.com/guards#putting-it-all-together for more info