diff --git a/lib/event_processor/batch_event_processor.spec.ts b/lib/event_processor/batch_event_processor.spec.ts index da02908ed..30d8d1bac 100644 --- a/lib/event_processor/batch_event_processor.spec.ts +++ b/lib/event_processor/batch_event_processor.spec.ts @@ -21,7 +21,7 @@ import { createImpressionEvent } from '../tests/mock/create_event'; import { ProcessableEvent } from './event_processor'; import { buildLogEvent } from './event_builder/log_event'; import { resolvablePromise } from '../utils/promise/resolvablePromise'; -import { advanceTimersByTime } from '../../tests/testUtils'; +import { advanceTimersByTime } from '../tests/testUtils'; import { getMockLogger } from '../tests/mock/mock_logger'; import { getMockRepeater } from '../tests/mock/mock_repeater'; import * as retry from '../utils/executor/backoff_retry_runner'; diff --git a/lib/event_processor/event_dispatcher/default_dispatcher.browser.spec.ts b/lib/event_processor/event_dispatcher/default_dispatcher.browser.spec.ts index bf83ca13b..82314cbc7 100644 --- a/lib/event_processor/event_dispatcher/default_dispatcher.browser.spec.ts +++ b/lib/event_processor/event_dispatcher/default_dispatcher.browser.spec.ts @@ -21,13 +21,13 @@ vi.mock('./default_dispatcher', () => { return { DefaultEventDispatcher }; }); -vi.mock('../../utils/http_request_handler/browser_request_handler', () => { +vi.mock('../../utils/http_request_handler/request_handler.browser', () => { const BrowserRequestHandler = vi.fn(); return { BrowserRequestHandler }; }); import { DefaultEventDispatcher } from './default_dispatcher'; -import { BrowserRequestHandler } from '../../utils/http_request_handler/browser_request_handler'; +import { BrowserRequestHandler } from '../../utils/http_request_handler/request_handler.browser'; import eventDispatcher from './default_dispatcher.browser'; describe('eventDispatcher', () => { diff --git a/lib/event_processor/event_dispatcher/default_dispatcher.browser.ts b/lib/event_processor/event_dispatcher/default_dispatcher.browser.ts index 893039d92..d38d266aa 100644 --- a/lib/event_processor/event_dispatcher/default_dispatcher.browser.ts +++ b/lib/event_processor/event_dispatcher/default_dispatcher.browser.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { BrowserRequestHandler } from "../../utils/http_request_handler/browser_request_handler"; +import { BrowserRequestHandler } from "../../utils/http_request_handler/request_handler.browser"; import { EventDispatcher } from './event_dispatcher'; import { DefaultEventDispatcher } from './default_dispatcher'; diff --git a/lib/event_processor/event_dispatcher/default_dispatcher.node.spec.ts b/lib/event_processor/event_dispatcher/default_dispatcher.node.spec.ts index abd319b09..084fcce67 100644 --- a/lib/event_processor/event_dispatcher/default_dispatcher.node.spec.ts +++ b/lib/event_processor/event_dispatcher/default_dispatcher.node.spec.ts @@ -20,13 +20,13 @@ vi.mock('./default_dispatcher', () => { return { DefaultEventDispatcher }; }); -vi.mock('../../utils/http_request_handler/node_request_handler', () => { +vi.mock('../../utils/http_request_handler/request_handler.node', () => { const NodeRequestHandler = vi.fn(); return { NodeRequestHandler }; }); import { DefaultEventDispatcher } from './default_dispatcher'; -import { NodeRequestHandler } from '../../utils/http_request_handler/node_request_handler'; +import { NodeRequestHandler } from '../../utils/http_request_handler/request_handler.node'; import eventDispatcher from './default_dispatcher.node'; describe('eventDispatcher', () => { diff --git a/lib/event_processor/event_dispatcher/default_dispatcher.node.ts b/lib/event_processor/event_dispatcher/default_dispatcher.node.ts index 52524140c..65dc115af 100644 --- a/lib/event_processor/event_dispatcher/default_dispatcher.node.ts +++ b/lib/event_processor/event_dispatcher/default_dispatcher.node.ts @@ -14,7 +14,7 @@ * limitations under the License. */ import { EventDispatcher } from './event_dispatcher'; -import { NodeRequestHandler } from '../../utils/http_request_handler/node_request_handler'; +import { NodeRequestHandler } from '../../utils/http_request_handler/request_handler.node'; import { DefaultEventDispatcher } from './default_dispatcher'; const eventDispatcher: EventDispatcher = new DefaultEventDispatcher(new NodeRequestHandler()); diff --git a/lib/index.lite.ts b/lib/index.lite.ts index a7cc7cf22..eae2a00e0 100644 --- a/lib/index.lite.ts +++ b/lib/index.lite.ts @@ -27,7 +27,7 @@ import * as enums from './utils/enums'; import * as loggerPlugin from './plugins/logger'; import Optimizely from './optimizely'; import { createNotificationCenter } from './notification_center'; -import { OptimizelyDecideOption, Client, ConfigLite } from './shared_types'; +import { OptimizelyDecideOption, Client, Config } from './shared_types'; import * as commonExports from './common_exports'; const logger = getLogger(); @@ -40,7 +40,7 @@ setLogLevel(LogLevel.ERROR); * @return {Client|null} the Optimizely client object * null on error */ - const createInstance = function(config: ConfigLite): Client | null { + const createInstance = function(config: Config): Client | null { try { // TODO warn about setting per instance errorHandler / logger / logLevel diff --git a/lib/index.node.ts b/lib/index.node.ts index 63f7e16e5..16605d246 100644 --- a/lib/index.node.ts +++ b/lib/index.node.ts @@ -73,7 +73,6 @@ const createInstance = function(config: Config): Client | null { } } - const errorHandler = getErrorHandler(); const notificationCenter = createNotificationCenter({ logger: logger, errorHandler: errorHandler }); diff --git a/lib/index.react_native.spec.ts b/lib/index.react_native.spec.ts new file mode 100644 index 000000000..64ca63520 --- /dev/null +++ b/lib/index.react_native.spec.ts @@ -0,0 +1,177 @@ +/** + * Copyright 2019-2020, 2022-2024 Optimizely + * + * 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. + */ +import { describe, beforeEach, afterEach, it, expect, vi } from 'vitest'; + +import * as logging from './modules/logging/logger'; + +import Optimizely from './optimizely'; +import testData from './tests/test_data'; +import packageJSON from '../package.json'; +import optimizelyFactory from './index.react_native'; +import configValidator from './utils/config_validator'; +import { getMockProjectConfigManager } from './tests/mock/mock_project_config_manager'; +import { createProjectConfig } from './project_config/project_config'; + +vi.mock('@react-native-community/netinfo'); +vi.mock('react-native-get-random-values') +vi.mock('fast-text-encoding') + +describe('javascript-sdk/react-native', () => { + beforeEach(() => { + vi.spyOn(optimizelyFactory.eventDispatcher, 'dispatchEvent'); + vi.useFakeTimers(); + }); + + afterEach(() => { + vi.resetAllMocks(); + }); + + describe('APIs', () => { + it('should expose logger, errorHandler, eventDispatcher and enums', () => { + expect(optimizelyFactory.logging).toBeDefined(); + expect(optimizelyFactory.logging.createLogger).toBeDefined(); + expect(optimizelyFactory.logging.createNoOpLogger).toBeDefined(); + expect(optimizelyFactory.errorHandler).toBeDefined(); + expect(optimizelyFactory.eventDispatcher).toBeDefined(); + expect(optimizelyFactory.enums).toBeDefined(); + }); + + describe('createInstance', () => { + const fakeErrorHandler = { handleError: function() {} }; + const fakeEventDispatcher = { dispatchEvent: async function() { + return Promise.resolve({}); + } }; + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + let silentLogger; + + beforeEach(() => { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + silentLogger = optimizelyFactory.logging.createLogger(); + vi.spyOn(console, 'error'); + vi.spyOn(configValidator, 'validate').mockImplementation(() => { + throw new Error('Invalid config or something'); + }); + }); + + afterEach(() => { + vi.resetAllMocks(); + }); + + it('should not throw if the provided config is not valid', () => { + expect(function() { + const optlyInstance = optimizelyFactory.createInstance({ + projectConfigManager: getMockProjectConfigManager(), + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + logger: silentLogger, + }); + }).not.toThrow(); + }); + + it('should create an instance of optimizely', () => { + const optlyInstance = optimizelyFactory.createInstance({ + projectConfigManager: getMockProjectConfigManager(), + errorHandler: fakeErrorHandler, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + logger: silentLogger, + }); + + expect(optlyInstance).toBeInstanceOf(Optimizely); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + expect(optlyInstance.clientVersion).toEqual('5.3.4'); + }); + + it('should set the React Native JS client engine and javascript SDK version', () => { + const optlyInstance = optimizelyFactory.createInstance({ + projectConfigManager: getMockProjectConfigManager(), + errorHandler: fakeErrorHandler, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + logger: silentLogger, + }); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + expect('react-native-js-sdk').toEqual(optlyInstance.clientEngine); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + expect(packageJSON.version).toEqual(optlyInstance.clientVersion); + }); + + it('should allow passing of "react-sdk" as the clientEngine and convert it to "react-native-sdk"', () => { + const optlyInstance = optimizelyFactory.createInstance({ + clientEngine: 'react-sdk', + projectConfigManager: getMockProjectConfigManager(), + errorHandler: fakeErrorHandler, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + logger: silentLogger, + }); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + expect('react-native-sdk').toEqual(optlyInstance.clientEngine); + }); + + describe('when passing in logLevel', () => { + beforeEach(() => { + vi.spyOn(logging, 'setLogLevel'); + }); + + afterEach(() => { + vi.resetAllMocks(); + }); + + it('should call logging.setLogLevel', () => { + optimizelyFactory.createInstance({ + projectConfigManager: getMockProjectConfigManager({ + initConfig: createProjectConfig(testData.getTestProjectConfig()), + }), + logLevel: optimizelyFactory.enums.LOG_LEVEL.ERROR, + }); + expect(logging.setLogLevel).toBeCalledTimes(1); + expect(logging.setLogLevel).toBeCalledWith(optimizelyFactory.enums.LOG_LEVEL.ERROR); + }); + }); + + describe('when passing in logger', () => { + beforeEach(() => { + vi.spyOn(logging, 'setLogHandler'); + }); + + afterEach(() => { + vi.resetAllMocks(); + }); + + it('should call logging.setLogHandler with the supplied logger', () => { + const fakeLogger = { log: function() {} }; + optimizelyFactory.createInstance({ + projectConfigManager: getMockProjectConfigManager({ + initConfig: createProjectConfig(testData.getTestProjectConfig()), + }), + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + logger: fakeLogger, + }); + expect(logging.setLogHandler).toBeCalledTimes(1); + expect(logging.setLogHandler).toBeCalledWith(fakeLogger); + }); + }); + }); + }); +}); diff --git a/tests/logger.spec.ts b/lib/modules/logging/logger.spec.ts similarity index 98% rename from tests/logger.spec.ts rename to lib/modules/logging/logger.spec.ts index 17d5cc38b..0440755bb 100644 --- a/tests/logger.spec.ts +++ b/lib/modules/logging/logger.spec.ts @@ -4,7 +4,7 @@ import { LogLevel, LogHandler, LoggerFacade, -} from '../lib/modules/logging/models' +} from './models' import { setLogHandler, @@ -13,10 +13,10 @@ import { ConsoleLogHandler, resetLogger, getLogLevel, -} from '../lib/modules/logging/logger' +} from './logger' -import { resetErrorHandler } from '../lib/modules/logging/errorHandler' -import { ErrorHandler, setErrorHandler } from '../lib/modules/logging/errorHandler' +import { resetErrorHandler } from './errorHandler' +import { ErrorHandler, setErrorHandler } from './errorHandler' describe('logger', () => { afterEach(() => { @@ -302,6 +302,7 @@ describe('logger', () => { it('should set logLevel to ERROR when setLogLevel is called with no value', () => { const logger = new ConsoleLogHandler() + // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore logger.setLogLevel() diff --git a/lib/odp/event_manager/odp_event_manager.spec.ts b/lib/odp/event_manager/odp_event_manager.spec.ts index dfe8d496a..12d061918 100644 --- a/lib/odp/event_manager/odp_event_manager.spec.ts +++ b/lib/odp/event_manager/odp_event_manager.spec.ts @@ -22,7 +22,7 @@ import { exhaustMicrotasks } from '../../tests/testUtils'; import { OdpEvent } from './odp_event'; import { OdpConfig } from '../odp_config'; import { EventDispatchResponse } from './odp_event_api_manager'; -import { advanceTimersByTime } from '../../../tests/testUtils'; +import { advanceTimersByTime } from '../../tests/testUtils'; const API_KEY = 'test-api-key'; const API_HOST = 'https://odp.example.com'; diff --git a/lib/odp/odp_manager_factory.browser.spec.ts b/lib/odp/odp_manager_factory.browser.spec.ts index 333856743..534046f94 100644 --- a/lib/odp/odp_manager_factory.browser.spec.ts +++ b/lib/odp/odp_manager_factory.browser.spec.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -vi.mock('../utils/http_request_handler/browser_request_handler', () => { +vi.mock('../utils/http_request_handler/request_handler.browser', () => { return { BrowserRequestHandler: vi.fn() }; }); @@ -26,7 +26,7 @@ vi.mock('./odp_manager_factory', () => { import { describe, it, expect, beforeEach, vi } from 'vitest'; import { getOdpManager, OdpManagerOptions } from './odp_manager_factory'; import { BROWSER_DEFAULT_API_TIMEOUT, createOdpManager } from './odp_manager_factory.browser'; -import { BrowserRequestHandler } from '../utils/http_request_handler/browser_request_handler'; +import { BrowserRequestHandler } from '../utils/http_request_handler/request_handler.browser'; import { pixelApiRequestGenerator } from './event_manager/odp_event_api_manager'; describe('createOdpManager', () => { diff --git a/lib/odp/odp_manager_factory.browser.ts b/lib/odp/odp_manager_factory.browser.ts index 481252278..f70dfe976 100644 --- a/lib/odp/odp_manager_factory.browser.ts +++ b/lib/odp/odp_manager_factory.browser.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { BrowserRequestHandler } from '../utils/http_request_handler/browser_request_handler'; +import { BrowserRequestHandler } from '../utils/http_request_handler/request_handler.browser'; import { pixelApiRequestGenerator } from './event_manager/odp_event_api_manager'; import { OdpManager } from './odp_manager'; import { getOdpManager, OdpManagerOptions } from './odp_manager_factory'; diff --git a/lib/odp/odp_manager_factory.node.spec.ts b/lib/odp/odp_manager_factory.node.spec.ts index b63850180..491fd7520 100644 --- a/lib/odp/odp_manager_factory.node.spec.ts +++ b/lib/odp/odp_manager_factory.node.spec.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -vi.mock('../utils/http_request_handler/node_request_handler', () => { +vi.mock('../utils/http_request_handler/request_handler.node', () => { return { NodeRequestHandler: vi.fn() }; }); @@ -26,7 +26,7 @@ vi.mock('./odp_manager_factory', () => { import { describe, it, expect, beforeEach, vi } from 'vitest'; import { getOdpManager, OdpManagerOptions } from './odp_manager_factory'; import { NODE_DEFAULT_API_TIMEOUT, NODE_DEFAULT_BATCH_SIZE, NODE_DEFAULT_FLUSH_INTERVAL, createOdpManager } from './odp_manager_factory.node'; -import { NodeRequestHandler } from '../utils/http_request_handler/node_request_handler'; +import { NodeRequestHandler } from '../utils/http_request_handler/request_handler.node'; import { eventApiRequestGenerator } from './event_manager/odp_event_api_manager'; describe('createOdpManager', () => { diff --git a/lib/odp/odp_manager_factory.node.ts b/lib/odp/odp_manager_factory.node.ts index 3d449fd3b..f2438dbd9 100644 --- a/lib/odp/odp_manager_factory.node.ts +++ b/lib/odp/odp_manager_factory.node.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { NodeRequestHandler } from '../utils/http_request_handler/node_request_handler'; +import { NodeRequestHandler } from '../utils/http_request_handler/request_handler.node'; import { eventApiRequestGenerator } from './event_manager/odp_event_api_manager'; import { OdpManager } from './odp_manager'; import { getOdpManager, OdpManagerOptions } from './odp_manager_factory'; diff --git a/lib/odp/odp_manager_factory.react_native.spec.ts b/lib/odp/odp_manager_factory.react_native.spec.ts index 604a71bc7..640e9cf4e 100644 --- a/lib/odp/odp_manager_factory.react_native.spec.ts +++ b/lib/odp/odp_manager_factory.react_native.spec.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -vi.mock('../utils/http_request_handler/browser_request_handler', () => { +vi.mock('../utils/http_request_handler/request_handler.browser', () => { return { BrowserRequestHandler: vi.fn() }; }); @@ -26,7 +26,7 @@ vi.mock('./odp_manager_factory', () => { import { describe, it, expect, beforeEach, vi } from 'vitest'; import { getOdpManager, OdpManagerOptions } from './odp_manager_factory'; import { RN_DEFAULT_API_TIMEOUT, RN_DEFAULT_BATCH_SIZE, RN_DEFAULT_FLUSH_INTERVAL, createOdpManager } from './odp_manager_factory.react_native'; -import { BrowserRequestHandler } from '../utils/http_request_handler/browser_request_handler' +import { BrowserRequestHandler } from '../utils/http_request_handler/request_handler.browser' import { eventApiRequestGenerator } from './event_manager/odp_event_api_manager'; describe('createOdpManager', () => { diff --git a/lib/odp/odp_manager_factory.react_native.ts b/lib/odp/odp_manager_factory.react_native.ts index c63982430..1ba0bcc5c 100644 --- a/lib/odp/odp_manager_factory.react_native.ts +++ b/lib/odp/odp_manager_factory.react_native.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { BrowserRequestHandler } from '../utils/http_request_handler/browser_request_handler'; +import { BrowserRequestHandler } from '../utils/http_request_handler/request_handler.browser'; import { eventApiRequestGenerator } from './event_manager/odp_event_api_manager'; import { OdpManager } from './odp_manager'; import { getOdpManager, OdpManagerOptions } from './odp_manager_factory'; diff --git a/lib/plugins/key_value_cache/persistentKeyValueCache.ts b/lib/plugins/key_value_cache/persistentKeyValueCache.ts deleted file mode 100644 index f6b182738..000000000 --- a/lib/plugins/key_value_cache/persistentKeyValueCache.ts +++ /dev/null @@ -1,62 +0,0 @@ -/** - * Copyright 2022, 2024, Optimizely - * - * 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 - * - * https://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. - */ - -/** - * An Interface to implement a persistent key value cache which supports strings as keys. - */ -export default interface PersistentKeyValueCache { - /** - * Checks if a key exists in the cache - * @param key - * Resolves promise with - * 1. true if the key exists - * 2. false if the key does not exist - * Rejects the promise in case of an error - */ - contains(key: string): Promise; - - /** - * Returns value stored against a key or undefined if not found. - * @param key - * @returns - * Resolves promise with - * 1. object as value if found. - * 2. undefined if the key does not exist in the cache. - * Rejects the promise in case of an error - */ - get(key: string): Promise; - - /** - * Removes the key value pair from cache. - * @param key * - * @returns - * Resolves promise with - * 1. true if key-value was removed or - * 2. false if key not found - * Rejects the promise in case of an error - */ - remove(key: string): Promise; - - /** - * Stores any object in the persistent cache against a key - * @param key - * @param val - * @returns - * Resolves promise without a value if successful - * Rejects the promise in case of an error - */ - set(key: string, val: V): Promise; -} diff --git a/lib/plugins/key_value_cache/reactNativeAsyncStorageCache.ts b/lib/plugins/key_value_cache/reactNativeAsyncStorageCache.ts deleted file mode 100644 index 9529595be..000000000 --- a/lib/plugins/key_value_cache/reactNativeAsyncStorageCache.ts +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Copyright 2020, 2022, 2024, Optimizely - * - * 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 - * - * https://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. - */ - -import PersistentKeyValueCache from './persistentKeyValueCache'; -import { getDefaultAsyncStorage } from '../../utils/import.react_native/@react-native-async-storage/async-storage'; - -export default class ReactNativeAsyncStorageCache implements PersistentKeyValueCache { - private asyncStorage = getDefaultAsyncStorage(); - - async contains(key: string): Promise { - return (await this.asyncStorage.getItem(key)) !== null; - } - - async get(key: string): Promise { - return (await this.asyncStorage.getItem(key)) || undefined; - } - - async remove(key: string): Promise { - if (await this.contains(key)) { - await this.asyncStorage.removeItem(key); - return true; - } - return false; - } - - set(key: string, val: string): Promise { - return this.asyncStorage.setItem(key, val); - } -} diff --git a/lib/project_config/config_manager_factory.browser.spec.ts b/lib/project_config/config_manager_factory.browser.spec.ts index 7141cc16c..843111fb4 100644 --- a/lib/project_config/config_manager_factory.browser.spec.ts +++ b/lib/project_config/config_manager_factory.browser.spec.ts @@ -22,14 +22,14 @@ vi.mock('./config_manager_factory', () => { }; }); -vi.mock('../utils/http_request_handler/browser_request_handler', () => { +vi.mock('../utils/http_request_handler/request_handler.browser', () => { const BrowserRequestHandler = vi.fn(); return { BrowserRequestHandler }; }); import { getPollingConfigManager, PollingConfigManagerConfig, PollingConfigManagerFactoryOptions } from './config_manager_factory'; import { createPollingProjectConfigManager } from './config_manager_factory.browser'; -import { BrowserRequestHandler } from '../utils/http_request_handler/browser_request_handler'; +import { BrowserRequestHandler } from '../utils/http_request_handler/request_handler.browser'; import { getMockSyncCache } from '../tests/mock/mock_cache'; describe('createPollingConfigManager', () => { diff --git a/lib/project_config/config_manager_factory.browser.ts b/lib/project_config/config_manager_factory.browser.ts index 8ae0bfd9e..8a5433bd5 100644 --- a/lib/project_config/config_manager_factory.browser.ts +++ b/lib/project_config/config_manager_factory.browser.ts @@ -15,7 +15,7 @@ */ import { getPollingConfigManager, PollingConfigManagerConfig } from './config_manager_factory'; -import { BrowserRequestHandler } from '../utils/http_request_handler/browser_request_handler'; +import { BrowserRequestHandler } from '../utils/http_request_handler/request_handler.browser'; import { ProjectConfigManager } from './project_config_manager'; export const createPollingProjectConfigManager = (config: PollingConfigManagerConfig): ProjectConfigManager => { diff --git a/lib/project_config/config_manager_factory.node.spec.ts b/lib/project_config/config_manager_factory.node.spec.ts index 6ef8e04e0..41dedd4f5 100644 --- a/lib/project_config/config_manager_factory.node.spec.ts +++ b/lib/project_config/config_manager_factory.node.spec.ts @@ -22,14 +22,14 @@ vi.mock('./config_manager_factory', () => { }; }); -vi.mock('../utils/http_request_handler/node_request_handler', () => { +vi.mock('../utils/http_request_handler/request_handler.node', () => { const NodeRequestHandler = vi.fn(); return { NodeRequestHandler }; }); import { getPollingConfigManager, PollingConfigManagerConfig } from './config_manager_factory'; import { createPollingProjectConfigManager } from './config_manager_factory.node'; -import { NodeRequestHandler } from '../utils/http_request_handler/node_request_handler'; +import { NodeRequestHandler } from '../utils/http_request_handler/request_handler.node'; import { getMockSyncCache } from '../tests/mock/mock_cache'; describe('createPollingConfigManager', () => { diff --git a/lib/project_config/config_manager_factory.node.ts b/lib/project_config/config_manager_factory.node.ts index 7a220bc12..241927c5a 100644 --- a/lib/project_config/config_manager_factory.node.ts +++ b/lib/project_config/config_manager_factory.node.ts @@ -15,7 +15,7 @@ */ import { getPollingConfigManager, PollingConfigManagerConfig } from "./config_manager_factory"; -import { NodeRequestHandler } from "../utils/http_request_handler/node_request_handler"; +import { NodeRequestHandler } from "../utils/http_request_handler/request_handler.node"; import { ProjectConfigManager } from "./project_config_manager"; import { DEFAULT_URL_TEMPLATE, DEFAULT_AUTHENTICATED_URL_TEMPLATE } from './constant'; diff --git a/lib/project_config/config_manager_factory.react_native.spec.ts b/lib/project_config/config_manager_factory.react_native.spec.ts index b047af03a..e688c588a 100644 --- a/lib/project_config/config_manager_factory.react_native.spec.ts +++ b/lib/project_config/config_manager_factory.react_native.spec.ts @@ -42,7 +42,7 @@ vi.mock('./config_manager_factory', () => { }; }); -vi.mock('../utils/http_request_handler/browser_request_handler', () => { +vi.mock('../utils/http_request_handler/request_handler.browser', () => { const BrowserRequestHandler = vi.fn(); return { BrowserRequestHandler }; }); @@ -58,7 +58,7 @@ vi.mock('../utils/cache/async_storage_cache.react_native', async (importOriginal import { getPollingConfigManager, PollingConfigManagerConfig } from './config_manager_factory'; import { createPollingProjectConfigManager } from './config_manager_factory.react_native'; -import { BrowserRequestHandler } from '../utils/http_request_handler/browser_request_handler'; +import { BrowserRequestHandler } from '../utils/http_request_handler/request_handler.browser'; import { AsyncStorageCache } from '../utils/cache/async_storage_cache.react_native'; import { getMockSyncCache } from '../tests/mock/mock_cache'; diff --git a/lib/project_config/config_manager_factory.react_native.ts b/lib/project_config/config_manager_factory.react_native.ts index 17e71f045..6edcbbe3f 100644 --- a/lib/project_config/config_manager_factory.react_native.ts +++ b/lib/project_config/config_manager_factory.react_native.ts @@ -15,7 +15,7 @@ */ import { getPollingConfigManager, PollingConfigManagerConfig } from "./config_manager_factory"; -import { BrowserRequestHandler } from "../utils/http_request_handler/browser_request_handler"; +import { BrowserRequestHandler } from "../utils/http_request_handler/request_handler.browser"; import { ProjectConfigManager } from "./project_config_manager"; import { AsyncStorageCache } from "../utils/cache/async_storage_cache.react_native"; diff --git a/lib/project_config/project_config_manager.spec.ts b/lib/project_config/project_config_manager.spec.ts index 967aec83c..682c2bede 100644 --- a/lib/project_config/project_config_manager.spec.ts +++ b/lib/project_config/project_config_manager.spec.ts @@ -21,7 +21,7 @@ import * as testData from '../tests/test_data'; import { createProjectConfig } from './project_config'; import { resolvablePromise } from '../utils/promise/resolvablePromise'; import { getMockDatafileManager } from '../tests/mock/mock_datafile_manager'; -import { wait } from '../../tests/testUtils'; +import { wait } from '../tests/testUtils'; const cloneDeep = (x: any) => JSON.parse(JSON.stringify(x)); diff --git a/lib/shared_types.ts b/lib/shared_types.ts index fa3579e69..b2ebad540 100644 --- a/lib/shared_types.ts +++ b/lib/shared_types.ts @@ -32,7 +32,6 @@ import { OdpSegmentManager } from './odp/segment_manager/odp_segment_manager'; import { DefaultOdpEventApiManager } from './odp/event_manager/odp_event_api_manager'; import { OdpEventManager } from './odp/event_manager/odp_event_manager'; import { OdpManager } from './odp/odp_manager'; -import PersistentCache from './plugins/key_value_cache/persistentKeyValueCache'; import { ProjectConfig } from './project_config/project_config'; import { ProjectConfigManager } from './project_config/project_config_manager'; import { EventDispatcher } from './event_processor/event_dispatcher/event_dispatcher'; @@ -359,25 +358,11 @@ export interface TrackListenerPayload extends ListenerPayload { logEvent: Event; } -export type PersistentCacheProvider = () => PersistentCache; - /** * Entry level Config Entities * For compatibility with the previous declaration file */ -export interface Config extends ConfigLite { - // eventBatchSize?: number; // Maximum size of events to be dispatched in a batch - // eventFlushInterval?: number; // Maximum time for an event to be enqueued - // eventMaxQueueSize?: number; // Maximum size for the event queue - sdkKey?: string; - persistentCacheProvider?: PersistentCacheProvider; -} - -/** - * Entry level Config Entities for Lite bundle - * For compatibility with the previous declaration file - */ -export interface ConfigLite { +export interface Config { projectConfigManager: ProjectConfigManager; // errorHandler object for logging error errorHandler?: ErrorHandler; diff --git a/lib/tests/testUtils.ts b/lib/tests/testUtils.ts index 8bcd093f8..2a4cbe3c5 100644 --- a/lib/tests/testUtils.ts +++ b/lib/tests/testUtils.ts @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { vi } from 'vitest'; export const exhaustMicrotasks = async (loop = 100): Promise => { for(let i = 0; i < loop; i++) { @@ -21,3 +22,9 @@ export const exhaustMicrotasks = async (loop = 100): Promise => { }; export const wait = (ms: number): Promise => new Promise(resolve => setTimeout(resolve, ms)); + +export const advanceTimersByTime = (waitMs: number): Promise => { + const timeoutPromise: Promise = new Promise(res => setTimeout(res, waitMs)); + vi.advanceTimersByTime(waitMs); + return timeoutPromise; +} diff --git a/lib/utils/executor/backoff_retry_runner.spec.ts b/lib/utils/executor/backoff_retry_runner.spec.ts index 6e2674b10..a1dd1f3a3 100644 --- a/lib/utils/executor/backoff_retry_runner.spec.ts +++ b/lib/utils/executor/backoff_retry_runner.spec.ts @@ -1,6 +1,6 @@ import { vi, describe, it, expect, beforeEach, afterEach } from 'vitest'; import { runWithRetry } from './backoff_retry_runner'; -import { advanceTimersByTime } from '../../../tests/testUtils'; +import { advanceTimersByTime } from '../../tests/testUtils'; const exhaustMicrotasks = async (loop = 100) => { for(let i = 0; i < loop; i++) { diff --git a/tests/utils.spec.ts b/lib/utils/fns/index.spec.ts similarity index 98% rename from tests/utils.spec.ts rename to lib/utils/fns/index.spec.ts index aa529e241..6f93c6ac6 100644 --- a/tests/utils.spec.ts +++ b/lib/utils/fns/index.spec.ts @@ -1,6 +1,6 @@ import { describe, it, expect } from 'vitest'; -import { isValidEnum, groupBy, objectEntries, objectValues, find, keyByUtil, sprintf } from '../lib/utils/fns' +import { isValidEnum, groupBy, objectEntries, objectValues, find, keyByUtil, sprintf } from '.' describe('utils', () => { describe('isValidEnum', () => { diff --git a/tests/browserRequestHandler.spec.ts b/lib/utils/http_request_handler/request_handler.browser.spec.ts similarity index 96% rename from tests/browserRequestHandler.spec.ts rename to lib/utils/http_request_handler/request_handler.browser.spec.ts index f28ee1f26..0bb0d98ed 100644 --- a/tests/browserRequestHandler.spec.ts +++ b/lib/utils/http_request_handler/request_handler.browser.spec.ts @@ -17,8 +17,8 @@ import { describe, beforeEach, afterEach, it, expect, vi } from 'vitest'; import { FakeXMLHttpRequest, FakeXMLHttpRequestStatic, fakeXhr } from 'nise'; -import { BrowserRequestHandler } from '../lib/utils/http_request_handler/browser_request_handler'; -import { NoOpLogger } from '../lib/plugins/logger'; +import { BrowserRequestHandler } from './request_handler.browser'; +import { NoOpLogger } from '../../plugins/logger'; describe('BrowserRequestHandler', () => { const host = 'https://endpoint.example.com/api/query'; diff --git a/lib/utils/http_request_handler/browser_request_handler.ts b/lib/utils/http_request_handler/request_handler.browser.ts similarity index 100% rename from lib/utils/http_request_handler/browser_request_handler.ts rename to lib/utils/http_request_handler/request_handler.browser.ts diff --git a/tests/nodeRequestHandler.spec.ts b/lib/utils/http_request_handler/request_handler.node.spec.ts similarity index 98% rename from tests/nodeRequestHandler.spec.ts rename to lib/utils/http_request_handler/request_handler.node.spec.ts index 9bcc0d813..ef10fbc21 100644 --- a/tests/nodeRequestHandler.spec.ts +++ b/lib/utils/http_request_handler/request_handler.node.spec.ts @@ -18,8 +18,8 @@ import { describe, beforeEach, afterEach, beforeAll, afterAll, it, vi, expect } import nock from 'nock'; import zlib from 'zlib'; -import { NodeRequestHandler } from '../lib/utils/http_request_handler/node_request_handler'; -import { NoOpLogger } from '../lib/plugins/logger'; +import { NodeRequestHandler } from './request_handler.node'; +import { NoOpLogger } from '../../plugins/logger'; beforeAll(() => { nock.disableNetConnect(); diff --git a/lib/utils/http_request_handler/node_request_handler.ts b/lib/utils/http_request_handler/request_handler.node.ts similarity index 100% rename from lib/utils/http_request_handler/node_request_handler.ts rename to lib/utils/http_request_handler/request_handler.node.ts diff --git a/lib/utils/repeater/repeater.spec.ts b/lib/utils/repeater/repeater.spec.ts index 7d998e7b6..e92594556 100644 --- a/lib/utils/repeater/repeater.spec.ts +++ b/lib/utils/repeater/repeater.spec.ts @@ -15,7 +15,7 @@ */ import { expect, vi, it, beforeEach, afterEach, describe } from 'vitest'; import { ExponentialBackoff, IntervalRepeater } from './repeater'; -import { advanceTimersByTime } from '../../../tests/testUtils'; +import { advanceTimersByTime } from '../../tests/testUtils'; import { resolvablePromise } from '../promise/resolvablePromise'; describe("ExponentialBackoff", () => { diff --git a/tests/index.react_native.spec.ts b/tests/index.react_native.spec.ts deleted file mode 100644 index a5fab6aff..000000000 --- a/tests/index.react_native.spec.ts +++ /dev/null @@ -1,346 +0,0 @@ -/** - * Copyright 2019-2020, 2022-2024 Optimizely - * - * 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. - */ -import { describe, beforeEach, afterEach, it, expect, vi } from 'vitest'; - -import * as logging from '../lib/modules/logging/logger'; - -import Optimizely from '../lib/optimizely'; -import testData from '../lib/tests/test_data'; -import packageJSON from '../package.json'; -import optimizelyFactory from '../lib/index.react_native'; -import configValidator from '../lib/utils/config_validator'; -import { getMockProjectConfigManager } from '../lib/tests/mock/mock_project_config_manager'; -import { createProjectConfig } from '../lib/project_config/project_config'; - -vi.mock('@react-native-community/netinfo'); -vi.mock('react-native-get-random-values') -vi.mock('fast-text-encoding') - -describe('javascript-sdk/react-native', () => { - beforeEach(() => { - vi.spyOn(optimizelyFactory.eventDispatcher, 'dispatchEvent'); - vi.useFakeTimers(); - }); - - afterEach(() => { - vi.resetAllMocks(); - }); - - describe('APIs', () => { - it('should expose logger, errorHandler, eventDispatcher and enums', () => { - expect(optimizelyFactory.logging).toBeDefined(); - expect(optimizelyFactory.logging.createLogger).toBeDefined(); - expect(optimizelyFactory.logging.createNoOpLogger).toBeDefined(); - expect(optimizelyFactory.errorHandler).toBeDefined(); - expect(optimizelyFactory.eventDispatcher).toBeDefined(); - expect(optimizelyFactory.enums).toBeDefined(); - }); - - describe('createInstance', () => { - const fakeErrorHandler = { handleError: function() {} }; - const fakeEventDispatcher = { dispatchEvent: async function() { - return Promise.resolve({}); - } }; - // @ts-ignore - let silentLogger; - - beforeEach(() => { - // @ts-ignore - silentLogger = optimizelyFactory.logging.createLogger(); - vi.spyOn(console, 'error'); - vi.spyOn(configValidator, 'validate').mockImplementation(() => { - throw new Error('Invalid config or something'); - }); - }); - - afterEach(() => { - vi.resetAllMocks(); - }); - - it('should not throw if the provided config is not valid', () => { - expect(function() { - const optlyInstance = optimizelyFactory.createInstance({ - projectConfigManager: getMockProjectConfigManager(), - // @ts-ignore - logger: silentLogger, - }); - }).not.toThrow(); - }); - - it('should create an instance of optimizely', () => { - const optlyInstance = optimizelyFactory.createInstance({ - projectConfigManager: getMockProjectConfigManager(), - errorHandler: fakeErrorHandler, - // @ts-ignore - logger: silentLogger, - }); - - expect(optlyInstance).toBeInstanceOf(Optimizely); - // @ts-ignore - expect(optlyInstance.clientVersion).toEqual('5.3.4'); - }); - - it('should set the React Native JS client engine and javascript SDK version', () => { - const optlyInstance = optimizelyFactory.createInstance({ - projectConfigManager: getMockProjectConfigManager(), - errorHandler: fakeErrorHandler, - // @ts-ignore - logger: silentLogger, - }); - - // @ts-ignore - expect('react-native-js-sdk').toEqual(optlyInstance.clientEngine); - // @ts-ignore - expect(packageJSON.version).toEqual(optlyInstance.clientVersion); - }); - - it('should allow passing of "react-sdk" as the clientEngine and convert it to "react-native-sdk"', () => { - const optlyInstance = optimizelyFactory.createInstance({ - clientEngine: 'react-sdk', - projectConfigManager: getMockProjectConfigManager(), - errorHandler: fakeErrorHandler, - // @ts-ignore - logger: silentLogger, - }); - // @ts-ignore - expect('react-native-sdk').toEqual(optlyInstance.clientEngine); - }); - - describe('when passing in logLevel', () => { - beforeEach(() => { - vi.spyOn(logging, 'setLogLevel'); - }); - - afterEach(() => { - vi.resetAllMocks(); - }); - - it('should call logging.setLogLevel', () => { - optimizelyFactory.createInstance({ - projectConfigManager: getMockProjectConfigManager({ - initConfig: createProjectConfig(testData.getTestProjectConfig()), - }), - logLevel: optimizelyFactory.enums.LOG_LEVEL.ERROR, - }); - expect(logging.setLogLevel).toBeCalledTimes(1); - expect(logging.setLogLevel).toBeCalledWith(optimizelyFactory.enums.LOG_LEVEL.ERROR); - }); - }); - - describe('when passing in logger', () => { - beforeEach(() => { - vi.spyOn(logging, 'setLogHandler'); - }); - - afterEach(() => { - vi.resetAllMocks(); - }); - - it('should call logging.setLogHandler with the supplied logger', () => { - const fakeLogger = { log: function() {} }; - optimizelyFactory.createInstance({ - projectConfigManager: getMockProjectConfigManager({ - initConfig: createProjectConfig(testData.getTestProjectConfig()), - }), - // @ts-ignore - logger: fakeLogger, - }); - expect(logging.setLogHandler).toBeCalledTimes(1); - expect(logging.setLogHandler).toBeCalledWith(fakeLogger); - }); - }); - - // TODO: user will create and inject an event processor - // these tests will be refactored accordingly - // describe('event processor configuration', () => { - // // @ts-ignore - // let eventProcessorSpy; - // beforeEach(() => { - // eventProcessorSpy = vi.spyOn(eventProcessor, 'createEventProcessor'); - // }); - - // afterEach(() => { - // vi.resetAllMocks(); - // }); - - // it('should use default event flush interval when none is provided', () => { - // optimizelyFactory.createInstance({ - // projectConfigManager: getMockProjectConfigManager({ - // initConfig: createProjectConfig(testData.getTestProjectConfigWithFeatures()), - // }), - // errorHandler: fakeErrorHandler, - // eventDispatcher: fakeEventDispatcher, - // // @ts-ignore - // logger: silentLogger, - // }); - - // expect( - // // @ts-ignore - // eventProcessorSpy - // ).toBeCalledWith( - // expect.objectContaining({ - // flushInterval: 1000, - // }) - // ); - // }); - - // describe('with an invalid flush interval', () => { - // beforeEach(() => { - // vi.spyOn(eventProcessorConfigValidator, 'validateEventFlushInterval').mockImplementation(() => false); - // }); - - // afterEach(() => { - // vi.resetAllMocks(); - // }); - - // it('should ignore the event flush interval and use the default instead', () => { - // optimizelyFactory.createInstance({ - // projectConfigManager: getMockProjectConfigManager({ - // initConfig: createProjectConfig(testData.getTestProjectConfigWithFeatures()), - // }), - // errorHandler: fakeErrorHandler, - // eventDispatcher: fakeEventDispatcher, - // // @ts-ignore - // logger: silentLogger, - // // @ts-ignore - // eventFlushInterval: ['invalid', 'flush', 'interval'], - // }); - // expect( - // // @ts-ignore - // eventProcessorSpy - // ).toBeCalledWith( - // expect.objectContaining({ - // flushInterval: 1000, - // }) - // ); - // }); - // }); - - // describe('with a valid flush interval', () => { - // beforeEach(() => { - // vi.spyOn(eventProcessorConfigValidator, 'validateEventFlushInterval').mockImplementation(() => true); - // }); - - // afterEach(() => { - // vi.resetAllMocks(); - // }); - - // it('should use the provided event flush interval', () => { - // optimizelyFactory.createInstance({ - // projectConfigManager: getMockProjectConfigManager({ - // initConfig: createProjectConfig(testData.getTestProjectConfigWithFeatures()), - // }), - // errorHandler: fakeErrorHandler, - // eventDispatcher: fakeEventDispatcher, - // // @ts-ignore - // logger: silentLogger, - // eventFlushInterval: 9000, - // }); - // expect( - // // @ts-ignore - // eventProcessorSpy - // ).toBeCalledWith( - // expect.objectContaining({ - // flushInterval: 9000, - // }) - // ); - // }); - // }); - - // it('should use default event batch size when none is provided', () => { - // optimizelyFactory.createInstance({ - // projectConfigManager: getMockProjectConfigManager({ - // initConfig: createProjectConfig(testData.getTestProjectConfigWithFeatures()), - // }), - // errorHandler: fakeErrorHandler, - // eventDispatcher: fakeEventDispatcher, - // // @ts-ignore - // logger: silentLogger, - // }); - // expect( - // // @ts-ignore - // eventProcessorSpy - // ).toBeCalledWith( - // expect.objectContaining({ - // batchSize: 10, - // }) - // ); - // }); - - // describe('with an invalid event batch size', () => { - // beforeEach(() => { - // vi.spyOn(eventProcessorConfigValidator, 'validateEventBatchSize').mockImplementation(() => false); - // }); - - // afterEach(() => { - // vi.resetAllMocks(); - // }); - - // it('should ignore the event batch size and use the default instead', () => { - // optimizelyFactory.createInstance({ - // datafile: testData.getTestProjectConfigWithFeatures(), - // errorHandler: fakeErrorHandler, - // eventDispatcher: fakeEventDispatcher, - // // @ts-ignore - // logger: silentLogger, - // // @ts-ignore - // eventBatchSize: null, - // }); - // expect( - // // @ts-ignore - // eventProcessorSpy - // ).toBeCalledWith( - // expect.objectContaining({ - // batchSize: 10, - // }) - // ); - // }); - // }); - - // describe('with a valid event batch size', () => { - // beforeEach(() => { - // vi.spyOn(eventProcessorConfigValidator, 'validateEventBatchSize').mockImplementation(() => true); - // }); - - // afterEach(() => { - // vi.resetAllMocks(); - // }); - - // it('should use the provided event batch size', () => { - // optimizelyFactory.createInstance({ - // projectConfigManager: getMockProjectConfigManager({ - // initConfig: createProjectConfig(testData.getTestProjectConfigWithFeatures()), - // }), - // errorHandler: fakeErrorHandler, - // eventDispatcher: fakeEventDispatcher, - // // @ts-ignore - // logger: silentLogger, - // eventBatchSize: 300, - // }); - // expect( - // // @ts-ignore - // eventProcessorSpy - // ).toBeCalledWith( - // expect.objectContaining({ - // batchSize: 300, - // }) - // ); - // }); - // }); - // }); - }); - }); -}); diff --git a/tests/reactNativeAsyncStorageCache.spec.ts b/tests/reactNativeAsyncStorageCache.spec.ts deleted file mode 100644 index 559c1f071..000000000 --- a/tests/reactNativeAsyncStorageCache.spec.ts +++ /dev/null @@ -1,74 +0,0 @@ -/** - * Copyright 2020, 2022, 2024, Optimizely - * - * 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 - * - * https://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. - */ - -import { describe, beforeEach, it, vi, expect } from 'vitest'; -import ReactNativeAsyncStorageCache from '../lib/plugins/key_value_cache/reactNativeAsyncStorageCache'; - -vi.mock('@react-native-async-storage/async-storage') - -describe('ReactNativeAsyncStorageCache', () => { - const TEST_OBJECT_KEY = 'testObject'; - const testObject = { name: 'An object', with: { some: 2, properties: ['one', 'two'] } }; - let cacheInstance: ReactNativeAsyncStorageCache; - - beforeEach(() => { - cacheInstance = new ReactNativeAsyncStorageCache(); - cacheInstance.set(TEST_OBJECT_KEY, JSON.stringify(testObject)); - }); - - describe('contains', () => { - it('should return true if value with key exists', async () => { - const keyWasFound = await cacheInstance.contains(TEST_OBJECT_KEY); - - expect(keyWasFound).toBe(true); - }); - - it('should return false if value with key does not exist', async () => { - const keyWasFound = await cacheInstance.contains('keyThatDoesNotExist'); - - expect(keyWasFound).toBe(false); - }); - }); - - describe('get', () => { - it('should return correct string when item is found in cache', async () => { - const json = await cacheInstance.get(TEST_OBJECT_KEY); - const parsedObject = JSON.parse(json ?? ''); - - expect(parsedObject).toEqual(testObject); - }); - - it('should return undefined if item is not found in cache', async () => { - const json = await cacheInstance.get('keyThatDoesNotExist'); - - expect(json).toBeUndefined(); - }); - }); - - describe('remove', () => { - it('should return true after removing a found entry', async () => { - const wasSuccessful = await cacheInstance.remove(TEST_OBJECT_KEY); - - expect(wasSuccessful).toBe(true); - }); - - it('should return false after trying to remove an entry that is not found ', async () => { - const wasSuccessful = await cacheInstance.remove('keyThatDoesNotExist'); - - expect(wasSuccessful).toBe(false); - }); - }); -}); diff --git a/tests/testUtils.ts b/tests/testUtils.ts deleted file mode 100644 index 118e3e78c..000000000 --- a/tests/testUtils.ts +++ /dev/null @@ -1,61 +0,0 @@ -/** - * Copyright 2022, 2024, Optimizely - * - * 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. - */ - -import { vi } from 'vitest'; - -import PersistentKeyValueCache from "../lib/plugins/key_value_cache/persistentKeyValueCache"; - -export function advanceTimersByTime(waitMs: number): Promise { - const timeoutPromise: Promise = new Promise(res => setTimeout(res, waitMs)); - vi.advanceTimersByTime(waitMs); - return timeoutPromise; -} - -export function getTimerCount(): number { - return vi.getTimerCount(); -} - -export const getTestPersistentCache = (): PersistentKeyValueCache => { - const cache = { - get: vi.fn().mockImplementation((key: string): Promise => { - let val : string | undefined = undefined; - switch (key) { - case 'opt-datafile-keyThatExists': - val = JSON.stringify({ name: 'keyThatExists' }); - break; - } - return Promise.resolve(val); - }), - - set: vi.fn().mockImplementation((): Promise => { - return Promise.resolve(); - }), - - contains: vi.fn().mockImplementation((): Promise => { - return Promise.resolve(false); - }), - - remove: vi.fn().mockImplementation((): Promise => { - return Promise.resolve(false); - }), - }; - - return cache; -} - -export const wait = (ms: number) => { - return new Promise((resolve) => setTimeout(resolve, ms)); -};