1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.test.ui.extension

File ExtensionTest.java

 

Code metrics

0
524
16
1
994
704
16
0.03
32.75
16
1

Classes

Class Line # Actions
ExtensionTest 76 524 0% 16 0
1.0100%
 

Contributing tests

This file is covered by 15 tests. .

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package org.xwiki.test.ui.extension;
21   
22    import java.text.SimpleDateFormat;
23    import java.util.ArrayList;
24    import java.util.Arrays;
25    import java.util.Collections;
26    import java.util.Date;
27    import java.util.HashMap;
28    import java.util.List;
29    import java.util.Map;
30   
31    import org.apache.commons.lang.math.RandomUtils;
32    import org.junit.Test;
33    import org.openqa.selenium.WebElement;
34    import org.openqa.selenium.support.ui.Select;
35    import org.xwiki.extension.DefaultExtensionAuthor;
36    import org.xwiki.extension.DefaultExtensionDependency;
37    import org.xwiki.extension.DefaultExtensionIssueManagement;
38    import org.xwiki.extension.DefaultExtensionScm;
39    import org.xwiki.extension.DefaultExtensionScmConnection;
40    import org.xwiki.extension.ExtensionId;
41    import org.xwiki.extension.ExtensionLicense;
42    import org.xwiki.extension.repository.xwiki.model.jaxb.ExtensionsSearchResult;
43    import org.xwiki.extension.test.po.AdvancedSearchPane;
44    import org.xwiki.extension.test.po.DependencyPane;
45    import org.xwiki.extension.test.po.ExtensionAdministrationPage;
46    import org.xwiki.extension.test.po.ExtensionDependenciesPane;
47    import org.xwiki.extension.test.po.ExtensionDescriptionPane;
48    import org.xwiki.extension.test.po.ExtensionPane;
49    import org.xwiki.extension.test.po.ExtensionProgressPane;
50    import org.xwiki.extension.test.po.LogItemPane;
51    import org.xwiki.extension.test.po.MergeConflictPane;
52    import org.xwiki.extension.test.po.PaginationFilterPane;
53    import org.xwiki.extension.test.po.ProgressBarPane;
54    import org.xwiki.extension.test.po.SearchResultsPane;
55    import org.xwiki.extension.test.po.SimpleSearchPane;
56    import org.xwiki.extension.test.po.UnusedPagesPane;
57    import org.xwiki.extension.version.internal.DefaultVersionConstraint;
58    import org.xwiki.repository.test.TestExtension;
59    import org.xwiki.test.ui.AbstractExtensionAdminAuthenticatedTest;
60    import org.xwiki.test.ui.po.ChangesPane;
61    import org.xwiki.test.ui.po.ViewPage;
62    import org.xwiki.test.ui.po.diff.EntityDiff;
63   
64    import static org.junit.Assert.assertEquals;
65    import static org.junit.Assert.assertFalse;
66    import static org.junit.Assert.assertNotNull;
67    import static org.junit.Assert.assertNull;
68    import static org.junit.Assert.assertTrue;
69   
70    /**
71    * Functional tests for the Extension Manager user interface.
72    *
73    * @version $Id: 1a60d8075cbc32471d21d4afe25503ff594022cb $
74    * @since 4.2M1
75    */
 
