@mintlify/previewing
Version:
Preview Mintlify docs locally
193 lines (192 loc) • 8.34 kB
JavaScript
import fse from 'fs-extra';
import { pipeline } from 'node:stream/promises';
import tar from 'tar';
import * as constants from '../constants.js';
import { downloadTargetMint } from '../local-preview/client.js';
import * as utils from '../util.js';
vi.mock('fs-extra', () => {
const mocks = {
existsSync: vi.fn().mockReturnValue(true),
moveSync: vi.fn().mockReturnValue(undefined),
ensureDirSync: vi.fn().mockReturnValue(undefined),
removeSync: vi.fn().mockReturnValue(undefined),
writeFileSync: vi.fn().mockReturnValue(undefined),
createWriteStream: vi.fn().mockReturnValue({ write: vi.fn(), end: vi.fn() }),
};
return {
...mocks,
default: mocks,
};
});
vi.mock('../util.js', () => ({
restoreMintlifyLast: vi.fn().mockReturnValue(undefined),
getTarUrl: vi.fn().mockReturnValue('https://asdfghjkl.cloudfront.net/mint-1.0.1.tar.gz'),
}));
vi.mock('node:stream/promises', () => ({
pipeline: vi.fn(),
}));
vi.mock('got', () => {
const mocks = {
stream: vi.fn().mockReturnValue({ pipe: vi.fn(), on: vi.fn() }),
};
return {
...mocks,
default: mocks,
};
});
vi.mock('tar', () => {
const mocks = {
x: vi.fn(),
};
return {
...mocks,
default: mocks,
};
});
const restoreMintlifyLastMock = vi.mocked(utils.restoreMintlifyLast);
const pipelineMock = vi.mocked(pipeline);
const getTarUrlMock = vi.mocked(utils.getTarUrl);
const writeFileSyncMock = vi.mocked(fse.writeFileSync);
const tarMock = vi.mocked(tar);
const existsSyncMock = vi.mocked(fse.existsSync);
const moveSyncMock = vi.mocked(fse.moveSync);
const removeSyncMock = vi.mocked(fse.removeSync);
describe('downloadTargetMint', () => {
beforeEach(() => {
vi.clearAllMocks();
});
it('downloads and extracts a new version happy path', async () => {
const targetMintVersion = '1.0.1';
const versionString = '1.0.0';
pipelineMock.mockResolvedValue(undefined);
await downloadTargetMint({
targetVersion: targetMintVersion,
existingVersion: versionString,
});
// Verify backup was created
expect(existsSyncMock).toHaveBeenCalledWith(constants.DOT_MINTLIFY);
expect(moveSyncMock).toHaveBeenCalledWith(constants.DOT_MINTLIFY, constants.DOT_MINTLIFY_LAST, {
overwrite: true,
});
expect(fse.ensureDirSync).toHaveBeenCalledWith(constants.DOT_MINTLIFY);
// Verify download and extraction
expect(getTarUrlMock).toHaveBeenCalledWith(targetMintVersion);
expect(pipelineMock).toHaveBeenCalled();
expect(tarMock.x).toHaveBeenCalled();
// Verify cleanup
expect(removeSyncMock).toHaveBeenCalledWith(constants.TAR_PATH);
expect(removeSyncMock).toHaveBeenCalledWith(constants.DOT_MINTLIFY_LAST);
expect(writeFileSyncMock).toHaveBeenCalledWith(constants.VERSION_PATH, targetMintVersion);
// Verify no restore was needed
expect(restoreMintlifyLastMock).not.toHaveBeenCalled();
});
it('downloads and extracts a specific client version happy path', async () => {
const versionString = '1.0.0';
const clientVersion = '2.0.0';
pipelineMock.mockResolvedValue(undefined);
await downloadTargetMint({
targetVersion: clientVersion,
existingVersion: versionString,
});
// Verify backup was created
expect(existsSyncMock).toHaveBeenCalledWith(constants.DOT_MINTLIFY);
expect(moveSyncMock).toHaveBeenCalledWith(constants.DOT_MINTLIFY, constants.DOT_MINTLIFY_LAST, {
overwrite: true,
});
expect(fse.ensureDirSync).toHaveBeenCalledWith(constants.DOT_MINTLIFY);
// Verify download and extraction
expect(getTarUrlMock).toHaveBeenCalledWith(clientVersion);
expect(pipelineMock).toHaveBeenCalled();
expect(tarMock.x).toHaveBeenCalled();
// Verify cleanup
expect(removeSyncMock).toHaveBeenCalledWith(constants.TAR_PATH);
expect(removeSyncMock).toHaveBeenCalledWith(constants.DOT_MINTLIFY_LAST);
expect(writeFileSyncMock).toHaveBeenCalledWith(constants.VERSION_PATH, clientVersion);
// Verify no restore was needed
expect(restoreMintlifyLastMock).not.toHaveBeenCalled();
});
describe('downloadTargetMint with backup version', () => {
beforeEach(() => {
vi.clearAllMocks();
});
it('fails to download new version', async () => {
const targetMintVersion = '1.0.1';
const versionString = '1.0.0';
const errorMessage = 'connection timed out';
pipelineMock.mockRejectedValue(new Error(errorMessage));
// does not throw
await downloadTargetMint({
targetVersion: targetMintVersion,
existingVersion: versionString,
});
// Verify backup was created
expect(existsSyncMock).toHaveBeenCalledWith(constants.DOT_MINTLIFY);
expect(moveSyncMock).toHaveBeenCalledWith(constants.DOT_MINTLIFY, constants.DOT_MINTLIFY_LAST, {
overwrite: true,
});
expect(fse.ensureDirSync).toHaveBeenCalledWith(constants.DOT_MINTLIFY);
// Verify use backup version
expect(restoreMintlifyLastMock).toHaveBeenCalled();
// Verify no extraction
expect(tarMock.x).not.toHaveBeenCalled();
// Verify no cleanup
expect(removeSyncMock).not.toHaveBeenCalled();
expect(writeFileSyncMock).not.toHaveBeenCalled();
});
it('fails to extract new version', async () => {
const targetMintVersion = '1.0.1';
const versionString = '1.0.0';
const errorMessage = 'zlib error';
pipelineMock.mockResolvedValue(undefined);
tarMock.x.mockImplementation(() => {
throw new Error(errorMessage);
});
// does not throw
await downloadTargetMint({
targetVersion: targetMintVersion,
existingVersion: versionString,
});
// Verify backup was created
expect(existsSyncMock).toHaveBeenCalledWith(constants.DOT_MINTLIFY);
expect(moveSyncMock).toHaveBeenCalledWith(constants.DOT_MINTLIFY, constants.DOT_MINTLIFY_LAST, {
overwrite: true,
});
expect(fse.ensureDirSync).toHaveBeenCalledWith(constants.DOT_MINTLIFY);
// Verify download success
expect(pipelineMock).toHaveBeenCalled();
// Verify use backup version
expect(restoreMintlifyLastMock).toHaveBeenCalled();
// Verify no cleanup
expect(removeSyncMock).not.toHaveBeenCalled();
expect(writeFileSyncMock).not.toHaveBeenCalled();
});
});
describe('downloadTargetMint without backup version', () => {
beforeEach(() => {
vi.clearAllMocks();
});
it('fails to download new version with no fallback', async () => {
const targetMintVersion = '1.0.1';
const versionString = null;
const errorMessage = 'connection timed out';
pipelineMock.mockRejectedValue(new Error(errorMessage));
await expect(downloadTargetMint({
targetVersion: targetMintVersion,
existingVersion: versionString,
})).rejects.toThrow(`failed to install mintlify framework version ${targetMintVersion}, Error: ${errorMessage}`);
});
it('fails to extract new version with no fallback', async () => {
const targetMintVersion = '1.0.1';
const versionString = null;
const errorMessage = 'zlib error';
pipelineMock.mockResolvedValue(undefined);
tarMock.x.mockImplementation(() => {
throw new Error(errorMessage);
});
await expect(downloadTargetMint({
targetVersion: targetMintVersion,
existingVersion: versionString,
})).rejects.toThrow(`failed to extract mintlify framework version ${targetMintVersion}, Error: ${errorMessage}`);
});
});
});