diff --git a/apps/frontend/src/app/mock/MockRepository/MockRepository.ts b/apps/frontend/src/app/mock/MockRepository/MockRepository.ts index 20f6646..25f7dc1 100644 --- a/apps/frontend/src/app/mock/MockRepository/MockRepository.ts +++ b/apps/frontend/src/app/mock/MockRepository/MockRepository.ts @@ -2,7 +2,7 @@ export type Identifiable = T & { id: string }; export class MockRepository { private _autoId = 0; - private memory: Identifiable[] = []; + protected memory: Identifiable[] = []; private isMatch(owner: Partial, target: Partial): boolean { for (const key in target) { @@ -16,29 +16,11 @@ export class MockRepository { return true; } - private isPartialMatch(owner: Partial, target: Partial): boolean { - for (const key in target) { - if (!Object.prototype.hasOwnProperty.call(owner, key)) return false; - - const ownerValue = owner[key as keyof T]; - const targetValue = target[key as keyof T]; - - if (typeof ownerValue === 'boolean' && ownerValue !== targetValue) { - return false; - } - - if (typeof targetValue === 'string' && !(ownerValue as string)?.includes(targetValue)) { - return false; - } - } - return true; - } - private generateId() { return String(this._autoId++); } - private paginate(items: Identifiable[], page: number, size: number) { + protected paginate(items: Identifiable[], page: number, size: number) { const start = (page - 1) * size; const end = start + size; const data = items.slice(start, end); @@ -88,9 +70,4 @@ export class MockRepository { return data; } - - async search({ query, page = 1, size = 10 }: { query?: Partial>; page?: number; size?: number }) { - const filtered = query ? this.memory.filter((item) => this.isPartialMatch(item, query)) : this.memory; - return this.paginate(filtered, page, size); - } } diff --git a/apps/frontend/src/app/mock/gistResolvers.ts b/apps/frontend/src/app/mock/controller/gistController.ts similarity index 100% rename from apps/frontend/src/app/mock/gistResolvers.ts rename to apps/frontend/src/app/mock/controller/gistController.ts diff --git a/apps/frontend/src/app/mock/controller/historyController.ts b/apps/frontend/src/app/mock/controller/historyController.ts new file mode 100644 index 0000000..51e0686 --- /dev/null +++ b/apps/frontend/src/app/mock/controller/historyController.ts @@ -0,0 +1,93 @@ +import { DefaultBodyType, HttpResponse, PathParams, StrictRequest } from 'msw'; +import { historyRepository } from '@/app/mock/repository/historyRepository'; + +// Lotus History 목록 조회 +export const getHistoryList = async ({ + request, + params +}: { + request: StrictRequest; + params: PathParams; +}) => { + const { lotusId } = params; + + const url = new URL(request.url); + const page = Number(url.searchParams.get('page')) || 1; + + if (!lotusId) { + return new HttpResponse('Bad Request', { + status: 400, + headers: { + 'Content-Type': 'text/plain' + } + }); + } + const { data, maxPage: max } = await historyRepository.findMany({ page }); + const list = data.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime()); + + return HttpResponse.json({ + list, + page: { + current: page, + max + } + }); +}; + +// 코드 실행 +interface PostCodeRunBody { + input?: string; + execFileName: string; +} + +export const postCodeRun = async ({ request }: { request: StrictRequest }) => { + const body = (await request.json()) as PostCodeRunBody; + + if (!body?.execFileName) + return new HttpResponse('Bad Request', { + status: 400, + headers: { + 'Content-Type': 'text/plain' + } + }); + + const newHistory = await historyRepository.create({ + filename: body.execFileName, + date: new Date().toISOString(), + status: 'PENDING', + input: body?.input ?? '', + output: '' + }); + + setTimeout(() => { + historyRepository.update( + { id: newHistory.id }, + { + status: 'SUCCESS', + output: `입력한 값: ${newHistory.input} ` + } + ); + }, 2000); + + return HttpResponse.json({ + status: newHistory.status + }); +}; + +// 해당 히스토리 정보 +export const getHistory = async ({ params }: { params: PathParams }) => { + const { lotusId, historyId } = params; + + if (!lotusId || !historyId) { + return new HttpResponse('Bad Request', { + status: 400, + headers: { + 'Content-Type': 'text/plain' + } + }); + } + + const history = await historyRepository.findOne({ id: historyId as string }); + + return HttpResponse.json(history); +}; diff --git a/apps/frontend/src/app/mock/controller/lotusController.ts b/apps/frontend/src/app/mock/controller/lotusController.ts new file mode 100644 index 0000000..3871749 --- /dev/null +++ b/apps/frontend/src/app/mock/controller/lotusController.ts @@ -0,0 +1,129 @@ +import { DefaultBodyType, HttpResponse, PathParams, StrictRequest } from 'msw'; +import { lotusMockFileData, lotusRepository } from '@/app/mock/repository/lotusRepository'; +import { userRepository } from '@/app/mock/repository/userRepository'; +import { LotusDto } from '@/feature/lotus'; + +const MOCK_UUID = 'mock-uuid'; + +// 사용자의 Lotus 목록 조회 +export const getUserLotusList = async ({ request }: { request: StrictRequest }) => { + const authorization = request.headers.get('Authorization'); + + const [type, token] = authorization?.split(' ') || []; + + if (token !== MOCK_UUID || type !== 'Bearer') { + return new HttpResponse('Unauthorized: Invalid or missing token', { + status: 401, + headers: { + 'Content-Type': 'text/plain' + } + }); + } + + const url = new URL(request.url); + const page = Number(url.searchParams.get('page')) || 1; + const size = Number(url.searchParams.get('size')) || 5; + + const { data: lotuses, maxPage: max } = await lotusRepository.findMany({ page, size }); + + return HttpResponse.json({ + lotuses, + page: { + current: page, + max + } + }); +}; + +// public lotus 목록 조회 +export const getPublicLotusList = async ({ request }: { request: StrictRequest }) => { + const url = new URL(request.url); + const page = Number(url.searchParams.get('page')) || 1; + const size = Number(url.searchParams.get('size')) || 5; + const search = url.searchParams.get('search') || ''; + + const { data: lotuses, maxPage: max } = await lotusRepository.search({ + query: { title: search, isPublic: true }, + page, + size + }); + + return HttpResponse.json({ + lotuses, + page: { + current: page, + max + } + }); +}; + +// public lotus 상세 조회 +export const getLotusDetail = async ({ params }: { params: Record }) => { + const lotusId = params.lotusId; + + const lotus = await lotusRepository.findOne({ id: lotusId }); + + return HttpResponse.json({ ...lotus, ...lotusMockFileData }); +}; + +type CreateLotusDto = { + title: string; + isPublic: false; + tags: string[]; + gistUuid: string; +}; + +//lotus 생성 +export const postCreateLotus = async ({ request }: { request: StrictRequest }) => { + const body = (await request.json()) as CreateLotusDto; + + const author = await userRepository.findOne({ id: '0' }); + + const lotus = await lotusRepository.create({ + ...body, + date: new Date().toISOString(), + author, + logo: '/image/exampleImage.jpeg', + link: 'https://devblog.com/articles/1000000001', + isPublic: false, + gistUrl: '' + }); + + return HttpResponse.json(lotus); +}; + +// lotus 수정 +export const patchLotus = async ({ + params, + request +}: { + params: PathParams; + request: StrictRequest; +}) => { + const { id } = params; + + const body = (await request.json()) as Partial; + + if (!id || typeof id !== 'string') return HttpResponse.json({ message: 'id is required' }); + + const lotus = await lotusRepository.findOne({ id }); + + const updatedLotus = await lotusRepository.update(lotus, body); + + return HttpResponse.json(updatedLotus); +}; + +// lotus 삭제 +export const deleteLotus = async ({ params }: { params: PathParams }) => { + const { id } = params; + + if (!id || typeof id !== 'string') return HttpResponse.json({ message: 'id is required' }); + + const lotus = await lotusRepository.findOne({ + id + }); + + await lotusRepository.delete(lotus); + + return HttpResponse.json(lotus); +}; diff --git a/apps/frontend/src/app/mock/userResolvers.ts b/apps/frontend/src/app/mock/controller/userController.ts similarity index 76% rename from apps/frontend/src/app/mock/userResolvers.ts rename to apps/frontend/src/app/mock/controller/userController.ts index 1dd517f..356fac1 100644 --- a/apps/frontend/src/app/mock/userResolvers.ts +++ b/apps/frontend/src/app/mock/controller/userController.ts @@ -1,25 +1,7 @@ import { DefaultBodyType, HttpResponse, StrictRequest } from 'msw'; -import { MockRepository } from './MockRepository'; +import { MOCK_CODE, MOCK_UUID, userRepository } from '@/app/mock/repository/userRepository'; import { UserDto } from '@/feature/user'; -const MOCK_CODE = 'mock-code'; -const MOCK_UUID = 'mock-uuid'; - -const userList = new MockRepository>(); - -const insertUser = () => { - const userMock: UserDto = { - id: '1', - nickname: 'mockUser', - profile: '/image/exampleImage.jpeg', - gistUrl: 'https://github.com' - }; - - userList.create(userMock); -}; - -insertUser(); - // github 사용자 기본 정보 조회 api export const getUserInfo = async ({ request }: { request: StrictRequest }) => { const authorization = request.headers.get('Authorization'); @@ -35,13 +17,12 @@ export const getUserInfo = async ({ request }: { request: StrictRequest }) => { const authorization = request.headers.get('Authorization'); @@ -57,9 +38,9 @@ export const patchUserInfo = async ({ request }: { request: StrictRequest; - const user = await userList.findOne({ id: '0' }); + const user = await userRepository.findOne({ id: '0' }); - const updatedUser = await userList.update(user, body); + const updatedUser = await userRepository.update(user, body); return HttpResponse.json(updatedUser); } catch (error) { diff --git a/apps/frontend/src/app/mock/handlers.ts b/apps/frontend/src/app/mock/handlers.ts index 73504cf..0b43908 100644 --- a/apps/frontend/src/app/mock/handlers.ts +++ b/apps/frontend/src/app/mock/handlers.ts @@ -1,6 +1,6 @@ import { http } from 'msw'; -import { getGistDetail, getUserGistList } from './gistResolvers'; -import { getHistory, getHistoryList, getTagList, postCodeRun, postTag } from './historyResolvers'; +import { getGistDetail, getUserGistList } from './controller/gistController'; +import { getHistory, getHistoryList, postCodeRun } from './controller/historyController'; import { deleteLotus, getLotusDetail, @@ -8,8 +8,8 @@ import { getUserLotusList, patchLotus, postCreateLotus -} from './lotusResolvers'; -import { getLogin, getUserInfo, patchUserInfo } from './userResolvers'; +} from './controller/lotusController'; +import { getLogin, getUserInfo, patchUserInfo } from './controller/userController'; const apiUrl = (path: string) => `${import.meta.env.VITE_API_URL}${path}`; @@ -19,6 +19,7 @@ export const handlers = [ http.patch(apiUrl(`/api/user`), patchUserInfo), http.get(apiUrl(`/api/user/login/callback`), getLogin), http.get(apiUrl(`/api/user/lotus`), getUserLotusList), + // gist http.get(apiUrl(`/api/user/gist`), getUserGistList), http.get(apiUrl(`/api/user/gist/:gistId`), getGistDetail), // lotus @@ -27,11 +28,13 @@ export const handlers = [ http.post(apiUrl(`/api/lotus`), postCreateLotus), http.patch(apiUrl(`/api/lotus/:id`), patchLotus), http.delete(apiUrl(`/api/lotus/:id`), deleteLotus), + http.get(apiUrl(`/api/lotus`), getPublicLotusList), + http.get(apiUrl(`/api/lotus/:lotusId`), getLotusDetail), + http.post(apiUrl(`/api/lotus`), postCreateLotus), + http.patch(apiUrl(`/api/lotus/:id`), patchLotus), + http.delete(apiUrl(`/api/lotus/:id`), deleteLotus), // history http.get(apiUrl(`/api/lotus/:lotusId/history`), getHistoryList), http.post(apiUrl(`/api/lotus/:lotusId/history`), postCodeRun), - http.get(apiUrl(`/api/lotus/:lotusId/history/:historyId`), getHistory), - // tag - http.get(apiUrl(`/api/tag`), getTagList), - http.post(apiUrl(`/api/tag`), postTag) + http.get(apiUrl(`/api/lotus/:lotusId/history/:historyId`), getHistory) ]; diff --git a/apps/frontend/src/app/mock/historyResolvers.ts b/apps/frontend/src/app/mock/historyResolvers.ts deleted file mode 100644 index 453de15..0000000 --- a/apps/frontend/src/app/mock/historyResolvers.ts +++ /dev/null @@ -1,207 +0,0 @@ -import { DefaultBodyType, HttpResponse, PathParams, StrictRequest } from 'msw'; -import { MockRepository } from './MockRepository'; -import { HistoryDto } from '@/feature/history'; - -const historyList = new MockRepository>(); - -const insertHistory = () => { - const historyMock: HistoryDto[] = [ - { - id: '2000001', - status: 'SUCCESS', - date: '2024-11-15T14:30:00Z', - filename: 'main.js', - input: '11', - output: '3' - }, - { - id: '2000002', - status: 'SUCCESS', - date: '2024-11-16T12:00:00Z', - filename: 'index.js', - input: '12', - output: 'console.log(7)' - }, - { - id: '2000003', - status: 'ERROR', - date: '2024-11-14T16:45:00Z', - filename: 'main.js', - input: '13', - output: 'Error: Cannot find module' - } - ]; - - for (const item of historyMock) { - historyList.create(item); - } -}; - -insertHistory(); - -// Lotus History 목록 조회 -export const getHistoryList = async ({ - request, - params -}: { - request: StrictRequest; - params: PathParams; -}) => { - const { lotusId } = params; - - const url = new URL(request.url); - const page = Number(url.searchParams.get('page')) || 1; - - if (!lotusId) { - return new HttpResponse('Bad Request', { - status: 400, - headers: { - 'Content-Type': 'text/plain' - } - }); - } - const { data, maxPage: max } = await historyList.findMany({ page }); - const list = data.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime()); - - return HttpResponse.json({ - list, - page: { - current: page, - max - } - }); -}; - -// 코드 실행 -interface PostCodeRunBody { - input?: string; - execFileName: string; -} - -export const postCodeRun = async ({ request }: { request: StrictRequest }) => { - const body = (await request.json()) as PostCodeRunBody; - - if (!body?.execFileName) - return new HttpResponse('Bad Request', { - status: 400, - headers: { - 'Content-Type': 'text/plain' - } - }); - - const newHistory = await historyList.create({ - filename: body.execFileName, - date: new Date().toISOString(), - status: 'PENDING', - input: body?.input ?? '', - output: '' - }); - - setTimeout(() => { - historyList.update( - { id: newHistory.id }, - { - status: 'SUCCESS', - output: `입력한 값: ${newHistory.input} ` - } - ); - }, 2000); - - return HttpResponse.json({ - status: newHistory.status - }); -}; - -// 해당 히스토리 정보 -export const getHistory = async ({ params }: { params: PathParams }) => { - const { lotusId, historyId } = params; - - if (!lotusId || !historyId) { - return new HttpResponse('Bad Request', { - status: 400, - headers: { - 'Content-Type': 'text/plain' - } - }); - } - - const history = await historyList.findOne({ id: historyId as string }); - - return HttpResponse.json(history); -}; - -// 태그 조회 -export const getTagList = ({ request }: { request: StrictRequest }) => { - const authorization = request.headers.get('Authorization'); - - if (!authorization || !authorization.startsWith('Bearer ')) { - return new HttpResponse('Unauthorized: Invalid or missing token', { - status: 401, - headers: { - 'Content-Type': 'text/plain' - } - }); - } - - const url = new URL(request.url); - const keyword = url.searchParams.get('keyword'); - - if (!keyword) { - return new HttpResponse('Bad Request', { - status: 400, - headers: { - 'Content-Type': 'text/plain' - } - }); - } - - return HttpResponse.json({ - tags: [ - { - tagName: 'TypeScript' - }, - { - tagName: 'Generics' - }, - { - tagName: 'Programming' - } - ] - }); -}; - -// 태그 생성 -interface PostTagBody { - tag: string; -} - -export const postTag = async ({ request }: { request: StrictRequest }) => { - const authorization = request.headers.get('Authorization'); - - if (!authorization || !authorization.startsWith('Bearer ')) { - return new HttpResponse('Unauthorized: Invalid or missing token', { - status: 401, - headers: { - 'Content-Type': 'text/plain' - } - }); - } - - try { - const body = (await request.json()) as PostTagBody; - - if (!body) throw new Error('요청 형식이 올바르지 않음'); - - return HttpResponse.json({ - message: '성공' - }); - } catch (error) { - console.error(error); - return new HttpResponse('Bad Request', { - status: 400, - headers: { - 'Content-Type': 'text/plain' - } - }); - } -}; diff --git a/apps/frontend/src/app/mock/lotusResolvers.ts b/apps/frontend/src/app/mock/lotusResolvers.ts deleted file mode 100644 index ba95478..0000000 --- a/apps/frontend/src/app/mock/lotusResolvers.ts +++ /dev/null @@ -1,362 +0,0 @@ -import { DefaultBodyType, HttpResponse, PathParams, StrictRequest } from 'msw'; -import { MockRepository } from './MockRepository'; -import { LotusDto } from '@/feature/lotus'; -import { UserDto } from '@/feature/user'; - -const lotusList = new MockRepository>(); - -insertLotus(); - -const MOCK_UUID = 'mock-uuid'; - -// 사용자의 Lotus 목록 조회 -export const getUserLotusList = async ({ request }: { request: StrictRequest }) => { - const authorization = request.headers.get('Authorization'); - - const [type, token] = authorization?.split(' ') || []; - - if (token !== MOCK_UUID || type !== 'Bearer') { - return new HttpResponse('Unauthorized: Invalid or missing token', { - status: 401, - headers: { - 'Content-Type': 'text/plain' - } - }); - } - - const url = new URL(request.url); - const page = Number(url.searchParams.get('page')) || 1; - const size = Number(url.searchParams.get('size')) || 5; - - const { data: lotuses, maxPage: max } = await lotusList.findMany({ page, size }); - - return HttpResponse.json({ - lotuses, - page: { - current: page, - max - } - }); -}; - -// public lotus 목록 조회 -export const getPublicLotusList = async ({ request }: { request: StrictRequest }) => { - const url = new URL(request.url); - const page = Number(url.searchParams.get('page')) || 1; - const size = Number(url.searchParams.get('size')) || 5; - const search = url.searchParams.get('search') || ''; - - const { data: lotuses, maxPage: max } = await lotusList.search({ - query: { title: search, isPublic: true }, - page, - size - }); - - return HttpResponse.json({ - lotuses, - page: { - current: page, - max - } - }); -}; - -// public lotus 상세 조회 -export const getLotusDetail = async ({ params }: { params: Record }) => { - const lotusId = params.lotusId; - - const lotus = await lotusList.findOne({ id: lotusId }); - - return HttpResponse.json({ - ...lotus, - language: 'javascript', - files: [ - { - filename: 'index.js', - language: 'javascript', - content: "console.log('Hello, World!');" - }, - { - filename: 'run.js', - language: 'javascript', - content: `function run() {\n console.log('Running...');\n}` - }, - { - filename: 'README.md', - language: 'markdown', - content: - '## #️⃣연관된 이슈\n' + - '\n' + - '#71\n' + - '\n' + - '## 📝작업 내용\n' + - '\n' + - '- MockRepository를 사용해 동적인 Mocking 구현\n' + - '- lotusList api 계층\n' + - '- lotusList query 계층\n' + - '- SuspenseLotusCardList 구현\n' + - '\n' + - '### 스크린샷 (선택)\n' + - '\n' + - '![lotusListPage](https://github.com/user-attachments/assets/01fa0ad7-f556-485f-b442-2b9a51161f0d)\n' + - '\n' + - '## 💬리뷰 요구사항(선택)\n' + - '\n' + - '> 모킹파일을 건드리고, 구조화 했더니 변경사항이 너무 많네요.. 죄송합니다.\n' + - '\n' + - '네이밍이 이상하거나 이해가 가지 않는 부분 모두 코멘트 남겨주세요!\n' + - '\n' + - '모킹은 순차적으로 동적으로 변경해볼 예정입니다.\n' + - '\n' + - '파일 경로나 query-key 구조화 같은 경우에는 추후에 정리가 필요해보입니다.\n' - } - ] - }); -}; - -type CreateLotusDto = { - title: string; - isPublic: false; - tags: string[]; - gistUuid: string; -}; - -//lotus 생성 -export const postCreateLotus = async ({ request }: { request: StrictRequest }) => { - const body = (await request.json()) as CreateLotusDto; - - const lotus = await lotusList.create({ - ...body, - date: new Date().toISOString(), - author: { id: '1', nickname: 'js_master', profile: 'https://devblog.com/authors/js_master', gistUrl: '' }, - logo: "data:image/png;base64,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';", - link: 'https://devblog.com/articles/1000000001', - isPublic: false, - gistUrl: '' - }); - - return HttpResponse.json(lotus); -}; - -// lotus 수정 -export const patchLotus = async ({ - params, - request -}: { - params: PathParams; - request: StrictRequest; -}) => { - const { id } = params; - - const body = (await request.json()) as Partial; - - if (!id || typeof id !== 'string') return HttpResponse.json({ message: 'id is required' }); - - const lotus = await lotusList.findOne({ id }); - - const updatedLotus = await lotusList.update(lotus, body); - - return HttpResponse.json(updatedLotus); -}; - -// lotus 삭제 -export const deleteLotus = async ({ params }: { params: PathParams }) => { - const { id } = params; - - if (!id || typeof id !== 'string') return HttpResponse.json({ message: 'id is required' }); - - const lotus = await lotusList.findOne({ - id - }); - - await lotusList.delete(lotus); - - return HttpResponse.json(lotus); -}; - -function insertLotus() { - const jsImage = - 'data:image/png;base64,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'; - - const mockLotusData: (LotusDto & { author: UserDto })[] = [ - { - id: '1000000001', - link: 'https://devblog.com/articles/1000000001', - title: 'Understanding JavaScript Closures', - logo: jsImage, - date: new Date('2024-11-01').toISOString(), - tags: ['JavaScript', 'Closures', 'Web Development'], - author: { - id: '0', - nickname: 'js_master', - profile: 'https://devblog.com/authors/js_master', - gistUrl: '' - }, - isPublic: true, - gistUrl: '' - }, - { - id: '1000000002', - link: 'https://devblog.com/articles/1000000002', - title: 'A Guide to Responsive Design with CSS', - logo: jsImage, - date: new Date('2024-10-28').toISOString(), - tags: ['CSS', 'Responsive Design', 'Frontend'], - author: { - id: '2', - nickname: 'css_wizard', - profile: 'https://devblog.com/authors/css_wizard', - gistUrl: '' - }, - isPublic: true, - gistUrl: '' - }, - { - id: '1000000003', - link: 'https://devblog.com/articles/1000000003', - title: 'TypeScript vs JavaScript: Key Differences', - logo: jsImage, - date: new Date('2024-10-25').toISOString(), - tags: ['TypeScript', 'JavaScript', 'Programming'], - author: { - id: '3', - nickname: 'ts_guru', - profile: 'https://devblog.com/authors/ts_guru', - gistUrl: '' - }, - isPublic: true, - gistUrl: '' - }, - { - id: '1000000004', - link: 'https://devblog.com/articles/1000000004', - title: 'How to Build RESTful APIs with Node.js', - logo: jsImage, - date: new Date('2024-10-20').toISOString(), - tags: ['Node.js', 'API', 'Backend'], - author: { - id: '4', - nickname: 'node_dev', - profile: 'https://devblog.com/authors/node_dev', - gistUrl: '' - }, - isPublic: false, - gistUrl: '' - }, - { - id: '1000000005', - link: 'https://devblog.com/articles/1000000005', - title: 'Top 10 Python Libraries for Data Science', - logo: jsImage, - date: new Date('2024-10-15').toISOString(), - tags: ['Python', 'Data Science', 'Libraries'], - author: { - id: '5', - nickname: 'data_scientist', - profile: 'https://devblog.com/authors/data_scientist', - gistUrl: '' - }, - isPublic: true, - gistUrl: '' - }, - { - id: '1000000006', - link: 'https://devblog.com/articles/1000000006', - title: 'React State Management: Context vs Redux', - logo: jsImage, - date: new Date('2024-10-10').toISOString(), - tags: ['React', 'Redux', 'Frontend'], - author: { - id: '6', - nickname: 'react_expert', - profile: 'https://devblog.com/authors/react_expert', - gistUrl: '' - }, - isPublic: false, - gistUrl: '' - }, - { - id: '1000000007', - link: 'https://devblog.com/articles/1000000007', - title: 'Mastering Git: Branching and Merging', - logo: jsImage, - date: new Date('2024-10-05').toISOString(), - tags: ['Git', 'Version Control', 'DevOps'], - author: { - id: '7', - nickname: 'git_master', - profile: 'https://devblog.com/authors/git_master', - gistUrl: '' - }, - isPublic: true, - gistUrl: '' - }, - { - id: '1000000008', - link: 'https://devblog.com/articles/1000000008', - title: 'Introduction to Kubernetes for Beginners', - logo: jsImage, - date: new Date('2024-10-01').toISOString(), - tags: ['Kubernetes', 'DevOps', 'Containers'], - author: { - id: '8', - nickname: 'k8s_pro', - profile: 'https://devblog.com/authors/k8s_pro', - gistUrl: '' - }, - isPublic: true, - gistUrl: '' - }, - { - id: '1000000009', - link: 'https://devblog.com/articles/1000000009', - title: 'Building Scalable Microservices with Spring Boot', - logo: jsImage, - date: new Date('2024-09-25').toISOString(), - tags: ['Spring Boot', 'Microservices', 'Backend'], - author: { - id: '9', - nickname: 'spring_dev', - profile: 'https://devblog.com/authors/spring_dev', - gistUrl: '' - }, - isPublic: false, - gistUrl: '' - }, - { - id: '1000000010', - link: 'https://devblog.com/articles/1000000010', - title: 'GraphQL Basics: Query Language for APIs', - logo: jsImage, - date: new Date('2024-09-20').toISOString(), - tags: ['GraphQL', 'API', 'Web Development'], - author: { - id: '10', - nickname: 'graphql_guru', - profile: 'https://devblog.com/authors/graphql_guru', - gistUrl: '' - }, - isPublic: true, - gistUrl: '' - }, - { - id: '1000000011', - link: 'https://devblog.com/articles/1000000011', - title: 'Understanding Docker: A Comprehensive Guide', - logo: jsImage, - date: new Date('2024-09-15').toISOString(), - tags: ['Docker', 'DevOps', 'Containers'], - author: { - id: '11', - nickname: 'docker_wizard', - profile: 'https://devblog.com/authors/docker_wizard', - gistUrl: '' - }, - isPublic: true, - gistUrl: '' - } - ]; - mockLotusData.forEach((lotus) => { - lotusList.create(lotus); - }); -} diff --git a/apps/frontend/src/app/mock/repository/historyRepository.ts b/apps/frontend/src/app/mock/repository/historyRepository.ts new file mode 100644 index 0000000..3a666b1 --- /dev/null +++ b/apps/frontend/src/app/mock/repository/historyRepository.ts @@ -0,0 +1,39 @@ +import { MockRepository } from '@/app/mock/MockRepository'; +import { HistoryDto } from '@/feature/history'; + +export const historyRepository = new MockRepository>(); + +const insertHistory = () => { + const historyMock: HistoryDto[] = [ + { + id: '2000001', + status: 'SUCCESS', + date: '2024-11-15T14:30:00Z', + filename: 'main.js', + input: '11', + output: '3' + }, + { + id: '2000002', + status: 'SUCCESS', + date: '2024-11-16T12:00:00Z', + filename: 'index.js', + input: '12', + output: 'console.log(7)' + }, + { + id: '2000003', + status: 'ERROR', + date: '2024-11-14T16:45:00Z', + filename: 'main.js', + input: '13', + output: 'Error: Cannot find module' + } + ]; + + for (const item of historyMock) { + historyRepository.create(item); + } +}; + +insertHistory(); diff --git a/apps/frontend/src/app/mock/repository/lotusRepository/index.ts b/apps/frontend/src/app/mock/repository/lotusRepository/index.ts new file mode 100644 index 0000000..019765b --- /dev/null +++ b/apps/frontend/src/app/mock/repository/lotusRepository/index.ts @@ -0,0 +1,2 @@ +export * from './lotusRepository'; +export * from './lotusMockData'; diff --git a/apps/frontend/src/app/mock/repository/lotusRepository/lotusMockData.ts b/apps/frontend/src/app/mock/repository/lotusRepository/lotusMockData.ts new file mode 100644 index 0000000..238ce5a --- /dev/null +++ b/apps/frontend/src/app/mock/repository/lotusRepository/lotusMockData.ts @@ -0,0 +1,228 @@ +import { LotusDto } from '@/feature/lotus'; +import { UserDto } from '@/feature/user'; + +// Lotus 더미데이터 +export const lotusMockData: (LotusDto & { author: UserDto })[] = [ + { + id: '1000000001', + link: 'https://devblog.com/articles/1000000001', + title: 'Understanding JavaScript Closures', + logo: '/image/exampleImage.jpeg', + date: new Date('2024-11-01').toISOString(), + tags: ['JavaScript', 'Closures', 'Web Development'], + author: { + id: '0', + nickname: 'js_master', + profile: 'https://devblog.com/authors/js_master', + gistUrl: '' + }, + isPublic: true, + gistUrl: '' + }, + { + id: '1000000002', + link: 'https://devblog.com/articles/1000000002', + title: 'A Guide to Responsive Design with CSS', + logo: '/image/exampleImage.jpeg', + date: new Date('2024-10-28').toISOString(), + tags: ['CSS', 'Responsive Design', 'Frontend'], + author: { + id: '2', + nickname: 'css_wizard', + profile: 'https://devblog.com/authors/css_wizard', + gistUrl: '' + }, + isPublic: true, + gistUrl: '' + }, + { + id: '1000000003', + link: 'https://devblog.com/articles/1000000003', + title: 'TypeScript vs JavaScript: Key Differences', + logo: '/image/exampleImage.jpeg', + date: new Date('2024-10-25').toISOString(), + tags: ['TypeScript', 'JavaScript', 'Programming'], + author: { + id: '3', + nickname: 'ts_guru', + profile: 'https://devblog.com/authors/ts_guru', + gistUrl: '' + }, + isPublic: true, + gistUrl: '' + }, + { + id: '1000000004', + link: 'https://devblog.com/articles/1000000004', + title: 'How to Build RESTful APIs with Node.js', + logo: '/image/exampleImage.jpeg', + date: new Date('2024-10-20').toISOString(), + tags: ['Node.js', 'API', 'Backend'], + author: { + id: '4', + nickname: 'node_dev', + profile: 'https://devblog.com/authors/node_dev', + gistUrl: '' + }, + isPublic: false, + gistUrl: '' + }, + { + id: '1000000005', + link: 'https://devblog.com/articles/1000000005', + title: 'Top 10 Python Libraries for Data Science', + logo: '/image/exampleImage.jpeg', + date: new Date('2024-10-15').toISOString(), + tags: ['Python', 'Data Science', 'Libraries'], + author: { + id: '5', + nickname: 'data_scientist', + profile: 'https://devblog.com/authors/data_scientist', + gistUrl: '' + }, + isPublic: true, + gistUrl: '' + }, + { + id: '1000000006', + link: 'https://devblog.com/articles/1000000006', + title: 'React State Management: Context vs Redux', + logo: '/image/exampleImage.jpeg', + date: new Date('2024-10-10').toISOString(), + tags: ['React', 'Redux', 'Frontend'], + author: { + id: '6', + nickname: 'react_expert', + profile: 'https://devblog.com/authors/react_expert', + gistUrl: '' + }, + isPublic: false, + gistUrl: '' + }, + { + id: '1000000007', + link: 'https://devblog.com/articles/1000000007', + title: 'Mastering Git: Branching and Merging', + logo: '/image/exampleImage.jpeg', + date: new Date('2024-10-05').toISOString(), + tags: ['Git', 'Version Control', 'DevOps'], + author: { + id: '7', + nickname: 'git_master', + profile: 'https://devblog.com/authors/git_master', + gistUrl: '' + }, + isPublic: true, + gistUrl: '' + }, + { + id: '1000000008', + link: 'https://devblog.com/articles/1000000008', + title: 'Introduction to Kubernetes for Beginners', + logo: '/image/exampleImage.jpeg', + date: new Date('2024-10-01').toISOString(), + tags: ['Kubernetes', 'DevOps', 'Containers'], + author: { + id: '8', + nickname: 'k8s_pro', + profile: 'https://devblog.com/authors/k8s_pro', + gistUrl: '' + }, + isPublic: true, + gistUrl: '' + }, + { + id: '1000000009', + link: 'https://devblog.com/articles/1000000009', + title: 'Building Scalable Microservices with Spring Boot', + logo: '/image/exampleImage.jpeg', + date: new Date('2024-09-25').toISOString(), + tags: ['Spring Boot', 'Microservices', 'Backend'], + author: { + id: '9', + nickname: 'spring_dev', + profile: 'https://devblog.com/authors/spring_dev', + gistUrl: '' + }, + isPublic: false, + gistUrl: '' + }, + { + id: '1000000010', + link: 'https://devblog.com/articles/1000000010', + title: 'GraphQL Basics: Query Language for APIs', + logo: '/image/exampleImage.jpeg', + date: new Date('2024-09-20').toISOString(), + tags: ['GraphQL', 'API', 'Web Development'], + author: { + id: '10', + nickname: 'graphql_guru', + profile: 'https://devblog.com/authors/graphql_guru', + gistUrl: '' + }, + isPublic: true, + gistUrl: '' + }, + { + id: '1000000011', + link: 'https://devblog.com/articles/1000000011', + title: 'Understanding Docker: A Comprehensive Guide', + logo: '/image/exampleImage.jpeg', + date: new Date('2024-09-15').toISOString(), + tags: ['Docker', 'DevOps', 'Containers'], + author: { + id: '11', + nickname: 'docker_wizard', + profile: 'https://devblog.com/authors/docker_wizard', + gistUrl: '' + }, + isPublic: true, + gistUrl: '' + } +]; + +// Lotus File 더미데이터 +export const lotusMockFileData = { + language: 'javascript', + files: [ + { + filename: 'index.js', + language: 'javascript', + content: "console.log('Hello, World!');" + }, + { + filename: 'run.js', + language: 'javascript', + content: `function run() {\n console.log('Running...');\n}` + }, + { + filename: 'README.md', + language: 'markdown', + content: + '## #️⃣연관된 이슈\n' + + '\n' + + '#71\n' + + '\n' + + '## 📝작업 내용\n' + + '\n' + + '- MockRepository를 사용해 동적인 Mocking 구현\n' + + '- lotusList api 계층\n' + + '- lotusList query 계층\n' + + '- SuspenseLotusCardList 구현\n' + + '\n' + + '### 스크린샷 (선택)\n' + + '\n' + + '![lotusListPage](https://github.com/user-attachments/assets/01fa0ad7-f556-485f-b442-2b9a51161f0d)\n' + + '\n' + + '## 💬리뷰 요구사항(선택)\n' + + '\n' + + '> 모킹파일을 건드리고, 구조화 했더니 변경사항이 너무 많네요.. 죄송합니다.\n' + + '\n' + + '네이밍이 이상하거나 이해가 가지 않는 부분 모두 코멘트 남겨주세요!\n' + + '\n' + + '모킹은 순차적으로 동적으로 변경해볼 예정입니다.\n' + + '\n' + + '파일 경로나 query-key 구조화 같은 경우에는 추후에 정리가 필요해보입니다.\n' + } + ] +}; diff --git a/apps/frontend/src/app/mock/repository/lotusRepository/lotusRepository.ts b/apps/frontend/src/app/mock/repository/lotusRepository/lotusRepository.ts new file mode 100644 index 0000000..1f61eb6 --- /dev/null +++ b/apps/frontend/src/app/mock/repository/lotusRepository/lotusRepository.ts @@ -0,0 +1,35 @@ +import { lotusMockData } from './lotusMockData'; +import { MockRepository } from '@/app/mock/MockRepository'; +import { LotusDto } from '@/feature/lotus'; +import { UserDto } from '@/feature/user'; + +class LotusRepository extends MockRepository> { + private isPartialMatch(owner: Partial, target: Partial): boolean { + for (const key in target) { + if (!Object.prototype.hasOwnProperty.call(owner, key)) return false; + + const ownerValue = owner[key as keyof LotusDto]; + const targetValue = target[key as keyof LotusDto]; + + if (typeof targetValue === 'boolean' && ownerValue !== targetValue) return false; + if (typeof targetValue === 'string' && !(ownerValue as string)?.includes(targetValue)) return false; + } + return true; + } + + async search({ query, page = 1, size = 10 }: { query?: Partial; page?: number; size?: number }) { + const filtered = query ? this.memory.filter((item) => this.isPartialMatch(item, query)) : this.memory; + + return this.paginate(filtered, page, size); + } +} + +export const lotusRepository = new LotusRepository(); + +const insertLotus = () => { + lotusMockData.forEach((lotus) => { + lotusRepository.create(lotus); + }); +}; + +insertLotus(); diff --git a/apps/frontend/src/app/mock/repository/userRepository.ts b/apps/frontend/src/app/mock/repository/userRepository.ts new file mode 100644 index 0000000..b8657c7 --- /dev/null +++ b/apps/frontend/src/app/mock/repository/userRepository.ts @@ -0,0 +1,20 @@ +import { MockRepository } from '@/app/mock/MockRepository'; +import { UserDto } from '@/feature/user'; + +export const MOCK_CODE = 'mock-code'; +export const MOCK_UUID = 'mock-uuid'; + +export const userRepository = new MockRepository>(); + +const insertUser = () => { + const userMock: UserDto = { + id: '1', + nickname: 'mockUser', + profile: '/image/exampleImage.jpeg', + gistUrl: 'https://github.com' + }; + + userRepository.create(userMock); +}; + +insertUser();