* Revert "Revert "feat(core): Align GitHub metadata handling with other backends (#3292)"" This reverts commit 5bdd3df9ccbb5149c22d79987ebdcd6cab4b261f. * fix(backend-github): fix migration code * test(backend-github): fix test * test(e2e): shorten wait time * test(e2e): try and fix test on CI
218 lines
6.8 KiB
JavaScript
218 lines
6.8 KiB
JavaScript
import GitHubImplementation from '../implementation';
|
|
|
|
jest.spyOn(console, 'error').mockImplementation(() => {});
|
|
|
|
describe('github backend implementation', () => {
|
|
const config = {
|
|
backend: {
|
|
repo: 'owner/repo',
|
|
open_authoring: false,
|
|
api_root: 'https://api.github.com',
|
|
},
|
|
};
|
|
|
|
const createObjectURL = jest.fn();
|
|
global.URL = {
|
|
createObjectURL,
|
|
};
|
|
|
|
createObjectURL.mockReturnValue('displayURL');
|
|
|
|
beforeEach(() => {
|
|
jest.clearAllMocks();
|
|
});
|
|
|
|
describe('forkExists', () => {
|
|
it('should return true when repo is fork and parent matches originRepo', async () => {
|
|
const gitHubImplementation = new GitHubImplementation(config);
|
|
gitHubImplementation.currentUser = jest.fn().mockResolvedValue({ login: 'login' });
|
|
|
|
global.fetch = jest.fn().mockResolvedValue({
|
|
// matching should be case-insensitive
|
|
json: () => ({ fork: true, parent: { full_name: 'OWNER/REPO' } }),
|
|
});
|
|
|
|
await expect(gitHubImplementation.forkExists({ token: 'token' })).resolves.toBe(true);
|
|
|
|
expect(gitHubImplementation.currentUser).toHaveBeenCalledTimes(1);
|
|
expect(gitHubImplementation.currentUser).toHaveBeenCalledWith({ token: 'token' });
|
|
expect(global.fetch).toHaveBeenCalledTimes(1);
|
|
expect(global.fetch).toHaveBeenCalledWith('https://api.github.com/repos/login/repo', {
|
|
method: 'GET',
|
|
headers: {
|
|
Authorization: 'token token',
|
|
},
|
|
});
|
|
});
|
|
|
|
it('should return false when repo is not a fork', async () => {
|
|
const gitHubImplementation = new GitHubImplementation(config);
|
|
gitHubImplementation.currentUser = jest.fn().mockResolvedValue({ login: 'login' });
|
|
|
|
global.fetch = jest.fn().mockResolvedValue({
|
|
// matching should be case-insensitive
|
|
json: () => ({ fork: false }),
|
|
});
|
|
|
|
expect.assertions(1);
|
|
await expect(gitHubImplementation.forkExists({ token: 'token' })).resolves.toBe(false);
|
|
});
|
|
|
|
it("should return false when parent doesn't match originRepo", async () => {
|
|
const gitHubImplementation = new GitHubImplementation(config);
|
|
gitHubImplementation.currentUser = jest.fn().mockResolvedValue({ login: 'login' });
|
|
|
|
global.fetch = jest.fn().mockResolvedValue({
|
|
json: () => ({ fork: true, parent: { full_name: 'owner/other_repo' } }),
|
|
});
|
|
|
|
expect.assertions(1);
|
|
await expect(gitHubImplementation.forkExists({ token: 'token' })).resolves.toBe(false);
|
|
});
|
|
});
|
|
|
|
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 gitHubImplementation = new GitHubImplementation(config);
|
|
gitHubImplementation.api = mockAPI;
|
|
|
|
const mediaFile = {
|
|
fileObj: { size: 100, name: 'image.png' },
|
|
path: '/media/image.png',
|
|
};
|
|
|
|
expect.assertions(5);
|
|
await expect(gitHubImplementation.persistMedia(mediaFile, {})).resolves.toEqual({
|
|
id: 0,
|
|
name: 'image.png',
|
|
size: 100,
|
|
displayURL: 'displayURL',
|
|
path: 'media/image.png',
|
|
});
|
|
|
|
expect(persistFiles).toHaveBeenCalledTimes(1);
|
|
expect(persistFiles).toHaveBeenCalledWith(null, [mediaFile], {});
|
|
expect(createObjectURL).toHaveBeenCalledTimes(1);
|
|
expect(createObjectURL).toHaveBeenCalledWith(mediaFile.fileObj);
|
|
});
|
|
|
|
it('should log and throw error on "persistFiles" error', async () => {
|
|
const gitHubImplementation = new GitHubImplementation(config);
|
|
gitHubImplementation.api = mockAPI;
|
|
|
|
const error = new Error('failed to persist files');
|
|
persistFiles.mockRejectedValue(error);
|
|
|
|
const mediaFile = {
|
|
value: 'image.png',
|
|
fileObj: { size: 100 },
|
|
path: '/media/image.png',
|
|
};
|
|
|
|
expect.assertions(5);
|
|
await expect(gitHubImplementation.persistMedia(mediaFile)).rejects.toThrowError(error);
|
|
|
|
expect(persistFiles).toHaveBeenCalledTimes(1);
|
|
expect(createObjectURL).toHaveBeenCalledTimes(0);
|
|
expect(console.error).toHaveBeenCalledTimes(1);
|
|
expect(console.error).toHaveBeenCalledWith(error);
|
|
});
|
|
});
|
|
|
|
describe('loadEntryMediaFiles', () => {
|
|
const readFile = jest.fn();
|
|
const mockAPI = {
|
|
readFile,
|
|
};
|
|
|
|
it('should return media files from meta data', async () => {
|
|
const gitHubImplementation = new GitHubImplementation(config);
|
|
gitHubImplementation.api = mockAPI;
|
|
|
|
const blob = new Blob(['']);
|
|
readFile.mockResolvedValue(blob);
|
|
|
|
const file = new File([blob], name);
|
|
|
|
await expect(
|
|
gitHubImplementation.loadEntryMediaFiles('branch', [
|
|
{ path: 'static/media/image.png', id: 'sha' },
|
|
]),
|
|
).resolves.toEqual([
|
|
{
|
|
id: 'sha',
|
|
displayURL: 'displayURL',
|
|
path: 'static/media/image.png',
|
|
name: 'image.png',
|
|
size: file.size,
|
|
file,
|
|
},
|
|
]);
|
|
});
|
|
});
|
|
|
|
describe('unpublishedEntry', () => {
|
|
const generateContentKey = jest.fn();
|
|
const readUnpublishedBranchFile = jest.fn();
|
|
|
|
const mockAPI = {
|
|
generateContentKey,
|
|
readUnpublishedBranchFile,
|
|
};
|
|
|
|
it('should return unpublished entry', async () => {
|
|
const gitHubImplementation = new GitHubImplementation(config);
|
|
gitHubImplementation.api = mockAPI;
|
|
gitHubImplementation.loadEntryMediaFiles = jest
|
|
.fn()
|
|
.mockResolvedValue([{ path: 'image.png', id: 'sha' }]);
|
|
|
|
generateContentKey.mockReturnValue('contentKey');
|
|
|
|
const data = {
|
|
fileData: 'fileData',
|
|
isModification: true,
|
|
metaData: {
|
|
branch: 'branch',
|
|
objects: {
|
|
entry: { path: 'entry-path', mediaFiles: [{ path: 'image.png', id: 'sha' }] },
|
|
},
|
|
},
|
|
};
|
|
readUnpublishedBranchFile.mockResolvedValue(data);
|
|
|
|
const collection = 'posts';
|
|
await expect(gitHubImplementation.unpublishedEntry(collection, 'slug')).resolves.toEqual({
|
|
slug: 'slug',
|
|
file: { path: 'entry-path', id: null },
|
|
data: 'fileData',
|
|
metaData: data.metaData,
|
|
mediaFiles: [{ path: 'image.png', id: 'sha' }],
|
|
isModification: true,
|
|
});
|
|
|
|
expect(generateContentKey).toHaveBeenCalledTimes(1);
|
|
expect(generateContentKey).toHaveBeenCalledWith('posts', 'slug');
|
|
|
|
expect(readUnpublishedBranchFile).toHaveBeenCalledTimes(1);
|
|
expect(readUnpublishedBranchFile).toHaveBeenCalledWith('contentKey');
|
|
|
|
expect(gitHubImplementation.loadEntryMediaFiles).toHaveBeenCalledTimes(1);
|
|
expect(gitHubImplementation.loadEntryMediaFiles).toHaveBeenCalledWith('branch', [
|
|
{ path: 'image.png', id: 'sha' },
|
|
]);
|
|
});
|
|
});
|
|
});
|