protected override async Task<Entity> UpdateAsync(IDictionary<string, object> propertyUpdates, IDictionary<string, string> attributeUpdates, IEnumerable<string> addedTags, IEnumerable<string> removedTags, int specificRevision)
        {
            var request = new UpdateArticleRequest {Id = this.Id, Type = this.Type};
            if (propertyUpdates != null && propertyUpdates.Count > 0)
                propertyUpdates.For(x => request.PropertyUpdates[x.Key] = x.Value);
            if (attributeUpdates != null && attributeUpdates.Count > 0)
                attributeUpdates.For(x => request.AttributeUpdates[x.Key] = x.Value);
            if (addedTags != null)
                request.AddedTags.AddRange(addedTags);
            if (removedTags != null)
                request.RemovedTags.AddRange(removedTags);

            // Check if an update is needed.
            if (request.PropertyUpdates.Count == 0 &&
                request.AttributeUpdates.Count == 0 &&
                request.AddedTags.Count == 0 &&
                request.RemovedTags.Count == 0)
                return null;

            var response = await request.ExecuteAsync();
            if (response.Status.IsSuccessful == false)
                throw response.Status.ToFault();

            // 3. Update the last known state based on the differences
            Debug.Assert(response.Article != null, "If status is successful, then updated article should not be null.");
            return response.Article;
        }
 public async Task<UpdateArticleResponse> UpdateArticleAsync(UpdateArticleRequest request)
 {
     byte[] bytes = null;
     bytes = await HttpOperation
                 .WithUrl(Urls.For.UpdateArticle(request.Type, request.Id, request.Revision, request.CurrentLocation, request.DebugEnabled, request.Verbosity, request.Fields))
                 .WithAppacitiveSession(request.SessionToken)
                 .WithEnvironment(request.Environment)
                 .WithUserToken(request.UserToken)
                 .PostAsyc(request.ToBytes());
     var response = UpdateArticleResponse.Parse(bytes);
     return response;
 }
        protected override async Task<Entity> UpdateAsync(IDictionary<string, string> propertyUpdates, IDictionary<string, string> attributeUpdates, IEnumerable<string> addedTags, IEnumerable<string> removedTags, int specificRevision)
        {
            var articleService = ObjectFactory.Build<IArticleService>();
            var request = new UpdateArticleRequest()
            {
                SessionToken = AppacitiveContext.SessionToken,
                Environment = AppacitiveContext.Environment,
                UserToken = AppacitiveContext.UserToken,
                Verbosity = AppacitiveContext.Verbosity,
                Revision = specificRevision,
                Id = this.Id,
                Type = this.Type
            };

            if (propertyUpdates != null && propertyUpdates.Count > 0)
                propertyUpdates.For(x => request.PropertyUpdates[x.Key] = x.Value);
            if (attributeUpdates != null && attributeUpdates.Count > 0)
                attributeUpdates.For(x => request.AttributeUpdates[x.Key] = x.Value);
            if (addedTags != null)
                request.AddedTags.AddRange(addedTags);
            if (removedTags != null)
                request.RemovedTags.AddRange(removedTags);

            // Check if an update is needed.
            if (request.PropertyUpdates.Count == 0 &&
                request.AttributeUpdates.Count == 0 &&
                request.AddedTags.Count == 0 &&
                request.RemovedTags.Count == 0)
                return null;

            var response = await articleService.UpdateArticleAsync(request);
            if (response.Status.IsSuccessful == false)
                throw response.Status.ToFault();

            // 3. Update the last known state based on the differences
            Debug.Assert(response.Article != null, "If status is successful, then updated article should not be null.");
            return response.Article;
        }
        public async Task BugId14Test()
        {
            // Ref: https://github.com/appacitive/Gossamer/issues/14
            // Updating a null property with a null value fails 
            // Create an article
            var now = DateTime.Now;
            dynamic obj = new Article("object");
            obj.intfield = 1;
            obj.decimalfield = 10.0m;
            obj.stringfield = null;

            var service = ObjectFactory.Build<IArticleService>();
            var createdResponse = await service.CreateArticleAsync(new CreateArticleRequest()
            {
                Article = obj
            });
            Assert.IsNotNull(createdResponse, "Article creation failed.");
            Assert.IsNotNull(createdResponse.Status, "Status is null.");
            Assert.IsTrue(createdResponse.Status.IsSuccessful, createdResponse.Status.Message ?? "Create article failed.");
            var created = createdResponse.Article;

            // Update the article twice
            for (int i = 0; i < 2; i++)
            {
                var updateRequest = new UpdateArticleRequest()
                {
                    Id = created.Id,
                    Type = created.Type
                };
                updateRequest.PropertyUpdates["stringfield"] = null;
                var updatedResponse = await service.UpdateArticleAsync(updateRequest);

                Assert.IsNotNull(updatedResponse, "Update article response is null.");
                Assert.IsNotNull(updatedResponse.Status, "Update article response status is null.");
                Assert.IsTrue(updatedResponse.Status.IsSuccessful, updatedResponse.Status.Message ?? "NULL");
                Assert.IsNotNull(updatedResponse.Article, "Updated article is null.");
                var updated = updatedResponse.Article;
                Assert.IsTrue(updated["stringfield"] == null);   
            }
        }
        public void UpdateArticleAsyncTest()
        {
            var waitHandle = new ManualResetEvent(false);
            Exception fault = null;
            Action action = async () =>
                {
                    try
                    {
                        // Create an article
                        var now = DateTime.Now;
                        dynamic obj = new Article("object");
                        obj.intfield = 1;
                        obj.decimalfield = 10.0m;
                        obj.datefield = "2012-12-20";
                        obj.stringfield = "initial";
                        obj.Tags.Add("initial");

                        var service = ObjectFactory.Build<IArticleService>();
                        var createdResponse = await service.CreateArticleAsync(new CreateArticleRequest()
                        {
                            Article = obj
                        });
                        Assert.IsNotNull(createdResponse, "Article creation failed.");
                        Assert.IsNotNull(createdResponse.Status, "Status is null.");
                        Assert.IsTrue(createdResponse.Status.IsSuccessful, createdResponse.Status.Message ?? "Create article failed.");
                        var created = createdResponse.Article;

                        // Update the article
                        var updateRequest = new UpdateArticleRequest()
                        {
                            Id = created.Id,
                            Type = created.Type
                        };
                        updateRequest.PropertyUpdates["intfield"] = "2";
                        updateRequest.PropertyUpdates["decimalfield"] = 20.0m.ToString();
                        updateRequest.PropertyUpdates["stringfield"] = null;
                        updateRequest.PropertyUpdates["datefield"] = "2013-11-20";
                        updateRequest.AddedTags.AddRange(new[] { "tag1", "tag2" });
                        updateRequest.RemovedTags.AddRange(new[] { "initial" });
                        var updatedResponse = await service.UpdateArticleAsync(updateRequest);

                        Assert.IsNotNull(updatedResponse, "Update article response is null.");
                        Assert.IsNotNull(updatedResponse.Status, "Update article response status is null.");
                        Assert.IsNotNull(updatedResponse.Article, "Updated article is null.");
                        var updated = updatedResponse.Article;
                        Assert.IsTrue(updated["intfield"] == "2");
                        Assert.IsTrue(updated["decimalfield"] == "20.0");
                        Assert.IsTrue(updated["stringfield"] == null);
                        Assert.IsTrue(updated["datefield"] == "2013-11-20");
                        Assert.IsTrue(updated.Tags.Count() == 2);
                        Assert.IsTrue(updated.Tags.Intersect(new[] { "tag1", "tag2" }).Count() == 2);
                    }
                    catch (Exception ex)
                    {
                        fault = ex;
                    }
                    finally
                    {
                        waitHandle.Set();
                    }
                };
            action();
            waitHandle.WaitOne();
            Assert.IsNull(fault);

        }
        public async Task UpdateArticleAsyncTest()
        {
            // Create an article
            var now = DateTime.Now;
            dynamic obj = new Article("object");
            obj.intfield = 1;
            obj.decimalfield = 10.0m;
            obj.datefield = "2012-12-20";
            obj.stringfield = "initial";
            obj.Tags.Add("initial");

            var createdResponse = await (new CreateArticleRequest()
                {
                    Article = obj
                }).ExecuteAsync();
            Assert.IsNotNull(createdResponse, "Article creation failed.");
            Assert.IsNotNull(createdResponse.Status, "Status is null.");
            Assert.IsTrue(createdResponse.Status.IsSuccessful,
                          createdResponse.Status.Message ?? "Create article failed.");
            var created = createdResponse.Article;

            // Update the article
            var updateRequest = new UpdateArticleRequest()
                {
                    Id = created.Id,
                    Type = created.Type
                };
            updateRequest.PropertyUpdates["intfield"] = "2";
            updateRequest.PropertyUpdates["decimalfield"] = 20.0m.ToString();
            updateRequest.PropertyUpdates["stringfield"] = null;
            updateRequest.PropertyUpdates["datefield"] = "2013-11-20";
            updateRequest.AddedTags.AddRange(new[] {"tag1", "tag2"});
            updateRequest.RemovedTags.AddRange(new[] {"initial"});
            var updatedResponse = await updateRequest.ExecuteAsync();


            Assert.IsNotNull(updatedResponse, "Update article response is null.");
            Assert.IsNotNull(updatedResponse.Status, "Update article response status is null.");
            Assert.IsNotNull(updatedResponse.Article, "Updated article is null.");
            var updated = updatedResponse.Article;
            Assert.IsTrue(updated.Get<string>("intfield") == "2");
            Assert.IsTrue(updated.Get<string>("decimalfield") == "20.0");
            Assert.IsTrue(updated.Get<string>("stringfield") == null);
            Assert.IsTrue(updated.Get<string>("datefield") == "2013-11-20");
            Assert.IsTrue(updated.Tags.Count() == 2);
            Assert.IsTrue(updated.Tags.Intersect(new[] {"tag1", "tag2"}).Count() == 2);

        }