public void TestAddChildThatExistsFails()
        {
            rootNode = rootNode.AsSubdivision();
              rootNode.AddChild(ProductDimensions.CreateBrand("google"));

              // Add the same child again. The call should fail.
              Assert.Throws<ArgumentException>(delegate() {
            rootNode.AddChild(ProductDimensions.CreateBrand("google"));
              });

              // Add the same child again, this time with a different case.
              // The call should fail.
              Assert.Throws<ArgumentException>(delegate() {
            rootNode.AddChild(ProductDimensions.CreateBrand("GOOGLE"));
              });
        }
        public void Init()
        {
            CAMPAIGN_ID = utils.CreateShoppingCampaign(user, BiddingStrategyType.MANUAL_CPC);
            ADGROUP_ID  = utils.CreateAdGroup(user, CAMPAIGN_ID);

            tree = ProductPartitionTree.CreateAdGroupTree(ADGROUP_ID,
                                                          new List <AdGroupCriterion>());
            ProductPartitionNode root = tree.Root.AsSubdivision();

            ProductPartitionNode clothing = root.AddChild(ProductDimensions.CreateType(
                                                              ProductDimensionType.PRODUCT_TYPE_L1, "clothing"));

            clothing.AsBiddableUnit().CpcBid = 200000;
            ProductPartitionNode shoes       = root.AddChild(ProductDimensions.CreateType(
                                                                 ProductDimensionType.PRODUCT_TYPE_L1, "shoes"));

            shoes.AsBiddableUnit().CpcBid  = 400000;
            ProductPartitionNode otherNode = root.AddChild(ProductDimensions.CreateType(
                                                               ProductDimensionType.PRODUCT_TYPE_L1));

            otherNode.AsBiddableUnit().CpcBid = 300000;

            tree = ExecuteTreeOperations();
        }
        /// <summary>
        /// Uses obsolete category Hardware > Flooring (5264193646140135688). This is expected to
        /// fail with the error {@code CriterionError.INVALID_PRODUCT_BIDDING_CATEGORY}.
        /// </summary>
        private void UseObsoleteCategory()
        {
            tree.Root.RemoveAllChildren();
            ProductPartitionNode hardwareLevel1 = tree.Root.AsSubdivision().AddChild(
                ProductDimensions.CreateBiddingCategory(ProductDimensionType.BIDDING_CATEGORY_L1,
                                                        1689639310991627077L)).AsSubdivision();

            hardwareLevel1.AddChild(ProductDimensions.CreateBiddingCategory(
                                        ProductDimensionType.BIDDING_CATEGORY_L2, 5264193646140135688L)).CpcBid = 1000000L;
            hardwareLevel1.AddChild(ProductDimensions.CreateBiddingCategory(
                                        ProductDimensionType.BIDDING_CATEGORY_L2)).AsExcludedUnit();
            tree.Root.AddChild(ProductDimensions.CreateBiddingCategory(
                                   ProductDimensionType.BIDDING_CATEGORY_L1)).AsExcludedUnit();
            try {
                tree = ExecuteTreeOperations();
                Assert.Fail("Did not throw CriterionError.INVALID_PRODUCT_BIDDING_CATEGORY");
            } catch (AdWordsApiException e) {
                ApiError[] errors = (e.ApiException as ApiException).errors;
                Assert.That(errors != null && errors.Length == 1);
                Assert.That(errors[0] is CriterionError);
                Assert.That((errors[0] as CriterionError).reason ==
                            CriterionErrorReason.INVALID_PRODUCT_BIDDING_CATEGORY);
            }
        }
        private void RebuildMultiNodeTree()
        {
            // Clear out the tree.
            ProductPartitionNode rootNode = tree.Root.RemoveAllChildren().AsSubdivision();

            long[]   bids = new long[] { 2500000L, 1500000L, 1000000L };
            String[] productTypeValues = new String[] { "shoes", "clothing", null };
            for (int i = 0; i < productTypeValues.Length; i++)
            {
                rootNode.AddChild(
                    ProductDimensions.CreateType(ProductDimensionType.PRODUCT_TYPE_L1,
                                                 productTypeValues[i])).AsBiddableUnit().CpcBid = bids[i];
            }
            Assert.DoesNotThrow(delegate() {
                tree = ExecuteTreeOperations();
            });
        }
    public void TestSetBidOnUnit() {
      rootNode = rootNode.AsSubdivision();
      ProductBrand childDimension = ProductDimensions.CreateBrand("google");
      ProductPartitionNode childNode = rootNode.AddChild(childDimension);

      Assert.That(childNode.CpcBidSpecified == false, "Bid should be null by default.");

      childNode.CpcBid = 1L;

      Assert.AreEqual(1L, childNode.CpcBid, "Bid does not reflect setBid.");
      Assert.True(childNode.IsBiddableUnit, "Node should be a biddable unit.");

      childNode = childNode.AsExcludedUnit();
      Assert.True(childNode.IsExcludedUnit, "Node should be an excluded unit.");
      Assert.False(childNode.IsBiddableUnit, "Node should not be a biddable unit.");
      Assert.False(childNode.CpcBidSpecified, "Excluded unit should have a null bid");

      // Set back to biddable.
      childNode = childNode.AsBiddableUnit();
      Assert.True(childNode.IsBiddableUnit, "Node should be a biddable unit.");
    }
        /// <summary>
        /// Subdivides the new shoes.
        /// </summary>
        /// Takes a tree with:
        /// <pre>
        /// ROOT
        ///   ...
        ///   shoes
        ///     new some bid
        /// </pre>
        ///
        /// and changes it to:
        ///
        /// <pre>
        ///   ROOT
        ///     ...
        ///     shoes
        ///       new
        ///       other offerId $1.00
        ///       offerId=2 $2.00
        ///       ...
        ///       offerId=20 $20.00
        /// </pre>
        private void SubdivideNewShoes()
        {
            ProductPartitionNode shoesLevel1 = tree.Root.GetChild(ProductDimensions.CreateType(
                                                                      ProductDimensionType.PRODUCT_TYPE_L1, "shoes")).AsSubdivision();
            ProductPartitionNode newShoesLevel2 = shoesLevel1.GetChild(
                ProductDimensions.CreateCanonicalCondition(ProductCanonicalConditionCondition.NEW))
                                                  .AsSubdivision();

            for (int i = 1; i <= 20; i++)
            {
                ProductOfferId offerId = ProductDimensions.CreateOfferId();
                if (i > 1)
                {
                    offerId.value = i.ToString();
                }

                newShoesLevel2.AddChild(offerId).AsBiddableUnit().CpcBid = i * 1000000L;
            }

            Assert.DoesNotThrow(delegate() {
                tree = ExecuteTreeOperations();
            });
        }
    public void TestChildNodeBasicFunctionality() {
      rootNode = rootNode.AsSubdivision();
      Assert.False(rootNode.IsUnit, "Parent should not be a unit.");
      Assert.True(rootNode.IsSubdivision, "Parent should be a subdivision.");
      ProductBrand childDimension = ProductDimensions.CreateBrand("google");
      ProductPartitionNode childNode = rootNode.AddChild(childDimension);

      Assert.AreSame(childDimension, childNode.Dimension, "Child node merely wraps the " +
          "underlying dimension node.");
      Assert.AreSame(rootNode, childNode.Parent, "child.GetParent should return parentNode.");
      Assert.That(childNode.ProductPartitionId == 0, "Partition ID is incorrect.");

      Assert.That(childNode.Children.Count() == 0, "ChildNode should not have any children.");
      Assert.True(childNode.IsUnit, "New node should be a unit node by default.");
      Assert.True(childNode.IsBiddableUnit, "New node should be a biddable unit node by default.");

      Assert.That(rootNode.HasChild(childDimension), "rootNode.HasChild should return true when " +
          "passed the dimension of the added child");
      Assert.False(rootNode.HasChild(ProductDimensions.CreateBrand("xyz")), "rootNode.HasChild " +
          "should return false when passed a dimension for a nonexistent child");
      Assert.False(rootNode.HasChild(null), "rootNode.HasChild should return false when passed " +
          "a dimension for a nonexistent child");
    }
        /// <summary>
        /// Creates a tree of the form:
        ///
        /// <pre>
        /// ROOT
        ///   ProductType Level1 shoes
        ///     ProductType Level2 athletic shoes
        ///       Condition new $2.50
        ///       Condition used $1.00
        ///       Other - exclude from bidding
        ///     ProductType Level2 walking shoes
        ///       Condition new $3.50
        ///       Condition used $1.25
        ///       Other $1.00
        ///     ProductType Level2 null (everything else) - exclude from bidding
        ///   ProductType Level1 clothing
        ///     ProductType Level2 winter clothing
        ///       Condition new $1.00
        ///       Condition used $1.25
        ///       Other $1.50
        ///     ProductType Level2 summer clothing
        ///       Condition new $1.10
        ///       Condition used $1.00
        ///       Other $1.25
        ///     ProductType Level2 null (everything else)
        ///       Condition new $0.90
        ///       Condition used $0.85
        ///       Other $0.75
        ///   ProductType Level1 null (everything else) - exclude from bidding
        /// </pre>
        /// </summary>
        private void RebuildComplexTree()
        {
            // Clear out the tree.
            ProductPartitionNode rootNode = tree.Root.RemoveAllChildren().AsSubdivision();

            ProductPartitionNode shoesLevel1 = rootNode.AddChild(ProductDimensions.CreateType(
                                                                     ProductDimensionType.PRODUCT_TYPE_L1, "shoes")).AsSubdivision();

            ProductPartitionNode athleticShoesLevel2 = shoesLevel1.AddChild(
                ProductDimensions.CreateType(ProductDimensionType.PRODUCT_TYPE_L2, "athletic shoes"))
                                                       .AsSubdivision();

            athleticShoesLevel2.AddChild(ProductDimensions.CreateCanonicalCondition(
                                             ProductCanonicalConditionCondition.NEW)).AsBiddableUnit().CpcBid = 2500000L;
            athleticShoesLevel2.AddChild(ProductDimensions.CreateCanonicalCondition(
                                             ProductCanonicalConditionCondition.USED)).AsBiddableUnit().CpcBid = 1000000L;
            athleticShoesLevel2.AddChild(ProductDimensions.CreateCanonicalCondition()).AsExcludedUnit();

            ProductPartitionNode walkingShoesLevel2 = shoesLevel1.AddChild(
                ProductDimensions.CreateType(ProductDimensionType.PRODUCT_TYPE_L2, "walking shoes"))
                                                      .AsSubdivision();

            walkingShoesLevel2.AddChild(ProductDimensions.CreateCanonicalCondition(
                                            ProductCanonicalConditionCondition.NEW)).AsBiddableUnit().CpcBid = 3500000L;
            walkingShoesLevel2.AddChild(ProductDimensions.CreateCanonicalCondition(
                                            ProductCanonicalConditionCondition.USED)).AsBiddableUnit().CpcBid = 1250000L;
            walkingShoesLevel2.AddChild(ProductDimensions.CreateCanonicalCondition()).AsBiddableUnit()
            .CpcBid = 1000000L;

            shoesLevel1.AddChild(ProductDimensions.CreateType(ProductDimensionType.PRODUCT_TYPE_L2))
            .AsExcludedUnit();

            ProductPartitionNode clothingLevel1 = rootNode.AddChild(ProductDimensions.CreateType(
                                                                        ProductDimensionType.PRODUCT_TYPE_L1, "clothing")).AsSubdivision();

            ProductPartitionNode winterClothingLevel2 = clothingLevel1.AddChild(
                ProductDimensions.CreateType(ProductDimensionType.PRODUCT_TYPE_L2, "winter clothing"))
                                                        .AsSubdivision();

            winterClothingLevel2.AddChild(ProductDimensions.CreateCanonicalCondition(
                                              ProductCanonicalConditionCondition.NEW)).AsBiddableUnit().CpcBid = 1000000L;
            winterClothingLevel2.AddChild(ProductDimensions.CreateCanonicalCondition(
                                              ProductCanonicalConditionCondition.USED)).AsBiddableUnit().CpcBid = 1250000L;
            winterClothingLevel2.AddChild(ProductDimensions.CreateCanonicalCondition()).AsBiddableUnit()
            .CpcBid = 1500000L;

            ProductPartitionNode summerClothingLevel2 = clothingLevel1.AddChild(
                ProductDimensions.CreateType(ProductDimensionType.PRODUCT_TYPE_L2, "summer clothing"))
                                                        .AsSubdivision();

            summerClothingLevel2.AddChild(ProductDimensions.CreateCanonicalCondition(
                                              ProductCanonicalConditionCondition.NEW)).AsBiddableUnit().CpcBid = 1100000L;
            summerClothingLevel2.AddChild(ProductDimensions.CreateCanonicalCondition(
                                              ProductCanonicalConditionCondition.USED)).AsBiddableUnit().CpcBid = 1000000L;
            summerClothingLevel2.AddChild(ProductDimensions.CreateCanonicalCondition()).AsBiddableUnit()
            .CpcBid = 1250000L;

            ProductPartitionNode otherClothingLevel2 = clothingLevel1.AddChild(
                ProductDimensions.CreateType(ProductDimensionType.PRODUCT_TYPE_L2, null))
                                                       .AsSubdivision();

            otherClothingLevel2.AddChild(ProductDimensions.CreateCanonicalCondition(
                                             ProductCanonicalConditionCondition.NEW)).AsBiddableUnit().CpcBid = 900000L;
            otherClothingLevel2.AddChild(ProductDimensions.CreateCanonicalCondition(
                                             ProductCanonicalConditionCondition.USED)).AsBiddableUnit().CpcBid = 850000L;
            otherClothingLevel2.AddChild(ProductDimensions.CreateCanonicalCondition()).AsBiddableUnit()
            .CpcBid = 750000L;

            rootNode.AddChild(ProductDimensions.CreateType(ProductDimensionType.PRODUCT_TYPE_L1, null))
            .AsExcludedUnit();

            Assert.DoesNotThrow(delegate() {
                tree = ExecuteTreeOperations();
            });
        }
        /// <summary>
        /// Runs the code example.
        /// </summary>
        /// <param name="user">The AdWords user.</param>
        /// <param name="adGroupId">The ad group to which product partition is
        /// added.</param>
        public void Run(AdWordsUser user, long adGroupId)
        {
            using (AdGroupCriterionService adGroupCriterionService =
                       (AdGroupCriterionService)user.GetService(
                           AdWordsService.v201802.AdGroupCriterionService)) {
                // Build a new ProductPartitionTree using the ad group's current set of criteria.
                ProductPartitionTree partitionTree =
                    ProductPartitionTree.DownloadAdGroupTree(user, adGroupId);

                Console.WriteLine("Original tree: {0}", partitionTree);

                // Clear out any existing criteria.
                ProductPartitionNode rootNode = partitionTree.Root.RemoveAllChildren();

                // Make the root node a subdivision.
                rootNode = rootNode.AsSubdivision();

                // Add a unit node for condition = NEW.
                ProductPartitionNode newConditionNode = rootNode.AddChild(
                    ProductDimensions.CreateCanonicalCondition(ProductCanonicalConditionCondition.NEW));
                newConditionNode.AsBiddableUnit().CpcBid = 200000;

                ProductPartitionNode usedConditionNode = rootNode.AddChild(
                    ProductDimensions.CreateCanonicalCondition(ProductCanonicalConditionCondition.USED));
                usedConditionNode.AsBiddableUnit().CpcBid = 100000;

                // Add a subdivision node for condition = null (everything else).
                ProductPartitionNode otherConditionNode =
                    rootNode.AddChild(ProductDimensions.CreateCanonicalCondition()).AsSubdivision();

                // Add a unit node under condition = null for brand = "CoolBrand".
                ProductPartitionNode coolBrandNode = otherConditionNode.AddChild(
                    ProductDimensions.CreateBrand("CoolBrand"));
                coolBrandNode.AsBiddableUnit().CpcBid = 900000L;

                // Add a unit node under condition = null for brand = "CheapBrand".
                ProductPartitionNode cheapBrandNode = otherConditionNode.AddChild(
                    ProductDimensions.CreateBrand("CheapBrand"));
                cheapBrandNode.AsBiddableUnit().CpcBid = 10000L;

                // Add a subdivision node under condition = null for brand = null (everything else).
                ProductPartitionNode otherBrandNode = otherConditionNode.AddChild(
                    ProductDimensions.CreateBrand(null)).AsSubdivision();

                // Add unit nodes under condition = null/brand = null.
                // The value for each bidding category is a fixed ID for a specific
                // category. You can retrieve IDs for categories from the ConstantDataService.
                // See the 'GetProductCategoryTaxonomy' example for more details.

                // Add a unit node under condition = null/brand = null for product type
                // level 1 = 'Luggage & Bags'.
                ProductPartitionNode luggageAndBagNode = otherBrandNode.AddChild(
                    ProductDimensions.CreateBiddingCategory(ProductDimensionType.BIDDING_CATEGORY_L1,
                                                            -5914235892932915235L));
                luggageAndBagNode.AsBiddableUnit().CpcBid = 750000L;

                // Add a unit node under condition = null/brand = null for product type
                // level 1 = null (everything else).
                ProductPartitionNode everythingElseNode = otherBrandNode.AddChild(
                    ProductDimensions.CreateBiddingCategory(ProductDimensionType.BIDDING_CATEGORY_L1));
                everythingElseNode.AsBiddableUnit().CpcBid = 110000L;

                try {
                    // Make the mutate request, using the operations returned by the ProductPartitionTree.
                    AdGroupCriterionOperation[] mutateOperations = partitionTree.GetMutateOperations();

                    if (mutateOperations.Length == 0)
                    {
                        Console.WriteLine("Skipping the mutate call because the original tree and the " +
                                          "current tree are logically identical.");
                    }
                    else
                    {
                        adGroupCriterionService.mutate(mutateOperations);
                    }

                    // The request was successful, so create a new ProductPartitionTree based on the updated
                    // state of the ad group.
                    partitionTree = ProductPartitionTree.DownloadAdGroupTree(user, adGroupId);

                    Console.WriteLine("Final tree: {0}", partitionTree);
                } catch (Exception e) {
                    throw new System.ApplicationException("Failed to set shopping product partition.", e);
                }
            }
        }
        public void TestNavigation()
        {
            rootNode = rootNode.AsSubdivision();
            ProductBrand brandGoogle = ProductDimensions.CreateBrand("google");
            ProductBrand brandOther  = ProductDimensions.CreateBrand(null);
            ProductCanonicalCondition conditionNew =
                ProductDimensions.CreateCanonicalCondition(ProductCanonicalConditionCondition.NEW);
            ProductCanonicalCondition conditionUsed =
                ProductDimensions.CreateCanonicalCondition(ProductCanonicalConditionCondition.USED);
            ProductCanonicalCondition conditionOther = ProductDimensions.CreateCanonicalCondition();

            // Build up the brand = Google node under the root.
            ProductPartitionNode brandGoogleNode = rootNode.AddChild(brandGoogle).AsSubdivision();

            brandGoogleNode.AddChild(conditionNew);
            brandGoogleNode.AddChild(conditionUsed);
            brandGoogleNode.AddChild(conditionOther);

            Assert.True(brandGoogleNode.HasChild(conditionNew),
                        "HasChild should return true for existing child dimension.");
            Assert.AreSame(brandGoogleNode, brandGoogleNode.GetChild(conditionNew).Parent,
                           "parent->GetChild->getParent should return parent.");
            Assert.True(brandGoogleNode.HasChild(conditionUsed),
                        "HasChild should return true for existing child dimension.");
            Assert.AreSame(brandGoogleNode, brandGoogleNode.GetChild(conditionUsed).Parent,
                           "parent->GetChild->getParent should return parent.");
            Assert.True(brandGoogleNode.HasChild(conditionOther),
                        "HasChild should return true for existing child dimension.");
            Assert.AreSame(brandGoogleNode, brandGoogleNode.GetChild(conditionOther).Parent,
                           "parent->GetChild->getParent should return parent.");

            // Build up the brand = null (other) node under the root.
            ProductPartitionNode brandOtherNode = rootNode.AddChild(brandOther).AsSubdivision();

            brandOtherNode.AddChild(conditionNew);
            Assert.True(brandOtherNode.HasChild(conditionNew),
                        "HasChild should return true for existing child dimension.");
            Assert.AreSame(brandOtherNode, brandOtherNode.GetChild(conditionNew).Parent,
                           "parent->GetChild->getParent should return parent.");
            Assert.False(brandOtherNode.HasChild(conditionUsed),
                         "HasChild should return false for nonexistent child dimension.");
            Assert.False(brandOtherNode.HasChild(conditionOther),
                         "HasChild should return false for nonexistent child dimension.");
            brandOtherNode.AddChild(conditionOther);
            Assert.True(brandOtherNode.HasChild(conditionOther),
                        "HasChild should return true for existing child dimension.");
            Assert.AreSame(brandOtherNode, brandOtherNode.GetChild(conditionOther).Parent,
                           "parent->GetChild->getParent should return parent.");

            // Remove one of the children of brand = null.
            brandOtherNode.RemoveChild(conditionOther);
            Assert.False(brandOtherNode.HasChild(conditionOther),
                         "HasChild should return false for a removed child dimension.");

            // Remove the rest of the children of brand = null.
            brandOtherNode.RemoveAllChildren();
            Assert.False(brandOtherNode.HasChild(conditionNew),
                         "HasChild should return false for any removed child dimension.");
            Assert.False(brandOtherNode.HasChild(conditionUsed),
                         "HasChild should return false for any removed child dimension.");
        }
        public void TestMutateMultiNodeTree()
        {
            ProductPartitionTree tree = shoppingTestUtils.CreateTestTreeForTransformation(ADGROUP_ID);

            Assert.AreEqual(ADGROUP_ID, tree.AdGroupId, "ad group ID is incorrect");

            // Change the bids on leaf nodes.
            ProductPartitionNode brandGoogleNode = tree.Root.GetChild(shoppingTestUtils.BRAND_GOOGLE);
            ProductPartitionNode offerANode      = brandGoogleNode.GetChild(shoppingTestUtils.OFFER_A);

            // This should produce 1 SET operation.
            offerANode.CpcBid = offerANode.CpcBid * 10;

            // Offer B is changed from Exclude to Biddable. This should produce 1
            // REMOVE operation + 1 ADD operation.
            ProductPartitionNode offerBNode = brandGoogleNode.GetChild(shoppingTestUtils.OFFER_B);

            offerBNode.AsBiddableUnit().CpcBid = 5000000L;

            // Other Brand node is changed from Exclude to Biddable. This should
            // produce 1 REMOVE operation + 1 ADD operation.
            ProductPartitionNode brandOtherNode = tree.Root.GetChild(shoppingTestUtils.BRAND_OTHER);

            brandOtherNode = brandOtherNode.AsBiddableUnit();

            // Add an offer C node. This should produce 1 ADD operation.
            ProductPartitionNode offerCNode = brandGoogleNode.AddChild(shoppingTestUtils.OFFER_C);

            offerCNode.AsBiddableUnit().CpcBid = 1500000L;

            // Remove the brand Motorola node. This should produce 1 REMOVE operation.
            ProductPartitionNode brandMotorolaNode = tree.Root.GetChild(
                shoppingTestUtils.BRAND_MOTOROLA);

            tree.Root.RemoveChild(shoppingTestUtils.BRAND_MOTOROLA);

            // Get the mutate operations generated by the modifications made to the tree.
            AdGroupCriterionOperation[] mutateOperations = tree.GetMutateOperations();
            Assert.AreEqual(7, mutateOperations.Length);

            List <AdGroupCriterionOperation> operations = null;

            // Since Offer A node only has modified attributes, there should only be
            // one SET operation.
            operations = shoppingTestUtils.GetOperationsForNode(offerANode, mutateOperations);
            Assert.That(operations.Count == 1);
            Assert.That(operations[0].@operator == Operator.SET);

            // Since Offer B node is being converted from Exclude to Biddable node,
            // there should be one REMOVE operation, and another ADD operation.
            operations = shoppingTestUtils.GetOperationsForNode(offerBNode, mutateOperations);
            Assert.That(operations.Count == 2);
            Assert.That(operations[0].@operator == Operator.REMOVE);
            Assert.That(operations[1].@operator == Operator.ADD);

            // Since Offer C node is being added, there should be one ADD operation.
            operations = shoppingTestUtils.GetOperationsForNode(offerCNode, mutateOperations);
            Assert.That(operations.Count == 1);
            Assert.That(operations[0].@operator == Operator.ADD);

            // Since Other Brand node is being converted from Exclude to Biddable node,
            // there should be one REMOVE operation, and another ADD operation.
            operations = shoppingTestUtils.GetOperationsForNode(brandOtherNode, mutateOperations);
            Assert.That(operations.Count == 2);
            Assert.That(operations[0].@operator == Operator.REMOVE);
            Assert.That(operations[1].@operator == Operator.ADD);

            // Since Offer B node is being removed, there should be one REMOVE
            // operation.
            operations = shoppingTestUtils.GetOperationsForNode(brandMotorolaNode, mutateOperations);
            Assert.That(operations.Count == 1);
            Assert.That(operations[0].@operator == Operator.REMOVE);
        }
 public void TestAddChildToUnitFails() {
   Assert.True(rootNode.IsUnit, "Root should be a unit by default.");
   Assert.Throws<ArgumentException>(delegate() {
     rootNode.AddChild(ProductDimensions.CreateBrand("google"));
   });
 }
        /// <summary>
        /// Using the criteria in <paramref name="parentIdMap"/>, recursively adds
        /// all children under the partition ID of <paramref name="parentNode"/> to
        /// <paramref name="parentNode"/>.
        /// </summary>
        /// <param name="parentNode">The parent node.</param>
        /// <param name="parentIdMap">The multimap from parent partition ID to list
        /// of child criteria</param>
        private static void AddChildNodes(ProductPartitionNode parentNode,
        Dictionary<long, List<AdGroupCriterion>> parentIdMap)
        {
            List<AdGroupCriterion> childCriteria = null;
              if (parentIdMap.ContainsKey(parentNode.ProductPartitionId)) {
            childCriteria = parentIdMap[parentNode.ProductPartitionId];
              }

              // no children, return.
              if (childCriteria == null || childCriteria.Count == 0) {
            return;
              }

              // Ensure that the parent is a subdivision.
              parentNode.AsSubdivision();

              foreach (AdGroupCriterion childCriterion in childCriteria) {
            ProductPartition partition = (ProductPartition) childCriterion.criterion;
            ProductPartitionNode childNode = parentNode.AddChild(partition.caseValue);
            childNode.ProductPartitionId = partition.id;

            if (childCriterion is BiddableAdGroupCriterion) {
              childNode = childNode.AsBiddableUnit();
              Money cpcBidAmount = GetBid((BiddableAdGroupCriterion) childCriterion);
              if (cpcBidAmount != null) {
            childNode.CpcBid = cpcBidAmount.microAmount;
              }
            } else {
              childNode = childNode.AsExcludedUnit();
            }

            AddChildNodes(childNode, parentIdMap);
              }
        }
        public void TestChildNodeBasicFunctionality()
        {
            rootNode = rootNode.AsSubdivision();
              Assert.False(rootNode.IsUnit, "Parent should not be a unit.");
              Assert.True(rootNode.IsSubdivision, "Parent should be a subdivision.");
              ProductBrand childDimension = ProductDimensions.CreateBrand("google");
              ProductPartitionNode childNode = rootNode.AddChild(childDimension);

              Assert.AreSame(childDimension, childNode.Dimension, "Child node merely wraps the " +
              "underlying dimension node.");
              Assert.AreSame(rootNode, childNode.Parent, "child.GetParent should return parentNode.");
              Assert.That(childNode.ProductPartitionId == 0, "Partition ID is incorrect.");

              Assert.That(childNode.Children.Count() == 0, "ChildNode should not have any children.");
              Assert.True(childNode.IsUnit, "New node should be a unit node by default.");
              Assert.True(childNode.IsBiddableUnit, "New node should be a biddable unit node by default.");

              Assert.That(rootNode.HasChild(childDimension), "rootNode.HasChild should return true when " +
              "passed the dimension of the added child");
              Assert.False(rootNode.HasChild(ProductDimensions.CreateBrand("xyz")), "rootNode.HasChild " +
              "should return false when passed a dimension for a nonexistent child");
              Assert.False(rootNode.HasChild(null), "rootNode.HasChild should return false when passed " +
              "a dimension for a nonexistent child");
        }
        public void TestSetBidOnUnit()
        {
            rootNode = rootNode.AsSubdivision();
              ProductBrand childDimension = ProductDimensions.CreateBrand("google");
              ProductPartitionNode childNode = rootNode.AddChild(childDimension);

              Assert.That(childNode.CpcBidSpecified == false, "Bid should be null by default.");

              childNode.CpcBid = 1L;

              Assert.AreEqual(1L, childNode.CpcBid, "Bid does not reflect setBid.");
              Assert.True(childNode.IsBiddableUnit, "Node should be a biddable unit.");

              childNode = childNode.AsExcludedUnit();
              Assert.True(childNode.IsExcludedUnit, "Node should be an excluded unit.");
              Assert.False(childNode.IsBiddableUnit, "Node should not be a biddable unit.");
              Assert.False(childNode.CpcBidSpecified, "Excluded unit should have a null bid");

              // Set back to biddable.
              childNode = childNode.AsBiddableUnit();
              Assert.True(childNode.IsBiddableUnit, "Node should be a biddable unit.");
        }
        public void TestNavigation()
        {
            rootNode = rootNode.AsSubdivision();
              ProductBrand brandGoogle = ProductDimensions.CreateBrand("google");
              ProductBrand brandOther = ProductDimensions.CreateBrand(null);
              ProductCanonicalCondition conditionNew =
              ProductDimensions.CreateCanonicalCondition(ProductCanonicalConditionCondition.NEW);
              ProductCanonicalCondition conditionUsed =
              ProductDimensions.CreateCanonicalCondition(ProductCanonicalConditionCondition.USED);
              ProductCanonicalCondition conditionOther = ProductDimensions.CreateCanonicalCondition();

              // Build up the brand = Google node under the root.
              ProductPartitionNode brandGoogleNode = rootNode.AddChild(brandGoogle).AsSubdivision();
              brandGoogleNode.AddChild(conditionNew);
              brandGoogleNode.AddChild(conditionUsed);
              brandGoogleNode.AddChild(conditionOther);

              Assert.True(brandGoogleNode.HasChild(conditionNew),
              "HasChild should return true for existing child dimension.");
              Assert.AreSame(brandGoogleNode, brandGoogleNode.GetChild(conditionNew).Parent,
              "parent->GetChild->getParent should return parent.");
              Assert.True(brandGoogleNode.HasChild(conditionUsed),
              "HasChild should return true for existing child dimension.");
              Assert.AreSame(brandGoogleNode, brandGoogleNode.GetChild(conditionUsed).Parent,
              "parent->GetChild->getParent should return parent.");
              Assert.True(brandGoogleNode.HasChild(conditionOther),
              "HasChild should return true for existing child dimension.");
              Assert.AreSame(brandGoogleNode, brandGoogleNode.GetChild(conditionOther).Parent,
              "parent->GetChild->getParent should return parent.");

              // Build up the brand = null (other) node under the root.
              ProductPartitionNode brandOtherNode = rootNode.AddChild(brandOther).AsSubdivision();
              brandOtherNode.AddChild(conditionNew);
              Assert.True(brandOtherNode.HasChild(conditionNew),
              "HasChild should return true for existing child dimension.");
              Assert.AreSame(brandOtherNode, brandOtherNode.GetChild(conditionNew).Parent,
              "parent->GetChild->getParent should return parent.");
              Assert.False(brandOtherNode.HasChild(conditionUsed),
              "HasChild should return false for nonexistent child dimension.");
              Assert.False(brandOtherNode.HasChild(conditionOther),
              "HasChild should return false for nonexistent child dimension.");
              brandOtherNode.AddChild(conditionOther);
              Assert.True(brandOtherNode.HasChild(conditionOther),
              "HasChild should return true for existing child dimension.");
              Assert.AreSame(brandOtherNode, brandOtherNode.GetChild(conditionOther).Parent,
              "parent->GetChild->getParent should return parent.");

              // Remove one of the children of brand = null.
              brandOtherNode.RemoveChild(conditionOther);
              Assert.False(brandOtherNode.HasChild(conditionOther),
              "HasChild should return false for a removed child dimension.");

              // Remove the rest of the children of brand = null.
              brandOtherNode.RemoveAllChildren();
              Assert.False(brandOtherNode.HasChild(conditionNew),
              "HasChild should return false for any removed child dimension.");
              Assert.False(brandOtherNode.HasChild(conditionUsed),
              "HasChild should return false for any removed child dimension.");
        }