2019-07-30 16:47:10 +08:00
|
|
|
using NUnit.Framework;
|
2019-09-23 16:16:04 +08:00
|
|
|
using System;
|
2019-07-30 16:47:10 +08:00
|
|
|
using System.Threading;
|
|
|
|
using System.Threading.Tasks;
|
2019-09-23 16:16:04 +08:00
|
|
|
using System.Collections.Generic;
|
2019-12-05 16:06:54 +08:00
|
|
|
using LeanCloud.Common;
|
2019-07-30 16:47:10 +08:00
|
|
|
|
2019-09-17 11:53:28 +08:00
|
|
|
namespace LeanCloud.Test {
|
2019-07-30 16:47:10 +08:00
|
|
|
public class ObjectTests {
|
|
|
|
[SetUp]
|
|
|
|
public void SetUp() {
|
2019-12-05 16:06:54 +08:00
|
|
|
Logger.LogDelegate += Utils.Print;
|
2019-08-28 12:10:59 +08:00
|
|
|
Utils.InitNorthChina();
|
2019-07-30 16:47:10 +08:00
|
|
|
}
|
|
|
|
|
2019-12-05 16:06:54 +08:00
|
|
|
[TearDown]
|
|
|
|
public void TearDown() {
|
|
|
|
Logger.LogDelegate -= Utils.Print;
|
|
|
|
}
|
|
|
|
|
2019-07-30 16:47:10 +08:00
|
|
|
[Test]
|
2019-09-23 16:16:04 +08:00
|
|
|
public async Task Save() {
|
|
|
|
AVObject obj = AVObject.Create("Foo");
|
|
|
|
obj["content"] = "hello, world";
|
|
|
|
obj["list"] = new List<int> { 1, 1, 2, 3, 5, 8 };
|
|
|
|
obj["dict"] = new Dictionary<string, int> {
|
|
|
|
{ "hello", 1 },
|
|
|
|
{ "world", 2 }
|
|
|
|
};
|
2019-12-09 16:18:59 +08:00
|
|
|
await obj.SaveAsync();
|
2019-09-23 16:16:04 +08:00
|
|
|
Assert.NotNull(obj.ObjectId);
|
|
|
|
Assert.NotNull(obj.CreatedAt);
|
|
|
|
Assert.NotNull(obj.UpdatedAt);
|
2019-07-30 16:47:10 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
2019-09-23 16:16:04 +08:00
|
|
|
public async Task SaveWithOptions() {
|
|
|
|
AVObject account = AVObject.CreateWithoutData("Account", "5d65fa5330863b008065e476");
|
|
|
|
account["balance"] = 100;
|
|
|
|
await account.SaveAsync();
|
|
|
|
AVQuery<AVObject> query = new AVQuery<AVObject>("Account");
|
|
|
|
query.WhereGreaterThan("balance", 80);
|
|
|
|
account["balance"] = 50;
|
|
|
|
await account.SaveAsync(true, query);
|
|
|
|
TestContext.Out.WriteLine($"balance: {account["balance"]}");
|
|
|
|
}
|
|
|
|
|
2019-12-05 16:06:54 +08:00
|
|
|
//[Test]
|
|
|
|
//public async Task SaveWithPointer() {
|
|
|
|
// AVObject comment = new AVObject("Comment") {
|
|
|
|
// { "content", "Hello, Comment" }
|
|
|
|
// };
|
|
|
|
|
|
|
|
// AVObject post = new AVObject("Post") {
|
|
|
|
// { "name", "New Post" },
|
|
|
|
// { "category", new AVObject("Category") {
|
|
|
|
// { "name", "new post category" }
|
|
|
|
// } }
|
|
|
|
// };
|
|
|
|
// comment["post"] = post;
|
|
|
|
|
|
|
|
// AVObject testPost = new AVObject("Post") {
|
|
|
|
// { "name", "Test Post" },
|
|
|
|
// { "category", new AVObject("Category") {
|
|
|
|
// { "name", "test post category" }
|
|
|
|
// } }
|
|
|
|
// };
|
|
|
|
// comment["test_post"] = testPost;
|
|
|
|
|
|
|
|
// await comment.Save();
|
|
|
|
// TestContext.Out.WriteLine(post);
|
|
|
|
// TestContext.Out.WriteLine(testPost);
|
|
|
|
// TestContext.Out.WriteLine(comment);
|
|
|
|
//}
|
|
|
|
|
2019-09-23 16:16:04 +08:00
|
|
|
[Test]
|
|
|
|
public async Task SaveWithPointer() {
|
2019-12-05 16:06:54 +08:00
|
|
|
AVObject parent = new AVObject("Parent");
|
|
|
|
AVObject c1 = new AVObject("C1");
|
|
|
|
AVObject c2 = new AVObject("C2");
|
|
|
|
parent["c1"] = c1;
|
|
|
|
parent["c2"] = c2;
|
2019-12-09 16:18:59 +08:00
|
|
|
await parent.SaveAsync();
|
2019-12-05 16:06:54 +08:00
|
|
|
}
|
2019-09-23 16:16:04 +08:00
|
|
|
|
2019-12-05 16:06:54 +08:00
|
|
|
[Test]
|
|
|
|
public async Task SaveWithPointerArray() {
|
|
|
|
AVObject parent = new AVObject("Parent");
|
|
|
|
AVObject c1 = new AVObject("C1");
|
|
|
|
AVObject c2 = new AVObject("C2");
|
|
|
|
parent["iList"] = new List<int> { 1, 1, 2, 3 };
|
|
|
|
parent["cList"] = new List<AVObject> { c1, c2 };
|
|
|
|
parent["cDict"] = new Dictionary<string, AVObject> {
|
|
|
|
{ "c1", c1 },
|
|
|
|
{ "c2", c2 }
|
2019-09-23 16:16:04 +08:00
|
|
|
};
|
2019-12-05 16:06:54 +08:00
|
|
|
await parent.SaveAsync();
|
2019-09-23 16:16:04 +08:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
public async Task SaveBatch() {
|
|
|
|
List<AVObject> objList = new List<AVObject>();
|
|
|
|
for (int i = 0; i < 5; i++) {
|
|
|
|
AVObject obj = AVObject.Create("Foo");
|
|
|
|
obj["content"] = "batch object";
|
|
|
|
objList.Add(obj);
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
await objList.SaveAllAsync();
|
|
|
|
objList.ForEach(obj => {
|
|
|
|
Assert.NotNull(obj.ObjectId);
|
|
|
|
});
|
|
|
|
} catch (Exception e) {
|
|
|
|
TestContext.Out.WriteLine(e.Message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
public async Task Fetch() {
|
|
|
|
AVObject obj = AVObject.CreateWithoutData("Todo", "5d5f6039d5de2b006cf29c8f");
|
|
|
|
await obj.FetchAsync();
|
|
|
|
Assert.NotNull(obj["title"]);
|
|
|
|
Assert.NotNull(obj["content"]);
|
|
|
|
TestContext.Out.WriteLine($"{obj["title"]}, {obj["content"]}");
|
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
public async Task FetchWithKeys() {
|
|
|
|
AVObject obj = AVObject.CreateWithoutData("Post", "5d3abfa530863b0068e1b326");
|
|
|
|
await obj.FetchAsync(new List<string> { "pubUser" });
|
|
|
|
TestContext.Out.WriteLine($"{obj["pubUser"]}");
|
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
public async Task FetchWithIncludes() {
|
|
|
|
AVObject obj = AVObject.CreateWithoutData("Post", "5d3abfa530863b0068e1b326");
|
|
|
|
await obj.FetchAsync(includes: new List<string> { "tag" });
|
|
|
|
AVObject tag = obj["tag"] as AVObject;
|
|
|
|
TestContext.Out.WriteLine($"{tag["name"]}");
|
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
public async Task FetchAll() {
|
|
|
|
List<AVObject> objList = new List<AVObject> {
|
|
|
|
AVObject.CreateWithoutData("Tag", "5d64e5ebc05a8000730340ba"),
|
|
|
|
AVObject.CreateWithoutData("Tag", "5d64e5eb12215f0073db271c"),
|
|
|
|
AVObject.CreateWithoutData("Tag", "5d64e57f43e78c0068a14315")
|
|
|
|
};
|
|
|
|
await objList.FetchAllAsync();
|
|
|
|
objList.ForEach(obj => {
|
|
|
|
Assert.NotNull(obj.ObjectId);
|
|
|
|
TestContext.Out.WriteLine($"{obj.ObjectId}, {obj["name"]}");
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
public async Task Delete() {
|
|
|
|
AVObject obj = AVObject.Create("Foo");
|
|
|
|
obj["content"] = "hello, world";
|
|
|
|
await obj.SaveAsync();
|
|
|
|
Assert.NotNull(obj);
|
|
|
|
await obj.DeleteAsync();
|
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
public async Task DeleteWithCondition() {
|
|
|
|
AVObject account = new AVObject("Account") {
|
|
|
|
{ "balance", 100 },
|
|
|
|
};
|
|
|
|
account.ACL = new AVACL {
|
|
|
|
PublicWriteAccess = true,
|
|
|
|
PublicReadAccess = true
|
|
|
|
};
|
|
|
|
await account.SaveAsync();
|
|
|
|
AVQuery<AVObject> condition = new AVQuery<AVObject>();
|
|
|
|
condition.WhereGreaterThan("balance", 10);
|
|
|
|
await account.DeleteAsync(condition);
|
|
|
|
|
|
|
|
account = new AVObject("Account") {
|
|
|
|
{ "balance", 8 },
|
|
|
|
};
|
|
|
|
account.ACL = new AVACL {
|
|
|
|
PublicWriteAccess = true,
|
|
|
|
PublicReadAccess = true
|
|
|
|
};
|
|
|
|
await account.SaveAsync();
|
|
|
|
condition = new AVQuery<AVObject>();
|
|
|
|
condition.WhereGreaterThan("balance", 10);
|
|
|
|
try {
|
|
|
|
await account.DeleteAsync(condition);
|
|
|
|
} catch (AVException e) {
|
|
|
|
Assert.AreEqual(e.Code, AVException.ErrorCode.NoEffectOnUpdatingOrDeleting);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
public async Task DeleteAll() {
|
|
|
|
List<AVObject> objList = new List<AVObject>();
|
|
|
|
for (int i = 0; i < 5; i++) {
|
|
|
|
AVObject obj = AVObject.Create("Foo");
|
2019-11-01 18:19:35 +08:00
|
|
|
obj.ACL = new AVACL {
|
|
|
|
PublicReadAccess = true,
|
|
|
|
PublicWriteAccess = i % 2 == 0
|
|
|
|
};
|
2019-09-23 16:16:04 +08:00
|
|
|
obj["content"] = "batch object";
|
|
|
|
objList.Add(obj);
|
|
|
|
}
|
|
|
|
await objList.SaveAllAsync();
|
2019-11-01 18:19:35 +08:00
|
|
|
try {
|
|
|
|
await AVObject.DeleteAllAsync(objList);
|
|
|
|
} catch (AggregateException e) {
|
|
|
|
foreach (AVException ie in e.InnerExceptions) {
|
|
|
|
TestContext.Out.WriteLine($"{ie.Code} : {ie.Message}");
|
|
|
|
}
|
|
|
|
}
|
2019-07-30 16:47:10 +08:00
|
|
|
}
|
|
|
|
|
2019-08-23 16:16:18 +08:00
|
|
|
[Test]
|
|
|
|
public async Task TestMassiveRequest() {
|
2019-09-09 16:34:49 +08:00
|
|
|
ThreadPool.SetMaxThreads(1, 1);
|
2019-08-23 16:16:18 +08:00
|
|
|
await Task.Run(() => {
|
|
|
|
for (int i = 0; i < 10; i++) {
|
|
|
|
for (int j = 0; j < 50; j++) {
|
|
|
|
AVObject obj = AVObject.Create("Foo");
|
|
|
|
obj.SaveAsync().ContinueWith(_ => {
|
2019-09-09 16:34:49 +08:00
|
|
|
TestContext.Out.WriteLine($"{obj.ObjectId} saved at {Thread.CurrentThread.ManagedThreadId}");
|
2019-08-23 16:16:18 +08:00
|
|
|
});
|
|
|
|
}
|
|
|
|
Thread.Sleep(1000);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2019-12-05 16:06:54 +08:00
|
|
|
|
|
|
|
[Test]
|
|
|
|
public void SimpleCircleReference() {
|
|
|
|
AVObject a = new AVObject("A");
|
|
|
|
AVObject b = new AVObject("B");
|
|
|
|
a["b"] = b;
|
|
|
|
b["a"] = a;
|
|
|
|
|
2019-12-09 16:18:59 +08:00
|
|
|
Assert.ThrowsAsync<AVException>(async () => await a.SaveAsync());
|
2019-12-05 16:06:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
public void IndirectCircleReference() {
|
|
|
|
AVObject a = new AVObject("A");
|
|
|
|
AVObject b = new AVObject("B");
|
|
|
|
AVObject c = new AVObject("C");
|
|
|
|
a["b"] = b;
|
|
|
|
b["c"] = c;
|
|
|
|
c["a"] = a;
|
|
|
|
|
2019-12-09 16:18:59 +08:00
|
|
|
Assert.ThrowsAsync<AVException>(async () => await a.SaveAsync());
|
2019-12-05 16:06:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
public void SimpleCollectionPointerCircleReference() {
|
|
|
|
AVObject a = new AVObject("A");
|
|
|
|
AVObject b = new AVObject("B");
|
|
|
|
a["children"] = new List<object> { 1, b };
|
|
|
|
b["children"] = new Dictionary<string, object> {
|
|
|
|
{ "c", a }
|
|
|
|
};
|
|
|
|
|
2019-12-09 16:18:59 +08:00
|
|
|
Assert.ThrowsAsync<AVException>(async () => await a.SaveAsync());
|
2019-12-05 16:06:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
public void IndirectCollectionPointerCircleReference() {
|
|
|
|
AVObject a = new AVObject("A");
|
|
|
|
AVObject b = new AVObject("B");
|
|
|
|
AVObject c = new AVObject("C");
|
|
|
|
|
|
|
|
a["children"] = new List<object> { 1, b };
|
|
|
|
b["children"] = new List<object> { 2, c };
|
|
|
|
c["children"] = new Dictionary<string, object> {
|
|
|
|
{ "c", a }
|
|
|
|
};
|
|
|
|
|
2019-12-09 16:18:59 +08:00
|
|
|
Assert.ThrowsAsync<AVException>(async () => await a.SaveAsync());
|
2019-12-05 16:06:54 +08:00
|
|
|
}
|
2019-12-05 16:36:11 +08:00
|
|
|
|
|
|
|
[Test]
|
|
|
|
public async Task SimpleSavePointerCollection() {
|
|
|
|
AVObject p = new AVObject("P");
|
|
|
|
AVObject c1 = new AVObject("C1");
|
|
|
|
AVObject c2 = new AVObject("C2");
|
|
|
|
p["cList"] = new List<AVObject> { c1, c2 };
|
|
|
|
p["cDict"] = new Dictionary<string, object> {
|
|
|
|
{ "c1", c1 },
|
|
|
|
{ "c2", c2 }
|
|
|
|
};
|
2019-12-09 16:18:59 +08:00
|
|
|
await p.SaveAsync();
|
2019-12-05 16:36:11 +08:00
|
|
|
}
|
2019-12-06 17:02:10 +08:00
|
|
|
|
|
|
|
[Test]
|
|
|
|
public async Task SaveWithQuery() {
|
|
|
|
AVObject p = new AVObject("P");
|
|
|
|
AVObject c1 = AVObject.CreateWithoutData("C1", "5dea05578a84ab00680b7ae5");
|
|
|
|
AVObject c2 = new AVObject("C2");
|
|
|
|
p["c"] = c1;
|
|
|
|
c1["c"] = c2;
|
2019-12-09 16:18:59 +08:00
|
|
|
await p.SaveAsync();
|
2019-12-06 17:02:10 +08:00
|
|
|
}
|
2019-07-30 16:47:10 +08:00
|
|
|
}
|
2019-12-06 17:02:10 +08:00
|
|
|
}
|