public async Task Import(string data) { // Phase 0: Turn the big string into structured data var lines = data.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries); var parsed = _rawParser.ParseRawImport(lines); var structured = _rawParser.StructuredImport(parsed); // Phase 1: Setup peripheral schema components // (The steps of this Phase are parallelizable, but it's way easier to read and // debug by blocking, and this is not a performance-critical operation yet.) var libraryNames = structured.Libraries.Select(a => a.LibraryName); var libraryMapping = await _libraryImporter.ImportLibraries(libraryNames); var allIngredients = structured.Libraries.SelectMany(library => library.Recipes.SelectMany(recipe => recipe.Ingredients)) // ToList() because the IEnumerable is reused .ToList(); var allUnits = allIngredients.Select(a => a.Unit); var unitMap = await _unitImporter.ImportUnits(allUnits); var allComponentTypes = allIngredients.Select(a => a.IngredientType); await _componentImporter.ImportComponentTypes(allComponentTypes); var componentMap = await _componentImporter.ImportComponents(allIngredients); // Phase 2: Handle Recipes // (The iterations of this Phase are parallelizable, but it's way easier to read and // debug by blocking, and this is not a performance-critical operation yet.) foreach (var library in structured.Libraries) { var libraryId = libraryMapping[library.LibraryName]; foreach (var recipe in library.Recipes) { var recipeId = await _recipeImporter.ImportRecipe(libraryId, recipe); await _recipeImporter.ImportIngredients(recipeId, recipe.Ingredients, unitMap, componentMap); } } }
public async Task GivenHappyPathData_ExecutesHappyPath() { var singleLine = String.Join(Environment.NewLine, InputLines); _rawParser .ParseRawImport(Arg.Any <IEnumerable <string> >()) .Returns(Enumerable.Empty <ImportRow>()); var libraryName = "Flagon Enterprises"; var unitName = "pint"; var ingredientName = "The GOB"; var importModel = new StructuredImport { Libraries = new [] { new ImportLibrary { LibraryName = libraryName, Recipes = new [] { new ImportRecipe { RecipeName = "Test Recipe", MixMethod = 1, Instructions = "Instructions", Ingredients = new [] { new ImportIngredient { Amount = "1", Unit = unitName, IngredientName = ingredientName, IngredientType = ingredientName, Index = 0, Garnish = 0 }, new ImportIngredient { Amount = "1", Unit = unitName, IngredientName = ingredientName, IngredientType = ingredientName, Index = 1, Garnish = 0 } } } } } } }; _rawParser .StructuredImport(Arg.Any <IEnumerable <ImportRow> >()) .Returns(importModel); _libraryImporter .ImportLibraries(Arg.Any <IEnumerable <string> >()) .Returns(new Dictionary <string, Guid> { { libraryName, Guid.NewGuid() } }); _unitImporter .ImportUnits(Arg.Any <IEnumerable <string> >()) .Returns(new Dictionary <string, int> { { unitName, 1 } }); _componentImporter .ImportComponents(Arg.Any <IEnumerable <ImportIngredient> >()) .Returns(new Dictionary <string, Guid> { { ingredientName, Guid.NewGuid() } }); _recipeImporter .ImportRecipe(Arg.Any <Guid>(), Arg.Any <ImportRecipe>()) .Returns(Guid.NewGuid()); await _sut.Import(singleLine); _rawParser .Received(1) .ParseRawImport(Arg.Any <IEnumerable <string> >()); _rawParser .Received(1) .StructuredImport(Arg.Any <IEnumerable <ImportRow> >()); await _libraryImporter .Received(1) .ImportLibraries(Arg.Any <IEnumerable <string> >()); await _unitImporter .Received(1) .ImportUnits(Arg.Any <IEnumerable <string> >()); await _componentImporter .Received(1) .ImportComponents(Arg.Any <IEnumerable <ImportIngredient> >()); await _recipeImporter .Received(1) .ImportRecipe(Arg.Any <Guid>(), Arg.Any <ImportRecipe>()); await _recipeImporter .Received(1) .ImportIngredients(Arg.Any <Guid>(), Arg.Any <IEnumerable <ImportIngredient> >(), Arg.Any <IDictionary <string, int> >(), Arg.Any <IDictionary <string, Guid> >()); }