E2E testing with JWT guard

2.6k views Asked by At

I’m trying to get e2e testing to work for this user update function. When user logs in their id and email are saved into JWT token and stored in HttpOnly Cookie. My problem is how to get this token so that it passes through JWT guard, gets id from JWT token and updates correct user. Because currently i'm obviously getting Unauthorized message.

user.2e2-spec.ts

const mockUser: UpdateUserDto = {
  email: '[email protected]',
  first_name: 'first_name1',
  last_name: 'last_name1',
  password: 'password1',
};

const mockLoginUser: LoginUserDto = {
  email: '[email protected]',
  password: 'password',
};

describe('Auth controller (e2e)', () => {
  let app: INestApplication;

  beforeAll(async () => {
    const moduleFixture: TestingModule = await Test.createTestingModule({
      imports: [AppModule],
    }).compile();

    app = moduleFixture.createNestApplication();
    await app.init();
  });

  it('should update user info', async () => {
    const loginRes = await request(app.getHttpServer())
      .post('/login')
      .send(mockLoginUser);

    const data = await request(app.getHttpServer())
      .put('/me/update')
      .send(mockUser)
      .expect('success');
  });

  afterAll(async () => {
    await app.close();
  });
});

user.controller.ts

  @UseGuards(jwtAuthGuard)
  @Put('me/update')
  async updateUser(@Req() request, @Body() updateUser: UpdateUserDto) {
    const data = await this.userService.updateUser(request.user.id, updateUser);
    return data;
  }

jwt.strategy.ts

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') {
  constructor() {
    super({
      jwtFromRequest: (req) => {
        var token = null;
        if (req && req.cookies) {
          token = req.cookies['jwt'];
        }
        return token;
      },
      ignoreExpiration: false,
      secretOrKey: process.env.ACCESS_SECRET,
    });
  }

  async validate(payload: any) {
    return {
      id: payload.id,
      email: payload.email,
    };
  }
}
1

There are 1 answers

0
tevvek On

You have to handle that yourself between calls:

  it('should update user info', async () => {
    const loginRes = await request(app.getHttpServer())
      .post('/login')
      .send(mockLoginUser);

    const cookies = loginRes.header('set-cookie');

    const data = await request(app.getHttpServer())
      .put('/me/update')
      .set('Cookie', cookies) // Set the cookies from login response on new req
      .send(mockUser)
      .expect('success');
  });

If using typescript, superagent which is used by supertest will give you a hint of the set function, it accepts a field parameter which only can be Cookie