feat(products): vitest 도입 + 제품 접근 확장 로직 (music tier 하위 호환)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-11 08:24:33 +09:00
parent fe055fd0d0
commit cf89e8cbdb
5 changed files with 1179 additions and 30 deletions

View File

@@ -0,0 +1,24 @@
import { describe, it, expect } from 'vitest';
import { expandProductAccess, MUSIC_PRODUCT_CHAIN } from '@/lib/product-access';
describe('expandProductAccess', () => {
it('일반 제품은 자기 자신만 반환', () => {
expect(expandProductAccess(['lotto_tool'])).toEqual(['lotto_tool']);
});
it('music_pro는 starter를 포함', () => {
expect(expandProductAccess(['music_pro']).sort()).toEqual(['music_pro', 'music_starter'].sort());
});
it('music_master는 전 tier 포함', () => {
expect(expandProductAccess(['music_master']).sort()).toEqual(
['music_master', 'music_pro', 'music_starter'].sort(),
);
});
it('중복 입력은 중복 없이 반환', () => {
expect(expandProductAccess(['music_pro', 'music_starter']).sort()).toEqual(
['music_pro', 'music_starter'].sort(),
);
});
it('빈 입력은 빈 배열', () => {
expect(expandProductAccess([])).toEqual([]);
});
});

17
lib/product-access.ts Normal file
View File

@@ -0,0 +1,17 @@
/**
* orders 기반 제품 접근 확장.
* 음악 팩 상위 tier는 하위 tier 파일도 포함(하위 호환) — 신규 제품은 1:1.
*/
export const MUSIC_PRODUCT_CHAIN: Record<string, string[]> = {
music_starter: ['music_starter'],
music_pro: ['music_pro', 'music_starter'],
music_master: ['music_master', 'music_pro', 'music_starter'],
};
export function expandProductAccess(paidProductIds: string[]): string[] {
const out = new Set<string>();
for (const id of paidProductIds) {
for (const expanded of MUSIC_PRODUCT_CHAIN[id] ?? [id]) out.add(expanded);
}
return Array.from(out);
}

1155
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -6,7 +6,8 @@
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "eslint"
"lint": "eslint",
"test": "vitest run"
},
"dependencies": {
"@anthropic-ai/sdk": "^0.79.0",
@@ -39,6 +40,7 @@
"eslint": "^9",
"eslint-config-next": "16.1.6",
"tailwindcss": "^4",
"typescript": "^5"
"typescript": "^5",
"vitest": "^4.1.8"
}
}

7
vitest.config.ts Normal file
View File

@@ -0,0 +1,7 @@
import { defineConfig } from 'vitest/config';
import path from 'path';
export default defineConfig({
test: { include: ['lib/**/*.test.ts'] },
resolve: { alias: { '@': path.resolve(__dirname, '.') } },
});