github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/ui/tests/integration/components/trigger-test.js (about) 1 /* eslint-disable ember-a11y-testing/a11y-audit-called */ 2 import { module, test } from 'qunit'; 3 import { setupRenderingTest } from 'ember-qunit'; 4 import { render, click, waitFor } from '@ember/test-helpers'; 5 import { hbs } from 'ember-cli-htmlbars'; 6 7 module('Integration | Component | trigger', function (hooks) { 8 setupRenderingTest(hooks); 9 10 module('Synchronous Interactions', function () { 11 test('it can trigger a synchronous action', async function (assert) { 12 this.set('name', 'Tomster'); 13 this.set('changeName', () => this.set('name', 'Zoey')); 14 await render(hbs` 15 <Trigger @do={{this.changeName}} as |trigger|> 16 <h2 data-test-name>{{this.name}}</h2> 17 <button data-test-button type="button" {{on "click" trigger.fns.do}}>Change my name.</button> 18 </Trigger> 19 `); 20 assert 21 .dom('[data-test-name]') 22 .hasText('Tomster', 'Initial state renders correctly.'); 23 24 await click('[data-test-button]'); 25 26 assert 27 .dom('[data-test-name]') 28 .hasText( 29 'Zoey', 30 'The name property changes when the button is clicked' 31 ); 32 }); 33 34 test('it sets the result of the action', async function (assert) { 35 this.set('tomster', () => 'Tomster'); 36 await render(hbs` 37 <Trigger @do={{this.tomster}} as |trigger|> 38 {{#if trigger.data.result}} 39 <h2 data-test-name>{{trigger.data.result}}</h2> 40 {{/if}} 41 <button data-test-button {{on "click" trigger.fns.do}}>Generate</button> 42 </Trigger> 43 `); 44 assert 45 .dom('[data-test-name]') 46 .doesNotExist( 47 'Initial state does not render because there is no result yet.' 48 ); 49 50 await click('[data-test-button]'); 51 52 assert 53 .dom('[data-test-name]') 54 .hasText( 55 'Tomster', 56 'The result state updates after the triggered action' 57 ); 58 }); 59 }); 60 61 module('Asynchronous Interactions', function () { 62 test('it can trigger an asynchronous action', async function (assert) { 63 this.set( 64 'onTrigger', 65 () => 66 new Promise((resolve) => { 67 this.set('resolve', resolve); 68 }) 69 ); 70 71 await render(hbs` 72 <Trigger @do={{this.onTrigger}} as |trigger|> 73 {{#if trigger.data.isBusy}} 74 <div data-test-div-loading>...Loading</div> 75 {{/if}} 76 {{#if trigger.data.isSuccess}} 77 <div data-test-div>Success!</div> 78 {{/if}} 79 <button data-test-button {{on "click" trigger.fns.do}}>Click Me</button> 80 </Trigger> 81 `); 82 83 assert 84 .dom('[data-test-div]') 85 .doesNotExist( 86 'The div does not render until after the action dispatches successfully' 87 ); 88 89 await click('[data-test-button]'); 90 assert 91 .dom('[data-test-div-loading]') 92 .exists( 93 'Loading state is displayed when the action hasnt resolved yet' 94 ); 95 assert 96 .dom('[data-test-div]') 97 .doesNotExist( 98 'Success message does not display until after promise resolves' 99 ); 100 101 this.resolve(); 102 await waitFor('[data-test-div]'); 103 assert 104 .dom('[data-test-div-loading]') 105 .doesNotExist( 106 'Loading state is no longer rendered after state changes from busy to success' 107 ); 108 assert 109 .dom('[data-test-div]') 110 .exists( 111 'Action has dispatched successfully after the promise resolves' 112 ); 113 114 await click('[data-test-button]'); 115 assert 116 .dom('[data-test-div]') 117 .doesNotExist( 118 'Aftering clicking the button, again, the state is reset' 119 ); 120 assert 121 .dom('[data-test-div-loading]') 122 .exists( 123 'After clicking the button, again, we are back in the loading state' 124 ); 125 126 this.resolve(); 127 await waitFor('[data-test-div]'); 128 129 assert 130 .dom('[data-test-div]') 131 .exists( 132 'An new action and new promise resolve after clicking the button for the second time' 133 ); 134 }); 135 136 test('it handles the success state', async function (assert) { 137 this.set( 138 'onTrigger', 139 () => 140 new Promise((resolve) => { 141 this.set('resolve', resolve); 142 }) 143 ); 144 this.set('onSuccess', () => assert.step('On success happened')); 145 146 await render(hbs` 147 <Trigger @do={{this.onTrigger}} @onSuccess={{this.onSuccess}} as |trigger|> 148 {{#if trigger.data.isSuccess}} 149 <span data-test-div>Success!</span> 150 {{/if}} 151 <button data-test-button {{on "click" trigger.fns.do}}>Click Me</button> 152 </Trigger> 153 `); 154 155 assert 156 .dom('[data-test-div]') 157 .doesNotExist( 158 'No text should appear until after the onSuccess callback is fired' 159 ); 160 await click('[data-test-button]'); 161 this.resolve(); 162 await waitFor('[data-test-div]'); 163 assert.verifySteps(['On success happened']); 164 }); 165 166 test('it handles the error state', async function (assert) { 167 this.set( 168 'onTrigger', 169 () => 170 new Promise((_, reject) => { 171 this.set('reject', reject); 172 }) 173 ); 174 this.set('onError', () => { 175 assert.step('On error happened'); 176 }); 177 178 await render(hbs` 179 <Trigger @do={{this.onTrigger}} @onError={{this.onError}} as |trigger|> 180 {{#if trigger.data.isBusy}} 181 <div data-test-div-loading>...Loading</div> 182 {{/if}} 183 {{#if trigger.data.isError}} 184 <span data-test-span>Error!</span> 185 {{/if}} 186 <button data-test-button {{on "click" trigger.fns.do}}>Click Me</button> 187 </Trigger> 188 `); 189 190 await click('[data-test-button]'); 191 assert 192 .dom('[data-test-div-loading]') 193 .exists( 194 'Loading state is displayed when the action hasnt resolved yet' 195 ); 196 197 assert 198 .dom('[data-test-div]') 199 .doesNotExist( 200 'No text should appear until after the onError callback is fired' 201 ); 202 203 this.reject(); 204 await waitFor('[data-test-span]'); 205 assert.verifySteps(['On error happened']); 206 207 await click('[data-test-button]'); 208 209 assert 210 .dom('[data-test-div-loading]') 211 .exists( 212 'The previous error state was cleared and we show loading, again.' 213 ); 214 215 assert.dom('[data-test-div]').doesNotExist('The error state is cleared'); 216 217 this.reject(); 218 await waitFor('[data-test-span]'); 219 assert.verifySteps(['On error happened'], 'The error dispatches'); 220 }); 221 }); 222 });