Skip to content

Commit

Permalink
Merge branch 'master' into fix/363-dynamic-values
Browse files Browse the repository at this point in the history
  • Loading branch information
Simply007 authored and Ondřej Chrastina committed Apr 11, 2023
2 parents 5d95e7d + 179e5af commit 74bdc8a
Show file tree
Hide file tree
Showing 15 changed files with 401 additions and 18 deletions.
11 changes: 11 additions & 0 deletions Kontent.Ai.Delivery.Abstractions/DeliveryClientExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,5 +76,16 @@ public static Task<IDeliveryLanguageListingResponse> GetLanguagesAsync(this IDel
{
return client.GetLanguagesAsync(parameters);
}

/// <summary>
/// Initializes synchronization of changes in content items based on the specified parameters. After the initialization, you'll get an X-Continuation token in the response.
/// </summary>
/// <param name="client">An instance of the <see cref="IDeliveryClient"/></param>
/// <param name="parameters">A collection of query parameters, for example, for filtering.</param>
/// <returns>The <see cref="IDeliverySyncInitResponse"/> instance that represents the sync init response that contains continuation token needed for further sync execution.</returns>
public static Task<IDeliverySyncInitResponse> PostSyncInitAsync(this IDeliveryClient client, params IQueryParameter[] parameters)
{
return client.PostSyncInitAsync(parameters);
}
}
}
13 changes: 13 additions & 0 deletions Kontent.Ai.Delivery.Abstractions/IDeliveryClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,5 +92,18 @@ public interface IDeliveryClient
/// <param name="parameters">A collection of query parameters, for example, for paging.</param>
/// <returns>The <see cref="IDeliveryLanguageListingResponse"/> instance that represents the languages. If no query parameters are specified, all languages are returned.</returns>
Task<IDeliveryLanguageListingResponse> GetLanguagesAsync(IEnumerable<IQueryParameter> parameters = null);

/// <summary>
/// Initializes synchronization of changes in content items based on the specified parameters. After the initialization, you'll get an X-Continuation token in the response.
/// </summary>
/// <param name="parameters">A collection of query parameters, for example, for filtering.</param>
/// <returns>The <see cref="IDeliverySyncInitResponse"/> instance that represents the sync init response that contains continuation token needed for further sync execution.</returns>
Task<IDeliverySyncInitResponse> PostSyncInitAsync(IEnumerable<IQueryParameter> parameters = null);

/// <summary>
/// Retrieve a list of delta updates to recently changed content items in the specified project. The types of items you get is determined by the X-Continuation token you use.
/// </summary>
/// <returns>The <see cref="IDeliverySyncResponse"/> instance that represents the sync response that contains collection of delta updates and continuation token needed for further sync execution.</returns>
Task<IDeliverySyncResponse> GetSyncAsync(string continuationToken);
}
}
14 changes: 14 additions & 0 deletions Kontent.Ai.Delivery.Abstractions/Sync/IDeliverySyncInitResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System.Collections.Generic;

namespace Kontent.Ai.Delivery.Abstractions;

/// <summary>
/// Represents a response from Kontent.ai Delivery API that contains a continuation token and .
/// </summary>
public interface IDeliverySyncInitResponse : IResponse
{
/// <summary>
/// Gets list of delta update items.
/// </summary>
IList<ISyncItem> SyncItems { get; }
}
14 changes: 14 additions & 0 deletions Kontent.Ai.Delivery.Abstractions/Sync/IDeliverySyncResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System.Collections.Generic;

namespace Kontent.Ai.Delivery.Abstractions;

/// <summary>
/// Represents a response from Kontent.ai Delivery API that contains a taxonomy group.
/// </summary>
public interface IDeliverySyncResponse : IResponse
{
/// <summary>
/// Gets list of delta update items.
/// </summary>
IList<ISyncItem> SyncItems { get; }
}
44 changes: 44 additions & 0 deletions Kontent.Ai.Delivery.Abstractions/Sync/ISyncItem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using System;

namespace Kontent.Ai.Delivery.Abstractions;

