1   package com.atlassian.plugins.codegen.modules.confluence.blueprint;
2   
3   import com.atlassian.plugins.codegen.modules.AbstractNameBasedModuleProperties;
4   import com.atlassian.plugins.codegen.modules.common.Resource;
5   import com.atlassian.plugins.codegen.modules.common.web.WebItemProperties;
6   import com.atlassian.plugins.codegen.modules.common.web.WebResourceProperties;
7   import com.atlassian.plugins.codegen.modules.common.web.WebResourceTransformation;
8   import com.atlassian.plugins.codegen.modules.common.web.WebResourceTransformer;
9   import com.google.common.collect.Lists;
10  import org.junit.Before;
11  import org.junit.Test;
12  
13  import java.util.List;
14  
15  import static com.atlassian.plugins.codegen.modules.confluence.blueprint.BlueprintI18nProperty.*;
16  import static com.atlassian.plugins.codegen.modules.confluence.blueprint.BlueprintPromptEntry.*;
17  import static com.atlassian.plugins.codegen.modules.confluence.blueprint.BlueprintProperties.*;
18  import static com.atlassian.plugins.codegen.modules.confluence.blueprint.ContentTemplateProperties.CONTENT_I18N_DEFAULT_VALUE;
19  import static org.hamcrest.MatcherAssert.assertThat;
20  import static org.hamcrest.Matchers.is;
21  import static org.hamcrest.Matchers.notNullValue;
22  import static org.junit.Assert.assertEquals;
23  
24  /**
25   * Tests that the builder converts a simple Properties object returned by the Prompter into a complete
26   * BlueprintProperties object.
27   *
28   * @since 4.1.8
29   */
30  public class BlueprintBuilderTest
31  {
32      public static final String PLUGIN_KEY = "com.atlassian.confluence.plugins.fooprint";
33  
34      private String webItemName = "FooPrint";
35      private String webItemDesc = "There's no Blueprint like my FooPrint.";
36      private String templateModuleKey = "foo-plate";
37      private String blueprintIndexKey = "foo-print";
38      private String blueprintModuleKey = blueprintIndexKey + "-blueprint";
39  
40      private BlueprintBuilder builder;
41      private BlueprintPromptEntries promptProps;
42  
43      private BlueprintStringer stringer = new BlueprintStringer(blueprintIndexKey, PLUGIN_KEY);
44  
45      @Before
46      public void setup()
47      {
48          promptProps = new BlueprintPromptEntries(PLUGIN_KEY);
49  
50          promptProps.put(INDEX_KEY_PROMPT, blueprintIndexKey);
51          promptProps.put(WEB_ITEM_NAME_PROMPT, webItemName);
52          promptProps.put(WEB_ITEM_DESC_PROMPT, webItemDesc);
53  
54          List<String> contentTemplateKeys = Lists.newArrayList();
55          contentTemplateKeys.add(templateModuleKey);
56          promptProps.put(CONTENT_TEMPLATE_KEYS_PROMPT, contentTemplateKeys);
57  
58          builder = new BlueprintBuilder(promptProps);
59      }
60  
61      @Test
62      public void basicPropertiesAreValid()
63      {
64          BlueprintProperties props = builder.build();
65  
66          assertThat(props.getPluginKey(), is(PLUGIN_KEY));
67  
68          // Create expected Properties objects that the prompter should return.
69          BlueprintProperties expectedProps = new BlueprintProperties();
70          expectedProps.setModuleKey(blueprintModuleKey);
71          expectedProps.setModuleName("FooPrint Blueprint");
72          expectedProps.setIndexKey(blueprintIndexKey);
73          expectedProps.setWebItem(makeExpectedWebItemProperties());
74          expectedProps.addContentTemplate(makeExpectedContentTemplateProperties());
75          expectedProps.setIndexTitleI18nKey("com.atlassian.confluence.plugins.fooprint.index.page.title");
76  
77          // Assert that all of the things are good things.
78          assertBlueprintProperties(expectedProps, props);
79          assertWebItemProperties(expectedProps.getWebItem(), props.getWebItem());
80          assertContentTemplatePropertiesEqual(expectedProps.getContentTemplates(), props.getContentTemplates());
81      }
82  
83      @Test
84      public void howToUseTemplateAdded()
85      {
86          promptProps.put(HOW_TO_USE_PROMPT, true);
87          BlueprintProperties props = builder.build();
88  
89          WebResourceProperties expectedWebResource = newExpectedWebResourceProperties(blueprintIndexKey);
90          addSoyTemplateToExpectedWebResource(expectedWebResource);
91          addHowToUseToExpectedSoyResource(expectedWebResource);
92  
93          assertEquals("Confluence.Blueprints.Plugin.FooPrint.howToUse", props.getHowToUseTemplate());
94          assertWebResourceProperties(expectedWebResource, props.getWebResource());
95      }
96  
97      @Test
98      public void editorIsSkipped() throws Exception
99      {
100         promptProps.put(SKIP_PAGE_EDITOR_PROMPT, true);
101         BlueprintProperties props = builder.build();
102 
103         assertThat(props.getCreateResult(), is(BlueprintProperties.CREATE_RESULT_VIEW));
104     }
105 
106     @Test
107     public void dialogWizardAdded()
108     {
109         promptProps.put(DIALOG_WIZARD_PROMPT, true);
110         BlueprintProperties props = builder.build();
111 
112         DialogWizardProperties expectedWizard = new DialogWizardProperties();
113         expectedWizard.setModuleKey("foo-print-wizard");
114         List<DialogPageProperties> pages = Lists.newArrayList();
115         DialogPageProperties page = new DialogPageProperties(0, "Confluence.Blueprints.Plugin.FooPrint", stringer);
116         pages.add(page);
117         expectedWizard.setDialogPages(pages);
118 
119         assertDialogWizard(expectedWizard, props.getDialogWizard());
120 
121         WebResourceProperties expectedWebResource = newExpectedWebResourceProperties(blueprintIndexKey);
122         addJsToExpectedWebResource(expectedWebResource);
123         addSoyTemplateToExpectedWebResource(expectedWebResource); // order of addition is important to assertions
124 
125         assertWebResourceProperties(expectedWebResource, props.getWebResource());
126 
127         assertThat(props.getWebResource().getProperty(BlueprintProperties.PLUGIN_KEY), is(PLUGIN_KEY));
128         assertThat(props.getWebResource().getProperty(BlueprintProperties.WEB_ITEM_KEY), is(
129             "foo-print-blueprint-web-item"));
130     }
131 
132     @Test
133     public void indexPageTemplateAdded() throws Exception
134     {
135         promptProps.put(INDEX_PAGE_TEMPLATE_PROMPT, true);
136         BlueprintProperties props = builder.build();
137 
138         ContentTemplateProperties expected = makeExpectedIndexPageContentTemplateProperties();
139         assertContentTemplatePropertiesEqual(expected, props.getIndexPageContentTemplate());
140     }
141 
142     private void addJsToExpectedWebResource(WebResourceProperties properties)
143     {
144         WebResourceTransformation transformation = new WebResourceTransformation("js");
145         WebResourceTransformer transformer = new WebResourceTransformer();
146         transformer.setModuleKey("jsI18n");
147         transformation.addTransformer(transformer);
148         properties.addTransformation(transformation);
149 
150         Resource soyResource = new Resource();
151         soyResource.setType("download");
152         soyResource.setName("dialog-wizard.js");
153         soyResource.setLocation("js/dialog-wizard.js");
154         properties.addResource(soyResource);
155 
156         addI18n(properties, WIZARD_FORM_TITLE_FIELD_LABEL);
157         addI18n(properties, WIZARD_FORM_TITLE_FIELD_PLACEHOLDER);
158         addI18n(properties, WIZARD_FORM_TITLE_FIELD_ERROR);
159         addI18n(properties, WIZARD_FORM_JSVAR_FIELD_LABEL);
160         addI18n(properties, WIZARD_FORM_JSVAR_FIELD_PLACEHOLDER);
161         addI18n(properties, WIZARD_FORM_PRE_RENDER_TEXT);
162         addI18n(properties, WIZARD_FORM_POST_RENDER_TEXT);
163         addI18n(properties, WIZARD_FORM_FIELD_REQUIRED);
164     }
165 
166     private void addI18n(WebResourceProperties properties, BlueprintI18nProperty i18n)
167     {
168         String i18nKey = i18n.getI18nKey(stringer);
169         properties.setProperty(i18n.getPropertyKey(), i18nKey);
170         properties.addI18nProperty(i18nKey, i18n.getI18nValue());
171     }
172 
173     private void assertDialogWizard(DialogWizardProperties expectedWizard, DialogWizardProperties actualWizard)
174     {
175         assertThat(actualWizard, notNullValue());
176 
177         List<DialogPageProperties> actualPages = actualWizard.getDialogPages();
178         List<DialogPageProperties> expectedPages = expectedWizard.getDialogPages();
179         assertThat(actualPages.size(), is(expectedPages.size()));
180 
181         DialogPageProperties actualPage = actualPages.get(0);
182         DialogPageProperties expectedPage = expectedPages.get(0);
183 
184         assertThat(actualPage, is(expectedPage));
185     }
186 
187     private void assertWebResourceProperties(WebResourceProperties expected, WebResourceProperties actual)
188     {
189         assertTransformationsEqual(expected.getTransformations(), actual.getTransformations());
190         assertResourcesEqual(expected.getResources(), actual.getResources());
191         assertEquals(expected.getContexts(), actual.getContexts());
192         assertEquals(expected.getDependencies(), actual.getDependencies());
193         assertEquals(expected.getI18nProperties(), actual.getI18nProperties());
194     }
195 
196     private void assertTransformationsEqual(List<WebResourceTransformation> expectedTransformations,
197         List<WebResourceTransformation> actualTransformations)
198     {
199         assertThat(actualTransformations.size(), is(expectedTransformations.size()));
200         for (int i = 0; i < expectedTransformations.size(); i++)
201         {
202             WebResourceTransformation expected = expectedTransformations.get(i);
203             WebResourceTransformation actual = actualTransformations.get(i);
204             assertTransformationEqual(expected, actual);
205         }
206     }
207 
208     private void assertTransformationEqual(WebResourceTransformation expected, WebResourceTransformation actual)
209     {
210         assertThat(actual.getExtension(), is(expected.getExtension()));
211         assertThat(actual.getTransformers(), is(expected.getTransformers()));
212     }
213 
214     private WebResourceProperties newExpectedWebResourceProperties(String indexKey)
215     {
216         WebResourceProperties properties = new WebResourceProperties();
217 
218         properties.addContext("atl.general");
219         properties.addContext("atl.admin");
220 
221         properties.addDependency("com.atlassian.confluence.plugins.confluence-create-content-plugin:resources");
222 
223         Resource soyResource = new Resource();
224         soyResource.setType("download");
225         soyResource.setName("blueprints.css");
226         soyResource.setLocation("css/blueprints.css");
227         properties.addResource(soyResource);
228 
229         properties.setProperty("INDEX_KEY", indexKey);
230 
231         return properties;
232     }
233 
234     private void addSoyTemplateToExpectedWebResource(WebResourceProperties properties)
235     {
236         // Soy transformer
237         WebResourceTransformation transformation = new WebResourceTransformation("soy");
238         WebResourceTransformer transformer = new WebResourceTransformer();
239         transformer.setModuleKey("soyTransformer");
240         transformer.addFunctions("com.atlassian.confluence.plugins.soy:soy-core-functions");
241         transformation.addTransformer(transformer);
242         properties.addTransformation(transformation);
243 
244         Resource soyResource = new Resource();
245         soyResource.setType("download");
246         soyResource.setName("templates-soy.js");
247         soyResource.setLocation("soy/my-templates.soy");
248         properties.addResource(soyResource);
249 
250         properties.setProperty(BlueprintProperties.SOY_PACKAGE, "Confluence.Blueprints.Plugin.FooPrint");
251     }
252 
253     private void addHowToUseToExpectedSoyResource(WebResourceProperties properties)
254     {
255         addI18n(properties, HOW_TO_USE_HEADING);
256         addI18n(properties, HOW_TO_USE_CONTENT);
257     }
258 
259     private void assertContentTemplatePropertiesEqual(List<ContentTemplateProperties> expectedTemplates,
260         List<ContentTemplateProperties> actualTemplates)
261     {
262         assertEquals("Wrong number of content templates", expectedTemplates.size(), actualTemplates.size());
263         for (int i = 0; i < expectedTemplates.size(); i++)
264         {
265             ContentTemplateProperties expected = expectedTemplates.get(i);
266             ContentTemplateProperties actual = actualTemplates.get(i);
267 
268             assertContentTemplatePropertiesEqual(expected, actual);
269         }
270     }
271 
272     private void assertContentTemplatePropertiesEqual(ContentTemplateProperties expected,
273         ContentTemplateProperties actual)
274     {
275         assertNameBasedModulesEqual(expected, actual);
276         assertEquals(expected.getContentText(), actual.getContentText());
277 
278         assertResourcesEqual(expected.getResources(), actual.getResources());
279     }
280 
281     private void assertNameBasedModulesEqual(AbstractNameBasedModuleProperties expected,
282         AbstractNameBasedModuleProperties actual)
283     {
284         assertEquals(expected.getModuleKey(), actual.getModuleKey());
285         assertEquals(expected.getNameI18nKey(), actual.getNameI18nKey());
286         assertEquals(expected.getModuleName(), actual.getModuleName());
287         assertEquals(expected.getDescriptionI18nKey(), actual.getDescriptionI18nKey());
288         assertEquals(expected.getDescription(), actual.getDescription());
289     }
290 
291     private void assertResourcesEqual(List<Resource> expectedResources, List<Resource> actualResources)
292     {
293         assertEquals("Wrong number of Resources", expectedResources.size(), actualResources.size());
294         for (int i = 0; i < expectedResources.size(); i++)
295         {
296             Resource expected = expectedResources.get(i);
297             Resource actual = actualResources.get(i);
298 
299             assertEquals(expected.getName(), actual.getName());
300             assertEquals(expected.getType(), actual.getType());
301             assertEquals(expected.getLocation(), actual.getLocation());
302         }
303     }
304 
305     private void assertWebItemProperties(WebItemProperties expected, WebItemProperties actual)
306     {
307         assertNameBasedModulesEqual(expected, actual);
308         assertEquals(expected.getSection(), actual.getSection());
309         assertResourcesEqual(expected.getResources(), actual.getResources());
310         assertEquals(expected.getParam(WEB_ITEM_BLUEPRINT_KEY), actual.getParam(WEB_ITEM_BLUEPRINT_KEY));
311     }
312 
313     private void assertBlueprintProperties(BlueprintProperties expected, BlueprintProperties actual)
314     {
315         assertEquals("Wrong module key", expected.getModuleKey(), actual.getModuleKey());
316         assertEquals("Wrong module name", expected.getModuleName(), actual.getModuleName());
317         assertEquals("Wrong index key", expected.getIndexKey(), actual.getIndexKey());
318         assertEquals("Wrong how-to-use template", expected.getHowToUseTemplate(), actual.getHowToUseTemplate());
319         assertEquals("Wrong index page title i18n", expected.getIndexTitleI18nKey(), actual.getIndexTitleI18nKey());
320 
321         assertNameBasedModulesEqual(expected, actual);
322     }
323 
324     private WebItemProperties makeExpectedWebItemProperties()
325     {
326         WebItemProperties webItem = new WebItemProperties();
327         webItem.setModuleKey("foo-print-blueprint-web-item");
328         webItem.setNameI18nKey(PLUGIN_KEY + ".blueprint.display.name");
329         webItem.setModuleName(webItemName);
330         webItem.setDescriptionI18nKey(PLUGIN_KEY + ".blueprint.display.desc");
331         webItem.setDescription(webItemDesc);
332         webItem.setSection("system.create.dialog/content");
333 
334         webItem.addParam(WEB_ITEM_BLUEPRINT_KEY, blueprintModuleKey);
335         return webItem;
336     }
337 
338     private ContentTemplateProperties makeExpectedContentTemplateProperties()
339     {
340         ContentTemplateProperties template = new ContentTemplateProperties(templateModuleKey);
341         template.setNameI18nKey(PLUGIN_KEY + ".foo-plate.name");
342         template.setModuleName("FooPrint Content Template 0");
343         template.setDescriptionI18nKey(PLUGIN_KEY + ".foo-plate.desc");
344         template.setDescription("Contains Storage-format XML used by the FooPrint Blueprint");
345         template.setContentText(PLUGIN_KEY + "." + templateModuleKey + ".content.text", CONTENT_I18N_DEFAULT_VALUE);
346 
347         Resource templateResource = new Resource();
348         templateResource.setName("template");
349         templateResource.setType("download");
350         templateResource.setLocation("xml/" + templateModuleKey + ".xml");
351         template.addResource(templateResource);
352         return template;
353     }
354 
355     private ContentTemplateProperties makeExpectedIndexPageContentTemplateProperties()
356     {
357         String moduleKey = BlueprintProperties.INDEX_TEMPLATE_DEFAULT_KEY;
358         ContentTemplateProperties template = new ContentTemplateProperties(moduleKey);
359         template.setNameI18nKey(PLUGIN_KEY + ".custom-index-page-template.name");
360         template.setDescriptionI18nKey(PLUGIN_KEY + ".custom-index-page-template.desc");
361         template.setModuleName("Custom Index Page Content Template");
362         template.setDescription("Contains Storage-format XML used by the FooPrint Blueprint's Index page");
363         template.setContentText(PLUGIN_KEY + ".custom-index-page-template.content.text", ContentTemplateProperties.INDEX_TEMPLATE_CONTENT_VALUE);
364 
365         Resource templateResource = new Resource();
366         templateResource.setName("template");
367         templateResource.setType("download");
368         templateResource.setLocation("xml/" + moduleKey + ".xml");
369         template.addResource(templateResource);
370         return template;
371     }
372 }