@capawesome/cli
Version:
The Capawesome Cloud Command Line Interface (CLI) to manage Live Updates and more.
84 lines (83 loc) • 4.33 kB
JavaScript
import { directoryContainsSymlinks, isReadable, isDirectory } from '../../../utils/file.js';
import { generateManifestJson } from '../../../utils/manifest.js';
import { prompt } from '../../../utils/prompt.js';
import consola from 'consola';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import generateManifestCommand from './generate-manifest.js';
// Mock dependencies
vi.mock('@/utils/file.js');
vi.mock('@/utils/manifest.js');
vi.mock('@/utils/prompt.js');
vi.mock('consola');
vi.mock('@/utils/environment.js', () => ({
isInteractive: () => true,
}));
describe('apps-liveupdates-generatemanifest', () => {
const mockIsReadable = vi.mocked(isReadable);
const mockIsDirectory = vi.mocked(isDirectory);
const mockDirectoryContainsSymlinks = vi.mocked(directoryContainsSymlinks);
const mockGenerateManifestJson = vi.mocked(generateManifestJson);
const mockPrompt = vi.mocked(prompt);
const mockConsola = vi.mocked(consola);
beforeEach(() => {
vi.clearAllMocks();
vi.spyOn(process, 'exit').mockImplementation((code) => {
throw new Error(`Process exited with code ${code}`);
});
});
afterEach(() => {
vi.restoreAllMocks();
});
it('should generate manifest with provided path', async () => {
const options = { path: './dist' };
mockIsReadable.mockResolvedValue(true);
mockIsDirectory.mockResolvedValue(true);
mockGenerateManifestJson.mockResolvedValue(undefined);
await generateManifestCommand.action(options, undefined);
expect(mockIsReadable).toHaveBeenCalledWith('./dist');
expect(mockGenerateManifestJson).toHaveBeenCalledWith('./dist');
expect(mockConsola.success).toHaveBeenCalledWith('Manifest file generated.');
});
it('should prompt for path when not provided', async () => {
const options = {};
mockPrompt.mockResolvedValueOnce('./www');
mockIsReadable.mockResolvedValue(true);
mockIsDirectory.mockResolvedValue(true);
mockGenerateManifestJson.mockResolvedValue(undefined);
await generateManifestCommand.action(options, undefined);
expect(mockPrompt).toHaveBeenCalledWith('Enter the path to the web assets folder (e.g., `dist` or `www`):', {
type: 'text',
});
expect(mockIsReadable).toHaveBeenCalledWith('./www');
expect(mockGenerateManifestJson).toHaveBeenCalledWith('./www');
expect(mockConsola.success).toHaveBeenCalledWith('Manifest file generated.');
});
it('should handle missing path in prompt', async () => {
const options = {};
mockPrompt.mockResolvedValueOnce('');
await expect(generateManifestCommand.action(options, undefined)).rejects.toThrow('Process exited with code 1');
expect(mockConsola.error).toHaveBeenCalledWith('You must provide a path to the web assets folder.');
});
it('should handle nonexistent path', async () => {
const options = { path: './nonexistent' };
mockIsReadable.mockResolvedValue(false);
await expect(generateManifestCommand.action(options, undefined)).rejects.toThrow('Process exited with code 1');
expect(mockConsola.error).toHaveBeenCalledWith('The path does not exist or is not accessible: ./nonexistent');
});
it('should handle non-directory path', async () => {
const options = { path: './file.txt' };
mockIsReadable.mockResolvedValue(true);
mockIsDirectory.mockResolvedValue(false);
await expect(generateManifestCommand.action(options, undefined)).rejects.toThrow('Process exited with code 1');
expect(mockConsola.error).toHaveBeenCalledWith('The path is not a directory.');
});
it('should warn when symlinks are detected', async () => {
const options = { path: './dist' };
mockIsReadable.mockResolvedValue(true);
mockIsDirectory.mockResolvedValue(true);
mockDirectoryContainsSymlinks.mockResolvedValue(true);
mockGenerateManifestJson.mockResolvedValue(undefined);
await generateManifestCommand.action(options, undefined);
expect(mockConsola.warn).toHaveBeenCalledWith('Symbolic links were detected in the specified path. Symbolic links are skipped during manifest generation.');
});
});