public void PreferHeader_CrossFeature() { DSPMetadata metadata = PreferHeader_CreateMetadata(); DSPSelfmodifyingResource existingItem = new DSPSelfmodifyingResource(metadata.GetResourceType("Item")); existingItem.SetRawValue("ID", 0); existingItem.SetRawValue("ETagProperty", 1); DSPServiceDefinition service = PreferHeader_CreateService(metadata, existingItem, null, null, null); ProcessingPipelineCallCount callCount = new ProcessingPipelineCallCount(); service.ProcessingPipeline.ProcessingRequest += (sender, args) => { callCount.ProcessingRequestCallCount++; }; service.ProcessingPipeline.ProcessedRequest += (sender, args) => { callCount.ProcessedRequestCallCount++; }; service.ProcessingPipeline.ProcessingChangeset += (sender, args) => { callCount.ProcessingChangesetCallCount++; }; service.ProcessingPipeline.ProcessedChangeset += (sender, args) => { callCount.ProcessedChangesetCallCount++; }; service.DataServiceType = typeof(PreferHeader_InterceptorsService); ProcessingPipelineCallCount expectedCallCount = new ProcessingPipelineCallCount() { ProcessingRequestCallCount = 1, ProcessedRequestCallCount = 1, ProcessingChangesetCallCount = 1, ProcessedChangesetCallCount = 1 }; // Can't get the payload from the service since we sometimes don't allow read rights XDocument existingItemAtom = XDocument.Parse("<entry xmlns:d='http://docs.oasis-open.org/odata/ns/data' xmlns:m='http://docs.oasis-open.org/odata/ns/metadata' xmlns='http://www.w3.org/2005/Atom'>" + "<id>http://host/Items(0)</id>" + "<title type='text'></title>" + "<updated>2010-07-19T14:20:32Z</updated>" + "<author><name /></author>" + "<category term='TestNS.Item' scheme='http://docs.oasis-open.org/odata/ns/scheme' />" + "<content type='application/xml'><m:properties>" + "<d:ID m:type='Edm.Int32'>0</d:ID>" + "<d:ETagProperty m:type='Edm.Int32'>1</d:ETagProperty>" + "</m:properties></content></entry>"); TestUtil.RunCombinations( UnitTestsUtil.BooleanValues, UnitTestsUtil.BooleanValues, (includeRelationshipLinks, allowReadAccess) => { service.DataServiceBehavior.IncludeRelationshipLinksInResponse = includeRelationshipLinks; service.EntitySetAccessRule = new Dictionary<string,EntitySetRights>() { {"Items", EntitySetRights.AllWrite | (allowReadAccess ? EntitySetRights.AllRead : EntitySetRights.None)} }; using (TestWebRequest request = service.CreateForInProcess()) { request.RegisterForDispose(PreferHeader_InterceptorsService.InterceptItems.Restore()); TestUtil.RunCombinations( new string[] { "POST", "PUT", "PATCH" }, new string[] { null, "return=representation", "return=minimal" }, new string[] { UnitTestsUtil.AtomFormat }, UnitTestsUtil.BooleanValues, UnitTestsUtil.BooleanValues, (httpMethod, preferHeader, format, batch, interceptItems) => { PreferHeader_InterceptorsService.InterceptItems.Value = interceptItems; PreferHeader_InterceptorsService.LastItemsUpdateOperation = UpdateOperations.None; PreferHeader_InterceptorsService.ItemsQueryInterceptorInvoked = false; service.ClearChanges(); callCount.Clear(); TestWebRequest r = request; if (batch) { r = new InMemoryWebRequest(); } r.RequestVersion = "4.0;"; r.RequestMaxVersion = "4.0;"; r.RequestHeaders["Prefer"] = preferHeader; PreferHeader_SetupRequest(r, httpMethod, format, existingItemAtom, existingItem, null); if (batch) { var batchRequest = new BatchWebRequest(); var changeset = new BatchWebRequest.Changeset(); changeset.Parts.Add((InMemoryWebRequest)r); batchRequest.Changesets.Add(changeset); batchRequest.SendRequest(request); } else { TestUtil.RunCatching(request.SendRequest); } Assert.AreEqual(httpMethod != "POST", PreferHeader_InterceptorsService.ItemsQueryInterceptorInvoked, "The query interceptor fire or didn't fire when it should have."); if (!allowReadAccess && httpMethod != "POST") { Assert.AreEqual(403, r.ResponseStatusCode, "The request should have failed due to access rights."); } else if (interceptItems && httpMethod != "POST") { Assert.AreEqual(404, r.ResponseStatusCode, "The request should not have found any resource."); } else { PreferHeader_VerifyResponse(r, request.ServiceRoot.ToString(), true, (response) => { var relationshipLinks = response.Root.Elements(UnitTestsUtil.AtomNamespace + "link") .Where(e => e.Attribute("rel").Value.Contains("http://docs.oasis-open.org/odata/ns/relatedlinks/")); if (includeRelationshipLinks) { Assert.AreEqual(1, relationshipLinks.Count(), "The response should contain a relationship link."); } else { Assert.AreEqual(0, relationshipLinks.Count(), "The resounrce should not contain any relationship links."); } }); callCount.AssertEquals(expectedCallCount); Assert.AreEqual(httpMethod == "POST" ? UpdateOperations.Add : UpdateOperations.Change, PreferHeader_InterceptorsService.LastItemsUpdateOperation, "The change interceptor didn't fire correctly."); } }); } }); }
private static void ExecuteUpdate(DSPResource resource, int id, TestWebRequest baseRequest, string httpMethod, string preferHeader, bool useBatch, DSPResourceSerializerFormat payloadFormat) { string payload = DSPResourceSerializer.WriteEntity(resource, payloadFormat); bool isPost = httpMethod == "POST"; bool expectedReturnContent = preferHeader == "return=representation" || isPost && preferHeader == null; string uriSuffix = isPost ? String.Empty : String.Format("({0})", id); TestWebRequest request = useBatch ? new InMemoryWebRequest() : baseRequest; request.RequestUriString = String.Format("/{0}s{1}", resource.ResourceType.Name, uriSuffix); request.HttpMethod = httpMethod; request.RequestVersion = "4.0;"; request.RequestMaxVersion = "4.0;"; request.RequestHeaders["Prefer"] = preferHeader; request.Accept = payloadFormat == DSPResourceSerializerFormat.Atom ? "application/atom+xml,application/xml" : UnitTestsUtil.JsonLightMimeType; request.RequestContentType = "application/atom+xml"; request.SetRequestStreamAsText(payload); if (useBatch) { var batchRequest = new BatchWebRequest(); var changeset = new BatchWebRequest.Changeset(); changeset.Parts.Add((InMemoryWebRequest)request); batchRequest.Changesets.Add(changeset); batchRequest.SendRequest(baseRequest); Assert.IsTrue(UnitTestsUtil.IsSuccessStatusCode(baseRequest.ResponseStatusCode), "Unexpected error occurred on batch."); } else { request.SendRequest(); } Assert.IsTrue(UnitTestsUtil.IsSuccessStatusCode(request.ResponseStatusCode), "Unexpected error occurred when sending the request."); if (expectedReturnContent) { // If the request is expected to return content, verify there were no instream errors Exception e = request.ParseResponseInStreamError(); string errorMessage = e != null ? e.Message : string.Empty; Assert.IsNull(e, "Expected no exception, but got the following error", errorMessage); } }
public void Collection_ProcessingPipeline() { var metadata = CreateMetadataForXFeatureEntity(); Func<int, DSPResource> CreateNewXFeatureEntityResource = (id) => { DSPResourceWithCollectionProperty newResource = new DSPResourceWithCollectionProperty(metadata.GetResourceType("XFeatureTestsEntity")); newResource.SetRawValue("ID", id); newResource.SetRawValue("Description", "Second"); newResource.SetRawValue("Strings", new List<string>() { "One", "Two" }); newResource.SetRawValue("Structs", new List<DSPResource>()); return newResource; }; var actualCallCount = new ProcessingPipelineCallCount(); DSPServiceDefinition service = new DSPServiceDefinition() { Metadata = metadata, CreateDataSource = (m) => { DSPContext context = new DSPContext(); context.GetResourceSetEntities("Entities").Add(CreateNewXFeatureEntityResource(0)); return context; }, Writable = true, }; service.ProcessingPipeline.ProcessingRequest = (sender, args) => { actualCallCount.ProcessingRequestCallCount++; }; service.ProcessingPipeline.ProcessedRequest = (sender, args) => { actualCallCount.ProcessedRequestCallCount++; }; service.ProcessingPipeline.ProcessingChangeset = (sender, args) => { actualCallCount.ProcessingChangesetCallCount++; }; service.ProcessingPipeline.ProcessedChangeset = (sender, args) => { actualCallCount.ProcessedChangesetCallCount++; }; var testCases = new ProcessingPipelineTestCase[] { new ProcessingPipelineTestCase() { SetupRequest = (r, format) => { r.HttpMethod = "GET"; r.RequestUriString = "/Entities"; r.Accept = format; }, }, new ProcessingPipelineTestCase() { SetupRequest = (r, format) => { r.HttpMethod = "GET"; r.RequestUriString = "/Entities(0)/Strings"; r.Accept = format == UnitTestsUtil.AtomFormat ? UnitTestsUtil.MimeApplicationXml : format; }, }, new ProcessingPipelineTestCase() { SetupRequest = (r, format) => { r.HttpMethod = "GET"; r.RequestUriString = "/Entities(0)/Structs"; r.Accept = format == UnitTestsUtil.AtomFormat ? UnitTestsUtil.MimeApplicationXml : format; }, }, new ProcessingPipelineTestCase() { SetupRequest = (r, format) => { r.HttpMethod = "POST"; r.RequestUriString = "/Entities"; r.Accept = format; r.RequestContentType = format; r.SetRequestStreamAsText(DSPResourceSerializer.WriteEntity( CreateNewXFeatureEntityResource(1), DSPResourceSerializer.SerializerFormatFromMimeType(format))); }, ExpectedCallCount = new ProcessingPipelineCallCount() { ProcessingChangesetCallCount = 1, ProcessedChangesetCallCount = 1 } }, new ProcessingPipelineTestCase() { SetupRequest = (r, format) => { r.HttpMethod = "PUT"; r.RequestUriString = "/Entities(0)"; r.Accept = format; r.RequestContentType = format; r.SetRequestStreamAsText(DSPResourceSerializer.WriteEntity( CreateNewXFeatureEntityResource(0), DSPResourceSerializer.SerializerFormatFromMimeType(format))); }, ExpectedCallCount = new ProcessingPipelineCallCount() { ProcessingChangesetCallCount = 1, ProcessedChangesetCallCount = 1 } }, new ProcessingPipelineTestCase() { SetupRequest = (r, format) => { r.HttpMethod = "PATCH"; r.RequestUriString = "/Entities(0)"; r.Accept = format; r.RequestContentType = format; r.SetRequestStreamAsText(DSPResourceSerializer.WriteEntity( CreateNewXFeatureEntityResource(0), DSPResourceSerializer.SerializerFormatFromMimeType(format))); }, ExpectedCallCount = new ProcessingPipelineCallCount() { ProcessingChangesetCallCount = 1, ProcessedChangesetCallCount = 1 } }, new ProcessingPipelineTestCase() { SetupRequest = (r, format) => { r.HttpMethod = "DELETE"; r.RequestUriString = "/Entities(0)"; r.Accept = format; }, ExpectedCallCount = new ProcessingPipelineCallCount() { ProcessingChangesetCallCount = 1, ProcessedChangesetCallCount = 1 } }, new ProcessingPipelineTestCase() { SetupRequest = (r, format) => { r.HttpMethod = "PUT"; r.RequestUriString = "/Entities(0)/Strings"; r.Accept = format == UnitTestsUtil.AtomFormat ? UnitTestsUtil.MimeApplicationXml : format; r.RequestContentType = format == UnitTestsUtil.AtomFormat ? UnitTestsUtil.MimeApplicationXml : format; r.SetRequestStreamAsText(DSPResourceSerializer.WriteProperty( metadata.GetResourceType("XFeatureTestsEntity").Properties.First(p => p.Name == "Strings"), new List<string> { "Foo", "Bar" }, DSPResourceSerializer.SerializerFormatFromMimeType(format))); }, ExpectedCallCount = new ProcessingPipelineCallCount() { ProcessingChangesetCallCount = 1, ProcessedChangesetCallCount = 1 } }, new ProcessingPipelineTestCase() { SetupRequest = (r, format) => { r.HttpMethod = "PUT"; r.RequestUriString = "/Entities(0)/Structs"; r.Accept = format == UnitTestsUtil.AtomFormat ? UnitTestsUtil.MimeApplicationXml : format; r.RequestContentType = format == UnitTestsUtil.AtomFormat ? UnitTestsUtil.MimeApplicationXml : format; r.SetRequestStreamAsText(DSPResourceSerializer.WriteProperty( metadata.GetResourceType("XFeatureTestsEntity").Properties.First(p => p.Name == "Structs"), new List<DSPResource>(), DSPResourceSerializer.SerializerFormatFromMimeType(format))); }, ExpectedCallCount = new ProcessingPipelineCallCount() { ProcessingChangesetCallCount = 1, ProcessedChangesetCallCount = 1 } }, }; using (DSPResourceWithCollectionProperty.CollectionPropertiesResettable.Restore()) using (TestWebRequest request = service.CreateForInProcess()) { DSPResourceWithCollectionProperty.CollectionPropertiesResettable.Value = true; TestUtil.RunCombinations(testCases, UnitTestsUtil.BooleanValues, UnitTestsUtil.ResponseFormats, (testCase, batch, format) => { service.ClearChanges(); actualCallCount.Clear(); var expectedCallCount = new ProcessingPipelineCallCount(testCase.ExpectedCallCount); // Each request must fire at least one ProcessingRequest and ProcessedRequest expectedCallCount.ProcessingRequestCallCount++; expectedCallCount.ProcessedRequestCallCount++; if (batch) { InMemoryWebRequest batchPart = new InMemoryWebRequest(); testCase.SetupRequest(batchPart, format); BatchWebRequest batchRequest = new BatchWebRequest(); if (batchPart.HttpMethod == "GET") { batchRequest.Parts.Add(batchPart); } else { var changeset = new BatchWebRequest.Changeset(); changeset.Parts.Add(batchPart); batchRequest.Changesets.Add(changeset); } batchRequest.SendRequest(request); } else { request.RequestContentType = null; request.RequestStream = null; testCase.SetupRequest(request, format); request.SendRequest(); } actualCallCount.AssertEquals(expectedCallCount); }); } }