/// <summary>
/// Represents a delta update.
/// </summary>
public interface ISyncItem
{
/// <summary>
/// Gets the content item's codename.
/// </summary>
string Codename { get; }

/// <summary>
/// Gets the content item's internal ID.
/// </summary>
Guid Id { get; }

/// <summary>
/// Gets the content item's type codename.
/// </summary>
string Type { get; }

/// <summary>
/// Gets the codename of the language that the content is in.
/// </summary>
string Language { get; }

/// <summary>
/// Gets the content item's collection codename. For projects without collections enabled, the value is default.
/// </summary>
string Collection { get; }

/// <summary>
/// Gets the information whether the content item was modified or deleted since the last synchronization.
/// </summary>
string ChangeType { get; }

/// <summary>
/// Gets the ISO-8601 formatted date and time in UTC of the last change to the content item. The timestamp identifies when the change occurred in Delivery API.
/// </summary>
DateTime Timestamp { get; }
}
16 changes: 16 additions & 0 deletions Kontent.Ai.Delivery.Caching/DeliveryClientCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,22 @@ public async Task<IDeliveryUniversalItemListingResponse> GetUniversalItemsAsync(
() => _deliveryClient.GetUniversalItemsAsync(queryParameters),
response => response.Items.Any(),
CacheHelpers.GetItemsDependencies);
/// Initializes synchronization of changes in content items based on the specified parameters. After the initialization, you'll get an X-Continuation token in the response.
/// </summary>
/// <param name="parameters">A collection of query parameters, for example, for filtering.</param>
/// <returns>The <see cref="IDeliverySyncInitResponse"/> instance that represents the sync init response that contains continuation token needed for further sync execution.</returns>
public Task<IDeliverySyncInitResponse> PostSyncInitAsync(IEnumerable<IQueryParameter> parameters = null)
{
return _deliveryClient.PostSyncInitAsync(parameters);
}

/// <summary>
/// Retrieve a list of delta updates to recently changed content items in the specified project. The types of items you get is determined by the X-Continuation token you use.
/// </summary>
/// <returns>The <see cref="IDeliverySyncResponse"/> instance that represents the sync response that contains collection of delta updates and continuation token needed for further sync execution.</returns>
public Task<IDeliverySyncResponse> GetSyncAsync(string continuationToken)
{
return _deliveryClient.GetSyncAsync(continuationToken);
}
}
}
85 changes: 85 additions & 0 deletions Kontent.Ai.Delivery.Tests/DeliveryClientTests.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web;
using AngleSharp.Html.Parser;
using FakeItEasy;
using Kontent.Ai.Delivery.Abstractions;
Expand All @@ -13,6 +15,7 @@
using Kontent.Ai.Delivery.ContentItems.Elements;
using Kontent.Ai.Delivery.ContentItems.RichText.Blocks;
using Kontent.Ai.Delivery.SharedModels;
using Kontent.Ai.Delivery.Sync;
using Kontent.Ai.Delivery.Tests.Factories;
using Kontent.Ai.Delivery.Tests.Models;
using Kontent.Ai.Delivery.Tests.Models.ContentTypes;
Expand Down Expand Up @@ -1977,6 +1980,88 @@ public async Task RetrieveContentItem_GetLinkedItems_TypeItemsManually()
Assert.Equal("2Ao5b6uqI40", (hostedVideoItem as HostedVideo).VideoId);
}

[Fact]
public async Task SyncApi_PostSyncInitAsync_GetContinuationToken()
{
var mockedResponse = await File.ReadAllTextAsync(Path.Combine(Environment.CurrentDirectory, $"Fixtures{Path.DirectorySeparatorChar}DeliveryClient{Path.DirectorySeparatorChar}sync_init.json"));

_mockHttp
.When($"{_baseUrl}/sync/init")
.Respond(new[] { new KeyValuePair<string, string>("X-Continuation", "token"), }, "application/json", mockedResponse);

var client = InitializeDeliveryClientWithCustomModelProvider(_mockHttp);

var syncInit = await client.PostSyncInitAsync();

Assert.NotNull(syncInit.ApiResponse.ContinuationToken);
Assert.Empty(syncInit.SyncItems);
}

