github.com/Ilhicas/nomad@v1.0.4-0.20210304152020-e86851182bc3/ui/tests/integration/components/job-page/periodic-test.js (about) 1 import { module, test } from 'qunit'; 2 import { setupRenderingTest } from 'ember-qunit'; 3 import { click, find, findAll, render } from '@ember/test-helpers'; 4 import hbs from 'htmlbars-inline-precompile'; 5 import moment from 'moment'; 6 import { create, collection } from 'ember-cli-page-object'; 7 import { startMirage } from 'nomad-ui/initializers/ember-cli-mirage'; 8 import pageSizeSelect from 'nomad-ui/tests/acceptance/behaviors/page-size-select'; 9 import pageSizeSelectPageObject from 'nomad-ui/tests/pages/components/page-size-select'; 10 import { 11 jobURL, 12 stopJob, 13 startJob, 14 expectError, 15 expectDeleteRequest, 16 expectStartRequest, 17 } from './helpers'; 18 import { componentA11yAudit } from 'nomad-ui/tests/helpers/a11y-audit'; 19 20 // A minimum viable page object to use with the pageSizeSelect behavior 21 const PeriodicJobPage = create({ 22 pageSize: 25, 23 jobs: collection('[data-test-job-row]'), 24 pageSizeSelect: pageSizeSelectPageObject(), 25 }); 26 27 module('Integration | Component | job-page/periodic', function(hooks) { 28 setupRenderingTest(hooks); 29 30 hooks.beforeEach(function() { 31 window.localStorage.clear(); 32 this.store = this.owner.lookup('service:store'); 33 this.server = startMirage(); 34 this.server.create('namespace'); 35 }); 36 37 hooks.afterEach(function() { 38 this.server.shutdown(); 39 window.localStorage.clear(); 40 }); 41 42 const commonTemplate = hbs` 43 <JobPage::Periodic 44 @job={{job}} 45 @sortProperty={{sortProperty}} 46 @sortDescending={{sortDescending}} 47 @currentPage={{currentPage}} 48 @gotoJob={{gotoJob}} /> 49 `; 50 51 const commonProperties = job => ({ 52 job, 53 sortProperty: 'name', 54 sortDescending: true, 55 currentPage: 1, 56 gotoJob: () => {}, 57 }); 58 59 test('Clicking Force Launch launches a new periodic child job', async function(assert) { 60 const childrenCount = 3; 61 62 this.server.create('job', 'periodic', { 63 id: 'parent', 64 childrenCount, 65 createAllocations: false, 66 }); 67 68 await this.store.findAll('job'); 69 70 const job = this.store.peekAll('job').findBy('plainId', 'parent'); 71 72 this.setProperties(commonProperties(job)); 73 await this.render(commonTemplate); 74 75 const currentJobCount = server.db.jobs.length; 76 77 assert.equal( 78 findAll('[data-test-job-name]').length, 79 childrenCount, 80 'The new periodic job launch is in the children list' 81 ); 82 83 await click('[data-test-force-launch]'); 84 85 const expectedURL = jobURL(job, '/periodic/force'); 86 87 assert.ok( 88 this.server.pretender.handledRequests 89 .filterBy('method', 'POST') 90 .find(req => req.url === expectedURL), 91 'POST URL was correct' 92 ); 93 94 assert.equal(server.db.jobs.length, currentJobCount + 1, 'POST request was made'); 95 }); 96 97 test('Clicking force launch without proper permissions shows an error message', async function(assert) { 98 this.server.pretender.post('/v1/job/:id/periodic/force', () => [403, {}, '']); 99 100 this.server.create('job', 'periodic', { 101 id: 'parent', 102 childrenCount: 1, 103 createAllocations: false, 104 status: 'running', 105 }); 106 107 await this.store.findAll('job'); 108 109 const job = this.store.peekAll('job').findBy('plainId', 'parent'); 110 111 this.setProperties(commonProperties(job)); 112 await this.render(commonTemplate); 113 114 assert.notOk(find('[data-test-job-error-title]'), 'No error message yet'); 115 116 await click('[data-test-force-launch]'); 117 118 assert.equal( 119 find('[data-test-job-error-title]').textContent, 120 'Could Not Force Launch', 121 'Appropriate error is shown' 122 ); 123 assert.ok( 124 find('[data-test-job-error-body]').textContent.includes('ACL'), 125 'The error message mentions ACLs' 126 ); 127 128 await click('[data-test-job-error-close]'); 129 130 assert.notOk(find('[data-test-job-error-title]'), 'Error message is dismissable'); 131 }); 132 133 test('Stopping a job sends a delete request for the job', async function(assert) { 134 const mirageJob = this.server.create('job', 'periodic', { 135 childrenCount: 0, 136 createAllocations: false, 137 status: 'running', 138 }); 139 140 let job; 141 await this.store.findAll('job'); 142 143 job = this.store.peekAll('job').findBy('plainId', mirageJob.id); 144 145 this.setProperties(commonProperties(job)); 146 await render(commonTemplate); 147 await stopJob(); 148 149 expectDeleteRequest(assert, this.server, job); 150 }); 151 152 test('Stopping a job without proper permissions shows an error message', async function(assert) { 153 this.server.pretender.delete('/v1/job/:id', () => [403, {}, '']); 154 155 const mirageJob = this.server.create('job', 'periodic', { 156 childrenCount: 0, 157 createAllocations: false, 158 status: 'running', 159 }); 160 161 await this.store.findAll('job'); 162 163 const job = this.store.peekAll('job').findBy('plainId', mirageJob.id); 164 165 this.setProperties(commonProperties(job)); 166 await render(commonTemplate); 167 168 await stopJob(); 169 expectError(assert, 'Could Not Stop Job'); 170 171 await componentA11yAudit(this.element, assert); 172 }); 173 174 test('Starting a job sends a post request for the job using the current definition', async function(assert) { 175 const mirageJob = this.server.create('job', 'periodic', { 176 childrenCount: 0, 177 createAllocations: false, 178 status: 'dead', 179 }); 180 await this.store.findAll('job'); 181 182 const job = this.store.peekAll('job').findBy('plainId', mirageJob.id); 183 184 this.setProperties(commonProperties(job)); 185 await render(commonTemplate); 186 187 await startJob(); 188 expectStartRequest(assert, this.server, job); 189 }); 190 191 test('Starting a job without proper permissions shows an error message', async function(assert) { 192 this.server.pretender.post('/v1/job/:id', () => [403, {}, '']); 193 194 const mirageJob = this.server.create('job', 'periodic', { 195 childrenCount: 0, 196 createAllocations: false, 197 status: 'dead', 198 }); 199 await this.store.findAll('job'); 200 201 const job = this.store.peekAll('job').findBy('plainId', mirageJob.id); 202 203 this.setProperties(commonProperties(job)); 204 await render(commonTemplate); 205 206 await startJob(); 207 expectError(assert, 'Could Not Start Job'); 208 }); 209 210 test('Each job row includes the submitted time', async function(assert) { 211 this.server.create('job', 'periodic', { 212 id: 'parent', 213 childrenCount: 1, 214 createAllocations: false, 215 }); 216 217 await this.store.findAll('job'); 218 219 const job = this.store.peekAll('job').findBy('plainId', 'parent'); 220 221 this.setProperties(commonProperties(job)); 222 await this.render(commonTemplate); 223 224 assert.equal( 225 find('[data-test-job-submit-time]').textContent, 226 moment(job.get('children.firstObject.submitTime')).format('MMM DD HH:mm:ss ZZ'), 227 'The new periodic job launch is in the children list' 228 ); 229 }); 230 231 pageSizeSelect({ 232 resourceName: 'job', 233 pageObject: PeriodicJobPage, 234 pageObjectList: PeriodicJobPage.jobs, 235 async setup() { 236 this.server.create('job', 'periodic', { 237 id: 'parent', 238 childrenCount: PeriodicJobPage.pageSize, 239 createAllocations: false, 240 }); 241 242 await this.store.findAll('job'); 243 244 const job = this.store.peekAll('job').findBy('plainId', 'parent'); 245 246 this.setProperties(commonProperties(job)); 247 await this.render(commonTemplate); 248 }, 249 }); 250 });