### Install ComponentFramework Mock with yarn Source: https://github.com/shko-online/componentframework-mock/blob/main/README.md Installs the ComponentFramework Mock package as a development dependency using yarn. ```cmd yarn add -D @shko.online/componentframework-mock ``` -------------------------------- ### Install ComponentFramework Mock with npm Source: https://github.com/shko-online/componentframework-mock/blob/main/README.md Installs the ComponentFramework Mock package as a development dependency using npm. ```cmd npm install -D @shko.online/componentframework-mock ``` -------------------------------- ### CSS Styling Import and Application Source: https://github.com/shko-online/componentframework-mock/blob/main/storybook/stories/Introduction.mdx Imports and applies CSS styles to the Introduction component. It uses a CSS module for scoped styling. ```javascript import style from './Introduction.style.css'; ``` -------------------------------- ### Storybook Metadata Configuration Source: https://github.com/shko-online/componentframework-mock/blob/main/storybook/stories/Introduction.mdx Configures the Storybook metadata for the Introduction component. It sets the title for the component within the Storybook UI. ```javascript import { Meta } from '@storybook/blocks'; ``` -------------------------------- ### Initialize and Test Property Mocks with ComponentFrameworkMockGenerator Source: https://context7.com/shko-online/componentframework-mock/llms.txt Demonstrates how to initialize and test various property mocks (DateTime, Enum, Lookup, String, WholeNumber, OptionSet, MultiSelectOptionSet) using the ComponentFrameworkMockGenerator. It covers setting initial values, reading raw property data, and simulating platform updates. ```typescript import { ComponentFrameworkMockGenerator, DateTimePropertyMock, EnumPropertyMock, LookupPropertyMock, StringPropertyMock, WholeNumberPropertyMock, OptionSetPropertyMock, MultiSelectOptionSetPropertyMock, } from '@shko.online/componentframework-mock'; import { MyControl } from './MyControl'; import { IInputs, IOutputs } from './MyControl/generated/ManifestTypes'; describe('Property Mocks', () => { let mockGenerator: ComponentFrameworkMockGenerator; beforeEach(() => { const container = document.createElement('div'); mockGenerator = new ComponentFrameworkMockGenerator( MyControl, { dateField: DateTimePropertyMock, enumField: EnumPropertyMock, lookupField: LookupPropertyMock, textField: StringPropertyMock, numberField: WholeNumberPropertyMock, statusField: OptionSetPropertyMock, tagsField: MultiSelectOptionSetPropertyMock, }, container, ); // Set initial values mockGenerator.context._SetCanvasItems({ dateField: new Date(2023, 5, 15), enumField: 'Yes', lookupField: { entityType: 'contact', id: 'contact-1', name: 'John Doe' }, textField: 'Hello World', numberField: 42, statusField: 1, tagsField: [1, 2, 3], }); }); it('Should read property values', () => { mockGenerator.ExecuteInit(); mockGenerator.ExecuteUpdateView(); expect(mockGenerator.context._parameters.dateField.raw).toEqual(new Date(2023, 5, 15)); expect(mockGenerator.context._parameters.enumField.raw).toEqual('Yes'); expect(mockGenerator.context._parameters.lookupField.raw[0].name).toEqual('John Doe'); expect(mockGenerator.context._parameters.textField.raw).toEqual('Hello World'); expect(mockGenerator.context._parameters.numberField.raw).toEqual(42); }); it('Should update property values from platform', () => { mockGenerator.ExecuteInit(); mockGenerator.ExecuteUpdateView(); // Simulate platform updating values mockGenerator.context._parameters.dateField._SetValue(new Date(2024, 0, 1)); mockGenerator.context._parameters.dateField._Refresh(); expect(mockGenerator.context._parameters.dateField.raw).toEqual(new Date(2024, 0, 1)); }); it('Should use UpdateValues for bulk updates', () => { mockGenerator.ExecuteInit(); mockGenerator.ExecuteUpdateView(); // Update multiple values at once (simulates platform changes) mockGenerator.UpdateValues({ textField: 'Updated Text', numberField: 100, enumField: 'No', }); mockGenerator.ExecuteUpdateView(); expect(mockGenerator.context.updatedProperties).toContain('textField'); expect(mockGenerator.context.updatedProperties).toContain('numberField'); expect(mockGenerator.context.updatedProperties).toContain('enumField'); }); }); ``` -------------------------------- ### Import PCF Component and Types Source: https://github.com/shko-online/componentframework-mock/blob/main/README.md Imports a sample PCF component (OwnerLookup) and its associated input/output types for use in tests or stories. ```typescript import { OwnerLookup } from '../__sample-components__/OwnerLookup'; import { IInputs, IOutputs } from '../__sample-components__/OwnerLookup/generated/ManifestTypes'; ``` -------------------------------- ### Initialize and Test DataSetMock with TypeScript Source: https://context7.com/shko-online/componentframework-mock/llms.txt Demonstrates initializing the DataSetMock with records using `_InitItems` and testing standard DataSet API methods like `sortedRecordIds`, `columns`, `records`, `paging`, and `filtering` within a TypeScript test environment. It also includes tests for record selection and clearing selections. ```typescript import { ComponentFrameworkMockGenerator, DataSetMock } from '@shko.online/componentframework-mock'; import { GridControl } from './GridControl'; import { IInputs, IOutputs } from './GridControl/generated/ManifestTypes'; describe('GridControl', () => { let mockGenerator: ComponentFrameworkMockGenerator; beforeEach(() => { const container = document.createElement('div'); mockGenerator = new ComponentFrameworkMockGenerator( GridControl, { records: DataSetMock, }, container, ); // Initialize dataset with records mockGenerator.context._parameters.records._InitItems([ { id: '1', name: 'Betim', company: 'Shko Online' }, { id: '2', name: 'John', company: 'AlbanianXrm' }, ]); document.body.appendChild(container); }); it('Should render data grid', (done) => { // Listen for dataset loaded callback mockGenerator.context._parameters.records._onLoaded.callsFake(() => { expect(mockGenerator.container).toMatchSnapshot(); // Verify dataset properties expect(mockGenerator.context._parameters.records.sortedRecordIds).toEqual(['1', '2']); expect(mockGenerator.context._parameters.records.columns.length).toBe(3); done(); }); mockGenerator.ExecuteInit(); mockGenerator.ExecuteUpdateView(); }); it('Should handle record selection', () => { mockGenerator.ExecuteInit(); const dataset = mockGenerator.context._parameters.records; dataset.setSelectedRecordIds(['1', '2']); expect(dataset.getSelectedRecordIds()).toEqual(['1', '2']); dataset.clearSelectedRecordIds(); expect(dataset.getSelectedRecordIds()).toEqual([]); }); }); ``` -------------------------------- ### Instantiate ComponentFrameworkMockGenerator Source: https://github.com/shko-online/componentframework-mock/blob/main/README.md Creates an instance of ComponentFrameworkMockGenerator, providing the component, parameter mappings, and a container element. ```typescript let mockGenerator: ComponentFrameworkMockGenerator = new ComponentFrameworkMockGenerator( OwnerLookup, { value: LookupPropertyMock, }, container, ); ``` -------------------------------- ### Execute Component Lifecycle Methods Source: https://github.com/shko-online/componentframework-mock/blob/main/README.md Executes the initialization and update view methods for the mock component. ExecuteInit should be called once, and ExecuteUpdateView at least once. ```typescript mockGenerator.ExecuteInit(); mockGenerator.ExecuteUpdateView(); ``` -------------------------------- ### Mock PCF Navigation API with Sinon Stubs (TypeScript) Source: https://context7.com/shko-online/componentframework-mock/llms.txt This snippet demonstrates how to mock the PCF Navigation API using Sinon stubs within a TypeScript test environment. It covers mocking alert dialogs, confirm dialogs with custom responses, form navigation, and tracking URL navigation calls. The mockGenerator from @shko.online/componentframework-mock is used to set up and interact with these mocked navigation methods. ```typescript import { ComponentFrameworkMockGenerator, StringPropertyMock } from '@shko.online/componentframework-mock'; import { MyControl } from './MyControl'; import { IInputs, IOutputs } from './MyControl/generated/ManifestTypes'; describe('NavigationMock', () => { let mockGenerator: ComponentFrameworkMockGenerator; beforeEach(() => { const container = document.createElement('div'); mockGenerator = new ComponentFrameworkMockGenerator( MyControl, { textField: StringPropertyMock }, container, ); }); it('Should mock alert dialogs', async () => { mockGenerator.ExecuteInit(); await mockGenerator.context.navigation.openAlertDialog({ text: 'This is an alert', confirmButtonLabel: 'OK', }); expect(mockGenerator.context.navigation.openAlertDialog.calledOnce).toBeTruthy(); }); it('Should mock confirm dialogs with custom response', async () => { // Configure custom response mockGenerator.context.navigation.openConfirmDialog.resolves({ confirmed: false }); mockGenerator.ExecuteInit(); const result = await mockGenerator.context.navigation.openConfirmDialog({ title: 'Confirm Action', text: 'Are you sure?', }); expect(result.confirmed).toBe(false); }); it('Should mock form navigation', async () => { mockGenerator.context.navigation.openForm.resolves({ savedEntityReference: [{ entityType: 'account', id: 'new-id', name: 'New Account' }], }); mockGenerator.ExecuteInit(); const result = await mockGenerator.context.navigation.openForm({ entityName: 'account', useQuickCreateForm: true, }); expect(result.savedEntityReference[0].entityType).toEqual('account'); }); it('Should track URL navigation', () => { mockGenerator.ExecuteInit(); mockGenerator.context.navigation.openUrl('https://example.com', { height: 600, width: 800 }); expect(mockGenerator.context.navigation.openUrl.calledWith('https://example.com')).toBeTruthy(); }); }); ``` -------------------------------- ### Test PCF Control Mode and Context Properties with TypeScript Source: https://context7.com/shko-online/componentframework-mock/llms.txt This TypeScript code demonstrates how to use the ComponentFrameworkMockGenerator to test various mode and context properties of a PCF control. It covers setting visibility, disabled states, fullscreen mode, tracking container resize, and accessing user settings. Dependencies include @shko.online/componentframework-mock and the control's generated manifest types. ```typescript import { ComponentFrameworkMockGenerator, LookupPropertyMock } from '@shko.online/componentframework-mock'; import { MyControl } from './MyControl'; import { IInputs, IOutputs } from './MyControl/generated/ManifestTypes'; describe('Mode and Context', () => { let mockGenerator: ComponentFrameworkMockGenerator; beforeEach(() => { const container = document.createElement('div'); mockGenerator = new ComponentFrameworkMockGenerator( MyControl, { value: LookupPropertyMock }, container, ); }); it('Should handle visibility and disabled states', () => { mockGenerator.context.mode.isVisible = true; mockGenerator.context.mode.isControlDisabled = false; mockGenerator.ExecuteInit(); mockGenerator.ExecuteUpdateView(); // Toggle disabled state mockGenerator.context.mode.isControlDisabled = true; mockGenerator.ExecuteUpdateView(); expect(mockGenerator.control.updateView.calledTwice).toBeTruthy(); }); it('Should handle fullscreen mode', () => { mockGenerator.ExecuteInit(); mockGenerator.context.mode.setFullScreen(true); expect(mockGenerator.context.updatedProperties).toContain('fullscreen_open'); mockGenerator.context.mode._FullScreen = true; mockGenerator.context.mode.setFullScreen(false); expect(mockGenerator.context.updatedProperties).toContain('fullscreen_close'); }); it('Should track container resize', () => { mockGenerator.ExecuteInit(); // Enable resize tracking mockGenerator.context.mode.trackContainerResize(true); // Access allocated dimensions mockGenerator.context.mode.allocatedHeight = 400; mockGenerator.context.mode.allocatedWidth = 600; mockGenerator.ExecuteUpdateView(); }); it('Should configure user settings', () => { mockGenerator.context.userSettings.userId = 'user-guid'; mockGenerator.context.userSettings.userName = 'Test User'; mockGenerator.context.userSettings.languageId = 1033; // English mockGenerator.ExecuteInit(); // User settings are available to the control expect(mockGenerator.context.userSettings.userId).toEqual('user-guid'); }); }); ``` -------------------------------- ### Test React PCF Controls with ComponentFrameworkMockGeneratorReact Source: https://context7.com/shko-online/componentframework-mock/llms.txt Tests virtual/React-based PCF controls using ComponentFrameworkMockGeneratorReact. Initializes the mock environment, sets property values, and simulates the PCF lifecycle to render ReactElements. Suitable for controls implementing ComponentFramework.ReactControl. ```typescript import { ComponentFrameworkMockGeneratorReact, StringPropertyMock } from '@shko.online/componentframework-mock'; import { render } from 'react-test-renderer'; import { MyReactControl } from './MyReactControl'; import { IInputs, IOutputs } from './MyReactControl/generated/ManifestTypes'; describe('MyReactControl', () => { let mockGenerator: ComponentFrameworkMockGeneratorReact; beforeEach(() => { mockGenerator = new ComponentFrameworkMockGeneratorReact( MyReactControl, { textValue: StringPropertyMock, }, ); mockGenerator.context._SetCanvasItems({ textValue: 'Hello World', }); }); it('Should render React component', () => { mockGenerator.ExecuteInit(); // ExecuteUpdateView returns a ReactElement for virtual controls const reactElement = mockGenerator.ExecuteUpdateView(); const tree = render(reactElement); expect(tree.toJSON()).toMatchSnapshot(); }); }); ``` -------------------------------- ### Orchestrate Multiple PCF Controls with Shared State Source: https://context7.com/shko-online/componentframework-mock/llms.txt Demonstrates how to use ComponentFrameworkMockOrchestrator to test multiple PCF controls that share state or interact. It creates a shared MetadataDB instance, allowing controls to access and coordinate updates to entity data. This is useful for scenarios involving complex inter-component communication. ```typescript import { ComponentFrameworkMockOrchestrator, DateTimePropertyMock, EnumPropertyMock, LookupPropertyMock, } from '@shko.online/componentframework-mock'; import { OwnerLookup } from './OwnerLookup'; import { YearPicker } from './YearPicker'; import { IInputs as IInputs1, IOutputs as IOutputs1 } from './OwnerLookup/generated/ManifestTypes'; import { IInputs as IInputs2, IOutputs as IOutputs2 } from './YearPicker/generated/ManifestTypes'; describe('Multiple Components', () => { let orchestrator: ComponentFrameworkMockOrchestrator<[IInputs1, IOutputs1, false, IInputs2, IOutputs2, false]>; beforeEach(() => { const container1 = document.createElement('div'); const container2 = document.createElement('div'); orchestrator = new ComponentFrameworkMockOrchestrator([ [OwnerLookup, { value: LookupPropertyMock }, container1], [YearPicker, { value: DateTimePropertyMock, enum: EnumPropertyMock }, container2], ]); // Configure first control orchestrator.mockGenerators[0].context._SetCanvasItems({ value: { entityType: 'team', id: 'guid1', name: 'Shko Online' }, }); // Configure second control orchestrator.mockGenerators[1].context._SetCanvasItems({ value: new Date(2023, 0, 1), enum: 'Yes', }); document.body.appendChild(container1); document.body.appendChild(container2); }); it('Should initialize and update both controls', () => { // Initialize all controls at once orchestrator.ExecuteInit(); // Update views individually orchestrator.mockGenerators[0].ExecuteUpdateView(); orchestrator.mockGenerators[1].ExecuteUpdateView(); expect(document.body).toMatchSnapshot(); }); it('Should share database between controls', () => { orchestrator.ExecuteInit(); // Both controls share the same MetadataDB const sharedDb = orchestrator.db; // Add data that both controls can access sharedDb.initMetadata([ { LogicalName: 'contact', EntitySetName: 'contacts', PrimaryIdAttribute: 'contactid', PrimaryNameAttribute: 'fullname', Attributes: [], }, ]); sharedDb.initItems({ '@odata.context': '#contacts', value: [{ contactid: 'c1', fullname: 'Test Contact' }], }); // Both controls can now query this data via context.webAPI }); }); ``` -------------------------------- ### WebAPI Mock Testing with TypeScript Source: https://context7.com/shko-online/componentframework-mock/llms.txt Demonstrates testing CRUD operations against a mocked Dataverse WebAPI using TypeScript. It initializes metadata, populates test data, and performs create, retrieve, update, and delete operations. ```typescript import { ComponentFrameworkMockGenerator, StringPropertyMock, AttributeType, ShkoOnline } from '@shko.online/componentframework-mock'; import { WebAPIControl } from './WebAPIControl'; import { IInputs, IOutputs } from './WebAPIControl/generated/ManifestTypes'; describe('WebAPIControl', () => { let mockGenerator: ComponentFrameworkMockGenerator; beforeEach(() => { const container = document.createElement('div'); mockGenerator = new ComponentFrameworkMockGenerator( WebAPIControl, { stringProperty: StringPropertyMock }, container, ); // Initialize entity metadata mockGenerator.metadata.initMetadata([ { LogicalName: 'account', EntitySetName: 'accounts', PrimaryIdAttribute: 'accountid', PrimaryNameAttribute: 'name', Attributes: [ { AttributeType: AttributeType.Uniqueidentifier, LogicalName: 'accountid', SchemaName: 'AccountId' } as ShkoOnline.AttributeMetadata, { AttributeType: AttributeType.String, LogicalName: 'name', SchemaName: 'Name' } as ShkoOnline.StringAttributeMetadata, { AttributeType: AttributeType.Money, LogicalName: 'revenue', SchemaName: 'Revenue' } as ShkoOnline.AttributeMetadata, ], }, ]); // Optional: Set WebAPI delay to 0 for faster tests mockGenerator.context.webAPI._Delay = 0; }); it('Should create and retrieve records', async () => { // Create a record const created = await mockGenerator.context.webAPI.createRecord('account', { name: 'Contoso', revenue: 1000000, }); expect(created.id).toBeDefined(); // Retrieve the record const retrieved = await mockGenerator.context.webAPI.retrieveRecord('account', created.id); expect(retrieved.name).toEqual('Contoso'); }); it('Should retrieve multiple records with FetchXML', async () => { // Add test data mockGenerator.metadata.initItems({ '@odata.context': '#accounts', value: [ { accountid: 'id-1', name: 'Account A', revenue: 500000 }, { accountid: 'id-2', name: 'Account B', revenue: 750000 }, ], }); const fetchXml = ` `; const result = await mockGenerator.context.webAPI.retrieveMultipleRecords( 'account', '?fetchXml=' + encodeURIComponent(fetchXml) ); expect(result.entities.length).toBe(2); expect(result.entities[0].name).toBe('Account A'); }); it('Should update and delete records', async () => { mockGenerator.metadata.initItems({ '@odata.context': '#accounts', value: [{ accountid: 'test-id', name: 'Original Name' }], }); // Update await mockGenerator.context.webAPI.updateRecord('account', 'test-id', { name: 'Updated Name' }); const updated = mockGenerator.metadata.GetRow('account', 'test-id'); expect(updated.row.name).toEqual('Updated Name'); // Delete const deleted = await mockGenerator.context.webAPI.deleteRecord('account', 'test-id'); expect(deleted.entityType).toEqual('account'); }); }); ``` -------------------------------- ### Import Mock Generator and Property Mocks Source: https://github.com/shko-online/componentframework-mock/blob/main/README.md Imports the necessary mock generator and property mock classes from the ComponentFramework Mock library. ```typescript import { ComponentFrameworkMockGenerator, LookupPropertyMock } from '@shko.online/componentframework-mock'; ``` -------------------------------- ### Test Standard PCF Controls with ComponentFrameworkMockGenerator Source: https://context7.com/shko-online/componentframework-mock/llms.txt Tests standard DOM-based PCF controls using ComponentFrameworkMockGenerator. Initializes the mock environment, sets property values, simulates user interactions, and verifies output changes. Requires the control class, property mocks, and a DOM container. ```typescript import { ComponentFrameworkMockGenerator, LookupPropertyMock } from '@shko.online/componentframework-mock'; import { OwnerLookup } from './OwnerLookup'; import { IInputs, IOutputs } from './OwnerLookup/generated/ManifestTypes'; describe('OwnerLookup', () => { let mockGenerator: ComponentFrameworkMockGenerator; beforeEach(() => { const container = document.createElement('div'); mockGenerator = new ComponentFrameworkMockGenerator( OwnerLookup, { value: LookupPropertyMock, }, container, ); // Set initial values using _SetCanvasItems mockGenerator.context._SetCanvasItems({ value: { entityType: 'team', id: 'guid1', name: 'Shko Online', }, }); // Configure user settings mockGenerator.context.userSettings.userId = 'MyUserId'; mockGenerator.context.userSettings.userName = 'Betim Beja'; document.body.appendChild(container); }); it('Should render lookup value', () => { mockGenerator.ExecuteInit(); mockGenerator.ExecuteUpdateView(); expect(mockGenerator.container).toMatchSnapshot(); }); it('Should detect output changes', () => { mockGenerator.ExecuteInit(); mockGenerator.ExecuteUpdateView(); // Simulate user interaction const button = mockGenerator.container.getElementsByTagName('button')[0]; button.click(); // Verify updatedProperties contains changed fields expect(mockGenerator.context.updatedProperties).toStrictEqual(['value', 'parameters']); expect(mockGenerator.onOutputChanged.called).toBeTruthy(); }); }); ``` -------------------------------- ### Mock PCF Formatting API for Locale-Aware Formatting Source: https://context7.com/shko-online/componentframework-mock/llms.txt Provides a mock implementation of the PCF Formatting API, enabling locale-aware formatting of various data types including currencies, numbers, and dates. This mock is essential for testing components that rely on the PCF's built-in formatting capabilities without needing a live environment. ```typescript import { FormattingMock } from '@shko.online/componentframework-mock'; describe('FormattingMock', () => { let formatting: FormattingMock; beforeEach(() => { formatting = new FormattingMock(); }); it('Should format currency values', () => { expect(formatting.formatCurrency(100500, 2, '$')).toEqual('$100,500.00'); expect(formatting.formatCurrency(100600, 2, '€')).toEqual('€100,600.00'); expect(formatting.formatCurrency(100100)).toEqual('100,100'); }); it('Should format decimal values', () => { expect(formatting.formatDecimal(10098, 2)).toEqual('10,098.00'); expect(formatting.formatDecimal(1234.5678, 3)).toEqual('1,234.568'); }); it('Should format integers', () => { expect(formatting.formatInteger(1000000)).toEqual('1,000,000'); }); }); ``` -------------------------------- ### Set Canvas Item State Source: https://github.com/shko-online/componentframework-mock/blob/main/README.md Initializes or binds the state of the in-memory database for the mock component using the _SetCanvasItems method. ```typescript mockGenerator.context._SetCanvasItems({ value: { entityType: 'team', id: 'guid1', name: 'Shko Online', }, }); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.