feat: 🎸 add host API support and mocks

This commit is contained in:
Randall Morey committed 2020-08-14 15:16:35 -04:00
1 parent 553bd74c5c
commit b86f05e977
14 files changed
+164 -37

No files matched your search

+38
View File
@@ -0,0 +1,38 @@
import ApplicationAdapter from './application';
import { inject as service } from '@ember/service';
export default class HostAdapter extends ApplicationAdapter {
// =services
@service store;
// =methods
/**
* Append a host catalog URL ahead of the host path if `hostCatalogID` is
* passed via adapter options. Otherwise, generate the prefix as normal.
*
* TODO: generalize the interface to resource-prefixed URLs by accepting
* a modelName and an ID, rather than looking for a known key.
*
* @override
* @param {string} path
* @param {string} parentURL
* @param {string} modelName
* @param {string} id
* @param {object} snapshot
* @return {string} urlPrefix
*/
urlPrefix(path, parentURL, modelName, id, snapshot) {
const hostCatalogID = snapshot?.adapterOptions?.hostCatalogID;
if (hostCatalogID) {
const hostCatalogAdapter = this.store.adapterFor('host-catalog');
return hostCatalogAdapter
._buildPrefixedURL('host-catalog', hostCatalogID, snapshot);
} else {
return super.urlPrefix(...arguments);
}
}
}
+42
View File
@@ -0,0 +1,42 @@
import BaseModel from '../../models/base';
import { attr } from '@ember-data/model';
/**
* Host contains all fields related to a Host resource
*/
export default class GeneratedHostModel extends BaseModel {
// =attributes
@attr('string', {
description: 'The type of the resource, to help differentiate schemas'
}) type;
@attr('string', {
description: 'Optional name for identification purposes'
}) name;
@attr('string', {
description: 'Optional user-set description for identification purposes'
}) description;
@attr('date', {
description: 'The time this resource was created\nOutput only.',
readOnly: true
}) created_time;
@attr('date', {
description: 'The time this resource was last updated\nOutput only.',
readOnly: true
}) updated_time;
@attr('number', {
description: 'Current version number of this resource.',
})
version;
@attr('string', {
description: 'The address (DNS or IP name) used to reach the host'
}) address;
}
+1 -9
View File
@@ -1,11 +1,3 @@
import GeneratedHostCatalogModel from '../generated/models/host-catalog';
import { hasMany } from '@ember-data/model';
export default class HostCatalogModel extends GeneratedHostCatalogModel {
/**
* @type {HostSetModel[]}
*/
@hasMany('host-set') hostSets;
}
export default class HostCatalogModel extends GeneratedHostCatalogModel {}
+1 -11
View File
@@ -1,13 +1,3 @@
import GeneratedHostSetModel from '../generated/models/host-set';
import { belongsTo } from '@ember-data/model';
export default class HostSetModel extends GeneratedHostSetModel {
// =relationships
/**
* @type {HostCatalogModel}
*/
@belongsTo('host-catalog') hostCatalog;
}
export default class HostSetModel extends GeneratedHostSetModel {}
+3
View File
@@ -0,0 +1,3 @@
import GeneratedHostModel from '../generated/models/host';
export default class HostModel extends GeneratedHostModel {}
+1
View File
@@ -0,0 +1 @@
export { default } from 'api/adapters/host';
+1
View File
@@ -0,0 +1 @@
export { default } from 'api/models/host';
@@ -0,0 +1,28 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module('Unit | Adapter | host', function(hooks) {
setupTest(hooks);
test('it generates correct complete URLs', function (assert) {
assert.expect(2);
const scopeID = 'o_1';
const hostCatalogID = 'hc_098';
const method = 'my-custom-method';
const mockSnapshot = {
adapterOptions: {
scopeID,
method
}
};
const adapter = this.owner.lookup('adapter:host');
// Without hostCatalogID...
let url = adapter.buildURL('host', null, mockSnapshot, 'findAll');
assert.equal(url, '/v1/scopes/o_1/hosts:my-custom-method');
// With hostCatalogID...
mockSnapshot.adapterOptions.hostCatalogID = hostCatalogID;
url = adapter.buildURL('host', null, mockSnapshot, 'findAll');
assert.equal(url, '/v1/scopes/o_1/host-catalogs/hc_098/hosts:my-custom-method');
});
});
+13
View File
@@ -0,0 +1,13 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module('Unit | Model | host', function(hooks) {
setupTest(hooks);
// Replace this with your real tests.
test('it exists', function(assert) {
let store = this.owner.lookup('service:store');
let model = store.createRecord('host', {});
assert.ok(model);
});
});
+8
View File
@@ -88,6 +88,14 @@ export default function() {
this.patch('/scopes/:scope_id/host-catalogs/:id');
this.del('/scopes/:scope_id/host-catalogs/:id');
// host
this.get('/scopes/:scope_id/host-catalogs/:host_catalog_id/hosts');
this.post('/scopes/:scope_id/host-catalogs/:host_catalog_id/hosts');
this.get('/scopes/:scope_id/host-catalogs/:host_catalog_id/hosts/:id');
this.patch('/scopes/:scope_id/host-catalogs/:host_catalog_id/hosts/:id');
this.del('/scopes/:scope_id/host-catalogs/:host_catalog_id/hosts/:id');
// host-set
this.get('/scopes/:scope_id/host-catalogs/:host_catalog_id/host-sets');
+1 -14
View File
@@ -1,16 +1,3 @@
import factory from '../generated/factories/host-catalog';
import { trait } from 'ember-cli-mirage';
export default factory.extend({
/**
* Create catalogs with associated host sets and hosts.
*/
withChildren: trait({
afterCreate(record, server) {
const host_set_ids = server.createList('host-set', 3).map(set => set.id);
record.update({ host_set_ids });
}
})
});
export default factory.extend();
+3
View File
@@ -0,0 +1,3 @@
import factory from '../generated/factories/host';
export default factory.extend();
@@ -0,0 +1,17 @@
import { Factory } from 'ember-cli-mirage';
import { random, date, internet } from 'faker';
/**
* GeneratedHostModelFactory
*/
export default Factory.extend({
type: 'static',
name: () => random.words(),
description: () => random.words(),
created_time: () => date.recent(),
updated_time: () => date.recent(),
version: () => random.number(),
address: () => internet.ipv6(),
});
+7 -3
View File
@@ -25,9 +25,13 @@ export default function(server) {
// Other resources
server.db.scopes.where({type: 'project'}).forEach(projectScope => {
const scope = { id: projectScope.id, type: projectScope.type };
server.createList('host-catalog', 2, { scope }, 'withChildren');
server.db.scopes.where({type: 'project'}).forEach(({ id, type }) => {
const scope = { id, type };
server.createList('host-catalog', 2, { scope });
// Hosts and host sets are supposed to be associated to a host catalog.
// For simplicity of mocks, we don't actually associate them here.
server.createList('host-set', 3, { scope });
server.createList('host', 10, { scope });
});
}