mirror of
https://git.shipoclu.com/moon/plspace.git
synced 2026-08-13 02:42:30 +00:00
124 lines
4.1 KiB
TypeScript
124 lines
4.1 KiB
TypeScript
import { fireEvent, render, waitFor } from '@testing-library/svelte'
|
|
import { describe, expect, it, vi } from 'vitest'
|
|
import { APP_SERVICES } from '$lib/app-services'
|
|
import type { ApiClient } from '$lib/api/client'
|
|
import type { Poll } from '$lib/api/types'
|
|
import { account, session, testServices } from '$test/fixtures'
|
|
import PollView from './PollView.svelte'
|
|
|
|
function poll(overrides: Partial<Poll> = {}): Poll {
|
|
return {
|
|
id: 'poll-1',
|
|
expires_at: '2099-01-01T00:00:00.000Z',
|
|
expired: false,
|
|
multiple: false,
|
|
votes_count: 0,
|
|
options: [
|
|
{ title: 'Cats', votes_count: null },
|
|
{ title: 'Dogs', votes_count: null },
|
|
{ title: 'Both', votes_count: null },
|
|
],
|
|
emojis: [],
|
|
voted: false,
|
|
own_votes: [],
|
|
...overrides,
|
|
}
|
|
}
|
|
|
|
function signedServices(
|
|
votePoll: (api: ApiClient, id: string, choices: number[]) => Promise<Poll>,
|
|
) {
|
|
return testServices({
|
|
session: session({ token: 'token', me: account(), signedIn: true }),
|
|
endpoints: { votePoll },
|
|
})
|
|
}
|
|
|
|
describe('PollView', () => {
|
|
it('submits one selected index and immediately shows returned results', async () => {
|
|
const updated = poll({
|
|
voted: true,
|
|
votes_count: 3,
|
|
own_votes: [1],
|
|
options: [
|
|
{ title: 'Cats', votes_count: 1 },
|
|
{ title: 'Dogs', votes_count: 2 },
|
|
{ title: 'Both', votes_count: 0 },
|
|
],
|
|
})
|
|
const votePoll = vi.fn().mockResolvedValue(updated)
|
|
const onupdate = vi.fn()
|
|
const view = render(PollView, {
|
|
props: { poll: poll(), authorId: 'someone-else', onupdate },
|
|
context: new Map([[APP_SERVICES, signedServices(votePoll)]]),
|
|
})
|
|
|
|
await fireEvent.click(view.getByRole('radio', { name: 'Dogs' }))
|
|
await fireEvent.click(view.getByRole('button', { name: 'Vote' }))
|
|
|
|
await waitFor(() => expect(votePoll).toHaveBeenCalledOnce())
|
|
expect(votePoll.mock.calls[0][1]).toBe('poll-1')
|
|
expect(votePoll.mock.calls[0][2]).toEqual([1])
|
|
expect(onupdate).toHaveBeenCalledWith(updated)
|
|
expect(await view.findByText('67%')).toBeInTheDocument()
|
|
expect(view.getByLabelText('Your vote')).toBeInTheDocument()
|
|
})
|
|
|
|
it('submits every selected index for a multiple-choice poll', async () => {
|
|
const votePoll = vi.fn().mockResolvedValue(
|
|
poll({ multiple: true, voted: true, own_votes: [0, 2] }),
|
|
)
|
|
const view = render(PollView, {
|
|
props: { poll: poll({ multiple: true }), authorId: 'someone-else' },
|
|
context: new Map([[APP_SERVICES, signedServices(votePoll)]]),
|
|
})
|
|
|
|
await fireEvent.click(view.getByRole('checkbox', { name: 'Cats' }))
|
|
await fireEvent.click(view.getByRole('checkbox', { name: 'Both' }))
|
|
await fireEvent.click(view.getByRole('button', { name: 'Vote' }))
|
|
|
|
await waitFor(() => expect(votePoll).toHaveBeenCalledOnce())
|
|
expect(votePoll.mock.calls[0][2]).toEqual([0, 2])
|
|
})
|
|
|
|
it('shows open poll options to signed-out readers without enabling a vote', () => {
|
|
const view = render(PollView, {
|
|
props: { poll: poll(), authorId: 'someone-else' },
|
|
context: new Map([[APP_SERVICES, testServices()]]),
|
|
})
|
|
|
|
expect(view.getByRole('radio', { name: 'Cats' })).toBeDisabled()
|
|
expect(view.getByRole('link', { name: 'Sign in to vote' })).toHaveAttribute('href', '#/login')
|
|
expect(view.queryByRole('button', { name: 'Vote' })).not.toBeInTheDocument()
|
|
})
|
|
|
|
it('renders custom emoji in poll choices', () => {
|
|
const view = render(PollView, {
|
|
props: {
|
|
poll: poll({
|
|
options: [
|
|
{ title: 'Choose :blobcat:', votes_count: null },
|
|
{ title: 'No thanks', votes_count: null },
|
|
],
|
|
emojis: [
|
|
{
|
|
shortcode: 'blobcat',
|
|
url: 'https://cdn.example/blobcat.png',
|
|
static_url: 'https://cdn.example/blobcat.png',
|
|
visible_in_picker: true,
|
|
},
|
|
],
|
|
}),
|
|
authorId: 'someone-else',
|
|
},
|
|
context: new Map([[APP_SERVICES, testServices()]]),
|
|
})
|
|
|
|
expect(view.getByAltText(':blobcat:')).toHaveAttribute(
|
|
'src',
|
|
'https://cdn.example/blobcat.png',
|
|
)
|
|
expect(view.getByRole('radio', { name: 'Choose :blobcat:' })).toBeDisabled()
|
|
})
|
|
})
|