github.com/anuvu/nomad@v0.8.7-atom1/ui/tests/unit/adapters/job-test.js (about) 1 import EmberObject from '@ember/object'; 2 import { run } from '@ember/runloop'; 3 import { assign } from '@ember/polyfills'; 4 import { test } from 'ember-qunit'; 5 import wait from 'ember-test-helpers/wait'; 6 import { startMirage } from 'nomad-ui/initializers/ember-cli-mirage'; 7 import moduleForAdapter from '../../helpers/module-for-adapter'; 8 9 moduleForAdapter('job', 'Unit | Adapter | Job', { 10 needs: [ 11 'adapter:job', 12 'service:token', 13 'service:system', 14 'model:allocation', 15 'model:deployment', 16 'model:evaluation', 17 'model:job-summary', 18 'model:job-version', 19 'model:namespace', 20 'adapter:application', 21 'service:watchList', 22 ], 23 beforeEach() { 24 window.sessionStorage.clear(); 25 26 this.server = startMirage(); 27 this.server.create('node'); 28 this.server.create('job', { id: 'job-1' }); 29 this.server.create('job', { id: 'job-2', namespaceId: 'some-namespace' }); 30 }, 31 afterEach() { 32 this.server.shutdown(); 33 }, 34 }); 35 36 test('The job summary is stitched into the job request', function(assert) { 37 const { pretender } = this.server; 38 const jobName = 'job-1'; 39 const jobNamespace = 'default'; 40 const jobId = JSON.stringify([jobName, jobNamespace]); 41 42 this.subject().findRecord(null, { modelName: 'job' }, jobId); 43 44 assert.deepEqual( 45 pretender.handledRequests.mapBy('url'), 46 ['/v1/namespaces', `/v1/job/${jobName}`], 47 'The two requests made are /namespaces and /job/:id' 48 ); 49 }); 50 51 test('When the job has a namespace other than default, it is in the URL', function(assert) { 52 const { pretender } = this.server; 53 const jobName = 'job-2'; 54 const jobNamespace = 'some-namespace'; 55 const jobId = JSON.stringify([jobName, jobNamespace]); 56 57 this.subject().findRecord(null, { modelName: 'job' }, jobId); 58 59 assert.deepEqual( 60 pretender.handledRequests.mapBy('url'), 61 ['/v1/namespaces', `/v1/job/${jobName}?namespace=${jobNamespace}`], 62 'The two requests made are /namespaces and /job/:id?namespace=:namespace' 63 ); 64 }); 65 66 test('When there is no token set in the token service, no x-nomad-token header is set', function(assert) { 67 const { pretender } = this.server; 68 const jobId = JSON.stringify(['job-1', 'default']); 69 70 this.subject().findRecord(null, { modelName: 'job' }, jobId); 71 72 assert.notOk( 73 pretender.handledRequests.mapBy('requestHeaders').some(headers => headers['X-Nomad-Token']), 74 'No token header present on either job request' 75 ); 76 }); 77 78 test('When a token is set in the token service, then x-nomad-token header is set', function(assert) { 79 const { pretender } = this.server; 80 const jobId = JSON.stringify(['job-1', 'default']); 81 const secret = 'here is the secret'; 82 83 this.subject().set('token.secret', secret); 84 this.subject().findRecord(null, { modelName: 'job' }, jobId); 85 86 assert.ok( 87 pretender.handledRequests 88 .mapBy('requestHeaders') 89 .every(headers => headers['X-Nomad-Token'] === secret), 90 'The token header is present on both job requests' 91 ); 92 }); 93 94 test('findAll can be watched', function(assert) { 95 const { pretender } = this.server; 96 97 const request = () => 98 this.subject().findAll(null, { modelName: 'job' }, null, { 99 reload: true, 100 adapterOptions: { watch: true }, 101 }); 102 103 request(); 104 assert.equal( 105 pretender.handledRequests[0].url, 106 '/v1/namespaces', 107 'First request is for namespaces' 108 ); 109 assert.equal( 110 pretender.handledRequests[1].url, 111 '/v1/jobs?index=1', 112 'Second request is a blocking request for jobs' 113 ); 114 115 return wait().then(() => { 116 request(); 117 assert.equal( 118 pretender.handledRequests[2].url, 119 '/v1/jobs?index=2', 120 'Third request is a blocking request with an incremented index param' 121 ); 122 123 return wait(); 124 }); 125 }); 126 127 test('findRecord can be watched', function(assert) { 128 const jobId = JSON.stringify(['job-1', 'default']); 129 const { pretender } = this.server; 130 131 const request = () => 132 this.subject().findRecord(null, { modelName: 'job' }, jobId, { 133 reload: true, 134 adapterOptions: { watch: true }, 135 }); 136 137 request(); 138 assert.equal( 139 pretender.handledRequests[0].url, 140 '/v1/namespaces', 141 'First request is for namespaces' 142 ); 143 assert.equal( 144 pretender.handledRequests[1].url, 145 '/v1/job/job-1?index=1', 146 'Second request is a blocking request for job-1' 147 ); 148 149 return wait().then(() => { 150 request(); 151 assert.equal( 152 pretender.handledRequests[2].url, 153 '/v1/job/job-1?index=2', 154 'Third request is a blocking request with an incremented index param' 155 ); 156 157 return wait(); 158 }); 159 }); 160 161 test('relationships can be reloaded', function(assert) { 162 const { pretender } = this.server; 163 const plainId = 'job-1'; 164 const mockModel = makeMockModel(plainId); 165 166 this.subject().reloadRelationship(mockModel, 'summary'); 167 assert.equal( 168 pretender.handledRequests[0].url, 169 `/v1/job/${plainId}/summary`, 170 'Relationship was reloaded' 171 ); 172 }); 173 174 test('relationship reloads can be watched', function(assert) { 175 const { pretender } = this.server; 176 const plainId = 'job-1'; 177 const mockModel = makeMockModel(plainId); 178 179 this.subject().reloadRelationship(mockModel, 'summary', true); 180 assert.equal( 181 pretender.handledRequests[0].url, 182 '/v1/job/job-1/summary?index=1', 183 'First request is a blocking request for job-1 summary relationship' 184 ); 185 186 return wait().then(() => { 187 this.subject().reloadRelationship(mockModel, 'summary', true); 188 assert.equal( 189 pretender.handledRequests[1].url, 190 '/v1/job/job-1/summary?index=2', 191 'Second request is a blocking request with an incremented index param' 192 ); 193 }); 194 }); 195 196 test('findAll can be canceled', function(assert) { 197 const { pretender } = this.server; 198 pretender.get('/v1/jobs', () => [200, {}, '[]'], true); 199 200 this.subject() 201 .findAll(null, { modelName: 'job' }, null, { 202 reload: true, 203 adapterOptions: { watch: true }, 204 }) 205 .catch(() => {}); 206 207 const { request: xhr } = pretender.requestReferences[0]; 208 assert.equal(xhr.status, 0, 'Request is still pending'); 209 210 // Schedule the cancelation before waiting 211 run.next(() => { 212 this.subject().cancelFindAll('job'); 213 }); 214 215 return wait().then(() => { 216 assert.ok(xhr.aborted, 'Request was aborted'); 217 }); 218 }); 219 220 test('findRecord can be canceled', function(assert) { 221 const { pretender } = this.server; 222 const jobId = JSON.stringify(['job-1', 'default']); 223 224 pretender.get('/v1/job/:id', () => [200, {}, '{}'], true); 225 226 this.subject().findRecord(null, { modelName: 'job' }, jobId, { 227 reload: true, 228 adapterOptions: { watch: true }, 229 }); 230 231 const { request: xhr } = pretender.requestReferences[0]; 232 assert.equal(xhr.status, 0, 'Request is still pending'); 233 234 // Schedule the cancelation before waiting 235 run.next(() => { 236 this.subject().cancelFindRecord('job', jobId); 237 }); 238 239 return wait().then(() => { 240 assert.ok(xhr.aborted, 'Request was aborted'); 241 }); 242 }); 243 244 test('relationship reloads can be canceled', function(assert) { 245 const { pretender } = this.server; 246 const plainId = 'job-1'; 247 const mockModel = makeMockModel(plainId); 248 pretender.get('/v1/job/:id/summary', () => [200, {}, '{}'], true); 249 250 this.subject().reloadRelationship(mockModel, 'summary', true); 251 252 const { request: xhr } = pretender.requestReferences[0]; 253 assert.equal(xhr.status, 0, 'Request is still pending'); 254 255 // Schedule the cancelation before waiting 256 run.next(() => { 257 this.subject().cancelReloadRelationship(mockModel, 'summary'); 258 }); 259 260 return wait().then(() => { 261 assert.ok(xhr.aborted, 'Request was aborted'); 262 }); 263 }); 264 265 test('requests can be canceled even if multiple requests for the same URL were made', function(assert) { 266 const { pretender } = this.server; 267 const jobId = JSON.stringify(['job-1', 'default']); 268 269 pretender.get('/v1/job/:id', () => [200, {}, '{}'], true); 270 271 this.subject().findRecord(null, { modelName: 'job' }, jobId, { 272 reload: true, 273 adapterOptions: { watch: true }, 274 }); 275 276 this.subject().findRecord(null, { modelName: 'job' }, jobId, { 277 reload: true, 278 adapterOptions: { watch: true }, 279 }); 280 281 const { request: xhr } = pretender.requestReferences[0]; 282 assert.equal(xhr.status, 0, 'Request is still pending'); 283 assert.equal(pretender.requestReferences.length, 2, 'Two findRecord requests were made'); 284 assert.equal( 285 pretender.requestReferences.mapBy('url').uniq().length, 286 1, 287 'The two requests have the same URL' 288 ); 289 290 // Schedule the cancelation before waiting 291 run.next(() => { 292 this.subject().cancelFindRecord('job', jobId); 293 }); 294 295 return wait().then(() => { 296 assert.ok(xhr.aborted, 'Request was aborted'); 297 }); 298 }); 299 300 test('canceling a find record request will never cancel a request with the same url but different method', function(assert) { 301 const { pretender } = this.server; 302 const jobId = JSON.stringify(['job-1', 'default']); 303 304 pretender.get('/v1/job/:id', () => [200, {}, '{}'], true); 305 pretender.delete('/v1/job/:id', () => [204, {}, ''], 200); 306 307 this.subject().findRecord(null, { modelName: 'job' }, jobId, { 308 reload: true, 309 adapterOptions: { watch: true }, 310 }); 311 312 this.subject().stop(EmberObject.create({ id: jobId })); 313 314 const { request: getXHR } = pretender.requestReferences[0]; 315 const { request: deleteXHR } = pretender.requestReferences[1]; 316 assert.equal(getXHR.status, 0, 'Get request is still pending'); 317 assert.equal(deleteXHR.status, 0, 'Delete request is still pending'); 318 319 // Schedule the cancelation before waiting 320 run.next(() => { 321 this.subject().cancelFindRecord('job', jobId); 322 }); 323 324 return wait().then(() => { 325 assert.ok(getXHR.aborted, 'Get request was aborted'); 326 assert.notOk(deleteXHR.aborted, 'Delete request was aborted'); 327 }); 328 }); 329 330 function makeMockModel(id, options) { 331 return assign( 332 { 333 relationshipFor(name) { 334 return { 335 kind: 'belongsTo', 336 type: 'job-summary', 337 key: name, 338 }; 339 }, 340 belongsTo(name) { 341 return { 342 link() { 343 return `/v1/job/${id}/${name}`; 344 }, 345 }; 346 }, 347 }, 348 options 349 ); 350 }