Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 41 additions & 5 deletions mirage/route-handlers/crates.js
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,11 @@ export function register(server) {
});

server.put('/api/v1/crates/:name/owners', (schema, request) => {
let { user } = getSession(schema);
if (!user) {
return new Response(403, {}, { errors: [{ detail: 'must be logged in to perform that action' }] });
}

let { name } = request.params;
let crate = schema.crates.findBy({ name });

Expand All @@ -235,17 +240,48 @@ export function register(server) {
}

const body = JSON.parse(request.requestBody);
const [ownerId] = body.owners;
const user = schema.users.findBy({ login: ownerId });

if (!user) {
return { errors: [{ detail: `could not find user with login \`${ownerId}\`` }] };
let users = [];
let teams = [];
let msgs = [];
for (let login of body.owners) {
if (login.includes(':')) {
let team = schema.teams.findBy({ login });
if (!team) {
return new Response(404, {}, { errors: [{ detail: `could not find team with login \`${login}\`` }] });
}

teams.push(team);
msgs.push(`team ${login} has been added as an owner of crate ${crate.name}`);
} else {
let user = schema.users.findBy({ login });
if (!user) {
return new Response(404, {}, { errors: [{ detail: `could not find user with login \`${login}\`` }] });
}

users.push(user);
msgs.push(`user ${login} has been invited to be an owner of crate ${crate.name}`);
}
}

return { ok: true };
for (let team of teams) {
schema.crateOwnerships.create({ crate, team });
}

for (let invitee of users) {
schema.crateOwnerInvitations.create({ crate, inviter: user, invitee });
}

let msg = msgs.join(',');
return { ok: true, msg };
});

server.delete('/api/v1/crates/:name/owners', (schema, request) => {
let { user } = getSession(schema);
if (!user) {
return new Response(403, {}, { errors: [{ detail: 'must be logged in to perform that action' }] });
}

let { name } = request.params;
let crate = schema.crates.findBy({ name });

Expand Down
4 changes: 1 addition & 3 deletions tests/adapters/crate-test.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { module, test } from 'qunit';

import { setupMirage } from 'ember-cli-mirage/test-support';

import { setupTest } from 'crates-io/tests/helpers';
import { setupMirage, setupTest } from 'crates-io/tests/helpers';

module('Adapter | crate', function (hooks) {
setupTest(hooks);
Expand Down
1 change: 1 addition & 0 deletions tests/helpers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { setupApplicationTest as upstreamSetupApplicationTest } from 'ember-quni
import { setupSentryMock } from './sentry';
import setupMirage from './setup-mirage';

export { default as setupMirage } from './setup-mirage';
export { setupTest, setupRenderingTest } from 'ember-qunit';

// see http://emberjs.github.io/rfcs/0637-customizable-test-setups.html
Expand Down
119 changes: 119 additions & 0 deletions tests/mirage/crates/add-owner-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { module, test } from 'qunit';

import fetch from 'fetch';

import { setupTest } from '../../helpers';
import setupMirage from '../../helpers/setup-mirage';

const ADD_USER_BODY = JSON.stringify({ owners: ['john-doe'] });

module('Mirage | PUT /api/v1/crates/:name/owners', function (hooks) {
setupTest(hooks);
setupMirage(hooks);

test('returns 403 if unauthenticated', async function (assert) {
let response = await fetch('/api/v1/crates/foo/owners', { method: 'PUT', body: ADD_USER_BODY });
assert.strictEqual(response.status, 403);
assert.deepEqual(await response.json(), {
errors: [{ detail: 'must be logged in to perform that action' }],
});
});

test('returns 404 for unknown crates', async function (assert) {
let user = this.server.create('user');
this.authenticateAs(user);

let response = await fetch('/api/v1/crates/foo/owners', { method: 'PUT', body: ADD_USER_BODY });
assert.strictEqual(response.status, 404);
assert.deepEqual(await response.json(), { errors: [{ detail: 'Not Found' }] });
});

test('can add new owner', async function (assert) {
let user = this.server.create('user');
this.authenticateAs(user);

let crate = this.server.create('crate', { name: 'foo' });
this.server.create('crate-ownership', { crate, user });

let user2 = this.server.create('user');

let body = JSON.stringify({ owners: [user2.login] });
let response = await fetch('/api/v1/crates/foo/owners', { method: 'PUT', body });
assert.strictEqual(response.status, 200);
assert.deepEqual(await response.json(), {
ok: true,
msg: 'user user-2 has been invited to be an owner of crate foo',
});

let owners = this.server.schema.crateOwnerships.where({ crateId: crate.id });
assert.strictEqual(owners.length, 1);
assert.strictEqual(owners.models[0].userId, user.id);

let invites = this.server.schema.crateOwnerInvitations.where({ crateId: crate.id });
assert.strictEqual(invites.length, 1);
assert.strictEqual(invites.models[0].inviterId, user.id);
assert.strictEqual(invites.models[0].inviteeId, user2.id);
});

test('can add team owner', async function (assert) {
let user = this.server.create('user');
this.authenticateAs(user);

let crate = this.server.create('crate', { name: 'foo' });
this.server.create('crate-ownership', { crate, user });

let team = this.server.create('team');

let body = JSON.stringify({ owners: [team.login] });
let response = await fetch('/api/v1/crates/foo/owners', { method: 'PUT', body });
assert.strictEqual(response.status, 200);
assert.deepEqual(await response.json(), {
ok: true,
msg: 'team github:rust-lang:team-1 has been added as an owner of crate foo',
});

let owners = this.server.schema.crateOwnerships.where({ crateId: crate.id });
assert.strictEqual(owners.length, 2);
assert.strictEqual(owners.models[0].userId, user.id);
assert.strictEqual(owners.models[0].teamId, null);
assert.strictEqual(owners.models[1].userId, null);
assert.strictEqual(owners.models[1].teamId, user.id);

let invites = this.server.schema.crateOwnerInvitations.where({ crateId: crate.id });
assert.strictEqual(invites.length, 0);
});

test('can add multiple owners', async function (assert) {
let user = this.server.create('user');
this.authenticateAs(user);

let crate = this.server.create('crate', { name: 'foo' });
this.server.create('crate-ownership', { crate, user });

let team = this.server.create('team');
let user2 = this.server.create('user');
let user3 = this.server.create('user');

let body = JSON.stringify({ owners: [user2.login, team.login, user3.login] });
let response = await fetch('/api/v1/crates/foo/owners', { method: 'PUT', body });
assert.strictEqual(response.status, 200);
assert.deepEqual(await response.json(), {
ok: true,
msg: 'user user-2 has been invited to be an owner of crate foo,team github:rust-lang:team-1 has been added as an owner of crate foo,user user-3 has been invited to be an owner of crate foo',
});

let owners = this.server.schema.crateOwnerships.where({ crateId: crate.id });
assert.strictEqual(owners.length, 2);
assert.strictEqual(owners.models[0].userId, user.id);
assert.strictEqual(owners.models[0].teamId, null);
assert.strictEqual(owners.models[1].userId, null);
assert.strictEqual(owners.models[1].teamId, user.id);

let invites = this.server.schema.crateOwnerInvitations.where({ crateId: crate.id });
assert.strictEqual(invites.length, 2);
assert.strictEqual(invites.models[0].inviterId, user.id);
assert.strictEqual(invites.models[0].inviteeId, user2.id);
assert.strictEqual(invites.models[1].inviterId, user.id);
assert.strictEqual(invites.models[1].inviteeId, user3.id);
});
});
22 changes: 16 additions & 6 deletions tests/models/crate-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ import { module, test } from 'qunit';

import AdapterError from '@ember-data/adapter/error';

import { setupMirage } from 'ember-cli-mirage/test-support';

import { setupTest } from 'crates-io/tests/helpers';
import { setupMirage, setupTest } from 'crates-io/tests/helpers';

module('Model | Crate', function (hooks) {
setupTest(hooks);
Expand All @@ -17,17 +15,23 @@ module('Model | Crate', function (hooks) {
module('inviteOwner()', function () {
test('happy path', async function (assert) {
let user = this.server.create('user');
this.authenticateAs(user);

let crate = this.server.create('crate');
this.server.create('version', { crate });

let user2 = this.server.create('user');

let crateRecord = await this.store.findRecord('crate', crate.name);

let result = await crateRecord.inviteOwner(user.login);
assert.deepEqual(result, { ok: true });
let result = await crateRecord.inviteOwner(user2.login);
assert.deepEqual(result, { ok: true, msg: 'user user-2 has been invited to be an owner of crate crate-0' });
});

test('error handling', async function (assert) {
let user = this.server.create('user');
this.authenticateAs(user);

let crate = this.server.create('crate');
this.server.create('version', { crate });

Expand All @@ -43,17 +47,23 @@ module('Model | Crate', function (hooks) {
module('removeOwner()', function () {
test('happy path', async function (assert) {
let user = this.server.create('user');
this.authenticateAs(user);

let crate = this.server.create('crate');
this.server.create('version', { crate });

let user2 = this.server.create('user');

let crateRecord = await this.store.findRecord('crate', crate.name);

let result = await crateRecord.removeOwner(user.login);
let result = await crateRecord.removeOwner(user2.login);
assert.deepEqual(result, { ok: true, msg: 'owners successfully removed' });
});

test('error handling', async function (assert) {
let user = this.server.create('user');
this.authenticateAs(user);

let crate = this.server.create('crate');
this.server.create('version', { crate });

Expand Down
6 changes: 1 addition & 5 deletions tests/models/version-test.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
import { setupTest } from 'ember-qunit';
import { module, test } from 'qunit';

import { setupMirage } from 'ember-cli-mirage/test-support';

import { setupFakeTimers } from '../helpers/fake-timers';
import { setupMirage, setupTest } from 'crates-io/tests/helpers';

module('Model | Version', function (hooks) {
setupTest(hooks);
setupMirage(hooks);
setupFakeTimers(hooks);

hooks.beforeEach(function () {
this.store = this.owner.lookup('service:store');
Expand Down
4 changes: 1 addition & 3 deletions tests/services/playground-test.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { module, test } from 'qunit';

import { setupMirage } from 'ember-cli-mirage/test-support';

import { setupTest } from 'crates-io/tests/helpers';
import { setupMirage, setupTest } from 'crates-io/tests/helpers';

module('Service | Playground', function (hooks) {
setupTest(hooks);
Expand Down
Loading