diff --git a/WebApi/EntityManagers/AnswerEntityManager.cs b/WebApi/EntityManagers/AnswerEntityManager.cs
index 119f676..73055b9 100644
--- a/WebApi/EntityManagers/AnswerEntityManager.cs
+++ b/WebApi/EntityManagers/AnswerEntityManager.cs
@@ -6,6 +6,9 @@ using OrderCriterias;
namespace EntityManagers
{
+ ///
+ /// a manager for answer entity
+ ///
public class AnswerEntityManager : IAnswerManager
{
private MyDbContext dbContext;
@@ -36,12 +39,20 @@ namespace EntityManagers
public IEnumerable getAnswers(int nb, int count, AnswerOrderCriteria orderCriteria = AnswerOrderCriteria.ById)
{
- return dbContext.Answers.OrderBy(a => a.Id).Skip((nb - 1) * count).Take(count).ToListAsync().Result;
+ if ((nb - 1) * count >= getNbElement()) throw new Exception("too many page skiped");
+ if (orderCriteria == AnswerOrderCriteria.ById)
+ {
+ return dbContext.Answers.OrderBy(a => a.Id).Skip((nb - 1) * count).Take(count).ToListAsync().Result;
+ }
+ else
+ {
+ return dbContext.Answers.OrderBy(a => a.Content).Skip((nb - 1) * count).Take(count).ToListAsync().Result;
+ }
}
public AnswerEntity? modifierAnswer(long id, AnswerEntity answer)
{
- var tmp = dbContext.Answers.Where(a => a.Id == id).FirstOrDefaultAsync().Result;
+ var tmp = getAnswer(id);
if (tmp == null) return null;
tmp.Content = answer.Content;
dbContext.SaveChangesAsync();
@@ -50,7 +61,7 @@ namespace EntityManagers
public AnswerEntity? supprimerAnswer(long id)
{
- var tmp = dbContext.Answers.Where(a => a.Id == id).FirstOrDefaultAsync().Result;
+ var tmp = getAnswer(id);
if (tmp == null) return null;
dbContext.Answers.Remove(tmp);
dbContext.SaveChangesAsync();
diff --git a/WebApi/ManagerInterfaces/IAnswerManager.cs b/WebApi/ManagerInterfaces/IAnswerManager.cs
index bf5cc69..f3bbb2f 100644
--- a/WebApi/ManagerInterfaces/IAnswerManager.cs
+++ b/WebApi/ManagerInterfaces/IAnswerManager.cs
@@ -1,29 +1,29 @@
-using OrderCriterias;
-
-namespace ManagerInterfaces
-{
+using OrderCriterias;
+
+namespace ManagerInterfaces
+{
///
/// All methods to handle answers
///
- /// a DTO or Entity type answer
- public interface IAnswerManager
- {
+ /// a DTO or Entity type answer
+ public interface IAnswerManager
+ {
///
/// get the number of T element
///
- /// the number of T element
- abstract int getNbElement();
+ /// the number of T element
+ abstract int getNbElement();
///
/// get a part of all answers
///
/// the actual page
/// number of T element in a page
/// the order criteria
- ///
- /// all T element of the database for
- /// this page (or null if (nb-1)*count
- /// is outside boundaries (0, getNbElement()-1)
- ///
+ ///
+ /// all T element of the database for
+ /// this page (or null if (nb-1)*count
+ /// is outside boundaries (0, getNbElement()-1)
+ ///
public IEnumerable? getAnswers(int nb, int count, AnswerOrderCriteria orderCriteria = AnswerOrderCriteria.ById);
///
/// get a T element with an id
@@ -60,7 +60,7 @@ namespace ManagerInterfaces
///
/// the T element (modified) that corresponde
/// to the id or null if there isn't any
- ///
- public T ajouterAnswer(T answer);
- }
-}
+ ///
+ public T ajouterAnswer(T answer);
+ }
+}
diff --git a/WebApi/UnitTestsEntityManagers/AbstractUnitTestEM.cs b/WebApi/UnitTestsEntityManagers/AbstractUnitTestEM.cs
new file mode 100644
index 0000000..9cbca87
--- /dev/null
+++ b/WebApi/UnitTestsEntityManagers/AbstractUnitTestEM.cs
@@ -0,0 +1,41 @@
+using DbConnectionLibrairie;
+using Microsoft.EntityFrameworkCore;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace UnitTestsEntityManagers
+{
+ ///
+ /// an abstract class to init the dbContext
+ /// (every unit tests need to implement it)
+ ///
+ public abstract class AbstractUnitTestEM
+ {
+ protected MyDbContext dbContext;
+
+ ///
+ /// constructor of the class :
+ /// initialise the dbContext
+ ///
+ public AbstractUnitTestEM()
+ {
+ var opt = new DbContextOptionsBuilder()
+ .UseSqlite("DataSource=:memory:")
+ .Options;
+
+ dbContext = new MyDbContext(opt);
+ }
+
+ ///
+ /// destructor of the class :
+ /// dispose the database context
+ ///
+ ~AbstractUnitTestEM()
+ {
+ dbContext.DisposeAsync();
+ }
+ }
+}
diff --git a/WebApi/UnitTestsEntityManagers/UnitTestAnswerManager.cs b/WebApi/UnitTestsEntityManagers/UnitTestAnswerManager.cs
new file mode 100644
index 0000000..ec3bd9d
--- /dev/null
+++ b/WebApi/UnitTestsEntityManagers/UnitTestAnswerManager.cs
@@ -0,0 +1,152 @@
+using DbConnectionLibrairie;
+using Entities;
+using EntityManagers;
+using static System.Net.WebRequestMethods;
+using Xunit.Abstractions;
+using System.Text.Json;
+using System.Net.Http.Json;
+using Newtonsoft.Json;
+
+namespace UnitTestsEntityManagers
+{
+
+ public class UnitTestAnswerManager : AbstractUnitTestEM
+ {
+ IEnumerable answers = JsonConvert
+ .DeserializeObject>
+ ("../FakeDatas/fake-Answer.json")!; // if this is null, we don't want to continue
+
+ AnswerEntityManager mgr;
+ public UnitTestAnswerManager()
+ : base()
+ {
+ mgr = new AnswerEntityManager(dbContext);
+ }
+
+ ///
+ /// test of the 'ajouterAnswer' method of an AnswerManager
+ ///
+ [Fact]
+ public void TestAjouterAnswer()
+ {
+ var answerToAdd = new AnswerEntity { Id = -1, Content = "châteîgne" };
+ var a = mgr.ajouterAnswer(answerToAdd);
+ // 1) with an id less than 0
+ // WF : it works so 'a' is not null,
+ // his content is equal to the
+ // content of 'answerToAdd'
+ // and since it's the first answer
+ // that we add, his id equal 0
+ Assert.NotNull(a);
+ Assert.Equal(answerToAdd.Content, a.Content);
+ Assert.NotEqual(0, a.Id);
+
+ answerToAdd = new AnswerEntity { Id = 5, Content = "damien" };
+ a = mgr.ajouterAnswer(answerToAdd);
+ // 2) with a random id greater than 0
+ // WF : it works so 'a' is not null,
+ // his content is equal to the
+ // content of 'answerToAdd'
+ // and since it's the second answer
+ // that we add, his id equal 1
+ Assert.NotNull(a);
+ Assert.Equal(answerToAdd.Content, a.Content);
+ Assert.NotEqual(1, a.Id);
+
+ answerToAdd = new AnswerEntity { Id = 7, Content = "châteîgne" };
+ a = mgr.ajouterAnswer(answerToAdd);
+ // 3) with a content that we already have added
+ // WF : it don't works so 'a' is null
+ Assert.Null(a);
+
+ answerToAdd = new AnswerEntity { Id = 7, Content = "CHÂTEÎGNE" };
+ a = mgr.ajouterAnswer(answerToAdd);
+ // 3) with a content that we already have added
+ // but in upperCase instead of lowerCase
+ // WF : it don't works so 'a' is null
+ Assert.Null(a);
+ }
+
+ ///
+ /// test of the 'supprimerAnswer' method of an AnswerManager
+ ///
+ [Fact]
+ public void TestSupprimerAnswer()
+ {
+ // remember that we have only 2 answers in the database :
+ // 1) (0, "châteigne")
+ // 2) (1, "damien")
+ var a = mgr.supprimerAnswer(-3);
+ // 1) with an id less than 0
+ // WF : it don't work because there's no
+ // negative id so 'a' is null
+ Assert.Null(a);
+
+ a = mgr.supprimerAnswer(3);
+ // 2) with an id greater or equal
+ // to the number of element
+ // WF : it don't works so 'a' is null,
+ Assert.Null(a);
+
+ a = mgr.supprimerAnswer(0);
+ // 1) with an id that belongs to an answer
+ // WF : it works so 'a' is not null,
+ // and since we've delete the answer with
+ // the id 0, the content is "châteigne"
+ Assert.NotNull(a);
+ Assert.Equal(0, a.Id);
+ Assert.Equal("châteigne", a.Content);
+
+ a = mgr.supprimerAnswer(0);
+ // 1) same thing with the id 1 just
+ // for cleaning the database
+ // WF : it works so 'a' is not null,
+ // and since we've delete the answer with
+ // the id 1, the content is "damien"
+ Assert.NotNull(a);
+ Assert.Equal(0, a.Id);
+ Assert.Equal("damien", a.Content);
+
+ // now, the database should be clean
+ }
+
+ // /!\ WARNING : since there was 2 answers added to the base,
+ // id index while now start at 2 (even though we've delete those)
+
+ ///
+ /// test of the 'getNbElement' method of an AnswerManager
+ ///
+ [Fact]
+ public void TestGetNbElement()
+ {
+ Assert.Equal(0, mgr.getNbElement()); // just to be sure
+
+ Assert.NotNull(answers); // just to be sure
+
+ int count = 0;
+ foreach (var answer in answers)
+ {
+ mgr.ajouterAnswer(answer);
+ count++;
+ Assert.Equal(count, mgr.getNbElement());
+ }
+ }
+
+ [Fact]
+ public void testGetAnswer()
+ {
+ // with an id which correspond of
+ // an answer which is in the database
+ foreach (var a in answers)
+ {
+ var tmp = mgr.getAnswer(a.Id+2);
+ Assert.NotNull(tmp);
+ Assert.Equal(a.Content, tmp.Content);
+ Assert.Equal(a.Id, tmp.Id);
+ }
+ }
+ // getAnswers
+
+ // modifierAnswer
+ }
+}
\ No newline at end of file
diff --git a/WebApi/UnitTestsEntityManagers/UnitTestsEntityManagers.csproj b/WebApi/UnitTestsEntityManagers/UnitTestsEntityManagers.csproj
new file mode 100644
index 0000000..089d180
--- /dev/null
+++ b/WebApi/UnitTestsEntityManagers/UnitTestsEntityManagers.csproj
@@ -0,0 +1,29 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+ false
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/WebApi/WebApi.sln b/WebApi/WebApi.sln
index c164e9f..8b3e568 100644
--- a/WebApi/WebApi.sln
+++ b/WebApi/WebApi.sln
@@ -3,8 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.9.34607.119
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebApplication", "WebApplication\WebApplication.csproj", "{9F05B995-3079-4905-A9B1-7B3E8621ECC1}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Entities", "Entities\Entities.csproj", "{19A1AA55-0FDF-427F-97EA-157E816C93CE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DbConnectionLibrairie", "DbConnectionLibrairie\DbConnectionLibrairie.csproj", "{8224E470-B008-4738-88FD-7DEDCAA4AE44}"
@@ -13,9 +11,16 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ManagerInterfaces", "Manage
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DTOs", "DTOs\DTOs.csproj", "{F911181D-6194-4CA9-A302-7A055652E5FA}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EntityManagers", "EntityManagers\EntityManagers.csproj", "{FAAF96CF-33DD-406A-B42D-E5768D3C46BB}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EntityManagers", "EntityManagers\EntityManagers.csproj", "{FAAF96CF-33DD-406A-B42D-E5768D3C46BB}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OrderCriterias", "OrderCriterias\OrderCriterias.csproj", "{EE565F87-6811-46C8-A03B-6550D692873A}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTestsEntityManagers", "UnitTestsEntityManagers\UnitTestsEntityManagers.csproj", "{6E2E46BB-91F0-4F5C-B378-A54E4F80ED0C}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OrderCriterias", "OrderCriterias\OrderCriterias.csproj", "{EE565F87-6811-46C8-A03B-6550D692873A}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FakeDatas", "FakeDatas", "{AB3977C6-DAF2-4E93-B2C4-BB33A9CAFC71}"
+ ProjectSection(SolutionItems) = preProject
+ FakeDatas\fake-Answers.json = FakeDatas\fake-Answers.json
+ EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -23,10 +28,6 @@ Global
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {9F05B995-3079-4905-A9B1-7B3E8621ECC1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {9F05B995-3079-4905-A9B1-7B3E8621ECC1}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {9F05B995-3079-4905-A9B1-7B3E8621ECC1}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {9F05B995-3079-4905-A9B1-7B3E8621ECC1}.Release|Any CPU.Build.0 = Release|Any CPU
{19A1AA55-0FDF-427F-97EA-157E816C93CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{19A1AA55-0FDF-427F-97EA-157E816C93CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{19A1AA55-0FDF-427F-97EA-157E816C93CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -51,6 +52,10 @@ Global
{EE565F87-6811-46C8-A03B-6550D692873A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EE565F87-6811-46C8-A03B-6550D692873A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EE565F87-6811-46C8-A03B-6550D692873A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6E2E46BB-91F0-4F5C-B378-A54E4F80ED0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6E2E46BB-91F0-4F5C-B378-A54E4F80ED0C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6E2E46BB-91F0-4F5C-B378-A54E4F80ED0C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6E2E46BB-91F0-4F5C-B378-A54E4F80ED0C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/WebApi/WebApplication/Controllers/WeatherForecastController.cs b/WebApi/WebApplication/Controllers/WeatherForecastController.cs
deleted file mode 100644
index 6377a80..0000000
--- a/WebApi/WebApplication/Controllers/WeatherForecastController.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using Microsoft.AspNetCore.Mvc;
-
-namespace WebApplication.Controllers
-{
- [ApiController]
- [Route("[controller]")]
- public class WeatherForecastController : ControllerBase
- {
- private static readonly string[] Summaries = new[]
- {
- "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
- };
-
- private readonly ILogger _logger;
-
- public WeatherForecastController(ILogger logger)
- {
- _logger = logger;
- }
-
- [HttpGet(Name = "GetWeatherForecast")]
- public IEnumerable Get()
- {
- return Enumerable.Range(1, 5).Select(index => new WeatherForecast
- {
- Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
- TemperatureC = Random.Shared.Next(-20, 55),
- Summary = Summaries[Random.Shared.Next(Summaries.Length)]
- })
- .ToArray();
- }
- }
-}
diff --git a/WebApi/WebApplication/Program.cs b/WebApi/WebApplication/Program.cs
deleted file mode 100644
index 48863a6..0000000
--- a/WebApi/WebApplication/Program.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-var builder = WebApplication.CreateBuilder(args);
-
-// Add services to the container.
-
-builder.Services.AddControllers();
-// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
-builder.Services.AddEndpointsApiExplorer();
-builder.Services.AddSwaggerGen();
-
-var app = builder.Build();
-
-// Configure the HTTP request pipeline.
-if (app.Environment.IsDevelopment())
-{
- app.UseSwagger();
- app.UseSwaggerUI();
-}
-
-app.UseHttpsRedirection();
-
-app.UseAuthorization();
-
-app.MapControllers();
-
-app.Run();
diff --git a/WebApi/WebApplication/Properties/launchSettings.json b/WebApi/WebApplication/Properties/launchSettings.json
deleted file mode 100644
index 9fd4ce5..0000000
--- a/WebApi/WebApplication/Properties/launchSettings.json
+++ /dev/null
@@ -1,41 +0,0 @@
-{
- "$schema": "http://json.schemastore.org/launchsettings.json",
- "iisSettings": {
- "windowsAuthentication": false,
- "anonymousAuthentication": true,
- "iisExpress": {
- "applicationUrl": "http://localhost:62623",
- "sslPort": 44358
- }
- },
- "profiles": {
- "http": {
- "commandName": "Project",
- "dotnetRunMessages": true,
- "launchBrowser": true,
- "launchUrl": "swagger",
- "applicationUrl": "http://localhost:5228",
- "environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
- }
- },
- "https": {
- "commandName": "Project",
- "dotnetRunMessages": true,
- "launchBrowser": true,
- "launchUrl": "swagger",
- "applicationUrl": "https://localhost:7256;http://localhost:5228",
- "environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
- }
- },
- "IIS Express": {
- "commandName": "IISExpress",
- "launchBrowser": true,
- "launchUrl": "swagger",
- "environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
- }
- }
- }
-}
diff --git a/WebApi/WebApplication/WeatherForecast.cs b/WebApi/WebApplication/WeatherForecast.cs
deleted file mode 100644
index bfdf165..0000000
--- a/WebApi/WebApplication/WeatherForecast.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-namespace WebApplication
-{
- public class WeatherForecast
- {
- public DateOnly Date { get; set; }
-
- public int TemperatureC { get; set; }
-
- public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
-
- public string? Summary { get; set; }
- }
-}
diff --git a/WebApi/WebApplication/WebApplication.csproj b/WebApi/WebApplication/WebApplication.csproj
deleted file mode 100644
index 9daa180..0000000
--- a/WebApi/WebApplication/WebApplication.csproj
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
- net8.0
- enable
- enable
-
-
-
-
-
-
-
diff --git a/WebApi/WebApplication/WebApplication.http b/WebApi/WebApplication/WebApplication.http
deleted file mode 100644
index 9c6f7be..0000000
--- a/WebApi/WebApplication/WebApplication.http
+++ /dev/null
@@ -1,6 +0,0 @@
-@WebApplication_HostAddress = http://localhost:5228
-
-GET {{WebApplication_HostAddress}}/weatherforecast/
-Accept: application/json
-
-###
diff --git a/WebApi/WebApplication/appsettings.Development.json b/WebApi/WebApplication/appsettings.Development.json
deleted file mode 100644
index 0c208ae..0000000
--- a/WebApi/WebApplication/appsettings.Development.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "Logging": {
- "LogLevel": {
- "Default": "Information",
- "Microsoft.AspNetCore": "Warning"
- }
- }
-}
diff --git a/WebApi/WebApplication/appsettings.json b/WebApi/WebApplication/appsettings.json
deleted file mode 100644
index 10f68b8..0000000
--- a/WebApi/WebApplication/appsettings.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "Logging": {
- "LogLevel": {
- "Default": "Information",
- "Microsoft.AspNetCore": "Warning"
- }
- },
- "AllowedHosts": "*"
-}