[Fact]
public async Task SyncApi_PostSyncInitAsync_WithParameters_GetContinuationToken()
{
var mockedResponse = await File.ReadAllTextAsync(Path.Combine(Environment.CurrentDirectory, $"Fixtures{Path.DirectorySeparatorChar}DeliveryClient{Path.DirectorySeparatorChar}sync_init.json"));

_mockHttp
.When($"{_baseUrl}/sync/init")
.Respond(new[] { new KeyValuePair<string, string>("X-Continuation", "token"), }, "application/json", mockedResponse);

var client = InitializeDeliveryClientWithCustomModelProvider(_mockHttp);

var syncInit = await client.PostSyncInitAsync(
new LanguageParameter("cs"),
new EqualsFilter("system.type", "article"),
new NotEqualsFilter("system.collection", "default"));

var requestUri = new Uri(syncInit.ApiResponse.RequestUrl);

var requestQuery = HttpUtility.ParseQueryString(requestUri.Query);

Assert.Equal(3, requestQuery.Count);
Assert.Equal("language", requestQuery.Keys[0]);
Assert.Equal("system.type[eq]", requestQuery.Keys[1]);
Assert.Equal("system.collection[neq]", requestQuery.Keys[2]);
Assert.NotNull(syncInit.ApiResponse.ContinuationToken);
Assert.Empty(syncInit.SyncItems);
}

[Fact]
public async Task SyncApi_GetSyncAsync_GetSyncItems()
{
var mockedResponse = await File.ReadAllTextAsync(Path.Combine(Environment.CurrentDirectory, $"Fixtures{Path.DirectorySeparatorChar}DeliveryClient{Path.DirectorySeparatorChar}sync.json"));

var expectedValue = JObject.Parse(mockedResponse).SelectToken("items").ToObject<IList<SyncItem>>();

_mockHttp
.When($"{_baseUrl}/sync")
.WithHeaders("X-Continuation", "token")
.Respond(new[] { new KeyValuePair<string, string>("X-Continuation", "token"), }, "application/json", mockedResponse);

var client = InitializeDeliveryClientWithCustomModelProvider(_mockHttp);

var sync = await client.GetSyncAsync("token");

Assert.NotNull(sync.ApiResponse.ContinuationToken);

Assert.Equal(2, sync.SyncItems.Count);

Assert.Equal(expectedValue[0].Codename, sync.SyncItems[0].Codename);
Assert.Equal(expectedValue[0].Id, sync.SyncItems[0].Id);
Assert.Equal(expectedValue[0].Type, sync.SyncItems[0].Type);
Assert.Equal(expectedValue[0].Language, sync.SyncItems[0].Language);
Assert.Equal(expectedValue[0].Collection, sync.SyncItems[0].Collection);
Assert.Equal(expectedValue[0].ChangeType, sync.SyncItems[0].ChangeType);
Assert.Equal(expectedValue[0].Timestamp, sync.SyncItems[0].Timestamp);

Assert.Equal(expectedValue[1].Codename, sync.SyncItems[1].Codename);
Assert.Equal(expectedValue[1].Id, sync.SyncItems[1].Id);
Assert.Equal(expectedValue[1].Type, sync.SyncItems[1].Type);
Assert.Equal(expectedValue[1].Language, sync.SyncItems[1].Language);
Assert.Equal(expectedValue[1].Collection, sync.SyncItems[1].Collection);
Assert.Equal(expectedValue[1].ChangeType, sync.SyncItems[1].ChangeType);
Assert.Equal(expectedValue[1].Timestamp, sync.SyncItems[1].Timestamp);
}

private DeliveryClient InitializeDeliveryClientWithACustomTypeProvider(MockHttpMessageHandler handler)
{
var customTypeProvider = new CustomTypeProvider();
Expand Down
22 changes: 22 additions & 0 deletions Kontent.Ai.Delivery.Tests/Fixtures/DeliveryClient/sync.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"items": [
{
"codename": "hello_world",
"id": "7adfb82a-1386-4228-bcc2-45073a0355f6",
"type": "article",
"language": "default",
"collection": "default",
"change_type": "changed",
"timestamp": "2022-10-06T08:38:40.0088127Z"
},
{
"codename": "bye__world",
"id": "42a3cfbd-4967-43e7-987b-e1e69c483e26",
"type": "article",
"language": "default",
"collection": "default",
"change_type": "deleted",
"timestamp": "2022-10-06T08:38:47.3613558Z"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"items": []
}
6 changes: 6 additions & 0 deletions Kontent.Ai.Delivery.Tests/Kontent.Ai.Delivery.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,12 @@
<None Update="Fixtures\DeliveryClient\types_accessory.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Fixtures\DeliveryClient\sync.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Fixtures\DeliveryClient\sync_init.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
Loading

0 comments on commit 74bdc8a

Please sign in to comment.