Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanseifert committed Oct 17, 2023
2 parents 9c685db + 49227e9 commit 74a468e
Show file tree
Hide file tree
Showing 16 changed files with 678 additions and 19 deletions.
12 changes: 12 additions & 0 deletions changes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@
xsi:schemaLocation="http://maven.apache.org/changes/1.0.0 http://maven.apache.org/plugins/maven-changes-plugin/xsd/changes-1.0.0.xsd">
<body>

<release version="5.4.0" date="2023-10-17">
<action type="add" dev="royteeuwen" issue="22">
Add mocks for ExperienceFragment and ExperienceFragmentVariation, adaptable from page objects.
</action>
<action type="update" dev="sseifert">
Update to latest Sling Mock.
</action>
<action type="update" dev="sseifert">
Resource Resolver Factory Activator: Provide old or new name for vanity paths allow/denylists by auto-detecting by auto-detecting form classpath (related to SLING-11742).
</action>
</release>

<release version="5.3.0" date="2023-08-21">
<action type="add" dev="catalinadumitruu" issue="19">
Implement MockTag.getLocalizedTitlePaths method.
Expand Down
2 changes: 1 addition & 1 deletion core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
<parent>
<groupId>io.wcm</groupId>
<artifactId>io.wcm.testing.aem-mock.parent</artifactId>
<version>5.3.0</version>
<version>5.4.0</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>

Expand Down
16 changes: 14 additions & 2 deletions core/src/main/java/io/wcm/testing/mock/aem/MockPageManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -430,15 +430,27 @@ public Resource move(Resource resource, String destination, String beforeName, b
throw new UnsupportedOperationException();
}

// AEM 6.5.18
@SuppressWarnings("unused")
public Resource move(Resource resource, String destination, String beforeName, boolean shallow,
boolean resolveConflict, String[] adjustRefs, String[] publishRefs, String arg7) throws WCMException {
throw new UnsupportedOperationException();
}

@Override
public Resource copy(CopyOptions options) throws WCMException {
throw new UnsupportedOperationException();
}

// AEM Cloud
@SuppressWarnings("unused")
@Override
public void delete(Resource arg0, boolean arg1, boolean arg2, boolean arg3) throws WCMException {
throw new UnsupportedOperationException();
}

