diff --git a/frontend/src/__tests__/api/players.test.ts b/frontend/src/__tests__/api/players.test.ts index 48ee166..f5e9e27 100644 --- a/frontend/src/__tests__/api/players.test.ts +++ b/frontend/src/__tests__/api/players.test.ts @@ -22,6 +22,7 @@ import { giveItem, getAllPlayerMetadata, updatePlayerMetadata, + setPlayerTier, } from '@/api/players' describe('Players API', () => { @@ -96,4 +97,17 @@ describe('Players API', () => { await updatePlayerMetadata('abc', { nameColor: '#00ff00' }) expect(mockPut).toHaveBeenCalledWith('/api/players/metadata/abc', { nameColor: '#00ff00' }) }) + + it('setPlayerTier calls PUT /api/players/metadata/{id}/tier with the tier', async () => { + mockPut.mockResolvedValue({ data: { data: { playerId: 'abc', vipTier: 'VIP' } } }) + const result = await setPlayerTier('abc', 'VIP') + expect(mockPut).toHaveBeenCalledWith('/api/players/metadata/abc/tier', { tier: 'VIP' }) + expect(result.vipTier).toBe('VIP') + }) + + it('setPlayerTier sends null to clear the tier and encodes the id', async () => { + mockPut.mockResolvedValue({ data: { data: { playerId: 'EOS_x/y', vipTier: null } } }) + await setPlayerTier('EOS_x/y', null) + expect(mockPut).toHaveBeenCalledWith('/api/players/metadata/EOS_x%2Fy/tier', { tier: null }) + }) }) diff --git a/frontend/src/__tests__/api/vipperks.test.ts b/frontend/src/__tests__/api/vipperks.test.ts new file mode 100644 index 0000000..447bccd --- /dev/null +++ b/frontend/src/__tests__/api/vipperks.test.ts @@ -0,0 +1,56 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest' + +const mockGet = vi.fn() +const mockPut = vi.fn() + +vi.mock('@/api/client', () => ({ + default: { + get: (...args: any[]) => mockGet(...args), + put: (...args: any[]) => mockPut(...args), + }, +})) + +import { getVipPerksSettings, updateVipPerksSettings, getVipTiers } from '@/api/vipperks' +import type { VipPerksSettings } from '@/types' + +const sampleSettings: VipPerksSettings = { + enabled: true, + tiers: ['VIP', 'VIP+'], + firstLoginPackEnabled: true, + firstLoginTemplateName: 'starter', + firstLoginMessage: 'hi {player}', + tierGifts: [{ tier: 'VIP', templateName: 'weekly-crate', period: 'weekly' }], +} + +describe('VipPerks API', () => { + beforeEach(() => { + mockGet.mockReset() + mockPut.mockReset() + }) + + it('getVipPerksSettings calls GET /api/vipperks/settings', async () => { + mockGet.mockResolvedValue({ data: { data: sampleSettings } }) + const result = await getVipPerksSettings() + expect(mockGet).toHaveBeenCalledWith('/api/vipperks/settings') + expect(result).toEqual(sampleSettings) + }) + + it('updateVipPerksSettings calls PUT /api/vipperks/settings with the body', async () => { + mockPut.mockResolvedValue({ data: {} }) + await updateVipPerksSettings(sampleSettings) + expect(mockPut).toHaveBeenCalledWith('/api/vipperks/settings', sampleSettings) + }) + + it('getVipTiers returns the tier list', async () => { + mockGet.mockResolvedValue({ data: { data: ['VIP', 'VIP+'] } }) + const result = await getVipTiers() + expect(mockGet).toHaveBeenCalledWith('/api/vipperks/tiers') + expect(result).toEqual(['VIP', 'VIP+']) + }) + + it('getVipTiers returns [] when data is null', async () => { + mockGet.mockResolvedValue({ data: { data: null } }) + const result = await getVipTiers() + expect(result).toEqual([]) + }) +}) diff --git a/frontend/src/__tests__/components/PlayerEditDialog.test.ts b/frontend/src/__tests__/components/PlayerEditDialog.test.ts new file mode 100644 index 0000000..93cce95 --- /dev/null +++ b/frontend/src/__tests__/components/PlayerEditDialog.test.ts @@ -0,0 +1,105 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest' +import { mount, flushPromises } from '@vue/test-utils' +import { createPinia } from 'pinia' +import PrimeVue from 'primevue/config' +import PlayerEditDialog from '@/components/PlayerEditDialog.vue' + +const mockUpdatePlayerMetadata = vi.fn() +const mockSetAdminLevel = vi.fn() +const mockSetPlayerTier = vi.fn() +const mockGetVipTiers = vi.fn() + +vi.mock('@/api/players', () => ({ + updatePlayerMetadata: (...a: any[]) => mockUpdatePlayerMetadata(...a), + setAdminLevel: (...a: any[]) => mockSetAdminLevel(...a), + setPlayerTier: (...a: any[]) => mockSetPlayerTier(...a), +})) +vi.mock('@/api/vipperks', () => ({ + getVipTiers: () => mockGetVipTiers(), +})) + +// Store returns no cached metadata by default → tier starts as '' (pleb). +const mockGetMetadata = vi.fn(() => undefined) +vi.mock('@/stores/players', () => ({ + usePlayersStore: () => ({ getMetadata: mockGetMetadata }), +})) + +const player = { + playerId: 'EOS_abc', + playerName: 'Alice', + entityId: 42, + isAdmin: false, + adminLevel: 1000, +} + +function mountDialog() { + return mount(PlayerEditDialog, { + props: { player, visible: false }, + global: { + plugins: [createPinia(), [PrimeVue, { theme: 'none' }]], + stubs: { + Dialog: { template: '
', props: ['visible', 'header', 'modal'] }, + Button: { template: '', props: ['label', 'icon', 'loading', 'text', 'severity', 'size'] }, + InputText: { template: '', props: ['modelValue', 'placeholder'] }, + Textarea: { template: '