Skip to content

Guards

You can also test the guard by only calling the method's instance. You will not get the exact behavior of the framework because if the guard's response is false, the framework will throw an error.

To reproduce the exact behavior, you will need to work with the ExecutableGuard class.

demo-http/tests/guard.test.ts
import type { RouterContext } from '@koa/router';
import { ExecutableGuard, ExecutableParam, ForbiddenError } from '@triptyk/nfw-http';
import type { ControllerContext } from '@triptyk/nfw-http/dist/src/types/controller-context.js';
import 'reflect-metadata';
import { AuthGuard } from '../src/guards/guard.js';

class FakeController {}

function setupContextAndGuardInstance () {
  const controllerInstance = new FakeController();
  const guard = new AuthGuard();
  const context: ControllerContext = {
    controllerAction: 'list',
    controllerInstance
  };
  return { context, guard };
}

function setupExecutableGuardWithOneParam (context: ControllerContext<any>, guard: AuthGuard, param: string) {
  const executableParam = new ExecutableParam(context, () => param);
  const executableGuard = new ExecutableGuard(guard, context, [executableParam]);
  return executableGuard;
}

test('Guard throws when no user is provided', async () => {
  const { context, guard } = setupContextAndGuardInstance();
  const executableGuard = setupExecutableGuardWithOneParam(context, guard, '');
  expect(() => executableGuard.execute({} as RouterContext)).rejects.toThrowError(ForbiddenError);
});

test('Guard does not throws when user admin is provided', async () => {
  const { context, guard } = setupContextAndGuardInstance();
  const executableGuard = setupExecutableGuardWithOneParam(context, guard, 'admin');
  await executableGuard.execute({} as RouterContext);
});
demo-http/src/guards/guard.ts
import type { GuardInterface } from '@triptyk/nfw-http';
import { QueryParam } from '@triptyk/nfw-http';

export class AuthGuard implements GuardInterface {
  public can (@QueryParam('user') user: string): boolean | Promise<boolean> {
    if (user === 'admin') {
      return true;
    }
    return false;
  }
}