github.com/zhizhiboom/nomad@v0.8.5-0.20180907175415-f28fd3a1a056/ui/tests/integration/job-page/periodic-test.js (about) 1 import { getOwner } from '@ember/application'; 2 import { test, moduleForComponent } from 'ember-qunit'; 3 import { click, find, findAll } from 'ember-native-dom-helpers'; 4 import wait from 'ember-test-helpers/wait'; 5 import hbs from 'htmlbars-inline-precompile'; 6 import { startMirage } from 'nomad-ui/initializers/ember-cli-mirage'; 7 import { 8 jobURL, 9 stopJob, 10 startJob, 11 expectError, 12 expectDeleteRequest, 13 expectStartRequest, 14 } from './helpers'; 15 16 moduleForComponent('job-page/periodic', 'Integration | Component | job-page/periodic', { 17 integration: true, 18 beforeEach() { 19 window.localStorage.clear(); 20 this.store = getOwner(this).lookup('service:store'); 21 this.server = startMirage(); 22 this.server.create('namespace'); 23 }, 24 afterEach() { 25 this.server.shutdown(); 26 window.localStorage.clear(); 27 }, 28 }); 29 30 const commonTemplate = hbs` 31 {{job-page/periodic 32 job=job 33 sortProperty=sortProperty 34 sortDescending=sortDescending 35 currentPage=currentPage 36 gotoJob=gotoJob}} 37 `; 38 39 const commonProperties = job => ({ 40 job, 41 sortProperty: 'name', 42 sortDescending: true, 43 currentPage: 1, 44 gotoJob: () => {}, 45 }); 46 47 test('Clicking Force Launch launches a new periodic child job', function(assert) { 48 const childrenCount = 3; 49 50 this.server.create('job', 'periodic', { 51 id: 'parent', 52 childrenCount, 53 createAllocations: false, 54 }); 55 56 this.store.findAll('job'); 57 58 return wait().then(() => { 59 const job = this.store.peekAll('job').findBy('plainId', 'parent'); 60 61 this.setProperties(commonProperties(job)); 62 this.render(commonTemplate); 63 64 return wait().then(() => { 65 const currentJobCount = server.db.jobs.length; 66 67 assert.equal( 68 findAll('[data-test-job-name]').length, 69 childrenCount, 70 'The new periodic job launch is in the children list' 71 ); 72 73 click('[data-test-force-launch]'); 74 75 return wait().then(() => { 76 const expectedURL = jobURL(job, '/periodic/force'); 77 78 assert.ok( 79 this.server.pretender.handledRequests 80 .filterBy('method', 'POST') 81 .find(req => req.url === expectedURL), 82 'POST URL was correct' 83 ); 84 85 assert.equal(server.db.jobs.length, currentJobCount + 1, 'POST request was made'); 86 }); 87 }); 88 }); 89 }); 90 91 test('Clicking force launch without proper permissions shows an error message', function(assert) { 92 this.server.pretender.post('/v1/job/:id/periodic/force', () => [403, {}, null]); 93 94 this.server.create('job', 'periodic', { 95 id: 'parent', 96 childrenCount: 1, 97 createAllocations: false, 98 status: 'running', 99 }); 100 101 this.store.findAll('job'); 102 103 return wait().then(() => { 104 const job = this.store.peekAll('job').findBy('plainId', 'parent'); 105 106 this.setProperties(commonProperties(job)); 107 this.render(commonTemplate); 108 109 return wait().then(() => { 110 assert.notOk(find('[data-test-job-error-title]'), 'No error message yet'); 111 112 click('[data-test-force-launch]'); 113 114 return wait().then(() => { 115 assert.equal( 116 find('[data-test-job-error-title]').textContent, 117 'Could Not Force Launch', 118 'Appropriate error is shown' 119 ); 120 assert.ok( 121 find('[data-test-job-error-body]').textContent.includes('ACL'), 122 'The error message mentions ACLs' 123 ); 124 125 click('[data-test-job-error-close]'); 126 127 assert.notOk(find('[data-test-job-error-title]'), 'Error message is dismissable'); 128 }); 129 }); 130 }); 131 }); 132 133 test('Stopping a job sends a delete request for the job', 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 this.store.findAll('job'); 142 143 return wait() 144 .then(() => { 145 job = this.store.peekAll('job').findBy('plainId', mirageJob.id); 146 147 this.setProperties(commonProperties(job)); 148 this.render(commonTemplate); 149 150 return wait(); 151 }) 152 .then(stopJob) 153 .then(() => expectDeleteRequest(assert, this.server, job)); 154 }); 155 156 test('Stopping a job without proper permissions shows an error message', function(assert) { 157 this.server.pretender.delete('/v1/job/:id', () => [403, {}, null]); 158 159 const mirageJob = this.server.create('job', 'periodic', { 160 childrenCount: 0, 161 createAllocations: false, 162 status: 'running', 163 }); 164 165 this.store.findAll('job'); 166 167 return wait() 168 .then(() => { 169 const job = this.store.peekAll('job').findBy('plainId', mirageJob.id); 170 171 this.setProperties(commonProperties(job)); 172 this.render(commonTemplate); 173 174 return wait(); 175 }) 176 .then(stopJob) 177 .then(expectError(assert, 'Could Not Stop Job')); 178 }); 179 180 test('Starting a job sends a post request for the job using the current definition', function(assert) { 181 let job; 182 183 const mirageJob = this.server.create('job', 'periodic', { 184 childrenCount: 0, 185 createAllocations: false, 186 status: 'dead', 187 }); 188 this.store.findAll('job'); 189 190 return wait() 191 .then(() => { 192 job = this.store.peekAll('job').findBy('plainId', mirageJob.id); 193 194 this.setProperties(commonProperties(job)); 195 this.render(commonTemplate); 196 197 return wait(); 198 }) 199 .then(startJob) 200 .then(() => expectStartRequest(assert, this.server, job)); 201 }); 202 203 test('Starting a job without proper permissions shows an error message', function(assert) { 204 this.server.pretender.post('/v1/job/:id', () => [403, {}, null]); 205 206 const mirageJob = this.server.create('job', 'periodic', { 207 childrenCount: 0, 208 createAllocations: false, 209 status: 'dead', 210 }); 211 this.store.findAll('job'); 212 213 return wait() 214 .then(() => { 215 const job = this.store.peekAll('job').findBy('plainId', mirageJob.id); 216 217 this.setProperties(commonProperties(job)); 218 this.render(commonTemplate); 219 220 return wait(); 221 }) 222 .then(startJob) 223 .then(expectError(assert, 'Could Not Start Job')); 224 });