001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.lar.test;
016    
017    import com.liferay.portal.LocaleException;
018    import com.liferay.portal.kernel.exception.PortalException;
019    import com.liferay.portal.kernel.portletdisplaytemplate.PortletDisplayTemplateManager;
020    import com.liferay.portal.kernel.template.TemplateHandler;
021    import com.liferay.portal.kernel.test.util.GroupTestUtil;
022    import com.liferay.portal.kernel.test.util.TestPropsValues;
023    import com.liferay.portal.kernel.util.GetterUtil;
024    import com.liferay.portal.kernel.util.LocaleUtil;
025    import com.liferay.portal.kernel.util.MapUtil;
026    import com.liferay.portal.kernel.util.StringPool;
027    import com.liferay.portal.kernel.util.Time;
028    import com.liferay.portal.kernel.util.Validator;
029    import com.liferay.portal.kernel.workflow.WorkflowConstants;
030    import com.liferay.portal.model.Group;
031    import com.liferay.portal.model.Portlet;
032    import com.liferay.portal.model.StagedModel;
033    import com.liferay.portal.model.User;
034    import com.liferay.portal.service.GroupLocalServiceUtil;
035    import com.liferay.portal.service.PortletLocalServiceUtil;
036    import com.liferay.portal.service.ServiceContext;
037    import com.liferay.portal.util.PortalUtil;
038    import com.liferay.portal.util.test.LayoutTestUtil;
039    import com.liferay.portlet.PortletPreferencesFactoryUtil;
040    import com.liferay.portlet.asset.model.AssetEntry;
041    import com.liferay.portlet.asset.model.AssetLink;
042    import com.liferay.portlet.asset.service.AssetEntryLocalServiceUtil;
043    import com.liferay.portlet.asset.service.AssetLinkLocalServiceUtil;
044    import com.liferay.portlet.dynamicdatamapping.DDMTemplate;
045    import com.liferay.portlet.dynamicdatamapping.util.test.DDMTemplateTestUtil;
046    import com.liferay.portlet.exportimport.configuration.ExportImportConfigurationConstants;
047    import com.liferay.portlet.exportimport.configuration.ExportImportConfigurationSettingsMapFactory;
048    import com.liferay.portlet.exportimport.lar.ExportImportClassedModelUtil;
049    import com.liferay.portlet.exportimport.lar.ExportImportDateUtil;
050    import com.liferay.portlet.exportimport.lar.ExportImportThreadLocal;
051    import com.liferay.portlet.exportimport.lar.PortletDataHandler;
052    import com.liferay.portlet.exportimport.lar.PortletDataHandlerKeys;
053    import com.liferay.portlet.exportimport.model.ExportImportConfiguration;
054    import com.liferay.portlet.exportimport.service.ExportImportConfigurationLocalServiceUtil;
055    import com.liferay.portlet.exportimport.service.ExportImportLocalServiceUtil;
056    
057    import java.io.Serializable;
058    
059    import java.util.Arrays;
060    import java.util.Collection;
061    import java.util.Date;
062    import java.util.HashMap;
063    import java.util.Iterator;
064    import java.util.LinkedHashMap;
065    import java.util.List;
066    import java.util.Locale;
067    import java.util.Map;
068    
069    import javax.portlet.PortletPreferences;
070    
071    import org.junit.Assert;
072    import org.junit.Test;
073    
074    /**
075     * @author Juan Fern??ndez
076     */
077    public abstract class BasePortletExportImportTestCase
078            extends BaseExportImportTestCase {
079    
080            public String getNamespace() {
081                    return null;
082            }
083    
084            public String getPortletId() throws Exception {
085                    return null;
086            }
087    
088            @Test
089            public void testExportImportAssetLinks() throws Exception {
090                    StagedModel stagedModel = addStagedModel(group.getGroupId());
091    
092                    StagedModel relatedStagedModel1 = addStagedModel(group.getGroupId());
093                    StagedModel relatedStagedModel2 = addStagedModel(group.getGroupId());
094    
095                    addAssetLink(stagedModel, relatedStagedModel1, 1);
096                    addAssetLink(stagedModel, relatedStagedModel2, 2);
097    
098                    exportImportPortlet(getPortletId());
099    
100                    StagedModel importedStagedModel = getStagedModel(
101                            getStagedModelUuid(stagedModel), importedGroup.getGroupId());
102    
103                    Assert.assertNotNull(importedStagedModel);
104    
105                    validateImportedLinks(stagedModel, importedStagedModel);
106            }
107    
108            @Test
109            public void testExportImportDeletions() throws Exception {
110                    StagedModel stagedModel = addStagedModel(group.getGroupId());
111    
112                    if (stagedModel == null) {
113                            return;
114                    }
115    
116                    String stagedModelUuid = getStagedModelUuid(stagedModel);
117    
118                    exportImportPortlet(getPortletId());
119    
120                    deleteStagedModel(stagedModel);
121    
122                    exportImportPortlet(getPortletId());
123    
124                    StagedModel importedStagedModel = getStagedModel(
125                            stagedModelUuid, importedGroup.getGroupId());
126    
127                    Assert.assertNotNull(importedStagedModel);
128    
129                    Map<String, String[]> exportParameterMap = new LinkedHashMap<>();
130    
131                    exportParameterMap.put(
132                            PortletDataHandlerKeys.DELETIONS,
133                            new String[] {String.valueOf(true)});
134    
135                    exportImportPortlet(
136                            getPortletId(), exportParameterMap, getImportParameterMap());
137    
138                    importedStagedModel = getStagedModel(
139                            stagedModelUuid, importedGroup.getGroupId());
140    
141                    Assert.assertNotNull(importedStagedModel);
142    
143                    Map<String, String[]> importParameterMap = new LinkedHashMap<>();
144    
145                    importParameterMap.put(
146                            PortletDataHandlerKeys.DELETIONS,
147                            new String[] {String.valueOf(true)});
148    
149                    exportImportPortlet(
150                            getPortletId(), exportParameterMap, importParameterMap);
151    
152                    try {
153                            importedStagedModel = getStagedModel(
154                                    stagedModelUuid, importedGroup.getGroupId());
155    
156                            Assert.assertNull(importedStagedModel);
157                    }
158                    catch (Exception e) {
159                    }
160            }
161    
162            @Test
163            public void testExportImportDisplayStyleFromCurrentGroup()
164                    throws Exception {
165    
166                    testExportImportDisplayStyle(group.getGroupId(), StringPool.BLANK);
167            }
168    
169            @Test
170            public void testExportImportDisplayStyleFromDifferentGroup()
171                    throws Exception {
172    
173                    Group group2 = GroupTestUtil.addGroup();
174    
175                    testExportImportDisplayStyle(group2.getGroupId(), StringPool.BLANK);
176            }
177    
178            @Test
179            public void testExportImportDisplayStyleFromGlobalScope() throws Exception {
180                    Group companyGroup = GroupLocalServiceUtil.getCompanyGroup(
181                            group.getCompanyId());
182    
183                    testExportImportDisplayStyle(companyGroup.getGroupId(), "company");
184            }
185    
186            @Test
187            public void testExportImportDisplayStyleFromLayoutScope() throws Exception {
188                    testExportImportDisplayStyle(group.getGroupId(), "layout");
189            }
190    
191            @Test
192            public void testExportImportInvalidAvailableLocales() throws Exception {
193                    testExportImportAvailableLocales(
194                            Arrays.asList(LocaleUtil.US, LocaleUtil.SPAIN),
195                            Arrays.asList(LocaleUtil.US, LocaleUtil.GERMANY), true);
196            }
197    
198            @Test
199            public void testExportImportValidAvailableLocales() throws Exception {
200                    testExportImportAvailableLocales(
201                            Arrays.asList(LocaleUtil.US, LocaleUtil.SPAIN),
202                            Arrays.asList(LocaleUtil.US, LocaleUtil.SPAIN, LocaleUtil.GERMANY),
203                            false);
204            }
205    
206            @Test
207            public void testUpdateLastPublishDate() throws Exception {
208                    Date lastPublishDate = new Date(System.currentTimeMillis() - Time.HOUR);
209    
210                    Date stagedModelCreationDate = new Date(
211                            lastPublishDate.getTime() + Time.MINUTE);
212    
213                    StagedModel stagedModel = addStagedModel(
214                            group.getGroupId(), stagedModelCreationDate);
215    
216                    if (stagedModel == null) {
217                            return;
218                    }
219    
220                    LayoutTestUtil.addPortletToLayout(
221                            TestPropsValues.getUserId(), layout, getPortletId(), "column-1",
222                            new HashMap<String, String[]>());
223    
224                    PortletPreferences portletPreferences =
225                            PortletPreferencesFactoryUtil.getStrictPortletSetup(
226                                    layout, getPortletId());
227    
228                    portletPreferences.setValue(
229                            "last-publish-date", String.valueOf(lastPublishDate.getTime()));
230    
231                    portletPreferences.store();
232    
233                    Map<String, String[]> exportParameterMap = new LinkedHashMap<>();
234    
235                    exportParameterMap.put(
236                            PortletDataHandlerKeys.UPDATE_LAST_PUBLISH_DATE,
237                            new String[] {String.valueOf(true)});
238                    exportParameterMap.put(
239                            "range",
240                            new String[] {ExportImportDateUtil.RANGE_FROM_LAST_PUBLISH_DATE});
241    
242                    Map<String, String[]> importParameterMap = new LinkedHashMap<>();
243    
244                    portletPreferences =
245                            PortletPreferencesFactoryUtil.getStrictPortletSetup(
246                                    layout, getPortletId());
247    
248                    Date oldLastPublishDate = ExportImportDateUtil.getLastPublishDate(
249                            portletPreferences);
250    
251                    exportImportPortlet(
252                            getPortletId(), exportParameterMap, importParameterMap);
253    
254                    portletPreferences =
255                            PortletPreferencesFactoryUtil.getStrictPortletSetup(
256                                    layout, getPortletId());
257    
258                    Date newLastPublishDate = ExportImportDateUtil.getLastPublishDate(
259                            portletPreferences);
260    
261                    Assert.assertTrue(newLastPublishDate.after(oldLastPublishDate));
262    
263                    StagedModel importedStagedModel = getStagedModel(
264                            getStagedModelUuid(stagedModel), importedGroup.getGroupId());
265    
266                    Assert.assertNotNull(importedStagedModel);
267            }
268    
269            @Test
270            public void testVersioning1() throws Exception {
271                    if (!isVersioningEnabled()) {
272                            return;
273                    }
274    
275                    StagedModel stagedModel = addStagedModel(group.getGroupId());
276    
277                    addVersion(stagedModel);
278    
279                    exportImportPortlet(getPortletId());
280    
281                    validateVersions();
282            }
283    
284            @Test
285            public void testVersioning2() throws Exception {
286                    if (!isVersioningEnabled()) {
287                            return;
288                    }
289    
290                    StagedModel stagedModel = addStagedModel(group.getGroupId());
291    
292                    Thread.sleep(4000);
293    
294                    exportImportPortlet(getPortletId());
295    
296                    validateVersions();
297    
298                    addVersion(stagedModel);
299    
300                    exportImportPortlet(getPortletId());
301    
302                    validateVersions();
303            }
304    
305            @Test
306            public void testVersioningDeleteFirst() throws Exception {
307                    if (!isVersioningEnabled()) {
308                            return;
309                    }
310    
311                    StagedModel stagedModel = addStagedModel(group.getGroupId());
312    
313                    stagedModel = addVersion(stagedModel);
314    
315                    exportImportPortlet(getPortletId());
316    
317                    validateVersions();
318    
319                    deleteFirstVersion(stagedModel);
320    
321                    exportImportPortlet(getPortletId());
322    
323                    validateVersions();
324            }
325    
326            @Test
327            public void testVersioningDeleteLatest() throws Exception {
328                    if (!isVersioningEnabled()) {
329                            return;
330                    }
331    
332                    StagedModel stagedModel = addStagedModel(group.getGroupId());
333    
334                    stagedModel = addVersion(stagedModel);
335    
336                    exportImportPortlet(getPortletId());
337    
338                    validateVersions();
339    
340                    deleteLatestVersion(stagedModel);
341    
342                    exportImportPortlet(getPortletId());
343    
344                    validateVersions();
345            }
346    
347            @Test
348            public void testVersioningExportImportTwice() throws Exception {
349                    if (!isVersioningEnabled()) {
350                            return;
351                    }
352    
353                    StagedModel stagedModel = addStagedModel(group.getGroupId());
354    
355                    addVersion(stagedModel);
356    
357                    exportImportPortlet(getPortletId());
358    
359                    validateVersions();
360    
361                    exportImportPortlet(getPortletId());
362    
363                    validateVersions();
364            }
365    
366            protected AssetLink addAssetLink(
367                            StagedModel sourceStagedModel, StagedModel targetStagedModel,
368                            int weight)
369                    throws PortalException {
370    
371                    AssetEntry originAssetEntry = getAssetEntry(sourceStagedModel);
372                    AssetEntry targetAssetEntry = getAssetEntry(targetStagedModel);
373    
374                    return AssetLinkLocalServiceUtil.addLink(
375                            TestPropsValues.getUserId(), originAssetEntry.getEntryId(),
376                            targetAssetEntry.getEntryId(), 0, weight);
377            }
378    
379            protected void addParameter(
380                    Map<String, String[]> parameterMap, String name, boolean value) {
381    
382                    addParameter(parameterMap, getNamespace(), name, value);
383            }
384    
385            protected StagedModel addVersion(StagedModel stagedModel) throws Exception {
386                    return null;
387            }
388    
389            protected void deleteFirstVersion(StagedModel stagedModel)
390                    throws Exception {
391            }
392    
393            protected void deleteLatestVersion(StagedModel stagedModel)
394                    throws Exception {
395            }
396    
397            protected void exportImportPortlet(String portletId) throws Exception {
398                    exportImportPortlet(
399                            portletId, new LinkedHashMap<String, String[]>(),
400                            new LinkedHashMap<String, String[]>());
401            }
402    
403            protected void exportImportPortlet(
404                            String portletId, Map<String, String[]> exportParameterMap,
405                            Map<String, String[]> importParameterMap)
406                    throws Exception {
407    
408                    User user = TestPropsValues.getUser();
409    
410                    MapUtil.merge(getExportParameterMap(), exportParameterMap);
411    
412                    Map<String, Serializable> settingsMap =
413                            ExportImportConfigurationSettingsMapFactory.
414                                    buildExportPortletSettingsMap(
415                                            user, layout.getPlid(), layout.getGroupId(), portletId,
416                                            exportParameterMap, StringPool.BLANK);
417    
418                    ExportImportConfiguration exportImportConfiguration =
419                            ExportImportConfigurationLocalServiceUtil.
420                                    addDraftExportImportConfiguration(
421                                            user.getUserId(),
422                                            ExportImportConfigurationConstants.TYPE_EXPORT_PORTLET,
423                                            settingsMap);
424    
425                    ExportImportThreadLocal.setPortletStagingInProcess(true);
426    
427                    try {
428                            larFile = ExportImportLocalServiceUtil.exportPortletInfoAsFile(
429                                    exportImportConfiguration);
430    
431                            importedLayout = LayoutTestUtil.addLayout(importedGroup);
432    
433                            MapUtil.merge(getImportParameterMap(), importParameterMap);
434    
435                            settingsMap =
436                                    ExportImportConfigurationSettingsMapFactory.
437                                            buildImportPortletSettingsMap(
438                                                    user, importedLayout.getPlid(),
439                                                    importedGroup.getGroupId(), portletId,
440                                                    importParameterMap);
441    
442                            exportImportConfiguration =
443                                    ExportImportConfigurationLocalServiceUtil.
444                                            addExportImportConfiguration(
445                                                    user.getUserId(), importedGroup.getGroupId(),
446                                                    StringPool.BLANK, StringPool.BLANK,
447                                                    ExportImportConfigurationConstants.TYPE_IMPORT_PORTLET,
448                                                    settingsMap, WorkflowConstants.STATUS_DRAFT,
449                                                    new ServiceContext());
450    
451                            ExportImportLocalServiceUtil.importPortletDataDeletions(
452                                    exportImportConfiguration, larFile);
453    
454                            ExportImportLocalServiceUtil.importPortletInfo(
455                                    exportImportConfiguration, larFile);
456                    }
457                    finally {
458                            ExportImportThreadLocal.setPortletStagingInProcess(false);
459                    }
460            }
461    
462            protected AssetEntry getAssetEntry(StagedModel stagedModel)
463                    throws PortalException {
464    
465                    return AssetEntryLocalServiceUtil.getEntry(
466                            ExportImportClassedModelUtil.getClassName(stagedModel),
467                            ExportImportClassedModelUtil.getClassPK(stagedModel));
468            }
469    
470            protected PortletPreferences getImportedPortletPreferences(
471                            Map<String, String[]> preferenceMap)
472                    throws Exception {
473    
474                    String portletId = LayoutTestUtil.addPortletToLayout(
475                            TestPropsValues.getUserId(), this.layout, getPortletId(),
476                            "column-1", preferenceMap);
477    
478                    exportImportPortlet(portletId);
479    
480                    return LayoutTestUtil.getPortletPreferences(importedLayout, portletId);
481            }
482    
483            protected boolean isVersioningEnabled() {
484                    return false;
485            }
486    
487            protected void testExportImportAvailableLocales(
488                            Collection<Locale> sourceAvailableLocales,
489                            Collection<Locale> targetAvailableLocales, boolean expectFailure)
490                    throws Exception {
491    
492                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
493                            group.getCompanyId(), getPortletId());
494    
495                    if (portlet == null) {
496                            return;
497                    }
498    
499                    PortletDataHandler portletDataHandler =
500                            portlet.getPortletDataHandlerInstance();
501    
502                    if (!portletDataHandler.isDataLocalized()) {
503                            Assert.assertTrue("This test does not apply", true);
504    
505                            return;
506                    }
507    
508                    GroupTestUtil.updateDisplaySettings(
509                            group.getGroupId(), sourceAvailableLocales, null);
510                    GroupTestUtil.updateDisplaySettings(
511                            importedGroup.getGroupId(), targetAvailableLocales, null);
512    
513                    try {
514                            exportImportPortlet(getPortletId());
515    
516                            Assert.assertFalse(expectFailure);
517                    }
518                    catch (LocaleException le) {
519                            Assert.assertTrue(expectFailure);
520                    }
521            }
522    
523            protected void testExportImportDisplayStyle(
524                            long displayStyleGroupId, String scopeType)
525                    throws Exception {
526    
527                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
528                            group.getCompanyId(), getPortletId());
529    
530                    if (portlet == null) {
531                            return;
532                    }
533    
534                    if (scopeType.equals("layout") && !portlet.isScopeable()) {
535                            Assert.assertTrue("This test does not apply", true);
536    
537                            return;
538                    }
539    
540                    TemplateHandler templateHandler = portlet.getTemplateHandlerInstance();
541    
542                    if (templateHandler == null) {
543                            Assert.assertTrue("This test does not apply", true);
544    
545                            return;
546                    }
547    
548                    String className = templateHandler.getClassName();
549                    long resourceClassNameId = PortalUtil.getClassNameId(
550                            "com.liferay.portlet.display.template.PortletDisplayTemplate");
551    
552                    DDMTemplate ddmTemplate = DDMTemplateTestUtil.addTemplate(
553                            displayStyleGroupId, PortalUtil.getClassNameId(className), 0,
554                            resourceClassNameId);
555    
556                    Map<String, String[]> preferenceMap = new HashMap<>();
557    
558                    String displayStyle =
559                            PortletDisplayTemplateManager.DISPLAY_STYLE_PREFIX +
560                                    ddmTemplate.getTemplateKey();
561    
562                    preferenceMap.put("displayStyle", new String[] {displayStyle});
563    
564                    preferenceMap.put(
565                            "displayStyleGroupId",
566                            new String[] {String.valueOf(ddmTemplate.getGroupId())});
567    
568                    if (scopeType.equals("layout")) {
569                            preferenceMap.put(
570                                    "lfrScopeLayoutUuid", new String[] {this.layout.getUuid()});
571                    }
572    
573                    preferenceMap.put("lfrScopeType", new String[] {scopeType});
574    
575                    PortletPreferences portletPreferences = getImportedPortletPreferences(
576                            preferenceMap);
577    
578                    String importedDisplayStyle = portletPreferences.getValue(
579                            "displayStyle", StringPool.BLANK);
580    
581                    Assert.assertEquals(displayStyle, importedDisplayStyle);
582    
583                    long importedDisplayStyleGroupId = GetterUtil.getLong(
584                            portletPreferences.getValue("displayStyleGroupId", null));
585    
586                    long expectedDisplayStyleGroupId = importedGroup.getGroupId();
587    
588                    if (scopeType.equals("company")) {
589                            Group companyGroup = GroupLocalServiceUtil.getCompanyGroup(
590                                    importedGroup.getCompanyId());
591    
592                            expectedDisplayStyleGroupId = companyGroup.getGroupId();
593                    }
594                    else if (displayStyleGroupId != group.getGroupId()) {
595                            expectedDisplayStyleGroupId = displayStyleGroupId;
596                    }
597    
598                    Assert.assertEquals(
599                            expectedDisplayStyleGroupId, importedDisplayStyleGroupId);
600            }
601    
602            protected void validateImportedLinks(
603                            StagedModel originalStagedModel, StagedModel importedStagedModel)
604                    throws PortalException {
605    
606                    AssetEntry originalAssetEntry = getAssetEntry(originalStagedModel);
607    
608                    List<AssetLink> originalAssetLinks = AssetLinkLocalServiceUtil.getLinks(
609                            originalAssetEntry.getEntryId());
610    
611                    AssetEntry importedAssetEntry = getAssetEntry(importedStagedModel);
612    
613                    List<AssetLink> importedAssetLinks = AssetLinkLocalServiceUtil.getLinks(
614                            importedAssetEntry.getEntryId());
615    
616                    Assert.assertEquals(
617                            originalAssetLinks.size(), importedAssetLinks.size());
618    
619                    for (AssetLink originalLink : originalAssetLinks) {
620                            AssetEntry sourceAssetEntry = AssetEntryLocalServiceUtil.getEntry(
621                                    originalLink.getEntryId1());
622    
623                            AssetEntry targetAssetEntry = AssetEntryLocalServiceUtil.getEntry(
624                                    originalLink.getEntryId2());
625    
626                            Iterator<AssetLink> iterator = importedAssetLinks.iterator();
627    
628                            while (iterator.hasNext()) {
629                                    AssetLink importedLink = iterator.next();
630    
631                                    AssetEntry importedLinkSourceAssetEntry =
632                                            AssetEntryLocalServiceUtil.getEntry(
633                                                    importedLink.getEntryId1());
634                                    AssetEntry importedLinkTargetAssetEntry =
635                                            AssetEntryLocalServiceUtil.getEntry(
636                                                    importedLink.getEntryId2());
637    
638                                    if (!Validator.equals(
639                                                    sourceAssetEntry.getClassUuid(),
640                                                    importedLinkSourceAssetEntry.getClassUuid())) {
641    
642                                            continue;
643                                    }
644    
645                                    if (!Validator.equals(
646                                                    targetAssetEntry.getClassUuid(),
647                                                    importedLinkTargetAssetEntry.getClassUuid())) {
648    
649                                            continue;
650                                    }
651    
652                                    Assert.assertEquals(
653                                            originalLink.getWeight(), importedLink.getWeight());
654                                    Assert.assertEquals(
655                                            originalLink.getType(), importedLink.getType());
656    
657                                    iterator.remove();
658    
659                                    break;
660                            }
661                    }
662    
663                    Assert.assertEquals(0, importedAssetLinks.size());
664            }
665    
666            protected void validateVersions() throws Exception {
667            }
668    
669    }