Skip to content

Commit

Permalink
Add support for UpdateMultipleRequest DynamicsValue/fake-xrm-easy#122.…
Browse files Browse the repository at this point in the history
… Add file attribute metadata support for MetadataGenerator
  • Loading branch information
jordimontana82 committed Mar 15, 2024
1 parent 8e056d6 commit 564f6a9
Show file tree
Hide file tree
Showing 7 changed files with 535 additions and 2 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
## [2.5.0]

- Added support for bulk operations: CreateMultipleRequest
### Added

- Added FileAttributeMetadata support to MetadataGenerator
- Added support for bulk operations: CreateMultipleRequest, UpdateMultipleRequest

## [2.4.2]

Expand Down
7 changes: 6 additions & 1 deletion src/FakeXrmEasy.Core/Metadata/MetadataGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ private static T GetCustomAttribute<T>(MemberInfo member) where T : Attribute
return (T)Attribute.GetCustomAttribute(member, typeof(T));
}

private static AttributeMetadata CreateAttributeMetadata(Type propertyType)
internal static AttributeMetadata CreateAttributeMetadata(Type propertyType)
{
if (typeof(string) == propertyType)
{
Expand Down Expand Up @@ -287,6 +287,11 @@ private static AttributeMetadata CreateAttributeMetadata(Type propertyType)
{
return new MultiSelectPicklistAttributeMetadata();
}
else if (typeof(object) == propertyType)
{

return new FileAttributeMetadata();
}
#endif
else
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
#if FAKE_XRM_EASY_9
using FakeXrmEasy.Abstractions;
using FakeXrmEasy.Abstractions.FakeMessageExecutors;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Messages;
using System;
using System.Collections.Generic;
using System.Linq;

namespace FakeXrmEasy.Middleware.Crud.FakeMessageExecutors
{
/// <summary>
/// CreateMultipleRequest Executor
/// </summary>
public class UpdateMultipleRequestExecutor : IFakeMessageExecutor
{
/// <summary>
///
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public bool CanExecute(OrganizationRequest request)
{
return request is UpdateMultipleRequest;
}

/// <summary>
/// Executes the CreateRequestMultiple request
/// </summary>
/// <param name="request"></param>
/// <param name="ctx"></param>
/// <returns></returns>
public OrganizationResponse Execute(OrganizationRequest request, IXrmFakedContext ctx)
{
var updateMultipleRequest = (UpdateMultipleRequest)request;

ValidateRequest(updateMultipleRequest, ctx);

var records = updateMultipleRequest.Targets.Entities;

foreach (var record in records)
{
ctx.UpdateEntity(record);
}

return new UpdateMultipleResponse()
{
ResponseName = "UpdateMultipleResponse"
};
}

private void ValidateRequiredParameters(UpdateMultipleRequest request, IXrmFakedContext ctx)
{
if (request.Targets == null)
{
throw FakeOrganizationServiceFaultFactory.New(ErrorCodes.InvalidArgument,
"Required field 'Targets' is missing");
}

var targets = request.Targets;
if (string.IsNullOrWhiteSpace(targets.EntityName))
{
throw FakeOrganizationServiceFaultFactory.New(ErrorCodes.InvalidArgument,
"Required member 'EntityName' missing for field 'Targets'");
}
}

private void ValidateEntityName(UpdateMultipleRequest request, IXrmFakedContext ctx)
{
var targets = request.Targets;
if (ctx.ProxyTypesAssemblies.Any())
{
var earlyBoundType = ctx.FindReflectedType(targets.EntityName);
if (earlyBoundType == null)
{
throw FakeOrganizationServiceFaultFactory.New(ErrorCodes.QueryBuilderNoEntity,
$"The entity with a name = '{targets.EntityName}' with namemapping = 'Logical' was not found in the MetadataCache.");
}
}

if (ctx.CreateMetadataQuery().Any())
{
var entityMetadata = ctx.CreateMetadataQuery().FirstOrDefault(m => m.LogicalName == targets.EntityName);
if (entityMetadata == null)
{
throw FakeOrganizationServiceFaultFactory.New(ErrorCodes.QueryBuilderNoEntity,
$"The entity with a name = '{targets.EntityName}' with namemapping = 'Logical' was not found in the MetadataCache.");
}
}
}

private void ValidateRecords(UpdateMultipleRequest request, IXrmFakedContext ctx)
{
var records = request.Targets.Entities;
if (records.Count == 0)
{
throw FakeOrganizationServiceFaultFactory.New(ErrorCodes.UnExpected,
$"System.ArgumentException: The value of the parameter 'Targets' cannot be null or empty.");
}

foreach (var record in records)
{
ValidateRecord(request, record, ctx);
}
}

private void ValidateRecord(UpdateMultipleRequest request, Entity recordToUpdate, IXrmFakedContext ctx)
{
if (!request.Targets.EntityName.Equals(recordToUpdate.LogicalName))
{
throw FakeOrganizationServiceFaultFactory.New(ErrorCodes.QueryBuilderNoAttribute,
$"This entity cannot be added to the specified collection. The collection can have entities with PlatformName = {request.Targets.EntityName} while this entity has Platform Name: {recordToUpdate.LogicalName}");
}

if (recordToUpdate.Id == Guid.Empty)
{
throw FakeOrganizationServiceFaultFactory.New(ErrorCodes.ObjectDoesNotExist,
$"Entity Id must be specified for Operation");
}

var exists = ctx.ContainsEntity(recordToUpdate.LogicalName, recordToUpdate.Id);
if (!exists)
{
throw FakeOrganizationServiceFaultFactory.New(ErrorCodes.ObjectDoesNotExist,
$"{recordToUpdate.LogicalName} With Ids = {recordToUpdate.Id} Do Not Exist");
}
}

private void ValidateRequest(UpdateMultipleRequest request, IXrmFakedContext ctx)
{
ValidateRequiredParameters(request, ctx);
ValidateEntityName(request, ctx);
ValidateRecords(request, ctx);
}

/// <summary>
/// Returns CreateMultipleRequest
/// </summary>
/// <returns></returns>
public Type GetResponsibleRequestType()
{
return typeof(UpdateMultipleRequest);
}
}
}
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public static IMiddlewareBuilder AddCrud(this IMiddlewareBuilder builder)
#if FAKE_XRM_EASY_9
crudMessageExecutors.Add(typeof(CreateMultipleRequest), new CreateMultipleRequestExecutor());
crudMessageExecutors.Add(typeof(UpdateMultipleRequest), new UpdateMultipleRequestExecutor());
#endif
context.SetProperty(crudMessageExecutors);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System;
using DataverseEntities;
using FakeXrmEasy.Metadata;
using Microsoft.Xrm.Sdk.Metadata;
using Xunit;

namespace FakeXrmEasy.Core.Tests.Metadata
{
public class CreateAttributeMetadataTests
{
private readonly Type[] _typesTestType;
public CreateAttributeMetadataTests()
{
_typesTestType = new Type[] { typeof(dv_test) };
}

[Fact]
public void Should_generate_file_type()
{
var attributeMetadata = MetadataGenerator.CreateAttributeMetadata(typeof(object));
Assert.NotNull(attributeMetadata);
Assert.IsType<FileAttributeMetadata>(attributeMetadata);
}
}
}
Loading

0 comments on commit 564f6a9

Please sign in to comment.