// AEMaaCS 2023.9.13665.20230927T063259Z-230800
@SuppressWarnings("unused")
public Resource override(CopyOptions options) throws WCMException {
throw new UnsupportedOperationException();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@
*/
package io.wcm.testing.mock.aem.context;

import io.wcm.testing.mock.aem.MockJcrTagManagerFactory;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import io.wcm.testing.mock.aem.xf.MockExperienceFragmentAdapterFactory;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolverFactory;
Expand All @@ -46,6 +46,7 @@
import io.wcm.testing.mock.aem.MockComponentContext;
import io.wcm.testing.mock.aem.MockContentPolicyStorage;
import io.wcm.testing.mock.aem.MockExternalizer;
import io.wcm.testing.mock.aem.MockJcrTagManagerFactory;
import io.wcm.testing.mock.aem.MockLanguageManager;
import io.wcm.testing.mock.aem.MockLayerAdapterFactory;
import io.wcm.testing.mock.aem.MockPageManagerFactory;
Expand Down Expand Up @@ -76,6 +77,7 @@ protected void registerDefaultServices() {
registerInjectActivateService(new MockAemAdapterFactory());
registerInjectActivateService(new MockAemDamAdapterFactory());
registerInjectActivateService(new MockLayerAdapterFactory());
registerInjectActivateService(new MockExperienceFragmentAdapterFactory());

// other services
registerInjectActivateService(new MockAssetHandler());
Expand Down Expand Up @@ -140,12 +142,12 @@ protected final Map<String, Object> resourceResolverFactoryActivatorPropsMergeWi
props.put("resource.resolver.vanitypath.maxEntries", -1);
props.put("resource.resolver.vanitypath.bloomfilter.maxBytes", 1024000);
props.put("resource.resolver.optimize.alias.resolution", false);
props.put("resource.resolver.vanitypath.whitelist", new String[] {
props.put(ResourceResolverFactoryConfigPropertyNames.getVanityPathAllowListPropertyName(), new String[] {
"/apps/",
"/libs/",
"/content/"
});
props.put("resource.resolver.vanitypath.blacklist", new String[] {
props.put(ResourceResolverFactoryConfigPropertyNames.getVanityPathDenyListPropertyName(), new String[] {
"/content/usergenerated"
});
props.put("resource.resolver.vanity.precedence", false);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* #%L
* wcm.io
* %%
* Copyright (C) 2023 wcm.io
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
package io.wcm.testing.mock.aem.context;

import java.lang.reflect.Method;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.apache.sling.resourceresolver.impl.ResourceResolverFactoryConfig;

/**
* The names of the vanity path allow/denylist configuration property changed between releases (SLING-11742).
* Auto-detect the correct name for the resource resolver in current classpath.
*/
final class ResourceResolverFactoryConfigPropertyNames {

private static final String VANITY_PATH_ALLOW_LIST_PROPERTY_NAME;
private static final String VANITY_PATH_DENY_LIST_PROPERTY_NAME;

static {
// old names as fallback
String vanityPathAllowListPropertyName = "resource.resolver.vanitypath.whitelist";
String vanityPathDenyListPropertyName = "resource.resolver.vanitypath.blacklist";

try {
Class<?> resourceResolverFactoryConfigClass = Class.forName(ResourceResolverFactoryConfig.class.getName());
Set<String> methodNames = Stream.of(resourceResolverFactoryConfigClass.getDeclaredMethods())
.map(Method::getName)
.collect(Collectors.toSet());
// use new names as fields do exist
if (methodNames.contains("resource_resolver_vanitypath_allowlist")
&& methodNames.contains("resource_resolver_vanitypath_denylist")) {
vanityPathAllowListPropertyName = "resource.resolver.vanitypath.allowlist";
vanityPathDenyListPropertyName = "resource.resolver.vanitypath.denylist";
}
}
catch (ClassNotFoundException ex) {
// ignore, keep old names
}

VANITY_PATH_ALLOW_LIST_PROPERTY_NAME = vanityPathAllowListPropertyName;
VANITY_PATH_DENY_LIST_PROPERTY_NAME = vanityPathDenyListPropertyName;
}

static String getVanityPathAllowListPropertyName() {
return VANITY_PATH_ALLOW_LIST_PROPERTY_NAME;
}

static String getVanityPathDenyListPropertyName() {
return VANITY_PATH_DENY_LIST_PROPERTY_NAME;
}

private ResourceResolverFactoryConfigPropertyNames() {
// static methods only
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* #%L
* wcm.io
* %%
* Copyright (C) 2019 wcm.io
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
package io.wcm.testing.mock.aem.xf;

import static com.adobe.cq.xf.ExperienceFragmentsConstants.PN_XF_VARIANT_TYPE;
import static com.adobe.cq.xf.ExperienceFragmentsConstants.RT_EXPERIENCE_FRAGMENT_PAGE;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.resource.ValueMap;

import com.adobe.cq.xf.ExperienceFragment;
import com.adobe.cq.xf.ExperienceFragmentVariation;
import com.day.cq.commons.Filter;
import com.day.cq.wcm.api.Page;

/**
* Mock implementation of {@link ExperienceFragment}.
*/
class MockExperienceFragment extends MockExperienceFragmentBase implements ExperienceFragment {

MockExperienceFragment(Page page) {
super(page);
}

@Override
public List<ExperienceFragmentVariation> getVariations() {
List<ExperienceFragmentVariation> variations = new ArrayList<>();
Iterator<Page> it = getPage().listChildren(element -> element.getContentResource().isResourceType(RT_EXPERIENCE_FRAGMENT_PAGE));
while (it.hasNext()) {
Page thePage = it.next();
variations.add(thePage.adaptTo(ExperienceFragmentVariation.class));
}
return variations;
}

@Override
public List<ExperienceFragmentVariation> getVariations(String... type) {
final Set<String> typeValues = new HashSet<>(List.of(type));
Filter<Page> typeFilter = element -> {
ValueMap properties = element.getProperties();
String variantType = properties.get(PN_XF_VARIANT_TYPE, "");
if (StringUtils.isEmpty(variantType)) {
return false;
}
return typeValues.contains(variantType);
};
List<ExperienceFragmentVariation> variations = new ArrayList<>();
for (Iterator<Page> it = getPage().listChildren(typeFilter); it.hasNext();) {
Page page = it.next();
variations.add(page.adaptTo(ExperienceFragmentVariation.class));
}
return variations;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* #%L
* wcm.io
* %%
* Copyright (C) 2019 wcm.io
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
package io.wcm.testing.mock.aem.xf;

import org.apache.sling.api.adapter.AdapterFactory;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.osgi.annotation.versioning.ProviderType;
import org.osgi.service.component.annotations.Component;

import com.adobe.cq.xf.ExperienceFragment;
import com.adobe.cq.xf.ExperienceFragmentVariation;
import com.adobe.cq.xf.ExperienceFragmentsConstants;
import com.day.cq.wcm.api.Page;

/**
* Mock adapter factory for AEM Experience Fragment-related adaptions.
*/
@Component(service = AdapterFactory.class,
property = {
AdapterFactory.ADAPTABLE_CLASSES + "=com.day.cq.wcm.api.Page",
AdapterFactory.ADAPTER_CLASSES + "=com.adobe.cq.xf.ExperienceFragment",
AdapterFactory.ADAPTER_CLASSES + "=com.adobe.cq.xf.ExperienceFragmentVariation"
})
@ProviderType
public final class MockExperienceFragmentAdapterFactory implements AdapterFactory {

@SuppressWarnings("unchecked")
@Override
public @Nullable <AdapterType> AdapterType getAdapter(@NotNull Object object, @NotNull Class<AdapterType> type) {
if (object instanceof Page) {
Page page = (Page)object;
if (page.getContentResource().isResourceType(ExperienceFragmentsConstants.RT_EXPERIENCE_FRAGMENT_MASTER) && (type == ExperienceFragment.class)) {
return (AdapterType)new MockExperienceFragment(page);

}
if (page.getContentResource().isResourceType(ExperienceFragmentsConstants.RT_EXPERIENCE_FRAGMENT_PAGE) && (type == ExperienceFragmentVariation.class)) {
return (AdapterType)new MockExperienceFragmentVariation(page);

}
}
return null;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* #%L
* wcm.io
* %%
* Copyright (C) 2019 wcm.io
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
package io.wcm.testing.mock.aem.xf;

import java.util.Arrays;
import java.util.List;

import org.apache.sling.api.adapter.SlingAdaptable;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ValueMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import com.day.cq.commons.inherit.HierarchyNodeInheritanceValueMap;
import com.day.cq.commons.inherit.InheritanceValueMap;
import com.day.cq.wcm.api.Page;

class MockExperienceFragmentBase extends SlingAdaptable {

private final Page page;

protected MockExperienceFragmentBase(Page page) {
this.page = page;
}

public String getPath() {
return page.getPath();
}

public ValueMap getProperties() {
return page.getProperties();
}

public List<String> getCloudserviceConfigurationsPaths() {
return Arrays.asList(getInheritedProperties().getInherited("cq:cloudserviceconfigs", new String[0]));
}

protected InheritanceValueMap getInheritedProperties() {
return new HierarchyNodeInheritanceValueMap(page.getContentResource());
}

@Override
@SuppressWarnings({ "unchecked", "null" })
public @Nullable <AdapterType> AdapterType adaptTo(@NotNull Class<AdapterType> type) {
if (type == Resource.class) {
return (AdapterType)page.adaptTo(Resource.class);
}
if (type == Page.class) {
return (AdapterType)page;
}
return super.adaptTo(type);
}

protected Page getPage() {
return page;
}

}
Loading

0 comments on commit 74a468e

Please sign in to comment.