Skip to content
This repository has been archived by the owner on Aug 22, 2024. It is now read-only.

Commit

Permalink
refactor(octokit-client): lifted creation to the top-level scaffolder
Browse files Browse the repository at this point in the history
to make the client available for actions beyond repo creation

for #1
  • Loading branch information
travi committed Apr 11, 2019
1 parent b63f12d commit ab6b4b7
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 30 deletions.
4 changes: 1 addition & 3 deletions src/create.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import chalk from 'chalk';
import {factory} from './github-client-factory';

async function authenticatedUserIsMemberOfRequestedOrganization(account, octokit) {
const {data: organizations} = await octokit.orgs.listForAuthenticatedUser();

return organizations.reduce((acc, organization) => acc || account === organization.login, false);
}

export default async function (name, owner, visibility) {
export default async function (name, owner, visibility, octokit) {
console.error(chalk.grey('Creating repository on GitHub')); // eslint-disable-line no-console

const octokit = factory();
const {data: {login: authenticatedUser}} = await octokit.users.getAuthenticated();

if (owner === authenticatedUser) {
Expand Down
4 changes: 3 additions & 1 deletion src/github-client-factory.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@ import Octokit from '../third-party-wrappers/octokit';
import netrc from '../third-party-wrappers/netrc';

export function factory() {
return new Octokit({auth: `token ${netrc()['github.com'].login}`});
const personalAccessToken = netrc()['github.com'].login;

return new Octokit({auth: `token ${personalAccessToken}`});
}
5 changes: 4 additions & 1 deletion src/scaffolder.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import chalk from 'chalk';
import scaffoldSettings from './settings-scaffolder';
import create from './create';
import {factory} from './github-client-factory';

export async function scaffold({name, owner, projectRoot, projectType, description, homepage, visibility}) {
console.error(chalk.blue('Generating GitHub')); // eslint-disable-line no-console

const octokit = factory();

const [, creationResult] = await Promise.all([
scaffoldSettings(projectRoot, name, description, homepage, visibility, projectType),
create(name, owner, visibility)
create(name, owner, visibility, octokit)
]);

return creationResult;
Expand Down
25 changes: 5 additions & 20 deletions test/unit/create-test.js
Original file line number Diff line number Diff line change
@@ -1,46 +1,34 @@
import sinon from 'sinon';
import {assert} from 'chai';
import any from '@travi/any';
import * as clientFactory from '../../src/github-client-factory';
import create from '../../src/create';

suite('creation', () => {
let sandbox;
const sshUrl = any.url();
const htmlUrl = any.url();
const creationResponse = {data: {ssh_url: sshUrl, html_url: htmlUrl}};
const account = any.word();
const name = any.word();

setup(() => {
sandbox = sinon.createSandbox();

sandbox.stub(clientFactory, 'factory');
});

teardown(() => sandbox.restore());

suite('for user', () => {
test('that the repository is created for the provided user account', async () => {
const createForAuthenticatedUser = sinon.stub();
const getAuthenticated = sinon.stub();
const client = {repos: {createForAuthenticatedUser}, users: {getAuthenticated}};
clientFactory.factory.returns(client);
createForAuthenticatedUser.withArgs({name, private: false}).resolves(creationResponse);
getAuthenticated.resolves({data: {login: account}});

assert.deepEqual(await create(name, account, 'Public'), {sshUrl, htmlUrl});
assert.deepEqual(await create(name, account, 'Public', client), {sshUrl, htmlUrl});
});

test('that the repository is created as private when visibility is `Private`', async () => {
const createForAuthenticatedUser = sinon.stub();
const getAuthenticated = sinon.stub();
const client = {repos: {createForAuthenticatedUser}, users: {getAuthenticated}};
clientFactory.factory.returns(client);
createForAuthenticatedUser.withArgs({name, private: true}).resolves(creationResponse);
getAuthenticated.resolves({data: {login: account}});

assert.deepEqual(await create(name, account, 'Private'), {sshUrl, htmlUrl});
assert.deepEqual(await create(name, account, 'Private', client), {sshUrl, htmlUrl});
});
});

Expand All @@ -50,7 +38,6 @@ suite('creation', () => {
const listForAuthenticatedUser = sinon.stub();
const createInOrg = sinon.stub();
const client = {repos: {createInOrg}, users: {getAuthenticated}, orgs: {listForAuthenticatedUser}};
clientFactory.factory.returns(client);
getAuthenticated.resolves({data: {login: any.word()}});
listForAuthenticatedUser
.resolves({
Expand All @@ -61,15 +48,14 @@ suite('creation', () => {
});
createInOrg.withArgs({org: account, name, private: false}).resolves(creationResponse);

assert.deepEqual(await create(name, account, 'Public'), {sshUrl, htmlUrl});
assert.deepEqual(await create(name, account, 'Public', client), {sshUrl, htmlUrl});
});

test('that the repository is created as private when visibility is `Private`', async () => {
const getAuthenticated = sinon.stub();
const listForAuthenticatedUser = sinon.stub();
const createInOrg = sinon.stub();
const client = {repos: {createInOrg}, users: {getAuthenticated}, orgs: {listForAuthenticatedUser}};
clientFactory.factory.returns(client);
getAuthenticated.resolves({data: {login: any.word()}});
listForAuthenticatedUser
.resolves({
Expand All @@ -80,7 +66,7 @@ suite('creation', () => {
});
createInOrg.withArgs({org: account, name, private: true}).resolves(creationResponse);

assert.deepEqual(await create(name, account, 'Private'), {sshUrl, htmlUrl});
assert.deepEqual(await create(name, account, 'Private', client), {sshUrl, htmlUrl});
});
});

Expand All @@ -90,12 +76,11 @@ suite('creation', () => {
const getAuthenticated = sinon.stub();
const listForAuthenticatedUser = sinon.stub();
const client = {users: {getAuthenticated}, orgs: {listForAuthenticatedUser}};
clientFactory.factory.returns(client);
getAuthenticated.resolves({data: {login: authenticatedUser}});
listForAuthenticatedUser.resolves({data: any.listOf(() => ({...any.simpleObject(), login: any.word}))});

return assert.isRejected(
create(name, account, any.word()),
create(name, account, any.word(), client),
`User ${authenticatedUser} does not have access to create a repository in the ${account} account`
);
});
Expand Down
14 changes: 9 additions & 5 deletions test/unit/scaffolder-test.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import {assert} from 'chai';
import sinon from 'sinon';
import any from '@travi/any';
import * as settingsSecaffolder from '../../src/settings-scaffolder';
import * as settingsScaffolder from '../../src/settings-scaffolder';
import * as creator from '../../src/create';
import * as clientFactory from '../../src/github-client-factory';
import {scaffold} from '../../src/scaffolder';

suite('github', () => {
Expand All @@ -13,8 +14,9 @@ suite('github', () => {
setup(() => {
sandbox = sinon.createSandbox();

sandbox.stub(settingsSecaffolder, 'default');
sandbox.stub(settingsScaffolder, 'default');
sandbox.stub(creator, 'default');
sandbox.stub(clientFactory, 'factory');
});

teardown(() => sandbox.restore());
Expand All @@ -26,8 +28,10 @@ suite('github', () => {
const projectOwner = any.word();
const visibility = any.word();
const creationResult = any.simpleObject();
settingsSecaffolder.default.resolves();
creator.default.withArgs(projectName, projectOwner, visibility).resolves(creationResult);
const octokitClient = any.simpleObject();
settingsScaffolder.default.resolves();
creator.default.withArgs(projectName, projectOwner, visibility, octokitClient).resolves(creationResult);
clientFactory.factory.returns(octokitClient);

assert.equal(
await scaffold({
Expand All @@ -43,7 +47,7 @@ suite('github', () => {
);

assert.calledWith(
settingsSecaffolder.default,
settingsScaffolder.default,
projectRoot,
projectName,
description,
Expand Down

0 comments on commit ab6b4b7

Please sign in to comment.