1
0
mirror of https://github.com/kremalicious/astro-redirect-from.git synced 2024-12-22 09:23:21 +01:00

refactor for better testability

This commit is contained in:
Matthias Kretschmann 2023-09-24 12:49:10 +01:00
parent d9e967aa31
commit 09dfa97af9
Signed by: m
GPG Key ID: 606EEEF3C479A91F
2 changed files with 124 additions and 43 deletions

View File

@ -10,57 +10,63 @@ export type PluginOptions = {
getSlug?: GetSlug
}
export type HookOptions = Parameters<
AstroIntegration['hooks']['astro:config:setup'] & { 0: any }
>[0]
export type Redirects = { [old: string]: string }
export async function initPlugin(
hookOptions: HookOptions,
options?: PluginOptions
) {
const _contentDir = options?.contentDir || 'src/pages/'
const _getSlug = options?.getSlug || getSlugFromFilePath
const _contentDirPath = path.join(process.cwd(), _contentDir)
const { logger, config, command, updateConfig } = hookOptions
try {
const markdownFiles = await getMarkdownFiles(_contentDirPath)
if (!markdownFiles?.length) {
logger.warn('No markdown files found')
return
}
const redirects = await getRedirects(
markdownFiles,
_contentDirPath,
_getSlug,
command
)
if (!redirects || !Object.keys(redirects).length) {
logger.warn('No redirects found in markdown files')
return
}
updateConfig({ redirects })
const redirectFilePath = path.join(
config.cacheDir.pathname, // Default is ./node_modules/.astro/
'redirect_from.json'
)
await writeJson(redirectFilePath, redirects)
logger.info(
`Added ${Object.keys(redirects).length} redirects to Astro config`
)
} catch (error: any) {
logger.error((error as Error).message)
}
}
export default function astroRedirectFrom(
options?: PluginOptions
): AstroIntegration {
const _contentDir = options?.contentDir || 'src/pages/'
const _getSlug = options?.getSlug || getSlugFromFilePath
const _contentDirPath = path.join(process.cwd(), _contentDir)
return {
name: 'redirect-from',
hooks: {
'astro:config:setup': async ({
config,
command,
updateConfig,
logger
}) => {
try {
const markdownFiles = await getMarkdownFiles(_contentDirPath)
if (!markdownFiles?.length) {
logger.warn('No markdown files found')
return
}
const redirects = await getRedirects(
markdownFiles,
_contentDirPath,
_getSlug,
command
)
if (!redirects || !Object.keys(redirects).length) {
logger.info('No redirects found in markdown files')
return
}
updateConfig({ redirects })
const redirectFilePath = path.join(
config.cacheDir.pathname, // Default is ./node_modules/.astro/
'redirect_from.json'
)
await writeJson(redirectFilePath, redirects)
logger.info(
`Added ${Object.keys(redirects).length} redirects to Astro config`
)
} catch (error: any) {
logger.error((error as Error).message)
}
}
'astro:config:setup': async (hookOptions) =>
await initPlugin(hookOptions, options)
}
}
}

75
test/index.test.ts Normal file
View File

@ -0,0 +1,75 @@
import { describe, it, expect, vi } from 'vitest'
import astroRedirectFrom, { initPlugin } from '../src/index'
import * as utils from '../src/utils'
import * as redirects from '../src/getRedirects'
describe('initPlugin', () => {
const mockLogger = {
warn: vi.fn(),
info: vi.fn(),
error: vi.fn()
}
const hookOptionsMock = {
logger: mockLogger,
config: {
cacheDir: { pathname: './node_modules/.astro/' }
},
command: 'dev',
updateConfig: vi.fn()
}
it('should handle no markdown files scenario', async () => {
const getMarkdownFilesSpy = vi.spyOn(utils, 'getMarkdownFiles')
getMarkdownFilesSpy.mockResolvedValue([])
await initPlugin(hookOptionsMock as any)
expect(mockLogger.warn).toBeCalledWith('No markdown files found')
expect(hookOptionsMock.updateConfig).not.toBeCalled()
})
it('should handle no redirects found scenario', async () => {
const getMarkdownFilesSpy = vi.spyOn(utils, 'getMarkdownFiles')
getMarkdownFilesSpy.mockResolvedValue(['test.md', 'test2.md'])
const getRedirectsSpy = vi.spyOn(redirects, 'getRedirects')
getRedirectsSpy.mockResolvedValue({})
await initPlugin(hookOptionsMock as any)
expect(mockLogger.warn).toBeCalledWith(
'No redirects found in markdown files'
)
expect(hookOptionsMock.updateConfig).not.toBeCalled()
})
it('should handle redirects found scenario', async () => {
const getMarkdownFilesSpy = vi.spyOn(utils, 'getMarkdownFiles')
getMarkdownFilesSpy.mockResolvedValue(['test.md', 'test2.md'])
const getRedirectsSpy = vi.spyOn(redirects, 'getRedirects')
getRedirectsSpy.mockResolvedValue({ '/old': '/new' })
const writeJsonSpy = vi.spyOn(utils, 'writeJson')
writeJsonSpy.mockImplementation(() => Promise.resolve())
await initPlugin(hookOptionsMock as any)
expect(hookOptionsMock.updateConfig).toBeCalledWith({
redirects: { '/old': '/new' }
})
expect(mockLogger.info).toBeCalledWith('Added 1 redirects to Astro config')
expect(writeJsonSpy).toBeCalled()
})
})
describe('astroRedirectFrom', () => {
it('should return an AstroIntegration object', () => {
const result = astroRedirectFrom()
expect(result).toHaveProperty('name', 'redirect-from')
expect(result).toHaveProperty('hooks')
expect(result.hooks).toHaveProperty('astro:config:setup')
})
})