private static void TestSpatialMetadata(DSPDataProviderKind providerKind) { DSPMetadata metadata = new DSPMetadata("SpatialMetadata", "AstoriaUnitTests.Tests"); // Entity with all types of geography properties KeyValuePair <string, Type>[] geographyProperties = new KeyValuePair <string, Type>[] { new KeyValuePair <string, Type>("GeographyProperty", typeof(Geography)), new KeyValuePair <string, Type>("PointProperty", typeof(GeographyPoint)), new KeyValuePair <string, Type>("LineStringProperty", typeof(GeographyLineString)), }; string entityTypeName = "AllGeographyTypes"; SpatialTestUtil.AddEntityType(metadata, entityTypeName, geographyProperties, useComplexType: false, useOpenTypes: false); metadata.SetReadOnly(); var service = new DSPUnitTestServiceDefinition(metadata, providerKind, new DSPContext()); using (TestWebRequest request = service.CreateForInProcess()) { request.StartService(); request.HttpMethod = "GET"; XDocument response = UnitTestsUtil.GetResponseAsAtomXLinq(request, "/$metadata"); XElement schemaElement = response.Root.Element(UnitTestsUtil.EdmxNamespace + "DataServices").Elements().Single(e => e.Name.LocalName == "Schema"); XNamespace edmNs = schemaElement.Name.Namespace; XElement entityElement = schemaElement.Elements(edmNs + "EntityType").Single(e => (string)e.Attribute("Name") == entityTypeName); foreach (KeyValuePair <string, Type> property in geographyProperties) { XElement propertyElement = entityElement.Elements(edmNs + "Property").Single(e => (string)e.Attribute("Name") == property.Key); // EF provider currently represents all types as Edm.Geography in metadata (property is DbGeography on the entity), otherwise it should reflect the actual type string expectedEdmTypeName = providerKind == DSPDataProviderKind.EF ? "Edm.Geography" : GetExpectedEdmTypeName(property.Value); Assert.AreEqual(expectedEdmTypeName, propertyElement.Attribute("Type").Value, "Wrong property type for property {0},", property.Key); XAttribute attribute = propertyElement.Attributes().Where(a => a.Name == "SRID").Single(); Assert.AreEqual("Variable", attribute.Value); } } }
public DSPUnitTestServiceDefinition(DSPMetadata metadata, DSPDataProviderKind kind, DSPContext context) { this.Metadata = metadata; if (kind == DSPDataProviderKind.CustomProvider) { this.DataServiceType = typeof(DSPDataService); this.ProviderKind = DSPDataProviderKind.CustomProvider; this.CreateDataSource = (m) => context; } else { Type contextType = GenerateAssemblyAndGetContextType(metadata, kind); this.ProviderKind = kind; this.DataServiceType = typeof(OpenWebDataService<>).MakeGenericType(contextType); if (kind == DSPDataProviderKind.EF || kind == DSPDataProviderKind.Reflection) { PopulateContextWithDefaultData(contextType, context, kind); } } }
public static void ClassInitialize(TestContext context) { DSPDataProviderKind providerKind = DSPDataProviderKind.EF; // set up the service DSPMetadata metadata = GetModel(false /*openType*/, false /*namedStreams*/); DSPContext defaultData = GetDefaultData(metadata); DSPUnitTestServiceDefinition.ModifyGeneratedCode = (currentCode) => { // Add namespace which includes Code First Attributes currentCode.Insert(currentCode.ToString().IndexOf("public class PeopleType"), "using System.ComponentModel.DataAnnotations;\n\n"); // Add the required attributes currentCode.Insert(currentCode.ToString().IndexOf("public string Name { get; set; }"), "[Required()]\n"); currentCode.Insert(currentCode.ToString().IndexOf("public byte[] Body { get; set; }"), "[Required()]\n"); currentCode.Insert(currentCode.ToString().IndexOf("public int? Age { get; set; }"), "[Required()]\n"); return(currentCode); }; service = new DSPUnitTestServiceDefinition(metadata, providerKind, defaultData); service.Writable = true; }
private static void TestSpatialMetadata(DSPDataProviderKind providerKind) { DSPMetadata metadata = new DSPMetadata("SpatialMetadata", "AstoriaUnitTests.Tests"); // Entity with all types of geography properties KeyValuePair<string, Type>[] geographyProperties = new KeyValuePair<string, Type>[] { new KeyValuePair<string, Type>("GeographyProperty", typeof(Geography)), new KeyValuePair<string, Type>("PointProperty", typeof(GeographyPoint)), new KeyValuePair<string, Type>("LineStringProperty", typeof(GeographyLineString)), }; string entityTypeName = "AllGeographyTypes"; SpatialTestUtil.AddEntityType(metadata, entityTypeName, geographyProperties, useComplexType: false, useOpenTypes: false); metadata.SetReadOnly(); var service = new DSPUnitTestServiceDefinition(metadata, providerKind, new DSPContext()); using (TestWebRequest request = service.CreateForInProcess()) { request.StartService(); request.HttpMethod = "GET"; XDocument response = UnitTestsUtil.GetResponseAsAtomXLinq(request, "/$metadata"); XElement schemaElement = response.Root.Element(UnitTestsUtil.EdmxNamespace + "DataServices").Elements().Single(e => e.Name.LocalName == "Schema"); XNamespace edmNs = schemaElement.Name.Namespace; XElement entityElement = schemaElement.Elements(edmNs + "EntityType").Single(e => (string)e.Attribute("Name") == entityTypeName); foreach (KeyValuePair<string, Type> property in geographyProperties) { XElement propertyElement = entityElement.Elements(edmNs + "Property").Single(e => (string)e.Attribute("Name") == property.Key); // EF provider currently represents all types as Edm.Geography in metadata (property is DbGeography on the entity), otherwise it should reflect the actual type string expectedEdmTypeName = providerKind == DSPDataProviderKind.EF ? "Edm.Geography" : GetExpectedEdmTypeName(property.Value); Assert.AreEqual(expectedEdmTypeName, propertyElement.Attribute("Type").Value, "Wrong property type for property {0},", property.Key); XAttribute attribute = propertyElement.Attributes().Where(a => a.Name == "SRID").Single(); Assert.AreEqual("Variable", attribute.Value); } } }
private static void PopulateContextWithDefaultData(Type contextType, DSPContext dspContext, DSPDataProviderKind providerKind) { Assert.IsTrue(providerKind == DSPDataProviderKind.EF || providerKind == DSPDataProviderKind.Reflection, "expecting only EF and reflection provider"); Dictionary<DSPResource, object> entitiesAlreadyAdded = new Dictionary<DSPResource, object>(); // push all the data to the context. // create a new instance of the context var context = Activator.CreateInstance(contextType); // Clear the database if the context is EF context if (providerKind == DSPDataProviderKind.EF) { if (((DbContext)context).Database.Exists()) { ((DbContext)context).Database.Delete(); } } foreach (var set in dspContext.EntitySets) { string setName = set.Key; List<object> entities = set.Value; foreach (var entity in entities) { DSPResource resource = (DSPResource)entity; if (!entitiesAlreadyAdded.ContainsKey(resource)) { Type entityType = contextType.Assembly.GetType(resource.ResourceType.FullName); var entityInstance = Activator.CreateInstance(entityType); if (providerKind == DSPDataProviderKind.EF) { ((DbContext)context).Set(entityType).Add(entityInstance); } else { IList list = (IList)context.GetType().GetField("_" + setName, BindingFlags.Public | BindingFlags.Static).GetValue(context); list.Add(entityInstance); } entitiesAlreadyAdded.Add(resource, entityInstance); PopulateProperties(context, entityInstance, resource, entitiesAlreadyAdded); } else if (providerKind == DSPDataProviderKind.Reflection) { // Since in reflection provider, adding to the collection does not add to the top level set, adding it explicitly now. IList list = (IList)context.GetType().GetField("_" + setName, BindingFlags.Public | BindingFlags.Static).GetValue(context); list.Add(entitiesAlreadyAdded[resource]); } } } if (providerKind == DSPDataProviderKind.EF) { ((DbContext)context).SaveChanges(); } }
private static Type GenerateAssemblyAndGetContextType(DSPMetadata metadata, DSPDataProviderKind providerKind) { Assert.IsTrue(providerKind == DSPDataProviderKind.EF || providerKind == DSPDataProviderKind.Reflection, "expecting only EF and reflection provider"); StringBuilder stringBuilder = new StringBuilder(); // Generate context class stringBuilder.Append("namespace " + metadata.ContainerNamespace); stringBuilder.AppendLine(" { "); stringBuilder.AppendLine("using System.Linq;"); string contextBaseType = (providerKind == DSPDataProviderKind.EF) ? " : System.Data.Entity.DbContext" : String.Empty; stringBuilder.Append("public class " + metadata.ContainerName + contextBaseType); stringBuilder.AppendLine(" { "); foreach (var set in metadata.ResourceSets) { if (providerKind == DSPDataProviderKind.EF) { stringBuilder.AppendLine(String.Format("public System.Data.Entity.DbSet<{0}> {1} {{ get; set; }}", set.ResourceType.FullName, set.Name)); } else { stringBuilder.AppendLine(String.Format("public static System.Collections.Generic.List<{0}> _{1} = new System.Collections.Generic.List<{0}>();", set.ResourceType.FullName, set.Name)); stringBuilder.AppendLine(String.Format("public System.Linq.IQueryable<{0}> {1} {{ get {{ return _{1}.AsQueryable(); }}}}", set.ResourceType.FullName, set.Name)); } } stringBuilder.AppendLine(" } "); // context class end stringBuilder.AppendLine(" } "); // end namespace // Generate C# code for the given metadata foreach (var resource in metadata.Types) { stringBuilder.Append("namespace " + resource.Namespace); stringBuilder.AppendLine(" { "); if (resource.ETagProperties.Any()) { stringBuilder.AppendFormat("[global::Microsoft.OData.Service.ETag({0})]", String.Join(",", resource.ETagProperties.Where(etagProp => resource.PropertiesDeclaredOnThisType.Contains(etagProp)).Select(etagProperty => string.Format("\"{0}\"", etagProperty.Name)))); } stringBuilder.Append("public class " + resource.Name); if (resource.BaseType != null) { stringBuilder.Append(" : " + resource.BaseType.FullName); } stringBuilder.AppendLine(" { "); // write the default constructor stringBuilder.AppendLine("public " + resource.Name + "()"); stringBuilder.AppendLine("{"); foreach (var property in resource.PropertiesDeclaredOnThisType.Where(p => p.Kind == ResourcePropertyKind.ResourceSetReference)) { stringBuilder.AppendLine(String.Format("this.{0} = new System.Collections.Generic.List<{1}>();", property.Name, property.ResourceType.FullName)); } stringBuilder.AppendLine(" } "); // constructor end // write all the properties foreach (var property in resource.PropertiesDeclaredOnThisType) { if (IsPropertyKind(property, ResourcePropertyKind.Primitive)) { if (providerKind == DSPDataProviderKind.EF && IsPropertyKind(property, ResourcePropertyKind.Key)) { stringBuilder.AppendLine("[System.ComponentModel.DataAnnotations.DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.None)]"); } // Entity Framework's spatial types are not currently the same as the type we use, so we need to use their type for the entity property Type resourcePropertyType = property.ResourceType.InstanceType; #if !EFRTM Type efPropertyType = typeof(Geography).IsAssignableFrom(resourcePropertyType) ? typeof(System.Data.Spatial.DbGeography) : resourcePropertyType; #else Type efPropertyType = resourcePropertyType; #endif stringBuilder.AppendLine(String.Format("public {0} {1} {{ get; set; }}", efPropertyType.ToCSharpString(), property.Name)); } else if (IsPropertyKind(property, ResourcePropertyKind.ComplexType) || property.Kind == ResourcePropertyKind.ResourceReference) { stringBuilder.AppendLine(String.Format("public {0} {1} {{ get; set; }}", property.ResourceType.FullName, property.Name)); } else if (property.Kind == ResourcePropertyKind.ResourceSetReference) { stringBuilder.AppendLine(String.Format("public System.Collections.Generic.List<{0}> {1} {{ get; set; }}", property.ResourceType.FullName, property.Name)); } else { throw new Exception("Invalid Property encountered"); } } stringBuilder.AppendLine(" } "); // class end stringBuilder.AppendLine(" } "); // end namespace } string contextTypeName = metadata.ContainerNamespace + "." + metadata.ContainerName; string assemblyName = contextTypeName + (providerKind == DSPDataProviderKind.EF ? "_EF" : "_Reflection"); string assemblyFullPath = Path.Combine(test.TestUtil.GeneratedFilesLocation, assemblyName + ".dll"); // Modify the generated code if (DSPUnitTestServiceDefinition.ModifyGeneratedCode != null) { stringBuilder = ModifyGeneratedCode(stringBuilder); } // compile the assembly test.TestUtil.GenerateAssembly(stringBuilder.ToString(), assemblyFullPath, new string[] { Path.Combine(test.TestUtil.GreenBitsReferenceAssembliesDirectory, "System.ComponentModel.DataAnnotations.dll"), "EntityFramework.dll" }); Assembly assembly = Assembly.LoadFrom(assemblyFullPath); return assembly.GetType(contextTypeName); }
internal static DSPUnitTestServiceDefinition CreateRoadTripServiceDefinition(DSPMetadata roadTripMetadata, GeographyPropertyValues defaultValues, DSPDataProviderKind providerKind, bool useComplexType = false, Action<string, List<KeyValuePair<string, object>>> modifyPropertyValues = null) { Assert.IsFalse(useComplexType, "Complex type support is not yet added to the property population in DSPUnitTestServiceDefinition."); DSPContext defaultData = PopulateRoadTripData(roadTripMetadata, defaultValues, useComplexType, modifyPropertyValues); var service = new DSPUnitTestServiceDefinition(roadTripMetadata, providerKind, defaultData); service.HostInterfaceType = typeof(IDataServiceHost2); service.DataServiceBehavior.AcceptSpatialLiteralsInQuery = true; service.Writable = true; service.DataServiceBehavior.MaxProtocolVersion = ODataProtocolVersion.V4; return service; }
private static DSPUnitTestServiceDefinition GetUnitTestServiceDefinition(DSPDataProviderKind providerKind, bool openType, bool namedStreams) { DSPMetadata metadata = GetModel(openType, namedStreams); DSPContext defaultData = GetDefaultData(metadata); var service = new DSPUnitTestServiceDefinition(metadata, providerKind, defaultData); service.DataServiceBehavior.IncludeRelationshipLinksInResponse = true; service.Writable = true; if (providerKind == DSPDataProviderKind.CustomProvider) { service.SupportNamedStream = true; service.MediaResourceStorage = new DSPMediaResourceStorage(); } return service; }
internal static DSPUnitTestServiceDefinition CreateRoadTripServiceDefinition(DSPMetadata roadTripMetadata, GeographyPropertyValues defaultValues, DSPDataProviderKind providerKind, bool useComplexType = false, Action <string, List <KeyValuePair <string, object> > > modifyPropertyValues = null) { Assert.IsFalse(useComplexType, "Complex type support is not yet added to the property population in DSPUnitTestServiceDefinition."); DSPContext defaultData = PopulateRoadTripData(roadTripMetadata, defaultValues, useComplexType, modifyPropertyValues); var service = new DSPUnitTestServiceDefinition(roadTripMetadata, providerKind, defaultData); service.HostInterfaceType = typeof(IDataServiceHost2); service.DataServiceBehavior.AcceptSpatialLiteralsInQuery = true; service.Writable = true; service.DataServiceBehavior.MaxProtocolVersion = ODataProtocolVersion.V4; return(service); }