When working on #620 my new discovered some shortcomings of the current test-support. This is a spin-off of the mentioned PR to discuss ideas to improve it :)
Utilize Test-Support ;)
Currently, the test-support for mirage is part of the public API for production code. It should be moved test-support to not pollute prod builds with that chunk of code.
Specifically: move addon/mirage to somewhere into addon-test-support
Multiple Adapters
At the moment, ember-file-upload ships with a handler for mirage. Would be nice to have support for polly.js, too.
Even better, I think equally imporant are the test-support utilities, such as extractFormData() and extractFileMetadata(). They are very much suitable for integration tests, ie.
// understand this as pseudo-code, I'm not writing this from memory (API and names are likely to be different)
test('it uploads (with polly)', async function(assert) {
this.server.polly.post('/photos/new', (req, res) => {
extractFileMetadata(req.responseBody);
});
});
As I created those tests myself without/prior to knowing those utils exists, they are likely to work with either polly as well as mirage :)
Imperatively Control the Upload Progress
Writing UIs around upload is definitely part of userland code. Giving developers a good way to test their UIs is key. To test what happens in each file.state? Using await selectFiles() would skip the uploading state and would require devs to either waitFor() of some dom node to appear or set some timeout on the request itself. Both are not reliable and have high potential to cause flaky tests, read more in this discussion.
An idea would be to have an imperative API to programmatically advance the state and be in control. Basically, a deferred promise - this is shim code:
test('it uploads (with polly)', async function(assert) {
const uploadHandler = new PollyUploadHandler();
this.server.polly.post('/photos/new', async (req, res) => {
return uploadHandler.handle((req, res) => {
// business logic code
});
});
await render(hbs`...`);
const upload = selectFilesForHandler('input[type="file"]', new File(...));
uploadHandler.startUpload(upload); // moves `state` into `uploading`
assert.dom('...').hasText('uploading...'); // asserts UI state for uploading
uploadHandler.success((req, res) => {
// possible business logic code
});
// --- OR ---
uploadHandler.fail(); // example for not making use of business logic
assert.dom('...').hasText('upload failed'); // assert UI for `error` state
});
This is a rough idea but I myself have too many questions how to shape the API around that, when and where to allow business logic, etc. My hope is to get the discussion going.
When working on #620 my new discovered some shortcomings of the current test-support. This is a spin-off of the mentioned PR to discuss ideas to improve it :)
Utilize Test-Support ;)
Currently, the test-support for mirage is part of the public API for production code. It should be moved
test-supportto not pollute prod builds with that chunk of code.Specifically: move
addon/mirageto somewhere intoaddon-test-supportMultiple Adapters
At the moment,
ember-file-uploadships with a handler for mirage. Would be nice to have support for polly.js, too.Even better, I think equally imporant are the test-support utilities, such as
extractFormData()andextractFileMetadata(). They are very much suitable for integration tests, ie.As I created those tests myself without/prior to knowing those utils exists, they are likely to work with either polly as well as mirage :)
Imperatively Control the Upload Progress
Writing UIs around upload is definitely part of userland code. Giving developers a good way to test their UIs is key. To test what happens in each
file.state? Usingawait selectFiles()would skip theuploadingstate and would require devs to eitherwaitFor()of some dom node to appear or set some timeout on the request itself. Both are not reliable and have high potential to cause flaky tests, read more in this discussion.An idea would be to have an imperative API to programmatically advance the
stateand be in control. Basically, a deferred promise - this is shim code:This is a rough idea but I myself have too many questions how to shape the API around that, when and where to allow business logic, etc. My hope is to get the discussion going.