Skip to content

Commit

Permalink
Merge pull request #137 from boostcampwm2023/feat/131-signout-api-res…
Browse files Browse the repository at this point in the history
…ponse-handling

[Feat] 로그아웃 API에 대한 서버 응답 수정 및 통합 테스트 작성
  • Loading branch information
mingxoxo authored Nov 23, 2023
2 parents 1a8f045 + a4901a8 commit 32fc01d
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 3 deletions.
10 changes: 10 additions & 0 deletions BE/src/auth/auth.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import { AuthCredentialsDto } from "./dto/auth-credential.dto";
import { AccessTokenDto } from "./dto/auth-access-token.dto";
import { NoDuplicateLoginGuard } from "./guard/auth.user-guard";
import { CreateUserDto } from "./dto/users.dto";
import { User } from "./users.entity";
import { GetUser } from "./get-user.decorator";
import { JwtAuthGuard } from "./guard/auth.jwt-guard";

@Controller("auth")
export class AuthController {
Expand All @@ -23,4 +26,11 @@ export class AuthController {
): Promise<AccessTokenDto> {
return this.authService.signIn(authCredentialsDto);
}

@Post("/signout")
@UseGuards(JwtAuthGuard)
@HttpCode(204)
signOut(@GetUser() user: User): void {
this.authService.signOut(user);
}
}
4 changes: 4 additions & 0 deletions BE/src/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,8 @@ export class AuthService {
throw new NotFoundException("올바르지 않은 비밀번호입니다.");
}
}

signOut(user: User): void {
// const hasRefreshToken = true;
}
}
5 changes: 2 additions & 3 deletions BE/test/int/auth.signin.int-spec.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import { Test, TestingModule } from "@nestjs/testing";
import { INestApplication } from "@nestjs/common";
import * as request from "supertest";
import { AppModule } from "../../src/app.module";
import { ValidationPipe } from "@nestjs/common";
import { AuthModule } from "src/auth/auth.module";
import { TypeOrmModule } from "@nestjs/typeorm";
import { typeORMTestConfig } from "src/configs/typeorm.test.config";
import { typeORMConfig } from "src/configs/typeorm.config";

describe("/auth/signin (e2e)", () => {
describe("[로그인] /auth/signin POST 통합 테스트", () => {
let app: INestApplication;

beforeAll(async () => {
Expand All @@ -22,6 +20,7 @@ describe("/auth/signin (e2e)", () => {

await app.init();
});

afterAll(async () => {
await app.close();
});
Expand Down
108 changes: 108 additions & 0 deletions BE/test/int/auth.signout.int-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import { Test, TestingModule } from "@nestjs/testing";
import { INestApplication } from "@nestjs/common";
import * as request from "supertest";
import { ValidationPipe } from "@nestjs/common";
import { AuthModule } from "src/auth/auth.module";
import { TypeOrmModule } from "@nestjs/typeorm";
import { typeORMTestConfig } from "src/configs/typeorm.test.config";
import { User } from "src/auth/users.entity";
import { UsersRepository } from "src/auth/users.repository";

describe("[로그아웃] /auth/signout POST 통합 테스트", () => {
let app: INestApplication;

beforeAll(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [TypeOrmModule.forRoot(typeORMTestConfig), AuthModule],
providers: [UsersRepository],
}).compile();

app = moduleFixture.createNestApplication();
app.enableCors();
app.useGlobalPipes(new ValidationPipe());

await app.init();

await request(app.getHttpServer())
.post("/auth/signup")
.send({
userId: "SignoutTestUserId",
password: "SignoutTestPassword",
email: "[email protected]",
nickname: "SignoutTestUser",
})
.expect(201);
});

afterAll(async () => {
const usersRepository = new UsersRepository();

const testUser = await usersRepository.getUserByUserId("SignoutTestUserId");
if (testUser) {
await User.remove(testUser);
}

await app.close();
});

it("올바른 토큰으로 요청 시 204 No Content 응답", async () => {
const signInResponse = await request(app.getHttpServer())
.post("/auth/signin")
.send({
userId: "SignoutTestUserId",
password: "SignoutTestPassword",
})
.expect(201);

expect(signInResponse.body).toHaveProperty("accessToken");

const { accessToken } = signInResponse.body;

await request(app.getHttpServer())
.post("/auth/signout")
.set("Authorization", `Bearer ${accessToken}`)
.expect(204);
});

it("유효하지 않은 액세스 토큰이 포함된 상태로 로그아웃 요청 시 401 Unauthorized 응답", async () => {
await request(app.getHttpServer())
.post("/auth/signin")
.send({
userId: "SignoutTestUserId",
password: "SignoutTestPassword",
})
.expect(201);

const invalidAccessToken = "1234";
const postResponse = await request(app.getHttpServer())
.post("/auth/signout")
.set("Authorization", `Bearer ${invalidAccessToken}`)
.expect(401);

expect(postResponse.body).toEqual({
error: "Unauthorized",
message: "유효하지 않은 토큰입니다.",
statusCode: 401,
});
});

it("토큰이 존재하지 않은 상태로 로그아웃 요청 시 401 Unauthorized 응답", async () => {
await request(app.getHttpServer())
.post("/auth/signin")
.send({
userId: "SignoutTestUserId",
password: "SignoutTestPassword",
})
.expect(201);

const postResponse = await request(app.getHttpServer())
.post("/auth/signout")
.expect(401);

expect(postResponse.body).toEqual({
error: "Unauthorized",
message: "비로그인 상태의 요청입니다.",
statusCode: 401,
});
});
});

0 comments on commit 32fc01d

Please sign in to comment.