New test.
[mono.git] / mcs / class / System.ServiceModel / Test / System.ServiceModel.Channels / MessageTest.cs
1 //
2 // MessageTest.cs
3 //
4 // Author:
5 //      Atsushi Enomoto <atsushi@ximian.com>
6 //
7 // Copyright (C) 2006 Novell, Inc.  http://www.novell.com
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28 using System;
29 using System.Globalization;
30 using System.IO;
31 using System.Runtime.Serialization;
32 using System.ServiceModel;
33 using System.ServiceModel.Channels;
34 using System.Xml;
35 using NUnit.Framework;
36
37 namespace MonoTests.System.ServiceModel.Channels
38 {
39         [TestFixture]
40         public class MessageTest
41         {
42                 public static string GetSerializedMessage (Message msg)
43                 {
44                         StringWriter sw = new StringWriter ();
45                         XmlWriterSettings settings = new XmlWriterSettings ();
46                         settings.OmitXmlDeclaration = true;
47                         using (XmlWriter xw = XmlWriter.Create (sw, settings)) {
48                                 msg.WriteMessage (xw);
49                         }
50                         return sw.ToString ();
51                 }
52
53                 [Test]
54                 public void CreateNullAction ()
55                 {
56                         StringWriter sw = new StringWriter ();
57                         using (XmlWriter w = XmlWriter.Create (sw)) {
58                                 Message.CreateMessage (MessageVersion.Default, (string) null).WriteMessage (w);
59                         }
60                         Assert.IsTrue (sw.ToString ().IndexOf ("Action") < 0);
61                 }
62
63                 [Test]
64                 [ExpectedException (typeof (ArgumentNullException))]
65                 public void CreateNullVersion ()
66                 {
67                         StringWriter sw = new StringWriter ();
68                         Message.CreateMessage (null, "http://tempuri.org/MyAction");
69                 }
70
71                 [Test]
72                 public void CreateSimpleAndWrite ()
73                 {
74                         string xml = @"<s:Envelope xmlns:a=""http://www.w3.org/2005/08/addressing"" xmlns:s=""http://www.w3.org/2003/05/soap-envelope""><s:Header><a:Action s:mustUnderstand=""1"">Ack</a:Action></s:Header><s:Body /></s:Envelope>";
75
76                         Message msg = Message.CreateMessage (
77                                 MessageVersion.Default, "Ack");
78                         // It should be XML comparison, not string comparison
79                         Assert.AreEqual (xml, GetSerializedMessage (msg));
80                 }
81
82                 [Test]
83                 public void CreateSimpleNonPrimitive ()
84                 {
85                         string xml = @"<s:Envelope xmlns:a=""http://www.w3.org/2005/08/addressing"" xmlns:s=""http://www.w3.org/2003/05/soap-envelope""><s:Header><a:Action s:mustUnderstand=""1"">Sample1</a:Action></s:Header><s:Body><MessageTest.Sample1 xmlns:i=""http://www.w3.org/2001/XMLSchema-instance"" xmlns=""http://schemas.datacontract.org/2004/07/MonoTests.System.ServiceModel.Channels""><Member1>member1</Member1><Member2><Member>sample2 member</Member></Member2></MessageTest.Sample1></s:Body></s:Envelope>";
86
87                         Message msg = Message.CreateMessage (
88                                 MessageVersion.Default, "Sample1", new Sample1 ());
89                         // It should be XML comparison, not string comparison
90                         Assert.AreEqual (xml, GetSerializedMessage (msg));
91                 }
92
93                 [DataContract]
94                 class Sample1
95                 {
96                         [DataMember]
97                         public string Member1 = "member1";
98
99                         [DataMember]
100                         public Sample2 Member2 = new Sample2 ();
101                 }
102
103                 [DataContract]
104                 class Sample2
105                 {
106                         [DataMember]
107                         public string Member = "sample2 member";
108                 }
109
110                 [Test]
111                 public void CreateSimpleSoap11WSA1_0 ()
112                 {
113                         string xml = @"<s:Envelope xmlns:a=""http://www.w3.org/2005/08/addressing"" xmlns:s=""http://schemas.xmlsoap.org/soap/envelope/""><s:Header><a:Action s:mustUnderstand=""1"">http://tempuri.org/IFoo/Echo</a:Action></s:Header><s:Body><string xmlns=""http://schemas.microsoft.com/2003/10/Serialization/"">hoge</string></s:Body></s:Envelope>";
114
115                         Message msg = Message.CreateMessage (
116                                 MessageVersion.Soap11WSAddressing10,
117                                 "http://tempuri.org/IFoo/Echo",
118                                 "hoge");
119                         // It should be XML comparison, not string comparison
120                         Assert.AreEqual (xml, GetSerializedMessage (msg));
121                 }
122
123                 [Test]
124                 public void CreateFaultMessageAndWrite ()
125                 {
126                         string xml = @"<s:Envelope xmlns:a=""http://www.w3.org/2005/08/addressing"" xmlns:s=""http://www.w3.org/2003/05/soap-envelope""><s:Header><a:Action s:mustUnderstand=""1"">http://www.w3.org/2005/08/addressing/fault</a:Action></s:Header><s:Body><s:Fault><s:Code><s:Value xmlns:a=""urn:me"">a:me</s:Value></s:Code><s:Reason><s:Text xml:lang="""">am so lazy</s:Text></s:Reason></s:Fault></s:Body></s:Envelope>";
127
128                         FaultCode fc = new FaultCode ("me", "urn:me");
129                         FaultReasonText ft = new FaultReasonText ("am so lazy", CultureInfo.InvariantCulture);
130                         Message msg = Message.CreateMessage (
131                                 MessageVersion.Default,
132                                 MessageFault.CreateFault (fc, new FaultReason (ft)),
133                                 "http://www.w3.org/2005/08/addressing/fault");
134                         // It should be XML comparison, not string comparison
135                         Assert.AreEqual (xml, GetSerializedMessage (msg));
136                 }
137
138                 [Test]
139                 public void CreateAndWriteBodyObject ()
140                 {
141                         string xml = @"<s:Envelope xmlns:a=""http://www.w3.org/2005/08/addressing"" xmlns:s=""http://www.w3.org/2003/05/soap-envelope""><s:Header><a:Action s:mustUnderstand=""1"">Ack</a:Action></s:Header><s:Body><string xmlns=""http://schemas.microsoft.com/2003/10/Serialization/"">TEST</string></s:Body></s:Envelope>";
142
143                         Message msg = Message.CreateMessage (
144                                 MessageVersion.Default, "Ack", "TEST");
145                         // It should be XML comparison, not string comparison
146                         Assert.AreEqual (xml, GetSerializedMessage (msg));
147                 }
148
149                 // From XmlReader
150
151                 [Test]
152                 public void CreateFromXmlReader ()
153                 {
154                         string xml = @"<s:Envelope xmlns:a=""http://www.w3.org/2005/08/addressing"" xmlns:s=""http://www.w3.org/2003/05/soap-envelope""><s:Header><a:Action s:mustUnderstand=""1"">Ack</a:Action><TestHeaderItem>test</TestHeaderItem></s:Header><s:Body></s:Body></s:Envelope>";
155
156                         XmlReader r = XmlReader.Create (new StringReader (xml));
157                         Message msg = Message.CreateMessage (r, 10000, MessageVersion.Default);
158                         Assert.AreEqual (MessageVersion.Default, msg.Version, "#2");
159                         Assert.AreEqual (2, msg.Headers.Count, "#4");
160                         Assert.AreEqual ("Ack", msg.Headers.Action, "#3");
161                         Assert.IsNull (msg.Headers.FaultTo, "#5");
162                         Assert.IsNull (msg.Headers.From, "#6");
163                         Assert.IsNull (msg.Headers.MessageId, "#7");
164                         Assert.IsTrue (msg.IsEmpty, "#8");
165
166                         MessageHeaderInfo hi = msg.Headers [0];
167                         Assert.AreEqual ("Action", hi.Name, "#h1-1");
168                         Assert.AreEqual ("http://www.w3.org/2005/08/addressing", hi.Namespace, "#h1-2");
169                         Assert.AreEqual (String.Empty, hi.Actor, "#h1-3");
170                         Assert.IsTrue (hi.MustUnderstand, "#h1-4");
171                         Assert.IsFalse (hi.Relay, "#h1-5");
172                         Assert.IsFalse (hi.IsReferenceParameter, "#h1-6");
173
174                         int count = 0;
175
176                         /* FIXME: test UnderstoodHeaders later
177                         foreach (MessageHeaderInfo i in msg.Headers.UnderstoodHeaders) {
178                                 count++;
179                                 Assert.AreEqual ("", i.Actor, "#9");
180                                 Assert.IsFalse (i.IsReferenceParameter, "#10");
181                                 Assert.IsTrue (i.MustUnderstand, "#11");
182                                 Assert.AreEqual ("Action", i.Name, "#12");
183                                 Assert.AreEqual ("http://www.w3.org/2005/08/addressing", i.Namespace, "#13");
184                                 Assert.AreEqual (false, i.Relay, "#14");
185                         }
186                         Assert.AreEqual (1, count, "#15"); // allow only once
187                         */
188
189                         // MS implementation closes XmlReader regardless of
190                         // its initial state, which isn't good.
191                         //Assert.AreEqual (ReadState.Closed, r.ReadState, "#1");
192
193                         r = XmlReader.Create (new StringReader (xml));
194                         r.MoveToContent ();
195                         msg = Message.CreateMessage (r, 10000, MessageVersion.Default);
196                         // ditto
197                         // Assert.AreEqual (ReadState.Closed, r.ReadState, "#1-2");
198
199                         string xml2 = @"<Wrap><s:Envelope xmlns:a=""http://www.w3.org/2005/08/addressing"" xmlns:s=""http://www.w3.org/2003/05/soap-envelope""><s:Header><a:Action s:mustUnderstand=""1"">Ack</a:Action></s:Header><s:Body /></s:Envelope></Wrap>";
200
201                         r = XmlReader.Create (new StringReader (xml2));
202                         r.MoveToContent ();
203                         r.Read (); // s:Envelope
204                         msg = Message.CreateMessage (r, 10000, MessageVersion.Default);
205                         // ditto
206                         // Assert.AreEqual (ReadState.Closed, r.ReadState, "#1-3");
207                 }
208
209                 [Test]
210                 public void CreateFromXmlReader2 ()
211                 {
212                         string xml = @"<s:Envelope xmlns:s=""http://schemas.xmlsoap.org/soap/envelope/""><s:Body><string xmlns=""http://schemas.microsoft.com/2003/10/Serialization/"">hoge</string></s:Body></s:Envelope>";
213                         XmlReader r = XmlReader.Create (new StringReader (xml));
214                         Message msg = Message.CreateMessage (r, 10000, MessageVersion.Soap11WSAddressing10);
215                         Assert.AreEqual (0, msg.Headers.Count, "#1");
216                         Assert.IsNull (msg.Headers.Action, "#2");
217                         Assert.IsFalse (msg.IsEmpty, "#3");
218                         Assert.AreEqual ("hoge", msg.GetBody<string> (), "#4");
219                 }
220
221                 [Test]
222                 [ExpectedException (typeof (InvalidOperationException))]
223                 public void GetReaderAtBodyContentsEmptyError ()
224                 {
225                         string xml = @"<s:Envelope xmlns:a=""http://www.w3.org/2005/08/addressing"" xmlns:s=""http://www.w3.org/2003/05/soap-envelope""><s:Header></s:Header><s:Body></s:Body></s:Envelope>";
226
227                         XmlReader r = XmlReader.Create (new StringReader (xml));
228                         Message msg = Message.CreateMessage (r, 10000, MessageVersion.Default);
229                         msg.GetReaderAtBodyContents ();
230                 }
231
232                 [Test]
233                 [ExpectedException (typeof (InvalidOperationException))]
234                 public void GetReaderAtBodyContentsTwice ()
235                 {
236                         string xml = @"<s:Envelope xmlns:a=""http://www.w3.org/2005/08/addressing"" xmlns:s=""http://www.w3.org/2003/05/soap-envelope""><s:Header></s:Header><s:Body>TEST</s:Body></s:Envelope>";
237
238                         XmlReader r = XmlReader.Create (new StringReader (xml));
239                         Message msg = Message.CreateMessage (r, 10000, MessageVersion.Default);
240                         msg.GetReaderAtBodyContents ();
241                         msg.GetReaderAtBodyContents ();
242                 }
243
244                 [Test]
245                 public void GetReaderAtBodyContentsAfterSourceClosed ()
246                 {
247                         string xml = @"<s:Envelope xmlns:a=""http://www.w3.org/2005/08/addressing"" xmlns:s=""http://www.w3.org/2003/05/soap-envelope""><s:Header></s:Header><s:Body>TEST</s:Body></s:Envelope>";
248
249                         Message msg;
250                         using (XmlReader r = XmlReader.Create (new StringReader (xml))) {
251                                 msg = Message.CreateMessage (r, 10000, MessageVersion.Default);
252                         }
253                         // The reader is already closed by nature of using statement.
254                         XmlDictionaryReader r2 = msg.GetReaderAtBodyContents ();
255                         Assert.AreEqual (ReadState.Closed, r2.ReadState);
256                 }
257
258                 [Test]
259                 public void WriteMessagePOX ()
260                 {
261                         string xml = "<?xml version=\"1.0\" encoding=\"utf-16\"?><z:anyType i:nil=\"true\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:z=\"http://schemas.microsoft.com/2003/10/Serialization/\" />";
262                         Message m = Message.CreateMessage (MessageVersion.None, "Blah", (object) null);
263                         StringWriter sw = new StringWriter ();
264                         using (XmlWriter w = XmlWriter.Create (sw)) {
265                                 m.WriteMessage (w);
266                         }
267                         Assert.AreEqual (xml, sw.ToString ());
268                 }
269
270                 [Test]
271                 public void ReadHeaders1 ()
272                 {
273                         string xml = "<s:Envelope xmlns:s='http://www.w3.org/2003/05/soap-envelope'><s:Header><custom1 /><custom2>bah</custom2></s:Header><s:Body/></s:Envelope>";
274                         using (XmlReader r = XmlReader.Create (new StringReader (xml))) {
275                                 Message m = Message.CreateMessage (r, 1000, MessageVersion.Default);
276                                 Assert.AreEqual (2, m.Headers.Count, "#1");
277                                 Assert.AreEqual (String.Empty, m.Headers.GetHeader<string> (0), "#2");
278                                 Assert.AreEqual ("bah", m.Headers.GetHeader<string> (1), "#3");
279                                 // 0, 1, then 0
280                                 Assert.AreEqual (String.Empty, m.Headers.GetHeader<string> (0), "#2");
281                         }
282                 }
283
284                 [Test]
285                 public void ReadHeaders2 ()
286                 {
287                         string xml = "<s:Envelope xmlns:s='http://www.w3.org/2003/05/soap-envelope'><s:Header><u:Timestamp xmlns:u='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd'><u:Created>blah</u:Created><u:Expires>bleh</u:Expires></u:Timestamp></s:Header><s:Body/></s:Envelope>";
288                         using (XmlReader r = XmlReader.Create (new StringReader (xml))) {
289                                 Message m = Message.CreateMessage (r, 1000, MessageVersion.Default);
290                                 Assert.AreEqual (1, m.Headers.Count, "#1");
291                         }
292                 }
293
294                 [Test]
295                 public void ReadHeadersMustUnderstand ()
296                 {
297                         // it includes mustUnderstand, but is ignored at
298                         // this stage.
299                         string xml = "<s:Envelope xmlns:s='http://www.w3.org/2003/05/soap-envelope'><s:Header><blah s:mustUnderstand='true'>foo</blah></s:Header><s:Body/></s:Envelope>";
300                         using (XmlReader r = XmlReader.Create (new StringReader (xml))) {
301                                 Message m = Message.CreateMessage (r, 1000, MessageVersion.Default);
302                                 Assert.AreEqual (1, m.Headers.Count, "#1");
303                         }
304                 }
305
306                 [Test]
307                 [Category ("NotWorking")]
308                 public void ToStringSomehowDoesNotConsumeMessage ()
309                 {
310                         Message m = Message.CreateMessage (MessageVersion.Default, "action", 1);
311                         Assert.AreEqual (m.ToString (), m.ToString ());
312                 }
313
314                 [Test]
315                 public void IsFault ()
316                 {
317                         Message m = Message.CreateMessage (MessageVersion.Default, "action", 1);
318                         Assert.IsFalse (m.IsFault, "#1");
319                         m = Message.CreateMessage (MessageVersion.Default, new FaultCode ("ActionNotSupported", "urn:myfault"), "I dunno", "urn:myaction");
320                         Assert.IsTrue (m.IsFault, "#2");
321                 }
322
323                 [Test]
324                 public void IsFault2 ()
325                 {
326                         string xml = @"
327 <s:Envelope xmlns:a='http://www.w3.org/2005/08/addressing' xmlns:s='http://www.w3.org/2003/05/soap-envelope'>
328   <s:Header>
329     <a:Action s:mustUnderstand='1'>http://www.w3.org/2005/08/addressing/fault</a:Action>
330   </s:Header>
331   <s:Body>
332     <s:Fault xmlns:s='http://www.w3.org/2003/05/soap-envelope'>
333       <s:Code>
334         <s:Value>s:Sender</s:Value>
335         <s:Subcode>
336           <s:Value>a:ActionNotSupported</s:Value>
337         </s:Subcode>
338       </s:Code>
339       <s:Reason>
340         <s:Text xml:lang='ja-JP'>message</s:Text>
341       </s:Reason>
342     </s:Fault>
343   </s:Body>
344 </s:Envelope>";
345                         var msg = Message.CreateMessage (MessageVersion.Soap11, "urn:foo", XmlReader.Create (new StringReader (xml)));
346                         Assert.AreEqual ("urn:foo", msg.Headers.Action, "#1");
347                         msg.ToString ();
348                         Assert.IsFalse (msg.IsFault, "#2"); // version mismatch
349
350                         msg = Message.CreateMessage (MessageVersion.Soap12, "urn:foo", XmlReader.Create (new StringReader (xml)));
351                         Assert.AreEqual ("urn:foo", msg.Headers.Action, "#3");
352                         msg.ToString ();
353                         Assert.IsFalse (msg.IsFault, "#4"); // version match, but it doesn't set as true. It is set true only when it is constructed with fault objects.
354                 }
355
356                 [Test]
357                 public void State ()
358                 {
359                         var msg = Message.CreateMessage (MessageVersion.Soap11, "urn:foo", (object) null);
360                         var xw = XmlDictionaryWriter.CreateDictionaryWriter (XmlWriter.Create (TextWriter.Null));
361                         msg.WriteStartEnvelope (xw);
362                         Assert.AreEqual (MessageState.Created, msg.State, "#1");
363                         msg.WriteStartBody (xw);
364                         Assert.AreEqual (MessageState.Created, msg.State, "#2");
365                 }
366         }
367 }