Skip to content
This repository has been archived by the owner on Jan 28, 2021. It is now read-only.

Commit

Permalink
Merge pull request #9 from Kentico/Product-updates
Browse files Browse the repository at this point in the history
Product updates
  • Loading branch information
StandaSojka authored Nov 1, 2019
2 parents df9bc31 + c63a5e9 commit e80c6e1
Show file tree
Hide file tree
Showing 12 changed files with 379 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,8 @@
</ItemGroup>
<ItemGroup>
<Compile Include="ContactMergeProcessorTests.cs" />
<Compile Include="ProductMapperTests.cs" />
<Compile Include="ProductUpdatesProcessorTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
Expand Down
48 changes: 48 additions & 0 deletions Kentico.Recombee.Admin.Tests/ProductMapperTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using CMS.Ecommerce;

using Kentico.Recombee.Mappers;

using NUnit.Framework;
using NSubstitute;

namespace Kentico.Recombee.Admin.Tests
{
[TestFixture]
public class ProductMapperTests
{
[Test]
public void Map_ProductIsNull_ThrowsArgumentNullException()
{
Assert.That(() => { ProductMapper.Map(null); }, Throws.ArgumentNullException);
}


[Test]
public void Map_ProductPropertiesMappedToCorrectStructure()
{
var sku = Substitute.For<SKUInfo>();
sku.SKUPrice.Returns(99.9M);
sku.SKUID.Returns(1);

var productPage = Substitute.For<SKUTreeNode>();
productPage.SKU = sku;
productPage.DocumentSKUName.Returns("DocumentSKUName");
productPage.DocumentSKUShortDescription.Returns("DocumentSKUShortDescription");
productPage.DocumentSKUDescription.Returns("DocumentSKUDescription");
productPage.DocumentCulture.Returns("DocumentCulture");
productPage.ClassName.Returns("ClassName");

var result = ProductMapper.Map(productPage);

Assert.Multiple(() => {
Assert.That(result["Name"], Is.EqualTo("DocumentSKUName"));
Assert.That(result["Description"], Is.EqualTo("DocumentSKUShortDescription"));
Assert.That(result["Content"], Is.EqualTo("DocumentSKUDescription"));
Assert.That(result["Culture"], Is.EqualTo("DocumentCulture"));
Assert.That(result["ClassName"], Is.EqualTo("ClassName"));
Assert.That(result["Price"], Is.EqualTo(99.9M));
Assert.That(result["Type"], Is.EqualTo("Product"));
});
}
}
}
77 changes: 77 additions & 0 deletions Kentico.Recombee.Admin.Tests/ProductUpdatesProcessorTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
using CMS.Core;
using CMS.Ecommerce;
using CMS.Tests;

using NSubstitute;
using NUnit.Framework;

namespace Kentico.Recombee.Admin.Tests
{
[TestFixture]
public class ProductUpdatesProcessorTests : UnitTests
{
private IProductUpdatesProcessor processor;
private IRecombeeClientService clientService;


[SetUp]
public void SetUp()
{
clientService = Substitute.For<IRecombeeClientService>();
Service.Use<IRecombeeClientService>(clientService);

processor = Service.Resolve<IProductUpdatesProcessor>();
}


[Test]
public void Ctor_NullArgument_ThrowsArgumentNullException()
{
Assert.That(() => { new ProductUpdatesProcessor(null); }, Throws.ArgumentNullException);
}


[Test]
public void Methods_NullArgumentt_ThrowsArgumentNullException()
{
Assert.Multiple(() =>
{
Assert.That(() => { processor.AddProduct(null); }, Throws.ArgumentNullException);
Assert.That(() => { processor.DeleteProduct(null); }, Throws.ArgumentNullException);
});
}


[Test]
public void AddProduct_ProductIsAdded()
{
var productPage = Substitute.For<SKUTreeNode>();

processor.AddProduct(productPage);

clientService.Received().UpdateProduct(Arg.Is(productPage));
}


[Test]
public void DeleteProduct_ProductIsDeleted()
{
var productPage = Substitute.For<SKUTreeNode>();

processor.DeleteProduct(productPage);

clientService.Received().Delete(Arg.Is(productPage));
}


[Test]
public void UpdateProduct_ProductIsUdated()
{
var productPage = Substitute.For<SKUTreeNode>();

processor.UpdateProduct(productPage);

clientService.Received().UpdateProduct(Arg.Is(productPage));
}
}
}
21 changes: 1 addition & 20 deletions Kentico.Recombee.Admin/DatabaseSetup/HistoryData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -193,25 +193,6 @@ private void PushArticles(IList<TreeNode> articles)
}, true));

