Change license header, remove stale pkg files.
[shibboleth/cpp-opensaml.git] / samltest / internal.h
1 /**
2  * Licensed to the University Corporation for Advanced Internet
3  * Development, Inc. (UCAID) under one or more contributor license
4  * agreements. See the NOTICE file distributed with this work for
5  * additional information regarding copyright ownership.
6  *
7  * UCAID licenses this file to you under the Apache License,
8  * Version 2.0 (the "License"); you may not use this file except
9  * in compliance with the License. You may obtain a copy of the
10  * License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing,
15  * software distributed under the License is distributed on an
16  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
17  * either express or implied. See the License for the specific
18  * language governing permissions and limitations under the License.
19  */
20
21 #ifdef WIN32
22 # define _CRT_SECURE_NO_DEPRECATE 1
23 # define _CRT_NONSTDC_NO_DEPRECATE 1
24 #endif
25
26 #include <cxxtest/TestSuite.h>
27
28 #include <saml/exceptions.h>
29 #include <saml/util/SAMLConstants.h>
30
31 #include <fstream>
32 #include <xmltooling/XMLObject.h>
33 #include <xmltooling/XMLObjectBuilder.h>
34 #include <xmltooling/XMLToolingConfig.h>
35 #include <xmltooling/util/DateTime.h>
36 #include <xmltooling/util/ParserPool.h>
37 #include <xmltooling/validation/Validator.h>
38
39 using namespace xmltooling;
40 using namespace xercesc;
41 using namespace std;
42
43 extern string data_path;
44
45 class SAMLObjectBaseTestCase
46 {
47 protected:
48     /** Location of file containing a single element with NO optional attributes */
49     string singleElementFile;
50
51     /** Location of file containing a single element with all optional attributes */
52     string singleElementOptionalAttributesFile;
53
54     /** Location of file containing a single element with child elements */
55     string childElementsFile;
56
57     /** The expected result of a marshalled single element with no optional attributes */
58     DOMDocument* expectedDOM;
59
60     /** The expected result of a marshalled single element with all optional attributes */
61     DOMDocument* expectedOptionalAttributesDOM;
62
63     /** The expected result of a marshalled single element with child elements */
64     DOMDocument* expectedChildElementsDOM;
65
66     /**
67      * Unmarshalls an element file into its SAML XMLObject.
68      * 
69      * @return the SAML XMLObject from the file
70      */
71     XMLObject* unmarshallElement(string elementFile) {
72         try {
73             ParserPool& p=XMLToolingConfig::getConfig().getParser();
74             ifstream fs(elementFile.c_str());
75             DOMDocument* doc = p.parse(fs);
76             const XMLObjectBuilder* b = XMLObjectBuilder::getBuilder(doc->getDocumentElement());
77             return b->buildFromDocument(doc);
78         }
79         catch (XMLToolingException& e) {
80             TS_TRACE(typeid(e).name());
81             TS_TRACE(e.what());
82             throw;
83         }
84     }
85
86     void assertEquals(const char* failMessage, DOMDocument* expectedDOM, XMLObject* xmlObject, bool canMarshall=true) {
87         DOMElement* generatedDOM = xmlObject->getDOM();
88         if (!generatedDOM) {
89             if (!canMarshall) {
90                 TSM_ASSERT("DOM not available", false);
91             }
92             else {
93                 generatedDOM = xmlObject->marshall();
94             }
95         }
96         if (!generatedDOM->isEqualNode(expectedDOM->getDocumentElement())) {
97             string buf;
98             XMLHelper::serialize(generatedDOM, buf);
99             TS_TRACE(buf.c_str());
100             buf.erase();
101             XMLHelper::serialize(expectedDOM->getDocumentElement(), buf);
102             TS_TRACE(buf.c_str());
103             TSM_ASSERT(failMessage, false);
104         }
105     }
106
107     void assertEquals(DOMDocument* expectedDOM, XMLObject* xmlObject, bool canMarshall=true) {
108         assertEquals("Marshalled DOM was not the same as the expected DOM", expectedDOM, xmlObject, canMarshall);
109         delete xmlObject;
110     }
111
112     void assertEquals(const char* failMessage, const XMLCh* expectedString, const XMLCh* testString) {
113         char* buf = nullptr;
114         if (!XMLString::equals(expectedString, testString)) {
115             buf = XMLString::transcode(testString);
116             TS_TRACE(buf ? buf : "(NULL)");
117             XMLString::release(&buf);
118             buf = XMLString::transcode(expectedString);
119             TS_TRACE(buf ? buf : "(NULL)");
120             XMLString::release(&buf);
121             TSM_ASSERT(failMessage, false);
122         }
123     }
124
125 public:
126     void setUp() {
127         ParserPool& p=XMLToolingConfig::getConfig().getParser();
128         if (!singleElementFile.empty()) {
129             ifstream fs(singleElementFile.c_str());
130             expectedDOM = p.parse(fs);
131         }
132
133         if (!singleElementOptionalAttributesFile.empty()) {
134             ifstream fs(singleElementOptionalAttributesFile.c_str());
135             expectedOptionalAttributesDOM = p.parse(fs);
136         }
137
138         if (!childElementsFile.empty()) {
139             ifstream fs(childElementsFile.c_str());
140             expectedChildElementsDOM = p.parse(fs);
141         }
142     }
143     
144     void tearDown() {
145         if (expectedDOM) expectedDOM->release();
146         if (expectedOptionalAttributesDOM) expectedOptionalAttributesDOM->release();
147         if (expectedChildElementsDOM) expectedChildElementsDOM->release();
148     }
149 };
150
151 class SAMLObjectValidatorBaseTestCase : virtual public SAMLObjectBaseTestCase {
152
153     public:
154         SAMLObjectValidatorBaseTestCase() : target(nullptr), targetQName(nullptr), builder(nullptr), validator(nullptr) {}
155
156         virtual ~SAMLObjectValidatorBaseTestCase() {
157             delete validator;
158         }
159
160     protected: 
161         /** The primary XMLObject which will be the target of a given test run */
162         XMLObject* target;
163
164         /** QName of the object to be tested */
165         xmltooling::QName targetQName;
166
167         /** Builder for XMLObjects of type targetQName */
168         const XMLObjectBuilder* builder;
169
170         /** Validator for the type corresponding to the test target */
171         Validator* validator;
172
173         /** Subclasses should override to populate required elements and attributes */
174         virtual void populateRequiredData() { }
175
176         /**
177          * Asserts that the validation of default test XMLObject target 
178          * was successful, as expected.
179          * 
180          * @param message
181          */
182         void assertValidationPass(const char* message) {
183             assertValidationPass(message, target);
184         }
185
186         /**
187          * Asserts that the validation of the specified XMLObject target 
188          * was successful, as expected.
189          * 
190          * @param message
191          * @param validateTarget
192          */
193         void assertValidationPass(const char* message, XMLObject* validateTarget) {
194             try {
195                 validator->validate(validateTarget);
196             } catch (ValidationException &e) {
197                 TS_TRACE(message);
198                 TS_TRACE("Expected success, but validation failure raised following ValidationException: ");
199                 TS_FAIL(e.getMessage());
200             }
201         }
202
203         /**
204          * Asserts that the validation of the default test XMLObject target 
205          * failed, as expected.
206          * 
207          * @param message
208          */
209         void assertValidationFail(const char* message) {
210             assertValidationFail(message, target);
211         }
212
213         /**
214          * Asserts that the validation of the specified XMLObject target 
215          * failed, as expected.
216          * 
217          * @param message
218          * @param validateTarget
219          */
220         void assertValidationFail(const char* message, XMLObject* validateTarget) {
221             try {
222                 validator->validate(validateTarget);
223                 TS_TRACE(message);
224                 TS_FAIL("Validation success, expected failure to raise ValidationException");
225             } catch (ValidationException&) {
226             }
227         }
228
229         /**
230          * Build an XMLObject based on the specified QName
231          * 
232          * @param targetQName QName of the type of object to build
233          * @returns new XMLObject of type targetQName
234          */
235         XMLObject* buildXMLObject(xmltooling::QName &targetQName) {
236             // Create the builder on the first request only, for efficiency
237             if (builder == nullptr) {
238                 builder = XMLObjectBuilder::getBuilder(targetQName);
239                 TSM_ASSERT("Unable to retrieve builder for object QName: " + targetQName.toString(), builder!=nullptr);
240             }
241             return builder->buildObject(targetQName.getNamespaceURI(), targetQName.getLocalPart(), targetQName.getPrefix());
242
243         }
244
245     public:
246
247         void setUp() {
248             SAMLObjectBaseTestCase::setUp();
249
250             TSM_ASSERT("targetQName was empty", targetQName.hasLocalPart());
251
252             TSM_ASSERT("validator was null", validator!=nullptr);
253
254             target = buildXMLObject(targetQName);
255             TSM_ASSERT("XMLObject target was NULL", target!=nullptr);
256             populateRequiredData();
257         }
258
259         void tearDown() {
260             delete target;
261             target=nullptr;
262             SAMLObjectBaseTestCase::tearDown();
263         }
264
265 };
266