Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions JSONAPI.EntityFramework.Tests/EntityFrameworkMaterializerTests.cs
Original file line number Diff line number Diff line change
@@ -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<string> 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<string> 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<string> keyNames = materializer.GetKeyNames(typeof(NotAnEntity));

// Assert
Assert.Fail("A System.ArgumentException should be thrown, this assertion should be unreachable!");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really like FluentAssertions for this sort of thing. You can do:

Action action = () =>
{
    IEnumerable<string> keyNames = materializer.GetKeyNames(typeof(NotAnEntity));
};
action.ShouldThrow<ArgumentException>();

which I think is clearer than adding an attribute on the method. You can also add additional checks against the exception object itself, which you can't do with the MSTest approach.

}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,13 @@
<ItemGroup>
<Compile Include="ActionFilters\EnumerateQueryableAsyncAttributeTests.cs" />
<Compile Include="EntityConverterTests.cs" />
<Compile Include="EntityFrameworkMaterializerTests.cs" />
<Compile Include="Helpers\TestDbAsyncEnumerable.cs" />
<Compile Include="Helpers\WaitsUntilCancellationDbAsyncEnumerator.cs" />
<Compile Include="Helpers\TestDbAsyncEnumerator.cs" />
<Compile Include="Helpers\TestDbAsyncQueryProvider.cs" />
<Compile Include="Models\Author.cs" />
<Compile Include="Models\Backlink.cs" />
<Compile Include="Models\Comment.cs" />
<Compile Include="Models\TestEntities.cs" />
<Compile Include="Models\Post.cs" />
Expand Down
18 changes: 18 additions & 0 deletions JSONAPI.EntityFramework.Tests/Models/Backlink.cs
Original file line number Diff line number Diff line change
@@ -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; }
}
}
5 changes: 4 additions & 1 deletion JSONAPI.EntityFramework.Tests/Models/TestEntities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,21 @@

public partial class TestEntities : DbContext
{
private class TestEntitiesInitializer : DropCreateDatabaseIfModelChanges<TestEntities> { }

public TestEntities()
: base("name=TestEntities")
{
}

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//throw new UnintentionalCodeFirstException();
Database.SetInitializer<TestEntities>(new TestEntitiesInitializer());
}

public virtual DbSet<Author> Authors { get; set; }
public virtual DbSet<Post> Posts { get; set; }
public virtual DbSet<Comment> Comments { get; set; }
public virtual DbSet<Backlink> Backlinks { get; set; }
}
}
33 changes: 18 additions & 15 deletions JSONAPI.EntityFramework/EntityFrameworkMaterializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -184,25 +184,28 @@ private Type GetSingleType(Type type)
return type;
}

protected virtual IEnumerable<string> GetKeyNames(Type type)
protected internal virtual IEnumerable<string> GetKeyNames(Type type)
{
try
{
// If this fails, type must not be in the context!!!
ObjectContext objectContext = ((IObjectContextAdapter)this.context).ObjectContext;
IEnumerable<string> retval = (IEnumerable<string>)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<System.Data.Entity.Core.Metadata.Edm.EdmMember>)meta
.MetadataProperties
.Where(mp => mp.Name == "KeyMembers")
.First()
.Value;
IEnumerable<string> retval = members.Select(m => m.Name);
return retval;
}

/// <summary>
Expand Down
2 changes: 2 additions & 0 deletions JSONAPI.EntityFramework/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down