/** * Copyright (c) 2020-present, Goldman Sachs * * 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 { type RenderResult, render, waitFor } from '@testing-library/react'; import { type AbstractPlugin, type AbstractPreset, type PlainObject, } from '@finos/legend-shared'; import { createMock, createSpy } from '@finos/legend-shared/test'; import { ApplicationStore, ApplicationStoreProvider, } from '@finos/legend-application'; import { LegendDataCubePluginManager } from '../../application/LegendDataCubePluginManager.js'; import { Core_LegendDataCubeApplicationPlugin } from '../../application/Core_LegendDataCubeApplicationPlugin.js'; import { TEST__getTestLegendDataCubeApplicationConfig } from '../../application/__test-utils__/LegendDataCubeApplicationTestUtils.js'; import { type LegendDataCubeBuilderState, LegendDataCubeBuilderStore, } from '../../stores/builder/LegendDataCubeBuilderStore.js'; import { type LegendDataCubeApplicationStore, LegendDataCubeBaseStore, } from '../../stores/LegendDataCubeBaseStore.js'; import { TEST__BrowserEnvironmentProvider } from '@finos/legend-application/test'; import { LegendDataCubeFrameworkProvider } from '../LegendDataCubeFrameworkProvider.js'; import { Route, Routes } from '@finos/legend-application/browser'; import { LEGEND_DATA_CUBE_ROUTE_PATTERN } from '../../__lib__/LegendDataCubeNavigation.js'; import { LegendDataCubeBuilder } from '../builder/LegendDataCubeBuilder.js'; import { LEGEND_DATACUBE_TEST_ID } from '@finos/legend-data-cube'; import { Core_LegendDataCube_LegendApplicationPlugin } from '../../application/Core_LegendDataCube_LegendApplicationPlugin.js'; import { V1_EngineServerClient, type PersistentDataCube, type V1_LambdaReturnTypeInput, type V1_Query, type V1_RawLambda, type V1_ValueSpecification, V1_AppDirLevel, V1_entitiesToPureModelContextData, V1_ExecuteInput, V1_PureGraphManager, V1_PureModelContextData, V1_serializePureModelContext, type V1_EntitlementsDataProductDetailsResponse, } from '@finos/legend-graph'; import { DSL_DataSpace_GraphManagerPreset } from '@finos/legend-extension-dsl-data-space/graph'; import { ENGINE_TEST_SUPPORT__execute, ENGINE_TEST_SUPPORT__getLambdaRelationType, ENGINE_TEST_SUPPORT__getLambdaReturnType, ENGINE_TEST_SUPPORT__grammarToJSON_lambda, ENGINE_TEST_SUPPORT__grammarToJSON_valueSpecification, ENGINE_TEST_SUPPORT__JSONToGrammar_valueSpecification, ENGINE_TEST_SUPPORT__transformTdsToRelation_lambda, } from '@finos/legend-graph/test'; import type { Entity } from '@finos/legend-storage'; import { LegendDataCubeDataCubeEngine } from '../../stores/LegendDataCubeDataCubeEngine.js'; import { LegendQueryDataCubeSourceBuilder_DataCubeApplicationPlugin } from '../builder/source/LegendQueryDataCubeSourceBuilder_DataCubeApplicationPlugin.js'; import { DepotServerClient } from '@finos/legend-server-depot'; import { LakehouseContractServerClient, LakehouseIngestServerClient, } from '@finos/legend-server-lakehouse'; export const DEFAULT_MOCK_ADHOC_DATA_PRODUCT: PlainObject = { dataProducts: [ { id: 'test-id', deploymentId: 22222, description: 'test description', origin: { type: 'AdHocDeployment', definition: 'test-definition', }, lakehouseEnvironment: { producerEnvironmentName: 'DEVELOPMENT', type: 'DEVELOPMENT', }, dataProduct: { name: 'MOCK_ADHOC_DATAPRODUCT', accessPoints: [ { name: 'TEST_VIEW', groups: ['GROUP1'], }, ], accessPointGroupStereotypeMappings: [], owner: { appDirId: 22222, level: V1_AppDirLevel.DEPLOYMENT, }, }, }, ], }; export const DEFAULT_MOCK_PMCD: PlainObject = { _type: 'pureModelContextData', elements: [ { _type: 'packageableElement', name: 'LakehouseConsumer', package: 'adhoc::test', }, ], }; export const TEST__provideMockedLegendDataCubeEngine = async (customization?: { mock?: LegendDataCubeDataCubeEngine | undefined; applicationStore?: LegendDataCubeApplicationStore | undefined; pluginManager?: LegendDataCubePluginManager | undefined; extraPlugins?: AbstractPlugin[] | undefined; extraPresets?: AbstractPreset[] | undefined; depotServerClient?: DepotServerClient | undefined; enginerServerClient?: V1_EngineServerClient | undefined; lakehouseContractServerClient?: LakehouseContractServerClient | undefined; ingestServer?: LakehouseIngestServerClient | undefined; graphManager?: V1_PureGraphManager | undefined; mockPMCD?: PlainObject; mockEntitlementsAdHocDataProduct?: PlainObject; }): Promise => { //create application store const pluginManager = customization?.pluginManager ?? LegendDataCubePluginManager.create(); pluginManager .usePlugins([ new Core_LegendDataCube_LegendApplicationPlugin(), new Core_LegendDataCubeApplicationPlugin(), new LegendQueryDataCubeSourceBuilder_DataCubeApplicationPlugin(), ...(customization?.extraPlugins ?? []), ]) .usePresets([ new DSL_DataSpace_GraphManagerPreset(), ...(customization?.extraPresets ?? []), ]) .install(); const applicationStore = customization?.applicationStore ?? new ApplicationStore( TEST__getTestLegendDataCubeApplicationConfig(), pluginManager, ); //Server Clients const depotServerClient = customization?.depotServerClient ?? new DepotServerClient({ serverUrl: applicationStore.config.depotServerUrl, }); const engineServerClient = customization?.enginerServerClient ?? new V1_EngineServerClient({ baseUrl: applicationStore.config.engineServerUrl, }); const lakehouseIngestServerClient = customization?.ingestServer ?? new LakehouseIngestServerClient(undefined); const lakehouseContractServerClient = customization?.lakehouseContractServerClient ?? new LakehouseContractServerClient({ baseUrl: applicationStore.config.lakehouseContractUrl, }); if (customization?.mockPMCD) { createSpy(depotServerClient, 'getPureModelContextData').mockResolvedValue( customization.mockPMCD, ); } if (customization?.mockEntitlementsAdHocDataProduct) { createSpy( lakehouseContractServerClient, 'getDataProduct', ).mockResolvedValue(customization.mockEntitlementsAdHocDataProduct); } createSpy( lakehouseIngestServerClient, 'getIngestDefinitionGrammar', ).mockResolvedValue('test-ingest-definition-grammar'); createSpy( lakehouseContractServerClient, 'getUserEntitlementEnvs', ).mockResolvedValue({ total: 1, users: [ { name: 'TESTER', userType: 'TEST_USER', lakehouseEnvironment: 'testEnv1', }, ], }); const graphManager = customization?.graphManager ?? new V1_PureGraphManager( applicationStore.pluginManager, applicationStore.logService, ); const value = customization?.mock ?? new LegendDataCubeDataCubeEngine( applicationStore, depotServerClient, engineServerClient, lakehouseContractServerClient, lakehouseIngestServerClient, graphManager, ); if ('initialize' in value && typeof value.initialize === 'function') { await value.initialize(); } return value; }; export const mockLakehouseConsumerAdHocDataProduct = { _type: 'lakehouseConsumer', warehouse: 'TEST_WAREHOUSE', // this environment gets overridden as we have runtime calls for fetching user entitlement envs // this makes saving view user agnostic environment: 'dev-testEnv', paths: ['dataProduct::test_DataProduct', 'test_dataset'], origin: { _type: 'AdHocDeployment', }, deploymentId: 123456, }; export const mockLakehouseProducerAdHocDataProduct = { _type: 'lakehouseProducer', ingestDefinitionUrn: 'test_ingest-definition-urn', warehouse: 'TEST_WAREHOUSE', ingestServerUrl: 'https://test-prod-ingest-server.com', paths: ['dataProduct::test_Data-Product', 'test_data-set'], }; export const columns = [ { name: 'testName0', type: 'testName0-test-type', }, { name: 'testName1', type: 'testName1-test-type', }, { name: 'testName2', type: 'testName2-test-type', }, { name: 'testName3', type: 'testName3-test-type', }, { name: 'testName4', type: 'testName4-test-type', }, { name: 'testName5', type: 'testName5-test-type', }, ]; export const mockAdHocDataProductPMCD = { _type: 'data', elements: [ { _type: 'ingestDefinition', package: 'test', name: 'IngestDefinition', owner: { _type: 'ownerTestType', production: { appDirId: 22222, level: 'DEPLOYMENT', }, }, }, { _type: 'dataProduct', package: 'test', name: 'Mock_AdHoc_DataProduct', title: 'Mock Ad-Hoc Data Product', description: 'test description', accessPointGroups: [ { _type: 'defaultAccessPointGroup', id: 'GROUP1', description: 'Test ad-hoc access point group', accessPoints: [ { _type: 'lakehouseAccessPoint', id: 'test_view', func: { _type: 'lambda', body: [ { _type: 'classInstance', type: 'I', value: { metadata: false, path: ['test', 'IngestDefinition'], }, }, ], parameters: [], }, }, ], }, ], }, { package: '__internal__', name: 'SectionIndex', sections: [ { parserName: 'Pure', elements: [], imports: [], _type: 'importAware', }, { parserName: 'Lakehouse', elements: ['migration_test::test:Product'], _type: 'default', }, { parserName: 'DataProduct', elements: ['lakeMigration::dataProduct::test:Product'], imports: [], _type: 'importAware', }, ], _type: 'sectionIndex', }, ], }; export const TEST__provideMockedLegendDataCubeBaseStore = async (customization?: { mock?: LegendDataCubeBaseStore | undefined; applicationStore?: LegendDataCubeApplicationStore | undefined; pluginManager?: LegendDataCubePluginManager | undefined; extraPlugins?: AbstractPlugin[] | undefined; extraPresets?: AbstractPreset[] | undefined; }): Promise => { const pluginManager = customization?.pluginManager ?? LegendDataCubePluginManager.create(); pluginManager .usePlugins([ new Core_LegendDataCube_LegendApplicationPlugin(), new Core_LegendDataCubeApplicationPlugin(), new LegendQueryDataCubeSourceBuilder_DataCubeApplicationPlugin(), ...(customization?.extraPlugins ?? []), ]) .usePresets([ new DSL_DataSpace_GraphManagerPreset(), ...(customization?.extraPresets ?? []), ]) .install(); const applicationStore = customization?.applicationStore ?? new ApplicationStore( TEST__getTestLegendDataCubeApplicationConfig(), pluginManager, ); const value = customization?.mock ?? new LegendDataCubeBaseStore(applicationStore); await value.initialize(); const MOCK__LegendDataCubeBaseStoreProvider = require('../LegendDataCubeFrameworkProvider.js'); // eslint-disable-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-require-imports MOCK__LegendDataCubeBaseStoreProvider.useLegendDataCubeBaseStore = createMock(); MOCK__LegendDataCubeBaseStoreProvider.useLegendDataCubeBaseStore.mockReturnValue( value, ); return value; }; export const TEST__provideMockedLegendDataCubeBuilderStore = async (customization?: { mock?: LegendDataCubeBuilderStore; mockBaseStore?: LegendDataCubeBaseStore; applicationStore?: LegendDataCubeApplicationStore; pluginManager?: LegendDataCubePluginManager; extraPlugins?: AbstractPlugin[]; extraPresets?: AbstractPreset[]; }): Promise => { const value = customization?.mock ?? new LegendDataCubeBuilderStore( await TEST__provideMockedLegendDataCubeBaseStore({ mock: customization?.mockBaseStore, applicationStore: customization?.applicationStore, pluginManager: customization?.pluginManager, extraPlugins: customization?.extraPlugins, extraPresets: customization?.extraPresets, }), ); const MOCK__LegendDataCubeBuilderStoreProvider = require('../builder/LegendDataCubeBuilderStoreProvider.js'); // eslint-disable-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-require-imports MOCK__LegendDataCubeBuilderStoreProvider.useLegendDataCubeBuilderStore = createMock(); MOCK__LegendDataCubeBuilderStoreProvider.useLegendDataCubeBuilderStore.mockReturnValue( value, ); return value; }; export const TEST__setUpDataCubeBuilder = async ( MOCK__builderStore: LegendDataCubeBuilderStore, mockDataCube?: PersistentDataCube, mockQuery?: V1_Query, mockEntities?: PlainObject[], forceUseInputModel: boolean = false, ): Promise<{ renderResult: RenderResult; legendDataCubeBuilderState: LegendDataCubeBuilderState | undefined; }> => { if (mockDataCube) { createSpy(MOCK__builderStore.graphManager, 'getDataCube').mockResolvedValue( mockDataCube, ); } if (mockQuery) { createSpy( MOCK__builderStore.graphManager.engine, 'getQuery', ).mockResolvedValue(mockQuery); } if (mockEntities) { const pmcd = new V1_PureModelContextData(); await V1_entitiesToPureModelContextData( mockEntities as unknown as Entity[], pmcd, MOCK__builderStore.application.pluginManager.getPureProtocolProcessorPlugins(), undefined, undefined, ); createSpy( MOCK__builderStore.depotServerClient, 'getVersionEntities', ).mockResolvedValue(mockEntities); createSpy( MOCK__builderStore.engineServerClient, 'lambdaReturnType', ).mockImplementation( async (input: PlainObject) => { return ENGINE_TEST_SUPPORT__getLambdaReturnType( input.lambda as PlainObject, forceUseInputModel ? (input.model as PlainObject) : V1_serializePureModelContext(pmcd), ); }, ); createSpy( MOCK__builderStore.engineServerClient, 'lambdaRelationType', ).mockImplementation( async (input: PlainObject) => { return ENGINE_TEST_SUPPORT__getLambdaRelationType( input.lambda as PlainObject, forceUseInputModel ? (input.model as PlainObject) : V1_serializePureModelContext(pmcd), ); }, ); createSpy( MOCK__builderStore.engineServerClient, 'transformTdsToRelation_lambda', ).mockImplementation( async (input: PlainObject) => { return ENGINE_TEST_SUPPORT__transformTdsToRelation_lambda( input.lambda as PlainObject, forceUseInputModel ? (input.model as PlainObject) : V1_serializePureModelContext(pmcd), ); }, ); createSpy( MOCK__builderStore.engineServerClient, 'runQuery', ).mockImplementation(async (input: PlainObject) => { const executeInput = V1_ExecuteInput.serialization.fromJson(input); executeInput.model = forceUseInputModel ? executeInput.model : pmcd; return ENGINE_TEST_SUPPORT__execute(executeInput); }); } createSpy( MOCK__builderStore.engineServerClient, 'grammarToJSON_lambda', ).mockImplementation(async (input: string) => ENGINE_TEST_SUPPORT__grammarToJSON_lambda(input), ); createSpy( MOCK__builderStore.engineServerClient, 'grammarToJSON_valueSpecification', ).mockImplementation(async (input: string) => ENGINE_TEST_SUPPORT__grammarToJSON_valueSpecification(input), ); createSpy( MOCK__builderStore.engineServerClient, 'JSONToGrammar_valueSpecification', ).mockImplementation(async (input: PlainObject) => ENGINE_TEST_SUPPORT__JSONToGrammar_valueSpecification(input), ); const renderResult = render( } /> , ); await waitFor(() => renderResult.getByTestId(LEGEND_DATACUBE_TEST_ID.PLACEHOLDER), ); return { renderResult, legendDataCubeBuilderState: MOCK__builderStore.builder, }; };