Skip to content

Commit 0aafb84

Browse files
author
Bart Koelman
committed
Fixes in handling add-to and remove-from to-many relationships
1 parent e0f6482 commit 0aafb84

File tree

3 files changed

+74
-48
lines changed

3 files changed

+74
-48
lines changed

src/JsonApiDotNetCore/AtomicOperations/AtomicOperationsProcessor.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,7 @@ public async Task<IList<AtomicResultObject>> ProcessAsync(IList<AtomicOperationO
5757
{
5858
foreach (var operation in operations)
5959
{
60-
// TODO: @OPS: Do we need to keep this in?
61-
// _dbContext.ResetChangeTracker();
60+
_dbContext.ResetChangeTracker();
6261

6362
var result = await ProcessOperation(operation, cancellationToken);
6463
results.Add(result);

src/JsonApiDotNetCore/Repositories/DbContextExtensions.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,16 +49,14 @@ public static object GetTrackedIdentifiable(this DbContext dbContext, IIdentifia
4949
return entityEntry?.Entity;
5050
}
5151

52-
// TODO: @OPS: Should we keep this?
5352
/// <summary>
5453
/// Detaches all entities from the change tracker.
5554
/// </summary>
5655
public static void ResetChangeTracker(this DbContext dbContext)
5756
{
5857
if (dbContext == null) throw new ArgumentNullException(nameof(dbContext));
5958

60-
List<EntityEntry> entriesWithChanges = dbContext.ChangeTracker.Entries().Where(entry =>
61-
entry.State != EntityState.Detached).ToList();
59+
List<EntityEntry> entriesWithChanges = dbContext.ChangeTracker.Entries().ToList();
6260

6361
foreach (EntityEntry entry in entriesWithChanges)
6462
{

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

Lines changed: 72 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1294,7 +1294,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext =>
12941294
public async Task Can_add_to_ManyToMany_relationship_using_local_ID()
12951295
{
12961296
// Arrange
1297-
var existingTrack = _fakers.MusicTrack.Generate();
1297+
var existingTracks = _fakers.MusicTrack.Generate(2);
12981298

12991299
var newPlaylistName = _fakers.Playlist.Generate().Name;
13001300
var newTrackTitle = _fakers.MusicTrack.Generate().Title;
@@ -1304,7 +1304,7 @@ public async Task Can_add_to_ManyToMany_relationship_using_local_ID()
13041304

13051305
await _testContext.RunOnDatabaseAsync(async dbContext =>
13061306
{
1307-
dbContext.MusicTracks.Add(existingTrack);
1307+
dbContext.MusicTracks.AddRange(existingTracks);
13081308
await dbContext.SaveChangesAsync();
13091309
});
13101310

@@ -1332,7 +1332,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext =>
13321332
new
13331333
{
13341334
type = "musicTracks",
1335-
id = existingTrack.StringId
1335+
id = existingTracks[0].StringId
13361336
}
13371337
}
13381338
}
@@ -1369,6 +1369,24 @@ await _testContext.RunOnDatabaseAsync(async dbContext =>
13691369
lid = trackLocalId
13701370
}
13711371
}
1372+
},
1373+
new
1374+
{
1375+
op = "add",
1376+
@ref = new
1377+
{
1378+
type = "playlists",
1379+
lid = playlistLocalId,
1380+
relationship = "tracks"
1381+
},
1382+
data = new[]
1383+
{
1384+
new
1385+
{
1386+
type = "musicTracks",
1387+
id = existingTracks[1].StringId
1388+
}
1389+
}
13721390
}
13731391
}
13741392
};
@@ -1381,7 +1399,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext =>
13811399
// Assert
13821400
httpResponse.Should().HaveStatusCode(HttpStatusCode.OK);
13831401

1384-
responseDocument.Results.Should().HaveCount(3);
1402+
responseDocument.Results.Should().HaveCount(4);
13851403

