Skip to content

Commit

Permalink
Fixes #756 (#791)
Browse files Browse the repository at this point in the history
* Make sure that every place a document could be rejected by the endpoint is logged and stored in LastError
* Add in a new test for 403 errors
  • Loading branch information
borrrden authored Dec 21, 2016
1 parent 16a7058 commit 3387323
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 6 deletions.
21 changes: 16 additions & 5 deletions src/Couchbase.Lite.Shared/Replication/Pusher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -281,10 +281,12 @@ private void UploadBulkDocs(IList<object> docsToSend, RevisionList revChanges)
// 403/Forbidden means validation failed; don't treat it as an error
// because I did my job in sending the revision. Other statuses are
// actual replication errors.
if (status.Code != StatusCode.Forbidden)
{
if(status.Code != StatusCode.Forbidden) {
var docId = itemObject.GetCast<string>("id");
failedIds.Add(docId);
} else {
LastError = Misc.CreateExceptionAndLog(Log.To.Sync, StatusCode.Forbidden, TAG,
$"{itemObject["id"]} was rejected by the endpoint with message: {itemObject["reason"]}");
}
}
}
Expand Down Expand Up @@ -390,9 +392,12 @@ private bool UploadMultipartRevision(RevisionInternal revision)
if (e != null) {
var httpError = Misc.Flatten(e).FirstOrDefault(ex => ex is HttpResponseException) as HttpResponseException;
if (httpError != null) {
if (httpError.StatusCode == System.Net.HttpStatusCode.UnsupportedMediaType) {
if(httpError.StatusCode == System.Net.HttpStatusCode.UnsupportedMediaType) {
_dontSendMultipart = true;
UploadJsonRevision(revision);
} else if(httpError.StatusCode == System.Net.HttpStatusCode.Forbidden) {
LastError = Misc.CreateExceptionAndLog(Log.To.Sync, StatusCode.Forbidden, TAG,
$"{revision.DocID} was rejected by the endpoint with message");
}
} else {
LastError = e;
Expand Down Expand Up @@ -427,8 +432,14 @@ private void UploadJsonRevision(RevisionInternal originalRev)
{
if (e != null)
{
LastError = e;
RevisionFailed();
var httpError = Misc.Flatten(e).FirstOrDefault(ex => ex is HttpResponseException) as HttpResponseException;
if(httpError != null) {
LastError = Misc.CreateExceptionAndLog(Log.To.Sync, StatusCode.Forbidden, TAG,
$"{rev.DocID} was rejected by the endpoint");
} else {
LastError = e;
RevisionFailed();
}
}
else
{
Expand Down
8 changes: 7 additions & 1 deletion src/Couchbase.Lite.Tests.Shared/Assets/GatewayConfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,13 @@
"jim" : { "password": "borden", "admin_channels": ["*"]}
},
"bucket":"testing",
"sync":`function(doc) {channel(doc.channels);}`
"sync":`function(doc) {
if(doc.reject) {
throw({forbidden: "Reject was set to true!"})
}

channel(doc.channels);
}`
},
"openid_db": {
"server":"walrus:",
Expand Down
48 changes: 48 additions & 0 deletions src/Couchbase.Lite.Tests.Shared/ReplicationTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
using System.Net.Sockets;
using Couchbase.Lite.Revisions;
using System.Diagnostics;
using FluentAssertions;

#if NET_3_5
using WebRequest = System.Net.Couchbase.WebRequest;
Expand Down Expand Up @@ -227,6 +228,53 @@ protected override void SetUp()
base.TearDown();
}*/

[Test]
public void TestRejectedDocument()
{
var push = database.CreatePushReplication(GetReplicationURL());
var wait = new WaitAssert();
push.Changed += (sender, e) => {
var err = e.LastError as HttpResponseException;
if(err != null) {
wait.RunAssert(() => err.StatusCode.Should().Be(HttpStatusCode.Forbidden,
"because the document should be rejected"));
}

var err2 = e.LastError as CouchbaseLiteException;
if(err2 != null) {
wait.RunAssert(() => err2.Code.Should().Be(StatusCode.Forbidden,
"because the document should be rejected"));
}
};

database.CreateDocument().PutProperties(new Dictionary<string, object> {
["reject"] = false
});

database.CreateDocument().PutProperties(new Dictionary<string, object> {
["reject"] = true
});

push.Start();

wait.WaitForResult(TimeSpan.FromSeconds(5));

var docWithAttach = database.CreateDocument();
docWithAttach.Update(rev => {
rev.SetUserProperties(new Dictionary<string, object> {
["reject"] = true
});

rev.SetAttachment("foo", "foo/bar", Enumerable.Repeat<byte>((byte)'a', 100000));
return true;
});

wait = new WaitAssert();
push.Start();

wait.WaitForResult(TimeSpan.FromSeconds(5));
}

[Test]
public void TestUnauthorized()
{
Expand Down

0 comments on commit 3387323

Please sign in to comment.