// Mock external modules by default jest.mock('@actions/core'); jest.mock('@actions/tool-cache'); // Mock Node.js core modules jest.mock('os'); const os = require('os'); const path = require('path'); const fs = require('fs').promises; const io = require('@actions/io'); const core = require('@actions/core'); const tc = require('@actions/tool-cache'); const nock = require('nock'); const json = require('./index.json'); const setup = require('../lib/setup-terraform'); // Overwrite defaults // core.debug = jest // .fn(console.log); // core.error = jest // .fn(console.error); describe('Setup Terraform', () => { const HOME = process.env.HOME; const APPDATA = process.env.APPDATA; beforeEach(() => { process.env.HOME = '/tmp/asdf'; process.env.APPDATA = '/tmp/asdf'; }); afterEach(async () => { await io.rmRF(process.env.HOME); process.env.HOME = HOME; process.env.APPDATA = APPDATA; }); test('gets specific version and adds token and hostname on linux, amd64', async () => { const version = '0.1.1'; const credentialsHostname = 'app.terraform.io'; const credentialsToken = 'asdfjkl'; core.getInput = jest .fn() .mockReturnValueOnce(version) .mockReturnValueOnce(credentialsHostname) .mockReturnValueOnce(credentialsToken); tc.downloadTool = jest .fn() .mockReturnValueOnce('file.zip'); tc.extractZip = jest .fn() .mockReturnValueOnce('file'); os.platform = jest .fn() .mockReturnValue('linux'); os.arch = jest .fn() .mockReturnValue('amd64'); nock('https://releases.hashicorp.com') .get('/terraform/index.json') .reply(200, json); await setup(); // downloaded CLI has been added to path expect(core.addPath).toHaveBeenCalled(); // expect credentials are in ${HOME}.terraformrc const creds = await fs.readFile(`${process.env.HOME}/.terraformrc`, { encoding: 'utf8' }); expect(creds.indexOf(credentialsHostname)).toBeGreaterThan(-1); expect(creds.indexOf(credentialsToken)).toBeGreaterThan(-1); }); test('gets specific version and adds token and hostname on windows, 386', async () => { const version = '0.1.1'; const credentialsHostname = 'app.terraform.io'; const credentialsToken = 'asdfjkl'; core.getInput = jest .fn() .mockReturnValueOnce(version) .mockReturnValueOnce(credentialsHostname) .mockReturnValueOnce(credentialsToken); tc.downloadTool = jest .fn() .mockReturnValueOnce('file.zip'); tc.extractZip = jest .fn() .mockReturnValueOnce('file'); os.platform = jest .fn() .mockReturnValue('win32'); os.arch = jest .fn() .mockReturnValue('386'); nock('https://releases.hashicorp.com') .get('/terraform/index.json') .reply(200, json); await setup(); // downloaded CLI has been added to path expect(core.addPath).toHaveBeenCalled(); // expect credentials are in ${HOME}.terraformrc const creds = await fs.readFile(`${process.env.HOME}/terraform.rc`, { encoding: 'utf8' }); expect(creds.indexOf(credentialsHostname)).toBeGreaterThan(-1); expect(creds.indexOf(credentialsToken)).toBeGreaterThan(-1); }); test('gets latest version and adds token and hostname on linux, amd64', async () => { const version = 'latest'; const credentialsHostname = 'app.terraform.io'; const credentialsToken = 'asdfjkl'; core.getInput = jest .fn() .mockReturnValueOnce(version) .mockReturnValueOnce(credentialsHostname) .mockReturnValueOnce(credentialsToken); tc.downloadTool = jest .fn() .mockReturnValueOnce('file.zip'); tc.extractZip = jest .fn() .mockReturnValueOnce('file'); os.platform = jest .fn() .mockReturnValue('linux'); os.arch = jest .fn() .mockReturnValue('amd64'); nock('https://releases.hashicorp.com') .get('/terraform/index.json') .reply(200, json); await setup(); // downloaded CLI has been added to path expect(core.addPath).toHaveBeenCalled(); // expect credentials are in ${HOME}.terraformrc const creds = await fs.readFile(`${process.env.HOME}/.terraformrc`, { encoding: 'utf8' }); expect(creds.indexOf(credentialsHostname)).toBeGreaterThan(-1); expect(creds.indexOf(credentialsToken)).toBeGreaterThan(-1); }); test('fails when metadata cannot be downloaded', async () => { const version = 'latest'; const credentialsHostname = 'app.terraform.io'; const credentialsToken = 'asdfjkl'; core.getInput = jest .fn() .mockReturnValueOnce(version) .mockReturnValueOnce(credentialsHostname) .mockReturnValueOnce(credentialsToken); nock('https://releases.hashicorp.com') .get('/terraform/index.json') .reply(404); try { await setup(); } catch (e) { expect(core.error).toHaveBeenCalled(); } }); test('fails when specific version cannot be found', async () => { const version = '0.9.9'; const credentialsHostname = 'app.terraform.io'; const credentialsToken = 'asdfjkl'; core.getInput = jest .fn() .mockReturnValueOnce(version) .mockReturnValueOnce(credentialsHostname) .mockReturnValueOnce(credentialsToken); nock('https://releases.hashicorp.com') .get('/terraform/index.json') .reply(200, json); try { await setup(); } catch (e) { expect(core.error).toHaveBeenCalled(); } }); test('fails when CLI for os and architecture cannot be found', async () => { const version = '0.1.1'; const credentialsHostname = 'app.terraform.io'; const credentialsToken = 'asdfjkl'; core.getInput = jest .fn() .mockReturnValueOnce(version) .mockReturnValueOnce(credentialsHostname) .mockReturnValueOnce(credentialsToken); nock('https://releases.hashicorp.com') .get('/terraform/index.json') .reply(200, json); tc.downloadTool = jest .fn() .mockReturnValueOnce('file.zip'); tc.extractZip = jest .fn() .mockReturnValueOnce('file'); os.platform = jest .fn() .mockReturnValue('madeupplat'); os.arch = jest .fn() .mockReturnValue('madeuparch'); try { await setup(); } catch (e) { expect(core.error).toHaveBeenCalled(); } }); test('fails when CLI cannot be downloaded', async () => { const version = '0.1.1'; const credentialsHostname = 'app.terraform.io'; const credentialsToken = 'asdfjkl'; core.getInput = jest .fn() .mockReturnValueOnce(version) .mockReturnValueOnce(credentialsHostname) .mockReturnValueOnce(credentialsToken); nock('https://releases.hashicorp.com') .get('/terraform/index.json') .reply(200, json); tc.downloadTool = jest .fn() .mockReturnValueOnce(''); tc.extractZip = jest .fn() .mockReturnValueOnce(''); os.platform = jest .fn() .mockReturnValue('linux'); os.arch = jest .fn() .mockReturnValue('amd64'); try { await setup(); } catch (e) { expect(core.error).toHaveBeenCalled(); } }); test('installs wrapper on linux', async () => { const version = '0.1.1'; const credentialsHostname = 'app.terraform.io'; const credentialsToken = 'asdfjkl'; const wrapperPath = path.resolve([__dirname, '..', 'wrapper', 'dist', 'index.js'].join(path.sep)); const ioMv = jest.spyOn(io, 'mv') .mockImplementation(() => {}); const ioCp = jest.spyOn(io, 'cp') .mockImplementation(() => {}); core.getInput = jest .fn() .mockReturnValueOnce(version) .mockReturnValueOnce(credentialsHostname) .mockReturnValueOnce(credentialsToken) .mockReturnValueOnce('true'); tc.downloadTool = jest .fn() .mockReturnValueOnce('file.zip'); tc.extractZip = jest .fn() .mockReturnValueOnce('file'); os.platform = jest .fn() .mockReturnValue('linux'); os.arch = jest .fn() .mockReturnValue('amd64'); nock('https://releases.hashicorp.com') .get('/terraform/index.json') .reply(200, json); await setup(); expect(ioMv).toHaveBeenCalledWith(`file${path.sep}terraform`, `file${path.sep}terraform-bin`); expect(ioCp).toHaveBeenCalledWith(wrapperPath, `file${path.sep}terraform`); }); test('installs wrapper on windows', async () => { const version = '0.1.1'; const credentialsHostname = 'app.terraform.io'; const credentialsToken = 'asdfjkl'; const wrapperPath = path.resolve([__dirname, '..', 'wrapper', 'dist', 'index.js'].join(path.sep)); const ioMv = jest.spyOn(io, 'mv') .mockImplementation(() => {}); const ioCp = jest.spyOn(io, 'cp') .mockImplementation(() => {}); core.getInput = jest .fn() .mockReturnValueOnce(version) .mockReturnValueOnce(credentialsHostname) .mockReturnValueOnce(credentialsToken) .mockReturnValueOnce('true'); tc.downloadTool = jest .fn() .mockReturnValueOnce('file.zip'); tc.extractZip = jest .fn() .mockReturnValueOnce('file'); os.platform = jest .fn() .mockReturnValue('win32'); os.arch = jest .fn() .mockReturnValue('386'); nock('https://releases.hashicorp.com') .get('/terraform/index.json') .reply(200, json); await setup(); expect(ioMv).toHaveBeenCalledWith(`file${path.sep}terraform.exe`, `file${path.sep}terraform-bin.exe`); expect(ioCp).toHaveBeenCalledWith(wrapperPath, `file${path.sep}terraform`); }); });