13861404
responseDocument.Results[0].SingleData.Should().NotBeNull();
13871405
responseDocument.Results[0].SingleData.Type.Should().Be("playlists");
@@ -1395,6 +1413,8 @@ await _testContext.RunOnDatabaseAsync(async dbContext =>
13951413

13961414
responseDocument.Results[2].Data.Should().BeNull();
13971415

1416+
responseDocument.Results[3].Data.Should().BeNull();
1417+
13981418
var newPlaylistId = long.Parse(responseDocument.Results[0].SingleData.Id);
13991419
var newTrackId = Guid.Parse(responseDocument.Results[1].SingleData.Id);
14001420

@@ -1407,8 +1427,9 @@ await _testContext.RunOnDatabaseAsync(async dbContext =>
14071427

14081428
playlistInDatabase.Name.Should().Be(newPlaylistName);
14091429

1410-
playlistInDatabase.PlaylistMusicTracks.Should().HaveCount(2);
1411-
playlistInDatabase.PlaylistMusicTracks.Should().ContainSingle(playlistMusicTrack => playlistMusicTrack.MusicTrack.Id == existingTrack.Id);
1430+
playlistInDatabase.PlaylistMusicTracks.Should().HaveCount(3);
1431+
playlistInDatabase.PlaylistMusicTracks.Should().ContainSingle(playlistMusicTrack => playlistMusicTrack.MusicTrack.Id == existingTracks[0].Id);
1432+
playlistInDatabase.PlaylistMusicTracks.Should().ContainSingle(playlistMusicTrack => playlistMusicTrack.MusicTrack.Id == existingTracks[1].Id);
14121433
playlistInDatabase.PlaylistMusicTracks.Should().ContainSingle(playlistMusicTrack => playlistMusicTrack.MusicTrack.Id == newTrackId);
14131434
});
14141435
}
@@ -1543,17 +1564,26 @@ await _testContext.RunOnDatabaseAsync(async dbContext =>
15431564
public async Task Can_remove_from_ManyToMany_relationship_using_local_ID()
15441565
{
15451566
// Arrange
1546-
var existingTrack = _fakers.MusicTrack.Generate();
1567+
var existingPlaylist = _fakers.Playlist.Generate();
1568+
existingPlaylist.PlaylistMusicTracks = new[]
1569+
{
1570+
new PlaylistMusicTrack
1571+
{
1572+
MusicTrack = _fakers.MusicTrack.Generate()
1573+
},
1574+
new PlaylistMusicTrack
1575+
{
1576+
MusicTrack = _fakers.MusicTrack.Generate()
1577+
}
1578+
};
15471579

1548-
var newPlaylistName = _fakers.Playlist.Generate().Name;
15491580
var newTrackTitle = _fakers.MusicTrack.Generate().Title;
15501581

1551-
const string playlistLocalId = "playlist-1";
15521582
const string trackLocalId = "track-1";
15531583

15541584
await _testContext.RunOnDatabaseAsync(async dbContext =>
15551585
{
1556-
dbContext.MusicTracks.Add(existingTrack);
1586+
dbContext.Playlists.Add(existingPlaylist);
15571587
await dbContext.SaveChangesAsync();
15581588
});
15591589

@@ -1577,32 +1607,36 @@ await _testContext.RunOnDatabaseAsync(async dbContext =>
15771607
new
15781608
{
15791609
op = "add",
1580-
data = new
1610+
@ref = new
15811611
{
15821612
type = "playlists",
1583-
lid = playlistLocalId,
1584-
attributes = new
1613+
id = existingPlaylist.StringId,
1614+
relationship = "tracks"
1615+
},
1616+
data = new[]
1617+
{
1618+
new
15851619
{
1586-
name = newPlaylistName
1587-
},
1588-
relationships = new
1620+
type = "musicTracks",
1621+
lid = trackLocalId
1622+
}
1623+
}
1624+
},
1625+
new
1626+
{
1627+
op = "remove",
1628+
@ref = new
1629+
{
1630+
type = "playlists",
1631+
id = existingPlaylist.StringId,
1632+
relationship = "tracks"
1633+
},
1634+
data = new[]
1635+
{
1636+
new
15891637
{
1590-
tracks = new
1591-
{
1592-
data = new object[]
1593-
{
1594-
new
1595-
{
1596-
type = "musicTracks",
1597-
id = existingTrack.StringId
1598-
},
1599-
new
1600-
{
1601-
type = "musicTracks",
1602-
lid = trackLocalId
1603-
}
1604-
}
1605-
}
1638+
type = "musicTracks",
1639+
id = existingPlaylist.PlaylistMusicTracks[1].MusicTrack.StringId
16061640
}
16071641
}
16081642
},
@@ -1612,7 +1646,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext =>
16121646
@ref = new
16131647
{
16141648
type = "playlists",
1615-
lid = playlistLocalId,
1649+
id = existingPlaylist.StringId,
16161650
relationship = "tracks"
16171651
},
16181652
data = new[]
@@ -1635,33 +1669,28 @@ await _testContext.RunOnDatabaseAsync(async dbContext =>
16351669
// Assert
16361670
httpResponse.Should().HaveStatusCode(HttpStatusCode.OK);
16371671

1638-
responseDocument.Results.Should().HaveCount(3);
1672+
responseDocument.Results.Should().HaveCount(4);
16391673

16401674
responseDocument.Results[0].SingleData.Should().NotBeNull();
16411675
responseDocument.Results[0].SingleData.Type.Should().Be("musicTracks");
16421676
responseDocument.Results[0].SingleData.Lid.Should().BeNull();
16431677
responseDocument.Results[0].SingleData.Attributes["title"].Should().Be(newTrackTitle);
16441678

1645-
responseDocument.Results[1].SingleData.Should().NotBeNull();
1646-
responseDocument.Results[1].SingleData.Type.Should().Be("playlists");
1647-
responseDocument.Results[1].SingleData.Lid.Should().BeNull();
1648-
responseDocument.Results[1].SingleData.Attributes["name"].Should().Be(newPlaylistName);
1679+
responseDocument.Results[1].Data.Should().BeNull();
16491680

16501681
responseDocument.Results[2].Data.Should().BeNull();
16511682

1652-
var newPlaylistId = long.Parse(responseDocument.Results[1].SingleData.Id);
1683+
responseDocument.Results[3].Data.Should().BeNull();
16531684

16541685
await _testContext.RunOnDatabaseAsync(async dbContext =>
16551686
{
16561687
var playlistInDatabase = await dbContext.Playlists
16571688
.Include(playlist => playlist.PlaylistMusicTracks)
16581689
.ThenInclude(playlistMusicTrack => playlistMusicTrack.MusicTrack)
1659-
.FirstAsync(playlist => playlist.Id == newPlaylistId);
1660-
1661-
playlistInDatabase.Name.Should().Be(newPlaylistName);
1690+
.FirstAsync(playlist => playlist.Id == existingPlaylist.Id);
16621691

16631692
playlistInDatabase.PlaylistMusicTracks.Should().HaveCount(1);
1664-
playlistInDatabase.PlaylistMusicTracks[0].MusicTrack.Id.Should().Be(existingTrack.Id);
1693+
playlistInDatabase.PlaylistMusicTracks[0].MusicTrack.Id.Should().Be(existingPlaylist.PlaylistMusicTracks[0].MusicTrack.Id);
16651694
});
16661695
}
16671696

0 commit comments

Comments
 (0)