diff --git a/Storage/Storage.Test/ACLTest.cs b/Storage/Storage.Test/ACLTest.cs new file mode 100644 index 0000000..5659687 --- /dev/null +++ b/Storage/Storage.Test/ACLTest.cs @@ -0,0 +1,54 @@ +using NUnit.Framework; +using System.Threading.Tasks; +using LeanCloud.Storage; + +namespace LeanCloud.Test { + public class ACLTest { + [SetUp] + public void SetUp() { + Logger.LogDelegate += Utils.Print; + LeanCloud.Initialize("ikGGdRE2YcVOemAaRbgp1xGJ-gzGzoHsz", "NUKmuRbdAhg1vrb2wexYo1jo", "https://ikggdre2.lc-cn-n1-shared.com"); + } + + [TearDown] + public void TearDown() { + Logger.LogDelegate -= Utils.Print; + } + + [Test] + public async Task PrivateReadAndWrite() { + LCObject account = new LCObject("Account"); + LCACL acl = new LCACL(); + acl.PublicReadAccess = false; + acl.PublicWriteAccess = false; + account.ACL = acl; + account["balance"] = 1024; + await account.Save(); + Assert.IsFalse(acl.PublicReadAccess); + Assert.IsFalse(acl.PublicWriteAccess); + } + + [Test] + public async Task UserReadAndWrite() { + //await LCUser.Login('hello', 'world'); + //LCObject account = new LCObject('Account'); + //LCUser currentUser = await LCUser.getCurrent(); + //LCACL acl = LCACL.createWithOwner(currentUser); + //account.acl = acl; + //account['balance'] = 512; + //await account.save(); + + //assert(acl.getUserReadAccess(currentUser) == true); + //assert(acl.getUserWriteAccess(currentUser) == true); + + //LCQuery query = new LCQuery('Account'); + //LCObject result = await query.get(account.objectId); + //print(result.objectId); + //assert(result.objectId != null); + + //LCUser.logout(); + //result = await query.get(account.objectId); + //assert(result == null); + } + } +} diff --git a/Storage/Storage.Test/QueryTest.cs b/Storage/Storage.Test/QueryTest.cs index a661cf2..66dee5b 100644 --- a/Storage/Storage.Test/QueryTest.cs +++ b/Storage/Storage.Test/QueryTest.cs @@ -1,121 +1,267 @@ using NUnit.Framework; using System.Collections.Generic; using System.Threading.Tasks; -using System.Linq; -using Newtonsoft.Json; +using LeanCloud.Storage; namespace LeanCloud.Test { public class QueryTest { [SetUp] public void SetUp() { - Utils.InitNorthChina(); + Logger.LogDelegate += Utils.Print; + LeanCloud.Initialize("ikGGdRE2YcVOemAaRbgp1xGJ-gzGzoHsz", "NUKmuRbdAhg1vrb2wexYo1jo", "https://ikggdre2.lc-cn-n1-shared.com"); + } + + [TearDown] + public void TearDown() { + Logger.LogDelegate -= Utils.Print; } [Test] - public async Task BasicQuery() { - var query = new AVQuery("Account"); - query.WhereGreaterThanOrEqualTo("balance", 100); - query.WhereLessThanOrEqualTo("balance", 100); - var results = await query.FindAsync(); - foreach (var result in results) { - TestContext.Out.WriteLine(result.ObjectId); + public async Task BaseQuery() { + LCQuery query = new LCQuery("Hello"); + query.Limit(2); + List list = await query.Find(); + TestContext.WriteLine(list.Count); + Assert.AreEqual(list.Count, 2); + + foreach (LCObject item in list) { + Assert.NotNull(item.ClassName); + Assert.NotNull(item.ObjectId); + Assert.NotNull(item.CreatedAt); + Assert.NotNull(item.UpdatedAt); + + TestContext.WriteLine(item.ClassName); + TestContext.WriteLine(item.ObjectId); + TestContext.WriteLine(item.CreatedAt); + TestContext.WriteLine(item.UpdatedAt); + TestContext.WriteLine(item["intValue"]); + TestContext.WriteLine(item["boolValue"]); + TestContext.WriteLine(item["stringValue"]); } } [Test] public async Task Count() { - var query = new AVQuery("Foo"); - query.WhereEqualTo("content", "hello, world"); - var count = await query.CountAsync(); - Assert.Greater(count, 8); + LCQuery query = new LCQuery("Account"); + query.WhereGreaterThan("balance", 200); + int count = await query.Count(); + TestContext.WriteLine(count); + Assert.Greater(count, 0); } [Test] - public async Task Or() { - AVQuery q1 = new AVQuery("Foo"); - q1.WhereEqualTo("content", "hello"); - AVQuery q2 = new AVQuery("Foo"); - q2.WhereEqualTo("content", "world"); - AVQuery query = AVQuery.Or(new List> { q1, q2 }); - IEnumerable results = await query.FindAsync(); - foreach (AVObject result in results) { - TestContext.Out.WriteLine(result.ObjectId); - } + public async Task OrderBy() { + LCQuery query = new LCQuery("Account"); + query.OrderBy("balance"); + List results = await query.Find(); + Assert.LessOrEqual((int)results[0]["balance"], (int)results[1]["balance"]); + + query = new LCQuery("Account"); + query.OrderByDescending("balance"); + results = await query.Find(); + Assert.GreaterOrEqual((int)results[0]["balance"], (int)results[1]["balance"]); + } + + [Test] + public async Task Include() { + LCQuery query = new LCQuery("Hello"); + query.Include("objectValue"); + LCObject hello = await query.Get("5e0d55aedd3c13006a53cd87"); + LCObject world = hello["objectValue"] as LCObject; + TestContext.WriteLine(world["content"]); + Assert.AreEqual(world["content"], "7788"); + } + + [Test] + public async Task Get() { + LCQuery query = new LCQuery("Account"); + LCObject account = await query.Get("5e0d9f7fd4b56c008e5d048a"); + Assert.AreEqual(account["balance"], 400); + } + + [Test] + public async Task First() { + LCQuery query = new LCQuery("Account"); + LCObject account = await query.First(); + Assert.NotNull(account.ObjectId); + } + + [Test] + public async Task GreaterQuery() { + LCQuery query = new LCQuery("Account"); + query.WhereGreaterThan("balance", 200); + List list = await query.Find(); + TestContext.WriteLine(list.Count); + Assert.Greater(list.Count, 0); } [Test] public async Task And() { - AVQuery q1 = new AVQuery("Foo"); - q1.WhereContains("content", "hello"); - AVQuery q2 = new AVQuery("Foo"); - q2.WhereContains("content", "world"); - AVQuery query = AVQuery.And(new List> { q1, q2 }); - IEnumerable results = await query.FindAsync(); - TestContext.Out.WriteLine($"Count: {results.Count()}"); - foreach (AVObject result in results) { - TestContext.Out.WriteLine(result.ObjectId); - } + LCQuery q1 = new LCQuery("Account"); + q1.WhereGreaterThan("balance", 100); + LCQuery q2 = new LCQuery("Account"); + q2.WhereLessThan("balance", 500); + LCQuery query = LCQuery.And(new List> { q1, q2 }); + List results = await query.Find(); + TestContext.WriteLine(results.Count); + results.ForEach(item => { + int balance = (int)item["balance"]; + Assert.IsTrue(balance >= 100 || balance <= 500); + }); } [Test] - public async Task OrPro() { - AVQuery q1 = AVQuery.Or(new List> { - new AVQuery("Account").WhereEqualTo("balance", 100) + public async Task Or() { + LCQuery q1 = new LCQuery("Account"); + q1.WhereLessThanOrEqualTo("balance", 100); + LCQuery q2 = new LCQuery("Account"); + q2.WhereGreaterThanOrEqualTo("balance", 500); + LCQuery query = LCQuery.Or(new List> { q1, q2 }); + List results = await query.Find(); + TestContext.WriteLine(results.Count); + results.ForEach(item => { + int balance = (int)item["balance"]; + Assert.IsTrue(balance <= 100 || balance >= 500); }); - AVQuery q2 = AVQuery.Or(new List> { - new AVQuery("Account").WhereEqualTo("balance", 200) - }); - AVQuery query = AVQuery.Or(new List> { - q1, q2 - }); - query.WhereEqualTo("balance", 100); - IEnumerable results = await query.FindAsync(); - foreach (AVObject result in results) { - TestContext.Out.WriteLine(result.ObjectId); - } } [Test] - public async Task Related() { - AVObject todo = AVObject.CreateWithoutData("Todo", "5d71f798d5de2b006c0136bc"); - AVQuery query = new AVQuery("Tag"); - query.WhereRelatedTo(todo, "tags"); - IEnumerable results = await query.FindAsync(); - foreach (AVObject tag in results) { - TestContext.Out.WriteLine(tag.ObjectId); - } + public async Task WhereObjectEquals() { + LCQuery worldQuery = new LCQuery("World"); + LCObject world = await worldQuery.Get("5e0d55ae21460d006a1ec931"); + LCQuery helloQuery = new LCQuery("Hello"); + helloQuery.WhereEqualTo("objectValue", world); + LCObject hello = await helloQuery.First(); + TestContext.WriteLine(hello.ObjectId); + Assert.AreEqual(hello.ObjectId, "5e0d55aedd3c13006a53cd87"); } [Test] - public void Where() { - AVQuery q1 = new AVQuery(); - q1.WhereEqualTo("aa", "bb"); - AVQuery q2 = new AVQuery(); - q2.WhereEqualTo("cc", "dd"); - q2.WhereEqualTo("ee", "ff"); - List> queryList = new List> { - q1, q2 - }; - AVQuery query = AVQuery.Or(queryList); - IDictionary obj = query.BuildWhere(); - TestContext.Out.WriteLine(JsonConvert.SerializeObject(obj)); + public async Task Exist() { + LCQuery query = new LCQuery("Account"); + query.WhereExists("user"); + List results = await query.Find(); + results.ForEach(item => { + Assert.NotNull(item["user"]); + }); - AVQuery q3 = new AVQuery(); - q3.WhereEqualTo("xx", "yy"); - IDictionary q3Obj = q3.BuildWhere(); - TestContext.Out.WriteLine(JsonConvert.SerializeObject(q3Obj)); + query = new LCQuery("Account"); + query.WhereDoesNotExist("user"); + results = await query.Find(); + results.ForEach(item => { + Assert.IsNull(item["user"]); + }); + } - AVQuery q4 = new AVQuery(); - q4.WhereEqualTo("aaa", "bbb"); - q4.WhereEqualTo("ccc", "ddd"); - IDictionary q4Obj = q4.BuildWhere(); - TestContext.Out.WriteLine(JsonConvert.SerializeObject(q4Obj)); + [Test] + public async Task Select() { + LCQuery query = new LCQuery("Account"); + query.Select("balance"); + List results = await query.Find(); + results.ForEach(item => { + Assert.NotNull(item["balance"]); + Assert.IsNull(item["user"]); + }); + } - AVQuery q5 = new AVQuery(); - q5.WhereEqualTo("aaa", "bbb"); - q5.WhereEqualTo("aaa", "ccc"); - IDictionary q5Obj = q5.BuildWhere(); - TestContext.Out.WriteLine(JsonConvert.SerializeObject(q5Obj)); + [Test] + public async Task String() { + // Start + LCQuery query = new LCQuery("Hello"); + query.WhereStartsWith("stringValue", "hello"); + List results = await query.Find(); + results.ForEach(item => { + string str = item["stringValue"] as string; + Assert.IsTrue(str.StartsWith("hello")); + }); + + // End + query = new LCQuery("Hello"); + query.WhereEndsWith("stringValue", "world"); + results = await query.Find(); + results.ForEach(item => { + string str = item["stringValue"] as string; + Assert.IsTrue(str.EndsWith("world")); + }); + + // Contains + query = new LCQuery("Hello"); + query.WhereContains("stringValue", ","); + results = await query.Find(); + results.ForEach(item => { + string str = item["stringValue"] as string; + Assert.IsTrue(str.Contains(',')); + }); + } + + [Test] + public async Task Array() { + // equal + LCQuery query = new LCQuery("Book"); + query.WhereEqualTo("pages", 3); + Listresults = await query.Find(); + results.ForEach(item => { + List pages = item["pages"] as List; + Assert.IsTrue(pages.Contains(3)); + }); + + // contain all + List containAlls = new List { 1, 2, 3, 4, 5, 6, 7 }; + query = new LCQuery("Book"); + query.WhereContainsAll("pages", containAlls); + results = await query.Find(); + results.ForEach(item => { + List pages = item["pages"] as List; + pages.ForEach(i => { + Assert.IsTrue(pages.Contains(i)); + }); + }); + + // contain in + List containIns = new List { 4, 5, 6 }; + query = new LCQuery("Book"); + query.WhereContainedIn("pages", containIns); + results = await query.Find(); + results.ForEach(item => { + List pages = item["pages"] as List; + bool f = false; + containIns.ForEach(i => { + f |= pages.Contains(i); + }); + Assert.IsTrue(f); + }); + + // size + query = new LCQuery("Book"); + query.WhereSizeEqualTo("pages", 7); + results = await query.Find(); + results.ForEach(item => { + List pages = item["pages"] as List; + Assert.AreEqual(pages.Count, 7); + }); + } + + [Test] + public async Task Geo() { + LCObject obj = new LCObject("Todo"); + LCGeoPoint location = new LCGeoPoint(39.9, 116.4); + obj["location"] = location; + await obj.Save(); + + // near + LCQuery query = new LCQuery("Todo"); + LCGeoPoint point = new LCGeoPoint(39.91, 116.41); + query.WhereNear("location", point); + List results = await query.Find(); + Assert.Greater(results.Count, 0); + + // in box + query = new LCQuery("Todo"); + LCGeoPoint southwest = new LCGeoPoint(30, 115); + LCGeoPoint northeast = new LCGeoPoint(40, 118); + query.WhereWithinGeoBox("location", southwest, northeast); + results = await query.Find(); + Assert.Greater(results.Count, 0); } } } diff --git a/Storage/Storage/Internal/Http/LCHttpClient.cs b/Storage/Storage/Internal/Http/LCHttpClient.cs index d5e1741..424a1b3 100644 --- a/Storage/Storage/Internal/Http/LCHttpClient.cs +++ b/Storage/Storage/Internal/Http/LCHttpClient.cs @@ -118,7 +118,7 @@ namespace LeanCloud.Storage.Internal.Http { try { // 尝试获取 LeanCloud 返回错误信息 Dictionary error = JsonConvert.DeserializeObject>(resultString, new LeanCloudJsonConverter()); - code = (int)(long)error["code"]; + code = (int)error["code"]; message = error["error"].ToString(); } catch (Exception e) { Logger.Error(e.Message); @@ -162,7 +162,7 @@ namespace LeanCloud.Storage.Internal.Http { try { // 尝试获取 LeanCloud 返回错误信息 Dictionary error = JsonConvert.DeserializeObject>(resultString, new LeanCloudJsonConverter()); - code = (int)(long)error["code"]; + code = (int)error["code"]; message = error["error"].ToString(); } catch (Exception e) { Logger.Error(e.Message); diff --git a/Storage/Storage/Internal_/Utilities/LeanCloudJsonConverter.cs b/Storage/Storage/Internal/Http/LeanCloudJsonConverter.cs similarity index 83% rename from Storage/Storage/Internal_/Utilities/LeanCloudJsonConverter.cs rename to Storage/Storage/Internal/Http/LeanCloudJsonConverter.cs index 0d17eab..ed5fd05 100644 --- a/Storage/Storage/Internal_/Utilities/LeanCloudJsonConverter.cs +++ b/Storage/Storage/Internal/Http/LeanCloudJsonConverter.cs @@ -23,6 +23,11 @@ namespace LeanCloud.Storage.Internal { serializer.Populate(reader, arr); return arr; } + if (reader.TokenType == JsonToken.Integer) { + if ((long)reader.Value < int.MaxValue) { + return Convert.ToInt32(reader.Value); + } + } return serializer.Deserialize(reader); } diff --git a/Storage/Storage/Internal/Query/LCCompositionalCondition.cs b/Storage/Storage/Internal/Query/LCCompositionalCondition.cs index 79af22d..917b2bf 100644 --- a/Storage/Storage/Internal/Query/LCCompositionalCondition.cs +++ b/Storage/Storage/Internal/Query/LCCompositionalCondition.cs @@ -72,7 +72,7 @@ namespace LeanCloud.Storage.Internal.Query { } internal void WhereLessThan(string key, object value) { - AddOperation(key, "$lt$lt", value); + AddOperation(key, "$lt", value); } internal void WhereLessThanOrEqualTo(string key, object value) { diff --git a/Storage/Storage/LCObject.cs b/Storage/Storage/LCObject.cs index d6c74c9..059ab0f 100644 --- a/Storage/Storage/LCObject.cs +++ b/Storage/Storage/LCObject.cs @@ -57,6 +57,8 @@ namespace LeanCloud.Storage { public LCACL ACL { get { return this["ACL"] as LCACL ; + } set { + this["ACL"] = value; } }