public void should_build_pageName_for_objectValue_equal_to_ActiveState()
        {
            //Arrange
            var omniture = new ExcelToXML.Model.Omniture();

            omniture.Domain = "domain";
            omniture.SiteSection = "site section";
            omniture.SubSection = "sub section";
            omniture.ActiveState = "active state";
            omniture.ObjectValue = "active state";
            omniture.ObjectDescription = "object description";
            omniture.CallToAction = "call to action";

            dynamic propBuilder = new PropBuilder(omniture);

            //Act
            string pageName = propBuilder.pageName;

            //Assert
            pageName.Should().NotBeNullOrEmpty()
                .And.Be("domain | site section | sub section | active state | object description");
        }
        public void CreateTrackingXml(string inputFileName, string trackingOutputFileName, string metadataOutputFileName)
        {
            Trace.WriteLine("opening source workbook... be patient :)");

            var workbook = new ClosedXML.Excel.XLWorkbook(inputFileName);
            Trace.WriteLine("omniture source workbook opened");

            var worksheet = workbook.Worksheets.Where(x => x.Name.ToLower() == "omniture").FirstOrDefault();

            XElement definitions = new XElement("definitions");

            int maxTrackingId = GetMaxTrackingId(definitions);
            var lastRowUsed = worksheet.LastRowUsed().RowNumber();
            var lastColumnUsed = worksheet.LastColumnUsed().ColumnNumber();

            String trackingId = "";

            for (int rowIndex = 2; rowIndex <= lastRowUsed; rowIndex++) {
                var row = worksheet.Row(rowIndex);
                var element = definitions.Elements("tracking").Where(x => string.Equals(
                    x.Attribute("id").Value,
                    row.Cell(1).GetValue<string>(),
                    StringComparison.InvariantCultureIgnoreCase)
                ).SingleOrDefault();

                var tracking = new XElement("tracking");

                var omniture = new Omniture(row);
                omniture.Skip = BuildSkipList(row, lastColumnUsed);

                dynamic propBuilder = new PropBuilder(omniture);
                DetectPatternFor("pageName", omniture, row.Cell(10).GetValue<string>(), propBuilder.pageName);
                DetectPatternFor("prop1", omniture, row.Cell(12).GetValue<string>(), propBuilder.prop1);
                DetectPatternFor("prop2", omniture, row.Cell(13).GetValue<string>(), propBuilder.prop2);
                DetectPatternFor("prop3", omniture, row.Cell(14).GetValue<string>(), propBuilder.prop3);
                DetectPatternFor("prop4", omniture, row.Cell(15).GetValue<string>(), propBuilder.prop4);
                DetectPatternFor("prop5", omniture, row.Cell(16).GetValue<string>(), propBuilder.prop5);
                DetectPatternFor("prop6", omniture, row.Cell(17).GetValue<string>(), propBuilder.prop6);
                DetectPatternFor("prop7", omniture, row.Cell(18).GetValue<string>(), propBuilder.prop7);
                DetectPatternFor("prop8", omniture, row.Cell(19).GetValue<string>(), propBuilder.prop8);
                DetectPatternFor("prop9", omniture, row.Cell(20).GetValue<string>(), propBuilder.prop9);
                DetectPatternFor("prop10", omniture, row.Cell(21).GetValue<string>(), propBuilder.prop10);
                DetectPatternFor("prop11", omniture, row.Cell(22).GetValue<string>(), propBuilder.prop11);
                DetectPatternFor("prop12", omniture, row.Cell(23).GetValue<string>(), propBuilder.prop12);
                DetectPatternFor("prop13", omniture, row.Cell(24).GetValue<string>(), propBuilder.prop13);
                DetectPatternFor("prop14", omniture, row.Cell(25).GetValue<string>(), propBuilder.prop14);
                DetectPatternFor("prop15", omniture, row.Cell(26).GetValue<string>(), propBuilder.prop15);
                DetectPatternFor("prop16", omniture, row.Cell(27).GetValue<string>(), propBuilder.prop16);
                DetectPatternFor("prop17", omniture, row.Cell(28).GetValue<string>(), propBuilder.prop17);
                DetectPatternFor("prop18", omniture, row.Cell(29).GetValue<string>(), propBuilder.prop18);
                DetectPatternFor("prop19", omniture, row.Cell(30).GetValue<string>(), propBuilder.prop19);
                DetectPatternFor("prop20", omniture, row.Cell(31).GetValue<string>(), propBuilder.prop20);
                DetectPatternFor("prop21", omniture, row.Cell(32).GetValue<string>(), propBuilder.prop21);
                DetectPatternFor("prop22", omniture, row.Cell(33).GetValue<string>(), propBuilder.prop22);
                DetectPatternFor("prop23", omniture, row.Cell(34).GetValue<string>(), propBuilder.prop23);
                DetectPatternFor("prop24", omniture, row.Cell(35).GetValue<string>(), propBuilder.prop24);
                DetectPatternFor("prop25", omniture, row.Cell(36).GetValue<string>(), propBuilder.prop25);

                if (!string.IsNullOrEmpty(omniture.ParentId)) {
                    var parentElementRow = FindRowById(omniture.ParentId, worksheet);
                    if (parentElementRow != null) {
                        var omnitureParent = new Omniture(parentElementRow);
                        var properties = typeof(Omniture).GetProperties();
                        properties
                            .Where(p => p.GetValue(omniture, null).GetType() == typeof(string) &&
                                string.Equals(
                                    p.GetValue(omniture, null).ToString(),
                                    p.GetValue(omnitureParent, null).ToString(),
                                    StringComparison.InvariantCultureIgnoreCase)
                                ).ToList()
                                .ForEach(p => p.SetValue(omniture, null, null));
                    } else {
                        omniture.ParentId = string.Empty;
                    }
                }

                trackingId = row.Cell(1).GetValue<string>();
                if (string.IsNullOrEmpty(trackingId)) {
                    maxTrackingId++;
                    trackingId = string.Format("t-{0}", maxTrackingId);
                    row.Cell(1).Value = string.Format("t-{0}", maxTrackingId);
                }

                if (!string.Equals(trackingId, "t-0", StringComparison.InvariantCultureIgnoreCase) && !omniture.isEmpty) {
                    tracking.Add((XElement)omniture);
                }

                if (tracking != null && !string.IsNullOrEmpty(trackingId)) {
                    tracking.SetAttributeValue("id", trackingId);
                    definitions.Add(tracking);
                }
            }

            var floodlightWorksheet = workbook.Worksheets.Where(x => x.Name.ToLower() == "floodlight").FirstOrDefault();
            lastRowUsed = floodlightWorksheet.LastRowUsed().RowNumber();
            lastColumnUsed = floodlightWorksheet.LastColumnUsed().ColumnNumber();

            trackingId = "";
            for (int rowIndex = 3; rowIndex <= lastRowUsed; rowIndex++) {
                var row = floodlightWorksheet.Row(rowIndex);

                var element = definitions.Elements("tracking").Where(x => string.Equals(
                    x.Attribute("id").Value,
                    row.Cell(1).GetValue<string>(),
                    StringComparison.InvariantCultureIgnoreCase)
                ).SingleOrDefault();

                if (element == null) {
                    trackingId = row.Cell(1).GetValue<string>();
                    if (string.IsNullOrEmpty(trackingId)) {
                        maxTrackingId++;
                        trackingId = string.Format("t-{0}", maxTrackingId);
                        row.Cell(1).Value = string.Format("t-{0}", maxTrackingId);
                    }
                    element = new XElement("tracking");
                    element.SetAttributeValue("id", trackingId);
                }

                var floodlight = new Floodlight(row);

                var floodlightElement = element.Elements("floodlight").Where(x => x.Elements("category").Where(c => c.Attribute("varyby") != null).Count() > 0).SingleOrDefault();
                if (floodlightElement != null && floodlight.Category.Items != null && floodlight.Category.Items.Count > 0) {
                    floodlightElement.Element("category").Add(
                        floodlight.Category.Items.Select<KeyValuePair<string, string>, XElement>(x => {
                            XElement valueElement = new XElement("value", x.Value);
                            valueElement.SetAttributeValue("for", x.Key);
                            return valueElement;
                        })
                    );
                } else {
                    element.Add((XElement)floodlight);
                }
            }

            floodlightWorksheet
                .Rows()
                .Where(x => x.Cell(1).GetValue<string>().StartsWith("t-"))
                .Select(x => {
                    var floodlight = new Floodlight(x);

                    return floodlight;
                })
                .ToList()
                .ForEach(x => { });

            Trace.WriteLine("saving tracking xml file");
            definitions.Save(trackingOutputFileName);
            Trace.WriteLine("saved");

            XElement metadata = new XElement("metadata"); ;

            var metadatatWorksheet = workbook.Worksheets.Where(x => x.Name.ToLower() == "meta").FirstOrDefault();
            lastRowUsed = floodlightWorksheet.LastRowUsed().RowNumber();

            metadata.Add(metadatatWorksheet
                .Rows()
                .Where(x => x.Cell(1).GetValue<string>().StartsWith("/"))
                .Select(x => {
                    var url = new XElement("url");
                    var id = x.Cell(1).GetValue<string>();

                    id = id.EndsWith("/") ? id : id + "/";

                    url.SetAttributeValue("id", id);
                    url.Add(new XElement("title", x.Cell(3).GetValue<string>()));
                    url.Add(new XElement("description", x.Cell(4).GetValue<string>()));
                    url.Add(new XElement("keywords", x.Cell(5).GetValue<string>()));
                    url.Add(new XElement("pageViewTracking", x.Cell(2).GetValue<string>()));

                    return url;
                }));

            Trace.WriteLine("saving metadata xml file");
            metadata.Save(metadataOutputFileName);
            Trace.WriteLine("saved");

            Trace.WriteLine("saving omniture workbook changes (ids and stuff)...");
            Trace.WriteLine("this may take a while, I'm not excel you know...");

            var fileName = String.Format("{0}-{1}.xlsx", Path.GetFileNameWithoutExtension(inputFileName), FileTimeStamp);

            workbook.SaveAs(Path.Combine(Path.GetDirectoryName(inputFileName), fileName));
            Trace.WriteLine("saved");
        }
        public void should_have_all_15_properties()
        {
            //Arrange
            var omniture = new ExcelToXML.Model.Omniture();
            omniture.Domain = "domain";
            omniture.SiteSection = "site section";
            omniture.SubSection = "sub section";
            omniture.ActiveState = "active state";
            omniture.ObjectValue = "object value";
            omniture.ObjectDescription = "object description";
            omniture.CallToAction = "call to action";

            dynamic propBuilder = new PropBuilder(omniture);

            //Act
            string prop1 = propBuilder.prop1;
            string prop2 = propBuilder.prop2;
            string prop3 = propBuilder.prop3;
            string prop4 = propBuilder.prop4;
            string prop5 = propBuilder.prop5;
            string prop6 = propBuilder.prop6;
            string prop7 = propBuilder.prop7;
            string prop8 = propBuilder.prop8;
            string prop9 = propBuilder.prop9;
            string prop10 = propBuilder.prop10;
            string prop11 = propBuilder.prop11;
            string prop12 = propBuilder.prop12;
            string prop13 = propBuilder.prop13;
            string prop14 = propBuilder.prop14;
            string prop15 = propBuilder.prop15;

            //Assert
            prop1.Should().NotBeNullOrEmpty()
                .And.Be("site section");
            prop2.Should().NotBeNullOrEmpty()
                .And.Be("sub section");
            prop3.Should().NotBeNullOrEmpty()
                .And.Be("site section | sub section");
            prop4.Should().NotBeNullOrEmpty()
                .And.Be("active state");
            prop5.Should().NotBeNullOrEmpty()
                .And.Be("sub section | active state");
            prop6.Should().NotBeNullOrEmpty()
                .And.Be("site section | sub section | active state");
            prop7.Should().NotBeNullOrEmpty()
                .And.Be("object value");
            prop8.Should().NotBeNullOrEmpty()
                .And.Be("site section | active state");
            prop9.Should().NotBeNullOrEmpty()
                .And.Be("sub section | active state | object value");
            prop10.Should().NotBeNullOrEmpty()
                .And.Be("site section | sub section | site section | active state");
            prop11.Should().NotBeNullOrEmpty()
                .And.Be("object description");
            prop12.Should().NotBeNullOrEmpty()
                .And.Be("object value | object description");
            prop13.Should().NotBeNullOrEmpty()
                .And.Be("active state | object value | object description");
            prop14.Should().NotBeNullOrEmpty()
                .And.Be("sub section | active state | object value | object description");
            prop15.Should().NotBeNullOrEmpty()
                .And.Be("site section | sub section | active state | object value | object description");
        }
        public void should_have_empty_values_for_empty_reference_object()
        {
            //Arrange
            var omniture = new ExcelToXML.Model.Omniture();
            dynamic propBuilder = new PropBuilder(omniture);

            //Act
            string pageName = propBuilder.pageName;
            string prop1 = propBuilder.prop1;
            string prop2 = propBuilder.prop2;
            string prop3 = propBuilder.prop3;
            string prop4 = propBuilder.prop4;
            string prop5 = propBuilder.prop5;
            string prop6 = propBuilder.prop6;
            string prop7 = propBuilder.prop7;
            string prop8 = propBuilder.prop8;
            string prop9 = propBuilder.prop9;
            string prop10 = propBuilder.prop10;
            string prop11 = propBuilder.prop11;
            string prop12 = propBuilder.prop12;
            string prop13 = propBuilder.prop13;
            string prop14 = propBuilder.prop14;
            string prop15 = propBuilder.prop15;

            //Assert
            pageName.Should().BeNullOrEmpty();
            prop1.Should().BeNullOrEmpty();
            prop2.Should().BeNullOrEmpty();
            prop3.Should().BeNullOrEmpty();
            prop4.Should().BeNullOrEmpty();
            prop5.Should().BeNullOrEmpty();
            prop6.Should().BeNullOrEmpty();
            prop7.Should().BeNullOrEmpty();
            prop8.Should().BeNullOrEmpty();
            prop9.Should().BeNullOrEmpty();
            prop10.Should().BeNullOrEmpty();
            prop11.Should().BeNullOrEmpty();
            prop12.Should().BeNullOrEmpty();
            prop13.Should().BeNullOrEmpty();
            prop14.Should().BeNullOrEmpty();
            prop15.Should().BeNullOrEmpty();
        }