diff --git a/src/create.js b/src/create.js index 956a515a..52af4cb6 100644 --- a/src/create.js +++ b/src/create.js @@ -1,5 +1,4 @@ import chalk from 'chalk'; -import {factory} from './github-client-factory'; async function authenticatedUserIsMemberOfRequestedOrganization(account, octokit) { const {data: organizations} = await octokit.orgs.listForAuthenticatedUser(); @@ -7,10 +6,9 @@ async function authenticatedUserIsMemberOfRequestedOrganization(account, octokit 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) { diff --git a/src/github-client-factory.js b/src/github-client-factory.js index 48c5b8b8..c8a774af 100644 --- a/src/github-client-factory.js +++ b/src/github-client-factory.js @@ -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}`}); } diff --git a/src/scaffolder.js b/src/scaffolder.js index a77cf8b1..ba08fb96 100644 --- a/src/scaffolder.js +++ b/src/scaffolder.js @@ -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; diff --git a/test/unit/create-test.js b/test/unit/create-test.js index 68f1a00e..f1df5ff0 100644 --- a/test/unit/create-test.js +++ b/test/unit/create-test.js @@ -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}); }); }); @@ -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({ @@ -61,7 +48,7 @@ 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 () => { @@ -69,7 +56,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({ @@ -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}); }); }); @@ -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` ); }); diff --git a/test/unit/scaffolder-test.js b/test/unit/scaffolder-test.js index 4ff07d46..bf56045f 100644 --- a/test/unit/scaffolder-test.js +++ b/test/unit/scaffolder-test.js @@ -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', () => { @@ -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()); @@ -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({ @@ -43,7 +47,7 @@ suite('github', () => { ); assert.calledWith( - settingsSecaffolder.default, + settingsScaffolder.default, projectRoot, projectName, description,