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");
            }
        }
Ejemplo n.º 4
0
            [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.");
                        }
                    }
                });
            }
Ejemplo n.º 5
0
        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.");
                });
            }
        }