Skip to content

Commit 59d2b51

Browse files
authored
Test controller provider (#969)
Registers only the controllers required for a particular test suite, rather than always registering all controllers from the entire test assembly.
1 parent debe4af commit 59d2b51

File tree

97 files changed

+372
-99
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

97 files changed

+372
-99
lines changed

src/JsonApiDotNetCore/Middleware/HeaderConstants.cs

+3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
using JetBrains.Annotations;
2+
13
#pragma warning disable AV1008 // Class should not be static
24

35
namespace JsonApiDotNetCore.Middleware
46
{
7+
[PublicAPI]
58
public static class HeaderConstants
69
{
710
public const string MediaType = "application/vnd.api+json";

src/JsonApiDotNetCore/Middleware/JsonApiRoutingConvention.cs

+8-13
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public class JsonApiRoutingConvention : IJsonApiRoutingConvention
3333
{
3434
private readonly IJsonApiOptions _options;
3535
private readonly IResourceContextProvider _resourceContextProvider;
36-
private readonly HashSet<string> _registeredTemplates = new HashSet<string>();
36+
private readonly Dictionary<string, string> _registeredControllerNameByTemplate = new Dictionary<string, string>();
3737
private readonly Dictionary<Type, ResourceContext> _resourceContextPerControllerTypeMap = new Dictionary<Type, ResourceContext>();
3838

3939
public JsonApiRoutingConvention(IJsonApiOptions options, IResourceContextProvider resourceContextProvider)
@@ -89,11 +89,14 @@ public void Apply(ApplicationModel application)
8989

9090
string template = TemplateFromResource(controller) ?? TemplateFromController(controller);
9191

92-
if (template == null)
92+
if (_registeredControllerNameByTemplate.ContainsKey(template))
9393
{
94-
throw new InvalidConfigurationException($"Controllers with overlapping route templates detected: {controller.ControllerType.FullName}");
94+
throw new InvalidConfigurationException(
95+
$"Cannot register '{controller.ControllerType.FullName}' for template '{template}' because '{_registeredControllerNameByTemplate[template]}' was already registered for this template.");
9596
}
9697

98+
_registeredControllerNameByTemplate.Add(template, controller.ControllerType.FullName);
99+
97100
controller.Selectors[0].AttributeRouteModel = new AttributeRouteModel
98101
{
99102
Template = template
@@ -116,10 +119,7 @@ private string TemplateFromResource(ControllerModel model)
116119
{
117120
string template = $"{_options.Namespace}/{resourceContext.PublicName}";
118121

119-
if (_registeredTemplates.Add(template))
120-
{
121-
return template;
122-
}
122+
return template;
123123
}
124124

125125
return null;
@@ -133,12 +133,7 @@ private string TemplateFromController(ControllerModel model)
133133
string controllerName = _options.SerializerNamingStrategy.GetPropertyName(model.ControllerName, false);
134134
string template = $"{_options.Namespace}/{controllerName}";
135135

136-
if (_registeredTemplates.Add(template))
137-
{
138-
return template;
139-
}
140-
141-
return null;
136+
return template;
142137
}
143138

144139
/// <summary>

src/JsonApiDotNetCore/Properties/AssemblyInfo.cs

+1
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44
[assembly: InternalsVisibleTo("JsonApiDotNetCoreExampleTests")]
55
[assembly: InternalsVisibleTo("UnitTests")]
66
[assembly: InternalsVisibleTo("DiscoveryTests")]
7+
[assembly: InternalsVisibleTo("TestBuildingBlocks")]

test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Controllers/AtomicConstrainedOperationsControllerTests.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public AtomicConstrainedOperationsControllerTests(ExampleIntegrationTestContext<
1919
{
2020
_testContext = testContext;
2121

22-
testContext.ConfigureServicesAfterStartup(services => services.AddControllersFromExampleProject());
22+
testContext.UseController<CreateMusicTrackOperationsController>();
2323
}
2424

2525
[Fact]

test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceTests.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using FluentAssertions;
88
using FluentAssertions.Extensions;
99
using JsonApiDotNetCore.Serialization.Objects;
10+
using JsonApiDotNetCoreExample.Controllers;
1011
using JsonApiDotNetCoreExampleTests.Startups;
1112
using Microsoft.EntityFrameworkCore;
1213
using TestBuildingBlocks;
@@ -23,7 +24,7 @@ public AtomicCreateResourceTests(ExampleIntegrationTestContext<TestableStartup<O
2324
{
2425
_testContext = testContext;
2526

26-
testContext.ConfigureServicesAfterStartup(services => services.AddControllersFromExampleProject());
27+
testContext.UseController<OperationsController>();
2728
}
2829

2930
[Fact]

test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithClientGeneratedIdTests.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using FluentAssertions;
66
using JsonApiDotNetCore.Configuration;
77
using JsonApiDotNetCore.Serialization.Objects;
8+
using JsonApiDotNetCoreExample.Controllers;
89
using JsonApiDotNetCoreExampleTests.Startups;
910
using Microsoft.Extensions.DependencyInjection;
1011
using TestBuildingBlocks;
@@ -23,7 +24,7 @@ public AtomicCreateResourceWithClientGeneratedIdTests(
2324
{
2425
_testContext = testContext;
2526

26-
testContext.ConfigureServicesAfterStartup(services => services.AddControllersFromExampleProject());
27+
testContext.UseController<OperationsController>();
2728

2829
var options = (JsonApiOptions)testContext.Factory.Services.GetRequiredService<IJsonApiOptions>();
2930
options.AllowClientGeneratedIds = true;

test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToManyRelationshipTests.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Threading.Tasks;
66
using FluentAssertions;
77
using JsonApiDotNetCore.Serialization.Objects;
8+
using JsonApiDotNetCoreExample.Controllers;
89
using JsonApiDotNetCoreExampleTests.Startups;
910
using Microsoft.EntityFrameworkCore;
1011
using TestBuildingBlocks;
@@ -23,7 +24,7 @@ public AtomicCreateResourceWithToManyRelationshipTests(
2324
{
2425
_testContext = testContext;
2526

26-
testContext.ConfigureServicesAfterStartup(services => services.AddControllersFromExampleProject());
27+
testContext.UseController<OperationsController>();
2728
}
2829

2930
[Fact]

test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToOneRelationshipTests.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Threading.Tasks;
77
using FluentAssertions;
88
using JsonApiDotNetCore.Serialization.Objects;
9+
using JsonApiDotNetCoreExample.Controllers;
910
using JsonApiDotNetCoreExampleTests.Startups;
1011
using Microsoft.EntityFrameworkCore;
1112
using Newtonsoft.Json;
@@ -25,7 +26,7 @@ public AtomicCreateResourceWithToOneRelationshipTests(
2526
{
2627
_testContext = testContext;
2728

28-
testContext.ConfigureServicesAfterStartup(services => services.AddControllersFromExampleProject());
29+
testContext.UseController<OperationsController>();
2930
}
3031

3132
[Fact]

test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Deleting/AtomicDeleteResourceTests.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Threading.Tasks;
77
using FluentAssertions;
88
using JsonApiDotNetCore.Serialization.Objects;
9+
using JsonApiDotNetCoreExample.Controllers;
910
using JsonApiDotNetCoreExampleTests.Startups;
1011
using Microsoft.EntityFrameworkCore;
1112
using TestBuildingBlocks;
@@ -22,7 +23,7 @@ public AtomicDeleteResourceTests(ExampleIntegrationTestContext<TestableStartup<O
2223
{
2324
_testContext = testContext;
2425

25-
testContext.ConfigureServicesAfterStartup(services => services.AddControllersFromExampleProject());
26+
testContext.UseController<OperationsController>();
2627
}
2728

2829
[Fact]

test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Links/AtomicAbsoluteLinksTests.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using FluentAssertions;
55
using JsonApiDotNetCore.Resources;
66
using JsonApiDotNetCore.Serialization.Objects;
7+
using JsonApiDotNetCoreExample.Controllers;
78
using JsonApiDotNetCoreExampleTests.Startups;
89
using Microsoft.Extensions.DependencyInjection;
910
using TestBuildingBlocks;
@@ -22,10 +23,10 @@ public AtomicAbsoluteLinksTests(ExampleIntegrationTestContext<TestableStartup<Op
2223
{
2324
_testContext = testContext;
2425

26+
testContext.UseController<OperationsController>();
27+
2528
testContext.ConfigureServicesAfterStartup(services =>
2629
{
27-
services.AddControllersFromExampleProject();
28-
2930
services.AddScoped(typeof(IResourceChangeTracker<>), typeof(NeverSameResourceChangeTracker<>));
3031
});
3132
}

test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Links/AtomicRelativeLinksWithNamespaceTests.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using FluentAssertions;
66
using JsonApiDotNetCore.Resources;
77
using JsonApiDotNetCore.Serialization.Objects;
8+
using JsonApiDotNetCoreExample.Controllers;
89
using JsonApiDotNetCoreExampleTests.Startups;
910
using Microsoft.Extensions.DependencyInjection;
1011
using TestBuildingBlocks;
@@ -22,10 +23,10 @@ public AtomicRelativeLinksWithNamespaceTests(
2223
{
2324
_testContext = testContext;
2425

26+
testContext.UseController<OperationsController>();
27+
2528
testContext.ConfigureServicesAfterStartup(services =>
2629
{
27-
services.AddControllersFromExampleProject();
28-
2930
services.AddScoped(typeof(IResourceChangeTracker<>), typeof(NeverSameResourceChangeTracker<>));
3031
});
3132
}

test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/LocalIds/AtomicLocalIdTests.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Threading.Tasks;
66
using FluentAssertions;
77
using JsonApiDotNetCore.Serialization.Objects;
8+
using JsonApiDotNetCoreExample.Controllers;
89
using JsonApiDotNetCoreExampleTests.Startups;
910
using Microsoft.EntityFrameworkCore;
1011
using TestBuildingBlocks;
@@ -21,7 +22,7 @@ public AtomicLocalIdTests(ExampleIntegrationTestContext<TestableStartup<Operatio
2122
{
2223
_testContext = testContext;
2324

24-
testContext.ConfigureServicesAfterStartup(services => services.AddControllersFromExampleProject());
25+
testContext.UseController<OperationsController>();
2526
}
2627

2728
[Fact]

test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Meta/AtomicResourceMetaTests.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using FluentAssertions.Extensions;
77
using JsonApiDotNetCore.Resources;
88
using JsonApiDotNetCore.Serialization.Objects;
9+
using JsonApiDotNetCoreExample.Controllers;
910
using JsonApiDotNetCoreExampleTests.Startups;
1011
using Microsoft.Extensions.DependencyInjection;
1112
using TestBuildingBlocks;
@@ -22,10 +23,10 @@ public AtomicResourceMetaTests(ExampleIntegrationTestContext<TestableStartup<Ope
2223
{
2324
_testContext = testContext;
2425

26+
testContext.UseController<OperationsController>();
27+
2528
testContext.ConfigureServicesAfterStartup(services =>
2629
{
27-
services.AddControllersFromExampleProject();
28-
2930
services.AddScoped<IResourceDefinition<MusicTrack, Guid>, MusicTrackMetaDefinition>();
3031
services.AddScoped<IResourceDefinition<TextLanguage, Guid>, TextLanguageMetaDefinition>();
3132
});

test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Meta/AtomicResponseMetaTests.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using FluentAssertions;
77
using JsonApiDotNetCore.Serialization;
88
using JsonApiDotNetCore.Serialization.Objects;
9+
using JsonApiDotNetCoreExample.Controllers;
910
using JsonApiDotNetCoreExampleTests.Startups;
1011
using Microsoft.Extensions.DependencyInjection;
1112
using Newtonsoft.Json.Linq;
@@ -23,10 +24,10 @@ public AtomicResponseMetaTests(ExampleIntegrationTestContext<TestableStartup<Ope
2324
{
2425
_testContext = testContext;
2526

27+
testContext.UseController<OperationsController>();
28+
2629
testContext.ConfigureServicesAfterStartup(services =>
2730
{
28-
services.AddControllersFromExampleProject();
29-
3031
services.AddSingleton<IResponseMeta, AtomicResponseMeta>();
3132
});
3233
}

test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Mixed/AtomicRequestBodyTests.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Threading.Tasks;
55
using FluentAssertions;
66
using JsonApiDotNetCore.Serialization.Objects;
7+
using JsonApiDotNetCoreExample.Controllers;
78
using JsonApiDotNetCoreExampleTests.Startups;
89
using Microsoft.EntityFrameworkCore;
910
using TestBuildingBlocks;
@@ -19,7 +20,7 @@ public AtomicRequestBodyTests(ExampleIntegrationTestContext<TestableStartup<Oper
1920
{
2021
_testContext = testContext;
2122

22-
testContext.ConfigureServicesAfterStartup(services => services.AddControllersFromExampleProject());
23+
testContext.UseController<OperationsController>();
2324
}
2425

2526
[Fact]

test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Mixed/MaximumOperationsPerRequestTests.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using FluentAssertions;
66
using JsonApiDotNetCore.Configuration;
77
using JsonApiDotNetCore.Serialization.Objects;
8+
using JsonApiDotNetCoreExample.Controllers;
89
using JsonApiDotNetCoreExampleTests.Startups;
910
using Microsoft.Extensions.DependencyInjection;
1011
using TestBuildingBlocks;
@@ -21,7 +22,7 @@ public MaximumOperationsPerRequestTests(ExampleIntegrationTestContext<TestableSt
2122
{
2223
_testContext = testContext;
2324

24-
testContext.ConfigureServicesAfterStartup(services => services.AddControllersFromExampleProject());
25+
testContext.UseController<OperationsController>();
2526
}
2627

2728
[Fact]

test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/ModelStateValidation/AtomicModelStateValidationTests.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Threading.Tasks;
44
using FluentAssertions;
55
using JsonApiDotNetCore.Serialization.Objects;
6+
using JsonApiDotNetCoreExample.Controllers;
67
using JsonApiDotNetCoreExampleTests.Startups;
78
using Microsoft.EntityFrameworkCore;
89
using TestBuildingBlocks;
@@ -20,7 +21,7 @@ public AtomicModelStateValidationTests(ExampleIntegrationTestContext<ModelStateV
2021
{
2122
_testContext = testContext;
2223

23-
testContext.ConfigureServicesAfterStartup(services => services.AddControllersFromExampleProject());
24+
testContext.UseController<OperationsController>();
2425
}
2526

2627
[Fact]

test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/QueryStrings/AtomicQueryStringTests.cs

+4-2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using JsonApiDotNetCore.Configuration;
99
using JsonApiDotNetCore.Resources;
1010
using JsonApiDotNetCore.Serialization.Objects;
11+
using JsonApiDotNetCoreExample.Controllers;
1112
using JsonApiDotNetCoreExampleTests.Startups;
1213
using Microsoft.AspNetCore.Authentication;
1314
using Microsoft.Extensions.DependencyInjection;
@@ -27,10 +28,11 @@ public AtomicQueryStringTests(ExampleIntegrationTestContext<TestableStartup<Oper
2728
{
2829
_testContext = testContext;
2930

31+
testContext.UseController<OperationsController>();
32+
testContext.UseController<MusicTracksController>();
33+
3034
testContext.ConfigureServicesAfterStartup(services =>
3135
{
32-
services.AddControllersFromExampleProject();
33-
3436
services.AddSingleton<ISystemClock>(new FrozenSystemClock
3537
{
3638
UtcNow = FrozenTime

test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/ResourceDefinitions/AtomicSparseFieldSetResourceDefinitionTests.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using FluentAssertions;
66
using JsonApiDotNetCore.Resources;
77
using JsonApiDotNetCore.Serialization.Objects;
8+
using JsonApiDotNetCoreExample.Controllers;
89
using JsonApiDotNetCoreExampleTests.Startups;
910
using Microsoft.Extensions.DependencyInjection;
1011
using TestBuildingBlocks;
@@ -22,10 +23,10 @@ public AtomicSparseFieldSetResourceDefinitionTests(ExampleIntegrationTestContext
2223
{
2324
_testContext = testContext;
2425

26+
testContext.UseController<OperationsController>();
27+
2528
testContext.ConfigureServicesAfterStartup(services =>
2629
{
27-
services.AddControllersFromExampleProject();
28-
2930
services.AddSingleton<LyricPermissionProvider>();
3031
services.AddScoped<IResourceDefinition<Lyric, long>, LyricTextDefinition>();
3132
services.AddScoped(typeof(IResourceChangeTracker<>), typeof(NeverSameResourceChangeTracker<>));

test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Transactions/AtomicRollbackTests.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Threading.Tasks;
66
using FluentAssertions;
77
using JsonApiDotNetCore.Serialization.Objects;
8+
using JsonApiDotNetCoreExample.Controllers;
89
using JsonApiDotNetCoreExampleTests.Startups;
910
using Microsoft.EntityFrameworkCore;
1011
using TestBuildingBlocks;
@@ -21,7 +22,7 @@ public AtomicRollbackTests(ExampleIntegrationTestContext<TestableStartup<Operati
2122
{
2223
_testContext = testContext;
2324

24-
testContext.ConfigureServicesAfterStartup(services => services.AddControllersFromExampleProject());
25+
testContext.UseController<OperationsController>();
2526
}
2627

2728
[Fact]

test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Transactions/AtomicTransactionConsistencyTests.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using FluentAssertions;
66
using JsonApiDotNetCore.Configuration;
77
using JsonApiDotNetCore.Serialization.Objects;
8+
using JsonApiDotNetCoreExample.Controllers;
89
using JsonApiDotNetCoreExampleTests.Startups;
910
using Microsoft.EntityFrameworkCore;
1011
using Microsoft.Extensions.DependencyInjection;
@@ -22,10 +23,10 @@ public AtomicTransactionConsistencyTests(ExampleIntegrationTestContext<TestableS
2223
{
2324
_testContext = testContext;
2425

26+
testContext.UseController<OperationsController>();
27+
2528
testContext.ConfigureServicesAfterStartup(services =>
2629
{
27-
services.AddControllersFromExampleProject();
28-
2930
services.AddResourceRepository<PerformerRepository>();
3031
services.AddResourceRepository<MusicTrackRepository>();
3132
services.AddResourceRepository<LyricRepository>();

0 commit comments

Comments
 (0)