context: using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Security.Principal;
  using N2.Configuration;
  using N2.Definitions;
  using N2.Definitions.Static;
  using N2.Details;
  using N2.Integrity;
  using N2.Persistence;
  using N2.Persistence.Proxying;
  using N2.Security;
  using N2.Tests.Definitions.Items;
  using N2.Web;
  using N2.Web.UI;
  using NUnit.Framework;
  using Rhino.Mocks;
  using Shouldly;
  
  namespace N2.Tests.Definitions
  {
      [TestFixture]
      public class DefinitionTests : TypeFindingBase
      {
          #region Setup
  
          private IPrincipal user;
          private DefinitionManager definitions;
          private ContentActivator activator;
          private DefinitionMap map;
  
          protected override Type[] GetTypes()
          {
              return new Type[]
              {
                  typeof (DefinitionNewsList),
                  typeof (DefinitionNewsPage),
                  typeof (DefinitionRightColumnPart),
                  typeof (DefinitionRightColumnTeaser),
                  typeof (DefinitionStartPage),
                  typeof (DefinitionTextItem),
                  typeof (DefinitionTextPage),
                  typeof (DefinitionTwoColumnPage),
                  typeof (DefinitionMenuItem),
                  typeof (DefinitionAutoCreatedItem),
                  typeof (DefinitionDisabled),
                  typeof (DefinitionReplaced),
                  typeof (DefinitionDisablingReplacement),
                  typeof (DefinitionReplacement),
                  typeof (DefinitionOne),
                  typeof (DefinitionTwo),
                  typeof (DefinitionReplacesNumber1),
                  typeof (DefinitionRemovesNumber2),
                  typeof (DefinitionUndefined),
                  typeof (DefinitionFreeItem),
                  typeof (DefinitionControllingParent),
                  typeof (DefinitionOppressedChild),
                  typeof (DefinitionPartDefinedItem),
                  typeof (DefinitionWithPersistable)
              };
          }
  
          [SetUp]
          public override void SetUp()
          {
              base.SetUp();
  
              user = CreatePrincipal("SomeSchmuck");
  
              map = new DefinitionMap();
              DefinitionBuilder builder = new DefinitionBuilder(map, typeFinder, new TransformerBase<IUniquelyNamed>[0], new EngineSection());
              IItemNotifier notifier = mocks.DynamicMock<IItemNotifier>();
              mocks.Replay(notifier);
              var changer = new N2.Edit.Workflow.StateChanger();
              activator = new ContentActivator(changer, notifier, new EmptyProxyFactory());
              definitions = new DefinitionManager(new[] { new DefinitionProvider(builder) }, activator, changer, new DefinitionMap());
          }
  
          #endregion
  
          [Test, Obsolete]
          public void CanCreate_NewItemInstance()
          {
              DefinitionTextPage item = definitions.CreateInstance<DefinitionTextPage>(null);
              Assert.IsNotNull(item, "Couldn't create item");
          }
  
          [Test]
          public void TextPage_HasRightZone()
          {
              ItemDefinition definition = definitions.GetDefinition(typeof (DefinitionTextPage));
              IList<AvailableZoneAttribute> availableZones = definition.AvailableZones;
              EnumerableAssert.Contains(availableZones, new AvailableZoneAttribute("Right", "Right"));
          }
  
          [Test]
          public void StartPageHas_LeftAndCenter_AndRightZone()
          {
              ItemDefinition definition = definitions.GetDefinition(typeof (DefinitionStartPage));
              IList<AvailableZoneAttribute> availableZones = definition.AvailableZones;
              EnumerableAssert.Contains(availableZones, new AvailableZoneAttribute("Right", "Right"));
              EnumerableAssert.Contains(availableZones, new AvailableZoneAttribute("Left and Center", "LeftAndCenter"));
          }
  
          [Test]
          public void RightColumnTeaser_AllowsRightZone()
          {
              ItemDefinition definition = definitions.GetDefinition(typeof (DefinitionRightColumnTeaser));
              IEnumerable<string> zones = definition.AllowedZoneNames;
              EnumerableAssert.Count(1, zones);
              EnumerableAssert.Contains(zones, "Right");
          }
  
          [Test]
          public void TextItemAllows_LeftAndCenter_AndRightZone()
          {
              ItemDefinition definition = definitions.GetDefinition(typeof (DefinitionTextItem));
              IEnumerable<string> zones = definition.AllowedZoneNames;
              EnumerableAssert.Count(2, zones);
              EnumerableAssert.Contains(zones, "Right");
              EnumerableAssert.Contains(zones, "LeftAndCenter");
          }
  
          // DefinitionAutoCreatedItem
          // DefinitionMenuItem
          //      parents: ILeftColumnlPage
          // DefinitionNewsList
          //      parents: DefinitionNewsPage
          // DefinitionNewsPage
          // DefinitionRightColumnPart
          // DefinitionRightColumnTeaser
          // DefinitionStartPage: DefinitionTwoColumnPage, ILeftColumnlPage
          //      parents: none
          // DefinitionTextItem
          //      parents: DefinitionTwoColumnPage
          // DefinitionTextPage: DefinitionTwoColumnPage, ILeftColumnPage
          // DefinitionTwoColumnPage
          // ILeftColumnPage
  
  
          [Test]
          public void StartPage_IsntAllowed_BelowStartPage()
          {
              ItemDefinition startPageDef = definitions.GetDefinition(typeof (DefinitionStartPage));
              var childDefinitions = definitions.GetAllowedChildren(new DefinitionStartPage(), string.Empty);
  
              EnumerableAssert.DoesntContain(childDefinitions, startPageDef, "One of the start page's child definitions was the start page itself.");
          }
  
          [Test]
          public void TextPage_IsAllowed_BelowStartPage()
          {
              ItemDefinition definition = definitions.GetDefinition(typeof (DefinitionStartPage));
              var childDefinitions = definitions.GetAllowedChildren(new DefinitionStartPage(), string.Empty);
  
              EnumerableAssert.Contains(childDefinitions, definitions.GetDefinition(typeof (DefinitionTextPage)));
          }
  
          [Test]
          public void AllowTeaser_InStartPage_RightZone()
          {
              ItemDefinition definition = definitions.GetDefinition(typeof (DefinitionStartPage));
              var childDefinitions = definitions.GetAllowedChildren(new DefinitionStartPage(), "Right");
  
              EnumerableAssert.Contains(childDefinitions, definitions.GetDefinition(typeof (DefinitionRightColumnTeaser)));
          }
  
          [Test]
          public void Teaser_IsAllowed_InTextPage_RightZone()
          {
              ItemDefinition definition = definitions.GetDefinition(typeof (DefinitionTextPage));
              var childDefinitions = definitions.GetAllowedChildren(new DefinitionTextPage(), "Right");
  
              EnumerableAssert.Contains(childDefinitions, definitions.GetDefinition(typeof (DefinitionRightColumnTeaser)));
          }
  
          [Test]
          public void TextItem_IsAllowed_OnStartPage_LeftAndCenterZone()
          {
              ItemDefinition definition = definitions.GetDefinition(typeof (DefinitionStartPage));
              var childDefinitions = definitions.GetAllowedChildren(new DefinitionStartPage(), "LeftAndCenter");
  
              EnumerableAssert.Contains(childDefinitions, definitions.GetDefinition(typeof (DefinitionTextItem)));
          }
  
          [Test]
          public void Teaser_IsntAllowed_OnStartPage_LeftAndCenterZone()
          {
              ItemDefinition definition = definitions.GetDefinition(typeof (DefinitionStartPage));
              var childDefinitions = definitions.GetAllowedChildren(new DefinitionStartPage(), "LeftAndCenter");
  
              EnumerableAssert.DoesntContain(childDefinitions, definitions.GetDefinition(typeof (DefinitionRightColumnTeaser)));
          }
  
          [Test]
          public void Accessing_AnUnexistantZone_DoesntThrowException()
          {
              ItemDefinition definition = definitions.GetDefinition(typeof (DefinitionTextPage));
              definitions.GetAllowedChildren(new DefinitionTextPage(), "LeftAndCenter");
          }
  
          [Test]
          public void Teaser_IsntAllowed_WithoutZone()
          {
              ItemDefinition definition = definitions.GetDefinition(typeof (DefinitionStartPage));
              var childDefinitions = definitions.GetAllowedChildren(new DefinitionStartPage(), string.Empty);
  
              EnumerableAssert.DoesntContain(childDefinitions, definitions.GetDefinition(typeof (DefinitionTextItem)));
          }
  
          [Test]
          public void NewsList_IsAllowed_OnNewsPageRightZone()
          {
              ItemDefinition definition = definitions.GetDefinition(typeof (DefinitionNewsPage));
              var childDefinitions = definitions.GetAllowedChildren(new DefinitionNewsPage(), "Right");
  
              EnumerableAssert.Contains(childDefinitions, definitions.GetDefinition(typeof (DefinitionNewsList)));
          }
  
          [Test]
          public void NewsList_HasTwo_AllowedZones()
          {
              ItemDefinition definition = definitions.GetDefinition(typeof (DefinitionNewsList));
              EnumerableAssert.Contains(definition.AllowedZoneNames, "Right");
              EnumerableAssert.Contains(definition.AllowedZoneNames, "");
          }
  
          [Test]
          public void NewsList_IsAllowed_OnNewsPageEmptyZone()
          {
              ItemDefinition definition = definitions.GetDefinition(typeof (DefinitionNewsPage));
              IEnumerable<ItemDefinition> childDefinitions = definitions.GetAllowedChildren(new DefinitionNewsPage(), string.Empty);
              EnumerableAssert.Contains(childDefinitions, definitions.GetDefinition(typeof (DefinitionNewsList)));
          }
  
          [Test]
          public void NewsList_IsntAllowed_OnTextPage()
          {
              ItemDefinition definition = definitions.GetDefinition(typeof (DefinitionTextPage));
              var childDefinitions = definitions.GetAllowedChildren(new DefinitionTextPage(), "Right");
  
              EnumerableAssert.DoesntContain(childDefinitions, definitions.GetDefinition(typeof (DefinitionNewsList)));
          }
  
          [Test]
          public void TextPage_Has2InheritedEditables_AndOneAddedToProperty()
          {
              ItemDefinition definition = definitions.GetDefinition(typeof (DefinitionTextPage));
              IList<IEditable> editables = definition.Editables;
              Assert.AreEqual(3, editables.Count);
          }
  
          [Test]
          public void No_ItemAttribute_DefaultsToTypeName()
          {
              Type itemType = typeof (DefinitionStartPage);
              ItemDefinition definition = definitions.GetDefinition(itemType);
              Assert.AreEqual(itemType.Name, definition.Discriminator);
          }
  
          [Test]
          public void ItemAttribute_WithoutDiscriminator_DefaultsToTypeName()
          {
  
gt:             Type itemType = typeof (DefinitionTextPage);