forked from
npmx.dev/npmx.dev
[READ-ONLY]
a fast, modern browser for the npm registry
1import { expect, test } from './test-utils'
2
3function toLocalUrl(baseURL: string | undefined, path: string): string {
4 if (!baseURL) return path
5 return baseURL.endsWith('/') ? `${baseURL}${path.slice(1)}` : `${baseURL}${path}`
6}
7
8async function fetchBadge(page: { request: { get: (url: string) => Promise<any> } }, url: string) {
9 const response = await page.request.get(url)
10 const body = await response.text()
11 return { response, body }
12}
13
14test.describe('badge API', () => {
15 const badgeMap: Record<string, string> = {
16 'version': 'version',
17 'license': 'license',
18 'size': 'install size',
19 'downloads': 'downloads/mo',
20 'downloads-day': 'downloads/day',
21 'downloads-week': 'downloads/wk',
22 'downloads-month': 'downloads/mo',
23 'downloads-year': 'downloads/yr',
24 'vulnerabilities': 'vulns',
25 'dependencies': 'dependencies',
26 'updated': 'updated',
27 'engines': 'node',
28 'types': 'types',
29 'created': 'created',
30 'maintainers': 'maintainers',
31 'deprecated': 'status',
32 'quality': 'quality',
33 'popularity': 'popularity',
34 'maintenance': 'maintenance',
35 'score': 'score',
36 }
37
38 const percentageTypes = new Set(['quality', 'popularity', 'maintenance', 'score'])
39
40 for (const [type, expectedLabel] of Object.entries(badgeMap)) {
41 test.describe(`${type} badge`, () => {
42 test('renders correct label', async ({ page, baseURL }) => {
43 const url = toLocalUrl(baseURL, `/api/registry/badge/${type}/nuxt`)
44 const { response, body } = await fetchBadge(page, url)
45
46 expect(response.status()).toBe(200)
47 expect(response.headers()['content-type']).toContain('image/svg+xml')
48 expect(body).toContain(expectedLabel)
49 })
50
51 test('scoped package renders successfully', async ({ page, baseURL }) => {
52 const url = toLocalUrl(baseURL, `/api/registry/badge/${type}/@nuxt/kit`)
53 const { response } = await fetchBadge(page, url)
54
55 expect(response.status()).toBe(200)
56 })
57
58 test('explicit version badge renders successfully', async ({ page, baseURL }) => {
59 const url = toLocalUrl(baseURL, `/api/registry/badge/${type}/nuxt/v/3.12.0`)
60 const { response, body } = await fetchBadge(page, url)
61
62 expect(response.status()).toBe(200)
63 if (type === 'version') {
64 expect(body).toContain('v3.12.0')
65 }
66 })
67
68 test('respects name=true parameter', async ({ page, baseURL }) => {
69 const packageName = 'nuxt'
70 const url = toLocalUrl(baseURL, `/api/registry/badge/${type}/${packageName}?name=true`)
71 const { body } = await fetchBadge(page, url)
72
73 expect(body).toContain(packageName)
74 expect(body).not.toContain(expectedLabel)
75 })
76
77 if (percentageTypes.has(type)) {
78 test('contains percentage value', async ({ page, baseURL }) => {
79 const url = toLocalUrl(baseURL, `/api/registry/badge/${type}/vue`)
80 const { body } = await fetchBadge(page, url)
81
82 expect(body).toMatch(/\d+%|unknown/)
83 })
84 }
85 })
86 }
87
88 test.describe('specific scenarios', () => {
89 test('downloads-year handles large numbers', async ({ page, baseURL }) => {
90 const url = toLocalUrl(baseURL, '/api/registry/badge/downloads-year/vue')
91 const { body } = await fetchBadge(page, url)
92
93 expect(body).toContain('downloads/yr')
94 expect(body).not.toContain('NaN')
95 })
96
97 test('deprecated badge shows active for non-deprecated packages', async ({ page, baseURL }) => {
98 const url = toLocalUrl(baseURL, '/api/registry/badge/deprecated/vue')
99 const { body } = await fetchBadge(page, url)
100
101 expect(body).toContain('active')
102 })
103 })
104
105 test('custom labelColor parameter is applied to SVG', async ({ page, baseURL }) => {
106 const customColor = '00ff00'
107 const url = toLocalUrl(baseURL, `/api/registry/badge/version/nuxt?labelColor=${customColor}`)
108 const { body } = await fetchBadge(page, url)
109
110 expect(body).toContain(`fill="#${customColor}"`)
111 })
112
113 test('custom color parameter is applied to SVG', async ({ page, baseURL }) => {
114 const customColor = 'ff69b4'
115 const url = toLocalUrl(baseURL, `/api/registry/badge/version/nuxt?color=${customColor}`)
116 const { body } = await fetchBadge(page, url)
117
118 expect(body).toContain(`fill="#${customColor}"`)
119 })
120
121 test('custom label parameter is applied to SVG', async ({ page, baseURL }) => {
122 const customLabel = 'my-label'
123 const url = toLocalUrl(baseURL, `/api/registry/badge/version/nuxt?label=${customLabel}`)
124 const { body } = await fetchBadge(page, url)
125
126 expect(body).toContain(customLabel)
127 })
128
129 test('invalid badge type defaults to version strategy', async ({ page, baseURL }) => {
130 const url = toLocalUrl(baseURL, '/api/registry/badge/invalid-type/nuxt')
131 const { body } = await fetchBadge(page, url)
132
133 expect(body).toContain('version')
134 })
135
136 test('missing package returns 404', async ({ page, baseURL }) => {
137 const url = toLocalUrl(baseURL, '/api/registry/badge/version/')
138 const { response } = await fetchBadge(page, url)
139
140 expect(response.status()).toBe(404)
141 })
142})