public void OneContentTwoStructuresInContext()
        {
            // without context, test2 is picked
            // with context, only test1 is visble

            const string json =
                "["
                + "{"
                + "\"Source\":\"test1\","
                + "\"Contexts\": [ \"ctx\" ]"
                + "},"
                + "{"
                + "\"Source\":\"test2\""
                + "},"
                + "]";

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

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

            Assert.IsNotNull(s);
            Assert.AreEqual("test1", s.Source);

            s = RenderingStructure.Compute(null, p, x => ((PublishedContent)x).Structures);
            Assert.IsNotNull(s);
            Assert.AreEqual("test2", s.Source);

            s = RenderingStructure.Compute(" ", p, x => ((PublishedContent)x).Structures);
            Assert.IsNotNull(s);
            Assert.AreEqual("test2", s.Source);
        }
        public void TwoContentsTwoStructuresWithNamedBlocksOverride2()
        {
            // 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)
                }
            };

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

            Assert.IsNotNull(s);

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

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

            // source
            Assert.AreEqual("source1", s.Blocks[0].Source);

            // merged data
            Assert.AreEqual(2, s.Blocks[0].Data.Count);
            Assert.AreEqual(123, s.Blocks[0].Data["x"]);
            Assert.AreEqual(456, s.Blocks[0].Data["y"]);
        }
        public void TwoContentsTwoStructures()
        {
            // test that structures at various levels can be processed

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

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

            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.IsEmpty(s.Blocks);
        }
        public void OneContentTwoStructures()
        {
            // test structures order when two structures exist
            // test2 should be picked

            const string json =
                "["
                + "{"
                + "\"Source\":\"test1\""
                + "},"
                + "{"
                + "\"Source\":\"test2\""
                + "},"
                + "]";

            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.IsEmpty(s.Blocks);
        }
        public void OneContentTwoStructuresWithLevels()
        {
            // test structure exclusion by level
            // same as test above, but test2 is ignored

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

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

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

            Assert.IsNotNull(s);

            Assert.AreEqual("test1", s.Source);
            Assert.IsEmpty(s.Blocks);
        }
        public void TwoContentsOneStructureOnParent()
        {
            // test that one basic structure, defined on parent, can be processed

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

            var p = new PublishedContent
            {
                Parent = 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 OneContentTwoStructuresContentTypesExcl()
        {
            const string json =
                "["
                + "{"
                + "\"Source\":\"test1\""
                + "},"
                + "{"
                + "\"Source\":\"test2\","
                + "\"ContentTypes\": [ \"ctype1\" ],"
                + "\"ContentTypesNegate\": true"
                + "},"
                + "]";

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

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

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

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

            s = RenderingStructure.Compute(p, x => ((PublishedContent)x).Structures);
            Assert.IsNotNull(s);
            Assert.AreEqual("test1", s.Source);
        }
        public void OneStructureWithBlocks()
        {
            // ensure it works

            const string json =
                "["
                + "{"
                + "\"Source\":\"test\","
                + "\"Blocks\":["
                + "{"
                + "\"Source\":\"b1\","
                + "},"
                + "{"
                + "\"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("test", s.Source);

            Assert.AreEqual(2, s.Blocks.Count);
            Assert.AreEqual("b1", s.Blocks[0].Source);
            Assert.AreEqual("b2", s.Blocks[1].Source);
        }
Beispiel #9
0
            public GetActionResultEventArgs(RenderModel model, RenderingStructure structure, string context)
            {
                Model     = model;
                Structure = structure;
                Context   = context;

                TraceBlocksInHtml = false;
            }
        public void NamedBlockUnderAnonymousBlock()
        {
            const string json =
                "["
                + "{"
                + "\"Source\":\"test1\","
                + "\"Blocks\":["
                + "{"             // anonymous
                + "\"Blocks\":["
                + "{"
                + "\"Name\":\"b\","                         // with a named block
                + "\"DataJson\":\"{\\\"value\\\":1}\","     // data
                + "},"
                + "{"
                + "\"Source\":\"c\","                         // and an anonymous
                + "},"
                + "{"
                + "\"Name\":\"b\","                         // repeat
                + "\"Data\":{\"value\":2},"                 // override
                + "},"
                + "]"
                + "},"
                + "]"
                + "},"
                + "]";

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

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

            Assert.IsNotNull(s);

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

            // one anonymous block
            Assert.AreEqual(1, s.Blocks.Count);
            var anon = s.Blocks[0];

            Assert.IsNull(s.Blocks[0].Data);

            // only two blocks 'cos one is named, in the right order
            Assert.AreEqual(2, anon.Blocks.Count);
            Assert.AreEqual("b", anon.Blocks[0].Source);
            Assert.AreEqual("c", anon.Blocks[1].Source);

            // and the named block can be accessed via index
            Assert.IsNotNull(anon.Blocks["b"]);

            // and has proper values
            Assert.AreEqual(2, anon.Blocks["b"].Data["value"]);
        }
        public void NamedBlocsIssues()
        {
            const string json =
                "["
                + "{"
                + "\"Name\":\"test\","
                + "\"Data\": { \"val\":1},"
                + "\"Blocks\" : ["
                + "{"
                + "\"Name\":\"block\","
                + "\"Data\": { \"val\":1}"
                + "}"
                + "]"
                + "},"
                + "{"
                + "\"Name\":\"test\","
                + "\"Data\": { \"val\":2 },"
                + "\"Blocks\" : ["
                + "{"
                + "\"Name\":\"block\","
                + "\"Data\": { \"val\":2}"
                + "}"
                + "]"
                + "},"
                + "{"
                + "\"Name\":\"test\","
                + "\"Data\": { \"val\":3 },"
                + "\"Blocks\" : ["
                + "{"
                + "\"Name\":\"block\","
                + "\"Data\": { \"val\":3}"
                + "}"
                + "]"
                + "}"
                + "]";

            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.AreEqual(3, s.GetData <Int64>("val"));
            Assert.AreEqual(1, s.Blocks.Count);
            Assert.AreEqual(3, s.Blocks[0].GetData <Int64>("val"));
        }
        public void TwoContentsTwoStructuresWithBlocksAndReset()
        {
            // test structure reset
            // ie entire structures above are ignored

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

            const string json2 =
                "["
                + "{"
                + "\"IsReset\":true,"    // reset => ignore above
                + "\"Blocks\":["         // 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 default because top is ignored
            Assert.AreEqual("default", s.Source);

            // only one block because top is ignored
            Assert.AreEqual(1, s.Blocks.Count);
            Assert.AreEqual("b2", s.Blocks[0].Source);
        }
        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);
        }
Beispiel #16
0
        public override ActionResult Index(RenderModel model)
        {
            var content = model.Content;

            // compute the rendering structure
            // get a context if a provider has been configured
            var context = _getContext == null ? null : _getContext(this);
            var rs      = RenderingStructure.Compute(context, content,
                                                     x => x.GetPropertyValue <IEnumerable <StructureDataValue> >(_structuresPropertyAlias));

            if (rs == null)
            {
                return(base.Index(model));
            }

            // event
            if (GetActionResult != null)
            {
                var args = new GetActionResultEventArgs(model, rs, context);
                GetActionResult(this, args);
                TraceBlocksInHtml = args.TraceBlocksInHtml;
                if (args.Result != null)
                {
                    return(args.Result);
                }
            }

            // should we cache?
            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);

            return(Content(text));
        }
        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 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
        }
        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 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 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);
        }