public void TestAddItem() { //due to the complexity of the add items. we are going to create a known set of data points and add them to the collection. ShoppingCartItem si = new ShoppingCartItem(); si.Description = "Description"; si.DigitalContent = new DigitalItem("Digital Item Key", "Digital Item Description"); si.MerchantItemID = "Merchant Item ID"; si.MerchantPrivateItemData = "Private Data"; XmlDocument mpdDoc = new XmlDocument(); mpdDoc.LoadXml("<data />"); mpdDoc.DocumentElement.AppendChild(mpdDoc.CreateElement("node1")); mpdDoc.DocumentElement.AppendChild(mpdDoc.CreateElement("node2")); XmlNode[] mpdNodes = new XmlNode[] { mpdDoc.DocumentElement.ChildNodes[0], mpdDoc.DocumentElement.ChildNodes[1] }; si.MerchantPrivateItemDataNodes = mpdNodes; si.Name = "Name"; si.Price = 0.99m; si.Quantity = 1; AlternateTaxTable taxTable = new AlternateTaxTable("Example"); taxTable.AddStateTaxRule("OH", .06); si.TaxTable = taxTable; si.Weight = 10.5; si.TaxTable.AddCountryTaxRule(GCheckout.AutoGen.USAreas.ALL, 5.0); CheckoutShoppingCartRequest request = new CheckoutShoppingCartRequest(MERCHANT_ID, MERCHANT_KEY, EnvironmentType.Sandbox, "USD", 120); request.ContinueShoppingUrl = "http://localhost/"; request.AnalyticsData = "Test data"; request.PlatformID = 1234567890; request.EditCartUrl = "http://localhost/editcart.aspx"; request.RequestBuyerPhoneNumber = true; request.MerchantCalculationsUrl = "http://localhost/calculate.aspx"; request.AcceptMerchantCoupons = true; request.AcceptMerchantGiftCertificates = true; request.SetRoundingPolicy(RoundingMode.FLOOR, RoundingRule.TOTAL); request.AddShippingPackage("main", "Cleveland", "OH", "44114"); request.MerchantPrivateData = "Test Cool Stuff"; request.AddMerchantPrivateDataNode(mpdNodes[0]); XmlNode[] mpdn = request.MerchantPrivateDataNodes; Assert.AreSame(mpdn[0], mpdNodes[0]); try { request.AddItem(null); Assert.Fail("Null can't be passed to the AddItem methods"); } catch { } try { MethodInfo mi = typeof(CheckoutShoppingCartRequest).GetMethod("AddItem", new Type[] { typeof(IShoppingCartItem) }); mi.Invoke(request, new object[] { null }); Assert.Fail("Null can't be passed to the AddItem methods"); } catch { } request.AddItem(si); request.AddItem(si.Clone() as IShoppingCartItem); MethodInfo[] methods = typeof(CheckoutShoppingCartRequest).GetMethods(); foreach (MethodInfo mi in methods) { bool cancel = false; //we are only working with AddItems if (mi.Name == "AddItem") { Type sct = typeof(ShoppingCartItem); ShoppingCartItem si2 = si.Clone() as ShoppingCartItem; ParameterInfo[] parameters = mi.GetParameters(); object[] setter = new object[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { ParameterInfo pi = parameters[i]; if (pi.ParameterType == typeof(ShoppingCartItem) || pi.ParameterType == typeof(IShoppingCartItem)) { cancel = true; continue; } //get the property from the object PropertyInfo source; if (pi.Name != "digitalItem") { source = sct.GetProperty(pi.Name, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance); } else { source = sct.GetProperty("DigitalContent"); } setter[i] = source.GetValue(si2, null); //we want to split and take the first item if (!pi.ParameterType.IsArray && source.PropertyType.IsArray) { object[] vals = setter[i] as object[]; setter[i] = vals[0] as object; } } if (!cancel) { //now call the method ShoppingCartItem called = mi.Invoke(request, setter) as ShoppingCartItem; //this is to fix a params array issue. if (parameters[parameters.Length - 1].Name == "MerchantPrivateItemDataNodes") { called.MerchantPrivateItemDataNodes = si2.MerchantPrivateItemDataNodes; } } } } byte[] toXml = request.GetXml(); //Make sure we can add an item to the cart. ShoppingCartItem item = request.AddItem("Item 1", "Cool Candy 1", "Merchant Item ID", 2.00M, 1); item.Weight = 2.2; item.MerchantPrivateItemData = null; //perform a null check //verify we can't set the price to fractions. item.Price = 1.975m; Assert.AreEqual(1.98m, item.Price); item.Price = 1.994m; Assert.AreEqual(1.99m, item.Price); Assert.AreEqual(2.2, item.Weight); Assert.AreEqual("Merchant Item ID", item.MerchantItemID); //this is a very specific test to make sure that if only one node exists, return it. it may be for a reason. XmlDocument doc = new XmlDocument(); doc.LoadXml("<data />"); doc.DocumentElement.SetAttribute("test", "cool"); string xml = doc.OuterXml; item.MerchantPrivateItemDataNodes = new XmlNode[] { doc.DocumentElement }; string xmlReturn = item.MerchantPrivateItemData; Assert.AreEqual(xml, xmlReturn); //create a new node XmlNode secondNode = doc.DocumentElement.AppendChild(doc.CreateElement("test")); item.MerchantPrivateItemDataNodes = new XmlNode[] { doc.DocumentElement, secondNode }; xmlReturn = item.MerchantPrivateItemData; Assert.AreEqual(null, xmlReturn); item.MerchantPrivateItemDataNodes = null; Assert.AreEqual(new XmlNode[] { }, item.MerchantPrivateItemDataNodes); //this should throw an exception try { item.Weight = -1; Assert.Fail("Weight should not be allowed to be negative."); } catch { } //create a new instance of the cart item ShoppingCartItem testItem = new ShoppingCartItem(); }