Merge pull request 'Implementation des commentaires' (#44) from feature/40-comments into dev
continuous-integration/drone/push Build is passing Details

Reviewed-on: #44
pull/49/head
Alexandre AGOSTINHO 2 years ago
commit cf98aee581

@ -11,34 +11,36 @@ Console.WriteLine("Hello, World!\n\n");
// TESTS:
DataManager dataMgr = new DataManager(new Stubs());
//DataManager dataMgr = new DataManager(new DataContractXML(xmlFolderPath: "../../../../DataPersistence/data"));
//DataManager dataMgr = new DataManager(new Stubs());
DataManager dataMgr = new DataManager(new DataContractXML());
//DataManager dataMgr = new DataManager(new DataContractJSON());
//dataMgr.Serializer = new DataContractXML(xmlFolderPath: "../../../../DataPersistence/data");
dataMgr.Serializer = new DataContractJSON();
//dataMgr.Serializer = new DataContractXML();
//dataMgr.Serializer = new DataContractJSON();
// /!\ here is an absolute path I put for testing purpose. It will only work on my computer so don't forget to change it whene you test.
//dataMgr.Export(rc[2], "C:\\Users\\alex6\\Downloads\\recipe2.json");
//dataMgr.Import<Recipe>("C:\\Users\\alex6\\Downloads\\recipe2.json");
Stub stub = new Stub();
PasswordManager passwordManager = new PasswordManager();
RecipeCollection rc = new RecipeCollection("All recipes", dataMgr.Data[nameof(Recipe)].Cast<Recipe>().ToArray());
User user = dataMgr.Data[nameof(User)].Cast<User>().Last();
//rc[0].AddReview(new Review(user, 1, "bonne recette !1"));
//rc[0].AddReview(new Review(user, 1, "bonne recette !2"));
//rc[0].AddReview(new Review(user, 4, "bonne recette !3"));
//rc[0].AddReview(new Review(user, 5, "bonne recette !4"));
//rc[0].AddReview(new Review(user, 3, "bonne recette !5"));
//rc[0].AddReview(new Review(user, 2, "bonne recette !6"));
//rc[0].AddReview(new Review(user, 2, "peut etre pas ducoup !"));
//rc[1].AddReview(new Review(user, 2, "Mais celle-ci oui !"));
dataMgr.Save();
MenuManager menuMgr = new MenuManager(dataMgr);
menuMgr.Loop();
foreach (RecipeCollection r in recipeCollections)
Console.WriteLine(r);
List<User> users = stub.ConstrucList();
foreach (User u in users)
Console.WriteLine(u);
bool isPassCorrect = stub.VerifPass();
Console.WriteLine(isPassCorrect);
Console.WriteLine(passwordManager.VerifyPassword(user.Password, "pamigos"));
Console.ReadKey();

@ -1,79 +0,0 @@
using Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp
{
internal struct Stub
{
private IPasswordManager passwordManager = new PasswordManager();
public List<Recipe> LoadRecipes()
{
List<Recipe> stub = new List<Recipe>();
stub.AddRange(new[]
{
new Recipe(),
new Recipe("Cookies"),
new Recipe("Cookies", 23),
new Recipe("Cookies", null),
new Recipe("", null),
new Recipe("", 24),
new Recipe("Cookies", 24,
new PreparationStep(1)),
new Recipe("Cookies", 26,
new PreparationStep(1),
new PreparationStep(2, "Faire cuire."))
});
return stub;
}
public List<RecipeCollection> LoadRecipeCollection()
{
List<RecipeCollection> stub = new List<RecipeCollection>();
stub.AddRange(new[]
{
new RecipeCollection("All", LoadRecipes().ToArray()),
new RecipeCollection("Starters", LoadRecipes().FindAll(x => x.Id.Equals(23)).ToArray()),
new RecipeCollection("Dishies", LoadRecipes().FindAll(x => x.Id.Equals(24)).ToArray()),
new RecipeCollection("Desserts", LoadRecipes().FindAll(x => x.Id.Equals(26)).ToArray()),
});
return stub;
}
public List<User> ConstrucList()
{
List<User> Users = new List<User>();
User Roger = new User("Roger", "Rabbit", "carotte@mail.fr",passwordManager.HashPassword("password"));
User Dylan = new User("d", "r", "dr@mail.fr", passwordManager.HashPassword("dede"));
User Val = new User("V", "entin", "Valentin@mail.fr", passwordManager.HashPassword("valentin"));
Users.Add(Roger);
Users.Add(Dylan);
Users.Add(Val);
return Users;
}
public bool VerifPass()
{
User John = new User("John", "Doe", "JD@gmail.com", passwordManager.HashPassword("GIJD"));
string entryPass = "GIJD";
User Val = new User("V", "entin", "Valentin@mail.fr", passwordManager.HashPassword("valentin"));
Val.Password = passwordManager.HashPassword("jeChange");
bool isPasswordCorrect = passwordManager.VerifyPassword(John.Password, entryPass);
return isPasswordCorrect;
}
public Stub()
{
}
}
}

@ -34,7 +34,12 @@ namespace DataPersistence
if (dataContractJsonSerializerSettings is null)
_dataContractJsonSerializerSettings = new DataContractJsonSerializerSettings()
{
KnownTypes = new[] { typeof(Recipe) }
KnownTypes = new[]
{
typeof(Recipe),
typeof(Review),
typeof(User)
}
};
else
_dataContractJsonSerializerSettings = dataContractJsonSerializerSettings;

@ -42,7 +42,12 @@ namespace DataPersistence
if (dataContractSerializerSettings is null)
_dataContractSerializerSettings = new DataContractSerializerSettings()
{
KnownTypes = new Type[] { typeof(Recipe) },
KnownTypes = new Type[]
{
typeof(Recipe),
typeof(Review),
typeof(User)
},
PreserveObjectReferences = true
};
else

@ -10,8 +10,4 @@
<ProjectReference Include="..\Model\Model.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="data\" />
</ItemGroup>
</Project>

@ -14,6 +14,8 @@ namespace DataPersistence
{
public Dictionary<string, List<object>> Load()
{
PasswordManager passwordManager = new PasswordManager();
Dictionary<string, List<object>> data = new Dictionary<string, List<object>>
{
{
@ -86,6 +88,24 @@ namespace DataPersistence
})
})
#endregion
},
{
#region Data: User
nameof(User),
new List<object>(new[]
{
new User(
name: "Admin",
surname: "Admin",
mail: "admin@mctg.fr",
password: passwordManager.HashPassword("admin")),
new User(
name: "Pedros",
surname: "Amigos",
mail: "pedrosamigos@hotmail.com",
password: passwordManager.HashPassword("pamigos"))
})
#endregion
}
};

