Skip to content

Commit bae4a78

Browse files
committed
test transaction rollbacks
1 parent afddbe4 commit bae4a78

File tree

4 files changed

+94
-5
lines changed

4 files changed

+94
-5
lines changed

src/Examples/OperationsExample/Startup.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
using System;
1+
using System;
22
using JsonApiDotNetCore.Extensions;
3-
using JsonApiDotNetCore.Models;
43
using Microsoft.AspNetCore.Builder;
54
using Microsoft.AspNetCore.Hosting;
65
using Microsoft.EntityFrameworkCore;

src/JsonApiDotNetCore/Internal/Generics/GenericProcessorFactory.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using Microsoft.AspNetCore.Http;
12
using System;
23

34
namespace JsonApiDotNetCore.Internal.Generics
@@ -30,9 +31,9 @@ public class GenericProcessorFactory : IGenericProcessorFactory
3031
{
3132
private readonly IServiceProvider _serviceProvider;
3233

33-
public GenericProcessorFactory(IServiceProvider serviceProvider)
34+
public GenericProcessorFactory(IHttpContextAccessor httpContextAccessor)
3435
{
35-
_serviceProvider = serviceProvider;
36+
_serviceProvider = httpContextAccessor.HttpContext.RequestServices;
3637
}
3738

3839
public TInterface GetProcessor<TInterface>(Type openGenericType, Type resourceType)

src/JsonApiDotNetCore/api/.manifest

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@
283283
"JsonApiDotNetCore.Internal.Generics.GenericProcessor`2.SetRelationships(System.Object,JsonApiDotNetCore.Models.RelationshipAttribute,System.Collections.Generic.IEnumerable{System.String})": "JsonApiDotNetCore.Internal.Generics.GenericProcessor-2.yml",
284284
"JsonApiDotNetCore.Internal.Generics.GenericProcessor`2.UpdateRelationshipsAsync(System.Object,JsonApiDotNetCore.Models.RelationshipAttribute,System.Collections.Generic.IEnumerable{System.String})": "JsonApiDotNetCore.Internal.Generics.GenericProcessor-2.yml",
285285
"JsonApiDotNetCore.Internal.Generics.GenericProcessorFactory": "JsonApiDotNetCore.Internal.Generics.GenericProcessorFactory.yml",
286-
"JsonApiDotNetCore.Internal.Generics.GenericProcessorFactory.#ctor(System.IServiceProvider)": "JsonApiDotNetCore.Internal.Generics.GenericProcessorFactory.yml",
286+
"JsonApiDotNetCore.Internal.Generics.GenericProcessorFactory.#ctor(Microsoft.AspNetCore.Http.IHttpContextAccessor)": "JsonApiDotNetCore.Internal.Generics.GenericProcessorFactory.yml",
287287
"JsonApiDotNetCore.Internal.Generics.GenericProcessorFactory.GetProcessor``1(System.Type,System.Type)": "JsonApiDotNetCore.Internal.Generics.GenericProcessorFactory.yml",
288288
"JsonApiDotNetCore.Internal.Generics.GenericProcessorFactory.GetProcessor``1(System.Type,System.Type,System.Type)": "JsonApiDotNetCore.Internal.Generics.GenericProcessorFactory.yml",
289289
"JsonApiDotNetCore.Internal.Generics.IGenericProcessor": "JsonApiDotNetCore.Internal.Generics.IGenericProcessor.yml",
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
using System;
2+
using System.Diagnostics;
3+
using System.Linq;
4+
using System.Net;
5+
using System.Threading;
6+
using System.Threading.Tasks;
7+
using Bogus;
8+
using JsonApiDotNetCore.Internal;
9+
using Microsoft.EntityFrameworkCore;
10+
using OperationsExample.Data;
11+
using OperationsExampleTests.Factories;
12+
using Xunit;
13+
14+
namespace OperationsExampleTests
15+
{
16+
[Collection("WebHostCollection")]
17+
public class TransactionFailureTests
18+
{
19+
private readonly Fixture _fixture;
20+
private readonly Faker _faker = new Faker();
21+
22+
public TransactionFailureTests(Fixture fixture)
23+
{
24+
_fixture = fixture;
25+
}
26+
27+
[Fact]
28+
public async Task Cannot_Create_Author_If_Article_Creation_Fails()
29+
{
30+
// arrange
31+
var context = _fixture.GetService<AppDbContext>();
32+
var author = AuthorFactory.Get();
33+
var article = ArticleFactory.Get();
34+
35+
// do this so that the name is random enough for db validations
36+
author.Name = Guid.NewGuid().ToString("N");
37+
article.Name = Guid.NewGuid().ToString("N");
38+
39+
var content = new
40+
{
41+
operations = new object[] {
42+
new {
43+
op = "add",
44+
data = new {
45+
type = "authors",
46+
attributes = new {
47+
name = author.Name
48+
},
49+
}
50+
},
51+
new {
52+
op = "add",
53+
data = new {
54+
type = "articles",
55+
attributes = new {
56+
name = article.Name
57+
},
58+
// by not including the author, the article creation will fail
59+
// relationships = new {
60+
// author = new {
61+
// data = new {
62+
// type = "authors",
63+
// lid = authorLocalId
64+
// }
65+
// }
66+
// }
67+
}
68+
}
69+
}
70+
};
71+
72+
// act
73+
var (response, data) = await _fixture.PatchAsync<ErrorCollection>("api/bulk", content);
74+
75+
// assert
76+
Assert.NotNull(response);
77+
// for now, it is up to application implementations to perform validation and
78+
// provide the proper HTTP response code
79+
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
80+
Assert.Equal(1, data.Errors.Count);
81+
Assert.Contains("operation[1] (add)", data.Errors[0].Title);
82+
83+
var dbAuthors = await context.Authors.Where(a => a.Name == author.Name).ToListAsync();
84+
var dbArticles = await context.Articles.Where(a => a.Name == article.Name).ToListAsync();
85+
Assert.Empty(dbAuthors);
86+
Assert.Empty(dbArticles);
87+
}
88+
}
89+
}

0 commit comments

Comments
 (0)