Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,53 @@ public async Task DeleteContentAsync_ThrowsNotImplementedException()
mockRestClient.VerifyAll();
}

[TestMethod]
public async Task DeleteContentItemsAsync_WhenThereAreOneItemToDelete_ShouldGenerateCorrectDeleteNdJson()
{
var expectedJsonString = @"{""delete"":{""_id"":""id1"",""language_routing"":""en""}}";

var response = new HttpResponseMessage(HttpStatusCode.OK);
mockRestClient.Setup(c => c.HandleResponse(response));
mockRestClient.Setup(c => c.SendAsync(It.IsAny<HttpRequestMessage>())).Callback<HttpRequestMessage>(req =>
{
// Read the content of the request
var content = req.Content.ReadAsStringAsync().GetAwaiter().GetResult();

// Assert
Assert.AreEqual(expectedJsonString, content);
}).ReturnsAsync(response);

// Act
await repository.DeleteContentItemsAsync("en", "id1");
}

[TestMethod]
public async Task DeleteContentItemsAsync_WhenThereAreSeveralItemToDelete_ShouldGenerateCorrectDeleteNdJson()
{
var expectedJsonStrings = new List<string>
{
@"{""delete"":{""_id"":""id1"",""language_routing"":""en""}}",
@"{""delete"":{""_id"":""id2"",""language_routing"":""en""}}",
@"{""delete"":{""_id"":""id3"",""language_routing"":""en""}}"
};

var response = new HttpResponseMessage(HttpStatusCode.OK);
mockRestClient.Setup(c => c.HandleResponse(response));
mockRestClient.Setup(c => c.SendAsync(It.IsAny<HttpRequestMessage>())).Callback<HttpRequestMessage>(req =>
{
// Read the content of the request
var content = req.Content.ReadAsStringAsync().GetAwaiter().GetResult();

// Assert
var contentResultItems = content.Split(Environment.NewLine);
Assert.AreEqual(expectedJsonStrings[0], contentResultItems[0]);
Assert.AreEqual(expectedJsonStrings[1], contentResultItems[1]);
Assert.AreEqual(expectedJsonStrings[2], contentResultItems[2]);
}).ReturnsAsync(response);

// Act
await repository.DeleteContentItemsAsync("en", "id1", "id2", "id3");
}

#region Private
private string BuildExpectedTypeJsonString()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
using Optimizely.Graph.Source.Sdk.JsonConverters;
using System.Text.Json;
using System.Text;
using Optimizely.Graph.Source.Sdk.RestClientHelpers;
using Optimizely.Graph.Source.Sdk.SourceConfiguration;
using System.Linq.Expressions;
using System.Text;
using System.Text.Json;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace Optimizely.Graph.Source.Sdk.Repositories
{
Expand Down Expand Up @@ -139,6 +140,41 @@ public async Task<string> DeleteContentAsync()
public void ConfigureLink<T, U>(string name, Expression<Func<T, object>> from, Expression<Func<U, object>> to)
{
SourceConfigurationModel.ConfigureLink<T, U>(name, from, to);
}
}

public async Task<string> DeleteContentItemsAsync(string language, params string[] ids)
{
var serializeOptions = new JsonSerializerOptions
{
WriteIndented = false,
Converters =
{
new SourceSdkContentConverter()
}
};

var itemJson = string.Empty;
for(int i = 0;i<ids.Length;i++)
{
itemJson += $"{{\"delete\":{{\"_id\":\"{ids[i]}\",\"language_routing\":\"{language}\"}}}}";

if (i < ids.Length - 1)
{
itemJson += Environment.NewLine;
}
}

var content = new StringContent(itemJson, Encoding.UTF8, "application/json");

using (var requestMessage = new HttpRequestMessage(HttpMethod.Post, $"{DataUrl}?id={source}"))
{
requestMessage.Content = content;
using (var responseMessage = await client.SendAsync(requestMessage))
{
await client.HandleResponse(responseMessage);
}
}
return string.Empty;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,51 +1,57 @@
using Optimizely.Graph.Source.Sdk.SourceConfiguration;
using System.Linq.Expressions;

namespace Optimizely.Graph.Source.Sdk.Repositories
{
public interface IGraphSourceRepository
{
/// <summary>
/// Adds language preference to SourceConfigurationModel.
/// </summary>
/// <param name="language"></param>
void AddLanguage(string language);

void ConfigureLink<T, U>(string name, Expression<Func<T, object>> from, Expression<Func<U, object>> to);

/// <summary>
/// Configures Content Types within the SourceConfigurationModel.
/// </summary>
/// <typeparam name="T">Generic content type.</typeparam>
/// <returns></returns>
SourceConfigurationModel<T> ConfigureContentType<T>() where T : class, new();

/// <summary>
/// Configures Content Property Types within the SourceConfigurationModel.
/// </summary>
/// <typeparam name="T">Generic property type.</typeparam>
/// <returns></returns>
SourceConfigurationModel<T> ConfigurePropertyType<T>() where T : class, new();

/// <summary>
/// Saves Content Types set in the SourceConfigurationModel to the Content Graph api.
/// </summary>
/// <returns></returns>
Task<string> SaveTypesAsync();

/// <summary>
/// Saves dynamic content sent in data array to the Content Graph api.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="generateId">Id associated with content.</param>
/// <param name="data">Dynamic data being saved to Content Graph.</param>
/// <returns></returns>
Task<string> SaveContentAsync<T>(Func<T, string> generateId, params T[] data) where T : class, new();

/// <summary>
/// Removes content previously stored by source.
/// </summary>
/// <returns></returns>
Task<string> DeleteContentAsync();
}
}
using Optimizely.Graph.Source.Sdk.SourceConfiguration;
using System.Linq.Expressions;

namespace Optimizely.Graph.Source.Sdk.Repositories
{
public interface IGraphSourceRepository
{
/// <summary>
/// Adds language preference to SourceConfigurationModel.
/// </summary>
/// <param name="language"></param>
void AddLanguage(string language);

void ConfigureLink<T, U>(string name, Expression<Func<T, object>> from, Expression<Func<U, object>> to);

/// <summary>
/// Configures Content Types within the SourceConfigurationModel.
/// </summary>
/// <typeparam name="T">Generic content type.</typeparam>
/// <returns></returns>
SourceConfigurationModel<T> ConfigureContentType<T>() where T : class, new();

/// <summary>
/// Configures Content Property Types within the SourceConfigurationModel.
/// </summary>
/// <typeparam name="T">Generic property type.</typeparam>
/// <returns></returns>
SourceConfigurationModel<T> ConfigurePropertyType<T>() where T : class, new();

/// <summary>
/// Saves Content Types set in the SourceConfigurationModel to the Content Graph api.
/// </summary>
/// <returns></returns>
Task<string> SaveTypesAsync();

/// <summary>
/// Saves dynamic content sent in data array to the Content Graph api.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="generateId">Id associated with content.</param>
/// <param name="data">Dynamic data being saved to Content Graph.</param>
/// <returns></returns>
Task<string> SaveContentAsync<T>(Func<T, string> generateId, params T[] data) where T : class, new();

/// <summary>
/// Removes content previously stored by source.
/// </summary>
/// <returns></returns>
Task<string> DeleteContentAsync();

/// <summary>
/// Removes content previously stored by source.
/// </summary>
/// <returns></returns>
Task<string> DeleteContentItemsAsync(string language, params string[] ids);
}
}