* ObjectTest.cs: chore: 整理 AVUser 接口,并编写简单测试用例。
* UserTest.cs: * AVUser.cs: * AVQuery.cs: * AVObject.cs: * MD5.cs: * AVCloudCodeController.cs:
parent
3786595bf1
commit
6969884bd9
|
@ -3,7 +3,6 @@ using LeanCloud;
|
|||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace LeanCloudTests {
|
||||
public class ObjectTests {
|
||||
|
@ -12,6 +11,7 @@ namespace LeanCloudTests {
|
|||
AVClient.Initialize(new AVClient.Configuration {
|
||||
ApplicationId = "BMYV4RKSTwo8WSqt8q9ezcWF-gzGzoHsz",
|
||||
ApplicationKey = "pbf6Nk5seyjilexdpyrPwjSp",
|
||||
ApiServer = "https://avoscloud.com",
|
||||
RTMServer = "https://router-g0-push.avoscloud.com",
|
||||
});
|
||||
AVClient.HttpLog(TestContext.Out.WriteLine);
|
||||
|
@ -54,5 +54,19 @@ namespace LeanCloudTests {
|
|||
Assert.Pass();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestMassiveRequest() {
|
||||
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(_ => {
|
||||
TestContext.Out.WriteLine($"{obj.ObjectId} saved");
|
||||
});
|
||||
}
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -70,5 +70,45 @@ namespace LeanCloudTests {
|
|||
await user.UpdatePasswordAsync("111111", "222222");
|
||||
await user.UpdatePasswordAsync("222222", "111111");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task LoginWithAuthData() {
|
||||
AVUser user = await AVUser.LogInWithAuthDataAsync(new Dictionary<string, object> {
|
||||
{ "openid", "0395BA18A5CD6255E5BA185E7BEBA242" },
|
||||
{ "access_token", "12345678-SaMpLeTuo3m2avZxh5cjJmIrAfx4ZYyamdofM7IjU" },
|
||||
{ "expires_in", 1382686496 }
|
||||
}, "qq");
|
||||
Assert.NotNull(user.SessionToken);
|
||||
TestContext.Out.WriteLine(user.SessionToken);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task AssociateAuthData() {
|
||||
AVUser user = await AVUser.LogInAsync("111111", "111111");
|
||||
Assert.NotNull(user.SessionToken);
|
||||
await user.AssociateAuthDataAsync(new Dictionary<string, object> {
|
||||
{ "openid", "0395BA18A5CD6255E5BA185E7BEBA243" },
|
||||
{ "access_token", "12345678-SaMpLeTuo3m2avZxh5cjJmIrAfx4ZYyamdofM7IjU" },
|
||||
{ "expires_in", 1382686496 }
|
||||
}, "qq");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Anonymously() {
|
||||
AVUser user = await AVUser.LogInAnonymouslyAsync();
|
||||
Assert.NotNull(user.SessionToken);
|
||||
TestContext.Out.WriteLine(user.SessionToken);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetRoles() {
|
||||
AVUser user = await AVUser.LogInAsync("111111", "111111");
|
||||
Assert.NotNull(user.SessionToken);
|
||||
IEnumerable<AVRole> roles = await user.GetRolesAsync();
|
||||
Assert.Greater(roles.Count(), 0);
|
||||
foreach (AVRole role in roles) {
|
||||
TestContext.Out.WriteLine(role.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ using System.Net.Http;
|
|||
|
||||
namespace LeanCloud.Storage.Internal {
|
||||
public class AVCloudCodeController {
|
||||
public Task<T> CallFunctionAsync<T>(String name,
|
||||
public Task<T> CallFunctionAsync<T>(string name,
|
||||
IDictionary<string, object> parameters,
|
||||
string sessionToken,
|
||||
CancellationToken cancellationToken) {
|
||||
|
@ -19,7 +19,7 @@ namespace LeanCloud.Storage.Internal {
|
|||
return AVPlugins.Instance.CommandRunner.RunCommandAsync<IDictionary<string, object>>(command, cancellationToken: cancellationToken).OnSuccess(t => {
|
||||
var decoded = AVDecoder.Instance.Decode(t.Result.Item2) as IDictionary<string, object>;
|
||||
if (!decoded.ContainsKey("result")) {
|
||||
return default(T);
|
||||
return default;
|
||||
}
|
||||
return Conversion.To<T>(decoded["result"]);
|
||||
});
|
||||
|
@ -34,7 +34,7 @@ namespace LeanCloud.Storage.Internal {
|
|||
return AVPlugins.Instance.CommandRunner.RunCommandAsync<IDictionary<string, object>>(command, cancellationToken: cancellationToken).OnSuccess(t => {
|
||||
var decoded = AVDecoder.Instance.Decode(t.Result.Item2) as IDictionary<string, object>;
|
||||
if (!decoded.ContainsKey("result")) {
|
||||
return default(T);
|
||||
return default;
|
||||
}
|
||||
return Conversion.To<T>(decoded["result"]);
|
||||
});
|
||||
|
|
|
@ -75,11 +75,11 @@ namespace LeanCloud.Storage.Internal
|
|||
private const byte S42 = 10;
|
||||
private const byte S43 = 15;
|
||||
private const byte S44 = 21;
|
||||
static private byte[] PADDING = new byte[] {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
private static readonly byte[] PADDING = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
#endregion
|
||||
|
||||
#region F, G, H and I are basic MD5 functions.
|
||||
|
|
|
@ -570,7 +570,7 @@ string propertyName
|
|||
// Get the JSON representation of the object.
|
||||
currentOperations = StartSave();
|
||||
|
||||
sessionToken = AVUser.CurrentUser.SessionToken;
|
||||
sessionToken = AVUser.CurrentUser?.SessionToken;
|
||||
|
||||
deepSaveTask = DeepSaveAsync(estimatedData, sessionToken, cancellationToken);
|
||||
}
|
||||
|
|
|
@ -654,10 +654,13 @@ namespace LeanCloud
|
|||
|
||||
internal AVQuery<T> WhereRelatedTo(AVObject parent, string key) {
|
||||
MergeWhereClauses(new Dictionary<string, object> {
|
||||
{ key, new Dictionary<string, object>{ { "$relatedTo", new Dictionary<string, object> {
|
||||
{ "object", parent},
|
||||
{ "key", key}
|
||||
} } } }
|
||||
{
|
||||
"$relatedTo",
|
||||
new Dictionary<string, object> {
|
||||
{ "object", parent },
|
||||
{ "key", key }
|
||||
}
|
||||
}
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -269,96 +269,6 @@ namespace LeanCloud {
|
|||
|
||||
#endregion
|
||||
|
||||
|
||||
#region 第三方登录
|
||||
|
||||
/// <summary>
|
||||
/// 使用第三方数据注册;如果已经存在相同的 Auth Data,则执行登录
|
||||
/// </summary>
|
||||
/// <param name="authData">Auth Data</param>
|
||||
/// <param name="platform">平台</param>
|
||||
/// <param name="options"></param>
|
||||
/// <returns></returns>
|
||||
public static Task<AVUser> LogInWithAuthDataAsync(IDictionary<string, object> authData, string platform, AVUserAuthDataLogInOption options = null) {
|
||||
if (options == null) {
|
||||
options = new AVUserAuthDataLogInOption();
|
||||
}
|
||||
return LogInWithAsync(platform, authData, options.FailOnNotExist);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用第三方数据注册;
|
||||
/// </summary>
|
||||
/// <param name="authData">Auth data</param>
|
||||
/// <param name="platform">平台标识</param>
|
||||
/// <param name="unionId"></param>
|
||||
/// <param name="options"></param>
|
||||
/// <returns></returns>
|
||||
public static Task<AVUser> LogInWithAuthDataAndUnionIdAsync(IDictionary<string, object> authData, string platform, string unionId,
|
||||
AVUserAuthDataLogInOption options = null) {
|
||||
if (options == null) {
|
||||
options = new AVUserAuthDataLogInOption();
|
||||
}
|
||||
MergeAuthData(authData, unionId, options);
|
||||
return LogInWithAsync(platform, authData, options.FailOnNotExist);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 绑定第三方登录
|
||||
/// </summary>
|
||||
/// <param name="authData">Auth data</param>
|
||||
/// <param name="platform">平台标识</param>
|
||||
/// <returns></returns>
|
||||
public Task AssociateAuthDataAsync(IDictionary<string, object> authData, string platform) {
|
||||
return LinkWithAsync(platform, authData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 绑定第三方登录
|
||||
/// </summary>
|
||||
/// <param name="authData">OAuth data</param>
|
||||
/// <param name="platform">平台标识</param>
|
||||
/// <param name="unionId"></param>
|
||||
/// <param name="options"></param>
|
||||
/// <returns></returns>
|
||||
public Task AssociateAuthDataAndUnionIdAsync(IDictionary<string, object> authData, string platform, string unionId,
|
||||
AVUserAuthDataLogInOption options = null) {
|
||||
if (options == null) {
|
||||
options = new AVUserAuthDataLogInOption();
|
||||
}
|
||||
MergeAuthData(authData, unionId, options);
|
||||
return LinkWithAsync(platform, authData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 解绑第三方登录
|
||||
/// </summary>
|
||||
/// <param name="platform">平台标识</param>
|
||||
/// <returns></returns>
|
||||
public Task DisassociateWithAuthDataAsync(string platform) {
|
||||
return LinkWithAsync(platform, null);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
public Task LinkWithAsync(string authType, IDictionary<string, object> data) {
|
||||
AuthData = new Dictionary<string, IDictionary<string, object>> {
|
||||
[authType] = data
|
||||
};
|
||||
return SaveAsync();
|
||||
}
|
||||
|
||||
internal static async Task<AVUser> LogInWithAsync(string authType, IDictionary<string, object> data, bool failOnNotExist) {
|
||||
var ret = await UserController.LogInAsync(authType, data, failOnNotExist);
|
||||
AVUser user = FromState<AVUser>(ret, "_User");
|
||||
user.AuthData = new Dictionary<string, IDictionary<string, object>> {
|
||||
[authType] = data
|
||||
};
|
||||
CurrentUser = user;
|
||||
return CurrentUser;
|
||||
}
|
||||
|
||||
#region 手机号登录
|
||||
|
||||
/// <summary>
|
||||
|
@ -430,6 +340,77 @@ namespace LeanCloud {
|
|||
|
||||
#endregion
|
||||
|
||||
#region 第三方登录
|
||||
|
||||
/// <summary>
|
||||
/// 使用第三方数据注册;如果已经存在相同的 Auth Data,则执行登录
|
||||
/// </summary>
|
||||
/// <param name="authData">Auth Data</param>
|
||||
/// <param name="platform">平台</param>
|
||||
/// <param name="options"></param>
|
||||
/// <returns></returns>
|
||||
public static Task<AVUser> LogInWithAuthDataAsync(IDictionary<string, object> authData, string platform, AVUserAuthDataLogInOption options = null) {
|
||||
if (options == null) {
|
||||
options = new AVUserAuthDataLogInOption();
|
||||
}
|
||||
return LogInWithAsync(platform, authData, options.FailOnNotExist);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用第三方数据注册;
|
||||
/// </summary>
|
||||
/// <param name="authData">Auth data</param>
|
||||
/// <param name="platform">平台标识</param>
|
||||
/// <param name="unionId"></param>
|
||||
/// <param name="options"></param>
|
||||
/// <returns></returns>
|
||||
public static Task<AVUser> LogInWithAuthDataAndUnionIdAsync(IDictionary<string, object> authData, string platform, string unionId,
|
||||
AVUserAuthDataLogInOption options = null) {
|
||||
if (options == null) {
|
||||
options = new AVUserAuthDataLogInOption();
|
||||
}
|
||||
MergeAuthData(authData, unionId, options);
|
||||
return LogInWithAsync(platform, authData, options.FailOnNotExist);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 绑定第三方登录
|
||||
/// </summary>
|
||||
/// <param name="authData">Auth data</param>
|
||||
/// <param name="platform">平台标识</param>
|
||||
/// <returns></returns>
|
||||
public Task AssociateAuthDataAsync(IDictionary<string, object> authData, string platform) {
|
||||
return LinkWithAuthDataAsync(platform, authData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 绑定第三方登录
|
||||
/// </summary>
|
||||
/// <param name="authData">Auth data</param>
|
||||
/// <param name="platform">平台标识</param>
|
||||
/// <param name="unionId"></param>
|
||||
/// <param name="options"></param>
|
||||
/// <returns></returns>
|
||||
public Task AssociateAuthDataAndUnionIdAsync(IDictionary<string, object> authData, string platform, string unionId,
|
||||
AVUserAuthDataLogInOption options = null) {
|
||||
if (options == null) {
|
||||
options = new AVUserAuthDataLogInOption();
|
||||
}
|
||||
MergeAuthData(authData, unionId, options);
|
||||
return LinkWithAuthDataAsync(platform, authData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 解绑第三方登录
|
||||
/// </summary>
|
||||
/// <param name="platform">平台标识</param>
|
||||
/// <returns></returns>
|
||||
public Task DisassociateWithAuthDataAsync(string platform) {
|
||||
return LinkWithAuthDataAsync(platform, null);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 重置密码
|
||||
|
||||
/// <summary>
|
||||
|
@ -552,7 +533,7 @@ namespace LeanCloud {
|
|||
/// <summary>
|
||||
/// 关注某个用户
|
||||
/// </summary>
|
||||
/// <param name="userObjectId">被关注的用户Id</param>
|
||||
/// <param name="userObjectId">被关注的用户 Id</param>
|
||||
/// <param name="data">关注的时候附加属性</param>
|
||||
/// <returns></returns>
|
||||
public Task FollowAsync(string userObjectId, IDictionary<string, object> data) {
|
||||
|
@ -570,7 +551,7 @@ namespace LeanCloud {
|
|||
/// <summary>
|
||||
/// 取关某一个用户
|
||||
/// </summary>
|
||||
/// <param name="userObjectId"></param>
|
||||
/// <param name="userObjectId">用户 Id</param>
|
||||
/// <returns></returns>
|
||||
public Task UnfollowAsync(string userObjectId) {
|
||||
var command = new AVCommand {
|
||||
|
@ -631,6 +612,28 @@ namespace LeanCloud {
|
|||
|
||||
#endregion
|
||||
|
||||
public Task<IEnumerable<AVRole>> GetRolesAsync() {
|
||||
AVQuery<AVRole> query = new AVQuery<AVRole>();
|
||||
query.WhereRelatedTo(this, "users");
|
||||
return query.FindAsync();
|
||||
}
|
||||
|
||||
Task LinkWithAuthDataAsync(string authType, IDictionary<string, object> data) {
|
||||
AuthData = new Dictionary<string, IDictionary<string, object>> {
|
||||
[authType] = data
|
||||
};
|
||||
return SaveAsync();
|
||||
}
|
||||
|
||||
internal static async Task<AVUser> LogInWithAsync(string authType, IDictionary<string, object> data, bool failOnNotExist) {
|
||||
var ret = await UserController.LogInAsync(authType, data, failOnNotExist);
|
||||
AVUser user = FromState<AVUser>(ret, "_User");
|
||||
user.AuthData = new Dictionary<string, IDictionary<string, object>> {
|
||||
[authType] = data
|
||||
};
|
||||
CurrentUser = user;
|
||||
return CurrentUser;
|
||||
}
|
||||
|
||||
internal static async Task<AVUser> LogInWithParametersAsync(Dictionary<string, object> strs) {
|
||||
IObjectState ret = await UserController.LogInWithParametersAsync("login", strs);
|
||||
|
|
Loading…
Reference in New Issue