chore: write tests for trigger component

This commit is contained in:
Jai Bhagat 2021-12-14 12:56:03 -05:00
parent 1188a5632f
commit e53a6072de
3 changed files with 200 additions and 6 deletions

View File

@ -18,11 +18,11 @@ export default class Trigger extends Component {
}
get isSuccess() {
return this.triggerTask.last.isSuccessful;
return this.triggerTask.last?.isSuccessful;
}
get isError() {
return this.triggerTask.lastErrored;
return !!this.error;
}
get fns() {
@ -44,12 +44,18 @@ export default class Trigger extends Component {
return { isBusy, isIdle, isSuccess, isError, result };
}
_reset() {
this.result = null;
this.error = null;
}
@task(function*() {
this._reset();
try {
this.result = yield this.args.do();
this.onSuccess(this.result);
} catch (e) {
this.error = e;
this.error = { Error: e };
this.onError(this.error);
}
})

View File

@ -29,9 +29,6 @@ module.exports = {
{
files: ['integration/components/**/*-test.js'],
plugins: ['ember-a11y-testing'],
rules: {
'ember-a11y-testing/a11y-audit-called': 'error',
},
settings: {
'ember-a11y-testing': {
auditModule: {

View File

@ -0,0 +1,191 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render, click, waitFor } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
module('Integration | Component | trigger', function(hooks) {
setupRenderingTest(hooks);
module('Synchronous Interactions', function() {
test('it can trigger a synchronous action', async function(assert) {
this.set('name', 'Tomster');
this.set('changeName', () => this.set('name', 'Zoey'));
await render(hbs`
<Trigger @do={{this.changeName}} as |trigger|>
<h2 data-test-name>{{this.name}}</h2>
<button data-test-button type="button" {{on "click" trigger.fns.do}}>Change my name.</button>
</Trigger>
`);
assert.dom('[data-test-name]').hasText('Tomster', 'Initial state renders correctly.');
await click('[data-test-button]');
assert
.dom('[data-test-name]')
.hasText('Zoey', 'The name property changes when the button is clicked');
});
test('it sets the result of the action', async function(assert) {
this.set('tomster', () => 'Tomster');
await render(hbs`
<Trigger @do={{this.tomster}} as |trigger|>
{{#if trigger.data.result}}
<h2 data-test-name>{{trigger.data.result}}</h2>
{{/if}}
<button data-test-button {{on "click" trigger.fns.do}}>Generate</button>
</Trigger>
`);
assert
.dom('[data-test-name]')
.doesNotExist('Initial state does not render because there is no result yet.');
await click('[data-test-button]');
assert
.dom('[data-test-name]')
.hasText('Tomster', 'The result state updates after the triggered action');
});
});
module('Asynchronous Interactions', function() {
test('it can trigger an asynchronous action', async function(assert) {
this.set(
'onTrigger',
() =>
new Promise(resolve => {
this.set('resolve', resolve);
})
);
await render(hbs`
<Trigger @do={{this.onTrigger}} as |trigger|>
{{#if trigger.data.isBusy}}
<div data-test-div-loading>...Loading</div>
{{/if}}
{{#if trigger.data.isSuccess}}
<div data-test-div>Success!</div>
{{/if}}
<button data-test-button {{on "click" trigger.fns.do}}>Click Me</button>
</Trigger>
`);
assert
.dom('[data-test-div]')
.doesNotExist('The div does not render until after the action dispatches successfully');
await click('[data-test-button]');
assert
.dom('[data-test-div-loading]')
.exists('Loading state is displayed when the action hasnt resolved yet');
assert
.dom('[data-test-div]')
.doesNotExist('Success message does not display until after promise resolves');
this.resolve();
await waitFor('[data-test-div]');
assert
.dom('[data-test-div-loading]')
.doesNotExist(
'Loading state is no longer rendered after state changes from busy to success'
);
assert
.dom('[data-test-div]')
.exists('Action has dispatched successfully after the promise resolves');
await click('[data-test-button]');
assert
.dom('[data-test-div]')
.doesNotExist('Aftering clicking the button, again, the state is reset');
assert
.dom('[data-test-div-loading]')
.exists('After clicking the button, again, we are back in the loading state');
this.resolve();
await waitFor('[data-test-div]');
assert
.dom('[data-test-div]')
.exists(
'An new action and new promise resolve after clicking the button for the second time'
);
});
test('it handles the success state', async function(assert) {
this.set(
'onTrigger',
() =>
new Promise(resolve => {
this.set('resolve', resolve);
})
);
this.set('onSuccess', () => assert.step('On success happened'));
await render(hbs`
<Trigger @do={{this.onTrigger}} @onSuccess={{this.onSuccess}} as |trigger|>
{{#if trigger.data.isSuccess}}
<span data-test-div>Success!</span>
{{/if}}
<button data-test-button {{on "click" trigger.fns.do}}>Click Me</button>
</Trigger>
`);
assert
.dom('[data-test-div]')
.doesNotExist('No text should appear until after the onSuccess callback is fired');
await click('[data-test-button]');
this.resolve();
await waitFor('[data-test-div]');
assert.verifySteps(['On success happened']);
});
test('it handles the error state', async function(assert) {
this.set(
'onTrigger',
() =>
new Promise((_, reject) => {
this.set('reject', reject);
})
);
this.set('onError', () => {
assert.step('On error happened');
});
await render(hbs`
<Trigger @do={{this.onTrigger}} @onError={{this.onError}} as |trigger|>
{{#if trigger.data.isBusy}}
<div data-test-div-loading>...Loading</div>
{{/if}}
{{#if trigger.data.isError}}
<span data-test-span>Error!</span>
{{/if}}
<button data-test-button {{on "click" trigger.fns.do}}>Click Me</button>
</Trigger>
`);
await click('[data-test-button]');
assert
.dom('[data-test-div-loading]')
.exists('Loading state is displayed when the action hasnt resolved yet');
assert
.dom('[data-test-div]')
.doesNotExist('No text should appear until after the onError callback is fired');
this.reject();
await waitFor('[data-test-span]');
assert.verifySteps(['On error happened']);
await click('[data-test-button]');
assert
.dom('[data-test-div-loading]')
.exists('The previous error state was cleared and we show loading, again.');
assert.dom('[data-test-div]').doesNotExist('The error state is cleared');
this.reject();
await waitFor('[data-test-span]');
assert.verifySteps(['On error happened'], 'The error dispatches');
});
});
});