github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/ui/tests/integration/components/task-group-row-test.js (about) 1 import { module, test } from 'qunit'; 2 import { setupRenderingTest } from 'ember-qunit'; 3 import { click, find, render, settled, waitUntil } from '@ember/test-helpers'; 4 import hbs from 'htmlbars-inline-precompile'; 5 import { startMirage } from 'nomad-ui/initializers/ember-cli-mirage'; 6 import { initialize as fragmentSerializerInitializer } from 'nomad-ui/initializers/fragment-serializer'; 7 import { componentA11yAudit } from 'nomad-ui/tests/helpers/a11y-audit'; 8 9 const jobName = 'test-job'; 10 const jobId = JSON.stringify([jobName, 'default']); 11 12 const countChange = () => { 13 const initial = find('[data-test-task-group-count]').textContent; 14 return () => find('[data-test-task-group-count]').textContent !== initial; 15 }; 16 17 let managementToken; 18 let clientToken; 19 20 const makeJob = (server, props = {}) => { 21 // These tests require a job with particular task groups. This requires 22 // mild Mirage surgery. 23 const job = server.create('job', { 24 id: jobName, 25 groupCount: 0, 26 createAllocations: false, 27 shallow: true, 28 ...props, 29 }); 30 const noScalingGroup = server.create('task-group', { 31 job, 32 name: 'no-scaling', 33 shallow: true, 34 withScaling: false, 35 }); 36 const scalingGroup = server.create('task-group', { 37 job, 38 count: 2, 39 name: 'scaling', 40 shallow: true, 41 withScaling: true, 42 }); 43 job.update({ 44 taskGroupIds: [noScalingGroup.id, scalingGroup.id], 45 }); 46 }; 47 48 module('Integration | Component | task group row', function (hooks) { 49 setupRenderingTest(hooks); 50 51 hooks.beforeEach(async function () { 52 fragmentSerializerInitializer(this.owner); 53 this.store = this.owner.lookup('service:store'); 54 this.token = this.owner.lookup('service:token'); 55 this.server = startMirage(); 56 this.server.create('node'); 57 58 managementToken = this.server.create('token'); 59 clientToken = this.server.create('token'); 60 window.localStorage.nomadTokenSecret = managementToken.secretId; 61 }); 62 63 hooks.afterEach(function () { 64 this.server.shutdown(); 65 window.localStorage.clear(); 66 }); 67 68 const commonTemplate = hbs` 69 <TaskGroupRow @taskGroup={{group}} /> 70 `; 71 72 test('Task group row conditionally shows scaling buttons based on the presence of the scaling attr on the task group', async function (assert) { 73 assert.expect(3); 74 75 makeJob(this.server, { noActiveDeployment: true }); 76 this.token.fetchSelfTokenAndPolicies.perform(); 77 await settled(); 78 79 const job = await this.store.find('job', jobId); 80 this.set('group', job.taskGroups.findBy('name', 'no-scaling')); 81 82 await render(commonTemplate); 83 assert.notOk(find('[data-test-scale]')); 84 85 this.set('group', job.taskGroups.findBy('name', 'scaling')); 86 87 await settled(); 88 assert.ok(find('[data-test-scale]')); 89 90 await componentA11yAudit(this.element, assert); 91 }); 92 93 test('Clicking scaling buttons immediately updates the rendered count but debounces the scaling API request', async function (assert) { 94 makeJob(this.server, { noActiveDeployment: true }); 95 this.token.fetchSelfTokenAndPolicies.perform(); 96 await settled(); 97 98 const job = await this.store.find('job', jobId); 99 this.set('group', job.taskGroups.findBy('name', 'scaling')); 100 101 await render(commonTemplate); 102 assert.equal(find('[data-test-task-group-count]').textContent, 2); 103 104 click('[data-test-scale="increment"]'); 105 await waitUntil(countChange()); 106 assert.equal(find('[data-test-task-group-count]').textContent, 3); 107 108 click('[data-test-scale="increment"]'); 109 await waitUntil(countChange()); 110 assert.equal(find('[data-test-task-group-count]').textContent, 4); 111 112 assert.notOk( 113 server.pretender.handledRequests.find( 114 (req) => req.method === 'POST' && req.url.endsWith('/scale') 115 ) 116 ); 117 118 await settled(); 119 const scaleRequests = server.pretender.handledRequests.filter( 120 (req) => req.method === 'POST' && req.url.endsWith('/scale') 121 ); 122 assert.equal(scaleRequests.length, 1); 123 assert.equal(JSON.parse(scaleRequests[0].requestBody).Count, 4); 124 }); 125 126 test('When the current count is equal to the max count, the increment count button is disabled', async function (assert) { 127 assert.expect(2); 128 129 makeJob(this.server, { noActiveDeployment: true }); 130 this.token.fetchSelfTokenAndPolicies.perform(); 131 await settled(); 132 133 const job = await this.store.find('job', jobId); 134 const group = job.taskGroups.findBy('name', 'scaling'); 135 group.set('count', group.scaling.max); 136 this.set('group', group); 137 138 await render(commonTemplate); 139 assert.ok(find('[data-test-scale="increment"]:disabled')); 140 141 await componentA11yAudit(this.element, assert); 142 }); 143 144 test('When the current count is equal to the min count, the decrement count button is disabled', async function (assert) { 145 assert.expect(2); 146 147 makeJob(this.server, { noActiveDeployment: true }); 148 this.token.fetchSelfTokenAndPolicies.perform(); 149 await settled(); 150 151 const job = await this.store.find('job', jobId); 152 const group = job.taskGroups.findBy('name', 'scaling'); 153 group.set('count', group.scaling.min); 154 this.set('group', group); 155 156 await render(commonTemplate); 157 assert.ok(find('[data-test-scale="decrement"]:disabled')); 158 159 await componentA11yAudit(this.element, assert); 160 }); 161 162 test('When there is an active deployment, both scale buttons are disabled', async function (assert) { 163 assert.expect(3); 164 165 makeJob(this.server, { activeDeployment: true }); 166 this.token.fetchSelfTokenAndPolicies.perform(); 167 await settled(); 168 169 const job = await this.store.find('job', jobId); 170 this.set('group', job.taskGroups.findBy('name', 'scaling')); 171 172 await render(commonTemplate); 173 assert.ok(find('[data-test-scale="increment"]:disabled')); 174 assert.ok(find('[data-test-scale="decrement"]:disabled')); 175 176 await componentA11yAudit(this.element, assert); 177 }); 178 179 test('When the current ACL token does not have the namespace:scale-job or namespace:submit-job policy rule', async function (assert) { 180 makeJob(this.server, { noActiveDeployment: true }); 181 window.localStorage.nomadTokenSecret = clientToken.secretId; 182 this.token.fetchSelfTokenAndPolicies.perform(); 183 await settled(); 184 185 const job = await this.store.find('job', jobId); 186 this.set('group', job.taskGroups.findBy('name', 'scaling')); 187 188 await render(commonTemplate); 189 assert.ok(find('[data-test-scale="increment"]:disabled')); 190 assert.ok(find('[data-test-scale="decrement"]:disabled')); 191 assert.ok( 192 find('[data-test-scale-controls]') 193 .getAttribute('aria-label') 194 .includes("You aren't allowed") 195 ); 196 }); 197 });