public void DuplicateProduct(bool crossTypeIdentifier, bool revisionTaken)
        {
            // Arrange
            var productMgr = new ProductManager
            {
                Factory = _factory,
                Storage = _storage
            };

            productMgr.TypeChanged += (sender, product) => { };
            var watch = SetupProduct("Jaques Lemans", "321");

            _storage.SaveType(watch);
            var recipe = new WatchProductRecipe
            {
                Product        = watch,
                Classification = RecipeClassification.Default,
                Name           = "TestRecipe",
                Workplan       = new Workplan {
                    Id = _workplanId
                }
            };

            _storage.SaveRecipe(recipe);

            // Act (& Assert)
            WatchType duplicate = null;

            if (crossTypeIdentifier | revisionTaken)
            {
                var newIdentity = crossTypeIdentifier
                    ? new ProductIdentity("3214711", 7)
                    : new ProductIdentity("321" + WatchMaterial, 5);
                var ex = Assert.Throws <IdentityConflictException>(() =>
                {
                    duplicate = (WatchType)productMgr.Duplicate(watch.Id, newIdentity);
                });
                Assert.AreEqual(crossTypeIdentifier, ex.InvalidTemplate);
                return;
            }

            Assert.DoesNotThrow(() =>
            {
                duplicate = (WatchType)productMgr.Duplicate(watch.Id,
                                                            new ProductIdentity("654" + WatchMaterial, 1));
            });

            var recipeDuplicates = _storage.LoadRecipes(duplicate.Id, RecipeClassification.Unset);

            // Assert
            Assert.AreEqual(watch.Watchface.Product.Id, duplicate.Watchface.Product.Id);
            Assert.AreEqual(watch.Needles.Sum(n => n.Product.Id), duplicate.Needles.Sum(n => n.Product.Id));
            Assert.Greater(recipeDuplicates.Count, 0);
            Assert.AreNotEqual(recipe.Id, recipeDuplicates[0].Id);
            Assert.AreEqual(recipe.Name, recipeDuplicates[0].Name);
            Assert.AreEqual(recipe.Classification, recipeDuplicates[0].Classification);
        }
        public void LoadRecipesByClassification()
        {
            // Arrange
            var watch = new WatchType
            {
                Name     = "Test",
                Identity = new ProductIdentity("8899665", 1),
            };

            _storage.SaveType(watch);

            CreateRecipe(RecipeClassification.Default);
            CreateRecipe(RecipeClassification.Alternative);
            CreateRecipe(RecipeClassification.Alternative);
            CreateRecipe(RecipeClassification.Part);

            // Act
            var defaults                = _storage.LoadRecipes(watch.Id, RecipeClassification.Default);
            var alternatives            = _storage.LoadRecipes(watch.Id, RecipeClassification.Alternative);
            var defaultsAndAlternatives = _storage.LoadRecipes(watch.Id, RecipeClassification.Default | RecipeClassification.Alternative);
            var parts = _storage.LoadRecipes(watch.Id, RecipeClassification.Part);
            var all   = _storage.LoadRecipes(watch.Id, RecipeClassification.CloneFilter);

            // Assert
            Assert.AreEqual(1, defaults.Count);
            Assert.AreEqual(2, alternatives.Count);
            Assert.AreEqual(3, defaultsAndAlternatives.Count);
            Assert.AreEqual(1, parts.Count);
            Assert.AreEqual(4, all.Count);

            void CreateRecipe(RecipeClassification classification)
            {
                var recipe = new WatchProductRecipe
                {
                    Product        = watch,
                    Classification = classification,
                    Name           = classification + ": TestRecipe",
                    Workplan       = new Workplan {
                        Id = _workplanId
                    }
                };

                _storage.SaveRecipe(recipe);
            }
        }