Skip to content

Commit 9d46f8a

Browse files
committed
add
1 parent 0657f72 commit 9d46f8a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+2245
-0
lines changed

Rest.Api.Solution.sln

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 16
4+
VisualStudioVersion = 16.0.31005.135
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Api", "Api", "{B55D2BE1-7C69-4EF0-BBB2-F1B8D0F9C8C4}"
7+
EndProject
8+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Rest.Api", "src\Api\Coding.Challenge.Api\Rest.Api.csproj", "{5D8B62B2-549D-44B4-BAEA-D95246B461FA}"
9+
EndProject
10+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Api.Test", "Api.Test", "{84CAFD70-C5BC-45F5-8066-1898CD37ED15}"
11+
EndProject
12+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Rest.Api.Tests", "src\Api.Test\Coding.Challenge.Api.Tests\Rest.Api.Tests.csproj", "{7825EF30-568B-428A-8125-C63AA149B101}"
13+
EndProject
14+
Global
15+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
16+
Debug|Any CPU = Debug|Any CPU
17+
Release|Any CPU = Release|Any CPU
18+
EndGlobalSection
19+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
20+
{5D8B62B2-549D-44B4-BAEA-D95246B461FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21+
{5D8B62B2-549D-44B4-BAEA-D95246B461FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
22+
{5D8B62B2-549D-44B4-BAEA-D95246B461FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
23+
{5D8B62B2-549D-44B4-BAEA-D95246B461FA}.Release|Any CPU.Build.0 = Release|Any CPU
24+
{7825EF30-568B-428A-8125-C63AA149B101}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
25+
{7825EF30-568B-428A-8125-C63AA149B101}.Debug|Any CPU.Build.0 = Debug|Any CPU
26+
{7825EF30-568B-428A-8125-C63AA149B101}.Release|Any CPU.ActiveCfg = Release|Any CPU
27+
{7825EF30-568B-428A-8125-C63AA149B101}.Release|Any CPU.Build.0 = Release|Any CPU
28+
EndGlobalSection
29+
GlobalSection(SolutionProperties) = preSolution
30+
HideSolutionNode = FALSE
31+
EndGlobalSection
32+
GlobalSection(NestedProjects) = preSolution
33+
{5D8B62B2-549D-44B4-BAEA-D95246B461FA} = {B55D2BE1-7C69-4EF0-BBB2-F1B8D0F9C8C4}
34+
{7825EF30-568B-428A-8125-C63AA149B101} = {84CAFD70-C5BC-45F5-8066-1898CD37ED15}
35+
EndGlobalSection
36+
GlobalSection(ExtensibilityGlobals) = postSolution
37+
SolutionGuid = {5583C167-7201-443B-A1F5-2399CB6EF0C4}
38+
EndGlobalSection
39+
EndGlobal
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
using Rest.Api.Tests.EndpointTests.UnitTests.V1.TestData;
2+
using Rest.Api.Tests.Setup;
3+
using Newtonsoft.Json;
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Linq;
7+
using System.Net.Http.Json;
8+
using System.Threading.Tasks;
9+
using Xunit;
10+
using Rest.Api.Domain;
11+
using Rest.Api.Domain.Models;
12+
13+
namespace Rest.Api.Tests.EndpointTests.IntegrationTests
14+
{
15+
[Trait("Category", "Integration")]
16+
public class ProductControllerTest : IDisposable
17+
{
18+
private CustomWebApplicationFactory<Startup> factory;
19+
20+
public ProductControllerTest()
21+
{
22+
factory = new CustomWebApplicationFactory<Startup>();
23+
}
24+
25+
[Theory]
26+
[InlineData("en-US", "1")]
27+
[InlineData("en-US", "2")]
28+
public async Task GetAsync_Returns_200(string culture, string version)
29+
{
30+
// Given
31+
var client = factory.CreateClient();
32+
33+
// When
34+
var response = await client.GetAsync(string.Format(SampleDataV1.productEndpoint, culture, version));
35+
36+
// Then
37+
Assert.Equal(System.Net.HttpStatusCode.OK, response.StatusCode);
38+
}
39+
40+
[Theory]
41+
[InlineData("en-US", "1")]
42+
[InlineData("en-US", "2")]
43+
public async Task GetByIdAsync_Returns_200(string culture, string version)
44+
{
45+
// Given
46+
var client = factory.CreateClient();
47+
var addProductResponse = await client.PostAsJsonAsync(string.Format(SampleDataV1.productEndpoint, culture, version), SampleDataV1.Product);
48+
var addedProduct = JsonConvert.DeserializeObject<Product>(await addProductResponse.Content.ReadAsStringAsync());
49+
var id = addedProduct.Id;
50+
51+
// When
52+
var response = await client.GetAsync(string.Format(SampleDataV1.productEndpoint, culture, version) + $"/{id}");
53+
54+
// Then
55+
Assert.Equal(System.Net.HttpStatusCode.OK, response.StatusCode);
56+
}
57+
58+
[Theory]
59+
[InlineData("en-US", "1")]
60+
[InlineData("en-US", "2")]
61+
public async Task PostAsync_Returns_201(string culture, string version)
62+
{
63+
// Given
64+
var client = factory.CreateClient();
65+
66+
// When
67+
var response = await client.PostAsJsonAsync(string.Format(SampleDataV1.productEndpoint, culture, version), SampleDataV1.Product);
68+
69+
// Then
70+
Assert.Equal(System.Net.HttpStatusCode.Created, response.StatusCode);
71+
}
72+
73+
[Theory]
74+
[InlineData("en-US", "1")]
75+
[InlineData("en-US", "2")]
76+
public async Task PutAsync_Returns_204(string culture, string version)
77+
{
78+
// Given
79+
var client = factory.CreateClient();
80+
var addResponse = await client.PostAsJsonAsync(string.Format(SampleDataV1.productEndpoint, culture, version), SampleDataV1.Product);
81+
82+
var productResponse = await client.GetAsync(string.Format(SampleDataV1.productEndpoint, culture, version));
83+
var products = JsonConvert.DeserializeObject<List<ProductDTO>>(await productResponse.Content.ReadAsStringAsync());
84+
var id = products.FirstOrDefault().Id;
85+
var putRequestPayload = new Product
86+
{
87+
Id = products.FirstOrDefault().Id,
88+
Name = products.FirstOrDefault().Name,
89+
DeliveryPrice = products.FirstOrDefault().DeliveryPrice,
90+
Price = products.FirstOrDefault().Price,
91+
Description = products.FirstOrDefault().Description
92+
};
93+
94+
// When
95+
var response = await client.PutAsJsonAsync(string.Format(SampleDataV1.productEndpoint, culture, version) + $"/{id}", putRequestPayload);
96+
97+
// Then
98+
Assert.Equal(System.Net.HttpStatusCode.NoContent, response.StatusCode);
99+
}
100+
101+
[Theory]
102+
[InlineData("en-US", "1")]
103+
//[InlineData("en-US", "2")]
104+
public async Task DeleteAsync_Returns_204(string culture, string version)
105+
{
106+
// Given
107+
var client = factory.CreateClient();
108+
var addProductResponse = await client.PostAsJsonAsync(string.Format(SampleDataV1.productEndpoint, culture, version), SampleDataV1.Product);
109+
var addedProduct = JsonConvert.DeserializeObject<Product>(await addProductResponse.Content.ReadAsStringAsync());
110+
var id = addedProduct.Id;
111+
112+
// When
113+
var response = await client.DeleteAsync(string.Format(SampleDataV1.productEndpoint, culture, version) + $"/{id}");
114+
115+
// Then
116+
Assert.Equal(System.Net.HttpStatusCode.NoContent, response.StatusCode);
117+
}
118+
119+
public void Dispose()
120+
{
121+
factory = null;
122+
}
123+
}
124+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
using Rest.Api.Endpoints.V1.Products;
2+
using Rest.Api.Domain.Models;
3+
using Microsoft.AspNetCore.Http;
4+
using Microsoft.AspNetCore.Mvc;
5+
using Microsoft.EntityFrameworkCore;
6+
using Microsoft.Extensions.Logging;
7+
using Moq;
8+
using System;
9+
using System.Threading.Tasks;
10+
using Xunit;
11+
using Rest.Api.Tests.EndpointTests.UnitTests.V1.TestData;
12+
using Rest.Api.Datastore;
13+
14+
namespace Rest.Api.Tests.EndpointTests.UnitTests.V1.Products
15+
{
16+
[Trait("Category", "Unit")]
17+
public class CreateTest : IDisposable
18+
{
19+
private Mock<ILogger<ProductsController>> moqLogger;
20+
private DbContextOptions<Database> options;
21+
22+
public CreateTest()
23+
{
24+
moqLogger = new Mock<ILogger<ProductsController>>();
25+
options = new DbContextOptionsBuilder<Database>().UseInMemoryDatabase(databaseName: SampleDataV1.Database).Options;
26+
}
27+
28+
[Fact]
29+
public async Task PostAsync_Adds_Product_Successfully_With_Valid_Product_Details()
30+
{
31+
//Given
32+
using var moqDatabase = new Database(options);
33+
var sut = new ProductsController(moqLogger.Object, moqDatabase)
34+
{
35+
ControllerContext = new ControllerContext()
36+
};
37+
sut.ControllerContext.HttpContext = new DefaultHttpContext
38+
{
39+
TraceIdentifier = SampleDataV1.TraceIdentifier
40+
};
41+
var products = await moqDatabase.Products.CountAsync();
42+
43+
//When
44+
var actualResponse = await sut.PostAsync(SampleDataV1.Product, "en-us") as CreatedAtRouteResult;
45+
var actualResponsePayload = actualResponse.Value as Product;
46+
47+
//Then
48+
Assert.NotNull(actualResponse);
49+
Assert.Equal(StatusCodes.Status201Created, actualResponse.StatusCode);
50+
Assert.Equal(CONSTANTS.RouteNames.GetByIdAsync, actualResponse.RouteName);
51+
}
52+
53+
public void Dispose()
54+
{
55+
moqLogger = null;
56+
options = null;
57+
}
58+
}
59+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
using Rest.Api.Endpoints.V1.Products;
2+
using Rest.Api.Tests.EndpointTests.UnitTests.V1.TestData;
3+
using Rest.Api.Domain;
4+
using Microsoft.AspNetCore.Http;
5+
using Microsoft.AspNetCore.Mvc;
6+
using Microsoft.EntityFrameworkCore;
7+
using Microsoft.Extensions.Logging;
8+
using Moq;
9+
using System;
10+
using System.Threading.Tasks;
11+
using Xunit;
12+
using Rest.Api.Datastore;
13+
14+
namespace Rest.Api.Tests.EndpointTests.UnitTests.V1.Products
15+
{
16+
[Trait("Category", "Unit")]
17+
public class DeleteTest : IDisposable
18+
{
19+
private Database moqDatabase;
20+
private Mock<ILogger<ProductsController>> moqLogger;
21+
22+
public DeleteTest()
23+
{
24+
moqLogger = new Mock<ILogger<ProductsController>>();
25+
var options = new DbContextOptionsBuilder<Database>().UseInMemoryDatabase(databaseName: SampleDataV1.Database).Options;
26+
moqDatabase = new Database(options);
27+
}
28+
29+
[Fact]
30+
public async Task DeleteAsync_Deletes_Product_Successfully_With_Valid_Product_Id()
31+
{
32+
//Given
33+
var sut = new ProductsController(moqLogger.Object, moqDatabase)
34+
{
35+
ControllerContext = new ControllerContext()
36+
};
37+
sut.ControllerContext.HttpContext = new DefaultHttpContext
38+
{
39+
TraceIdentifier = SampleDataV1.TraceIdentifier
40+
};
41+
42+
var product = await moqDatabase.Products.AddAsync(SampleDataV1.Product); //adding the product to be database
43+
await moqDatabase.SaveAsync(); //saving the product to be deleted
44+
45+
//When
46+
var actualResponse = await sut.DeleteAsync(product.Entity.Id) as NoContentResult;
47+
48+
//Then
49+
Assert.NotNull(actualResponse);
50+
Assert.Equal(StatusCodes.Status204NoContent, actualResponse.StatusCode);
51+
}
52+
53+
public void Dispose()
54+
{
55+
moqDatabase = null;
56+
moqLogger = null;
57+
}
58+
}
59+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
using Rest.Api.Endpoints.V1.Products;
2+
using Rest.Api.Domain;
3+
using Microsoft.AspNetCore.Http;
4+
using Microsoft.AspNetCore.Mvc;
5+
using Microsoft.EntityFrameworkCore;
6+
using Microsoft.Extensions.Logging;
7+
using Moq;
8+
using System;
9+
using System.Collections.Generic;
10+
using System.Threading.Tasks;
11+
using Xunit;
12+
using Rest.Api.Domain.Models;
13+
using Rest.Api.Tests.EndpointTests.UnitTests.V1.TestData;
14+
using Rest.Api.Datastore;
15+
16+
namespace Rest.Api.Tests.EndpointTests.UnitTests.V1.Products
17+
{
18+
[Trait("Category", "Unit")]
19+
public class ReadTest : IDisposable
20+
{
21+
private Database moqDatabase;
22+
private Mock<ILogger<ProductsController>> moqLogger;
23+
private ProductsController sut;
24+
25+
public ReadTest()
26+
{
27+
moqLogger = new Mock<ILogger<ProductsController>>();
28+
var options = new DbContextOptionsBuilder<Database>().UseInMemoryDatabase(databaseName: SampleDataV1.Database).Options;
29+
moqDatabase = new Database(options);
30+
sut = new ProductsController(moqLogger.Object, moqDatabase)
31+
{
32+
ControllerContext = new ControllerContext()
33+
};
34+
sut.ControllerContext.HttpContext = new DefaultHttpContext
35+
{
36+
TraceIdentifier = SampleDataV1.TraceIdentifier
37+
};
38+
}
39+
40+
public void Dispose()
41+
{
42+
moqDatabase = null;
43+
moqLogger = null;
44+
sut = null;
45+
}
46+
47+
[Fact]
48+
public async Task GetAsync_Gets_All_Product_Successfully()
49+
{
50+
//Given
51+
var products = new List<Product>();
52+
products.Add(SampleDataV1.Product);
53+
products.Add(SampleDataV1.Product);
54+
moqDatabase.Products.AddRange(products); //adding the products to be database
55+
await moqDatabase.SaveAsync(); //saving the product to be deleted
56+
57+
//When
58+
var actualResponse = await sut.GetAsync() as OkObjectResult;
59+
var actualResponsePayload = actualResponse.Value as List<ProductDTO>;
60+
61+
//Then
62+
Assert.NotNull(actualResponse);
63+
Assert.Equal(StatusCodes.Status200OK, actualResponse.StatusCode);
64+
Assert.Equal(await moqDatabase.Products.CountAsync(), actualResponsePayload.Count);
65+
}
66+
67+
[Fact]
68+
public async Task GetByIdAsync_Gets_All_Product_Successfully()
69+
{
70+
//Given
71+
var product = await moqDatabase.Products.AddAsync(SampleDataV1.Product); //adding the product to be database
72+
await moqDatabase.SaveAsync(); //saving the product to be deleted
73+
74+
//When
75+
var actualResponse = await sut.GetByIdAsync(product.Entity.Id) as OkObjectResult;
76+
var actualResponsePayload = actualResponse.Value as ProductDTO;
77+
78+
//Then
79+
Assert.NotNull(actualResponse);
80+
Assert.Equal(StatusCodes.Status200OK, actualResponse.StatusCode);
81+
Assert.Equal(SampleDataV1.Product.Name, actualResponsePayload.Name);
82+
}
83+
}
84+
}

0 commit comments

Comments
 (0)