CSLA.NET 6.0.0
CSLA .NET is a software development framework that helps you build a reusable, maintainable object-oriented business layer for your app.
DataPortalTests.cs
Go to the documentation of this file.
1//-----------------------------------------------------------------------
2// <copyright file="DataPortalTests.cs" company="Marimer LLC">
3// Copyright (c) Marimer LLC. All rights reserved.
4// Website: https://cslanet.com
5// </copyright>
6// <summary>no summary</summary>
7//-----------------------------------------------------------------------
8using System;
9using System.Collections.Generic;
10using System.Text;
12using System.Data;
13using System.Data.SqlClient;
14using Csla.TestHelpers;
16
17#if NUNIT
18using NUnit.Framework;
19using TestClass = NUnit.Framework.TestFixtureAttribute;
20using TestInitialize = NUnit.Framework.SetUpAttribute;
21using TestCleanup = NUnit.Framework.TearDownAttribute;
22using TestMethod = NUnit.Framework.TestAttribute;
23using TestSetup = NUnit.Framework.SetUpAttribute;
24#elif MSTEST
25using Microsoft.VisualStudio.TestTools.UnitTesting;
26#endif
27
29{
30 [TestClass()]
31 public class DataPortalTests
32 {
33 private static TestDIContext _testDIContext;
34
36 public static void ClassInitialize(TestContext context)
37 {
38 _testDIContext = TestDIContextFactory.CreateDefaultContext();
39 }
40
41 private static string CONNECTION_STRING = WellKnownValues.DataPortalTestDatabase;
42 public void ClearDataBase()
43 {
44 SqlConnection cn = new SqlConnection(CONNECTION_STRING);
45 SqlCommand cm = new SqlCommand("DELETE FROM Table2", cn);
46
47 try
48 {
49 cn.Open();
50 cm.ExecuteNonQuery();
51 }
52 catch (Exception)
53 {
54 //do nothing
55 }
56 finally
57 {
58 cn.Close();
59 }
60 }
61
62#if DEBUG
63 [TestMethod()]
64
65 public void TestTransactionScopeUpdate()
66 {
67 IDataPortal<TransactionalRoot> dataPortal = _testDIContext.CreateDataPortal<TransactionalRoot>();
68
70 tr.FirstName = "Bill";
71 tr.LastName = "Johnson";
72 //setting smallColumn to a string less than or equal to 5 characters will
73 //not cause the transaction to rollback
74 tr.SmallColumn = "abc";
75
76 tr = tr.Save();
77
78 // TODO: These connection strings got lost, so I've tried to recreate them, but not sure how to do this
79 SqlConnection cn = new SqlConnection(CONNECTION_STRING);
80 SqlCommand cm = new SqlCommand("SELECT * FROM Table2", cn);
81
82 try
83 {
84 cn.Open();
85 SqlDataReader dr = cm.ExecuteReader();
86
87 //will have rows since no sqlexception was thrown on the insert
88 Assert.AreEqual(true, dr.HasRows);
89 dr.Close();
90 }
91 catch (Exception)
92 {
93 //do nothing
94 }
95 finally
96 {
97 cn.Close();
98 }
99
101
103 tr2.FirstName = "Jimmy";
104 tr2.LastName = "Smith";
105 //intentionally input a string longer than varchar(5) to
106 //cause a sql exception and rollback the transaction
107 tr2.SmallColumn = "this will cause a sql exception";
108
109 try
110 {
111 //will throw a sql exception since the SmallColumn property is too long
112 tr2 = tr2.Save();
113 }
114 catch (Exception ex)
115 {
116 Assert.IsTrue(ex.Message.StartsWith("DataPortal.Update failed"), "Invalid exception message");
117 }
118
119 //within the DataPortal_Insert method, two commands are run to insert data into
120 //the database. Here we verify that both commands have been rolled back
121 try
122 {
123 cn.Open();
124 SqlDataReader dr = cm.ExecuteReader();
125
126 //should not have rows since both commands were rolled back
127 Assert.AreEqual(false, dr.HasRows);
128 dr.Close();
129 }
130 catch (Exception)
131 {
132 //do nothing
133 }
134 finally
135 {
136 cn.Close();
137 }
138
140 }
141#endif
142
143 [TestMethod()]
145 {
146 IDataPortal<StronglyTypedDP> dataPortal = _testDIContext.CreateDataPortal<StronglyTypedDP>();
147
148 //test strongly-typed DataPortal_Fetch method
151
152 Assert.AreEqual("Fetched", TestResults.GetResult("StronglyTypedDP"));
153 Assert.AreEqual("fetched existing data", root.Data);
154 Assert.AreEqual(456, root.Id);
155
156 //test strongly-typed DataPortal_Create method
159
160 Assert.AreEqual("Created", TestResults.GetResult("StronglyTypedDP"));
161 Assert.AreEqual("new default data", root2.Data);
162 Assert.AreEqual(56, root2.Id);
163
164 //test strongly-typed DataPortal_Delete method
166 Assert.AreEqual("567", TestResults.GetResult("StronglyTypedDP_Criteria"));
167 }
168
169 [TestMethod]
171 {
172 IDataPortal<EncapsulatedBusy> dataPortal = _testDIContext.CreateDataPortal<EncapsulatedBusy>();
173
174 try
175 {
176 var obj = dataPortal.Fetch();
177 }
178 catch (DataPortalException ex)
179 {
180 Assert.IsInstanceOfType(ex.InnerException, typeof(InvalidOperationException));
181 return;
182 }
183 Assert.Fail("Expected exception");
184 }
185
186 [TestMethod]
187 public void FactoryIsBusyFails()
188 {
189 IDataPortal<FactoryBusy> dataPortal = _testDIContext.CreateDataPortal<FactoryBusy>();
190
191 try
192 {
193 var obj = dataPortal.Fetch();
194 }
195 catch (DataPortalException ex)
196 {
197 Assert.IsInstanceOfType(ex.InnerException, typeof(InvalidOperationException));
198 return;
199 }
200 Assert.Fail("Expected exception");
201 }
202
203 // TODO: Is this a relevant concept any more? These events do not seem to be exposed
204 [TestMethod()]
205 public void DataPortalEvents()
206 {
207 IDataPortal<DpRoot> dataPortal = _testDIContext.CreateDataPortal<DpRoot>();
208
209 // TODO: Not sure how to replicate this in Csla 6
210 //dataPortal.DataPortalInvoke += new Action<DataPortalEventArgs>(ClientPortal_DataPortalInvoke);
211 //dataPortal.DataPortalInvokeComplete += new Action<DataPortalEventArgs>(ClientPortal_DataPortalInvokeComplete);
212
213 try
214 {
216 DpRoot root = dataPortal.Create(new DpRoot.Criteria());
217
218 root.Data = "saved";
220 root = root.Save();
221
222 Assert.AreEqual("true", TestResults.GetResult("dpinvoke"), "DataPortalInvoke not called");
223 Assert.AreEqual("true", TestResults.GetResult("dpinvokecomplete"), "DataPortalInvokeComplete not called");
224 Assert.AreEqual("true", TestResults.GetResult("serverinvoke"), "Server DataPortalInvoke not called");
225 Assert.AreEqual("true", TestResults.GetResult("serverinvokecomplete"), "Server DataPortalInvokeComplete not called");
226 }
227 finally
228 {
229 // TODO: Not sure how to replicate this in Csla 6
230 //dataPortal.DataPortalInvoke -= new Action<DataPortalEventArgs>(ClientPortal_DataPortalInvoke);
231 //dataPortal.DataPortalInvokeComplete -= new Action<DataPortalEventArgs>(ClientPortal_DataPortalInvokeComplete);
232 }
233 }
234
235 [TestMethod]
237 {
239
240 var dps = _testDIContext.ServiceProvider.GetRequiredService<Server.DataPortalSelector>();
242
243 try
244 {
245 DataPortalTest.Single single = NewSingle();
246
247 Assert.AreEqual(TestResults.GetResult("Single"), "Created");
248 Assert.AreEqual(TestResults.GetResult("CustomDataPortalServer"), "Create Called");
249
251
252 single.Save();
253
254 Assert.AreEqual(TestResults.GetResult("Single"), "Inserted");
255 Assert.AreEqual(TestResults.GetResult("CustomDataPortalServer"), "Update Called");
256
258
259 single = GetSingle(1);
260
261 Assert.AreEqual(TestResults.GetResult("Single"), "Fetched");
262 Assert.AreEqual(TestResults.GetResult("CustomDataPortalServer"), "Fetch Called");
263
265
266 single.Save();
267
268 Assert.AreEqual(TestResults.GetResult("Single"), "Updated");
269 Assert.AreEqual(TestResults.GetResult("CustomDataPortalServer"), "Update Called");
270
272
273 DeleteSingle(1);
274
275 Assert.AreEqual(TestResults.GetResult("Single"), "Deleted");
276 Assert.AreEqual(TestResults.GetResult("CustomDataPortalServer"), "Delete Called");
277 }
278 finally
279 {
282 }
283 }
284
285 [TestMethod]
286
288 {
289 IDataPortal<ParentEntity> dataPortal = _testDIContext.CreateDataPortal<ParentEntity>();
290
292 ParentEntity parent = ParentEntity.NewParentEntity(dataPortal);
293 parent.Data = "something";
294
295 Assert.AreEqual(false, parent.IsDeleted);
296 Assert.AreEqual(true, parent.IsValid);
297 Assert.AreEqual(true, parent.IsNew);
298 Assert.AreEqual(true, parent.IsDirty);
299 Assert.AreEqual(true, parent.IsSavable);
300
301 parent = parent.Save();
302
303 Assert.AreEqual("Inserted", TestResults.GetResult("ParentEntity"));
304
305 Assert.AreEqual(false, parent.IsDeleted);
306 Assert.AreEqual(true, parent.IsValid);
307 Assert.AreEqual(false, parent.IsNew);
308 Assert.AreEqual(false, parent.IsDirty);
309 Assert.AreEqual(false, parent.IsSavable);
310
311 parent.Data = "something new";
312
313 Assert.AreEqual(false, parent.IsDeleted);
314 Assert.AreEqual(true, parent.IsValid);
315 Assert.AreEqual(false, parent.IsNew);
316 Assert.AreEqual(true, parent.IsDirty);
317 Assert.AreEqual(true, parent.IsSavable);
318
319 parent = parent.Save();
320
321 Assert.AreEqual("Updated", TestResults.GetResult("ParentEntity"));
322
323 parent.Delete();
324 Assert.AreEqual(true, parent.IsDeleted);
325 parent = parent.Save();
326 Assert.AreEqual("Deleted Self", TestResults.GetResult("ParentEntity"));
327
328 ParentEntity.DeleteParentEntity(33, dataPortal);
329 Assert.AreEqual("Deleted", TestResults.GetResult("ParentEntity"));
330 Assert.AreEqual(false, parent.IsDeleted);
331 Assert.AreEqual(true, parent.IsValid);
332 Assert.AreEqual(true, parent.IsNew);
333 Assert.AreEqual(true, parent.IsDirty);
334 Assert.AreEqual(true, parent.IsSavable);
335
336 ParentEntity.GetParentEntity(33, dataPortal);
337 Assert.AreEqual("Fetched", TestResults.GetResult("ParentEntity"));
338 }
339
340 private void ClientPortal_DataPortalInvoke(DataPortalEventArgs obj)
341 {
342 TestResults.Add("dpinvoke", "true");
343 }
344
345 private void ClientPortal_DataPortalInvokeComplete(DataPortalEventArgs obj)
346 {
347 TestResults.Add("dpinvokecomplete", "true");
348 }
349
350 private DataPortalTest.Single NewSingle()
351 {
352 IDataPortal<DataPortalTest.Single> dataPortal = _testDIContext.CreateDataPortal<DataPortalTest.Single>();
353
354 return dataPortal.Create();
355 }
356
357 private DataPortalTest.Single GetSingle(int id)
358 {
359 IDataPortal<DataPortalTest.Single> dataPortal = _testDIContext.CreateDataPortal<DataPortalTest.Single>();
360
361 return dataPortal.Fetch(id);
362 }
363
364 private void DeleteSingle(int id)
365 {
366 IDataPortal<DataPortalTest.Single> dataPortal = _testDIContext.CreateDataPortal<DataPortalTest.Single>();
367
368 dataPortal.Delete(id);
369 }
370
371 }
372
374 public class EncapsulatedBusy : BusinessBase<EncapsulatedBusy>
375 {
376 [Create]
377 protected void DataPortal_Create()
378 {
379 BusinessRules.CheckRules();
380 MarkBusy();
381 }
382
383 private void DataPortal_Fetch()
384 {
385 MarkBusy();
386 }
387 }
388
390 [Csla.Server.ObjectFactory(typeof(FactoryBusyFactory))]
391 public class FactoryBusy : BusinessBase<FactoryBusy>
392 {
393 public void MarkObjectBusy()
394 {
395 MarkBusy();
396 }
397 }
398
399 public class FactoryBusyFactory : Csla.Server.ObjectFactory
400 {
401 public FactoryBusyFactory(ApplicationContext applicationContext) : base(applicationContext)
402 {
403 }
404
406 {
407 var obj = new FactoryBusy();
408 MarkOld(obj);
409 obj.MarkObjectBusy();
410 return obj;
411 }
412 }
413}
Provides consistent context information between the client and server DataPortal objects.
This is the base class from which most business objects will be derived.
Definition: BusinessBase.cs:38
T Save()
Saves the object to the database.
Provides information about the DataPortal call.
This exception is returned for any errors occurring during the server-side DataPortal invocation.
Allows the Data Portal call to be intercepted by a custom IDataPortalServer implementation.
static IDataPortalServer DataPortalServer
Gets or sets a reference to a implementation of IDataPortalServer to be used.
Base class to be used when creating a data portal factory object.
void MarkOld(object obj)
Calls the MarkOld method on the specified object, if possible.
static ParentEntity NewParentEntity(IDataPortal< ParentEntity > dataPortal)
static ParentEntity GetParentEntity(int ID, IDataPortal< ParentEntity > dataPortal)
static void DeleteParentEntity(int ID, IDataPortal< ParentEntity > dataPortal)
static void ClassInitialize(TestContext context)
FactoryBusyFactory(ApplicationContext applicationContext)
static StronglyTypedDP NewStronglyTypedDP(IDataPortal< StronglyTypedDP > dataPortal)
static void DeleteStronglyTypedDP(int id, IDataPortal< StronglyTypedDP > dataPortal)
static StronglyTypedDP GetStronglyTypedDP(int id, IDataPortal< StronglyTypedDP > dataPortal)
static TransactionalRoot NewTransactionalRoot(IDataPortal< TransactionalRoot > dataPortal)
Static dictionary-like class that offers similar functionality to GlobalContext This is used in tests...
Definition: TestResults.cs:21
static void Reinitialise()
Reinitialise the dictionary, clearing any existing results, ready for the next test
Definition: TestResults.cs:69
static string GetResult(string key)
Get a result of an operation from the underlying results dictionary
Definition: TestResults.cs:49
static void Add(string key, string value)
Add an item to the test results, to indicate an outcome of a particular operation
Definition: TestResults.cs:29
static string DataPortalTestDatabase
Type to carry context information for DI in unit tests
IServiceProvider ServiceProvider
The service provider used to perform DI operations
Interface defining the members of the data portal type.
Definition: IDataPortalT.cs:17
void Delete(params object[] criteria)
Called by a Shared (static in C#) method in the business class to cause immediate deletion of a speci...
object Fetch(params object[] criteria)
Called by a factory method in a business class to retrieve an object, which is loaded with values fro...
object Create(params object[] criteria)
Called by a factory method in a business class to create a new object, which is loaded with default v...
@ Serializable
Prevents updating or inserting until the transaction is complete.
@ Create
Create operation.