1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.syncope.fit;
20
21 import static org.junit.jupiter.api.Assertions.assertEquals;
22 import static org.junit.jupiter.api.Assertions.assertNotNull;
23 import static org.junit.jupiter.api.Assertions.fail;
24
25 import com.fasterxml.jackson.databind.JsonNode;
26 import com.fasterxml.jackson.databind.json.JsonMapper;
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.io.Serializable;
30 import java.lang.reflect.Method;
31 import java.util.Properties;
32 import java.util.Set;
33 import java.util.stream.Collectors;
34 import javax.ws.rs.core.MediaType;
35 import org.apache.commons.lang3.StringUtils;
36 import org.apache.cxf.jaxrs.client.WebClient;
37 import org.apache.syncope.common.rest.api.service.SyncopeService;
38 import org.apache.wicket.Component;
39 import org.apache.wicket.MarkupContainer;
40 import org.apache.wicket.behavior.AbstractAjaxBehavior;
41 import org.apache.wicket.core.util.lang.PropertyResolver;
42 import org.apache.wicket.feedback.ExactLevelFeedbackMessageFilter;
43 import org.apache.wicket.feedback.FeedbackMessage;
44 import org.apache.wicket.markup.html.list.ListItem;
45 import org.apache.wicket.util.tester.WicketTester;
46 import org.apache.wicket.util.visit.IVisit;
47 import org.junit.jupiter.api.BeforeAll;
48 import org.slf4j.Logger;
49 import org.slf4j.LoggerFactory;
50
51 public abstract class AbstractUIITCase {
52
53 protected static final Logger LOG = LoggerFactory.getLogger(AbstractUIITCase.class);
54
55 protected static final JsonMapper JSON_MAPPER = JsonMapper.builder().findAndAddModules().build();
56
57 protected static final String ADMIN_UNAME = "admin";
58
59 protected static final String ADMIN_PWD = "password";
60
61 protected static final String ADDRESS = "http://localhost:9080/syncope/rest";
62
63 protected static final String KEY = "key";
64
65 protected static final String SCHEMA = "schema";
66
67 protected static String ANONYMOUS_UNAME;
68
69 protected static String ANONYMOUS_KEY;
70
71 protected static WicketTester TESTER;
72
73 protected static SyncopeService SYNCOPE_SERVICE;
74
75 protected static boolean IS_FLOWABLE_ENABLED = false;
76
77 protected static boolean IS_EXT_SEARCH_ENABLED = false;
78
79 @BeforeAll
80 public static void anonymousSetup() throws IOException {
81 try (InputStream propStream = AbstractITCase.class.getResourceAsStream("/core.properties")) {
82 Properties props = new Properties();
83 props.load(propStream);
84
85 ANONYMOUS_UNAME = props.getProperty("security.anonymousUser");
86 ANONYMOUS_KEY = props.getProperty("security.anonymousKey");
87 } catch (Exception e) {
88 LOG.error("Could not read core.properties", e);
89 }
90
91 assertNotNull(ANONYMOUS_UNAME);
92 assertNotNull(ANONYMOUS_KEY);
93
94 JsonNode beans = JSON_MAPPER.readTree(
95 (InputStream) WebClient.create(
96 StringUtils.substringBeforeLast(ADDRESS, "/") + "/actuator/beans",
97 ANONYMOUS_UNAME,
98 ANONYMOUS_KEY,
99 null).
100 accept(MediaType.APPLICATION_JSON).get().getEntity());
101
102 JsonNode uwfAdapter = beans.findValues("uwfAdapter").get(0);
103 IS_FLOWABLE_ENABLED = uwfAdapter.get("resource").asText().contains("Flowable");
104
105 JsonNode anySearchDAO = beans.findValues("anySearchDAO").get(0);
106 IS_EXT_SEARCH_ENABLED = anySearchDAO.get("type").asText().contains("Elasticsearch")
107 || anySearchDAO.get("type").asText().contains("OpenSearch");
108 }
109
110 protected static <V extends Serializable> Component findComponentByProp(
111 final String property, final String path, final V key) {
112
113 Component component = TESTER.getComponentFromLastRenderedPage(path);
114 return (component instanceof MarkupContainer ? MarkupContainer.class.cast(component) : component.getPage()).
115 visitChildren(ListItem.class, (ListItem<?> object, IVisit<Component> visit) -> {
116 try {
117 Method getter = PropertyResolver.getPropertyGetter(property, object.getModelObject());
118 if (getter != null && getter.invoke(object.getModelObject()).equals(key)) {
119 visit.stop(object);
120 }
121 } catch (Exception e) {
122 LOG.debug("Error finding component by property ({},{}) on path {}", property, key, path, e);
123 }
124 });
125 }
126
127 protected static <V extends Serializable> Component findComponentByPropNotNull(
128 final String property, final String path) {
129
130 Component component = TESTER.getComponentFromLastRenderedPage(path);
131 return (component instanceof MarkupContainer ? MarkupContainer.class.cast(component) : component.getPage()).
132 visitChildren(ListItem.class, (ListItem<?> object, IVisit<Component> visit) -> {
133 try {
134 Method getter = PropertyResolver.getPropertyGetter(property, object.getModelObject());
135 if (getter != null && getter.invoke(object.getModelObject()) != null) {
136 visit.stop(object);
137 }
138 } catch (Exception e) {
139 LOG.debug("Error finding component by property {} not null on path {}", property, path, e);
140 }
141 });
142 }
143
144 protected static Component findComponentById(final String searchPath, final String id) {
145 Component component = TESTER.getComponentFromLastRenderedPage(searchPath);
146 return (component instanceof MarkupContainer ? MarkupContainer.class.cast(component) : component.getPage()).
147 visitChildren(Component.class, (object, visit) -> {
148 if (object.getId().equals(id)) {
149 visit.stop(object);
150 }
151 });
152 }
153
154 protected static Component findComponentByMarkupId(final String searchPath, final String markupId) {
155 Component component = TESTER.getComponentFromLastRenderedPage(searchPath);
156 return (component instanceof MarkupContainer ? MarkupContainer.class.cast(component) : component.getPage()).
157 visitChildren(Component.class, (object, visit) -> {
158 if (object.getMarkupId().equals(markupId)) {
159 visit.stop(object);
160 }
161 });
162 }
163
164 protected static void closeCallBack(final Component modal) {
165 modal.getBehaviors().stream().
166 filter(behavior -> (behavior instanceof AbstractAjaxBehavior)).
167 forEachOrdered(behavior -> TESTER.executeBehavior((AbstractAjaxBehavior) behavior));
168 }
169
170 protected static void assertSuccessMessage() {
171 Set<Serializable> messages = TESTER.getFeedbackMessages(
172 new ExactLevelFeedbackMessageFilter(FeedbackMessage.SUCCESS)).stream().
173 map(FeedbackMessage::getMessage).collect(Collectors.toSet());
174 if (messages.size() != 1) {
175 fail("Expected single message but found " + messages);
176 }
177 assertEquals("Operation successfully executed", messages.iterator().next());
178 }
179 }