2009-07-11 Michael Barker <mike@middlesoft.co.uk>
[mono.git] / mcs / class / System.Web.DynamicData / Test / System.Web.DynamicData / MetaModelTest.cs
1 //
2 // MetaModelTest.cs
3 //
4 // Authors:
5 //      Atsushi Enomoto <atsushi@ximian.com>
6 //      Marek Habersack <mhabersack@novell.com>
7 //
8 // Copyright (C) 2008-2009 Novell Inc. http://novell.com
9 //
10
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 // 
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 // 
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 //
31 using System;
32 using System.Collections;
33 using System.Collections.Generic;
34 using System.Collections.ObjectModel;
35 using System.Collections.Specialized;
36 using System.ComponentModel.DataAnnotations;
37 using System.Data.SqlClient;
38 using System.Data.Linq;
39 using System.Data.Linq.Mapping;
40 using System.Globalization;
41 using System.Reflection;
42 using System.Security.Permissions;
43 using System.Security.Principal;
44 using System.Web;
45 using System.Web.UI;
46 using System.Web.DynamicData;
47 using System.Web.DynamicData.ModelProviders;
48 using System.Web.Routing;
49
50 using NUnit.Framework;
51 using NUnit.Mocks;
52 using MonoTests.stand_alone.WebHarness;
53 using MonoTests.SystemWeb.Framework;
54 using MonoTests.Common;
55
56 using MetaModel = System.Web.DynamicData.MetaModel;
57 using MetaTable = System.Web.DynamicData.MetaTable;
58
59 namespace MonoTests.System.Web.DynamicData
60 {
61         [TestFixture]
62         public class MetaModelTest
63         {
64                 static MetaModel defaultModel;
65
66                 static MetaModelTest ()
67                 {
68                         defaultModel = new MetaModel ();
69                 }
70
71                 [Test]
72                 public void DefaultValues ()
73                 {
74                         var model = new MetaModel ();
75
76                         Assert.IsNotNull (MetaModel.Default, "#A1");
77
78                         // We can't be sure which model will be the default one when running under Nunit
79                         //Assert.IsTrue (MetaModel.Default == defaultModel, "#A2");
80                         Assert.IsNotNull (model.Tables, "#A3");
81                         Assert.IsNotNull (model.VisibleTables, "#A4");
82                         Assert.IsNotNull (model.FieldTemplateFactory, "#A5");
83                         Assert.AreEqual ("~/DynamicData/", model.DynamicDataFolderVirtualPath, "#A6");
84
85                         Assert.AreEqual (0, model.VisibleTables.Count, "#B1");
86                         Assert.AreEqual (0, model.Tables.Count, "#B2");
87                         Assert.AreEqual (typeof (FieldTemplateFactory), model.FieldTemplateFactory.GetType (), "#B3");
88                 }
89
90                 [Test]
91                 public void DynamicDataFolderVirtualPath ()
92                 {
93                         var model = new MetaModel ();
94
95                         Assert.AreEqual ("~/DynamicData/", model.DynamicDataFolderVirtualPath, "#A1");
96                         model.DynamicDataFolderVirtualPath = null;
97                         Assert.AreEqual ("~/DynamicData/", model.DynamicDataFolderVirtualPath, "#A2");
98                         model.DynamicDataFolderVirtualPath = String.Empty;
99                         Assert.AreEqual (String.Empty, model.DynamicDataFolderVirtualPath, "#A3");
100                         model.DynamicDataFolderVirtualPath = "~/FolderNoTrailingSlash";
101                         Assert.AreEqual ("~/FolderNoTrailingSlash/", model.DynamicDataFolderVirtualPath, "#A4");
102                         model.DynamicDataFolderVirtualPath = "AnotherFolder";
103                         Assert.AreEqual ("AnotherFolder/", model.DynamicDataFolderVirtualPath, "#A5");
104                         model.DynamicDataFolderVirtualPath = "/YetAnotherFolder";
105                         Assert.AreEqual ("/YetAnotherFolder/", model.DynamicDataFolderVirtualPath, "#A6");
106                         model.DynamicDataFolderVirtualPath = null;
107                         Assert.AreEqual ("~/DynamicData/", model.DynamicDataFolderVirtualPath, "#A7");
108                 }
109
110                 [Test]
111                 [ExpectedException (typeof (ArgumentNullException))]
112                 public void GetTableNull ()
113                 {
114                         new MetaModel ().GetTable ((Type) null);
115                 }
116
117                 [Test]
118                 public void RegisterContext ()
119                 {
120                         var m = new MetaModel ();
121                         try {
122                                 m.RegisterContext (typeof (Foo));
123                                 Assert.Fail ("#1");
124                         } catch (TargetInvocationException ex) {
125                                 Assert.AreEqual ("ERROR", ex.InnerException.Message, "#2");
126                         } finally {
127                                 MetaModel.ResetRegistrationException ();
128                         }
129                 }
130
131                 [Test]
132                 [ExpectedException (typeof (ArgumentException))]
133                 public void RegisterContext2 ()
134                 {
135                         try {
136                                 var m = new MetaModel ();
137                                 m.RegisterContext (typeof (Bar)); // not supported
138                         } finally {
139                                 MetaModel.ResetRegistrationException ();
140                         }
141                 }
142
143                 [Test]
144                 [ExpectedException (typeof (MissingMethodException))]
145                 public void RegisterContext3 ()
146                 {
147                         var m = new MetaModel ();
148                         try {
149                                 // no public constructor
150                                 m.RegisterContext (typeof (DataContext));
151                         } finally {
152                                 MetaModel.ResetRegistrationException ();
153                         }
154                 }
155
156                 [Test]
157                 public void RegisterContext4 ()
158                 {
159                         MetaModel m = Utils.GetModel<MyDataContext1> ();
160                         Assert.AreEqual (0, m.Tables.Count, "#1-1");
161                         Assert.AreEqual (0, m.VisibleTables.Count, "#1-2");
162                         Assert.IsNotNull (MetaModel.GetModel (typeof (MyDataContext1)), "#2");
163                 }
164
165                 [Test]
166                 public void RegisterContext5 ()
167                 {
168                         // In the process of several experiments (as the docs lack any good explanation),
169                         // I determined that this test needs the following for succesful completion:
170                         //
171                         //  - a worker request
172                         //  - a HttpContext
173                         //  - a fake route handler derived from DynamicDataRouteHandler, so that its CreateHandler
174                         //    returns a handler without attempting to actually find a View for the requested action
175                         //  - a route which can match table actions (taken from the skeleton DynamicData project
176                         //    generated by VisualStudio)
177                         //  - _empty_ query string returned from the fake worker request, or .NET will populate the
178                         //    HttpRequest.QueryString collection with one null item, and .NET's DynamicData will happily
179                         //    assume any entry in that collection is not null (it seems null checks aren't very popular
180                         //    in DynamicData code)
181                         var req = new FakeHttpWorkerRequest ();
182                         var ctx = new HttpContext (req);
183                         HttpContext.Current = ctx;
184                         MetaModel m = Utils.GetModel<MyDataContext2> ();
185
186                         RouteTable.Routes.Add (
187                             new DynamicDataRoute ("{table}/{action}.aspx") {
188                                     Constraints = new RouteValueDictionary (new { action = "List|Details|Edit|Insert" }),
189                                     Model = m,
190                                     RouteHandler = new MyDynamicDataRouteHandler ()
191                             });
192
193                         MetaTable t = m.Tables[0];
194
195                         Assert.AreEqual (1, m.Tables.Count, "#1-1");
196                         Assert.AreEqual (1, m.VisibleTables.Count, "#1-2");
197                         Assert.AreEqual (typeof (Foo), t.EntityType, "#1-3");
198
199                         // Those names are only the last part before '.' (i.e. without schema name).
200                         Assert.AreEqual ("FooTable", t.Name, "#2-1");
201                         Assert.AreEqual ("FooTable", t.DisplayName, "#2-2");
202                         Assert.AreEqual ("FooTable", t.DataContextPropertyName, "#2-3");
203                         Assert.AreEqual ("/FooTable/List.aspx", t.ListActionPath, "#2-4");
204
205                         Assert.AreEqual ("FooTable", t.Provider.Name, "#3-1");
206                 }
207
208                 [Test]
209                 public void ResetRegistrationException ()
210                 {
211                         MetaModel.ResetRegistrationException ();
212
213                         var m = new MetaModel ();
214                         try {
215                                 m.RegisterContext (typeof (Foo));
216                                 Assert.Fail ("#1");
217                         } catch (TargetInvocationException) {
218                         }
219
220                         try {
221                                 m.RegisterContext (typeof (MyDataContext1));
222                                 Assert.Fail ("#2");
223                         } catch (InvalidOperationException) {
224                         } finally {
225                                 MetaModel.ResetRegistrationException ();
226                         }
227                 }
228
229                 [Test]
230                 [ExpectedException (typeof (ArgumentException))]
231                 public void GetTableObject ()
232                 {
233                         // entity type 'System.Object' not found.
234                         new MetaModel ().GetTable (typeof (object));
235                 }
236
237                 [Test]
238                 public void GetModel ()
239                 {
240                         Utils.GetModel<UseOnlyInGetModelTestDataContext> ();
241                         AssertExtensions.Throws<ArgumentNullException> (() => MetaModel.GetModel (null), "#A1");
242                         AssertExtensions.Throws<InvalidOperationException> (() => MetaModel.GetModel (typeof (object)), "#A2");
243                         Assert.IsNotNull (MetaModel.GetModel (typeof (UseOnlyInGetModelTestDataContext)));
244                 }
245
246                 [Test]
247                 public void TryGetTable ()
248                 {
249                         MetaModel m = Utils.GetModel<MyDataContext2> ();
250                         MetaTable t;
251
252                         AssertExtensions.Throws<ArgumentNullException> (() => m.TryGetTable (null, out t), "#A1");
253
254                         Assert.IsTrue (m.TryGetTable ("FooTable", out t), "#B1");
255                         Assert.IsNotNull (t, "#B2");
256                         Assert.AreEqual (typeof (Foo), t.EntityType, "#B3");
257
258                         Assert.IsFalse (m.TryGetTable (String.Empty, out t), "#C1");
259                         Assert.IsNull (t, "#C2");
260                         Assert.IsFalse (m.TryGetTable ("NoSuchTable", out t), "#C3");
261                         Assert.IsNull (t, "#C4");
262                 }
263
264                 [Test]
265                 public void GetTable ()
266                 {
267                         MetaModel m = Utils.GetModel<MyDataContext2> ();
268                         MetaTable t;
269                         string str = null;
270                         Type type = null;
271
272                         AssertExtensions.Throws<ArgumentNullException> (() => t = m.GetTable (str), "#A1");
273                         AssertExtensions.Throws<ArgumentNullException> (() => t = m.GetTable (type), "#A2");
274                         AssertExtensions.Throws<ArgumentNullException> (() => t = m.GetTable (null, null), "#A3");
275                         AssertExtensions.Throws<ArgumentNullException> (() => t = m.GetTable (null, typeof (Foo)), "#A4");
276                         AssertExtensions.Throws<ArgumentNullException> (() => t = m.GetTable ("FooTable", null), "#A5");
277
278                         AssertExtensions.Throws<ArgumentException> (() => t = m.GetTable (String.Empty), "#B1");
279                         AssertExtensions.Throws<ArgumentException> (() => t = m.GetTable ("NoSuchName"), "#B2");
280                         AssertExtensions.Throws<ArgumentException> (() => t = m.GetTable (typeof (object)), "#B3");
281                         AssertExtensions.Throws<ArgumentException> (() => t = m.GetTable ("FooTable", typeof (object)), "#B4");
282                         AssertExtensions.Throws<ArgumentException> (() => t = m.GetTable ("NoSuchTable", typeof (object)), "#B5");
283
284                         Assert.IsNotNull (t = m.GetTable ("FooTable"), "#C1");
285                         Assert.AreEqual (typeof (Foo), t.EntityType, "#C2");
286                         Assert.IsNotNull (t = m.GetTable (typeof (Foo)), "#C3");
287                         Assert.AreEqual (typeof (Foo), t.EntityType, "#C4");
288                         Assert.IsNotNull (t = m.GetTable ("FooTable", typeof (MyDataContext2)), "#C5");
289                         Assert.AreEqual (typeof (Foo), t.EntityType, "#C6");
290                 }
291
292                 [Test]
293                 public void GetActionPath ()
294                 {
295                         var foo = new Foo (true);
296                         MetaModel m = Utils.GetModel<MyDataContext2> ();
297
298                         // None of those are thrown from GetTable - it seems this method performs NO checks at all, sigh...
299                         //
300                         //AssertExtensions.Throws<ArgumentNullException> (() => m.GetActionPath (null, PageAction.List, foo), "#A1");
301                         //AssertExtensions.Throws<ArgumentException> (() => m.GetActionPath (String.Empty, PageAction.List, foo), "#A2");
302                         //AssertExtensions.Throws<ArgumentNullException> (() => m.GetActionPath ("FooTable", null, foo), "#A3");
303                         //AssertExtensions.Throws<ArgumentNullException> (() => m.GetActionPath ("FooTable", PageAction.List, null), "#A4");
304                         //AssertExtensions.Throws<ArgumentException> (() => m.GetActionPath ("NoSuchTable", PageAction.List, foo), "#A5");
305                 }
306
307                 [Test]
308                 public void GetActionPath2 ()
309                 {
310                         var foo = new Foo (true);
311                         var req = new FakeHttpWorkerRequest ();
312                         var ctx = new HttpContext (req);
313                         HttpContext.Current = ctx;
314                         MetaModel m = Utils.GetModel<MyDataContext2> ();
315
316                         RouteTable.Routes.Add (
317                             new DynamicDataRoute ("{table}/{action}.aspx") {
318                                     Constraints = new RouteValueDictionary (new { action = "List|Details|Edit|Insert" }),
319                                     Model = m,
320                                     RouteHandler = new MyDynamicDataRouteHandler ()
321                             });
322
323                         // .NET stacktrace:
324                         //
325                         // at System.Web.DynamicData.MetaModel.TryGetTable(String uniqueTableName, MetaTable& table)
326                         // at System.Web.DynamicData.MetaModel.GetTable(String uniqueTableName)
327                         AssertExtensions.Throws<ArgumentNullException> (() => m.GetActionPath (null, PageAction.List, foo), "#A1");
328                         Assert.AreEqual (String.Empty, m.GetActionPath ("FooTable", null, foo), "#A2");
329                         Assert.AreEqual ("/FooTable/List.aspx", m.GetActionPath ("FooTable", PageAction.List, null), "#A3");
330                         AssertExtensions.Throws<ArgumentException> (() => m.GetActionPath ("NoSuchTable", PageAction.List, foo), "#A4");
331
332                         Assert.AreEqual ("/FooTable/List.aspx", m.GetActionPath ("FooTable", "List", foo), "#B1");
333                 }
334         }
335 }