diff --git a/coffeecard/CoffeeCard.Library/Services/v2/ProductService.cs b/coffeecard/CoffeeCard.Library/Services/v2/ProductService.cs index 666cd4ba..e1e471ce 100644 --- a/coffeecard/CoffeeCard.Library/Services/v2/ProductService.cs +++ b/coffeecard/CoffeeCard.Library/Services/v2/ProductService.cs @@ -78,31 +78,24 @@ public async Task AddProduct(AddProductRequest newProduc Name = newProduct.Name, NumberOfTickets = newProduct.NumberOfTickets, ExperienceWorth = 0, - Visible = newProduct.Visible + Visible = newProduct.Visible, + ProductUserGroup = newProduct.AllowedUserGroups.Select(userGroup => new ProductUserGroup + { + UserGroup = userGroup + }).ToList() }; _context.Products.Add(product); await _context.SaveChangesAsync(); - var productUserGroups = newProduct.AllowedUserGroups.Select(userGroup => new ProductUserGroup - { - ProductId = product.Id, - UserGroup = userGroup - }).ToList(); - - _context.ProductUserGroups.AddRange(productUserGroups); - - - await _context.SaveChangesAsync(); - - var result = new ChangedProductResponse { Price = product.Price, Description = product.Description, Name = product.Name, NumberOfTickets = product.NumberOfTickets, - Visible = product.Visible + Visible = product.Visible, + AllowedUserGroups = newProduct.AllowedUserGroups }; return result; @@ -116,6 +109,11 @@ public async Task UpdateProduct(UpdateProductRequest cha product.NumberOfTickets = changedProduct.NumberOfTickets; product.Name = changedProduct.Name; product.Visible = changedProduct.Visible; + product.ProductUserGroup = changedProduct.AllowedUserGroups.Select(userGroup => new ProductUserGroup + { + ProductId = changedProduct.Id, + UserGroup = userGroup + }).ToList(); await _context.SaveChangesAsync(); @@ -125,7 +123,8 @@ public async Task UpdateProduct(UpdateProductRequest cha Description = product.Description, Name = product.Name, NumberOfTickets = product.NumberOfTickets, - Visible = product.Visible + Visible = product.Visible, + AllowedUserGroups = changedProduct.AllowedUserGroups }; return result; diff --git a/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Product/AddProductRequest.cs b/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Product/AddProductRequest.cs index 6c42d988..148b75ac 100644 --- a/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Product/AddProductRequest.cs +++ b/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Product/AddProductRequest.cs @@ -14,7 +14,8 @@ namespace CoffeeCard.Models.DataTransferObjects.v2.Product /// "Price": 25, /// "NumberOfTickets": 10, /// "Description": "xxx", - /// "Visible": true + /// "Visible": true, + /// "AllowedUserGroups": ["Manager", "Board"] /// } /// public class AddProductRequest @@ -63,8 +64,13 @@ public class AddProductRequest [DefaultValue(true)] public bool Visible { get; set; } = true; + /// + /// Gets or sets the user groups that can access the product. + /// + /// Product User Groups + /// Manager, Board [Required] - public IEnumerable AllowedUserGroups { get; set; } + public IEnumerable AllowedUserGroups { get; set; } = new List(); } } \ No newline at end of file diff --git a/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Product/ChangedProductResponse.cs b/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Product/ChangedProductResponse.cs index 8a0cfba0..2fac818a 100644 --- a/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Product/ChangedProductResponse.cs +++ b/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Product/ChangedProductResponse.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; +using CoffeeCard.Models.Entities; namespace CoffeeCard.Models.DataTransferObjects.v2.Product { @@ -51,5 +52,13 @@ public class ChangedProductResponse /// true [Required] public bool Visible { get; set; } + + /// + /// Gets or sets the user groups that can access the product. + /// + /// Product User Groups + /// Manager, Board + [Required] + public IEnumerable AllowedUserGroups { get; set; } = new List(); } } \ No newline at end of file diff --git a/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Product/UpdateProductRequest.cs b/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Product/UpdateProductRequest.cs index a939c1ae..e0aa10b2 100644 --- a/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Product/UpdateProductRequest.cs +++ b/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Product/UpdateProductRequest.cs @@ -1,5 +1,7 @@ +using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; +using CoffeeCard.Models.Entities; namespace CoffeeCard.Models.DataTransferObjects.v2.Product { @@ -13,7 +15,8 @@ namespace CoffeeCard.Models.DataTransferObjects.v2.Product /// "NumberOfTickets": 10, /// "Name": "Espresso", /// "Description": "A coffee made by forcing steam through ground coffee beans.", - /// "Visible": false + /// "Visible": false, + /// "AllowedUserGroups": ["Manager", "Board"] /// } /// public class UpdateProductRequest @@ -69,5 +72,13 @@ public class UpdateProductRequest /// true [DefaultValue(true)] public bool Visible { get; set; } = true; + + /// + /// Gets or sets the user groups that can access the product. + /// + /// Product User Groups + /// Manager, Board + [Required] + public IEnumerable AllowedUserGroups { get; set; } = new List(); } } \ No newline at end of file diff --git a/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Products/ProductResponse.cs b/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Products/ProductResponse.cs index b9dfad28..959cd2b0 100644 --- a/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Products/ProductResponse.cs +++ b/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Products/ProductResponse.cs @@ -1,4 +1,6 @@ -using System.ComponentModel.DataAnnotations; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using CoffeeCard.Models.Entities; namespace CoffeeCard.Models.DataTransferObjects.v2.Products { @@ -12,7 +14,8 @@ namespace CoffeeCard.Models.DataTransferObjects.v2.Products /// "numberOfTickets": 10, /// "name": "Coffee clip card", /// "description": "Coffee clip card of 10 clips", - /// "isPerk": true + /// "isPerk": true, + /// "AllowedUserGroups": ["Manager", "Board"] /// } /// public class ProductResponse @@ -64,5 +67,13 @@ public class ProductResponse /// true [Required] public bool IsPerk { get; set; } + + /// + /// Decides the user groups that can access the product. + /// + /// Product User Groups + /// Manager, Board + [Required] + public IEnumerable AllowedUserGroups { get; set; } = new List(); } } diff --git a/coffeecard/CoffeeCard.Tests.Unit/Services/v2/ProductServiceTest.cs b/coffeecard/CoffeeCard.Tests.Unit/Services/v2/ProductServiceTest.cs new file mode 100644 index 00000000..f50876ed --- /dev/null +++ b/coffeecard/CoffeeCard.Tests.Unit/Services/v2/ProductServiceTest.cs @@ -0,0 +1,128 @@ +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Threading.Tasks; +using CoffeeCard.Common.Configuration; +using CoffeeCard.Library.Persistence; +using CoffeeCard.Library.Services.v2; +using CoffeeCard.Models.DataTransferObjects.v2.Product; +using CoffeeCard.Models.Entities; +using Microsoft.EntityFrameworkCore; +using Xunit; + +namespace CoffeeCard.Tests.Unit.Services.v2 +{ + public class ProductServiceTest + { + [Fact(DisplayName = "UpdateProduct removes ommitted user groups and only adds selected user groups")] + public async Task UpdateProduct_Removes_Omitted_UserGroups() + { + var builder = new DbContextOptionsBuilder() + .UseInMemoryDatabase(nameof(UpdateProduct_Removes_Omitted_UserGroups)); + + var databaseSettings = new DatabaseSettings + { + SchemaName = "test" + }; + var environmentSettings = new EnvironmentSettings() + { + EnvironmentType = EnvironmentType.Test + }; + + await using var context = new CoffeeCardContext(builder.Options, databaseSettings, environmentSettings); + var p = new Product + { + Id = 1, + Name = "Coffee", + Description = "Coffee Clip card", + NumberOfTickets = 10, + Price = 10, + ExperienceWorth = 10, + Visible = true + }; + await context.AddAsync(p); + await context.SaveChangesAsync(); + + await context.AddAsync(new ProductUserGroup + { + Product = p, + UserGroup = UserGroup.Barista + }); + + await context.AddAsync(new ProductUserGroup + { + Product = p, + UserGroup = UserGroup.Manager + }); + + await context.SaveChangesAsync(); + + using var productService = new ProductService(context); + + await productService.UpdateProduct(new UpdateProductRequest() + { + Id = 1, + Visible = true, + Price = 10, + NumberOfTickets = 10, + Name = "Coffee", + Description = "Coffee Clip card", + AllowedUserGroups = new List() { UserGroup.Customer, UserGroup.Board } + }); + + var expected = new List + { + UserGroup.Customer, UserGroup.Board + }; + + var result = await productService.GetProductAsync(1); + + Assert.Collection(expected, + e => e.Equals(UserGroup.Customer), + e => e.Equals(UserGroup.Board)); + } + + [Fact(DisplayName = "AddProduct adds only selected user groups")] + public async Task AddProduct_Sets_Correct_UserGroups() + { + var builder = new DbContextOptionsBuilder() + .UseInMemoryDatabase(nameof(AddProduct_Sets_Correct_UserGroups)); + + var databaseSettings = new DatabaseSettings + { + SchemaName = "test" + }; + var environmentSettings = new EnvironmentSettings() + { + EnvironmentType = EnvironmentType.Test + }; + + await using var context = new CoffeeCardContext(builder.Options, databaseSettings, environmentSettings); + + using var productService = new ProductService(context); + + var p = new AddProductRequest + { + Name = "Coffee", + Description = "Coffee Clip card", + NumberOfTickets = 10, + Price = 10, + Visible = true, + AllowedUserGroups = new List { UserGroup.Manager, UserGroup.Board } + }; + + await productService.AddProduct(p); + + var expected = new List + { + UserGroup.Manager, UserGroup.Board + }; + + var result = await productService.GetProductAsync(1); + + Assert.Collection(expected, + e => e.Equals(UserGroup.Customer), + e => e.Equals(UserGroup.Board)); + } + } +} \ No newline at end of file