@ -1,168 +0,0 @@
[
{
"Key": "Recipe",
"Value": [
{
"__type": "recipe:#Model",
"id": 26700,
"preparation-steps": [
{
"description": "Faire cuire.",
"order": 1
},
{
"description": "Manger.",
"order": 2
}
],
"title": "Cookies classiques"
},
{
"__type": "recipe:#Model",
"id": 16433,
"preparation-steps": [
{
"description": "Moulinez la pâte.",
"order": 1
},
{
"description": "Faire cuire pendant une bonne heure.",
"order": 2
},
{
"description": "Sortir du four et mettre dans un plat.",
"order": 3
}
],
"title": "Cookies au chocolat"
},
{
"__type": "recipe:#Model",
"id": 26093,
"preparation-steps": [
{
"description": "Achetez les ingrédients.",
"order": 1
},
{
"description": "Préparez le matériel. Ustensiles et tout.",
"order": 2
},
{
"description": "Pleurez.",
"order": 3
}
],
"title": "Gateau nature"
},
{
"__type": "recipe:#Model",
"id": 21481,
"preparation-steps": [
{
"description": "Achetez les légumes.",
"order": 1
},
{
"description": "Préparez le plat. Ustensiles et préchauffez le four.",
"order": 2
},
{
"description": "Coupez les pommes en morceaux et disposez-les sur le plat.",
"order": 3
},
{
"description": "Mettez enfin le plat au four, puis une fois cuit, dégustez !",
"order": 4
}
],
"title": "Gateau au pommes"
},
{
"__type": "recipe:#Model",
"id": 15049,
"preparation-steps": [
{
"description": "Ajouter les oeufs.",
"order": 1
},
{
"description": "Ajouter la farine.",
"order": 2
},
{
"description": "Ajouter 100g de chocolat fondu.",
"order": 3
},
{
"description": "Mélanger le tout.",
"order": 4
},
{
"description": "Faire cuire 45h au four traditionnel.",
"order": 5
}
],
"title": "Gateau au chocolat"
},
{
"__type": "recipe:#Model",
"id": 28153,
"preparation-steps": [
{
"description": "Faire une cuisson bien sec de la dinde à la poêle",
"order": 1
},
{
"description": "Mettre la dinde au frigo.",
"order": 2
},
{
"description": "Mettre le jambon dans le micro-onde.",
"order": 3
},
{
"description": "Faire chauffer 3min.",
"order": 4
},
{
"description": "Présentez sur un plat la dinde et le jambon : Miam !",
"order": 5
}
],
"title": "Dinde au jambon"
},
{
"__type": "recipe:#Model",
"id": 8053,
"preparation-steps": [
{
"description": "Trouvez des épices de curry.",
"order": 1
},
{
"description": "Trouvez maintenant du poulet.",
"order": 2
},
{
"description": "Coupez la tête du poulet et posez-la dans un plat.",
"order": 3
},
{
"description": "Parsemez d'épices curry la tête de la poule.",
"order": 4
},
{
"description": "Mettre le tout au four traditionnel 30min.",
"order": 5
},
{
"description": "Dégustez en famille !",
"order": 6
}
],
"title": "Poulet au curry"
}
]
}
]