client.Send(new Batch(articlesToPush));
}


private void PushProducts(IEnumerable<SKUTreeNode> products)
{
var productsToPush = products.Select(productPage => new SetItemValues(productPage.DocumentGUID.ToString(),
new Dictionary<string, object>
{
{ "Name", productPage.DocumentSKUName },
{ "Description", productPage.DocumentSKUShortDescription },
{ "Content", productPage.DocumentSKUDescription},
{ "Culture", productPage.DocumentCulture},
{ "ClassName", productPage.ClassName},
{ "Price", productPage.SKU.SKUPrice },
{ "Type", "Product"},

}, true));

client.Send(new Batch(productsToPush));
}
}
}
}
20 changes: 7 additions & 13 deletions Kentico.Recombee.Admin/DatabaseSetup/RecombeeStructure.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
using CMS.DataEngine;
using CMS.DocumentEngine;
using CMS.Ecommerce;
using Kentico.Recombee.Helpers;

using Kentico.Recombee.Helpers;
using Kentico.Recombee.Mappers;
using Recombee.ApiClient;
using Recombee.ApiClient.ApiRequests;

Expand Down Expand Up @@ -85,18 +86,11 @@ private IList<SKUTreeNode> GetProducts()

private void PushProducts(IEnumerable<SKUTreeNode> products)
{
var productsToPush = products.Select(productPage => new SetItemValues(productPage.DocumentGUID.ToString(),
new Dictionary<string, object>
{
{ "Name", productPage.DocumentSKUName },
{ "Description", productPage.DocumentSKUShortDescription },
{ "Content", productPage.DocumentSKUDescription},
{ "Culture", productPage.DocumentCulture},
{ "ClassName", productPage.ClassName},
{ "Price", productPage.SKU.SKUPrice },
{ "Type", "Product"},

}, true));
var productsToPush = products.Select(productPage => new SetItemValues(
productPage.DocumentGUID.ToString(),
ProductMapper.Map(productPage),
true)
);

client.Send(new Batch(productsToPush));
}
Expand Down
35 changes: 35 additions & 0 deletions Kentico.Recombee.Admin/IProductUpdatesProcessor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using CMS;
using CMS.Ecommerce;

using Kentico.Recombee;

[assembly: RegisterImplementation(typeof(IProductUpdatesProcessor), typeof(ProductUpdatesProcessor))]

namespace Kentico.Recombee
{
/// <summary>
/// The contract for an implementation handling product updates.
/// </summary>
public interface IProductUpdatesProcessor
{
/// <summary>
/// Process added product in Recombee.
/// </summary>
/// <param name="productPage">Product page.</param>
void AddProduct(SKUTreeNode productPage);


/// <summary>
/// Deletes given product from recombee database.
/// </summary>
/// <param name="user">Product to delete.</param>
void DeleteProduct(SKUTreeNode productPage);


/// <summary>
/// Updates given product from recombee database.
/// </summary>
/// <param name="user">Product to update.</param>
void UpdateProduct(SKUTreeNode productPage);
}
}
15 changes: 15 additions & 0 deletions Kentico.Recombee.Admin/IRecombeeClientService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

using CMS;
using CMS.ContactManagement;
using CMS.Ecommerce;

using Kentico.Recombee;

