Set fourth file version digit to signify rebuild.
[shibboleth/cpp-opensaml.git] / samltest / internal.h
index 251b3c1..2389848 100644 (file)
@@ -1,30 +1,43 @@
-/*
- *  Copyright 2001-2006 Internet2
- * 
- * 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
+/**
+ * Licensed to the University Corporation for Advanced Internet
+ * Development, Inc. (UCAID) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for
+ * additional information regarding copyright ownership.
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ * UCAID 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
  *
- * 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.
+ * 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.
  */
 
+#ifdef WIN32
+# define _CRT_SECURE_NO_DEPRECATE 1
+# define _CRT_NONSTDC_NO_DEPRECATE 1
+#endif
+
 #include <cxxtest/TestSuite.h>
 
-#include <fstream>
 #include <saml/exceptions.h>
-#include <saml/SAMLConfig.h>
 #include <saml/util/SAMLConstants.h>
+
+#include <fstream>
 #include <xmltooling/XMLObject.h>
 #include <xmltooling/XMLObjectBuilder.h>
+#include <xmltooling/XMLToolingConfig.h>
+#include <xmltooling/util/DateTime.h>
+#include <xmltooling/util/ParserPool.h>
+#include <xmltooling/validation/Validator.h>
 
-using namespace opensaml;
 using namespace xmltooling;
+using namespace xercesc;
 using namespace std;
 
 extern string data_path;
@@ -64,21 +77,53 @@ protected:
             return b->buildFromDocument(doc);
         }
         catch (XMLToolingException& e) {
+            TS_TRACE(typeid(e).name());
             TS_TRACE(e.what());
             throw;
         }
     }
 
