/* * Copyright (c) 2010-2015 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.model.intest.negative; import java.io.File; import java.util.Map; import javax.xml.namespace.QName; import com.evolveum.midpoint.prism.marshaller.XNodeProcessorEvaluationMode; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext.ClassMode; import org.springframework.test.context.ContextConfiguration; import org.testng.AssertJUnit; import org.testng.annotations.Test; import com.evolveum.midpoint.model.intest.AbstractInitializedModelIntegrationTest; import com.evolveum.midpoint.prism.xnode.PrimitiveXNode; import com.evolveum.midpoint.prism.xnode.ValueParser; import com.evolveum.midpoint.schema.constants.ObjectTypes; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.test.DummyResourceContoller; import com.evolveum.midpoint.test.util.TestUtil; import com.evolveum.midpoint.util.DOMUtil; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.xml.ns._public.common.api_types_3.ObjectDeltaListType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ModelExecuteOptionsType; import com.evolveum.midpoint.xml.ns._public.common.fault_3.FaultMessage; import com.evolveum.midpoint.xml.ns._public.common.fault_3.FaultType; import com.evolveum.midpoint.xml.ns._public.common.fault_3.SchemaViolationFaultType; import com.evolveum.prism.xml.ns._public.types_3.ChangeTypeType; import com.evolveum.prism.xml.ns._public.types_3.ItemDeltaType; import com.evolveum.prism.xml.ns._public.types_3.ItemPathType; import com.evolveum.prism.xml.ns._public.types_3.ModificationTypeType; import com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType; import com.evolveum.prism.xml.ns._public.types_3.RawType; /** * @author semancik * */ @ContextConfiguration(locations = {"classpath:ctx-model-intest-test-main.xml"}) @DirtiesContext(classMode = ClassMode.AFTER_CLASS) public class TestModelWebServiceNegative extends AbstractInitializedModelIntegrationTest { public static final File TEST_DIR = new File("src/test/resources/crud"); public static final File TEST_CONTRACT_DIR = new File("src/test/resources/contract"); public static final File RESOURCE_MAROON_FILE = new File(TEST_DIR, "resource-dummy-maroon.xml"); public static final String RESOURCE_MAROON_OID = "10000000-0000-0000-0000-00000000e104"; private static final String USER_MORGAN_OID = "c0c010c0-d34d-b33f-f00d-171171117777"; private static final String USER_BLACKBEARD_OID = "c0c010c0-d34d-b33f-f00d-161161116666"; private static String accountOid; /** * First tests are positive, to make sure that this method works. */ @Test public void test100ModifyAccountExplicitType() throws Exception { final String TEST_NAME = "test100ModifyUserAddAccount"; TestUtil.displayTestTile(this, TEST_NAME); // GIVEN Task task = taskManager.createTaskInstance(TestModelWebServiceNegative.class.getName() + "." + TEST_NAME); ObjectDeltaType objectChange = createShadowReplaceChange(ACCOUNT_SHADOW_GUYBRUSH_OID, "attributes/"+DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_GOSSIP_NAME, "foo", DOMUtil.XSD_STRING); ObjectDeltaListType deltaList = new ObjectDeltaListType(); deltaList.getDelta().add(objectChange); // WHEN modelWeb.executeChanges(deltaList, null); // THEN // Check account in dummy resource assertDefaultDummyAccount(ACCOUNT_GUYBRUSH_DUMMY_USERNAME, ACCOUNT_GUYBRUSH_DUMMY_FULLNAME, true); assertDummyAccountAttribute(null, ACCOUNT_GUYBRUSH_DUMMY_USERNAME, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_GOSSIP_NAME, "foo"); } /** * First tests are positive, to make sure that this method works. */ @Test public void test110ModifyAccountImplicitType() throws Exception { final String TEST_NAME = "test110ModifyAccountImplicitType"; TestUtil.displayTestTile(this, TEST_NAME); // GIVEN Task task = taskManager.createTaskInstance(TestModelWebServiceNegative.class.getName() + "." + TEST_NAME); ObjectDeltaType objectChange = createShadowReplaceChange(ACCOUNT_SHADOW_GUYBRUSH_OID, "attributes/"+DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_GOSSIP_NAME, "bar", null); ObjectDeltaListType deltaList = new ObjectDeltaListType(); deltaList.getDelta().add(objectChange); // WHEN modelWeb.executeChanges(deltaList, null); // THEN // Check account in dummy resource assertDefaultDummyAccount(ACCOUNT_GUYBRUSH_DUMMY_USERNAME, ACCOUNT_GUYBRUSH_DUMMY_FULLNAME, true); assertDummyAccountAttribute(null, ACCOUNT_GUYBRUSH_DUMMY_USERNAME, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_GOSSIP_NAME, "bar"); } @Test public void test200ModifyAccountWrongExplicitType() throws Exception { final String TEST_NAME = "test200ModifyAccountWrongExplicitType"; TestUtil.displayTestTile(this, TEST_NAME); // GIVEN Task task = taskManager.createTaskInstance(TestModelWebServiceNegative.class.getName() + "." + TEST_NAME); ObjectDeltaType objectChange = createShadowReplaceChange(ACCOUNT_SHADOW_GUYBRUSH_OID, "attributes/"+DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_GOSSIP_NAME, "42", DOMUtil.XSD_INT); ObjectDeltaListType deltaList = new ObjectDeltaListType(); deltaList.getDelta().add(objectChange); // WHEN, THEN //assertExecuteChangesFailure(deltaList, null, SchemaViolationFaultType.class, "The value of type", "cannot be applied to attribute"); assertExecuteChangesFailure(deltaList, null, SchemaViolationFaultType.class, "Expected", "but got class"); } private void assertExecuteChangesFailure(ObjectDeltaListType deltaList, ModelExecuteOptionsType options, Class<? extends FaultType> expectedFaultTypeClass, String... messagePatterns) throws Exception { try { modelWeb.executeChanges(deltaList, options); AssertJUnit.fail("Unexpected success"); } catch (FaultMessage f) { FaultType faultInfo = f.getFaultInfo(); if (expectedFaultTypeClass.isAssignableFrom(faultInfo.getClass())) { // This is expected String message = f.getMessage(); for (String pattern: messagePatterns) { if (!message.contains(pattern)) { AssertJUnit.fail("Exception message does not contain pattern '"+pattern+"': "+message); } } } else { AssertJUnit.fail("Expected fault type of "+expectedFaultTypeClass+" but got "+faultInfo.getClass()); } } } // TODO: more negative tests private ObjectDeltaType createShadowReplaceChange(String oid, String path, final String value, QName type) { ObjectDeltaType objectChange = new ObjectDeltaType(); objectChange.setOid(oid); objectChange.setChangeType(ChangeTypeType.MODIFY); objectChange.setObjectType(ObjectTypes.SHADOW.getTypeQName()); ItemDeltaType itemDeltaType = new ItemDeltaType(); itemDeltaType.setModificationType(ModificationTypeType.REPLACE); ItemPathType itemPath = new ItemPathType(path); itemDeltaType.setPath(itemPath); PrimitiveXNode<String> xnode = new PrimitiveXNode<>(); ValueParser<String> valueParser = new ValueParser<String>() { @Override public String parse(QName typeName, XNodeProcessorEvaluationMode mode) throws SchemaException { return value; } @Override public boolean isEmpty() { return false; } @Override public String getStringValue() { return value; } @Override public Map<String, String> getPotentiallyRelevantNamespaces() { throw new UnsupportedOperationException(); } }; xnode.setValueParser(valueParser); if (type != null) { xnode.setExplicitTypeDeclaration(true); xnode.setTypeQName(type); } RawType rawValue = new RawType(xnode, prismContext); itemDeltaType.getValue().add(rawValue); objectChange.getItemDelta().add(itemDeltaType); return objectChange; } }