diff options
author | Jon Bratseth <bratseth@yahoo-inc.com> | 2016-06-15 23:09:44 +0200 |
---|---|---|
committer | Jon Bratseth <bratseth@yahoo-inc.com> | 2016-06-15 23:09:44 +0200 |
commit | 72231250ed81e10d66bfe70701e64fa5fe50f712 (patch) | |
tree | 2728bba1131a6f6e5bdf95afec7d7ff9358dac50 /container-search/src/test/java/com/yahoo/search/pagetemplates |
Publish
Diffstat (limited to 'container-search/src/test/java/com/yahoo/search/pagetemplates')
54 files changed, 2448 insertions, 0 deletions
diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/MapPageTemplateXMLReadingTestCase.java b/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/MapPageTemplateXMLReadingTestCase.java new file mode 100644 index 00000000000..052ea62d4f0 --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/MapPageTemplateXMLReadingTestCase.java @@ -0,0 +1,48 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.search.pagetemplates.config.test; + +import com.yahoo.search.pagetemplates.PageTemplate; +import com.yahoo.search.pagetemplates.PageTemplateRegistry; +import com.yahoo.search.pagetemplates.config.PageTemplateXMLReader; +import com.yahoo.search.pagetemplates.model.*; + +import java.util.List; + +/** + * @author <a href="mailto:bratseth@yahoo-inc.com">Jon Bratseth</a> + */ +public class MapPageTemplateXMLReadingTestCase extends junit.framework.TestCase { + + private String root="src/test/java/com/yahoo/search/pagetemplates/config/test/examples/mapexamples/"; + + public void testMap1() { + PageTemplateRegistry registry=new PageTemplateXMLReader().read(root); + assertCorrectMap1(registry.getComponent("map1")); + } + + private void assertCorrectMap1(PageTemplate page) { + assertNotNull("map1 was read",page); + Section root=page.getSection(); + assertTrue(((Section)((Section)root.elements(Section.class).get(0)).elements(Section.class).get(0)).elements().get(0) instanceof Placeholder); + assertTrue(((Section)((Section)root.elements(Section.class).get(0)).elements(Section.class).get(1)).elements().get(0) instanceof Placeholder); + assertTrue(((Section)((Section)root.elements(Section.class).get(1)).elements(Section.class).get(0)).elements().get(0) instanceof Placeholder); + assertTrue(((Section)((Section)root.elements(Section.class).get(1)).elements(Section.class).get(1)).elements().get(0) instanceof Placeholder); + assertEquals("box1source",((Placeholder) ((Section)((Section)root.elements(Section.class).get(0)).elements(Section.class).get(0)).elements().get(0)).getId()); + assertEquals("box2source",((Placeholder) ((Section)((Section)root.elements(Section.class).get(0)).elements(Section.class).get(1)).elements().get(0)).getId()); + assertEquals("box3source",((Placeholder) ((Section)((Section)root.elements(Section.class).get(1)).elements(Section.class).get(0)).elements().get(0)).getId()); + assertEquals("box4source",((Placeholder) ((Section)((Section)root.elements(Section.class).get(1)).elements(Section.class).get(1)).elements().get(0)).getId()); + + MapChoice map=(MapChoice)root.elements().get(2); + assertEquals("box1source",map.placeholderIds().get(0)); + assertEquals("box2source",map.placeholderIds().get(1)); + assertEquals("box3source",map.placeholderIds().get(2)); + assertEquals("box4source",map.placeholderIds().get(3)); + assertEquals("source1",((Source)((List<?>)map.values().get(0)).get(0)).getName()); + assertEquals("source2",((Source)((List<?>)map.values().get(1)).get(0)).getName()); + assertEquals("source3",((Source)((List<?>)map.values().get(2)).get(0)).getName()); + assertEquals("source4",((Source)((List<?>)map.values().get(3)).get(0)).getName()); + + PageTemplateXMLReadingTestCase.assertCorrectSources("source1 source2 source3 source4",page); + } + +} diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/PageTemplateXMLReadingTestCase.java b/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/PageTemplateXMLReadingTestCase.java new file mode 100644 index 00000000000..7832719412a --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/PageTemplateXMLReadingTestCase.java @@ -0,0 +1,279 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.search.pagetemplates.config.test; + +import com.yahoo.search.pagetemplates.PageTemplate; +import com.yahoo.search.pagetemplates.PageTemplateRegistry; +import com.yahoo.search.pagetemplates.PageTemplatesConfig; +import com.yahoo.search.pagetemplates.config.PageTemplateConfigurer; +import com.yahoo.search.pagetemplates.config.PageTemplateXMLReader; +import com.yahoo.search.pagetemplates.engine.Resolution; +import com.yahoo.search.pagetemplates.engine.Resolver; +import com.yahoo.search.pagetemplates.engine.resolvers.DeterministicResolver; +import com.yahoo.search.pagetemplates.model.Choice; +import com.yahoo.search.pagetemplates.model.Renderer; +import com.yahoo.search.pagetemplates.model.Section; +import com.yahoo.search.pagetemplates.model.Source; + +import java.util.HashSet; +import java.util.Set; + +/** + * @author <a href="mailto:bratseth@yahoo-inc.com">Jon Bratseth</a> + */ +public class PageTemplateXMLReadingTestCase extends junit.framework.TestCase { + + private String root="src/test/java/com/yahoo/search/pagetemplates/config/test/"; + + public void testExamples() { + PageTemplateRegistry registry=new PageTemplateXMLReader().read(root + "examples"); + assertCorrectSerp(registry.getComponent("serp")); + assertCorrectSlottingSerp(registry.getComponent("slottingSerp")); + assertCorrectRichSerp(registry.getComponent("richSerp")); + assertCorrectRicherSerp(registry.getComponent("richerSerp")); + assertCorrectIncluder(registry.getComponent("includer")); + assertCorrectGeneric(registry.getComponent("generic")); + } + + public void testConfigReading() { + PageTemplatesConfig config = new PageTemplatesConfig(new PageTemplatesConfig.Builder() + .page("<page id=\"slottingSerp\" layout=\"mainAndRight\">\n <section layout=\"column\" region=\"main\" source=\"*\" order=\"-[rank]\"/>\n <section layout=\"column\" region=\"right\" source=\"ads\"/>\n</page>\n") + .page("<page id=\"richSerp\" layout=\"mainAndRight\">\n <section layout=\"row\" region=\"main\">\n <section layout=\"column\" description=\"left main pane\">\n <section layout=\"row\" max=\"5\" description=\"Bar of images, from one of two possible sources\">\n <choice method=\"annealing\">\n <source name=\"images\"/>\n <source name=\"flickr\"/>\n </choice>\n </section>\n <section max=\"1\" source=\"local map video ticker weather\" description=\"A single relevant graphically rich element\"/>\n <section order=\"-[rank]\" max=\"10\" source=\"web news\" description=\"Various kinds of traditional search results\"/>\n </section>\n <section layout=\"column\" order=\"[source]\" source=\"answers blogs twitter\" description=\"right main pane, ugc stuff, grouped by source\"/>\n </section>\n <section layout=\"column\" source=\"ads\" region=\"right\"/>\n</page>\n") + .page("<page id=\"footer\">\n <section layout=\"row\" source=\"popularSearches\"/>\n <section id=\"extraFooter\" layout=\"row\" source=\"topArticles\"/>\n</page>\n") + .page("<page id=\"richerSerp\" layout=\"column\">\n <include idref=\"header\"/>\n <section layout=\"mainAndRight\">\n <section layout=\"row\" region=\"main\">\n <section layout=\"column\" description=\"left main pane\">\n <choice>\n <alternative>\n <section layout=\"row\" max=\"5\" description=\"Bar of images, from one of two possible sources\">\n <choice>\n <source name=\"images\"/>\n <alternative>\n <source name=\"flickr\">\n <renderer name=\"mouseOverImage\"/>\n </source>\n <source name=\"twitpic\">\n <choice>\n <renderer name=\"mouseOverImage\">\n <parameter name=\"hovertime\">5</parameter>\n <parameter name=\"borderColor\">#ff00ff</parameter>\n </renderer>\n <renderer name=\"regularImage\"/>\n </choice>\n <parameter name=\"filter\">origin=twitter</parameter>\n </source>\n </alternative>\n </choice>\n <choice>\n <renderer name=\"regularImageBox\"/>\n <renderer name=\"newImageBox\"/>\n </choice>\n </section>\n <section max=\"1\" source=\"local map video ticker weather\" description=\"A single relevant graphically rich element\"/>\n </alternative>\n <section order=\"[source]\" max=\"10\" source=\"web news\" description=\"Various kinds of traditional search results\"/>\n </choice>\n </section>\n <section layout=\"column\" order=\"[source]\" source=\"answers blogs twitter\" description=\"right main pane, ugc stuff, grouped by source\"/>\n </section>\n <section layout=\"column\" source=\"ads\" region=\"right\" order=\"-[rank] clickProbability\">\n <renderer name=\"newAdBox\"/>\n </section>\n </section>\n <include idref=\"footer\"/>\n</page>\n") + .page("<page id=\"header\">\n <section layout=\"row\">\n <section source=\"global\"/>\n <section source=\"notifications\"/>\n </section>\n</page>\n") + ); + PageTemplateRegistry registry = PageTemplateConfigurer.toRegistry(config); + assertCorrectSlottingSerp(registry.getComponent("slottingSerp")); + assertCorrectRichSerp(registry.getComponent("richSerp")); + assertCorrectRicherSerp(registry.getComponent("richerSerp")); + } + + public void testInvalidFilename() { + try { + PageTemplateRegistry registry=new PageTemplateXMLReader().read(root + "examples/invalidfilename"); + assertEquals(0,registry.allComponents().size()); + fail("Should have caused an exception"); + } + catch (IllegalArgumentException e) { + assertEquals("The file name of page template 'notinvalid' must be 'notinvalid.xml' but was 'invalid.xml'",e.getMessage()); + } + } + + protected void assertCorrectSerp(PageTemplate page) { + assertNotNull("'serp' was read",page); + Section rootSection=page.getSection(); + assertNotNull(rootSection); + assertEquals("mainAndRight",rootSection.getLayout().getName()); + Section main=(Section)rootSection.elements(Section.class).get(0); + assertEquals("column",main.getLayout().getName()); + assertEquals("main",main.getRegion()); + assertEquals("web",((Source)main.elements(Source.class).get(0)).getName()); + Section right=(Section)rootSection.elements(Section.class).get(1); + assertEquals("column",right.getLayout().getName()); + assertEquals("right",right.getRegion()); + assertEquals("ads",((Source)right.elements(Source.class).get(0)).getName()); + } + + protected void assertCorrectSlottingSerp(PageTemplate page) { + assertNotNull("'slotting serp' was read",page); + Section rootSection=page.getSection(); + Section main=(Section)rootSection.elements(Section.class).get(0); + assertEquals("-[rank]",main.getOrder().toString()); + assertEquals(Source.any,main.elements(Source.class).get(0)); + + assertCorrectSources("* ads",page); + } + + protected void assertCorrectRichSerp(PageTemplate page) { + assertNotNull("'rich serp' was read",page); + Section rootSection=page.getSection(); + assertNotNull(rootSection); + assertEquals("mainAndRight",rootSection.getLayout().getName()); + + Section main=(Section)rootSection.elements(Section.class).get(0); + assertEquals("row",main.getLayout().getName()); + assertEquals("main",main.getRegion()); + Section leftMain=(Section)main.elements(Section.class).get(0); + assertEquals("column",leftMain.getLayout().getName()); + Section imageBar=(Section)leftMain.elements(Section.class).get(0); + assertEquals("row",imageBar.getLayout().getName()); + assertEquals(5,imageBar.getMax()); + assertEquals("annealing",((Choice)imageBar.elements(Source.class).get(0)).getMethod().toString()); + assertEquals("images",((Source)((Choice)imageBar.elements(Source.class).get(0)).alternatives().get(0).get(0)).getName()); + assertEquals("flickr",((Source)((Choice)imageBar.elements(Source.class).get(0)).alternatives().get(1).get(0)).getName()); + Section richElement=(Section)leftMain.elements(Section.class).get(1); + assertEquals(1,richElement.getMax()); + assertEquals("[source 'local', source 'map', source 'video', source 'ticker', source 'weather']",richElement.elements(Source.class).toString()); + Section webResults=(Section)leftMain.elements(Section.class).get(2); + assertEquals("-[rank]",webResults.getOrder().toString()); + assertEquals(10,webResults.getMax()); + assertEquals("[source 'web', source 'news']",webResults.elements(Source.class).toString()); + Section rightMain=(Section)main.elements(Section.class).get(1); + assertEquals("column",rightMain.getLayout().getName()); + assertEquals("+[source]",rightMain.getOrder().toString()); + assertEquals("[source 'answers', source 'blogs', source 'twitter']",rightMain.elements(Source.class).toString()); + + Section right=(Section)rootSection.elements(Section.class).get(1); + assertEquals("column",right.getLayout().getName()); + assertEquals("right",right.getRegion()); + assertEquals("ads",((Source)right.elements(Source.class).get(0)).getName()); + } + + protected void assertCorrectRicherSerp(PageTemplate page) { + assertNotNull("'richer serp' was read",page); + + // Check resolution as we go + Resolver resolver=new DeterministicResolver(); + Resolution resolution=resolver.resolve(Choice.createSingleton(page),null,null); + + Section root=page.getSection(); + assertNotNull(root); + assertEquals("column",root.getLayout().getName()); + + assertEquals("Sections was correctly imported and combined with the section in this",4,root.elements(Section.class).size()); + + assertCorrectHeader((Section)root.elements(Section.class).get(0)); + + Section body=(Section)root.elements(Section.class).get(1); + assertEquals("mainAndRight",body.getLayout().getName()); + + Section main=(Section)body.elements(Section.class).get(0); + assertEquals("row",main.getLayout().getName()); + assertEquals("main",main.getRegion()); + + Section leftMain=(Section)main.elements(Section.class).get(0); + assertEquals("column",leftMain.getLayout().getName()); + assertEquals(1,resolution.getResolution((Choice)leftMain.elements(Section.class).get(0))); + + Section imageBar=(Section)((Choice)leftMain.elements(Section.class).get(0)).alternatives().get(0).get(0); + assertEquals("row",imageBar.getLayout().getName()); + assertEquals(5,imageBar.getMax()); + assertEquals(2,((Choice)imageBar.elements(Source.class).get(0)).alternatives().size()); + assertEquals("images",((Source)((Choice)imageBar.elements(Source.class).get(0)).alternatives().get(0).get(0)).getName()); + assertEquals(1,resolution.getResolution((Choice)imageBar.elements(Source.class).get(0))); + assertEquals(1,resolution.getResolution((Choice)imageBar.elements(Renderer.class).get(0))); + + Source flickrSource=(Source)((Choice)imageBar.elements(Source.class).get(0)).alternatives().get(1).get(0); + assertEquals("flickr",flickrSource.getName()); + assertEquals(1,flickrSource.renderers().size()); + assertEquals("mouseOverImage",((Renderer)flickrSource.renderers().get(0)).getName()); + + Source twitpicSource=(Source)((Choice)imageBar.elements(Source.class).get(0)).alternatives().get(1).get(1); + assertEquals("twitpic",twitpicSource.getName()); + assertEquals(1,twitpicSource.parameters().size()); + assertEquals("origin=twitter",twitpicSource.parameters().get("filter")); + assertEquals(2,((Choice)twitpicSource.renderers().get(0)).alternatives().size()); + assertEquals(1,resolution.getResolution((Choice)twitpicSource.renderers().get(0))); + + Renderer mouseOverImageRenderer=(Renderer)((Choice)twitpicSource.renderers().get(0)).alternatives().get(0).get(0); + assertEquals("mouseOverImage", mouseOverImageRenderer.getName()); + assertEquals(2, mouseOverImageRenderer.parameters().size()); + assertEquals("5", mouseOverImageRenderer.parameters().get("hovertime")); + assertEquals("#ff00ff", mouseOverImageRenderer.parameters().get("borderColor")); + assertEquals("regularImage",((Renderer)((Choice)twitpicSource.renderers().get(0)).alternatives().get(1).get(0)).getName()); + assertEquals(2,((Choice)imageBar.elements(Renderer.class).get(0)).alternatives().size()); + assertEquals("regularImageBox",((Renderer)((Choice)imageBar.elements(Renderer.class).get(0)).alternatives().get(0).get(0)).getName()); + assertEquals("newImageBox",((Renderer)((Choice)imageBar.elements(Renderer.class).get(0)).alternatives().get(1).get(0)).getName()); + + Section richElement=(Section)((Choice)leftMain.elements(Section.class).get(0)).get(0).get(1); + assertEquals(1,richElement.getMax()); + assertEquals("[source 'local', source 'map', source 'video', source 'ticker', source 'weather']",richElement.elements(Source.class).toString()); + + Section webResults=(Section)((Choice)leftMain.elements(Section.class).get(0)).get(1).get(0); + assertEquals("+[source]",webResults.getOrder().toString()); + assertEquals(10,webResults.getMax()); + assertEquals("[source 'web', source 'news']",webResults.elements(Source.class).toString()); + + Section rightMain=(Section)main.elements(Section.class).get(1); + assertEquals("column",rightMain.getLayout().getName()); + assertEquals("+[source]",rightMain.getOrder().toString()); + assertEquals("[source 'answers', source 'blogs', source 'twitter']",rightMain.elements(Source.class).toString()); + + Section right=(Section)body.elements(Section.class).get(1); + assertEquals("column",right.getLayout().getName()); + assertEquals("right",right.getRegion()); + assertEquals("ads",((Source)right.elements(Source.class).get(0)).getName()); + assertEquals("newAdBox",((Renderer)right.elements(Renderer.class).get(0)).getName()); + assertEquals("-[rank] +clickProbability",right.getOrder().toString()); + + assertCorrectFooter((Section)root.elements(Section.class).get(2)); + assertEquals("extraFooter",((Section)root.elements(Section.class).get(3)).getId()); + + // Check getSources() + assertCorrectSources("ads answers blogs flickr global images local map news notifications " + + "popularSearches ticker topArticles twitpic twitter video weather web",page); + } + + static void assertCorrectSources(String expectedSourceNameString,PageTemplate page) { + String[] expectedSourceNames=expectedSourceNameString.split(" "); + Set<String> sourceNames=new HashSet<>(); + for (Source source : page.getSources()) + sourceNames.add(source.getName()); + assertEquals("Expected " + expectedSourceNames.length + " elements in " + sourceNames, + expectedSourceNames.length,sourceNames.size()); + for (String expectedSourceName : expectedSourceNames) + assertTrue("Sources did not include '" + expectedSourceName+ "'",sourceNames.contains(expectedSourceName)); + } + + protected void assertCorrectIncluder(PageTemplate page) { + assertNotNull("'includer' was read",page); + + Resolution resolution=new DeterministicResolver().resolve(Choice.createSingleton(page),null,null); + + Section case1=(Section)page.getSection().elements(Section.class).get(0); + assertCorrectHeader((Section)case1.elements(Section.class).get(0)); + assertCorrectFooter((Section)case1.elements(Section.class).get(1)); + + Section case2=(Section)page.getSection().elements(Section.class).get(1); + assertCorrectHeader((Section)((Choice)case2.elements(Section.class).get(0)).get(0).get(0)); + assertCorrectFooter((Section)((Choice)case2.elements(Section.class).get(0)).get(1).get(0)); + assertEquals(1,resolution.getResolution((Choice)case2.elements(Section.class).get(0))); + + Section case3=(Section)page.getSection().elements(Section.class).get(2); + assertCorrectHeader((Section)((Choice)case3.elements(Section.class).get(0)).get(0).get(0)); + assertCorrectFooter((Section)((Choice)case3.elements(Section.class).get(0)).get(1).get(0)); + assertEquals(1,resolution.getResolution((Choice)case3.elements(Section.class).get(0))); + + Section case4=(Section)page.getSection().elements(Section.class).get(3); + assertEquals("first",((Section)((Choice)case4.elements(Section.class).get(0)).get(0).get(0)).getId()); + assertCorrectHeader((Section)((Choice)case4.elements(Section.class).get(0)).get(1).get(0)); + assertEquals("middle",((Section)((Choice)case4.elements(Section.class).get(0)).get(2).get(0)).getId()); + assertCorrectFooter((Section)((Choice)case4.elements(Section.class).get(0)).get(3).get(0)); + assertEquals("last",((Section)((Choice)case4.elements(Section.class).get(0)).get(4).get(0)).getId()); + assertEquals(4,resolution.getResolution((Choice)case4.elements(Section.class).get(0))); + + Section case5=(Section)page.getSection().elements(Section.class).get(4); + assertEquals(2,((Choice)case5.elements(Section.class).get(0)).alternatives().size()); + assertCorrectHeader((Section)((Choice)case5.elements(Section.class).get(0)).get(0).get(0)); + assertEquals("second",((Section)((Choice)case5.elements(Section.class).get(0)).get(1).get(0)).getId()); + assertEquals(1,resolution.getResolution((Choice)case5.elements(Section.class).get(0))); + + // This case - a choice inside a choice - makes little sense. It is included as a reminder - + // what we really want is to be able to include some additional alternatives of a choice, + // but without any magic. That requires allowing alternative as a top-level tag, or something + Section case6=(Section)page.getSection().elements(Section.class).get(5); + Choice includerChoice=(Choice)case6.elements().get(0); + Choice includedChoice=(Choice)includerChoice.alternatives().get(0).get(0); + assertCorrectFooter((Section)includedChoice.alternatives().get(0).get(0)); + } + + private void assertCorrectHeader(Section header) { + assertEquals("row",header.getLayout().getName()); + assertEquals(2,header.elements(Section.class).size()); + assertEquals( "global",((Source)((Section)header.elements(Section.class).get(0)).elements(Source.class).get(0)).getName()); + assertEquals("notifications",((Source)((Section)header.elements(Section.class).get(1)).elements(Source.class).get(0)).getName()); + } + + private void assertCorrectFooter(Section footer) { + assertEquals("row",footer.getLayout().getName()); + assertTrue(footer.elements(Section.class).isEmpty()); + assertEquals("popularSearches",((Source)footer.elements(Source.class).get(0)).getName()); + } + + private void assertCorrectGeneric(PageTemplate page) { + assertEquals("image", ((Source)((Section)page.getSection().elements(Section.class).get(0)).elements(Source.class).get(0)).getName()); + assertEquals("flickr", ((Source)((Section)page.getSection().elements(Section.class).get(0)).elements(Source.class).get(1)).getName()); + assertEquals(Source.any,((Section)page.getSection().elements(Section.class).get(1)).elements(Source.class).get(0)); + } + +} diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/examples/choiceFooter.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/examples/choiceFooter.xml new file mode 100644 index 00000000000..9ebdaeb9302 --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/examples/choiceFooter.xml @@ -0,0 +1,6 @@ +<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<page id="choiceFooter"> + <choice> + <section layout="row" source="popularSearches"/> + </choice> +</page> diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/examples/choiceHeader.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/examples/choiceHeader.xml new file mode 100644 index 00000000000..36b0ae6430c --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/examples/choiceHeader.xml @@ -0,0 +1,10 @@ +<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<page id="choiceHeader"> + <choice> + <section layout="row"> + <section source="global"/> + <section source="notifications"/> + </section> + <section id="second" source="blog"/> + </choice> +</page> diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/examples/footer.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/examples/footer.xml new file mode 100644 index 00000000000..0866aaaa583 --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/examples/footer.xml @@ -0,0 +1,5 @@ +<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<page id="footer"> + <section layout="row" source="popularSearches"/> + <section id="extraFooter" layout="row" source="topArticles"/> +</page> diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/examples/generic.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/examples/generic.xml new file mode 100644 index 00000000000..319f3058d24 --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/examples/generic.xml @@ -0,0 +1,5 @@ +<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<page id="generic"> + <section source="image flickr"/> + <section source="*"/> +</page> diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/examples/header.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/examples/header.xml new file mode 100644 index 00000000000..a894e8b9a3e --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/examples/header.xml @@ -0,0 +1,7 @@ +<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<page id="header"> + <section layout="row"> + <section source="global"/> + <section source="notifications"/> + </section> +</page> diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/examples/includer.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/examples/includer.xml new file mode 100644 index 00000000000..6d4f6121991 --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/examples/includer.xml @@ -0,0 +1,36 @@ +<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<page id="includer" description="Demonstrates the various include cases"> + <section id="case1" description="No choices"> + <include idref="header"/> + <include idref="footer"/> + </section> + <section id="case2" description="Include as implicit alternatives"> + <choice> + <include idref="header"/> + <include idref="footer"/> + </choice> + </section> + <section id="case3" description="Include as explicit alternatives - same result as above"> + <choice> + <alternative><include idref="header"/></alternative> + <alternative><include idref="footer"/></alternative> + </choice> + </section> + <section id="case4" description="Mixed with un-included"> + <choice> + <section id="first" source="music"/> + <alternative><include idref="header"/></alternative> + <section id="middle" source="video"/> + <alternative><include idref="footer"/></alternative> + <section id="last" source="books"/> + </choice> + </section> + <section id="case5" description="Including two alternatives"> + <include idref="choiceHeader"/> + </section> + <section id="case6" description="Including one choice"> + <choice> + <include idref="choiceFooter"/> + </choice> + </section> +</page> diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/examples/invalidfilename/invalid.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/examples/invalidfilename/invalid.xml new file mode 100644 index 00000000000..0e799a472de --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/examples/invalidfilename/invalid.xml @@ -0,0 +1,4 @@ +<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<page id="notinvalid"> + +</page> diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/examples/mapexamples/map1.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/examples/mapexamples/map1.xml new file mode 100644 index 00000000000..c13fdcdbbca --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/examples/mapexamples/map1.xml @@ -0,0 +1,21 @@ +<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<page id="map1" layout="column" description="Contains 4 boxes, to which 4 sources may be added"> + + <section layout="row" description="row 1"> + <section id="box1"><placeholder id="box1source"/></section> + <section id="box2"><placeholder id="box2source"/></section> + </section> + <section layout="row" description="row 2"> + <section id="box3"><placeholder id="box3source"/></section> + <section id="box4"><placeholder id="box4source"/></section> + </section> + + <choice> + <map to="box1source box2source box3source box4source"> + <source name="source1"/> + <source name="source2"/> + <source name="source3"/> + <source name="source4"/> + </map> + </choice> +</page> diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/examples/richSerp.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/examples/richSerp.xml new file mode 100644 index 00000000000..32ab6086b82 --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/examples/richSerp.xml @@ -0,0 +1,17 @@ +<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<page id="richSerp" layout="mainAndRight"> + <section layout="row" region="main"> + <section layout="column" description="left main pane"> + <section layout="row" max="5" description="Bar of images, from one of two possible sources"> + <choice method="annealing"> + <source name="images"/> + <source name="flickr"/> + </choice> + </section> + <section max="1" source="local map video ticker weather" description="A single relevant graphically rich element"/> + <section order="-[rank]" max="10" source="web news" description="Various kinds of traditional search results"/> + </section> + <section layout="column" order="[source]" source="answers blogs twitter" description="right main pane, ugc stuff, grouped by source"/> + </section> + <section layout="column" source="ads" region="right"/> +</page> diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/examples/richerSerp.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/examples/richerSerp.xml new file mode 100644 index 00000000000..d3e11288ef1 --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/examples/richerSerp.xml @@ -0,0 +1,45 @@ +<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<page id="richerSerp" layout="column"> + <include idref="header"/> + <section layout="mainAndRight"> + <section layout="row" region="main"> + <section layout="column" description="left main pane"> + <choice> + <alternative> + <section layout="row" max="5" description="Bar of images, from one of two possible sources"> + <choice> + <source name="images"/> + <alternative> + <source name="flickr"> + <renderer name="mouseOverImage"/> + </source> + <source name="twitpic"> + <choice> + <renderer name="mouseOverImage"> + <parameter name="hovertime">5</parameter> + <parameter name="borderColor">#ff00ff</parameter> + </renderer> + <renderer name="regularImage"/> + </choice> + <parameter name="filter">origin=twitter</parameter> + </source> + </alternative> + </choice> + <choice> + <renderer name="regularImageBox"/> + <renderer name="newImageBox"/> + </choice> + </section> + <section max="1" source="local map video ticker weather" description="A single relevant graphically rich element"/> + </alternative> + <section order="[source]" max="10" source="web news" description="Various kinds of traditional search results"/> + </choice> + </section> + <section layout="column" order="[source]" source="answers blogs twitter" description="right main pane, ugc stuff, grouped by source"/> + </section> + <section layout="column" source="ads" region="right" order="-[rank] clickProbability"> + <renderer name="newAdBox"/> + </section> + </section> + <include idref="footer"/> +</page> diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/examples/serp.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/examples/serp.xml new file mode 100644 index 00000000000..194c551f84c --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/examples/serp.xml @@ -0,0 +1,5 @@ +<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<page id="serp" layout="mainAndRight"> + <section layout="column" region="main" source="web"/> + <section layout="column" region="right" source="ads"/> +</page> diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/examples/slottingSerp.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/examples/slottingSerp.xml new file mode 100644 index 00000000000..301f7e77edb --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/config/test/examples/slottingSerp.xml @@ -0,0 +1,5 @@ +<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<page id="slottingSerp" layout="mainAndRight"> + <section layout="column" region="main" source="*" order="-[rank]"/> + <section layout="column" region="right" source="ads"/> +</page> diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/AnySource.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/AnySource.xml new file mode 100644 index 00000000000..4a5b6b3a1dd --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/AnySource.xml @@ -0,0 +1,4 @@ +<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<page id="AnySource" source="source3 *"> + +</page> diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/AnySourceResult.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/AnySourceResult.xml new file mode 100644 index 00000000000..40cc6b6935e --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/AnySourceResult.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<result version="1.0"> + + <hit relevance="1.0" source="source3"> + <id>source3-1</id> + </hit> + + <hit relevance="1.0" source="source1"> + <id>source1-1</id> + </hit> + + <hit relevance="1.0" source="source2"> + <id>source2-1</id> + </hit> + + <hit relevance="0.5" source="source3"> + <id>source3-2</id> + </hit> + + <hit relevance="0.5" source="source1"> + <id>source1-2</id> + </hit> + + <hit relevance="0.5" source="source2"> + <id>source2-2</id> + </hit> + + <hit relevance="0.3333333333333333" source="source3"> + <id>source3-3</id> + </hit> + + <hit relevance="0.3333333333333333" source="source1"> + <id>source1-3</id> + </hit> + + <hit relevance="0.3333333333333333" source="source2"> + <id>source2-3</id> + </hit> + +</result> diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/AnySourceTestCase.java b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/AnySourceTestCase.java new file mode 100644 index 00000000000..dc20e5483ca --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/AnySourceTestCase.java @@ -0,0 +1,59 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.search.pagetemplates.engine.test; + +import com.yahoo.search.Query; +import com.yahoo.search.Result; +import com.yahoo.search.pagetemplates.engine.Organizer; +import com.yahoo.search.pagetemplates.engine.Resolution; +import com.yahoo.search.pagetemplates.engine.Resolver; +import com.yahoo.search.pagetemplates.engine.resolvers.DeterministicResolver; +import com.yahoo.search.pagetemplates.model.Choice; +import com.yahoo.search.result.HitGroup; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * @author bratseth + */ +public class AnySourceTestCase extends ExecutionAbstractTestCase { + + @Test + public void testExecution() { + // Create the page template + Choice page=Choice.createSingleton(importPage("AnySource.xml")); + + // Create a federated result + Query query=new Query(); + Result result=new Result(query); + result.hits().add(createHits("source1",3)); + result.hits().add(createHits("source2",3)); + result.hits().add(createHits("source3",3)); + + // Resolve (noop here) + Resolver resolver=new DeterministicResolver(); + Resolution resolution=resolver.resolve(page,query,result); + + // Execute + Organizer organizer =new Organizer(); + organizer.organize(page,resolution,result); + + // Check execution: + // all three sources, ordered by relevance, source 3 first in each relevance group + HitGroup hits=result.hits(); + assertEquals(9,hits.size()); + assertEquals("source3-1",hits.get(0).getId().stringValue()); + assertEquals("source1-1",hits.get(1).getId().stringValue()); + assertEquals("source2-1",hits.get(2).getId().stringValue()); + assertEquals("source3-2",hits.get(3).getId().stringValue()); + assertEquals("source1-2",hits.get(4).getId().stringValue()); + assertEquals("source2-2",hits.get(5).getId().stringValue()); + assertEquals("source3-3",hits.get(6).getId().stringValue()); + assertEquals("source1-3",hits.get(7).getId().stringValue()); + assertEquals("source2-3",hits.get(8).getId().stringValue()); + + // Check rendering + assertRendered(result,"AnySourceResult.xml"); + } + +} diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfRenderers.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfRenderers.xml new file mode 100644 index 00000000000..e0306872149 --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfRenderers.xml @@ -0,0 +1,17 @@ +<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<page id="ChoiceOfRenderers" source="source1 source2"> + + <choice> + <renderer name="sectionLook1"/> + <renderer name="sectionLook2"/> + </choice> + <choice> + <renderer name="source1Look1" for="source1"/> + <renderer name="source1Look2" for="source1"/> + <renderer name="source1Look3" for="source1"> + <parameter name="color">#ff00ff</parameter> + <parameter name="blink">true</parameter> + </renderer> + </choice> + +</page> diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfRenderersResult.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfRenderersResult.xml new file mode 100644 index 00000000000..47ed1bd2f12 --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfRenderersResult.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<result version="1.0"> + + <renderer name="sectionLook2"/> + + <renderer for="source1" name="source1Look3"> + <parameter name="color">#ff00ff</parameter> + <parameter name="blink">true</parameter> + </renderer> + + <hit relevance="1.0" source="source1"> + <id>source1-1</id> + </hit> + + <hit relevance="1.0" source="source2"> + <id>source2-1</id> + </hit> + + <hit relevance="0.5" source="source1"> + <id>source1-2</id> + </hit> + + <hit relevance="0.5" source="source2"> + <id>source2-2</id> + </hit> + + <hit relevance="0.3333333333333333" source="source1"> + <id>source1-3</id> + </hit> + + <hit relevance="0.3333333333333333" source="source2"> + <id>source2-3</id> + </hit> + +</result> diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfRenderersTestCase.java b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfRenderersTestCase.java new file mode 100644 index 00000000000..58d05971805 --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfRenderersTestCase.java @@ -0,0 +1,51 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.search.pagetemplates.engine.test; + +import com.yahoo.search.Query; +import com.yahoo.search.Result; +import com.yahoo.search.pagetemplates.PageTemplate; +import com.yahoo.search.pagetemplates.engine.Organizer; +import com.yahoo.search.pagetemplates.engine.Resolution; +import com.yahoo.search.pagetemplates.engine.Resolver; +import com.yahoo.search.pagetemplates.engine.resolvers.DeterministicResolver; +import com.yahoo.search.pagetemplates.model.Choice; +import com.yahoo.search.pagetemplates.model.Renderer; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * @author <a href="mailto:bratseth@yahoo-inc.com">Jon Bratseth</a> + */ +public class ChoiceOfRenderersTestCase extends ExecutionAbstractTestCase { + + //This test is order dependent. Fix this!! + @Test + public void testExecution() { + // Create the page template + Choice page=Choice.createSingleton(importPage("ChoiceOfRenderers.xml")); + + // Create a federated result + Query query=new Query(); + Result result=new Result(query); + result.hits().add(createHits("source1",3)); + result.hits().add(createHits("source2",3)); + result.hits().add(createHits("source3",3)); + + // Resolve + Resolver resolver=new DeterministicResolver(); + Resolution resolution=resolver.resolve(page,query,result); + assertEquals(1,resolution.getResolution((Choice)((PageTemplate)page.get(0).get(0)).getSection().elements(Renderer.class).get(0))); + assertEquals(2,resolution.getResolution((Choice)((PageTemplate)page.get(0).get(0)).getSection().elements(Renderer.class).get(1))); + + // Execute + Organizer organizer =new Organizer(); + organizer.organize(page,resolution,result); + + assertEquals(6,result.getConcreteHitCount()); + assertEquals(6,result.getHitCount()); + + // Check rendering + assertRendered(result,"ChoiceOfRenderersResult.xml"); + } +} diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfSubsections.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfSubsections.xml new file mode 100644 index 00000000000..f7323ba094d --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfSubsections.xml @@ -0,0 +1,20 @@ +<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<page id="ChoiceOfSubsections"> + <choice method="method1"> + <alternative> + <section source="source0"/> + </alternative> + <alternative> + <section source="source1"/> + </alternative> + <alternative> + <section source="source2"/> + <section> + <choice method="method2"> + <source name="source3"/> + <source name="source4"/> + </choice> + </section> + </alternative> + </choice> +</page> diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfSubsectionsResult.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfSubsectionsResult.xml new file mode 100644 index 00000000000..b1d29995312 --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfSubsectionsResult.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<result version="1.0"> + + <section> + <hit relevance="1.0" source="source2"> + <id>source2-1</id> + </hit> + <hit relevance="0.5" source="source2"> + <id>source2-2</id> + </hit> + <hit relevance="0.3333333333333333" source="source2"> + <id>source2-3</id> + </hit> + </section> + + <section> + <hit relevance="1.0" source="source4"> + <id>source4-1</id> + </hit> + <hit relevance="0.5" source="source4"> + <id>source4-2</id> + </hit> + <hit relevance="0.3333333333333333" source="source4"> + <id>source4-3</id> + </hit> + </section> + +</result> diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfSubsectionsTestCase.java b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfSubsectionsTestCase.java new file mode 100644 index 00000000000..3d92a721f0d --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfSubsectionsTestCase.java @@ -0,0 +1,68 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.search.pagetemplates.engine.test; + +import com.yahoo.search.Query; +import com.yahoo.search.Result; +import com.yahoo.search.pagetemplates.engine.Organizer; +import com.yahoo.search.pagetemplates.engine.Resolution; +import com.yahoo.search.pagetemplates.engine.resolvers.DeterministicResolver; +import com.yahoo.search.pagetemplates.model.Choice; +import com.yahoo.search.result.HitGroup; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * @author <a href="mailto:bratseth@yahoo-inc.com">Jon Bratseth</a> + */ +public class ChoiceOfSubsectionsTestCase extends ExecutionAbstractTestCase { + + @Test + public void testExecution() { + // Create the page template + Choice page=Choice.createSingleton(importPage("ChoiceOfSubsections.xml")); + + // Create a federated result + Query query=new Query(); + Result result=new Result(query); + result.hits().add(createHits("source1",3)); + result.hits().add(createHits("source2",3)); + result.hits().add(createHits("source3",3)); + result.hits().add(createHits("source4",3)); + + new Organizer().organize(page,new DeterministicResolverAssertingMethod().resolve(page,query,result),result); + + // Check execution: + // Two subsections with one source each + assertEquals(2,result.hits().size()); + HitGroup section1=(HitGroup)result.hits().get(0); + HitGroup section2=(HitGroup)result.hits().get(1); + assertEqualHitGroups(createHits("source2",3),section1); + assertEqualHitGroups(createHits("source4",3),section2); + + // Check rendering + assertRendered(result,"ChoiceOfSubsectionsResult.xml"); + } + + /** Same as deterministic resolver, but asserts that it received the correct method names for each choice */ + private static class DeterministicResolverAssertingMethod extends DeterministicResolver { + + private int invocationNumber=0; + + /** Chooses the last alternative of any choice */ + @Override + public void resolve(Choice choice, Query query, Result result, Resolution resolution) { + invocationNumber++; + if (invocationNumber==2) + assertEquals("method1",choice.getMethod()); + else if (invocationNumber==3) + assertEquals("method2",choice.getMethod()); + else if (invocationNumber>3) + throw new IllegalStateException("Unexpected number of resolver invocations"); + + super.resolve(choice,query,result,resolution); + } + + } + +} diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfTwoSources.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfTwoSources.xml new file mode 100644 index 00000000000..c6a0af9ddd2 --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfTwoSources.xml @@ -0,0 +1,7 @@ +<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<page id="ChoiceOfTwoSources"> + <choice> + <source name="source1"/> + <source name="source2"/> + </choice> +</page> diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfTwoSourcesResult.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfTwoSourcesResult.xml new file mode 100644 index 00000000000..35d913fd9fa --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfTwoSourcesResult.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<result version="1.0"> + + <hit relevance="1.0" source="source2"> + <id>source2-1</id> + </hit> + + <hit relevance="0.5" source="source2"> + <id>source2-2</id> + </hit> + + <hit relevance="0.3333333333333333" source="source2"> + <id>source2-3</id> + </hit> + +</result> diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfTwoSourcesTestCase.java b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfTwoSourcesTestCase.java new file mode 100644 index 00000000000..facffb50649 --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfTwoSourcesTestCase.java @@ -0,0 +1,51 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.search.pagetemplates.engine.test; + +import com.yahoo.search.Query; +import com.yahoo.search.Result; +import com.yahoo.search.pagetemplates.PageTemplate; +import com.yahoo.search.pagetemplates.engine.Organizer; +import com.yahoo.search.pagetemplates.engine.Resolution; +import com.yahoo.search.pagetemplates.engine.Resolver; +import com.yahoo.search.pagetemplates.engine.resolvers.DeterministicResolver; +import com.yahoo.search.pagetemplates.model.Choice; +import com.yahoo.search.pagetemplates.model.Source; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * @author <a href="mailto:bratseth@yahoo-inc.com">Jon Bratseth</a> + */ +public class ChoiceOfTwoSourcesTestCase extends ExecutionAbstractTestCase { + + @Test + public void testExecution() { + // Create the page template + Choice page=Choice.createSingleton(importPage("ChoiceOfTwoSources.xml")); + + // Create a federated result + Query query=new Query(); + Result result=new Result(query); + result.hits().add(createHits("source1",3)); + result.hits().add(createHits("source2",3)); + result.hits().add(createHits("source3",3)); + + // Resolve + Resolver resolver=new DeterministicResolver(); + Resolution resolution=resolver.resolve(page,query,result); + assertEquals(1,resolution.getResolution((Choice)((PageTemplate)page.get(0).get(0)).getSection().elements(Source.class).get(0))); + + // Execute + Organizer organizer =new Organizer(); + organizer.organize(page,resolution,result); + + // Check execution: + // No subsections: Last choice (source2) used + assertEqualHitGroups(createHits("source2",3),result.hits()); + + // Check rendering + assertRendered(result,"ChoiceOfTwoSourcesResult.xml"); + } + +} diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/Choices.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/Choices.xml new file mode 100644 index 00000000000..e8d1736f46c --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/Choices.xml @@ -0,0 +1,45 @@ +<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<page id="Choices"> + <choice> + + <alternative> + <section layout="row"> + <section id="realtime"> + <choice> + <source name="news"/> + <source name="blog"/> + </choice> + </section> + <section source="images" max="2" id="multimedia"/> + <section source="web" id="web"/> + </section> + </alternative> + + <alternative> + <section source="*" id="blended"/> + </alternative> + + <alternative> + <section layout="row" description="row 1"> + <section id="box1"><placeholder id="box1source"/></section> + <section id="box2"><placeholder id="box2source"/></section> + </section> + <section layout="row" description="row 2"> + <section id="box3"><placeholder id="box3source"/></section> + <section id="box4"><placeholder id="box4source"/></section> + </section> + + <choice method="myMethod"> + <map to="box1source box2source box3source box4source"> + <source name="news"/> + <source name="web"/> + <source name="blog"/> + <source name="images"/> + </map> + </choice> + + </alternative> + + </choice> + +</page> diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoicesResult.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoicesResult.xml new file mode 100644 index 00000000000..ab995365f22 --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoicesResult.xml @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<result version="1.0"> + + <section layout="row"> + <section id="section:box1"> + <hit relevance="1.0" source="news"> + <id>news-1</id> + </hit> + <hit relevance="0.5" source="news"> + <id>news-2</id> + </hit> + <hit relevance="0.3333333333333333" source="news"> + <id>news-3</id> + </hit> + </section> + <section id="section:box2"> + <hit relevance="1.0" source="web"> + <id>web-1</id> + </hit> + <hit relevance="0.5" source="web"> + <id>web-2</id> + </hit> + <hit relevance="0.3333333333333333" source="web"> + <id>web-3</id> + </hit> + </section> + </section> + + <section layout="row"> + <section id="section:box3"> + <hit relevance="1.0" source="blog"> + <id>blog-1</id> + </hit> + <hit relevance="0.5" source="blog"> + <id>blog-2</id> + </hit> + <hit relevance="0.3333333333333333" source="blog"> + <id>blog-3</id> + </hit> + </section> + <section id="section:box4"> + <hit relevance="1.0" source="images"> + <id>images-1</id> + </hit> + <hit relevance="0.5" source="images"> + <id>images-2</id> + </hit> + <hit relevance="0.3333333333333333" source="images"> + <id>images-3</id> + </hit> + </section> + </section> + +</result> diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoicesTestCase.java b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoicesTestCase.java new file mode 100644 index 00000000000..a646823c8cb --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoicesTestCase.java @@ -0,0 +1,50 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.search.pagetemplates.engine.test; + +import com.yahoo.search.Query; +import com.yahoo.search.Result; +import com.yahoo.search.pagetemplates.engine.Organizer; +import com.yahoo.search.pagetemplates.engine.Resolution; +import com.yahoo.search.pagetemplates.engine.Resolver; +import com.yahoo.search.pagetemplates.engine.resolvers.DeterministicResolver; +import com.yahoo.search.pagetemplates.model.Choice; +import com.yahoo.search.pagetemplates.model.PageElement; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author <a href="mailto:bratseth@yahoo-inc.com">Jon Bratseth</a> + */ +public class ChoicesTestCase extends ExecutionAbstractTestCase { + + @Test + public void testExecution() { + // Create the page template (second alternative will be chosen) + List<PageElement> pages=new ArrayList<>(); + pages.add(importPage("AnySource.xml")); + pages.add(importPage("Choices.xml")); + Choice page=Choice.createSingletons(pages); + + // Create a federated result + Query query=new Query(); + Result result=new Result(query); + result.hits().add(createHits("news",3)); + result.hits().add(createHits("web",3)); + result.hits().add(createHits("blog",3)); + result.hits().add(createHits("images",3)); + + // Resolve + Resolver resolver=new DeterministicResolver(); + Resolution resolution=resolver.resolve(page,query,result); + + // Execute + Organizer organizer =new Organizer(); + organizer.organize(page,resolution,result); + + // Check rendering + assertRendered(result,"ChoicesResult.xml"); + } + +} diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ExecutionAbstractTestCase.java b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ExecutionAbstractTestCase.java new file mode 100644 index 00000000000..544366758f3 --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ExecutionAbstractTestCase.java @@ -0,0 +1,74 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.search.pagetemplates.engine.test; + +import com.yahoo.io.IOUtils; +import com.yahoo.prelude.templates.TiledTemplateSet; +import com.yahoo.prelude.templates.UserTemplate; +import com.yahoo.prelude.templates.test.TilingTestCase; +import com.yahoo.search.Result; +import com.yahoo.search.pagetemplates.PageTemplate; +import com.yahoo.search.pagetemplates.config.PageTemplateXMLReader; +import com.yahoo.search.result.Hit; +import com.yahoo.search.result.HitGroup; + +import java.io.*; + +import static org.junit.Assert.*; + +/** + * @author bratseth + */ +public class ExecutionAbstractTestCase { + + private static final String root="src/test/java/com/yahoo/search/pagetemplates/engine/test/"; + + protected PageTemplate importPage(String name) { + PageTemplate template=new PageTemplateXMLReader().readFile(root + name); + assertNotNull("Could look up page template '" + name + "'",template); + return template; + } + + protected void assertEqualHitGroups(HitGroup expected,HitGroup actual) { + assertEquals(expected.size(),actual.size()); + int i=0; + for (Hit expectedHit : expected.asList()) { + Hit actualHit=actual.get(i++); + assertEquals(expectedHit.getId(),actualHit.getId()); + assertEquals(expectedHit.getSource(),actualHit.getSource()); + } + } + + protected HitGroup createHits(String sourceName,int hitCount) { + HitGroup source=new HitGroup("source:" + sourceName); + for (int i=1; i<=hitCount; i++) { + Hit hit=new Hit(sourceName + "-" + i,1/(double)i); + hit.setSource(sourceName); + source.add(hit); + } + return source; + } + + protected void assertRendered(Result result,String resultFileName) { + assertRendered(result,resultFileName,false); + } + + protected void assertRendered(Result result,String resultFileName, UserTemplate<?> template) { + assertRendered(result,resultFileName,template,false); + } + + protected void assertRendered(Result result,String resultFileName,boolean print) { + assertRendered(result,resultFileName,new TiledTemplateSet(),print); + } + + @SuppressWarnings("deprecation") + protected void assertRendered(Result result,String resultFileName,UserTemplate<?> template, boolean print) { + result.getTemplating().setTemplates(template); + try { + TilingTestCase.assertRendered(IOUtils.readFile(new File(root + resultFileName)), result); + } + catch (IOException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSectionsToSections.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSectionsToSections.xml new file mode 100644 index 00000000000..2bc75fba5f4 --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSectionsToSections.xml @@ -0,0 +1,28 @@ +<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<page id="MapSectionsToSections" layout="column" description="Contains 4 boxes, to which 4 sections are mapped"> + + <section layout="row" description="row 1"> + <placeholder id="box1holder"/> + <placeholder id="box2holder"/> + </section> + <section layout="row" description="row 2"> + <placeholder id="box3holder"/> + <placeholder id="box4holder"/> + </section> + + <choice method="myMethod"> + <map to="box1holder box2holder box3holder box4holder"> + <section id="box1" source="source1"/> + <section id="box2" source="source2"/> + <item> + <section id="box3" source="source3"/> + <section id="box5" source="source5"/> + </item> + <section id="box4" source="source4"/> + </map> + </choice> + + <choice> <!-- Empty choices should have no effect --> + </choice> + +</page> diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSectionsToSectionsResult.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSectionsToSectionsResult.xml new file mode 100644 index 00000000000..3a163e5f804 --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSectionsToSectionsResult.xml @@ -0,0 +1,96 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<result version="1.0" layout="column"> + + <section layout="row"> + <section id="section:box1"> + <hit relevance="1.0" source="source1"> + <id>source1-1</id> + </hit> + <hit relevance="0.5" source="source1"> + <id>source1-2</id> + </hit> + <hit relevance="0.3333333333333333" source="source1"> + <id>source1-3</id> + </hit> + </section> + <section id="section:box2"> + <hit relevance="1.0" source="source2"> + <id>source2-1</id> + </hit> + <hit relevance="0.5" source="source2"> + <id>source2-2</id> + </hit> + <hit relevance="0.3333333333333333" source="source2"> + <id>source2-3</id> + </hit> + <hit relevance="0.25" source="source2"> + <id>source2-4</id> + </hit> + </section> + </section> + + <section layout="row"> + <section id="section:box3"> + <hit relevance="1.0" source="source3"> + <id>source3-1</id> + </hit> + <hit relevance="0.5" source="source3"> + <id>source3-2</id> + </hit> + <hit relevance="0.3333333333333333" source="source3"> + <id>source3-3</id> + </hit> + <hit relevance="0.25" source="source3"> + <id>source3-4</id> + </hit> + <hit relevance="0.2" source="source3"> + <id>source3-5</id> + </hit> + </section> + <section id="section:box5"> + <hit relevance="1.0" source="source5"> + <id>source5-1</id> + </hit> + <hit relevance="0.5" source="source5"> + <id>source5-2</id> + </hit> + <hit relevance="0.3333333333333333" source="source5"> + <id>source5-3</id> + </hit> + <hit relevance="0.25" source="source5"> + <id>source5-4</id> + </hit> + <hit relevance="0.2" source="source5"> + <id>source5-5</id> + </hit> + <hit relevance="0.1666666666666667" source="source5"> + <id>source5-6</id> + </hit> + <hit relevance="0.1428571428571428" source="source5"> + <id>source5-7</id> + </hit> + </section> + <section id="section:box4"> + <hit relevance="1.0" source="source4"> + <id>source4-1</id> + </hit> + <hit relevance="0.5" source="source4"> + <id>source4-2</id> + </hit> + <hit relevance="0.3333333333333333" source="source4"> + <id>source4-3</id> + </hit> + <hit relevance="0.25" source="source4"> + <id>source4-4</id> + </hit> + <hit relevance="0.2" source="source4"> + <id>source4-5</id> + </hit> + <hit relevance="0.1666666666666667" source="source4"> + <id>source4-6</id> + </hit> + </section> + </section> + +</result> diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSectionsToSectionsTestCase.java b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSectionsToSectionsTestCase.java new file mode 100644 index 00000000000..54fc342aa22 --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSectionsToSectionsTestCase.java @@ -0,0 +1,90 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.search.pagetemplates.engine.test; + +import com.yahoo.search.Query; +import com.yahoo.search.Result; +import com.yahoo.search.pagetemplates.PageTemplate; +import com.yahoo.search.pagetemplates.engine.Organizer; +import com.yahoo.search.pagetemplates.engine.Resolution; +import com.yahoo.search.pagetemplates.engine.Resolver; +import com.yahoo.search.pagetemplates.engine.resolvers.DeterministicResolver; +import com.yahoo.search.pagetemplates.model.Choice; +import com.yahoo.search.pagetemplates.model.MapChoice; +import com.yahoo.search.pagetemplates.model.PageElement; +import com.yahoo.search.pagetemplates.model.Section; +import com.yahoo.search.result.HitGroup; +import org.junit.Test; + +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +/** + * @author <a href="mailto:bratseth@yahoo-inc.com">Jon Bratseth</a> + */ +public class MapSectionsToSectionsTestCase extends ExecutionAbstractTestCase { + + @Test + public void testExecution() { + // Create the page template + Choice page=Choice.createSingleton(importPage("MapSectionsToSections.xml")); + + // Create a federated result + Query query=new Query(); + Result result=new Result(query); + result.hits().add(createHits("source1",3)); + result.hits().add(createHits("source2",4)); + result.hits().add(createHits("source3",5)); + result.hits().add(createHits("source4",6)); + result.hits().add(createHits("source5",7)); + + // Resolve + Resolver resolver=new DeterministicResolverAssertingMethod(); + Resolution resolution=resolver.resolve(page,query,result); + Map<String, List<PageElement>> mapping= + resolution.getResolution((MapChoice)((PageTemplate)page.get(0).get(0)).getSection().elements().get(2)); + assertNotNull(mapping); + assertEquals("box1",((Section)mapping.get("box1holder").get(0)).getId()); + assertEquals("box2",((Section)mapping.get("box2holder").get(0)).getId()); + assertEquals("box3",((Section)mapping.get("box3holder").get(0)).getId()); + assertEquals("box4",((Section)mapping.get("box4holder").get(0)).getId()); + + // Execute + Organizer organizer =new Organizer(); + organizer.organize(page,resolution,result); + + // Check execution: + // Two subsections, each containing two sub-subsections with one source each + assertEquals(2,result.hits().size()); + HitGroup row1=(HitGroup)result.hits().get(0); + HitGroup column11=(HitGroup)row1.get(0); + HitGroup column12=(HitGroup)row1.get(1); + HitGroup row2=(HitGroup)result.hits().get(1); + HitGroup column21a=(HitGroup)row2.get(0); + HitGroup column21b=(HitGroup)row2.get(1); + HitGroup column22=(HitGroup)row2.get(2); + assertEqualHitGroups(createHits("source1",3),column11); + assertEqualHitGroups(createHits("source2",4),column12); + assertEqualHitGroups(createHits("source3",5),column21a); + assertEqualHitGroups(createHits("source5",7),column21b); + assertEqualHitGroups(createHits("source4",6),column22); + + // Check rendering + assertRendered(result,"MapSectionsToSectionsResult.xml"); + } + + /** Same as deterministic resolver, but asserts that it received the correct method names for each map choice */ + private static class DeterministicResolverAssertingMethod extends DeterministicResolver { + + /** Chooses the last alternative of any choice */ + @Override + public void resolve(MapChoice mapChoice, Query query, Result result, Resolution resolution) { + assertEquals("myMethod",mapChoice.getMethod()); + super.resolve(mapChoice,query,result,resolution); + } + + } + +} diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSourcesToSections.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSourcesToSections.xml new file mode 100644 index 00000000000..7b5c0770096 --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSourcesToSections.xml @@ -0,0 +1,22 @@ +<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<page id="MapSourcesToSections" layout="column" description="4 sources are assigned to a section each"> + + <section layout="row" description="row 1"> + <section id="box1"><placeholder id="box1source"/></section> + <section id="box2"><placeholder id="box2source"/></section> + </section> + <section layout="row" description="row 2"> + <section id="box3"><placeholder id="box3source"/></section> + <section id="box4"><placeholder id="box4source"/></section> + </section> + + <choice method="myMethod"> + <map to="box1source box2source box3source box4source"> + <source name="source1"/> + <source name="source2"/> + <source name="source3"/> + <source name="source4"/> + </map> + </choice> + +</page> diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSourcesToSectionsResult.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSourcesToSectionsResult.xml new file mode 100644 index 00000000000..034330c071c --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSourcesToSectionsResult.xml @@ -0,0 +1,73 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<result version="1.0" layout="column"> + + <section layout="row"> + <section id="section:box1"> + <hit relevance="1.0" source="source1"> + <id>source1-1</id> + </hit> + <hit relevance="0.5" source="source1"> + <id>source1-2</id> + </hit> + <hit relevance="0.3333333333333333" source="source1"> + <id>source1-3</id> + </hit> + </section> + <section id="section:box2"> + <hit relevance="1.0" source="source2"> + <id>source2-1</id> + </hit> + <hit relevance="0.5" source="source2"> + <id>source2-2</id> + </hit> + <hit relevance="0.3333333333333333" source="source2"> + <id>source2-3</id> + </hit> + <hit relevance="0.25" source="source2"> + <id>source2-4</id> + </hit> + </section> + </section> + + <section layout="row"> + <section id="section:box3"> + <hit relevance="1.0" source="source3"> + <id>source3-1</id> + </hit> + <hit relevance="0.5" source="source3"> + <id>source3-2</id> + </hit> + <hit relevance="0.3333333333333333" source="source3"> + <id>source3-3</id> + </hit> + <hit relevance="0.25" source="source3"> + <id>source3-4</id> + </hit> + <hit relevance="0.2" source="source3"> + <id>source3-5</id> + </hit> + </section> + <section id="section:box4"> + <hit relevance="1.0" source="source4"> + <id>source4-1</id> + </hit> + <hit relevance="0.5" source="source4"> + <id>source4-2</id> + </hit> + <hit relevance="0.3333333333333333" source="source4"> + <id>source4-3</id> + </hit> + <hit relevance="0.25" source="source4"> + <id>source4-4</id> + </hit> + <hit relevance="0.2" source="source4"> + <id>source4-5</id> + </hit> + <hit relevance="0.1666666666666667" source="source4"> + <id>source4-6</id> + </hit> + </section> + </section> + +</result> diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSourcesToSectionsTestCase.java b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSourcesToSectionsTestCase.java new file mode 100644 index 00000000000..49cc0411ac5 --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSourcesToSectionsTestCase.java @@ -0,0 +1,88 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.search.pagetemplates.engine.test; + +import com.yahoo.search.Query; +import com.yahoo.search.Result; +import com.yahoo.search.pagetemplates.PageTemplate; +import com.yahoo.search.pagetemplates.engine.Organizer; +import com.yahoo.search.pagetemplates.engine.Resolution; +import com.yahoo.search.pagetemplates.engine.Resolver; +import com.yahoo.search.pagetemplates.engine.resolvers.DeterministicResolver; +import com.yahoo.search.pagetemplates.model.Choice; +import com.yahoo.search.pagetemplates.model.MapChoice; +import com.yahoo.search.pagetemplates.model.PageElement; +import com.yahoo.search.pagetemplates.model.Source; +import com.yahoo.search.result.HitGroup; +import org.junit.Test; + +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +/** + * @author <a href="mailto:bratseth@yahoo-inc.com">Jon Bratseth</a> + */ +public class MapSourcesToSectionsTestCase extends ExecutionAbstractTestCase { + + @Test + public void testExecution() { + // Create the page template + Choice page=Choice.createSingleton(importPage("MapSourcesToSections.xml")); + + // Create a federated result + Query query=new Query(); + Result result=new Result(query); + result.hits().add(createHits("source1",3)); + result.hits().add(createHits("source2",4)); + result.hits().add(createHits("source3",5)); + result.hits().add(createHits("source4",6)); + result.hits().add(createHits("source5",7)); + + // Resolve + Resolver resolver=new DeterministicResolverAssertingMethod(); + Resolution resolution=resolver.resolve(page,query,result); + Map<String, List<PageElement>> mapping= + resolution.getResolution((MapChoice)((PageTemplate)page.get(0).get(0)).getSection().elements().get(2)); + assertNotNull(mapping); + assertEquals("source1",((Source)mapping.get("box1source").get(0)).getName()); + assertEquals("source2",((Source)mapping.get("box2source").get(0)).getName()); + assertEquals("source3",((Source)mapping.get("box3source").get(0)).getName()); + assertEquals("source4",((Source)mapping.get("box4source").get(0)).getName()); + + // Execute + Organizer organizer =new Organizer(); + organizer.organize(page,resolution,result); + + // Check execution: + // Two subsections, each containing two sub-subsections with one source each + assertEquals(2,result.hits().size()); + HitGroup row1=(HitGroup)result.hits().get(0); + HitGroup column11=(HitGroup)row1.get(0); + HitGroup column12=(HitGroup)row1.get(1); + HitGroup row2=(HitGroup)result.hits().get(1); + HitGroup column21=(HitGroup)row2.get(0); + HitGroup column22=(HitGroup)row2.get(1); + assertEqualHitGroups(createHits("source1",3),column11); + assertEqualHitGroups(createHits("source2",4),column12); + assertEqualHitGroups(createHits("source3",5),column21); + assertEqualHitGroups(createHits("source4",6),column22); + + // Check rendering + assertRendered(result,"MapSourcesToSectionsResult.xml"); + } + + /** Same as deterministic resolver, but asserts that it received the correct method names for each map choice */ + private static class DeterministicResolverAssertingMethod extends DeterministicResolver { + + /** Chooses the last alternative of any choice */ + @Override + public void resolve(MapChoice mapChoice, Query query, Result result, Resolution resolution) { + assertEquals("myMethod",mapChoice.getMethod()); + super.resolve(mapChoice,query,result,resolution); + } + + } + +} diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/Page.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/Page.xml new file mode 100644 index 00000000000..967da527b6e --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/Page.xml @@ -0,0 +1,31 @@ +<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<page id="Page"> + + <renderer name="two-column"/> + + <section region="left"> + <source url="http://carmot.yahoo.com:4080/resource/[news article id]"/> + <renderer name="articleBodyRenderer"> + <parameter name="color">blue</parameter> + </renderer> + </section> + + <section region="right"> + <renderer name="multi-item-column"> + <parameter name="items">3</parameter> + </renderer> + + <section region="1" source="news"> + <renderer name="articleListRenderer"/> + </section> + + <section region="2"> + <source url="http://vitality.yahoo.com:4080/consumption-widget"/> + <renderer name="identityRenderer"/> + </section> + + <section region="3" source="htmlSource"> + <renderer name="htmlRenderer"/> + </section> + </section> +</page> diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageResult.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageResult.xml new file mode 100644 index 00000000000..95b86ef1f4d --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageResult.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<page version="1.0"> + + <renderer name="two-column"/> + + <section region="left"> + <source url="http://carmot.yahoo.com:4080/resource/[news article id]"/> + <renderer name="articleBodyRenderer"> + <parameter name="color">blue</parameter> + </renderer> + </section> + + <section region="right"> + <renderer name="multi-item-column"> + <parameter name="items">3</parameter> + </renderer> + <section region="1"> + <renderer name="articleListRenderer"/> + <content> + <hit relevance="1.0" source="news"> + <id>news-1</id> + </hit> + <hit relevance="0.5" source="news"> + <id>news-2</id> + </hit> + </content> + </section> + <section region="2"> + <source url="http://vitality.yahoo.com:4080/consumption-widget"/> + <renderer name="identityRenderer"/> + </section> + <section region="3"> + <renderer name="htmlRenderer"/> + <content> + <hit relevance="1.0" source="htmlSource"> + <id>htmlSource-1</id> + </hit> + </content> + </section> + </section> + +</page> diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageTestCase.java b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageTestCase.java new file mode 100644 index 00000000000..33930f3d0e0 --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageTestCase.java @@ -0,0 +1,44 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.search.pagetemplates.engine.test; + +import com.yahoo.prelude.templates.PageTemplateSet; +import com.yahoo.search.Query; +import com.yahoo.search.Result; +import com.yahoo.search.pagetemplates.engine.Organizer; +import com.yahoo.search.pagetemplates.engine.Resolution; +import com.yahoo.search.pagetemplates.engine.Resolver; +import com.yahoo.search.pagetemplates.engine.resolvers.DeterministicResolver; +import com.yahoo.search.pagetemplates.model.Choice; +import org.junit.Test; + +/** + * Tests an example page. + * + * @author bratseth + */ +public class PageTestCase extends ExecutionAbstractTestCase { + + @Test + public void testExecution() { + // Create the page template + Choice page=Choice.createSingleton(importPage("Page.xml")); + + // Create a federated result + Query query=new Query(); + Result result=new Result(query); + result.hits().add(createHits("news",2)); + result.hits().add(createHits("htmlSource",1)); + + // Resolve (noop here) + Resolver resolver=new DeterministicResolver(); + Resolution resolution=resolver.resolve(page,query,result); + + // Execute + Organizer organizer =new Organizer(); + organizer.organize(page,resolution,result); + + // Check rendering + assertRendered(result,"PageResult.xml",new PageTemplateSet()); + } + +} diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithBlending.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithBlending.xml new file mode 100644 index 00000000000..dca31eb42e1 --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithBlending.xml @@ -0,0 +1,37 @@ +<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<page id="PageWithBlending"> + + <renderer name="two-column"/> + + <section region="left"> + <source url="http://carmot.yahoo.com:4080/resource/[news article id]"/> + <renderer name="articleBodyRenderer"> + <parameter name="color">blue</parameter> + </renderer> + </section> + + <section region="right"> + <renderer name="multi-item-column"> + <parameter name="items">3</parameter> + </renderer> + + <section region="1"> + <renderer for="newsImage" name="newsImageRenderer"/> + <source name="news"> + <renderer name="articleRenderer"/> + </source> + <source name="image"> + <renderer name="imageRenderer"/> + </source> + </section> + + <section region="2"> + <source url="http://vitality.yahoo.com:4080/consumption-widget"/> + <renderer name="identityRenderer"/> + </section> + + <section region="3" source="htmlSource"> + <renderer name="htmlRenderer"/> + </section> + </section> +</page> diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithBlendingResult.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithBlendingResult.xml new file mode 100644 index 00000000000..7ac78f3e820 --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithBlendingResult.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<page version="1.0"> + + <renderer name="two-column"/> + + <section region="left"> + <source url="http://carmot.yahoo.com:4080/resource/[news article id]"/> + <renderer name="articleBodyRenderer"> + <parameter name="color">blue</parameter> + </renderer> + </section> + + <section region="right"> + <renderer name="multi-item-column"> + <parameter name="items">3</parameter> + </renderer> + <section region="1"> + <renderer for="newsImage" name="newsImageRenderer"/> + <renderer for="news" name="articleRenderer"/> + <renderer for="image" name="imageRenderer"/> + <content> + <hit relevance="1.0" source="news"> + <id>news-1</id> + </hit> + <hit relevance="0.5" source="news"> + <id>news-2</id> + </hit> + </content> + </section> + <section region="2"> + <source url="http://vitality.yahoo.com:4080/consumption-widget"/> + <renderer name="identityRenderer"/> + </section> + <section region="3"> + <renderer name="htmlRenderer"/> + <content> + <hit relevance="1.0" source="htmlSource"> + <id>htmlSource-1</id> + </hit> + </content> + </section> + </section> + +</page> diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithBlendingTestCase.java b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithBlendingTestCase.java new file mode 100644 index 00000000000..445105cfd2f --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithBlendingTestCase.java @@ -0,0 +1,44 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.search.pagetemplates.engine.test; + +import com.yahoo.prelude.templates.PageTemplateSet; +import com.yahoo.search.Query; +import com.yahoo.search.Result; +import com.yahoo.search.pagetemplates.engine.Organizer; +import com.yahoo.search.pagetemplates.engine.Resolution; +import com.yahoo.search.pagetemplates.engine.Resolver; +import com.yahoo.search.pagetemplates.engine.resolvers.DeterministicResolver; +import com.yahoo.search.pagetemplates.model.Choice; +import org.junit.Test; + +/** + * Tests an exapnded example. + * + * @author bratseth + */ +public class PageWithBlendingTestCase extends ExecutionAbstractTestCase { + + @Test + public void testExecution() { + // Create the page template + Choice page=Choice.createSingleton(importPage("PageWithBlending.xml")); + + // Create a federated result + Query query=new Query(); + Result result=new Result(query); + result.hits().add(createHits("news",2)); + result.hits().add(createHits("htmlSource",1)); + + // Resolve (noop here) + Resolver resolver=new DeterministicResolver(); + Resolution resolution=resolver.resolve(page,query,result); + + // Execute + Organizer organizer =new Organizer(); + organizer.organize(page,resolution,result); + + // Check rendering + assertRendered(result,"PageWithBlendingResult.xml",new PageTemplateSet()); + } + +} diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithSourceRenderer.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithSourceRenderer.xml new file mode 100644 index 00000000000..5d3e38c2beb --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithSourceRenderer.xml @@ -0,0 +1,36 @@ +<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<page id="PageWithSourceRenderer"> + + <renderer name="two-column"/> + + <section region="left"> + <choice> + <source url="notchosen"/> + <source url="http://carmot.yahoo.com:4080/resource/[news article id]"/> + </choice> + <renderer name="articleBodyRenderer"> + <parameter name="color">blue</parameter> + </renderer> + </section> + + <section region="right"> + <renderer name="multi-item-column"> + <parameter name="items">3</parameter> + </renderer> + + <section region="1"> + <source name="news"> + <renderer name="articleRenderer"/> + </source> + </section> + + <section region="2"> + <source url="http://vitality.yahoo.com:4080/consumption-widget"/> + <renderer name="identityRenderer"/> + </section> + + <section region="3" source="htmlSource"> + <renderer name="htmlRenderer"/> + </section> + </section> +</page> diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithSourceRendererResult.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithSourceRendererResult.xml new file mode 100644 index 00000000000..00656399331 --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithSourceRendererResult.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<page version="1.0"> + + <renderer name="two-column"/> + + <section region="left"> + <source url="http://carmot.yahoo.com:4080/resource/[news article id]"/> + <renderer name="articleBodyRenderer"> + <parameter name="color">blue</parameter> + </renderer> + </section> + + <section region="right"> + <renderer name="multi-item-column"> + <parameter name="items">3</parameter> + </renderer> + <section region="1"> + <renderer for="news" name="articleRenderer"/> + <content> + <hit relevance="1.0" source="news"> + <id>news-1</id> + </hit> + <hit relevance="0.5" source="news"> + <id>news-2</id> + </hit> + </content> + </section> + <section region="2"> + <source url="http://vitality.yahoo.com:4080/consumption-widget"/> + <renderer name="identityRenderer"/> + </section> + <section region="3"> + <renderer name="htmlRenderer"/> + <content> + <hit relevance="1.0" source="htmlSource"> + <id>htmlSource-1</id> + </hit> + </content> + </section> + </section> + +</page> diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithSourceRendererTestCase.java b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithSourceRendererTestCase.java new file mode 100644 index 00000000000..e7dbae21d47 --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithSourceRendererTestCase.java @@ -0,0 +1,44 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.search.pagetemplates.engine.test; + +import com.yahoo.prelude.templates.PageTemplateSet; +import com.yahoo.search.Query; +import com.yahoo.search.Result; +import com.yahoo.search.pagetemplates.engine.Organizer; +import com.yahoo.search.pagetemplates.engine.Resolution; +import com.yahoo.search.pagetemplates.engine.Resolver; +import com.yahoo.search.pagetemplates.engine.resolvers.DeterministicResolver; +import com.yahoo.search.pagetemplates.model.Choice; +import org.junit.Test; + +/** + * Tests an example with two data sources with a renderer each. + * + * @author bratseth + */ +public class PageWithSourceRendererTestCase extends ExecutionAbstractTestCase { + + @Test + public void testExecution() { + // Create the page template + Choice page=Choice.createSingleton(importPage("PageWithSourceRenderer.xml")); + + // Create a federated result + Query query=new Query(); + Result result=new Result(query); + result.hits().add(createHits("news",2)); + result.hits().add(createHits("htmlSource",1)); + + // Resolve + Resolver resolver=new DeterministicResolver(); + Resolution resolution=resolver.resolve(page,query,result); + + // Execute + Organizer organizer =new Organizer(); + organizer.organize(page,resolution,result); + + // Check rendering + assertRendered(result,"PageWithSourceRendererResult.xml",new PageTemplateSet()); + } + +} diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/SourceChoice.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/SourceChoice.xml new file mode 100644 index 00000000000..ff39ef1d3d1 --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/SourceChoice.xml @@ -0,0 +1,7 @@ +<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<page id="SourceChoice"> + <choice> + <source name="news"/> + <source name="web"/> + </choice> +</page> diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/SourceChoiceResult.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/SourceChoiceResult.xml new file mode 100644 index 00000000000..c9e0909a476 --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/SourceChoiceResult.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<page version="1.0"> + + <content> + <hit relevance="1.0" source="web"> + <id>web-1</id> + </hit> + <hit relevance="0.5" source="web"> + <id>web-2</id> + </hit> + <hit relevance="0.3333333333333333" source="web"> + <id>web-3</id> + </hit> + </content> + +</page> diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/SourceChoiceTestCase.java b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/SourceChoiceTestCase.java new file mode 100644 index 00000000000..04e550a631c --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/SourceChoiceTestCase.java @@ -0,0 +1,43 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.search.pagetemplates.engine.test; + +import com.yahoo.prelude.templates.PageTemplateSet; +import com.yahoo.search.Query; +import com.yahoo.search.Result; +import com.yahoo.search.pagetemplates.engine.Organizer; +import com.yahoo.search.pagetemplates.engine.Resolution; +import com.yahoo.search.pagetemplates.engine.Resolver; +import com.yahoo.search.pagetemplates.engine.resolvers.DeterministicResolver; +import com.yahoo.search.pagetemplates.model.Choice; +import org.junit.Test; + +/** + * @author <a href="mailto:bratseth@yahoo-inc.com">Jon Bratseth</a> + */ +public class SourceChoiceTestCase extends ExecutionAbstractTestCase { + + @Test + public void testExecution() { + // Create the page template + Choice page=Choice.createSingleton(importPage("SourceChoice.xml")); + + // Create a federated result + Query query=new Query(); + Result result=new Result(query); + result.hits().add(createHits("web",3)); + result.hits().add(createHits("news",3)); + result.hits().add(createHits("blog",3)); + + // Resolve (noop here) + Resolver resolver=new DeterministicResolver(); + Resolution resolution=resolver.resolve(page,query,result); + + // Execute + Organizer organizer =new Organizer(); + organizer.organize(page,resolution,result); + + // Check rendering + assertRendered(result,"SourceChoiceResult.xml",new PageTemplateSet(),true); + } + +} diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/TwoSectionsFourSources.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/TwoSectionsFourSources.xml new file mode 100644 index 00000000000..36cace66ff7 --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/TwoSectionsFourSources.xml @@ -0,0 +1,5 @@ +<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<page id="TwoSectionsFourSources" layout="twoColumns"> + <section source="source3 source1" order="[source]" max="8" region="left"/> + <section source="source4 source2" order="-[rank]" max="10" region="right"/> +</page> diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/TwoSectionsFourSourcesResult.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/TwoSectionsFourSourcesResult.xml new file mode 100644 index 00000000000..0ca5bfc7ea0 --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/TwoSectionsFourSourcesResult.xml @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<result version="1.0" layout="twoColumns"> + + <section region="left"> + <hit relevance="1.0" source="source3"> + <id>source3-1</id> + </hit> + <hit relevance="0.5" source="source3"> + <id>source3-2</id> + </hit> + <hit relevance="0.3333333333333333" source="source3"> + <id>source3-3</id> + </hit> + <hit relevance="0.25" source="source3"> + <id>source3-4</id> + </hit> + <hit relevance="0.2" source="source3"> + <id>source3-5</id> + </hit> + <hit relevance="1.0" source="source1"> + <id>source1-1</id> + </hit> + <hit relevance="0.5" source="source1"> + <id>source1-2</id> + </hit> + <hit relevance="0.3333333333333333" source="source1"> + <id>source1-3</id> + </hit> + </section> + + <section region="right"> + <hit relevance="1.0" source="source4"> + <id>source4-1</id> + </hit> + <hit relevance="1.0" source="source2"> + <id>source2-1</id> + </hit> + <hit relevance="0.5" source="source4"> + <id>source4-2</id> + </hit> + <hit relevance="0.5" source="source2"> + <id>source2-2</id> + </hit> + <hit relevance="0.3333333333333333" source="source4"> + <id>source4-3</id> + </hit> + <hit relevance="0.3333333333333333" source="source2"> + <id>source2-3</id> + </hit> + <hit relevance="0.25" source="source4"> + <id>source4-4</id> + </hit> + <hit relevance="0.25" source="source2"> + <id>source2-4</id> + </hit> + <hit relevance="0.2" source="source4"> + <id>source4-5</id> + </hit> + <hit relevance="0.1666666666666667" source="source4"> + <id>source4-6</id> + </hit> + </section> + +</result> diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/TwoSectionsFourSourcesTestCase.java b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/TwoSectionsFourSourcesTestCase.java new file mode 100644 index 00000000000..3fff2103332 --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/TwoSectionsFourSourcesTestCase.java @@ -0,0 +1,140 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.search.pagetemplates.engine.test; + +import com.yahoo.search.Query; +import com.yahoo.search.Result; +import com.yahoo.search.pagetemplates.engine.Organizer; +import com.yahoo.search.pagetemplates.engine.resolvers.DeterministicResolver; +import com.yahoo.search.pagetemplates.model.Choice; +import com.yahoo.search.result.Hit; +import com.yahoo.search.result.HitGroup; +import org.junit.Test; + +import java.util.List; + +import static org.junit.Assert.assertEquals; + +/** + * @author <a href="mailto:bratseth@yahoo-inc.com">Jon Bratseth</a> + */ +public class TwoSectionsFourSourcesTestCase extends ExecutionAbstractTestCase { + + @Test + public void testExecution() { + // Create the page template + Choice page=Choice.createSingleton(importPage("TwoSectionsFourSources.xml")); + + // Create a federated result + Query query=new Query(); + Result result=new Result(query); + result.hits().add(createHits("source1",3)); + result.hits().add(createHits("source2",4)); + result.hits().add(createHits("source3",12)); + result.hits().add(createHits("source4",13)); + + new Organizer().organize(page,new DeterministicResolver().resolve(page,query,result),result); + + // Check execution: + // Two subsections with two sources each, the first grouped the second blended + assertEquals(2,result.hits().size()); + HitGroup section1=(HitGroup)result.hits().get(0); + HitGroup section2=(HitGroup)result.hits().get(1); + assertGroupedSource3Source1(section1.asList()); + assertBlendedSource4Source2(section2.asList()); + + // Check rendering + assertRendered(result,"TwoSectionsFourSourcesResult.xml"); + } + + @Test + public void testExecutionMissingOneSource() { + // Create the page template + Choice page=Choice.createSingleton(importPage("TwoSectionsFourSources.xml")); + + // Create a federated result + Query query=new Query(); + Result result=new Result(query); + result.hits().add(createHits("source1",3)); + result.hits().add(createHits("source3",12)); + result.hits().add(createHits("source4",13)); + + new Organizer().organize(page,new DeterministicResolver().resolve(page,query,result),result); + + // Check execution: + // Two subsections with two sources each, the first grouped the second blended + assertEquals(2,result.hits().size()); + HitGroup section1=(HitGroup)result.hits().get(0); + HitGroup section2=(HitGroup)result.hits().get(1); + assertGroupedSource3Source1(section1.asList()); + assertEqualHitGroups(createHits("source4",10),section2); + } + + @Test + public void testExecutionMissingTwoSources() { + // Create the page template + Choice page=Choice.createSingleton(importPage("TwoSectionsFourSources.xml")); + + // Create a federated result + Query query=new Query(); + Result result=new Result(query); + result.hits().add(createHits("source1",3)); + result.hits().add(createHits("source3",12)); + + new Organizer().organize(page,new DeterministicResolver().resolve(page,query,result),result); + + // Check execution: + // Two subsections with two sources each, the first grouped the second blended + assertEquals(2,result.hits().size()); + HitGroup section1=(HitGroup)result.hits().get(0); + HitGroup section2=(HitGroup)result.hits().get(1); + assertGroupedSource3Source1(section1.asList()); + assertEquals(0,section2.size()); + } + + @Test + public void testExecutionMissingAllSources() { + // Create the page template + Choice page=Choice.createSingleton(importPage("TwoSectionsFourSources.xml")); + + // Create a federated result + Query query=new Query(); + Result result=new Result(query); + + new Organizer().organize(page,new DeterministicResolver().resolve(page,query,result),result); + + // Check execution: + // Two subsections with two sources each, the first grouped the second blended + assertEquals(2,result.hits().size()); + HitGroup section1=(HitGroup)result.hits().get(0); + HitGroup section2=(HitGroup)result.hits().get(1); + assertEquals(0,section1.size()); + assertEquals(0,section2.size()); + } + + private void assertGroupedSource3Source1(List<Hit> hits) { + assertEquals(8,hits.size()); + assertEquals("source3-1",hits.get(0).getId().stringValue()); + assertEquals("source3-2",hits.get(1).getId().stringValue()); + assertEquals("source3-3",hits.get(2).getId().stringValue()); + assertEquals("source3-4",hits.get(3).getId().stringValue()); + assertEquals("source3-5",hits.get(4).getId().stringValue()); + assertEquals("source1-1",hits.get(5).getId().stringValue()); + assertEquals("source1-2",hits.get(6).getId().stringValue()); + assertEquals("source1-3",hits.get(7).getId().stringValue()); + } + + private void assertBlendedSource4Source2(List<Hit> hits) { + assertEquals(10,hits.size()); + assertEquals("source4-1",hits.get(0).getId().stringValue()); + assertEquals("source2-1",hits.get(1).getId().stringValue()); + assertEquals("source4-2",hits.get(2).getId().stringValue()); + assertEquals("source2-2",hits.get(3).getId().stringValue()); + assertEquals("source4-3",hits.get(4).getId().stringValue()); + assertEquals("source2-3",hits.get(5).getId().stringValue()); + assertEquals("source4-4",hits.get(6).getId().stringValue()); + assertEquals("source2-4",hits.get(7).getId().stringValue()); + assertEquals("source4-5",hits.get(8).getId().stringValue()); + assertEquals("source4-6",hits.get(9).getId().stringValue()); + } + +} diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/test/PageTemplateSearcherTestCase.java b/container-search/src/test/java/com/yahoo/search/pagetemplates/test/PageTemplateSearcherTestCase.java new file mode 100644 index 00000000000..22c269e761f --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/test/PageTemplateSearcherTestCase.java @@ -0,0 +1,220 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.search.pagetemplates.test; + +import com.yahoo.component.ComponentId; +import com.yahoo.component.chain.Chain; +import com.yahoo.search.Query; +import com.yahoo.search.Result; +import com.yahoo.search.Searcher; +import com.yahoo.search.intent.model.*; +import com.yahoo.search.pagetemplates.PageTemplate; +import com.yahoo.search.pagetemplates.PageTemplateRegistry; +import com.yahoo.search.pagetemplates.PageTemplateSearcher; +import com.yahoo.search.pagetemplates.engine.Resolution; +import com.yahoo.search.pagetemplates.engine.resolvers.DeterministicResolver; +import com.yahoo.search.pagetemplates.model.Choice; +import com.yahoo.search.pagetemplates.model.PageElement; +import com.yahoo.search.result.Hit; +import com.yahoo.search.result.HitGroup; +import com.yahoo.search.searchchain.Execution; +import com.yahoo.text.interpretation.Interpretation; + +import java.util.*; + +/** + * @author bratseth + */ +@SuppressWarnings("deprecation") +public class PageTemplateSearcherTestCase extends junit.framework.TestCase { + + public void testSearcher() { + PageTemplateSearcher s = new PageTemplateSearcher(createPageTemplateRegistry(), new FirstChoiceResolver()); + Chain<Searcher> chain = new Chain<>(s,new MockFederator()); + + { + // No template specified, should use default + Result result=new Execution(chain, Execution.Context.createContextStub()).search(new Query("?query=foo&page.resolver=native.deterministic")); + assertSources("source1 source2",result); + } + + { + Result result=new Execution(chain, Execution.Context.createContextStub()).search(new Query("?query=foo&page.id=oneSource&page.resolver=native.deterministic")); + assertSources("source1",result); + } + + { + Result result=new Execution(chain, Execution.Context.createContextStub()).search(new Query("?query=foo&page.id=twoSources&model.sources=source1&page.resolver=native.deterministic")); + assertSources("source1",result); + } + + { + Query query=new Query("?query=foo&page.resolver=native.deterministic"); + addIntentModelSpecifyingSource3(query); + Result result=new Execution(chain, Execution.Context.createContextStub()).search(query); + assertSources("source1 source2",result); + } + + { + Query query=new Query("?query=foo&page.id=twoSourcesAndAny&page.resolver=native.deterministic"); + addIntentModelSpecifyingSource3(query); + Result result=new Execution(chain, Execution.Context.createContextStub()).search(query); + assertSources("source1 source2 source3",result); + } + + { + Query query=new Query("?query=foo&page.id=anySource&page.resolver=native.deterministic"); + addIntentModelSpecifyingSource3(query); + Result result=new Execution(chain, Execution.Context.createContextStub()).search(query); + assertSources("source3",result); + } + + { + Query query=new Query("?query=foo&page.id=anySource&page.resolver=native.deterministic"); + Result result=new Execution(chain, Execution.Context.createContextStub()).search(query); + assertTrue(query.getModel().getSources().isEmpty()); + assertNotNull(result.hits().get("source1")); + assertNotNull(result.hits().get("source2")); + assertNotNull(result.hits().get("source3")); + } + + { + Query query=new Query("?query=foo&page.id=choiceOfSources&page.resolver=native.deterministic"); + Result result=new Execution(chain, Execution.Context.createContextStub()).search(query); + assertSources("source1 source2","source2",result); + } + + { + Query query=new Query("?query=foo&page.id=choiceOfSources&page.resolver=test.firstChoice"); + Result result=new Execution(chain, Execution.Context.createContextStub()).search(query); + assertSources("source1 source2","source1",result); + } + + { // Specifying two templates, should pick the last + Query query=new Query("?query=foo&page.id=threeSources+oneSource&page.resolver=native.deterministic"); + Result result=new Execution(chain, Execution.Context.createContextStub()).search(query); + assertSources("source1 source2 source3","source1",result); + } + + { // Specifying two templates as a list, should override the page.id setting + Query query=new Query("?query=foo&page.id=anySource&page.resolver=native.deterministic"); + query.properties().set("page.idList",Arrays.asList("oneSource","threeSources")); + Result result=new Execution(chain, Execution.Context.createContextStub()).search(query); + assertSources("source1 source2 source3","source1 source2 source3",result); + } + + { + try { + Query query=new Query("?query=foo&page.id=oneSource+choiceOfSources&page.resolver=noneSuch"); + new Execution(chain, Execution.Context.createContextStub()).search(query); + fail("Expected exception"); + } + catch (IllegalArgumentException e) { + assertEquals("No page template resolver 'noneSuch'",e.getMessage()); + } + } + + } + + private PageTemplateRegistry createPageTemplateRegistry() { + PageTemplateRegistry registry=new PageTemplateRegistry(); + + PageTemplate twoSources=new PageTemplate(new ComponentId("default")); + twoSources.getSection().elements().add(new com.yahoo.search.pagetemplates.model.Source("source1")); + twoSources.getSection().elements().add(new com.yahoo.search.pagetemplates.model.Source("source2")); + registry.register(twoSources); + + PageTemplate oneSource=new PageTemplate(new ComponentId("oneSource")); + oneSource.getSection().elements().add(new com.yahoo.search.pagetemplates.model.Source("source1")); + registry.register(oneSource); + + PageTemplate threeSources=new PageTemplate(new ComponentId("threeSources")); + threeSources.getSection().elements().add(new com.yahoo.search.pagetemplates.model.Source("source1")); + threeSources.getSection().elements().add(new com.yahoo.search.pagetemplates.model.Source("source2")); + threeSources.getSection().elements().add(new com.yahoo.search.pagetemplates.model.Source("source3")); + registry.register(threeSources); + + PageTemplate twoSourcesAndAny=new PageTemplate(new ComponentId("twoSourcesAndAny")); + twoSourcesAndAny.getSection().elements().add(new com.yahoo.search.pagetemplates.model.Source("source1")); + twoSourcesAndAny.getSection().elements().add(new com.yahoo.search.pagetemplates.model.Source("source2")); + twoSourcesAndAny.getSection().elements().add(com.yahoo.search.pagetemplates.model.Source.any); + registry.register(twoSourcesAndAny); + + PageTemplate anySource=new PageTemplate(new ComponentId("anySource")); + anySource.getSection().elements().add(com.yahoo.search.pagetemplates.model.Source.any); + registry.register(anySource); + + PageTemplate choiceOfSources=new PageTemplate(new ComponentId("choiceOfSources")); + List<PageElement> alternatives=new ArrayList<>(); + alternatives.add(new com.yahoo.search.pagetemplates.model.Source("source1")); + alternatives.add(new com.yahoo.search.pagetemplates.model.Source("source2")); + choiceOfSources.getSection().elements().add(Choice.createSingletons(alternatives)); + registry.register(choiceOfSources); + + registry.freeze(); + return registry; + } + + private void addIntentModelSpecifyingSource3(Query query) { + IntentModel intentModel=new IntentModel(); + InterpretationNode interpretation=new InterpretationNode(new Interpretation("ignored")); + IntentNode intent=new IntentNode(new Intent("ignored"),1.0); + intent.children().add(new SourceNode(new com.yahoo.search.intent.model.Source("source3"),1.0)); + interpretation.children().add(intent); + intentModel.children().add(interpretation); + intentModel.setTo(query); + } + + private void assertSources(String expectedSourceString,Result result) { + assertSources(expectedSourceString,expectedSourceString,result); + } + + private void assertSources(String expectedQuerySourceString,String expectedResultSourceString,Result result) { + Set<String> expectedQuerySources=new HashSet<>(Arrays.asList(expectedQuerySourceString.split(" "))); + assertEquals(expectedQuerySources,result.getQuery().getModel().getSources()); + + Set<String> expectedResultSources=new HashSet<>(Arrays.asList(expectedResultSourceString.split(" "))); + for (String sourceName : Arrays.asList("source1 source2 source3".split(" "))) { + if (expectedResultSources.contains(sourceName)) + assertNotNull("Result contains '" + sourceName + "'",result.hits().get(sourceName)); + else + assertNull("Result does not contain '" + sourceName + "'",result.hits().get(sourceName)); + } + } + + private static class MockFederator extends Searcher { + + @Override + public Result search(Query query,Execution execution) { + Result result=new Result(query); + for (String sourceName : Arrays.asList("source1 source2 source3".split(" "))) + if (query.getModel().getSources().isEmpty() || query.getModel().getSources().contains(sourceName)) + result.hits().add(createSource(sourceName)); + return result; + } + + private HitGroup createSource(String sourceName) { + HitGroup hitGroup=new HitGroup("source:" + sourceName); + Hit hit=new Hit(sourceName); + hit.setSource(sourceName); + hitGroup.add(hit); + return hitGroup; + } + + } + + /** Like the deterministic resolver except that it takes the <i>first</i> option of all choices */ + private static class FirstChoiceResolver extends DeterministicResolver { + + public FirstChoiceResolver() { + super("test.firstChoice"); + } + + /** Chooses the first alternative of any choice */ + @Override + public void resolve(Choice choice, Query query, Result result, Resolution resolution) { + resolution.addChoiceResolution(choice,0); + } + + } + +} diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/test/SourceParameters.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/test/SourceParameters.xml new file mode 100644 index 00000000000..2a98ef6918f --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/test/SourceParameters.xml @@ -0,0 +1,16 @@ +<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<page id="SourceParameters"> + <source name="source1"> + <parameter name="p1">source1p1Value</parameter> + <parameter name="p2">source1p2Value</parameter> + </source> + <choice> + <source name="source2"> + <parameter name="p1">source2p1Value</parameter> + <parameter name="p3">source2p3Value</parameter> + </source> + <source name="source3"> + <parameter name="p1">source3p1Value</parameter> + </source> + </choice> +</page> diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/test/SourceParametersTestCase.java b/container-search/src/test/java/com/yahoo/search/pagetemplates/test/SourceParametersTestCase.java new file mode 100644 index 00000000000..1f79637119a --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/test/SourceParametersTestCase.java @@ -0,0 +1,54 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.search.pagetemplates.test; + +import com.yahoo.search.Query; +import com.yahoo.search.pagetemplates.PageTemplate; +import com.yahoo.search.pagetemplates.PageTemplateRegistry; +import com.yahoo.search.pagetemplates.PageTemplateSearcher; +import com.yahoo.search.pagetemplates.config.PageTemplateXMLReader; +import com.yahoo.search.searchchain.Execution; + +/** + * @author bratseth + */ +public class SourceParametersTestCase extends junit.framework.TestCase { + + private static final String root="src/test/java/com/yahoo/search/pagetemplates/test/"; + + public void testSourceParametersWithSourcesDeterminedByTemplate() { + // Create the page template + PageTemplateRegistry pageTemplateRegistry=new PageTemplateRegistry(); + PageTemplate page=importPage("SourceParameters.xml"); + pageTemplateRegistry.register(page); + PageTemplateSearcher s=new PageTemplateSearcher(pageTemplateRegistry); + Query query=new Query("?query=foo&page.id=SourceParameters&page.resolver=native.deterministic"); + new Execution(s, Execution.Context.createContextStub()).search(query); + assertEquals("source1p1Value",query.properties().get("source.source1.p1")); + assertEquals("source1p1Value",query.properties().get("source.source1.p1")); + assertEquals("source2p1Value",query.properties().get("source.source2.p1")); + assertEquals("source2p3Value",query.properties().get("source.source2.p3")); + assertEquals("source3p1Value",query.properties().get("source.source3.p1")); + assertEquals("We get the correct number of parameters",5,query.properties().listProperties("source").size()); + } + + public void testSourceParametersWithSourcesDeterminedByParameter() { + // Create the page template + PageTemplateRegistry pageTemplateRegistry=new PageTemplateRegistry(); + PageTemplate page=importPage("SourceParameters.xml"); + pageTemplateRegistry.register(page); + PageTemplateSearcher s=new PageTemplateSearcher(pageTemplateRegistry); + Query query=new Query("?query=foo&page.id=SourceParameters&model.sources=source1,source3&page.resolver=native.deterministic"); + new Execution(s, Execution.Context.createContextStub()).search(query); + assertEquals("source1p1Value",query.properties().get("source.source1.p1")); + assertEquals("source1p1Value",query.properties().get("source.source1.p1")); + assertEquals("source3p1Value",query.properties().get("source.source3.p1")); + assertEquals("We get the correct number of parameters",3,query.properties().listProperties("source").size()); + } + + protected PageTemplate importPage(String name) { + PageTemplate template=new PageTemplateXMLReader().readFile(root + name); + assertNotNull("Could look up read template '" + name + "'",template); + return template; + } + +} |