decap-cms-backend-gitea
Version:
Gitea backend for Decap CMS
285 lines (228 loc) • 8.31 kB
JavaScript
import { Cursor, CURSOR_COMPATIBILITY_SYMBOL } from 'decap-cms-lib-util';
import GiteaImplementation from '../implementation';
jest.spyOn(console, 'error').mockImplementation(() => {});
describe('gitea backend implementation', () => {
const config = {
backend: {
repo: 'owner/repo',
api_root: 'https://try.gitea.io/api/v1',
},
};
const createObjectURL = jest.fn();
global.URL = {
createObjectURL,
};
createObjectURL.mockReturnValue('displayURL');
beforeAll(() => {
// eslint-disable-next-line @typescript-eslint/no-empty-function
});
beforeEach(() => {
jest.clearAllMocks();
});
afterAll(() => {
jest.restoreAllMocks();
});
describe('persistMedia', () => {
const persistFiles = jest.fn();
const mockAPI = {
persistFiles,
};
persistFiles.mockImplementation((_, files) => {
files.forEach((file, index) => {
file.sha = index;
});
});
it('should persist media file', async () => {
const giteaImplementation = new GiteaImplementation(config);
giteaImplementation.api = mockAPI;
const mediaFile = {
fileObj: { size: 100, name: 'image.png' },
path: '/media/image.png',
};
expect.assertions(5);
await expect(
giteaImplementation.persistMedia(mediaFile, { commitMessage: 'Persisting media' }),
).resolves.toEqual({
id: 0,
name: 'image.png',
size: 100,
displayURL: 'displayURL',
path: 'media/image.png',
});
expect(persistFiles).toHaveBeenCalledTimes(1);
expect(persistFiles).toHaveBeenCalledWith([], [mediaFile], {
commitMessage: 'Persisting media',
});
expect(createObjectURL).toHaveBeenCalledTimes(1);
expect(createObjectURL).toHaveBeenCalledWith(mediaFile.fileObj);
});
it('should log and throw error on "persistFiles" error', async () => {
const giteaImplementation = new GiteaImplementation(config);
giteaImplementation.api = mockAPI;
const error = new Error('failed to persist files');
persistFiles.mockRejectedValue(error);
const mediaFile = {
fileObj: { size: 100 },
path: '/media/image.png',
};
expect.assertions(5);
await expect(
giteaImplementation.persistMedia(mediaFile, { commitMessage: 'Persisting media' }),
).rejects.toThrowError(error);
expect(persistFiles).toHaveBeenCalledTimes(1);
expect(createObjectURL).toHaveBeenCalledTimes(0);
expect(console.error).toHaveBeenCalledTimes(1);
expect(console.error).toHaveBeenCalledWith(error);
});
});
describe('entriesByFolder', () => {
const listFiles = jest.fn();
const readFile = jest.fn();
const readFileMetadata = jest.fn(() => Promise.resolve({ author: '', updatedOn: '' }));
const mockAPI = {
listFiles,
readFile,
readFileMetadata,
originRepoURL: 'originRepoURL',
};
it('should return entries and cursor', async () => {
const giteaImplementation = new GiteaImplementation(config);
giteaImplementation.api = mockAPI;
const files = [];
const count = 1501;
for (let i = 0; i < count; i++) {
const id = `${i}`.padStart(`${count}`.length, '0');
files.push({
id,
path: `posts/post-${id}.md`,
});
}
listFiles.mockResolvedValue(files);
readFile.mockImplementation((_path, id) => Promise.resolve(`${id}`));
const expectedEntries = files
.slice(0, 20)
.map(({ id, path }) => ({ data: id, file: { path, id, author: '', updatedOn: '' } }));
const expectedCursor = Cursor.create({
actions: ['next', 'last'],
meta: { page: 1, count, pageSize: 20, pageCount: 76 },
data: { files },
});
// eslint-disable-next-line @typescript-eslint/no-explicit-any
expectedEntries[CURSOR_COMPATIBILITY_SYMBOL] = expectedCursor;
const result = await giteaImplementation.entriesByFolder('posts', 'md', 1);
expect(result).toEqual(expectedEntries);
expect(listFiles).toHaveBeenCalledTimes(1);
expect(listFiles).toHaveBeenCalledWith('posts', { depth: 1, repoURL: 'originRepoURL' });
expect(readFile).toHaveBeenCalledTimes(20);
});
});
describe('traverseCursor', () => {
const listFiles = jest.fn();
const readFile = jest.fn((_path, id) => Promise.resolve(`${id}`));
const readFileMetadata = jest.fn(() => Promise.resolve({}));
const mockAPI = {
listFiles,
readFile,
originRepoURL: 'originRepoURL',
readFileMetadata,
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const files = [];
const count = 1501;
for (let i = 0; i < count; i++) {
const id = `${i}`.padStart(`${count}`.length, '0');
files.push({
id,
path: `posts/post-${id}.md`,
});
}
it('should handle next action', async () => {
const giteaImplementation = new GiteaImplementation(config);
giteaImplementation.api = mockAPI;
const cursor = Cursor.create({
actions: ['next', 'last'],
meta: { page: 1, count, pageSize: 20, pageCount: 76 },
data: { files },
});
const expectedEntries = files
.slice(20, 40)
.map(({ id, path }) => ({ data: id, file: { path, id } }));
const expectedCursor = Cursor.create({
actions: ['prev', 'first', 'next', 'last'],
meta: { page: 2, count, pageSize: 20, pageCount: 76 },
data: { files },
});
const result = await giteaImplementation.traverseCursor(cursor, 'next');
expect(result).toEqual({
entries: expectedEntries,
cursor: expectedCursor,
});
});
it('should handle prev action', async () => {
const giteaImplementation = new GiteaImplementation(config);
giteaImplementation.api = mockAPI;
const cursor = Cursor.create({
actions: ['prev', 'first', 'next', 'last'],
meta: { page: 2, count, pageSize: 20, pageCount: 76 },
data: { files },
});
const expectedEntries = files
.slice(0, 20)
.map(({ id, path }) => ({ data: id, file: { path, id } }));
const expectedCursor = Cursor.create({
actions: ['next', 'last'],
meta: { page: 1, count, pageSize: 20, pageCount: 76 },
data: { files },
});
const result = await giteaImplementation.traverseCursor(cursor, 'prev');
expect(result).toEqual({
entries: expectedEntries,
cursor: expectedCursor,
});
});
it('should handle last action', async () => {
const giteaImplementation = new GiteaImplementation(config);
giteaImplementation.api = mockAPI;
const cursor = Cursor.create({
actions: ['next', 'last'],
meta: { page: 1, count, pageSize: 20, pageCount: 76 },
data: { files },
});
const expectedEntries = files
.slice(1500)
.map(({ id, path }) => ({ data: id, file: { path, id } }));
const expectedCursor = Cursor.create({
actions: ['prev', 'first'],
meta: { page: 76, count, pageSize: 20, pageCount: 76 },
data: { files },
});
const result = await giteaImplementation.traverseCursor(cursor, 'last');
expect(result).toEqual({
entries: expectedEntries,
cursor: expectedCursor,
});
});
it('should handle first action', async () => {
const giteaImplementation = new GiteaImplementation(config);
giteaImplementation.api = mockAPI;
const cursor = Cursor.create({
actions: ['prev', 'first'],
meta: { page: 76, count, pageSize: 20, pageCount: 76 },
data: { files },
});
const expectedEntries = files
.slice(0, 20)
.map(({ id, path }) => ({ data: id, file: { path, id } }));
const expectedCursor = Cursor.create({
actions: ['next', 'last'],
meta: { page: 1, count, pageSize: 20, pageCount: 76 },
data: { files },
});
const result = await giteaImplementation.traverseCursor(cursor, 'first');
expect(result).toEqual({
entries: expectedEntries,
cursor: expectedCursor,
});
});
});
});