View Javadoc
1   /**
2    * This file Copyright (c) 2013-2017 Magnolia International
3    * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10   * This file is distributed in the hope that it will be
11   * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12   * implied warranty of MERCHANTABILITY or FITNESS FOR A
13   * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14   * Redistribution, except as permitted by whichever of the GPL
15   * or MNA you select, is prohibited.
16   *
17   * 1. For the GPL license (GPL), you can redistribute and/or
18   * modify this file under the terms of the GNU General
19   * Public License, Version 3, as published by the Free Software
20   * Foundation.  You should have received a copy of the GNU
21   * General Public License, Version 3 along with this program;
22   * if not, write to the Free Software Foundation, Inc., 51
23   * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24   *
25   * 2. For the Magnolia Network Agreement (MNA), this file
26   * and the accompanying materials are made available under the
27   * terms of the MNA which accompanies this distribution, and
28   * is available at http://www.magnolia-cms.com/mna.html
29   *
30   * Any modifications to this file must keep this entire header
31   * intact.
32   *
33   */
34  package info.magnolia.module.googlesitemap.setup;
35  
36  import static info.magnolia.test.hamcrest.ExecutionMatcher.throwsNothing;
37  import static info.magnolia.test.hamcrest.NodeMatchers.hasNode;
38  import static info.magnolia.test.hamcrest.NodeMatchers.hasProperty;
39  import static org.hamcrest.CoreMatchers.not;
40  import static org.hamcrest.MatcherAssert.assertThat;
41  import static org.junit.Assert.assertEquals;
42  import static org.junit.Assert.assertTrue;
43  
44  import info.magnolia.cms.core.version.VersionManager;
45  import info.magnolia.cms.util.ClasspathResourcesUtil;
46  import info.magnolia.context.MgnlContext;
47  import info.magnolia.jcr.util.NodeTypes;
48  import info.magnolia.jcr.util.NodeUtil;
49  import info.magnolia.module.InstallContext;
50  import info.magnolia.module.ModuleManagementException;
51  import info.magnolia.module.ModuleVersionHandler;
52  import info.magnolia.module.ModuleVersionHandlerTestCase;
53  import info.magnolia.module.googlesitemap.GoogleSiteMapConfiguration;
54  import info.magnolia.module.googlesitemap.SiteMapNodeTypes;
55  import info.magnolia.module.googlesitemap.app.subapp.sitemapdetail.contentviews.formatter.FolderNameColumnFormatter;
56  import info.magnolia.module.model.Version;
57  import info.magnolia.objectfactory.Components;
58  import info.magnolia.repository.RepositoryConstants;
59  import info.magnolia.repository.RepositoryManager;
60  import info.magnolia.test.hamcrest.Execution;
61  
62  import java.util.Arrays;
63  import java.util.List;
64  
65  import javax.jcr.Node;
66  import javax.jcr.NodeIterator;
67  import javax.jcr.RepositoryException;
68  import javax.jcr.Session;
69  
70  import org.junit.Test;
71  
72  /**
73   * Tests for {@link GoogleSiteMapVersionHandler}.
74   */
75  public class GoogleSiteMapVersionHandlerTest extends ModuleVersionHandlerTestCase {
76  
77      private Session session;
78      private final String siteMapNodeTypeConfigFile = "/test-google-sitemap-nodetypes.xml";
79  
80      @Override
81      protected String getModuleDescriptorPath() {
82          return "/META-INF/magnolia/google-sitemap.xml";
83      }
84  
85      @Override
86      protected ModuleVersionHandler newModuleVersionHandlerForTests() {
87          return new GoogleSiteMapVersionHandler();
88      }
89  
90      @Override
91      protected String[] getExtraWorkspaces() {
92          return new String[]{"templates", GoogleSiteMapConfiguration.WORKSPACE};
93      }
94  
95      @Override
96      protected List<String> getModuleDescriptorPathsForTests() {
97          return Arrays.asList("/META-INF/magnolia/core.xml");
98      }
99  
100     @Override
101     protected String getExtraNodeTypes() {
102         return siteMapNodeTypeConfigFile;
103     }
104 
105     @Override
106     public String getRepositoryConfigFileName() {
107         return "/test-siteMap-repositories.xml";
108     }
109 
110     @Override
111     public void setUp() throws Exception {
112         super.setUp();
113 
114         session = MgnlContext.getJCRSession(RepositoryConstants.CONFIG);
115 
116         addSupportForSetupModuleRepositoriesTask(null);
117 
118         // Register Google SiteMap node type
119         try {
120             Components.getComponent(RepositoryManager.class).getRepositoryProvider("magnolia").registerNodeTypes(ClasspathResourcesUtil.getResource(siteMapNodeTypeConfigFile).openStream());
121         } catch (RepositoryException e) {
122         }
123 
124         this.setupConfigProperty("/modules/google-sitemap/dialogs/components/content/siteComponentTab/form/tabs/tabSites/fields/sites/field", "workspace", "website");
125         this.setupConfigNode("/modules/google-sitemap/dialogs/generic/controls/googleSiteMapTab/form/tabs/tabGoogleSitemapProps/fields/googleSitemapPriority");
126         this.setupConfigNode("/modules/google-sitemap/dialogs/generic/controls/googleSiteMapTab/form/tabs/tabGoogleSitemapProps/fields/googleSitemapChangefreq");
127         this.setupConfigNode("/modules/google-sitemap/dialogs/generic/controls/googleVirtualUriMapTab/form/tabs/tabGoogleSitemapProps/fields/googleSitemapPriority");
128         this.setupConfigNode("/modules/google-sitemap/dialogs/generic/controls/googleVirtualUriMapTab/form/tabs/tabGoogleSitemapProps/fields/googleSitemapChangefreq");
129         this.setupConfigNode("/modules/google-sitemap/templates/pages/siteMapsConfiguration");
130         this.setupConfigNode("/modules/google-sitemap/apps/siteMaps/subApps/browser/actions/deactivate");
131         this.setupConfigNode("/modules/google-sitemap/apps/siteMaps/subApps/browser/actions/export");
132         this.setupConfigNode("/modules/google-sitemap/apps/siteMaps/subApps/browser/actions/editSiteMap");
133     }
134 
135     @Test
136     public void updateFrom123ReordersSitemapBeforeConfigApp() throws Exception {
137         // GIVEN
138         Node manageApps = NodeUtil.createPath(session.getRootNode(), "modules/ui-admincentral/config/appLauncherLayout/groups/manage/apps", NodeTypes.ContentNode.NAME);
139         NodeUtil.createPath(manageApps, "rssAggregator", NodeTypes.ContentNode.NAME);
140         NodeUtil.createPath(manageApps, "configuration", NodeTypes.ContentNode.NAME);
141 
142         // WHEN
143         executeUpdatesAsIfTheCurrentlyInstalledVersionWas(Version.parseVersion("1.2.3"));
144 
145         // THEN
146         NodeIterator it = manageApps.getNodes();
147         assertTrue(manageApps.hasNode("siteMaps"));
148         assertEquals("rssAggregator", it.nextNode().getName());
149         assertEquals("siteMaps", it.nextNode().getName());
150         assertEquals("configuration", it.nextNode().getName());
151     }
152 
153     @Test
154     public void freshInstallReordersSitemapBeforeConfigApp() throws Exception {
155         // GIVEN
156         Node manageApps = NodeUtil.createPath(session.getRootNode(), "modules/ui-admincentral/config/appLauncherLayout/groups/manage/apps", NodeTypes.ContentNode.NAME);
157         NodeUtil.createPath(manageApps, "rssAggregator", NodeTypes.ContentNode.NAME);
158         NodeUtil.createPath(manageApps, "configuration", NodeTypes.ContentNode.NAME);
159         // we have to create the siteMaps node artificially before bootstrapping, otherwise test would fail in maven
160         NodeUtil.createPath(manageApps, "siteMaps", NodeTypes.ContentNode.NAME);
161 
162         // WHEN
163         executeUpdatesAsIfTheCurrentlyInstalledVersionWas(null);
164 
165         // THEN
166         NodeIterator it = manageApps.getNodes();
167         assertTrue(manageApps.hasNode("siteMaps"));
168         assertEquals("rssAggregator", it.nextNode().getName());
169         assertEquals("siteMaps", it.nextNode().getName());
170         assertEquals("configuration", it.nextNode().getName());
171     }
172 
173     @Test
174     public void update22() throws RepositoryException, ModuleManagementException {
175         // GIVEN
176         this.setupConfigProperty("/modules/google-sitemap/dialogs/components/content/siteComponentTab/form/tabs/siteMap", "property", "value");
177         this.setupConfigNode("/modules/google-sitemap/apps/siteMaps/subApps/browser");
178         this.setupConfigProperty("/modules/google-sitemap/apps/siteMaps/subApps/pages", "property", "value");
179         this.setupConfigProperty("/modules/google-sitemap/apps/siteMaps/subApps/browser/workbench/contentViews/list/columns/name", "formatterClass", "info.magnolia.module.googlesitemap.app.subapp.sitemapdetail.formatter.FolderNameColumnFormatter");
180 
181         // WHEN
182         executeUpdatesAsIfTheCurrentlyInstalledVersionWas(Version.parseVersion("2.0"));
183 
184         // THEN
185         NodeIterator it = session.getNode("/modules/google-sitemap/apps/siteMaps/subApps").getNodes();
186         assertEquals("browser", it.nextNode().getName());
187         assertEquals("pages", it.nextNode().getName());
188         assertConfig(FolderNameColumnFormatter.class.getName(), "/modules/google-sitemap/apps/siteMaps/subApps/browser/workbench/contentViews/list/columns/name/formatterClass");
189         assertConfig("0.5", "/modules/google-sitemap/config/priority");
190         assertConfig("weekly", "/modules/google-sitemap/config/changeFrequency");
191         assertTrue(session.nodeExists("/modules/google-sitemap/fieldTypes/siteMapSelect"));
192     }
193 
194     @Test
195     public void updateFrom21ConfigureActions() throws Exception {
196         // GIVEN
197         Session session = MgnlContext.getJCRSession(RepositoryConstants.CONFIG);
198         this.setupConfigProperty("/modules/google-sitemap/apps/siteMaps/subApps/browser/workbench/contentViews/list/columns/name", "formatterClass", "info.magnolia.module.googlesitemap.app.subapp.sitemapdetail.formatter.FolderNameColumnFormatter");
199         Node addSiteMapAction = NodeUtil.createPath(session.getRootNode(), GoogleSiteMapVersionHandler.GOOGLESITEMAP_APP_BROWSER_ACTIONS + "addSiteMap", NodeTypes.ContentNode.NAME);
200         Node deleteAction = NodeUtil.createPath(session.getRootNode(), GoogleSiteMapVersionHandler.GOOGLESITEMAP_APP_BROWSER_ACTIONS + "delete", NodeTypes.ContentNode.NAME);
201         Node editSiteMapAction = NodeUtil.createPath(session.getRootNode(), GoogleSiteMapVersionHandler.GOOGLESITEMAP_APP_BROWSER_ACTIONS + "editSiteMap", NodeTypes.ContentNode.NAME);
202         Node activateAction = NodeUtil.createPath(session.getRootNode(), GoogleSiteMapVersionHandler.GOOGLESITEMAP_APP_BROWSER_ACTIONS + "activate", NodeTypes.ContentNode.NAME);
203         Node deactivateAction = NodeUtil.createPath(session.getRootNode(), GoogleSiteMapVersionHandler.GOOGLESITEMAP_APP_BROWSER_ACTIONS + "deactivate", NodeTypes.ContentNode.NAME);
204         Node activateDeletedAction = NodeUtil.createPath(session.getRootNode(), GoogleSiteMapVersionHandler.GOOGLESITEMAP_APP_BROWSER_ACTIONS + "activateDeleted", NodeTypes.ContentNode.NAME);
205 
206         // WHEN
207         executeUpdatesAsIfTheCurrentlyInstalledVersionWas(Version.parseVersion("2.1"));
208 
209         // THEN
210         assertThat(addSiteMapAction, hasNode("availability"));
211         assertThat(addSiteMapAction.getNode("availability"), hasProperty("writePermissionRequired", true));
212         assertThat(deleteAction, hasNode("availability"));
213         assertThat(deleteAction.getNode("availability"), hasProperty("writePermissionRequired", true));
214         assertThat(editSiteMapAction, hasNode("availability"));
215         assertThat(editSiteMapAction.getNode("availability"), hasProperty("writePermissionRequired", true));
216         assertThat(activateAction, hasNode("availability"));
217         assertThat(activateAction.getNode("availability"), hasProperty("writePermissionRequired", true));
218         assertThat(deactivateAction, hasNode("availability"));
219         assertThat(deactivateAction.getNode("availability"), hasProperty("writePermissionRequired", true));
220         assertThat(activateDeletedAction, hasNode("availability"));
221         assertThat(activateDeletedAction.getNode("availability"), hasProperty("writePermissionRequired", true));
222     }
223 
224     @Test
225     public void updateFrom222NewCatalogProperty() throws RepositoryException, ModuleManagementException {
226         // GIVEN
227 
228         // WHEN
229         executeUpdatesAsIfTheCurrentlyInstalledVersionWas(Version.parseVersion("2.2.2"));
230 
231         // THEN
232         assertTrue(session.propertyExists("/modules/google-sitemap/apps/siteMaps/subApps/browser/actions/deactivate/catalog"));
233         assertEquals("website", session.getProperty("/modules/google-sitemap/apps/siteMaps/subApps/browser/actions/deactivate/catalog").getString());
234     }
235 
236     @Test
237     public void updateFrom232RemovesHiddenProperty() throws Exception {
238         // GIVEN
239         setupConfigProperty("/modules/google-sitemap/dialogs/components/content/siteComponentTab/form/tabs/siteMap/fields/template", "hidden", "true");
240 
241         // WHEN
242         executeUpdatesAsIfTheCurrentlyInstalledVersionWas(Version.parseVersion("2.3.2"));
243 
244         // THEN
245         assertThat(session.getNode("/modules/google-sitemap/dialogs/components/content/siteComponentTab/form/tabs/siteMap/fields/template"), not(hasProperty("hidden")));
246     }
247 
248     @Test
249     public void updateFrom232ChangesBrokenTemplateOnExistingSites() throws Exception {
250         // GIVEN
251         final Session siteMapSession = MgnlContext.getJCRSession(GoogleSiteMapConfiguration.WORKSPACE);
252         final Node siteMap = NodeUtil.createPath(siteMapSession.getRootNode(), "testSiteMap", SiteMapNodeTypes.SiteMap.NAME);
253         siteMap.setProperty(NodeTypes.Renderable.TEMPLATE, "GoogleSiteMap");
254 
255         Components.getComponent(VersionManager.class).addVersion(siteMap);
256 
257         // WHEN
258         assertThat("We want to make sure that the update task is not executed on jcr:system nodes (modifying a property would result in exception)", new Execution() {
259             @Override
260             public void evaluate() throws Exception {
261                 executeUpdatesAsIfTheCurrentlyInstalledVersionWas(Version.parseVersion("2.3.2"));
262             }
263         }, throwsNothing());
264 
265         // THEN
266         assertThat(siteMapSession.getNode("/testSiteMap"), hasProperty(NodeTypes.Renderable.TEMPLATE, "google-sitemap:pages/siteMapsConfiguration"));
267     }
268 
269     @Test
270     public void updateFrom233SetsDefaultType() throws Exception {
271         // GIVEN
272 
273         // WHEN
274         executeUpdatesAsIfTheCurrentlyInstalledVersionWas(Version.parseVersion("2.3.3"));
275 
276         // THEN
277         assertThat(session.getNode("/modules/google-sitemap/dialogs/components/content/siteComponentTab/form/tabs/siteMap/fields/mgnl-googleSiteMapType/options/standard"), hasProperty("selected", "true"));
278     }
279 
280     @Test
281     public void updateFrom233AddsRendererAndUsage() throws Exception {
282         // GIVEN
283         setupConfigProperty("/modules/google-sitemap/templates/pages/siteMapsConfiguration", "renderType", "freemarker");
284 
285         // WHEN
286         executeUpdatesAsIfTheCurrentlyInstalledVersionWas(Version.parseVersion("2.3.3"));
287 
288         // THEN
289         assertThat(session.getNode("/modules/google-sitemap/renderers/sitemap"), hasProperty("contentType", "application/xml"));
290         assertThat(session.getNode("/modules/google-sitemap/templates/pages/siteMapsConfiguration"), hasProperty("renderType", "sitemap"));
291     }
292 
293     @Test
294     public void updateFrom24RemovesInvalidProperties() throws Exception {
295         // GIVEN
296         Node exportAction = session.getNode("/modules/google-sitemap/apps/siteMaps/subApps/browser/actions/export");
297         Node editSiteMapAction = session.getNode("/modules/google-sitemap/apps/siteMaps/subApps/browser/actions/editSiteMap");
298         Node siteMapPagesField = NodeUtil.createPath(session.getRootNode(), "modules/google-sitemap/dialogs/components/content/siteComponentTab/form/tabs/tabSites/fields/mgnl:googleSiteMapPages", NodeTypes.ContentNode.NAME);
299         exportAction.setProperty("extends", "");
300         editSiteMapAction.setProperty("nodeType", "");
301         siteMapPagesField.setProperty("chooseOnClick", "");
302 
303         // WHEN
304         executeUpdatesAsIfTheCurrentlyInstalledVersionWas(Version.parseVersion("2.4"));
305         siteMapPagesField = session.getNode("/modules/google-sitemap/dialogs/components/content/siteComponentTab/form/tabs/tabSites/fields/mgnl-googleSiteMapPages");
306 
307         // THEN
308         assertThat(exportAction, not(hasProperty("export")));
309         assertThat(exportAction, hasProperty("icon"));
310         assertThat(editSiteMapAction, not(hasProperty("nodeType")));
311         assertThat(siteMapPagesField, not(hasProperty("chooseOnClick")));
312         assertThat(siteMapPagesField, hasProperty("name", "mgnl:googleSiteMapPages"));
313     }
314 
315     @Test
316     public void updateFrom24UpdatesURI2RepoMapping() throws Exception {
317         // GIVEN
318         setupConfigProperty("/server/URI2RepositoryMapping/mappings/sitemaps", "URIPrefix", "/sitemaps");
319         // WHEN
320         InstallContext ctx = executeUpdatesAsIfTheCurrentlyInstalledVersionWas(Version.parseVersion("2.4"));
321         // THEN
322         Node uriNode = ctx.getJCRSession(RepositoryConstants.CONFIG).getNode("/server/URI2RepositoryMapping/mappings/sitemaps");
323         assertThat(uriNode, hasProperty("URIPrefix", "/sitemaps/"));
324 
325     }
326 
327     @Test
328     public void updateFrom242AddEditIcon() throws Exception {
329         // GIVEN
330         setupConfigNode("/modules/google-sitemap/apps/siteMaps/subApps/pages");
331         setupConfigNode("/modules/google-sitemap/apps/siteMaps/subApps/virtualURI");
332 
333         // WHEN
334         executeUpdatesAsIfTheCurrentlyInstalledVersionWas(Version.parseVersion("2.4.2"));
335 
336         // THEN
337         assertThat(session.getNode("/modules/google-sitemap/apps/siteMaps/subApps/pages"), hasProperty("icon", "icon-edit"));
338         assertThat(session.getNode("/modules/google-sitemap/apps/siteMaps/subApps/virtualURI"), hasProperty("icon", "icon-edit"));
339     }
340 
341     @Test
342     public void updateFrom242ChangeVirtualUriMappings() throws Exception {
343         // GIVEN
344         String path = "/modules/google-sitemap/virtualURIMapping/siteMaps";
345         setupConfigNode(path);
346         setupConfigProperty(path, "class", "info.magnolia.module.googlesitemap.config.SiteMapVirtualUriMapping");
347         setupConfigProperty(path, "prefix", "redirect:/sitemaps");
348 
349         // WHEN
350         executeUpdatesAsIfTheCurrentlyInstalledVersionWas(Version.parseVersion("2.4.2"));
351 
352         // THEN
353         String newPath = "/modules/google-sitemap/virtualUriMappings/siteMaps";
354         assertThat(session.getNode(newPath), hasProperty("class", "info.magnolia.module.googlesitemap.config.mapping.SiteMapVirtualUriMapping"));
355         assertThat(session.getNode(newPath), hasProperty("prefix", "redirect:/sitemaps"));
356     }
357 
358     @Test
359     public void freshInstallToWithNewVirtualUriMappings() throws Exception {
360         // WHEN
361         executeUpdatesAsIfTheCurrentlyInstalledVersionWas(null);
362 
363         // THEN
364         String newPath = "/modules/google-sitemap/virtualUriMappings/siteMaps";
365         assertThat(session.getNode(newPath), hasProperty("class", "info.magnolia.module.googlesitemap.config.mapping.SiteMapVirtualUriMapping"));
366         assertThat(session.getNode(newPath), hasProperty("prefix", "redirect:/sitemaps"));
367     }
368 
369 }