context: /* This file is part of the db4o object database http://www.db4o.com
  
  Copyright (C) 2004 - 2011  Versant Corporation http://www.versant.com
  
  db4o is free software; you can redistribute it and/or modify it under
  the terms of version 3 of the GNU General Public License as published
  by the Free Software Foundation.
  
  db4o is distributed in the hope that it will be useful, but WITHOUT ANY
  WARRANTY; without even the implied warranty of MERCHANTABILITY or
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  for more details.
  
  You should have received a copy of the GNU General Public License along
  with this program.  If not, see http://www.gnu.org/licenses/. */
  
  using System;
  using System.Collections.Generic;
  using System.Data.Services;
  using System.Data.Services.Client;
  using System.Data.Services.Common;
  using System.Linq;
  using System.Linq.Expressions;
  using System.ServiceModel;
  using Db4objects.Db4o.Linq;
  using Db4oUnit;
  using Moq;
  using Moq.Language.Flow;
  
  namespace Db4objects.Db4o.Data.Services.Tests.Integration
  {
      internal class DataServiceHostIntegrationTestCase : ITestLifeCycle
      {
          private static readonly Uri ServiceUri = new Uri("http://127.0.0.1:666/integration");
  
          private readonly MockFactory _mockery = new MockFactory(MockBehavior.Strict)
          {
              DefaultValue = DefaultValue.Mock
          };
  
          private readonly Mock<IResourceFinder> _resourceFinderMock;
          private readonly Mock<IObjectContainer> _sessionMock;
          private DataServiceHost _dataHost;
  
          public DataServiceHostIntegrationTestCase()
          {
              _sessionMock = Mock<IObjectContainer>();
              _resourceFinderMock = Mock<IResourceFinder>();
          }
  
          public void SetUp()
          {
              _dataHost = new DataServiceHost(typeof (IntegrationDataService), new[] {ServiceUri});
              _dataHost.Open();
          }
  
          public void TearDown()
          {
              _dataHost.Close();
          }
  
          private Mock<T> Mock<T>() where T : class
          {
              return _mockery.Create<T>();
          }
  
          public void TestAddObject()
          {
              var contact = new Contact {Email = "a@b.c", Name = "abc"};
  
              Setup(session => session.Store(It.Is<Contact>(actual => actual.Equals(contact))))
                  .AtMostOnce();
  
              Setup(session => session.Commit())
                  .AtMostOnce();
  
              Playback(() =>
              {
                  var context = new DataServiceContext(ServiceUri);
                  context.AddObject("Contacts", contact);
                  context.SaveChanges();
              });
          }
  
          public void TestUpdateObject()
          {
              var contact = new Contact {Email = "a@b.c", Name = "new name"};
  
              _resourceFinderMock.Setup(
                  resourceFinder => resourceFinder.GetResource(It.IsAny<IQueryable<Contact>>(), typeof (Contact).FullName))
                  .Returns(contact)
                  .AtMostOnce();
  
              Setup(session => session.Store(It.Is<Contact>(actual => actual == contact)))
                  .AtMostOnce();
  
              Setup(session => session.Commit())
                  .AtMostOnce();
  
              Playback(() =>
              {
                  var context = new DataServiceContext(ServiceUri);
                  context.AttachTo("Contacts", contact);
                  context.UpdateObject(contact);
                  context.SaveChanges();
              });
          }
  
          public void TestDeleteObject()
          {
              var contact = new Contact {Email = "a@b.c", Name = "abc"};
  
              _resourceFinderMock.Setup(
                  resourceFinder => resourceFinder.GetResource(It.IsAny<IQueryable<Contact>>(), null))
                  .Returns(contact)
                  .AtMostOnce();
  
              Setup(session => session.Delete(It.Is<Contact>(actual => actual == contact)))
                  .AtMostOnce();
  
              Setup(session => session.Commit())
                  .AtMostOnce();
  
              Playback(() =>
              {
                  var context = new DataServiceContext(ServiceUri);
                  context.AttachTo("Contacts", contact);
                  context.DeleteObject(contact);
                  context.SaveChanges();
              });
          }
  
          public void TestAddObjectGraph()
          {
              var message = new Message
              {
                  Id = Guid.NewGuid(),
                  Body = "Hi!",
                  To = new Contact
                  {
                      Email = "a@b.c",
                      Name = "abc"
                  }
              };
  
              Setup(session => session.Store(It.Is<Contact>(actual => actual.Equals(message.To))))
                  .AtMostOnce();
  
              Setup(session => session.Commit())
                  .AtMost(2);
  
              _resourceFinderMock.Setup(
                  resourceFinder => resourceFinder.GetResource(It.IsAny<IQueryable<Contact>>(), null))
                  .Returns(message.To)
                  .AtMostOnce();
  
              Setup(session => session.Store(It.Is<Message>(actual => actual.Equals(message))))
                  .AtMostOnce();
  
              var context = new DataServiceContext(ServiceUri);
              Playback(() =>
              {
                  context.AddObject("Contacts", message.To);
                  context.AddObject("Messages", message);
                  context.SetLink(message, "To", message.To);
                  context.SaveChanges();
              });
          }
  
          public void TestReferenceUpdate()
          {
              var message = new Message
              {
                  Id = Guid.NewGuid(),
                  Body = "Hi!",
                  To = new Contact
                  {
                      Email = "a@b.c"
                  }
              };
  
              var newContact = new Contact
              {
                  Email = "d@e.f"
              };
  
              _resourceFinderMock.Setup(
                  resourceFinder => resourceFinder.GetResource(It.IsAny<IQueryable<Message>>(), null))
                  .Returns(message)
                  .AtMostOnce();
  
              _resourceFinderMock.Setup(
                  resourceFinder => resourceFinder.GetResource(It.IsAny<IQueryable<Contact>>(), null))
                  .Returns(newContact)
                  .AtMostOnce();
  
              Setup(session => session.Store(It.Is<Message>(actual => actual == message && actual.To == newContact)))
                  .AtMostOnce();
  
              Setup(session => session.Commit())
                  .AtMostOnce();
  
              var context = new DataServiceContext(ServiceUri);
              Playback(() =>
              {
                  context.AttachTo("Contacts", newContact);
                  context.AttachTo("Messages", message);
                  context.SetLink(message, "To", newContact);
                  context.SaveChanges();
              });
          }
  
          public void TestCollectionAdd()
          {
              var message = new Message
              {
                  Id = Guid.NewGuid(),
                  Body = "Hi!",
                  CC = new List<Contact>()
              };
  
              var cc = new Contact
              {
                  Email = "d@e.f",
                  Name = "def"
              };
  
              _resourceFinderMock.Setup(
                  resourceFinder => resourceFinder.GetResource(It.IsAny<IQueryable<Message>>(), null))
                  .Returns(message)
                  .AtMostOnce();
  
              _resourceFinderMock.Setup(
                  resourceFinder => resourceFinder.GetResource(It.IsAny<IQueryable<Contact>>(), null))
                  .Returns(cc)
                  .AtMostOnce();
  
              Setup(session => session.Store(It.Is<Message>(actual => actual == message && actual.CC.First() == cc)))
                  .AtMostOnce();
  
              Setup(session => session.Commit())
                  .AtMostOnce();
  
              var context = new DataServiceContext(ServiceUri);
              Playback(() =>
              {
                  context.AttachTo("Contacts", cc);
                  context.AttachTo("Messages", message);
                  context.AddLink(message, "CC", cc);
                  context.SaveChanges();
              });
          }
  
          public void TestCollectionDelete()
          {
              var cc = new Contact
              {
                  Email = "d@e.f",
                  Name = "def"
              };
  
              var message = new Message
              {
                  Id = Guid.NewGuid(),
                  CC = new List<Contact> {cc}
              };
  
              _resourceFinderMock.Setup(
                  resourceFinder => resourceFinder.GetResource(It.IsAny<IQueryable<Message>>(), null))
                  .Returns(message)
                  .AtMostOnce();
  
              _resourceFinderMock.Setup(
                  resourceFinder => resourceFinder.GetResource(It.IsAny<IQueryable<Contact>>(), null))
                  .Returns(cc)
                  .AtMostOnce();
  
              Setup(session => session.Store(It.Is<Message>(actual => actual == message && actual.CC.Count == 0)))
                  .AtMostOnce();
  
              Setup(session => session.Commit())
                  .AtMostOnce();
  
              var context = new DataServiceContext(ServiceUri);
              Playback(() =>
              {
                  context.AttachTo("Contacts", cc);
                  context.AttachTo("Messages", message);
  
                  context.DeleteLink(message, "CC", cc);
  
                  context.SaveChanges();
              });
          }
  
          private ISetup<IObjectContainer> Setup(Expression<Action<IObjectContainer>> expression)
          {
              return _sessionMock.Setup(expression);
          }
  
          private void Playback(Action action)
          {
              IntegrationDataContext.Session = _sessionMock.Object;
              IntegrationDataContext.ResourceFinder = _resourceFinderMock.Object;
              action();
              _mockery.VerifyAll();
          }
      }
  
      [ServiceBehavior(IncludeExceptionDetailInFaults = true)]
      public class IntegrationDataService : DataService<IntegrationDataContext>
      {
          public static void InitializeService(IDataServiceConfiguration config)
          {
              config.SetEntitySetAccessRule("*", EntitySetRights.All);
              config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
              config.UseVerboseErrors = true;
          }
      }
  
      [DataServiceKey("Id")]
      public class Message
      {
          public Guid Id { get; set; }
          public Contact To { get; set; }
          public string Body { get; set; }
          public List<Contact> CC { get; set; }
  
          public override bool Equals(object obj)
          {
              var other = obj as Message;
              if (null == other)
                  return false;
              return Id == other.Id
                     && Equals(To, other.To)
  
gt:                    && Body == other.Body;