/**
* Copyright (c) 2010-2016 Evolveum
*
* 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.
*/
package com.evolveum.midpoint.notifications.impl;
import com.evolveum.midpoint.notifications.impl.formatters.TextFormatter;
import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.delta.ObjectDelta;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.prism.util.PrismTestUtil;
import com.evolveum.midpoint.schema.DeltaConvertor;
import com.evolveum.midpoint.schema.MidPointPrismContextFactory;
import com.evolveum.midpoint.schema.constants.MidPointConstants;
import com.evolveum.midpoint.util.PrettyPrinter;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.xml.ns._public.common.api_types_3.ObjectModificationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.Test;
import org.xml.sax.SAXException;
import javax.xml.bind.JAXBException;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import static org.testng.AssertJUnit.assertFalse;
import static org.testng.AssertJUnit.assertTrue;
/**
* @author mederly
*/
@ContextConfiguration(locations = {"classpath:ctx-task.xml",
"classpath:ctx-repo-cache.xml",
"classpath:ctx-provisioning.xml",
"classpath*:ctx-repository-test.xml",
"classpath:ctx-configuration-test.xml",
"classpath:ctx-common.xml",
"classpath:ctx-security.xml",
"classpath:ctx-audit.xml",
"classpath:ctx-model.xml",
"classpath:ctx-model-common.xml",
"classpath:ctx-notifications-test.xml",
"classpath*:ctx-notifications.xml"})
public class TestTextFormatter extends AbstractTestNGSpringContextTests {
public static final String OBJECTS_DIR_NAME = "src/test/resources/objects";
public static final String USER_JACK_FILE = OBJECTS_DIR_NAME + "/user-jack.xml";
public static final String ACCOUNT_JACK_FILE = OBJECTS_DIR_NAME + "/account-jack.xml";
public static final String CHANGES_DIR_NAME = "src/test/resources/changes";
public static final String USER_JACK_MODIFICATION_FILE = CHANGES_DIR_NAME + "/user-jack-modification.xml";
protected static final List<ItemPath> auxiliaryPaths = Arrays.asList(
new ItemPath(UserType.F_FAMILY_NAME), // for testing purposes
new ItemPath(ShadowType.F_METADATA),
new ItemPath(ShadowType.F_ACTIVATION, ActivationType.F_VALIDITY_STATUS),
new ItemPath(ShadowType.F_ACTIVATION, ActivationType.F_VALIDITY_CHANGE_TIMESTAMP),
new ItemPath(ShadowType.F_ACTIVATION, ActivationType.F_EFFECTIVE_STATUS),
new ItemPath(ShadowType.F_ACTIVATION, ActivationType.F_DISABLE_TIMESTAMP),
new ItemPath(ShadowType.F_ACTIVATION, ActivationType.F_ARCHIVE_TIMESTAMP),
new ItemPath(ShadowType.F_ACTIVATION, ActivationType.F_ENABLE_TIMESTAMP),
new ItemPath(ShadowType.F_ITERATION),
new ItemPath(ShadowType.F_ITERATION_TOKEN),
new ItemPath(UserType.F_LINK_REF),
new ItemPath(ShadowType.F_TRIGGER)
);
private static final List<ItemPath> synchronizationPaths = Arrays.asList(
new ItemPath(ShadowType.F_SYNCHRONIZATION_SITUATION),
new ItemPath(ShadowType.F_SYNCHRONIZATION_SITUATION_DESCRIPTION),
new ItemPath(ShadowType.F_SYNCHRONIZATION_TIMESTAMP),
new ItemPath(ShadowType.F_FULL_SYNCHRONIZATION_TIMESTAMP));
@Autowired
private TextFormatter textFormatter;
@Autowired
private PrismContext prismContext;
static {
// We set the locale to US to avoid translation of item names.
// It is crucial that this method is called before TextFormatter class is loaded.
// Currently this solution suffices but it is quite fragile. If something would change
// in this respect and breaking it, a different mechanism to set correct locale would need to be used.
Locale.setDefault(Locale.US);
}
@BeforeSuite
public void setup() throws SchemaException, SAXException, IOException {
PrettyPrinter.setDefaultNamespacePrefix(MidPointConstants.NS_MIDPOINT_PUBLIC_PREFIX);
PrismTestUtil.resetPrismContext(MidPointPrismContextFactory.FACTORY);
}
@Test
public void test010FormatUser() throws Exception {
// GIVEN
PrismObject<UserType> jack = PrismTestUtil.parseObject(new File(USER_JACK_FILE));
System.out.println(jack.debugDump());
// WHEN
String jackFormattedHideNone = textFormatter.formatObject(jack, null, true);
System.out.println("no hidden paths + show operational attributes: " + jackFormattedHideNone);
String jackFormattedHideOper = textFormatter.formatObject(jack, null, false);
System.out.println("no hidden paths + hide operational attributes: " + jackFormattedHideOper);
String jackFormattedHideAux = textFormatter.formatObject(jack, auxiliaryPaths, true);
System.out.println("hide auxiliary paths + show operational attributes: " + jackFormattedHideAux);
String jackFormattedHideAuxAndOper = textFormatter.formatObject(jack, auxiliaryPaths, false);
System.out.println("hide auxiliary paths + hide operational attributes: " + jackFormattedHideAuxAndOper);
// THEN
final String CREATE_TIMESTAMP = "createTimestamp:";
final String EFFECTIVE_STATUS = "Effective status: ENABLED";
final String FAMILY_NAME = "Family name: Sparrow";
final String SHIP = "ship: Black Pearl";
assertTrue("hidden operational attribute when it should be shown ('hide none')", jackFormattedHideNone.contains(CREATE_TIMESTAMP));
assertTrue("hidden auxiliary attribute (effective status) when it should be shown ('hide none')", jackFormattedHideNone.contains(EFFECTIVE_STATUS));
assertTrue("hidden auxiliary attribute (family name) when it should be shown ('hide none')", jackFormattedHideNone.contains(FAMILY_NAME));
assertTrue("hidden standard attribute when it should be shown ('hide none')", jackFormattedHideNone.contains(SHIP));
assertTrue("shown operational attribute when it should be hidden ('hide oper')", !jackFormattedHideOper.contains(CREATE_TIMESTAMP));
assertTrue("shown operational attribute when it should be shown ('hide oper')", !jackFormattedHideOper.contains(EFFECTIVE_STATUS));
assertTrue("hidden auxiliary attribute (family name) when it should be shown ('hide oper')", jackFormattedHideOper.contains(FAMILY_NAME));
assertTrue("hidden standard attribute when it should be shown ('hide oper')", jackFormattedHideOper.contains(SHIP));
assertTrue("shown auxiliary attribute (metadata) when it should be hidden ('hide aux')", !jackFormattedHideAux.contains(CREATE_TIMESTAMP));
assertTrue("shown auxiliary attribute (family name) when it should be hidden ('hide aux')", !jackFormattedHideAux.contains(FAMILY_NAME));
assertTrue("shown auxiliary attribute (effective status) when it should be hidden ('hide aux')", !jackFormattedHideAux.contains(EFFECTIVE_STATUS));
assertTrue("hidden standard attribute when it should be shown ('hide aux')", jackFormattedHideAux.contains(SHIP));
assertTrue("shown operational attribute when it should be hidden ('hide aux and oper')", !jackFormattedHideAuxAndOper.contains(CREATE_TIMESTAMP));
assertTrue("shown auxiliary attribute (effective status) when it should be hidden ('hide aux and oper')", !jackFormattedHideAuxAndOper.contains(EFFECTIVE_STATUS));
assertTrue("shown auxiliary attribute (family name) when it should be hidden ('hide aux and oper')", !jackFormattedHideAuxAndOper.contains(FAMILY_NAME));
assertTrue("hidden standard attribute when it should be shown ('hide aux and oper')", jackFormattedHideAuxAndOper.contains(SHIP));
}
@Test
public void test020FormatUserModification() throws Exception {
// GIVEN
ObjectDelta<UserType> delta = parseDelta(USER_JACK_MODIFICATION_FILE);
PrismObject<UserType> jack = PrismTestUtil.parseObject(new File(USER_JACK_FILE));
System.out.println(delta.debugDump());
// WHEN
String deltaFormattedHideNone = textFormatter.formatObjectModificationDelta(delta, null, true, jack, null);
System.out.println("no hidden paths + show operational attributes: " + deltaFormattedHideNone);
String deltaFormattedHideOper = textFormatter.formatObjectModificationDelta(delta, null, false, jack, null);
System.out.println("no hidden paths + hide operational attributes: " + deltaFormattedHideOper);
String deltaFormattedHideAux = textFormatter.formatObjectModificationDelta(delta, auxiliaryPaths, true, jack, null);
System.out.println("hide auxiliary paths + show operational attributes: " + deltaFormattedHideAux);
String deltaFormattedHideAuxAndOper = textFormatter.formatObjectModificationDelta(delta, auxiliaryPaths, false, jack, null);
System.out.println("hide auxiliary paths + hide operational attributes: " + deltaFormattedHideAuxAndOper);
// THEN
checkNotes(deltaFormattedHideAux);
checkNotes(deltaFormattedHideAuxAndOper);
checkNotes(deltaFormattedHideNone);
checkNotes(deltaFormattedHideOper);
assertTrue("hidden operational attribute when it should be shown ('hide none')", deltaFormattedHideNone.contains("createTimestamp:"));
assertTrue("hidden auxiliary attribute (family name) when it should be shown ('hide none')", deltaFormattedHideNone.contains("SPARROW"));
assertTrue("hidden password change when it should be shown ('hide none')", deltaFormattedHideNone.contains("(protected string)"));
assertTrue("hidden standard attribute when it should be shown ('hide none')", deltaFormattedHideNone.contains("BLACK PEARL"));
assertTrue("shown operational attribute when it should be hidden ('hide oper')", !deltaFormattedHideOper.contains("createTimestamp:"));
assertTrue("hidden auxiliary attribute (family name) when it should be shown ('hide oper')", deltaFormattedHideOper.contains("SPARROW"));
assertTrue("hidden password change when it should be shown ('hide oper')", deltaFormattedHideOper.contains("(protected string)"));
assertTrue("hidden standard attribute when it should be shown ('hide oper')", deltaFormattedHideOper.contains("BLACK PEARL"));
assertTrue("shown auxiliary attribute (metadata) when it should be hidden ('hide aux')", !deltaFormattedHideAux.contains("createTimestamp:"));
assertTrue("shown auxiliary attribute (family name) when it should be hidden ('hide aux')", !deltaFormattedHideAux.contains("SPARROW"));
assertTrue("hidden standard attribute when it should be shown ('hide aux')", deltaFormattedHideAux.contains("BLACK PEARL"));
assertTrue("shown operational attribute when it should be hidden ('hide aux and oper')", !deltaFormattedHideAuxAndOper.contains("createTimestamp:"));
assertTrue("shown auxiliary attribute (family name) when it should be hidden ('hide aux and oper')", !deltaFormattedHideAuxAndOper.contains("SPARROW"));
assertTrue("hidden standard attribute when it should be shown ('hide aux and oper')", deltaFormattedHideAuxAndOper.contains("BLACK PEARL"));
}
private void checkNotes(String notification) {
String NOTES_DELIMITER = "Notes:";
int i = notification.indexOf(NOTES_DELIMITER);
if (i == -1) {
throw new AssertionError("No Notes section in " + notification);
}
String notes = notification.substring(i);
assertFalse(notes.contains("Assignment #1"));
assertFalse(notes.contains("Assignment #2"));
assertFalse(notes.contains("Assignment #3"));
assertTrue(notes.contains("Assignment[1]"));
assertTrue(notes.contains("Assignment[2]"));
assertFalse(notes.contains("Assignment[3]"));
}
@Test
public void test030FormatAccount() throws Exception {
// GIVEN
PrismObject<ShadowType> jack = PrismTestUtil.parseObject(new File(ACCOUNT_JACK_FILE));
System.out.println(jack.debugDump());
// WHEN
String jackFormattedHideNone = textFormatter.formatAccountAttributes(jack.asObjectable(), null, true);
System.out.println("no hidden paths + show operational attributes: " + jackFormattedHideNone);
String jackFormattedHideAux = textFormatter.formatAccountAttributes(jack.asObjectable(), auxiliaryPaths, true);
System.out.println("hide auxiliary paths + show operational attributes: " + jackFormattedHideAux);
// THEN
final String NAME = "Name: jack";
final String PASSWORD = "(protected string)";
final String ADMINISTRATIVE_STATUS = "Administrative status: ENABLED";
final String EFFECTIVE_STATUS = "Effective status: ENABLED";
assertTrue("account name is not shown", jackFormattedHideNone.contains(NAME));
assertTrue("account password is not shown", jackFormattedHideNone.contains(PASSWORD));
assertTrue("administrative status is not shown", jackFormattedHideNone.contains(ADMINISTRATIVE_STATUS));
assertTrue("effective status is not shown", jackFormattedHideNone.contains(EFFECTIVE_STATUS));
assertTrue("account name is not shown", jackFormattedHideAux.contains(NAME));
assertTrue("account password is not shown", jackFormattedHideAux.contains(PASSWORD));
assertTrue("administrative status is not shown", jackFormattedHideAux.contains(ADMINISTRATIVE_STATUS));
assertTrue("effective status is shown although it should be hidden", !jackFormattedHideAux.contains(EFFECTIVE_STATUS));
// AssertJUnit.assertTrue("hidden operational attribute when it should be shown ('hide none')", jackFormattedHideNone.contains("createTimestamp:"));
// AssertJUnit.assertTrue("hidden auxiliary attribute (effective status) when it should be shown ('hide none')", jackFormattedHideNone.contains("Effective Status: ENABLED"));
// AssertJUnit.assertTrue("hidden auxiliary attribute (family name) when it should be shown ('hide none')", jackFormattedHideNone.contains("Family Name: Sparrow"));
// AssertJUnit.assertTrue("hidden standard attribute when it should be shown ('hide none')", jackFormattedHideNone.contains("ship: Black Pearl"));
//
// AssertJUnit.assertTrue("shown operational attribute when it should be hidden ('hide oper')", !jackFormattedHideOper.contains("createTimestamp:"));
// AssertJUnit.assertTrue("hidden auxiliary attribute when it should be shown ('hide oper')", jackFormattedHideOper.contains("Effective Status: ENABLED"));
// AssertJUnit.assertTrue("hidden auxiliary attribute (family name) when it should be shown ('hide oper')", jackFormattedHideOper.contains("Family Name: Sparrow"));
// AssertJUnit.assertTrue("hidden standard attribute when it should be shown ('hide oper')", jackFormattedHideOper.contains("ship: Black Pearl"));
//
// AssertJUnit.assertTrue("shown auxiliary attribute (metadata) when it should be hidden ('hide aux')", !jackFormattedHideAux.contains("createTimestamp:"));
// AssertJUnit.assertTrue("shown auxiliary attribute (family name) when it should be hidden ('hide aux')", !jackFormattedHideAux.contains("Family Name: Sparrow"));
// AssertJUnit.assertTrue("shown auxiliary attribute (effective status) when it should be hidden ('hide aux')", !jackFormattedHideAux.contains("Effective Status: ENABLED"));
// AssertJUnit.assertTrue("hidden standard attribute when it should be shown ('hide aux')", jackFormattedHideAux.contains("ship: Black Pearl"));
//
// AssertJUnit.assertTrue("shown operational attribute when it should be hidden ('hide aux and oper')", !jackFormattedHideAuxAndOper.contains("createTimestamp:"));
// AssertJUnit.assertTrue("shown auxiliary attribute (effective status) when it should be hidden ('hide aux and oper')", !jackFormattedHideAuxAndOper.contains("Effective Status: ENABLED"));
// AssertJUnit.assertTrue("shown auxiliary attribute (family name) when it should be hidden ('hide aux and oper')", !jackFormattedHideAuxAndOper.contains("Family Name: Sparrow"));
// AssertJUnit.assertTrue("hidden standard attribute when it should be shown ('hide aux and oper')", jackFormattedHideAuxAndOper.contains("ship: Black Pearl"));
}
private ObjectDelta<UserType> parseDelta(String filename) throws JAXBException, SchemaException, IOException {
ObjectModificationType modElement = PrismTestUtil.parseAtomicValue(new File(filename), ObjectModificationType.COMPLEX_TYPE);
return DeltaConvertor.createObjectDelta(modElement, UserType.class, prismContext);
}
}