claude rework

This commit is contained in:
2026-06-07 15:43:43 +02:00
parent a2e2ff141e
commit b4874ad318
63 changed files with 5945 additions and 1752 deletions
@@ -0,0 +1,78 @@
import { describe, it, expect, vi, beforeEach } from 'vitest'
import { mount, flushPromises } from '@vue/test-utils'
import axios from 'axios'
import RssFeeds from '../RssFeeds.vue'
vi.mock('axios')
// jsdom does not implement IntersectionObserver, but the component sets one up
// once the feed list has rendered.
class FakeIntersectionObserver {
observe() {}
unobserve() {}
disconnect() {}
}
vi.stubGlobal('IntersectionObserver', FakeIntersectionObserver)
describe('RssFeeds', () => {
beforeEach(() => {
localStorage.setItem('user-token', 'test-token')
localStorage.setItem('user-id', '7')
vi.clearAllMocks()
})
it('fetches the current user articles and shows the empty state', async () => {
axios.get.mockResolvedValueOnce({ data: { feeds: [] } })
const wrapper = mount(RssFeeds)
await flushPromises()
expect(axios.get).toHaveBeenCalledWith('/api/v1/article/get/7', expect.anything())
expect(wrapper.text()).toContain('No unread articles.')
})
it('renders the fetched feed items', async () => {
axios.get.mockResolvedValueOnce({
data: {
feeds: [
{
title: 'My Feed',
items: [
{
id: 1,
title: 'Article one',
content: '<p>hello</p>',
url: 'https://example.test/1',
timestamp: '2026-01-01',
},
],
},
],
},
})
const wrapper = mount(RssFeeds)
await flushPromises()
expect(wrapper.text()).toContain('Article one')
expect(wrapper.text()).toContain('My Feed')
expect(wrapper.text()).not.toContain('No unread articles.')
})
it('syncs feeds for the current user', async () => {
axios.get.mockResolvedValue({ data: { feeds: [] } })
axios.post.mockResolvedValueOnce({ status: 200 })
const wrapper = mount(RssFeeds)
await flushPromises()
await wrapper.find('.feed-actions p').trigger('click')
await flushPromises()
expect(axios.post).toHaveBeenCalledWith(
'/api/v1/article/sync',
{ user_id: 7 },
expect.anything(),
)
})
})