Tests for watching and canceling requests

This commit is contained in:
Michael Lange
2018-02-16 18:59:40 -08:00
parent 0a0cea0f87
commit 504ff2d4b7
3 changed files with 224 additions and 7 deletions

View File

@@ -4,6 +4,7 @@ import { makeArray } from '@ember/array';
import { inject as service } from '@ember/service';
import queryString from 'npm:query-string';
import ApplicationAdapter from './application';
import { AbortError } from 'ember-data/adapters/errors';
export default ApplicationAdapter.extend({
watchList: service(),
@@ -40,6 +41,11 @@ export default ApplicationAdapter.extend({
return this.ajax(url, 'GET', {
data: params,
}).catch(error => {
if (error instanceof AbortError) {
return [];
}
throw error;
});
},
@@ -53,6 +59,11 @@ export default ApplicationAdapter.extend({
return this.ajax(url, 'GET', {
data: params,
}).catch(error => {
if (error instanceof AbortError) {
return {};
}
throw error;
});
},
@@ -76,16 +87,24 @@ export default ApplicationAdapter.extend({
return this.ajax(url, 'GET', {
data: params,
}).then(json => {
this.get('store').pushPayload(relationship.type, {
[relationship.type]: makeArray(json),
});
});
}).then(
json => {
this.get('store').pushPayload(relationship.type, {
[relationship.type]: makeArray(json),
});
},
error => {
if (error instanceof AbortError) {
return relationship.kind === 'belongsTo' ? {} : [];
}
throw error;
}
);
}
},
handleResponse(status, headers, payload, requestData) {
const newIndex = headers['x-nomad-index'];
const newIndex = headers['X-Nomad-Index'];
if (newIndex) {
this.get('watchList').setIndexFor(requestData.url, newIndex);
}

View File

@@ -2,13 +2,17 @@ import { readOnly } from '@ember/object/computed';
import { copy } from '@ember/object/internals';
import Service from '@ember/service';
const list = {};
let list = {};
export default Service.extend({
list: readOnly(function() {
return copy(list, true);
}),
init() {
list = {};
},
getIndexFor(url) {
return list[url] || 0;
},

View File

@@ -1,4 +1,7 @@
import { run } from '@ember/runloop';
import { assign } from '@ember/polyfills';
import { test, moduleFor } from 'ember-qunit';
import wait from 'ember-test-helpers/wait';
import { startMirage } from 'nomad-ui/initializers/ember-cli-mirage';
moduleFor('adapter:job', 'Unit | Adapter | Job', {
@@ -80,3 +83,194 @@ test('When a token is set in the token service, then x-nomad-token header is set
'The token header is present on both job requests'
);
});
test('findAll can be watched', function(assert) {
const { pretender } = this.server;
const request = () =>
this.subject().findAll(null, { modelName: 'job' }, null, {
reload: true,
adapterOptions: { watch: true },
});
request();
assert.equal(
pretender.handledRequests[0].url,
'/v1/namespaces',
'First request is for namespaces'
);
assert.equal(
pretender.handledRequests[1].url,
'/v1/jobs?index=0',
'Second request is a blocking request for jobs'
);
return wait().then(() => {
request();
assert.equal(
pretender.handledRequests[2].url,
'/v1/jobs?index=1',
'Third request is a blocking request with an incremented index param'
);
return wait();
});
});
test('findRecord can be watched', function(assert) {
const jobId = JSON.stringify(['job-1', 'default']);
const { pretender } = this.server;
const request = () =>
this.subject().findRecord(null, { modelName: 'job' }, jobId, {
reload: true,
adapterOptions: { watch: true },
});
request();
assert.equal(
pretender.handledRequests[0].url,
'/v1/namespaces',
'First request is for namespaces'
);
assert.equal(
pretender.handledRequests[1].url,
'/v1/job/job-1?index=0',
'Second request is a blocking request for job-1'
);
return wait().then(() => {
request();
assert.equal(
pretender.handledRequests[2].url,
'/v1/job/job-1?index=1',
'Third request is a blocking request with an incremented index param'
);
return wait();
});
});
test('relationships can be reloaded', function(assert) {
const { pretender } = this.server;
const plainId = 'job-1';
const mockModel = makeMockModel(plainId);
this.subject().reloadRelationship(mockModel, 'summary');
assert.equal(
pretender.handledRequests[0].url,
`/v1/job/${plainId}/summary`,
'Relationship was reloaded'
);
});
test('relationship reloads can be watched', function(assert) {
const { pretender } = this.server;
const plainId = 'job-1';
const mockModel = makeMockModel(plainId);
this.subject().reloadRelationship(mockModel, 'summary', true);
assert.equal(
pretender.handledRequests[0].url,
'/v1/job/job-1/summary?index=0',
'First request is a blocking request for job-1 summary relationship'
);
return wait().then(() => {
this.subject().reloadRelationship(mockModel, 'summary', true);
assert.equal(
pretender.handledRequests[1].url,
'/v1/job/job-1/summary?index=1',
'Second request is a blocking request with an incremented index param'
);
});
});
test('findAll can be canceled', function(assert) {
const { pretender } = this.server;
pretender.get('/v1/jobs', () => [200, {}, '[]'], true);
this.subject().findAll(null, { modelName: 'job' }, null, {
reload: true,
adapterOptions: { watch: true },
});
const { request: xhr } = pretender.requestReferences[0];
assert.equal(xhr.status, 0, 'Request is still pending');
// Schedule the cancelation before waiting
run.next(() => {
this.subject().cancelFindAll('job');
});
return wait().then(() => {
assert.ok(xhr.aborted, 'Request was aborted');
});
});
test('findRecord can be canceled', function(assert) {
const { pretender } = this.server;
const jobId = JSON.stringify(['job-1', 'default']);
pretender.get('/v1/job/:id', () => [200, {}, '{}'], true);
this.subject().findRecord(null, { modelName: 'job' }, jobId, {
reload: true,
adapterOptions: { watch: true },
});
const { request: xhr } = pretender.requestReferences[0];
assert.equal(xhr.status, 0, 'Request is still pending');
// Schedule the cancelation before waiting
run.next(() => {
this.subject().cancelFindRecord('job', jobId);
});
return wait().then(() => {
assert.ok(xhr.aborted, 'Request was aborted');
});
});
test('relationship reloads can be canceled', function(assert) {
const { pretender } = this.server;
const plainId = 'job-1';
const mockModel = makeMockModel(plainId);
pretender.get('/v1/job/:id/summary', () => [200, {}, '{}'], true);
this.subject().reloadRelationship(mockModel, 'summary', true);
const { request: xhr } = pretender.requestReferences[0];
assert.equal(xhr.status, 0, 'Request is still pending');
// Schedule the cancelation before waiting
run.next(() => {
this.subject().cancelReloadRelationship(mockModel, 'summary');
});
return wait().then(() => {
assert.ok(xhr.aborted, 'Request was aborted');
});
});
function makeMockModel(id, options) {
return assign(
{
relationshipFor(name) {
return {
kind: 'belongsTo',
type: 'job-summary',
key: name,
};
},
belongsTo(name) {
return {
link() {
return `/v1/job/${id}/${name}`;
},
};
},
},
options
);
}