* RelationTest.cs: chore: 完善 Relation 和 Role 的功能和测试

* LCRole.cs:
* LCObject.cs:
* LCRelation.cs:
* RoleTest.cs:
* LCDecoder.cs:
* LCEncoder.cs:
* LCAddRelationOperation.cs:
* LCRemoveRelationOperation.cs:
oneRain 2020-02-27 12:31:48 +08:00
parent 6576cbd47f
commit 83ad15a8ec
9 changed files with 189 additions and 51 deletions

View File

@ -1,46 +1,66 @@
using NUnit.Framework;
using LeanCloud;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Linq;
using LeanCloud.Storage;
namespace LeanCloud.Test {
public class RelationTest {
[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 CreateRelation() {
AVObject tag1 = new AVObject("Tag") {
["name"] = "hello"
};
await tag1.SaveAsync();
AVObject tag2 = new AVObject("Tag") {
{ "name", "world" }
};
await tag2.SaveAsync();
AVObject todo = new AVObject("Todo");
AVRelation<AVObject> relation = todo.GetRelation<AVObject>("tags");
relation.Add(tag1);
relation.Add(tag2);
await todo.SaveAsync();
public async Task AddAndRemove() {
LCObject parent = new LCObject("Parent");
LCObject c1 = new LCObject("Child");
parent.AddRelation("children", c1);
LCObject c2 = new LCObject("Child");
parent.AddRelation("children", c2);
await parent.Save();
LCRelation<LCObject> relation = parent["children"] as LCRelation<LCObject>;
LCQuery<LCObject> query = relation.Query;
int count = await query.Count();
TestContext.WriteLine($"count: {count}");
Assert.AreEqual(count, 2);
parent.RemoveRelation("children", c2);
await parent.Save();
int count2 = await query.Count();
TestContext.WriteLine($"count: {count2}");
Assert.AreEqual(count2, 1);
}
[Test]
public async Task QueryRelation() {
AVQuery<AVObject> query = new AVQuery<AVObject>("Todo");
query.OrderByDescending("createdAt");
AVObject todo = await query.FirstAsync();
AVRelation<AVObject> relation = todo.GetRelation<AVObject>("tags");
AVQuery<AVObject> tagQuery = relation.Query;
IEnumerable<AVObject> tags = await tagQuery.FindAsync();
Assert.Greater(tags.Count(), 0);
TestContext.Out.WriteLine($"count: {tags.Count()}");
foreach (AVObject tag in tags) {
TestContext.Out.WriteLine($"{tag.ObjectId}, {tag["name"]}");
}
public async Task Query() {
LCQuery<LCObject> query = new LCQuery<LCObject>("Parent");
LCObject parent = await query.Get("5e13112021b47e0070ed0922");
LCRelation<LCObject> relation = parent["children"] as LCRelation<LCObject>;
TestContext.WriteLine(relation.Key);
TestContext.WriteLine(relation.Parent);
TestContext.WriteLine(relation.TargetClass);
Assert.NotNull(relation.Key);
Assert.NotNull(relation.Parent);
Assert.NotNull(relation.TargetClass);
LCQuery<LCObject> relationQuery = relation.Query;
List<LCObject> list = await relationQuery.Find();
list.ForEach(item => {
TestContext.WriteLine(item.ObjectId);
Assert.NotNull(item.ObjectId);
});
}
}
}

View File

@ -1,28 +1,49 @@
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using LeanCloud;
using System.Linq;
using LeanCloud.Storage;
namespace LeanCloud.Test {
[TestFixture]
public class RoleTest {
[SetUp]
public void SetUp() {
Utils.InitNorthChina(true);
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 GetUsersFromRole() {
AVQuery<AVRole> query = new AVQuery<AVRole>();
AVRole role = await query.FirstAsync();
AVQuery<AVUser> userQuery = role.Users.Query;
IEnumerable<AVUser> users = await userQuery.FindAsync();
Assert.Greater(users.Count(), 0);
TestContext.Out.WriteLine($"count: {users.Count()}");
foreach (AVUser user in users) {
TestContext.Out.WriteLine($"{user.ObjectId}, {user.Username}");
public async Task NewRole() {
LCUser currentUser = await LCUser.Login("game", "play");
LCACL acl = new LCACL();
acl.PublicReadAccess = true;
acl.SetUserWriteAccess(currentUser, true);
string name = $"role_{DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}";
LCRole role = LCRole.Create(name, acl);
role.AddRelation("users", currentUser);
await role.Save();
}
[Test]
public async Task Query() {
LCQuery<LCRole> query = LCRole.GetQuery();
List<LCRole> list = await query.Find();
list.ForEach(item => {
TestContext.WriteLine($"{item.ObjectId} : {item.Name}");
Assert.NotNull(item.ObjectId);
Assert.NotNull(item.Name);
TestContext.WriteLine(item.Roles.GetType());
TestContext.WriteLine(item.Users.GetType());
Assert.IsTrue(item.Roles is LCRelation<LCRole>);
Assert.IsTrue(item.Users is LCRelation<LCUser>);
});
}
}
}

View File

@ -63,7 +63,7 @@ namespace LeanCloud.Storage.Internal.Codec {
static LCRelation<LCObject> DecodeRelation(IDictionary dict) {
LCRelation<LCObject> relation = new LCRelation<LCObject>();
relation.targetClass = dict["className"].ToString();
relation.TargetClass = dict["className"].ToString();
return relation;
}

View File

@ -100,7 +100,7 @@ namespace LeanCloud.Storage.Internal.Codec {
static object EncodeRelation(LCRelation<LCObject> relation) {
return new Dictionary<string, object> {
{ "__type", "Relation" },
{ "className", relation.targetClass }
{ "className", relation.TargetClass }
};
}

View File

@ -32,7 +32,7 @@ namespace LeanCloud.Storage.Internal.Operation {
public object Apply(object oldValue, string key) {
LCRelation<LCObject> relation = new LCRelation<LCObject>();
relation.targetClass = valueList[0].ClassName;
relation.TargetClass = valueList[0].ClassName;
return relation;
}

View File

@ -31,7 +31,7 @@ namespace LeanCloud.Storage.Internal.Operation {
public object Apply(object oldValue, string key) {
LCRelation<LCObject> relation = new LCRelation<LCObject>();
relation.targetClass = valueList[0].ClassName;
relation.TargetClass = valueList[0].ClassName;
return relation;
}

View File

@ -140,6 +140,28 @@ namespace LeanCloud.Storage {
ApplyOperation(key, deleteOp);
}
public void AddRelation(string key, LCObject value) {
if (string.IsNullOrEmpty(key)) {
throw new ArgumentNullException(nameof(key));
}
if (value == null) {
throw new ArgumentNullException(nameof(value));
}
LCAddRelationOperation op = new LCAddRelationOperation(new List<LCObject> { value });
ApplyOperation(key, op);
}
public void RemoveRelation(string key, LCObject value) {
if (string.IsNullOrEmpty(key)) {
throw new ArgumentNullException(nameof(key));
}
if (value == null) {
throw new ArgumentNullException(nameof(value));
}
LCRemoveRelationOperation op = new LCRemoveRelationOperation(value);
ApplyOperation(key, op);
}
static async Task SaveBatches(Stack<LCBatch> batches) {
while (batches.Count > 0) {
LCBatch batch = batches.Pop();

View File

@ -1,20 +1,41 @@
using System;
/// <summary>
/// 关系类
/// </summary>
namespace LeanCloud.Storage {
public class LCRelation<T> where T : LCObject {
/// <summary>
/// 字段名
/// </summary>
public string Key {
get; set;
}
/// <summary>
/// 父对象
/// </summary>
public LCObject Parent {
get; set;
}
public string targetClass {
/// <summary>
/// 关联类型名
/// </summary>
public string TargetClass {
get; set;
}
public LCRelation() {
}
/// <summary>
/// 获取 Relation 的查询对象
/// </summary>
public LCQuery<T> Query {
get {
LCQuery<T> query = new LCQuery<T>(TargetClass);
query.WhereRelatedTo(Parent, Key);
return query;
}
}
}
}

View File

@ -1,10 +1,64 @@
using System;
namespace LeanCloud.Storage {
namespace LeanCloud.Storage {
/// <summary>
/// 角色
/// </summary>
public class LCRole : LCObject {
public const string CLASS_NAME = "_Role";
/// <summary>
/// 名字
/// </summary>
public string Name {
get {
return this["name"] as string;
} set {
this["name"] = value;
}
}
/// <summary>
/// 关联角色
/// </summary>
public LCRelation<LCRole> Roles {
get {
LCRelation<LCObject> roles = this["roles"] as LCRelation<LCObject>;
return new LCRelation<LCRole> {
Parent = roles.Parent,
Key = "roles"
};
}
}
/// <summary>
/// 关联用户
/// </summary>
public LCRelation<LCUser> Users {
get {
LCRelation<LCObject> users = this["users"] as LCRelation<LCObject>;
return new LCRelation<LCUser> {
Parent = users.Parent,
Key = "users"
};
}
}
public LCRole() : base(CLASS_NAME) {
}
public static LCRole Create(string name, LCACL acl) {
LCRole role = new LCRole() {
Name = name,
ACL = acl
};
return role;
}
/// <summary>
/// 获取角色查询对象
/// </summary>
/// <returns></returns>
public static LCQuery<LCRole> GetQuery() {
return new LCQuery<LCRole>(CLASS_NAME);
}
}
}