18bb25f140
- heads.py: conf_map = dict(conf) instead of a dict comprehension (ruff C416). - postCard.spec.js: the modal-playlist rename (postImageIds→playlistIds) missed this frontend test (grep was src-only); update the expected call args. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CDgx8bQS5YrGRK76v8HUnM
86 lines
3.6 KiB
JavaScript
86 lines
3.6 KiB
JavaScript
// @vitest-environment happy-dom
|
|
import { describe, it, expect, vi } from 'vitest'
|
|
import { flushPromises } from '@vue/test-utils'
|
|
|
|
import PostCard from '../../src/components/posts/PostCard.vue'
|
|
import { useModalStore } from '../../src/stores/modal.js'
|
|
import { freshPinia, mountComponent } from '../support/mountComponent.js'
|
|
|
|
const now = new Date().toISOString()
|
|
const BASE = {
|
|
id: 1, external_post_id: 'P1',
|
|
post_title: '<strong>Hello World</strong>',
|
|
post_url: 'https://x/1', post_date: now, downloaded_at: now,
|
|
artist: { id: 1, name: 'Sabu', slug: 'sabu' },
|
|
source: { id: 1, platform: 'subscribestar' },
|
|
thumbnails: [], thumbnails_more: 0, attachments: [],
|
|
}
|
|
|
|
describe('PostCard', () => {
|
|
it('renders the HTML-stripped title and the artist', () => {
|
|
const post = { ...BASE, description_plain: 'a description' }
|
|
const w = mountComponent(PostCard, { props: { post }, pinia: freshPinia() })
|
|
const t = w.text()
|
|
expect(t).toContain('Hello World') // plain title
|
|
expect(t).not.toContain('<strong>') // tags stripped
|
|
expect(t).toContain('Sabu') // artist (RouterLink slot)
|
|
})
|
|
|
|
it('shows a "Show more" toggle only when the description is truncated', () => {
|
|
const truncated = mountComponent(PostCard, {
|
|
props: { post: { ...BASE, description_plain: 'lots of text…', description_truncated: true } },
|
|
pinia: freshPinia(),
|
|
})
|
|
expect(truncated.text()).toContain('Show more')
|
|
|
|
const full = mountComponent(PostCard, {
|
|
props: { post: { ...BASE, description_plain: 'short', description_truncated: false } },
|
|
pinia: freshPinia(),
|
|
})
|
|
expect(full.text()).not.toContain('Show more')
|
|
})
|
|
|
|
const thumbs = (n) =>
|
|
Array.from({ length: n }, (_, i) => ({ image_id: 100 + i, thumbnail_url: `/t${i}` }))
|
|
|
|
it('fills the rail to full width (5 cells, no overflow) for a 6-image post', () => {
|
|
const post = { ...BASE, description_plain: 'd', thumbnails: thumbs(6), thumbnails_more: 0 }
|
|
const w = mountComponent(PostCard, { props: { post }, pinia: freshPinia() })
|
|
// hero + 5 rail thumbnails, no "+N" tile.
|
|
expect(w.findAll('.fc-post-card__rail-cell')).toHaveLength(5)
|
|
expect(w.find('.fc-post-card__rail-more').exists()).toBe(false)
|
|
// The grid spans the hero width via a column count == cells shown.
|
|
expect(w.find('.fc-post-card__rail').attributes('style')).toContain('--fc-rail-cols: 5')
|
|
})
|
|
|
|
it('reserves the last cell for a "+N" overflow tile when there are more images', () => {
|
|
const post = { ...BASE, description_plain: 'd', thumbnails: thumbs(6), thumbnails_more: 4 }
|
|
const w = mountComponent(PostCard, { props: { post }, pinia: freshPinia() })
|
|
// 4 thumbnails + 1 overflow tile == 5 columns; tile counts every hidden image.
|
|
expect(w.findAll('.fc-post-card__rail-cell')).toHaveLength(4)
|
|
const more = w.find('.fc-post-card__rail-more')
|
|
expect(more.exists()).toBe(true)
|
|
expect(more.text()).toBe('+5')
|
|
expect(w.find('.fc-post-card__rail').attributes('style')).toContain('--fc-rail-cols: 5')
|
|
})
|
|
|
|
it('clicking an image opens the post-scoped modal (never expands the card)', async () => {
|
|
const pinia = freshPinia()
|
|
const modal = useModalStore()
|
|
const openSpy = vi.spyOn(modal, 'open').mockResolvedValue()
|
|
const post = {
|
|
...BASE,
|
|
description_plain: 'd',
|
|
thumbnails: [
|
|
{ image_id: 10, thumbnail_url: '/a' },
|
|
{ image_id: 11, thumbnail_url: '/b' },
|
|
],
|
|
thumbnails_more: 0,
|
|
}
|
|
const w = mountComponent(PostCard, { props: { post }, pinia })
|
|
await w.find('.fc-post-card__hero').trigger('click')
|
|
await flushPromises()
|
|
expect(openSpy).toHaveBeenCalledWith(10, { playlistIds: [10, 11] })
|
|
})
|
|
})
|