diff --git a/src/ApplicationCore/Exceptions/CatalogImageMissingException.cs b/src/ApplicationCore/Exceptions/CatalogImageMissingException.cs
new file mode 100644
index 0000000..a7c1062
--- /dev/null
+++ b/src/ApplicationCore/Exceptions/CatalogImageMissingException.cs
@@ -0,0 +1,13 @@
+using System;
+
+namespace ApplicationCore.Exceptions
+{
+ public class CatalogImageMissingException : Exception
+ {
+ public CatalogImageMissingException(string message,
+ Exception innerException = null)
+ : base(message, innerException: innerException)
+ {
+ }
+ }
+}
diff --git a/src/ApplicationCore/Interfaces/IBasketService.cs b/src/ApplicationCore/Interfaces/IBasketService.cs
index 1b868a1..a5f25b9 100644
--- a/src/ApplicationCore/Interfaces/IBasketService.cs
+++ b/src/ApplicationCore/Interfaces/IBasketService.cs
@@ -14,5 +14,4 @@ namespace ApplicationCore.Interfaces
{
T Parse(IPrincipal principal);
}
-
}
diff --git a/src/ApplicationCore/Interfaces/IImageService.cs b/src/ApplicationCore/Interfaces/IImageService.cs
new file mode 100644
index 0000000..ae41333
--- /dev/null
+++ b/src/ApplicationCore/Interfaces/IImageService.cs
@@ -0,0 +1,16 @@
+using ApplicationCore.Entities;
+using Microsoft.eShopWeb.ApplicationCore.Entities;
+using System.Security.Principal;
+using System.Threading.Tasks;
+
+namespace ApplicationCore.Interfaces
+{
+
+ public interface IImageService
+ {
+ byte[] GetImageBytesById(int id);
+ }
+
+
+
+}
diff --git a/src/Infrastructure/FileSystem/LocalFileImageService.cs b/src/Infrastructure/FileSystem/LocalFileImageService.cs
new file mode 100644
index 0000000..ab876af
--- /dev/null
+++ b/src/Infrastructure/FileSystem/LocalFileImageService.cs
@@ -0,0 +1,22 @@
+using ApplicationCore.Interfaces;
+using Microsoft.AspNetCore.Hosting;
+using System.IO;
+
+namespace Infrastructure.FileSystem
+{
+ public class LocalFileImageService : IImageService
+ {
+ private readonly IHostingEnvironment _env;
+
+ public LocalFileImageService(IHostingEnvironment env)
+ {
+ _env = env;
+ }
+ public byte[] GetImageBytesById(int id)
+ {
+ var contentRoot = _env.ContentRootPath + "//Pics";
+ var path = Path.Combine(contentRoot, id + ".png");
+ return File.ReadAllBytes(path);
+ }
+ }
+}
diff --git a/src/Infrastructure/Infrastructure.csproj b/src/Infrastructure/Infrastructure.csproj
index b377567..c2c8f95 100644
--- a/src/Infrastructure/Infrastructure.csproj
+++ b/src/Infrastructure/Infrastructure.csproj
@@ -14,5 +14,8 @@
+
+
+
\ No newline at end of file
diff --git a/src/Web/Controllers/CatalogController.cs b/src/Web/Controllers/CatalogController.cs
index 25d50ae..fa7bb18 100644
--- a/src/Web/Controllers/CatalogController.cs
+++ b/src/Web/Controllers/CatalogController.cs
@@ -5,18 +5,24 @@ using Microsoft.AspNetCore.Mvc;
using System;
using System.IO;
using System.Threading.Tasks;
+using ApplicationCore.Interfaces;
+using ApplicationCore.Exceptions;
namespace Microsoft.eShopWeb.Controllers
{
public class CatalogController : Controller
{
private readonly IHostingEnvironment _env;
- private readonly ICatalogService _catalogSvc;
+ private readonly ICatalogService _catalogService;
+ private readonly IImageService _imageService;
- public CatalogController(IHostingEnvironment env, ICatalogService catalogSvc)
+ public CatalogController(IHostingEnvironment env,
+ ICatalogService catalogService,
+ IImageService imageService)
{
_env = env;
- _catalogSvc = catalogSvc;
+ _catalogService = catalogService;
+ _imageService = imageService;
}
@@ -24,13 +30,13 @@ namespace Microsoft.eShopWeb.Controllers
public async Task Index(int? BrandFilterApplied, int? TypesFilterApplied, int? page)
{
var itemsPage = 10;
- var catalog = await _catalogSvc.GetCatalogItems(page ?? 0, itemsPage, BrandFilterApplied, TypesFilterApplied);
+ var catalog = await _catalogService.GetCatalogItems(page ?? 0, itemsPage, BrandFilterApplied, TypesFilterApplied);
var vm = new CatalogIndex()
{
CatalogItems = catalog.Data,
- Brands = await _catalogSvc.GetBrands(),
- Types = await _catalogSvc.GetTypes(),
+ Brands = await _catalogService.GetBrands(),
+ Types = await _catalogService.GetTypes(),
BrandFilterApplied = BrandFilterApplied ?? 0,
TypesFilterApplied = TypesFilterApplied ?? 0,
PaginationInfo = new PaginationInfo()
@@ -53,13 +59,18 @@ namespace Microsoft.eShopWeb.Controllers
// GET: //pic/{id}
public IActionResult GetImage(int id)
{
- var contentRoot = _env.ContentRootPath + "//Pics";
- var path = Path.Combine(contentRoot, id + ".png");
- Byte[] b = System.IO.File.ReadAllBytes(path);
- return File(b, "image/png");
-
+ byte[] imageBytes;
+ try
+ {
+ imageBytes = _imageService.GetImageBytesById(id);
+ }
+ catch (CatalogImageMissingException ex)
+ {
+ return NotFound();
+ }
+ return File(imageBytes, "image/png");
}
-
+
public IActionResult Error()
{
return View();
diff --git a/src/Web/Startup.cs b/src/Web/Startup.cs
index 0bf788f..6ec6990 100644
--- a/src/Web/Startup.cs
+++ b/src/Web/Startup.cs
@@ -11,6 +11,8 @@ using Infrastructure.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using System.Text;
using Microsoft.AspNetCore.Http;
+using ApplicationCore.Interfaces;
+using Infrastructure.FileSystem;
namespace Microsoft.eShopWeb
{
@@ -65,6 +67,7 @@ namespace Microsoft.eShopWeb
services.AddScoped();
services.AddScoped();
services.Configure(Configuration);
+ services.AddSingleton();
services.AddMvc();
_services = services;
diff --git a/tests/IntegrationTests/IntegrationTests.csproj b/tests/IntegrationTests/IntegrationTests.csproj
index f27ff35..c3a4881 100644
--- a/tests/IntegrationTests/IntegrationTests.csproj
+++ b/tests/IntegrationTests/IntegrationTests.csproj
@@ -14,4 +14,8 @@
+
+
+
+
diff --git a/tests/UnitTests/UnitTests.csproj b/tests/UnitTests/UnitTests.csproj
index f032596..18ba44b 100644
--- a/tests/UnitTests/UnitTests.csproj
+++ b/tests/UnitTests/UnitTests.csproj
@@ -1,13 +1,25 @@
-
+
netcoreapp1.1
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/UnitTests/Web/Controllers/CatalogControllerGetImage.cs b/tests/UnitTests/Web/Controllers/CatalogControllerGetImage.cs
new file mode 100644
index 0000000..6bcdb4e
--- /dev/null
+++ b/tests/UnitTests/Web/Controllers/CatalogControllerGetImage.cs
@@ -0,0 +1,60 @@
+using ApplicationCore.Exceptions;
+using ApplicationCore.Interfaces;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.eShopWeb.Controllers;
+using Moq;
+using Xunit;
+
+namespace UnitTests
+{
+ public class CatalogControllerGetImage
+ {
+ private Mock _mockImageService = new Mock();
+ private CatalogController _controller;
+ private int _testImageId = 123;
+ private byte[] _testBytes = { 0x01, 0x02, 0x03 };
+
+ public CatalogControllerGetImage()
+ {
+ _controller = new CatalogController(null, null, _mockImageService.Object);
+ }
+
+ [Fact]
+ public void CallsImageServiceWithId()
+ {
+ _mockImageService
+ .Setup(i => i.GetImageBytesById(_testImageId))
+ .Returns(_testBytes)
+ .Verifiable();
+
+ _controller.GetImage(_testImageId);
+ _mockImageService.Verify();
+ }
+
+ [Fact]
+ public void ReturnsFileResultWithBytesGivenSuccess()
+ {
+ _mockImageService
+ .Setup(i => i.GetImageBytesById(_testImageId))
+ .Returns(_testBytes);
+
+ var result = _controller.GetImage(_testImageId);
+
+ var fileResult = Assert.IsType(result);
+ var bytes = Assert.IsType(fileResult.FileContents);
+ }
+
+ [Fact]
+ public void ReturnsNotFoundResultGivenImageMissingException()
+ {
+ _mockImageService
+ .Setup(i => i.GetImageBytesById(_testImageId))
+ .Throws(new CatalogImageMissingException("missing image"));
+
+ var result = _controller.GetImage(_testImageId);
+
+ var actionResult = Assert.IsType(result);
+ }
+ }
+}