public void TwoContentsTwoStructuresWithAnonymousBlocks()
        {
            // ensure blocks are in the right order

            const string json1 =
                "["
                + "{"
                + "\"Source\":\"test1\","
                + "\"Blocks\":["
                + "{"
                + "\"Source\":\"b1\","
                + "},"
                + "]"
                + "},"
                + "]";

            const string json2 =
                "["
                + "{"
                + "\"Source\":\"test2\","
                + "\"Blocks\":["
                + "{"
                + "\"Source\":\"b2\","
                + "},"
                + "]"
                + "},"
                + "]";

            var p = new PublishedContent
            {
                Structures = JsonSerializer.Instance.Deserialize <StructureDataValue[]>(json2),
                Parent     = new PublishedContent
                {
                    Structures = JsonSerializer.Instance.Deserialize <StructureDataValue[]>(json1)
                }
            };

            var s = RenderingStructure.Compute(p, x => ((PublishedContent)x).Structures);

            Assert.IsNotNull(s);

            Assert.AreEqual("test2", s.Source);

            Assert.AreEqual(2, s.Blocks.Count);
            Assert.AreEqual("b1", s.Blocks[0].Source);
            Assert.AreEqual("b2", s.Blocks[1].Source);
        }
        public void TwoContentsTwoStructuresWithNamedBlocksOverride1()
        {
            // test named blocks can be overriden

            const string json1 =
                "["
                + "{"
                + "\"Source\":\"test1\","         // template
                + "\"Blocks\":["
                + "{"
                + "\"Name\":\"b\","                 // defined a name block
                + "\"Source\":\"source1\","         // with a source
                + "\"Data\":{\"x\":123}"
                + "},"
                + "]"
                + "},"
                + "]";

            const string json2 =
                "["
                + "{"
                + "\"Source\":\"test2\","         // use another template
                + "\"Blocks\":["
                + "{"
                + "\"Name\":\"b\","                 // named => same block
                + "\"Source\":\"source2\","         // override the source
                + "\"Data\":{\"y\":456}"
                + "},"
                + "]"
                + "},"
                + "]";

            var p = new PublishedContent
            {
                Structures = JsonSerializer.Instance.Deserialize <StructureDataValue[]>(json2),
                Parent     = new PublishedContent
                {
                    Structures = JsonSerializer.Instance.Deserialize <StructureDataValue[]>(json1)
                }
            };

            // illegal to override the source
            Assert.Throws <StructureException>(
                () => RenderingStructure.Compute(p, x => ((PublishedContent)x).Structures));
        }
        public void OneContentManyStructuresAndBlocksAndIndexes2()
        {
            const string json =
                "["
                + "{"
                + "\"Source\":\"test1\","
                + "\"Blocks\":["
                + "{"
                + "\"Source\":\"b1\","
                + "\"Index\":1000"                 // move it down
                + "},"
                + "]"
                + "},"
                + "{"
                + "\"Source\":\"test2\","
                + "\"Blocks\":["
                + "{"
                + "\"Source\":\"b2\","
                + "},"
                + "]"
                + "},"
                + "]";

            var p = new PublishedContent
            {
                Structures = JsonSerializer.Instance.Deserialize <StructureDataValue[]>(json)
            };

            var s = RenderingStructure.Compute(p, x => ((PublishedContent)x).Structures);

            Assert.IsNotNull(s);

            Assert.AreEqual("test2", s.Source);

            Assert.AreEqual(2, s.Blocks.Count);
            Assert.AreEqual("b2", s.Blocks[0].Source);
            Assert.AreEqual("b1", s.Blocks[1].Source);
        }
        public void OneContentOneStructure()
        {
            // test that one basic structure can be processed

            const string json =
                "["
                + "{"
                + "\"Source\":\"test\""
                + "}"
                + "]";

            var p = new PublishedContent
            {
                Structures = JsonSerializer.Instance.Deserialize <StructureDataValue[]>(json)
            };

            var s = RenderingStructure.Compute(p, x => ((PublishedContent)x).Structures);

            Assert.IsNotNull(s);

            Assert.AreEqual("test", s.Source);
            Assert.IsEmpty(s.Blocks);
        }
        public void TwoContentsTwoStructuresWithLevels()
        {
            // test that levels work with parents

            const string json1 =
                "["
                + "{"
                + "\"Source\":\"test1\","
                + "\"MinLevel\":1,"
                + "\"MaxLevel\":1"
                + "}"
                + "]";

            const string json2 =
                "["
                + "{"
                + "\"Source\":\"test2\","
                + "\"MinLevel\":8"
                + "}"
                + "]";

            var p = new PublishedContent
            {
                Structures = JsonSerializer.Instance.Deserialize <StructureDataValue[]>(json2),
                Parent     = new PublishedContent
                {
                    Structures = JsonSerializer.Instance.Deserialize <StructureDataValue[]>(json1)
                }
            };

            var s = RenderingStructure.Compute(p, x => ((PublishedContent)x).Structures);

            Assert.IsNotNull(s);

            Assert.AreEqual("test1", s.Source);
            Assert.IsEmpty(s.Blocks);
        }
        public void TwoContentsTwoStructuresWithNamedBlocksAndSubBlocksAndKill()
        {
            // test block kill

            const string json1 =
                "["
                + "{"
                + "\"Source\":\"test1\","         // template
                + "\"Blocks\":["
                + "{"
                + "\"Name\":\"ba\","             // define a named block
                + "\"Source\":\"ba\","
                + "\"Blocks\":["                 // define sub-blocks
                + "{"
                + "\"Source\":\"b1\","
                + "},"
                + "]"
                + "},"
                + "{"
                + "\"Name\":\"bb\","             // define a named block
                + "\"Blocks\":["                 // define sub-blocks
                + "{"
                + "\"Source\":\"b1\","
                + "},"
                + "]"
                + "},"
                + "]"
                + "},"
                + "]";

            const string json2 =
                "["
                + "{"
                + "\"Source\":\"test2\","         // use another template
                + "\"Blocks\":["
                + "{"
                + "\"Name\":\"ba\","             // named => same block
                + "\"Blocks\":["                 // add sub-blocks
                + "{"
                + "\"Source\":\"b2\","
                + "},"
                + "]"
                + "},"
                + "{"
                + "\"Name\":\"bb\","                 // named => same block
                + "\"IsKill\":true,"                 // kill that block
                + "},"
                + "]"
                + "},"
                + "]";

            var p = new PublishedContent
            {
                Structures = JsonSerializer.Instance.Deserialize <StructureDataValue[]>(json2),
                Parent     = new PublishedContent
                {
                    Structures = JsonSerializer.Instance.Deserialize <StructureDataValue[]>(json1)
                }
            };

            var s = RenderingStructure.Compute(p, x => ((PublishedContent)x).Structures);

            Assert.IsNotNull(s);

            // template is ok
            Assert.AreEqual("test2", s.Source);

            // only one named block, ba, because bb has been killed
            Assert.AreEqual(1, s.Blocks.Count);
            Assert.AreEqual("ba", s.Blocks[0].Source);

            // block contains the two sub-blocks in the right order
            Assert.AreEqual(2, s.Blocks[0].Blocks.Count);
            Assert.AreEqual("b1", s.Blocks[0].Blocks[0].Source);
            Assert.AreEqual("b2", s.Blocks[0].Blocks[1].Source);
        }
        public void TwoContentsTwoStructuresWithNamedBlocksAndSubBlocksAndReset()
        {
            // test block reset

            const string json1 =
                "["
                + "{"
                + "\"Source\":\"test1\","         // template
                + "\"Blocks\":["
                + "{"
                + "\"Name\":\"b\","              // define a named block
                + "\"Source\":\"b\","
                + "\"Blocks\":["                 // define sub blocks - will be resetted
                + "{"
                + "\"Source\":\"b1\","
                + "},"
                + "]"
                + "},"
                + "]"
                + "},"
                + "]";

            const string json2 =
                "["
                + "{"
                + "\"Source\":\"test2\","         // use another template
                + "\"Blocks\":["
                + "{"
                + "\"Name\":\"b\","              // named => same block
                + "\"IsReset\":true,"            // but reset contents
                + "\"Blocks\":["                 // so this defines the sub blocks
                + "{"
                + "\"Source\":\"b2\","
                + "},"
                + "]"
                + "},"
                + "]"
                + "},"
                + "]";

            var p = new PublishedContent
            {
                Structures = JsonSerializer.Instance.Deserialize <StructureDataValue[]>(json2),
                Parent     = new PublishedContent
                {
                    Structures = JsonSerializer.Instance.Deserialize <StructureDataValue[]>(json1)
                }
            };

            var s = RenderingStructure.Compute(p, x => ((PublishedContent)x).Structures);

            Assert.IsNotNull(s);

            // template is ok
            Assert.AreEqual("test2", s.Source);

            // only one named block
            Assert.AreEqual(1, s.Blocks.Count);
            Assert.AreEqual("b", s.Blocks[0].Name);
            Assert.AreEqual("b", s.Blocks[0].Source);

            // only one sub-block, b2
            Assert.AreEqual(1, s.Blocks[0].Blocks.Count);
            Assert.AreEqual("b2", s.Blocks[0].Blocks[0].Source);
        }
        public void TwoContentsTwoStructuresWithBlocksAndMinLevel()
        {
            // ensure blocks are in the right order

            const string json1 =
                "["
                + "{"
                + "\"Source\":\"test1\","         // template
                + "\"Blocks\":["
                + "{"
                + "\"Source\":\"b1before\","                 // block with minlevel
                + "\"MinLevel\":8"
                + "},"
                + "{"
                + "\"Source\":\"b1\","                 // block
                + "},"
                + "{"
                + "\"Source\":\"b1before\","                 // block with minlevel
                + "\"MinLevel\":8"
                + "},"
                + "]"
                + "},"
                + "]";

            const string json2 =
                "["
                + "{"
                + "\"Source\":\"test2\","         // use another template
                + "\"Blocks\":["
                + "{"
                + "\"Source\":\"b2before\","                 // block with minlevel
                + "\"MinLevel\":8"
                + "},"
                + "{"
                + "\"Source\":\"b2\","                 // block
                + "},"
                + "{"
                + "\"Source\":\"b2after\","                 // block with minlevel
                + "\"MinLevel\":8"
                + "},"
                + "]"
                + "},"
                + "]";

            var p = new PublishedContent
            {
                Structures = JsonSerializer.Instance.Deserialize <StructureDataValue[]>(json2),
                Parent     = new PublishedContent
                {
                    Structures = JsonSerializer.Instance.Deserialize <StructureDataValue[]>(json1)
                }
            };

            var s = RenderingStructure.Compute(p, x => ((PublishedContent)x).Structures);

            Assert.IsNotNull(s);

            // template is ok
            Assert.AreEqual("test2", s.Source);

            // only blocks with appropriate level are here
            Assert.AreEqual(2, s.Blocks.Count);
            Assert.AreEqual("b1", s.Blocks[0].Source);
            Assert.AreEqual("b2", s.Blocks[1].Source);
        }
        public void RendererViewText()
        {
            // setup environment for unit testing

            RunContext.IsTesting    = true;
            RunContext.RuntimeCache = new TestRuntimeCacheProvider();

            // setup MVC

            var controller = new TestBlocksController();

            var controllerContextMock = new Mock <ControllerContext>();

            controllerContextMock.Setup(c => c.Controller).Returns(controller);
            var controllerContext = controllerContextMock.Object;

            var engineMock = new Mock <IViewEngine>();
            var engine     = engineMock.Object;

            engineMock.Setup(e => e.FindView(It.IsAny <ControllerContext>(), "main", null, It.IsAny <bool>()))
            .Returns(new ViewEngineResult(new MainView(), engine));
            engineMock.Setup(e => e.FindPartialView(It.IsAny <ControllerContext>(), "block1", It.IsAny <bool>()))
            .Returns(new ViewEngineResult(new Block1View(), engine));
            engineMock.Setup(e => e.FindPartialView(It.IsAny <ControllerContext>(), "block2", It.IsAny <bool>()))
            .Returns(new ViewEngineResult(new Block2View(), engine));

            ViewEngines.Engines.Clear();
            ViewEngines.Engines.Add(engine);

            // setup blocks

            BlocksController.Settings.CacheProfiles["forever"] = new CacheProfile
            {
                Mode     = "cache",
                Duration = 6666666
            };

            BlocksController.Settings.CacheMode["cache"] = (xBlock, xContent, xViewData) => CacheMode.Cache;

            BlocksController.Settings.MergeMeta = (blockModel, objects) =>
            {
                if (objects == null)
                {
                    return;
                }
                var list = (List <string>)objects["test"];
                if (!blockModel.Meta.ContainsKey("test"))
                {
                    blockModel.Meta["test"] = new List <string>();
                }
                ((List <string>)blockModel.Meta["test"]).AddRange(list);
            };

            // test

            const string json = @"
[
    {
        ""Source"": ""main"",
        ""Blocks"": [
            {
                ""Source"": ""Block1""
            },
            {
                ""Source"": ""Block2"",
                ""Cache"": ""forever""
            }
        ]
    }
]
";

            var content = new PublishedContent
            {
                Structures = JsonSerializer.Instance.Deserialize <StructureDataValue[]>(json)
            };
            var model = new RenderModel(content, CultureInfo.CurrentUICulture);

            var rs = RenderingStructure.Compute(null, content, x => ((PublishedContent)x).Structures);

            Assert.IsNotNull(rs);

            var cacheMode = rs.Cache == null
                ? CacheMode.Ignore
                : rs.Cache.GetCacheMode(rs, model.Content, null);

            var text = cacheMode == CacheMode.Ignore
                ? Renderer.ViewText(controllerContext, rs, model.Content, model.CurrentCulture)
                : Renderer.ViewTextWithCache(controllerContext, rs, model.Content, model.CurrentCulture, cacheMode == CacheMode.Refresh);

            Console.WriteLine(text);

            text = cacheMode == CacheMode.Ignore
                ? Renderer.ViewText(controllerContext, rs, model.Content, model.CurrentCulture)
                : Renderer.ViewTextWithCache(controllerContext, rs, model.Content, model.CurrentCulture, cacheMode == CacheMode.Refresh);

            Console.WriteLine(text);

            // expected:
            //main
            //block1 635640043255160266
            //block2 635640043255520520
            //meta: block1,block2
            //main
            //block1 635640043255580629 <<<< different
            //block2 635640043255520520 <<<< identical to previous one
            //meta: block1,block2
        }