Skip to content

Commit 7662023

Browse files
authored
(#47) integration tests for byte[] versions. (#92)
1 parent 92a2936 commit 7662023

File tree

4 files changed

+154
-2
lines changed

4 files changed

+154
-2
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using CommunityToolkit.Datasync.Server;
6+
using CommunityToolkit.Datasync.TestCommon.Models;
7+
using System.ComponentModel.DataAnnotations;
8+
using System.ComponentModel.DataAnnotations.Schema;
9+
10+
namespace CommunityToolkit.Datasync.Client.Test.Helpers;
11+
12+
[ExcludeFromCodeCoverage]
13+
public class ByteVersionMovie
14+
{
15+
public ByteVersionMovie()
16+
{
17+
}
18+
19+
public ByteVersionMovie(object source)
20+
{
21+
if (source is ITableData metadata)
22+
{
23+
Id = metadata.Id;
24+
Deleted = metadata.Deleted;
25+
UpdatedAt = metadata.UpdatedAt;
26+
Version = [..metadata.Version];
27+
}
28+
29+
if (source is IMovie movie)
30+
{
31+
BestPictureWinner = movie.BestPictureWinner;
32+
Duration = movie.Duration;
33+
Rating = movie.Rating;
34+
ReleaseDate = movie.ReleaseDate;
35+
Title = movie.Title;
36+
Year = movie.Year;
37+
}
38+
}
39+
40+
[Key]
41+
public string Id { get; set; }
42+
43+
[Column(TypeName = "INTEGER")]
44+
public DateTimeOffset? UpdatedAt { get; set; }
45+
public byte[] Version { get; set; }
46+
public bool Deleted { get; set; }
47+
48+
public bool BestPictureWinner { get; set; }
49+
public int Duration { get; set; }
50+
public MovieRating Rating { get; set; } = MovieRating.Unrated;
51+
public DateOnly ReleaseDate { get; set; }
52+
public string Title { get; set; } = string.Empty;
53+
public int Year { get; set; }
54+
}
55+

tests/CommunityToolkit.Datasync.Client.Test/Helpers/IntegrationDbContext.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ public class IntegrationDbContext(DbContextOptions<IntegrationDbContext> options
1414
{
1515
public DbSet<ClientMovie> Movies => Set<ClientMovie>();
1616

17+
public DbSet<ByteVersionMovie> ByteMovies => Set<ByteVersionMovie>();
18+
1719
public ServiceApplicationFactory Factory { get; set; }
1820

1921
public SqliteConnection Connection { get; set; }
@@ -28,6 +30,12 @@ protected override void OnDatasyncInitialization(DatasyncOfflineOptionsBuilder o
2830
cfg.ClientName = "movies";
2931
cfg.Endpoint = new Uri($"/{Factory.MovieEndpoint}", UriKind.Relative);
3032
});
33+
34+
optionsBuilder.Entity<ByteVersionMovie>(cfg =>
35+
{
36+
cfg.ClientName = "movies";
37+
cfg.Endpoint = new Uri($"/{Factory.MovieEndpoint}", UriKind.Relative);
38+
});
3139
}
3240

3341
protected override void Dispose(bool disposing)

tests/CommunityToolkit.Datasync.Client.Test/Offline/Integration_Pull_Tests.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,22 @@ public async Task PullAsync_ViaDbSet_Works()
5757
}
5858
}
5959

60+
[Fact]
61+
public async Task PullAsync_ViaDbSet_Works_ByteVersion()
62+
{
63+
await this.context.ByteMovies.PullAsync();
64+
List<ByteVersionMovie> movies = await this.context.ByteMovies.ToListAsync();
65+
66+
movies.Count.Should().Be(248);
67+
foreach (ByteVersionMovie movie in movies)
68+
{
69+
InMemoryMovie serviceMovie = GetServerEntityById<InMemoryMovie>(movie.Id);
70+
serviceMovie.Should().NotBeNull()
71+
.And.BeEquivalentTo<IMovie>(serviceMovie)
72+
.And.HaveEquivalentMetadataTo(serviceMovie);
73+
}
74+
}
75+
6076
[Fact]
6177
public async Task PullAsync_ViaContext_Works()
6278
{

tests/CommunityToolkit.Datasync.Client.Test/Offline/Integration_Push_Tests.cs

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,14 +104,87 @@ public async Task PushAsync_Complex_Situation()
104104
this.context.DatasyncOperationsQueue.Should().BeEmpty();
105105

106106
// Now use PullAsync() again - these should all be pulled down again
107-
PullResult pullResults = await this.context.PullAsync();
107+
PullResult pullResults = await this.context.Movies.PullAsync();
108108
pullResults.IsSuccessful.Should().BeTrue();
109109
pullResults.Additions.Should().Be(0);
110110
pullResults.Deletions.Should().Be(0);
111111
// The service always replaces additions and replacements - updating the last updatedAt.
112112
pullResults.Replacements.Should().Be(moviesToReplace.Count + 1);
113113
}
114114

