Commit 28384648 authored by Enrique Alcantara's avatar Enrique Alcantara

Upload file service

The upload file service sends a post request
to the URL defined in the uploadsPath parameter
and parses the HTML response to extract
the src and canonicalSrc of the uploaded attachment
parent bf328f47
import axios from '~/lib/utils/axios_utils';
const extractAttachmentLinkUrl = (html) => {
const parser = new DOMParser();
const { body } = parser.parseFromString(html, 'text/html');
const link = body.querySelector('a');
const src = link.getAttribute('href');
const { canonicalSrc } = link.dataset;
return { src, canonicalSrc };
};
/**
* Uploads a file with a post request to the URL indicated
* in the uploadsPath parameter. The expected response of the
* uploads service is a JSON object that contains, at least, a
* link property. The link property should contain markdown link
* definition (i.e. [GitLab](https://gitlab.com)).
*
* This Markdown will be rendered to extract its canonical and full
* URLs using GitLab Flavored Markdown renderer in the backend.
*
* @param {Object} params
* @param {String} params.uploadsPath An absolute URL that points to a service
* that allows sending a file for uploading via POST request.
* @param {String} params.renderMarkdown A function that accepts a markdown string
* and returns a rendered version in HTML format.
* @param {File} params.file The file to upload
*
* @returns Returns an object with two properties:
*
* canonicalSrc: The URL as defined in the Markdown
* src: The absolute URL that points to the resource in the server
*/
export const uploadFile = async ({ uploadsPath, renderMarkdown, file }) => {
const formData = new FormData();
formData.append('file', file, file.name);
const { data } = await axios.post(uploadsPath, formData);
const { markdown } = data.link;
const rendered = await renderMarkdown(markdown);
return extractAttachmentLinkUrl(rendered);
};
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
import { uploadFile } from '~/content_editor/services/upload_file';
import httpStatus from '~/lib/utils/http_status';
describe('content_editor/services/upload_file', () => {
const uploadsPath = '/uploads';
const file = new File(['content'], 'file.txt');
// TODO: Replace with automated fixture
const renderedAttachmentLinkFixture =
'<a href="/group1/project1/-/wikis/test-file.png" data-canonical-src="test-file.png"><img data-src="/group1/project1/-/wikis/test-file.png" data-canonical-src="test-file.png"></a></p>';
const successResponse = {
link: {
markdown: '[GitLab](https://gitlab.com)',
},
};
const parseHTML = (html) => new DOMParser().parseFromString(html, 'text/html');
let mock;
let renderMarkdown;
let renderedMarkdown;
beforeEach(() => {
const formData = new FormData();
formData.append('file', file);
renderedMarkdown = parseHTML(renderedAttachmentLinkFixture);
mock = new MockAdapter(axios);
mock.onPost(uploadsPath, formData).reply(httpStatus.OK, successResponse);
renderMarkdown = jest.fn().mockResolvedValue(renderedAttachmentLinkFixture);
});
afterEach(() => {
mock.restore();
});
it('returns src and canonicalSrc of uploaded file', async () => {
const response = await uploadFile({ uploadsPath, renderMarkdown, file });
expect(renderMarkdown).toHaveBeenCalledWith(successResponse.link.markdown);
expect(response).toEqual({
src: renderedMarkdown.querySelector('a').getAttribute('href'),
canonicalSrc: renderedMarkdown.querySelector('a').dataset.canonicalSrc,
});
});
});
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment