Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions packages/decap-cms-backend-gitlab/src/API.ts
Original file line number Diff line number Diff line change
Expand Up @@ -346,18 +346,19 @@ export default class API {
readFile = async (
path: string,
sha?: string | null,
{ parseText = true, branch = this.branch } = {},
{ parseText = true, branch = this.branch, lfs = false } = {},
): Promise<string | Blob> => {
const fetchContent = async () => {
const content = await this.request({
url: `${this.repoURL}/repository/files/${encodeURIComponent(path)}/raw`,
params: { ref: branch },
params: { ref: branch, ...(lfs ? { lfs: true } : {}) },
cache: 'no-store',
}).then<Blob | string>(parseText ? this.responseToText : this.responseToBlob);
return content;
};

const content = await readFile(sha, fetchContent, localForage, parseText);
const cacheKey = sha && lfs ? `${sha}.lfs` : sha;
const content = await readFile(cacheKey, fetchContent, localForage, parseText);
return content;
};

Expand Down
35 changes: 35 additions & 0 deletions packages/decap-cms-backend-gitlab/src/__tests__/API.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,41 @@ describe('GitLab API', () => {
});
});

describe('readFile', () => {
test('does not request GitLab LFS content by default', async () => {
const api = new API({ repo: 'foo/bar' });

api.request = jest.fn().mockResolvedValue({});
api.responseToText = jest.fn().mockReturnValue('file content');

await expect(api.readFile('static/uploads/image.png', null)).resolves.toBe('file content');

expect(api.request).toHaveBeenCalledWith({
url: '/projects/foo%2Fbar/repository/files/static%2Fuploads%2Fimage.png/raw',
params: { ref: 'master' },
cache: 'no-store',
});
});

test('requests GitLab LFS content when requested', async () => {
const api = new API({ repo: 'foo/bar' });
const blob = new Blob(['image content']);

api.request = jest.fn().mockResolvedValue({});
api.responseToBlob = jest.fn().mockReturnValue(blob);

await expect(
api.readFile('static/uploads/image.png', null, { parseText: false, lfs: true }),
).resolves.toBe(blob);

expect(api.request).toHaveBeenCalledWith({
url: '/projects/foo%2Fbar/repository/files/static%2Fuploads%2Fimage.png/raw',
params: { ref: 'master', lfs: true },
cache: 'no-store',
});
});
});

describe('getStatuses', () => {
test('should get preview statuses', async () => {
const api = new API({ repo: 'repo' });
Expand Down
71 changes: 71 additions & 0 deletions packages/decap-cms-backend-gitlab/src/__tests__/gitlab.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,77 @@ describe('gitlab backend', () => {
});
});

describe('media files', () => {
it('requests GitLab LFS content for media display files', async () => {
backend = resolveBackend(defaultConfig);
const blob = new Blob(['image content']);
const readFile = jest.fn().mockResolvedValue(blob);
backend.implementation.api = { readFile };
global.URL.createObjectURL = jest.fn().mockReturnValue('blob:http://localhost/image');

await expect(
backend.implementation.getMediaDisplayURL({
id: 'image-sha',
path: 'static/uploads/image.png',
}),
).resolves.toBe('blob:http://localhost/image');

expect(readFile).toHaveBeenCalledWith('static/uploads/image.png', 'image-sha', {
parseText: false,
lfs: true,
});
});

it('requests GitLab LFS content when downloading media files', async () => {
backend = resolveBackend(defaultConfig);
const blob = new Blob(['image content']);
const readFile = jest.fn().mockResolvedValue(blob);
backend.implementation.api = { readFile };
global.URL.createObjectURL = jest.fn().mockReturnValue('blob:http://localhost/image');

await expect(
backend.implementation.getMediaFile('static/uploads/image.png'),
).resolves.toEqual(
expect.objectContaining({
displayURL: 'blob:http://localhost/image',
path: 'static/uploads/image.png',
name: 'image.png',
}),
);

expect(readFile).toHaveBeenCalledWith('static/uploads/image.png', null, {
parseText: false,
lfs: true,
});
});

it('requests GitLab LFS content when loading unpublished entry media files', async () => {
backend = resolveBackend(defaultConfig);
const blob = new Blob(['image content']);
const readFile = jest.fn().mockResolvedValue(blob);
backend.implementation.api = { readFile };
global.URL.createObjectURL = jest.fn().mockReturnValue('blob:http://localhost/image');

await expect(
backend.implementation.loadMediaFile('cms/posts/example', {
path: 'static/uploads/image.png',
}),
).resolves.toEqual(
expect.objectContaining({
displayURL: 'blob:http://localhost/image',
path: 'static/uploads/image.png',
name: 'image.png',
}),
);

expect(readFile).toHaveBeenCalledWith('static/uploads/image.png', null, {
branch: 'cms/posts/example',
parseText: false,
lfs: true,
});
});
});

describe('listEntries', () => {
sharedSetup();

Expand Down
21 changes: 14 additions & 7 deletions packages/decap-cms-backend-gitlab/src/implementation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,16 +265,23 @@ export default class GitLab implements Implementation {

getMediaDisplayURL(displayURL: DisplayURL) {
this._mediaDisplayURLSem = this._mediaDisplayURLSem || semaphore(MAX_CONCURRENT_DOWNLOADS);
return getMediaDisplayURL(
displayURL,
this.api!.readFile.bind(this.api!),
this._mediaDisplayURLSem,
);
const readMediaFile = (
path: string,
id: string | null | undefined,
{ parseText }: { parseText: boolean },
) => this.api!.readFile(path, id, { parseText, lfs: true });

return getMediaDisplayURL(displayURL, readMediaFile, this._mediaDisplayURLSem);
}

async getMediaFile(path: string) {
const name = basename(path);
const blob = await getMediaAsBlob(path, null, this.api!.readFile.bind(this.api!));
const readMediaFile = (
path: string,
id: string | null | undefined,
{ parseText }: { parseText: boolean },
) => this.api!.readFile(path, id, { parseText, lfs: true });
const blob = await getMediaAsBlob(path, null, readMediaFile);
const fileObj = blobToFileObj(name, blob);
const url = URL.createObjectURL(fileObj);
const id = await getBlobSHA(blob);
Expand Down Expand Up @@ -354,7 +361,7 @@ export default class GitLab implements Implementation {
path: string,
id: string | null | undefined,
{ parseText }: { parseText: boolean },
) => this.api!.readFile(path, id, { branch, parseText });
) => this.api!.readFile(path, id, { branch, parseText, lfs: true });

return getMediaAsBlob(file.path, null, readFile).then(blob => {
const name = basename(file.path);
Expand Down
Loading