Skip to content

Commit

Permalink
[Fix] (Workbox wizard) Manually enter the path of the web app root an…
Browse files Browse the repository at this point in the history
…d unselectable separator (#2766)

* fix: 🐛 workbox-cli ask root of web app question

Make separator unselectable as an answer to root of web application
question when multiple child directories are present. Fix the manual
input to root of the web application question - when manual input option
is chosen a new question / input will be provided to the user to specify
the root of the web app.

✅ Closes: #2764

* test: 💍 workbox-cli ask root of web app question

Extend upon the existing workbox-cli ask root of web app question with
additional unit tests.

✅ Closes: #2764

* chore: 🤖 workbox-cli root web app question variable naming

workbox-cli package, rename `root of the web application` question
variable names to use camelcase naming pattern instead of snake case
format.

✅ Closes: #2766
  • Loading branch information
ognjenjevremovic authored Mar 10, 2021
1 parent 5a2d509 commit 2c8bfe7
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 23 deletions.
39 changes: 20 additions & 19 deletions packages/workbox-cli/src/lib/questions/ask-root-of-web-app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ import {constants} from '../constants';

const ROOT_PROMPT = 'Please enter the path to the root of your web app:';

// The key used for the question/answer.
const name = 'globDirectory';
// The keys used for the questions/answers.
const questionRootDirectory = 'globDirectory';
const questionManualInput = 'manualDirectoryInput';

/**
* @return {Promise<Array<string>>} The subdirectories of the current
Expand All @@ -41,44 +42,44 @@ async function getSubdirectories(): Promise<Array<string>> {
/**
* @return {Promise<Object>} The answers from inquirer.
*/
async function askQuestion() {
const subdirectories = await getSubdirectories();
async function askQuestion(): Promise<{ globDirectory: string; manualDirectoryInput?: string }> {
const subdirectories: (string | InstanceType<typeof Separator>)[] = await getSubdirectories();

if (subdirectories.length > 0) {
const manualEntryChoice = 'Manually enter path';
return prompt([{
name,
name: questionRootDirectory,
type: 'list',
message: ol`What is the root of your web app (i.e. which directory do
you deploy)?`,
choices: subdirectories.concat([
new Separator().toString(),
new Separator(),
manualEntryChoice,
]),
}, {
name,
when: (answers: { [x: string]: string }) => answers[name] === manualEntryChoice,
name: questionManualInput,
when: (answers: { globDirectory: string }) => answers.globDirectory === manualEntryChoice,
message: ROOT_PROMPT,
}]);
} else {
return prompt([{
name,
message: ROOT_PROMPT,
default: '.',
}]);
}
]);
}

return prompt([{
name: questionRootDirectory,
message: ROOT_PROMPT,
default: '.',
}]);
}

export async function askRootOfWebApp() {
const answers = await askQuestion();
const globDirectory = answers[name];
const { manualDirectoryInput, globDirectory } = await askQuestion();

try {
const stat = await fse.stat(globDirectory);
const stat = await fse.stat(manualDirectoryInput || globDirectory);
assert(stat.isDirectory());
} catch (error) {
throw new Error(errors['glob-directory-invalid']);
}

return globDirectory;
return manualDirectoryInput || globDirectory;
}
120 changes: 116 additions & 4 deletions test/workbox-cli/node/lib/questions/ask-root-of-web-app.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,12 @@ const {errors} = require('../../../../../packages/workbox-cli/build/lib/errors')
const MODULE_PATH = '../../../../../packages/workbox-cli/build/lib/questions/ask-root-of-web-app';
// This is the hardcoded name of the question that's passed to inquirer.
// It's used as the key to read the response from the answer.
const QUESTION_NAME = 'globDirectory';
const questionRootDirectory = 'globDirectory';
const questionManualInput = 'manualDirectoryInput';
const DIRECTORY = '/path/to/directory';
const CHILD_DIRECTORY = '/path/to/directory/child';
const CHILD_DIRECTORY_WHITE_SPACE = '/path/to/directory/ child';
const CHILD_DIRECTORY_BLANK = ' ';

