Skip to content

Commit 8a4a05d

Browse files
author
Bart Koelman
committed
Fixed: throw at startup when multiple controllers are registered for the same resource type
1 parent b8e4f38 commit 8a4a05d

File tree

8 files changed

+88
-6
lines changed

8 files changed

+88
-6
lines changed

src/JsonApiDotNetCore/Middleware/JsonApiRoutingConvention.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,11 @@ public void Apply(ApplicationModel application)
8181

8282
if (resourceType != null)
8383
{
84+
if (_controllerPerResourceTypeMap.ContainsKey(resourceType))
85+
{
86+
throw new InvalidConfigurationException($"Multiple controllers found for resource type '{resourceType}'.");
87+
}
88+
8489
_resourceTypePerControllerTypeMap.Add(controller.ControllerType, resourceType);
8590
_controllerPerResourceTypeMap.Add(resourceType, controller);
8691
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using JsonApiDotNetCore.Configuration;
2+
using JsonApiDotNetCore.Controllers;
3+
using JsonApiDotNetCore.Services;
4+
using Microsoft.Extensions.Logging;
5+
6+
namespace JsonApiDotNetCoreTests.IntegrationTests.NonJsonApiControllers
7+
{
8+
public sealed class DuplicateKnownResourcesController : JsonApiController<KnownResource, int>
9+
{
10+
public DuplicateKnownResourcesController(IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory,
11+
IResourceService<KnownResource, int> resourceService)
12+
: base(options, resourceGraph, loggerFactory, resourceService)
13+
{
14+
}
15+
}
16+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using System;
2+
using FluentAssertions;
3+
using JsonApiDotNetCore.Errors;
4+
using TestBuildingBlocks;
5+
using Xunit;
6+
7+
namespace JsonApiDotNetCoreTests.IntegrationTests.NonJsonApiControllers
8+
{
9+
public sealed class DuplicateResourceControllerTests : IntegrationTestContext<TestableStartup<KnownDbContext>, KnownDbContext>
10+
{
11+
public DuplicateResourceControllerTests()
12+
{
13+
UseController<KnownResourcesController>();
14+
UseController<DuplicateKnownResourcesController>();
15+
}
16+
17+
[Fact]
18+
public void Fails_at_startup_when_multiple_controllers_exist_for_same_resource_type()
19+
{
20+
// Act
21+
Action action = () => _ = Factory;
22+
23+
// Assert
24+
action.Should().ThrowExactly<InvalidConfigurationException>().WithMessage("Multiple controllers found for resource type 'knownResources'.");
25+
}
26+
27+
public override void Dispose()
28+
{
29+
// Prevents crash when test cleanup tries to access lazily constructed Factory.
30+
}
31+
}
32+
}

test/JsonApiDotNetCoreTests/IntegrationTests/NonJsonApiControllers/NonJsonApiDbContext.cs renamed to test/JsonApiDotNetCoreTests/IntegrationTests/NonJsonApiControllers/EmptyDbContext.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
namespace JsonApiDotNetCoreTests.IntegrationTests.NonJsonApiControllers
55
{
66
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
7-
public sealed class NonJsonApiDbContext : DbContext
7+
public sealed class EmptyDbContext : DbContext
88
{
9-
public NonJsonApiDbContext(DbContextOptions<NonJsonApiDbContext> options)
9+
public EmptyDbContext(DbContextOptions<EmptyDbContext> options)
1010
: base(options)
1111
{
1212
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using JetBrains.Annotations;
2+
using Microsoft.EntityFrameworkCore;
3+
4+
namespace JsonApiDotNetCoreTests.IntegrationTests.NonJsonApiControllers
5+
{
6+
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
7+
public sealed class KnownDbContext : DbContext
8+
{
9+
public DbSet<KnownResource> KnownResources => Set<KnownResource>();
10+
11+
public KnownDbContext(DbContextOptions<KnownDbContext> options)
12+
: base(options)
13+
{
14+
}
15+
}
16+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using JetBrains.Annotations;
2+
using JsonApiDotNetCore.Resources;
3+
using JsonApiDotNetCore.Resources.Annotations;
4+
5+
namespace JsonApiDotNetCoreTests.IntegrationTests.NonJsonApiControllers
6+
{
7+
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
8+
[Resource(ControllerNamespace = "JsonApiDotNetCoreTests.IntegrationTests.NonJsonApiControllers")]
9+
public sealed class KnownResource : Identifiable<int>
10+
{
11+
public string? Value { get; set; }
12+
}
13+
}

test/JsonApiDotNetCoreTests/IntegrationTests/NonJsonApiControllers/NonJsonApiControllerTests.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@
88

99
namespace JsonApiDotNetCoreTests.IntegrationTests.NonJsonApiControllers
1010
{
11-
public sealed class NonJsonApiControllerTests : IClassFixture<IntegrationTestContext<TestableStartup<NonJsonApiDbContext>, NonJsonApiDbContext>>
11+
public sealed class NonJsonApiControllerTests : IClassFixture<IntegrationTestContext<TestableStartup<EmptyDbContext>, EmptyDbContext>>
1212
{
13-
private readonly IntegrationTestContext<TestableStartup<NonJsonApiDbContext>, NonJsonApiDbContext> _testContext;
13+
private readonly IntegrationTestContext<TestableStartup<EmptyDbContext>, EmptyDbContext> _testContext;
1414

15-
public NonJsonApiControllerTests(IntegrationTestContext<TestableStartup<NonJsonApiDbContext>, NonJsonApiDbContext> testContext)
15+
public NonJsonApiControllerTests(IntegrationTestContext<TestableStartup<EmptyDbContext>, EmptyDbContext> testContext)
1616
{
1717
_testContext = testContext;
1818

test/JsonApiDotNetCoreTests/IntegrationTests/NonJsonApiControllers/UnknownResourceControllerTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
namespace JsonApiDotNetCoreTests.IntegrationTests.NonJsonApiControllers
88
{
9-
public sealed class UnknownResourceControllerTests : IntegrationTestContext<TestableStartup<NonJsonApiDbContext>, NonJsonApiDbContext>
9+
public sealed class UnknownResourceControllerTests : IntegrationTestContext<TestableStartup<EmptyDbContext>, EmptyDbContext>
1010
{
1111
public UnknownResourceControllerTests()
1212
{

0 commit comments

Comments
 (0)