diff --git a/JSONAPI.EntityFramework.Tests/EntityFrameworkMaterializerTests.cs b/JSONAPI.EntityFramework.Tests/EntityFrameworkMaterializerTests.cs new file mode 100644 index 00000000..01f9e437 --- /dev/null +++ b/JSONAPI.EntityFramework.Tests/EntityFrameworkMaterializerTests.cs @@ -0,0 +1,88 @@ +using System; +using System.Linq; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using JSONAPI.EntityFramework.Tests.Models; +using FluentAssertions; +using System.Collections.Generic; + +namespace JSONAPI.EntityFramework.Tests +{ + [TestClass] + public class EntityFrameworkMaterializerTests + { + private class NotAnEntity + { + public string Id { get; set; } + public string Temporary { get; set; } + } + + private TestEntities context; + private Backlink b1, b2; + + [TestInitialize] + public void SetupEntities() + { + //- See http://stackoverflow.com/a/19130718/489116 + var instance = System.Data.Entity.SqlServer.SqlProviderServices.Instance; + //- + + context = new TestEntities(); + //JSONAPI.EntityFramework.Json.ContractResolver.ObjectContext = context; + + + // Clear it out! + foreach (Backlink o in context.Backlinks) context.Backlinks.Remove(o); + context.SaveChanges(); + + b1 = new Backlink + { + Url = "http://www.google.com/", + Snippet = "1 Results" + }; + + context.SaveChanges(); + } + + [TestMethod] + public void GetKeyNamesStandardIdTest() + { + // Arrange + var materializer = new EntityFrameworkMaterializer(context); + + // Act + IEnumerable keyNames = materializer.GetKeyNames(typeof(Post)); + + // Assert + keyNames.Count().Should().Be(1); + keyNames.First().Should().Be("Id"); + } + + [TestMethod] + public void GetKeyNamesNonStandardIdTest() + { + // Arrange + var materializer = new EntityFrameworkMaterializer(context); + + // Act + IEnumerable keyNames = materializer.GetKeyNames(typeof(Backlink)); + + // Assert + keyNames.Count().Should().Be(1); + keyNames.First().Should().Be("Url"); + } + + [TestMethod] + [ExpectedException(typeof(System.ArgumentException))] + public void GetKeyNamesNotAnEntityTest() + { + // Arrange + var materializer = new EntityFrameworkMaterializer(context); + + // Act + IEnumerable keyNames = materializer.GetKeyNames(typeof(NotAnEntity)); + + // Assert + Assert.Fail("A System.ArgumentException should be thrown, this assertion should be unreachable!"); + } + } +} diff --git a/JSONAPI.EntityFramework.Tests/JSONAPI.EntityFramework.Tests.csproj b/JSONAPI.EntityFramework.Tests/JSONAPI.EntityFramework.Tests.csproj index 791fab24..a8608ba1 100644 --- a/JSONAPI.EntityFramework.Tests/JSONAPI.EntityFramework.Tests.csproj +++ b/JSONAPI.EntityFramework.Tests/JSONAPI.EntityFramework.Tests.csproj @@ -90,11 +90,13 @@ + + diff --git a/JSONAPI.EntityFramework.Tests/Models/Backlink.cs b/JSONAPI.EntityFramework.Tests/Models/Backlink.cs new file mode 100644 index 00000000..168f19be --- /dev/null +++ b/JSONAPI.EntityFramework.Tests/Models/Backlink.cs @@ -0,0 +1,18 @@ +using JSONAPI.Attributes; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace JSONAPI.EntityFramework.Tests.Models +{ + public class Backlink + { + [UseAsId] + [System.ComponentModel.DataAnnotations.Key] + public string Url { get; set; } + + public Post Post { get; set; } + public string Snippet { get; set; } + } +} diff --git a/JSONAPI.EntityFramework.Tests/Models/TestEntities.cs b/JSONAPI.EntityFramework.Tests/Models/TestEntities.cs index cb6a7db9..67b61d3b 100644 --- a/JSONAPI.EntityFramework.Tests/Models/TestEntities.cs +++ b/JSONAPI.EntityFramework.Tests/Models/TestEntities.cs @@ -6,6 +6,8 @@ public partial class TestEntities : DbContext { + private class TestEntitiesInitializer : DropCreateDatabaseIfModelChanges { } + public TestEntities() : base("name=TestEntities") { @@ -13,11 +15,12 @@ public TestEntities() protected override void OnModelCreating(DbModelBuilder modelBuilder) { - //throw new UnintentionalCodeFirstException(); + Database.SetInitializer(new TestEntitiesInitializer()); } public virtual DbSet Authors { get; set; } public virtual DbSet Posts { get; set; } public virtual DbSet Comments { get; set; } + public virtual DbSet Backlinks { get; set; } } } diff --git a/JSONAPI.EntityFramework/EntityFrameworkMaterializer.cs b/JSONAPI.EntityFramework/EntityFrameworkMaterializer.cs index 635128d2..cca5b1f4 100644 --- a/JSONAPI.EntityFramework/EntityFrameworkMaterializer.cs +++ b/JSONAPI.EntityFramework/EntityFrameworkMaterializer.cs @@ -184,25 +184,28 @@ private Type GetSingleType(Type type) return type; } - protected virtual IEnumerable GetKeyNames(Type type) + protected internal virtual IEnumerable GetKeyNames(Type type) { - try - { - // If this fails, type must not be in the context!!! - ObjectContext objectContext = ((IObjectContextAdapter)this.context).ObjectContext; - IEnumerable retval = (IEnumerable)objectContext.MetadataWorkspace - .GetType(type.Name, type.Namespace, System.Data.Entity.Core.Metadata.Edm.DataSpace.CSpace) - .MetadataProperties - .Where(mp => mp.Name == "KeyMembers") - .First() - .Value; - return retval; + ObjectContext objectContext = ((IObjectContextAdapter)this.context).ObjectContext; + System.Data.Entity.Core.Metadata.Edm.EdmType meta; + try { + meta = objectContext.MetadataWorkspace + .GetType(type.Name, type.Namespace, System.Data.Entity.Core.Metadata.Edm.DataSpace.CSpace); } - catch (Exception e) + catch (System.ArgumentException e) { - // Type is not an entity type in the context. Um...now what? Either override this in a subclass, or we'll assume it's "Id"! - return new string[] { "Id" }; + throw new ArgumentException( + String.Format("The Type {0} was not found in the DbContext with Type {1}", type.Name, this.context.GetType().Name), + e + ); } + var members = (IEnumerable)meta + .MetadataProperties + .Where(mp => mp.Name == "KeyMembers") + .First() + .Value; + IEnumerable retval = members.Select(m => m.Name); + return retval; } /// diff --git a/JSONAPI.EntityFramework/Properties/AssemblyInfo.cs b/JSONAPI.EntityFramework/Properties/AssemblyInfo.cs index 1a587afe..3205b9a6 100644 --- a/JSONAPI.EntityFramework/Properties/AssemblyInfo.cs +++ b/JSONAPI.EntityFramework/Properties/AssemblyInfo.cs @@ -22,6 +22,8 @@ // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("cdabab0c-3332-4b93-8cb6-ad521265a701")] +[assembly: InternalsVisibleTo("JSONAPI.EntityFramework.Tests")] + // Version information for an assembly consists of the following four values: // // Major Version