diff --git a/src/__tests__/kkuko/profile/components/ItemModal.test.tsx b/src/__tests__/kkuko/profile/components/ItemModal.test.tsx index 5822b54..9692298 100644 --- a/src/__tests__/kkuko/profile/components/ItemModal.test.tsx +++ b/src/__tests__/kkuko/profile/components/ItemModal.test.tsx @@ -13,6 +13,7 @@ jest.mock('@/app/kkuko/profile/utils/profileHelper', () => ({ })); jest.mock('@/app/kkuko/shared/lib/const', () => ({ NICKNAME_COLORS: {}, + OPTION_NAMES: { gEXP: '획득 경험치' } })); describe('ItemModal', () => { @@ -28,7 +29,7 @@ describe('ItemModal', () => { name: 'Cool Hat', image: 'hat.png', desc: 'A nice hat', - options: { score: 10 } + options: { gEXP: 0.1 } }, ] as any; @@ -38,8 +39,8 @@ describe('ItemModal', () => { expect(screen.getByText('장착 아이템 목록')).toBeInTheDocument(); expect(screen.getByText('Cool Hat')).toBeInTheDocument(); - expect(screen.getByText('score:')).toBeInTheDocument(); - expect(screen.getByText('+10')).toBeInTheDocument(); + expect(screen.getByText('gEXP:')).toBeInTheDocument(); + expect(screen.getByText('+10%p')).toBeInTheDocument(); }); it('should call onClose when close button is clicked', () => { diff --git a/src/__tests__/kkuko/profile/components/ProfileHeader.test.tsx b/src/__tests__/kkuko/profile/components/ProfileHeader.test.tsx index 0364cec..2726f26 100644 --- a/src/__tests__/kkuko/profile/components/ProfileHeader.test.tsx +++ b/src/__tests__/kkuko/profile/components/ProfileHeader.test.tsx @@ -37,7 +37,7 @@ describe('ProfileHeader', () => { }); it('should render user info', () => { - render(); + render( {}} isRefreshing={false} />); expect(screen.getByText('Test Nick')).toBeInTheDocument(); expect(screen.getByText('Hello World')).toBeInTheDocument(); @@ -47,7 +47,7 @@ describe('ProfileHeader', () => { }); it('should render badges', () => { - render(); + render( {}} isRefreshing={false} />); expect(screen.getByAltText('Best Badge')).toBeInTheDocument(); }); diff --git a/src/__tests__/kkuko/profile/components/ProfileStats.test.tsx b/src/__tests__/kkuko/profile/components/ProfileStats.test.tsx index 658bed7..122c0ae 100644 --- a/src/__tests__/kkuko/profile/components/ProfileStats.test.tsx +++ b/src/__tests__/kkuko/profile/components/ProfileStats.test.tsx @@ -14,7 +14,7 @@ describe('ProfileStats', () => { beforeEach(() => { (profileHelper.calculateTotalOptions as jest.Mock).mockReturnValue({ - 'str': 10000, + 'hEXP': 10000, 'gEXP': 5000 }); (profileHelper.getOptionName as jest.Mock).mockImplementation((key) => key); @@ -24,8 +24,8 @@ describe('ProfileStats', () => { it('should render total options correctly', () => { render(); - // STR: 10000 -> +10 - expect(screen.getByText('str')).toBeInTheDocument(); + // hEXP: 10000 -> +10 + expect(screen.getByText('hEXP')).toBeInTheDocument(); expect(screen.getByText('+10')).toBeInTheDocument(); // gEXP: 5000 -> +5%p diff --git a/src/__tests__/kkuko/profile/utils/profileHelper.test.ts b/src/__tests__/kkuko/profile/utils/profileHelper.test.ts index 4f0cbfa..7f17ea2 100644 --- a/src/__tests__/kkuko/profile/utils/profileHelper.test.ts +++ b/src/__tests__/kkuko/profile/utils/profileHelper.test.ts @@ -72,13 +72,13 @@ describe('profileHelper', () => { describe('calculateTotalOptions', () => { it('should calculate totals correctly for normal options', () => { const items: ItemInfo[] = [ - { id: '1', name: 'Item1', description: '', group: '', options: { str: 1, dex: 2 }, updatedAt: 1 }, - { id: '2', name: 'Item2', description: '', group: '', options: { str: 3 }, updatedAt: 1 } + { id: '1', name: 'Item1', description: '', group: '', options: { gEXP: 0.01, dex: 2 }, updatedAt: 1 }, + { id: '2', name: 'Item2', description: '', group: '', options: { gEXP: 0.03 }, updatedAt: 1 } ]; const result = calculateTotalOptions(items); - // 1 * 1 + 3 * 1 = 4 - expect(result['str']).toBe(4); - expect(result['dex']).toBe(2); + // 0.01 + 0.03 = 0.04 -> formatted to 4 + expect(result['gEXP']).toBe(4); + expect(result['dex']).toBe(undefined); }); it('should handle special options', () => { @@ -88,14 +88,14 @@ describe('profileHelper', () => { id: '3', name: 'Special', description: '', group: '', options: { date: now - 10000, // Past - before: { str: 1 }, - after: { str: 5 } + before: { gEXP: 0.01 }, + after: { gEXP: 0.05 } }, updatedAt: 1 } ]; const result = calculateTotalOptions(items); // Should use 'after' - expect(result['str']).toBe(5); + expect(result['gEXP']).toBe(5); }); it('should handle special options (before)', () => { @@ -105,14 +105,14 @@ describe('profileHelper', () => { id: '3', name: 'Special', description: '', group: '', options: { date: now + 10000, // Future - before: { str: 1 }, - after: { str: 5 } + before: { gEXP: 0.01 }, + after: { gEXP: 0.05 } }, updatedAt: 1 } ]; const result = calculateTotalOptions(items); // Should use 'before' - expect(result['str']).toBe(1); + expect(result['gEXP']).toBe(1); }); }); diff --git a/src/app/api/kkuko/api/ranking/route.ts b/src/app/api/kkuko/api/ranking/route.ts index edf8f40..e53b7f6 100644 --- a/src/app/api/kkuko/api/ranking/route.ts +++ b/src/app/api/kkuko/api/ranking/route.ts @@ -1,36 +1,42 @@ import { NextRequest, NextResponse } from 'next/server'; -import axios from 'axios'; type RankingResponse = { target: string; data: { - id: string, - rank: number, - score: number, - nick: string - diff: string - }[] + id: string; + rank: number; + score: number; + nick: string; + diff: string; + }[]; }; -export async function GET(request: NextRequest){ +export async function GET(request: NextRequest) { try { const id = request.nextUrl.searchParams.get('id'); - if (!id || isNaN(Number(id))){ - return NextResponse.json( - { error: 'Invalid ranking ID' }, - { status: 400 } - ); + + if (!id || isNaN(Number(id))) { + return NextResponse.json({ error: 'Invalid ranking ID' }, { status: 400 }); } - const res = await axios.get(`https://kkutu.co.kr/o/ranking?id=${id}`); - const rankingData = res.data.data.find(user => user.id === id); + + const res = await fetch(`https://kkutu.co.kr/o/ranking?id=${id}`, { + next: { revalidate: 300 } + }); + + if (!res.ok) throw new Error('Network response was not ok'); + + const data: RankingResponse = await res.json(); + const rankingData = data.data.find(user => user.id === id); + if (!rankingData) { - return NextResponse.json( - { error: 'User not found in ranking data' }, - { status: 404 } - ); - } else { - return NextResponse.json({rank: rankingData.rank + 1, id: rankingData.id}); + return NextResponse.json({ error: 'User not found' }, { status: 404 }); } + + return NextResponse.json({ + rank: rankingData.rank + 1, + id: rankingData.id + }); + } catch { return NextResponse.json( { error: 'Failed to fetch ranking data' }, diff --git a/src/app/kkuko/profile/components/ProfileHeader.tsx b/src/app/kkuko/profile/components/ProfileHeader.tsx index 3289f37..c50883c 100644 --- a/src/app/kkuko/profile/components/ProfileHeader.tsx +++ b/src/app/kkuko/profile/components/ProfileHeader.tsx @@ -5,7 +5,7 @@ import Link from 'next/link'; import { ItemInfo, ProfileData } from '@/src/app/types/kkuko.types'; import TryRenderImg from '../../shared/components/TryRenderImg'; import ProfileAvatar from '../../shared/components/ProfileAvatar'; -import { formatLastSeen, formatObservedAt, getNicknameStyle } from '../utils/profileHelper'; +import { formatObservedAt, getNicknameStyle } from '../utils/profileHelper'; interface ProfileHeaderProps { profileData: ProfileData; @@ -117,34 +117,6 @@ export default function ProfileHeader({

{formatObservedAt(profileData.user.observedAt)}

-
-

접속 상태

-

- {profileData.presence.channelId ? ( - 온라인 - ) : ( - 오프라인 - )} -

- {profileData.presence.channelId ? ( -

채널: {profileData.presence.channelId}

- ) : ( - profileData.presence.updatedAt !== null ? -

마지막 접속: {formatLastSeen(profileData.presence.updatedAt)}

: - null - )} -
- -
-

방 정보

-

- {profileData.presence.roomId ? ( - 방 {profileData.presence.roomId} - ) : ( - 미입장 - )} -

-