-    void assertEquals(const char* failMessage, DOMDocument* expectedDOM, XMLObject* xmlObject) {
-        DOMElement* generatedDOM = xmlObject->marshall();
-        TSM_ASSERT(failMessage,generatedDOM->isEqualNode(expectedDOM->getDocumentElement()));
+    void assertEquals(const char* failMessage, DOMDocument* expectedDOM, XMLObject* xmlObject, bool canMarshall=true) {
+        DOMElement* generatedDOM = xmlObject->getDOM();
+        if (!generatedDOM) {
+            if (!canMarshall) {
+                TSM_ASSERT("DOM not available", false);
+            }
+            else {
+                generatedDOM = xmlObject->marshall();
+            }
+        }
+        if (!generatedDOM->isEqualNode(expectedDOM->getDocumentElement())) {
+            string buf;
+            XMLHelper::serialize(generatedDOM, buf);
+            TS_TRACE(buf.c_str());
+            buf.erase();
+            XMLHelper::serialize(expectedDOM->getDocumentElement(), buf);
+            TS_TRACE(buf.c_str());
+            TSM_ASSERT(failMessage, false);
+        }
     }
 
-    void assertEquals(DOMDocument* expectedDOM, XMLObject* xmlObject) {
-        assertEquals("Marshalled DOM was not the same as the expected DOM", expectedDOM, xmlObject);
+    void assertEquals(DOMDocument* expectedDOM, XMLObject* xmlObject, bool canMarshall=true) {
+        xmlObject->releaseThisAndChildrenDOM();
+        auto_ptr<XMLObject> cloned(xmlObject->clone());
+        assertEquals("Marshalled DOM was not the same as the expected DOM", expectedDOM, cloned.get(), canMarshall);
         delete xmlObject;
     }
 
+    void assertEquals(const char* failMessage, const XMLCh* expectedString, const XMLCh* testString) {
+        char* buf = nullptr;
+        if (!XMLString::equals(expectedString, testString)) {
+            buf = XMLString::transcode(testString);
+            TS_TRACE(buf ? buf : "(NULL)");
+            XMLString::release(&buf);
+            buf = XMLString::transcode(expectedString);
+            TS_TRACE(buf ? buf : "(NULL)");
+            XMLString::release(&buf);
+            TSM_ASSERT(failMessage, false);
+        }
+    }
+
 public:
     void setUp() {
         ParserPool& p=XMLToolingConfig::getConfig().getParser();
@@ -104,3 +149,120 @@ public:
         if (expectedChildElementsDOM) expectedChildElementsDOM->release();
     }
 };
+
+class SAMLObjectValidatorBaseTestCase : virtual public SAMLObjectBaseTestCase {
+
+    public:
+        SAMLObjectValidatorBaseTestCase() : target(nullptr), targetQName(nullptr), builder(nullptr), validator(nullptr) {}
+
+        virtual ~SAMLObjectValidatorBaseTestCase() {
+            delete validator;
+        }
+
+    protected: 
+        /** The primary XMLObject which will be the target of a given test run */
+        XMLObject* target;
+
+        /** QName of the object to be tested */
+        xmltooling::QName targetQName;
+
+        /** Builder for XMLObjects of type targetQName */
+        const XMLObjectBuilder* builder;
+
+        /** Validator for the type corresponding to the test target */
+        Validator* validator;
+
+        /** Subclasses should override to populate required elements and attributes */
+        virtual void populateRequiredData() { }
+
+        /**
+         * Asserts that the validation of default test XMLObject target 
+         * was successful, as expected.
+         * 
+         * @param message
+         */
+        void assertValidationPass(const char* message) {
+            assertValidationPass(message, target);
+        }
+
+        /**
+         * Asserts that the validation of the specified XMLObject target 
+         * was successful, as expected.
+         * 
+         * @param message
+         * @param validateTarget
+         */
+        void assertValidationPass(const char* message, XMLObject* validateTarget) {
+            try {
+                validator->validate(validateTarget);
+            } catch (ValidationException &e) {
+                TS_TRACE(message);
+                TS_TRACE("Expected success, but validation failure raised following ValidationException: ");
+                TS_FAIL(e.getMessage());
+            }
+        }
+
+        /**
+         * Asserts that the validation of the default test XMLObject target 
+         * failed, as expected.
+         * 
+         * @param message
+         */
+        void assertValidationFail(const char* message) {
+            assertValidationFail(message, target);
+        }
+
+        /**
+         * Asserts that the validation of the specified XMLObject target 
+         * failed, as expected.
+         * 
+         * @param message
+         * @param validateTarget
+         */
+        void assertValidationFail(const char* message, XMLObject* validateTarget) {
+            try {
+                validator->validate(validateTarget);
+                TS_TRACE(message);
+                TS_FAIL("Validation success, expected failure to raise ValidationException");
+            } catch (ValidationException&) {
+            }
+        }
+
+        /**
+         * Build an XMLObject based on the specified QName
+         * 
+         * @param targetQName QName of the type of object to build
+         * @returns new XMLObject of type targetQName
+         */
+        XMLObject* buildXMLObject(xmltooling::QName &targetQName) {
+            // Create the builder on the first request only, for efficiency
+            if (builder == nullptr) {
+                builder = XMLObjectBuilder::getBuilder(targetQName);
+                TSM_ASSERT("Unable to retrieve builder for object QName: " + targetQName.toString(), builder!=nullptr);
+            }
+            return builder->buildObject(targetQName.getNamespaceURI(), targetQName.getLocalPart(), targetQName.getPrefix());
+
+        }
+
+    public:
+
+        void setUp() {
+            SAMLObjectBaseTestCase::setUp();
+
+            TSM_ASSERT("targetQName was empty", targetQName.hasLocalPart());
+
+            TSM_ASSERT("validator was null", validator!=nullptr);
+
+            target = buildXMLObject(targetQName);
+            TSM_ASSERT("XMLObject target was NULL", target!=nullptr);
+            populateRequiredData();
+        }
+
+        void tearDown() {
+            delete target;
+            target=nullptr;
+            SAMLObjectBaseTestCase::tearDown();
+        }
+
+};
+