diff --git a/src/plugins/screenshot_mode/common/index.ts b/src/plugins/screenshot_mode/common/index.ts index fd9ad6f70febac..9c8c3d24ef289a 100644 --- a/src/plugins/screenshot_mode/common/index.ts +++ b/src/plugins/screenshot_mode/common/index.ts @@ -10,6 +10,7 @@ export { getScreenshotMode, setScreenshotModeEnabled, setScreenshotModeDisabled, + KBN_SCREENSHOT_MODE_ENABLED_KEY, } from './get_set_browser_screenshot_mode'; export { KBN_SCREENSHOT_MODE_HEADER } from './constants'; diff --git a/src/plugins/screenshot_mode/public/index.ts b/src/plugins/screenshot_mode/public/index.ts index 6a46b240d592e7..a5ad37dd5b760d 100644 --- a/src/plugins/screenshot_mode/public/index.ts +++ b/src/plugins/screenshot_mode/public/index.ts @@ -12,6 +12,10 @@ export function plugin() { return new ScreenshotModePlugin(); } -export { KBN_SCREENSHOT_MODE_HEADER, setScreenshotModeEnabled } from '../common'; +export { + KBN_SCREENSHOT_MODE_HEADER, + setScreenshotModeEnabled, + KBN_SCREENSHOT_MODE_ENABLED_KEY, +} from '../common'; export { ScreenshotModePluginSetup } from './types'; diff --git a/src/plugins/screenshot_mode/server/index.ts b/src/plugins/screenshot_mode/server/index.ts index 68714e9a21b874..b9f19a474ccbe3 100644 --- a/src/plugins/screenshot_mode/server/index.ts +++ b/src/plugins/screenshot_mode/server/index.ts @@ -8,7 +8,11 @@ import { ScreenshotModePlugin } from './plugin'; -export { setScreenshotModeEnabled, KBN_SCREENSHOT_MODE_HEADER } from '../common'; +export { + setScreenshotModeEnabled, + KBN_SCREENSHOT_MODE_HEADER, + KBN_SCREENSHOT_MODE_ENABLED_KEY, +} from '../common'; export { ScreenshotModeRequestHandlerContext, diff --git a/src/plugins/telemetry/kibana.json b/src/plugins/telemetry/kibana.json index 520ca6076dbbd5..a9895ba2e5e9cd 100644 --- a/src/plugins/telemetry/kibana.json +++ b/src/plugins/telemetry/kibana.json @@ -3,15 +3,7 @@ "version": "kibana", "server": true, "ui": true, - "requiredPlugins": [ - "telemetryCollectionManager", - "usageCollection" - ], - "extraPublicDirs": [ - "common/constants" - ], - "requiredBundles": [ - "kibanaUtils", - "kibanaReact" - ] + "requiredPlugins": ["telemetryCollectionManager", "usageCollection", "screenshotMode"], + "extraPublicDirs": ["common/constants"], + "requiredBundles": ["kibanaUtils", "kibanaReact"] } diff --git a/src/plugins/telemetry/public/mocks.ts b/src/plugins/telemetry/public/mocks.ts index 34063e6486041f..418aeace77c704 100644 --- a/src/plugins/telemetry/public/mocks.ts +++ b/src/plugins/telemetry/public/mocks.ts @@ -22,12 +22,14 @@ import { TelemetryPluginStart, TelemetryPluginSetup, TelemetryPluginConfig } fro export interface TelemetryServiceMockOptions { reportOptInStatusChange?: boolean; currentKibanaVersion?: string; + isScreenshotMode?: boolean; config?: Partial; } export function mockTelemetryService({ reportOptInStatusChange, currentKibanaVersion = 'mockKibanaVersion', + isScreenshotMode = false, config: configOverride = {}, }: TelemetryServiceMockOptions = {}) { const config = { @@ -47,6 +49,7 @@ export function mockTelemetryService({ config, http: httpServiceMock.createStartContract(), notifications: notificationServiceMock.createStartContract(), + isScreenshotMode, currentKibanaVersion, reportOptInStatusChange, }); diff --git a/src/plugins/telemetry/public/plugin.ts b/src/plugins/telemetry/public/plugin.ts index 5e85fa7ea2d51b..04fabe3d62b17c 100644 --- a/src/plugins/telemetry/public/plugin.ts +++ b/src/plugins/telemetry/public/plugin.ts @@ -17,6 +17,8 @@ import type { ApplicationStart, } from 'src/core/public'; +import type { ScreenshotModePluginSetup } from 'src/plugins/screenshot_mode/public'; + import { TelemetrySender, TelemetryService, TelemetryNotifications } from './services'; import type { TelemetrySavedObjectAttributes, @@ -38,6 +40,8 @@ export interface TelemetryServicePublicApis { getIsOptedIn: () => boolean | null; /** Is the user allowed to change the opt-in/out status? **/ userCanChangeSettings: boolean; + /** Can phone-home telemetry calls be made? This depends on whether we have opted-in or if we are rendering a report */ + canSendTelemetry: () => boolean; /** Is the cluster allowed to change the opt-in/out status? **/ getCanChangeOptInStatus: () => boolean; /** Fetches an unencrypted telemetry payload so we can show it to the user **/ @@ -76,6 +80,10 @@ export interface TelemetryPluginStart { }; } +interface TelemetryPluginSetupDependencies { + screenshotMode: ScreenshotModePluginSetup; +} + /** * Public-exposed configuration */ @@ -113,11 +121,15 @@ export class TelemetryPlugin implements Plugin telemetryService.getIsOptedIn(), setOptIn: (optedIn) => telemetryService.setOptIn(optedIn), + canSendTelemetry: () => telemetryService.canSendTelemetry(), userCanChangeSettings: telemetryService.userCanChangeSettings, getCanChangeOptInStatus: () => telemetryService.getCanChangeOptInStatus(), fetchExample: () => telemetryService.fetchExample(), diff --git a/src/plugins/telemetry/public/services/telemetry_sender.test.ts b/src/plugins/telemetry/public/services/telemetry_sender.test.ts index 4dd1fe37a75691..6459f15fc60f74 100644 --- a/src/plugins/telemetry/public/services/telemetry_sender.test.ts +++ b/src/plugins/telemetry/public/services/telemetry_sender.test.ts @@ -118,6 +118,16 @@ describe('TelemetrySender', () => { expect(shouldSendReport).toBe(true); }); + it('returns false if we are in screenshot mode', () => { + const telemetryService = mockTelemetryService({ isScreenshotMode: true }); + telemetryService.getIsOptedIn = jest.fn().mockReturnValue(false); + const telemetrySender = new TelemetrySender(telemetryService); + const shouldSendReport = telemetrySender['shouldSendReport'](); + + expect(telemetryService.getIsOptedIn).toBeCalledTimes(0); + expect(shouldSendReport).toBe(false); + }); + describe('sendIfDue', () => { let originalFetch: typeof window['fetch']; let mockFetch: jest.Mock; @@ -151,6 +161,15 @@ describe('TelemetrySender', () => { expect(mockFetch).toBeCalledTimes(0); }); + it('does not send if we are in screenshot mode', async () => { + const telemetryService = mockTelemetryService({ isScreenshotMode: true }); + const telemetrySender = new TelemetrySender(telemetryService); + telemetrySender['isSending'] = false; + await telemetrySender['sendIfDue'](); + + expect(mockFetch).toBeCalledTimes(0); + }); + it('sends report if due', async () => { const mockTelemetryUrl = 'telemetry_cluster_url'; const mockTelemetryPayload = ['hashed_cluster_usage_data1']; diff --git a/src/plugins/telemetry/public/services/telemetry_sender.ts b/src/plugins/telemetry/public/services/telemetry_sender.ts index 937416d283872a..fa973344951222 100644 --- a/src/plugins/telemetry/public/services/telemetry_sender.ts +++ b/src/plugins/telemetry/public/services/telemetry_sender.ts @@ -33,8 +33,7 @@ export class TelemetrySender { }; private shouldSendReport = (): boolean => { - // check if opt-in for telemetry is enabled - if (this.telemetryService.getIsOptedIn()) { + if (this.telemetryService.canSendTelemetry()) { if (!this.lastReported) { return true; } diff --git a/src/plugins/telemetry/public/services/telemetry_service.test.ts b/src/plugins/telemetry/public/services/telemetry_service.test.ts index c06352208651ad..94630c0cb8d80e 100644 --- a/src/plugins/telemetry/public/services/telemetry_service.test.ts +++ b/src/plugins/telemetry/public/services/telemetry_service.test.ts @@ -256,4 +256,24 @@ describe('TelemetryService', () => { expect(mockFetch).toHaveBeenCalledTimes(1); }); }); + + describe('canSendTelemetry', () => { + it('does not send telemetry if screenshotMode is true', () => { + const telemetryService = mockTelemetryService({ + isScreenshotMode: true, + config: { optIn: true }, + }); + + expect(telemetryService.canSendTelemetry()).toBe(false); + }); + + it('does send telemetry if screenshotMode is false and we are opted in', () => { + const telemetryService = mockTelemetryService({ + isScreenshotMode: false, + config: { optIn: true }, + }); + + expect(telemetryService.canSendTelemetry()).toBe(true); + }); + }); }); diff --git a/src/plugins/telemetry/public/services/telemetry_service.ts b/src/plugins/telemetry/public/services/telemetry_service.ts index 4ae29569020925..515d2039a4a114 100644 --- a/src/plugins/telemetry/public/services/telemetry_service.ts +++ b/src/plugins/telemetry/public/services/telemetry_service.ts @@ -14,6 +14,7 @@ interface TelemetryServiceConstructor { config: TelemetryPluginConfig; http: CoreStart['http']; notifications: CoreStart['notifications']; + isScreenshotMode: boolean; currentKibanaVersion: string; reportOptInStatusChange?: boolean; } @@ -27,6 +28,7 @@ export class TelemetryService { private readonly reportOptInStatusChange: boolean; private readonly notifications: CoreStart['notifications']; private readonly defaultConfig: TelemetryPluginConfig; + private readonly isScreenshotMode: boolean; private updatedConfig?: TelemetryPluginConfig; /** Current version of Kibana */ @@ -35,11 +37,13 @@ export class TelemetryService { constructor({ config, http, + isScreenshotMode, notifications, currentKibanaVersion, reportOptInStatusChange = true, }: TelemetryServiceConstructor) { this.defaultConfig = config; + this.isScreenshotMode = isScreenshotMode; this.reportOptInStatusChange = reportOptInStatusChange; this.notifications = notifications; this.currentKibanaVersion = currentKibanaVersion; @@ -63,7 +67,7 @@ export class TelemetryService { /** Is the cluster opted-in to telemetry **/ public get isOptedIn() { - return this.config.optIn; + return Boolean(this.config.optIn); } /** Changes the opt-in status **/ @@ -122,10 +126,15 @@ export class TelemetryService { } /** Is the cluster opted-in to telemetry **/ - public getIsOptedIn = () => { + public getIsOptedIn = (): boolean => { return this.isOptedIn; }; + /** Are there any blockers for sending telemetry */ + public canSendTelemetry = (): boolean => { + return !this.isScreenshotMode && this.getIsOptedIn(); + }; + /** Fetches an unencrypted telemetry payload so we can show it to the user **/ public fetchExample = async () => { return await this.fetchTelemetry({ unencrypted: true }); diff --git a/src/plugins/telemetry/tsconfig.json b/src/plugins/telemetry/tsconfig.json index 6629e479906c98..3b043b8aab895e 100644 --- a/src/plugins/telemetry/tsconfig.json +++ b/src/plugins/telemetry/tsconfig.json @@ -8,17 +8,13 @@ "declarationMap": true, "isolatedModules": true }, - "include": [ - "public/**/**/*", - "server/**/**/*", - "common/**/*", - "../../../typings/**/*" - ], + "include": ["public/**/**/*", "server/**/**/*", "common/**/*", "../../../typings/**/*"], "references": [ { "path": "../../core/tsconfig.json" }, - { "path": "../../plugins/usage_collection/tsconfig.json" }, - { "path": "../../plugins/telemetry_collection_manager/tsconfig.json" }, + { "path": "../../plugins/kibana_react/tsconfig.json" }, { "path": "../../plugins/kibana_utils/tsconfig.json" }, - { "path": "../../plugins/kibana_react/tsconfig.json" } + { "path": "../../plugins/screenshot_mode/tsconfig.json" }, + { "path": "../../plugins/telemetry_collection_manager/tsconfig.json" }, + { "path": "../../plugins/usage_collection/tsconfig.json" } ] } diff --git a/src/plugins/telemetry_management_section/public/components/__snapshots__/telemetry_management_section.test.tsx.snap b/src/plugins/telemetry_management_section/public/components/__snapshots__/telemetry_management_section.test.tsx.snap index e0ba7e7527af7d..c4cee25a33b7ff 100644 --- a/src/plugins/telemetry_management_section/public/components/__snapshots__/telemetry_management_section.test.tsx.snap +++ b/src/plugins/telemetry_management_section/public/components/__snapshots__/telemetry_management_section.test.tsx.snap @@ -306,6 +306,7 @@ exports[`TelemetryManagementSectionComponent renders null because allowChangingO showAppliesSettingMessage={true} telemetryService={ TelemetryService { + "canSendTelemetry": [Function], "currentKibanaVersion": "mock_kibana_version", "defaultConfig": Object { "allowChangingOptInStatus": false, @@ -350,6 +351,7 @@ exports[`TelemetryManagementSectionComponent renders null because allowChangingO "post": [MockFunction], "put": [MockFunction], }, + "isScreenshotMode": false, "notifications": Object { "toasts": Object { "add": [MockFunction], diff --git a/src/plugins/telemetry_management_section/public/components/telemetry_management_section.test.tsx b/src/plugins/telemetry_management_section/public/components/telemetry_management_section.test.tsx index 019dedd793fa2f..fe6f8e254142b5 100644 --- a/src/plugins/telemetry_management_section/public/components/telemetry_management_section.test.tsx +++ b/src/plugins/telemetry_management_section/public/components/telemetry_management_section.test.tsx @@ -32,6 +32,7 @@ describe('TelemetryManagementSectionComponent', () => { optInStatusUrl: '', sendUsageFrom: 'browser', }, + isScreenshotMode: false, reportOptInStatusChange: false, currentKibanaVersion: 'mock_kibana_version', notifications: coreStart.notifications, @@ -66,6 +67,7 @@ describe('TelemetryManagementSectionComponent', () => { optInStatusUrl: '', sendUsageFrom: 'browser', }, + isScreenshotMode: false, reportOptInStatusChange: false, notifications: coreStart.notifications, currentKibanaVersion: 'mock_kibana_version', @@ -121,6 +123,7 @@ describe('TelemetryManagementSectionComponent', () => { optInStatusUrl: '', sendUsageFrom: 'browser', }, + isScreenshotMode: false, reportOptInStatusChange: false, notifications: coreStart.notifications, currentKibanaVersion: 'mock_kibana_version', @@ -169,6 +172,7 @@ describe('TelemetryManagementSectionComponent', () => { optInStatusUrl: '', sendUsageFrom: 'browser', }, + isScreenshotMode: false, reportOptInStatusChange: false, notifications: coreStart.notifications, currentKibanaVersion: 'mock_kibana_version', @@ -208,6 +212,7 @@ describe('TelemetryManagementSectionComponent', () => { optInStatusUrl: '', sendUsageFrom: 'browser', }, + isScreenshotMode: false, reportOptInStatusChange: false, notifications: coreStart.notifications, currentKibanaVersion: 'mock_kibana_version', @@ -248,6 +253,7 @@ describe('TelemetryManagementSectionComponent', () => { optInStatusUrl: '', sendUsageFrom: 'browser', }, + isScreenshotMode: false, reportOptInStatusChange: false, notifications: coreStart.notifications, currentKibanaVersion: 'mock_kibana_version', @@ -288,6 +294,7 @@ describe('TelemetryManagementSectionComponent', () => { optInStatusUrl: '', sendUsageFrom: 'browser', }, + isScreenshotMode: false, reportOptInStatusChange: false, currentKibanaVersion: 'mock_kibana_version', notifications: coreStart.notifications, @@ -328,6 +335,7 @@ describe('TelemetryManagementSectionComponent', () => { optInStatusUrl: '', sendUsageFrom: 'browser', }, + isScreenshotMode: false, reportOptInStatusChange: false, notifications: coreStart.notifications, currentKibanaVersion: 'mock_kibana_version', @@ -378,6 +386,7 @@ describe('TelemetryManagementSectionComponent', () => { optInStatusUrl: '', sendUsageFrom: 'browser', }, + isScreenshotMode: false, reportOptInStatusChange: false, notifications: coreStart.notifications, currentKibanaVersion: 'mock_kibana_version', diff --git a/test/plugin_functional/config.ts b/test/plugin_functional/config.ts index 1ff55edc010da1..631cbc8146d654 100644 --- a/test/plugin_functional/config.ts +++ b/test/plugin_functional/config.ts @@ -22,6 +22,7 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { return { testFiles: [ require.resolve('./test_suites/usage_collection'), + require.resolve('./test_suites/telemetry'), require.resolve('./test_suites/core'), require.resolve('./test_suites/custom_visualizations'), require.resolve('./test_suites/panel_actions'), diff --git a/test/plugin_functional/plugins/telemetry/kibana.json b/test/plugin_functional/plugins/telemetry/kibana.json new file mode 100644 index 00000000000000..40a7d59d7dc2d8 --- /dev/null +++ b/test/plugin_functional/plugins/telemetry/kibana.json @@ -0,0 +1,9 @@ +{ + "id": "telemetryTestPlugin", + "version": "0.0.1", + "kibanaVersion": "kibana", + "configPath": ["telemetryTestPlugin"], + "requiredPlugins": ["telemetry"], + "server": false, + "ui": true +} diff --git a/test/plugin_functional/plugins/telemetry/package.json b/test/plugin_functional/plugins/telemetry/package.json new file mode 100644 index 00000000000000..8e850fb582fec4 --- /dev/null +++ b/test/plugin_functional/plugins/telemetry/package.json @@ -0,0 +1,14 @@ +{ + "name": "telemetry_test_plugin", + "version": "1.0.0", + "main": "target/test/plugin_functional/plugins/telemetry", + "kibana": { + "version": "kibana", + "templateVersion": "1.0.0" + }, + "license": "SSPL-1.0 OR Elastic License 2.0", + "scripts": { + "kbn": "node ../../../../scripts/kbn.js", + "build": "rm -rf './target' && ../../../../node_modules/.bin/tsc" + } +} diff --git a/test/plugin_functional/plugins/telemetry/public/index.ts b/test/plugin_functional/plugins/telemetry/public/index.ts new file mode 100644 index 00000000000000..b32ccb51153a12 --- /dev/null +++ b/test/plugin_functional/plugins/telemetry/public/index.ts @@ -0,0 +1,11 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { TelemetryTestPlugin } from './plugin'; + +export const plugin = () => new TelemetryTestPlugin(); diff --git a/test/plugin_functional/plugins/telemetry/public/plugin.ts b/test/plugin_functional/plugins/telemetry/public/plugin.ts new file mode 100644 index 00000000000000..441675b1aa4ed0 --- /dev/null +++ b/test/plugin_functional/plugins/telemetry/public/plugin.ts @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { CoreSetup, Plugin } from 'src/core/public'; +import type { TelemetryPluginSetup } from '../../../../../src/plugins/telemetry/public'; + +interface TelemetryTestPluginSetupDependencies { + telemetry: TelemetryPluginSetup; +} + +export class TelemetryTestPlugin implements Plugin { + setup(core: CoreSetup, { telemetry }: TelemetryTestPluginSetupDependencies) { + window._checkCanSendTelemetry = async () => { + await telemetry.telemetryService.setOptIn(true); + return telemetry.telemetryService.canSendTelemetry(); + }; + + window._resetTelemetry = async () => { + await telemetry.telemetryService.setOptIn(false); + }; + } + start() {} +} diff --git a/test/plugin_functional/plugins/telemetry/tsconfig.json b/test/plugin_functional/plugins/telemetry/tsconfig.json new file mode 100644 index 00000000000000..947eb49a61b3a5 --- /dev/null +++ b/test/plugin_functional/plugins/telemetry/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../../../tsconfig.base.json", + "compilerOptions": { + "outDir": "./target", + "skipLibCheck": true + }, + "include": ["public/**/*.ts", "types.ts", "../../../../typings/**/*"], + "exclude": [], + "references": [{ "path": "../../../../src/core/tsconfig.json" }] +} diff --git a/test/plugin_functional/plugins/telemetry/types.ts b/test/plugin_functional/plugins/telemetry/types.ts new file mode 100644 index 00000000000000..aba7bc0abca809 --- /dev/null +++ b/test/plugin_functional/plugins/telemetry/types.ts @@ -0,0 +1,17 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +declare global { + interface Window { + _checkCanSendTelemetry: () => Promise; + _resetTelemetry: () => Promise; + } +} + +// Turn this file into a module +export {}; diff --git a/test/plugin_functional/test_suites/telemetry/index.ts b/test/plugin_functional/test_suites/telemetry/index.ts new file mode 100644 index 00000000000000..2e94cc5d3bfd1b --- /dev/null +++ b/test/plugin_functional/test_suites/telemetry/index.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { PluginFunctionalProviderContext } from '../../services'; + +export default function ({ loadTestFile }: PluginFunctionalProviderContext) { + describe('telemetry', function () { + loadTestFile(require.resolve('./telemetry')); + }); +} diff --git a/test/plugin_functional/test_suites/telemetry/telemetry.ts b/test/plugin_functional/test_suites/telemetry/telemetry.ts new file mode 100644 index 00000000000000..8ebc78c9b2f84b --- /dev/null +++ b/test/plugin_functional/test_suites/telemetry/telemetry.ts @@ -0,0 +1,45 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import expect from '@kbn/expect'; +import { PluginFunctionalProviderContext } from '../../services'; +import { KBN_SCREENSHOT_MODE_ENABLED_KEY } from '../../../../src/plugins/screenshot_mode/public'; + +export default function ({ getService, getPageObjects }: PluginFunctionalProviderContext) { + const browser = getService('browser'); + const PageObjects = getPageObjects(['common']); + + describe('Telemetry service', () => { + const checkCanSendTelemetry = (): Promise => { + return browser.executeAsync((cb) => { + ((window as unknown) as Record Promise>) + ._checkCanSendTelemetry() + .then(cb); + }); + }; + + after(async () => { + await browser.removeLocalStorageItem(KBN_SCREENSHOT_MODE_ENABLED_KEY); + await browser.executeAsync((cb) => { + ((window as unknown) as Record Promise>) + ._resetTelemetry() + .then(() => cb()); + }); + }); + + it('detects that telemetry cannot be sent in screenshot mode', async () => { + await PageObjects.common.navigateToApp('home'); + expect(await checkCanSendTelemetry()).to.be(true); + + await browser.setLocalStorageItem(KBN_SCREENSHOT_MODE_ENABLED_KEY, 'true'); + await PageObjects.common.navigateToApp('home'); + + expect(await checkCanSendTelemetry()).to.be(false); + }); + }); +}