Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### Fixes

- [#2462: Update from inquirer 8.2.6 to @inquirer/confirm 5.1.15 to address a vulnerability in tmp](https://github.com/alphagov/govuk-prototype-kit/pull/2462)

## 13.18.0

### New features
Expand Down
19 changes: 10 additions & 9 deletions lib/usage-data.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const os = require('os')
const path = require('path')

// npm dependencies
const inquirer = require('inquirer')
const { default: confirm } = require('@inquirer/confirm')
const universalAnalytics = require('universal-analytics')
const { v4: uuidv4 } = require('uuid')
const ansiColors = require('ansi-colors')
Expand Down Expand Up @@ -50,14 +50,15 @@ function setUsageDataConfig (usageDataConfig) {

// Ask for permission to track data
// returns a Promise with the user's answer
function askForUsageDataPermission () {
return inquirer.prompt([{
name: 'usageData',
message: USAGE_DATA_PROMPT,
type: 'confirm',
when: () => process.stdout.isTTY,
default: false
}]).then(answers => answers.usageData)
async function askForUsageDataPermission () {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note Using async ensures the function returns a Promise if the if block doesn't run. This is not critical as the code calling askForUsageForDataPermission is called with an await rather than using .then, but better safe than sorry.

.then would throw if askForUsageDataPermission returned undefined while await will happily use undefined as a return value on the next tick of the event loop.

if (process.stdout.isTTY) {
return confirm({
message: USAGE_DATA_PROMPT,
default: false
})
}

return false
}

function startTracking (usageDataConfig) {
Expand Down
77 changes: 77 additions & 0 deletions lib/usage-data.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
const { askForUsageDataPermission } = require('./usage-data')

jest.mock('@inquirer/confirm')

const { default: confirm } = require('@inquirer/confirm')

describe('askForUsageDataPermission', () => {
afterEach(() => {
jest.resetAllMocks()
})

describe('when in an interactive shell', () => {
// We can't use jest.replaceProperty here because in a non-TTY environment
// the isTTY property doesn't exist on process.stdout, and Jest will only
// replace existing properties.
let originalTTY

beforeAll(() => {
originalTTY = process.stdout.isTTY
process.stdout.isTTY = true
})

afterAll(() => {
process.stdout.isTTY = originalTTY
})

it('asks the user for confirmation', () => {
askForUsageDataPermission()

expect(confirm).toHaveBeenCalledTimes(1)
expect(confirm).toHaveBeenCalledWith({
default: false,
message: expect.stringContaining(
'Do you give permission for the kit to send anonymous usage data?'
)
})
})

it('returns true if the user accepts tracking', async () => {
confirm.mockResolvedValue(true)

expect(await askForUsageDataPermission()).toBe(true)
})

it('returns false if the user does not accept tracking', async () => {
confirm.mockResolvedValue(false)

expect(await askForUsageDataPermission()).toBe(false)
})
})

describe('when in a non-interactive shell', () => {
// We can't use jest.replaceProperty here because in a non-TTY environment
// the isTTY property doesn't exist on process.stdout, and Jest will only
// replace existing properties.
let originalTTY

beforeAll(() => {
originalTTY = process.stdout.isTTY
process.stdout.isTTY = undefined
})

afterAll(() => {
process.stdout.isTTY = originalTTY
})

it('does not ask the user for confirmation', () => {
askForUsageDataPermission()

expect(confirm).not.toHaveBeenCalled()
})

it('returns false', async () => {
expect(await askForUsageDataPermission()).toBe(false)
})
})
})
12 changes: 5 additions & 7 deletions lib/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const semver = require('semver')
const { existsSync } = require('fs')

// npm dependencies
const inquirer = require('inquirer')
const { default: confirm } = require('@inquirer/confirm')
const portScanner = require('portscanner')
const { marked } = require('marked')

Expand Down Expand Up @@ -108,12 +108,10 @@ function findAvailablePort (callback) {
console.error('ERROR: Port ' + port + ' in use - you may have another prototype running.\n')

// Ask user if they want to change port
inquirer.prompt([{
name: 'changePort',
message: 'Change to an available port?',
type: 'confirm'
}]).then(answers => {
if (answers.changePort) {
confirm({
message: 'Change to an available port?'
}).then(changePort => {
if (changePort) {
// User answers yes
port = availablePort

Expand Down
Loading
Loading