Skip to content
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

[Mypage - Final/be] 마이페이지 프로필 사진을 object storage를 사용하여 저장 #175

Merged
1 change: 1 addition & 0 deletions be/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#config
typeorm.config.ts
objectStorage.config.ts

# Logs
logs
Expand Down
107 changes: 107 additions & 0 deletions be/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions be/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"@nestjs/platform-express": "^10.0.0",
"@nestjs/swagger": "^7.1.15",
"@nestjs/typeorm": "^10.0.1",
"aws-sdk": "^2.348.0",
"axios": "^1.6.2",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
Expand All @@ -39,6 +40,7 @@
"rxjs": "^7.8.1",
"swagger-ui-express": "^5.0.0",
"typeorm": "^0.3.17",
"uuid": "^9.0.1",
"winston": "^3.11.0"
},
"devDependencies": {
Expand Down
2 changes: 2 additions & 0 deletions be/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { ReviewModule } from "./review/review.module";
import { CustomLoggerService } from "./custom.logger";
import { APP_INTERCEPTOR } from "@nestjs/core";
import { LoggingInterceptor } from "./logger.interceptor";
import { AwsModule } from './aws/aws.module';

@Module({
imports: [
Expand All @@ -16,6 +17,7 @@ import { LoggingInterceptor } from "./logger.interceptor";
AuthModule,
RestaurantModule,
ReviewModule,
AwsModule,
],
providers: [
CustomLoggerService,
Expand Down
107 changes: 99 additions & 8 deletions be/src/auth/auth.service.spec.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,109 @@
import { Test, TestingModule } from "@nestjs/testing";
import { AuthService } from "./auth.service";
import { DataSource } from "typeorm";
import { User } from "src/user/entities/user.entity";
import { TypeOrmModule } from "@nestjs/typeorm";
import { FollowEntity } from "src/user/entities/user.followList.entity";
import { RestaurantInfoEntity } from "src/restaurant/entities/restaurant.entity";
import { UserRestaurantListEntity } from "src/user/entities/user.restaurantlist.entity";
import { ReviewInfoEntity } from "src/review/entities/review.entity";
import { JwtService } from "@nestjs/jwt";
import { UserModule } from "src/user/user.module";
import { RestaurantModule } from "src/restaurant/restaurant.module";
import { ReviewModule } from "src/review/review.module";
import { HttpException } from '@nestjs/common';
import { UserInfoDto } from "src/user/dto/userInfo.dto";
import { UserService } from "src/user/user.service";
import { AuthModule } from "./auth.module";

describe("AuthService", () => {
let service: AuthService;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [AuthService],
let authService: AuthService;
let dataSource: DataSource;
let jwtService: JwtService;
let userService: UserService;

beforeAll(async () => {
const testModule = await Test.createTestingModule({
imports: [
AuthModule,
UserModule,
RestaurantModule,
ReviewModule,
TypeOrmModule.forRoot({
type: 'postgres',
host: 'localhost',
port: 5433,
username: 'user',
password: 'password',
database: 'testdb',
entities: [User, FollowEntity, RestaurantInfoEntity, UserRestaurantListEntity, ReviewInfoEntity],
synchronize: true,
}),
],
}).compile();

service = module.get<AuthService>(AuthService);
authService = testModule.get<AuthService>(AuthService);
jwtService = testModule.get<JwtService>(JwtService);
dataSource = testModule.get<DataSource>(DataSource);
userService = testModule.get<UserService>(UserService);
});

it("should be defined", () => {
expect(service).toBeDefined();


beforeEach(async () => {
const repository = dataSource.getRepository(User);
await repository.query('DELETE FROM public.user');
});
});

it("회원가입 된 유저가 로그인 요청을 한 경우", async () => {

const userInfoDto: UserInfoDto = {
email: "[email protected]",
password: "",
provider: "naver",
nickName: "test",
region: "인천",
birthdate: "1999/10/13",
isMale: true,
};

await userService.signup(userInfoDto);

const loginRequestUser = {
email: "[email protected]"
}

const result = await authService.signin(loginRequestUser);
expect(result).toBeDefined();
expect(jwtService.verify(result.accessToken)).toBeTruthy();
expect(jwtService.verify(result.refreshToken)).toBeTruthy();
})

it("회원가입이 안된 유저가 로그인 요청을 한 경우",async () => {
const loginRequestUser = {
email: "[email protected]"
}

await expect(authService.signin(loginRequestUser))
.rejects
.toThrow(HttpException);
})

it("정상적인 리프레쉬 토큰을 받은 경우", async () => {
const refreshToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ0ZXN0IiwiaWQiOi0xLCJpYXQiOjIwMTYyMzkwMjJ9.zOd1UtNxKjPqNUYGapfDgqY78M5iBEj2Ike386HTDOA"

const result = await authService.checkRefreshToken(refreshToken);

expect(result).toBeDefined();
expect(jwtService.verify(result.accessToken)).toBeTruthy();
})

it("비정상적인 리프레쉬 토큰을 받은 경우", async () => {
const refreshToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ0ZXN0IiwiaWQiOjEsImlhdCI6MjAxNjIzOTAyMn0.3nRp6Qdxf5xj2C0M7-0lOURWx-dAKEjl9eS9dRoQTsA"

await expect(authService.checkRefreshToken(refreshToken))
.rejects
.toThrow(HttpException);
})
});
9 changes: 9 additions & 0 deletions be/src/aws/aws.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Global, Module } from '@nestjs/common';
import { AwsService } from './aws.service';

@Global()
@Module({
providers: [AwsService],
exports: [AwsService],
})
export class AwsModule {}
18 changes: 18 additions & 0 deletions be/src/aws/aws.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AwsService } from './aws.service';

describe('AwsService', () => {
let service: AwsService;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [AwsService],
}).compile();

service = module.get<AwsService>(AwsService);
});

it('should be defined', () => {
expect(service).toBeDefined();
});
});
38 changes: 38 additions & 0 deletions be/src/aws/aws.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Injectable } from "@nestjs/common";
import * as AWS from "aws-sdk";
import { awsConfig } from "objectStorage.config";
import { v4 } from "uuid";

@Injectable()
export class AwsService {
private s3: AWS.S3;

constructor() {
this.s3 = new AWS.S3({
endpoint: awsConfig.endpoint,
region: awsConfig.region,
credentials: {
accessKeyId: awsConfig.accessKey,
secretAccessKey: awsConfig.secretKey,
},
});
}

async uploadToS3(path: string, data: Buffer){
await this.s3.putObject({
Bucket: awsConfig.bucket,
Key: path,
Body: data,
}).promise();
}

getImageURL(path: string) {
const signedUrl = this.s3.getSignedUrl("getObject", {
Bucket: awsConfig.bucket,
Key: path,
Expires: 60,
});

return signedUrl;
}
}
Loading