Skip to content
This repository has been archived by the owner on Aug 2, 2024. It is now read-only.

Commit

Permalink
(#627) Added tests for PurgeItemsAsync and updates to solve issues. (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
adrianhall authored Feb 24, 2023
1 parent 8d6f990 commit e1af9be
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ public async Task DeleteOperationsAsync(QueryDescription query, CancellationToke
throw new InvalidOperationException("To delete an operation in the operations queue by query, ensure the operations queue is the target.");
}
await OfflineStore.DeleteAsync(query, cancellationToken).ConfigureAwait(false);
await UpdatePendingOperationsAsync(cancellationToken).ConfigureAwait(false);
}
}

Expand Down Expand Up @@ -236,10 +237,23 @@ public async Task InitializeAsync(CancellationToken cancellationToken = default)
pendingOperations = page.Count ?? 0;
sequenceId = page.Items?.Select(v => v.Value<long>("sequence")).FirstOrDefault() ?? 0;


IsInitialized = true;
}
}

/// <summary>
/// Updates the pendingOperations field securely.
/// </summary>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> to observe.</param>
/// <returns>A task that completes when the operation is complete.</returns>
private async Task UpdatePendingOperationsAsync(CancellationToken cancellationToken = default)
{
var query = new QueryDescription(SystemTables.OperationsQueue) { IncludeTotalCount = true, Top = 1 };
Page<JObject> page = await OfflineStore.GetPageAsync(query, cancellationToken).ConfigureAwait(false);
Interlocked.Exchange(ref pendingOperations, page.Count ?? 0);
}

/// <summary>
/// Peeks inside the operations queue for the next operation (after the given sequence ID)targeting the set of tables
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,18 @@ internal static string GetTableMemberName(Expression expression, DatasyncContrac
Arguments.IsNotNull(expression, nameof(expression));
Arguments.IsNotNull(contractResolver, nameof(contractResolver));

if (expression is MemberExpression member && member.Expression.NodeType == ExpressionType.Parameter)
if (expression is MemberExpression member)
{
JsonProperty property = contractResolver.ResolveProperty(member.Member);
return property.PropertyName;
if (member.Expression.NodeType == ExpressionType.Parameter)
{
JsonProperty property = contractResolver.ResolveProperty(member.Member);
return property.PropertyName;
}
if (member.Expression.NodeType == ExpressionType.Convert && member.Member.MemberType == MemberTypes.Property)
{
JsonProperty property = contractResolver.ResolveProperty(member.Member);
return property.PropertyName;
}
}
return null;
}
Expand Down
8 changes: 7 additions & 1 deletion sdk/dotnet/test/Datasync.Common.Test/Models/ClientMovie.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,14 @@

namespace Datasync.Common.Test.Models
{
public interface ISystemData
{
string Id { get; set; }
bool Deleted { get; set; }
}

[ExcludeFromCodeCoverage(Justification = "Test suite")]
public class ClientMovie : DatasyncClientData, IMovie, IEquatable<IMovie>
public class ClientMovie : DatasyncClientData, ISystemData, IMovie, IEquatable<IMovie>
{
/// <summary>
/// True if the movie won the oscar for Best Picture
Expand Down
21 changes: 21 additions & 0 deletions sdk/dotnet/test/Microsoft.Datasync.Client.Test/Helpers/Models.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,25 @@ public class BadEntityIntId
{
public int Id { get; set; }
}

public interface IDatasyncEntity
{
string Id { get; set; }
bool Deleted { get; set; }
DateTimeOffset? UpdatedAt { get; set; }
string Version { get; set; }
}

public class TestDatasyncEntity : IDatasyncEntity
{
public string Id { get; set; }
public bool Deleted { get; set; }
public DateTimeOffset? UpdatedAt { get; set; }
public string Version { get; set; }
}

public class DerivedTestDatasyncEntity : TestDatasyncEntity
{
public string StringValue { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
using Moq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NuGet.Frameworks;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
Expand Down Expand Up @@ -880,6 +879,7 @@ public async Task PurgeItems_Discard_NoRecords()
Assert.Empty(store.TableMap[SystemTables.OperationsQueue]);
Assert.Empty(store.TableMap[SystemTables.Configuration]);
Assert.Empty(store.TableMap[tableName]);
Assert.Equal(0, context.PendingOperations);
}

[Fact]
Expand All @@ -896,6 +896,7 @@ public async Task PurgeItems_Discard_QID_NoRecords()
Assert.Empty(store.TableMap[SystemTables.OperationsQueue]);
Assert.Empty(store.TableMap[SystemTables.Configuration]);
Assert.Empty(store.TableMap[tableName]);
Assert.Equal(0, context.PendingOperations);
}

[Fact]
Expand All @@ -912,6 +913,7 @@ public async Task PurgeItems_NoDiscard_NoRecords()
Assert.Empty(store.TableMap[SystemTables.OperationsQueue]);
Assert.Empty(store.TableMap[SystemTables.Configuration]);
Assert.Empty(store.TableMap[tableName]);
Assert.Equal(0, context.PendingOperations);
}

[Fact]
Expand All @@ -928,6 +930,7 @@ public async Task PurgeItems_NoDiscard_QID_NoRecords()
Assert.Empty(store.TableMap[SystemTables.OperationsQueue]);
Assert.Empty(store.TableMap[SystemTables.Configuration]);
Assert.Empty(store.TableMap[tableName]);
Assert.Equal(0, context.PendingOperations);
}

