text: 'use strict';
  
  const { join } = require('path');
  const { homedir: getHomedir } = require('os');
  const { expect } = require('chai');
  const sinon = require('sinon');
  const BbPromise = require('bluebird');
  const { remove: rmDir, lstat, outputFile: writeFile } = require('fs-extra');
  const { resolveFileProfiles } = require('../aws/utils/credentials');
  const inquirer = require('@serverless/inquirer');
  const configureInquirerStub = require('@serverless/test/configure-inquirer-stub');
  const runServerless = require('../../../test/utils/run-serverless');
  
  const fixturesPath = join(__dirname, 'test/fixtures');
  const lifecycleHookNamesBlacklist = [
    'before:interactiveCli:setupAws',
    'interactiveCli:initializeService',
    'interactiveCli:tabCompletion',
  ];
  
  const openBrowserUrls = [];
  const modulesCacheStub = {
    [require.resolve('../../utils/openBrowser')]: url =>
      BbPromise.try(() => {
        openBrowserUrls.push(url);
      }),
    // Ensure to rely on same inquirer module that we mock in tests
    [require.resolve('@serverless/inquirer')]: inquirer,
  };
  
  describe('interactiveCli: setupAws', () => {
    const awsProjectPath = join(fixturesPath, 'some-aws-service');
    const accessKeyId = 'AKIAIOSFODNN7EXAMPLE';
    const secretAccessKey = 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY';
    let backupIsTTY;
  
    before(() => {
      backupIsTTY = process.stdin.isTTY;
      process.stdin.isTTY = true;
    });
    after(() => (process.stdin.isTTY = backupIsTTY));
  
    afterEach(() => {
      openBrowserUrls.length = 0;
      sinon.restore();
    });
  
    it('Should be ineffective, when not at service path', () =>
      runServerless({
        cwd: fixturesPath,
        lifecycleHookNamesBlacklist,
      }));
  
    it('Should be ineffective, when not at AWS service', () =>
      runServerless({
        cwd: join(fixturesPath, 'some-other-service'),
        lifecycleHookNamesBlacklist,
      }));
  
    it('Should be ineffective, when credentials are set in environment', () =>
      runServerless({
        cwd: awsProjectPath,
        env: { AWS_ACCESS_KEY_ID: accessKeyId, AWS_SECRET_ACCESS_KEY: secretAccessKey },
        lifecycleHookNamesBlacklist,
      }));
  
    it("Should not setup if user doesn't the setup", () => {
      configureInquirerStub(inquirer, { confirm: { shouldSetupAwsCredentials: false } });
      return runServerless({
        cwd: awsProjectPath,
        lifecycleHookNamesBlacklist,
      });
    });
  
    describe('AWS config handling', () => {
      const credentialsDirPath = join(getHomedir(), '.aws');
      const credentialsFilePath = join(credentialsDirPath, 'credentials');
  
      before(() => {
        // Abort if credentials are found in home directory
        // (it should not be the case, as home directory is mocked to point temp dir)
        return lstat(credentialsDirPath).then(
          () => {
            throw new Error('Unexpected ~/.aws directory, related tests aborted');
          },
          error => {
            if (error.code === 'ENOENT') return;
            throw error;
          }
        );
      });
  
      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', () =>
          runServerless({
            cwd: awsProjectPath,
            lifecycleHookNamesBlacklist,
          }));
      });
  
      it('Should setup credentials for users not having an AWS account', () => {
        configureInquirerStub(inquirer, {
          confirm: { shouldSetupAwsCredentials: true, hasAwsAccount: false },
          input: {
            createAwsAccountPrompt: '',
            generateAwsCredsPrompt: '',
            accessKeyId,
            secretAccessKey,
          },
        });
        return runServerless({
          cwd: awsProjectPath,
          lifecycleHookNamesBlacklist,
          modulesCacheStub,
        }).then(() => {
          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;
          return resolveFileProfiles().then(profiles => {
            expect(profiles).to.deep.equal(new Map([['default', { accessKeyId, secretAccessKey }]]));
          });
        });
      });
  
      it('Should setup credentials for users having an AWS account', () => {
        configureInquirerStub(inquirer, {
          confirm: { shouldSetupAwsCredentials: true, hasAwsAccount: true },
          input: { generateAwsCredsPrompt: '', accessKeyId, secretAccessKey },
        });
        return runServerless({
          cwd: awsProjectPath,
          lifecycleHookNamesBlacklist,
          modulesCacheStub,
        }).then(() => {
          expect(openBrowserUrls.length).to.equal(1);
          expect(openBrowserUrls[0].includes('console.aws.amazon.com')).to.be.true;
          return resolveFileProfiles().then(profiles => {
            expect(profiles).to.deep.equal(new Map([['default', { accessKeyId, secretAccessKey }]]));
          });
        });
      });
  
      it('Should not accept invalid access key id', () => {
        configureInquirerStub(inquirer, {
          confirm: { shouldSetupAwsCredentials: true, hasAwsAccount: true },
          input: { generateAwsCredsPrompt: '', accessKeyId: 'foo', secretAccessKey },
        });
        return runServerless({
          cwd: awsProjectPath,
          lifecycleHookNamesBlacklist,
          modulesCacheStub,
        }).then(
          () => {
            throw new Error('Unexpected');
          },
          error => expect(error.code).to.equal('INVALID_ANSWER')
        );
      });
  
      it('Should not accept invalid secret access key', () => {
        configureInquirerStub(inquirer, {
          confirm: { shouldSetupAwsCredentials: true, hasAwsAccount: true },
          input: { generateAwsCredsPrompt: '', accessKeyId, secretAccessKey: 'foo' },
        });
        return runServerless({
          cwd: awsProjectPath,
          lifecycleHookNamesBlacklist,
          modulesCacheStub,
        }).then(
          () => {
            throw new Error('Unexpected');
          },
          error => expect(error.code).to.equal('INVALID_ANSWER')
        );
      });
    });
  });
  