From 9ad25bdc8b134d83d2c0e50b38a9c8318709e950 Mon Sep 17 00:00:00 2001 From: Ryan Lamb <4955475+kinyoklion@users.noreply.github.com> Date: Tue, 1 Oct 2024 13:12:53 -0700 Subject: [PATCH] chore: Remove shared mocks package. (#601) The dependencies between the mocks, and the unpublished nature of the package, made maintenance complex. Additionally the mocks themselves cause the tests to be harder to maintain and understand. This PR changes all test dependencies to be in their own project. If we need shared test code, then we could make shared code and not a package. The main motivator for removal is the circular dependency relationship between the mocks and common. Updating common to support ESM is made more difficult, but needs to be done. Overall this makes things much simpler at the cost of a couple hundred lines of total duplication. (As indicated by the PR additions versus subtractions.) There was code that was shared that was actually only used in singular test locations. Fixes SDK-729. --- .github/workflows/mocks.yml | 25 ---- .github/workflows/react-native-detox.yml | 1 - package.json | 1 - packages/sdk/browser/package.json | 1 - packages/sdk/cloudflare/jsr.json | 12 +- .../react-native-sse/EventSource.test.ts | 12 +- packages/sdk/react-native/package.json | 1 - .../__tests__/LDClientNode.listeners.test.ts | 13 +- .../__tests__/LDClientNode.test.ts | 12 +- .../__tests__/LDClientNode.tls.test.ts | 13 +- packages/sdk/server-node/package.json | 1 - .../__tests__}/contextDeduplicator.ts | 3 +- .../__tests__/createBasicPlatform.ts} | 5 +- .../diagnostics/DiagnosticsManager.test.ts | 5 +- .../internal/events/EventProcessor.test.ts | 18 +-- .../internal/events/EventSender.test.ts | 50 +++---- .../stream/StreamingProcessor.test.ts | 26 ++-- .../__tests__/options/ApplicationTags.test.ts | 104 ++++++++++++-- .../__tests__/setupCrypto.ts} | 2 +- packages/shared/common/package.json | 1 - packages/shared/common/rollup.config.js | 43 ++++++ packages/shared/mocks/CHANGELOG.md | 3 - packages/shared/mocks/LICENSE | 13 -- packages/shared/mocks/README.md | 131 ------------------ packages/shared/mocks/jest.config.js | 7 - packages/shared/mocks/package.json | 55 -------- packages/shared/mocks/src/index.ts | 15 -- packages/shared/mocks/src/logger.ts | 6 - packages/shared/mocks/tsconfig.eslint.json | 5 - packages/shared/mocks/tsconfig.json | 26 ---- packages/shared/mocks/tsconfig.ref.json | 7 - .../__tests__/LDClientImpl.events.test.ts | 19 +-- .../__tests__/LDClientImpl.storage.test.ts | 13 +- .../sdk-client/__tests__/LDClientImpl.test.ts | 13 +- .../__tests__/LDClientImpl.timeout.test.ts | 13 +- .../__tests__/LDClientImpl.variation.test.ts | 19 ++- .../__tests__/context/addAutoEnv.test.ts | 12 +- .../__tests__/context/ensureKey.test.ts | 2 +- .../__tests__/createBasicPlatform.ts | 59 ++++++++ .../__tests__}/eventProcessor.ts | 2 +- .../sdk-client/__tests__/setupCrypto.ts | 20 +++ .../storage/getOrGenerateKey.test.ts | 2 +- .../streaming/StreamingProcessor.test.ts | 12 +- packages/shared/sdk-client/package.json | 1 - packages/shared/sdk-client/rollup.config.js | 43 ++++++ .../__tests__/api/LDClient.test.ts | 2 +- .../__tests__/api/createCallbacks.test.ts | 13 +- .../__tests__/createBasicPlatform.ts | 59 ++++++++ .../sdk-server-edge/__tests__/setupCrypto.ts | 20 +++ packages/shared/sdk-server-edge/package.json | 1 - .../__tests__/LDClient.allFlags.test.ts | 7 +- .../__tests__/LDClient.evaluation.test.ts | 33 ++--- .../__tests__/LDClient.events.test.ts | 4 +- .../__tests__/LDClient.hooks.test.ts | 7 +- .../__tests__/LDClient.migrations.test.ts | 5 +- .../LDClientImpl.bigSegments.test.ts | 10 +- .../__tests__/LDClientImpl.listeners.test.ts | 5 +- .../sdk-server/__tests__/LDClientImpl.test.ts | 115 +++++++++------ .../sdk-server/__tests__/Migration.test.ts | 5 +- .../__tests__/MigrationOpEvent.test.ts | 4 +- .../__tests__/createBasicPlatform.ts | 59 ++++++++ .../data_sources/FileDataSource.test.ts | 2 +- .../data_sources/PollingProcessor.test.ts | 2 +- .../createDiagnosticsInitConfig.test.ts | 9 +- .../__tests__/evaluation/Bucketer.test.ts | 2 +- .../evaluation/Evaluator.bucketing.test.ts | 2 +- .../evaluation/Evaluator.clause.test.ts | 2 +- .../evaluation/Evaluator.rules.test.ts | 2 +- .../evaluation/Evaluator.segments.test.ts | 2 +- .../__tests__/evaluation/Evaluator.test.ts | 2 +- .../__tests__/events/EventProcessor.test.ts | 2 +- .../integrations/test_data/TestData.test.ts | 2 +- .../sdk-server/__tests__/setupCrypto.ts | 20 +++ .../__tests__}/streamingProcessor.ts | 2 +- packages/shared/sdk-server/package.json | 1 - .../createStreamListeners.test.ts | 11 +- .../node-server-sdk-otel/package.json | 1 - tsconfig.json | 3 - 78 files changed, 710 insertions(+), 553 deletions(-) delete mode 100644 .github/workflows/mocks.yml rename packages/shared/{mocks/src => common/__tests__}/contextDeduplicator.ts (82%) rename packages/shared/{mocks/src/platform.ts => common/__tests__/createBasicPlatform.ts} (92%) rename packages/shared/common/{src => __tests__}/internal/diagnostics/DiagnosticsManager.test.ts (95%) rename packages/shared/common/{src => __tests__}/internal/events/EventSender.test.ts (84%) rename packages/shared/common/{src => __tests__}/internal/stream/StreamingProcessor.test.ts (92%) rename packages/shared/{mocks/src/crypto.ts => common/__tests__/setupCrypto.ts} (91%) create mode 100644 packages/shared/common/rollup.config.js delete mode 100644 packages/shared/mocks/CHANGELOG.md delete mode 100644 packages/shared/mocks/LICENSE delete mode 100644 packages/shared/mocks/README.md delete mode 100644 packages/shared/mocks/jest.config.js delete mode 100644 packages/shared/mocks/package.json delete mode 100644 packages/shared/mocks/src/index.ts delete mode 100644 packages/shared/mocks/src/logger.ts delete mode 100644 packages/shared/mocks/tsconfig.eslint.json delete mode 100644 packages/shared/mocks/tsconfig.json delete mode 100644 packages/shared/mocks/tsconfig.ref.json create mode 100644 packages/shared/sdk-client/__tests__/createBasicPlatform.ts rename packages/shared/{mocks/src => sdk-client/__tests__}/eventProcessor.ts (85%) create mode 100644 packages/shared/sdk-client/__tests__/setupCrypto.ts create mode 100644 packages/shared/sdk-client/rollup.config.js create mode 100644 packages/shared/sdk-server-edge/__tests__/createBasicPlatform.ts create mode 100644 packages/shared/sdk-server-edge/__tests__/setupCrypto.ts create mode 100644 packages/shared/sdk-server/__tests__/createBasicPlatform.ts rename packages/shared/sdk-server/{src => __tests__}/diagnostics/createDiagnosticsInitConfig.test.ts (92%) create mode 100644 packages/shared/sdk-server/__tests__/setupCrypto.ts rename packages/shared/{mocks/src => sdk-server/__tests__}/streamingProcessor.ts (98%) diff --git a/.github/workflows/mocks.yml b/.github/workflows/mocks.yml deleted file mode 100644 index 6a5b5d6b7..000000000 --- a/.github/workflows/mocks.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: shared/mocks - -on: - push: - branches: [main, 'feat/**'] - paths-ignore: - - '**.md' #Do not need to run CI for markdown changes. - pull_request: - branches: [main, 'feat/**'] - paths-ignore: - - '**.md' - -jobs: - build-test-mocks: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - - id: shared - name: Shared CI Steps - uses: ./actions/ci - with: - workspace_name: '@launchdarkly/private-js-mocks' - workspace_path: packages/shared/mocks - should_build_docs: false diff --git a/.github/workflows/react-native-detox.yml b/.github/workflows/react-native-detox.yml index d42886a67..1b491d0de 100644 --- a/.github/workflows/react-native-detox.yml +++ b/.github/workflows/react-native-detox.yml @@ -16,7 +16,6 @@ on: - 'packages/shared/common/**' - 'packages/shared/sdk-client/**' - 'packages/sdk/react-native/**' - - 'packages/shared/mocks/**' jobs: detox-android: diff --git a/package.json b/package.json index dd94fbcb1..2778c9e9d 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,6 @@ "name": "@launchdarkly/js-core", "workspaces": [ "packages/shared/common", - "packages/shared/mocks", "packages/shared/sdk-client", "packages/shared/sdk-server", "packages/shared/sdk-server-edge", diff --git a/packages/sdk/browser/package.json b/packages/sdk/browser/package.json index 96ff6bcf4..6cc036846 100644 --- a/packages/sdk/browser/package.json +++ b/packages/sdk/browser/package.json @@ -40,7 +40,6 @@ }, "devDependencies": { "@jest/globals": "^29.7.0", - "@launchdarkly/private-js-mocks": "0.0.1", "@rollup/plugin-commonjs": "^25.0.0", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^15.0.2", diff --git a/packages/sdk/cloudflare/jsr.json b/packages/sdk/cloudflare/jsr.json index 39c3d457d..6ebe70663 100644 --- a/packages/sdk/cloudflare/jsr.json +++ b/packages/sdk/cloudflare/jsr.json @@ -3,15 +3,7 @@ "version": "2.5.14", "exports": "./src/index.ts", "publish": { - "include": [ - "LICENSE", - "README.md", - "package.json", - "jsr.json", - "src/**/*.ts" - ], - "exclude": [ - "src/**/*.test.ts" - ] + "include": ["LICENSE", "README.md", "package.json", "jsr.json", "src/**/*.ts"], + "exclude": ["src/**/*.test.ts"] } } diff --git a/packages/sdk/react-native/__tests__/fromExternal/react-native-sse/EventSource.test.ts b/packages/sdk/react-native/__tests__/fromExternal/react-native-sse/EventSource.test.ts index f6c4173ad..a7d323fa9 100644 --- a/packages/sdk/react-native/__tests__/fromExternal/react-native-sse/EventSource.test.ts +++ b/packages/sdk/react-native/__tests__/fromExternal/react-native-sse/EventSource.test.ts @@ -1,15 +1,19 @@ -import { type EventName } from '@launchdarkly/js-client-sdk-common'; -import { createLogger } from '@launchdarkly/private-js-mocks'; +import { type EventName, LDLogger } from '@launchdarkly/js-client-sdk-common'; import EventSource, { backoff, jitter, } from '../../../src/fromExternal/react-native-sse/EventSource'; -let logger: ReturnType; +let logger: LDLogger; beforeEach(() => { - logger = createLogger(); + logger = { + error: jest.fn(), + warn: jest.fn(), + info: jest.fn(), + debug: jest.fn(), + }; }); describe('EventSource', () => { diff --git a/packages/sdk/react-native/package.json b/packages/sdk/react-native/package.json index 2a045f012..6419af347 100644 --- a/packages/sdk/react-native/package.json +++ b/packages/sdk/react-native/package.json @@ -46,7 +46,6 @@ "base64-js": "^1.5.1" }, "devDependencies": { - "@launchdarkly/private-js-mocks": "0.0.1", "@testing-library/react": "^14.1.2", "@trivago/prettier-plugin-sort-imports": "^4.1.1", "@types/jest": "^29.5.11", diff --git a/packages/sdk/server-node/__tests__/LDClientNode.listeners.test.ts b/packages/sdk/server-node/__tests__/LDClientNode.listeners.test.ts index 182488b15..2a8fd8cce 100644 --- a/packages/sdk/server-node/__tests__/LDClientNode.listeners.test.ts +++ b/packages/sdk/server-node/__tests__/LDClientNode.listeners.test.ts @@ -1,15 +1,18 @@ -import { integrations } from '@launchdarkly/js-server-sdk-common'; -import { createLogger } from '@launchdarkly/private-js-mocks'; +import { integrations, LDLogger } from '@launchdarkly/js-server-sdk-common'; import { Context, LDClient } from '../src'; import LDClientNode from '../src/LDClientNode'; -let logger: ReturnType; +let logger: LDLogger; beforeEach(() => { - logger = createLogger(); + logger = { + error: jest.fn(), + warn: jest.fn(), + info: jest.fn(), + debug: jest.fn(), + }; }); - describe('given an LDClient with test data', () => { let client: LDClient; let td: integrations.TestData; diff --git a/packages/sdk/server-node/__tests__/LDClientNode.test.ts b/packages/sdk/server-node/__tests__/LDClientNode.test.ts index 28d8cb1d6..8de453297 100644 --- a/packages/sdk/server-node/__tests__/LDClientNode.test.ts +++ b/packages/sdk/server-node/__tests__/LDClientNode.test.ts @@ -1,12 +1,16 @@ -import { LDContext } from '@launchdarkly/js-server-sdk-common'; -import { createLogger } from '@launchdarkly/private-js-mocks'; +import { LDContext, LDLogger } from '@launchdarkly/js-server-sdk-common'; import { init } from '../src'; -let logger: ReturnType; +let logger: LDLogger; beforeEach(() => { - logger = createLogger(); + logger = { + error: jest.fn(), + warn: jest.fn(), + info: jest.fn(), + debug: jest.fn(), + }; }); it('fires ready event in offline mode', (done) => { diff --git a/packages/sdk/server-node/__tests__/LDClientNode.tls.test.ts b/packages/sdk/server-node/__tests__/LDClientNode.tls.test.ts index 2034b49f4..11454bb43 100644 --- a/packages/sdk/server-node/__tests__/LDClientNode.tls.test.ts +++ b/packages/sdk/server-node/__tests__/LDClientNode.tls.test.ts @@ -6,15 +6,18 @@ import { TestHttpServer, } from 'launchdarkly-js-test-helpers'; -import { createLogger } from '@launchdarkly/private-js-mocks'; - -import { LDClient } from '../src'; +import { LDClient, LDLogger } from '../src'; import LDClientNode from '../src/LDClientNode'; -let logger: ReturnType; +let logger: LDLogger; beforeEach(() => { - logger = createLogger(); + logger = { + error: jest.fn(), + warn: jest.fn(), + info: jest.fn(), + debug: jest.fn(), + }; }); describe('When using a TLS connection', () => { diff --git a/packages/sdk/server-node/package.json b/packages/sdk/server-node/package.json index a8d2958bd..eaceeedd9 100644 --- a/packages/sdk/server-node/package.json +++ b/packages/sdk/server-node/package.json @@ -50,7 +50,6 @@ "launchdarkly-eventsource": "2.0.3" }, "devDependencies": { - "@launchdarkly/private-js-mocks": "0.0.1", "@trivago/prettier-plugin-sort-imports": "^4.1.1", "@types/jest": "^29.4.0", "@typescript-eslint/eslint-plugin": "^6.20.0", diff --git a/packages/shared/mocks/src/contextDeduplicator.ts b/packages/shared/common/__tests__/contextDeduplicator.ts similarity index 82% rename from packages/shared/mocks/src/contextDeduplicator.ts rename to packages/shared/common/__tests__/contextDeduplicator.ts index b04d0d277..0c4ff2b8f 100644 --- a/packages/shared/mocks/src/contextDeduplicator.ts +++ b/packages/shared/common/__tests__/contextDeduplicator.ts @@ -1,4 +1,5 @@ -import type { Context, subsystem } from '@common'; +import { subsystem } from '../src/api'; +import Context from '../src/Context'; export default class ContextDeduplicator implements subsystem.LDContextDeduplicator { flushInterval?: number | undefined = 0.1; diff --git a/packages/shared/mocks/src/platform.ts b/packages/shared/common/__tests__/createBasicPlatform.ts similarity index 92% rename from packages/shared/mocks/src/platform.ts rename to packages/shared/common/__tests__/createBasicPlatform.ts index e3b0b9ecc..6b64d40dd 100644 --- a/packages/shared/mocks/src/platform.ts +++ b/packages/shared/common/__tests__/createBasicPlatform.ts @@ -1,6 +1,5 @@ -import type { PlatformData, SdkData } from '@common'; - -import { setupCrypto } from './crypto'; +import { PlatformData, SdkData } from '../src/api'; +import { setupCrypto } from './setupCrypto'; const setupInfo = () => ({ platformData: jest.fn( diff --git a/packages/shared/common/src/internal/diagnostics/DiagnosticsManager.test.ts b/packages/shared/common/__tests__/internal/diagnostics/DiagnosticsManager.test.ts similarity index 95% rename from packages/shared/common/src/internal/diagnostics/DiagnosticsManager.test.ts rename to packages/shared/common/__tests__/internal/diagnostics/DiagnosticsManager.test.ts index c73d02007..6cfa7b6a8 100644 --- a/packages/shared/common/src/internal/diagnostics/DiagnosticsManager.test.ts +++ b/packages/shared/common/__tests__/internal/diagnostics/DiagnosticsManager.test.ts @@ -1,6 +1,5 @@ -import { createBasicPlatform } from '@launchdarkly/private-js-mocks'; - -import DiagnosticsManager from './DiagnosticsManager'; +import DiagnosticsManager from '../../../src/internal/diagnostics/DiagnosticsManager'; +import { createBasicPlatform } from '../../createBasicPlatform'; describe('given a diagnostics manager', () => { const dateNowString = '2023-08-10'; diff --git a/packages/shared/common/__tests__/internal/events/EventProcessor.test.ts b/packages/shared/common/__tests__/internal/events/EventProcessor.test.ts index e972fa46e..82de97679 100644 --- a/packages/shared/common/__tests__/internal/events/EventProcessor.test.ts +++ b/packages/shared/common/__tests__/internal/events/EventProcessor.test.ts @@ -1,10 +1,5 @@ -import { - ContextDeduplicator, - createBasicPlatform, - createLogger, -} from '@launchdarkly/private-js-mocks'; - import { LDContextCommon, LDMultiKindContext } from '../../../src/api/context'; +import { LDLogger } from '../../../src/api/logging/LDLogger'; import { LDContextDeduplicator, LDDeliveryStatus, LDEventType } from '../../../src/api/subsystem'; import Context from '../../../src/Context'; import { EventProcessor, InputIdentifyEvent } from '../../../src/internal'; @@ -13,13 +8,20 @@ import shouldSample from '../../../src/internal/events/sampling'; import BasicLogger from '../../../src/logging/BasicLogger'; import format from '../../../src/logging/format'; import ClientContext from '../../../src/options/ClientContext'; +import ContextDeduplicator from '../../contextDeduplicator'; +import { createBasicPlatform } from '../../createBasicPlatform'; let mockPlatform: ReturnType; let clientContext: ClientContext; -let logger: ReturnType; +let logger: LDLogger; beforeEach(() => { - logger = createLogger(); + logger = { + error: jest.fn(), + warn: jest.fn(), + info: jest.fn(), + debug: jest.fn(), + }; mockPlatform = createBasicPlatform(); clientContext = { basicConfiguration: { diff --git a/packages/shared/common/src/internal/events/EventSender.test.ts b/packages/shared/common/__tests__/internal/events/EventSender.test.ts similarity index 84% rename from packages/shared/common/src/internal/events/EventSender.test.ts rename to packages/shared/common/__tests__/internal/events/EventSender.test.ts index 3bd27d77c..2e4c3f3dd 100644 --- a/packages/shared/common/src/internal/events/EventSender.test.ts +++ b/packages/shared/common/__tests__/internal/events/EventSender.test.ts @@ -1,21 +1,20 @@ -import { createBasicPlatform } from '@launchdarkly/private-js-mocks'; - -import { Info, PlatformData, SdkData } from '../../api'; -import { LDDeliveryStatus, LDEventSenderResult, LDEventType } from '../../api/subsystem'; -import { ApplicationTags, ClientContext } from '../../options'; -import EventSender from './EventSender'; +import { Info, PlatformData, SdkData } from '../../../src/api'; +import { LDDeliveryStatus, LDEventSenderResult, LDEventType } from '../../../src/api/subsystem'; +import EventSender from '../../../src/internal/events/EventSender'; +import { ApplicationTags, ClientContext } from '../../../src/options'; +import { createBasicPlatform } from '../../createBasicPlatform'; let mockPlatform: ReturnType; +function runWithTimers(fn: () => Promise) { + const promise = fn(); + return jest.runAllTimersAsync().then(() => promise); +} + beforeEach(() => { mockPlatform = createBasicPlatform(); }); -jest.mock('../../utils', () => { - const actual = jest.requireActual('../../utils'); - return { ...actual, sleep: jest.fn() }; -}); - const basicConfig = { tags: new ApplicationTags({ application: { id: 'testApplication1', version: '1.0.0' } }), serviceEndpoints: { @@ -120,9 +119,8 @@ describe('given an event sender', () => { }, ); - eventSenderResult = await eventSender.sendEventData( - LDEventType.AnalyticsEvents, - testEventData1, + eventSenderResult = await runWithTimers(() => + eventSender.sendEventData(LDEventType.AnalyticsEvents, testEventData1), ); }); @@ -142,9 +140,8 @@ describe('given an event sender', () => { it('includes the payload', async () => { const { status: status1 } = eventSenderResult; - const { status: status2 } = await eventSender.sendEventData( - LDEventType.DiagnosticEvent, - testEventData2, + const { status: status2 } = await runWithTimers(() => + eventSender.sendEventData(LDEventType.DiagnosticEvent, testEventData2), ); expect(status1).toEqual(LDDeliveryStatus.Succeeded); @@ -168,7 +165,9 @@ describe('given an event sender', () => { it('sends a unique payload for analytics events', async () => { // send the same request again to assert unique uuids - await eventSender.sendEventData(LDEventType.AnalyticsEvents, testEventData1); + await runWithTimers(() => + eventSender.sendEventData(LDEventType.AnalyticsEvents, testEventData1), + ); expect(mockFetch).toHaveBeenCalledTimes(2); expect(mockFetch).toHaveBeenNthCalledWith( @@ -190,9 +189,8 @@ describe('given an event sender', () => { describe.each([400, 408, 429, 503])('given recoverable errors', (responseStatusCode) => { beforeEach(async () => { setupMockFetch(responseStatusCode); - eventSenderResult = await eventSender.sendEventData( - LDEventType.AnalyticsEvents, - testEventData1, + eventSenderResult = await runWithTimers(() => + eventSender.sendEventData(LDEventType.AnalyticsEvents, testEventData1), ); }); @@ -210,9 +208,8 @@ describe('given an event sender', () => { it('given a result for too large of a payload', async () => { setupMockFetch(413); - eventSenderResult = await eventSender.sendEventData( - LDEventType.AnalyticsEvents, - testEventData1, + eventSenderResult = await runWithTimers(() => + eventSender.sendEventData(LDEventType.AnalyticsEvents, testEventData1), ); const errorMessage = `Received error 413 for event posting - giving up permanently`; @@ -228,9 +225,8 @@ describe('given an event sender', () => { describe.each([401, 403])('given unrecoverable errors', (responseStatusCode) => { beforeEach(async () => { setupMockFetch(responseStatusCode); - eventSenderResult = await eventSender.sendEventData( - LDEventType.AnalyticsEvents, - testEventData1, + eventSenderResult = await runWithTimers(() => + eventSender.sendEventData(LDEventType.AnalyticsEvents, testEventData1), ); }); diff --git a/packages/shared/common/src/internal/stream/StreamingProcessor.test.ts b/packages/shared/common/__tests__/internal/stream/StreamingProcessor.test.ts similarity index 92% rename from packages/shared/common/src/internal/stream/StreamingProcessor.test.ts rename to packages/shared/common/__tests__/internal/stream/StreamingProcessor.test.ts index 56f738da5..293e35124 100644 --- a/packages/shared/common/src/internal/stream/StreamingProcessor.test.ts +++ b/packages/shared/common/__tests__/internal/stream/StreamingProcessor.test.ts @@ -1,14 +1,13 @@ -import { createBasicPlatform, createLogger } from '@launchdarkly/private-js-mocks'; +import { EventName, Info, LDLogger, ProcessStreamResponse } from '../../../src/api'; +import { LDStreamProcessor } from '../../../src/api/subsystem'; +import { DataSourceErrorKind } from '../../../src/datasource/DataSourceErrorKinds'; +import { LDStreamingError } from '../../../src/datasource/errors'; +import { DiagnosticsManager } from '../../../src/internal/diagnostics'; +import StreamingProcessor from '../../../src/internal/stream/StreamingProcessor'; +import { defaultHeaders } from '../../../src/utils'; +import { createBasicPlatform } from '../../createBasicPlatform'; -import { EventName, Info, LDLogger, ProcessStreamResponse } from '../../api'; -import { LDStreamProcessor } from '../../api/subsystem'; -import { DataSourceErrorKind } from '../../datasource/DataSourceErrorKinds'; -import { LDStreamingError } from '../../datasource/errors'; -import { defaultHeaders } from '../../utils'; -import { DiagnosticsManager } from '../diagnostics'; -import StreamingProcessor from './StreamingProcessor'; - -let logger: ReturnType; +let logger: LDLogger; const serviceEndpoints = { events: '', @@ -44,7 +43,12 @@ let basicPlatform: any; beforeEach(() => { basicPlatform = createBasicPlatform(); - logger = createLogger(); + logger = { + error: jest.fn(), + warn: jest.fn(), + info: jest.fn(), + debug: jest.fn(), + }; }); const createMockEventSource = (streamUri: string = '', options: any = {}) => ({ diff --git a/packages/shared/common/__tests__/options/ApplicationTags.test.ts b/packages/shared/common/__tests__/options/ApplicationTags.test.ts index 51ae58449..ffc51b3d9 100644 --- a/packages/shared/common/__tests__/options/ApplicationTags.test.ts +++ b/packages/shared/common/__tests__/options/ApplicationTags.test.ts @@ -1,10 +1,16 @@ -import { createLogger } from '@launchdarkly/private-js-mocks'; - import ApplicationTags from '../../src/options/ApplicationTags'; describe.each([ [ - { application: { id: 'is-valid', version: 'also-valid' }, logger: createLogger() }, + { + application: { id: 'is-valid', version: 'also-valid' }, + logger: { + error: jest.fn(), + warn: jest.fn(), + info: jest.fn(), + debug: jest.fn(), + }, + }, 'application-id/is-valid application-version/also-valid', [], ], @@ -16,36 +22,105 @@ describe.each([ name: 'test-app-1', versionName: 'test-version-1', }, - logger: createLogger(), + logger: { + error: jest.fn(), + warn: jest.fn(), + info: jest.fn(), + debug: jest.fn(), + }, }, 'application-id/is-valid application-name/test-app-1 application-version/also-valid application-version-name/test-version-1', [], ], - [{ application: { id: 'is-valid' }, logger: createLogger() }, 'application-id/is-valid', []], [ - { application: { version: 'also-valid' }, logger: createLogger() }, + { + application: { id: 'is-valid' }, + logger: { + error: jest.fn(), + warn: jest.fn(), + info: jest.fn(), + debug: jest.fn(), + }, + }, + 'application-id/is-valid', + [], + ], + [ + { + application: { version: 'also-valid' }, + logger: { + error: jest.fn(), + warn: jest.fn(), + info: jest.fn(), + debug: jest.fn(), + }, + }, 'application-version/also-valid', [], ], - [{ application: {}, logger: createLogger() }, undefined, []], - [{ logger: createLogger() }, undefined, []], + [ + { + application: {}, + logger: { + error: jest.fn(), + warn: jest.fn(), + info: jest.fn(), + debug: jest.fn(), + }, + }, + undefined, + [], + ], + [ + { + logger: { + error: jest.fn(), + warn: jest.fn(), + info: jest.fn(), + debug: jest.fn(), + }, + }, + undefined, + [], + ], [undefined, undefined, []], // Above ones are 'valid' cases. Below are invalid. [ - { application: { id: 'bad tag' }, logger: createLogger() }, + { + application: { id: 'bad tag' }, + logger: { + error: jest.fn(), + warn: jest.fn(), + info: jest.fn(), + debug: jest.fn(), + }, + }, undefined, [/Config option "application.id" must/], ], [ - { application: { id: 'bad tag', version: 'good-tag' }, logger: createLogger() }, + { + application: { id: 'bad tag', version: 'good-tag' }, + logger: { + error: jest.fn(), + warn: jest.fn(), + info: jest.fn(), + debug: jest.fn(), + }, + }, 'application-version/good-tag', [/Config option "application.id" must/], ], [ { application: { id: 'bad tag', version: 'good-tag', name: '', versionName: 'test-version-1' }, - logger: createLogger(), + logger: { + error: jest.fn(), + warn: jest.fn(), + info: jest.fn(), + debug: jest.fn(), + }, }, 'application-version/good-tag application-version-name/test-version-1', [/Config option "application.id" must/, /Config option "application.name" must/], @@ -58,7 +133,12 @@ describe.each([ name: 'invalid name', versionName: 'invalid version name', }, - logger: createLogger(), + logger: { + error: jest.fn(), + warn: jest.fn(), + info: jest.fn(), + debug: jest.fn(), + }, }, undefined, [ diff --git a/packages/shared/mocks/src/crypto.ts b/packages/shared/common/__tests__/setupCrypto.ts similarity index 91% rename from packages/shared/mocks/src/crypto.ts rename to packages/shared/common/__tests__/setupCrypto.ts index 8a7d9a625..72b2d13ef 100644 --- a/packages/shared/mocks/src/crypto.ts +++ b/packages/shared/common/__tests__/setupCrypto.ts @@ -1,4 +1,4 @@ -import type { Hasher } from '@common'; +import { Hasher } from '../src/api'; export const setupCrypto = () => { let counter = 0; diff --git a/packages/shared/common/package.json b/packages/shared/common/package.json index 19de8318f..8c2f2e666 100644 --- a/packages/shared/common/package.json +++ b/packages/shared/common/package.json @@ -30,7 +30,6 @@ }, "license": "Apache-2.0", "devDependencies": { - "@launchdarkly/private-js-mocks": "0.0.1", "@trivago/prettier-plugin-sort-imports": "^4.1.1", "@types/jest": "^29.4.0", "@typescript-eslint/eslint-plugin": "^6.20.0", diff --git a/packages/shared/common/rollup.config.js b/packages/shared/common/rollup.config.js new file mode 100644 index 000000000..d8fb93ed9 --- /dev/null +++ b/packages/shared/common/rollup.config.js @@ -0,0 +1,43 @@ +import common from '@rollup/plugin-commonjs'; +import json from '@rollup/plugin-json'; +import resolve from '@rollup/plugin-node-resolve'; +import terser from '@rollup/plugin-terser'; +import typescript from '@rollup/plugin-typescript'; + +const getSharedConfig = (format, file) => ({ + input: 'src/index.ts', + output: [ + { + format: format, + sourcemap: true, + file: file, + }, + ], + onwarn: (warning) => { + if (warning.code !== 'CIRCULAR_DEPENDENCY') { + console.error(`(!) ${warning.message}`); + } + }, +}); + +export default [ + { + ...getSharedConfig('es', 'dist/index.es.js'), + plugins: [ + typescript({ + module: 'esnext', + }), + common({ + transformMixedEsModules: true, + esmExternals: true, + }), + resolve(), + terser(), + json(), + ], + }, + { + ...getSharedConfig('cjs', 'dist/index.cjs.js'), + plugins: [typescript(), common(), resolve(), terser(), json()], + }, +]; diff --git a/packages/shared/mocks/CHANGELOG.md b/packages/shared/mocks/CHANGELOG.md deleted file mode 100644 index cc1a5afb9..000000000 --- a/packages/shared/mocks/CHANGELOG.md +++ /dev/null @@ -1,3 +0,0 @@ -# Changelog - -All notable changes to `@launchdarkly/private-js-mocks` will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org). diff --git a/packages/shared/mocks/LICENSE b/packages/shared/mocks/LICENSE deleted file mode 100644 index ab8bd335b..000000000 --- a/packages/shared/mocks/LICENSE +++ /dev/null @@ -1,13 +0,0 @@ -Copyright 2023 Catamorphic, Co. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/packages/shared/mocks/README.md b/packages/shared/mocks/README.md deleted file mode 100644 index 2d178b398..000000000 --- a/packages/shared/mocks/README.md +++ /dev/null @@ -1,131 +0,0 @@ -# LaunchDarkly SDK JavaScript Mocks - -[![Actions Status][mocks-ci-badge]][mocks-ci] - -> [!CAUTION] -> Internal use only. -> This project contains JavaScript mocks that are consumed in unit tests in client-side and server-side JavaScript SDKs. - -## Installation - -This package is not published publicly. To use it internally, add the following line to your project's package.json -devDependencies. yarn workspace has been setup to recognize this package so this dependency should automatically work: - -```bash - "devDependencies": { - "@launchdarkly/private-js-mocks": "0.0.1", - ... -``` - -Then in your jest config add `@launchdarkly/private-js-mocks/setup` to setupFilesAfterEnv: - -```js -// jest.config.js or jest.config.json -module.exports = { - setupFilesAfterEnv: ['@launchdarkly/private-js-mocks/setup'], - ... -} -``` - -## Usage - -> [!IMPORTANT] -> basicPlatform and clientContext must be used inside a test because it's setup before each test. - -- `basicPlatform`: a concrete but basic implementation of [Platform](https://github.com/launchdarkly/js-core/blob/main/packages/shared/common/src/api/platform/Platform.ts). This is setup beforeEach so it must be used inside a test. - -- `clientContext`: ClientContext object including `basicPlatform` above. This is setup beforeEach so it must be used inside a test as well. - -- `hasher`: a Hasher object returned by `Crypto.createHash`. All functions in this object are jest mocks. This is exported - separately as a top level export because `Crypto` does not expose this publicly and we want to respect that. - -## Example - -```tsx -import { basicPlatform, clientContext, hasher } from '@launchdarkly/private-js-mocks'; - -// DOES NOT WORK: crypto is undefined because basicPlatform must be inside a test -// because it's setup by the package in beforeEach. -const { crypto } = basicPlatform; // DON'T DO THIS HERE - -// DOES NOT WORK: clientContext must be used inside a test. Otherwise all properties -// of it will be undefined. -const { - basicConfiguration: { serviceEndpoints, tags }, - platform: { info }, -} = clientContext; // DON'T DO THIS HERE - -describe('button', () => { - // DOES NOT WORK: again must be inside an actual test. At the test suite, - // level, beforeEach has not been run. - const { crypto } = basicPlatform; // DON'T DO THIS HERE - - // DO THIS - let crypto: Crypto; - let info: Info; - let serviceEndpoints: ServiceEndpoints; - let tags: ApplicationTags; - - beforeEach(() => { - // WORKS: basicPlatform and clientContext have been setup by the package. - ({ crypto, info } = basicPlatform); - - // WORKS - ({ - basicConfiguration: { serviceEndpoints, tags }, - platform: { info }, - } = clientContext); - }); - - afterEach(() => { - jest.resetAllMocks(); - }); - - it('hashes the correct string', () => { - // arrange - const bucketer = new Bucketer(crypto); - - // act - const [bucket, hadContext] = bucketer.bucket(); - - // assert - // WORKS - expect(crypto.createHash).toHaveBeenCalled(); - - // WORKS: alternatively you can just use the full path to access the properties - // of basicPlatform - expect(basicPlatform.crypto.createHash).toHaveBeenCalled(); - - // GOTCHA: hasher is a separte import from crypto to respect - // the public Crypto interface. - expect(hasher.update).toHaveBeenCalledWith(expected); - expect(hasher.digest).toHaveBeenCalledWith('hex'); - }); -}); -``` - -## Developing this package - -If you make changes to this package, you'll need to run `yarn build` in the `mocks` directory for changes to take effect. - -## Contributing - -See [Contributing](../shared/CONTRIBUTING.md). - -## About LaunchDarkly - -- LaunchDarkly is a continuous delivery platform that provides feature flags as a service and allows developers to iterate quickly and safely. We allow you to easily flag your features and manage them from the LaunchDarkly dashboard. With LaunchDarkly, you can: - - Roll out a new feature to a subset of your users (like a group of users who opt-in to a beta tester group), gathering feedback and bug reports from real-world use cases. - - Gradually roll out a feature to an increasing percentage of users, and track the effect that the feature has on key metrics (for instance, how likely is a user to complete a purchase if they have feature A versus feature B?). - - Turn off a feature that you realize is causing performance problems in production, without needing to re-deploy, or even restart the application with a changed configuration file. - - Grant access to certain features based on user attributes, like payment plan (eg: users on the ‘gold’ plan get access to more features than users in the ‘silver’ plan). - - Disable parts of your application to facilitate maintenance, without taking everything offline. -- LaunchDarkly provides feature flag SDKs for a wide variety of languages and technologies. Check out [our documentation](https://docs.launchdarkly.com/sdk) for a complete list. -- Explore LaunchDarkly - - [launchdarkly.com](https://www.launchdarkly.com/ 'LaunchDarkly Main Website') for more information - - [docs.launchdarkly.com](https://docs.launchdarkly.com/ 'LaunchDarkly Documentation') for our documentation and SDK reference guides - - [apidocs.launchdarkly.com](https://apidocs.launchdarkly.com/ 'LaunchDarkly API Documentation') for our API documentation - - [blog.launchdarkly.com](https://blog.launchdarkly.com/ 'LaunchDarkly Blog Documentation') for the latest product updates - -[mocks-ci-badge]: https://github.com/launchdarkly/js-core/actions/workflows/mocks.yml/badge.svg -[mocks-ci]: https://github.com/launchdarkly/js-core/actions/workflows/mocks.yml diff --git a/packages/shared/mocks/jest.config.js b/packages/shared/mocks/jest.config.js deleted file mode 100644 index 6753062cc..000000000 --- a/packages/shared/mocks/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - transform: { '^.+\\.ts?$': 'ts-jest' }, - testMatch: ['**/*.test.ts?(x)'], - testEnvironment: 'node', - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'], - collectCoverageFrom: ['src/**/*.ts'], -}; diff --git a/packages/shared/mocks/package.json b/packages/shared/mocks/package.json deleted file mode 100644 index 4ffdc0ba9..000000000 --- a/packages/shared/mocks/package.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "name": "@launchdarkly/private-js-mocks", - "private": true, - "version": "0.0.1", - "type": "commonjs", - "main": "./dist/index.js", - "types": "./dist/index.d.ts", - "exports": { - ".": "./dist/index.js" - }, - "homepage": "https://github.com/launchdarkly/js-core/tree/main/packages/shared/common", - "repository": { - "type": "git", - "url": "https://github.com/launchdarkly/js-core.git" - }, - "description": "LaunchDarkly SDK for JavaScript - mocks", - "files": [ - "dist" - ], - "keywords": [ - "mocks", - "unit", - "tests", - "launchdarkly", - "js", - "client" - ], - "scripts": { - "test": "", - "build-types": "yarn workspace @launchdarkly/js-sdk-common build-types", - "build": "yarn build-types && npx tsc", - "clean": "npx tsc --build --clean", - "lint": "npx eslint --ext .ts", - "lint:fix": "yarn run lint -- --fix" - }, - "license": "Apache-2.0", - "devDependencies": { - "@trivago/prettier-plugin-sort-imports": "^4.2.0", - "@types/jest": "^29.5.5", - "@typescript-eslint/eslint-plugin": "^6.20.0", - "@typescript-eslint/parser": "^6.20.0", - "eslint": "^8.50.0", - "eslint-config-airbnb-base": "^15.0.0", - "eslint-config-airbnb-typescript": "^17.1.0", - "eslint-config-prettier": "^9.0.0", - "eslint-plugin-import": "^2.28.1", - "eslint-plugin-jest": "^27.6.3", - "eslint-plugin-prettier": "^5.0.0", - "jest": "^29.7.0", - "launchdarkly-js-test-helpers": "^2.2.0", - "prettier": "^3.0.3", - "ts-jest": "^29.0.5", - "typescript": "^5.2.2" - } -} diff --git a/packages/shared/mocks/src/index.ts b/packages/shared/mocks/src/index.ts deleted file mode 100644 index 0fffd6117..000000000 --- a/packages/shared/mocks/src/index.ts +++ /dev/null @@ -1,15 +0,0 @@ -import ContextDeduplicator from './contextDeduplicator'; -import { MockEventProcessor, setupMockEventProcessor } from './eventProcessor'; -import { createLogger } from './logger'; -import { createBasicPlatform } from './platform'; -import { MockStreamingProcessor, setupMockStreamingProcessor } from './streamingProcessor'; - -export { - createLogger, - ContextDeduplicator, - MockEventProcessor, - setupMockEventProcessor, - MockStreamingProcessor, - setupMockStreamingProcessor, - createBasicPlatform, -}; diff --git a/packages/shared/mocks/src/logger.ts b/packages/shared/mocks/src/logger.ts deleted file mode 100644 index 80cb3e728..000000000 --- a/packages/shared/mocks/src/logger.ts +++ /dev/null @@ -1,6 +0,0 @@ -export const createLogger = () => ({ - error: jest.fn(), - warn: jest.fn(), - info: jest.fn(), - debug: jest.fn(), -}); diff --git a/packages/shared/mocks/tsconfig.eslint.json b/packages/shared/mocks/tsconfig.eslint.json deleted file mode 100644 index 56c9b3830..000000000 --- a/packages/shared/mocks/tsconfig.eslint.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "extends": "./tsconfig.json", - "include": ["/**/*.ts"], - "exclude": ["node_modules"] -} diff --git a/packages/shared/mocks/tsconfig.json b/packages/shared/mocks/tsconfig.json deleted file mode 100644 index 93b5f38e5..000000000 --- a/packages/shared/mocks/tsconfig.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "compilerOptions": { - "rootDir": "src", - "outDir": "dist", - "target": "ES2017", - "lib": ["es6"], - "module": "commonjs", - "strict": true, - "noImplicitOverride": true, - // Needed for CommonJS modules: markdown-it, fs-extra - "allowSyntheticDefaultImports": true, - "sourceMap": true, - "declaration": true, - "declarationMap": true, // enables importers to jump to source - "stripInternal": true, - "paths": { - "@common": ["../common"] - } - }, - "exclude": ["**/*.test.ts", "dist", "node_modules", "__tests__"], - "references": [ - { - "path": "../common" - } - ] -} diff --git a/packages/shared/mocks/tsconfig.ref.json b/packages/shared/mocks/tsconfig.ref.json deleted file mode 100644 index 0c86b2c55..000000000 --- a/packages/shared/mocks/tsconfig.ref.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "./tsconfig.json", - "include": ["src/**/*"], - "compilerOptions": { - "composite": true - } -} diff --git a/packages/shared/sdk-client/__tests__/LDClientImpl.events.test.ts b/packages/shared/sdk-client/__tests__/LDClientImpl.events.test.ts index 3b6c6a084..ca7b006e0 100644 --- a/packages/shared/sdk-client/__tests__/LDClientImpl.events.test.ts +++ b/packages/shared/sdk-client/__tests__/LDClientImpl.events.test.ts @@ -4,17 +4,15 @@ import { clone, internal, LDContext, + LDLogger, subsystem, } from '@launchdarkly/js-sdk-common'; -import { - createBasicPlatform, - createLogger, - MockEventProcessor, -} from '@launchdarkly/private-js-mocks'; import LDClientImpl from '../src/LDClientImpl'; import { Flags } from '../src/types'; +import { createBasicPlatform } from './createBasicPlatform'; import * as mockResponseJson from './evaluation/mockResponse.json'; +import { MockEventProcessor } from './eventProcessor'; import { MockEventSource } from './streaming/LDClientImpl.mocks'; import { makeTestDataManagerFactory } from './TestDataManager'; @@ -22,16 +20,21 @@ type InputCustomEvent = internal.InputCustomEvent; type InputIdentifyEvent = internal.InputIdentifyEvent; let mockPlatform: ReturnType; -let logger: ReturnType; +let logger: LDLogger; beforeEach(() => { mockPlatform = createBasicPlatform(); - logger = createLogger(); + logger = { + error: jest.fn(), + warn: jest.fn(), + info: jest.fn(), + debug: jest.fn(), + }; }); jest.mock('@launchdarkly/js-sdk-common', () => { const actual = jest.requireActual('@launchdarkly/js-sdk-common'); - const m = jest.requireActual('@launchdarkly/private-js-mocks'); + const m = jest.requireActual('./eventProcessor'); return { ...actual, ...{ diff --git a/packages/shared/sdk-client/__tests__/LDClientImpl.storage.test.ts b/packages/shared/sdk-client/__tests__/LDClientImpl.storage.test.ts index 863dcb5c0..4fe6fe50f 100644 --- a/packages/shared/sdk-client/__tests__/LDClientImpl.storage.test.ts +++ b/packages/shared/sdk-client/__tests__/LDClientImpl.storage.test.ts @@ -1,20 +1,25 @@ -import { AutoEnvAttributes, clone, type LDContext } from '@launchdarkly/js-sdk-common'; -import { createBasicPlatform, createLogger } from '@launchdarkly/private-js-mocks'; +import { AutoEnvAttributes, clone, type LDContext, LDLogger } from '@launchdarkly/js-sdk-common'; import { toMulti } from '../src/context/addAutoEnv'; import LDClientImpl from '../src/LDClientImpl'; import LDEmitter from '../src/LDEmitter'; import { Flags, PatchFlag } from '../src/types'; +import { createBasicPlatform } from './createBasicPlatform'; import * as mockResponseJson from './evaluation/mockResponse.json'; import { MockEventSource } from './streaming/LDClientImpl.mocks'; import { makeTestDataManagerFactory } from './TestDataManager'; let mockPlatform: ReturnType; -let logger: ReturnType; +let logger: LDLogger; beforeEach(() => { mockPlatform = createBasicPlatform(); - logger = createLogger(); + logger = { + error: jest.fn(), + warn: jest.fn(), + info: jest.fn(), + debug: jest.fn(), + }; }); const testSdkKey = 'test-sdk-key'; diff --git a/packages/shared/sdk-client/__tests__/LDClientImpl.test.ts b/packages/shared/sdk-client/__tests__/LDClientImpl.test.ts index 44b169e36..f6308e9cb 100644 --- a/packages/shared/sdk-client/__tests__/LDClientImpl.test.ts +++ b/packages/shared/sdk-client/__tests__/LDClientImpl.test.ts @@ -1,9 +1,9 @@ -import { AutoEnvAttributes, clone, Hasher, LDContext } from '@launchdarkly/js-sdk-common'; -import { createBasicPlatform, createLogger } from '@launchdarkly/private-js-mocks'; +import { AutoEnvAttributes, clone, Hasher, LDContext, LDLogger } from '@launchdarkly/js-sdk-common'; import { DataSourceState } from '../src/datasource/DataSourceStatus'; import LDClientImpl from '../src/LDClientImpl'; import { Flags } from '../src/types'; +import { createBasicPlatform } from './createBasicPlatform'; import * as mockResponseJson from './evaluation/mockResponse.json'; import { MockEventSource } from './streaming/LDClientImpl.mocks'; import { makeTestDataManagerFactory } from './TestDataManager'; @@ -32,7 +32,7 @@ describe('sdk-client object', () => { let simulatedEvents: { data?: any }[] = []; let defaultPutResponse: Flags; let mockPlatform: ReturnType; - let logger: ReturnType; + let logger: LDLogger; function onDataSourceChangePromise(numToAwait: number) { let countdown = numToAwait; @@ -49,7 +49,12 @@ describe('sdk-client object', () => { beforeEach(() => { mockPlatform = createBasicPlatform(); - logger = createLogger(); + logger = { + error: jest.fn(), + warn: jest.fn(), + info: jest.fn(), + debug: jest.fn(), + }; defaultPutResponse = clone(mockResponseJson); mockPlatform.crypto.randomUUID.mockReturnValue('random1'); const hasher = { diff --git a/packages/shared/sdk-client/__tests__/LDClientImpl.timeout.test.ts b/packages/shared/sdk-client/__tests__/LDClientImpl.timeout.test.ts index fd2bc60f5..51a1503e7 100644 --- a/packages/shared/sdk-client/__tests__/LDClientImpl.timeout.test.ts +++ b/packages/shared/sdk-client/__tests__/LDClientImpl.timeout.test.ts @@ -1,19 +1,24 @@ -import { AutoEnvAttributes, clone, LDContext } from '@launchdarkly/js-sdk-common'; -import { createBasicPlatform, createLogger } from '@launchdarkly/private-js-mocks'; +import { AutoEnvAttributes, clone, LDContext, LDLogger } from '@launchdarkly/js-sdk-common'; import { toMulti } from '../src/context/addAutoEnv'; import LDClientImpl from '../src/LDClientImpl'; import { Flags } from '../src/types'; +import { createBasicPlatform } from './createBasicPlatform'; import * as mockResponseJson from './evaluation/mockResponse.json'; import { MockEventSource } from './streaming/LDClientImpl.mocks'; import { makeTestDataManagerFactory } from './TestDataManager'; let mockPlatform: ReturnType; -let logger: ReturnType; +let logger: LDLogger; beforeEach(() => { mockPlatform = createBasicPlatform(); - logger = createLogger(); + logger = { + error: jest.fn(), + warn: jest.fn(), + info: jest.fn(), + debug: jest.fn(), + }; }); const testSdkKey = 'test-sdk-key'; diff --git a/packages/shared/sdk-client/__tests__/LDClientImpl.variation.test.ts b/packages/shared/sdk-client/__tests__/LDClientImpl.variation.test.ts index c360e33bd..257d1a10a 100644 --- a/packages/shared/sdk-client/__tests__/LDClientImpl.variation.test.ts +++ b/packages/shared/sdk-client/__tests__/LDClientImpl.variation.test.ts @@ -1,18 +1,29 @@ -import { AutoEnvAttributes, clone, Context, LDContext } from '@launchdarkly/js-sdk-common'; -import { createBasicPlatform, createLogger } from '@launchdarkly/private-js-mocks'; +import { + AutoEnvAttributes, + clone, + Context, + LDContext, + LDLogger, +} from '@launchdarkly/js-sdk-common'; import LDClientImpl from '../src/LDClientImpl'; import { Flags } from '../src/types'; +import { createBasicPlatform } from './createBasicPlatform'; import * as mockResponseJson from './evaluation/mockResponse.json'; import { MockEventSource } from './streaming/LDClientImpl.mocks'; import { makeTestDataManagerFactory } from './TestDataManager'; let mockPlatform: ReturnType; -let logger: ReturnType; +let logger: LDLogger; beforeEach(() => { mockPlatform = createBasicPlatform(); - logger = createLogger(); + logger = { + error: jest.fn(), + warn: jest.fn(), + info: jest.fn(), + debug: jest.fn(), + }; }); const testSdkKey = 'test-sdk-key'; diff --git a/packages/shared/sdk-client/__tests__/context/addAutoEnv.test.ts b/packages/shared/sdk-client/__tests__/context/addAutoEnv.test.ts index b686a3c1b..cc0759d86 100644 --- a/packages/shared/sdk-client/__tests__/context/addAutoEnv.test.ts +++ b/packages/shared/sdk-client/__tests__/context/addAutoEnv.test.ts @@ -2,10 +2,10 @@ import { Crypto, Info, type LDContext, + LDLogger, LDMultiKindContext, LDUser, } from '@launchdarkly/js-sdk-common'; -import { createBasicPlatform, createLogger } from '@launchdarkly/private-js-mocks'; import { Configuration, ConfigurationImpl } from '../../src/configuration'; import { @@ -14,13 +14,19 @@ import { addDeviceInfo, toMulti, } from '../../src/context/addAutoEnv'; +import { createBasicPlatform } from '../createBasicPlatform'; let mockPlatform: ReturnType; -let logger: ReturnType; +let logger: LDLogger; beforeEach(() => { mockPlatform = createBasicPlatform(); - logger = createLogger(); + logger = { + error: jest.fn(), + warn: jest.fn(), + info: jest.fn(), + debug: jest.fn(), + }; }); describe('automatic environment attributes', () => { diff --git a/packages/shared/sdk-client/__tests__/context/ensureKey.test.ts b/packages/shared/sdk-client/__tests__/context/ensureKey.test.ts index 2faf60177..60efb0e0a 100644 --- a/packages/shared/sdk-client/__tests__/context/ensureKey.test.ts +++ b/packages/shared/sdk-client/__tests__/context/ensureKey.test.ts @@ -5,9 +5,9 @@ import type { LDMultiKindContext, LDUser, } from '@launchdarkly/js-sdk-common'; -import { createBasicPlatform } from '@launchdarkly/private-js-mocks'; import { ensureKey } from '../../src/context/ensureKey'; +import { createBasicPlatform } from '../createBasicPlatform'; let mockPlatform: ReturnType; diff --git a/packages/shared/sdk-client/__tests__/createBasicPlatform.ts b/packages/shared/sdk-client/__tests__/createBasicPlatform.ts new file mode 100644 index 000000000..17178f061 --- /dev/null +++ b/packages/shared/sdk-client/__tests__/createBasicPlatform.ts @@ -0,0 +1,59 @@ +import { PlatformData, SdkData } from '@launchdarkly/js-sdk-common'; + +import { setupCrypto } from './setupCrypto'; + +const setupInfo = () => ({ + platformData: jest.fn( + (): PlatformData => ({ + os: { + name: 'An OS', + version: '1.0.1', + arch: 'An Arch', + }, + name: 'The SDK Name', + additional: { + nodeVersion: '42', + }, + ld_application: { + key: '', + envAttributesVersion: '1.0', + id: 'com.testapp.ld', + name: 'LDApplication.TestApp', + version: '1.1.1', + }, + ld_device: { + key: '', + envAttributesVersion: '1.0', + os: { name: 'Another OS', version: '99', family: 'orange' }, + manufacturer: 'coconut', + }, + }), + ), + sdkData: jest.fn( + (): SdkData => ({ + name: 'An SDK', + version: '2.0.2', + userAgentBase: 'TestUserAgent', + wrapperName: 'Rapper', + wrapperVersion: '1.2.3', + }), + ), +}); + +export const createBasicPlatform = () => ({ + encoding: { + btoa: (s: string) => Buffer.from(s).toString('base64'), + }, + info: setupInfo(), + crypto: setupCrypto(), + requests: { + fetch: jest.fn(), + createEventSource: jest.fn(), + getEventSourceCapabilities: jest.fn(), + }, + storage: { + get: jest.fn(), + set: jest.fn(), + clear: jest.fn(), + }, +}); diff --git a/packages/shared/mocks/src/eventProcessor.ts b/packages/shared/sdk-client/__tests__/eventProcessor.ts similarity index 85% rename from packages/shared/mocks/src/eventProcessor.ts rename to packages/shared/sdk-client/__tests__/eventProcessor.ts index ffa577e16..30fa70802 100644 --- a/packages/shared/mocks/src/eventProcessor.ts +++ b/packages/shared/sdk-client/__tests__/eventProcessor.ts @@ -1,4 +1,4 @@ -import type { ClientContext, internal, subsystem } from '@common'; +import { ClientContext, internal, subsystem } from '@launchdarkly/js-sdk-common'; export const MockEventProcessor = jest.fn(); diff --git a/packages/shared/sdk-client/__tests__/setupCrypto.ts b/packages/shared/sdk-client/__tests__/setupCrypto.ts new file mode 100644 index 000000000..fc8d0b460 --- /dev/null +++ b/packages/shared/sdk-client/__tests__/setupCrypto.ts @@ -0,0 +1,20 @@ +import { Hasher } from '@launchdarkly/js-sdk-common'; + +export const setupCrypto = () => { + let counter = 0; + const hasher = { + update: jest.fn((): Hasher => hasher), + digest: jest.fn(() => '1234567890123456'), + }; + + return { + createHash: jest.fn(() => hasher), + createHmac: jest.fn(), + randomUUID: jest.fn(() => { + counter += 1; + // Will provide a unique value for tests. + // Very much not a UUID of course. + return `${counter}`; + }), + }; +}; diff --git a/packages/shared/sdk-client/__tests__/storage/getOrGenerateKey.test.ts b/packages/shared/sdk-client/__tests__/storage/getOrGenerateKey.test.ts index 8065871ff..589f4e585 100644 --- a/packages/shared/sdk-client/__tests__/storage/getOrGenerateKey.test.ts +++ b/packages/shared/sdk-client/__tests__/storage/getOrGenerateKey.test.ts @@ -1,7 +1,7 @@ import { Crypto, Storage } from '@launchdarkly/js-sdk-common'; -import { createBasicPlatform } from '@launchdarkly/private-js-mocks'; import { getOrGenerateKey } from '../../src/storage/getOrGenerateKey'; +import { createBasicPlatform } from '../createBasicPlatform'; let mockPlatform: ReturnType; diff --git a/packages/shared/sdk-client/__tests__/streaming/StreamingProcessor.test.ts b/packages/shared/sdk-client/__tests__/streaming/StreamingProcessor.test.ts index 3ace5342b..f1d4eda76 100644 --- a/packages/shared/sdk-client/__tests__/streaming/StreamingProcessor.test.ts +++ b/packages/shared/sdk-client/__tests__/streaming/StreamingProcessor.test.ts @@ -5,15 +5,16 @@ import { EventName, Info, internal, + LDLogger, LDStreamingError, Platform, ProcessStreamResponse, } from '@launchdarkly/js-sdk-common'; -import { createBasicPlatform, createLogger } from '@launchdarkly/private-js-mocks'; import { StreamingDataSourceConfig, StreamingProcessor } from '../../src/streaming'; +import { createBasicPlatform } from '../createBasicPlatform'; -let logger: ReturnType; +let logger: LDLogger; const serviceEndpoints = { events: '', @@ -69,7 +70,12 @@ function getStreamingDataSourceConfig( beforeEach(() => { basicPlatform = createBasicPlatform(); - logger = createLogger(); + logger = { + error: jest.fn(), + warn: jest.fn(), + info: jest.fn(), + debug: jest.fn(), + }; }); const createMockEventSource = (streamUri: string = '', options: any = {}) => ({ diff --git a/packages/shared/sdk-client/package.json b/packages/shared/sdk-client/package.json index 9d79dc224..c651eda60 100644 --- a/packages/shared/sdk-client/package.json +++ b/packages/shared/sdk-client/package.json @@ -33,7 +33,6 @@ "@launchdarkly/js-sdk-common": "2.9.0" }, "devDependencies": { - "@launchdarkly/private-js-mocks": "0.0.1", "@testing-library/dom": "^9.3.1", "@testing-library/jest-dom": "^5.16.5", "@types/jest": "^29.5.3", diff --git a/packages/shared/sdk-client/rollup.config.js b/packages/shared/sdk-client/rollup.config.js new file mode 100644 index 000000000..d8fb93ed9 --- /dev/null +++ b/packages/shared/sdk-client/rollup.config.js @@ -0,0 +1,43 @@ +import common from '@rollup/plugin-commonjs'; +import json from '@rollup/plugin-json'; +import resolve from '@rollup/plugin-node-resolve'; +import terser from '@rollup/plugin-terser'; +import typescript from '@rollup/plugin-typescript'; + +const getSharedConfig = (format, file) => ({ + input: 'src/index.ts', + output: [ + { + format: format, + sourcemap: true, + file: file, + }, + ], + onwarn: (warning) => { + if (warning.code !== 'CIRCULAR_DEPENDENCY') { + console.error(`(!) ${warning.message}`); + } + }, +}); + +export default [ + { + ...getSharedConfig('es', 'dist/index.es.js'), + plugins: [ + typescript({ + module: 'esnext', + }), + common({ + transformMixedEsModules: true, + esmExternals: true, + }), + resolve(), + terser(), + json(), + ], + }, + { + ...getSharedConfig('cjs', 'dist/index.cjs.js'), + plugins: [typescript(), common(), resolve(), terser(), json()], + }, +]; diff --git a/packages/shared/sdk-server-edge/__tests__/api/LDClient.test.ts b/packages/shared/sdk-server-edge/__tests__/api/LDClient.test.ts index 617375778..26bad83fa 100644 --- a/packages/shared/sdk-server-edge/__tests__/api/LDClient.test.ts +++ b/packages/shared/sdk-server-edge/__tests__/api/LDClient.test.ts @@ -1,7 +1,7 @@ import { internal } from '@launchdarkly/js-server-sdk-common'; -import { createBasicPlatform } from '@launchdarkly/private-js-mocks'; import LDClient from '../../src/api/LDClient'; +import { createBasicPlatform } from '../createBasicPlatform'; jest.mock('@launchdarkly/js-sdk-common', () => { const actual = jest.requireActual('@launchdarkly/js-sdk-common'); diff --git a/packages/shared/sdk-server-edge/__tests__/api/createCallbacks.test.ts b/packages/shared/sdk-server-edge/__tests__/api/createCallbacks.test.ts index 957542a6c..665f3f19b 100644 --- a/packages/shared/sdk-server-edge/__tests__/api/createCallbacks.test.ts +++ b/packages/shared/sdk-server-edge/__tests__/api/createCallbacks.test.ts @@ -1,16 +1,19 @@ import { EventEmitter } from 'node:events'; -import { noop } from '@launchdarkly/js-server-sdk-common'; -import { createLogger } from '@launchdarkly/private-js-mocks'; +import { LDLogger, noop } from '@launchdarkly/js-server-sdk-common'; import createCallbacks from '../../src/api/createCallbacks'; -let logger: ReturnType; +let logger: LDLogger; beforeEach(() => { - logger = createLogger(); + logger = { + error: jest.fn(), + warn: jest.fn(), + info: jest.fn(), + debug: jest.fn(), + }; }); - describe('createCallbacks', () => { let emitter: EventEmitter; const err = new Error('test error'); diff --git a/packages/shared/sdk-server-edge/__tests__/createBasicPlatform.ts b/packages/shared/sdk-server-edge/__tests__/createBasicPlatform.ts new file mode 100644 index 000000000..e5139ccec --- /dev/null +++ b/packages/shared/sdk-server-edge/__tests__/createBasicPlatform.ts @@ -0,0 +1,59 @@ +import { PlatformData, SdkData } from '@launchdarkly/js-server-sdk-common'; + +import { setupCrypto } from './setupCrypto'; + +const setupInfo = () => ({ + platformData: jest.fn( + (): PlatformData => ({ + os: { + name: 'An OS', + version: '1.0.1', + arch: 'An Arch', + }, + name: 'The SDK Name', + additional: { + nodeVersion: '42', + }, + ld_application: { + key: '', + envAttributesVersion: '1.0', + id: 'com.testapp.ld', + name: 'LDApplication.TestApp', + version: '1.1.1', + }, + ld_device: { + key: '', + envAttributesVersion: '1.0', + os: { name: 'Another OS', version: '99', family: 'orange' }, + manufacturer: 'coconut', + }, + }), + ), + sdkData: jest.fn( + (): SdkData => ({ + name: 'An SDK', + version: '2.0.2', + userAgentBase: 'TestUserAgent', + wrapperName: 'Rapper', + wrapperVersion: '1.2.3', + }), + ), +}); + +export const createBasicPlatform = () => ({ + encoding: { + btoa: (s: string) => Buffer.from(s).toString('base64'), + }, + info: setupInfo(), + crypto: setupCrypto(), + requests: { + fetch: jest.fn(), + createEventSource: jest.fn(), + getEventSourceCapabilities: jest.fn(), + }, + storage: { + get: jest.fn(), + set: jest.fn(), + clear: jest.fn(), + }, +}); diff --git a/packages/shared/sdk-server-edge/__tests__/setupCrypto.ts b/packages/shared/sdk-server-edge/__tests__/setupCrypto.ts new file mode 100644 index 000000000..bdf62024f --- /dev/null +++ b/packages/shared/sdk-server-edge/__tests__/setupCrypto.ts @@ -0,0 +1,20 @@ +import { Hasher } from '@launchdarkly/js-server-sdk-common'; + +export const setupCrypto = () => { + let counter = 0; + const hasher = { + update: jest.fn((): Hasher => hasher), + digest: jest.fn(() => '1234567890123456'), + }; + + return { + createHash: jest.fn(() => hasher), + createHmac: jest.fn(), + randomUUID: jest.fn(() => { + counter += 1; + // Will provide a unique value for tests. + // Very much not a UUID of course. + return `${counter}`; + }), + }; +}; diff --git a/packages/shared/sdk-server-edge/package.json b/packages/shared/sdk-server-edge/package.json index 25fcb5538..5c4044f9c 100644 --- a/packages/shared/sdk-server-edge/package.json +++ b/packages/shared/sdk-server-edge/package.json @@ -40,7 +40,6 @@ "crypto-js": "^4.1.1" }, "devDependencies": { - "@launchdarkly/private-js-mocks": "0.0.1", "@trivago/prettier-plugin-sort-imports": "^4.1.1", "@types/crypto-js": "^4.1.1", "@types/jest": "^29.5.0", diff --git a/packages/shared/sdk-server/__tests__/LDClient.allFlags.test.ts b/packages/shared/sdk-server/__tests__/LDClient.allFlags.test.ts index 9903eb51d..585c6a9b5 100644 --- a/packages/shared/sdk-server/__tests__/LDClient.allFlags.test.ts +++ b/packages/shared/sdk-server/__tests__/LDClient.allFlags.test.ts @@ -1,7 +1,6 @@ -import { createBasicPlatform } from '@launchdarkly/private-js-mocks'; - import { LDClientImpl } from '../src'; import TestData from '../src/integrations/test_data/TestData'; +import { createBasicPlatform } from './createBasicPlatform'; import TestLogger, { LogLevel } from './Logger'; import makeCallbacks from './makeCallbacks'; @@ -16,7 +15,7 @@ describe('given an LDClient with test data', () => { logger = new TestLogger(); td = new TestData(); client = new LDClientImpl( - 'sdk-key', + 'sdk-key-all-flags-test-data', createBasicPlatform(), { updateProcessor: td.getFactory(), @@ -280,7 +279,7 @@ describe('given an offline client', () => { logger = new TestLogger(); td = new TestData(); client = new LDClientImpl( - 'sdk-key', + 'sdk-key-all-flags-offline', createBasicPlatform(), { offline: true, diff --git a/packages/shared/sdk-server/__tests__/LDClient.evaluation.test.ts b/packages/shared/sdk-server/__tests__/LDClient.evaluation.test.ts index 2ef0d660d..a57dc8599 100644 --- a/packages/shared/sdk-server/__tests__/LDClient.evaluation.test.ts +++ b/packages/shared/sdk-server/__tests__/LDClient.evaluation.test.ts @@ -1,31 +1,14 @@ import { subsystem } from '@launchdarkly/js-sdk-common'; -import { - createBasicPlatform, - MockStreamingProcessor, - setupMockStreamingProcessor, -} from '@launchdarkly/private-js-mocks'; import { LDClientImpl, LDFeatureStore } from '../src'; import TestData from '../src/integrations/test_data/TestData'; import AsyncStoreFacade from '../src/store/AsyncStoreFacade'; import InMemoryFeatureStore from '../src/store/InMemoryFeatureStore'; import VersionedDataKinds from '../src/store/VersionedDataKinds'; +import { createBasicPlatform } from './createBasicPlatform'; import TestLogger, { LogLevel } from './Logger'; import makeCallbacks from './makeCallbacks'; -jest.mock('@launchdarkly/js-sdk-common', () => { - const actual = jest.requireActual('@launchdarkly/js-sdk-common'); - return { - ...actual, - ...{ - internal: { - ...actual.internal, - StreamingProcessor: MockStreamingProcessor, - }, - }, - }; -}); - const defaultUser = { key: 'user' }; describe('given an LDClient with test data', () => { @@ -35,7 +18,7 @@ describe('given an LDClient with test data', () => { beforeEach(async () => { td = new TestData(); client = new LDClientImpl( - 'sdk-key', + 'sdk-key-evaluation-test-data', createBasicPlatform(), { updateProcessor: td.getFactory(), @@ -281,7 +264,7 @@ describe('given an offline client', () => { logger = new TestLogger(); td = new TestData(); client = new LDClientImpl( - 'sdk-key', + 'sdk-key-evaluation-offline', createBasicPlatform(), { offline: true, @@ -345,7 +328,7 @@ describe('given a client and store that are uninitialized', () => { }); client = new LDClientImpl( - 'sdk-key', + 'sdk-key-evaluation-uninitialized-store', createBasicPlatform(), { updateProcessor: new InertUpdateProcessor(), @@ -392,14 +375,18 @@ describe('given a client that is un-initialized and store that is initialized', }, segments: {}, }); - setupMockStreamingProcessor(true); client = new LDClientImpl( - 'sdk-key', + 'sdk-key-initialized-store', createBasicPlatform(), { sendEvents: false, featureStore: store, + updateProcessor: () => ({ + start: jest.fn(), + stop: jest.fn(), + close: jest.fn(), + }), }, makeCallbacks(true), ); diff --git a/packages/shared/sdk-server/__tests__/LDClient.events.test.ts b/packages/shared/sdk-server/__tests__/LDClient.events.test.ts index 075fb5802..5d1cdd84e 100644 --- a/packages/shared/sdk-server/__tests__/LDClient.events.test.ts +++ b/packages/shared/sdk-server/__tests__/LDClient.events.test.ts @@ -1,10 +1,10 @@ import { AsyncQueue } from 'launchdarkly-js-test-helpers'; import { Context, internal } from '@launchdarkly/js-sdk-common'; -import { createBasicPlatform } from '@launchdarkly/private-js-mocks'; import { LDClientImpl } from '../src'; import TestData from '../src/integrations/test_data/TestData'; +import { createBasicPlatform } from './createBasicPlatform'; import TestLogger, { LogLevel } from './Logger'; import makeCallbacks from './makeCallbacks'; @@ -29,7 +29,7 @@ describe('given a client with mock event processor', () => { td = new TestData(); client = new LDClientImpl( - 'sdk-key', + 'sdk-key-events', createBasicPlatform(), { updateProcessor: td.getFactory(), diff --git a/packages/shared/sdk-server/__tests__/LDClient.hooks.test.ts b/packages/shared/sdk-server/__tests__/LDClient.hooks.test.ts index b108a71d2..929d8f67a 100644 --- a/packages/shared/sdk-server/__tests__/LDClient.hooks.test.ts +++ b/packages/shared/sdk-server/__tests__/LDClient.hooks.test.ts @@ -1,8 +1,7 @@ -import { createBasicPlatform } from '@launchdarkly/private-js-mocks'; - import { LDClientImpl, LDMigrationStage } from '../src'; import Reasons from '../src/evaluation/Reasons'; import TestData from '../src/integrations/test_data/TestData'; +import { createBasicPlatform } from './createBasicPlatform'; import { TestHook } from './hooks/TestHook'; import TestLogger from './Logger'; import makeCallbacks from './makeCallbacks'; @@ -20,7 +19,7 @@ describe('given an LDClient with test data', () => { testHook = new TestHook(); td = new TestData(); client = new LDClientImpl( - 'sdk-key', + 'sdk-key-hooks-test-data', createBasicPlatform(), { updateProcessor: td.getFactory(), @@ -351,7 +350,7 @@ it('can add a hook after initialization', async () => { const logger = new TestLogger(); const td = new TestData(); const client = new LDClientImpl( - 'sdk-key', + 'sdk-key-hook-after-init', createBasicPlatform(), { updateProcessor: td.getFactory(), diff --git a/packages/shared/sdk-server/__tests__/LDClient.migrations.test.ts b/packages/shared/sdk-server/__tests__/LDClient.migrations.test.ts index d494245a7..3a5df82a4 100644 --- a/packages/shared/sdk-server/__tests__/LDClient.migrations.test.ts +++ b/packages/shared/sdk-server/__tests__/LDClient.migrations.test.ts @@ -1,8 +1,7 @@ -import { createBasicPlatform } from '@launchdarkly/private-js-mocks'; - import { LDClientImpl, LDMigrationStage } from '../src'; import TestData from '../src/integrations/test_data/TestData'; import { LDClientCallbacks } from '../src/LDClientImpl'; +import { createBasicPlatform } from './createBasicPlatform'; /** * Basic callback handler that records errors for tests. @@ -33,7 +32,7 @@ describe('given an LDClient with test data', () => { td = new TestData(); [errors, callbacks] = makeCallbacks(); client = new LDClientImpl( - 'sdk-key', + 'sdk-key-migration', createBasicPlatform(), { updateProcessor: td.getFactory(), diff --git a/packages/shared/sdk-server/__tests__/LDClientImpl.bigSegments.test.ts b/packages/shared/sdk-server/__tests__/LDClientImpl.bigSegments.test.ts index 471121256..9015cc338 100644 --- a/packages/shared/sdk-server/__tests__/LDClientImpl.bigSegments.test.ts +++ b/packages/shared/sdk-server/__tests__/LDClientImpl.bigSegments.test.ts @@ -1,11 +1,11 @@ import { Crypto, Hasher, Hmac } from '@launchdarkly/js-sdk-common'; -import { createBasicPlatform } from '@launchdarkly/private-js-mocks'; import { LDBigSegmentsOptions } from '../src'; import { BigSegmentStore } from '../src/api/interfaces'; import makeBigSegmentRef from '../src/evaluation/makeBigSegmentRef'; import TestData from '../src/integrations/test_data/TestData'; import LDClientImpl from '../src/LDClientImpl'; +import { createBasicPlatform } from './createBasicPlatform'; import { makeSegmentMatchClause } from './evaluation/flags'; import makeCallbacks from './makeCallbacks'; @@ -75,7 +75,7 @@ describe('given test data with big segments', () => { }; client = new LDClientImpl( - 'sdk-key', + 'sdk-key-big-segments-test-data', { ...createBasicPlatform(), crypto }, { updateProcessor: td.getFactory(), @@ -114,7 +114,7 @@ describe('given test data with big segments', () => { }; client = new LDClientImpl( - 'sdk-key', + 'sdk-key-big-segments-with-user', { ...createBasicPlatform(), crypto }, { updateProcessor: td.getFactory(), @@ -153,7 +153,7 @@ describe('given test data with big segments', () => { }; client = new LDClientImpl( - 'sdk-key', + 'sdk-key-big-segments-store-error', { ...createBasicPlatform(), crypto }, { updateProcessor: td.getFactory(), @@ -180,7 +180,7 @@ describe('given test data with big segments', () => { describe('given a client without big segment support.', () => { beforeEach(async () => { client = new LDClientImpl( - 'sdk-key', + 'sdk-key-big-segments-no-store', { ...createBasicPlatform(), crypto }, { updateProcessor: td.getFactory(), diff --git a/packages/shared/sdk-server/__tests__/LDClientImpl.listeners.test.ts b/packages/shared/sdk-server/__tests__/LDClientImpl.listeners.test.ts index a97b7c083..d32ef6d24 100644 --- a/packages/shared/sdk-server/__tests__/LDClientImpl.listeners.test.ts +++ b/packages/shared/sdk-server/__tests__/LDClientImpl.listeners.test.ts @@ -1,10 +1,9 @@ import { AsyncQueue } from 'launchdarkly-js-test-helpers'; -import { createBasicPlatform } from '@launchdarkly/private-js-mocks'; - import { AttributeReference, LDClientImpl } from '../src'; import { Op } from '../src/evaluation/data/Clause'; import TestData from '../src/integrations/test_data/TestData'; +import { createBasicPlatform } from './createBasicPlatform'; import { makeFlagWithSegmentMatch } from './evaluation/flags'; import TestLogger from './Logger'; import makeCallbacks from './makeCallbacks'; @@ -18,7 +17,7 @@ describe('given an LDClient with test data', () => { queue = new AsyncQueue(); td = new TestData(); client = new LDClientImpl( - 'sdk-key', + 'sdk-key-listeners', createBasicPlatform(), { updateProcessor: td.getFactory(), diff --git a/packages/shared/sdk-server/__tests__/LDClientImpl.test.ts b/packages/shared/sdk-server/__tests__/LDClientImpl.test.ts index 4995ebc6b..34d97823d 100644 --- a/packages/shared/sdk-server/__tests__/LDClientImpl.test.ts +++ b/packages/shared/sdk-server/__tests__/LDClientImpl.test.ts @@ -1,24 +1,46 @@ -import { - createBasicPlatform, - MockStreamingProcessor, - setupMockStreamingProcessor, -} from '@launchdarkly/private-js-mocks'; +import { LDClientContext, LDStreamingError } from '@launchdarkly/js-sdk-common'; -import { LDClientImpl, LDOptions } from '../src'; +import { LDOptions } from '../src/api/options/LDOptions'; +import { LDFeatureStore } from '../src/api/subsystems/LDFeatureStore'; +import LDClientImpl from '../src/LDClientImpl'; +import { createBasicPlatform } from './createBasicPlatform'; import TestLogger, { LogLevel } from './Logger'; -jest.mock('@launchdarkly/js-sdk-common', () => { - const actual = jest.requireActual('@launchdarkly/js-sdk-common'); - return { - ...actual, - ...{ - internal: { - ...actual.internal, - StreamingProcessor: MockStreamingProcessor, - }, - }, - }; -}); +function getUpdateProcessorFactory(shouldError: boolean = false, initTimeoutMs: number = 0) { + let initTimeoutHandle: any; + let patchTimeoutHandle: any; + let deleteTimeoutHandle: any; + + return ( + _clientContext: LDClientContext, + featureStore: LDFeatureStore, + initSuccessHandler: Function, + errorHandler?: (e: Error) => void, + ) => ({ + start: jest.fn(async () => { + if (shouldError) { + initTimeoutHandle = setTimeout(() => { + const unauthorized = new Error('test-error') as LDStreamingError; + // @ts-ignore + unauthorized.code = 401; + errorHandler?.(unauthorized); + }, 0); + } else { + // execute put which will resolve the identify promise + initTimeoutHandle = setTimeout(() => { + featureStore.init({}, () => {}); + initSuccessHandler(); + }, initTimeoutMs); + } + }), + close: jest.fn(() => { + clearTimeout(initTimeoutHandle); + clearTimeout(patchTimeoutHandle); + clearTimeout(deleteTimeoutHandle); + }), + eventSource: {}, + }); +} describe('LDClientImpl', () => { let client: LDClientImpl; @@ -30,11 +52,7 @@ describe('LDClientImpl', () => { hasEventListeners: jest.fn().mockName('hasEventListeners'), }; const createClient = (options: LDOptions = {}) => - new LDClientImpl('sdk-key', createBasicPlatform(), options, callbacks); - - beforeEach(() => { - setupMockStreamingProcessor(); - }); + new LDClientImpl('sdk-key-ldclientimpl.test', createBasicPlatform(), options, callbacks); afterEach(() => { client.close(); @@ -42,7 +60,7 @@ describe('LDClientImpl', () => { }); it('fires ready event in online mode', async () => { - client = createClient(); + client = createClient({ updateProcessor: getUpdateProcessorFactory() }); const initializedClient = await client.waitForInitialization({ timeout: 10 }); expect(initializedClient).toEqual(client); @@ -53,8 +71,7 @@ describe('LDClientImpl', () => { }); it('wait for initialization completes even if initialization completes before it is called', (done) => { - setupMockStreamingProcessor(); - client = createClient(); + client = createClient({ updateProcessor: getUpdateProcessorFactory() }); setTimeout(async () => { const initializedClient = await client.waitForInitialization({ timeout: 10 }); @@ -64,7 +81,7 @@ describe('LDClientImpl', () => { }); it('waiting for initialization the second time produces the same result', async () => { - client = createClient(); + client = createClient({ updateProcessor: getUpdateProcessorFactory() }); await client.waitForInitialization({ timeout: 10 }); const initializedClient = await client.waitForInitialization({ timeout: 10 }); @@ -83,9 +100,7 @@ describe('LDClientImpl', () => { }); it('initialization fails: failed event fires and initialization promise rejects', async () => { - setupMockStreamingProcessor(true); - client = createClient(); - + client = createClient({ updateProcessor: getUpdateProcessorFactory(true) }); await expect(client.waitForInitialization({ timeout: 10 })).rejects.toThrow('failed'); expect(client.initialized()).toBeFalsy(); @@ -95,8 +110,7 @@ describe('LDClientImpl', () => { }); it('initialization promise is rejected even if the failure happens before wait is called', (done) => { - setupMockStreamingProcessor(true); - client = createClient(); + client = createClient({ updateProcessor: getUpdateProcessorFactory(true) }); setTimeout(async () => { await expect(client.waitForInitialization({ timeout: 10 })).rejects.toThrow('failed'); @@ -110,8 +124,7 @@ describe('LDClientImpl', () => { }); it('waiting a second time results in the same rejection', async () => { - setupMockStreamingProcessor(true); - client = createClient(); + client = createClient({ updateProcessor: getUpdateProcessorFactory(true) }); await expect(client.waitForInitialization({ timeout: 10 })).rejects.toThrow('failed'); await expect(client.waitForInitialization({ timeout: 10 })).rejects.toThrow('failed'); @@ -128,13 +141,13 @@ describe('LDClientImpl', () => { }); it('resolves immediately if the client is already ready', async () => { - client = createClient(); + client = createClient({ updateProcessor: getUpdateProcessorFactory() }); await client.waitForInitialization({ timeout: 10 }); await client.waitForInitialization({ timeout: 10 }); }); it('creates only one Promise when waiting for initialization - when not using a timeout', async () => { - client = createClient(); + client = createClient({ updateProcessor: getUpdateProcessorFactory() }); const p1 = client.waitForInitialization(); const p2 = client.waitForInitialization(); @@ -142,17 +155,20 @@ describe('LDClientImpl', () => { }); it('rejects the returned promise when initialization does not complete within the timeout', async () => { - setupMockStreamingProcessor(undefined, undefined, undefined, undefined, undefined, 10000); - client = createClient(); + client = createClient({ + updateProcessor: getUpdateProcessorFactory(false, 10000), + }); await expect(async () => client.waitForInitialization({ timeout: 1 })).rejects.toThrow( 'waitForInitialization timed out after 1 seconds.', ); }); it('logs an error when the initialization does not complete within the timeout', async () => { - setupMockStreamingProcessor(undefined, undefined, undefined, undefined, undefined, 10000); const logger = new TestLogger(); - client = createClient({ logger }); + client = createClient({ + logger, + updateProcessor: getUpdateProcessorFactory(false, 10000), + }); try { await client.waitForInitialization({ timeout: 1 }); } catch { @@ -167,14 +183,18 @@ describe('LDClientImpl', () => { }); it('does not reject the returned promise when initialization completes within the timeout', async () => { - setupMockStreamingProcessor(undefined, undefined, undefined, undefined, undefined, 1000); - client = createClient(); - await expect(async () => client.waitForInitialization({ timeout: 5 })).not.toThrow(); + client = createClient({ + updateProcessor: getUpdateProcessorFactory(false, 100), + }); + await expect(client.waitForInitialization({ timeout: 3 })).resolves.not.toThrow(); }); it('logs when no timeout is set', async () => { const logger = new TestLogger(); - client = createClient({ logger }); + client = createClient({ + logger, + updateProcessor: getUpdateProcessorFactory(), + }); await client.waitForInitialization(); logger.expectMessages([ { @@ -187,7 +207,10 @@ describe('LDClientImpl', () => { it('logs when the timeout is too high', async () => { const logger = new TestLogger(); - client = createClient({ logger }); + client = createClient({ + logger, + updateProcessor: getUpdateProcessorFactory(), + }); await client.waitForInitialization({ timeout: Number.MAX_SAFE_INTEGER }); logger.expectMessages([ @@ -203,7 +226,7 @@ describe('LDClientImpl', () => { 'does not log when timeout is under high timeout threshold', async (timeout) => { const logger = new TestLogger(); - client = createClient({ logger }); + client = createClient({ logger, updateProcessor: getUpdateProcessorFactory() }); await client.waitForInitialization({ timeout }); expect(logger.getCount(LogLevel.Warn)).toBe(0); }, diff --git a/packages/shared/sdk-server/__tests__/Migration.test.ts b/packages/shared/sdk-server/__tests__/Migration.test.ts index 6434ec5f5..06db9a688 100644 --- a/packages/shared/sdk-server/__tests__/Migration.test.ts +++ b/packages/shared/sdk-server/__tests__/Migration.test.ts @@ -1,5 +1,3 @@ -import { createBasicPlatform } from '@launchdarkly/private-js-mocks'; - import { LDClientImpl, LDConcurrentExecution, @@ -10,6 +8,7 @@ import { import { TestData } from '../src/integrations'; import { LDClientCallbacks } from '../src/LDClientImpl'; import { createMigration, LDMigrationError, LDMigrationSuccess } from '../src/Migration'; +import { createBasicPlatform } from './createBasicPlatform'; import makeCallbacks from './makeCallbacks'; describe('given an LDClient with test data', () => { @@ -21,7 +20,7 @@ describe('given an LDClient with test data', () => { td = new TestData(); callbacks = makeCallbacks(false); client = new LDClientImpl( - 'sdk-key', + 'sdk-key-migration', createBasicPlatform(), { updateProcessor: td.getFactory(), diff --git a/packages/shared/sdk-server/__tests__/MigrationOpEvent.test.ts b/packages/shared/sdk-server/__tests__/MigrationOpEvent.test.ts index f3b60b406..435c45a70 100644 --- a/packages/shared/sdk-server/__tests__/MigrationOpEvent.test.ts +++ b/packages/shared/sdk-server/__tests__/MigrationOpEvent.test.ts @@ -1,7 +1,6 @@ import { AsyncQueue } from 'launchdarkly-js-test-helpers'; import { internal } from '@launchdarkly/js-sdk-common'; -import { createBasicPlatform } from '@launchdarkly/private-js-mocks'; import { LDClientImpl, @@ -16,6 +15,7 @@ import { TestData } from '../src/integrations'; import { LDClientCallbacks } from '../src/LDClientImpl'; import { createMigration, LDMigrationError, LDMigrationSuccess } from '../src/Migration'; import MigrationOpEventConversion from '../src/MigrationOpEventConversion'; +import { createBasicPlatform } from './createBasicPlatform'; import makeCallbacks from './makeCallbacks'; jest.mock('@launchdarkly/js-sdk-common', () => ({ @@ -43,7 +43,7 @@ describe('given an LDClient with test data', () => { td = new TestData(); callbacks = makeCallbacks(false); client = new LDClientImpl( - 'sdk-key', + 'sdk-key-migration-op', createBasicPlatform(), { updateProcessor: td.getFactory(), diff --git a/packages/shared/sdk-server/__tests__/createBasicPlatform.ts b/packages/shared/sdk-server/__tests__/createBasicPlatform.ts new file mode 100644 index 000000000..17178f061 --- /dev/null +++ b/packages/shared/sdk-server/__tests__/createBasicPlatform.ts @@ -0,0 +1,59 @@ +import { PlatformData, SdkData } from '@launchdarkly/js-sdk-common'; + +import { setupCrypto } from './setupCrypto'; + +const setupInfo = () => ({ + platformData: jest.fn( + (): PlatformData => ({ + os: { + name: 'An OS', + version: '1.0.1', + arch: 'An Arch', + }, + name: 'The SDK Name', + additional: { + nodeVersion: '42', + }, + ld_application: { + key: '', + envAttributesVersion: '1.0', + id: 'com.testapp.ld', + name: 'LDApplication.TestApp', + version: '1.1.1', + }, + ld_device: { + key: '', + envAttributesVersion: '1.0', + os: { name: 'Another OS', version: '99', family: 'orange' }, + manufacturer: 'coconut', + }, + }), + ), + sdkData: jest.fn( + (): SdkData => ({ + name: 'An SDK', + version: '2.0.2', + userAgentBase: 'TestUserAgent', + wrapperName: 'Rapper', + wrapperVersion: '1.2.3', + }), + ), +}); + +export const createBasicPlatform = () => ({ + encoding: { + btoa: (s: string) => Buffer.from(s).toString('base64'), + }, + info: setupInfo(), + crypto: setupCrypto(), + requests: { + fetch: jest.fn(), + createEventSource: jest.fn(), + getEventSourceCapabilities: jest.fn(), + }, + storage: { + get: jest.fn(), + set: jest.fn(), + clear: jest.fn(), + }, +}); diff --git a/packages/shared/sdk-server/__tests__/data_sources/FileDataSource.test.ts b/packages/shared/sdk-server/__tests__/data_sources/FileDataSource.test.ts index 000314563..df0a2c920 100644 --- a/packages/shared/sdk-server/__tests__/data_sources/FileDataSource.test.ts +++ b/packages/shared/sdk-server/__tests__/data_sources/FileDataSource.test.ts @@ -1,5 +1,4 @@ import { ClientContext, Context, Filesystem, WatchHandle } from '@launchdarkly/js-sdk-common'; -import { createBasicPlatform } from '@launchdarkly/private-js-mocks'; import { Flag } from '../../src/evaluation/data/Flag'; import { Segment } from '../../src/evaluation/data/Segment'; @@ -9,6 +8,7 @@ import Configuration from '../../src/options/Configuration'; import AsyncStoreFacade from '../../src/store/AsyncStoreFacade'; import InMemoryFeatureStore from '../../src/store/InMemoryFeatureStore'; import VersionedDataKinds from '../../src/store/VersionedDataKinds'; +import { createBasicPlatform } from '../createBasicPlatform'; import TestLogger from '../Logger'; const flag1Key = 'flag1'; diff --git a/packages/shared/sdk-server/__tests__/data_sources/PollingProcessor.test.ts b/packages/shared/sdk-server/__tests__/data_sources/PollingProcessor.test.ts index 19e2ac8a0..05ae9ff28 100644 --- a/packages/shared/sdk-server/__tests__/data_sources/PollingProcessor.test.ts +++ b/packages/shared/sdk-server/__tests__/data_sources/PollingProcessor.test.ts @@ -1,5 +1,4 @@ import { ClientContext } from '@launchdarkly/js-sdk-common'; -import { createBasicPlatform } from '@launchdarkly/private-js-mocks'; import { LDFeatureStore } from '../../src'; import PollingProcessor from '../../src/data_sources/PollingProcessor'; @@ -8,6 +7,7 @@ import Configuration from '../../src/options/Configuration'; import AsyncStoreFacade from '../../src/store/AsyncStoreFacade'; import InMemoryFeatureStore from '../../src/store/InMemoryFeatureStore'; import VersionedDataKinds from '../../src/store/VersionedDataKinds'; +import { createBasicPlatform } from '../createBasicPlatform'; import TestLogger, { LogLevel } from '../Logger'; describe('given an event processor', () => { diff --git a/packages/shared/sdk-server/src/diagnostics/createDiagnosticsInitConfig.test.ts b/packages/shared/sdk-server/__tests__/diagnostics/createDiagnosticsInitConfig.test.ts similarity index 92% rename from packages/shared/sdk-server/src/diagnostics/createDiagnosticsInitConfig.test.ts rename to packages/shared/sdk-server/__tests__/diagnostics/createDiagnosticsInitConfig.test.ts index 1605d277c..f0e3d21ad 100644 --- a/packages/shared/sdk-server/src/diagnostics/createDiagnosticsInitConfig.test.ts +++ b/packages/shared/sdk-server/__tests__/diagnostics/createDiagnosticsInitConfig.test.ts @@ -1,8 +1,7 @@ -import { createBasicPlatform } from '@launchdarkly/private-js-mocks'; - -import { LDOptions } from '../api'; -import Configuration from '../options/Configuration'; -import createDiagnosticsInitConfig from './createDiagnosticsInitConfig'; +import { LDOptions } from '../../src/api'; +import createDiagnosticsInitConfig from '../../src/diagnostics/createDiagnosticsInitConfig'; +import Configuration from '../../src/options/Configuration'; +import { createBasicPlatform } from '../createBasicPlatform'; let mockPlatform: ReturnType; diff --git a/packages/shared/sdk-server/__tests__/evaluation/Bucketer.test.ts b/packages/shared/sdk-server/__tests__/evaluation/Bucketer.test.ts index a1c10754c..5da1868e5 100644 --- a/packages/shared/sdk-server/__tests__/evaluation/Bucketer.test.ts +++ b/packages/shared/sdk-server/__tests__/evaluation/Bucketer.test.ts @@ -9,9 +9,9 @@ import { Hasher, LDContext, } from '@launchdarkly/js-sdk-common'; -import { createBasicPlatform } from '@launchdarkly/private-js-mocks'; import Bucketer from '../../src/evaluation/Bucketer'; +import { createBasicPlatform } from '../createBasicPlatform'; let mockPlatform: ReturnType; diff --git a/packages/shared/sdk-server/__tests__/evaluation/Evaluator.bucketing.test.ts b/packages/shared/sdk-server/__tests__/evaluation/Evaluator.bucketing.test.ts index 35ddcd431..568292887 100644 --- a/packages/shared/sdk-server/__tests__/evaluation/Evaluator.bucketing.test.ts +++ b/packages/shared/sdk-server/__tests__/evaluation/Evaluator.bucketing.test.ts @@ -1,9 +1,9 @@ import { Context } from '@launchdarkly/js-sdk-common'; -import { createBasicPlatform } from '@launchdarkly/private-js-mocks'; import { Flag } from '../../src/evaluation/data/Flag'; import { Rollout } from '../../src/evaluation/data/Rollout'; import Evaluator from '../../src/evaluation/Evaluator'; +import { createBasicPlatform } from '../createBasicPlatform'; import noQueries from './mocks/noQueries'; describe('given a flag with a rollout', () => { diff --git a/packages/shared/sdk-server/__tests__/evaluation/Evaluator.clause.test.ts b/packages/shared/sdk-server/__tests__/evaluation/Evaluator.clause.test.ts index 8c32c816b..df260d17d 100644 --- a/packages/shared/sdk-server/__tests__/evaluation/Evaluator.clause.test.ts +++ b/packages/shared/sdk-server/__tests__/evaluation/Evaluator.clause.test.ts @@ -1,10 +1,10 @@ import { AttributeReference, Context, LDContext } from '@launchdarkly/js-sdk-common'; -import { createBasicPlatform } from '@launchdarkly/private-js-mocks'; import { Clause } from '../../src/evaluation/data/Clause'; import { Flag } from '../../src/evaluation/data/Flag'; import { FlagRule } from '../../src/evaluation/data/FlagRule'; import Evaluator from '../../src/evaluation/Evaluator'; +import { createBasicPlatform } from '../createBasicPlatform'; import { makeBooleanFlagWithOneClause, makeBooleanFlagWithRules, diff --git a/packages/shared/sdk-server/__tests__/evaluation/Evaluator.rules.test.ts b/packages/shared/sdk-server/__tests__/evaluation/Evaluator.rules.test.ts index 7ee33eaba..3be3e2819 100644 --- a/packages/shared/sdk-server/__tests__/evaluation/Evaluator.rules.test.ts +++ b/packages/shared/sdk-server/__tests__/evaluation/Evaluator.rules.test.ts @@ -1,12 +1,12 @@ // Tests of flag evaluation at the rule level. Clause-level behavior is covered // in detail in Evaluator.clause.tests and (TODO: File for segments). import { AttributeReference, Context, LDContext } from '@launchdarkly/js-sdk-common'; -import { createBasicPlatform } from '@launchdarkly/private-js-mocks'; import { Clause } from '../../src/evaluation/data/Clause'; import { Flag } from '../../src/evaluation/data/Flag'; import { FlagRule } from '../../src/evaluation/data/FlagRule'; import Evaluator from '../../src/evaluation/Evaluator'; +import { createBasicPlatform } from '../createBasicPlatform'; import { makeClauseThatDoesNotMatchUser, makeClauseThatMatchesUser, diff --git a/packages/shared/sdk-server/__tests__/evaluation/Evaluator.segments.test.ts b/packages/shared/sdk-server/__tests__/evaluation/Evaluator.segments.test.ts index d0f1f4eeb..d27ac07dd 100644 --- a/packages/shared/sdk-server/__tests__/evaluation/Evaluator.segments.test.ts +++ b/packages/shared/sdk-server/__tests__/evaluation/Evaluator.segments.test.ts @@ -7,13 +7,13 @@ import { Hmac, LDContext, } from '@launchdarkly/js-sdk-common'; -import { createBasicPlatform } from '@launchdarkly/private-js-mocks'; import { BigSegmentStoreMembership } from '../../src/api/interfaces'; import { Flag } from '../../src/evaluation/data/Flag'; import { Segment } from '../../src/evaluation/data/Segment'; import Evaluator from '../../src/evaluation/Evaluator'; import { Queries } from '../../src/evaluation/Queries'; +import { createBasicPlatform } from '../createBasicPlatform'; import { makeClauseThatDoesNotMatchUser, makeClauseThatMatchesUser, diff --git a/packages/shared/sdk-server/__tests__/evaluation/Evaluator.test.ts b/packages/shared/sdk-server/__tests__/evaluation/Evaluator.test.ts index 99325b8ef..64640b0c4 100644 --- a/packages/shared/sdk-server/__tests__/evaluation/Evaluator.test.ts +++ b/packages/shared/sdk-server/__tests__/evaluation/Evaluator.test.ts @@ -1,10 +1,10 @@ import { Context, LDContext } from '@launchdarkly/js-sdk-common'; -import { createBasicPlatform } from '@launchdarkly/private-js-mocks'; import { Flag } from '../../src/evaluation/data/Flag'; import EvalResult from '../../src/evaluation/EvalResult'; import Evaluator from '../../src/evaluation/Evaluator'; import Reasons from '../../src/evaluation/Reasons'; +import { createBasicPlatform } from '../createBasicPlatform'; import noQueries from './mocks/noQueries'; const offBaseFlag = { diff --git a/packages/shared/sdk-server/__tests__/events/EventProcessor.test.ts b/packages/shared/sdk-server/__tests__/events/EventProcessor.test.ts index 6ea238ac9..98d747890 100644 --- a/packages/shared/sdk-server/__tests__/events/EventProcessor.test.ts +++ b/packages/shared/sdk-server/__tests__/events/EventProcessor.test.ts @@ -14,11 +14,11 @@ import { Response, SdkData, } from '@launchdarkly/js-sdk-common'; -import { createBasicPlatform } from '@launchdarkly/private-js-mocks'; import ContextDeduplicator from '../../src/events/ContextDeduplicator'; import Configuration from '../../src/options/Configuration'; import InMemoryFeatureStore from '../../src/store/InMemoryFeatureStore'; +import { createBasicPlatform } from '../createBasicPlatform'; let mockPlatform: ReturnType; diff --git a/packages/shared/sdk-server/__tests__/integrations/test_data/TestData.test.ts b/packages/shared/sdk-server/__tests__/integrations/test_data/TestData.test.ts index 06c97f0fe..facb21258 100644 --- a/packages/shared/sdk-server/__tests__/integrations/test_data/TestData.test.ts +++ b/packages/shared/sdk-server/__tests__/integrations/test_data/TestData.test.ts @@ -1,5 +1,4 @@ import { AttributeReference, ClientContext } from '@launchdarkly/js-sdk-common'; -import { createBasicPlatform } from '@launchdarkly/private-js-mocks'; import { Flag } from '../../../src/evaluation/data/Flag'; import { FlagRule } from '../../../src/evaluation/data/FlagRule'; @@ -8,6 +7,7 @@ import Configuration from '../../../src/options/Configuration'; import AsyncStoreFacade from '../../../src/store/AsyncStoreFacade'; import InMemoryFeatureStore from '../../../src/store/InMemoryFeatureStore'; import VersionedDataKinds from '../../../src/store/VersionedDataKinds'; +import { createBasicPlatform } from '../../createBasicPlatform'; const basicBooleanFlag: Flag = { fallthrough: { diff --git a/packages/shared/sdk-server/__tests__/setupCrypto.ts b/packages/shared/sdk-server/__tests__/setupCrypto.ts new file mode 100644 index 000000000..fc8d0b460 --- /dev/null +++ b/packages/shared/sdk-server/__tests__/setupCrypto.ts @@ -0,0 +1,20 @@ +import { Hasher } from '@launchdarkly/js-sdk-common'; + +export const setupCrypto = () => { + let counter = 0; + const hasher = { + update: jest.fn((): Hasher => hasher), + digest: jest.fn(() => '1234567890123456'), + }; + + return { + createHash: jest.fn(() => hasher), + createHmac: jest.fn(), + randomUUID: jest.fn(() => { + counter += 1; + // Will provide a unique value for tests. + // Very much not a UUID of course. + return `${counter}`; + }), + }; +}; diff --git a/packages/shared/mocks/src/streamingProcessor.ts b/packages/shared/sdk-server/__tests__/streamingProcessor.ts similarity index 98% rename from packages/shared/mocks/src/streamingProcessor.ts rename to packages/shared/sdk-server/__tests__/streamingProcessor.ts index cd038e7ef..2f6e2a802 100644 --- a/packages/shared/mocks/src/streamingProcessor.ts +++ b/packages/shared/sdk-server/__tests__/streamingProcessor.ts @@ -5,7 +5,7 @@ import type { LDHeaders, LDStreamingError, ProcessStreamResponse, -} from '@common'; +} from '@launchdarkly/js-sdk-common'; export const MockStreamingProcessor = jest.fn(); diff --git a/packages/shared/sdk-server/package.json b/packages/shared/sdk-server/package.json index 2ea1d6ac9..77de3fcbb 100644 --- a/packages/shared/sdk-server/package.json +++ b/packages/shared/sdk-server/package.json @@ -31,7 +31,6 @@ "semver": "7.5.4" }, "devDependencies": { - "@launchdarkly/private-js-mocks": "0.0.1", "@trivago/prettier-plugin-sort-imports": "^4.1.1", "@types/jest": "^29.4.0", "@types/semver": "^7.3.13", diff --git a/packages/shared/sdk-server/src/data_sources/createStreamListeners.test.ts b/packages/shared/sdk-server/src/data_sources/createStreamListeners.test.ts index 661a084c4..02df75aad 100644 --- a/packages/shared/sdk-server/src/data_sources/createStreamListeners.test.ts +++ b/packages/shared/sdk-server/src/data_sources/createStreamListeners.test.ts @@ -1,4 +1,4 @@ -import { createLogger } from '@launchdarkly/private-js-mocks'; +import { LDLogger } from '@launchdarkly/js-sdk-common'; import { LDDataSourceUpdates } from '../api/subsystems'; import { deserializeAll, deserializeDelete, deserializePatch } from '../store/serialization'; @@ -7,10 +7,15 @@ import { createStreamListeners } from './createStreamListeners'; jest.mock('../store/serialization'); -let logger: ReturnType; +let logger: LDLogger; beforeEach(() => { - logger = createLogger(); + logger = { + error: jest.fn(), + warn: jest.fn(), + info: jest.fn(), + debug: jest.fn(), + }; }); const allData = { diff --git a/packages/telemetry/node-server-sdk-otel/package.json b/packages/telemetry/node-server-sdk-otel/package.json index c52bdba45..27f53c379 100644 --- a/packages/telemetry/node-server-sdk-otel/package.json +++ b/packages/telemetry/node-server-sdk-otel/package.json @@ -34,7 +34,6 @@ }, "devDependencies": { "@launchdarkly/node-server-sdk": "9.6.0", - "@launchdarkly/private-js-mocks": "0.0.1", "@opentelemetry/api": ">=1.3.0", "@opentelemetry/sdk-node": "0.49.1", "@opentelemetry/sdk-trace-node": "1.22.0", diff --git a/tsconfig.json b/tsconfig.json index 91b995e66..e7ffa9fe3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,9 +7,6 @@ { "path": "./packages/shared/common/tsconfig.ref.json" }, - { - "path": "./packages/shared/mocks/tsconfig.ref.json" - }, { "path": "./packages/shared/sdk-client/tsconfig.ref.json" },