Skip to content

Commit

Permalink
Merge pull request heroku#44 from heroku/eb/warn-users-when-adding-si…
Browse files Browse the repository at this point in the history
…xth-member

Warn users when going over free team limit
  • Loading branch information
eablack authored and jdx committed Jun 19, 2018
1 parent a3862c2 commit ce5cb51
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 13 deletions.
12 changes: 12 additions & 0 deletions packages/heroku-orgs/commands/members/add.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,28 @@ let co = require('co');
let extend = require('util')._extend;

function* run (context, heroku) {
// Users receive `You'll be billed monthly for teams over 5 members.`
// message when going over the FREE_TEAM_LIMIT
const FREE_TEAM_LIMIT = 5;
let org = context.org;
let email = context.args.email;
let role = context.flags.role;
let features = yield heroku.get('/account/features');
let orgCreationFeature = features.find(function(feature) {
return feature.name === 'standard-org-creation';
});

let request = heroku.request({
method: 'PUT',
path: `/organizations/${org}/members`,
body: {email, role},
});
yield cli.action(`Adding ${cli.color.cyan(email)} to ${cli.color.magenta(org)} as ${cli.color.green(role)}`, request);

let members = yield heroku.get(`/organizations/${org}/members`);
if ((members.length === (FREE_TEAM_LIMIT + 1)) && orgCreationFeature) {
cli.log("You'll be billed monthly for teams over 5 members.");
}
}

let cmd = {
Expand Down
46 changes: 46 additions & 0 deletions packages/heroku-orgs/test/commands/members/add.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,64 @@
'use strict';

let cmd = require('../../../commands/members/add').add;
let stubGet = require('../../stub/get');

describe('heroku members:add', () => {
beforeEach(() => cli.mockConsole());
afterEach(() => nock.cleanAll());

it('adds a member to an org', () => {
stubGet.variableSizeOrgMembers(1);
stubGet.userFeatureFlags([]);
let api = nock('https://api.heroku.com:443')
.put('/organizations/myorg/members', {email: '[email protected]', role: 'admin'})
.reply(200);

return cmd.run({org: 'myorg', args: {email: '[email protected]'}, flags: {role: 'admin'}})
.then(() => expect(``).to.eq(cli.stdout))
.then(() => expect(`Adding [email protected] to myorg as admin... done\n`).to.eq(cli.stderr))
.then(() => api.done());
});

context('adding a member with the standard org creation flag', () => {
beforeEach(() => {
stubGet.userFeatureFlags([{name: 'standard-org-creation'}]);
});

it('does not warn the user when under the free org limit', () => {
stubGet.variableSizeOrgMembers(1);
let api = nock('https://api.heroku.com:443')
.put('/organizations/myorg/members', {email: '[email protected]', role: 'admin'})
.reply(200);

return cmd.run({org: 'myorg', args: {email: '[email protected]'}, flags: {role: 'admin'}})
.then(() => expect(``).to.eq(cli.stdout))
.then(() => expect(`Adding [email protected] to myorg as admin... done\n`).to.eq(cli.stderr))
.then(() => api.done());
});

it('does not warn the user when over the free org limit', () => {
stubGet.variableSizeOrgMembers(7);
let api = nock('https://api.heroku.com:443')
.put('/organizations/myorg/members', {email: '[email protected]', role: 'admin'})
.reply(200);

return cmd.run({org: 'myorg', args: {email: '[email protected]'}, flags: {role: 'admin'}})
.then(() => expect(``).to.eq(cli.stdout))
.then(() => expect(`Adding [email protected] to myorg as admin... done\n`).to.eq(cli.stderr))
.then(() => api.done());
});

it('does warn the user when at the free org limit', () => {
stubGet.variableSizeOrgMembers(6);
let api = nock('https://api.heroku.com:443')
.put('/organizations/myorg/members', {email: '[email protected]', role: 'admin'})
.reply(200);

return cmd.run({org: 'myorg', args: {email: '[email protected]'}, flags: {role: 'admin'}})
.then(() => expect(`You'll be billed monthly for teams over 5 members.\n`).to.eq(cli.stdout))
.then(() => expect(`Adding [email protected] to myorg as admin... done\n`).to.eq(cli.stderr))
.then(() => api.done());
});
});
});
48 changes: 35 additions & 13 deletions packages/heroku-orgs/test/stub/get.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
'use strict';

function appCollaborators() {
return nock('https://api.heroku.com:443')
.get('/apps/myapp/collaborators')
Expand Down Expand Up @@ -82,21 +84,33 @@ function orgMembers() {
return nock('https://api.heroku.com:443')
.get('/organizations/myorg/members')
.reply(200, [
{
email: '[email protected]', role: 'admin',
user: { email: '[email protected]' }
},
{
email: '[email protected]', role: 'viewer',
user: { email: '[email protected]' }
},
{
email: '[email protected]', role: 'collaborator',
user: { email: '[email protected]' }
}
{
email: '[email protected]', role: 'admin',
user: { email: '[email protected]' }
},
{
email: '[email protected]', role: 'viewer',
user: { email: '[email protected]' }
},
{
email: '[email protected]', role: 'collaborator',
user: { email: '[email protected]' }
}
]);
}

function variableSizeOrgMembers(orgSize) {
orgSize = (typeof(orgSize) === 'undefined') ? 1 : orgSize;
let orgMembers = [];
for(let i = 0; i < orgSize; i++) {
orgMembers.push({email: `test${i}@heroku.com`, role: 'admin',
user: { email: `test${i}@heroku.com` }});
}
return nock('https://api.heroku.com:443')
.get('/organizations/myorg/members')
.reply(200, orgMembers);
}

function personalApp() {
return nock('https://api.heroku.com:443')
.get('/apps/myapp')
Expand All @@ -106,6 +120,12 @@ function personalApp() {
});
}

function userFeatureFlags(flags) {
return nock('https://api.heroku.com:443')
.get('/account/features')
.reply(200, flags);
}

module.exports = {
appCollaborators: appCollaborators,
appPrivileges: appPrivileges,
Expand All @@ -114,5 +134,7 @@ module.exports = {
orgAppCollaboratorsWithPrivileges: orgAppCollaboratorsWithPrivileges,
orgFlags: orgFlags,
orgMembers: orgMembers,
personalApp: personalApp
personalApp: personalApp,
userFeatureFlags: userFeatureFlags,
variableSizeOrgMembers: variableSizeOrgMembers
};

0 comments on commit ce5cb51

Please sign in to comment.