@ -1,184 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<ArrayOfKeyValueOfstringArrayOfanyTypety7Ep6D1 xmlns:i="http://www.w3.org/2001/XMLSchema-instance" z:Id="1" z:Size="1" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<KeyValueOfstringArrayOfanyTypety7Ep6D1>
<Key z:Id="2">Recipe</Key>
<Value z:Id="3" z:Size="8">
<anyType z:Id="4" xmlns:d4p1="http://schemas.datacontract.org/2004/07/Model" i:type="d4p1:recipe">
<d4p1:id>9062</d4p1:id>
<d4p1:preparation-steps z:Id="5" z:Size="2">
<d4p1:preparation-step z:Id="6">
<d4p1:description z:Id="7">Faire cuire.</d4p1:description>
<d4p1:order>1</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="8">
<d4p1:description z:Id="9">Manger.</d4p1:description>
<d4p1:order>2</d4p1:order>
</d4p1:preparation-step>
</d4p1:preparation-steps>
<d4p1:title z:Id="10">Cookies classiques</d4p1:title>
</anyType>
<anyType z:Id="11" xmlns:d4p1="http://schemas.datacontract.org/2004/07/Model" i:type="d4p1:recipe">
<d4p1:id>27627</d4p1:id>
<d4p1:preparation-steps z:Id="12" z:Size="3">
<d4p1:preparation-step z:Id="13">
<d4p1:description z:Id="14">Moulinez la pâte.</d4p1:description>
<d4p1:order>1</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="15">
<d4p1:description z:Id="16">Faire cuire pendant une bonne heure.</d4p1:description>
<d4p1:order>2</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="17">
<d4p1:description z:Id="18">Sortir du four et mettre dans un plat.</d4p1:description>
<d4p1:order>3</d4p1:order>
</d4p1:preparation-step>
</d4p1:preparation-steps>
<d4p1:title z:Id="19">Cookies au chocolat</d4p1:title>
</anyType>
<anyType z:Id="20" xmlns:d4p1="http://schemas.datacontract.org/2004/07/Model" i:type="d4p1:recipe">
<d4p1:id>8517</d4p1:id>
<d4p1:preparation-steps z:Id="21" z:Size="3">
<d4p1:preparation-step z:Id="22">
<d4p1:description z:Id="23">Achetez les ingrédients.</d4p1:description>
<d4p1:order>1</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="24">
<d4p1:description z:Id="25">Préparez le matériel. Ustensiles et tout.</d4p1:description>
<d4p1:order>2</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="26">
<d4p1:description z:Id="27">Pleurez.</d4p1:description>
<d4p1:order>3</d4p1:order>
</d4p1:preparation-step>
</d4p1:preparation-steps>
<d4p1:title z:Id="28">Gateau nature</d4p1:title>
</anyType>
<anyType z:Id="29" xmlns:d4p1="http://schemas.datacontract.org/2004/07/Model" i:type="d4p1:recipe">
<d4p1:id>6161</d4p1:id>
<d4p1:preparation-steps z:Id="30" z:Size="4">
<d4p1:preparation-step z:Id="31">
<d4p1:description z:Id="32">Achetez les légumes.</d4p1:description>
<d4p1:order>1</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="33">
<d4p1:description z:Id="34">Préparez le plat. Ustensiles et préchauffez le four.</d4p1:description>
<d4p1:order>2</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="35">
<d4p1:description z:Id="36">Coupez les pommes en morceaux et disposez-les sur le plat.</d4p1:description>
<d4p1:order>3</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="37">
<d4p1:description z:Id="38">Mettez enfin le plat au four, puis une fois cuit, dégustez !</d4p1:description>
<d4p1:order>4</d4p1:order>
</d4p1:preparation-step>
</d4p1:preparation-steps>
<d4p1:title z:Id="39">Gateau au pommes</d4p1:title>
</anyType>
<anyType z:Id="40" xmlns:d4p1="http://schemas.datacontract.org/2004/07/Model" i:type="d4p1:recipe">
<d4p1:id>17869</d4p1:id>
<d4p1:preparation-steps z:Id="41" z:Size="5">
<d4p1:preparation-step z:Id="42">
<d4p1:description z:Id="43">Ajouter les oeufs.</d4p1:description>
<d4p1:order>1</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="44">
<d4p1:description z:Id="45">Ajouter la farine.</d4p1:description>
<d4p1:order>2</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="46">
<d4p1:description z:Id="47">Ajouter 100g de chocolat fondu.</d4p1:description>
<d4p1:order>3</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="48">
<d4p1:description z:Id="49">Mélanger le tout.</d4p1:description>
<d4p1:order>4</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="50">
<d4p1:description z:Id="51">Faire cuire 45h au four traditionnel.</d4p1:description>
<d4p1:order>5</d4p1:order>
</d4p1:preparation-step>
</d4p1:preparation-steps>
<d4p1:title z:Id="52">Gateau au chocolat</d4p1:title>
</anyType>
<anyType z:Id="53" xmlns:d4p1="http://schemas.datacontract.org/2004/07/Model" i:type="d4p1:recipe">
<d4p1:id>4810</d4p1:id>
<d4p1:preparation-steps z:Id="54" z:Size="5">
<d4p1:preparation-step z:Id="55">
<d4p1:description z:Id="56">Faire une cuisson bien sec de la dinde à la poêle</d4p1:description>
<d4p1:order>1</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="57">
<d4p1:description z:Id="58">Mettre la dinde au frigo.</d4p1:description>
<d4p1:order>2</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="59">
<d4p1:description z:Id="60">Mettre le jambon dans le micro-onde.</d4p1:description>
<d4p1:order>3</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="61">
<d4p1:description z:Id="62">Faire chauffer 3min.</d4p1:description>
<d4p1:order>4</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="63">
<d4p1:description z:Id="64">Présentez sur un plat la dinde et le jambon : Miam !</d4p1:description>
<d4p1:order>5</d4p1:order>
</d4p1:preparation-step>
</d4p1:preparation-steps>
<d4p1:title z:Id="65">Dinde au jambon</d4p1:title>
</anyType>
<anyType z:Id="66" xmlns:d4p1="http://schemas.datacontract.org/2004/07/Model" i:type="d4p1:recipe">
<d4p1:id>13570</d4p1:id>
<d4p1:preparation-steps z:Id="67" z:Size="6">
<d4p1:preparation-step z:Id="68">
<d4p1:description z:Id="69">Trouvez des épices de curry.</d4p1:description>
<d4p1:order>1</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="70">
<d4p1:description z:Id="71">Trouvez maintenant du poulet.</d4p1:description>
<d4p1:order>2</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="72">
<d4p1:description z:Id="73">Coupez la tête du poulet et posez-la dans un plat.</d4p1:description>
<d4p1:order>3</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="74">
<d4p1:description z:Id="75">Parsemez d'épices curry la tête de la poule.</d4p1:description>
<d4p1:order>4</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="76">
<d4p1:description z:Id="77">Mettre le tout au four traditionnel 30min.</d4p1:description>
<d4p1:order>5</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="78">
<d4p1:description z:Id="79">Dégustez en famille !</d4p1:description>
<d4p1:order>6</d4p1:order>
</d4p1:preparation-step>
</d4p1:preparation-steps>
<d4p1:title z:Id="80">Poulet au curry</d4p1:title>
</anyType>
<anyType z:Id="81" xmlns:d4p1="http://schemas.datacontract.org/2004/07/Model" i:type="d4p1:recipe">
<d4p1:id>26918</d4p1:id>
<d4p1:preparation-steps z:Id="82" z:Size="4">
<d4p1:preparation-step z:Id="83">
<d4p1:description z:Id="84">Achetez les ingrédients.</d4p1:description>
<d4p1:order>1</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="85">
<d4p1:description z:Id="86">Préparez le matériel. Ustensiles et tout.</d4p1:description>
<d4p1:order>2</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="87">
<d4p1:description z:Id="88">Pleurez.</d4p1:description>
<d4p1:order>3</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="89">
<d4p1:description z:Id="90">Aprenez de vos echecs.</d4p1:description>
<d4p1:order>4</d4p1:order>
</d4p1:preparation-step>
</d4p1:preparation-steps>
<d4p1:title z:Id="91">Gateau nature v2</d4p1:title>
</anyType>
</Value>
</KeyValueOfstringArrayOfanyTypety7Ep6D1>
</ArrayOfKeyValueOfstringArrayOfanyTypety7Ep6D1>

