public void NamedStreams_DeepEntityProjection_CannotAccessEntitiesAcrossLevels() { // projecting out deep links to get stream url in DSSL property with multiple parameters in scope - 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); var q = from s in context.CreateQuery <EntityWithNamedStreams1>("MySet1") where s.ID == 1 from c in s.Collection select new EntityWithNamedStreams2() { ID = c.ID, Stream1 = s.Stream1 }; try { q.ToList(); } catch (NotSupportedException ex) { Assert.AreEqual(ex.Message, DataServicesClientResourceUtil.GetString("ALinq_CanOnlyProjectTheLeaf"), "error message should match as expected"); } Assert.AreEqual(context.Entities.Count, 0, "there should be no entities tracked by the context in error case"); } }
public void SetDollarFormatInAddQueryOption() { using (TestWebRequest web = TestWebRequest.CreateForInProcessWcf()) { web.DataServiceType = typeof(DollarFormatTestService); web.StartService(); DataServiceContext ctx = new DataServiceContext(web.ServiceRoot, ODataProtocolVersion.V4); List <string> options = new List <string>() { "atom", "json", "jsonlight", "xml", }; foreach (string option in options) { try { ctx.CreateQuery <Customer>("Customers").AddQueryOption("$format", option).Execute(); } catch (NotSupportedException e) { Assert.AreEqual(DataServicesClientResourceUtil.GetString("ALinq_FormatQueryOptionNotSupported"), e.Message); } } } }
public void NamedStreams_CannotReferenceDeepLinksDuringEntityMaterialization() { // If the entity getting projected out in an entity, one should not be able to refer deep links { // Flattening of entity types is not allowed, when the projected type is an entity type. DataServiceContext context = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4); var q = from s in context.CreateQuery <EntityWithNamedStreams1>("MySet1") select new EntityWithNamedStreams1 { ID = s.ID, Name = s.Name, Stream1 = s.Ref.Stream1 }; try { foreach (var o in q) { } } catch (NotSupportedException ex) { Assert.AreEqual(ex.Message, DataServicesClientResourceUtil.GetString("ALinq_ProjectionMemberAssignmentMismatch", typeof(EntityWithNamedStreams1).FullName, "s", "s.Ref")); } Assert.AreEqual(context.Entities.Count, 0, "there should be no entities tracked by the context, since we are doing flattening"); } { // Flattening of entity types is not allowed, when the projected type is an entity type. DataServiceContext context = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4); var q = from s in context.CreateQuery <EntityWithNamedStreams1>("MySet1") select new EntityWithNamedStreams1 { ID = s.Ref.ID, Name = s.Ref.Name, Stream1 = s.Stream1 }; try { foreach (var o in q) { } } catch (NotSupportedException ex) { Assert.AreEqual(ex.Message, DataServicesClientResourceUtil.GetString("ALinq_ProjectionMemberAssignmentMismatch", typeof(EntityWithNamedStreams1).FullName, "s.Ref", "s")); } Assert.AreEqual(context.Entities.Count, 0, "there should be no entities tracked by the context, since we are doing flattening"); } }
[Ignore] // Remove Atom // [TestCategory("Partition2"), TestMethod, Variation] public void BatchContentTypeTest() { var testCases = new BatchContentTypeTestCase[] { // Completely wrong content type new BatchContentTypeTestCase { ContentType = "text/plain", ExpectedErrorStatusCode = 400, ExpectedClientErrorMessage = DataServicesClientResourceUtil.GetString("Batch_ExpectedContentType", "text/plain") }, // Just type is correct, subtype is wrong new BatchContentTypeTestCase { ContentType = "multipart/text", ExpectedErrorStatusCode = 400, ExpectedClientErrorMessage = DataServicesClientResourceUtil.GetString("Batch_ExpectedContentType", "multipart/text") }, // No boundary - still wrong new BatchContentTypeTestCase { ContentType = "multipart/mixed", ExpectedErrorStatusCode = 400, ExpectedClientErrorMessage = ODataLibResourceUtil.GetString("MediaTypeUtils_BoundaryMustBeSpecifiedForBatchPayloads", "multipart/mixed", "boundary") }, // Some other parameter but no boundary new BatchContentTypeTestCase { ContentType = "multipart/mixed;param=value", ExpectedErrorStatusCode = 400, ExpectedClientErrorMessage = ODataLibResourceUtil.GetString("MediaTypeUtils_BoundaryMustBeSpecifiedForBatchPayloads", "multipart/mixed;param=value", "boundary") }, // Empty boundary - fails new BatchContentTypeTestCase { ContentType = "multipart/mixed;boundary=", ExpectedErrorStatusCode = 400, ExpectedClientErrorMessage = ODataLibResourceUtil.GetString("ValidationUtils_InvalidBatchBoundaryDelimiterLength", string.Empty, "70") }, new BatchContentTypeTestCase { ContentType = "multipart/mixed;boundary=;param=value", ExpectedErrorStatusCode = 400, ExpectedClientErrorMessage = ODataLibResourceUtil.GetString("ValidationUtils_InvalidBatchBoundaryDelimiterLength", string.Empty, "70") }, // Two boundary parameters - wrong new BatchContentTypeTestCase { ContentType = "multipart/mixed;boundary=one;boundary=two", ExpectedErrorStatusCode = 400, ExpectedClientErrorMessage = ODataLibResourceUtil.GetString("MediaTypeUtils_BoundaryMustBeSpecifiedForBatchPayloads", "multipart/mixed;boundary=one;boundary=two", "boundary") }, // Valid simple boundary new BatchContentTypeTestCase { ContentType = "multipart/mixed;boundary=batchboundary", PayloadBatchBoundary = "batchboundary" }, // Valid simple boundary - mimetype using different casing new BatchContentTypeTestCase { ContentType = "MultiPart/mIxed;boundary=batchboundary", PayloadBatchBoundary = "batchboundary" }, // Valid simple boundary - boundary parameter name different casing new BatchContentTypeTestCase { ContentType = "multipart/mixed;BounDary=batchboundary", PayloadBatchBoundary = "batchboundary" }, }; OpenWebDataServiceDefinition serverService = new OpenWebDataServiceDefinition() { DataServiceType = typeof(CustomDataContext) }; PlaybackServiceDefinition clientService = new PlaybackServiceDefinition(); TestUtil.RunCombinations( testCases, (testCase) => { using (TestWebRequest request = serverService.CreateForInProcess()) { request.RequestContentType = testCase.ContentType; request.SetRequestStreamAsText(string.Format( "--{0}\r\n" + "Content-Type: multipart/mixed; boundary=changesetresponse_00000001-0000-0000-0000-000000000000\r\n\r\n" + "--changesetresponse_00000001-0000-0000-0000-000000000000\r\n" + "--changesetresponse_00000001-0000-0000-0000-000000000000--\r\n" + "--{0}--\r\n", testCase.PayloadBatchBoundary)); request.RequestUriString = "/$batch"; request.HttpMethod = "POST"; Exception exception = TestUtil.RunCatching(request.SendRequest); int actualStatusCode = 0; if (exception != null) { actualStatusCode = request.ResponseStatusCode; } else { Assert.AreEqual(202, request.ResponseStatusCode, "Wrong response code for no-exception request."); BatchWebRequest batchResponse = BatchWebRequest.FromResponse(InMemoryWebRequest.FromResponse(request)); if (batchResponse.Parts.Count > 0) { actualStatusCode = batchResponse.Parts[0].ResponseStatusCode; if (actualStatusCode == 200) { actualStatusCode = 0; } } } Assert.AreEqual(testCase.ExpectedErrorStatusCode, actualStatusCode, "Wrong status code."); } using (TestWebRequest request = clientService.CreateForInProcessWcf()) { request.StartService(); clientService.ProcessRequestOverride = clientRequest => { var clientResponse = new InMemoryWebRequest(); clientResponse.SetResponseStatusCode(202); clientResponse.ResponseHeaders["Content-Type"] = testCase.ContentType; clientResponse.SetResponseStreamAsText(string.Format( "--{0}\r\n" + "Content-Type: application/http\r\n" + "Content-Transfer-Encoding: binary\r\n" + "\r\n" + "200 OK\r\n" + "<feed xmlns='http://www.w3.org/2005/Atom'/>\r\n" + "--{0}--\r\n", testCase.PayloadBatchBoundary)); return(clientResponse); }; DataServiceContext ctx = new DataServiceContext(request.ServiceRoot); Exception exception = TestUtil.RunCatching(() => ctx.ExecuteBatch(ctx.CreateQuery <Customer>("/Customers"))); if (exception != null) { exception = ((DataServiceRequestException)exception).InnerException; Assert.AreEqual(testCase.ExpectedClientErrorMessage, exception.Message, "Unexpected error message."); } else { Assert.IsNull(testCase.ExpectedClientErrorMessage, "Expected exception, but none was thrown."); } } }); }
public void AtomParserAttributeNamespaceTest() { const string atomPayloadTemplate = @"HTTP/1.1 200 OK Content-Type: application/atom+xml <feed xmlns:d='http://docs.oasis-open.org/odata/ns/data' xmlns:m='http://docs.oasis-open.org/odata/ns/metadata' xmlns:atom='http://www.w3.org/2005/Atom' xmlns:invalid='http://odata.org/invalid/namespace' xmlns:gml='http://www.opengis.net/gml' xmlns='http://www.w3.org/2005/Atom'> <title type='text'>ASet</title> <id>http://host/ASet</id> <updated>2010-09-01T23:36:00Z</updated> <link rel='self' title='ASet' href='ASet' /> <entry> <id>http://host/ASet(1)</id> <title type='text'></title> <updated>2010-09-01T23:36:00Z</updated> <author> <name /> </author> <link rel='self' title='EntityA' href='ASet(1)' /> <link rel='edit' title='EntityA' href='ASet(1)' /> <link rel='edit-media' title='EntityA' href='ASet(1)/$value' /> <category {0}='NamespaceName.EntityA' {1}='http://docs.oasis-open.org/odata/ns/scheme' /> <content {3}='http://odata.org/readstream1' /> <m:properties> <d:ID {4}='Edm.Int32'>1</d:ID> </m:properties> </entry> </feed>"; const string defaultCategoryTerm = "term"; const string defaultCategoryScheme = "scheme"; const string defaultContentType = "type"; const string defaultContentSource = "src"; const string defaultPropertyType = "m:type"; AtomParserAttributeNamespaceTestCase[] testCases = new AtomParserAttributeNamespaceTestCase[] { // Error cases new AtomParserAttributeNamespaceTestCase { CategoryScheme = "invalid:scheme" }, new AtomParserAttributeNamespaceTestCase { CategoryTerm = "invalid:term" }, new AtomParserAttributeNamespaceTestCase { ContentType = "invalid:type" }, new AtomParserAttributeNamespaceTestCase { ContentSrc = "invalid:src" }, new AtomParserAttributeNamespaceTestCase { PropertyType = "invalid:type" }, }; PlaybackServiceDefinition playbackService = new PlaybackServiceDefinition(); using (TestWebRequest request = playbackService.CreateForInProcessWcf()) { request.ServiceType = typeof(PlaybackService); request.ForceVerboseErrors = true; request.StartService(); TestUtil.RunCombinations( testCases, testCase => { DataServiceContext ctx = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4); ctx.EnableAtom = true; // {0} - atom:category/@term // {1} - atom:category/@scheme // {2} - atom:content/@type // {3} - atom:content/@src // {4} - d:property/@m:type string atomPayload = string.Format( atomPayloadTemplate, testCase.CategoryTerm ?? defaultCategoryTerm, testCase.CategoryScheme ?? defaultCategoryScheme, testCase.ContentType ?? defaultContentType, testCase.ContentSrc ?? defaultContentSource, testCase.PropertyType ?? defaultPropertyType); playbackService.OverridingPlayback = atomPayload; EntityA[] items; try { items = ctx.CreateQuery <EntityA>("ASet").ToArray(); } catch (InvalidOperationException ex) { if (testCase.ContentSrc != null && testCase.ContentSrc.StartsWith("invalid")) { Assert.AreEqual(ODataLibResourceUtil.GetString("ODataAtomReader_MediaLinkEntryMismatch"), ex.Message); return; } else if (testCase.PropertyType != null && testCase.PropertyType.StartsWith("invalid")) { Assert.AreEqual(DataServicesClientResourceUtil.GetString("Deserialize_ExpectingSimpleValue"), ex.Message); return; } Assert.Fail("Exception received but did not expect any failure.\n" + ex.Message); return; } Assert.AreEqual(1, items.Length, "Expected 1 item in the payload."); var firstItem = items[0]; var entities = ctx.Entities; Assert.AreEqual(1, entities.Count, "Expected 1 entity in the context."); var firstEntity = entities[0]; // Verify category/@term and category/@scheme by testing the type name string expectedTypeName = testCase.CategoryScheme != null && testCase.CategoryScheme.StartsWith("invalid") || testCase.CategoryTerm != null && testCase.CategoryTerm.StartsWith("invalid") ? null : "NamespaceName.EntityA"; Assert.AreEqual(expectedTypeName, firstEntity.ServerTypeName, "Type names don't match."); // Verify content/@src by checking that the read stream of the entry is correct Assert.AreEqual("http://odata.org/readstream1", firstEntity.ReadStreamUri.OriginalString, "ReadStreams don't match."); // Verify content/@type by making sure the properties were read Assert.AreEqual(1, firstItem.ID, "IDs don't match."); }); } }