/// <summary> /// Executes the <see cref="DataDeleteRequest{TEntity}" />. /// </summary> /// <param name="parameters"></param> /// <returns></returns> public override Message Execute(DataRequestParameters parameters) { if (parameters == null) { throw new ArgumentNullException("parameters"); } if (Entities == null || !Entities.Any()) { throw new ArgumentException("Could not execute request because no entities have been set."); } DataServiceContext serviceContext = Resolve(parameters); foreach (TEntity entity in Entities) { if (!serviceContext.Entities.Contains(serviceContext.GetEntityDescriptor(entity))) { serviceContext.AttachTo(parameters.EntitySet, entity); } serviceContext.DeleteObject(entity); } serviceContext.SaveChanges(); return(null); }
private static void RunEndToEndSmokeTestWithClient(Action <DataServiceContext> customize = null) { using (TestWebRequest request = TestWebRequest.CreateForInProcessWcf()) { request.DataServiceType = typeof(KeyAsSegmentService); request.StartService(); DataServiceContext ctx = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4) { UrlConventions = DataServiceUrlConventions.KeyAsSegment }; if (customize != null) { customize(ctx); } var customer = ctx.CreateQuery <Customer>("Customers").Where(c => c.ID == 0).Single(); var descriptor = ctx.GetEntityDescriptor(customer); var baseUri = request.ServiceRoot.AbsoluteUri; Assert.AreEqual(baseUri + "/Customers/0", descriptor.Identity.OriginalString); Assert.AreEqual(baseUri + "/Customers/0", descriptor.EditLink.OriginalString); Assert.AreEqual(baseUri + "/Customers/0/BestFriend/$ref", descriptor.LinkInfos[0].AssociationLink.OriginalString); Assert.AreEqual(baseUri + "/Customers/0/BestFriend", descriptor.LinkInfos[0].NavigationLink.OriginalString); Assert.AreEqual(baseUri + "/Customers/0/Orders/$ref", descriptor.LinkInfos[1].AssociationLink.OriginalString); Assert.AreEqual(baseUri + "/Customers/0/Orders", descriptor.LinkInfos[1].NavigationLink.OriginalString); } }
public void AdvertiseLargeNumberOfActionsTests() { // Test advertising large number of actions. var testCases = new[] { new { RequestUri = "/Customers(1)", }, }; using (TestWebRequest request = service.CreateForInProcessWcf()) { request.StartService(); t.TestUtil.RunCombinations(testCases, (testCase) => { DataServiceContext ctx = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4); //ctx.EnableAtom = true; //ctx.Format.UseAtom(); ctx.ResolveType = name => typeof(Customer); Uri uri = new Uri(request.ServiceRoot + testCase.RequestUri); QueryOperationResponse <object> qor = (QueryOperationResponse <object>)ctx.Execute <object>(uri); Assert.IsNotNull(qor); IEnumerator <object> entities = qor.GetEnumerator(); entities.MoveNext(); Assert.IsNotNull(entities.Current); EntityDescriptor ed = ctx.GetEntityDescriptor(entities.Current); Assert.IsNotNull(ed); Assert.IsNotNull(ed.OperationDescriptors); Assert.AreEqual(ed.OperationDescriptors.Count(), TotalNumberOfActions, "Invalid count of total number of advertised actions."); }); } }
private List <Tuple <T, string> > PairEntitiesWithEtags(DataServiceContext svcContext, List <T> entities) { var result = new List <Tuple <T, string> >(entities.Count); foreach (var entity in entities) { EntityDescriptor eDesc = svcContext.GetEntityDescriptor(entity); string etag = eDesc.ETag; result.Add(Tuple.Create(entity, etag)); } return(result); }
public void NamedStreams_DeepLinkProjection() { // projecting out deep links to get stream url in DSSL property - both narrow type and anonymous type { // Querying url of the nested type - doing this makes the entity non-tracking, but populated the link property DataServiceContext context = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4); context.EnableAtom = true; context.Format.UseAtom(); var q = from s in context.CreateQuery <EntityWithNamedStreams1>("MySet1") select new { ID = s.Ref.ID, Url = s.Ref.RefStream1 }; Assert.AreEqual(request.ServiceRoot.AbsoluteUri + "/MySet1?$expand=Ref($select=ID),Ref($select=RefStream1)", q.ToString(), "make sure the right uri is produced by the linq translator"); foreach (var o in q) { Assert.IsNotNull(o.Url, "Stream11 must have some value"); Assert.AreEqual(o.Url.EditLink.AbsoluteUri, request.ServiceRoot.AbsoluteUri + "/MySet2(3)/RefStream1", "the stream url must be populated correctly"); Assert.IsNull(context.GetEntityDescriptor(o), "the entity must not be tracked by the context since we are trying to flatten the hierarchy"); } Assert.AreEqual(context.Entities.Count, 0, "there should be no entities tracked by the context, since we are doing flattening"); } { // Querying url of the nested type - doing this makes the entity non-tracking, but populated the link property DataServiceContext context = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4); context.EnableAtom = true; context.Format.UseAtom(); var q = from s in context.CreateQuery <EntityWithNamedStreams1>("MySet1") select new EntityWithNamedStreams1 { ID = s.Ref.ID, RefStream1 = s.Ref.RefStream1 }; Assert.AreEqual(request.ServiceRoot.AbsoluteUri + "/MySet1?$expand=Ref($select=ID),Ref($select=RefStream1)", q.ToString(), "make sure the right uri is produced by the linq translator"); foreach (var o in q) { Assert.IsNotNull(o.RefStream1, "Stream11 must have some value"); Assert.AreEqual(o.RefStream1.EditLink, context.GetReadStreamUri(o, "RefStream1"), "the stream url must be populated correctly"); } Assert.AreEqual(context.Entities.Count, 1, "there should be exactly one entity tracked by the context - the nested entity"); Assert.AreEqual(context.Entities[0].EditLink.AbsoluteUri, request.ServiceRoot.AbsoluteUri + "/MySet2(3)", "the nested entity is the one that should be tracked"); } }
/// <summary> /// Creates the ResponseInfo object. /// </summary> /// <returns>ResponseInfo object.</returns> protected override ResponseInfo CreateResponseInfo() { DataServiceContext context = (DataServiceContext)this.Source; ClientEdmModel model = context.Model; ClientTypeAnnotation type = model.GetClientTypeAnnotation(model.GetOrCreateEdmType(this.entity.GetType())); Debug.Assert(type.IsEntityType, "Must be entity type to be contained."); return(this.RequestInfo.GetDeserializationInfoForLoadProperty( null, context.GetEntityDescriptor(this.entity), type.GetProperty(this.propertyName, false))); }
public void NamedStreams_SimpleLinkProjection() { // Simple projections to get stream url in DSSL property - both narrow type and anonymous type { // Testing querying anonymous types and making sure one is able to project out the stream url DataServiceContext context = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4); context.EnableAtom = true; context.Format.UseAtom(); var q = from s in context.CreateQuery <EntityWithNamedStreams1>("MySet1") select new { ID = s.ID, Stream11 = s.Stream1 }; Assert.AreEqual(q.ToString(), request.ServiceRoot.AbsoluteUri + "/MySet1?$select=ID,Stream1", "make sure the right uri is produced by the linq translator"); foreach (var o in q) { Assert.IsNotNull(o.Stream11, "Stream11 must have some value"); Assert.AreEqual(o.Stream11.EditLink.AbsoluteUri, request.ServiceRoot.AbsoluteUri + "/MySet1(1)/Stream1", "make sure the url property is correctly populated"); Assert.IsNull(context.GetEntityDescriptor(o), "anonymous types are never tracked, even if we do a simple projection"); } Assert.AreEqual(context.Entities.Count, 0, "there should be no entity tracked by the context"); } { // Testing querying narrow entity types and making sure one is able to project out the stream url DataServiceContext context = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4); context.EnableAtom = true; context.Format.UseAtom(); var q = from s in context.CreateQuery <EntityWithNamedStreams1>("MySet1") select new EntityWithNamedStreams1 { ID = s.ID, Stream1 = s.Stream1 }; Assert.AreEqual(q.ToString(), request.ServiceRoot.AbsoluteUri + "/MySet1?$select=ID,Stream1", "make sure the right uri is produced by the linq translator"); foreach (EntityWithNamedStreams1 o in q) { Assert.IsNotNull(o.Stream1, "Stream11 must have some value"); Assert.AreEqual(o.Stream1.EditLink, context.GetReadStreamUri(o, "Stream1"), "the value in the entity descriptor must match with the property value"); } Assert.AreEqual(context.Entities.Count, 1, "there should be only one entity tracked by the context"); } }
private static void RunNegativeActionTestWithAtom(TestCase testCase) { // These tests are specific to Atom and don't apply to JSON Light. // Any JSON Light negative cases are covered by ODL reader tests. See ODL tests OperationReaderJsonLightTests and ODataJsonLightDeserializerTests. using (TestWebRequest request = TestWebRequest.CreateForInProcessWcf()) using (PlaybackService.ProcessRequestOverride.Restore()) { request.ServiceType = typeof(AstoriaUnitTests.Stubs.PlaybackService); request.StartService(); PlaybackService.ProcessRequestOverride.Value = (req) => { // These tests intentionally don't set the base URI of the context, so we need to also remove the xml:base attribute that is automatically // generated by the PayloadGenerator. Otherwise another parsing error will occur before we hit the actual errors we are trying to validate. string payload = PayloadGenerator.Generate(testCase.ResponsePayloadBuilder, ODataFormat.Atom); string xmlBaseAttribute = @"xml:base=""/"""; payload = payload.Remove(payload.IndexOf(xmlBaseAttribute), xmlBaseAttribute.Length); req.SetResponseStreamAsText(payload); req.ResponseHeaders.Add("Content-Type", "application/atom+xml"); req.SetResponseStatusCode(200); return(req); }; Uri uri = new Uri(request.ServiceRoot + "/" + testCase.RequestUriString); DataServiceContext ctx = new DataServiceContext(null, ODataProtocolVersion.V4); ctx.EnableAtom = true; QueryOperationResponse <CustomerEntity> qor = (QueryOperationResponse <CustomerEntity>)ctx.Execute <CustomerEntity>(uri); Assert.IsNotNull(qor); Assert.IsNull(qor.Error); IEnumerator <CustomerEntity> entities = qor.GetEnumerator(); Exception exception = AstoriaTest.TestUtil.RunCatching(delegate() { while (entities.MoveNext()) { CustomerEntity c = entities.Current; EntityDescriptor ed = ctx.GetEntityDescriptor(c); IEnumerable <OperationDescriptor> actualDescriptors = ed.OperationDescriptors; } }); Assert.IsNotNull(exception); Assert.AreEqual(testCase.ExpectedErrorMessage, exception.Message); } }
public static EntityStates GetStateForEntity(DataServiceContext context, object target) { if (context == null) { throw new ArgumentNullException("context"); } if (target == null) { throw new ArgumentNullException("target"); } EntityDescriptor descriptor = context.GetEntityDescriptor(target); EntityStates result = (descriptor == null) ? EntityStates.Detached : descriptor.State; return result; }
/// <summary> /// loading a property from a response /// </summary> /// <returns>QueryOperationResponse instance containing information about the response.</returns> internal QueryOperationResponse LoadProperty() { MaterializeAtom results = null; DataServiceContext context = (DataServiceContext)this.Source; ClientEdmModel model = context.Model; ClientTypeAnnotation type = model.GetClientTypeAnnotation(model.GetOrCreateEdmType(this.entity.GetType())); Debug.Assert(type.IsEntityType, "must be entity type to be contained"); EntityDescriptor box = context.GetEntityDescriptor(this.entity); if (EntityStates.Added == box.State) { throw Error.InvalidOperation(Strings.Context_NoLoadWithInsertEnd); } ClientPropertyAnnotation property = type.GetProperty(this.propertyName, false); Type elementType = property.EntityCollectionItemType ?? property.NullablePropertyType; try { if (type.MediaDataMember == property) { results = this.ReadPropertyFromRawData(property); } else { results = this.ReadPropertyFromAtom(property); } return(this.GetResponseWithType(results, elementType)); } catch (InvalidOperationException ex) { QueryOperationResponse response = this.GetResponseWithType(results, elementType); if (response != null) { response.Error = ex; throw new DataServiceQueryException(Strings.DataServiceException_GeneralError, ex, response); } throw; } }
public static EntityStates GetStateForEntity(DataServiceContext context, object target) { if (context == null) { throw new ArgumentNullException("context"); } if (target == null) { throw new ArgumentNullException("target"); } EntityDescriptor descriptor = context.GetEntityDescriptor(target); EntityStates result = (descriptor == null) ? EntityStates.Detached : descriptor.State; return(result); }
private static void RunPositiveTest(ODataFormat format, TestCase testCase) { MyDSPActionProvider actionProvider = new MyDSPActionProvider(); DSPServiceDefinition service = new DSPServiceDefinition() { Metadata = Metadata, CreateDataSource = CreateDataSource, ActionProvider = actionProvider }; service.DataServiceBehavior.MaxProtocolVersion = ODataProtocolVersion.V4; using (TestWebRequest request = service.CreateForInProcessWcf()) { request.StartService(); DataServiceContext ctx = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4); //ctx.EnableAtom = true; Uri uri = new Uri(request.ServiceRoot + "/" + testCase.RequestUriString); MakeFinalChangesToTestCase(testCase, format, actionProvider, request); if (format == ODataFormat.Json) { JsonLightTestUtil.ConfigureContextForJsonLight(ctx, null); } else { //ctx.Format.UseAtom(); } QueryOperationResponse <CustomerEntity> qor = (QueryOperationResponse <CustomerEntity>)ctx.Execute <CustomerEntity>(uri); Assert.IsNotNull(qor); Assert.IsNull(qor.Error); IEnumerator <CustomerEntity> entities = qor.GetEnumerator(); int expectedDescriptorsPerEntity = 0; while (entities.MoveNext()) { CustomerEntity c = entities.Current; EntityDescriptor ed = ctx.GetEntityDescriptor(c); IEnumerable <OperationDescriptor> actualDescriptors = ed.OperationDescriptors; TestEquality(actualDescriptors, testCase.GetExpectedDescriptors(format)[expectedDescriptorsPerEntity++]); } } }
public void AdvertiseLargeNumberOfActionsTests() { // Test advertising large number of actions. var testCases = new[] { new { RequestUri = "/Customers(1)", }, }; using (TestWebRequest request = service.CreateForInProcessWcf()) { request.StartService(); t.TestUtil.RunCombinations(testCases, (testCase) => { DataServiceContext ctx = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4); ctx.EnableAtom = true; ctx.Format.UseAtom(); ctx.ResolveType = name => typeof(Customer); Uri uri = new Uri(request.ServiceRoot + testCase.RequestUri); QueryOperationResponse<object> qor = (QueryOperationResponse<object>)ctx.Execute<object>(uri); Assert.IsNotNull(qor); IEnumerator<object> entities = qor.GetEnumerator(); entities.MoveNext(); Assert.IsNotNull(entities.Current); EntityDescriptor ed = ctx.GetEntityDescriptor(entities.Current); Assert.IsNotNull(ed); Assert.IsNotNull(ed.OperationDescriptors); Assert.AreEqual(ed.OperationDescriptors.Count(), TotalNumberOfActions, "Invalid count of total number of advertised actions."); }); } }
private static void VerifyStateOfEntities(DataServiceContext ctx, IEnumerable<object> entities, EntityStates expectedState) { Debug.Assert(ctx != null, "ctx != null"); Debug.Assert(entities != null, "entities != null"); foreach (object entity in entities) { EntityDescriptor descriptor = ctx.GetEntityDescriptor(entity); Debug.Assert(descriptor != null, "EntityDescriptor not found for the given entity"); Assert.AreEqual(expectedState, descriptor.State); } }
/// <summary> /// Verifies the descriptor after execute. /// </summary> /// <param name="continuation">The continuation.</param> /// <param name="dataContext">The data context.</param> /// <param name="entityPayloads">The list of entities</param> /// <param name="expectedValue">The expected value.</param> protected void VerifyDescriptorAfterExecute(IAsyncContinuation continuation, DataServiceContext dataContext, IEnumerable <object> entityPayloads, QueryValue expectedValue) { // If no streams were generated as part of the test initialization then this block of verification is needed if (this.SkipGenerateNamedStream) { continuation.Continue(); } else { object[] entities = entityPayloads.ToArray(); if (this.DataProviderSettings.UsePayloadDrivenVerification) { expectedValue = this.baselineQueryValue; } var expectedEntities = expectedValue as QueryCollectionValue; QueryStructuralValue element; if (expectedEntities == null) { continuation.Continue(); } else { AsyncHelpers.AsyncForEach( expectedEntities.Elements.ToList(), continuation, (qv, entityContinuation) => { // NOTE: The results could be a list of AnonTypes at which point these wouldn't be have descriptors so // no need to verify element = qv as QueryStructuralValue; var queryEntityType = element.Type as QueryEntityType; if (queryEntityType == null) { entityContinuation.Continue(); } else { var queryEntityValue = element as QueryEntityValue; QueryKeyStructuralValue key = queryEntityValue.Key(); // This handles the expand scenario (Orders(1)?$expand=Customer) where the entity in the list doesn't have a corresponding QueryStructuralValue object entity = entities.Where(upe => queryEntityType.ClrType.IsAssignableFrom(upe.GetType()) && queryEntityType.GetEntityInstanceKey(upe).Equals(key)).FirstOrDefault(); if (entity == null) { entityContinuation.Continue(); } else { EntityDescriptor ed = dataContext.GetEntityDescriptor(entity); var streamProperties = queryEntityType.Properties.Where(p => p.IsStream()).ToList(); // intentionally include the default stream int expectedStreamDescriptorCount = streamProperties.Count(p => p.Name != AstoriaQueryStreamType.DefaultStreamPropertyName); this.Assert.AreEqual(expectedStreamDescriptorCount, ed.StreamDescriptors.Count, "Entity descriptor had unexpected number of stream descriptors"); AsyncHelpers.AsyncForEach( streamProperties, entityContinuation, (streamProperty, streamDescriptorContinuation) => { if (streamProperty.Name == AstoriaQueryStreamType.DefaultStreamPropertyName) { this.VerifyDefaultStream(dataContext, element, ed, streamDescriptorContinuation); } else { this.VerifyNamedStreams(dataContext, element, streamProperty, ed, streamDescriptorContinuation); } }); } } }); } } }
public void NamedStreams_DeepLinkProjection() { // projecting out deep links to get stream url in DSSL property - both narrow type and anonymous type { // Querying url of the nested type - doing this makes the entity non-tracking, but populated the link property DataServiceContext context = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4); context.EnableAtom = true; context.Format.UseAtom(); var q = from s in context.CreateQuery<EntityWithNamedStreams1>("MySet1") select new { ID = s.Ref.ID, Url = s.Ref.RefStream1 }; Assert.AreEqual(request.ServiceRoot.AbsoluteUri + "/MySet1?$expand=Ref($select=ID),Ref($select=RefStream1)", q.ToString(), "make sure the right uri is produced by the linq translator"); foreach (var o in q) { Assert.IsNotNull(o.Url, "Stream11 must have some value"); Assert.AreEqual(o.Url.EditLink.AbsoluteUri, request.ServiceRoot.AbsoluteUri + "/MySet2(3)/RefStream1", "the stream url must be populated correctly"); Assert.IsNull(context.GetEntityDescriptor(o), "the entity must not be tracked by the context since we are trying to flatten the hierarchy"); } Assert.AreEqual(context.Entities.Count, 0, "there should be no entities tracked by the context, since we are doing flattening"); } { // Querying url of the nested type - doing this makes the entity non-tracking, but populated the link property DataServiceContext context = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4); context.EnableAtom = true; context.Format.UseAtom(); var q = from s in context.CreateQuery<EntityWithNamedStreams1>("MySet1") select new EntityWithNamedStreams1 { ID = s.Ref.ID, RefStream1 = s.Ref.RefStream1 }; Assert.AreEqual(request.ServiceRoot.AbsoluteUri + "/MySet1?$expand=Ref($select=ID),Ref($select=RefStream1)", q.ToString(), "make sure the right uri is produced by the linq translator"); foreach (var o in q) { Assert.IsNotNull(o.RefStream1, "Stream11 must have some value"); Assert.AreEqual(o.RefStream1.EditLink, context.GetReadStreamUri(o, "RefStream1"), "the stream url must be populated correctly"); } Assert.AreEqual(context.Entities.Count, 1, "there should be exactly one entity tracked by the context - the nested entity"); Assert.AreEqual(context.Entities[0].EditLink.AbsoluteUri, request.ServiceRoot.AbsoluteUri + "/MySet2(3)", "the nested entity is the one that should be tracked"); } }
private void RunPositiveFunctionTest(ODataFormat format, TestCase testCase) { // All of the functions tests use the PlaybackService since the WCF Data Services server doesn't support functions // The PlaybackService itself will not automatically turn Metadata into an absolute URI, so set that to false on all tests. // The tests also use absolute URIs for Target, so suppress that as well. testCase.AddBaseUriToMetadata = false; testCase.AddBaseUriToTarget = false; using (TestWebRequest request = TestWebRequest.CreateForInProcessWcf()) using (PlaybackService.ProcessRequestOverride.Restore()) { request.ServiceType = typeof(AstoriaUnitTests.Stubs.PlaybackService); request.StartService(); var payloadBuilder = testCase.ResponsePayloadBuilder; PlaybackService.ProcessRequestOverride.Value = (req) => { string contentType; if (format == ODataFormat.Json) { contentType = UnitTestsUtil.JsonLightMimeType; payloadBuilder.Metadata = request.BaseUri + "/$metadata#TestService.CustomerEntities/$entity"; } else { contentType = UnitTestsUtil.AtomFormat; } req.SetResponseStreamAsText(PayloadGenerator.Generate(payloadBuilder, format)); req.ResponseHeaders.Add("Content-Type", contentType); req.SetResponseStatusCode(200); return(req); }; testCase.AddBaseUriStringToExpectedDescriptors(request.ServiceRoot.OriginalString, format); Uri uri = new Uri(request.ServiceRoot + "/" + testCase.RequestUriString); DataServiceContext ctx = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4); //ctx.EnableAtom = true; if (format == ODataFormat.Json) { string serviceEdmx = GetServiceEdmxWithOperations(payloadBuilder); JsonLightTestUtil.ConfigureContextForJsonLight(ctx, serviceEdmx); } QueryOperationResponse <CustomerEntity> qor = (QueryOperationResponse <CustomerEntity>)ctx.Execute <CustomerEntity>(uri); Assert.IsNotNull(qor); Assert.IsNull(qor.Error); IEnumerator <CustomerEntity> entities = qor.GetEnumerator(); int expectedDescriptorsPerEntity = 0; while (entities.MoveNext()) { CustomerEntity c = entities.Current; EntityDescriptor ed = ctx.GetEntityDescriptor(c); IEnumerable <OperationDescriptor> actualDescriptors = ed.OperationDescriptors; TestEquality(actualDescriptors, testCase.GetExpectedDescriptors(format)[expectedDescriptorsPerEntity++]); } } }
public void NamedStreams_SimpleLinkProjection() { // Simple projections to get stream url in DSSL property - both narrow type and anonymous type { // Testing querying anonymous types and making sure one is able to project out the stream url DataServiceContext context = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4); context.EnableAtom = true; context.Format.UseAtom(); var q = from s in context.CreateQuery<EntityWithNamedStreams1>("MySet1") select new { ID = s.ID, Stream11 = s.Stream1 }; Assert.AreEqual(q.ToString(), request.ServiceRoot.AbsoluteUri + "/MySet1?$select=ID,Stream1", "make sure the right uri is produced by the linq translator"); foreach (var o in q) { Assert.IsNotNull(o.Stream11, "Stream11 must have some value"); Assert.AreEqual(o.Stream11.EditLink.AbsoluteUri, request.ServiceRoot.AbsoluteUri + "/MySet1(1)/Stream1", "make sure the url property is correctly populated"); Assert.IsNull(context.GetEntityDescriptor(o), "anonymous types are never tracked, even if we do a simple projection"); } Assert.AreEqual(context.Entities.Count, 0, "there should be no entity tracked by the context"); } { // Testing querying narrow entity types and making sure one is able to project out the stream url DataServiceContext context = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4); context.EnableAtom = true; context.Format.UseAtom(); var q = from s in context.CreateQuery<EntityWithNamedStreams1>("MySet1") select new EntityWithNamedStreams1 { ID = s.ID, Stream1 = s.Stream1 }; Assert.AreEqual(q.ToString(), request.ServiceRoot.AbsoluteUri + "/MySet1?$select=ID,Stream1", "make sure the right uri is produced by the linq translator"); foreach (EntityWithNamedStreams1 o in q) { Assert.IsNotNull(o.Stream1, "Stream11 must have some value"); Assert.AreEqual(o.Stream1.EditLink, context.GetReadStreamUri(o, "Stream1"), "the value in the entity descriptor must match with the property value"); } Assert.AreEqual(context.Entities.Count, 1, "there should be only one entity tracked by the context"); } }
private static void RunNegativeActionTestWithAtom(TestCase testCase) { // These tests are specific to Atom and don't apply to JSON Light. // Any JSON Light negative cases are covered by ODL reader tests. See ODL tests OperationReaderJsonLightTests and ODataJsonLightDeserializerTests. using (TestWebRequest request = TestWebRequest.CreateForInProcessWcf()) using (PlaybackService.ProcessRequestOverride.Restore()) { request.ServiceType = typeof(AstoriaUnitTests.Stubs.PlaybackService); request.StartService(); PlaybackService.ProcessRequestOverride.Value = (req) => { // These tests intentionally don't set the base URI of the context, so we need to also remove the xml:base attribute that is automatically // generated by the PayloadGenerator. Otherwise another parsing error will occur before we hit the actual errors we are trying to validate. string payload = PayloadGenerator.Generate(testCase.ResponsePayloadBuilder, ODataFormat.Atom); string xmlBaseAttribute = @"xml:base=""/"""; payload = payload.Remove(payload.IndexOf(xmlBaseAttribute), xmlBaseAttribute.Length); req.SetResponseStreamAsText(payload); req.ResponseHeaders.Add("Content-Type", "application/atom+xml"); req.SetResponseStatusCode(200); return req; }; Uri uri = new Uri(request.ServiceRoot + "/" + testCase.RequestUriString); DataServiceContext ctx = new DataServiceContext(null, ODataProtocolVersion.V4); ctx.EnableAtom = true; QueryOperationResponse<CustomerEntity> qor = (QueryOperationResponse<CustomerEntity>)ctx.Execute<CustomerEntity>(uri); Assert.IsNotNull(qor); Assert.IsNull(qor.Error); IEnumerator<CustomerEntity> entities = qor.GetEnumerator(); Exception exception = AstoriaTest.TestUtil.RunCatching(delegate() { while (entities.MoveNext()) { CustomerEntity c = entities.Current; EntityDescriptor ed = ctx.GetEntityDescriptor(c); IEnumerable<OperationDescriptor> actualDescriptors = ed.OperationDescriptors; } }); Assert.IsNotNull(exception); Assert.AreEqual(testCase.ExpectedErrorMessage, exception.Message); } }
private static void RunPositiveTest(ODataFormat format, TestCase testCase) { MyDSPActionProvider actionProvider = new MyDSPActionProvider(); DSPServiceDefinition service = new DSPServiceDefinition() {Metadata = Metadata, CreateDataSource = CreateDataSource, ActionProvider = actionProvider}; service.DataServiceBehavior.MaxProtocolVersion = ODataProtocolVersion.V4; using (TestWebRequest request = service.CreateForInProcessWcf()) { request.StartService(); DataServiceContext ctx = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4); ctx.EnableAtom = true; Uri uri = new Uri(request.ServiceRoot + "/" + testCase.RequestUriString); MakeFinalChangesToTestCase(testCase, format, actionProvider, request); if (format == ODataFormat.Json) { JsonLightTestUtil.ConfigureContextForJsonLight(ctx, null); } else { ctx.Format.UseAtom(); } QueryOperationResponse<CustomerEntity> qor = (QueryOperationResponse<CustomerEntity>)ctx.Execute<CustomerEntity>(uri); Assert.IsNotNull(qor); Assert.IsNull(qor.Error); IEnumerator<CustomerEntity> entities = qor.GetEnumerator(); int expectedDescriptorsPerEntity = 0; while (entities.MoveNext()) { CustomerEntity c = entities.Current; EntityDescriptor ed = ctx.GetEntityDescriptor(c); IEnumerable<OperationDescriptor> actualDescriptors = ed.OperationDescriptors; TestEquality(actualDescriptors, testCase.GetExpectedDescriptors(format)[expectedDescriptorsPerEntity++]); } } }
private void RunPositiveFunctionTest(ODataFormat format, TestCase testCase) { // All of the functions tests use the PlaybackService since the WCF Data Services server doesn't support functions // The PlaybackService itself will not automatically turn Metadata into an absolute URI, so set that to false on all tests. // The tests also use absolute URIs for Target, so suppress that as well. testCase.AddBaseUriToMetadata = false; testCase.AddBaseUriToTarget = false; using (TestWebRequest request = TestWebRequest.CreateForInProcessWcf()) using (PlaybackService.ProcessRequestOverride.Restore()) { request.ServiceType = typeof(AstoriaUnitTests.Stubs.PlaybackService); request.StartService(); var payloadBuilder = testCase.ResponsePayloadBuilder; PlaybackService.ProcessRequestOverride.Value = (req) => { string contentType; if (format == ODataFormat.Json) { contentType = UnitTestsUtil.JsonLightMimeType; payloadBuilder.Metadata = request.BaseUri + "/$metadata#TestService.CustomerEntities/$entity"; } else { contentType = UnitTestsUtil.AtomFormat; } req.SetResponseStreamAsText(PayloadGenerator.Generate(payloadBuilder, format)); req.ResponseHeaders.Add("Content-Type", contentType); req.SetResponseStatusCode(200); return req; }; testCase.AddBaseUriStringToExpectedDescriptors(request.ServiceRoot.OriginalString, format); Uri uri = new Uri(request.ServiceRoot + "/" + testCase.RequestUriString); DataServiceContext ctx = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4); ctx.EnableAtom = true; if (format == ODataFormat.Json) { string serviceEdmx = GetServiceEdmxWithOperations(payloadBuilder); JsonLightTestUtil.ConfigureContextForJsonLight(ctx, serviceEdmx); } QueryOperationResponse<CustomerEntity> qor = (QueryOperationResponse<CustomerEntity>)ctx.Execute<CustomerEntity>(uri); Assert.IsNotNull(qor); Assert.IsNull(qor.Error); IEnumerator<CustomerEntity> entities = qor.GetEnumerator(); int expectedDescriptorsPerEntity = 0; while (entities.MoveNext()) { CustomerEntity c = entities.Current; EntityDescriptor ed = ctx.GetEntityDescriptor(c); IEnumerable<OperationDescriptor> actualDescriptors = ed.OperationDescriptors; TestEquality(actualDescriptors, testCase.GetExpectedDescriptors(format)[expectedDescriptorsPerEntity++]); } } }
public void OperationDescriptorsShouldBeUpdatedForEachRequest() { #region Response payload var response = @"HTTP/1.1 200 OK Connection: Keep-Alive Content-Length: 2011 Date: Thu, 06 Jun 2013 22:07:07 GMT Content-Type: application/atom+xml;type=entry;charset=utf-8 Server: Microsoft-IIS/7.5 Cache-Control: no-cache X-Content-Type-Options: nosniff OData-Version: 4.0; X-AspNet-Version: 4.0.30319 X-Powered-By: ASP.NET <?xml version='1.0' encoding='utf-8'?> <entry xml:base='http://services.odata.org/V3/(S(imdxx1ujw4ludze1t3k2wmgs))/OData/OData.svc/' xmlns='http://www.w3.org/2005/Atom' xmlns:d='http://docs.oasis-open.org/odata/ns/data' xmlns:m='http://docs.oasis-open.org/odata/ns/metadata' xmlns:georss='http://www.georss.org/georss' xmlns:gml='http://www.opengis.net/gml'> <id>http://services.odata.org/V3/(S(imdxx1ujw4ludze1t3k2wmgs))/OData/OData.svc/Products(0)</id> <category term='ODataDemo.Product' scheme='http://docs.oasis-open.org/odata/ns/scheme' /> <link rel='edit' title='Product' href='Products(0)' /> <link rel='http://docs.oasis-open.org/odata/ns/related/Category' type='application/atom+xml;type=entry' title='Category' href='Products(0)/Category' /> <link rel='http://docs.oasis-open.org/odata/ns/related/Supplier' type='application/atom+xml;type=entry' title='Supplier' href='Products(0)/Supplier' /> <title type='text'>Bread</title> <summary type='text'>Whole grain bread</summary> <updated>2013-06-06T22:07:08Z</updated> <author> <name /> </author> <link rel='http://docs.oasis-open.org/odata/ns/relatedlinks/OrderDetails' type='application/xml' title='OrderDetails' href='Products(0)/OrderDetails/$ref' /> <m:action metadata='http://services.odata.org/V3/(S(imdxx1ujw4ludze1t3k2wmgs))/OData/OData.svc/$metadata#DemoService.{0}' title='{0}' target='http://services.odata.org/V3/(S(imdxx1ujw4ludze1t3k2wmgs))/OData/OData.svc/Products(0)/{0}' /> <content type='application/xml'> <m:properties> <d:ID m:type='Edm.Int32'>0</d:ID> <d:ProductName m:type='Edm.String'>Demo Product</d:ProductName> <d:Discontinued m:type='Edm.Boolean'>false</d:Discontinued> </m:properties> </content> </entry> "; #endregion // Consider two actions that an entity Product supports, and they are mutually exclusive, i.e. only one action // is returned in the response string action1 = "Discount"; string action2 = "Discount1234"; // Create two responses with each of above actions var response1 = string.Format(response, action1); var response2 = string.Format(response, action2); PlaybackServiceDefinition playbackService = new PlaybackServiceDefinition(); using (TestWebRequest request = playbackService.CreateForInProcessWcf()) { request.ServiceType = typeof(PlaybackService); request.ForceVerboseErrors = true; request.StartService(); DataServiceContext ctx = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4); ctx.EnableAtom = true; try { for (int i = 0; i < 2; i++) { playbackService.OverridingPlayback = (i % 2 == 0) ? response1 : response2; Product product = ctx.Execute <Product>(new Uri("Products(0)", UriKind.Relative)).First(); EntityDescriptor descriptor = ctx.GetEntityDescriptor(product); descriptor.OperationDescriptors.Count.Should().Be(1); var actionName = descriptor.OperationDescriptors.First().Title; if (i % 2 == 0) { actionName.Should().Be(action1); } else { actionName.Should().Be(action2); } } } finally { request.StopService(); } } }