Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
using Dataverse.ConfigurationMigrationTool.Console.Features.Import.Interceptors;
using Microsoft.Xrm.Sdk;
using NSubstitute;
using Shouldly;

namespace Dataverse.ConfigurationMigrationTool.Console.Tests.Features.Import.Interceptors;
public abstract class BaseEntityReferenceFieldInterceptorTests<T> : BaseEntityInterceptorTests<T>
where T : BaseEntityReferenceFieldInterceptor
{
protected string EntityName { get; }
protected string PrimaryKeyName { get; }
protected BaseEntityReferenceFieldInterceptorTests(string EntityName, string PrimaryKeyName)
{
this.EntityName = EntityName;
this.PrimaryKeyName = PrimaryKeyName;
}
protected abstract Task<Entity> GetEntityByIdAsync(Guid Id);
protected abstract Task<Entity> GetEntityByNameAsync(string Name);
[Fact]
public async Task GivenAnEntityWithEntityReferenceField_WhenItsIntercepted_ThenItShouldResolveLookUpByName()
{
//Arrange
var recordName = "Test Team";
var expectedRecord = new Entity(EntityName)
{
Id = Guid.NewGuid(),
["name"] = recordName
};
GetEntityByNameAsync(recordName).Returns(expectedRecord);

var entity = new Entity("account")
{
Id = Guid.NewGuid(),
["name"] = "Test Account",
[PrimaryKeyName] = new EntityReference(EntityName, Guid.NewGuid()) { Name = recordName }
};

//Act
var result = await InterceptAsync(entity);
//Assert
result.GetAttributeValue<EntityReference>(PrimaryKeyName).Id.ShouldBe(expectedRecord.Id);
}
[Fact]
public async Task GivenAnEntityWithEntityReferenceField_WhenItsIntercepted_ThenItShouldResolveLookUpById()
{
//Arrange
var recordName = "Test team";
var expectedRecord = new Entity(EntityName)
{
Id = Guid.NewGuid(),
["name"] = recordName
};
GetEntityByIdAsync(expectedRecord.Id).Returns(expectedRecord);

var entity = new Entity("account")
{
Id = Guid.NewGuid(),
["name"] = "Test Account",
[PrimaryKeyName] = expectedRecord.ToEntityReference()
};

//Act
var result = await InterceptAsync(entity);
//Assert
result.GetAttributeValue<EntityReference>(PrimaryKeyName).Id.ShouldBe(expectedRecord.Id);
}
[Fact]
public async Task GivenAnEntityWithLookUpField_WhenItsInterceptedAndCantBeResolved_ThenItShouldRemoveFieldFromEntity()
{
//Arrange
var recordName = "Test team";
var expectedRecord = new Entity(EntityName)
{
Id = Guid.NewGuid(),
["name"] = recordName
};

var entity = new Entity("account")
{
Id = Guid.NewGuid(),
["name"] = "Test Account",
[PrimaryKeyName] = expectedRecord.ToEntityReference()
};

//Act
var result = await InterceptAsync(entity);
//Assert
result.Attributes.FirstOrDefault(kv => kv.Key == PrimaryKeyName).ShouldBe(default);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Dataverse.ConfigurationMigrationTool.Console.Features.Import.Interceptors;
using Dataverse.ConfigurationMigrationTool.Console.Services.Dataverse;
using Microsoft.Xrm.Sdk;
using NSubstitute;

namespace Dataverse.ConfigurationMigrationTool.Console.Tests.Features.Import.Interceptors;
public class TargetTransactionCurrencyInterceptorTests : BaseEntityReferenceFieldInterceptorTests<TargetTransactionCurrencyInterceptor>
{
private readonly IProductCatalogService _productCatalogService = Substitute.For<IProductCatalogService>();

public TargetTransactionCurrencyInterceptorTests() : base("transactioncurrency", "transactioncurrencyid")
{
}

protected override TargetTransactionCurrencyInterceptor CreateInterceptor() => new TargetTransactionCurrencyInterceptor(_productCatalogService);

protected override Task<Entity> GetEntityByIdAsync(Guid Id)
{
return _productCatalogService.GetTransacationCurrencyById(Id);
}

protected override Task<Entity> GetEntityByNameAsync(string Name)
{
return _productCatalogService.GetTransacationCurrencyByName(Name);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Dataverse.ConfigurationMigrationTool.Console.Features.Import.Interceptors;
using Dataverse.ConfigurationMigrationTool.Console.Services.Dataverse;
using Microsoft.Xrm.Sdk;
using NSubstitute;

namespace Dataverse.ConfigurationMigrationTool.Console.Tests.Features.Import.Interceptors;
public class TargetUoMInterceptorTests : BaseEntityReferenceFieldInterceptorTests<TargetUoMInterceptor>
{
private readonly IProductCatalogService _productCatalogService = Substitute.For<IProductCatalogService>();

public TargetUoMInterceptorTests() : base("uom", "uomid")
{
}

protected override TargetUoMInterceptor CreateInterceptor() => new TargetUoMInterceptor(_productCatalogService);

protected override Task<Entity> GetEntityByIdAsync(Guid Id)
{
return _productCatalogService.GetUoMById(Id);
}

protected override Task<Entity> GetEntityByNameAsync(string Name)
{
return _productCatalogService.GetUoMByName(Name);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Dataverse.ConfigurationMigrationTool.Console.Features.Import.Interceptors;
using Dataverse.ConfigurationMigrationTool.Console.Services.Dataverse;
using Microsoft.Xrm.Sdk;
using NSubstitute;

namespace Dataverse.ConfigurationMigrationTool.Console.Tests.Features.Import.Interceptors;
public class TargetUoMScheduleInterceptorTests : BaseEntityReferenceFieldInterceptorTests<TargetUoMScheduleInterceptor>
{
private readonly IProductCatalogService _productCatalogService = Substitute.For<IProductCatalogService>();

public TargetUoMScheduleInterceptorTests() : base("uomschedule", "uomscheduleid")
{
}

protected override TargetUoMScheduleInterceptor CreateInterceptor() => new TargetUoMScheduleInterceptor(_productCatalogService);

protected override Task<Entity> GetEntityByIdAsync(Guid Id)
{
return _productCatalogService.GetUoMScheduleById(Id);
}

protected override Task<Entity> GetEntityByNameAsync(string Name)
{
return _productCatalogService.GetUoMScheduleByName(Name);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
using Dataverse.ConfigurationMigrationTool.Console.Services.Dataverse;
using FakeXrmEasy.Abstractions;
using FakeXrmEasy.Abstractions.Enums;
using FakeXrmEasy.Middleware;
using FakeXrmEasy.Middleware.Crud;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Xrm.Sdk;
using NSubstitute;
using Shouldly;

namespace Dataverse.ConfigurationMigrationTool.Console.Tests.Services.Dataverse;
public class DataverseProductCatalogServiceTests
{
private readonly IXrmFakedContext _fakedContext;
private readonly IMemoryCache _memoryCache = Substitute.For<IMemoryCache>();
private readonly DataverseProductCatalogService _repository;
public DataverseProductCatalogServiceTests()
{
// Arrange
_fakedContext = MiddlewareBuilder.New()
.SetLicense(FakeXrmEasyLicense.NonCommercial)
.AddCrud()
.UseCrud()
.Build();
_repository = new DataverseProductCatalogService(_fakedContext.GetAsyncOrganizationService2(), _memoryCache);
}
[Fact]
public async Task GivenAProductCatalogServicey_WhenItFetchesTransactionCurrencyById_ThenItShouldCacheItsResult()
{
//Arrange
var recordname = "Test Team";

var record = new Entity("transactioncurrency")
{
Id = Guid.NewGuid(),
["currencyname"] = recordname
};
var cacheKey = $"product.GetTransacationCurrencyById.{record.Id}";
_fakedContext.Initialize(record);
var CacheEntry = Substitute.For<ICacheEntry>();
_memoryCache.TryGetValue(cacheKey, out Arg.Any<object>()).Returns(false);
_memoryCache.CreateEntry(cacheKey).Returns(CacheEntry);

//Act

var result = await _repository.GetTransacationCurrencyById(record.Id);

//Assert
result.Id.ShouldBe(record.Id);
CacheEntry.Received().SetValue(Arg.Is<Entity>(e => e.Id == record.Id));

}
[Fact]
public async Task GivenAProductCatalogServicey_WhenItFetchesTransactionCurrencyByName_ThenItShouldCacheItsResult()
{
//Arrange
var recordname = "Test Team";
var cacheKey = $"product.GetTransacationCurrencyByName.{recordname}";
var record = new Entity("transactioncurrency")
{
Id = Guid.NewGuid(),
["currencyname"] = recordname
};
_fakedContext.Initialize(record);
var CacheEntry = Substitute.For<ICacheEntry>();
_memoryCache.TryGetValue(cacheKey, out Arg.Any<object>()).Returns(false);
_memoryCache.CreateEntry(cacheKey).Returns(CacheEntry);

//Act

var result = await _repository.GetTransacationCurrencyByName(recordname);

//Assert
result.Id.ShouldBe(record.Id);
CacheEntry.Received().SetValue(Arg.Is<Entity>(e => e.Id == record.Id));

}
[Fact]
public async Task GivenAProductCatalogServicey_WhenItFetchesUoMById_ThenItShouldCacheItsResult()
{
//Arrange
var recordname = "Test Team";

var record = new Entity("uom")
{
Id = Guid.NewGuid(),
["name"] = recordname
};
var cacheKey = $"product.GetUoMById.{record.Id}";
_fakedContext.Initialize(record);
var CacheEntry = Substitute.For<ICacheEntry>();
_memoryCache.TryGetValue(cacheKey, out Arg.Any<object>()).Returns(false);
_memoryCache.CreateEntry(cacheKey).Returns(CacheEntry);

//Act

var result = await _repository.GetUoMById(record.Id);

//Assert
result.Id.ShouldBe(record.Id);
CacheEntry.Received().SetValue(Arg.Is<Entity>(e => e.Id == record.Id));

}
[Fact]
public async Task GivenAProductCatalogServicey_WhenItFetchesUoMByName_ThenItShouldCacheItsResult()
{
//Arrange
var recordname = "Test Team";
var cacheKey = $"product.GetUoMByName.{recordname}";
var record = new Entity("uom")
{
Id = Guid.NewGuid(),
["name"] = recordname
};
_fakedContext.Initialize(record);
var CacheEntry = Substitute.For<ICacheEntry>();
_memoryCache.TryGetValue(cacheKey, out Arg.Any<object>()).Returns(false);
_memoryCache.CreateEntry(cacheKey).Returns(CacheEntry);

//Act

var result = await _repository.GetUoMByName(recordname);

//Assert
result.Id.ShouldBe(record.Id);
CacheEntry.Received().SetValue(Arg.Is<Entity>(e => e.Id == record.Id));

}
[Fact]
public async Task GivenAProductCatalogServicey_WhenItFetchesUoMScheduleById_ThenItShouldCacheItsResult()
{
//Arrange
var recordname = "Test Team";

var record = new Entity("uomschedule")
{
Id = Guid.NewGuid(),
["name"] = recordname
};
var cacheKey = $"product.GetUoMScheduleById.{record.Id}";
_fakedContext.Initialize(record);
var CacheEntry = Substitute.For<ICacheEntry>();
_memoryCache.TryGetValue(cacheKey, out Arg.Any<object>()).Returns(false);
_memoryCache.CreateEntry(cacheKey).Returns(CacheEntry);

//Act

var result = await _repository.GetUoMScheduleById(record.Id);

//Assert
result.Id.ShouldBe(record.Id);
CacheEntry.Received().SetValue(Arg.Is<Entity>(e => e.Id == record.Id));

}
[Fact]
public async Task GivenAProductCatalogServicey_WhenItFetchesUoMScheduleByName_ThenItShouldCacheItsResult()
{
//Arrange
var recordname = "Test Team";
var cacheKey = $"product.GetUoMScheduleByName.{recordname}";
var record = new Entity("uomschedule")
{
Id = Guid.NewGuid(),
["name"] = recordname
};
_fakedContext.Initialize(record);
var CacheEntry = Substitute.For<ICacheEntry>();
_memoryCache.TryGetValue(cacheKey, out Arg.Any<object>()).Returns(false);
_memoryCache.CreateEntry(cacheKey).Returns(CacheEntry);

//Act

var result = await _repository.GetUoMScheduleByName(recordname);

//Assert
result.Id.ShouldBe(record.Id);
CacheEntry.Received().SetValue(Arg.Is<Entity>(e => e.Id == record.Id));

}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Dataverse.ConfigurationMigrationTool.Console.Features.Shared;
using Dataverse.ConfigurationMigrationTool.Console.Features.Shared.Domain;
using Microsoft.Xrm.Sdk;
using System.Globalization;
using System.Web;

namespace Dataverse.ConfigurationMigrationTool.Console.Features.Export.Mappers;
Expand Down Expand Up @@ -46,17 +47,17 @@ public Field Map((FieldSchema, object) source)
}
if (value is Money moneyValue)
{
fieldResult.Value = moneyValue.Value.ToString();
fieldResult.Value = moneyValue.Value.ToString(CultureInfo.InvariantCulture);
return fieldResult;
}
if (value is decimal decimalValue)
{
fieldResult.Value = decimalValue.ToString();
fieldResult.Value = decimalValue.ToString(CultureInfo.InvariantCulture);
return fieldResult;
}
if (value is double doubleValue)
{
fieldResult.Value = doubleValue.ToString();
fieldResult.Value = doubleValue.ToString(CultureInfo.InvariantCulture);
return fieldResult;
}
var str = value?.ToString() ?? string.Empty;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ public static IServiceCollection AddSharedServices(this IServiceCollection servi
{
return services.RegisterFromReflection<IFieldSchemaValidationRule>()
.RegisterFromReflection<IRelationshipSchemaValidationRule>()
.AddTransient<IValidator<DataSchema>, SchemaValidator>()
.AddTransient<IValidator<EntitySchema>, EntitySchemaValidator>();
.AddScoped<IValidator<DataSchema>, SchemaValidator>()
.AddScoped<IValidator<EntitySchema>, EntitySchemaValidator>();
}
public static IServiceCollection UseCommands(this IServiceCollection services, params string[] args)
{
Expand Down
Loading
Loading