115+
[Fact]
116+
public async Task PushAsync_ByteVersion()
117+
{
118+
ResetInMemoryMovies();
119+
120+
PullResult initialPullResults = await this.context.ByteMovies.PullAsync();
121+
initialPullResults.IsSuccessful.Should().BeTrue();
122+
initialPullResults.Additions.Should().Be(248);
123+
initialPullResults.Deletions.Should().Be(0);
124+
initialPullResults.Replacements.Should().Be(0);
125+
this.context.ByteMovies.Should().HaveCount(248);
126+
127+
// Let's add some new movies
128+
ByteVersionMovie blackPanther = new(TestCommon.TestData.Movies.BlackPanther) { Id = Guid.NewGuid().ToString("N") };
129+
this.context.ByteMovies.Add(blackPanther);
130+
await this.context.SaveChangesAsync();
131+
132+
// And remove any movie that matches some criteria
133+
List<ByteVersionMovie> moviesToDelete = await this.context.ByteMovies.Where(x => x.Duration > 180).ToListAsync();
134+
this.context.ByteMovies.RemoveRange(moviesToDelete);
135+
await this.context.SaveChangesAsync();
136+
137+
// Then replace all the Unrated movies with a rating of NC17
138+
List<ByteVersionMovie> moviesToReplace = await this.context.ByteMovies.Where(x => x.Rating == MovieRating.Unrated).ToListAsync();
139+
moviesToReplace.ForEach(r =>
140+
{
141+
r.Rating = MovieRating.NC17;
142+
r.Title = r.Title.PadLeft('-');
143+
this.context.ByteMovies.Update(r);
144+
});
145+
await this.context.SaveChangesAsync();
146+
147+
// Check the queue.
148+
List<DatasyncOperation> operations = await this.context.DatasyncOperationsQueue.ToListAsync();
149+
operations.Count.Should().Be(1 + moviesToDelete.Count + moviesToReplace.Count);
150+
operations.Count(x => x.Kind is OperationKind.Add).Should().Be(1);
151+
operations.Count(x => x.Kind is OperationKind.Delete).Should().Be(moviesToDelete.Count);
152+
operations.Count(x => x.Kind is OperationKind.Replace).Should().Be(moviesToReplace.Count);
153+
154+
// Now push the results and check what we did
155+
PushResult pushResults = await this.context.PushAsync();
156+
157+
// This little snippet of code is to aid debugging if this test fails
158+
if (!pushResults.IsSuccessful)
159+
{
160+
foreach (KeyValuePair<string, ServiceResponse> failedRequest in pushResults.FailedRequests)
161+
{
162+
string id = failedRequest.Key;
163+
ServiceResponse response = failedRequest.Value;
164+
string jsonContent = string.Empty;
165+
if (response.HasContent)
166+
{
167+
using StreamReader reader = new(response.ContentStream);
168+
jsonContent = reader.ReadToEnd();
169+
}
170+
171+
Console.WriteLine($"FAILED REQUEST FOR ID: {id}: {response.StatusCode}\n{jsonContent}");
172+
}
173+
}
174+
175+
pushResults.IsSuccessful.Should().BeTrue();
176+
pushResults.CompletedOperations.Should().Be(1 + moviesToDelete.Count + moviesToReplace.Count);
177+
this.context.DatasyncOperationsQueue.Should().BeEmpty();
178+
179+
// Now use PullAsync() again - these should all be pulled down again
180+
PullResult pullResults = await this.context.ByteMovies.PullAsync();
181+
pullResults.IsSuccessful.Should().BeTrue();
182+
pullResults.Additions.Should().Be(0);
183+
pullResults.Deletions.Should().Be(0);
184+
// The service always replaces additions and replacements - updating the last updatedAt.
185+
pullResults.Replacements.Should().Be(moviesToReplace.Count + 1);
186+
}
187+
115188
[Fact]
116189
public async Task PushAsync_Multithreaded()
117190
{
@@ -176,7 +249,7 @@ public async Task PushAsync_Multithreaded()
176249
this.context.DatasyncOperationsQueue.Should().BeEmpty();
177250

178251
// Now use PullAsync() again - these should all be pulled down again
179-
PullResult pullResults = await this.context.PullAsync();
252+
PullResult pullResults = await this.context.Movies.PullAsync();
180253
pullResults.IsSuccessful.Should().BeTrue();
181254
pullResults.Additions.Should().Be(0);
182255
pullResults.Deletions.Should().Be(0);

0 commit comments

Comments
 (0)