From 8e57e2f02a8de754408fa9138fb5458ca5b4c20a Mon Sep 17 00:00:00 2001 From: mace Date: Sun, 14 Jun 2026 17:13:41 +0200 Subject: [PATCH] Added sync on reload --- vue/src/components/RssFeeds.vue | 2 ++ vue/src/components/__tests__/RssFeeds.spec.js | 21 ++++++++++++++++--- vue/src/composables/useFeeds.js | 8 ++++--- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/vue/src/components/RssFeeds.vue b/vue/src/components/RssFeeds.vue index 0314883..250ff7b 100644 --- a/vue/src/components/RssFeeds.vue +++ b/vue/src/components/RssFeeds.vue @@ -13,6 +13,7 @@ const { nextArticle, prevArticle, fetchData, + sync, getReadable, setInitialLoad, showMessageForXSeconds, @@ -78,6 +79,7 @@ async function shareUrl(url) { onMounted(async () => { setInitialLoad(false) await fetchData() + sync(true) setTimeout(function () { setInitialLoad(true) console.log('set to true') diff --git a/vue/src/components/__tests__/RssFeeds.spec.js b/vue/src/components/__tests__/RssFeeds.spec.js index 493a704..3d4c168 100644 --- a/vue/src/components/__tests__/RssFeeds.spec.js +++ b/vue/src/components/__tests__/RssFeeds.spec.js @@ -119,7 +119,14 @@ describe('RssFeeds', () => { ], }, }) - axios.post.mockResolvedValueOnce({ data: { content: '

full text

' } }) + // axios.post is also hit by the sync triggered on mount, so branch on the + // URL rather than relying on call order via `mockResolvedValueOnce`. + axios.post.mockImplementation((url) => { + if (url === '/api/v1/article/sync') { + return Promise.resolve({ status: 200 }) + } + return Promise.resolve({ data: { content: '

full text

' } }) + }) const { layout } = useFeeds() layout.value = 'cards' @@ -199,7 +206,14 @@ describe('RssFeeds', () => { ], }, }) - axios.post.mockResolvedValueOnce({ data: { content: '

full text

' } }) + // axios.post is also hit by the sync triggered on mount, so branch on the + // URL rather than relying on call order via `mockResolvedValueOnce`. + axios.post.mockImplementation((url) => { + if (url === '/api/v1/article/sync') { + return Promise.resolve({ status: 200 }) + } + return Promise.resolve({ data: { content: '

full text

' } }) + }) const wrapper = mount(RssFeeds) await flushPromises() @@ -255,7 +269,8 @@ describe('RssFeeds', () => { expect(wrapper.find('.article-single .article-feature__title').text()).toBe('Article one') // Same as in list view: the readable content is loaded on demand by // clicking the headline, not fetched automatically on entering the view. - expect(axios.post).not.toHaveBeenCalled() + // (axios.post is also hit by the sync triggered on mount.) + expect(axios.post).not.toHaveBeenCalledWith('/api/v1/article/read', expect.anything(), expect.anything()) expect(wrapper.find('.article-single .feed-original-link a').exists()).toBe(true) await wrapper.find('.article-single .article-feature__title').trigger('click') diff --git a/vue/src/composables/useFeeds.js b/vue/src/composables/useFeeds.js index 6fbc3b4..f01d969 100644 --- a/vue/src/composables/useFeeds.js +++ b/vue/src/composables/useFeeds.js @@ -159,19 +159,21 @@ const fetchData = async () => { } }; -async function sync() { +async function sync(silent = false) { try { const response = await axios.post('/api/v1/article/sync', { user_id: parseInt(localStorage.getItem("user-id")) }, authHeaders()) - if (response.status == 200) { + if (response.status == 200 && !silent) { showMessageForXSeconds('Sync successful.', 5) } fetchData(); } catch (error) { console.error('Error sync', error) - showMessageForXSeconds(error, 5) + if (!silent) { + showMessageForXSeconds(error, 5) + } } }