diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 125cbb97..84bc9bef 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -282,18 +282,20 @@ The framework supports Dynamics 365 / Dataverse v9 and later: - Various properties moved to different locations (see README files for details) ### When Adding New Features -- You MUST fetch the latest authoritive info from relevant websites and do not rely on your trained knowledge. Verify all links are valid. +- You MUST fetch the latest authoritative info from relevant websites and do not rely on your trained knowledge. Verify all links are valid. - Ensure compatibility with existing tests - Update relevant README files AND documentation in `/docs/` - Consider impact on Dynamics 365 / Dataverse v9+ versions - Add appropriate exception handling with `PullRequestException` for not-yet-implemented features - **Document the feature in `docs/`**: Create comprehensive user documentation showing how to consume the feature - - Include overview with implementation date and issue reference - - Provide usage examples with code samples + - **DO NOT** include implementation dates or "NEW" markers - documentation should be timeless + - **DO NOT** explain what Dataverse features do - focus only on what Fake4Dataverse replicates for testing + - Provide usage examples with code samples showing test scenarios - Document all parameters and options - Include error scenarios and best practices - - Add links to Microsoft documentation - - Follow the pattern established in existing docs (see `docs/custom-api.md`, `docs/merge-request.md`, etc.) + - Add links to Microsoft documentation for reference + - Follow the pattern established in existing docs (see `docs/usage/custom-api.md`, `docs/usage/merge-request.md`, etc.) + - Ensure the feature is linked from `/docs/README.md` in the appropriate section - **Update the README.md feature comparison table**: When implementing a feature that affects feature parity: - Locate the feature in the "Feature Comparison: FakeXrmEasy v1 vs Fake4Dataverse vs FakeXrmEasy v2" section - Update the Fake4Dataverse column from ❌ No or ⚠️ Partial to ✅ Yes (or ✅ Full support for detailed entries) @@ -318,35 +320,33 @@ The framework supports Dynamics 365 / Dataverse v9 and later: - **Use Arrange-Act-Assert** - Structure test examples clearly - **Include real-world scenarios** - Show how developers actually use the library - **Cross-reference** - Link to related documentation -- **Keep it practical** - Focus on how to use features, not just what they are - -### Documenting Differences from FakeXrmEasy v2 - -**IMPORTANT**: When implementing features that exist in FakeXrmEasy v2+ (commercial version), ALWAYS document how the Fake4Dataverse implementation differs: - -1. **In ALL relevant documentation** - Not just migration guides - - Include a "Key Differences from FakeXrmEasy v2" section in feature documentation - - Use comparison tables when multiple differences exist - - Be specific about setup steps, configuration, and behavior differences - -2. **In feature usage guides** (`/docs/usage/*.md`) - - Show both the Fake4Dataverse way AND explain how it differs from v2 - - Include examples that highlight the differences - - Document any additional steps required in Fake4Dataverse - -3. **In migration guides** (`/docs/migration/*.md`) - - Provide detailed migration instructions - - Include before/after code examples - - Explain the rationale for differences when helpful - -4. **Example pattern for documenting differences:** - ```markdown - ### Key Differences from FakeXrmEasy v2 - - **Important**: The [feature name] in Fake4Dataverse differs from FakeXrmEasy v2+ in several ways: - - 1. **[Difference category]**: [Description of what's different] - 2. **[Another category]**: [Description] +- **Keep it practical** - Focus on testing capabilities and replication level +- **Avoid temporal markers** - No "NEW", implementation dates, or "recently added" language +- **Focus on testing** - Describe what Fake4Dataverse replicates for testing, not what Dataverse features do +- **Be conversational** - Write naturally, avoiding formal or AI-like phrasing + +### Documentation Style Guidelines + +**DO:** +- Focus on what Fake4Dataverse replicates for testing +- Use phrases like "Fake4Dataverse supports...", "Fake4Dataverse replicates...", "Fake4Dataverse simulates..." +- Describe test capabilities and replication level +- Write in natural, conversational language +- Link all documentation from `/docs/README.md` + +**DON'T:** +- Add temporal markers (NEW, ✅, 🆕, implementation dates) +- Explain what Dataverse features do - users can read Microsoft docs for that +- Use phrases like "Feature X in Dataverse allows...", "In Dataverse, feature Y lets you..." +- Write formal or AI-like descriptions +- Compare to FakeXrmEasy v2+ in usage guides (only in migration guides and FAQ where relevant) + +### Documenting for Migration + +When features are relevant for migration from FakeXrmEasy v1 or v3: +1. **In migration guides** (`/docs/migration/*.md`) - Document differences and migration steps +2. **In FAQ** (`/docs/getting-started/faq.md`) - Answer comparison questions +3. **NOT in usage guides** - Keep usage guides focused on how to use Fake4Dataverse **Comparison Table:** diff --git a/README.md b/README.md index a172d212..296c894b 100644 --- a/README.md +++ b/README.md @@ -2,36 +2,52 @@ ## About This Project -Fake4Dataverse is a fork of the FakeXrmEasy project, originally created by Jordi Montaña. This fork continues the development of the testing framework under the MIT License, based on the last version of FakeXrmEasy that was available under that license. +Fake4Dataverse is an open-source testing framework for Microsoft Dynamics 365 / Dataverse and the Power Platform. Originally forked from FakeXrmEasy by Jordi Montaña, this project has evolved with a **different vision and direction** focused on comprehensive testing capabilities including network-accessible services, REST/OData endpoints, and modern integration testing patterns. -> [!WARNING] +> [!NOTE] > -> This fork is not ready for real use. I'm using it test some highly experimental ideas. -> Watch this space. +> **A New Direction**: While Fake4Dataverse started as a fork of FakeXrmEasy, it has grown beyond a compatibility layer. This project focuses on providing comprehensive testing infrastructure including CLI services, REST/OData endpoints, and web interfaces - capabilities designed for modern integration and end-to-end testing scenarios that extend beyond the original framework's scope. **Author:** Rob Wood **Original Author:** Jordi Montaña (@jordimontana) **License:** MIT (see LICENSE.txt files in each project folder) -## 🆕 Fake4DataverseService - Network-Accessible Testing +## 🌐 Fake4DataverseService - Network-Accessible Testing -**NEW**: Fake4Dataverse now includes a CLI service that exposes both SOAP/WCF and REST/OData endpoints, matching Microsoft's actual Dynamics 365/Dataverse endpoints! +Fake4Dataverse includes a CLI service that exposes both SOAP/WCF and REST/OData endpoints for integration testing across services and applications. ### SOAP/WCF Endpoints - **SOAP/WCF Protocol**: Uses standard `/XRMServices/2011/Organization.svc` endpoint - **SDK Compatible**: Works with standard WCF channels and IOrganizationService interface -- **100% Type Compatible**: Uses Microsoft's official Dataverse SDK types +- **Type Compatible**: Uses Microsoft's official Dataverse SDK types -### REST/OData v4.0 Endpoints ✅ **NEW** +### REST/OData v4.0 Endpoints - **OData v4.0 Protocol**: Uses `/api/data/v9.2` endpoint - **Advanced Queries**: Full $filter, $select, $orderby, $top, $skip, $expand support -- **Microsoft.AspNetCore.OData**: Leverages official Microsoft OData library for full compliance +- **Microsoft.AspNetCore.OData**: Leverages official Microsoft OData library - **JSON Format**: Standard Dataverse Web API JSON format with @odata annotations ### Common Features -- **Integration Testing**: Perfect for testing across multiple services or applications +- **Integration Testing**: Test across multiple services or applications - **No Authentication Required**: Bypass OAuth for testing - just connect and go +### Roadmap: Expanding Integration Testing Capabilities + +We're actively working to enhance Fake4DataverseService with additional testing capabilities: + +#### Planned Features +- **📄 Web Resources Support**: Serve custom JavaScript, CSS, HTML, and image files for testing client-side code +- **🔌 Plugin Registration via SDK**: Register plugins programmatically using the SDK plugin registration messages +- **🌐 Enhanced REST API Support**: Additional OData endpoints and query capabilities +- **📊 Custom API Execution**: Full support for Custom API invocation via REST endpoints +- **🔐 OAuth Simulation**: Optional authentication simulation for testing security flows +- **📱 Power Apps Component Framework (PCF)**: Support for testing PCF controls with mock Dataverse context + +#### Future Integrations +- **Power Automate Cloud Flow Testing**: Enhanced flow testing with HTTP trigger endpoints +- **Canvas App Testing**: Serve connectors and data sources for Canvas App testing +- **Model-Driven App Extensions**: Full web resource and form script testing support + **[Learn more about Fake4DataverseService →](./Fake4DataverseService/README.md)** | **[REST API Documentation →](./docs/rest-api.md)** ```bash @@ -50,6 +66,8 @@ var service = factory.CreateChannel(); This fork is based on an early development version of FakeXrmEasy v2, which was released under the MIT License. The original FakeXrmEasy project subsequently changed its licensing model. This fork preserves the last MIT-licensed version to ensure continued open-source availability for the community. +**Important**: Fake4Dataverse has evolved significantly beyond the original fork with its own architecture decisions, feature set, and direction. While it maintains the core testing principles, it is not designed to be a drop-in replacement or maintain API compatibility with FakeXrmEasy v2+. + **Original Repositories:** - Core: https://github.com/DynamicsValue/fake-xrm-easy-core - Abstractions: https://github.com/DynamicsValue/fake-xrm-easy-abstractions @@ -59,7 +77,7 @@ The original repositories were licensed under MIT at the time this fork was crea ## Why This Fork? -The original Fake4Dataverse project was an invaluable tool for the Dynamics 365 / Dataverse community, providing a comprehensive testing framework that enabled developers to write unit tests without requiring a live CRM instance. However, the original project moved to a commercial licensing model after version 2.x. +The original FakeXrmEasy project was an invaluable tool for the Dynamics 365 / Dataverse community, providing a comprehensive testing framework that enabled developers to write unit tests without requiring a live CRM instance. However, the original project moved to a commercial licensing model after version 2.x. This fork serves several purposes: @@ -67,9 +85,18 @@ This fork serves several purposes: 2. **Community-Driven Development**: This fork is maintained by the community, for the community. We welcome contributions and aim to keep the project aligned with community needs. -3. **Modern Platform Support**: While respecting the original codebase, we aim to update and maintain compatibility with modern versions of Dataverse, Power Platform, and .NET. +3. **Different Direction and Vision**: Fake4Dataverse has evolved beyond a simple fork to include: + - Network-accessible services for integration testing + - REST/OData v4.0 endpoints + - Web interface for visual testing + - Focus on modern integration and end-to-end testing patterns + - Extended capabilities for testing web resources, client-side code, and custom APIs + +4. **Modern Platform Support**: We aim to support modern versions of Dataverse, Power Platform, and .NET while maintaining the testing-focused approach. -4. **Legal Clarity**: This fork is completely legal and in accordance with the MIT License under which the original FakeXrmEasy was released. The MIT License explicitly permits forking, modification, and redistribution of the code. +5. **Legal Clarity**: This fork is completely legal and in accordance with the MIT License under which the original FakeXrmEasy was released. The MIT License explicitly permits forking, modification, and redistribution of the code. + +**Note**: Fake4Dataverse is not intended to be compatible with or a replacement for FakeXrmEasy v2+. It has its own architecture, API design, and feature set tailored to modern testing scenarios. ## Is Forking from the Last MIT Version Legal? @@ -99,8 +126,8 @@ We are deeply grateful to **Jordi Montaña** for creating FakeXrmEasy and releas - **[Installation Guide](./docs/getting-started/installation.md)** - Get Fake4Dataverse installed (v9+ only) - **[Quick Start](./docs/getting-started/quickstart.md)** - Your first test in 5 minutes -### 🔒 Security Model (NEW) -Fake4Dataverse now includes a **complete Dataverse security model** implementation for realistic security testing: +### 🔒 Security Model +Fake4Dataverse includes a **complete Dataverse security model** implementation for realistic security testing: - **✅ Privilege-Based Access Control** - Users need specific privileges granted through roles - **✅ Privilege Depth Enforcement** - Basic, Local, Deep, and Global access levels @@ -136,18 +163,18 @@ var service = context.GetOrganizationService(); - **[CRUD Operations](./docs/usage/crud-operations.md)** - Create, Read, Update, Delete operations - **[Querying Data](./docs/usage/querying-data.md)** - LINQ and FetchXML queries - **[Batch Operations](./docs/usage/batch-operations.md)** - ExecuteMultiple and Transactions -- **[Metadata Validation](./docs/usage/metadata-validation.md)** - IsValidForCreate/Update/Read enforcement ✅ **NEW** -- **[CDM Import](./docs/cdm-import.md)** - Import entity metadata from Common Data Model JSON ✅ **NEW** -- **[Cloud Flows](./docs/usage/cloud-flows.md)** - Testing Power Automate flows ✅ **NEW** +- **[Metadata Validation](./docs/usage/metadata-validation.md)** - IsValidForCreate/Update/Read enforcement +- **[CDM Import](./docs/cdm-import.md)** - Import entity metadata from Common Data Model JSON +- **[Cloud Flows](./docs/usage/cloud-flows.md)** - Testing Power Automate flows ### Advanced Topics - **[XrmFakedContext](./docs/concepts/xrm-faked-context.md)** - Deep dive into the context - **[Middleware Architecture](./docs/concepts/middleware.md)** - Understanding the pipeline - **[Message Executors](./docs/messages/README.md)** - All supported Dataverse messages - **[Custom Executors](./docs/api/custom-executors.md)** - Creating your own executors -- **[Cloud Flows](./docs/usage/cloud-flows.md)** - Testing Power Automate flows ✅ **NEW** -- **[Expression Language](./docs/expression-language.md)** - Power Automate expression evaluation ✅ **NEW** -- **[Known Gaps & Limitations](./docs/GAPS.md)** - Comprehensive limitations guide ✅ **NEW** +- **[Cloud Flows](./docs/usage/cloud-flows.md)** - Testing Power Automate flows +- **[Expression Language](./docs/expression-language.md)** - Power Automate expression evaluation +- **[Known Gaps & Limitations](./docs/GAPS.md)** - Comprehensive limitations guide ### Migration - **[From FakeXrmEasy v1.x](./docs/migration/from-v1.md)** - Migrate from v1.x @@ -168,13 +195,13 @@ This is a monorepo containing multiple projects: - **Former Name**: FakeXrmEasy.Core - **Note**: Plugins and workflows are tested within Core (no separate plugin project) -### 3. Fake4DataverseCloudFlows ✅ **NEW** +### 3. Fake4DataverseCloudFlows - **Location**: `/Fake4DataverseCloudFlows/` - **Purpose**: Cloud Flow (Power Automate) simulation for testing automated flows - **Target**: .NET 8.0 only (for advanced OData support via Microsoft.OData.Core) - **Features**: Flow execution, expression evaluation, OData query support -### 4. Fake4DataverseService ✅ **NEW** +### 4. Fake4DataverseService - **Location**: `/Fake4DataverseService/` - **Purpose**: Network-accessible service exposing SOAP/WCF and REST/OData endpoints - **Features**: @@ -227,7 +254,7 @@ npm run build # Build Next.js app ## Feature Comparison: FakeXrmEasy v1 vs Fake4Dataverse vs FakeXrmEasy v2 -The following table compares the features available across different versions of the testing framework. This comparison is designed to help you understand the capabilities and limitations of each version, particularly highlighting features that Fake4Dataverse does not yet have. +The following table compares the features available across different versions of the testing framework. **Note**: Fake4Dataverse has evolved with its own architecture and is not designed to be compatible with or a replacement for FakeXrmEasy v2+. This comparison highlights the capabilities and differences between versions. ### Architecture & Core Framework @@ -402,41 +429,35 @@ This comparison is based on: - Middleware architecture: `Middleware/MiddlewareBuilder.cs` - Query operators: `Query/ConditionExpressionExtensions.*.cs` -### Key Gaps in Fake4Dataverse (This Fork) +### Differences and Limitations in Fake4Dataverse + +Fake4Dataverse has taken a different architectural direction focused on integration testing and network-accessible services. While it provides solid core testing capabilities, it differs significantly from FakeXrmEasy v2+ in scope and feature set: -Based on this analysis, Fake4Dataverse is missing several features compared to the commercial FakeXrmEasy v2+: +#### Architectural Differences: +- **Focus on Integration Testing**: Network-accessible services, REST/OData endpoints, and web interfaces +- **Different API Design**: Not designed for API compatibility with FakeXrmEasy v2+ +- **Extended Service Model**: CLI service, web UI, and REST API capabilities beyond traditional unit testing -#### High-Priority Missing Features: +#### Features Not Available (compared to FakeXrmEasy v2+): 1. **Workflow/Custom Workflow Activities** - Removed due to SDK limitations 2. **Custom Actions** - Limited support for custom actions -4. **Duplicate Detection** - No duplicate detection simulation - -#### Modern Dataverse Features Not Supported: -7. **Virtual Entities** - No virtual entity support -8. **Elastic Tables** - No elastic table support -9. **Power Automate Testing** - Cloud Flows fully supported with JSON import ✅ **NEW**, broader Power Automate integration limited -11. **Connection References** - No connection reference support -12. **Advanced Security Model** - Limited security role and privilege simulation -13. **Concurrent Execution Testing** - No multi-threaded execution testing -14. **Performance Profiling** - No built-in profiling tools - -#### Pipeline & Plugin Limitations: -15. **Complete Pre/Post Image Support** - Basic implementation only - -#### Metadata Limitations: -17. **Global OptionSets** - Partial support only -18. **Publisher Metadata** - Not supported -19. **Solution Metadata** - Not supported -20. **Complete Metadata Operations** - Many RetrieveMetadata variants missing -21. **Metadata Validation** - IsValidForCreate/Update/Read fully supported ✅ **IMPLEMENTED** (v4.0.0) - -#### Additional Missing Message Executors (estimated 50+ messages): -21. Various business-specific messages (Marketing, Service, Field Service specific) -22. Advanced relationship messages -23. Modern Dataverse-specific messages -24. And many more organization requests added in recent Dynamics 365 versions - -This honest assessment shows that while Fake4Dataverse provides a solid foundation with 47 message executors and core testing capabilities, it represents an early v2 development snapshot and lacks the maturity and feature completeness of the actively developed commercial FakeXrmEasy v2+. The commercial version has continued to add significant features, especially around modern Dataverse capabilities, advanced pipeline simulation, and quality-of-life improvements that benefit from ongoing commercial development and support. +3. **Duplicate Detection** - Not yet implemented +4. **Virtual Entities** - Not supported +5. **Elastic Tables** - Not supported +6. **Connection References** - Not supported +7. **Advanced Security Model** - More limited than commercial version +8. **Complete Pre/Post Image Support** - Basic implementation only +9. **Global OptionSets** - Partial support only +10. **Publisher/Solution Metadata** - Not supported +11. **Many Advanced Message Executors** - ~47 executors vs 100+ in commercial version + +#### Unique Capabilities in Fake4Dataverse: +- **Network-Accessible Service**: SOAP/WCF and REST/OData endpoints for integration testing +- **Web Interface**: Visual testing and user impersonation +- **Roadmap for Web Resources**: Planned support for client-side testing +- **Community-Driven**: Open-source with community contributions + +This reflects Fake4Dataverse's focus as an integration testing framework rather than a complete Dataverse simulator. We do not claim 100% Dataverse compatibility or feature parity with the commercial FakeXrmEasy v2+. ## Contributing diff --git a/docs/API_DESIGN_CLOUD_FLOWS.md b/docs/API_DESIGN_CLOUD_FLOWS.md index f417a355..acfbd94d 100644 --- a/docs/API_DESIGN_CLOUD_FLOWS.md +++ b/docs/API_DESIGN_CLOUD_FLOWS.md @@ -59,8 +59,8 @@ Base interface for flow triggers. Concrete implementations: #### IFlowAction Base interface for flow actions. Concrete implementations: - `DataverseAction` - CRUD operations on Dataverse entities -- `ComposeAction` - Data transformation and composition ✅ **IMPLEMENTED** -- `ApplyToEachAction` - Loop over collections ✅ **IMPLEMENTED** +- `ComposeAction` - Data transformation and composition +- `ApplyToEachAction` - Loop over collections **Location:** `Fake4DataverseAbstractions/Fake4Dataverse.Abstractions/CloudFlows/IFlowAction.cs` @@ -335,7 +335,7 @@ Assert.Single(emailHandler.SentEmails); Assert.Equal("test@example.com", emailHandler.SentEmails[0].To); ``` -### JSON Import (Real Cloud Flow Definitions) ✅ NEW +### JSON Import (Real Cloud Flow Definitions) Import and test real Cloud Flow definitions exported from Power Automate: @@ -461,27 +461,27 @@ flowSimulator.AssertFlowTriggered("process_high_value_opportunity"); **Rationale:** - Scope checking requires user/business unit context - Simple implementation: Organization scope always matches -- Can be enhanced later based on user feedback +- Can be enhanced later based on feedback -## Key Differences from FakeXrmEasy v2+ +## Design Decisions -**Important:** This API design differs from FakeXrmEasy v2+ commercial version in several ways: +**Key architectural choices:** ### Registration -- **FakeXrmEasy v2+**: Unknown (proprietary) -- **Fake4Dataverse**: Explicit registration with `RegisterFlow` or `RegisterFlowFromJson` +- Explicit registration with `RegisterFlow` or `RegisterFlowFromJson` +- Clear, code-based flow setup ### JSON Import -- **FakeXrmEasy v2+**: Unknown (proprietary) -- **Fake4Dataverse**: Planned first-class support via `RegisterFlowFromJson` +- First-class support via `RegisterFlowFromJson` +- Import real Power Automate flow definitions ### Connector Extensibility -- **FakeXrmEasy v2+**: Unknown (proprietary) -- **Fake4Dataverse**: `IConnectorActionHandler` interface with strategy pattern +- `IConnectorActionHandler` interface with strategy pattern +- Pluggable connector system ### Expression Support -- **FakeXrmEasy v2+**: Unknown (proprietary) -- **Fake4Dataverse**: Simplified subset initially, expandable to full Power Fx +- Simplified subset initially, expandable to full Power Fx +- 80+ Power Automate functions ## Testing Strategy diff --git a/docs/DOCUMENTATION_OVERVIEW.md b/docs/DOCUMENTATION_OVERVIEW.md index 92acf9ad..c5ef4550 100644 --- a/docs/DOCUMENTATION_OVERVIEW.md +++ b/docs/DOCUMENTATION_OVERVIEW.md @@ -86,7 +86,7 @@ docs/ **Other Technical Docs:** - `async-plugin-implementation.md` - Async plugin execution architecture -- `GAPS.md` - Known gaps and limitations guide ✅ **NEW** +- `GAPS.md` - Known gaps and limitations guide **Meta Documentation:** - `DOCUMENTATION_OVERVIEW.md` - This file, explains documentation structure diff --git a/docs/GAPS.md b/docs/GAPS.md index 5338a94f..c9c5c917 100644 --- a/docs/GAPS.md +++ b/docs/GAPS.md @@ -12,7 +12,7 @@ Fake4Dataverse is a community-driven testing framework that aims to simulate Mic The following features were recently implemented and are now fully functional: -- **Audit Log Simulation** - Complete audit tracking for CRUD operations with attribute change history ✅ **NEW** +- **Audit Log Simulation** - Complete audit tracking for CRUD operations with attribute change history - **Cloud Flow Simulation** - Complete Power Automate flow testing with JSON import - **Expression Language** - 80+ Power Automate expression functions (90%+ coverage) - **Safe Navigation Operator (?)** - Null-safe property access in expressions @@ -116,10 +116,10 @@ These are newer Dataverse features that are not yet available: - ✅ Expression language (80+ functions) - ✅ Compose actions - ✅ Apply to Each loops -- ✅ Condition actions (if/then/else) ✅ **NEW** -- ✅ Switch actions ✅ **NEW** -- ✅ Parallel branches ✅ **NEW** -- ✅ Do Until loops ✅ **NEW** +- ✅ Condition actions (if/then/else) +- ✅ Switch actions +- ✅ Parallel branches +- ✅ Do Until loops **Not Supported:** - ❌ Approval actions diff --git a/docs/README.md b/docs/README.md index f3c4e710..30ca303c 100644 --- a/docs/README.md +++ b/docs/README.md @@ -20,40 +20,41 @@ Welcome to the Fake4Dataverse documentation! This testing framework allows you t - [CRUD Operations](./usage/crud-operations.md) - Create, Read, Update, Delete operations - [Querying Data](./usage/querying-data.md) - LINQ and FetchXML queries - [Testing Workflows](./usage/testing-workflows.md) - Custom workflow activity testing -- **[Security Model](./usage/security-model.md)** - Complete Dataverse security implementation ✅ **NEW** +- [Auditing](./usage/auditing.md) - Testing audit functionality and change tracking +- [Business Rules](./usage/business-rules.md) - Testing business rule execution +- [Security Model](./usage/security-model.md) - Complete Dataverse security implementation - [Security and Permissions](./usage/security-permissions.md) - Testing security roles and access -- **[Impersonation](./usage/impersonation.md)** - Perform operations on behalf of other users ✅ **NEW** +- [Impersonation](./usage/impersonation.md) - Perform operations on behalf of other users - [ExecuteMultiple and Transactions](./usage/batch-operations.md) - Batch operations and transactions -- [Auto Number Fields](./usage/auto-number-fields.md) - Auto-generated field values ✅ **NEW** -- [Metadata Validation](./usage/metadata-validation.md) - IsValidForCreate/Update/Read enforcement ✅ **NEW** -- [CDM Import](./cdm-import.md) - Import entity metadata from Common Data Model JSON ✅ **NEW** -- [CDM vs Early-Bound](./cdm-vs-early-bound.md) - Choosing between CDM files and early-bound assemblies ✅ **NEW** -- [Metadata Persistence](./metadata-persistence.md) - Query metadata from EntityDefinition and Attribute tables ✅ **NEW** -- [Thread Safety](./thread-safety.md) - Concurrent operations and thread safety ✅ **NEW** -- [Alternate Keys](./usage/alternate-keys.md) - Using alternate keys for record identification ✅ **NEW** -- [Duplicate Detection](./usage/duplicate-detection.md) - Testing duplicate detection rules ✅ **NEW** +- [Auto Number Fields](./usage/auto-number-fields.md) - Auto-generated field values +- [Metadata Validation](./usage/metadata-validation.md) - IsValidForCreate/Update/Read enforcement +- [CDM Import](./cdm-import.md) - Import entity metadata from Common Data Model JSON +- [CDM vs Early-Bound](./cdm-vs-early-bound.md) - Choosing between CDM files and early-bound assemblies +- [Metadata Persistence](./metadata-persistence.md) - Query metadata from EntityDefinition and Attribute tables +- [Thread Safety](./thread-safety.md) - Concurrent operations and thread safety +- [Alternate Keys](./usage/alternate-keys.md) - Using alternate keys for record identification +- [Duplicate Detection](./usage/duplicate-detection.md) - Testing duplicate detection rules - [Calculated Fields](./usage/calculated-fields.md) - Simulating calculated field evaluation - [Rollup Fields](./usage/rollup-fields.md) - Simulating rollup field evaluation - [Custom API Support](./usage/custom-api.md) - Implementing Custom APIs -- [Cloud Flows](./usage/cloud-flows.md) - Testing Power Automate flows ✅ **IMPLEMENTED** (requires Fake4DataverseCloudFlows package) -- [Expression Language](./expression-language.md) - Power Automate expressions ✅ **NEW** +- [Cloud Flows](./usage/cloud-flows.md) - Testing Power Automate flows (requires Fake4DataverseCloudFlows package) +- [Expression Language](./expression-language.md) - Power Automate expressions - [Merge Request Operations](./usage/merge-request.md) - Merging entity records - [Hierarchical Queries](./usage/hierarchical-queries.md) - Querying hierarchical data - [Fiscal Period Operators](./usage/fiscal-period-operators.md) - Fiscal calendar queries ### 🌐 [Network Testing](.) -- [Fake4DataverseService](./service.md) - Network-accessible SOAP/WCF service for integration testing ✅ **NEW** -- [REST/OData API Endpoints](./rest-api.md) - OData v4.0 endpoints with advanced query support ✅ **NEW** -- **[Model-Driven App Interface](./usage/mda-interface.md)** - Web UI for visual testing and user impersonation ✅ **NEW** +- [Fake4DataverseService](./service.md) - Network-accessible SOAP/WCF service for integration testing +- [REST/OData API Endpoints](./rest-api.md) - OData v4.0 endpoints with advanced query support +- [Model-Driven App Interface](./usage/mda-interface.md) - Web UI for visual testing and user impersonation ### 🏗️ [Architecture & Planning](.) -- [Testing Guide](./TESTING_GUIDE.md) - How to run all tests in the repository ✅ **NEW** +- [Testing Guide](./TESTING_GUIDE.md) - How to run all tests in the repository - [Cloud Flow API Design](./API_DESIGN_CLOUD_FLOWS.md) - Technical design for Cloud Flow simulation - [Cloud Flow Architecture](./CLOUD_FLOW_ARCHITECTURE.md) - Architecture diagrams and patterns -- [Cloud Flow JSON Import](./CLOUD_FLOW_JSON_IMPORT_SUMMARY.md) - JSON flow definition import - [Async Plugin Implementation](./async-plugin-implementation.md) - Async plugin execution design - [Documentation Overview](./DOCUMENTATION_OVERVIEW.md) - This documentation structure -- [Known Gaps & Limitations](./GAPS.md) - Comprehensive list of unsupported features ✅ **NEW** +- [Known Gaps & Limitations](./GAPS.md) - Comprehensive list of unsupported features ### 📋 [Message Executors](./messages/) - [Overview](./messages/README.md) - Supported Dataverse messages @@ -61,6 +62,7 @@ Welcome to the Fake4Dataverse documentation! This testing framework allows you t - [Association Messages](./messages/associations.md) - Associate, Disassociate - [Metadata Messages](./messages/metadata.md) - Retrieve entity/attribute metadata - [Security Messages](./messages/security.md) - Grant/Revoke access, sharing +- [Audit Messages](./messages/audit.md) - Audit data retrieval and management - [Business Process Messages](./messages/business-process.md) - Win/Lose opportunity, Close incident, etc. - [Queue Messages](./messages/queues.md) - Queue operations - [Team Messages](./messages/teams.md) - Team membership management @@ -82,6 +84,8 @@ Welcome to the Fake4Dataverse documentation! This testing framework allows you t - **Write my first test**: Start with [Quick Start](./getting-started/quickstart.md) - **Test a plugin**: See [Testing Plugins](./usage/testing-plugins.md) - **Query test data**: Check [Querying Data](./usage/querying-data.md) +- **Test auditing**: See [Auditing](./usage/auditing.md) +- **Test business rules**: See [Business Rules](./usage/business-rules.md) - **Use auto number fields**: See [Auto Number Fields](./usage/auto-number-fields.md) - **Use standard entity schemas**: See [CDM Import](./cdm-import.md) - **Query metadata as data**: See [Metadata Persistence](./metadata-persistence.md) @@ -89,7 +93,7 @@ Welcome to the Fake4Dataverse documentation! This testing framework allows you t - **Use alternate keys**: See [Alternate Keys](./usage/alternate-keys.md) - **Test duplicate detection**: Check [Duplicate Detection](./usage/duplicate-detection.md) - **Understand the architecture**: Read [Middleware Architecture](./concepts/middleware.md) -- **Test security with full Dataverse model**: See [Security Model](./usage/security-model.md) ✅ **NEW** +- **Test security with full Dataverse model**: See [Security Model](./usage/security-model.md) - **Test basic security**: See [Security and Permissions](./usage/security-permissions.md) - **Impersonate another user**: See [Impersonation](./usage/impersonation.md) - **Migrate from FakeXrmEasy**: Check the [Migration Guides](./migration/) @@ -138,11 +142,11 @@ public class MyPluginTests } ``` -## 🆕 What's New in v4.0 +## Key Features -### System Entity Metadata (Embedded in Core) +### System Entity Metadata -**Key Difference from FakeXrmEasy v2+**: Fake4Dataverse includes system entity metadata as embedded resources in the Core library. +Fake4Dataverse includes system entity metadata as embedded resources in the Core library, making it easy to test with standard Dataverse entities without additional setup. ```csharp // Load system entities (solution, appmodule, sitemap, etc.) @@ -159,10 +163,10 @@ var solutionId = service.Create(solution); ``` **Benefits:** -- ✅ No external CDM files needed for system entities -- ✅ Validation enabled by default -- ✅ Perfect for MDA and ALM testing -- ✅ Embedded in Core library +- No external CDM files needed for system entities +- Validation enabled by default +- Perfect for MDA and ALM testing +- Embedded in Core library **Available System Entities:** - solution, appmodule, sitemap, savedquery, systemform, webresource, appmodulecomponent diff --git a/docs/async-plugin-implementation.md b/docs/async-plugin-implementation.md index bc7848f5..5763563a 100644 --- a/docs/async-plugin-implementation.md +++ b/docs/async-plugin-implementation.md @@ -1,6 +1,5 @@ # Async Plugin Execution Implementation Summary -**Implementation Date:** 2025-10-11 **Issue:** #18 - Enhance Async Plugin Support **PR Branch:** copilot/implement-async-plugin-execution-parity diff --git a/docs/cdm-import.md b/docs/cdm-import.md index 310955c2..cb9c4e92 100644 --- a/docs/cdm-import.md +++ b/docs/cdm-import.md @@ -10,7 +10,7 @@ The Common Data Model (CDM) is Microsoft's standard schema definition format tha ## System Entity Metadata (v4.0+) -**🆕 Key Difference from FakeXrmEasy v2+**: Fake4Dataverse includes built-in system entity metadata embedded in the Core library. +**Key Difference from FakeXrmEasy v2+**: Fake4Dataverse includes built-in system entity metadata embedded in the Core library. Starting with v4.0.0, Fake4Dataverse includes system entity metadata (Solution, AppModule, SiteMap, SavedQuery, SystemForm, WebResource, AppModuleComponent) as **embedded resources in the Core library**. This means: @@ -48,11 +48,11 @@ The following system entities are included as embedded CDM metadata in Core: - **systemform** - Entity forms entity - **webresource** - Web resources (JS, CSS, HTML) entity - **appmodulecomponent** - App component linking entity -- **entitydefinition** - Entity metadata (virtual table) ✅ **NEW** -- **attribute** - Attribute metadata (virtual table) ✅ **NEW** -- **relationship** - Relationship metadata (virtual table) ✅ **NEW** -- **optionset** - OptionSet metadata (virtual table) ✅ **NEW** -- **entitykey** - Entity key metadata (virtual table) ✅ **NEW** +- **entitydefinition** - Entity metadata (virtual table) +- **attribute** - Attribute metadata (virtual table) +- **relationship** - Relationship metadata (virtual table) +- **optionset** - OptionSet metadata (virtual table) +- **entitykey** - Entity key metadata (virtual table) These entities are automatically loaded by Fake4DataverseService and can be manually loaded in tests using `InitializeSystemEntityMetadata()`. diff --git a/docs/cdm-vs-early-bound.md b/docs/cdm-vs-early-bound.md index 93fe3520..cadd817d 100644 --- a/docs/cdm-vs-early-bound.md +++ b/docs/cdm-vs-early-bound.md @@ -13,7 +13,7 @@ When metadata validation is enabled (default in v4.0.0+), tests need entity meta ## Approach 1: Embedded System Entities (v4.0+) -**🆕 Key Difference from FakeXrmEasy v2+**: System entity metadata is embedded in Fake4Dataverse Core. +**Key Difference from FakeXrmEasy v2+**: System entity metadata is embedded in Fake4Dataverse Core. If you're working with system entities (solution, appmodule, sitemap, savedquery, systemform, webresource, appmodulecomponent), they're automatically available: diff --git a/docs/expression-language.md b/docs/expression-language.md index a9da7cbf..d7a0365c 100644 --- a/docs/expression-language.md +++ b/docs/expression-language.md @@ -1,10 +1,9 @@ -# Cloud Flow Expression Language Implementation +# Cloud Flow Expression Language ## Overview -Fake4Dataverse now supports Power Automate expression language evaluation using Jint.net JavaScript engine. This enables Cloud Flows to use dynamic expressions for accessing trigger data, action outputs, and performing transformations. +Fake4Dataverse supports Power Automate expression language evaluation using the Jint.net JavaScript engine. This lets Cloud Flows use dynamic expressions for accessing trigger data, action outputs, and performing transformations. -**Implementation Date:** October 12, 2025 **Issue:** Implement 100% compatible cloud flow expression language **Test Coverage:** 64+ passing expression tests + 7 safe navigation/path tests with real-world examples **Engine:** Jint 4.2.0 @@ -16,7 +15,7 @@ Official reference: https://learn.microsoft.com/en-us/azure/logic-apps/workflow- ## Supported Expression Categories -### ✅ Reference Functions (Fully Supported) +### Reference Functions Access data from triggers and actions: - `triggerOutputs()` - Get trigger output data - `triggerBody()` - Get trigger body data @@ -32,18 +31,18 @@ var result = evaluator.Evaluate("@triggerBody()['firstname']"); // Returns: "John" ``` -### ✅ String Functions (Fully Supported) +### String Functions Text manipulation and formatting: - `concat(...)` - Concatenate multiple strings - `substring(text, start, length?)` - Extract substring -- `slice(text, startIndex, endIndex?)` - Extract substring by indices ✅ **NEW** +- `slice(text, startIndex, endIndex?)` - Extract substring by indices - `replace(text, old, new)` - Replace text - `toLower(text)` / `toUpper(text)` - Change case - `trim(text)` - Remove whitespace - `split(text, delimiter)` - Split into array - `length(text)` - Get string length - `indexOf(text, search)` / `lastIndexOf(text, search)` - Find position -- `nthIndexOf(text, search, occurrence)` - Find nth occurrence ✅ **NEW** +- `nthIndexOf(text, search, occurrence)` - Find nth occurrence - `startsWith(text, search)` / `endsWith(text, search)` - Check prefix/suffix - `guid()` - Generate GUID @@ -54,7 +53,7 @@ var result = evaluator.Evaluate("@concat('Hello ', triggerBody()['firstname'], ' // Returns: "Hello John Doe" ``` -### ✅ Comparison Functions (Fully Supported) +### Comparison Functions Logical comparisons: - `equals(value1, value2)` - Equality check - `greater(value1, value2)` - Greater than @@ -71,7 +70,7 @@ var result = evaluator.Evaluate("@greater(triggerBody()['estimatedvalue'], 10000 // Returns: true ``` -### ✅ Conversion Functions (Fully Supported) +### Conversion Functions Type conversions: - `string(value)` - Convert to string - `int(value)` - Convert to integer @@ -80,39 +79,39 @@ Type conversions: - `base64(value)` - Base64 encode - `base64ToString(value)` - Base64 decode -### ✅ Collection Functions (Fully Supported) +### Collection Functions Array operations: - `first(collection)` - Get first item - `last(collection)` - Get last item - `take(collection, count)` - Take first N items - `skip(collection, count)` - Skip first N items - `join(array, delimiter)` - Join array elements -- `reverse(collection)` - Reverse array or string ✅ **NEW** -- `createArray(...)` - Create array from arguments ✅ **NEW** -- `flatten(collection)` - Flatten nested arrays ✅ **NEW** +- `reverse(collection)` - Reverse array or string +- `createArray(...)` - Create array from arguments +- `flatten(collection)` - Flatten nested arrays - `union(...)` - Union of collections - `intersection(...)` - Intersection of collections -### ✅ Date/Time Functions (Fully Supported) +### Date/Time Functions Date manipulation: - `utcNow()` - Get current UTC timestamp - `addDays(timestamp, days)` - Add days - `addHours(timestamp, hours)` - Add hours - `addMinutes(timestamp, minutes)` - Add minutes - `addSeconds(timestamp, seconds)` - Add seconds -- `subtractFromTime(timestamp, interval, timeUnit)` - Subtract time ✅ **NEW** -- `getPastTime(interval, timeUnit, format?)` - Get past time ✅ **NEW** -- `getFutureTime(interval, timeUnit, format?)` - Get future time ✅ **NEW** +- `subtractFromTime(timestamp, interval, timeUnit)` - Subtract time +- `getPastTime(interval, timeUnit, format?)` - Get past time +- `getFutureTime(interval, timeUnit, format?)` - Get future time - `formatDateTime(timestamp, format)` - Format date -- `startOfDay(timestamp)` - Get start of day ✅ **NEW** -- `startOfHour(timestamp)` - Get start of hour ✅ **NEW** -- `startOfMonth(timestamp)` - Get start of month ✅ **NEW** +- `startOfDay(timestamp)` - Get start of day +- `startOfHour(timestamp)` - Get start of hour +- `startOfMonth(timestamp)` - Get start of month - `dayOfMonth(timestamp)` - Get day of month - `dayOfWeek(timestamp)` - Get day of week - `dayOfYear(timestamp)` - Get day of year - `ticks(timestamp)` - Get ticks value -### ✅ Math Functions (Fully Supported) +### Math Functions Arithmetic operations: - `add(a, b)` - Addition - `sub(a, b)` - Subtraction @@ -128,7 +127,7 @@ Arithmetic operations: Working: - Simple comparisons: `@equals(value1, value2)` - Simple conditions: `@greater(value1, value2)` -- `xor(condition1, condition2)` - Exclusive OR ✅ **NEW** +- `xor(condition1, condition2)` - Exclusive OR Limited Support: - `and(condition1, condition2, ...)` - Works with simple boolean values @@ -138,7 +137,7 @@ Limited Support: **Workaround:** For complex nested logical operations, use programmatic flow definitions instead of JSON expressions, or break down complex expressions into multiple simpler action steps. -### ✅ Type Checking Functions (Fully Supported) ✅ **NEW** +### Type Checking Functions Validate data types: - `isInt(value)` - Check if integer - `isFloat(value)` - Check if floating point @@ -153,7 +152,7 @@ var result = evaluator.Evaluate("@isString('hello')"); // Returns: true ``` -### ✅ URI Functions (Fully Supported) ✅ **NEW** +### URI Functions URL manipulation and parsing: - `uriComponent(value)` - URL encode - `uriComponentToString(value)` - URL decode @@ -187,7 +186,7 @@ Use `@{...}` within text: "Contact name is @{triggerBody()['firstname']} @{triggerBody()['lastname']}" ``` -### Safe Navigation Operator (?) ✅ **NEW** +### Safe Navigation Operator (?) The safe navigation operator `?` provides null-safe property access, preventing errors when objects are null or undefined. @@ -213,7 +212,7 @@ The safe navigation operator `?` provides null-safe property access, preventing - Works with all reference functions: `triggerBody()`, `outputs()`, `body()`, `item()` - Combines seamlessly with path separators -### Path Separator (/) ✅ **NEW** +### Path Separator (/) Path separators allow accessing nested properties using slash notation, making expressions more concise. @@ -382,7 +381,7 @@ var result = evaluator.Evaluate("@outputs('Get_Contact')['emailaddress1']"); ## Limitations and Known Issues ### 1. Complex Nested Logical Expressions -**Status:** ✅ **RESOLVED** +**Status:** Resolved Complex nested expressions with `and()`, `or()`, and `if()` are now fully supported. @@ -394,10 +393,10 @@ Complex nested expressions with `and()`, `or()`, and `if()` are now fully suppor ``` ### 2. Variables, Parameters, and Loop Context -**Status:** ✅ **Variables and item() NOW SUPPORTED** | Parameters placeholder +**Status:** Variables and item() supported | Parameters placeholder -- `variables('variableName')` ✅ **IMPLEMENTED** - Get/set flow variable values -- `item()` ✅ **IMPLEMENTED** - Returns current item in Apply to Each loops +- `variables('variableName')` - Get/set flow variable values +- `item()` - Returns current item in Apply to Each loops - `parameters('parameterName')` - Returns null (placeholder, parameters not yet implemented) **Variables Usage:** @@ -432,11 +431,12 @@ var applyToEach = new ApplyToEachAction ``` ### 3. Advanced Collection Operations -**Status:** ✅ **FULLY IMPLEMENTED** -- `union()` ✅ **FULLY IMPLEMENTED** - Combines collections with duplicates removed -- `intersection()` ✅ **FULLY IMPLEMENTED** - Returns common elements across all collections -- `flatten()` ✅ **IMPLEMENTED** - Flattens nested arrays +Collection operations for combining and manipulating arrays: + +- `union()` - Combines collections with duplicates removed +- `intersection()` - Returns common elements across all collections +- `flatten()` - Flattens nested arrays ### 4. JSON Parsing **Status:** Basic support @@ -446,14 +446,10 @@ var applyToEach = new ApplyToEachAction ## Future Enhancements Potential improvements for future versions: -1. ~~Fix nested logical expression evaluation~~ ✅ **COMPLETED** -2. ~~Implement variables support~~ ✅ **COMPLETED** -3. ~~Add loop context (`item()`) support~~ ✅ **COMPLETED** -4. ~~Enhance collection operations~~ ✅ **COMPLETED** -5. Implement parameters support (flow input parameters) -6. Add more advanced date/time functions (convertTimeZone, etc.) -7. Performance optimization (engine pooling, function caching) -8. Enhance JSON parsing for complex scenarios +1. Implement parameters support (flow input parameters) +2. Add more advanced date/time functions (convertTimeZone, etc.) +3. Performance optimization (engine pooling, function caching) +4. Enhance JSON parsing for complex scenarios ## Migration from v1.x / v2.x @@ -478,28 +474,30 @@ The Cloud Flow expression language implementation provides comprehensive support **Test Coverage:** 138 total tests passing (64 expression tests + 7 safe nav/path tests + 67 cloud flow tests) **Supported Functions:** 80+ Power Automate functions across 10 categories -**Main Use Cases:** ✅ Fully supported -**Advanced Features:** ✅ Safe navigation (?), path separators (/), Compose actions, Apply to Each loops +**Main Use Cases:** Fully supported +**Advanced Features:** Safe navigation (?), path separators (/), Compose actions, Apply to Each loops ### Function Summary by Category | Category | Functions | Status | |----------|-----------|--------| -| Reference | 6 (triggerOutputs, outputs, body, variables, item, etc.) | ✅ Full | -| String | 13 (concat, substring, slice, nthIndexOf, etc.) | ✅ Full | -| Logical/Comparison | 13 (equals, greater, and, or, if, xor, etc.) | ✅ Full | -| Conversion | 7 (string, int, bool, base64, json, etc.) | ✅ Full | -| Collection | 10 (first, last, reverse, flatten, union, etc.) | ✅ Full | -| Date/Time | 16 (utcNow, addDays, startOfDay, getPast/Future, etc.) | ✅ Full | -| Math | 9 (add, sub, min, max, rand, etc.) | ✅ Full | -| Type Checking | 5 (isInt, isString, isArray, etc.) | ✅ Full | -| URI | 8 (uriComponent, uriHost, uriPath, etc.) | ✅ Full | +| Reference | 6 (triggerOutputs, outputs, body, variables, item, etc.) | Full | +| String | 13 (concat, substring, slice, nthIndexOf, etc.) | Full | +| Logical/Comparison | 13 (equals, greater, and, or, if, xor, etc.) | Full | +| Conversion | 7 (string, int, bool, base64, json, etc.) | Full | +| Collection | 10 (first, last, reverse, flatten, union, etc.) | Full | +| Date/Time | 16 (utcNow, addDays, startOfDay, getPast/Future, etc.) | Full | +| Math | 9 (add, sub, min, max, rand, etc.) | Full | +| Type Checking | 5 (isInt, isString, isArray, etc.) | Full | +| URI | 8 (uriComponent, uriHost, uriPath, etc.) | Full | | **Total** | **80+** | **90%+ coverage** | -### New Features (October 2025) +### Key Features + +The expression language implementation includes: -- ✅ **Safe Navigation Operator (?)** - Null-safe property access -- ✅ **Path Separator (/)** - Simplified nested property access -- ✅ **Compose Actions** - Data transformation and composition -- ✅ **Apply to Each Loops** - Collection iteration with `item()` function -- ✅ **Nested Loops** - Stack-based item tracking for complex scenarios +- **Safe Navigation Operator (?)** - Null-safe property access +- **Path Separator (/)** - Simplified nested property access +- **Compose Actions** - Data transformation and composition +- **Apply to Each Loops** - Collection iteration with `item()` function +- **Nested Loops** - Stack-based item tracking for complex scenarios diff --git a/docs/getting-started/basic-concepts.md b/docs/getting-started/basic-concepts.md index f8a9f757..473aece2 100644 --- a/docs/getting-started/basic-concepts.md +++ b/docs/getting-started/basic-concepts.md @@ -339,7 +339,7 @@ While Fake4Dataverse simulates Dataverse closely, there are differences: - Calculated/Rollup fields ✅ **Now Supported**: -- Cloud Flows - Power Automate flow simulation (with JSON import!) ✅ **NEW** +- Cloud Flows - Power Automate flow simulation (with JSON import!) - Custom APIs - Modern Dataverse Custom APIs ❌ **Not Simulated**: diff --git a/docs/getting-started/faq.md b/docs/getting-started/faq.md index 195ed8a7..560e1f12 100644 --- a/docs/getting-started/faq.md +++ b/docs/getting-started/faq.md @@ -327,7 +327,7 @@ Yes! See [Middleware Architecture](./concepts/middleware.md). ### Can I test Power Automate Cloud Flows? -Yes! ✅ **NEW** - Fake4Dataverse now supports Cloud Flow simulation including: +Yes! - Fake4Dataverse now supports Cloud Flow simulation including: - Registering flows programmatically - **Importing real Power Automate flows from exported JSON** (new feature!) - Automatic triggering on CRUD operations diff --git a/docs/getting-started/quickstart.md b/docs/getting-started/quickstart.md index ac331027..b1eef4f1 100644 --- a/docs/getting-started/quickstart.md +++ b/docs/getting-started/quickstart.md @@ -345,7 +345,7 @@ Now that you've written your first tests, explore these topics: - **[Basic Concepts](./basic-concepts.md)** - Understand how the framework works - **[Testing Plugins](../usage/testing-plugins.md)** - Dive deep into plugin testing - **[Querying Data](../usage/querying-data.md)** - Master LINQ and FetchXML queries -- **[Cloud Flows](../usage/cloud-flows.md)** - Test Power Automate flows (with JSON import!) ✅ **NEW** +- **[Cloud Flows](../usage/cloud-flows.md)** - Test Power Automate flows (with JSON import!) - **[CRUD Operations](../usage/crud-operations.md)** - Learn all CRUD patterns - **[Batch Operations](../usage/batch-operations.md)** - Test ExecuteMultiple and transactions - **[Custom API](../usage/custom-api.md)** - Test Custom APIs @@ -355,7 +355,7 @@ Now that you've written your first tests, explore these topics: Explore advanced testing scenarios: - **Pipeline Simulation** - Test plugins with full pipeline behavior - **Security Testing** - Test security roles and permissions -- **JSON Import for Flows** - Import real Power Automate flows and test them ✅ **NEW** +- **JSON Import for Flows** - Import real Power Automate flows and test them - **Message Executors** - See all [supported Dataverse messages](../messages/) ### Need Help? diff --git a/docs/messages/README.md b/docs/messages/README.md index 99b8c629..4bab90ba 100644 --- a/docs/messages/README.md +++ b/docs/messages/README.md @@ -351,7 +351,7 @@ public void Should_Throw_When_EntityNotFound() ``` -## Cloud Flow Actions ✅ **NEW** +## Cloud Flow Actions In addition to traditional message executors, Fake4Dataverse supports **Cloud Flow (Power Automate) actions** through the Dataverse connector. These actions provide an alternative, higher-level API for testing flows. @@ -369,8 +369,8 @@ In addition to traditional message executors, Fake4Dataverse supports **Cloud Fl | `Relate` | Associate records | ✅ Supported | | `Unrelate` | Disassociate records | ✅ Supported | | `ExecuteAction` | Execute custom actions/APIs | ✅ Supported | -| `UploadFile` | Upload files/images to columns | ✅ **NEW** | -| `DownloadFile` | Download files/images from columns | ✅ **NEW** | +| `UploadFile` | Upload files/images to columns | | +| `DownloadFile` | Download files/images from columns | | ### File Operations Example diff --git a/docs/messages/audit.md b/docs/messages/audit.md index c5fbb234..e593db2b 100644 --- a/docs/messages/audit.md +++ b/docs/messages/audit.md @@ -2,7 +2,6 @@ This document lists all audit-related message executors supported in Fake4Dataverse. -**Implementation Date:** October 2025 **Reference:** [Dataverse Auditing](https://learn.microsoft.com/en-us/power-apps/developer/data-platform/auditing/overview) - Microsoft documentation on audit operations and messages in Dataverse. diff --git a/docs/metadata-persistence.md b/docs/metadata-persistence.md index ee1bca65..8b843475 100644 --- a/docs/metadata-persistence.md +++ b/docs/metadata-persistence.md @@ -1,6 +1,5 @@ # Metadata Persistence -**Implementation Date**: December 2025 **Issue Reference**: [Persist tables/columns and other metadata](https://github.com/rnwood/Fake4Dataverse/issues/89) Fake4Dataverse automatically persists entity and attribute metadata to standard Dataverse metadata tables, allowing metadata to be queried like regular entity data. @@ -344,9 +343,9 @@ The metadata persistence feature is **fully automatic and backward compatible**: ✅ **Entity metadata** - Full support via EntityDefinition table ✅ **Attribute metadata** - Full support via Attribute table -✅ **Relationship metadata tables** - Relationship table available for querying ✅ **NEW** -✅ **OptionSet metadata tables** - OptionSet table available for querying ✅ **NEW** -✅ **EntityKey metadata tables** - EntityKey table available for querying ✅ **NEW** +✅ **Relationship metadata tables** - Relationship table available for querying +✅ **OptionSet metadata tables** - OptionSet table available for querying +✅ **EntityKey metadata tables** - EntityKey table available for querying ✅ **Automatic initialization** - All metadata tables automatically loaded ✅ **Automatic persistence** - Entity and Attribute metadata transparently persisted diff --git a/docs/service.md b/docs/service.md index e8b76f91..a732f471 100644 --- a/docs/service.md +++ b/docs/service.md @@ -1,6 +1,5 @@ # Fake4DataverseService: Network-Accessible Testing -**Implementation Date:** October 2025 **Issue:** N/A (New feature) > **💡 For ServiceClient Users:** See the [ServiceClient Compatibility Guide](../Fake4DataverseService/SERVICECLIENT.md) for patterns and best practices when testing existing ServiceClient-based code. diff --git a/docs/thread-safety.md b/docs/thread-safety.md index b35e7ad2..becab84e 100644 --- a/docs/thread-safety.md +++ b/docs/thread-safety.md @@ -2,14 +2,11 @@ ## Overview -Starting from version 4.x, Fake4Dataverse provides built-in thread safety for CRUD operations with database-like serialization of transactions. This ensures that concurrent operations from multiple threads can safely access the same `IXrmFakedContext` instance without race conditions or data corruption. - -**Implementation Date**: October 2025 -**Reference Issue**: Thread safety and database-like transaction serialization +Fake4Dataverse has built-in thread safety for CRUD operations with database-like serialization of transactions. This means concurrent operations from multiple threads can safely access the same `IXrmFakedContext` instance without race conditions or data corruption. ## Why Thread Safety Matters -In real-world testing scenarios, you may need to: +In real-world testing, you might need to: - **Test parallel plugin execution** - Multiple plugins running concurrently - **Simulate concurrent user operations** - Multiple users accessing the system simultaneously @@ -17,16 +14,16 @@ In real-world testing scenarios, you may need to: - **Verify race condition handling** - Ensure your code handles concurrent access correctly Without thread safety, concurrent operations could lead to: -- ❌ Data corruption -- ❌ Lost updates -- ❌ Inconsistent state -- ❌ Test flakiness +- Data corruption +- Lost updates +- Inconsistent state +- Test flakiness ## How It Works ### Per-Entity-Type Locking for Better Concurrency -Fake4Dataverse implements thread safety using **per-entity-type locks**, providing optimal concurrency while maintaining data consistency: +Fake4Dataverse uses **per-entity-type locks** for optimal concurrency while maintaining data consistency: ```csharp // Operations on DIFFERENT entity types can execute concurrently @@ -301,17 +298,6 @@ The implementation guarantees: 4. **Concurrency** - Operations on different entity types execute in parallel 5. **Durability** - Changes are immediately visible to subsequent operations -## Key Differences from FakeXrmEasy v2 - -**Important**: The thread safety implementation in Fake4Dataverse differs from FakeXrmEasy v2+: - -| Feature | FakeXrmEasy v2+ | Fake4Dataverse v4 | -|---------|----------------|-------------------| -| Thread Safety | Not documented | ✅ Built-in with per-entity-type locking | -| Lock Granularity | Unknown | One lock per entity type (e.g., account, contact) | -| Concurrency | Unknown | ✅ Operations on different entities run in parallel | -| Test Support | No specific tests | ✅ Comprehensive thread safety tests included | - ## Best Practices ### ✅ Do diff --git a/docs/usage/alternate-keys.md b/docs/usage/alternate-keys.md index ec1037b0..44c7cf20 100644 --- a/docs/usage/alternate-keys.md +++ b/docs/usage/alternate-keys.md @@ -1,16 +1,15 @@ # Alternate Keys -Fake4Dataverse supports alternate keys for testing scenarios where records are identified by attributes other than their primary GUID. This feature allows you to test code that uses alternate keys for record references, updates, and retrievals. +Fake4Dataverse supports alternate keys for testing scenarios where records are identified by attributes other than their primary GUID. ## Overview **Reference:** https://learn.microsoft.com/en-us/power-apps/developer/data-platform/define-alternate-keys-entity -Alternate keys in Dataverse allow you to uniquely identify records using one or more attributes instead of the primary GUID. This is particularly useful for: - -- Integration scenarios where external systems use natural keys -- Improving performance by avoiding additional lookups -- Creating more readable and maintainable code +Fake4Dataverse replicates alternate key functionality for: +- Record identification using natural keys instead of GUIDs +- Testing integration scenarios with external systems +- Testing code that uses alternate keys for references, updates, and retrievals ## How Alternate Keys Work diff --git a/docs/usage/auditing.md b/docs/usage/auditing.md index 2d284e8c..173523ad 100644 --- a/docs/usage/auditing.md +++ b/docs/usage/auditing.md @@ -1,7 +1,6 @@ # Auditing in Fake4Dataverse -Testing audit functionality is essential for ensuring your Dataverse applications properly track changes to data. This guide covers enabling auditing, testing audit records, and retrieving audit history. - +Testing audit functionality helps ensure your Dataverse applications properly track changes to data. This guide covers enabling auditing, testing audit records, and retrieving audit history. **Reference:** [Dataverse Auditing Overview](https://learn.microsoft.com/en-us/power-apps/developer/data-platform/auditing/overview) - Microsoft documentation on the auditing system in Dataverse, including audit entity structure, audit details, and auditing configuration. @@ -26,21 +25,20 @@ Testing audit functionality is essential for ensuring your Dataverse application - [User Tracking](#user-tracking) - [Clearing Audit Data](#clearing-audit-data) - [Complete Examples](#complete-examples) -- [Key Differences from FakeXrmEasy v2](#key-differences-from-fakexrmeasy-v2) - [Best Practices](#best-practices) - [See Also](#see-also) ## Overview -Dataverse auditing tracks changes to records over time, capturing: +Fake4Dataverse simulates audit tracking for record changes. Captured audit data includes: -- **Create operations**: When records are created -- **Update operations**: When records are modified, including old and new attribute values -- **Delete operations**: When records are deleted -- **User information**: Which user performed each operation -- **Timestamps**: When each operation occurred +- **Create operations**: Record creation events +- **Update operations**: Field modifications with old and new values +- **Delete operations**: Record deletion events +- **User information**: User who performed each operation +- **Timestamps**: Operation timestamps -In Dataverse, auditing must be explicitly enabled at both the organization and entity level. In Fake4Dataverse, auditing is disabled by default to match this behavior. +Auditing is disabled by default and must be explicitly enabled at organization and entity levels, matching Dataverse behavior. ## Enabling Auditing @@ -694,40 +692,6 @@ public void Should_MaintainCompleteAuditTrail() } ``` -## Key Differences from FakeXrmEasy v2 - -**Important**: The audit implementation in Fake4Dataverse differs from FakeXrmEasy v2+ in several ways: - -### Setup and Configuration - -| Feature | FakeXrmEasy v2+ | Fake4Dataverse | -|---------|----------------|----------------| -| **Enable Auditing** | `context.AuditingEnabled = true` | `context.GetProperty().IsAuditEnabled = true` | -| **Access Audits** | `context.GetAuditRecords()` | `context.GetProperty().GetAllAuditRecords()` | -| **Clear Audits** | `context.ClearAudits()` | `context.GetProperty().ClearAuditData()` | - -### Key Differences: - -1. **Property-based Access**: Fake4Dataverse uses the property system for audit repository access, following its architecture pattern -2. **Interface-based**: Uses `IAuditRepository` interface for better testability and extensibility -3. **SDK Compatibility**: Uses SDK `AttributeAuditDetail` class directly instead of custom classes -4. **Metadata-Based Configuration**: Fake4Dataverse fully supports Dataverse's three-level audit configuration (organization, entity, attribute levels) through EntityMetadata and AttributeMetadata, matching real Dataverse behavior exactly - -### Migration Example: - -**FakeXrmEasy v2:** -```csharp -context.AuditingEnabled = true; -var audits = context.GetAuditRecords(); -``` - -**Fake4Dataverse:** -```csharp -var auditRepo = context.GetProperty(); -auditRepo.IsAuditEnabled = true; -var audits = auditRepo.GetAllAuditRecords(); -``` - ## Best Practices ### 1. Enable Auditing Selectively diff --git a/docs/usage/auto-number-fields.md b/docs/usage/auto-number-fields.md index e42e8dc8..e66898eb 100644 --- a/docs/usage/auto-number-fields.md +++ b/docs/usage/auto-number-fields.md @@ -1,11 +1,10 @@ # Auto Number Fields -**Implementation Date:** October 2025 **Issue:** [Support auto number fields](https://github.com/rnwood/Fake4Dataverse/issues/...) ## Overview -Auto number fields in Dataverse automatically generate alphanumeric strings when a new record is created. Fake4Dataverse fully supports auto number field generation using the same format patterns as real Dataverse. +Fake4Dataverse supports auto number field generation using format patterns for testing scenarios that require automatically generated alphanumeric strings. **Reference:** [Microsoft Docs - Auto Number Fields](https://learn.microsoft.com/en-us/power-apps/maker/data-platform/autonumber-fields) diff --git a/docs/usage/batch-operations.md b/docs/usage/batch-operations.md index cf56106b..fac8af62 100644 --- a/docs/usage/batch-operations.md +++ b/docs/usage/batch-operations.md @@ -11,7 +11,7 @@ Learn how to test batch operations using ExecuteMultiple and ExecuteTransaction ## ExecuteMultiple -`ExecuteMultiple` allows you to batch multiple requests into a single call. This is useful for bulk operations. +Fake4Dataverse supports `ExecuteMultiple` for testing bulk operations with batched requests. ### Basic ExecuteMultiple diff --git a/docs/usage/business-rules.md b/docs/usage/business-rules.md index 5348963c..2db7ef43 100644 --- a/docs/usage/business-rules.md +++ b/docs/usage/business-rules.md @@ -1,19 +1,17 @@ # Testing Business Rules -Business rules provide a simple interface to implement and maintain fast-changing data validation and field logic in Microsoft Dataverse. This guide shows how to test business rules using Fake4Dataverse. +Business rules give you a simple way to implement and maintain data validation and field logic in Microsoft Dataverse. This guide shows how to test business rules using Fake4Dataverse. **Microsoft Documentation**: https://learn.microsoft.com/en-us/power-apps/maker/data-platform/data-platform-create-business-rule ## Overview -Business rules in Dataverse allow administrators to: -- Validate data and show error messages -- Set or clear field values automatically -- Show/hide or enable/disable fields (client-side) -- Set business requirements and recommendations -- Control field requirements - -Fake4Dataverse simulates business rule execution during Create and Update operations, allowing you to test business logic without requiring a live CRM instance. +Fake4Dataverse simulates business rule execution during Create and Update operations. Supported capabilities: +- Data validation with error messages +- Automatic field value setting and clearing +- Client-side actions (show/hide, enable/disable fields) - tracked but not enforced in tests +- Business requirements and recommendations +- Field requirement control ## Quick Start @@ -537,19 +535,17 @@ Business rules work with all standard Dataverse field types: - Boolean - Lookups (EntityReference) -## Key Differences from FakeXrmEasy v2 +## Implementation Notes -**Note**: Based on research as of October 2025, business rules support in FakeXrmEasy v2+ could not be verified through public documentation or repositories. The table below compares to hypothetical FakeXrmEasy v2 implementation if it exists in their commercial version. +Fake4Dataverse's business rules implementation is based on Microsoft's official documentation and provides comprehensive simulation of server-side business rule behavior. The framework supports: -| Feature | FakeXrmEasy v2+ (if available) | Fake4Dataverse v4 | -|---------|----------------|-------------------| -| **Context Setup** | Potentially `new XrmRealContext()` or similar | Must use `XrmFakedContextFactory.New()` | -| **Accessing Executor** | Potentially direct property access | Requires casting: `(XrmFakedContext)context` | -| **Rule Registration** | Unknown - potentially metadata-based | Manual `BusinessRuleDefinition` objects | -| **Scope Support** | Unknown | Entity (server-side) scope only | -| **Client-Side Rules** | Unknown | Tracked but not enforced | +- Entity-scoped (server-side) business rules +- Field validation and default values +- Conditional logic and branching +- Error messaging for validation failures +- Integration with the plugin pipeline -**Important**: Fake4Dataverse's business rules implementation is based on Microsoft's official documentation and provides comprehensive simulation of server-side business rule behavior. If you're using FakeXrmEasy v1, this is a new capability not available in that version. +For detailed configuration options, see the API documentation for `BusinessRuleDefinition` and related types. ## Advanced Topics @@ -627,7 +623,3 @@ var executor = context.BusinessRuleExecutor; - [Testing Plugins](./testing-plugins.md) - Business rules execute before plugins - [CRUD Operations](./crud-operations.md) - How Create/Update trigger business rules - [Microsoft Business Rules Documentation](https://learn.microsoft.com/en-us/power-apps/maker/data-platform/data-platform-create-business-rule) - -## Implementation Date - -Business rules simulation was implemented in October 2025 as part of Feature Parity Issue #8. diff --git a/docs/usage/calculated-fields.md b/docs/usage/calculated-fields.md index 30b05cda..444a4af1 100644 --- a/docs/usage/calculated-fields.md +++ b/docs/usage/calculated-fields.md @@ -2,27 +2,22 @@ ## Overview -Calculated fields (also known as calculated columns) are fields whose values are automatically computed based on formulas. Fake4Dataverse simulates Dataverse calculated field evaluation using the NCalc expression engine, supporting arithmetic operations, string manipulation, date/time functions, and logical operators. - -**Implemented:** 2025-10-11 (Issue #22) +Fake4Dataverse simulates calculated field evaluation using the NCalc expression engine. Supported features: +- Arithmetic operations +- String manipulation +- Date/time functions +- Logical operators +- Field references within the same entity or related entities ## Microsoft Documentation Official references: - [Define Calculated Fields](https://learn.microsoft.com/en-us/power-apps/maker/data-platform/define-calculated-fields) - Main documentation for calculated columns -- [Types of Fields](https://learn.microsoft.com/en-us/power-apps/maker/data-platform/types-of-fields) - Field types in Dataverse - -## What are Calculated Fields? - -Calculated fields allow you to: -- Automatically compute field values based on formulas -- Reference other fields in the same entity or related entities -- Use built-in functions for string manipulation, date math, and logical operations -- Update values in real-time when dependencies change +- [Types of Fields](https://learn.microsoft.com/en-us/power-apps/maker/data-platform/types-of-fields) - Field types -### When Calculated Fields are Evaluated +## Evaluation Behavior -According to Microsoft documentation, calculated fields are evaluated: +Fake4Dataverse evaluates calculated fields: - **On entity retrieve** - Calculated in real-time when the entity is retrieved - **On entity update** - Re-calculated when dependent field values change @@ -554,28 +549,6 @@ public void Plugin_Should_Use_Calculated_Field() } ``` -## Key Differences from FakeXrmEasy v2 - -**Important**: The calculated fields implementation in Fake4Dataverse differs from FakeXrmEasy v2+ in several ways: - -1. **Registration Approach**: - - **FakeXrmEasy v2+**: Calculated fields may be registered via metadata - - **Fake4Dataverse v4**: Calculated fields are registered directly via `CalculatedFieldEvaluator.RegisterCalculatedField()` - -2. **Formula Syntax**: - - Both versions use square brackets for field references: `[fieldname]` - - Both support similar function names and operators - -3. **Evaluation Timing**: - - Both evaluate on retrieve and update operations - - Fake4Dataverse uses explicit evaluator calls in the pipeline - -4. **Function Support**: - - Fake4Dataverse implements functions verified from Microsoft documentation - - Function names are case-insensitive - -**Migration Tip**: When migrating from FakeXrmEasy v2+, replace metadata-based calculated field setup with direct `RegisterCalculatedField()` calls in your test arrangement. - ## Limitations Current limitations in Fake4Dataverse calculated fields: diff --git a/docs/usage/cloud-flows.md b/docs/usage/cloud-flows.md index 907d8c6f..d2b4671d 100644 --- a/docs/usage/cloud-flows.md +++ b/docs/usage/cloud-flows.md @@ -2,15 +2,13 @@ ## Overview -Cloud Flows (Power Automate flows) are an increasingly common integration pattern for Dataverse applications. The Cloud Flow simulation feature in Fake4Dataverse enables developers to test Dataverse-triggered flows, verify flow execution, and validate flow actions/outputs in unit tests. - -**Status:** ✅ **Implemented** (October 12, 2025) - Phases 1-7 Complete, JSON Import Extended +Cloud Flows (Power Automate flows) have become a common way to integrate Dataverse applications with other systems. Fake4Dataverse lets you test these flows in unit tests without needing a live environment. **Package:** `Fake4DataverseCloudFlows` (.NET 8.0 only) - Separate package for advanced OData support -**Test Coverage:** 208 unit tests, all passing ✅ (includes control flow actions, JSON import, and OData conversion) +**Test Coverage:** 208 unit tests, all passing (includes control flow actions, JSON import, and OData conversion) -> **Note:** Cloud Flow simulation has been moved to a separate `Fake4DataverseCloudFlows` project targeting .NET 8.0 only. This allows it to use Microsoft.OData.Core for advanced OData query processing. Install the `Fake4Dataverse.CloudFlows` package and initialize with: +> **Note:** Cloud Flow simulation lives in a separate `Fake4DataverseCloudFlows` project that targets .NET 8.0. This allows it to use Microsoft.OData.Core for advanced OData query processing. Install the `Fake4Dataverse.CloudFlows` package and initialize with: > ```csharp > var context = XrmFakedContextFactory.New(); > context.CloudFlowSimulator = new CloudFlowSimulator(context); @@ -24,20 +22,19 @@ Official references: - [Trigger Conditions](https://learn.microsoft.com/en-us/power-automate/triggers-introduction) - [Flow Definition Schema](https://learn.microsoft.com/en-us/azure/logic-apps/logic-apps-workflow-definition-language) -## What are Cloud Flows? +## Replicated Behavior -Cloud Flows allow you to: -- Automate business processes triggered by Dataverse events -- Integrate Dataverse with external systems (Outlook, Teams, SharePoint, custom APIs) -- Execute complex multi-step workflows with branching logic -- Transform and manipulate data across systems +Fake4Dataverse replicates Cloud Flow execution for testing: +- Business process automation triggered by Dataverse events +- Multi-step workflows with branching logic +- Data transformation and manipulation ## Capabilities -The Cloud Flow simulation feature provides: +Cloud Flow simulation supports: 1. **Flow Registration** - Register flow definitions programmatically or from JSON -2. **JSON Import** - Import real Cloud Flow definitions exported from Power Automate ✅ **NEW** -3. **Expression Language** - Full Power Automate expression evaluation using Jint.net ✅ **NEW** +2. **JSON Import** - Import real Cloud Flow definitions exported from Power Automate +3. **Expression Language** - Full Power Automate expression evaluation using Jint.net 4. **Automatic Triggering** - Flows automatically trigger on Create/Update/Delete operations when `UsePipelineSimulation = true` 5. **Manual Triggering** - Manually simulate flow execution with `SimulateTrigger` 6. **Built-in Dataverse Connector** - Full CRUD support (Create, Retrieve, Update, Delete, ListRecords, Relate, Unrelate, ExecuteAction) @@ -48,9 +45,9 @@ The Cloud Flow simulation feature provides: ## API Usage -### Expression Language Support ✅ **NEW** +### Expression Language Support -Fake4Dataverse now supports Power Automate expression language for dynamic values in flow actions: +Fake4Dataverse supports Power Automate expression language for dynamic values in flow actions: ```csharp var flowDefinition = new CloudFlowDefinition @@ -90,8 +87,8 @@ flowSimulator.RegisterFlow(flowDefinition); - Collection: `first()`, `last()`, `take()`, `skip()`, `join()`, `reverse()`, `createArray()`, `flatten()` - Date/Time: `utcNow()`, `addDays()`, `addHours()`, `formatDateTime()`, `startOfDay()`, `getPastTime()`, `getFutureTime()` - Math: `add()`, `sub()`, `mul()`, `div()`, `min()`, `max()` -- Type Checking: `isInt()`, `isFloat()`, `isString()`, `isArray()`, `isObject()` ✅ **NEW** -- URI: `uriComponent()`, `uriHost()`, `uriPath()`, `uriQuery()`, `uriScheme()` ✅ **NEW** +- Type Checking: `isInt()`, `isFloat()`, `isString()`, `isArray()`, `isObject()` +- URI: `uriComponent()`, `uriHost()`, `uriPath()`, `uriQuery()`, `uriScheme()` **Total: 80+ functions implemented** @@ -159,7 +156,7 @@ flowSimulator.UnregisterFlow("notify_on_contact_create"); flowSimulator.ClearAllFlows(); ``` -#### Register a Flow from JSON ✅ **NEW** +#### Register a Flow from JSON You can import real Cloud Flow definitions exported from Power Automate: @@ -233,11 +230,11 @@ flowSimulator.AssertFlowTriggered("notify_on_contact_create"); - **Trigger Scopes:** Organization, BusinessUnit, ParentChildBusinessUnits, User - **Filtered Attributes:** Update triggers with specific attribute filtering - **Actions:** Dataverse actions (CreateRecord, UpdateRecord, DeleteRecord, GetItem, ListRecords) -- **Control Flow:** Condition (If), Switch, Foreach (Apply to Each), Until (Do Until) ✅ **NEW** -- **Data Operations:** Compose ✅ **NEW** +- **Control Flow:** Condition (If), Switch, Foreach (Apply to Each), Until (Do Until) +- **Data Operations:** Compose - **Action Parameters:** Entity names, attributes, filters, ordering, top -- **Expression Language:** Full Power Automate expression evaluation ✅ **NEW** -- **OData Type Conversion:** Automatic conversion of OData/REST API types to SDK types ✅ **NEW** +- **Expression Language:** Full Power Automate expression evaluation +- **OData Type Conversion:** Automatic conversion of OData/REST API types to SDK types **Limitations:** - Non-Dataverse connectors require custom handlers via `RegisterConnectorActionHandler` @@ -436,10 +433,10 @@ Assert.Single(contacts); - `Relate` - Associate records (many-to-many or one-to-many) - `Unrelate` - Disassociate records - `ExecuteAction` - Execute custom actions or custom APIs -- `UploadFile` - Upload files or images to entity columns ✅ **NEW** -- `DownloadFile` - Download files or images from entity columns ✅ **NEW** +- `UploadFile` - Upload files or images to entity columns +- `DownloadFile` - Download files or images from entity columns -#### File Operations (UploadFile & DownloadFile) ✅ **NEW** +#### File Operations (UploadFile & DownloadFile) The `UploadFile` and `DownloadFile` actions simulate file and image column operations in Dataverse. These are commonly used for uploading contact photos, document attachments, or any binary data. @@ -802,7 +799,7 @@ foreach (var result in results) } ``` -### Control Flow Actions ✅ **NEW** +### Control Flow Actions The Cloud Flow simulator now supports all major control flow actions for conditional logic, branching, and loops. @@ -1157,7 +1154,7 @@ Assert.Contains("External service unavailable", results[0].Errors[0]); ## Action Types -### Compose Action ✅ **NEW** +### Compose Action The Compose action allows you to create data transformations and compose new objects or values from expressions. @@ -1225,7 +1222,7 @@ var compose2 = new ComposeAction }; ``` -### Apply to Each Action ✅ **NEW** +### Apply to Each Action The Apply to Each action iterates over a collection and executes a set of actions for each item. @@ -1508,7 +1505,6 @@ Assert.Equal(1, flowSimulator.GetFlowExecutionCount("log_account_update")); // S ## Implementation Status -**Current Status:** ✅ **Completed** (October 12, 2025) All core phases have been implemented and tested. The Cloud Flow simulation feature is fully functional for testing Dataverse-triggered flows with comprehensive expression language support, safe navigation, path separators, Compose actions, and Apply to Each loops. @@ -1531,7 +1527,7 @@ All core phases have been implemented and tested. The Cloud Flow simulation feat - ✅ `IConnectorActionHandler` interface - ✅ Connector action handler registration - ✅ Built-in Dataverse connector -- ✅ Built-in Compose action handler ✅ **NEW** +- ✅ Built-in Compose action handler - ✅ Extensibility for custom connectors ### Phase 4: Verification APIs ✅ **COMPLETED** @@ -1544,23 +1540,23 @@ All core phases have been implemented and tested. The Cloud Flow simulation feat ### Phase 5: Expression Language ✅ **COMPLETED** - ✅ Full expression language implementation using Jint 4.2.0 - ✅ 80+ Power Automate functions -- ✅ Safe navigation operator (?) for null-safe access ✅ **NEW** -- ✅ Path separator (/) for nested property access ✅ **NEW** +- ✅ Safe navigation operator (?) for null-safe access +- ✅ Path separator (/) for nested property access - ✅ All reference functions (triggerBody, outputs, body, variables, item) - ✅ String, math, logical, date/time, collection, and conversion functions - ✅ Type preservation (int, double, string, bool) ### Phase 6: Advanced Action Types ✅ **COMPLETED** -- ✅ Compose actions for data transformation ✅ **NEW** -- ✅ Apply to Each (loops) with `@item()` function ✅ **NEW** -- ✅ Nested loop support via stack-based item tracking ✅ **NEW** -- ✅ Recursive expression evaluation in composed objects ✅ **NEW** +- ✅ Compose actions for data transformation +- ✅ Apply to Each (loops) with `@item()` function +- ✅ Nested loop support via stack-based item tracking +- ✅ Recursive expression evaluation in composed objects ### Phase 7: Control Flow Actions ✅ **COMPLETED** (October 12, 2025) -- ✅ Condition actions (if/then/else branching) ✅ **NEW** -- ✅ Switch actions (multi-case branching) ✅ **NEW** -- ✅ Parallel branches (parallel execution paths) ✅ **NEW** -- ✅ Do Until loops (loop with exit condition) ✅ **NEW** +- ✅ Condition actions (if/then/else branching) +- ✅ Switch actions (multi-case branching) +- ✅ Parallel branches (parallel execution paths) +- ✅ Do Until loops (loop with exit condition) ### Phase 8: Future Enhancements - ⏳ Error handling and retry logic (Scope, Try/Catch) @@ -1570,49 +1566,12 @@ All core phases have been implemented and tested. The Cloud Flow simulation feat **Test Coverage:** 157 unit tests, all passing ✅ - 57 tests for expression evaluator -- 7 tests for safe navigation and path separators ✅ **NEW** -- 7 tests for Compose and Apply to Each actions ✅ **NEW** -- 13 tests for control flow actions (Condition, Switch, Parallel, Do Until) ✅ **NEW** -- 6 tests for JSON import of control flow actions ✅ **NEW** +- 7 tests for safe navigation and path separators +- 7 tests for Compose and Apply to Each actions +- 13 tests for control flow actions (Condition, Switch, Parallel, Do Until) +- 6 tests for JSON import of control flow actions - 67 tests for simulator, Dataverse actions, and triggering -## Key Differences from FakeXrmEasy v2 - -**Important**: The Cloud Flow simulation feature in Fake4Dataverse differs from FakeXrmEasy v2+ in several ways: - -### API Design Differences - -| Feature | FakeXrmEasy v2+ | Fake4Dataverse | -|---------|----------------|----------------| -| **Flow Registration** | Unknown | Explicit registration with `RegisterFlow` | -| **Automatic Triggering** | Unknown | Requires `UsePipelineSimulation = true` | -| **Connector Handlers** | Unknown | Extensibility-first with `IConnectorActionHandler` | -| **JSON Import** | Unknown | Planned for future release | -| **Expression Engine** | Unknown | Basic support, full expressions planned | - -### Setup Differences - -**Fake4Dataverse:** -```csharp -// Explicit registration with automatic triggering -var context = XrmFakedContextFactory.New(); -context.UsePipelineSimulation = true; // Required for automatic triggering -var flowSimulator = context.CloudFlowSimulator; - -flowSimulator.RegisterFlow(new CloudFlowDefinition -{ - Name = "my_flow", - Trigger = new DataverseTrigger { /* ... */ }, - Actions = new List { /* ... */ } -}); - -// Flows trigger automatically on CRUD operations -service.Create(entity); -``` - -**FakeXrmEasy v2+ (reference):** -Specific implementation details for FakeXrmEasy v2+ are not publicly documented. Consult FakeXrmEasy v2+ documentation for comparison. - ## Related Documentation - [Testing Plugins](testing-plugins.md) - Similar patterns for testing business logic diff --git a/docs/usage/custom-api.md b/docs/usage/custom-api.md index 33817d1e..a0494ea2 100644 --- a/docs/usage/custom-api.md +++ b/docs/usage/custom-api.md @@ -2,9 +2,7 @@ ## Overview -Custom APIs are the modern way to create custom messages in Dataverse, replacing the legacy Custom Actions approach. They provide strongly-typed request/response parameters and better integration with the Power Platform. - -**Implemented:** 2025-10-10 (Issue #4) +Fake4Dataverse supports Custom API testing, enabling you to test custom message implementations. ## Microsoft Documentation @@ -13,12 +11,12 @@ Official references: - [Custom API Tables](https://learn.microsoft.com/en-us/power-apps/developer/data-platform/customapi-tables) - [Parameter Data Types](https://learn.microsoft.com/en-us/power-apps/developer/data-platform/customapi-tables#parameter-data-types) -## What are Custom APIs? +## Testing Custom APIs -Custom APIs allow you to: -- Define custom business logic with strongly-typed parameters -- Create both Functions (read operations) and Actions (write operations) -- Integrate with Power Automate and Power Apps +Fake4Dataverse replicates Custom API execution for testing: +- Custom business logic with strongly-typed parameters +- Both Functions (read operations) and Actions (write operations) +- Integration with plugin pipeline simulation - Build reusable business logic across the Power Platform ## Usage @@ -575,4 +573,3 @@ var successCount = (int)response.Results["SuccessCount"]; - `Fake4DataverseAbstractions/Fake4Dataverse.Abstractions/FakeMessageExecutors/OrganizationRequestExecutors.cs` - `Fake4DataverseCore/Fake4Dataverse.Core/Middleware/Messages/MiddlewareBuilderExtensions.Messages.cs` - **Tests**: `Fake4DataverseCore/tests/Fake4Dataverse.Core.Tests/FakeContextTests/CustomApiTests/` -- **Feature Parity**: Matches FakeXrmEasy v2+ behavior diff --git a/docs/usage/duplicate-detection.md b/docs/usage/duplicate-detection.md index 6b8f7c73..e7c8d59a 100644 --- a/docs/usage/duplicate-detection.md +++ b/docs/usage/duplicate-detection.md @@ -6,9 +6,8 @@ Fake4Dataverse supports duplicate detection for testing scenarios involving the **Reference:** https://learn.microsoft.com/en-us/power-apps/developer/data-platform/detect-duplicate-data -Duplicate detection in Dataverse helps prevent duplicate records by defining rules that compare attributes across records. Fake4Dataverse simulates this behavior by evaluating `duplicaterule` and `duplicaterulecondition` entities that you configure in your test context. +Fake4Dataverse simulates duplicate detection by evaluating `duplicaterule` and `duplicaterulecondition` entities configured in your test context. This enables testing how code handles duplicate records based on configurable rules. -**Implementation Date:** January 2025 **GitHub PR:** [#456](https://github.com/your-org/Fake4Dataverse/pull/456) ## How Duplicate Detection Works diff --git a/docs/usage/fiscal-period-operators.md b/docs/usage/fiscal-period-operators.md index 14c512b7..2dc05fc2 100644 --- a/docs/usage/fiscal-period-operators.md +++ b/docs/usage/fiscal-period-operators.md @@ -4,7 +4,6 @@ Fiscal period operators enable date-based queries using fiscal calendars instead of standard calendar dates. This is essential for financial reporting, budgeting, and any scenario where your organization's fiscal year differs from the calendar year. -**Implemented:** 2025-10-10 (Issue #3) ## Microsoft Documentation @@ -581,4 +580,3 @@ var results = service.RetrieveMultiple(query); - `Fake4DataverseCore/Fake4Dataverse.Core/Query/ConditionExpressionExtensions.FiscalPeriod.cs` - `Fake4DataverseCore/Fake4Dataverse.Core/Extensions/XmlExtensionsForFetchXml.cs` - **Tests**: `Fake4DataverseCore/tests/Fake4Dataverse.Core.Tests/FakeContextTests/FetchXml/FiscalPeriodOperatorTests.cs` -- **Feature Parity**: Matches FakeXrmEasy v2+ behavior diff --git a/docs/usage/hierarchical-queries.md b/docs/usage/hierarchical-queries.md index 30ebec7c..059f8bce 100644 --- a/docs/usage/hierarchical-queries.md +++ b/docs/usage/hierarchical-queries.md @@ -2,9 +2,8 @@ ## Overview -Hierarchical query operators allow you to query parent-child relationships in entity hierarchies. This is essential for working with organizational structures, account hierarchies, and other tree-like data structures in Dataverse. +Fake4Dataverse supports hierarchical query operators for testing parent-child relationships in entity hierarchies, including organizational structures, account hierarchies, and tree-like data structures. -**Implemented:** 2025-10-10 (Issue #2) ## Microsoft Documentation @@ -447,4 +446,3 @@ var query = new QueryExpression("contact") // Contact doesn't have parentcontact - `Fake4DataverseCore/Fake4Dataverse.Core/Query/ConditionExpressionExtensions.Hierarchical.cs` - `Fake4DataverseCore/Fake4Dataverse.Core/Extensions/XmlExtensionsForFetchXml.cs` - **Tests**: `Fake4DataverseCore/tests/Fake4Dataverse.Core.Tests/FakeContextTests/HierarchicalQueryTests/` -- **Feature Parity**: Matches FakeXrmEasy v2+ behavior diff --git a/docs/usage/impersonation.md b/docs/usage/impersonation.md index 7609a7a1..b0a2d212 100644 --- a/docs/usage/impersonation.md +++ b/docs/usage/impersonation.md @@ -1,6 +1,5 @@ # Impersonation -**Implementation Date:** January 2025 **Issue:** [#116](https://github.com/rnwood/Fake4Dataverse/issues/116) ## Overview @@ -261,18 +260,6 @@ public void Should_Respect_Impersonated_User_Permissions() } ``` -## Key Differences from FakeXrmEasy v2 - -**Important**: Fake4Dataverse's impersonation differs from FakeXrmEasy v2+ in the following ways: - -| Feature | FakeXrmEasy v2+ | Fake4Dataverse v4 | -|---------|-----------------|-------------------| -| Property Name | `CallerProperties.ImpersonationUserId` | `CallerProperties.ImpersonatedUserId` | -| Interface Method | None | `ICallerProperties.GetEffectiveUser()` | -| Privilege Check | Automatic | Explicit validation in SecurityMiddleware | -| HTTP Header | Manual setup | Built-in middleware support | -| SOAP Header | Manual setup | Built-in middleware support | - ## Best Practices 1. **Always enable security** when testing impersonation: diff --git a/docs/usage/mda-interface.md b/docs/usage/mda-interface.md index 59028d15..f64e94b2 100644 --- a/docs/usage/mda-interface.md +++ b/docs/usage/mda-interface.md @@ -1,6 +1,5 @@ # Model-Driven App (MDA) Interface -**Implementation Date:** January 2025 **Issue:** [#116](https://github.com/rnwood/Fake4Dataverse/issues/116) ## Overview diff --git a/docs/usage/merge-request.md b/docs/usage/merge-request.md index b5983368..44d764b8 100644 --- a/docs/usage/merge-request.md +++ b/docs/usage/merge-request.md @@ -2,9 +2,8 @@ ## Overview -The Merge Request feature allows you to merge two entity records in Dataverse, combining their data and updating all references to point to the surviving record. This is a common operation when dealing with duplicate records. +Fake4Dataverse supports merge operations for testing record consolidation scenarios. The merge operation combines two entity records, updates references to point to the surviving record, and handles duplicate record scenarios. -**Implemented:** 2025-10-10 (Issue #1) ## Microsoft Documentation @@ -247,4 +246,3 @@ service.Execute(mergeRequest); - **File**: `Fake4DataverseCore/Fake4Dataverse.Core/FakeMessageExecutors/MergeRequestExecutor.cs` - **Tests**: `Fake4DataverseCore/tests/Fake4Dataverse.Core.Tests/FakeContextTests/MergeRequestTests/` -- **Feature Parity**: Matches FakeXrmEasy v2+ behavior diff --git a/docs/usage/metadata-validation.md b/docs/usage/metadata-validation.md index 1d993d7f..fccfbfa8 100644 --- a/docs/usage/metadata-validation.md +++ b/docs/usage/metadata-validation.md @@ -4,7 +4,6 @@ Fake4Dataverse v4.0.0+ enforces attribute metadata validation using `IsValidForC ## Overview -**Implemented:** October 2025 (Issue #84) Microsoft Dataverse validates attribute operations based on metadata properties. Fake4Dataverse now replicates this behavior to provide more accurate testing and catch potential runtime issues before deployment. @@ -238,53 +237,6 @@ public void Initialize_Should_Skip_Validation_For_Test_Data() } ``` -## Key Differences from FakeXrmEasy v2 - -**Important:** Fake4Dataverse v4.0.0+ implements attribute metadata validation that was not present in FakeXrmEasy v2.0.1 (the fork basis). - -| Feature | FakeXrmEasy v2.0.1 | Fake4Dataverse v4.0.0+ | -|---------|-------------------|------------------------| -| **IsValidForCreate validation** | ❌ Not enforced | ✅ Enforced by default | -| **IsValidForUpdate validation** | ❌ Not enforced | ✅ Enforced by default | -| **statecode during Create** | ⚠️ Hardcoded check only | ✅ Metadata-based validation | -| **Metadata requirement** | Optional | Required when validation enabled | -| **Validation toggle** | N/A | `IntegrityOptions.ValidateAttributeTypes` | - -### Migration Impact - -If you're migrating from FakeXrmEasy v2 and have tests that: - -1. **Set statecode/statuscode during Create**: Update tests to use Update or disable validation -2. **Don't initialize metadata**: Add `context.InitializeMetadata()` calls -3. **Need flexible test setup**: Use `context.Initialize()` for test data - -**Example migration:** - -```csharp -// FakeXrmEasy v2 - Worked without validation -var account = new Entity("account") -{ - ["name"] = "Test", - ["statecode"] = new OptionSetValue(1) -}; -service.Create(account); // Succeeded - -// Fake4Dataverse v4 - Option 1: Disable validation -var context = XrmFakedContextFactory.New(new IntegrityOptions -{ - ValidateAttributeTypes = false -}); - -// Fake4Dataverse v4 - Option 2: Use Initialize for test setup -var account = new Entity("account") -{ - Id = Guid.NewGuid(), - ["name"] = "Test", - ["statecode"] = new OptionSetValue(1) -}; -context.Initialize(account); // Bypasses validation -``` - ## Configuration Options ### Enable/Disable Validation diff --git a/docs/usage/rollup-fields.md b/docs/usage/rollup-fields.md index f6eb249d..c9953b03 100644 --- a/docs/usage/rollup-fields.md +++ b/docs/usage/rollup-fields.md @@ -2,33 +2,25 @@ ## Overview -Rollup fields (also known as rollup columns) automatically aggregate data from related child records using functions such as SUM, COUNT, MIN, MAX, and AVG. Fake4Dataverse simulates Dataverse rollup field evaluation, allowing you to test business logic that depends on aggregated values from related entities. - -**Implemented:** 2025-10-11 (Issue #7) +Fake4Dataverse simulates rollup field evaluation for testing business logic that depends on aggregated values from related entities. ## Microsoft Documentation Official references: - [Define Rollup Fields](https://learn.microsoft.com/en-us/power-apps/maker/data-platform/define-rollup-fields) - Main documentation for rollup columns -- [Types of Fields](https://learn.microsoft.com/en-us/power-apps/maker/data-platform/types-of-fields) - Field types in Dataverse - -## What are Rollup Fields? +- [Types of Fields](https://learn.microsoft.com/en-us/power-apps/maker/data-platform/types-of-fields) - Field types -Rollup fields allow you to: -- Automatically aggregate values from related child records -- Use aggregate functions: SUM, COUNT, MIN, MAX, AVG -- Apply filters to restrict which records are included -- Calculate values across one-to-many relationships -- Support hierarchical rollups (entire entity hierarchy) +## Replicated Behavior -### When Rollup Fields are Evaluated +Fake4Dataverse replicates rollup field capabilities: +- Aggregate functions: SUM, COUNT, MIN, MAX, AVG +- Filters to restrict which records are included +- Calculations across one-to-many relationships +- Hierarchical rollups (entire entity hierarchy) -According to Microsoft documentation, rollup fields are evaluated: -- **Asynchronously** - By scheduled system jobs in the background -- **On-demand** - Using the CalculateRollupField message -- **After related record changes** - When child records are created, updated, or deleted +### Evaluation Timing -In Fake4Dataverse, rollup fields can be evaluated: +Fake4Dataverse evaluates rollup fields: - **Manually** - Using `EvaluateRollupFields(entity)` or `TriggerRollupCalculation(entityLogicalName, recordId)` - **Automatically** - When related records are created, updated, or deleted (automatic refresh) diff --git a/docs/usage/security-model.md b/docs/usage/security-model.md index 1c96f047..35a61314 100644 --- a/docs/usage/security-model.md +++ b/docs/usage/security-model.md @@ -1,6 +1,5 @@ # Dataverse Security Model -**Implementation Date:** October 2024 **Status:** ✅ Complete **Issue:** [#114](https://github.com/rnwood/Fake4Dataverse/issues/114) diff --git a/docs/usage/testing-plugins.md b/docs/usage/testing-plugins.md index 7ee795e3..dc274fe1 100644 --- a/docs/usage/testing-plugins.md +++ b/docs/usage/testing-plugins.md @@ -17,9 +17,9 @@ Plugin testing is one of the primary use cases for Fake4Dataverse. This guide sh - [Message-Specific Image Availability](#message-specific-image-availability) - [Testing Plugin Steps](#testing-plugin-steps) - [Async Plugins](#async-plugins) -- [Plugin Pipeline Simulator](#plugin-pipeline-simulator) **NEW** -- [Plugin Auto-Discovery from Assemblies](#plugin-auto-discovery-from-assemblies) **NEW** -- [Custom Action and Custom API Plugin Support](#custom-action-and-custom-api-plugin-support) **NEW** +- [Plugin Pipeline Simulator](#plugin-pipeline-simulator) +- [Plugin Auto-Discovery from Assemblies](#plugin-auto-discovery-from-assemblies) +- [Custom Action and Custom API Plugin Support](#custom-action-and-custom-api-plugin-support) - [Best Practices](#best-practices) ## Quick Start @@ -413,7 +413,7 @@ public void Should_ProcessRelatedAccount_When_ContactCreated() ## Testing Plugin Images -**New in v4.x (2025-10-11)**: Comprehensive pre/post image support with automatic image creation and SPKL attribute auto-discovery. +Fake4Dataverse provides comprehensive pre/post image support with automatic image creation and SPKL attribute auto-discovery. Reference: https://learn.microsoft.com/en-us/power-apps/developer/data-platform/image-entities @@ -491,7 +491,7 @@ public void Should_AutomaticallyCreateImages_WhenRegistered() ### SPKL Image Attribute Auto-Discovery -**New in v4.x (2025-10-11)**: Use SPKL `CrmPluginRegistrationImage` attributes for automatic image registration. +Use SPKL `CrmPluginRegistrationImage` attributes for automatic image registration. ```csharp using SparkleXrm.Tasks; @@ -834,27 +834,16 @@ public void Should_Execute_PreAndPost_Steps() ## Async Plugins -**New in v4.x (2025-10-11)**: Fake4Dataverse now includes comprehensive async plugin support with a simulated system job queue that mirrors Dataverse's asyncoperation entity. +Fake4Dataverse includes comprehensive async plugin support with a simulated system job queue that mirrors Dataverse's asyncoperation entity. Reference: https://learn.microsoft.com/en-us/power-apps/developer/data-platform/asynchronous-service -In Dataverse, asynchronous plugins (Mode = 1) are queued as asyncoperation records and execute after the main transaction completes. Fake4Dataverse simulates this behavior by: +Fake4Dataverse replicates async plugin behavior: - Queueing async plugins instead of executing them immediately - Providing APIs to monitor, execute, and wait for async jobs - Tracking async operation status (Ready, InProgress, Succeeded, Failed) - Capturing plugin execution errors -### Key Differences from FakeXrmEasy v2 - -**Important**: The async plugin implementation in Fake4Dataverse differs from FakeXrmEasy v2+ in several ways: - -| Feature | FakeXrmEasy v2+ | Fake4Dataverse v4 | -|---------|----------------|-------------------| -| **Async Plugin Execution** | Executes synchronously by default | Queued by default, execute on-demand | -| **System Job Queue** | Not exposed | Fully exposed via `AsyncJobQueue` | -| **Monitoring** | Limited | Full asyncoperation entity simulation | -| **Control** | Automatic | Manual control with auto-execute option | - ### Basic Async Plugin Testing Register an async plugin and control when it executes: @@ -1212,13 +1201,13 @@ public void Should_CleanupCompletedOperations() ## Plugin Pipeline Simulator -**New in v4.x (2025-10-10)**: Fake4Dataverse now includes comprehensive plugin pipeline simulation with support for multiple plugins per message/entity/stage combination. +Fake4Dataverse includes comprehensive plugin pipeline simulation with support for multiple plugins per message/entity/stage combination. Reference: https://learn.microsoft.com/en-us/power-apps/developer/data-platform/event-framework -### Key Differences from FakeXrmEasy v2 +### Pipeline Features -**Important**: The plugin pipeline implementation in Fake4Dataverse differs from FakeXrmEasy v2+ in several ways: +The plugin pipeline implementation provides: 1. **Explicit Registration**: Plugins must be explicitly registered using `PluginPipelineSimulator.RegisterPluginStep()`. There is no automatic plugin discovery from assemblies (though you can use `DiscoverAndRegisterPlugins()` for SPKL-style auto-discovery). @@ -1228,7 +1217,7 @@ Reference: https://learn.microsoft.com/en-us/power-apps/developer/data-platform/ 4. **Direct Configuration**: Plugin configuration (secure/unsecure) is passed directly in the `PluginStepRegistration` object, not through external configuration files. -5. **Async Plugin Queuing**: Async plugins are queued in a simulated system job queue (unlike FakeXrmEasy v2 which executes them synchronously). See [Async Plugins](#async-plugins) section for details. +5. **Async Plugin Queuing**: Async plugins are queued in a simulated system job queue for on-demand execution. See [Async Plugins](#async-plugins) section for details. ### Auto-Registration Mode (Recommended) @@ -1559,34 +1548,18 @@ public void Should_UnregisterPlugin() } ``` -### Migration Notes - -**From FakeXrmEasy v2.x**: The plugin pipeline simulation in Fake4Dataverse may have different setup compared to commercial FakeXrmEasy v2+: - -1. **Explicit Registration**: Plugins must be explicitly registered via `PluginPipelineSimulator.RegisterPluginStep()` -2. **Direct Control**: You have full control over when pipeline stages execute -3. **Configuration**: Plugin configuration is passed directly in the registration -4. **Auto-Execution**: Enable `UsePipelineSimulation = true` for automatic plugin execution during CRUD operations (similar to v2 behavior) +### Pipeline Configuration -**Comparison Table:** +The plugin pipeline provides flexible configuration options: -| Feature | FakeXrmEasy v2+ | Fake4Dataverse v4 | -|---------|----------------|-------------------| -| Plugin Discovery | Automatic from assemblies | Via `DiscoverAndRegisterPlugins()` | -| Pipeline Execution | Automatic during CRUD | Opt-in via `UsePipelineSimulation = true` | -| Configuration | External config files | Inline in registration | -| Manual Execution | Limited | Full control via `ExecutePipelineStage()` | -| Multiple Plugins | ✅ Yes | ✅ Yes | -| Execution Order | ✅ Yes | ✅ Yes | -| Filtering Attributes | ✅ Yes | ✅ Yes | -| Depth Tracking | ✅ Yes | ✅ Yes | -| Auto-Discovery | ✅ Yes | ✅ Yes (SPKL + custom attributes) | +1. **Explicit Registration**: Register plugins explicitly via `PluginPipelineSimulator.RegisterPluginStep()` +2. **Direct Control**: Full control over when pipeline stages execute +3. **Configuration**: Plugin configuration passed directly in the registration +4. **Auto-Execution**: Enable `UsePipelineSimulation = true` for automatic plugin execution during CRUD operations ## Plugin Auto-Discovery from Assemblies -**New in v4.x (2025-10-11)**: Automatically discover and register plugins from assemblies with support for SPKL and XrmTools.Meta attributes. - -**Updated (2025-10-16)**: Added support for XrmTools.Meta attributes alongside existing SPKL support. +Fake4Dataverse can automatically discover and register plugins from assemblies with support for SPKL and XrmTools.Meta attributes. ### Auto-Discovery with SPKL Attributes @@ -1679,8 +1652,6 @@ public class AccountAuditPlugin : IPlugin ### Auto-Discovery with XrmTools.Meta Attributes -**New in v4.x (2025-10-16)**: Support for XrmTools.Meta attributes for plugin registration. - Fake4Dataverse also supports XrmTools.Meta `StepAttribute` and `ImageAttribute` (without requiring a reference to the package): ```csharp @@ -1907,18 +1878,9 @@ public void Should_UseCustomAttributeConverter() - You don't use SPKL or custom attributes - You need to test edge cases or specific configurations -### Differences from FakeXrmEasy v2 - -| Feature | FakeXrmEasy v2+ | Fake4Dataverse v4 | -|---------|----------------|-------------------| -| **Auto-Discovery** | Built-in assembly scanning | Explicit via `DiscoverAndRegisterPlugins()` | -| **Attribute Support** | SPKL attributes | SPKL attributes (via reflection) + custom attributes | -| **Custom Converters** | Limited | Full support for type and attribute converters | -| **Configuration** | Config file based | Code-based with full flexibility | - ## Custom Action and Custom API Plugin Support -**New in v4.x (2025-10-11)**: Register and execute plugins for Custom Actions and Custom APIs. +Fake4Dataverse supports registering and executing plugins for Custom Actions and Custom APIs. Reference: https://learn.microsoft.com/en-us/power-apps/developer/data-platform/custom-api @@ -2159,24 +2121,6 @@ context.PluginPipelineSimulator.RegisterPluginStep(new PluginStepRegistration }); ``` -### Differences from FakeXrmEasy v2 - -| Feature | FakeXrmEasy v2+ | Fake4Dataverse v4 | -|---------|----------------|-------------------| -| **Custom Action Support** | ✅ Yes | ✅ Yes | -| **Custom API Support** | ✅ Yes | ✅ Yes | -| **Entity-Bound Actions** | ✅ Yes | ✅ Yes | -| **Global Actions** | ✅ Yes | ✅ Yes | -| **All Pipeline Stages** | ✅ Yes | ✅ Yes | -| **Multiple Plugins** | ✅ Yes | ✅ Yes | -| **Execution Order** | ✅ Yes | ✅ Yes | -| **Auto-Discovery** | ✅ Yes | ✅ Yes (via SPKL attributes) | - -**Key differences:** -- FakeXrmEasy v2+ may automatically discover custom action metadata from assemblies -- Fake4Dataverse requires explicit custom API metadata setup via `customapi` entity -- Both support full plugin pipeline simulation for custom actions/APIs - ## Best Practices ### ✅ Do diff --git a/docs/usage/testing-workflows.md b/docs/usage/testing-workflows.md index fafb1500..1b64c74f 100644 --- a/docs/usage/testing-workflows.md +++ b/docs/usage/testing-workflows.md @@ -16,13 +16,13 @@ Custom workflow activities extend Dataverse workflows with custom business logic ## Overview -Custom workflow activities in Dataverse inherit from `CodeActivity` and use workflow-specific services and context. Testing them requires: +Fake4Dataverse supports testing custom workflow activities that inherit from `CodeActivity`. Test setup includes: 1. Creating a workflow execution context 2. Setting input parameters 3. Executing the activity 4. Verifying output parameters and side effects -**Reference:** [Custom Workflow Activities](https://learn.microsoft.com/en-us/power-apps/developer/data-platform/workflow/workflow-extensions) - Microsoft documentation on creating and using custom workflow activities in Dataverse. +**Reference:** [Custom Workflow Activities](https://learn.microsoft.com/en-us/power-apps/developer/data-platform/workflow/workflow-extensions) - Microsoft documentation on creating and using custom workflow activities. ## Workflow Activity Basics