describe(`[workbox-cli] lib/questions/ask-root-of-web-app.js`, function() {
it(`should reject with a 'glob-directory-invalid' error when the answer isn't a valid directory`, async function() {
Expand All @@ -24,7 +28,7 @@ describe(`[workbox-cli] lib/questions/ask-root-of-web-app.js`, function() {
callback(null, []);
},
'inquirer': {
prompt: () => Promise.resolve({[QUESTION_NAME]: DIRECTORY}),
prompt: () => Promise.resolve({[questionRootDirectory]: DIRECTORY}),
},
'fs-extra': {
stat: (path) => {
Expand All @@ -47,13 +51,43 @@ describe(`[workbox-cli] lib/questions/ask-root-of-web-app.js`, function() {
}
});

it(`should resolve with a valid answer to the question`, async function() {
it(`should reject with a 'glob-directory-invalid' error when the manual input is provided (directory does not exist)`, async function() {
const {askRootOfWebApp} = proxyquire(MODULE_PATH, {
'glob': (pattern, config, callback) => {
callback(null, []);
},
'inquirer': {
prompt: () => Promise.resolve({[QUESTION_NAME]: DIRECTORY}),
prompt: () => Promise.resolve({
[questionRootDirectory]: DIRECTORY,
[questionManualInput]: CHILD_DIRECTORY,
}),
},
'fs-extra': {
stat: (path) => {
return {
isDirectory: () => {
return path !== CHILD_DIRECTORY;
},
};
},
},
});

try {
await askRootOfWebApp();
throw new Error('Unexpected success.');
} catch (error) {
expect(error.message).to.eql(errors['glob-directory-invalid']);
}
});

it(`should resolve with a valid answer to the question when no child directories are present (default: use current directory)`, async function() {
const {askRootOfWebApp} = proxyquire(MODULE_PATH, {
'glob': (pattern, config, callback) => {
callback(null, []);
},
'inquirer': {
prompt: () => Promise.resolve({[questionRootDirectory]: DIRECTORY}),
},
'fs-extra': {
stat: (path) => {
Expand All @@ -71,5 +105,83 @@ describe(`[workbox-cli] lib/questions/ask-root-of-web-app.js`, function() {
const answer = await askRootOfWebApp();
expect(answer).to.eql(DIRECTORY);
});

it(`should resolve with a valid answer to the question when manual input is provided (directory exists)`, async function() {
const {askRootOfWebApp} = proxyquire(MODULE_PATH, {
'glob': (pattern, config, callback) => {
callback(null, []);
},
'inquirer': {
prompt: () => Promise.resolve({
[questionRootDirectory]: DIRECTORY,
[questionManualInput]: CHILD_DIRECTORY,
}),
},
'fs-extra': {
stat: (path) => {
return {
isDirectory: () => {
return path === CHILD_DIRECTORY;
},
};
},
},
});

const answer = await askRootOfWebApp();
expect(answer).to.eql(CHILD_DIRECTORY);
});

it(`should resolve with a valid answer to the question when manual input is provided (directory exists and name contains white space)`, async function() {
const {askRootOfWebApp} = proxyquire(MODULE_PATH, {
'glob': (pattern, config, callback) => {
callback(null, []);
},
'inquirer': {
prompt: () => Promise.resolve({
[questionRootDirectory]: DIRECTORY,
[questionManualInput]: CHILD_DIRECTORY_WHITE_SPACE,
}),
},
'fs-extra': {
stat: (path) => {
return {
isDirectory: () => {
return path === CHILD_DIRECTORY_WHITE_SPACE;
},
};
},
},
});

const answer = await askRootOfWebApp();
expect(answer).to.eql(CHILD_DIRECTORY_WHITE_SPACE);
});

it(`should resolve with a valid answer to the question when manual input is provided (directory exists and name is composed of only white space)`, async function() {
const {askRootOfWebApp} = proxyquire(MODULE_PATH, {
'glob': (pattern, config, callback) => {
callback(null, []);
},
'inquirer': {
prompt: () => Promise.resolve({
[questionRootDirectory]: DIRECTORY,
[questionManualInput]: CHILD_DIRECTORY_BLANK,
}),
},
'fs-extra': {
stat: (path) => {
return {
isDirectory: () => {
return path === CHILD_DIRECTORY_BLANK;
},
};
},
},
});

const answer = await askRootOfWebApp();
expect(answer).to.eql(CHILD_DIRECTORY_BLANK);
});
});

0 comments on commit 2c8bfe7

Please sign in to comment.