Skip to content

Commit 77f2d0e

Browse files
committed
ImportTaskService unit tests for relationship
1 parent 03fe196 commit 77f2d0e

File tree

3 files changed

+310
-133
lines changed

3 files changed

+310
-133
lines changed

src/Dataverse.ConfigurationMigrationTool/Console.Tests/FakeBuilders/FakeEntityMetadataBuilder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public FakeEntityMetadataBuilder AddRelationship(string SchemaName, string Targe
3131
{
3232
Entity1LogicalName = EntityName,
3333
Entity2LogicalName = TargetEntity,
34-
34+
IntersectEntityName = SchemaName,
3535
SchemaName = SchemaName
3636
};
3737
ManyToManyRelationships.Add(relationship);
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
using Dataverse.ConfigurationMigrationTool.Console.Features.Import;
2+
using Dataverse.ConfigurationMigrationTool.Console.Features.Import.Model;
3+
using Dataverse.ConfigurationMigrationTool.Console.Features.Import.ValueConverters;
4+
using Dataverse.ConfigurationMigrationTool.Console.Features.Shared;
5+
using Dataverse.ConfigurationMigrationTool.Console.Services.Dataverse;
6+
using Dataverse.ConfigurationMigrationTool.Console.Tests.FakeBuilders;
7+
using Microsoft.Extensions.Logging;
8+
using Microsoft.Xrm.Sdk;
9+
using Microsoft.Xrm.Sdk.Messages;
10+
using Microsoft.Xrm.Sdk.Metadata;
11+
using NSubstitute;
12+
using Shouldly;
13+
14+
namespace Dataverse.ConfigurationMigrationTool.Console.Tests.Features.Import;
15+
public class ImportTaskProcessorServiceTests
16+
{
17+
private readonly IMetadataService metadataService;
18+
private readonly ILogger<ImportTaskProcessorService> logger;
19+
private readonly IDataverseValueConverter _dataverseValueConverter;
20+
private readonly IBulkOrganizationService bulkOrganizationService;
21+
private readonly ImportTaskProcessorService importService;
22+
23+
public ImportTaskProcessorServiceTests()
24+
{
25+
this.metadataService = Substitute.For<IMetadataService>();
26+
this.logger = Substitute.For<ILogger<ImportTaskProcessorService>>();
27+
_dataverseValueConverter = Substitute.For<IDataverseValueConverter>();
28+
this.bulkOrganizationService = Substitute.For<IBulkOrganizationService>();
29+
this.importService = new ImportTaskProcessorService(metadataService, logger, _dataverseValueConverter, bulkOrganizationService);
30+
}
31+
[Fact]
32+
public async Task GivenAnImportTaskWhereEntitySchemaIsNotFound_WhenExecuted_ThenItShouldReturnCompleted()
33+
{
34+
// Arrange
35+
var task = new ImportDataTask
36+
{
37+
SouceEntityName = "nonexistent_entity",
38+
EntitySchema = FakeSchemas.Contact,
39+
RelationshipSchema = null
40+
};
41+
var dataImport = new Entities
42+
{
43+
Entity = new List<EntityImport>
44+
{
45+
new EntityImport { Name = "account" }
46+
}
47+
};
48+
// Act
49+
var result = await importService.Execute(task, dataImport);
50+
// Assert
51+
result.ShouldBe(TaskResult.Completed);
52+
}
53+
[Fact]
54+
public async Task GivenARelationshipImportTask_WhenExecuted_ThenItShouldAssociateINDataverseAndReturnCompleted()
55+
{
56+
// Arrange
57+
var task = new ImportDataTask
58+
{
59+
SouceEntityName = "contact",
60+
RelationshipSchema = FakeSchemas.Contact.Relationships.Relationship.FirstOrDefault(),
61+
};
62+
var dataImport = new Entities
63+
{
64+
Entity = new List<EntityImport>
65+
{
66+
FakeDatasets.ContactSets
67+
}
68+
};
69+
IEnumerable<AssociateRequest> requestsSent = null;
70+
bulkOrganizationService.When(x => x.ExecuteBulk(Arg.Any<IEnumerable<AssociateRequest>>(), Arg.Any<IEnumerable<string>>()))
71+
.Do(x => requestsSent = x.Arg<IEnumerable<AssociateRequest>>());
72+
var requests = FakeDatasets.ContactSets.M2mrelationships.M2mrelationship.SelectMany(r => r.Targetids.Targetid.Select(t =>
73+
new AssociateRequest
74+
{
75+
Target = new EntityReference
76+
{
77+
Id = r.Sourceid,
78+
LogicalName = task.SouceEntityName,
79+
},
80+
Relationship = new Relationship("contact_opportunities"),
81+
RelatedEntities = new EntityReferenceCollection() {
82+
new EntityReference
83+
{
84+
Id = t,
85+
LogicalName = r.Targetentityname
86+
}
87+
}
88+
89+
}));
90+
metadataService.GetEntity(task.SouceEntityName).Returns(FakeMetadata.Contact);
91+
// Act
92+
var result = await importService.Execute(task, dataImport);
93+
// Assert
94+
bulkOrganizationService.Received(1).ExecuteBulk(Arg.Any<IEnumerable<AssociateRequest>>(), Arg.Is<IEnumerable<string>>(s => s.Contains("Cannot insert duplicate key")));
95+
foreach (var request in requestsSent)
96+
{
97+
98+
request.Target.ShouldBeEquivalentTo(new EntityReference
99+
{
100+
Id = FakeDatasets.ContactSets.M2mrelationships.M2mrelationship.First().Sourceid,
101+
LogicalName = task.SouceEntityName
102+
});
103+
request.Relationship.SchemaName.ShouldBe("contact_opportunities");
104+
}
105+
requests.SelectMany(r => r.RelatedEntities)
106+
.ShouldBeEquivalentTo(requestsSent.SelectMany(r => r.RelatedEntities));
107+
result.ShouldBe(TaskResult.Completed);
108+
}
109+
[Fact]
110+
public async Task GivenARelationshipImportTask_WhenExecutedAndAnAssociateRequestHasFailed_ThenItShouldReturnFailed()
111+
{
112+
// Arrange
113+
var task = new ImportDataTask
114+
{
115+
SouceEntityName = "contact",
116+
RelationshipSchema = FakeSchemas.Contact.Relationships.Relationship.FirstOrDefault(),
117+
};
118+
var dataImport = new Entities
119+
{
120+
Entity = new List<EntityImport>
121+
{
122+
FakeDatasets.ContactSets
123+
}
124+
};
125+
IEnumerable<AssociateRequest> requestsSent = null;
126+
bulkOrganizationService.ExecuteBulk(Arg.Any<IEnumerable<AssociateRequest>>(), Arg.Any<IEnumerable<string>>())
127+
.Returns([new() {
128+
Fault = new() {
129+
Message = "test error"
130+
},
131+
OriginalRequest = new AssociateRequest
132+
{
133+
Target = new EntityReference
134+
{
135+
Id = Guid.NewGuid(),
136+
LogicalName = "contact"
137+
}
138+
}
139+
}]);
140+
bulkOrganizationService.When(x => x.ExecuteBulk(Arg.Any<IEnumerable<AssociateRequest>>(), Arg.Any<IEnumerable<string>>()))
141+
.Do(x => requestsSent = x.Arg<IEnumerable<AssociateRequest>>());
142+
143+
metadataService.GetEntity(task.SouceEntityName).Returns(FakeMetadata.Contact);
144+
// Act
145+
var result = await importService.Execute(task, dataImport);
146+
// Assert
147+
bulkOrganizationService.Received(1).ExecuteBulk(Arg.Any<IEnumerable<AssociateRequest>>(), Arg.Is<IEnumerable<string>>(s => s.Contains("Cannot insert duplicate key")));
148+
149+
result.ShouldBe(TaskResult.Failed);
150+
}
151+
[Fact]
152+
public async Task GivenARelationshipImportTaskWhereRelationshipNotFound_WhenExecuted_ThenItShouldReturnFailed()
153+
{
154+
// Arrange
155+
var task = new ImportDataTask
156+
{
157+
SouceEntityName = "contact",
158+
RelationshipSchema = FakeSchemas.Contact.Relationships.Relationship.FirstOrDefault(),
159+
};
160+
var dataImport = new Entities
161+
{
162+
Entity = new List<EntityImport>
163+
{
164+
FakeDatasets.ContactSets
165+
}
166+
};
167+
var emd = new FakeEntityMetadataBuilder("account", "accountid", "name")
168+
.AddAttribute<StringAttributeMetadata>("accountnumber")
169+
.AddAttribute<StringAttributeMetadata>("companyname")
170+
.AddRelationship("account_opportunities", "opportunity")
171+
.Build();
172+
metadataService.GetEntity(task.SouceEntityName).Returns(emd);
173+
// Act
174+
var result = await importService.Execute(task, dataImport);
175+
// Assert
176+
result.ShouldBe(TaskResult.Failed);
177+
}
178+
}

0 commit comments

Comments
 (0)