76    public class ExtensionTest extends AbstractExtensionAdminAuthenticatedTest
77    {
 
78  15 toggle @Override
79    public void setUp() throws Exception
80    {
81  15 super.setUp();
82   
83    // Make sure the extensions we are playing with are not already installed.
84  15 getExtensionTestUtils().finishCurrentJob();
85  15 getExtensionTestUtils().uninstall("alice-xar-extension");
86  15 getExtensionTestUtils().uninstall("bob-xar-extension");
87  15 getExtensionTestUtils().uninstall("scriptServiceJarExtension");
88   
89    // Delete the pages that are provided by the XAR extensions we use in tests.
90  15 getUtil().rest().deletePage("ExtensionTest", "Alice");
91  15 assertFalse(getUtil().pageExists("ExtensionTest", "Alice"));
92  15 getUtil().rest().deletePage("ExtensionTest", "Bob");
93  15 assertFalse(getUtil().pageExists("ExtensionTest", "Bob"));
94   
95    // Delete from the repository the XAR extensions we use in tests.
96    // The extension page name is either the extension name, if specified, or the extension id. Most of the tests
97    // don't set the extension name but some do and we end up with two extensions (two pages) with the same id.
98  15 getRepositoryTestUtils().deleteExtension("Alice Wiki Macro");
99  15 getRepositoryTestUtils().deleteExtension("Bob Wiki Macro");
100  15 getRepositoryTestUtils().deleteExtension("alice-xar-extension");
101  15 getRepositoryTestUtils().deleteExtension("bob-xar-extension");
102  15 getRepositoryTestUtils().deleteExtension("scriptServiceJarExtension");
103   
104  15 getRepositoryTestUtils().waitUntilReady();
105   
106    // Double check that the XWiki Extension Repository is empty.
107  15 ExtensionsSearchResult searchResult =
108    getUtil().rest().getResource("repository/search", Collections.singletonMap("number", new Object[] {1}));
109  15 assertEquals(0, searchResult.getTotalHits());
110    }
111   
112    /**
113    * The extension search results pagination.
114    */
 
115  1 toggle @Test
116    public void testPagination()
117    {
118  1 ExtensionAdministrationPage adminPage = ExtensionAdministrationPage.gotoPage().clickCoreExtensionsSection();
119   
120  1 SearchResultsPane searchResults = adminPage.getSearchResults();
121  1 assertNull(searchResults.getNoResultsMessage());
122  1 assertEquals(20, searchResults.getDisplayedResultsCount());
123   
124  1 PaginationFilterPane pagination = searchResults.getPagination();
125  1 assertEquals((pagination.getResultsCount() + 20 - 1) / 20, pagination.getPageCount());
126  1 assertEquals("1 - 20", pagination.getCurrentRange());
127  1 assertEquals(1, pagination.getCurrentPageIndex());
128  1 assertFalse(pagination.hasPreviousPage());
129  1 assertTrue(pagination.hasNextPage());
130  1 assertTrue(pagination.getPageCount() > 5);
131  1 assertTrue(pagination.getResultsCount() > 100);
132  1 String firstExtensionName = searchResults.getExtension(0).getName();
133   
134  1 pagination = pagination.gotoPage(4);
135  1 searchResults = new SearchResultsPane();
136  1 assertEquals(20, searchResults.getDisplayedResultsCount());
137  1 assertEquals("61 - 80", pagination.getCurrentRange());
138  1 assertEquals(4, pagination.getCurrentPageIndex());
139  1 assertTrue(pagination.hasNextPage());
140  1 String secondExtensionName = searchResults.getExtension(0).getName();
141  1 assertFalse(firstExtensionName.equals(secondExtensionName));
142   
143  1 pagination = pagination.previousPage();
144  1 searchResults = new SearchResultsPane();
145  1 assertEquals(20, searchResults.getDisplayedResultsCount());
146  1 assertEquals("41 - 60", pagination.getCurrentRange());
147  1 assertEquals(3, pagination.getCurrentPageIndex());
148  1 String thirdExtensionName = searchResults.getExtension(0).getName();
149  1 assertFalse(firstExtensionName.equals(thirdExtensionName));
150  1 assertFalse(secondExtensionName.equals(thirdExtensionName));
151   
152  1 pagination = pagination.nextPage();
153  1 searchResults = new SearchResultsPane();
154  1 assertEquals(20, searchResults.getDisplayedResultsCount());
155  1 assertEquals("61 - 80", pagination.getCurrentRange());
156  1 assertEquals(4, pagination.getCurrentPageIndex());
157  1 assertEquals(secondExtensionName, searchResults.getExtension(0).getName());
158   
159  1 pagination = pagination.gotoPage(pagination.getPageCount());
160  1 searchResults = new SearchResultsPane();
161  1 assertEquals(((pagination.getResultsCount() - 1) % 20) + 1, searchResults.getDisplayedResultsCount());
162  1 assertEquals(pagination.getPageCount(), pagination.getCurrentPageIndex());
163  1 assertFalse(pagination.hasNextPage());
164  1 assertTrue(pagination.hasPreviousPage());
165    }
166   
167    /**
168    * Tests the simple search form.
169    */
 
170  1 toggle @Test
171    public void testSimpleSearch()
172    {
173  1 ExtensionAdministrationPage adminPage = ExtensionAdministrationPage.gotoPage().clickCoreExtensionsSection();
174  1 int coreExtensionCount = adminPage.getSearchResults().getPagination().getResultsCount();
175  1 SimpleSearchPane searchBar = adminPage.getSearchBar();
176   
177    // Check if the tip is displayed.
178  1 assertEquals("search extension...", searchBar.getSearchInput().getAttribute("placeholder"));
179    // Check that the input is empty
180  1 assertEquals("", searchBar.getSearchInput().getAttribute("value"));
181   
182  1 SearchResultsPane searchResults = searchBar.search("XWiki Commons");
183  1 assertTrue(searchResults.getPagination().getResultsCount() < coreExtensionCount);
184   
185    // Make sure the search input is not cleared.
186  1 searchBar = new SimpleSearchPane();
187  1 assertEquals("XWiki Commons", searchBar.getSearchInput().getAttribute("value"));
188   
189  1 assertNull(searchResults.getNoResultsMessage());
190   
191    // Check that the result matches the search query.
192  1 ExtensionPane extension = searchResults.getExtension(RandomUtils.nextInt(20));
193  1 assertTrue(extension.getName().toLowerCase().contains("commons"));
194  1 assertEquals("core", extension.getStatus());
195   
196    // Test search query with no results.
197  1 searchResults = new SimpleSearchPane().search("blahblah");
198  1 assertEquals(0, searchResults.getDisplayedResultsCount());
199  1 assertNull(searchResults.getPagination());
200  1 assertEquals("There were no extensions found matching 'blahblah'. Try different keywords. "
201    + "Alternatively, if you know the identifier and the version of the extension you're "
202    + "looking for, you can use the Advanced Search form above.", searchResults.getNoResultsMessage());
203   
204    // Test a search query with only a few results (only one page).
205  1 searchResults = searchBar.search("restlet");
206  1 assertNull(searchResults.getNoResultsMessage());
207  1 assertNull(searchResults.getPagination());
208  1 assertTrue(searchResults.getDisplayedResultsCount() > 1);
209   
210  1 extension = searchResults.getExtension(0);
211  1 assertEquals("core", extension.getStatus());
212  1 assertTrue(extension.getName().toLowerCase().contains("restlet"));
213    }
214   
215    /**
216    * Tests the advanced search form.
217    */
 
218  1 toggle @Test
219    public void testAdvancedSearch()
220    {
221  1 ExtensionAdministrationPage adminPage = ExtensionAdministrationPage.gotoPage().clickCoreExtensionsSection();
222   
223  1 SearchResultsPane searchResults = adminPage.getSearchBar().search("restlet");
224  1 String version = searchResults.getExtension(0).getVersion();
225   
226  1 searchResults = new SimpleSearchPane().clickAdvancedSearch().search("org.restlet.jse:org.restlet", version);
227  1 assertEquals(1, searchResults.getDisplayedResultsCount());
228  1 assertNull(searchResults.getNoResultsMessage());
229  1 ExtensionPane extension = searchResults.getExtension(0);
230  1 assertEquals("core", extension.getStatus());
231  1 assertTrue(extension.getName().toLowerCase().contains("restlet"));
232  1 assertEquals(version, extension.getVersion());
233   
234  1 searchResults = new SimpleSearchPane().clickAdvancedSearch().search("foo", "bar");
235  1 assertEquals(0, searchResults.getDisplayedResultsCount());
236  1 assertNull(searchResults.getPagination());
237  1 assertEquals(
238    "We couldn't find any extension with id 'foo' and version 'bar'. "
239    + "Make sure you have the right extension repositories configured.",
240    searchResults.getNoResultsMessage());
241   
242    // Test cancel advanced search.
243  1 AdvancedSearchPane advancedSearchPane = new SimpleSearchPane().clickAdvancedSearch();
244  1 advancedSearchPane.getIdInput().sendKeys("id");
245  1 assertTrue(advancedSearchPane.getVersionInput().isDisplayed());
246  1 advancedSearchPane.getCancelButton().click();
247  1 assertFalse(advancedSearchPane.getVersionInput().isDisplayed());
248    }
249   
250    /**
251    * Tests how core extensions are displayed.
252    */
 
253  1 toggle @Test
254    public void testCoreExtensions()
255    {
256  1 ExtensionAdministrationPage adminPage = ExtensionAdministrationPage.gotoPage().clickCoreExtensionsSection();
257   
258    // Assert that the core extension repository is selected.
259  1 SimpleSearchPane searchBar = adminPage.getSearchBar();
260  1 assertEquals("Core extensions", searchBar.getRepositorySelect().getFirstSelectedOption().getText());
261   
262  1 ExtensionPane extension = adminPage.getSearchResults().getExtension(RandomUtils.nextInt(20));
263  1 assertEquals("core", extension.getStatus());
264  1 assertEquals("Provided", extension.getStatusMessage());
265  1 assertNull(extension.getInstallButton());
266  1 assertNull(extension.getUninstallButton());
267  1 assertNull(extension.getUpgradeButton());
268  1 assertNull(extension.getDowngradeButton());
269    // Just test that the button to show the extension details is present.
270  1 assertEquals("core", extension.showDetails().getStatus());
271    }
272   
273    /**
274    * Tests the extension repository selector (all, core, installed, local).
275    */
 
276  1 toggle @Test
277    public void testRepositorySelector() throws Exception
278    {
279    // Setup the extension.
280  1 ExtensionId extensionId = new ExtensionId("alice-xar-extension", "1.3");
281  1 TestExtension extension = getRepositoryTestUtils().getTestExtension(extensionId, "xar");
282  1 getRepositoryTestUtils().addExtension(extension);
283  1 getRepositoryTestUtils().waitUntilReady();
284   
285    // Check if the section links point to the right repository.
286  1 ExtensionAdministrationPage adminPage = ExtensionAdministrationPage.gotoPage().clickAddExtensionsSection();
287  1 Select repositorySelect = adminPage.getSearchBar().getRepositorySelect();
288  1 assertEquals("Recommended Extensions", repositorySelect.getFirstSelectedOption().getText());
289   
290  1 adminPage = adminPage.clickCoreExtensionsSection();
291  1 repositorySelect = adminPage.getSearchBar().getRepositorySelect();
292  1 assertEquals("Core extensions", repositorySelect.getFirstSelectedOption().getText());
293   
294  1 adminPage = adminPage.clickInstalledExtensionsSection();
295  1 repositorySelect = adminPage.getSearchBar().getRepositorySelect();
296  1 assertEquals("Installed extensions", repositorySelect.getFirstSelectedOption().getText());
297   
298    // Check that a remote extension appears only in the list of "All Remote Extensions".
299  1 SearchResultsPane searchResults = adminPage.getSearchBar().search("alice");
300  1 assertNull(searchResults.getExtension(extensionId));
301   
302  1 new SimpleSearchPane().getRepositorySelect().selectByVisibleText("All Remote Extensions");
303  1 adminPage = new ExtensionAdministrationPage();
304  1 adminPage.waitUntilPageIsLoaded();
305    // The value of the search input must be preserved when we switch the repository.
306  1 assertEquals("alice", adminPage.getSearchBar().getSearchInput().getAttribute("value"));
307  1 assertNotNull(adminPage.getSearchResults().getExtension(extensionId));
308  1 assertNull(new SimpleSearchPane().selectRepository("local").getExtension(extensionId));
309   
310    // Check that an installed extension appears also in "Installed Extensions" and "Local Extensions".
311  1 getExtensionTestUtils().install(extensionId);
312  1 adminPage = ExtensionAdministrationPage.gotoPage().clickInstalledExtensionsSection();
313  1 searchResults = adminPage.getSearchBar().search("alice");
314  1 assertNotNull(searchResults.getExtension(extensionId));
315  1 assertNotNull(new SimpleSearchPane().selectRepository("local").getExtension(extensionId));
316  1 assertNotNull(new SimpleSearchPane().selectRepository("").getExtension(extensionId));
317   
318    // Check local extension.
319  1 getExtensionTestUtils().uninstall(extensionId.getId(), true);
320  1 adminPage = ExtensionAdministrationPage.gotoPage().clickInstalledExtensionsSection();
321  1 searchResults = adminPage.getSearchBar().search("alice");
322  1 assertNull(searchResults.getExtension(extensionId));
323  1 assertNotNull(new SimpleSearchPane().selectRepository("local").getExtension(extensionId));
324  1 assertNotNull(new SimpleSearchPane().selectRepository("").getExtension(extensionId));
325    }
326   
327    /**
328    * Tests the extension details (license, web site).
329    */
 
330  1 toggle @Test
331    public void testShowDetails() throws Exception
332    {
333    // Setup the extension.
334  1 ExtensionId extensionId = new ExtensionId("alice-xar-extension", "1.3");
335  1 TestExtension extension = getRepositoryTestUtils().getTestExtension(extensionId, "xar");
336  1 extension.setName("Alice Wiki Macro");
337  1 extension.setSummary("A **useless** macro");
338  1 extension.addAuthor(new DefaultExtensionAuthor("Thomas", null));
339  1 extension.addAuthor(new DefaultExtensionAuthor("Marius", null));
340  1 extension.addFeature("alice-extension");
341  1 extension.addLicense(new ExtensionLicense("My own license", null));
342  1 extension.setWebsite("http://www.alice.com");
343  1 extension.setScm(new DefaultExtensionScm("https://github.com/xwiki-contrib/alice-xar-extension",
344    new DefaultExtensionScmConnection("git", "git://github.com/xwiki-contrib/alice-xar-extension.git"),
345    new DefaultExtensionScmConnection("git", "git:git@github.com:xwiki-contrib/alice-xar-extension.git")));
346  1 extension.setIssueManagement(new DefaultExtensionIssueManagement("jira", "http://jira.xwiki.org/browse/ALICE"));
347  1 getRepositoryTestUtils().addExtension(extension);
348   
349    // Search the extension and assert the displayed information.
350  1 ExtensionAdministrationPage adminPage = ExtensionAdministrationPage.gotoPage().clickAddExtensionsSection();
351  1 ExtensionPane extensionPane =
352    adminPage.getSearchBar().clickAdvancedSearch().search(extensionId).getExtension(0);
353  1 assertEquals("remote", extensionPane.getStatus());
354  1 assertNull(extensionPane.getStatusMessage());
355  1 assertEquals(extension.getName(), extensionPane.getName());
356  1 assertEquals(extensionId.getVersion().getValue(), extensionPane.getVersion());
357  1 List<WebElement> authors = extensionPane.getAuthors();
358  1 assertEquals(2, authors.size());
359  1 assertEquals("Thomas", authors.get(0).getText());
360  1 assertEquals("Marius", authors.get(1).getText());
361  1 assertEquals(extension.getSummary(), extensionPane.getSummary());
362   
363    // Check the extension details.
364  1 ExtensionDescriptionPane descriptionPane = extensionPane.openDescriptionSection();
365  1 assertEquals(extension.getLicenses().iterator().next().getName(), descriptionPane.getLicense());
366  1 assertEquals(extension.getId().getId(), descriptionPane.getId());
367  1 assertEquals(extension.getFeatures().iterator().next(), descriptionPane.getFeatures().get(0));
368  1 assertEquals(extension.getType(), descriptionPane.getType());
369   
370  1 WebElement webSiteLink = descriptionPane.getWebSite();
371  1 assertEquals(extension.getWebSite().substring("http://".length()), webSiteLink.getText());
372  1 assertEquals(extension.getWebSite() + '/', webSiteLink.getAttribute("href"));
373   
374    // Install the extension to check the details that are specific to installed extensions.
375  1 Date beforeInstall = new Date();
376  1 descriptionPane = extensionPane.install().confirm().openDescriptionSection();
377  1 Date afterInstall = new Date();
378   
379  1 List<String> namespaces = descriptionPane.getNamespaces();
380  1 assertEquals(1, namespaces.size());
381  1 String prefix = "Home, by superadmin on ";
382  1 assertTrue(namespaces.get(0).startsWith(prefix));
383  1 Date installDate = new SimpleDateFormat("yyyy/MM/dd HH:mm").parse(namespaces.get(0).substring(prefix.length()));
384    // Ignore the seconds as they are not displayed.
385  1 assertTrue(String.format("Install date [%s] should be after [%s].", installDate, beforeInstall),
386    installDate.getTime() / 60000 >= beforeInstall.getTime() / 60000);
387  1 assertTrue(String.format("Install date [%s] should be before [%s].", installDate, afterInstall),
388    installDate.before(afterInstall));
389    }
390   
391    /**
392    * Tests how extension dependencies are displayed (both direct and backward dependencies).
393    */
 
394  1 toggle @Test
395    public void testDependencies() throws Exception
396    {
397    // Setup the extension and its dependencies.
398  1 ExtensionId dependencyId = new ExtensionId("bob-xar-extension", "2.5-milestone-2");
399  1 TestExtension dependency = getRepositoryTestUtils().getTestExtension(dependencyId, "xar");
400  1 dependency.setName("Bob Wiki Macro");
401  1 dependency.setSummary("Required by Alice");
402  1 getRepositoryTestUtils().addExtension(dependency);
403   
404  1 ExtensionId extensionId = new ExtensionId("alice-xar-extension", "1.3");
405  1 TestExtension extension = getRepositoryTestUtils().getTestExtension(extensionId, "xar");
406  1 extension.addDependency(new DefaultExtensionDependency(dependencyId.getId(),
407    new DefaultVersionConstraint(dependencyId.getVersion().getValue())));
408  1 extension
409    .addDependency(new DefaultExtensionDependency("missing-dependency", new DefaultVersionConstraint("135")));
410  1 extension.addDependency(new DefaultExtensionDependency("org.xwiki.platform:xwiki-platform-sheet-api",
411    new DefaultVersionConstraint("[3.2,)")));
412  1 extension.addDependency(new DefaultExtensionDependency("org.xwiki.commons:xwiki-commons-diff-api",
413    new DefaultVersionConstraint("2.7")));
414  1 extension.addDependency(new DefaultExtensionDependency("org.xwiki.platform:xwiki-platform-display-api",
415    new DefaultVersionConstraint("100.1")));
416  1 getRepositoryTestUtils().addExtension(extension);
417   
418    // Search the extension and assert the list of dependencies.
419  1 ExtensionAdministrationPage adminPage = ExtensionAdministrationPage.gotoPage().clickAddExtensionsSection();
420  1 ExtensionPane extensionPane =
421    adminPage.getSearchBar().clickAdvancedSearch().search(extensionId).getExtension(0);
422  1 ExtensionDependenciesPane dependenciesPane = extensionPane.openDependenciesSection();
423   
424  1 List<DependencyPane> directDependencies = dependenciesPane.getDirectDependencies();
425  1 assertEquals(5, directDependencies.size());
426   
427  1 assertEquals(dependency.getName(), directDependencies.get(0).getName());
428  1 assertEquals(dependencyId.getVersion().getValue(), directDependencies.get(0).getVersion());
429  1 assertEquals("remote", directDependencies.get(0).getStatus());
430  1 assertNull(directDependencies.get(0).getStatusMessage());
431   
432  1 assertNull(directDependencies.get(1).getLink());
433  1 assertEquals("missing-dependency", directDependencies.get(1).getName());
434  1 assertEquals("135", directDependencies.get(1).getVersion());
435  1 assertEquals("unknown", directDependencies.get(1).getStatus());
436  1 assertNull(directDependencies.get(1).getStatusMessage());
437   
438  1 assertNotNull(directDependencies.get(2).getLink());
439  1 assertEquals("XWiki Platform - Sheet - API", directDependencies.get(2).getName());
440  1 assertEquals("[3.2,)", directDependencies.get(2).getVersion());
441  1 assertEquals("core", directDependencies.get(2).getStatus());
442  1 assertEquals("Provided", directDependencies.get(2).getStatusMessage());
443   
444  1 assertNotNull(directDependencies.get(3).getLink());
445  1 assertEquals("XWiki Commons - Diff API", directDependencies.get(3).getName());
446  1 assertEquals("2.7", directDependencies.get(3).getVersion());
447  1 assertEquals("remote-core", directDependencies.get(3).getStatus());
448  1 assertTrue(directDependencies.get(3).getStatusMessage().matches("Version [^\\s]+ is provided"));
449   
450  1 assertEquals("XWiki Platform - Display API", directDependencies.get(4).getName());
451  1 assertEquals("100.1", directDependencies.get(4).getVersion());
452  1 assertEquals("remote-core-incompatible", directDependencies.get(4).getStatus());
453  1 assertTrue(directDependencies.get(4).getStatusMessage().matches("Incompatible with provided version [^\\s]+"));
454   
455  1 assertTrue(dependenciesPane.getBackwardDependencies().isEmpty());
456   
457    // Follow the link to a dependency.
458  1 directDependencies.get(0).getLink().click();
459  1 adminPage = new ExtensionAdministrationPage();
460  1 extensionPane = adminPage.getSearchResults().getExtension(0);
461  1 assertEquals(dependency.getName(), extensionPane.getName());
462  1 assertEquals(dependencyId.getVersion().getValue(), extensionPane.getVersion());
463  1 assertEquals(dependency.getSummary(), extensionPane.getSummary());
464   
465    // Check that we are still in the administration.
466  1 adminPage.clickInstalledExtensionsSection();
467    }
468   
469    /**
470    * Tests how an extension is installed.
471    */
 
472  1 toggle @Test
473    public void testInstall() throws Exception
474    {
475    // Setup the extension and its dependencies.
476  1 ExtensionId extensionId = new ExtensionId("alice-xar-extension", "1.3");
477  1 TestExtension extension = getRepositoryTestUtils().getTestExtension(extensionId, "xar");
478   
479  1 ExtensionId dependencyId = new ExtensionId("bob-xar-extension", "2.5-milestone-2");
480  1 getRepositoryTestUtils().addExtension(getRepositoryTestUtils().getTestExtension(dependencyId, "xar"));
481  1 extension.addDependency(new DefaultExtensionDependency(dependencyId.getId(),
482    new DefaultVersionConstraint(dependencyId.getVersion().getValue())));
483   
484  1 extension.addDependency(new DefaultExtensionDependency("org.xwiki.platform:xwiki-platform-sheet-api",
485    new DefaultVersionConstraint("[3.2,)")));
486  1 getRepositoryTestUtils().addExtension(extension);
487   
488    // Search the extension and install it.
489  1 ExtensionAdministrationPage adminPage = ExtensionAdministrationPage.gotoPage().clickAddExtensionsSection();
490  1 ExtensionPane extensionPane =
491    adminPage.getSearchBar().clickAdvancedSearch().search(extensionId).getExtension(0);
492  1 extensionPane = extensionPane.install();
493   
494    // Assert the install plan.
495  1 List<DependencyPane> installPlan = extensionPane.openProgressSection().getJobPlan();
496  1 assertEquals(2, installPlan.size());
497  1 assertEquals(dependencyId, installPlan.get(0).getId());
498  1 assertEquals(extensionId, installPlan.get(1).getId());
499   
500    // Finish the install and assert the install log.
501  1 List<LogItemPane> log = extensionPane.confirm().openProgressSection().getJobLog();
502  1 int logSize = log.size();
503  1 assertTrue(logSize > 1);
504  1 assertEquals("info", log.get(0).getLevel());
505  1 assertEquals(
506    "Starting job of type [install] with identifier " + "[extension/action/alice-xar-extension/wiki:xwiki]",
507    log.get(0).getMessage());
508  1 assertEquals("info", log.get(logSize - 1).getLevel());
509  1 assertEquals(
510    "Finished job of type [install] with identifier " + "[extension/action/alice-xar-extension/wiki:xwiki]",
511    log.get(logSize - 1).getMessage());
512   
513    // Test that both extensions are usable.
514  1 ViewPage viewPage = getUtil().createPage(getTestClassName(), getTestMethodName(), "{{alice/}}\n\n{{bob/}}", "");
515  1 String content = viewPage.getContent();
516  1 assertTrue(content.contains("Alice says hello!"));
517  1 assertTrue(content.contains("Bob says hi!"));
518   
519    // Check the list of installed extensions.
520  1 adminPage = ExtensionAdministrationPage.gotoPage().clickInstalledExtensionsSection();
521   
522  1 SearchResultsPane searchResults = adminPage.getSearchBar().search("bob");
523  1 assertEquals(1, searchResults.getDisplayedResultsCount());
524  1 extensionPane = searchResults.getExtension(0);
525  1 assertEquals("installed-dependency", extensionPane.getStatus());
526  1 assertEquals("Installed as dependency", extensionPane.getStatusMessage());
527  1 assertEquals(dependencyId, extensionPane.getId());
528  1 assertNotNull(extensionPane.getUninstallButton());
529   
530  1 searchResults = new SimpleSearchPane().search("alice");
531  1 assertEquals(1, searchResults.getDisplayedResultsCount());
532  1 extensionPane = searchResults.getExtension(0);
533  1 assertEquals("installed", extensionPane.getStatus());
534  1 assertEquals("Installed", extensionPane.getStatusMessage());
535  1 assertEquals(extensionId, extensionPane.getId());
536  1 assertNotNull(extensionPane.getUninstallButton());
537   
538    // Check if the progress log is persisted.
539  1 extensionPane = extensionPane.showDetails();
540  1 log = extensionPane.openProgressSection().getJobLog();
541  1 assertEquals(logSize, log.size());
542  1 assertEquals("info", log.get(0).getLevel());
543  1 assertEquals(
544    "Starting job of type [install] with identifier " + "[extension/action/alice-xar-extension/wiki:xwiki]",
545    log.get(0).getMessage());
546  1 assertEquals("info", log.get(logSize - 1).getLevel());
547  1 assertEquals(
548    "Finished job of type [install] with identifier " + "[extension/action/alice-xar-extension/wiki:xwiki]",
549    log.get(logSize - 1).getMessage());
550   
551    // Check if the dependency is properly listed as installed.
552  1 List<DependencyPane> dependencies = extensionPane.openDependenciesSection().getDirectDependencies();
553  1 assertEquals(2, dependencies.size());
554  1 assertEquals(dependencyId, dependencies.get(0).getId());
555  1 assertEquals("installed-dependency", dependencies.get(0).getStatus());
556  1 assertEquals("Installed as dependency", dependencies.get(0).getStatusMessage());
557   
558    // Check the backward dependency.
559  1 dependencies.get(0).getLink().click();
560  1 extensionPane = new ExtensionAdministrationPage().getSearchResults().getExtension(0);
561  1 dependencies = extensionPane.openDependenciesSection().getBackwardDependencies();
562  1 assertEquals(1, dependencies.size());
563  1 assertEquals(extensionId, dependencies.get(0).getId());
564  1 assertEquals("installed", dependencies.get(0).getStatus());
565  1 assertEquals("Installed", dependencies.get(0).getStatusMessage());
566    }
567   
568    /**
569    * Tests how an extension is uninstalled.
570    */
 
571  1 toggle @Test
572    public void testUninstall() throws Exception
573    {
574    // Setup the extension and its dependencies.
575  1 ExtensionId dependencyId = new ExtensionId("bob-xar-extension", "2.5-milestone-2");
576  1 getRepositoryTestUtils().addExtension(getRepositoryTestUtils().getTestExtension(dependencyId, "xar"));
577   
578  1 ExtensionId extensionId = new ExtensionId("alice-xar-extension", "1.3");
579  1 TestExtension extension = getRepositoryTestUtils().getTestExtension(extensionId, "xar");
580  1 extension.addDependency(new DefaultExtensionDependency(dependencyId.getId(),
581    new DefaultVersionConstraint(dependencyId.getVersion().getValue())));
582  1 getRepositoryTestUtils().addExtension(extension);
583   
584    // Install the extensions.
585  1 getExtensionTestUtils().install(extensionId);
586   
587    // Check if the installed pages are present.
588  1 assertTrue(getUtil().pageExists("ExtensionTest", "Alice"));
589  1 assertTrue(getUtil().pageExists("ExtensionTest", "Bob"));
590   
591    // Uninstall the dependency.
592  1 ExtensionAdministrationPage adminPage =
593    ExtensionAdministrationPage.gotoPage().clickInstalledExtensionsSection();
594  1 ExtensionPane extensionPane =
595    adminPage.getSearchBar().clickAdvancedSearch().search(dependencyId).getExtension(0);
596  1 extensionPane = extensionPane.uninstall();
597   
598    // Check the uninstall plan. Both extensions should be included.
599  1 List<DependencyPane> uninstallPlan = extensionPane.openProgressSection().getJobPlan();
600  1 assertEquals(2, uninstallPlan.size());
601   
602  1 assertEquals(extensionId, uninstallPlan.get(0).getId());
603  1 assertEquals("installed", uninstallPlan.get(0).getStatus());
604  1 assertEquals("Installed", uninstallPlan.get(0).getStatusMessage());
605   
606  1 assertEquals(dependencyId, uninstallPlan.get(1).getId());
607  1 assertEquals("installed-dependency", uninstallPlan.get(1).getStatus());
608  1 assertEquals("Installed as dependency", uninstallPlan.get(1).getStatusMessage());
609   
610    // Check the confirmation to delete the unused wiki pages.
611  1 extensionPane = extensionPane.confirm();
612  1 UnusedPagesPane unusedPages = extensionPane.openProgressSection().getUnusedPages();
613  1 assertTrue(unusedPages.contains("ExtensionTest", "Alice"));
614  1 assertTrue(unusedPages.contains("ExtensionTest", "Bob"));
615   
616    // Finish the uninstall and check the log.
617  1 extensionPane = extensionPane.confirm();
618  1 List<LogItemPane> log = extensionPane.openProgressSection().getJobLog();
619  1 assertTrue(log.size() > 2);
620  1 assertEquals("info", log.get(2).getLevel());
621  1 assertEquals("Resolving extension [bob-xar-extension 2.5-milestone-2] from namespace [Home]",
622    log.get(2).getMessage());
623  1 assertEquals("info", log.get(log.size() - 1).getLevel());
624  1 assertEquals(
625    "Finished job of type [uninstall] with identifier " + "[extension/action/bob-xar-extension/wiki:xwiki]",
626    log.get(log.size() - 1).getMessage());
627   
628    // Check if the uninstalled pages have been deleted.
629  1 assertFalse(getUtil().pageExists("ExtensionTest", "Alice"));
630  1 assertFalse(getUtil().pageExists("ExtensionTest", "Bob"));
631   
632    // Install both extension again and uninstall only the one with the dependency.
633  1 getExtensionTestUtils().install(extensionId);
634   
635  1 adminPage = ExtensionAdministrationPage.gotoPage().clickInstalledExtensionsSection();
636  1 extensionPane = adminPage.getSearchBar().clickAdvancedSearch().search(extensionId).getExtension(0);
637  1 extensionPane = extensionPane.uninstall();
638   
639    // Check the uninstall plan. Only one extension should be included.
640  1 uninstallPlan = extensionPane.openProgressSection().getJobPlan();
641  1 assertEquals(1, uninstallPlan.size());
642  1 assertEquals(extensionId, uninstallPlan.get(0).getId());
643   
644    // Check the confirmation to delete the unused wiki pages.
645  1 extensionPane = extensionPane.confirm();
646  1 unusedPages = extensionPane.openProgressSection().getUnusedPages();
647  1 assertTrue(unusedPages.contains("ExtensionTest", "Alice"));
648  1 assertFalse(unusedPages.contains("ExtensionTest", "Bob"));
649   
650    // Finish the uninstall and check the log.
651  1 log = extensionPane.confirm().openProgressSection().getJobLog();
652  1 assertTrue(log.size() > 2);
653  1 assertEquals("info", log.get(2).getLevel());
654  1 assertEquals("Resolving extension [alice-xar-extension 1.3] from namespace [Home]", log.get(2).getMessage());
655  1 assertEquals("info", log.get(log.size() - 1).getLevel());
656  1 assertEquals(
657    "Finished job of type [uninstall] with identifier " + "[extension/action/alice-xar-extension/wiki:xwiki]",
658    log.get(log.size() - 1).getMessage());
659   
660    // Check if the uninstalled pages have been deleted.
661  1 assertFalse(getUtil().pageExists("ExtensionTest", "Alice"));
662  1 assertTrue(getUtil().pageExists("ExtensionTest", "Bob"));
663   
664    // Check the list of installed extensions. It should contain only the second extension.
665  1 adminPage = ExtensionAdministrationPage.gotoPage().clickInstalledExtensionsSection();
666  1 SearchResultsPane searchResults = adminPage.getSearchBar().search("alice");
667  1 assertEquals(0, searchResults.getDisplayedResultsCount());
668  1 assertNotNull(searchResults.getNoResultsMessage());
669   
670  1 searchResults = new SimpleSearchPane().search("bob");
671  1 assertEquals(1, searchResults.getDisplayedResultsCount());
672  1 extensionPane = searchResults.getExtension(0);
673  1 assertEquals("installed-dependency", extensionPane.getStatus());
674  1 assertEquals(dependencyId, extensionPane.getId());
675    }
676   
677    /**
678    * Tests that an extension can be installed and uninstalled without reloading the extension manager UI.
679    */
 
680  1 toggle @Test
681    public void testInstallAndUninstallWithoutReload() throws Exception
682    {
683    // Setup the extension.
684  1 ExtensionId extensionId = new ExtensionId("alice-xar-extension", "1.3");
685  1 getRepositoryTestUtils().addExtension(getRepositoryTestUtils().getTestExtension(extensionId, "xar"));
686   
687    // Search the extension to install.
688  1 ExtensionAdministrationPage adminPage = ExtensionAdministrationPage.gotoPage().clickAddExtensionsSection();
689  1 ExtensionPane extensionPane =
690    adminPage.getSearchBar().clickAdvancedSearch().search(extensionId).getExtension(0);
691   
692    // Install and uninstall.
693  1 extensionPane = extensionPane.install().confirm().uninstall().confirm().confirm().install();
694  1 assertEquals("remote", extensionPane.getStatus());
695    }
696   
697    /**
698    * Tests how an extension is upgraded.
699    */
 
700  1 toggle @Test
701    public void testUpgrade() throws Exception
702    {
703    // Setup the extension.
704  1 String extensionId = "alice-xar-extension";
705  1 String oldVersion = "1.3";
706  1 String newVersion = "2.1.4";
707  1 TestExtension oldExtension =
708    getRepositoryTestUtils().getTestExtension(new ExtensionId(extensionId, oldVersion), "xar");
709  1 getRepositoryTestUtils().addExtension(oldExtension);
710  1 TestExtension newExtension =
711    getRepositoryTestUtils().getTestExtension(new ExtensionId(extensionId, newVersion), "xar");
712  1 getRepositoryTestUtils().attachFile(newExtension);
713  1 getRepositoryTestUtils().addVersionObject(newExtension, newVersion,
714    "attach:" + newExtension.getFile().getName());
715   
716    // Make sure the old version is installed.
717  1 getExtensionTestUtils().install(new ExtensionId(extensionId, oldVersion));
718   
719    // Upgrade the extension.
720  1 ExtensionAdministrationPage adminPage = ExtensionAdministrationPage.gotoPage().clickAddExtensionsSection();
721  1 ExtensionPane extensionPane =
722    adminPage.getSearchBar().clickAdvancedSearch().search(extensionId, newVersion).getExtension(0);
723  1 assertEquals("remote-installed", extensionPane.getStatus());
724  1 assertEquals("Version 1.3 is installed", extensionPane.getStatusMessage());
725  1 extensionPane = extensionPane.upgrade();
726   
727    // Check the upgrade plan.
728  1 List<DependencyPane> upgradePlan = extensionPane.openProgressSection().getJobPlan();
729  1 assertEquals(1, upgradePlan.size());
730  1 assertEquals(extensionId, upgradePlan.get(0).getName());
731  1 assertEquals(newVersion, upgradePlan.get(0).getVersion());
732  1 assertEquals("remote-installed", upgradePlan.get(0).getStatus());
733  1 assertEquals("Version 1.3 is installed", upgradePlan.get(0).getStatusMessage());
734   
735    // Finish the upgrade and check the upgrade log.
736  1 extensionPane = extensionPane.confirm();
737  1 assertEquals("installed", extensionPane.getStatus());
738  1 assertEquals("Installed", extensionPane.getStatusMessage());
739  1 List<LogItemPane> log = extensionPane.openProgressSection().getJobLog();
740  1 assertTrue(log.size() > 2);
741  1 assertEquals("info", log.get(2).getLevel());
742  1 assertEquals("Resolving extension [alice-xar-extension 2.1.4] on namespace [Home]", log.get(2).getMessage());
743  1 assertEquals("info", log.get(log.size() - 1).getLevel());
744  1 assertEquals(
745    "Finished job of type [install] with identifier " + "[extension/action/alice-xar-extension/wiki:xwiki]",
746    log.get(log.size() - 1).getMessage());
747   
748    // Assert the changes.
749  1 ViewPage viewPage = getUtil().gotoPage("ExtensionTest", "Alice");
750  1 assertEquals("Alice Wiki Macro (upgraded)", viewPage.getDocumentTitle());
751  1 assertTrue(viewPage.getContent().contains("Alice says hi guys!"));
752    }
753   
754    /**
755    * Tests how an extension is upgraded when there is a merge conflict.
756    */
 
757  1 toggle @Test
758    public void testUpgradeWithMergeConflict() throws Exception
759    {
760    // Setup the extension.
761  1 String extensionId = "alice-xar-extension";
762  1 String oldVersion = "1.3";
763  1 String newVersion = "2.1.4";
764  1 TestExtension oldExtension =
765    getRepositoryTestUtils().getTestExtension(new ExtensionId(extensionId, oldVersion), "xar");
766  1 getRepositoryTestUtils().addExtension(oldExtension);
767  1 TestExtension newExtension =
768    getRepositoryTestUtils().getTestExtension(new ExtensionId(extensionId, newVersion), "xar");
769  1 getRepositoryTestUtils().attachFile(newExtension);
770  1 getRepositoryTestUtils().addVersionObject(newExtension, newVersion,
771    "attach:" + newExtension.getFile().getName());
772   
773    // Make sure the old version is installed.
774  1 getExtensionTestUtils().install(new ExtensionId(extensionId, oldVersion));
775   
776    // Edit the installed version so that we have a merge conflict.
777  1 Map<String, String> queryParameters = new HashMap<String, String>();
778  1 queryParameters.put("title", "Alice Extension");
779  1 queryParameters.put("content",
780    "== Usage ==\n\n{{code language=\"none\"}}\n" + "{{alice/}}\n{{/code}}\n\n== Output ==\n\n{{alice/}}");
781  1 queryParameters.put("XWiki.WikiMacroClass_0_code", "{{info}}Alice says hello!{{/info}}");
782  1 getUtil().gotoPage("ExtensionTest", "Alice", "save", queryParameters);
783   
784    // Initiate the upgrade process.
785  1 ExtensionAdministrationPage adminPage = ExtensionAdministrationPage.gotoPage().clickAddExtensionsSection();
786  1 SearchResultsPane searchResults =
787    adminPage.getSearchBar().clickAdvancedSearch().search(extensionId, newVersion);
788  1 ExtensionPane extensionPane = searchResults.getExtension(0);
789  1 extensionPane = extensionPane.upgrade().confirm();
790   
791    // Check the merge conflict UI.
792  1 assertEquals("loading", extensionPane.getStatus());
793  1 assertNull(extensionPane.getStatusMessage());
794   
795  1 ProgressBarPane progressBar = extensionPane.getProgressBar();
796  1 assertEquals(66, progressBar.getPercent());
797  1 assertEquals("Conflict between [@@ -1,1 +1,1 @@] and [@@ -1,1 +1,1 @@]", progressBar.getMessage());
798   
799  1 ExtensionProgressPane progressPane = extensionPane.openProgressSection();
800  1 WebElement jobLogLabel = progressPane.getJobLogLabel();
801  1 assertEquals("INSTALL LOG".toLowerCase(), jobLogLabel.getText().toLowerCase());
802    // The job log is collapsed when the job is waiting for user input so we need to expand it before asserting its
803    // content (otherwise #getText() returns the empty string because the text is not visible).
804  1 jobLogLabel.click();
805  1 List<LogItemPane> upgradeLog = progressPane.getJobLog();
806  1 LogItemPane lastLogItem = upgradeLog.get(upgradeLog.size() - 1);
807  1 assertEquals("loading", lastLogItem.getLevel());
808  1 assertEquals(progressBar.getMessage(), lastLogItem.getMessage());
809   
810  1 MergeConflictPane mergeConflictPane = progressPane.getMergeConflict();
811  1 ChangesPane changesPane = mergeConflictPane.getChanges();
812  1 assertEquals(Arrays.asList("Page properties", "XWiki.WikiMacroClass[0]"), changesPane.getChangedEntities());
813   
814  1 EntityDiff pagePropertiesDiff = changesPane.getEntityDiff("Page properties");
815  1 assertEquals(Arrays.asList("Parent", "Content"), pagePropertiesDiff.getPropertyNames());
816  1 assertFalse(pagePropertiesDiff.getDiff("Content").isEmpty());
817   
818  1 EntityDiff macroDiff = changesPane.getEntityDiff("XWiki.WikiMacroClass[0]");
819  1 assertEquals(Arrays.asList("Macro description"), macroDiff.getPropertyNames());
820  1 assertEquals(
821    Arrays.asList("@@ -1,1 +1,1 @@", "-<del>Test</del> macro.", "+<ins>A</ins> <ins>cool </ins>macro."),
822    macroDiff.getDiff("Macro description"));
823   
824  1 mergeConflictPane.getFromVersionSelect().selectByVisibleText("Previous version");
825  1 mergeConflictPane.getToVersionSelect().selectByVisibleText("Current version");
826  1 mergeConflictPane = mergeConflictPane.clickShowChanges();
827   
828  1 changesPane = mergeConflictPane.getChanges();
829  1 List<String> expectedDiff = new ArrayList<>();
830  1 expectedDiff.add("@@ -1,9 +1,9 @@");
831  1 expectedDiff.add("-= Usage =");
832  1 expectedDiff.add("+=<ins>=</ins> Usage =<ins>=</ins>");
833  1 expectedDiff.add(" ");
834  1 expectedDiff.add("-{{code}}");
835  1 expectedDiff.add("+{{code<ins> language=\"none\"</ins>}}");
836  1 expectedDiff.add(" {{alice/}}");
837  1 expectedDiff.add(" {{/code}}");
838  1 expectedDiff.add(" ");
839  1 expectedDiff.add("-= <del>Res</del>u<del>l</del>t =");
840  1 expectedDiff.add("+=<ins>=</ins> <ins>O</ins>ut<ins>put</ins> =<ins>=</ins>");
841  1 expectedDiff.add(" ");
842  1 expectedDiff.add(" {{alice/}}");
843  1 assertEquals(expectedDiff, changesPane.getEntityDiff("Page properties").getDiff("Content"));
844  1 assertEquals(1, changesPane.getDiffSummary().toggleObjectsDetails().getModifiedObjects().size());
845  1 assertEquals(
846    Arrays.asList("@@ -1,1 +1,1 @@", "-Alice says hello!",
847    "+<ins>{{info}}</ins>Alice says hello!<ins>{{/info}}</ins>"),
848    changesPane.getEntityDiff("XWiki.WikiMacroClass[0]").getDiff("Macro code"));
849   
850    // Finish the merge.
851  1 mergeConflictPane.getVersionToKeepSelect().selectByValue("NEXT");
852    // FIXME: We get the extension pane from the search results because it is reloaded when we compare the versions.
853  1 extensionPane = searchResults.getExtension(0).confirm();
854   
855  1 assertEquals("installed", extensionPane.getStatus());
856  1 assertNull(extensionPane.getProgressBar());
857  1 upgradeLog = extensionPane.openProgressSection().getJobLog();
858  1 lastLogItem = upgradeLog.get(upgradeLog.size() - 1);
859  1 assertEquals("info", lastLogItem.getLevel());
860  1 assertEquals(
861    "Finished job of type [install] with identifier " + "[extension/action/alice-xar-extension/wiki:xwiki]",
862    lastLogItem.getMessage());
863   
864    // Check the merge result.
865  1 ViewPage mergedPage = getUtil().gotoPage("ExtensionTest", "Alice");
866  1 assertEquals("Alice Wiki Macro (upgraded)", mergedPage.getDocumentTitle());
867    }
868   
869    /**
870    * Tests how an extension is downgraded.
871    */
 
872  1 toggle @Test
873    public void testDowngrade() throws Exception
874    {
875    // Setup the extension.
876  1 String extensionId = "alice-xar-extension";
877  1 String oldVersion = "1.3";
878  1 String newVersion = "2.1.4";
879  1 TestExtension oldExtension =
880    getRepositoryTestUtils().getTestExtension(new ExtensionId(extensionId, oldVersion), "xar");
881  1 getRepositoryTestUtils().addExtension(oldExtension);
882  1 TestExtension newExtension =
883    getRepositoryTestUtils().getTestExtension(new ExtensionId(extensionId, newVersion), "xar");
884  1 getRepositoryTestUtils().attachFile(newExtension);
885  1 getRepositoryTestUtils().addVersionObject(newExtension, newVersion,
886    "attach:" + newExtension.getFile().getName());
887   
888    // Make sure the new version is installed.
889  1 getExtensionTestUtils().install(new ExtensionId(extensionId, newVersion));
890   
891    // Downgrade the extension.
892  1 ExtensionAdministrationPage adminPage = ExtensionAdministrationPage.gotoPage().clickAddExtensionsSection();
893  1 ExtensionPane extensionPane =
894    adminPage.getSearchBar().clickAdvancedSearch().search(extensionId, oldVersion).getExtension(0);
895  1 assertEquals("remote-installed", extensionPane.getStatus());
896  1 assertEquals("Version 2.1.4 is installed", extensionPane.getStatusMessage());
897  1 extensionPane = extensionPane.downgrade();
898   
899    // Check the downgrade plan.
900  1 List<DependencyPane> downgradePlan = extensionPane.openProgressSection().getJobPlan();
901  1 assertEquals(1, downgradePlan.size());
902  1 assertEquals(extensionId, downgradePlan.get(0).getName());
903  1 assertEquals(oldVersion, downgradePlan.get(0).getVersion());
904  1 assertEquals("remote-installed", downgradePlan.get(0).getStatus());
905  1 assertEquals("Version 2.1.4 is installed", downgradePlan.get(0).getStatusMessage());
906   
907    // Finish the downgrade and check the downgrade log.
908  1 extensionPane = extensionPane.confirm();
909  1 assertEquals("installed", extensionPane.getStatus());
910  1 assertEquals("Installed", extensionPane.getStatusMessage());
911  1 List<LogItemPane> log = extensionPane.openProgressSection().getJobLog();
912  1 assertTrue(log.size() > 2);
913  1 assertEquals("info", log.get(2).getLevel());
914  1 assertEquals("Resolving extension [alice-xar-extension 1.3] on namespace [Home]", log.get(2).getMessage());
915  1 assertEquals("info", log.get(log.size() - 1).getLevel());
916  1 assertEquals(
917    "Finished job of type [install] with identifier " + "[extension/action/alice-xar-extension/wiki:xwiki]",
918    log.get(log.size() - 1).getMessage());
919   
920    // Assert the changes.
921  1 ViewPage viewPage = getUtil().gotoPage("ExtensionTest", "Alice");
922  1 assertEquals("Alice Macro", viewPage.getDocumentTitle());
923  1 assertTrue(viewPage.getContent().contains("Alice says hello!"));
924    }
925   
926    /**
927    * Tests if a Java component script service is properly installed.
928    */
 
929  1 toggle @Test
930    public void testInstallScriptService() throws Exception
931    {
932    // Make sure the script service is not available before the extension is installed.
933  1 ViewPage viewPage = getUtil().createPage(getTestClassName(), getTestMethodName(),
934    "{{velocity}}$services.greeter.greet('world') "
935    + "$services.greeter.greet('XWiki', 'default'){{/velocity}}",
936    "");
937  1 assertFalse(viewPage.getContent().contains("Hello world! Hello XWiki!"));
938   
939    // Setup the extension.
940  1 ExtensionId extensionId = new ExtensionId("scriptServiceJarExtension", "4.2-milestone-1");
941  1 TestExtension extension = getRepositoryTestUtils().getTestExtension(extensionId, "jar");
942  1 getRepositoryTestUtils().addExtension(extension);
943   
944    // Search the extension and install it.
945  1 ExtensionAdministrationPage adminPage = ExtensionAdministrationPage.gotoPage().clickAddExtensionsSection();
946  1 ExtensionPane extensionPane =
947    adminPage.getSearchBar().clickAdvancedSearch().search(extensionId).getExtension(0);
948  1 extensionPane.install().confirm();
949   
950    // Check the result.
951  1 assertEquals("Hello world! Hello XWiki!",
952    getUtil().gotoPage(getTestClassName(), getTestMethodName()).getContent());
953    }
954   
955    /**
956    * Make sure recommended extension are properly filtered.
957    */
 
958  1 toggle @Test
959    public void testFilterRecommended() throws Exception
960    {
961    // Add recommended extension
962  1 ExtensionId recommendedExtensionId = new ExtensionId("alice-xar-extension", "1.3");
963  1 TestExtension recommendedExtension = getRepositoryTestUtils().getTestExtension(recommendedExtensionId, "xar");
964  1 recommendedExtension.setRecommended(true);
965  1 getRepositoryTestUtils().addExtension(recommendedExtension);
966   
967    // Add not recommended extension
968  1 ExtensionId notRecommendedExtensionId = new ExtensionId("bob-xar-extension", "2.5-milestone-2");
969  1 TestExtension notRecommendedExtension =
970    getRepositoryTestUtils().getTestExtension(notRecommendedExtensionId, "xar");
971  1 getRepositoryTestUtils().addExtension(notRecommendedExtension);
972   
973    // Make sure everything is ready
974  1 getRepositoryTestUtils().waitUntilReady();
975   
976  1 ExtensionAdministrationPage adminPage = ExtensionAdministrationPage.gotoPage().clickAddExtensionsSection();
977   
978    // Empty search
979  1 SearchResultsPane searchResults = adminPage.getSearchResults();
980  1 assertNotNull(searchResults.getExtension(recommendedExtensionId));
981  1 assertNull(searchResults.getExtension(notRecommendedExtensionId));
982   
983    // Search among recommended extensions
984  1 SimpleSearchPane searchBar = adminPage.getSearchBar();
985  1 searchResults = searchBar.search("alice-xar-extension");
986  1 assertNotNull(searchResults.getExtension(recommendedExtensionId));
987  1 assertNull(searchResults.getExtension(notRecommendedExtensionId));
988   
989    // Fallback on all extensions
990  1 searchResults = searchBar.search("bob-xar-extension");
991  1 assertNull(searchResults.getExtension(recommendedExtensionId));
992  1 assertNotNull(searchResults.getExtension(notRecommendedExtensionId));
993    }
994    }