Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invoking Upsert with alternate keys throws exception if pipeline simulation is turned on #166

Open
Zerajima opened this issue Oct 23, 2024 · 1 comment

Comments

@Zerajima
Copy link

The exception thrown is: "The id parameter '00000000-0000-0000-0000-000000000000' for entity logical name 'dcpwr_datamigration' is not valid."

It is thrown by XrmFakedContext.GetEntityById_Internal, which is called from MiddlewareBuilderPipelineExtensions.GetPreImageEntityForRequest. Here is a full callstack:

System.InvalidOperationException: The id parameter '00000000-0000-0000-0000-000000000000' for entity logical name 'dcpwr_datamigration' is not valid.
   at FakeXrmEasy.XrmFakedContext.GetEntityById_Internal(String sLogicalName, Guid id, Type t)
   at FakeXrmEasy.XrmFakedContext.GetEntityById(String logicalName, Guid id)
   at FakeXrmEasy.Middleware.Pipeline.MiddlewareBuilderPipelineExtensions.GetPreImageEntityForRequest(IXrmFakedContext context, OrganizationRequest request)
   at FakeXrmEasy.Middleware.Pipeline.MiddlewareBuilderPipelineExtensions.<>c__DisplayClass4_0.<UsePipelineSimulation>b__1(IXrmFakedContext context, OrganizationRequest request)
   at FakeXrmEasy.Middleware.MiddlewareBuilder.<>c__DisplayClass9_0.<Build>b__2(OrganizationRequest request)
   at FakeItEasy.ReturnValueConfigurationExtensions.<>c__DisplayClass8_0`2.<ReturnsLazily>b__0(IFakeObjectCall call)
   at FakeItEasy.Configuration.RuleBuilder.ReturnValueConfiguration`1.<>c__DisplayClass28_0.<ReturnsLazily>b__0(IInterceptedFakeObjectCall call)
   at FakeItEasy.Configuration.BuildableCallRule.Apply(IInterceptedFakeObjectCall fakeObjectCall)
   at FakeItEasy.Core.FakeManager.ApplyBestRule(IInterceptedFakeObjectCall fakeObjectCall)
   at FakeItEasy.Core.FakeManager.FakeItEasy.Core.IFakeCallProcessor.Process(InterceptedFakeObjectCall fakeObjectCall)
   at FakeItEasy.Creation.CastleDynamicProxy.CastleDynamicProxyGenerator.ProxyInterceptor.Intercept(IInvocation invocation)
   at Castle.DynamicProxy.AbstractInvocation.Proceed()
   at Castle.Proxies.ObjectProxy.Execute(OrganizationRequest request)
   at FakeXrmEasy.Middleware.Crud.MiddlewareBuilderCrudExtensions.<>c__DisplayClass7_0.<AddFakeUpdate>b__1(Entity e)
   at FakeItEasy.CallbackConfigurationExtensions.<>c__DisplayClass2_0`2.<Invokes>b__0(IFakeObjectCall call)
   at FakeItEasy.Configuration.BuildableCallRule.Apply(IInterceptedFakeObjectCall fakeObjectCall)
   at FakeItEasy.Core.FakeManager.ApplyBestRule(IInterceptedFakeObjectCall fakeObjectCall)
   at FakeItEasy.Core.FakeManager.FakeItEasy.Core.IFakeCallProcessor.Process(InterceptedFakeObjectCall fakeObjectCall)
   at FakeItEasy.Creation.CastleDynamicProxy.CastleDynamicProxyGenerator.ProxyInterceptor.Intercept(IInvocation invocation)
   at Castle.DynamicProxy.AbstractInvocation.Proceed()
   at Castle.Proxies.ObjectProxy.Update(Entity entity)
   at FakeXrmEasy.Middleware.Crud.FakeMessageExecutors.UpsertRequestExecutor.Execute(OrganizationRequest request, IXrmFakedContext ctx)
   at FakeXrmEasy.Middleware.Crud.MiddlewareBuilderCrudExtensions.ProcessRequest(IXrmFakedContext context, OrganizationRequest request)
   at FakeXrmEasy.Middleware.Crud.MiddlewareBuilderCrudExtensions.<>c__DisplayClass3_0.<UseCrud>b__1(IXrmFakedContext context, OrganizationRequest request)
   at FakeXrmEasy.Middleware.Pipeline.MiddlewareBuilderPipelineExtensions.<>c__DisplayClass4_0.<UsePipelineSimulation>b__1(IXrmFakedContext context, OrganizationRequest request)
   at FakeXrmEasy.Middleware.MiddlewareBuilder.<>c__DisplayClass9_0.<Build>b__2(OrganizationRequest request)
   at FakeItEasy.ReturnValueConfigurationExtensions.<>c__DisplayClass8_0`2.<ReturnsLazily>b__0(IFakeObjectCall call)
   at FakeItEasy.Configuration.RuleBuilder.ReturnValueConfiguration`1.<>c__DisplayClass28_0.<ReturnsLazily>b__0(IInterceptedFakeObjectCall call)
   at FakeItEasy.Configuration.BuildableCallRule.Apply(IInterceptedFakeObjectCall fakeObjectCall)
   at FakeItEasy.Core.FakeManager.ApplyBestRule(IInterceptedFakeObjectCall fakeObjectCall)
   at FakeItEasy.Core.FakeManager.FakeItEasy.Core.IFakeCallProcessor.Process(InterceptedFakeObjectCall fakeObjectCall)
   at FakeItEasy.Creation.CastleDynamicProxy.CastleDynamicProxyGenerator.ProxyInterceptor.Intercept(IInvocation invocation)
   at Castle.DynamicProxy.AbstractInvocation.Proceed()
   at Castle.Proxies.ObjectProxy.Execute(OrganizationRequest request)
   at FakeXrmEasy.FakeMessageExecutors.ExecuteMultipleRequestExecutor.Execute(OrganizationRequest request, IXrmFakedContext ctx)
@BetimBeja
Copy link

Hey @Zerajima and @jordimontana82 ,
I added the following test in the FakeXrmEasy.Plugins.Tests project and it failed with the same error stack as shared in this issue.

   [Fact]
   public void Should_pass_preimage_when_there_is_a_registered_preimage_in_prevalidation_with_alternatekey()
   {
       var accountMetadata = new Microsoft.Xrm.Sdk.Metadata.EntityMetadata();
       accountMetadata.LogicalName = Account.EntityLogicalName;
       var alternateKeyMetadata = new Microsoft.Xrm.Sdk.Metadata.EntityKeyMetadata();
       alternateKeyMetadata.KeyAttributes = new string[] { "AccountNumber" };
       accountMetadata.SetFieldValue("_keys", new Microsoft.Xrm.Sdk.Metadata.EntityKeyMetadata[]
            {
            alternateKeyMetadata
            });
       _context.InitializeMetadata(accountMetadata);

       _context.Initialize(new List<Entity>()
       {
           _newContact, _previousContact, _account
       });

       string registeredPreImageName = "PreImage";
       PluginImageDefinition preImageDefinition = new PluginImageDefinition(registeredPreImageName, ProcessingStepImageType.PreImage);

       _context.RegisterPluginStep<EntityImagesInPluginPipeline>(new PluginStepDefinition()
       {
           MessageName = "Update",
           Stage = ProcessingStepStage.Prevalidation,
           ImagesDefinitions = new List<PluginImageDefinition>()
           {
               preImageDefinition
           }
       });

       var _target = new Account()
       {
           AccountNumber = "1234",
           AccountCategoryCode = new OptionSetValue(2),
           NumberOfEmployees = 10,
           Revenue = new Money(10000),
           PrimaryContactId = _newContact.ToEntityReference()
       };
       _target.KeyAttributes.Add("AccountNumber", "1234");

       //Act
       _service.Update(_target);

       //Assert
       var allAccounts = _context.CreateQuery<Account>().ToList();

       var updatedAccount = allAccounts.Where(a => a.Id == _account.Id);
       Assert.NotNull(updatedAccount);

       var preImages = allAccounts.Where(a => a.Contains(preImageStoredAttributeName)).ToList();
       var postImages = allAccounts.Where(a => a.Contains(postImageStoredAttributeName)).ToList();

       Assert.Single(preImages);
       Assert.Empty(postImages);

       var preImage = preImages.First();
       Assert.Equal(registeredPreImageName, preImage.GetAttributeValue<string>("preimagename"));
   }

I will try to do a PR with a fix soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants