Ejemplo n.º 1
0
        public void BlobStreamSaveChanges()
        {
            using (TestWebRequest request = TestWebRequest.CreateForInProcessWcf())
                using (PlaybackService.InspectRequestPayload.Restore())
                    using (PlaybackService.OverridingPlayback.Restore())
                    {
                        request.ServiceType        = typeof(PlaybackService);
                        request.ForceVerboseErrors = true;
                        request.StartService();
                        byte[] content = new byte[] { 1, 2, 3 };

                        DataServiceContext ctx = new DataServiceContext(new Uri(request.BaseUri, UriKind.RelativeOrAbsolute));
                        ctx.EnableAtom = true;
                        ctx.Format.UseAtom();
                        Stream stream = new MemoryStream(content);
                        ClientCSharpRegressionTests.CustomerWithStream customer = new ClientCSharpRegressionTests.CustomerWithStream()
                        {
                            ID = 1, Name = "Foo"
                        };
                        ctx.AddObject("Customers", customer);
                        ctx.SetSaveStream(customer, stream, true, new DataServiceRequestArgs()
                        {
                            ContentType = "application/jpeg"
                        });

                        EntityDescriptor ed = ctx.Entities[0];

                        int    i              = 0;
                        string id             = "http://myidhost/somerandomIDUrl";
                        string selfLink       = request.BaseUri + "/self-link/Customer(1)";
                        string editLink       = request.BaseUri + "/edit-link/Customer(1)";
                        string etag           = "someetagvalue";
                        string serverTypeName = "SomeRandomTypeName";

                        string editMediaLink  = "http://myhost/somerandomeUrl/edit-media-link/v1";
                        string readMediaLink  = "http://myedithost/somerandomUrl/foo/self-media-link/v1";
                        string streamETag     = "somerandomeStreamETag";
                        string mediaType      = "application/jpeg";
                        string locationHeader = "http://mylocationhost/somerandomUrl/location/";

                        PlaybackService.InspectRequestPayload.Value = (message) =>
                        {
                            if (i == 0)
                            {
                                string xml = MediaEntry(
                                    id: id,
                                    selfLink: selfLink,
                                    editLink: editLink,
                                    etag: etag,
                                    properties: "<d:ID>5</d:ID>",
                                    serverTypeName: serverTypeName,
                                    readStreamUrl: readMediaLink,
                                    editStreamUrl: editMediaLink,
                                    mediaETag: streamETag,
                                    mediaType: mediaType);

                                // The response payload has some random location header and no etag header.
                                // Verify that the edit link, etag and type name are used from the payload.
                                string responsePayload =
                                    "HTTP/1.1 201 Created" + Environment.NewLine +
                                    "Content-Type: application/atom+xml" + Environment.NewLine +
                                    "Location: " + locationHeader + Environment.NewLine +
                                    Environment.NewLine +
                                    xml;
                                PlaybackService.OverridingPlayback.Value = responsePayload;
                            }
                            else if (i == 1)
                            {
                                // Make sure that no metadata from the payload is merged yet into the public entity descriptor
                                // In V2, we already set the edit link and id to the location header. So that part cannot be changed now.
                                Assert.AreEqual(ed.Identity, locationHeader, "id must be set to location header");
                                Assert.AreEqual(ed.EditLink.AbsoluteUri, locationHeader, "edit link value must be equal to the location header");
                                Assert.AreEqual(ed.SelfLink, null, "Self link must not be populated");
                                Assert.AreEqual(ed.ETag, null, "etag must be null");
                                Assert.AreEqual(ed.ServerTypeName, null, "server type name must be null");
                                Assert.AreEqual(ed.EditStreamUri, null, "edit media stream must be null");
                                Assert.AreEqual(ed.ReadStreamUri, null, "read media stream must be null");
                                Assert.AreEqual(ed.StreamETag, null, "stream etag must be null");

                                // no response for PUT
                                string responsePayload =
                                    "HTTP/1.1 200 OK" + Environment.NewLine +
                                    "Content-Type: application/atom+xml" + Environment.NewLine +
                                    Environment.NewLine;
                                PlaybackService.OverridingPlayback.Value = responsePayload;
                            }

                            i++;
                        };


                        ctx.SaveChanges();

                        Assert.IsTrue(i == 2, "only 2 requests should be sent to the server)");

                        // Make sure the edit link from the payload is used, not the location header
                        Assert.IsTrue(PlaybackService.LastPlayback.Contains("PATCH " + editLink), "should use edit link from the POST response payload");

                        // make sure the etag is used from the payload
                        Assert.IsTrue(PlaybackService.LastPlayback.Contains("If-Match: W/\"" + etag + "\""), "should use the etag value from the POST response payload");

                        // make sure the type is used from the payload
                        Assert.IsTrue(PlaybackService.LastPlayback.Contains("category term=\"#" + serverTypeName + "\" scheme=\"http://docs.oasis-open.org/odata/ns/scheme\""), "should use the server type name as specified in the POST response payload");

                        Assert.AreEqual(ed.Identity, id, "id must be set to location header");
                        Assert.AreEqual(ed.EditLink.AbsoluteUri, editLink, "edit link value must be equal to the location header");
                        Assert.AreEqual(ed.SelfLink, selfLink, "Self link should be populated");
                        Assert.AreEqual(ed.ETag, null, "etag must be null, since the PATCH response didn't send any etag in the response header");
                        Assert.AreEqual(ed.ServerTypeName, serverTypeName, "server type name must NOT be null");
                        Assert.AreEqual(ed.EditStreamUri, editMediaLink, "edit media stream must NOT be null");
                        Assert.AreEqual(ed.ReadStreamUri, readMediaLink, "read media stream must NOT be null");
                        Assert.AreEqual(ed.StreamETag, streamETag, "stream etag must NOT be null");
                    }
        }
Ejemplo n.º 2
0
        public void InsertMLEAndSetSaveStream()
        {
            // Making sure that inserting an MLE/MR followed by SetSaveStream works well
            TestUtil.RunCombinations(
                (IEnumerable<SaveChangesMode>)Enum.GetValues(typeof(SaveChangesMode)),
                UnitTestsUtil.BooleanValues,
                (mode, closeStream) =>
                {
                    using (PlaybackService.OverridingPlayback.Restore())
                    using (PlaybackService.InspectRequestPayload.Restore())
                    {
                        DataServiceContext context = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4);
                        context.EnableAtom = true;
                        context.Format.UseAtom();

                        ClientCSharpRegressionTests.CustomerWithStream c = new ClientCSharpRegressionTests.CustomerWithStream() { ID = 1, Name = "Foo" };
                        context.AddObject("Customers", c);
                        MemoryStream defaultStream = new MemoryStream(new byte[] { 0, 1, 2, 3 });
                        MemoryStream thumbnailStream = new MemoryStream(new byte[] { 0, 1, 2, 3, 4 });
                        context.SetSaveStream(c, defaultStream, closeStream, new DataServiceRequestArgs() { ContentType = "image/bmp" });
                        context.SetSaveStream(c, "Thumbnail", thumbnailStream, closeStream, new DataServiceRequestArgs() { ContentType = "image/bmp" });

                        // verify the entity descriptor state
                        EntityDescriptor entityDescriptor = context.Entities.Single();
                        StreamDescriptor streamInfo = entityDescriptor.StreamDescriptors.Single();
                        Assert.IsTrue(entityDescriptor.State == EntityStates.Added, "entity must be in added state");
                        Assert.AreEqual(streamInfo.StreamLink.Name, "Thumbnail");
                        Assert.IsTrue(streamInfo.State == EntityStates.Modified, "named stream must be in modified state");

                        string editLink = request.ServiceRoot.AbsoluteUri + "/editLink/Customers(1)";
                        int i = 0;
                        PlaybackService.InspectRequestPayload.Value = (message) =>
                        {
                            if (i == 2)
                            {
                                // Verify that the second request was a PUT request
                                Assert.IsTrue(PlaybackService.LastPlayback.Contains(String.Format("PATCH {0}", editLink)), "the second request must be a PATCH request with the edit link");
                                Assert.AreEqual(!defaultStream.CanWrite, closeStream, "The default stream must have been in the desired state");
                            }
                            else if (i == 1)
                            {
                                // Verify the first request was a POST request
                                Assert.IsTrue(PlaybackService.LastPlayback.Contains(String.Format("POST {0}/Customers", request.ServiceRoot)), "the first request must be a POST request");
                                PlaybackService.OverridingPlayback.Value = PlaybackService.ConvertToPlaybackServicePayload(null, null);
                                XDocument document = XDocument.Load(message);
                                Assert.IsTrue(document.Element(AstoriaUnitTests.Tests.UnitTestsUtil.AtomNamespace + "entry") != null, "must contain an entry element");
                                Assert.AreEqual(!defaultStream.CanWrite, closeStream, "The default stream must have been in the desired state immd after the request");
                            }
                            else if (i == 0)
                            {
                                // Populate the context with a single customer instance
                                string payload = AtomParserTests.MediaEntry(
                                    id: Id,
                                    editLink: editLink,
                                    properties: Properties,
                                    readStreamUrl: request.ServiceRoot + "/Customers(1)/readStreamUrl/$value",
                                    links: GetNamedStreamSelfLink(request.ServiceRoot + "/Customers(1)/SelfLink/Thumbnail", contentType: MediaContentType) +
                                           GetNamedStreamEditLink(request.ServiceRoot.AbsoluteUri + "/Customers(1)/EditLink/Thumbnail", contentType: MediaContentType, etag: MediaETag));

                                var headers = new List<KeyValuePair<string, string>>() {
                                new KeyValuePair<string, string>("Location", "http://locationservice/locationheader") };
                                PlaybackService.OverridingPlayback.Value = PlaybackService.ConvertToPlaybackServicePayload(headers, payload);

                                // entity state should not be modified until all the responses have been changed
                                Assert.IsTrue(entityDescriptor.State == EntityStates.Modified, "entity must be in added state");
                                Assert.IsTrue(defaultStream.CanWrite, "The default stream hasn't been closed yet");
                            }

                            Assert.AreEqual(streamInfo.StreamLink.Name, "Thumbnail");
                            Assert.IsTrue(streamInfo.State == EntityStates.Modified, "named stream must be in modified state");

                            // Also the stream info links should not be modified
                            Assert.IsTrue(streamInfo.StreamLink.SelfLink == null, "descriptor should not have been modified yet - self link must be null");
                            Assert.IsTrue(streamInfo.StreamLink.EditLink == null, "descriptor should not have been modified yet - edit link must be null");
                            Assert.IsTrue(String.IsNullOrEmpty(streamInfo.StreamLink.ContentType), "descriptor should not have been modified yet - content type must be null");
                            Assert.IsTrue(String.IsNullOrEmpty(streamInfo.StreamLink.ETag), "descriptor should not have been modified yet - etag must be null");
                            Assert.IsTrue(thumbnailStream.CanWrite, "The thumbnail stream hasn't been closed yet");
                            i++;

                        };

                        DataServiceContextTestUtil.SaveChanges(context, SaveChangesOptions.None, mode);
                        Assert.AreEqual(i, 3, "Only 2 request should have been made");

                        // Verify that the second request was a PUT request
                        Assert.IsTrue(PlaybackService.LastPlayback.Contains(String.Format("PUT {0}", streamInfo.StreamLink.EditLink)), "the second request must be a PUT request with the edit link");
                        Assert.AreEqual(streamInfo.StreamLink.SelfLink.AbsoluteUri, request.ServiceRoot + "/Customers(1)/SelfLink/Thumbnail", "self link must be null, since the payload did not have self link");
                        Assert.AreEqual(streamInfo.StreamLink.EditLink.AbsoluteUri, request.ServiceRoot + "/Customers(1)/EditLink/Thumbnail", "edit link should have been populated");
                        Assert.AreEqual(!thumbnailStream.CanWrite, closeStream, "The stream must be in the desired state");
                    }
                });
        }