@ -1,106 +1,170 @@
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Security.Cryptography;
using System.Text;
namespace Model
{
/// <summary>
/// Define a Recipe for the preparation of a meal.
/// </summary>
[DataContract(Name = "recipe")]
public class Recipe : IEquatable<Recipe>
{
#region Attributes
[DataMember(Name = "title")]
private string _title = "";
#endregion
#region Properties
/// <summary>
/// The ID of the recipe - allows you to compare and/or get this item in an easier way.
/// </summary>
[DataMember(Name = "id")]
public int Id { get; init; }
/// <summary>
/// The Title of the recipe. <br/>
/// Set to "No title." when the value passed is null, empty or contain white spaces.
/// </summary>
public string Title
{
get => _title;
set
{
if (string.IsNullOrWhiteSpace(value))
_title = "No title.";
else
_title = value;
}
}
/// <summary>
/// The steps of the preparation. See: <see cref="PreparationStep"/>.
/// </summary>
[DataMember(Name = "preparation-steps")]
public List<PreparationStep> PreparationSteps { get; set; }
#endregion
#region Constructors
/// <summary>
/// Construct a new recipe.
/// </summary>
/// <param name="title">The title of the recipe</param>
/// <param name="id">The id of the recipe. If not given, get a new id.</param>
/// <param name="preparationSteps">The steps of the preparation of the meal</param>
public Recipe(string title = "", int? id = null,
params PreparationStep[] preparationSteps)
{
Title = title;
PreparationSteps = new List<PreparationStep>(preparationSteps);
if (id == null)
{
var randomGenerator = RandomNumberGenerator.Create();
byte[] data = new byte[16];
randomGenerator.GetBytes(data);
Id = Math.Abs(BitConverter.ToInt16(data));
}
else Id = (int)id;
}
#endregion
#region Methods
public virtual bool Equals(Recipe? other)
{
if (other == null) return false;
if (other == this) return true;
return Title.Equals(other.Title) && PreparationSteps.Equals(other.PreparationSteps);
}
public override bool Equals(object? obj)
{
var item = obj as Recipe;
if (item == null) return false;
return Equals(obj);
}
public override int GetHashCode()
{
return Id.GetHashCode();
}
public override string ToString()
{
StringBuilder sb = new StringBuilder($"[Recipe n°{Id}] - {Title}\n");
foreach (PreparationStep ps in PreparationSteps)
{
sb.AppendFormat("\t* {0}\n", ps.ToString());
}
return sb.ToString();
}
#endregion
}
}
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Security.Cryptography;
using System.Text;
namespace Model
{
/// <summary>
/// Define a Recipe for the preparation of a meal.
/// </summary>
[DataContract(Name = "recipe")]
public class Recipe : IEquatable<Recipe>
{
#region Attributes
[DataMember(Name = "title")]
private string _title = "";
#endregion
#region Properties
/// <summary>
/// The ID of the recipe - allows you to compare and/or get this item in an easier way.
/// </summary>
[DataMember(Name = "id")]
public int Id { get; init; }
/// <summary>
/// List of reviews of this recipe.
/// </summary>
[DataMember(Name = "reviews")]
public List<Review> Reviews { get; private set; }
/// <summary>
/// The Title of the recipe. <br/>
/// Set to "No title." when the value passed is null, empty or contain white spaces.
/// </summary>
public string Title
{
get => _title;
set
{
if (string.IsNullOrWhiteSpace(value))
_title = "No title.";
else
_title = value;
}
}
/// <summary>
/// The steps of the preparation. See: <see cref="PreparationStep"/>.
/// </summary>
[DataMember(Name = "preparation-steps")]
public List<PreparationStep> PreparationSteps { get; set; }
#endregion
#region Constructors
/// <summary>
/// Construct a new recipe.
/// </summary>
/// <param name="title">The title of the recipe</param>
/// <param name="id">The id of the recipe. If not given, get a new id.</param>
/// <param name="preparationSteps">The steps of the preparation of the meal</param>
public Recipe(string title, int? id,
List<Review> reviews,
params PreparationStep[] preparationSteps)
{
Title = title;
PreparationSteps = new List<PreparationStep>(preparationSteps);
Reviews = reviews;
if (id == null)
{
var randomGenerator = RandomNumberGenerator.Create();
byte[] data = new byte[16];
randomGenerator.GetBytes(data);
Id = Math.Abs(BitConverter.ToInt16(data));
}
else Id = (int)id;
}
/// <summary>
/// <inheritdoc cref="Recipe.Recipe(string, int?, List{Review}, PreparationStep[])"/>
/// </summary>
/// <param name="title">The title of the recipe.</param>
public Recipe(string title)
: this(title, null, new List<Review>())
{
}
/// <summary>
/// <inheritdoc cref="Recipe.Recipe(string, int?, List{Review}, PreparationStep[])"/>
/// </summary>
/// <param name="title">The title of the recipe.</param>
/// <param name="preparationSteps">The steps of the preparation of the meal.</param>
public Recipe(string title, params PreparationStep[] preparationSteps)
: this(title, null, new List<Review>(), preparationSteps)
{
}
/// <summary>
/// <inheritdoc cref="Recipe.Recipe(string, int?, List{Review}, PreparationStep[])"/>
/// </summary>
/// <param name="title">The title of the recipe.</param>
/// <param name="id">The id of the recipe. If not given, get a new id.</param>
/// <param name="preparationSteps">The steps of the preparation of the meal.</param>
public Recipe(string title, int? id, params PreparationStep[] preparationSteps)
: this(title, id, new List<Review>(), preparationSteps)
{
}
#endregion
#region Methods
/// <summary>
/// Add a review for the recipe.
/// </summary>
/// <param name="review">The new review to add.</param>
public void AddReview(Review review)
=> Reviews.Add(review);
/// <summary>
/// Get a string representing all the reviews and their informations.
/// </summary>
/// <returns></returns>
public string GetReviews()
{
StringBuilder sb = new StringBuilder("Reviews:\n------------------------------\n");
foreach (Review review in Reviews)
{
sb.AppendLine(review.ToString());
}
return sb.ToString();
}
public virtual bool Equals(Recipe? other)
{
if (other == null) return false;
if (other == this) return true;
return Title.Equals(other.Title) && PreparationSteps.Equals(other.PreparationSteps);
}
public override bool Equals(object? obj)
{
var item = obj as Recipe;
if (item == null) return false;
return Equals(obj);
}
public override int GetHashCode()
{
return Id.GetHashCode();
}
public override string ToString()
{
StringBuilder sb = new StringBuilder($"[Recipe n°{Id}] - {Title}\n");
foreach (PreparationStep ps in PreparationSteps)
{
sb.AppendFormat("\t* {0}\n", ps.ToString());
}
sb.AppendLine();
foreach (Review review in Reviews)
{
sb.AppendLine(review.ToString());
}
return sb.ToString();
}
#endregion
}
}

