-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
6,730 additions
and
1,036 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
node_modules | ||
lib | ||
cjs | ||
cjs | ||
coverage | ||
.DS_Store |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
module.exports = { | ||
presets: [ | ||
["@babel/preset-env", { targets: { node: "current" } }], | ||
"@babel/preset-typescript", | ||
], | ||
}; |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
import React from "react"; | ||
import { screen, render, act } from "@testing-library/react"; | ||
import { BasicTestUpload } from "./TestComponents"; | ||
import userEvent from "@testing-library/user-event"; | ||
|
||
test("It uploads a file correctly", async () => { | ||
global.xhrOpen = jest.fn(); | ||
global.xhrSend = jest.fn(); | ||
render(<BasicTestUpload method="POST" url="github.gov" />); | ||
//loading is hidden | ||
expect(screen.queryByText("loading")).toEqual(null); | ||
|
||
//upload a file into the input | ||
const file = new File(["hello"], "hello.png", { type: "image/png" }); | ||
userEvent.upload(screen.getByLabelText("upload"), file); | ||
|
||
//loading is now shown | ||
screen.getByText("loading"); | ||
|
||
await act(() => new Promise((resolve) => setTimeout(resolve, 0))); | ||
|
||
expect(global.xhrOpen.mock.calls[0][0]).toEqual("POST"); | ||
expect(global.xhrOpen.mock.calls[0][1]).toEqual("github.gov"); | ||
//check the type sent to the server | ||
expect(global.xhrSend.mock.calls[0][0].name).toEqual("hello.png"); | ||
expect(global.xhrSend.mock.calls[0][0].type).toEqual("image/png"); | ||
}); | ||
|
||
test("Renders done after upload is complete", async () => { | ||
global.xhrListener = jest.fn(); | ||
render(<BasicTestUpload method="POST" url="github.gov" />); | ||
|
||
//upload a file into the input | ||
const file = new File(["hello"], "hello.png", { type: "image/png" }); | ||
userEvent.upload(screen.getByLabelText("upload"), file); | ||
//wait for the next tick | ||
await act(() => new Promise((resolve) => setTimeout(resolve, 0))); | ||
|
||
expect(global.xhrListener.mock.calls[1][0]).toEqual("load"); | ||
expect(screen.queryByText("done")).toEqual(null); | ||
|
||
//call the load method on the xhr mock | ||
act(() => global.xhrListener.mock.calls[1][1]()); | ||
|
||
expect(screen.getByText("done")).toBeTruthy(); | ||
}); | ||
|
||
test("Renders upload progress", async () => { | ||
global.xhrListener = jest.fn(); | ||
render(<BasicTestUpload method="POST" url="github.gov" />); | ||
|
||
//upload a file into the input | ||
const file = new File(["hello"], "hello.png", { type: "image/png" }); | ||
userEvent.upload(screen.getByLabelText("upload"), file); | ||
//wait for the next tick | ||
await act(() => new Promise((resolve) => setTimeout(resolve, 0))); | ||
|
||
expect(global.xhrListener.mock.calls[0][0]).toEqual("progress"); | ||
expect(screen.queryByText("done")).toEqual(null); | ||
|
||
//call the load method on the xhr mock | ||
act(() => global.xhrListener.mock.calls[0][1]({ loaded: 20, total: 100 })); | ||
|
||
expect(screen.getByText("loading")).toBeTruthy(); | ||
expect(screen.getByText("20% progress")).toBeTruthy(); | ||
}); | ||
|
||
test("Renders error message if xhr fails", async () => { | ||
global.xhrListener = jest.fn(); | ||
render(<BasicTestUpload method="POST" url="github.gov" />); | ||
|
||
//upload a file into the input | ||
const file = new File(["hello"], "hello.png", { type: "image/png" }); | ||
userEvent.upload(screen.getByLabelText("upload"), file); | ||
//wait for the next tick | ||
await act(() => new Promise((resolve) => setTimeout(resolve, 0))); | ||
|
||
expect(global.xhrListener.mock.calls[2][0]).toEqual("error"); | ||
expect(screen.queryByText("bad error!")).toEqual(null); | ||
|
||
//call the load method on the xhr mock | ||
act(() => global.xhrListener.mock.calls[2][1]("bad error!")); | ||
|
||
expect(screen.getByText("bad error!")).toBeTruthy(); | ||
}); | ||
|
||
test("Renders error message if xhr aborts", async () => { | ||
global.xhrListener = jest.fn(); | ||
render(<BasicTestUpload method="POST" url="github.gov" />); | ||
|
||
//upload a file into the input | ||
const file = new File(["hello"], "hello.png", { type: "image/png" }); | ||
userEvent.upload(screen.getByLabelText("upload"), file); | ||
//wait for the next tick | ||
await act(() => new Promise((resolve) => setTimeout(resolve, 0))); | ||
|
||
expect(global.xhrListener.mock.calls[3][0]).toEqual("abort"); | ||
expect(screen.queryByText("bad abort!")).toEqual(null); | ||
|
||
//call the load method on the xhr mock | ||
act(() => global.xhrListener.mock.calls[3][1]("bad abort!")); | ||
|
||
expect(screen.getByText("bad abort!")).toBeTruthy(); | ||
}); | ||
|
||
test("Skips upload if options return null", async () => { | ||
let skipOptions = jest.fn(); | ||
render( | ||
<BasicTestUpload | ||
method="POST" | ||
url="github.gov" | ||
skipOptionsCb={skipOptions} | ||
/> | ||
); | ||
|
||
//upload a file into the input | ||
const file = new File(["hello"], "hello.png", { type: "image/png" }); | ||
userEvent.upload(screen.getByLabelText("upload"), file); | ||
//wait for the next tick | ||
await act(() => new Promise((resolve) => setTimeout(resolve, 0))); | ||
|
||
expect(skipOptions.mock.calls.length).toEqual(1); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import React from "react"; | ||
import { screen, render, act } from "@testing-library/react"; | ||
import { BasicTestUpload } from "./TestComponents"; | ||
import userEvent from "@testing-library/user-event"; | ||
|
||
test("Sets response headers into an object", async () => { | ||
global.xhrListener = jest.fn(); | ||
render(<BasicTestUpload method="POST" url="github.gov" />); | ||
|
||
//upload a file into the input | ||
const file = new File(["hello"], "hello.png", { type: "image/png" }); | ||
userEvent.upload(screen.getByLabelText("upload"), file); | ||
//wait for the next tick | ||
await act(() => new Promise((resolve) => setTimeout(resolve, 0))); | ||
|
||
expect(global.xhrListener.mock.calls[1][0]).toEqual("load"); | ||
expect(screen.queryByText("done")).toEqual(null); | ||
|
||
//call the load method on the xhr mock | ||
act(() => global.xhrListener.mock.calls[1][1]()); | ||
|
||
expect(screen.getByText("The test response header")).toBeTruthy(); | ||
}); | ||
|
||
test("Sets request headers from options object", async () => { | ||
global.xhrRequestHeader = jest.fn(); | ||
render( | ||
<BasicTestUpload | ||
method="POST" | ||
url="github.gov" | ||
headers={{ yo: "awesome", another: "cool" }} | ||
/> | ||
); | ||
|
||
//upload a file into the input | ||
const file = new File(["hello"], "hello.png", { type: "image/png" }); | ||
userEvent.upload(screen.getByLabelText("upload"), file); | ||
//wait for the next tick | ||
await act(() => new Promise((resolve) => setTimeout(resolve, 0))); | ||
|
||
expect(global.xhrRequestHeader.mock.calls[0][0]).toEqual("yo"); | ||
expect(global.xhrRequestHeader.mock.calls[0][1]).toEqual("awesome"); | ||
expect(global.xhrRequestHeader.mock.calls[1][0]).toEqual("another"); | ||
expect(global.xhrRequestHeader.mock.calls[1][1]).toEqual("cool"); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import React from "react"; | ||
import { useEffect } from "react"; | ||
import { useUpload } from "../src"; | ||
|
||
type Props = { | ||
method: string; | ||
url: string; | ||
headers?: any; | ||
skipOptionsCb?: () => any; | ||
}; | ||
export const BasicTestUpload = ({ | ||
skipOptionsCb, | ||
method, | ||
url, | ||
headers, | ||
}: Props) => { | ||
let [upload, { error, responseHeaders, progress, done, loading }] = useUpload( | ||
({ files }) => { | ||
if (skipOptionsCb) { | ||
skipOptionsCb(); | ||
return undefined; | ||
} | ||
return { | ||
method, | ||
url, | ||
headers, | ||
body: files[0], | ||
}; | ||
} | ||
); | ||
|
||
return ( | ||
<div> | ||
{responseHeaders ? <div>{responseHeaders.Test}</div> : null} | ||
{error ? <div>{error}</div> : null} | ||
{done ? <div>done</div> : null} | ||
{loading ? <div>loading</div> : null} | ||
{loading ? `${progress}% progress` : null} | ||
<input | ||
type="file" | ||
aria-label="upload" | ||
onChange={(e) => { | ||
if (e.target.files) { | ||
upload({ files: e.target.files }); | ||
} | ||
}} | ||
/> | ||
</div> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
declare var xhrOpen: jest.Mock; | ||
declare var xhrSend: jest.Mock; | ||
declare var xhrListener: jest.Mock; | ||
declare var xhrRequestHeader: jest.Mock; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
global.XMLHttpRequest = function () { | ||
let addEventListener = (name, callback) => | ||
global.xhrListener?.(name, callback); | ||
let fake = () => true; | ||
return { | ||
open: global.xhrOpen ?? fake, | ||
send: global.xhrSend ?? fake, | ||
upload: { | ||
addEventListener, | ||
}, | ||
addEventListener, | ||
setRequestHeader: global.xhrRequestHeader ?? fake, | ||
getAllResponseHeaders: () => "Test: The test response header", | ||
}; | ||
}; |