From 9f8b4fa9d86d6435deefdb3f9e95e87d86bd7393 Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Fri, 2 Mar 2018 17:54:38 -0800 Subject: [PATCH] start adding media upload test --- package.json | 6 ++++- routes/_actions/media.js | 4 +-- routes/_api/media.js | 2 +- .../_components/compose/ComposeToolbar.html | 11 ++++++++ tests/blobUtils.js | 15 +++++++++++ tests/images.js | 1 + tests/spec/12-compose.js | 8 +++++- tests/utils.js | 26 +++++++++---------- 8 files changed, 55 insertions(+), 18 deletions(-) create mode 100644 tests/blobUtils.js create mode 100644 tests/images.js diff --git a/package.json b/package.json index 6dd57e5b..225cdd5d 100644 --- a/package.json +++ b/package.json @@ -96,7 +96,11 @@ "__assets__", "test", "fixture", - "Element" + "Element", + "FormData", + "atob", + "btoa", + "Blob" ], "ignore": [ "dist", diff --git a/routes/_actions/media.js b/routes/_actions/media.js index 35e50cb9..0c5ba9e4 100644 --- a/routes/_actions/media.js +++ b/routes/_actions/media.js @@ -2,7 +2,7 @@ import { store } from '../_store/store' import { uploadMedia } from '../_api/media' import { toast } from '../_utils/toast' -export async function doMediaUpload(file) { +export async function doMediaUpload (file) { let instanceName = store.get('currentInstance') let accessToken = store.get('accessToken') store.set({uploadingMedia: true}) @@ -20,4 +20,4 @@ export async function doMediaUpload(file) { } finally { store.set({uploadingMedia: false}) } -} \ No newline at end of file +} diff --git a/routes/_api/media.js b/routes/_api/media.js index 5fe76587..c3a6c1f8 100644 --- a/routes/_api/media.js +++ b/routes/_api/media.js @@ -6,4 +6,4 @@ export async function uploadMedia (instanceName, accessToken, file) { formData.append('file', file) let url = `${basename(instanceName)}/api/v1/media` return postWithTimeout(url, formData, auth(accessToken)) -} \ No newline at end of file +} diff --git a/routes/_components/compose/ComposeToolbar.html b/routes/_components/compose/ComposeToolbar.html index 88d56a25..62a426f6 100644 --- a/routes/_components/compose/ComposeToolbar.html +++ b/routes/_components/compose/ComposeToolbar.html @@ -32,6 +32,17 @@ import { doMediaUpload } from '../../_actions/media' export default { + oncreate() { + if (process.env.NODE_ENV !== 'production') { + window.__fakeFileInput = (file) => { + this.onFileChange({ + target: { + files: [file] + } + }) + } + } + }, components: { IconButton }, diff --git a/tests/blobUtils.js b/tests/blobUtils.js new file mode 100644 index 00000000..3e032093 --- /dev/null +++ b/tests/blobUtils.js @@ -0,0 +1,15 @@ +export function base64StringToBlob (base64, type) { + function binaryStringToArrayBuffer (binary) { + let length = binary.length + let buf = new ArrayBuffer(length) + let arr = new Uint8Array(buf) + let i = -1 + while (++i < length) { + arr[i] = binary.charCodeAt(i) + } + return buf + } + + let parts = [binaryStringToArrayBuffer(atob(base64))] + return type ? new Blob(parts, {type: type}) : new Blob(parts) +} diff --git a/tests/images.js b/tests/images.js new file mode 100644 index 00000000..4fb25735 --- /dev/null +++ b/tests/images.js @@ -0,0 +1 @@ +export const image1 = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==' diff --git a/tests/spec/12-compose.js b/tests/spec/12-compose.js index 588bea2e..f07d2ec4 100644 --- a/tests/spec/12-compose.js +++ b/tests/spec/12-compose.js @@ -2,7 +2,7 @@ import { Selector as $ } from 'testcafe' import { composeButton, composeInput, composeLengthIndicator, emojiButton, getComposeSelectionStart, getUrl, homeNavButton, - notificationsNavButton + notificationsNavButton, uploadMedia } from '../utils' import { foobarRole } from '../roles' import times from 'lodash/times' @@ -91,3 +91,9 @@ test('inserts emoji without typing anything', async t => { .click($('button img[title=":blobpeek:"]')) .expect(composeInput.value).eql(':blobpeek: :blobpats: ') }) + +test('inserts media', async t => { + await t.useRole(foobarRole) + await uploadMedia() + await t.expect($('.compose-media:nth-child(1) img').getAttribute('alt')).eql('foo.png') +}) diff --git a/tests/utils.js b/tests/utils.js index de122a78..f21707e4 100644 --- a/tests/utils.js +++ b/tests/utils.js @@ -1,10 +1,11 @@ import { ClientFunction as exec, Selector as $ } from 'testcafe' +import * as images from './images' +import * as blobUtils from './blobUtils' const SCROLL_INTERVAL = 3 export const settingsButton = $('nav a[aria-label=Settings]') export const instanceInput = $('#instanceInput') -export const addInstanceButton = $('.add-new-instance button') export const modalDialogContents = $('.modal-dialog-contents') export const closeDialogButton = $('.close-dialog-button') export const notificationsNavButton = $('nav a[href="/notifications"]') @@ -38,6 +39,17 @@ export const getComposeSelectionStart = exec(() => composeInput().selectionStart dependencies: { composeInput } }) +export const uploadMedia = exec(() => { + let blob = blobUtils.base64StringToBlob(images.image1, 'image/png') + blob.name = 'foo.png' + window.__fakeFileInput(blob) +}, { + dependencies: { + images, + blobUtils + } +}) + export function getNthStatus (n) { return $(`div[aria-hidden="false"] > article[aria-posinset="${n}"]`) } @@ -106,18 +118,6 @@ export async function validateTimeline (t, timeline) { } } -export async function scrollTimelineUp (t) { - let oldFirstItem = await getFirstVisibleStatus().getAttribute('aria-posinset') - await t.hover(getFirstVisibleStatus()) - let newFirstItem - while (true) { - newFirstItem = await getFirstVisibleStatus().getAttribute('aria-posinset') - if (newFirstItem === '0' || newFirstItem !== oldFirstItem) { - break - } - } -} - export async function scrollToTopOfTimeline (t) { let i = await getFirstVisibleStatus().getAttribute('aria-posinset') while (true) {