diff --git a/MCTG/Tests/Model_UnitTests/Recipe_UT.cs b/MCTG/Tests/Model_UnitTests/Recipe_UT.cs index 6f7d8ef..8ee0b49 100644 --- a/MCTG/Tests/Model_UnitTests/Recipe_UT.cs +++ b/MCTG/Tests/Model_UnitTests/Recipe_UT.cs @@ -12,5 +12,20 @@ namespace Model_UnitTests Assert.NotNull(r.Title); } + + [Theory] + [InlineData("recipe", RecipeType.Dish, Priority.Light, "recipe", RecipeType.Dish, Priority.Light)] + [InlineData("No title.", RecipeType.Unspecified, Priority.Light, "", RecipeType.Unspecified, Priority.Light)] + [InlineData("re cipe", RecipeType.Unspecified, Priority.Light, "re cipe", RecipeType.Unspecified, Priority.Light)] + public void TestValuesConstructor( + string expectedTitle, RecipeType expectedType, Priority expectedPriority, + string title, RecipeType type, Priority priority) + { + Recipe rc = new Recipe(title, type, priority); + + Assert.Equal(expectedTitle, rc.Title); + Assert.Equal(expectedType, rc.Type); + Assert.Equal(expectedPriority, rc.Priority); + } } } diff --git a/MCTG/Views/App.xaml.cs b/MCTG/Views/App.xaml.cs index d5c1bbf..0dd959c 100644 --- a/MCTG/Views/App.xaml.cs +++ b/MCTG/Views/App.xaml.cs @@ -5,6 +5,7 @@ using Managers; using System.Diagnostics; using System.Runtime.Serialization; using System.Diagnostics.CodeAnalysis; +using System.Runtime.Serialization.Json; namespace Views { @@ -20,7 +21,7 @@ namespace Views Debug.WriteLine("Hello, World!\n\n"); string path = FileSystem.Current.AppDataDirectory; // - path to the save file - string strategy = "xml"; // - strategy is 'xml' or 'json' (/!\ this is case sensitive) + string strategy = "json"; // - strategy is 'xml' or 'json' (/!\ this is case sensitive) // Initialize the data serializer IDataSerializer dataSerializer = (strategy == "xml") ? @@ -31,7 +32,7 @@ namespace Views IDataManager dataManager; if (!File.Exists(Path.Combine(path, $"data.{strategy}"))) { - var data = LoadXMLBundledFilesAsync("data.xml"); + var data = LoadJSONBundledFilesAsync("data.json"); dataManager = new DataDefaultManager(dataSerializer, data); } else @@ -72,6 +73,7 @@ namespace Views base.OnSleep(); } + /// /// Load XML raw assets from data. /// @@ -79,9 +81,8 @@ namespace Views /// A dictionary containing the data loaded. private static IDictionary> LoadXMLBundledFilesAsync(string path) { - //using Stream stream = await FileSystem.Current.OpenAppPackageFileAsync(path); - DataContractSerializerSettings _dataContractSerializerSettings - = new DataContractSerializerSettings() + DataContractSerializerSettings _dataContractSerializerSettings = + new DataContractSerializerSettings() { KnownTypes = new Type[] { @@ -97,5 +98,29 @@ namespace Views return data; } + + /// + /// Load JSON raw assets from data. + /// + /// The path in the raw assets directory. + /// A dictionary containing the data loaded. + private static IDictionary> LoadJSONBundledFilesAsync(string path) + { + DataContractJsonSerializerSettings _dataContractJsonSerializerSettings = + new DataContractJsonSerializerSettings() + { + KnownTypes = new Type[] + { + typeof(Recipe), typeof(RecipeType), typeof(Priority), typeof(Review), typeof(User), typeof(Ingredient), typeof(Quantity) + } + }; + var jsonSerializer = new DataContractJsonSerializer(typeof(Dictionary>), _dataContractJsonSerializerSettings); + IDictionary> data; + + using Stream stream = FileSystem.Current.OpenAppPackageFileAsync(path).Result; + data = jsonSerializer.ReadObject(stream) as IDictionary>; + + return data; + } } } diff --git a/MCTG/Views/ContentPages/AddRecipe.xaml.cs b/MCTG/Views/ContentPages/AddRecipe.xaml.cs index aa95ce7..c6ca924 100644 --- a/MCTG/Views/ContentPages/AddRecipe.xaml.cs +++ b/MCTG/Views/ContentPages/AddRecipe.xaml.cs @@ -13,6 +13,9 @@ namespace Views private Ingredient ingredient; private PreparationStep preparationStep; private string titleRecipe; + + public FileResult ImageSource { get; private set; } = null; + public string? ImageSourcePath { get; private set; } = null; public MasterManager Master => (Application.Current as App).Master; public User CurrentUser => Master.User.CurrentConnected; public Recipe RecipeToAdd{ get=> recipeToAdd; set => recipeToAdd = value; } @@ -38,20 +41,30 @@ namespace Views IngredientList = new List(); PreparationStepList = new List(); } - private void PickPhoto(object sender, EventArgs e) + private async void PickPhoto(object sender, EventArgs e) { - MediaPicker.PickPhotoAsync(); + ImageSource = await MediaPicker.Default.PickPhotoAsync(); } - private void AddRecipeValidation(object sender, EventArgs e) + private async void AddRecipeValidation(object sender, EventArgs e) { - if (string.IsNullOrWhiteSpace(TitleRecipe)) { - DisplayAlert("Erreur", "Entrez un nom de recette.", "Ok"); + await DisplayAlert("Erreur", "Entrez un nom de recette.", "Ok"); return; } + if (ImageSource != null) + { + // save the file into local storage + ImageSourcePath = Path.Combine(FileSystem.Current.AppDataDirectory, $"{TitleRecipe.Replace(" ", "")}.{ImageSource.FileName}"); + + using Stream sourceStream = await ImageSource.OpenReadAsync(); + using FileStream localFileStream = File.OpenWrite(ImageSourcePath); + + await sourceStream.CopyToAsync(localFileStream); + } + RecipeType newRecipeType = GetSelectedRecipeType(); Priority selectedPriority = GetSelectedPriority(); string authorMail = CurrentUser.Mail; @@ -62,26 +75,35 @@ namespace Views newRecipeType, selectedPriority, null, - authorMail + authorMail, + ImageSourcePath ); newRecipe.PreparationSteps.AddRange(PreparationStepList); newRecipe.Ingredients.AddRange(IngredientList); bool isRecipeSave = Master.Recipe.AddRecipeToData(newRecipe); + + // Save data. + Debug.Write($"[ {DateTime.Now:H:mm:ss} ] Saving...\t"); + Master.Data.SaveData(); + + Debug.WriteLine("Done."); + Debug.WriteLine(FileSystem.Current.AppDataDirectory); + if (isRecipeSave) { - DisplayAlert("Succès", "La recette a été ajoutée avec succès", "OK"); + await DisplayAlert("Succès", "La recette a été ajoutée avec succès", "OK"); } else { - DisplayAlert("Echec", "La recette n'a pas été ajoutée", "OK"); + await DisplayAlert("Echec", "La recette n'a pas été ajoutée", "OK"); } newRecipe = new Recipe("Nouvelle Recette"); PreparationStepList.Clear(); IngredientList.Clear(); - Navigation.PopAsync(); + await Navigation.PopModalAsync(); } private void AddStepRecipe(object sender, EventArgs e) @@ -115,6 +137,12 @@ namespace Views private void AddIngredient(object sender, EventArgs e) { + if (nameIngredient.Text is null || quantityNumber.Text is null) + { + DisplayAlert("Warning", "some values are null, please provide correct values.", "Ok"); + return; + } + string ingredientName = nameIngredient.Text; int numberQuantity = Convert.ToInt32(quantityNumber.Text); Unit unitQuantity = (Unit)UnitPicker.SelectedItem; diff --git a/MCTG/Views/ContentPages/Login.xaml.cs b/MCTG/Views/ContentPages/Login.xaml.cs index ac40aa2..4bdb2c6 100644 --- a/MCTG/Views/ContentPages/Login.xaml.cs +++ b/MCTG/Views/ContentPages/Login.xaml.cs @@ -1,5 +1,6 @@ using AppException; using Model; +using System.Diagnostics; namespace Views; @@ -24,6 +25,13 @@ public partial class Login : ContentPage try { usermgr.AddUserToData(usermgr.CreateUser(mail, password)); + + // Save data. + Debug.Write($"[ {DateTime.Now:H:mm:ss} ] Saving...\t"); + Master.Data.SaveData(); + + Debug.WriteLine("Done."); + Debug.WriteLine(FileSystem.Current.AppDataDirectory); } catch (BadMailFormatException) { diff --git a/MCTG/Views/ContentPages/MyPosts.xaml b/MCTG/Views/ContentPages/MyPosts.xaml index bf8dcac..fc7bc07 100644 --- a/MCTG/Views/ContentPages/MyPosts.xaml +++ b/MCTG/Views/ContentPages/MyPosts.xaml @@ -1,6 +1,7 @@ @@ -8,45 +9,59 @@ + - + -