diff --git a/assets/js/__tests__/upload-test.png b/assets/js/__tests__/upload-test.png new file mode 100644 index 000000000..770601f79 Binary files /dev/null and b/assets/js/__tests__/upload-test.png differ diff --git a/assets/js/__tests__/upload-test.webm b/assets/js/__tests__/upload-test.webm new file mode 100644 index 000000000..12442b6a3 Binary files /dev/null and b/assets/js/__tests__/upload-test.webm differ diff --git a/assets/js/__tests__/upload.spec.ts b/assets/js/__tests__/upload.spec.ts new file mode 100644 index 000000000..e9c5a5f07 --- /dev/null +++ b/assets/js/__tests__/upload.spec.ts @@ -0,0 +1,83 @@ +import { $, $$, clearEl } from '../utils/dom'; +import { setupImageUpload } from '../upload'; +import { assertNotNull, assertNotUndefined } from '../utils/assert'; +import { promises } from 'fs'; +import { join } from 'path'; +import { fireEvent } from '@testing-library/dom'; + +describe('Image upload form', () => { + let form: HTMLFormElement; + let imgPreviews: HTMLDivElement; + let fileField: HTMLInputElement; + let remoteUrl: HTMLInputElement; + let scraperError: HTMLDivElement; + let fetchButton: HTMLButtonElement; + let tagsEl: HTMLTextAreaElement; + let sourceEl: HTMLInputElement; + let descrEl: HTMLTextAreaElement; + + beforeAll(() => { + document.documentElement.insertAdjacentHTML('beforeend', ` +
+
+ + + + + + + + +
+ `); + + form = assertNotNull($('form')); + imgPreviews = assertNotNull($('#js-image-upload-previews')); + fileField = assertNotUndefined($$('.js-scraper')[0]); + remoteUrl = assertNotUndefined($$('.js-scraper')[1]); + scraperError = assertNotUndefined($$('.js-scraper')[2]); + tagsEl = assertNotNull($('.js-image-tags-input')); + sourceEl = assertNotNull($('.js-source-url')); + descrEl = assertNotNull($('.js-image-descr-input')); + fetchButton = assertNotNull($('#js-scraper-preview')); + + setupImageUpload(); + }); + + let mockPng: File; + let mockWebm: File; + + beforeAll(async() => { + const mockPngPath = join(__dirname, 'upload-test.png'); + const mockWebmPath = join(__dirname, 'upload-test.webm'); + + mockPng = new File([(await promises.readFile(mockPngPath, { encoding: null })).buffer], 'upload-test.png', { type: 'image/png' }); + mockWebm = new File([(await promises.readFile(mockWebmPath, { encoding: null })).buffer], 'upload-test.webm', { type: 'video/webm' }); + }); + + beforeEach(() => { + // Reset the state of everything between runs + clearEl(imgPreviews); + form.reset(); + }); + + it('should disable fetch button on empty source', () => { + fireEvent.input(remoteUrl, { target: { value: '' }}); + expect(fetchButton.disabled).toBe(true); + }); + + it('should enable fetch button on non-empty source', () => { + fireEvent.input(remoteUrl, { target: { value: 'http://localhost/images/1' }}); + expect(fetchButton.disabled).toBe(false); + }); + + it('should create a preview element when an image file is uploaded', () => { + fireEvent.change(fileField, { target: { files: [mockPng] }}); + expect(imgPreviews.querySelectorAll('img').length).toBe(1); + }); + + it('should create a preview element when a Matroska video file is uploaded', () => { + fireEvent.change(fileField, { target: { files: [mockWebm] }}); + expect(imgPreviews.querySelectorAll('video').length).toBe(1); + }); +});