diff --git a/components/blocks/Landing/Landing.test.ts b/components/blocks/Landing/Landing.test.ts index 2cee0574..e76fad18 100644 --- a/components/blocks/Landing/Landing.test.ts +++ b/components/blocks/Landing/Landing.test.ts @@ -6,7 +6,7 @@ import LandingLeaderboards from './LandingLeaderboards.vue' const mockSuccessGetLeaderboards = vi.fn(() => Promise.resolve({ ok: true })) vi.mock('lib/api/Leaderboards', () => ({ Leaderboards: function Leaderboards() { - this.getLeaderboards = mockSuccessGetLeaderboards + this.listLeaderboards = mockSuccessGetLeaderboards }, })) diff --git a/components/blocks/Landing/LandingLeaderboards.test.ts b/components/blocks/Landing/LandingLeaderboards.test.ts index a74e0b38..3228761b 100644 --- a/components/blocks/Landing/LandingLeaderboards.test.ts +++ b/components/blocks/Landing/LandingLeaderboards.test.ts @@ -1,5 +1,5 @@ import { mountSuspended } from '@nuxt/test-utils/runtime' -import Landing from './LandingLeaderboards.vue' +import LandingLeaderboards from './LandingLeaderboards.vue' import type { LeaderboardViewModel } from '~/lib/api/data-contracts' const games: LeaderboardViewModel[] = [ @@ -7,7 +7,7 @@ const games: LeaderboardViewModel[] = [ id: 1, name: 'Getting Over It With Bennet Foddy', slug: 'slug-2', - info: null, + info: '', createdAt: '2024-11-02T22:11:08+0000', updatedAt: '2024-11-02T22:11:08+0000', deletedAt: null, @@ -17,7 +17,7 @@ const games: LeaderboardViewModel[] = [ id: 2, name: 'Getting Over It With Bennet Foddy', slug: 'slug-2', - info: null, + info: '', createdAt: '2024-11-02T22:11:08+0000', updatedAt: '2024-11-02T22:11:08+0000', deletedAt: null, @@ -27,7 +27,7 @@ const games: LeaderboardViewModel[] = [ id: 3, name: 'Getting Over It With Bennet Foddy', slug: 'slug-3', - info: null, + info: '', createdAt: '2024-11-02T22:11:08+0000', updatedAt: '2024-11-02T22:11:08+0000', deletedAt: null, @@ -36,12 +36,8 @@ const games: LeaderboardViewModel[] = [ ] describe('LandingLeaderboards Component', () => { - afterEach(() => { - vi.restoreAllMocks() - }) - it('should render without crashing', async () => { - const wrapper = await mountSuspended(Landing, { + const wrapper = await mountSuspended(LandingLeaderboards, { props: { leaderboards: games, }, diff --git a/components/blocks/Landing/LandingLeaderboards.vue b/components/blocks/Landing/LandingLeaderboards.vue index d2deb002..1ba7df19 100644 --- a/components/blocks/Landing/LandingLeaderboards.vue +++ b/components/blocks/Landing/LandingLeaderboards.vue @@ -20,7 +20,7 @@ defineProps() class="mb-2 h-full content-center rounded-lg bg-gray-200 p-8 text-blue-500 underline hover:cursor-pointer" :to=" localePath({ - name: 'board-slug', + name: 'game-slug', params: { slug: leaderboard.slug }, }) " diff --git a/components/blocks/LeaderboardInfo/Desktop/Desktop.test.ts b/components/blocks/LeaderboardInfo/Desktop/Desktop.test.ts deleted file mode 100644 index 5c841c62..00000000 --- a/components/blocks/LeaderboardInfo/Desktop/Desktop.test.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { mountSuspended } from '@nuxt/test-utils/runtime' -import { getByTestId } from 'root/testUtils' -import Desktop from './Desktop.vue' - -describe('', () => { - async function getDesktopWrapper() { - return await mountSuspended(Desktop, { - props: { - leaderboard: { - categories: [{ id: 1, name: 'Any%', slug: 'any' }], - id: 1, - name: 'Stuck in the Train Simulator 2', - slug: 'stuck-in-the-train-sim-2', - }, - todoPlatforms: ['XBox', 'PC'], - }, - }) - } - - afterEach(() => { - vi.restoreAllMocks() - }) - - it('should render without crashing', async () => { - const wrapper = await getDesktopWrapper() - expect(wrapper.isVisible()).toBe(true) - - expect(getByTestId(wrapper, 'title').text()).toBe( - 'Stuck in the Train Simulator 2', - ) - expect(getByTestId(wrapper, 'tag').text()).toBe('Any%') - }) -}) diff --git a/components/blocks/LeaderboardInfo/Desktop/Desktop.vue b/components/blocks/LeaderboardInfo/Desktop/Desktop.vue deleted file mode 100644 index dae18f2d..00000000 --- a/components/blocks/LeaderboardInfo/Desktop/Desktop.vue +++ /dev/null @@ -1,141 +0,0 @@ - - - - - -elements/buttons/Dropdown/Dropdown.vueelements/buttons/Dropdown/DropdownItem.vue diff --git a/components/blocks/LeaderboardInfo/LeaderboardInfo.test.ts b/components/blocks/LeaderboardInfo/LeaderboardInfo.test.ts index 897899e1..bd4bf512 100644 --- a/components/blocks/LeaderboardInfo/LeaderboardInfo.test.ts +++ b/components/blocks/LeaderboardInfo/LeaderboardInfo.test.ts @@ -1,47 +1,30 @@ import { mountSuspended } from '@nuxt/test-utils/runtime' -import { getByTestId } from 'root/testUtils' import LeaderboardInfo from './LeaderboardInfo.vue' +import type { LeaderboardViewModel } from '~/lib/api/data-contracts' -describe('', () => { - async function getLeaderboardInfoWrapper() { - return await mountSuspended(LeaderboardInfo, { +const game: LeaderboardViewModel = { + id: 1, + name: 'Getting Over It With Bennet Foddy', + slug: 'slug-2', + info: 'Something special', + createdAt: '2024-11-02T22:11:08+0000', + updatedAt: '2024-11-02T22:11:08+0000', + deletedAt: null, + categories: [], +} + +describe('LeaderboardInfo Component', () => { + it('should render without crashing', async () => { + const wrapper = await mountSuspended(LeaderboardInfo, { props: { - leaderboard: { - categories: [], - id: 1, - name: 'Stuck in the Train Simulator 2', - slug: 'stuck-in-the-train-sim-2', - }, + leaderboard: game, }, }) - } - afterEach(() => { - vi.restoreAllMocks() - vi.unstubAllGlobals() - }) - - it('should render without crashing', async () => { - const wrapper = await getLeaderboardInfoWrapper() expect(wrapper.isVisible()).toBe(true) - }) - - it('should render if device width is large', async () => { - vi.stubGlobal('innerWidth', 1980) - const wrapper = await getLeaderboardInfoWrapper() - expect(wrapper.html()).toContain('Guides') - }) - it('should render if device width is small', async () => { - vi.stubGlobal('innerWidth', 600) - const wrapper = await getLeaderboardInfoWrapper() - expect(wrapper.html()).toContain('Submit Run') - }) + const header = wrapper.get('div#leaderboard-show-header h1') - // TODO: The follow event doesn't trigger in the test, somehow - it.skip('should emit event when the Follow Button is triggered', async () => { - const wrapper = await getLeaderboardInfoWrapper() - await getByTestId(wrapper, 'child').trigger('follow') - expect(wrapper.emitted().follow).toBeTruthy() + expect(header.text()).toContain(game.name) }) }) diff --git a/components/blocks/LeaderboardInfo/LeaderboardInfo.vue b/components/blocks/LeaderboardInfo/LeaderboardInfo.vue index c9395469..c783dd27 100644 --- a/components/blocks/LeaderboardInfo/LeaderboardInfo.vue +++ b/components/blocks/LeaderboardInfo/LeaderboardInfo.vue @@ -1,55 +1,21 @@ - - - diff --git a/components/blocks/LeaderboardInfo/LeaderboardInfoAccordion.test.ts b/components/blocks/LeaderboardInfo/LeaderboardInfoAccordion.test.ts new file mode 100644 index 00000000..a36560d8 --- /dev/null +++ b/components/blocks/LeaderboardInfo/LeaderboardInfoAccordion.test.ts @@ -0,0 +1,25 @@ +import { mountSuspended } from '@nuxt/test-utils/runtime' +import LeaderboardInfoAccordion from './LeaderboardInfoAccordion.vue' + +const info = 'Some Special Info' + +describe('LeaderboardInfoAccordion Component', () => { + it('should render without crashing', async () => { + const wrapper = await mountSuspended(LeaderboardInfoAccordion, { + props: { + info: info, + }, + }) + + expect(wrapper.isVisible()).toBe(true) + + // click the info button to open the info pane + const button = wrapper.get('button#leaderboard-info-button') + button.trigger('click') + await wrapper.vm.$nextTick() + + const infoText = wrapper.get('p#leaderboard-info-text') + + expect(infoText.text()).toContain(info) + }) +}) diff --git a/components/blocks/LeaderboardInfo/LeaderboardInfoAccordion.vue b/components/blocks/LeaderboardInfo/LeaderboardInfoAccordion.vue new file mode 100644 index 00000000..aadf926e --- /dev/null +++ b/components/blocks/LeaderboardInfo/LeaderboardInfoAccordion.vue @@ -0,0 +1,33 @@ + + + diff --git a/components/blocks/LeaderboardInfo/Mobile/Mobile.test.ts b/components/blocks/LeaderboardInfo/Mobile/Mobile.test.ts deleted file mode 100644 index fce62d74..00000000 --- a/components/blocks/LeaderboardInfo/Mobile/Mobile.test.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { mountSuspended } from '@nuxt/test-utils/runtime' -import { getByTestId } from 'root/testUtils' -import Mobile from './Mobile.vue' - -describe('', () => { - async function getMobileWrapper() { - return await mountSuspended(Mobile, { - props: { - leaderboard: { - categories: [{ id: 1, name: 'Any%', slug: 'any' }], - id: 1, - name: 'Stuck in the Train Simulator 2', - slug: 'stuck-in-the-train-sim-2', - }, - todoPlatforms: ['XBox', 'PC'], - }, - }) - } - - afterEach(() => { - vi.restoreAllMocks() - }) - - it('should render without crashing', async () => { - const wrapper = await getMobileWrapper() - expect(wrapper.isVisible()).toBe(true) - - expect(getByTestId(wrapper, 'title').text()).toBe( - 'Stuck in the Train Simulator 2', - ) - expect(getByTestId(wrapper, 'tag').text()).toBe('Any%') - }) -}) diff --git a/components/blocks/LeaderboardInfo/Mobile/Mobile.vue b/components/blocks/LeaderboardInfo/Mobile/Mobile.vue deleted file mode 100644 index 99c16642..00000000 --- a/components/blocks/LeaderboardInfo/Mobile/Mobile.vue +++ /dev/null @@ -1,84 +0,0 @@ - - - - - diff --git a/components/blocks/LeaderboardInfo/PlatformTags/PlatformTags.test.ts b/components/blocks/LeaderboardInfo/PlatformTags/PlatformTags.test.ts deleted file mode 100644 index 1331bded..00000000 --- a/components/blocks/LeaderboardInfo/PlatformTags/PlatformTags.test.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { mountSuspended } from '@nuxt/test-utils/runtime' -import PlatformTags from './PlatformTags.vue' - -describe('', () => { - const tags = ['XBox', 'PS4', 'Amiga DS'] - - it('should render without crashing', async () => { - const wrapper = await mountSuspended(PlatformTags, { - props: { - tags, - }, - }) - - expect(wrapper.isVisible()).toBe(true) - - wrapper - .getComponent('div.platform-tags') - .findAllComponents('div') - .forEach((c, i) => { - expect(c.text()).toBe(tags[i]) - }) - }) -}) diff --git a/components/blocks/LeaderboardInfo/PlatformTags/PlatformTags.vue b/components/blocks/LeaderboardInfo/PlatformTags/PlatformTags.vue deleted file mode 100644 index ae069c42..00000000 --- a/components/blocks/LeaderboardInfo/PlatformTags/PlatformTags.vue +++ /dev/null @@ -1,22 +0,0 @@ - - - - - diff --git a/composables/api/useGetLeaderboardBySlug/index.ts b/composables/api/useGetLeaderboardBySlug/index.ts index c5f5bc8d..378a8b6c 100644 --- a/composables/api/useGetLeaderboardBySlug/index.ts +++ b/composables/api/useGetLeaderboardBySlug/index.ts @@ -18,7 +18,7 @@ export default async function useGetLeaderboardBySlug( id: -1, name: '', slug: '', - info: null, + info: '', createdAt: '', updatedAt: null, deletedAt: null, diff --git a/composables/api/useGetLeaderboards/index.ts b/composables/api/useGetLeaderboards/index.ts index 7eb394e8..932aa509 100644 --- a/composables/api/useGetLeaderboards/index.ts +++ b/composables/api/useGetLeaderboards/index.ts @@ -18,7 +18,7 @@ export default async function useGetLeaderboards( id: -1, name: '', slug: '', - info: null, + info: '', createdAt: '', updatedAt: null, deletedAt: null, @@ -30,7 +30,7 @@ export default async function useGetLeaderboards( }) return await useApi( - async () => await leaderboardClient.getLeaderboards({}), + async () => await leaderboardClient.listLeaderboards({}), { onError, onOkay, diff --git a/composables/api/useGetLeaderboards/useGetLeaderboards.test.ts b/composables/api/useGetLeaderboards/useGetLeaderboards.test.ts index 2b4ed631..6571303b 100644 --- a/composables/api/useGetLeaderboards/useGetLeaderboards.test.ts +++ b/composables/api/useGetLeaderboards/useGetLeaderboards.test.ts @@ -8,7 +8,7 @@ describe('useGetLeaderboard', () => { it('creates a GET request to fetch the a list of leaderboards', async () => { vi.mock('lib/api/Leaderboards', () => ({ Leaderboards: function Leaderboards() { - this.getLeaderboards = mockSuccessGetLeaderboards + this.listLeaderboards = mockSuccessGetLeaderboards }, })) diff --git a/i18n/en/index.ts b/i18n/en/index.ts index ee03553b..4e78d8b8 100644 --- a/i18n/en/index.ts +++ b/i18n/en/index.ts @@ -12,4 +12,5 @@ export const English = { 'Something went wrong. Reach out to support if the problem persists.', signup: 'Sign Up', welcome: 'Welcome', + info: 'Info', } satisfies LanguageIndexFile diff --git a/i18n/language.ts b/i18n/language.ts index bcabde6d..8aef93e2 100644 --- a/i18n/language.ts +++ b/i18n/language.ts @@ -8,4 +8,5 @@ export interface LanguageIndexFile { confirmationReceived?: string confirmationReceivedText?: string signup?: string + info?: string } diff --git a/pages/board/[slug].vue b/pages/board/[slug].vue deleted file mode 100644 index 588a1d58..00000000 --- a/pages/board/[slug].vue +++ /dev/null @@ -1,21 +0,0 @@ - - - diff --git a/pages/game/[slug].test.ts b/pages/game/[slug].test.ts new file mode 100644 index 00000000..945e69b6 --- /dev/null +++ b/pages/game/[slug].test.ts @@ -0,0 +1,57 @@ +import { mountSuspended } from '@nuxt/test-utils/runtime' +import useGetLeaderboardBySlug from '~/composables/api/useGetLeaderboardBySlug/index' +import gamePage from 'pages/game/[slug].vue' +import { useError } from '#imports' +import type { LeaderboardViewModel } from '~/lib/api/data-contracts' + +const leaderboard: LeaderboardViewModel = { + id: 1, + name: 'Getting Over It With Bennet Foddy', + slug: 'slug-2', + info: '', + createdAt: '2024-11-02T22:11:08+0000', + updatedAt: '2024-11-02T22:11:08+0000', + deletedAt: null, + categories: [], +} + +vi.mock('composables/api/useGetLeaderboardBySlug') + +afterEach(() => { + vi.restoreAllMocks() +}) + +describe('/game/:slug', () => { + it('should render without crashing with a valid leaderboard', async () => { + vi.mocked(useGetLeaderboardBySlug).mockResolvedValue({ + error: null, + loading: false, + data: leaderboard, + errors: null, + }) + const wrapper = await mountSuspended(gamePage, { + route: '/game/validslug', + }) + + expect(wrapper.text()).toContain(leaderboard.name) + expect(wrapper.isVisible()).toBe(true) + }) + + it('should render 404 if leaderboard status is 404', async () => { + vi.mocked(useGetLeaderboardBySlug).mockResolvedValue({ + error: { status: 404 }, + loading: false, + data: leaderboard, + errors: null, + }) + + const wrapper = await mountSuspended(gamePage, { + route: '/game/invalidslug', + }) + + const error = useError() + + expect(error?.value?.statusCode).toBe(404) + expect(wrapper.text()).not.toContain(leaderboard.name) + }) +}) diff --git a/pages/game/[slug].vue b/pages/game/[slug].vue new file mode 100644 index 00000000..aad432f3 --- /dev/null +++ b/pages/game/[slug].vue @@ -0,0 +1,30 @@ + + +