[Fact]
Expand All @@ -942,11 +945,14 @@ public async Task PurgeItems_NoOptions_WithRecords()
const string query = "";
var options = new PurgeOptions();

Assert.Equal(store.TableMap[SystemTables.OperationsQueue].Count, context.PendingOperations);

await Assert.ThrowsAsync<InvalidOperationException>(() => context.PurgeItemsAsync(tableName, query, options));

Assert.NotEmpty(store.TableMap["test"]);
Assert.NotEmpty(store.TableMap[SystemTables.OperationsQueue]);
Assert.NotEmpty(store.TableMap[SystemTables.Configuration]["dt.test.abc123"]);
Assert.Equal(store.TableMap[SystemTables.OperationsQueue].Count, context.PendingOperations);
}

[Fact]
Expand All @@ -961,11 +967,14 @@ public async Task PurgeItems_Discard_WithRecords()
const string query = "";
var options = new PurgeOptions() { DiscardPendingOperations = true };

Assert.Equal(store.TableMap[SystemTables.OperationsQueue].Count, context.PendingOperations);

await context.PurgeItemsAsync(tableName, query, options);

Assert.Empty(store.TableMap[SystemTables.OperationsQueue]);
Assert.NotEmpty(store.TableMap[SystemTables.Configuration]["dt.test.abc123"]);
Assert.Empty(store.TableMap[tableName]);
Assert.Equal(0, context.PendingOperations);
}

[Fact]
Expand All @@ -980,11 +989,14 @@ public async Task PurgeItems_Discard_QID_WithRecords()
const string query = "";
var options = new PurgeOptions() { DiscardPendingOperations = true, QueryId = "abc123" };

Assert.Equal(store.TableMap[SystemTables.OperationsQueue].Count, context.PendingOperations);

await context.PurgeItemsAsync(tableName, query, options);

Assert.Empty(store.TableMap[SystemTables.OperationsQueue]);
Assert.Empty(store.TableMap[SystemTables.Configuration]);
Assert.Empty(store.TableMap[tableName]);
Assert.Equal(0, context.PendingOperations);
}

[Fact]
Expand All @@ -999,11 +1011,14 @@ public async Task PurgeItems_NoDiscard_WithRecords()
const string query = "";
var options = new PurgeOptions() { DiscardPendingOperations = false };

Assert.Equal(store.TableMap[SystemTables.OperationsQueue].Count, context.PendingOperations);

await Assert.ThrowsAsync<InvalidOperationException>(() => context.PurgeItemsAsync(tableName, query, options));

Assert.NotEmpty(store.TableMap["test"]);
Assert.NotEmpty(store.TableMap[SystemTables.OperationsQueue]);
Assert.NotEmpty(store.TableMap[SystemTables.Configuration]["dt.test.abc123"]);
Assert.Equal(store.TableMap[SystemTables.OperationsQueue].Count, context.PendingOperations);
}

[Fact]
Expand All @@ -1018,11 +1033,34 @@ public async Task PurgeItems_NoDiscard_QID_WithRecords()
const string query = "";
var options = new PurgeOptions() { DiscardPendingOperations = false, QueryId = "abc123" };

Assert.Equal(store.TableMap[SystemTables.OperationsQueue].Count, context.PendingOperations);

await Assert.ThrowsAsync<InvalidOperationException>(() => context.PurgeItemsAsync(tableName, query, options));

Assert.NotEmpty(store.TableMap["test"]);
Assert.NotEmpty(store.TableMap[SystemTables.OperationsQueue]);
Assert.NotEmpty(store.TableMap[SystemTables.Configuration]["dt.test.abc123"]);
Assert.Equal(store.TableMap[SystemTables.OperationsQueue].Count, context.PendingOperations);
}

[Fact]
[Trait("Method", "PurgeItemsAsync")]
public async Task PurgeItems_WithSearch_WithRecords()
{
AddRandomOperations("test", 10);
AddRandomRecords("test", 10);
SetDeltaToken("test", "abc123");
var context = await GetSyncContext();
const string tableName = "test";
const string query = "deleted eq false";
var options = new PurgeOptions() { DiscardPendingOperations = true };

await context.PurgeItemsAsync(tableName, query, options);

Assert.Empty(store.TableMap[SystemTables.OperationsQueue]);
Assert.NotEmpty(store.TableMap[SystemTables.Configuration]);
Assert.Empty(store.TableMap[tableName]);
Assert.Equal(0, context.PendingOperations);
}
#endregion

Expand Down
14 changes: 14 additions & 0 deletions sdk/dotnet/test/Microsoft.Datasync.Client.Test/Query/Linq.Test.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,20 @@ public Linq_Tests()
_query = new TableQuery<KitchenSink>(_table);
}

[Fact]
public void Linq_DerivedTest()
{
var client = GetMockClient();
var table = client.GetRemoteTable<DerivedTestDatasyncEntity>("derived");
var queryString = GetDerivedQuery(table);
Assert.Equal("$filter=deleted", queryString);
}

public static string GetDerivedQuery<T>(IRemoteTable<T> table) where T : IDatasyncEntity
{
return table.Where(x => x.Deleted).ToODataString();
}

[Fact]
public void Linq_EndsWith_NoStringComparison()
{
Expand Down

0 comments on commit e1af9be

Please sign in to comment.