1 #region Copyright ©  2003-2008 Richard Beauchamp <rbeauchamp@gmail.com>
   2 
   3 /*
   4 * DomainObjects for .NET
   5 * Copyright ©  2003-2008 Richard Beauchamp
   6 *
   7 * This library is free software; you can redistribute it and/or
   8 * modify it under the terms of the GNU Lesser General Public
   9 * License as published by the Free Software Foundation; either
  10 * version 2.1 of the License, or (at your option) any later version.
  11 *
  12 * This library is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15 * Lesser General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU Lesser General Public
  18 * License along with this library; if not, write to the Free Software
  19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  20 */
  21 
  22 #endregion
  23 
  24 using System;
  25 using DomainObjects.Facade.Command;
  26 using DomainObjects.Facade.Test;
  27 using DomainObjects.Test.Domain;
  28 using DomainObjects.Test.TestType.Service;
  29 using NUnit.Framework;
  30 
  31 namespace DomainObjects.Test.TestFixture
  32 {
  33   /// <summary>
  34   /// Tests object transaction behavior in DomainObjects.
  35   /// (Database transactions are tested in AdoNetTransactionTests)
  36   /// </summary>
  37   [TestFixture]
  38   public class ObjectTransactionTests : DomainObjectsTestFixture
  39   {
  40     /// <summary>
  41     /// Tests that objects involved in a transaction are ordered
  42     /// according to their type releationships not just their
  43     /// instance relationships. This is to help prevent deadlocks
  44     /// from occuring.
  45     ///
  46     /// This unit test is referred to by ITransactionSetAware interface documentation.
  47     /// </summary>
  48     [Test]
  49     public void ReorderingOccursAtTheTypeLevel()
  50     {
  51       ProductCategory productCategory1 = new ProductCategory("categoryName1", "description1").Manage<ProductCategory>();
  52       Product product1 = new Product(productCategory1, "productName1").Manage<Product>();
  53 
  54       ProductCategory productCategory2 = new ProductCategory("categoryName2", "description2").Manage<ProductCategory>();
  55       Product product2 = new Product(productCategory2, "productName2").Manage<Product>();
  56 
  57       // The call to the transactional method below causes
  58       // DomainObjects to invoke ReorderValidator.AfterCommit()
  59       // which then asserts that all ProductCategory instances
  60       // have been ordered before all Product instances.
  61       //
  62       // The instances are passed into the method call in non-type order to test
  63       // that DomainObjects reorders them correctly.
  64       ReorderValidationService.Instance.Persist(product1, productCategory1, productCategory2, product2);
  65     }
  66 
  67     /// <summary>
  68     /// Tests the following scenario:
  69     /// 1. Edit and bind an object to an object transaction.
  70     /// 2. Within the same transaction, query for the same
  71     ///    object using a criteria objectBasedQuery.
  72     ///
  73     /// Assert: The bound object is not re-initialized to
  74     ///         a non-edited state in step 2 above.
  75     /// </summary>
  76     [Test]
  77     public void ObjectIsNotReInitializedAfterBind()
  78     {
  79       try
  80       {
  81         // create and then retrieve an object
  82         ProductCategory productCategory = new ProductCategory("boundObjectTest", "originalDescription").Manage<ProductCategory>();
  83         PersistenceFacade.Persist(productCategory);
  84         ClearAppDomainAndContextCache();
  85         Criteria criteria = new Criteria();
  86         criteria.AddEqualTo(Types.ProductCategory.Field._name, "boundObjectTest");
  87         ProductCategory productCategoryFromDb = QueryFacade.FindObject<ProductCategory>(criteria).Manage<ProductCategory>();
  88 
  89         // modify it
  90         productCategoryFromDb.Description = "modifiedDescription";
  91 
  92         // requery it from the database
  93         QueryFacade.FindObject<ProductCategory>(criteria);
  94 
  95         // commit the transaction
  96         PersistenceFacade.Persist(productCategoryFromDb);
  97 
  98         // assert that the object was updated to the database
  99         ClearAppDomainAndContextCache();
 100         ProductCategory productCategoryFromDb2 = QueryFacade.FindObject<ProductCategory>(criteria);
 101         Assert.AreEqual("modifiedDescription", productCategoryFromDb2.Description, "The modified, bound and then requeried object was persisted to the database.");
 102       }
 103       catch (Exception ex)
 104       {
 105         base.Fail(ex);
 106       }
 107     }
 108 
 109     [Test]
 110     public void Bind()
 111     {
 112       try
 113       {
 114         ProductCategory productCategory = new ProductCategory("test name", "test description").Manage<ProductCategory>();
 115 
 116         // persist the new product category
 117         PersistenceFacade.Persist(productCategory);
 118 
 119         ClearAppDomainAndContextCache();
 120 
 121         // ensure that the new product category was persisted to the database
 122         ProductCategory productCategoryFromDB1 = Query.FindObjectByPrimaryKey<ProductCategory>(productCategory.PrimaryKey);
 123         Assert.IsNotNull(productCategoryFromDB1, "A ProductCategory was retrieved from the database");
 124 
 125         // modify an attribute that is self-binding
 126         productCategoryFromDB1.Name = "name2";
 127 
 128         // ensure that the name change was persisted to the database.
 129         PersistenceFacade.Persist(productCategoryFromDB1);
 130         ClearAppDomainAndContextCache();
 131         ProductCategory productCategoryFromDB3 = Query.FindObjectByPrimaryKey<ProductCategory>(productCategory.PrimaryKey);
 132         Assert.IsNotNull(productCategoryFromDB3, "A ProductCategory was retrieved from the database");
 133         Assert.AreEqual("name2", productCategoryFromDB3.Name, "The name was changed");
 134       }
 135       catch (Exception ex)
 136       {
 137         base.Fail(ex);
 138       }
 139     }
 140   }
 141 }