Skip to content

Commit

Permalink
Merge pull request #51 from DevKor-github/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
astorverse authored Aug 2, 2024
2 parents 29f1df5 + 64d93db commit 791e033
Show file tree
Hide file tree
Showing 9 changed files with 219 additions and 49 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/deploy-to-master.yml
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ jobs:
ssh -i deploy_key.pem $SERVER "aws ecr get-login-password --region ${{ env.AWS_DEFAULT_REGION }} | docker login --username AWS --password-stdin ${{ env.ECR_URL }}"
ssh -i deploy_key.pem $SERVER "docker pull ${{ env.ECR_URL }}/${{ env.SERVICE_NAME }}:${{ env.DOCKER_TAG }}"
ssh -i deploy_key.pem $SERVER "docker run --env-file /home/${{ env.ACCOUNT }}/upload/.env.prod -d -p $NEW_PORT:3000 --name $NEW_SERVICE_NAME -e TZ=Asia/Seoul ${{ env.ECR_URL }}/${{ env.SERVICE_NAME }}:${{ env.DOCKER_TAG }}"
ssh -i deploy_key.pem $SERVER "docker run --env-file /home/${{ env.ACCOUNT }}/upload/.env.prod -d -p $NEW_PORT:3000 --name $NEW_SERVICE_NAME -e TZ=Asia/Seoul ${{ env.ECR_URL }}/${{ env.SERVICE_NAME }}:${{ env.DOCKER_TAG }} --network blccu_network"
for i in {1..20}; do
HEALTH_CHECK=$(ssh -i deploy_key.pem $SERVER "curl -v -s -o /dev/null -w '%{http_code}' http://localhost:$NEW_PORT/health || true")
Expand Down
4 changes: 2 additions & 2 deletions deploy/deploy-prod.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ fi
# PEM 파일 권한 확인 및 수정
chmod 400 "$PEM_PATH"

HOSTS=("13.209.215.21" "3.35.68.4")
HOSTS=("13.209.215.21")
ACCOUNT=ubuntu
SERVICE_NAME=blccu
DOCKER_TAG=latest
Expand Down Expand Up @@ -66,7 +66,7 @@ for HOST in "${HOSTS[@]}"; do
echo -e "\n## new docker pull & run on $HOST ##\n"
ssh -i $PEM_PATH $SERVER "aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin $ECR_URL"
ssh -i $PEM_PATH $SERVER "docker pull $ECR_URL/$SERVICE_NAME:$DOCKER_TAG"
ssh -i $PEM_PATH $SERVER "docker run --env-file /home/$ACCOUNT/upload/.env.prod -d -p $NEW_PORT:3000 --name $NEW_SERVICE_NAME -e TZ=Asia/Seoul $ECR_URL/$SERVICE_NAME"
ssh -i $PEM_PATH $SERVER "docker run --env-file /home/$ACCOUNT/upload/.env.prod -d -p $NEW_PORT:3000 --name $NEW_SERVICE_NAME -e TZ=Asia/Seoul $ECR_URL/$SERVICE_NAME --network blccu_network"

# 헬스체크 수행
echo -e "\n## 헬스체크 수행 on $HOST ##\n"
Expand Down
83 changes: 63 additions & 20 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -1,23 +1,66 @@
version: "3.7"
networks:
t4y:
driver: bridge
blccu_network:
external: true

services:
blccu-ecr:
build:
context: .
dockerfile: Dockerfile
args:
PLATFORM: linux/amd64
redis:
image: redis:latest
ports:
- 3000:3000
env_file:
- ./.env.prod
# my-database:
# image: "mysql:latest"
# restart: always
# env_file:
# - ./.env.prod
# environment:
# MYSQL_DATABASE: 'mydocker'
# MYSQL_ROOT_PASSWORD: 'root'
# ports:
# - 3306:3306
- '6379:6379'
restart: always
networks:
- blccu_network
# prometheus:
# image: prom/prometheus
# container_name: prometheus
# volumes:
# - ./prometheus/config:/etc/prometheus
# - prometheus-data:/prometheus
# ports:
# - 9090:9090
# command:
# - '--storage.tsdb.path=/prometheus'
# - '--config.file=/etc/prometheus/prometheus.yaml'
# restart: always
# networks:
# - t4y

