blob: 985aed06a71b83a642b23fb5f794f6cf6242c888 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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
*/
package org.apache.unomi.itests;
import org.apache.unomi.api.CustomItem;
import org.apache.unomi.api.Event;
import org.apache.unomi.api.Metadata;
import org.apache.unomi.api.Profile;
import org.apache.unomi.api.actions.Action;
import org.apache.unomi.api.conditions.Condition;
import org.apache.unomi.api.rules.Rule;
import org.apache.unomi.api.services.DefinitionsService;
import org.apache.unomi.api.services.EventService;
import org.apache.unomi.api.services.ProfileService;
import org.apache.unomi.api.services.RulesService;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.ops4j.pax.exam.junit.PaxExam;
import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
import org.ops4j.pax.exam.spi.reactors.PerSuite;
import org.ops4j.pax.exam.util.Filter;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import static org.apache.unomi.itests.BasicIT.ITEM_TYPE_PAGE;
@RunWith(PaxExam.class)
@ExamReactorStrategy(PerSuite.class)
public class IncrementPropertyIT extends BaseIT {
private Profile profile;
private Rule rule;
private Event event;
@Inject
@Filter(timeout = 600000)
protected ProfileService profileService;
@Inject
@Filter(timeout = 600000)
protected EventService eventService;
@Inject
@Filter(timeout = 600000)
protected RulesService rulesService;
@Inject
@Filter(timeout = 600000)
protected DefinitionsService definitionsService;
@Before
public void setup() throws Exception {
profile = createProfile();
rule = new Rule();
}
@After
public void tearDown() throws InterruptedException {
rulesService.removeRule(rule.getItemId());
profileService.delete(profile.getItemId(), false);
waitForNullValue("Rule still present after deletion", () -> rulesService.getRule(rule.getItemId()), DEFAULT_TRYING_TIMEOUT,
DEFAULT_TRYING_TRIES);
waitForNullValue("Profile still present after deletion", () -> profileService.load(profile.getItemId()), DEFAULT_TRYING_TIMEOUT,
DEFAULT_TRYING_TRIES);
}
@Test
public void testIncrementNotExistingPropertyWithDynamicName() throws InterruptedException {
int eventCode = buildActionAndSendEvent("pageView.${eventProperty::target.scope}", null, null, null);
if (eventCode == EventService.PROFILE_UPDATED) {
Profile updatedProfile = profileService.save(event.getProfile());
int value = ((Map<String, Integer>) updatedProfile.getProperty("pageView")).get("acme-space");
Assert.assertEquals(1, value, 0.0);
} else {
Assert.fail("Profile was not updated");
}
}
@Test
public void testIncrementExistingPropertyWithDynamicName() throws InterruptedException {
Map<String, Object> properties = new HashMap<>();
Map<String, Integer> propertyValue = new HashMap<>();
propertyValue.put("acme-space", 24);
properties.put("pageView", propertyValue);
int eventCode = buildActionAndSendEvent("pageView.${eventProperty::target.scope}", null, properties, null);
if (eventCode == EventService.PROFILE_UPDATED) {
Profile updatedProfile = profileService.save(event.getProfile());
int value = ((Map<String, Integer>) updatedProfile.getProperty("pageView")).get("acme-space");
Assert.assertEquals(25, value, 0.0);
} else {
Assert.fail("Profile was not updated");
}
}
@Test
public void testIncrementNotExistingProperty() throws InterruptedException {
int eventCode = buildActionAndSendEvent("pageView.acme", null, null, null);
if (eventCode == EventService.PROFILE_UPDATED) {
Profile updatedProfile = profileService.save(event.getProfile());
int value = ((Map<String, Integer>) updatedProfile.getProperty("pageView")).get("acme");
Assert.assertEquals(1, value, 0.0);
} else {
Assert.fail("Profile was not updated");
}
}
@Test
public void testIncrementExistingProperty() throws InterruptedException {
Map<String, Object> properties = new HashMap<>();
Map<String, Integer> propertyValue = new HashMap<>();
propertyValue.put("acme", 49);
properties.put("pageView", propertyValue);
int eventCode = buildActionAndSendEvent("pageView.acme", null, properties, null);
if (eventCode == EventService.PROFILE_UPDATED) {
Profile updatedProfile = profileService.save(event.getProfile());
int value = ((Map<String, Integer>) updatedProfile.getProperty("pageView")).get("acme");
Assert.assertEquals(50, value, 0.0);
} else {
Assert.fail("Profile was not updated");
}
}
@Test
public void testIncrementExistingPropertyWithExistingEventProperty() throws InterruptedException {
Map<String, Object> properties = new HashMap<>();
Map<String, Integer> propertyValue = new HashMap<>();
propertyValue.put("acme", 49);
properties.put("pageView", propertyValue);
Map<String, Object> targetProperties = new HashMap<>();
propertyValue = new HashMap<>();
propertyValue.put("nasa", 19);
targetProperties.put("project", propertyValue);
int eventCode = buildActionAndSendEvent("pageView.acme", "project.nasa", properties, targetProperties);
if (eventCode == EventService.PROFILE_UPDATED) {
Profile updatedProfile = profileService.save(event.getProfile());
int value = ((Map<String, Integer>) updatedProfile.getProperty("pageView")).get("acme");
Assert.assertEquals(68, value, 0.0);
} else {
Assert.fail("Profile was not updated");
}
}
@Test
public void testIncrementNotExistingObjectPropertyWithExistingEventObjectProperty() throws InterruptedException {
Map<String, Object> targetProperties = new HashMap<>();
Map<String, Integer> propertyValue = new HashMap<>();
propertyValue.put("acme", 49);
propertyValue.put("health", 18);
propertyValue.put("sport", 99);
targetProperties.put("pageView", propertyValue);
int eventCode = buildActionAndSendEvent("pageView", "pageView", null, targetProperties);
if (eventCode == EventService.PROFILE_UPDATED) {
Profile updatedProfile = profileService.save(event.getProfile());
Map<String, Integer> property = ((Map<String, Integer>) updatedProfile.getProperty("pageView"));
Assert.assertEquals(49, property.get("acme"), 0.0);
Assert.assertEquals(18, property.get("health"), 0.0);
Assert.assertEquals(99, property.get("sport"), 0.0);
} else {
Assert.fail("Profile was not updated");
}
}
@Test
public void testIncrementExistingObjectProperty() throws InterruptedException {
Map<String, Object> properties = new HashMap<>();
Map<String, Integer> propertyValue = new HashMap<>();
propertyValue.put("acme", 49);
propertyValue.put("nasa", 5);
properties.put("pageView", propertyValue);
int eventCode = buildActionAndSendEvent("pageView", null, properties, null);
if (eventCode == EventService.PROFILE_UPDATED) {
Profile updatedProfile = profileService.save(event.getProfile());
Map<String, Integer> property = ((Map<String, Integer>) updatedProfile.getProperty("pageView"));
Assert.assertEquals(50, property.get("acme"), 0.0);
Assert.assertEquals(6, property.get("nasa"), 0.0);
} else {
Assert.fail("Profile was not updated");
}
}
@Test
public void testIncrementExistingObjectPropertyWithExistingEventObjectProperty() throws InterruptedException {
Map<String, Object> properties = new HashMap<>();
Map<String, Integer> propertyValue = new HashMap<>();
propertyValue.put("acme", 49);
properties.put("pageView", propertyValue);
Map<String, Object> targetProperties = new HashMap<>();
Map<String, Integer> propertyValue1 = new HashMap<>();
propertyValue1.put("acme", 31);
propertyValue1.put("health", 88);
propertyValue1.put("sport", 9);
targetProperties.put("pageView", propertyValue1);
int eventCode = buildActionAndSendEvent("pageView", "pageView", properties, targetProperties);
if (eventCode == EventService.PROFILE_UPDATED) {
Profile updatedProfile = profileService.save(event.getProfile());
Map<String, Integer> property = ((Map<String, Integer>) updatedProfile.getProperty("pageView"));
Assert.assertEquals(80, property.get("acme"), 0.0);
Assert.assertEquals(88, property.get("health"), 0.0);
Assert.assertEquals(9, property.get("sport"), 0.0);
} else {
Assert.fail("Profile was not updated");
}
}
@Test
public void testIncrementExistingPropertyNested() throws InterruptedException {
Map<String, Object> properties = new HashMap<>();
Map<String, Object> properties1 = new HashMap<>();
Map<String, Object> properties2 = new HashMap<>();
Map<String, Integer> propertyValue = new HashMap<>();
propertyValue.put("city", 13);
properties2.put("state", propertyValue);
properties1.put("country", properties2);
properties.put("continent", properties1);
int eventCode = buildActionAndSendEvent("continent.country.state.city", null, properties, null);
if (eventCode == EventService.PROFILE_UPDATED) {
Profile updatedProfile = profileService.save(event.getProfile());
Map<String, Integer> property = (Map<String, Integer>) ((Map<String, Object>) ((Map<String, Object>) updatedProfile
.getProperty("continent")).get("country")).get("state");
Assert.assertEquals(14, property.get("city"), 0.0);
} else {
Assert.fail("Profile was not updated");
}
}
@Test
public void testIncrementNotExistingPropertyNested() throws InterruptedException {
int eventCode = buildActionAndSendEvent("continent.country.state.city", null, null, null);
if (eventCode == EventService.PROFILE_UPDATED) {
Profile updatedProfile = profileService.save(event.getProfile());
Map<String, Integer> property = (Map<String, Integer>) ((Map<String, Object>) ((Map<String, Object>) updatedProfile
.getProperty("continent")).get("country")).get("state");
Assert.assertEquals(1, property.get("city"), 0.0);
} else {
Assert.fail("Profile was not updated");
}
}
@Test
public void testIncrementExistingPropertyNestedWithExistingEventProperty() throws InterruptedException {
Map<String, Object> properties = new HashMap<>();
Map<String, Object> properties1 = new HashMap<>();
Map<String, Object> properties2 = new HashMap<>();
Map<String, Integer> propertyValue = new HashMap<>();
propertyValue.put("city", 13);
properties2.put("state", propertyValue);
properties1.put("country", properties2);
properties.put("continent", properties1);
Map<String, Object> targetProperties = new HashMap<>();
Map<String, Object> properties3 = new HashMap<>();
Map<String, Object> propertyValue1 = new HashMap<>();
propertyValue1.put("zone", 107);
properties3.put("mars", propertyValue1);
targetProperties.put("planet", properties3);
int eventCode = buildActionAndSendEvent("continent.country.state.city", "planet.mars.zone", properties, targetProperties);
if (eventCode == EventService.PROFILE_UPDATED) {
Profile updatedProfile = profileService.save(event.getProfile());
Map<String, Integer> property = (Map<String, Integer>) ((Map<String, Object>) ((Map<String, Object>) updatedProfile
.getProperty("continent")).get("country")).get("state");
Assert.assertEquals(120, property.get("city"), 0.0);
} else {
Assert.fail("Profile was not updated");
}
}
@Test
public void testIncrementObjectPropertyContainsStringValue() throws InterruptedException {
Map<String, Object> properties = new HashMap<>();
Map<String, Object> propertyValue = new HashMap<>();
propertyValue.put("books", 59);
propertyValue.put("chapters", 1001);
propertyValue.put("featured", "The forty rules");
properties.put("library", propertyValue);
int eventCode = buildActionAndSendEvent("library", null, properties, null);
if (eventCode == EventService.PROFILE_UPDATED) {
Profile updatedProfile = profileService.save(event.getProfile());
Map<String, Object> property = ((Map<String, Object>) updatedProfile.getProperty("library"));
Assert.assertEquals(60, (int) property.get("books"), 0.0);
Assert.assertEquals(1002, (int) property.get("chapters"), 0.0);
Assert.assertEquals("The forty rules", property.get("featured"));
} else {
Assert.fail("Profile was not updated");
}
}
@Test
public void testIncrementObjectPropertyContainsStringValueWithExistingEventProperty() throws InterruptedException {
Map<String, Object> properties = new HashMap<>();
Map<String, Object> propertyValue = new HashMap<>();
propertyValue.put("books", 59);
propertyValue.put("chapters", 1001);
propertyValue.put("featured", "The forty rules");
properties.put("library", propertyValue);
Map<String, Object> targetProperties = new HashMap<>();
Map<String, Object> properties1 = new HashMap<>();
Map<String, Object> propertyValue1 = new HashMap<>();
propertyValue1.put("books", 222);
propertyValue1.put("chapters", 2048);
propertyValue1.put("featured", "Bible");
properties1.put("library", propertyValue1);
targetProperties.put("main", properties1);
int eventCode = buildActionAndSendEvent("library", "main.library", properties, targetProperties);
if (eventCode == EventService.PROFILE_UPDATED) {
Profile updatedProfile = profileService.save(event.getProfile());
Map<String, Object> property = ((Map<String, Object>) updatedProfile.getProperty("library"));
Assert.assertEquals(281, (int) property.get("books"), 0.0);
Assert.assertEquals(3049, (int) property.get("chapters"), 0.0);
Assert.assertEquals("The forty rules", property.get("featured"));
} else {
Assert.fail("Profile was not updated");
}
}
private void createRule(Action incrementPropertyAction) throws InterruptedException {
Condition condition = createCondition();
Metadata metadata = createMetadata();
List<Action> actions = new ArrayList<>();
actions.add(incrementPropertyAction);
rule.setCondition(condition);
rule.setActions(actions);
rule.setMetadata(metadata);
createAndWaitForRule(rule);
}
private int buildActionAndSendEvent(String propertyName, String propertyTargetName, Map<String, Object> properties,
Map<String, Object> targetProperties) throws InterruptedException {
Action incrementPropertyAction = new Action(definitionsService.getActionType("incrementPropertyAction"));
incrementPropertyAction.setParameter("propertyName", propertyName);
if (propertyTargetName != null)
incrementPropertyAction.setParameter("propertyTarget", propertyTargetName);
createRule(incrementPropertyAction);
if (properties != null)
profile.setProperties(properties);
CustomItem target = new CustomItem("ITEM_ID_PAGE", ITEM_TYPE_PAGE);
target.setScope("acme-space");
if (targetProperties == null) {
targetProperties = new HashMap<>();
}
Map<String, Object> pageInfo = new HashMap<>();
pageInfo.put("language", "en");
pageInfo.put("destinationURL", "https://www.acme.com/test-page.html");
pageInfo.put("referringURL", "https://unomi.apache.org");
pageInfo.put("pageID", "ITEM_ID_PAGE");
pageInfo.put("pagePath", "/test-page.html");
pageInfo.put("pageName", "Test page");
targetProperties.put("pageInfo", pageInfo);
target.setProperties(targetProperties);
event = new Event("view", null, profile, null, null, target, new Date());
event.setPersistent(false);
int eventCode = eventService.send(event);
return eventCode;
}
private Metadata createMetadata() {
String itemId = UUID.randomUUID().toString();
Metadata metadata = new Metadata();
metadata.setId(itemId);
metadata.setName(itemId);
metadata.setDescription(itemId);
metadata.setEnabled(true);
metadata.setScope("systemscope");
return metadata;
}
private Condition createCondition() {
Condition condition = new Condition(definitionsService.getConditionType("eventTypeCondition"));
condition.setParameter("eventTypeId", "view");
return condition;
}
private Profile createProfile() throws InterruptedException {
Profile profile = new Profile(UUID.randomUUID().toString());
profileService.save(profile);
return keepTrying("Profile " + profile.getItemId() + " not found in the required time",
() -> profileService.load(profile.getItemId()), Objects::nonNull, DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES);
}
}