diff --git a/client/src/App.spec.js b/client/src/App.spec.js index 1758ed3..af9a26c 100644 --- a/client/src/App.spec.js +++ b/client/src/App.spec.js @@ -1,6 +1,6 @@ import { flushPromises, mount } from '@vue/test-utils'; import { createMemoryHistory, createRouter } from 'vue-router'; -import { beforeEach, describe, expect, it, vi } from 'vitest'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import App from './App.vue'; @@ -47,6 +47,8 @@ function createRouterForTest() { } describe('App', () => { + let openSpy; + beforeEach(() => { apiMocks.fetchCategories.mockResolvedValue([]); apiMocks.fetchHotKeywords.mockResolvedValue([]); @@ -65,6 +67,7 @@ describe('App', () => { description: 'Simple tool', category: { id: 'cat_demo', name: 'Developer Tools' }, tags: ['cli'], + displayVersion: '2026.04', latestVersion: '1.0.0', updatedAt: '2026-04-11', accessMode: 'web', @@ -95,10 +98,17 @@ describe('App', () => { features: [], updatedAt: '2026-04-11', openUrl: 'https://example.com/tool', + displayVersion: '2026.04', latestVersion: null, fileSize: null, downloadReady: true, }); + + openSpy = vi.spyOn(window, 'open').mockReturnValue({}); + }); + + afterEach(() => { + vi.restoreAllMocks(); }); it('navigates detail actions to the slug route and does not render the old detail modal', async () => { @@ -143,4 +153,123 @@ describe('App', () => { expect(wrapper.findAll('.modal-backdrop.open')).toHaveLength(1); expect(wrapper.get('button.nav-btn').attributes('aria-expanded')).toBe('true'); }); + + it('renders displayVersion from the API payload', async () => { + const router = createRouterForTest(); + await router.push('/'); + await router.isReady(); + + const wrapper = mount(App, { + global: { + plugins: [router], + }, + }); + + await flushPromises(); + + expect(wrapper.text()).toContain('2026.04'); + expect(wrapper.text()).not.toContain('1.0.0'); + }); + + it('keeps the current route unchanged when launching a download tool', async () => { + apiMocks.fetchTools.mockResolvedValue({ + list: [ + { + id: 'tool_download', + slug: 'download-tool', + name: 'Download Tool', + description: 'Download tool', + category: { id: 'cat_demo', name: 'Developer Tools' }, + tags: ['installer'], + displayVersion: '2.0.0', + latestVersion: '2.0.0', + updatedAt: '2026-04-11', + accessMode: 'download', + openUrl: 'https://example.com/download', + downloadReady: true, + downloadCount: 12, + openCount: 0, + }, + ], + pagination: { + page: 1, + pageSize: 6, + total: 1, + totalPages: 1, + }, + }); + apiMocks.launchTool.mockResolvedValue({ + mode: 'download', + actionUrl: 'https://example.com/download', + openIn: 'same_tab', + }); + + const router = createRouterForTest(); + await router.push('/'); + await router.isReady(); + + const wrapper = mount(App, { + global: { + plugins: [router], + }, + }); + + await flushPromises(); + + await wrapper.findAll('button.btn-small.btn-with-icon')[0].trigger('click'); + await flushPromises(); + + expect(openSpy).toHaveBeenCalledWith('https://example.com/download', '_blank', 'noopener,noreferrer'); + expect(router.currentRoute.value.fullPath).toBe('/'); + }); + + it('uses the primary action as a detail shortcut for none mode tools', async () => { + apiMocks.fetchTools.mockResolvedValue({ + list: [ + { + id: 'tool_none', + slug: 'preview-tool', + name: 'Preview Tool', + description: 'Preview only', + category: { id: 'cat_demo', name: 'Developer Tools' }, + tags: ['preview'], + displayVersion: 'preview-1', + latestVersion: null, + updatedAt: '2026-04-11', + accessMode: 'none', + openUrl: null, + downloadReady: false, + downloadCount: 0, + openCount: 0, + }, + ], + pagination: { + page: 1, + pageSize: 6, + total: 1, + totalPages: 1, + }, + }); + + const router = createRouterForTest(); + await router.push('/'); + await router.isReady(); + + const wrapper = mount(App, { + global: { + plugins: [router], + }, + }); + + await flushPromises(); + + expect(wrapper.text()).toContain('查看详情'); + expect(wrapper.text()).toContain('preview-1'); + + await wrapper.get('button.btn-small.btn-with-icon').trigger('click'); + await flushPromises(); + + expect(apiMocks.launchTool).not.toHaveBeenCalled(); + expect(router.currentRoute.value.fullPath).toBe('/tools/preview-tool'); + }); }); diff --git a/client/src/App.vue b/client/src/App.vue index d7ac2f2..e9a864d 100644 --- a/client/src/App.vue +++ b/client/src/App.vue @@ -152,7 +152,7 @@ 版本 - {{ tool.latestVersion || '暂无版本' }} + {{ tool.displayVersion || '暂无版本' }}
  • @@ -175,7 +175,7 @@