mirror of
https://github.com/serverless/serverless.git
synced 2026-01-18 14:58:43 +00:00
794 lines
25 KiB
JavaScript
794 lines
25 KiB
JavaScript
'use strict';
|
|
|
|
const chai = require('chai');
|
|
const sinon = require('sinon');
|
|
const proxyquire = require('proxyquire');
|
|
const overrideEnv = require('process-utils/override-env');
|
|
const overrideStdoutWrite = require('process-utils/override-stdout-write');
|
|
const requireUncached = require('ncjsm/require-uncached');
|
|
const chalk = require('chalk');
|
|
const { StepHistory } = require('@serverless/utils/telemetry');
|
|
|
|
const { expect } = chai;
|
|
|
|
chai.use(require('chai-as-promised'));
|
|
chai.use(require('sinon-chai'));
|
|
|
|
const { join, resolve } = require('path');
|
|
const { remove: rmDir, outputFile: writeFile } = require('fs-extra');
|
|
const { resolveFileProfiles } = require('../../../../../lib/plugins/aws/utils/credentials');
|
|
|
|
const mockedSdk = {
|
|
organizations: {
|
|
get: () => {
|
|
return {
|
|
orgUid: 'org-uid',
|
|
};
|
|
},
|
|
},
|
|
getProviders: async () => {
|
|
return { result: [] };
|
|
},
|
|
};
|
|
|
|
const step = proxyquire('../../../../../lib/cli/interactive-setup/aws-credentials', {
|
|
'../../utils/openBrowser': async (url) => {
|
|
openBrowserUrls.push(url);
|
|
},
|
|
'@serverless/dashboard-plugin/lib/clientUtils': {
|
|
getPlatformClientWithAccessKey: async () => mockedSdk,
|
|
},
|
|
});
|
|
|
|
const inquirer = require('@serverless/utils/inquirer');
|
|
const configureInquirerStub = require('@serverless/test/configure-inquirer-stub');
|
|
|
|
const openBrowserUrls = [];
|
|
|
|
describe('test/unit/lib/cli/interactive-setup/aws-credentials.test.js', () => {
|
|
const accessKeyId = 'AKIAIOSFODNN7EXAMPLE';
|
|
const secretAccessKey = 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY';
|
|
|
|
afterEach(() => {
|
|
openBrowserUrls.length = 0;
|
|
sinon.restore();
|
|
});
|
|
|
|
it('Should be ineffective, when not at service path', async () => {
|
|
const context = {};
|
|
expect(await step.isApplicable(context)).to.equal(false);
|
|
expect(context.inapplicabilityReasonCode).to.equal('NOT_IN_SERVICE_DIRECTORY');
|
|
});
|
|
|
|
it('Should be ineffective, when not at AWS service', async () => {
|
|
const context = {
|
|
serviceDir: process.cwd(),
|
|
configuration: {},
|
|
configurationFilename: 'serverless.yml',
|
|
};
|
|
expect(await step.isApplicable(context)).to.equal(false);
|
|
expect(context.inapplicabilityReasonCode).to.equal('NON_AWS_PROVIDER');
|
|
});
|
|
|
|
it('Should be ineffective, when user has default provider set', async () => {
|
|
const internalMockedSdk = {
|
|
...mockedSdk,
|
|
getProviders: async () => {
|
|
return {
|
|
result: [
|
|
{
|
|
alias: 'someprovider',
|
|
providerName: 'aws',
|
|
providerType: 'roleArn',
|
|
providerUid: 'provideruid',
|
|
isDefault: true,
|
|
providerDetails: {
|
|
roleArn: 'arn:xxx',
|
|
},
|
|
},
|
|
],
|
|
};
|
|
},
|
|
};
|
|
const mockedStep = proxyquire('../../../../../lib/cli/interactive-setup/aws-credentials', {
|
|
'@serverless/dashboard-plugin/lib/clientUtils': {
|
|
getPlatformClientWithAccessKey: async () => internalMockedSdk,
|
|
},
|
|
'@serverless/dashboard-plugin/lib/isAuthenticated': () => true,
|
|
});
|
|
|
|
const context = {
|
|
serviceDir: process.cwd(),
|
|
configuration: { provider: { name: 'aws' }, org: 'someorg' },
|
|
configurationFilename: 'serverless.yml',
|
|
};
|
|
expect(await mockedStep.isApplicable(context)).to.be.false;
|
|
expect(context.inapplicabilityReasonCode).to.equal('DEFAULT_PROVIDER_CONFIGURED');
|
|
});
|
|
|
|
it('Should be ineffective, when existing service already has a provider set', async () => {
|
|
const internalMockedSdk = {
|
|
...mockedSdk,
|
|
getProviders: async () => {
|
|
return {
|
|
result: [
|
|
{
|
|
alias: 'someprovider',
|
|
providerName: 'aws',
|
|
providerType: 'roleArn',
|
|
providerUid: 'provideruid',
|
|
isDefault: false,
|
|
providerDetails: {
|
|
roleArn: 'arn:xxx',
|
|
},
|
|
},
|
|
],
|
|
};
|
|
},
|
|
};
|
|
const mockedStep = proxyquire('../../../../../lib/cli/interactive-setup/aws-credentials', {
|
|
'@serverless/dashboard-plugin/lib/clientUtils': {
|
|
getPlatformClientWithAccessKey: async () => internalMockedSdk,
|
|
},
|
|
'@serverless/dashboard-plugin/lib/isAuthenticated': () => true,
|
|
'./utils': {
|
|
doesServiceInstanceHaveLinkedProvider: () => true,
|
|
},
|
|
});
|
|
|
|
const context = {
|
|
history: new Set(),
|
|
serviceDir: process.cwd(),
|
|
configuration: {
|
|
provider: { name: 'aws' },
|
|
org: 'someorg',
|
|
app: 'someapp',
|
|
service: 'service',
|
|
},
|
|
options: {},
|
|
configurationFilename: 'serverless.yml',
|
|
};
|
|
expect(await mockedStep.isApplicable(context)).to.be.false;
|
|
expect(context.inapplicabilityReasonCode).to.equal('LINKED_PROVIDER_CONFIGURED');
|
|
});
|
|
|
|
it('Should be effective, when existing service instance does not have a provider set', async () => {
|
|
const internalMockedSdk = {
|
|
...mockedSdk,
|
|
getProviders: async () => {
|
|
return {
|
|
result: [
|
|
{
|
|
alias: 'someprovider',
|
|
providerName: 'aws',
|
|
providerType: 'roleArn',
|
|
providerUid: 'provideruid',
|
|
isDefault: false,
|
|
providerDetails: {
|
|
roleArn: 'arn:xxx',
|
|
},
|
|
},
|
|
],
|
|
};
|
|
},
|
|
};
|
|
const mockedStep = proxyquire('../../../../../lib/cli/interactive-setup/aws-credentials', {
|
|
'@serverless/dashboard-plugin/lib/clientUtils': {
|
|
getPlatformClientWithAccessKey: async () => internalMockedSdk,
|
|
},
|
|
'@serverless/dashboard-plugin/lib/isAuthenticated': () => true,
|
|
'./utils': {
|
|
doesServiceInstanceHaveLinkedProvider: () => false,
|
|
},
|
|
});
|
|
|
|
expect(
|
|
await mockedStep.isApplicable({
|
|
history: new Set(),
|
|
serviceDir: process.cwd(),
|
|
configuration: {
|
|
provider: { name: 'aws' },
|
|
org: 'someorg',
|
|
app: 'someapp',
|
|
service: 'service',
|
|
},
|
|
options: {},
|
|
configurationFilename: 'serverless.yml',
|
|
})
|
|
).to.be.true;
|
|
});
|
|
|
|
it('Should emit warning when dashboard is not available when fetching providers', async () => {
|
|
const internalMockedSdk = {
|
|
...mockedSdk,
|
|
getProviders: async () => {
|
|
const err = new Error('unavailable');
|
|
err.statusCode = 500;
|
|
throw err;
|
|
},
|
|
};
|
|
const mockedStep = proxyquire('../../../../../lib/cli/interactive-setup/aws-credentials', {
|
|
'@serverless/dashboard-plugin/lib/clientUtils': {
|
|
getPlatformClientWithAccessKey: async () => internalMockedSdk,
|
|
},
|
|
'@serverless/dashboard-plugin/lib/isAuthenticated': () => true,
|
|
});
|
|
|
|
let stdoutData = '';
|
|
await overrideStdoutWrite(
|
|
(data) => (stdoutData += data),
|
|
async () =>
|
|
expect(
|
|
await mockedStep.isApplicable({
|
|
serviceDir: process.cwd(),
|
|
configuration: { provider: { name: 'aws' }, org: 'someorg' },
|
|
configurationFilename: 'serverless.yml',
|
|
})
|
|
).to.be.false
|
|
);
|
|
|
|
expect(stdoutData).to.include('Dashboard service is currently unavailable');
|
|
});
|
|
|
|
it('Should be effective, at AWS service and no credentials are set', async () =>
|
|
expect(
|
|
await step.isApplicable({
|
|
serviceDir: process.cwd(),
|
|
configuration: { provider: { name: 'aws' } },
|
|
configurationFilename: 'serverless.yml',
|
|
})
|
|
).to.equal(true));
|
|
|
|
it('Should emit a message when user decides to skip credentials setup', async () => {
|
|
configureInquirerStub(inquirer, {
|
|
list: { credentialsSetupChoice: '_skip_' },
|
|
});
|
|
|
|
const context = {
|
|
serviceDir: process.cwd(),
|
|
configuration: { provider: { name: 'aws' } },
|
|
configurationFilename: 'serverless.yml',
|
|
stepHistory: new StepHistory(),
|
|
options: {},
|
|
};
|
|
let stdoutData = '';
|
|
await overrideStdoutWrite(
|
|
(data) => (stdoutData += data),
|
|
async () => await step.run(context)
|
|
);
|
|
|
|
expect(stdoutData).to.include('You can setup your AWS account later');
|
|
expect(context.stepHistory.valuesMap()).to.deep.equal(
|
|
new Map([['credentialsSetupChoice', '_skip_']])
|
|
);
|
|
});
|
|
|
|
describe('In environment credentials', () => {
|
|
let restoreEnv;
|
|
let uncachedStep;
|
|
|
|
before(() => {
|
|
({ restoreEnv } = overrideEnv({ asCopy: true }));
|
|
process.env.AWS_ACCESS_KEY_ID = accessKeyId;
|
|
process.env.AWS_SECRET_ACCESS_KEY = secretAccessKey;
|
|
uncachedStep = requireUncached(() =>
|
|
require('../../../../../lib/cli/interactive-setup/aws-credentials')
|
|
);
|
|
});
|
|
|
|
after(() => restoreEnv);
|
|
|
|
it('Should be ineffective, when credentials are set in environment', async () => {
|
|
expect(
|
|
await uncachedStep.isApplicable({
|
|
serviceDir: process.cwd(),
|
|
configuration: { provider: { name: 'aws' } },
|
|
configurationFilename: 'serverless.yml',
|
|
})
|
|
).to.equal(false);
|
|
});
|
|
});
|
|
|
|
describe('AWS config handling', () => {
|
|
let credentialsDirPath;
|
|
let credentialsFilePath;
|
|
|
|
before(() => {
|
|
credentialsDirPath = resolve('.aws');
|
|
credentialsFilePath = join(credentialsDirPath, 'credentials');
|
|
});
|
|
|
|
afterEach(() => rmDir(credentialsDirPath));
|
|
|
|
describe('Existing credentials case', () => {
|
|
before(() =>
|
|
writeFile(
|
|
credentialsFilePath,
|
|
[
|
|
'[some-profile]',
|
|
`aws_access_key_id = ${accessKeyId}`,
|
|
`aws_secret_access_key = ${secretAccessKey}`,
|
|
].join('\n')
|
|
)
|
|
);
|
|
|
|
it('Should be ineffective, When credentials are set in AWS config', async () =>
|
|
expect(
|
|
await step.isApplicable({
|
|
serviceDir: process.cwd(),
|
|
configuration: { provider: { name: 'aws' } },
|
|
configurationFilename: 'serverless.yml',
|
|
})
|
|
).to.equal(false));
|
|
});
|
|
|
|
it('Should setup credentials for users not having an AWS account', async () => {
|
|
configureInquirerStub(inquirer, {
|
|
list: { credentialsSetupChoice: '_local_' },
|
|
confirm: { hasAwsAccount: false },
|
|
input: {
|
|
createAwsAccountPrompt: '',
|
|
generateAwsCredsPrompt: '',
|
|
accessKeyId,
|
|
secretAccessKey,
|
|
},
|
|
});
|
|
const context = {
|
|
configuration: { provider: {} },
|
|
options: {},
|
|
stepHistory: new StepHistory(),
|
|
};
|
|
await step.run(context);
|
|
expect(openBrowserUrls.length).to.equal(2);
|
|
expect(openBrowserUrls[0].includes('signup')).to.be.true;
|
|
expect(openBrowserUrls[1].includes('console.aws.amazon.com')).to.be.true;
|
|
resolveFileProfiles().then((profiles) => {
|
|
expect(profiles).to.deep.equal(new Map([['default', { accessKeyId, secretAccessKey }]]));
|
|
});
|
|
expect(context.stepHistory.valuesMap()).to.deep.equal(
|
|
new Map([
|
|
['credentialsSetupChoice', '_local_'],
|
|
['createAwsAccountPrompt', '_continuation_'],
|
|
['generateAwsCredsPrompt', '_continuation_'],
|
|
['accessKeyId', '_user_input_'],
|
|
['secretAccessKey', '_user_input_'],
|
|
])
|
|
);
|
|
});
|
|
|
|
it('Should setup credentials for users having an AWS account', async () => {
|
|
configureInquirerStub(inquirer, {
|
|
list: { credentialsSetupChoice: '_local_' },
|
|
confirm: { hasAwsAccount: true },
|
|
input: { generateAwsCredsPrompt: '', accessKeyId, secretAccessKey },
|
|
});
|
|
const context = {
|
|
configuration: { provider: {} },
|
|
options: {},
|
|
stepHistory: new StepHistory(),
|
|
};
|
|
await step.run(context);
|
|
expect(openBrowserUrls.length).to.equal(1);
|
|
expect(openBrowserUrls[0].includes('console.aws.amazon.com')).to.be.true;
|
|
expect(context.stepHistory.valuesMap()).to.deep.equal(
|
|
new Map([
|
|
['credentialsSetupChoice', '_local_'],
|
|
['generateAwsCredsPrompt', '_continuation_'],
|
|
['accessKeyId', '_user_input_'],
|
|
['secretAccessKey', '_user_input_'],
|
|
])
|
|
);
|
|
return resolveFileProfiles().then((profiles) => {
|
|
expect(profiles).to.deep.equal(new Map([['default', { accessKeyId, secretAccessKey }]]));
|
|
});
|
|
});
|
|
|
|
it('Should not accept invalid access key id', async () => {
|
|
configureInquirerStub(inquirer, {
|
|
list: { credentialsSetupChoice: '_local_' },
|
|
confirm: { hasAwsAccount: true },
|
|
input: { generateAwsCredsPrompt: '', accessKeyId: 'foo', secretAccessKey },
|
|
});
|
|
const context = {
|
|
configuration: { provider: {} },
|
|
options: {},
|
|
stepHistory: new StepHistory(),
|
|
};
|
|
await expect(step.run(context)).to.eventually.be.rejected.and.have.property(
|
|
'code',
|
|
'INVALID_ANSWER'
|
|
);
|
|
expect(context.stepHistory.valuesMap()).to.deep.equal(
|
|
new Map([
|
|
['credentialsSetupChoice', '_local_'],
|
|
['generateAwsCredsPrompt', '_continuation_'],
|
|
['accessKeyId', undefined],
|
|
])
|
|
);
|
|
});
|
|
|
|
it('Should not accept invalid secret access key', async () => {
|
|
configureInquirerStub(inquirer, {
|
|
list: { credentialsSetupChoice: '_local_' },
|
|
confirm: { hasAwsAccount: true },
|
|
input: { generateAwsCredsPrompt: '', accessKeyId, secretAccessKey: 'foo' },
|
|
});
|
|
const context = {
|
|
configuration: { provider: {} },
|
|
options: {},
|
|
stepHistory: new StepHistory(),
|
|
};
|
|
await expect(step.run(context)).to.eventually.be.rejected.and.have.property(
|
|
'code',
|
|
'INVALID_ANSWER'
|
|
);
|
|
expect(context.stepHistory.valuesMap()).to.deep.equal(
|
|
new Map([
|
|
['credentialsSetupChoice', '_local_'],
|
|
['generateAwsCredsPrompt', '_continuation_'],
|
|
['accessKeyId', '_user_input_'],
|
|
['secretAccessKey', undefined],
|
|
])
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('Provider config handling', () => {
|
|
it('Should correctly setup with newly created provider when no previous providers exist', async () => {
|
|
const mockedOpenBrowser = sinon.stub().returns();
|
|
const mockedDisconnect = sinon.stub().returns();
|
|
const mockedCreateProviderLink = sinon.stub().resolves();
|
|
const providerUid = 'provideruid';
|
|
const internalMockedSdk = {
|
|
...mockedSdk,
|
|
connect: ({ onEvent }) => {
|
|
onEvent({
|
|
data: {
|
|
object: {
|
|
provider_uid: providerUid,
|
|
},
|
|
},
|
|
});
|
|
},
|
|
disconnect: mockedDisconnect,
|
|
createProviderLink: mockedCreateProviderLink,
|
|
};
|
|
const mockedStep = proxyquire('../../../../../lib/cli/interactive-setup/aws-credentials', {
|
|
'@serverless/dashboard-plugin/lib/clientUtils': {
|
|
getPlatformClientWithAccessKey: async () => internalMockedSdk,
|
|
},
|
|
'../../utils/openBrowser': mockedOpenBrowser,
|
|
'@serverless/dashboard-plugin/lib/isAuthenticated': () => true,
|
|
});
|
|
|
|
configureInquirerStub(inquirer, {
|
|
list: { credentialsSetupChoice: '_create_provider_' },
|
|
});
|
|
|
|
let stdoutData = '';
|
|
const context = {
|
|
serviceDir: process.cwd(),
|
|
configuration: {
|
|
service: 'someservice',
|
|
provider: { name: 'aws' },
|
|
org: 'someorg',
|
|
app: 'someapp',
|
|
},
|
|
options: {},
|
|
configurationFilename: 'serverless.yml',
|
|
stepHistory: new StepHistory(),
|
|
};
|
|
await overrideStdoutWrite(
|
|
(data) => (stdoutData += data),
|
|
async () => await mockedStep.run(context)
|
|
);
|
|
|
|
expect(stdoutData).to.include('AWS Access Role provider was successfully created');
|
|
expect(mockedOpenBrowser).to.have.been.calledWith(
|
|
chalk.bold.white(
|
|
'https://app.serverless.com/someorg/settings/providers?source=cli&providerId=new&provider=aws'
|
|
)
|
|
);
|
|
expect(mockedDisconnect).to.have.been.called;
|
|
expect(mockedCreateProviderLink).not.to.have.been.called;
|
|
expect(context.stepHistory.valuesMap()).to.deep.equal(
|
|
new Map([['credentialsSetupChoice', '_create_provider_']])
|
|
);
|
|
});
|
|
|
|
it('Should correctly setup with newly created provider when previous providers exist', async () => {
|
|
const mockedOpenBrowser = sinon.stub().returns();
|
|
const mockedDisconnect = sinon.stub().returns();
|
|
const mockedCreateProviderLink = sinon.stub().resolves();
|
|
const providerUid = 'provideruid';
|
|
const internalMockedSdk = {
|
|
...mockedSdk,
|
|
connect: ({ onEvent }) => {
|
|
onEvent({
|
|
data: {
|
|
object: {
|
|
provider_uid: providerUid,
|
|
},
|
|
},
|
|
});
|
|
},
|
|
getProviders: async () => {
|
|
return {
|
|
result: [
|
|
{
|
|
alias: 'someprovider',
|
|
providerName: 'aws',
|
|
providerType: 'roleArn',
|
|
providerUid,
|
|
providerDetails: {
|
|
roleArn: 'arn:xxx',
|
|
},
|
|
},
|
|
],
|
|
};
|
|
},
|
|
disconnect: mockedDisconnect,
|
|
createProviderLink: mockedCreateProviderLink,
|
|
};
|
|
const mockedStep = proxyquire('../../../../../lib/cli/interactive-setup/aws-credentials', {
|
|
'@serverless/dashboard-plugin/lib/clientUtils': {
|
|
getPlatformClientWithAccessKey: async () => internalMockedSdk,
|
|
},
|
|
'../../utils/openBrowser': mockedOpenBrowser,
|
|
'@serverless/dashboard-plugin/lib/isAuthenticated': () => true,
|
|
});
|
|
|
|
configureInquirerStub(inquirer, {
|
|
list: { credentialsSetupChoice: '_create_provider_' },
|
|
});
|
|
|
|
const context = {
|
|
serviceDir: process.cwd(),
|
|
configuration: {
|
|
service: 'someservice',
|
|
provider: { name: 'aws' },
|
|
org: 'someorg',
|
|
app: 'someapp',
|
|
},
|
|
options: {},
|
|
configurationFilename: 'serverless.yml',
|
|
stepHistory: new StepHistory(),
|
|
};
|
|
let stdoutData = '';
|
|
await overrideStdoutWrite(
|
|
(data) => (stdoutData += data),
|
|
async () => await mockedStep.run(context)
|
|
);
|
|
|
|
expect(stdoutData).to.include('AWS Access Role provider was successfully created');
|
|
expect(mockedOpenBrowser).to.have.been.calledWith(
|
|
chalk.bold.white(
|
|
'https://app.serverless.com/someorg/settings/providers?source=cli&providerId=new&provider=aws'
|
|
)
|
|
);
|
|
expect(mockedDisconnect).to.have.been.called;
|
|
expect(mockedCreateProviderLink).to.have.been.calledWith(
|
|
'org-uid',
|
|
'instance',
|
|
'appName|someapp|serviceName|someservice|stage|dev|region|us-east-1',
|
|
providerUid
|
|
);
|
|
expect(context.stepHistory.valuesMap()).to.deep.equal(
|
|
new Map([['credentialsSetupChoice', '_create_provider_']])
|
|
);
|
|
});
|
|
|
|
it('Should emit warning when dashboard unavailable when connecting to it', async () => {
|
|
const mockedOpenBrowser = sinon.stub().returns();
|
|
const internalMockedSdk = {
|
|
...mockedSdk,
|
|
connect: () => {
|
|
const err = new Error('error');
|
|
err.statusCode = 500;
|
|
throw err;
|
|
},
|
|
};
|
|
const mockedStep = proxyquire('../../../../../lib/cli/interactive-setup/aws-credentials', {
|
|
'@serverless/dashboard-plugin/lib/clientUtils': {
|
|
getPlatformClientWithAccessKey: async () => internalMockedSdk,
|
|
},
|
|
'../../utils/openBrowser': mockedOpenBrowser,
|
|
});
|
|
|
|
configureInquirerStub(inquirer, {
|
|
list: { credentialsSetupChoice: '_create_provider_' },
|
|
});
|
|
|
|
const context = {
|
|
serviceDir: process.cwd(),
|
|
configuration: {
|
|
service: 'someservice',
|
|
provider: { name: 'aws' },
|
|
org: 'someorg',
|
|
app: 'someapp',
|
|
},
|
|
configurationFilename: 'serverless.yml',
|
|
stepHistory: new StepHistory(),
|
|
};
|
|
let stdoutData = '';
|
|
await overrideStdoutWrite(
|
|
(data) => (stdoutData += data),
|
|
async () => await mockedStep.run(context)
|
|
);
|
|
|
|
expect(stdoutData).to.include('Dashboard service is currently unavailable');
|
|
expect(mockedOpenBrowser).to.have.been.calledWith(
|
|
chalk.bold.white(
|
|
'https://app.serverless.com/someorg/settings/providers?source=cli&providerId=new&provider=aws'
|
|
)
|
|
);
|
|
expect(context.stepHistory.valuesMap()).to.deep.equal(
|
|
new Map([['credentialsSetupChoice', '_create_provider_']])
|
|
);
|
|
});
|
|
|
|
it('Should correctly setup with existing provider', async () => {
|
|
const providerUid = 'provideruid';
|
|
const mockedCreateProviderLink = sinon.stub().resolves();
|
|
const internalMockedSdk = {
|
|
...mockedSdk,
|
|
getProviders: async () => {
|
|
return {
|
|
result: [
|
|
{
|
|
alias: 'someprovider',
|
|
providerName: 'aws',
|
|
providerType: 'accessKey',
|
|
providerUid,
|
|
providerDetails: {
|
|
accessKeyId: 'axx',
|
|
},
|
|
},
|
|
],
|
|
};
|
|
},
|
|
createProviderLink: mockedCreateProviderLink,
|
|
};
|
|
const mockedStep = proxyquire('../../../../../lib/cli/interactive-setup/aws-credentials', {
|
|
'@serverless/dashboard-plugin/lib/clientUtils': {
|
|
getPlatformClientWithAccessKey: async () => internalMockedSdk,
|
|
},
|
|
});
|
|
|
|
configureInquirerStub(inquirer, {
|
|
list: { credentialsSetupChoice: providerUid },
|
|
});
|
|
|
|
const context = {
|
|
serviceDir: process.cwd(),
|
|
configuration: {
|
|
service: 'someservice',
|
|
provider: { name: 'aws' },
|
|
org: 'someorg',
|
|
app: 'someapp',
|
|
},
|
|
options: {},
|
|
configurationFilename: 'serverless.yml',
|
|
stepHistory: new StepHistory(),
|
|
};
|
|
let stdoutData = '';
|
|
await overrideStdoutWrite(
|
|
(data) => (stdoutData += data),
|
|
async () => await mockedStep.run(context)
|
|
);
|
|
|
|
expect(mockedCreateProviderLink).to.have.been.calledWith(
|
|
'org-uid',
|
|
'instance',
|
|
'appName|someapp|serviceName|someservice|stage|dev|region|us-east-1',
|
|
'provideruid'
|
|
);
|
|
expect(stdoutData).to.include('Selected provider was successfully linked');
|
|
expect(context.stepHistory.valuesMap()).to.deep.equal(
|
|
new Map([['credentialsSetupChoice', '_user_choice_']])
|
|
);
|
|
});
|
|
|
|
it('Should emit a warning when dashboard is not available and link cannot be created', async () => {
|
|
const providerUid = 'provideruid';
|
|
const mockedCreateProviderLink = sinon.stub().callsFake(async () => {
|
|
const err = new Error('error');
|
|
err.statusCode = 500;
|
|
throw err;
|
|
});
|
|
const internalMockedSdk = {
|
|
...mockedSdk,
|
|
getProviders: async () => {
|
|
return {
|
|
result: [
|
|
{
|
|
alias: 'someprovider',
|
|
providerName: 'aws',
|
|
providerType: 'roleArn',
|
|
providerUid,
|
|
providerDetails: {
|
|
roleArn: 'arn:xxx',
|
|
},
|
|
},
|
|
],
|
|
};
|
|
},
|
|
createProviderLink: mockedCreateProviderLink,
|
|
};
|
|
const mockedStep = proxyquire('../../../../../lib/cli/interactive-setup/aws-credentials', {
|
|
'@serverless/dashboard-plugin/lib/clientUtils': {
|
|
getPlatformClientWithAccessKey: async () => internalMockedSdk,
|
|
},
|
|
});
|
|
|
|
configureInquirerStub(inquirer, {
|
|
list: { credentialsSetupChoice: providerUid },
|
|
});
|
|
|
|
const context = {
|
|
serviceDir: process.cwd(),
|
|
configuration: {
|
|
service: 'someservice',
|
|
provider: { name: 'aws' },
|
|
org: 'someorg',
|
|
app: 'someapp',
|
|
},
|
|
options: {},
|
|
stepHistory: new StepHistory(),
|
|
configurationFilename: 'serverless.yml',
|
|
};
|
|
let stdoutData = '';
|
|
await overrideStdoutWrite(
|
|
(data) => (stdoutData += data),
|
|
async () => await mockedStep.run(context)
|
|
);
|
|
|
|
expect(stdoutData).to.include(
|
|
'Dashboard service is currently unavailable, please try again later'
|
|
);
|
|
expect(stdoutData).not.to.include('Selected provider was successfully linked');
|
|
expect(mockedCreateProviderLink).to.have.been.calledWith(
|
|
'org-uid',
|
|
'instance',
|
|
'appName|someapp|serviceName|someservice|stage|dev|region|us-east-1',
|
|
'provideruid'
|
|
);
|
|
|
|
expect(context.stepHistory.valuesMap()).to.deep.equal(
|
|
new Map([['credentialsSetupChoice', '_user_choice_']])
|
|
);
|
|
});
|
|
|
|
it('Should emit a warning when dashboard is not available when fetching providers', async () => {
|
|
const internalMockedSdk = {
|
|
...mockedSdk,
|
|
getProviders: async () => {
|
|
const err = new Error('unavailable');
|
|
err.statusCode = 500;
|
|
throw err;
|
|
},
|
|
};
|
|
const mockedStep = proxyquire('../../../../../lib/cli/interactive-setup/aws-credentials', {
|
|
'@serverless/dashboard-plugin/lib/clientUtils': {
|
|
getPlatformClientWithAccessKey: async () => internalMockedSdk,
|
|
},
|
|
'@serverless/dashboard-plugin/lib/isAuthenticated': () => true,
|
|
});
|
|
|
|
let stdoutData = '';
|
|
await overrideStdoutWrite(
|
|
(data) => (stdoutData += data),
|
|
async () =>
|
|
await mockedStep.run({
|
|
serviceDir: process.cwd(),
|
|
configuration: { provider: { name: 'aws' }, org: 'someorg' },
|
|
options: {},
|
|
configurationFilename: 'serverless.yml',
|
|
})
|
|
);
|
|
|
|
expect(stdoutData).to.include('Dashboard service is currently unavailable');
|
|
});
|
|
});
|
|
});
|