AbdulElahGwaith's picture
Upload folder using huggingface_hub
88df9e4 verified
import { beforeAll, describe, expect, test } from 'vitest'
import { get } from '@/tests/helpers/e2etest'
const makeURL = (pathname: string, apiVersion?: string): string => {
const params = new URLSearchParams({ pathname })
if (apiVersion) {
params.set('apiVersion', apiVersion)
}
return `/api/article/body?${params}`
}
describe('REST transformer', () => {
beforeAll(() => {
if (!process.env.ROOT) {
console.warn(
'WARNING: The REST transformer tests require the ROOT environment variable to be set to the fixture root',
)
}
})
test('REST page renders with markdown structure', async () => {
const res = await get(makeURL('/en/rest/actions/artifacts'))
expect(res.statusCode).toBe(200)
expect(res.headers['content-type']).toContain('text/markdown')
// Check for the main heading
expect(res.body).toContain('# GitHub Actions Artifacts')
// Check for intro (using fixture's prodname_actions which is 'HubGit Actions')
expect(res.body).toContain('Use the REST API to interact with artifacts in HubGit Actions.')
// Check for manual content section heading
expect(res.body).toContain('## About artifacts in HubGit Actions')
})
test('REST operations are formatted correctly', async () => {
const res = await get(makeURL('/en/rest/actions/artifacts'))
expect(res.statusCode).toBe(200)
// Check for operation heading
expect(res.body).toContain('## List artifacts for a repository')
// Check for HTTP method and endpoint
expect(res.body).toContain('GET /repos/{owner}/{repo}/actions/artifacts')
// Check for operation description
expect(res.body).toContain('Lists all artifacts for a repository.')
})
test('Parameters section includes headers', async () => {
const res = await get(makeURL('/en/rest/actions/artifacts'))
expect(res.statusCode).toBe(200)
// Check for parameters heading
expect(res.body).toContain('### Parameters')
// Check for headers section
expect(res.body).toContain('#### Headers')
// Check for accept header
expect(res.body).toContain('**`accept`** (string)')
expect(res.body).toContain('Setting to `application/vnd.github+json` is recommended.')
})
test('Path and query parameters are listed', async () => {
const res = await get(makeURL('/en/rest/actions/artifacts'))
expect(res.statusCode).toBe(200)
// Check for path and query parameters section
expect(res.body).toContain('#### Path and query parameters')
// Check for specific parameters
expect(res.body).toContain('**`owner`** (string) (required)')
expect(res.body).toContain('The account owner of the repository.')
expect(res.body).toContain('**`repo`** (string) (required)')
expect(res.body).toContain('**`per_page`** (integer)')
expect(res.body).toContain('Default: `30`')
})
test('Status codes are formatted correctly', async () => {
const res = await get(makeURL('/en/rest/actions/artifacts'))
expect(res.statusCode).toBe(200)
// Check for status codes section
expect(res.body).toContain('### HTTP response status codes')
// Check for specific status code
expect(res.body).toContain('**200**')
expect(res.body).toContain('OK')
})
test('Code examples include curl with proper formatting', async () => {
const res = await get(makeURL('/en/rest/actions/artifacts'))
expect(res.statusCode).toBe(200)
// Check for code examples section
expect(res.body).toContain('### Code examples')
// Check for request/response labels
expect(res.body).toContain('**Request:**')
expect(res.body).toContain('**Response schema:**')
// Check for curl code block
expect(res.body).toContain('```curl')
expect(res.body).toContain('curl -L \\')
expect(res.body).toContain('-X GET \\')
expect(res.body).toContain('https://api.github.com/repos/OWNER/REPO/actions/artifacts \\')
expect(res.body).toContain('-H "Accept: application/vnd.github.v3+json" \\')
expect(res.body).toContain('-H "Authorization: Bearer <YOUR-TOKEN>"')
})
test('Code examples include X-GitHub-Api-Version header by default', async () => {
const res = await get(makeURL('/en/rest/actions/artifacts'))
expect(res.statusCode).toBe(200)
// Check for API version header in curl example
expect(res.body).toContain('-H "X-GitHub-Api-Version: 2022-11-28"')
})
test('Code examples include specified API version', async () => {
const res = await get(makeURL('/en/rest/actions/artifacts', '2022-11-28'))
expect(res.statusCode).toBe(200)
// Check for the specified API version header
expect(res.body).toContain('-H "X-GitHub-Api-Version: 2022-11-28"')
})
test('Liquid tags are rendered in intro', async () => {
const res = await get(makeURL('/en/rest/actions/artifacts'))
expect(res.statusCode).toBe(200)
// Liquid tags should be rendered, not shown as raw tags (fixture uses 'HubGit Actions')
expect(res.body).toContain('HubGit Actions')
expect(res.body).not.toContain('{% data variables.product.prodname_actions %}')
// Check in both the intro and the manual content section
expect(res.body).toMatch(/Use the REST API to interact with artifacts in HubGit Actions/)
expect(res.body).toMatch(/About artifacts in HubGit Actions/)
})
test('AUTOTITLE links are resolved', async () => {
const res = await get(makeURL('/en/rest/actions/artifacts'))
expect(res.statusCode).toBe(200)
// Check that AUTOTITLE has been resolved to actual link text
// The link should have the actual page title, not "AUTOTITLE"
expect(res.body).toContain('[Storing workflow data as artifacts]')
expect(res.body).toContain('(/en/actions/using-workflows/storing-workflow-data-as-artifacts)')
// Make sure the raw AUTOTITLE tag is not present
expect(res.body).not.toContain('[AUTOTITLE]')
// Verify the link appears in the manual content section
expect(res.body).toMatch(
/About artifacts in HubGit Actions[\s\S]*Storing workflow data as artifacts/,
)
})
test('Markdown links are preserved in descriptions', async () => {
const res = await get(makeURL('/en/rest/actions/artifacts'))
expect(res.statusCode).toBe(200)
// Check that markdown links are preserved
expect(res.body).toMatch(/\[.*?\]\(\/en\/.*?\)/)
})
test('Response schema is formatted correctly', async () => {
const res = await get(makeURL('/en/rest/actions/artifacts'))
expect(res.statusCode).toBe(200)
// Check for JSON code block with schema label
expect(res.body).toContain('**Response schema:**')
expect(res.body).toContain('```json')
expect(res.body).toContain('Status: 200')
// Verify schema structure is present (not an example)
expect(res.body).toContain('"type":')
expect(res.body).toContain('"properties":')
// Check for common schema keywords
const schemaMatch = res.body.match(/```json\s+Status: 200\s+([\s\S]*?)```/)
expect(schemaMatch).toBeTruthy()
if (schemaMatch) {
const schemaContent = schemaMatch[1]
const schema = JSON.parse(schemaContent)
// Verify it's a valid OpenAPI/JSON schema structure
expect(schema).toHaveProperty('type')
expect(schema.type).toBe('object')
expect(schema).toHaveProperty('properties')
// Verify it has expected properties for artifacts response
expect(schema.properties).toHaveProperty('total_count')
expect(schema.properties).toHaveProperty('artifacts')
}
})
test('Non-REST pages return appropriate error', async () => {
const res = await get(makeURL('/en/get-started/start-your-journey/hello-world'))
expect(res.statusCode).toBe(200)
// Regular article pages should still work, they just won't use the transformer
expect(res.body).toContain('## Introduction')
})
test('Invalid apiVersion returns 400 error', async () => {
// An invalid API version should return a validation error with 400 status
const res = await get(makeURL('/en/rest/actions/artifacts', 'invalid-version'))
// Returns 400 because the apiVersion is invalid (client error)
expect(res.statusCode).toBe(400)
const parsed = JSON.parse(res.body)
expect(parsed.error).toContain("Invalid apiVersion 'invalid-version'")
expect(parsed.error).toContain('Valid API versions are:')
expect(parsed.error).toContain('2022-11-28')
})
test('Multiple apiVersion query parameters returns 400 error', async () => {
// Multiple apiVersion parameters should be rejected
const res = await get(
'/api/article/body?pathname=/en/rest/actions/artifacts&apiVersion=2022-11-28&apiVersion=2023-01-01',
)
expect(res.statusCode).toBe(400)
const parsed = JSON.parse(res.body)
expect(parsed.error).toBe("Multiple 'apiVersion' keys")
})
test('Valid apiVersion passes validation', async () => {
// A valid API version should work
const res = await get(makeURL('/en/rest/actions/artifacts', '2022-11-28'))
expect(res.statusCode).toBe(200)
expect(res.body).toContain('-H "X-GitHub-Api-Version: 2022-11-28"')
})
test('Missing apiVersion defaults to latest', async () => {
// When no apiVersion is provided, it should default to the latest version
const res = await get(makeURL('/en/rest/actions/artifacts'))
expect(res.statusCode).toBe(200)
// Should include the default API version header
expect(res.body).toContain('-H "X-GitHub-Api-Version: 2022-11-28"')
})
test('Multiple operations on a page are all rendered', async () => {
const res = await get(makeURL('/en/rest/actions/artifacts'))
expect(res.statusCode).toBe(200)
// Check for multiple operation headings
expect(res.body).toContain('## List artifacts for a repository')
expect(res.body).toContain('## Get an artifact')
expect(res.body).toContain('## Delete an artifact')
})
test('Body parameters are formatted correctly for POST/PUT operations', async () => {
const res = await get(makeURL('/en/rest/actions/artifacts'))
expect(res.statusCode).toBe(200)
// For operations with body parameters, check formatting
// (artifacts endpoint is mostly GET/DELETE, but structure should be there)
// The transformer handles body parameters when present
})
test('Content-type header is included for operations that need it', async () => {
const res = await get(makeURL('/en/rest/actions/artifacts'))
expect(res.statusCode).toBe(200)
// Content-type header appears for operations that require it
// The REST transformer adds this based on the operation data
})
test('Non-English language paths work correctly', async () => {
// Note: This test may fail in dev mode with ENABLED_LANGUAGES=en
// but the transformer itself should handle any language path
const res = await get(makeURL('/ja/rest/actions/artifacts'))
expect(res.statusCode).toBe(200)
// The transformer should work regardless of language prefix
// because it looks for 'rest' in the path and gets the category/subcategory after it
// e.g. /ja/rest/actions/artifacts should work the same as /en/rest/actions/artifacts
// Verify the operation content is present (in English, since REST data is not translated)
expect(res.body).toContain('## List artifacts for a repository')
expect(res.body).toContain('GET /repos/{owner}/{repo}/actions/artifacts')
// Check what language is actually being served by examining the response
// If Japanese translations are loaded, the title will be in Japanese
// Otherwise, it falls back to English
const hasJapaneseTitle = res.body.includes('# GitHub Actions アーティファクト')
const hasEnglishTitle = res.body.includes('# GitHub Actions Artifacts')
// One of them must be present
expect(hasJapaneseTitle || hasEnglishTitle).toBe(true)
// Verify the appropriate content based on which language was served
if (hasJapaneseTitle) {
// If Japanese is loaded, expect Japanese intro text
expect(res.body).toContain('アーティファクト')
} else {
// If Japanese is not loaded, expect English fallback
expect(res.body).toContain('Use the REST API to interact with artifacts in HubGit Actions')
}
})
})