import { describe, it, expect, beforeEach, vi } from 'vitest' import { mount } from '@vue/test-utils' import { createPinia, setActivePinia } from 'pinia' import Stats from './Stats.vue' import { usePackageStore } from '../stores/packages' describe('Stats.vue', () => { beforeEach(() => { setActivePinia(createPinia()) }) it('renders stats component', () => { const wrapper = mount(Stats) expect(wrapper.find('h2').text()).toBe('Statistics') }) it('displays loading state when loading', async () => { const wrapper = mount(Stats) const store = usePackageStore() store.loading = true await wrapper.vm.$nextTick() expect(wrapper.text()).toContain('Loading statistics...') }) it('displays error message when error occurs', async () => { const wrapper = mount(Stats) const store = usePackageStore() store.error = 'Failed to fetch statistics' await wrapper.vm.$nextTick() expect(wrapper.text()).toContain('Failed to fetch statistics') }) it('displays overall statistics', async () => { const wrapper = mount(Stats) const store = usePackageStore() store.loading = false store.stats = { registry: '', total_packages: 100, total_size: 1073741824, // 1 GB max_cache_size: 10737418240, total_downloads: 500, scanned_packages: 90, vulnerable_packages: 5, blocked_packages: 0, } await wrapper.vm.$nextTick() expect(wrapper.text()).toContain('Overall Statistics') expect(wrapper.text()).toContain('100') expect(wrapper.text()).toContain('500') }) it('displays security scanning statistics', async () => { const wrapper = mount(Stats) const store = usePackageStore() store.loading = false store.stats = { registry: '', total_packages: 100, total_size: 1073741824, max_cache_size: 10737418240, total_downloads: 500, scanned_packages: 90, vulnerable_packages: 5, blocked_packages: 0, } await wrapper.vm.$nextTick() expect(wrapper.text()).toContain('Security Scanning') expect(wrapper.text()).toContain('Scanned Packages') expect(wrapper.text()).toContain('Vulnerable Packages') }) it('displays registry breakdown', async () => { const wrapper = mount(Stats) const store = usePackageStore() store.loading = false store.stats = { registry: '', total_packages: 100, total_size: 1073741824, max_cache_size: 10737418240, total_downloads: 500, scanned_packages: 90, vulnerable_packages: 5, blocked_packages: 0, } store.registries = { npm: { count: 50, size: 536870912, // 512 MB downloads: 300, }, pypi: { count: 30, size: 322122547, // ~307 MB downloads: 150, }, go: { count: 20, size: 214748365, // ~205 MB downloads: 50, }, } await wrapper.vm.$nextTick() expect(wrapper.text()).toContain('Registry Breakdown') expect(wrapper.text()).toContain('NPM Registry') expect(wrapper.text()).toContain('PyPI Registry') expect(wrapper.text()).toContain('Go Modules') expect(wrapper.text()).toContain('50 packages') expect(wrapper.text()).toContain('30 packages') expect(wrapper.text()).toContain('20 packages') }) it('formats bytes correctly in overall stats', async () => { const wrapper = mount(Stats) const store = usePackageStore() store.loading = false store.stats = { registry: '', total_packages: 100, total_size: 1073741824, // 1 GB max_cache_size: 10737418240, total_downloads: 500, scanned_packages: 90, vulnerable_packages: 5, blocked_packages: 0, } await wrapper.vm.$nextTick() expect(wrapper.text()).toContain('1 GB') }) it('calls fetchStats on mount', () => { const store = usePackageStore() const fetchSpy = vi.spyOn(store, 'fetchStats') mount(Stats) expect(fetchSpy).toHaveBeenCalled() }) it('displays correct icon colors for different registries', async () => { const wrapper = mount(Stats) const store = usePackageStore() store.loading = false store.stats = { registry: '', total_packages: 3, total_size: 0, max_cache_size: 10737418240, total_downloads: 0, scanned_packages: 0, vulnerable_packages: 0, blocked_packages: 0, } store.registries = { npm: { count: 1, size: 0, downloads: 0 }, pypi: { count: 1, size: 0, downloads: 0 }, go: { count: 1, size: 0, downloads: 0 }, } await wrapper.vm.$nextTick() // Scope to the registry icon containers (w-12 h-12 rounded-full), // excluding the storage progress bar which also uses rounded-full. const containers = wrapper.findAll('.w-12.h-12.rounded-full') expect(containers).toHaveLength(3) expect(containers[0].classes()).toContain('bg-red-100') // npm expect(containers[1].classes()).toContain('bg-blue-100') // pypi expect(containers[2].classes()).toContain('bg-cyan-100') // go }) it('handles empty registries data', async () => { const wrapper = mount(Stats) const store = usePackageStore() store.loading = false store.stats = { registry: '', total_packages: 0, total_size: 0, max_cache_size: 10737418240, total_downloads: 0, scanned_packages: 0, vulnerable_packages: 0, blocked_packages: 0, } store.registries = {} await wrapper.vm.$nextTick() expect(wrapper.text()).toContain('Registry Breakdown') // Should have no registry items const registryItems = wrapper.findAll('.bg-gray-50') expect(registryItems.length).toBe(3) // Only the overall stats cards }) })