Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="8.0.11" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Cosmos" Version="8.0.11" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.InMemory" Version="8.0.11" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Proxies" Version="8.0.11" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.11" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.11" />
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="8.0.1" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ internal OperationsQueueManager(OfflineDbContext context)
internal List<EntityEntry> GetChangedEntitiesInScope()
=> ChangeTracker.Entries()
.Where(e => e.State is EntityState.Added or EntityState.Modified or EntityState.Deleted)
.Where(e => this._entityMap.ContainsKey(e.Entity.GetType().FullName.AsNullableEmptyString()))
.Where(e => this._entityMap.ContainsKey(e.Metadata.Name.AsNullableEmptyString()))
.ToList();

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" />
<PackageReference Include="System.Linq.Async" />
</ItemGroup>
<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@ public abstract class BaseTest
/// <summary>
/// Creates a version of the TestDbContext backed by SQLite.
/// </summary>
protected static TestDbContext CreateContext()
protected static TestDbContext CreateContext(Action<DbContextOptionsBuilder<TestDbContext>> configureOptions = null)
{
SqliteConnection connection = new("Data Source=:memory:");
connection.Open();
DbContextOptionsBuilder<TestDbContext> optionsBuilder = new DbContextOptionsBuilder<TestDbContext>()
.UseSqlite(connection);
configureOptions?.Invoke(optionsBuilder);
TestDbContext context = new(optionsBuilder.Options) { Connection = connection };

// Ensure the database is created.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -411,4 +411,76 @@ public void ToOperationKind_Invalid_Throws()
act.Should().Throw<InvalidOperationException>();
}
#endregion

#region LazyLoadingProxies Support
[Fact]
public async Task LLP_PushAsync_Addition_Works()
{
TestDbContext llpContext = CreateContext(x => x.UseLazyLoadingProxies());
ClientMovie clientMovie = new(TestData.Movies.BlackPanther) { Id = Guid.NewGuid().ToString("N") };
string clientMovieJson = DatasyncSerializer.Serialize(clientMovie);
llpContext.Movies.Add(clientMovie);
llpContext.SaveChanges();

ClientMovie responseMovie = new(TestData.Movies.BlackPanther) { Id = clientMovie.Id, UpdatedAt = DateTimeOffset.UtcNow, Version = Guid.NewGuid().ToString() };
string expectedJson = DatasyncSerializer.Serialize(responseMovie);
llpContext.Handler.AddResponseContent(expectedJson, HttpStatusCode.Created);

PushResult results = await llpContext.QueueManager.PushAsync([typeof(ClientMovie)], new PushOptions());
results.IsSuccessful.Should().BeTrue();
results.CompletedOperations.Should().Be(1);
results.FailedRequests.Should().BeEmpty();

llpContext.DatasyncOperationsQueue.Should().BeEmpty();

ClientMovie actualMovie = llpContext.Movies.SingleOrDefault(x => x.Id == clientMovie.Id);
actualMovie.UpdatedAt!.Should().BeCloseTo((DateTimeOffset)responseMovie.UpdatedAt, TimeSpan.FromMicroseconds(1000));
actualMovie.Version.Should().Be(responseMovie.Version);
}

[Fact]
public async Task LLP_PushAsync_Removal_Works()
{
TestDbContext llpContext = CreateContext(x => x.UseLazyLoadingProxies());
ClientMovie clientMovie = new(TestData.Movies.BlackPanther) { Id = Guid.NewGuid().ToString("N") };
llpContext.Movies.Add(clientMovie);
llpContext.SaveChanges(acceptAllChangesOnSuccess: true, addToQueue: false);

llpContext.Movies.Remove(clientMovie);
llpContext.SaveChanges();
llpContext.Handler.AddResponse(HttpStatusCode.NoContent);

PushResult results = await llpContext.QueueManager.PushAsync([typeof(ClientMovie)], new PushOptions());
results.IsSuccessful.Should().BeTrue();
results.CompletedOperations.Should().Be(1);
results.FailedRequests.Should().BeEmpty();

llpContext.DatasyncOperationsQueue.Should().BeEmpty();
llpContext.Movies.Find(clientMovie.Id).Should().BeNull();
}

[Fact]
public async Task LLP_PushAsync_Replacement_Works()
{
TestDbContext llpContext = CreateContext(x => x.UseLazyLoadingProxies());
ClientMovie clientMovie = new(TestData.Movies.BlackPanther) { Id = Guid.NewGuid().ToString("N") };
llpContext.Movies.Add(clientMovie);
llpContext.SaveChanges(acceptAllChangesOnSuccess: true, addToQueue: false);

clientMovie.Title = "Foo";
llpContext.Update(clientMovie);
llpContext.SaveChanges();

ClientMovie responseMovie = new(TestData.Movies.BlackPanther) { Id = clientMovie.Id, UpdatedAt = DateTimeOffset.UtcNow, Version = Guid.NewGuid().ToString() };
string expectedJson = DatasyncSerializer.Serialize(responseMovie);
llpContext.Handler.AddResponseContent(expectedJson, HttpStatusCode.OK);

PushResult results = await llpContext.QueueManager.PushAsync([typeof(ClientMovie)], new PushOptions());
results.IsSuccessful.Should().BeTrue();
results.CompletedOperations.Should().Be(1);
results.FailedRequests.Should().BeEmpty();

llpContext.DatasyncOperationsQueue.Should().BeEmpty();
}
#endregion
}
Loading