diff --git a/addons/api/addon/generated/models/auth-method.js b/addons/api/addon/generated/models/auth-method.js index c006b935c..995e65efd 100644 --- a/addons/api/addon/generated/models/auth-method.js +++ b/addons/api/addon/generated/models/auth-method.js @@ -4,7 +4,7 @@ import { attr } from '@ember-data/model'; /** * */ -export default class GeneratedOrganizationModel extends BaseModel { +export default class GeneratedAuthMethodModel extends BaseModel { // =attributes @@ -34,4 +34,9 @@ export default class GeneratedOrganizationModel extends BaseModel { }) updated_time; + @attr('boolean', { + description: 'Whether the resource is disabled', + }) + disabled; + } diff --git a/addons/api/addon/generated/models/organization.js b/addons/api/addon/generated/models/org.js similarity index 89% rename from addons/api/addon/generated/models/organization.js rename to addons/api/addon/generated/models/org.js index 773afb70f..64cea0154 100644 --- a/addons/api/addon/generated/models/organization.js +++ b/addons/api/addon/generated/models/org.js @@ -4,7 +4,7 @@ import { attr } from '@ember-data/model'; /** * */ -export default class GeneratedOrganizationModel extends BaseModel { +export default class GeneratedOrgModel extends BaseModel { // =attributes diff --git a/addons/api/addon/models/org.js b/addons/api/addon/models/org.js new file mode 100644 index 000000000..5b6bb4136 --- /dev/null +++ b/addons/api/addon/models/org.js @@ -0,0 +1,3 @@ +import GeneratedOrgModel from '../generated/models/org'; + +export default class OrgModel extends GeneratedOrgModel {} diff --git a/addons/api/addon/models/organization.js b/addons/api/addon/models/organization.js deleted file mode 100644 index a9478f967..000000000 --- a/addons/api/addon/models/organization.js +++ /dev/null @@ -1,3 +0,0 @@ -import GeneratedOrganizationModel from '../generated/models/organization'; - -export default class OrganizationModel extends GeneratedOrganizationModel {} diff --git a/addons/api/app/models/org.js b/addons/api/app/models/org.js new file mode 100644 index 000000000..8ef9d3f59 --- /dev/null +++ b/addons/api/app/models/org.js @@ -0,0 +1 @@ +export { default } from 'api/models/org'; diff --git a/addons/api/app/models/organization.js b/addons/api/app/models/organization.js deleted file mode 100644 index f9e7429d3..000000000 --- a/addons/api/app/models/organization.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from 'api/models/organization'; diff --git a/addons/api/tests/unit/models/organization-test.js b/addons/api/tests/unit/models/org-test.js similarity index 70% rename from addons/api/tests/unit/models/organization-test.js rename to addons/api/tests/unit/models/org-test.js index 9d94b9ea4..2f042eadc 100644 --- a/addons/api/tests/unit/models/organization-test.js +++ b/addons/api/tests/unit/models/org-test.js @@ -1,13 +1,13 @@ import { module, test } from 'qunit'; import { setupTest } from 'ember-qunit'; -module('Unit | Model | organization', function(hooks) { +module('Unit | Model | org', 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('organization', {}); + let model = store.createRecord('org', {}); assert.ok(model); }); }); diff --git a/ui/core/app/routes/orgs.js b/ui/core/app/routes/orgs.js index b3f86119f..199076b0b 100644 --- a/ui/core/app/routes/orgs.js +++ b/ui/core/app/routes/orgs.js @@ -1,3 +1,15 @@ import Route from '@ember/routing/route'; -export default class OrgsRoute extends Route {} +export default class OrgsRoute extends Route { + + // =methods + + /** + * Returns all orgs from the store. + * @return {Promise[OrgModel]} + */ + model() { + return this.store.findAll('org'); + } + +} diff --git a/ui/core/app/routes/orgs/org.js b/ui/core/app/routes/orgs/org.js index fcedca1e1..59055906e 100644 --- a/ui/core/app/routes/orgs/org.js +++ b/ui/core/app/routes/orgs/org.js @@ -9,13 +9,12 @@ export default class OrgsOrgRoute extends Route { // =methods /** - * Returns a mock organization object containing the specified ID. - * TODO: load a real org instance from the API. + * Returns an org by id. * @param {object} params - * @return {object} + * @return {Promise{OrgModel}} */ model({ org_id: id }) { - return { id }; + return this.store.findRecord('org', id); } /** diff --git a/ui/core/mirage/config.js b/ui/core/mirage/config.js index 7ff10e439..b81ef488f 100644 --- a/ui/core/mirage/config.js +++ b/ui/core/mirage/config.js @@ -15,14 +15,34 @@ export default function() { if (config.api.host) this.passthrough(`${config.api.host}/**`); this.passthrough(); + // Scope resources + // org + + this.get('/orgs'); + this.post('/orgs'); + this.get('/orgs/:id'); + this.patch('/orgs/:id'); + this.del('/orgs/:id'); + // project + this.get('/orgs/:org_id/projects'); this.post('/orgs/:org_id/projects'); this.get('/orgs/:org_id/projects/:id'); this.patch('/orgs/:org_id/projects/:id'); this.del('/orgs/:org_id/projects/:id'); + // Auth & IAM resources + + this.get('/orgs/:org_id/auth-methods'); + this.post('/orgs/:org_id/auth-methods'); + this.get('/orgs/:org_id/auth-methods/:id'); + this.patch('/orgs/:org_id/auth-methods/:id'); + this.del('/orgs/:org_id/auth-methods/:id'); + + // Other resources // host-catalog + this.get('/orgs/:org_id/projects/:project_id/host-catalogs'); this.post('/orgs/:org_id/projects/:project_id/host-catalogs'); this.get('/orgs/:org_id/projects/:project_id/host-catalogs/:id'); diff --git a/ui/core/mirage/factories/auth-method.js b/ui/core/mirage/factories/auth-method.js new file mode 100644 index 000000000..aa15a1103 --- /dev/null +++ b/ui/core/mirage/factories/auth-method.js @@ -0,0 +1,3 @@ +import factory from '../generated/factories/auth-method'; + +export default factory.extend(); diff --git a/ui/core/mirage/factories/org.js b/ui/core/mirage/factories/org.js new file mode 100644 index 000000000..fe119cba6 --- /dev/null +++ b/ui/core/mirage/factories/org.js @@ -0,0 +1,3 @@ +import factory from '../generated/factories/org'; + +export default factory.extend(); diff --git a/ui/core/mirage/generated/factories/auth-method.js b/ui/core/mirage/generated/factories/auth-method.js new file mode 100644 index 000000000..d76245946 --- /dev/null +++ b/ui/core/mirage/generated/factories/auth-method.js @@ -0,0 +1,16 @@ +import { Factory } from 'ember-cli-mirage'; +import { random, date } from 'faker'; + +/** + * GeneratedAuthMethodModelFactory + */ +export default Factory.extend({ + + type: 'password', + name: () => random.words(), + description: () => random.words(), + created_time: () => date.recent(), + updated_time: () => date.recent(), + disabled: () => random.boolean(), + +}); diff --git a/ui/core/mirage/generated/factories/org.js b/ui/core/mirage/generated/factories/org.js new file mode 100644 index 000000000..81ee23629 --- /dev/null +++ b/ui/core/mirage/generated/factories/org.js @@ -0,0 +1,15 @@ +import { Factory } from 'ember-cli-mirage'; +import { random, date } from 'faker'; + +/** + * GeneratedOrgModelFactory + * + */ +export default Factory.extend({ + + name: () => random.words(), + description: () => random.words(), + created_time: () => date.recent(), + updated_time: () => date.recent(), + +}); diff --git a/ui/core/mirage/scenarios/default.js b/ui/core/mirage/scenarios/default.js index fbf47a0b6..b8accbf8b 100644 --- a/ui/core/mirage/scenarios/default.js +++ b/ui/core/mirage/scenarios/default.js @@ -1,14 +1,19 @@ export default function(server) { - // Scope resources (org and project) have their relationship modelled. + // Scope resources - server.createList('project', 3); + server.createList('org', 3); + server.createList('project', 6); - // For simplicity, other resources have their relationships modelled _except_ - // their relationships to scope. These leads to the situation where the UI - // displays _all subresources_ as if they belong to _every scope_. This is - // a tradeoff due to the complexity of relationship modelling. + // Auth - server.createList('host-catalog', 3); + // Auth methods exist both at the global scope and the org scope. + // For simplicity we don't scope our mock auth methods and just return the + // same items for request at all scopes. + server.createList('auth-method', 3); + + // Other resources + + server.createList('host-catalog', 6); } diff --git a/ui/core/mirage/serializers/auth-method.js b/ui/core/mirage/serializers/auth-method.js new file mode 100644 index 000000000..cabe9ee7b --- /dev/null +++ b/ui/core/mirage/serializers/auth-method.js @@ -0,0 +1,5 @@ +import ApplicationSerializer from './application'; + +export default ApplicationSerializer.extend({ + modelName: 'auth-method' +}); diff --git a/ui/core/mirage/serializers/org.js b/ui/core/mirage/serializers/org.js new file mode 100644 index 000000000..43404176b --- /dev/null +++ b/ui/core/mirage/serializers/org.js @@ -0,0 +1,5 @@ +import ApplicationSerializer from './application'; + +export default ApplicationSerializer.extend({ + modelName: 'org' +}); diff --git a/ui/core/tests/acceptance/bread-crumbs-test.js b/ui/core/tests/acceptance/bread-crumbs-test.js index acdd9e736..2b134ae0a 100644 --- a/ui/core/tests/acceptance/bread-crumbs-test.js +++ b/ui/core/tests/acceptance/bread-crumbs-test.js @@ -7,6 +7,7 @@ module('Acceptance | breadcrumbs', function (hooks) { setupApplicationTest(hooks); setupMirage(hooks); + let org; let project; let hostCatalog; let projectsURL; @@ -19,9 +20,10 @@ module('Acceptance | breadcrumbs', function (hooks) { let crumbPath; hooks.beforeEach(function () { + org = this.server.create('org'); project = this.server.create('project'); hostCatalog = this.server.create('host-catalog'); - projectsURL = `/orgs/1/projects`; + projectsURL = `/orgs/${org.id}/projects`; newProjectURL = `${projectsURL}/new`; projectURL = `${projectsURL}/${project.id}`; hostCatalogsURL = `${projectURL}/host-catalogs`; @@ -36,7 +38,7 @@ module('Acceptance | breadcrumbs', function (hooks) { crumbPath = new URL(find('.rose-nav-breadcrumbs-link:last-child').href).pathname; assert.equal(crumbPath, projectURL, 'Last crumb has expected URL.'); await click(find('.rose-nav-breadcrumbs-link:first-child')); - assert.equal(currentURL(), '/orgs/1/projects', 'After navigating via breadcrumbs, we are one level up.'); + assert.equal(currentURL(), projectsURL, 'After navigating via breadcrumbs, we are one level up.'); }); test('can navigate via breadcrumbs to projects from new project', async function (assert) { @@ -46,7 +48,7 @@ module('Acceptance | breadcrumbs', function (hooks) { crumbPath = new URL(find('.rose-nav-breadcrumbs-link:last-child').href).pathname; assert.equal(crumbPath, newProjectURL, 'Last crumb has expected URL.'); await click(find('.rose-nav-breadcrumbs-link:first-child')); - assert.equal(currentURL(), '/orgs/1/projects', 'After navigating via breadcrumbs, we are one level up.'); + assert.equal(currentURL(), projectsURL, 'After navigating via breadcrumbs, we are one level up.'); }); test('can navigate via breadcrumbs to project from host catalogs', async function (assert) { diff --git a/ui/core/tests/acceptance/host-catalogs-test.js b/ui/core/tests/acceptance/host-catalogs-test.js index 7a54340b3..4be43309f 100644 --- a/ui/core/tests/acceptance/host-catalogs-test.js +++ b/ui/core/tests/acceptance/host-catalogs-test.js @@ -9,6 +9,10 @@ module('Acceptance | host catalogs', function(hooks) { setupApplicationTest(hooks); setupMirage(hooks); + hooks.beforeEach(function () { + this.server.create('org'); + }); + test('visiting host catalogs', async function (assert) { assert.expect(1); this.server.createList('project', 1); diff --git a/ui/core/tests/acceptance/projects-test.js b/ui/core/tests/acceptance/projects-test.js index af00df26d..0e7877c97 100644 --- a/ui/core/tests/acceptance/projects-test.js +++ b/ui/core/tests/acceptance/projects-test.js @@ -9,6 +9,10 @@ module('Acceptance | projects', function (hooks) { setupApplicationTest(hooks); setupMirage(hooks); + hooks.beforeEach(function () { + this.server.create('org'); + }); + test('visiting projects', async function (assert) { assert.expect(1); this.server.createList('project', 1);