@ -0,0 +1,99 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace Model
{
[DataContract(Name = "review")]
public class Review : IEquatable<Review>
{
[DataMember(Name = "stars")]
private int _stars;
[DataMember(Name = "content")]
private string _content = "";
[DataMember(Name = "id")]
public int Id { get; init; }
[DataMember(Name = "user")]
public User Author { get; private set; }
public int Stars
{
get => _stars;
set
{
if (value < 0 || value > 5) throw new ArgumentException(nameof(Stars));
else _stars = value;
}
}
public string Content
{
get => _content;
set
{
if (string.IsNullOrEmpty(value)) _content = "No data...";
else _content = value;
}
}
public Review(User author, int? id, int stars, string content)
{
if (id == null)
{
var randomGenerator = RandomNumberGenerator.Create();
byte[] data = new byte[16];
randomGenerator.GetBytes(data);
Id = Math.Abs(BitConverter.ToInt16(data));
}
else Id = (int)id;
Author = author;
Stars = stars;
Content = content;
}
public Review(User author, int stars, string content)
: this(author, null, stars, content)
{
}
public Review(int stars, string content)
: this(new User("admin", "admin", "admin@mctg.fr", new PasswordManager().HashPassword("admin")),
null, stars, content)
{
}
public override string ToString()
{
return $"{Author.Name} {Author.Surname}: [ {Stars} stars ]\n{Content}";
}
public bool Equals(Review? other)
{
if (other is null) return false;
return Id.Equals(other.Id);
}
public override bool Equals(object? obj)
{
if (ReferenceEquals(obj, null)) return false;
if (ReferenceEquals(obj, this)) return true;
if (GetType() != obj.GetType()) return false;
return Equals(obj);
}
public override int GetHashCode()
{
return Id.GetHashCode();
}
}
}

