Skip to content

Commit

Permalink
fix(ecau): drop images without jQuery
Browse files Browse the repository at this point in the history
  • Loading branch information
ROpdebee committed Jun 11, 2022
1 parent 5da479d commit 45085f1
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 87 deletions.
42 changes: 0 additions & 42 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
"@types/greasemonkey": "4.0.3",
"@types/jest": "28.1.1",
"@types/jest-when": "3.5.0",
"@types/jquery": "3.5.14",
"@types/postcss-preset-env": "6.7.3",
"@types/rollup__plugin-virtual": "2.0.1",
"@types/rollup-plugin-progress": "1.1.1",
Expand Down Expand Up @@ -87,7 +86,6 @@
"warcio": "1.5.1"
},
"dependencies": {
"jquery": "3.6.0",
"p-throttle": "5.0.0",
"ts-custom-error": "3.2.0"
}
Expand Down
33 changes: 9 additions & 24 deletions src/mb_enhanced_cover_art_uploads/form.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type { ArtworkTypeIDs } from '@lib/MB/CoverArt';
import type { EditNote } from '@lib/MB/EditNote';
import { cloneIntoPageContext, getFromPageContext } from '@lib/compat';
import { assertDefined } from '@lib/util/assert';
import { retryTimes } from '@lib/util/async';
import { qs, qsa } from '@lib/util/dom';
Expand All @@ -13,12 +12,6 @@ export async function enqueueImages({ images }: FetchedImages, defaultTypes: Art
}));
}

declare global {
interface Window {
$: typeof jQuery;
}
}

async function enqueueImage(image: FetchedImage, defaultTypes: ArtworkTypeIDs[], defaultComment: string): Promise<void> {
dropImage(image.content);
await retryTimes(setImageParameters.bind(
Expand All @@ -30,23 +23,15 @@ async function enqueueImage(image: FetchedImage, defaultTypes: ArtworkTypeIDs[],
}

function dropImage(imageData: File): void {
// Fake event to trigger the drop event on the drag'n'drop element
// Using jQuery because native JS cannot manually trigger such events
// for security reasons.
const $ = getFromPageContext('$');
const dropEvent = $.Event('drop') as JQuery.TriggeredEvent;
// We need to clone the underlying data since we might be running as a
// content script, meaning that even though we trigger the event through
// unsafeWindow, the page context may not be able to access the event's
// properties.
dropEvent.originalEvent = cloneIntoPageContext({
dataTransfer: { files: [imageData] },
} as unknown as DragEvent);

// Note that we're using MB's own jQuery here, not a script-local one.
// We need to reuse MB's own jQuery to be able to trigger the event
// handler.
$('#drop-zone').trigger(dropEvent);
const dataTransfer = new DataTransfer();
// `files` is a readonly property, but we can circumvent that with Object.defineProperty.
Object.defineProperty(dataTransfer, 'files', {
value: [imageData],
});

const dropEvent = new DragEvent('drop', { dataTransfer });

qs('#drop-zone').dispatchEvent(dropEvent);
}

function setImageParameters(imageName: string, imageTypes: ArtworkTypeIDs[], imageComment: string): void {
Expand Down
2 changes: 1 addition & 1 deletion src/mb_enhanced_cover_art_uploads/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
{ "path": "../lib/" }
],
"compilerOptions": {
"types": ["jquery", "nativejsx/types/jsx", "greasemonkey"]
"types": ["nativejsx/types/jsx", "greasemonkey"]
}
}
47 changes: 29 additions & 18 deletions tests/unit/mb_enhanced_cover_art_uploads/form.test.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,40 @@
import fs from 'fs/promises';
import path from 'path';

import $ from 'jquery';

import { ArtworkTypeIDs } from '@lib/MB/CoverArt';
import { EditNote } from '@lib/MB/EditNote';
import { qs } from '@lib/util/dom';
import { enqueueImages, fillEditNote } from '@src/mb_enhanced_cover_art_uploads/form';

import { createFetchedImage, createImageFile } from './test-utils/dummy-data';

// @ts-expect-error need to inject a jQuery
global.$ = $;
beforeAll(() => {
// Need to mock DataTransfer and DragEvent.
class DataTransfer {
public readonly files: File[];

constructor(files: File[]) {
this.files = files;
}
}

class DragEvent {
public readonly dataTransfer: DataTransfer;

public constructor(type: string, initOpts: { dataTransfer: DataTransfer }) {
this.dataTransfer = initOpts.dataTransfer;
}
}

global.DataTransfer = DataTransfer as unknown as typeof window.DataTransfer;
global.DragEvent = DragEvent as unknown as typeof window.DragEvent;
});

describe('enqueuing images', () => {
const mockHtml = '<div id="drop-zone"/><table><tbody data-bind="foreach: files_to_upload"/></table>';

async function insertFileRows(evt: JQuery.TriggeredEvent): Promise<void> {
const files = (evt.originalEvent as (DragEvent | undefined))?.dataTransfer?.files;
async function insertFileRows(evt: DragEvent): Promise<void> {
const files = evt.dataTransfer?.files;
if (!files) return;

const fileRowPath = path.resolve('.', 'tests', 'test-data', 'mb_enhanced_cover_art_uploads', 'form-row.html');
Expand All @@ -38,12 +56,12 @@ describe('enqueuing images', () => {
return row?.querySelector<HTMLInputElement>('input.comment')?.value;
}

const onDropMock = jest.fn().mockImplementation(insertFileRows);

beforeEach(() => {
document.body.innerHTML = mockHtml;
onDropMock.mockClear();
$('#drop-zone').on('drop', onDropMock);
jest.spyOn(qs<HTMLElement>('#drop-zone'), 'dispatchEvent').mockImplementation((evt) => {
void insertFileRows(evt as unknown as DragEvent);
return true;
});
});

it('triggers the correct drop event', async () => {
Expand All @@ -54,14 +72,7 @@ describe('enqueuing images', () => {
})],
});

expect(onDropMock).toHaveBeenCalledOnce();
expect(onDropMock).toHaveBeenCalledWith(expect.objectContaining({
originalEvent: {
dataTransfer: {
files: [image],
},
},
}));
expect(document.querySelector('tr')).not.toBeNil();
});

it('fills the correct parameters', async () => {
Expand Down

0 comments on commit 45085f1

Please sign in to comment.