Files
FabledCurator/frontend/test/components/postCard.spec.js
T
bvandeusen 509a7958cf
CI / lint (push) Successful in 2s
CI / backend-lint-and-test (push) Successful in 11s
CI / frontend-build (push) Successful in 27s
CI / integration (push) Successful in 3m2s
feat(posts): images open the modal; only text expands in place
Post cards no longer expand the whole card on click (the old two-click path
to the images). The card is compact-only now:
- Hero / rail thumbs / the +N tile are buttons that open the post-scoped image
  modal (modal.open(id, { postImageIds })) so you view big + arrow through ALL
  the post's images. The feed caps thumbnails at 6, so for posts with more we
  lazily getPostFull to get the complete id list; +N opens at the first hidden
  image.
- The description is the ONLY in-place expansion: a Show more / Show less toggle
  shown only when the text is actually truncated (server description_truncated
  flag OR a measured CSS-clamp overflow, ResizeObserver-guarded). Expanding
  loads description_full when server-truncated and renders it unclamped.
- Attachments: download chips now render inline in the compact card (the feed
  already carries download_url), since the expanded view is gone.

Removes PostImageGrid.vue (the mosaic, now unused). Tests cover show-more
visibility + image-click opening the scoped modal.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 17:29:19 -04:00

62 lines
2.3 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')
})
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, { postImageIds: [10, 11] })
})
})