refactor: 💡 implement new pathing for users
This commit is contained in:
17 files changed
+154
-78
No files matched your search
@@ -0,0 +1,13 @@
|
||||
import ApplicationAdapter from './application';
|
||||
|
||||
export default class UserAdapter extends ApplicationAdapter {
|
||||
|
||||
// =attributes
|
||||
|
||||
/**
|
||||
* Users use the new, unprefixed pathing style.
|
||||
* @override
|
||||
*/
|
||||
hasScopePrefix = false;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import ApplicationSerializer from './application';
|
||||
|
||||
export default class UserSerializer extends ApplicationSerializer {
|
||||
|
||||
// =attributes
|
||||
|
||||
/**
|
||||
* Serialized the scope ID into the `scope_id` field.
|
||||
* @type {boolean}
|
||||
*/
|
||||
serializeScopeID = true;
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from 'api/adapters/user';
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from 'api/serializers/user';
|
||||
@@ -0,0 +1,12 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module('Unit | Adapter | user', function(hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function(assert) {
|
||||
let adapter = this.owner.lookup('adapter:user');
|
||||
assert.ok(adapter);
|
||||
});
|
||||
});
|
||||
@@ -97,17 +97,17 @@ module('Unit | Model | base', function (hooks) {
|
||||
assert.expect(3);
|
||||
const store = this.owner.lookup('service:store');
|
||||
const model = store.createRecord('user', { scopeID: 'o_123' });
|
||||
this.server.post('/v1/scopes/o_123/users', () => {
|
||||
this.server.post('/v1/users', () => {
|
||||
assert.ok(true, 'Correctly scoped create record URL was requested.')
|
||||
return {};
|
||||
});
|
||||
await model.save();
|
||||
this.server.patch('/v1/scopes/o_123/users', () => {
|
||||
this.server.patch('/v1/users', () => {
|
||||
assert.ok(true, 'Correctly scoped update record URL was requested.')
|
||||
return {};
|
||||
});
|
||||
await model.save();
|
||||
this.server.delete('/v1/scopes/o_123/users', () => {
|
||||
this.server.delete('/v1/users', () => {
|
||||
assert.ok(true, 'Correctly scoped delete record URL was requested.')
|
||||
return {};
|
||||
});
|
||||
@@ -120,17 +120,17 @@ module('Unit | Model | base', function (hooks) {
|
||||
const customScopeID = 'global';
|
||||
const scope = {scope_id: 'o_123'};
|
||||
const model = store.createRecord('user', { scope });
|
||||
this.server.post('/v1/scopes/global/users', () => {
|
||||
this.server.post('/v1/users', () => {
|
||||
assert.ok(true, 'Correctly scoped create record URL was requested.')
|
||||
return {};
|
||||
});
|
||||
await model.save({adapterOptions: {scopeID: customScopeID}});
|
||||
this.server.patch('/v1/scopes/global/users', () => {
|
||||
this.server.patch('/v1/users', () => {
|
||||
assert.ok(true, 'Correctly scoped update record URL was requested.')
|
||||
return {};
|
||||
});
|
||||
await model.save({adapterOptions: {scopeID: customScopeID}});
|
||||
this.server.delete('/v1/scopes/global/users', () => {
|
||||
this.server.delete('/v1/users', () => {
|
||||
assert.ok(true, 'Correctly scoped delete record URL was requested.')
|
||||
return {};
|
||||
});
|
||||
@@ -143,7 +143,7 @@ module('Unit | Model | base', function (hooks) {
|
||||
const method = 'my-custom-method';
|
||||
const scope = {scope_id: 'o_123'};
|
||||
const model = store.createRecord('user', { scope });
|
||||
this.server.post(`/v1/scopes/o_123/users:${method}`, () => {
|
||||
this.server.post(`/v1/users:${method}`, () => {
|
||||
assert.ok(true, 'Correctly scoped create record URL was requested.')
|
||||
return {};
|
||||
});
|
||||
|
||||
@@ -25,7 +25,8 @@ module('Unit | Serializer | application', function (hooks) {
|
||||
const serializedRecord = record.serialize();
|
||||
assert.deepEqual(serializedRecord, {
|
||||
name: 'User',
|
||||
description: 'Description'
|
||||
description: 'Description',
|
||||
scope_id: 'global'
|
||||
});
|
||||
});
|
||||
|
||||
@@ -33,6 +34,7 @@ module('Unit | Serializer | application', function (hooks) {
|
||||
assert.expect(2);
|
||||
const store = this.owner.lookup('service:store');
|
||||
const serializer = store.serializerFor('user');
|
||||
serializer.serializeScopeID = false;
|
||||
const record = store.createRecord('user', {
|
||||
name: 'User',
|
||||
description: 'Description',
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module('Unit | Serializer | user', function(hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function(assert) {
|
||||
let store = this.owner.lookup('service:store');
|
||||
let serializer = store.serializerFor('user');
|
||||
|
||||
assert.ok(serializer);
|
||||
});
|
||||
|
||||
test('it serializes records', function(assert) {
|
||||
let store = this.owner.lookup('service:store');
|
||||
let record = store.createRecord('user', {});
|
||||
|
||||
let serializedRecord = record.serialize();
|
||||
|
||||
assert.ok(serializedRecord);
|
||||
});
|
||||
});
|
||||
@@ -24,10 +24,11 @@ export default class ScopesScopeGroupsGroupAddMembersRoute extends Route {
|
||||
* @return {Promise{GroupModel, [UserModel]}}
|
||||
*/
|
||||
model() {
|
||||
const { id: scopeID } = this.modelFor('scopes.scope');
|
||||
const group = this.modelFor('scopes.scope.groups.group');
|
||||
const { scopeID: scope_id } = group;
|
||||
return hash({
|
||||
group: this.modelFor('scopes.scope.groups.group'),
|
||||
users: this.store.findAll('user', { adapterOptions: { scopeID } })
|
||||
users: this.store.query('user', { scope_id })
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -12,27 +12,17 @@ export default class ScopesScopeRolesRoleAddPrincipalsRoute extends Route {
|
||||
|
||||
// =methods
|
||||
|
||||
/**
|
||||
* Empty out any previously loaded users and groups.
|
||||
* (collectively, principals).
|
||||
*/
|
||||
beforeModel() {
|
||||
this.store.unloadAll('user');
|
||||
//this.store.unloadAll('group');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current role, all users, and all groups
|
||||
* @return {{role: RoleModel, users: [UserModel], groups: [GroupModel]}}
|
||||
*/
|
||||
model() {
|
||||
const role = this.modelFor('scopes.scope.roles.role');
|
||||
const { scopeID } = role;
|
||||
const options = { adapterOptions: { scopeID } };
|
||||
const { scopeID: scope_id } = role;
|
||||
return hash({
|
||||
role,
|
||||
users: this.store.findAll('user', options),
|
||||
groups: this.store.query('group', { scope_id: scopeID })
|
||||
users: this.store.query('user', { scope_id }),
|
||||
groups: this.store.query('group', { scope_id })
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -23,8 +23,8 @@ export default class ScopesScopeUsersRoute extends Route {
|
||||
* @return {Promise{[UserModel]}}
|
||||
*/
|
||||
async model() {
|
||||
const { id: scopeID } = this.modelFor('scopes.scope');
|
||||
return this.store.findAll('user', { adapterOptions: { scopeID } });
|
||||
const { id: scope_id } = this.modelFor('scopes.scope');
|
||||
return this.store.query('user', { scope_id });
|
||||
}
|
||||
|
||||
// =actions
|
||||
|
||||
@@ -10,9 +10,6 @@ export default class ScopesScopeUsersUserRoute extends Route {
|
||||
* @return {UserModel}
|
||||
*/
|
||||
async model({ user_id }) {
|
||||
const { id: scopeID } = this.modelFor('scopes.scope');
|
||||
return this.store.findRecord('user', user_id, {
|
||||
adapterOptions: { scopeID },
|
||||
});
|
||||
return this.store.findRecord('user', user_id);
|
||||
}
|
||||
}
|
||||
+41
-39
@@ -54,11 +54,47 @@ export default function() {
|
||||
this.post('/scopes/:id_method', deauthHandler);
|
||||
|
||||
// IAM : Users
|
||||
this.get('/scopes/:scope_id/users');
|
||||
this.post('/scopes/:scope_id/users');
|
||||
this.get('/scopes/:scope_id/users/:id');
|
||||
this.patch('/scopes/:scope_id/users/:id');
|
||||
this.del('/scopes/:scope_id/users/:id');
|
||||
this.get('/users', ({ users }, { queryParams: { scope_id: scopeId } }) => {
|
||||
return users.where({ scopeId });
|
||||
});
|
||||
this.post('/users');
|
||||
this.get('/users/:id');
|
||||
this.patch('/users/:id');
|
||||
this.del('/users/:id');
|
||||
|
||||
// IAM: Groups
|
||||
this.get('/groups', ({ groups }, { queryParams: { scope_id: scopeId } }) => {
|
||||
return groups.where({ scopeId });
|
||||
});
|
||||
this.post('/groups');
|
||||
this.get('/groups/:id');
|
||||
this.patch('/groups/:id');
|
||||
this.del('/groups/:id');
|
||||
this.post('/groups/:idMethod', function ({ groups }, { params: { idMethod } }) {
|
||||
const attrs = this.normalizedRequestAttrs();
|
||||
const id = idMethod.split(':')[0];
|
||||
const method = idMethod.split(':')[1];
|
||||
const group = groups.find(id);
|
||||
const updatedAttrs = {
|
||||
version: attrs.version,
|
||||
memberIds: group.memberIds
|
||||
};
|
||||
// If adding members, push them into the array
|
||||
if (method === 'add-members') {
|
||||
attrs.memberIds.forEach(id => {
|
||||
if (!updatedAttrs.memberIds.includes(id)) {
|
||||
updatedAttrs.memberIds.push(id);
|
||||
}
|
||||
});
|
||||
}
|
||||
// If deleting members, filter them out of the array
|
||||
if (method === 'remove-members') {
|
||||
updatedAttrs.memberIds = updatedAttrs.memberIds.filter(id => {
|
||||
return !attrs.memberIds.includes(id);
|
||||
});
|
||||
}
|
||||
return group.update(updatedAttrs);
|
||||
});
|
||||
|
||||
// IAM: Roles
|
||||
this.get('/scopes/:scope_id/roles');
|
||||
@@ -106,40 +142,6 @@ export default function() {
|
||||
return role.update(updatedAttrs);
|
||||
});
|
||||
|
||||
// IAM: Groups
|
||||
this.get('/groups', ({ groups }, { queryParams: { scope_id: scopeId } }) => {
|
||||
return groups.where({ scopeId });
|
||||
});
|
||||
this.post('/groups');
|
||||
this.get('/groups/:id');
|
||||
this.patch('/groups/:id');
|
||||
this.del('/groups/:id');
|
||||
this.post('/groups/:idMethod', function ({ groups }, { params: { idMethod } }) {
|
||||
const attrs = this.normalizedRequestAttrs();
|
||||
const id = idMethod.split(':')[0];
|
||||
const method = idMethod.split(':')[1];
|
||||
const group = groups.find(id);
|
||||
const updatedAttrs = {
|
||||
version: attrs.version,
|
||||
memberIds: group.memberIds
|
||||
};
|
||||
// If adding members, push them into the array
|
||||
if (method === 'add-members') {
|
||||
attrs.memberIds.forEach(id => {
|
||||
if (!updatedAttrs.memberIds.includes(id)) {
|
||||
updatedAttrs.memberIds.push(id);
|
||||
}
|
||||
});
|
||||
}
|
||||
// If deleting members, filter them out of the array
|
||||
if (method === 'remove-members') {
|
||||
updatedAttrs.memberIds = updatedAttrs.memberIds.filter(id => {
|
||||
return !attrs.memberIds.includes(id);
|
||||
});
|
||||
}
|
||||
return group.update(updatedAttrs);
|
||||
});
|
||||
|
||||
// Other resources
|
||||
// host-catalog
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import { Model, belongsTo } from 'ember-cli-mirage';
|
||||
|
||||
export default Model.extend({
|
||||
|
||||
scope: belongsTo()
|
||||
|
||||
});
|
||||
@@ -1,5 +1,22 @@
|
||||
import ApplicationSerializer from './application';
|
||||
import { underscore } from '@ember/string';
|
||||
|
||||
export default ApplicationSerializer.extend({
|
||||
modelName: 'user'
|
||||
modelName: 'user',
|
||||
|
||||
keyForRelationshipId(relationshipName) {
|
||||
return `${this._container.inflector.singularize(
|
||||
underscore(relationshipName)
|
||||
)}_id`;
|
||||
},
|
||||
|
||||
_hashForModel(model) {
|
||||
const json = ApplicationSerializer.prototype._hashForModel.apply(this, arguments);
|
||||
json.scope = {
|
||||
id: model.scope.id,
|
||||
type: model.scope.type
|
||||
};
|
||||
return json;
|
||||
}
|
||||
|
||||
});
|
||||
@@ -42,7 +42,7 @@ module('Acceptance | breadcrumbs', function (hooks) {
|
||||
this.server.schema.scopes.where({ type: 'project' }).models[0];
|
||||
|
||||
project = getProjectScope();
|
||||
user = this.server.create('user');
|
||||
user = this.server.create('user', { scope: orgScope });
|
||||
role = this.server.create('role');
|
||||
group = this.server.create('group', { scope: orgScope });
|
||||
hostCatalog = this.server.create('host-catalog', {
|
||||
|
||||
@@ -30,10 +30,7 @@ module('Acceptance | users', function (hooks) {
|
||||
);
|
||||
|
||||
const user = this.server.create('user', {
|
||||
scope: {
|
||||
id: orgScope.id,
|
||||
type: orgScope.type,
|
||||
},
|
||||
scope: orgScope
|
||||
});
|
||||
|
||||
usersURL = `/scopes/${orgScope.id}/users`;
|
||||
@@ -78,7 +75,7 @@ module('Acceptance | users', function (hooks) {
|
||||
|
||||
test('saving a new user with invalid fields displays error messages', async function (assert) {
|
||||
assert.expect(2);
|
||||
this.server.post('scopes/:scope_id/users', () => {
|
||||
this.server.post('/users', () => {
|
||||
return new Response(
|
||||
400,
|
||||
{},
|
||||
@@ -139,7 +136,7 @@ module('Acceptance | users', function (hooks) {
|
||||
|
||||
test('saving an existing user with invalid fields displays error messages', async function (assert) {
|
||||
assert.expect(2);
|
||||
this.server.patch('/scopes/:scope_id/users/:id', () => {
|
||||
this.server.patch('/users/:id', () => {
|
||||
return new Response(
|
||||
400,
|
||||
{},
|
||||
@@ -175,7 +172,7 @@ module('Acceptance | users', function (hooks) {
|
||||
|
||||
test('errors are displayed when saving user fails', async function (assert) {
|
||||
assert.expect(1);
|
||||
this.server.patch('/scopes/:scope_id/users/:id', () => {
|
||||
this.server.patch('/users/:id', () => {
|
||||
return new Response(
|
||||
490,
|
||||
{},
|
||||
@@ -198,7 +195,7 @@ module('Acceptance | users', function (hooks) {
|
||||
|
||||
test('errors are displayed when user deletion fails', async function (assert) {
|
||||
assert.expect(1);
|
||||
this.server.del('/scopes/:scope_id/users/:id', () => {
|
||||
this.server.del('/users/:id', () => {
|
||||
return new Response(
|
||||
490,
|
||||
{},
|
||||
|
||||
Reference in new issue
Block a user