# grafana:
# image: grafana/grafana
# container_name: grafana
# ports:
# - 9000:3000
# volumes:
# - grafana-data:/var/lib/grafana
# - ./grafana/provisioning/:/etc/grafana/provisioning/
# restart: always
# depends_on:
# - prometheus
# networks:
# - t4y

# volumes:
# grafana-data:
# prometheus-data:
# blccu-ecr:
# build:
# context: .
# dockerfile: Dockerfile
# args:
# PLATFORM: linux/amd64
# ports:
# - 3000:3000
# env_file:
# - ./.env.prod
# my-database:
# image: "mysql:latest"
# restart: always
# env_file:
# - ./.env.prod
# environment:
# MYSQL_DATABASE: 'mydocker'
# MYSQL_ROOT_PASSWORD: 'root'
# ports:
# - 3306:3306
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@
"**/*.(t|j)s"
],
"coverageDirectory": "../coverage",
"testEnvironment": "node"
"testEnvironment": "node",
"moduleNameMapper": {
"^src/(.*)$": "<rootDir>/$1",
"^@/(.*)$": "<rootDir>/$1"
}
}
}
143 changes: 143 additions & 0 deletions src/APIs/agreements/__test__/agreements.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AgreementsService } from '../agreements.service';
import { AgreementsRepository } from '../agreements.repository';
import { UsersValidateService } from '@/APIs/users/services/users-validate-service';
import { AgreementDto } from '../dtos/common/agreement.dto';
import { Agreement } from '../entities/agreement.entity';
import { plainToClass } from 'class-transformer';
import fs from 'fs';
import { AgreementType } from '@/common/enums/agreement-type.enum';
import { BlccuException } from '@/common/blccu-exception';

describe('AgreementsService', () => {
let service: AgreementsService;
let repo: AgreementsRepository;
let usersValidateService: UsersValidateService;

const agreementEntity: Agreement = {
id: 1,
user: null,
userId: 1,
agreementType: AgreementType.TERMS_OF_SERVICE,
isAgreed: true,
dateCreated: new Date(),
dateUpdated: new Date(),
dateDeleted: null,
};

const agreementDto: AgreementDto = plainToClass(
AgreementDto,
agreementEntity,
);

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
AgreementsService,
{
provide: AgreementsRepository,
useValue: {
save: jest.fn().mockResolvedValue(agreementEntity),
findOne: jest.fn().mockResolvedValue(agreementEntity),
find: jest.fn().mockResolvedValue([agreementEntity]),
},
},
{
provide: UsersValidateService,
useValue: {
adminCheck: jest.fn(),
},
},
],
}).compile();

service = module.get<AgreementsService>(AgreementsService);
repo = module.get<AgreementsRepository>(AgreementsRepository);
usersValidateService =
module.get<UsersValidateService>(UsersValidateService);
});

it('adminCheck_ShouldCallAdminCheck_ValidUserId', async () => {
const userId = 1;
await service.adminCheck({ userId });
expect(usersValidateService.adminCheck).toHaveBeenCalledWith({ userId });
});

it('createAgreement_ShouldReturnAgreementDto_ValidInput', async () => {
const result = await service.createAgreement({
userId: 1,
agreementType: AgreementType.TERMS_OF_SERVICE,
isAgreed: true,
});

expect(result).toEqual(agreementDto);
expect(repo.save).toHaveBeenCalledWith({
agreementType: AgreementType.TERMS_OF_SERVICE,
isAgreed: true,
userId: 1,
});
});