Expand Down Expand Up @@ -71,5 +72,19 @@ public interface IRecombeeClientService
/// </summary>
/// <param name="itemsToAdd">Cart additions to add.</param>
void Add(IEnumerable<AddCartAddition> itemsToAdd);


/// <summary>
/// Updates given product <paramref name="productPage"/> in Recombee database.
/// </summary>
/// <param name="productPage">Product to update.</param>
void UpdateProduct(SKUTreeNode productPage);


/// <summary>
/// Deletes given product from recombee database.
/// </summary>
/// <param name="user">Product to delete.</param>
void Delete(SKUTreeNode productPage);
}
}
3 changes: 3 additions & 0 deletions Kentico.Recombee.Admin/Kentico.Recombee.Admin.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,10 @@
<Compile Include="DatabaseSetup\RecombeeStructure.cs" />
<Compile Include="Helpers\RecommendedProductsSettings.cs" />
<Compile Include="IContactMergeProcessor.cs" />
<Compile Include="IProductUpdatesProcessor.cs" />
<Compile Include="IRecombeeClientService.cs" />
<Compile Include="Mappers\ProductMapper.cs" />
<Compile Include="ProductUpdatesProcessor.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RecombeeClientService.cs" />
<Compile Include="RecombeeModule.cs" />
Expand Down
36 changes: 36 additions & 0 deletions Kentico.Recombee.Admin/Mappers/ProductMapper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;

using CMS.Ecommerce;

namespace Kentico.Recombee.Mappers
{
/// <summary>
/// Encapsulates mapping Kentico objects to Recombee parameters.
/// </summary>
public static class ProductMapper
{
/// <summary>
/// Maps <paramref name="productPage"/> to Recombee structure.
/// </summary>
/// <param name="productPage">Product page.</param>
public static Dictionary<string, object> Map(SKUTreeNode productPage)
{
if (productPage is null)
{
throw new ArgumentNullException(nameof(productPage));
}

return new Dictionary<string, object>
{
{ "Name", productPage.DocumentSKUName },
{ "Description", productPage.DocumentSKUShortDescription },
{ "Content", productPage.DocumentSKUDescription},
{ "Culture", productPage.DocumentCulture},
{ "ClassName", productPage.ClassName},
{ "Price", productPage.SKU.SKUPrice },
{ "Type", "Product"},
};
}
}
}
67 changes: 67 additions & 0 deletions Kentico.Recombee.Admin/ProductUpdatesProcessor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using System;
using CMS.Ecommerce;

namespace Kentico.Recombee
{
/// <summary>
/// Reflects product actions in Recombee database.
/// </summary>
public class ProductUpdatesProcessor : IProductUpdatesProcessor
{
private readonly IRecombeeClientService recombeeClientService;

/// <summary>
/// Creates an instance of the <see cref="ProductUpdatesProcessor"/> class.
/// </summary>
/// <param name="recombeeClientService">Client service.</param>
public ProductUpdatesProcessor(IRecombeeClientService recombeeClientService)
{
this.recombeeClientService = recombeeClientService ?? throw new ArgumentNullException(nameof(recombeeClientService));
}


/// <summary>
/// Process added product in Recombee.
/// </summary>
/// <param name="productPage">Product page.</param>
public void AddProduct(SKUTreeNode productPage)
{
if (productPage is null)
{
throw new ArgumentNullException(nameof(productPage));
}

UpdateProduct(productPage);
}


/// <summary>
/// Deletes given product from recombee database.
/// </summary>
/// <param name="user">Product to delete.</param>
public void DeleteProduct(SKUTreeNode productPage)
{
if (productPage is null)
{
throw new ArgumentNullException(nameof(productPage));
}

recombeeClientService.Delete(productPage);
}


/// <summary>
/// Updates given product from recombee database.
/// </summary>
/// <param name="user">Product to update.</param>
public void UpdateProduct(SKUTreeNode productPage)
{
if (productPage is null)
{
throw new ArgumentNullException(nameof(productPage));
}

recombeeClientService.UpdateProduct(productPage);
}
}
}
Loading

0 comments on commit e80c6e1

Please sign in to comment.