Exemple #1
0
        /// <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);
            }
        }
Exemple #3
0
        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");
            }
        }
Exemple #6
0
        /// <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;
        }
Exemple #10
0
        /// <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;
            }
        }
Exemple #11
0
        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);
                }
            }
Exemple #15
0
        /// <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();
                }
            }
        }