/// <summary>
        /// Takes a tree with product type L1 "clothing" and sets its bid.
        /// </summary>
        /// <param name="bid">The bid.</param>
        private void UpdateClothingBid(long bid)
        {
            tree.Root.GetChild(ProductDimensions.CreateType(ProductDimensionType.PRODUCT_TYPE_L1,
                                                            "clothing")).AsBiddableUnit().CpcBid = bid;

            Assert.DoesNotThrow(delegate() { tree = ExecuteTreeOperations(); });
        }
 /// <summary>
 /// Takes a tree with product type L1 "shoes" SUBDIVISION and collapses that node to a UNIT.
 /// </summary>
 private void CollapseShoes()
 {
     tree.Root.GetChild(
         ProductDimensions.CreateType(ProductDimensionType.PRODUCT_TYPE_L1, "shoes"))
     .AsBiddableUnit().CpcBid = (1500000L);
     Assert.DoesNotThrow(delegate() { tree = ExecuteTreeOperations(); });
 }
        /// <summary>
        /// Removes product type L1 "shoes".
        /// </summary>
        private void RemoveShoes()
        {
            tree.Root.RemoveChild(
                ProductDimensions.CreateType(ProductDimensionType.PRODUCT_TYPE_L1, "shoes"));

            Assert.DoesNotThrow(delegate() { tree = ExecuteTreeOperations(); });
        }
        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(); });
        }
        /// <summary>
        /// Takes a tree with:
        ///
        /// <pre>
        /// ROOT
        ///  ...
        ///  shoes
        ///    new
        ///      offerId=1 $1.00
        ///      offerId=2 $2.00
        ///      ...
        ///      offerId=20 $20.00
        ///    other - excluded
        /// </pre>
        ///
        ///  and changes it to:
        ///
        ///  <pre>
        /// ROOT
        ///  ...
        ///  shoes
        ///    new $1.25
        ///    other $0.50
        /// </pre>
        /// </summary>
        private void CollapseNewShoes()
        {
            ProductPartitionNode shoesLevel1 = tree.Root.GetChild(ProductDimensions.CreateType(
                                                                      ProductDimensionType.PRODUCT_TYPE_L1, "shoes"));

            shoesLevel1.GetChild(ProductDimensions.CreateCanonicalCondition(
                                     ProductCanonicalConditionCondition.NEW)).AsBiddableUnit().CpcBid = 1250000L;
            shoesLevel1.GetChild(ProductDimensions.CreateCanonicalCondition()).AsBiddableUnit()
            .CpcBid = 500000L;

            Assert.DoesNotThrow(delegate() {
                tree = ExecuteTreeOperations();
            });
        }
        /// <summary>
        /// Takes a tree with product type L1 "shoes" UNIT and subdivides that node into UNITs:
        ///
        /// <pre>
        /// shoes
        ///   new $1.00
        ///   refurbished $1.50
        ///   other - excluded
        /// </pre>
        /// </summary>
        private void SubdivideShoes()
        {
            ProductPartitionNode shoesLevel1 = tree.Root.GetChild(ProductDimensions.CreateType(
                                                                      ProductDimensionType.PRODUCT_TYPE_L1, "shoes"))
                                               .AsSubdivision();

            shoesLevel1.AddChild(ProductDimensions.CreateCanonicalCondition(
                                     ProductCanonicalConditionCondition.NEW)).AsBiddableUnit().CpcBid = 1000000L;
            shoesLevel1.AddChild(ProductDimensions.CreateCanonicalCondition(
                                     ProductCanonicalConditionCondition.REFURBISHED)).AsBiddableUnit().CpcBid = 1500000L;
            shoesLevel1.AddChild(ProductDimensions.CreateCanonicalCondition()).AsExcludedUnit();

            Assert.DoesNotThrow(delegate() {
                tree = ExecuteTreeOperations();
            });
        }
    public void TestProductTypeEquals() {
      ProductType productTypeA = new ProductType() {
        type = ProductDimensionType.BRAND,
        value = "google",
      };

      ProductType productTypeB = ProductDimensions.CreateType(ProductDimensionType.BRAND,
          "google");

      Assert.True(comparer.Equals(productTypeA, productTypeB));

      ProductType productTypeC = new ProductType() {
        type = ProductDimensionType.BRAND,
      };

      ProductType productTypeD = ProductDimensions.CreateType(ProductDimensionType.BRAND);

      Assert.True(comparer.Equals(productTypeC, productTypeD));
    }
        /// <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 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>
        /// 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();
            });
        }