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