From e3387c78825f37aadaf170cedf8a932e0abf2324 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20=C3=81ngel=20Garc=C3=ADa?= Date: Mon, 8 Jun 2026 10:12:34 -0700 Subject: [PATCH 1/4] feat(telemetry): make telemetry opt-out with a one-time notice --- README.md | 10 ++--- package.json | 3 +- src/hooks/init.js | 13 +++--- src/telemetry-lib.js | 39 ++++++----------- test/hooks.test.js | 86 ++++++++++++-------------------------- test/index.test.js | 1 - test/telemetry-lib.test.js | 13 ++++++ 7 files changed, 63 insertions(+), 102 deletions(-) diff --git a/README.md b/README.md index 614d421..cd86ede 100644 --- a/README.md +++ b/README.md @@ -43,8 +43,8 @@ When this plugin is hosted by different CLIs: - `aioTelemetry` (optional object in the root `package.json` of the **host CLI** — the same `pjson` oclif passes into the init hook): - `postUrl` (optional string): HTTPS URL of the telemetry proxy that receives POSTed metric batches. Use this when your CLI should send telemetry to a different App Builder action or gateway than the plugin default. - `fetchHeaders`: Optional extra headers merged into telemetry requests (`Content-Type` is always set) - - `productPrivacyPolicyLink`: A link to display to users when prompting to opt in -- `productName`: How to refer to the CLI when the user is prompted to enable telemetry (from `displayName` or `name` in `package.json`) + - `productPrivacyPolicyLink`: A link shown in the one-time telemetry notice (what is collected and how to opt out) +- `productName`: How to refer to the CLI in the telemetry notice (from `displayName` or `name` in `package.json`) - `productBin`: Shown in help text (from `bin` in `package.json`; if several bins exist, the first is used). Example: run `${productBin} telemetry on` ### Overriding the telemetry POST URL @@ -80,7 +80,7 @@ The resolved URL is passed to the flush worker on each telemetry send; it applie Telemetry is suppressed when `AIO_TELEMETRY_DISABLED` is set to one of **`true`**, **`1`**, or **`yes`** (exact match; case-sensitive). Other values such as `0`, `false`, `no`, or an empty string do **not** disable telemetry via this variable. -This does not change the persisted opt-in state. Useful for CI pipelines and scripted environments. +This does not change the persisted opt-out state. Useful for CI pipelines and scripted environments. ```sh AIO_TELEMETRY_DISABLED=true aio app deploy @@ -94,7 +94,7 @@ Telemetry is **best-effort**: events are not persisted when the proxy is down or On **`postrun`**, any in-memory metrics from earlier hooks in the same command are merged with the `postrun` metric and the combined batch is handed off to a **fire-and-forget detached subprocess** (`src/flush-worker.js`). The parent CLI spawns the worker and immediately `unref()`s it, so the CLI can exit without waiting for the HTTP POST. If the POST fails (network error or non-2xx response), the batch is dropped; telemetry must not block or slow normal CLI use. -Non-`postrun` events (for example `command-error`, `telemetry-prompt`) are held in an **in-memory buffer** until that flush. If the process exits before `postrun` (crash, `SIGKILL`), buffered events are lost. The buffer is cleared when telemetry is disabled or when `init` runs again (new command session). +Non-`postrun` events (for example `command-error`, `telemetry-notice`) are held in an **in-memory buffer** until that flush. If the process exits before `postrun` (crash, `SIGKILL`), buffered events are lost. The buffer is cleared when telemetry is disabled or when `init` runs again (new command session). ## Agent detection @@ -122,7 +122,7 @@ To opt into agent tracking without setting a tool-specific variable, set `AIO_IN ## POST data -The `eventData` attribute is always a string. Objects and arrays are stored as a JSON text (e.g. `"{}"`, `"{\"message\":\"…\"}"`). String payloads (such as telemetry prompt outcomes `accepted` / `declined`) are stored as that plain text without an extra layer of JSON quoting. Numbers and booleans use their usual string forms (`"0"`, `"false"`). +The `eventData` attribute is always a string. Objects and arrays are stored as a JSON text (e.g. `"{}"`, `"{\"message\":\"…\"}"`). String payloads (such as the telemetry notice outcome `shown`) are stored as that plain text without an extra layer of JSON quoting. Numbers and booleans use their usual string forms (`"0"`, `"false"`). Example shape of the metric payload: diff --git a/package.json b/package.json index a773fd3..c0fd77b 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,7 @@ "@adobe/aio-lib-core-networking": "^5.0.4", "@oclif/core": "^4", "ci-info": "^4.0.0", - "debug": "^4.1.1", - "inquirer": "^8.2.1" + "debug": "^4.1.1" }, "devDependencies": { "@adobe/eslint-config-aio-lib-config": "5.0.0", diff --git a/src/hooks/init.js b/src/hooks/init.js index f1d0910..c3e68b3 100644 --- a/src/hooks/init.js +++ b/src/hooks/init.js @@ -37,17 +37,16 @@ module.exports = async function (opts) { opts.argv.filter(arg => arg.indexOf('-') === 0).join(','), global.prerunTimer) - // init event does not post telemetry, it stores some info that will be used later - // this will prompt to optIn/Out if telemetry.optIn is undefined + // Telemetry is opt-out (on by default). On the first run we show a one-time, + // non-blocking notice instead of an opt-in prompt. isNull() is true only until the + // notice records the default, so this shows once. if ((opts.argv.indexOf('--no-telemetry') < 0) && !inCI && telemetryLib.isNull()) { - // let's ask! - // unfortunately the `oclif-dev readme` run by prepack fires this event, which hangs CI - // Also we don't prompt for telemetry if the first command is a telemetry command because they - // are probably setting it on or off already + // skip in CI (handled above) and when oclif-dev readme runs (it fires this event); + // also skip for telemetry commands, where the user is already setting state. if (['readme', 'telemetry'].indexOf(opts.id) < 0) { - return telemetryLib.prompt(productName, binName, opts?.config?.pjson?.aioTelemetry?.productPrivacyPolicyLink) + telemetryLib.notice(productName, binName, opts?.config?.pjson?.aioTelemetry?.productPrivacyPolicyLink) } } } diff --git a/src/telemetry-lib.js b/src/telemetry-lib.js index 51c83c0..e4ca2c8 100644 --- a/src/telemetry-lib.js +++ b/src/telemetry-lib.js @@ -14,7 +14,6 @@ const path = require('path') const os = require('os') const config = require('@adobe/aio-lib-core-config') -const inquirer = require('inquirer') const debug = require('debug')('aio-telemetry:telemetry-lib') /** Adobe I/O App Builder web action that forwards CLI metrics to New Relic (ingest key stays server-side). */ @@ -120,6 +119,12 @@ const getOnMessage = (productName, binName) => { const getOffMessage = (binName) => { return `\nTelemetry is off.\nIf you would like to turn telemetry on, simply run \`${binName} telemetry on\`` } +const getNoticeMessage = (productName, binName, privacyPolicyLink) => { + return `${productName} collects anonymous usage data to help us improve our products. ` + + 'Telemetry is on by default; read what we collect and how it is used here:\n' + + ` ${privacyPolicyLink || defaultPrivacyPolicyLink}\n` + + `To opt out, run \`${binName} telemetry off\` (or set AIO_TELEMETRY_DISABLED=true).` +} /** * Builds the value stored in the metric `eventData` attribute. For `postrun`, an empty object is @@ -276,7 +281,7 @@ module.exports = { config.set(`${configKey}.optOut`, true) }, isEnabled: () => { - return !isDisabledForCommand && !isEnvTelemetryDisabled() && config.get(`${configKey}.optOut`, 'global') === false + return !isDisabledForCommand && !isEnvTelemetryDisabled() && config.get(`${configKey}.optOut`, 'global') !== true }, disableForCommand: () => { isDisabledForCommand = true @@ -296,30 +301,10 @@ module.exports = { }, getOnMessage, getOffMessage, - prompt: async (productName, binName, privacyPolicyLink) => { - console.log(` - How you use ${productName} provides us with important data that we can use - to make our products better. Please read our guide for more information on - the data we anonymously collect, and how we use it. - ${privacyPolicyLink || defaultPrivacyPolicyLink} - `) - - const response = await inquirer.prompt([{ - name: 'accept', - type: 'confirm', - message: `Would you like to allow ${productName} to collect anonymous usage data?` - }]) - if (response.accept) { - config.set(`${configKey}.optOut`, false) - console.log(getOnMessage(productName, binName)) - trackEvent('telemetry-prompt', 'accepted') - } else { - // we will set optOut to true after tracking this one event - // todo: check if tty error - config.set(`${configKey}.optOut`, false) - console.log(getOffMessage(binName)) - trackEvent('telemetry-prompt', 'declined') - config.set(`${configKey}.optOut`, true) - } + getNoticeMessage, + notice: (productName, binName, privacyPolicyLink) => { + console.log(getNoticeMessage(productName, binName, privacyPolicyLink)) + config.set(`${configKey}.optOut`, false) + trackEvent('telemetry-notice', 'shown') } } diff --git a/test/hooks.test.js b/test/hooks.test.js index 8de8270..aa24115 100644 --- a/test/hooks.test.js +++ b/test/hooks.test.js @@ -11,10 +11,8 @@ */ const { createFetch } = require('@adobe/aio-lib-core-networking') -const inquirer = require('inquirer') const config = require('@adobe/aio-lib-core-config') -jest.mock('inquirer') jest.mock('@adobe/aio-lib-core-config') jest.mock('child_process', () => ({ spawn: jest.fn(() => ({ unref: jest.fn() })) @@ -31,10 +29,16 @@ const mockPackageJson = { } describe('hook interfaces', () => { + let noticeSpy beforeEach(() => { fetch.mockReset() spawn.mockClear() config.get.mockReset() + config.set.mockClear() + noticeSpy = jest.spyOn(telemetryLib, 'notice') + }) + afterEach(() => { + noticeSpy.mockRestore() }) test('command-error', async () => { @@ -65,114 +69,77 @@ describe('hook interfaces', () => { expect(bodyNf[0].metrics.map((m) => m.attributes.eventType)).toEqual(['command-not-found', 'postrun']) }) - /** - * Should prompt when config.get(optOut) returns undefined - * post results - */ - test('init prompt accept:true', async () => { + test('init shows one-time notice on first run', async () => { const preEnv = process.env process.env = { ...preEnv, CI: undefined, GITHUB_ACTIONS: undefined } const hook = require('../src/hooks/init') expect(typeof hook).toBe('function') - inquirer.prompt = jest.fn().mockResolvedValue({ accept: true }) config.get = jest.fn().mockReturnValue(undefined) await hook({ config: { name: 'name', version: '0.0.1', pjson: mockPackageJson }, argv: [] }) - expect(inquirer.prompt).toHaveBeenCalled() + expect(noticeSpy).toHaveBeenCalled() + expect(config.set).toHaveBeenCalledWith('aio-cli-telemetry.optOut', false) expect(spawn).not.toHaveBeenCalled() await telemetryLib.trackEvent('postrun') expect(spawn).toHaveBeenCalledTimes(1) const flushPayloadAcc = JSON.parse(spawn.mock.calls[0][1][1]) const bodyAcc = JSON.parse(flushPayloadAcc.body) - expect(bodyAcc[0].metrics.map((m) => m.attributes.eventType)).toEqual(['telemetry-prompt', 'postrun']) - expect(bodyAcc[0].metrics[0].attributes.eventData).toBe('accepted') + expect(bodyAcc[0].metrics.map((m) => m.attributes.eventType)).toEqual(['telemetry-notice', 'postrun']) + expect(bodyAcc[0].metrics[0].attributes.eventData).toBe('shown') process.env = preEnv }) - test('init prompt - full coverage when run by gh actions', async () => { + test('init - no notice for telemetry commands', async () => { const preEnv = process.env process.env = { ...preEnv, CI: undefined, GITHUB_ACTIONS: undefined } const hook = require('../src/hooks/init') expect(typeof hook).toBe('function') - inquirer.prompt = jest.fn().mockResolvedValue({ accept: true }) config.get = jest.fn().mockReturnValue(undefined) await hook({ id: 'telemetry', config: { name: 'name', version: '0.0.1' }, argv: [] }) - expect(inquirer.prompt).not.toHaveBeenCalled() + expect(noticeSpy).not.toHaveBeenCalled() expect(spawn).not.toHaveBeenCalled() process.env = preEnv }) - test('init prompt - dont ask for telemetry for telemetry commands', async () => { - const hook = require('../src/hooks/init') - expect(typeof hook).toBe('function') - inquirer.prompt = jest.fn().mockResolvedValue({ accept: true }) - config.get = jest.fn().mockReturnValue(undefined) - await hook({ id: 'telemetry', config: { name: 'name', version: '0.0.1' }, argv: [] }) - expect(inquirer.prompt).not.toHaveBeenCalled() - expect(spawn).not.toHaveBeenCalled() - }) - - test('init prompt - dont run when oclif is generating readme', async () => { - const hook = require('../src/hooks/init') - expect(typeof hook).toBe('function') - inquirer.prompt = jest.fn().mockResolvedValue({ accept: true }) - config.get = jest.fn().mockReturnValue(undefined) - await hook({ id: 'readme', config: { name: 'name', version: '0.0.1' }, argv: [] }) - expect(inquirer.prompt).not.toHaveBeenCalled() - expect(spawn).not.toHaveBeenCalled() - }) - - test('init prompt - dont run when oclif is generating readme and CI is off', async () => { + test('init - no notice when oclif is generating readme', async () => { const preEnv = process.env - process.env = { ...preEnv, CI: undefined } + process.env = { ...preEnv, CI: undefined, GITHUB_ACTIONS: undefined } const hook = require('../src/hooks/init') expect(typeof hook).toBe('function') - inquirer.prompt = jest.fn().mockResolvedValue({ accept: true }) config.get = jest.fn().mockReturnValue(undefined) await hook({ id: 'readme', config: { name: 'name', version: '0.0.1' }, argv: [] }) - expect(inquirer.prompt).not.toHaveBeenCalled() + expect(noticeSpy).not.toHaveBeenCalled() expect(spawn).not.toHaveBeenCalled() process.env = preEnv }) - test('no prompt when process.env.CI', async () => { + test('init - no notice when process.env.CI', async () => { const preEnv = process.env process.env = { ...preEnv, CI: 'true' } let hook jest.isolateModules(() => { hook = require('../src/hooks/init') }) - expect(typeof hook).toBe('function') - inquirer.prompt = jest.fn().mockResolvedValue({ accept: false }) config.get = jest.fn().mockReturnValue(undefined) - expect(inquirer.prompt).not.toHaveBeenCalled() await hook({ config: { name: 'name', version: '0.0.1' }, argv: ['--verbose'] }) + expect(noticeSpy).not.toHaveBeenCalled() expect(spawn).not.toHaveBeenCalled() - expect(inquirer.prompt).not.toHaveBeenCalled() process.env = preEnv }) /** - * Should prompt when config.get(optOut) returns undefined - * should still post after prompt even though it is declined, this is the last post + * When the user has already chosen a state (optOut defined), isNull() is false, + * so the notice is not shown again. */ - test('init prompt accept:false', async () => { + test('init - no notice when telemetry state already set', async () => { const preEnv = process.env process.env = { ...preEnv, CI: undefined, GITHUB_ACTIONS: undefined } const hook = require('../src/hooks/init') expect(typeof hook).toBe('function') - inquirer.prompt = jest.fn().mockResolvedValue({ accept: false }) - config.get = jest.fn().mockReturnValue(undefined) - await hook({ config: { name: 'name', version: '0.0.1', pjson: mockPackageJson }, argv: ['--verbose'] }) - expect(inquirer.prompt).toHaveBeenCalled() + config.get = jest.fn().mockReturnValue(false) // optOut already set -> isNull() false + await hook({ config: { name: 'name', version: '0.0.1', pjson: mockPackageJson }, argv: [] }) + expect(noticeSpy).not.toHaveBeenCalled() expect(spawn).not.toHaveBeenCalled() - telemetryLib.enable() - await telemetryLib.trackEvent('postrun') - expect(spawn).toHaveBeenCalledTimes(1) - const flushPayloadDec = JSON.parse(spawn.mock.calls[0][1][1]) - const bodyDec = JSON.parse(flushPayloadDec.body) - expect(bodyDec[0].metrics.map((m) => m.attributes.eventType)).toEqual(['telemetry-prompt', 'postrun']) - expect(bodyDec[0].metrics[0].attributes.eventData).toBe('declined') process.env = preEnv }) @@ -210,13 +177,12 @@ describe('hook interfaces', () => { * Should NOT prompt even though config.get(optOut) returned undefined * --no-telemetry flag wins */ - test('init --no-telemetry no prompt', async () => { + test('init --no-telemetry no notice', async () => { const hook = require('../src/hooks/init') expect(typeof hook).toBe('function') - inquirer.prompt = jest.fn() config.get = jest.fn().mockReturnValue(undefined) await hook({ config: { name: 'name', version: '0.0.1' }, argv: ['--no-telemetry'] }) - expect(inquirer.prompt).not.toHaveBeenCalled() + expect(noticeSpy).not.toHaveBeenCalled() expect(spawn).not.toHaveBeenCalled() }) diff --git a/test/index.test.js b/test/index.test.js index b0306e9..7eafdae 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -15,7 +15,6 @@ const TheCommand = require('../src/commands/telemetry') const { stdout } = require('stdout-stderr') const config = require('@adobe/aio-lib-core-config') -jest.mock('inquirer') jest.mock('@adobe/aio-lib-core-config') const fetch = createFetch() diff --git a/test/telemetry-lib.test.js b/test/telemetry-lib.test.js index cd77de1..31ecd86 100644 --- a/test/telemetry-lib.test.js +++ b/test/telemetry-lib.test.js @@ -35,6 +35,19 @@ describe('telemetry-lib', () => { expect(telemetryLib.getOnMessage).toBeDefined() expect(telemetryLib.getOnMessage).toBeInstanceOf(Function) + + expect(telemetryLib.getNoticeMessage).toBeInstanceOf(Function) + expect(telemetryLib.notice).toBeInstanceOf(Function) + }) + + test('getNoticeMessage uses the default privacy link, or a provided one', async () => { + const withDefault = telemetryLib.getNoticeMessage('Adobe Developer CLI', 'aio') + expect(withDefault).toMatch('on by default') + expect(withDefault).toMatch('aio telemetry off') + expect(withDefault).toMatch('developer.adobe.com/app-builder/docs/guides/telemetry') + + const withLink = telemetryLib.getNoticeMessage('Adobe Developer CLI', 'aio', 'https://example.com/privacy') + expect(withLink).toMatch('https://example.com/privacy') }) test('exports init function', async () => { From aa5cee1df13564600bb608a5ea993fd058608c36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20=C3=81ngel=20Garc=C3=ADa?= Date: Mon, 8 Jun 2026 10:33:56 -0700 Subject: [PATCH 2/4] feat(telemetry): point default telemetry URL at production proxy (ACNA-4597) Repoint DEFAULT_TELEMETRY_POST_URL from the stage namespace (53444-aioclitelemetryproxy-stage) to production (53444-aioclitelemetryproxy), now that the prod proxy is deployed and verified. Override via aioTelemetry.postUrl or AIO_TELEMETRY_POST_URL is unchanged. --- src/telemetry-lib.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/telemetry-lib.js b/src/telemetry-lib.js index e4ca2c8..1096c84 100644 --- a/src/telemetry-lib.js +++ b/src/telemetry-lib.js @@ -17,7 +17,7 @@ const config = require('@adobe/aio-lib-core-config') const debug = require('debug')('aio-telemetry:telemetry-lib') /** Adobe I/O App Builder web action that forwards CLI metrics to New Relic (ingest key stays server-side). */ -const DEFAULT_TELEMETRY_POST_URL = 'https://53444-aioclitelemetryproxy-stage.adobeio-static.net/api/v1/web/dx-excshell-1/telemetry' +const DEFAULT_TELEMETRY_POST_URL = 'https://53444-aioclitelemetryproxy.adobeio-static.net/api/v1/web/dx-excshell-1/telemetry' /** @returns {boolean} Whether `AIO_TELEMETRY_DISABLED` opts out (only the literal string `"true"`). */ function isEnvTelemetryDisabled () { From abaacfc3004b62f03bbca951b15d32c463bc97de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20=C3=81ngel=20Garc=C3=ADa?= Date: Mon, 8 Jun 2026 13:59:51 -0700 Subject: [PATCH 3/4] chore(telemetry): interpolate trackEvent debug line so values show under aio --- src/telemetry-lib.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/telemetry-lib.js b/src/telemetry-lib.js index 1096c84..7b34179 100644 --- a/src/telemetry-lib.js +++ b/src/telemetry-lib.js @@ -191,7 +191,7 @@ async function trackEvent (eventType, rawEventData = {}) { const optedOut = isDisabledForCommand || isEnvTelemetryDisabled() || config.get(`${configKey}.optOut`, 'global') === true const willSend = !optedOut - debug('trackEvent %s eventData=%j postUrl=%s willSend=%s', eventType, eventData, postUrl, willSend) + debug(`trackEvent ${eventType} eventData=${JSON.stringify(eventData)} postUrl=${postUrl} willSend=${willSend}`) if (optedOut) { pendingCommandMetrics.length = 0 From e1f0b38d5b6835f6baa8112240b90a122e202e78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20=C3=81ngel=20Garc=C3=ADa?= Date: Mon, 8 Jun 2026 14:59:19 -0700 Subject: [PATCH 4/4] refactor(telemetry): simplify one-time notice per review Drop the explicit 'To opt out, run ...' line from the telemetry notice (per @purplecabbage on PR #40) so it does not over-nudge opt-out; the privacy link already covers how to opt out. Removes the now-unused binName argument from getNoticeMessage/notice. --- src/hooks/init.js | 2 +- src/telemetry-lib.js | 12 +++++------- test/telemetry-lib.test.js | 5 ++--- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/hooks/init.js b/src/hooks/init.js index c3e68b3..1631fc9 100644 --- a/src/hooks/init.js +++ b/src/hooks/init.js @@ -46,7 +46,7 @@ module.exports = async function (opts) { // skip in CI (handled above) and when oclif-dev readme runs (it fires this event); // also skip for telemetry commands, where the user is already setting state. if (['readme', 'telemetry'].indexOf(opts.id) < 0) { - telemetryLib.notice(productName, binName, opts?.config?.pjson?.aioTelemetry?.productPrivacyPolicyLink) + telemetryLib.notice(productName, opts?.config?.pjson?.aioTelemetry?.productPrivacyPolicyLink) } } } diff --git a/src/telemetry-lib.js b/src/telemetry-lib.js index 7b34179..12c113f 100644 --- a/src/telemetry-lib.js +++ b/src/telemetry-lib.js @@ -119,11 +119,9 @@ const getOnMessage = (productName, binName) => { const getOffMessage = (binName) => { return `\nTelemetry is off.\nIf you would like to turn telemetry on, simply run \`${binName} telemetry on\`` } -const getNoticeMessage = (productName, binName, privacyPolicyLink) => { - return `${productName} collects anonymous usage data to help us improve our products. ` + - 'Telemetry is on by default; read what we collect and how it is used here:\n' + - ` ${privacyPolicyLink || defaultPrivacyPolicyLink}\n` + - `To opt out, run \`${binName} telemetry off\` (or set AIO_TELEMETRY_DISABLED=true).` +const getNoticeMessage = (productName, privacyPolicyLink) => { + return `${productName} collects anonymous usage data to help us improve our products.\n` + + `Telemetry is on by default; read what we collect and how it is used here: ${privacyPolicyLink || defaultPrivacyPolicyLink}` } /** @@ -302,8 +300,8 @@ module.exports = { getOnMessage, getOffMessage, getNoticeMessage, - notice: (productName, binName, privacyPolicyLink) => { - console.log(getNoticeMessage(productName, binName, privacyPolicyLink)) + notice: (productName, privacyPolicyLink) => { + console.log(getNoticeMessage(productName, privacyPolicyLink)) config.set(`${configKey}.optOut`, false) trackEvent('telemetry-notice', 'shown') } diff --git a/test/telemetry-lib.test.js b/test/telemetry-lib.test.js index 31ecd86..f4b2485 100644 --- a/test/telemetry-lib.test.js +++ b/test/telemetry-lib.test.js @@ -41,12 +41,11 @@ describe('telemetry-lib', () => { }) test('getNoticeMessage uses the default privacy link, or a provided one', async () => { - const withDefault = telemetryLib.getNoticeMessage('Adobe Developer CLI', 'aio') + const withDefault = telemetryLib.getNoticeMessage('Adobe Developer CLI') expect(withDefault).toMatch('on by default') - expect(withDefault).toMatch('aio telemetry off') expect(withDefault).toMatch('developer.adobe.com/app-builder/docs/guides/telemetry') - const withLink = telemetryLib.getNoticeMessage('Adobe Developer CLI', 'aio', 'https://example.com/privacy') + const withLink = telemetryLib.getNoticeMessage('Adobe Developer CLI', 'https://example.com/privacy') expect(withLink).toMatch('https://example.com/privacy') })