it('findContract_ShouldReturnContractHtml_ValidAgreementType', async () => {
const agreementType = AgreementType.TERMS_OF_SERVICE;
const mockData = '<html>Contract Terms</html>';

jest.spyOn(fs.promises, 'readFile').mockResolvedValue(mockData);

const result = await service.findContract({ agreementType });

expect(result).toBe(mockData);
});

it('findAgreement_ShouldReturnAgreementDto_ValidAgreementId', async () => {
const result = await service.findAgreement({ agreementId: 1 });

expect(result).toEqual(agreementDto);
expect(repo.findOne).toHaveBeenCalledWith({ where: { id: 1 } });
});

it('existCheck_ShouldThrowBlccuException_AgreementNotFound', async () => {
jest.spyOn(service, 'findAgreement').mockResolvedValue(null);

await expect(service.existCheck({ agreementId: 1 })).rejects.toThrow(
new BlccuException('AGREEMENT_NOT_FOUND'),
);
});

it('findAgreements_ShouldReturnAgreementDtoArray_ValidUserId', async () => {
const result = await service.findAgreements({ userId: 1 });

expect(result).toEqual([agreementDto]);
expect(repo.find).toHaveBeenCalledWith({ where: { user: { id: 1 } } });
});

it('patchAgreement_ShouldThrowBlccuException_NotTheOwner', async () => {
const otherUserAgreement: Agreement = { ...agreementEntity, userId: 2 };

jest.spyOn(service, 'existCheck').mockResolvedValue(otherUserAgreement);

await expect(
service.patchAgreement({
userId: 1,
agreementId: 1,
isAgreed: true,
}),
).rejects.toThrow(new BlccuException('NOT_THE_OWNER'));
});

it('patchAgreement_ShouldReturnUpdatedAgreement_ValidInput', async () => {
const updatedAgreement: Agreement = { ...agreementEntity, isAgreed: true };

jest.spyOn(service, 'existCheck').mockResolvedValue(agreementEntity);
jest.spyOn(repo, 'save').mockResolvedValue(updatedAgreement);

const result = await service.patchAgreement({
userId: 1,
agreementId: 1,
isAgreed: true,
});

expect(result).toEqual(plainToClass(AgreementDto, updatedAgreement));
expect(repo.save).toHaveBeenCalledWith(updatedAgreement);
});
});
2 changes: 1 addition & 1 deletion src/APIs/articles/services/articles-delete.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { IArticlesServiceArticleUserIdPair } from '../interfaces/articles.servic
import { ArticlesReadRepository } from '../repositories/articles-read.repository';
import { ImagesService } from 'src/modules/images/images.service';
import { MergeExceptionMetadata } from '@/common/decorators/merge-exception-metadata.decorator';
import { IsUrl, isURL } from 'class-validator';
import { isURL } from 'class-validator';

@Injectable()
export class ArticlesDeleteService {
Expand Down
4 changes: 3 additions & 1 deletion src/APIs/users/dtos/common/user.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ export class UserDto extends OmitType(User, [
export const USER_SELECT_OPTION: { [key: string]: boolean } =
getUserFields().reduce(
(options, field) => {
options[field] = true;
if (field !== 'currentRefreshToken') {
options[field] = true;
}
return options;
},
{} as { [key: string]: boolean },
Expand Down
22 changes: 0 additions & 22 deletions src/app.controller.spec.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/modules/aws/aws.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export class AwsService {
throw new BlccuException('IMAGE_UPLOAD_TO_S3_ERROR');
}
}
@ExceptionMetadata([EXCEPTIONS.IMAGE_DELETE_FROM_S3_ERROR])
// @ExceptionMetadata([EXCEPTIONS.IMAGE_DELETE_FROM_S3_ERROR])
async deleteImageFromS3({ url }) {
try {
const fileNameRegex = /\/([^\/]+)\.[^.]+$/;
Expand Down

0 comments on commit 791e033

Please sign in to comment.