@ -6,6 +6,7 @@ using System.Threading.Tasks;
using System.Runtime.CompilerServices;
using System.Text.RegularExpressions;
using System.Text;
using System.Runtime.Serialization;
namespace Model
{
@ -13,16 +14,17 @@ namespace Model
/// A user is an entity with a name, a surname, mail, profilePict and a list of priority.
/// This user can login with an Id and a password
/// </summary>
[DataContract(Name = "user")]
public class User : IEquatable<User>
{
#region Private Attributes
private string name="";
private string surname="";
private string mail = "";
private string picture = "";
private int password ;
private List<Priority> priorities;
[DataMember] private string name="";
[DataMember] private string surname="";
[DataMember] private string mail = "";
[DataMember] private string picture = "";
[DataMember] private int password ;
[DataMember] private List<Priority> priorities;
#endregion
#region Properties

@ -17,15 +17,14 @@ namespace Model_UnitTests
description: "test recipe",
recipes: new[]
{
new Recipe(title: "Gateau à la crème", id: 1),
new Recipe(title: "Gateau au chocolat", id: 2),
new Recipe(title: "Gateau aux cerises", id: 3)
new Recipe(title: "Gateau à la crème"),
new Recipe(title: "Gateau au chocolat"),
new Recipe(title: "Gateau aux cerises")
});
Recipe? recipe = recipes.ResearchByName("chocolat").FirstOrDefault();
Assert.NotNull(recipe);
Assert.Equal(2, recipe.Id);
Recipe? search_result = recipes.ResearchByName("chocolat").FirstOrDefault();
Assert.NotNull(search_result);
Assert.Equal("Gateau au chocolat", search_result.Title);
}
}
}

@ -7,22 +7,8 @@ namespace Model_UnitTests
[Fact]
public void TestVoidConstructor()
{
Recipe r = new Recipe(id: 999); // id is given to avoid tests errors with the static atrribute 'idCreator'.
Recipe r = new Recipe(""); // id is given to avoid tests errors with the static atrribute 'idCreator'.
Assert.NotNull(r.Title);
}
[Theory]
[InlineData("Cookies", 23, "Cookies", 23)]
[InlineData("Cookies", 1, "Cookies", 1)]
[InlineData("No title.", 1, "", 1)]
public void TestConstructor(string expectedTitle, int expectedId, string title, int? id)
{
Recipe r = new Recipe(title, id);
Assert.NotNull(r.Title);
Assert.Equal(expectedId, r.Id);
Assert.Equal(expectedTitle, r.Title);
}
}
}

Loading…
Cancel
Save