* 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.Net.Http;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
|
|
||||||
namespace LeanCloudTests {
|
namespace LeanCloudTests {
|
||||||
public class ObjectTests {
|
public class ObjectTests {
|
||||||
|
@ -12,6 +11,7 @@ namespace LeanCloudTests {
|
||||||
AVClient.Initialize(new AVClient.Configuration {
|
AVClient.Initialize(new AVClient.Configuration {
|
||||||
ApplicationId = "BMYV4RKSTwo8WSqt8q9ezcWF-gzGzoHsz",
|
ApplicationId = "BMYV4RKSTwo8WSqt8q9ezcWF-gzGzoHsz",
|
||||||
ApplicationKey = "pbf6Nk5seyjilexdpyrPwjSp",
|
ApplicationKey = "pbf6Nk5seyjilexdpyrPwjSp",
|
||||||
|
ApiServer = "https://avoscloud.com",
|
||||||
RTMServer = "https://router-g0-push.avoscloud.com",
|
RTMServer = "https://router-g0-push.avoscloud.com",
|
||||||
});
|
});
|
||||||
AVClient.HttpLog(TestContext.Out.WriteLine);
|
AVClient.HttpLog(TestContext.Out.WriteLine);
|
||||||
|
@ -54,5 +54,19 @@ namespace LeanCloudTests {
|
||||||
Assert.Pass();
|
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("111111", "222222");
|
||||||
await user.UpdatePasswordAsync("222222", "111111");
|
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 {
|
namespace LeanCloud.Storage.Internal {
|
||||||
public class AVCloudCodeController {
|
public class AVCloudCodeController {
|
||||||
public Task<T> CallFunctionAsync<T>(String name,
|
public Task<T> CallFunctionAsync<T>(string name,
|
||||||
IDictionary<string, object> parameters,
|
IDictionary<string, object> parameters,
|
||||||
string sessionToken,
|
string sessionToken,
|
||||||
CancellationToken cancellationToken) {
|
CancellationToken cancellationToken) {
|
||||||
|
@ -19,7 +19,7 @@ namespace LeanCloud.Storage.Internal {
|
||||||
return AVPlugins.Instance.CommandRunner.RunCommandAsync<IDictionary<string, object>>(command, cancellationToken: cancellationToken).OnSuccess(t => {
|
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>;
|
var decoded = AVDecoder.Instance.Decode(t.Result.Item2) as IDictionary<string, object>;
|
||||||
if (!decoded.ContainsKey("result")) {
|
if (!decoded.ContainsKey("result")) {
|
||||||
return default(T);
|
return default;
|
||||||
}
|
}
|
||||||
return Conversion.To<T>(decoded["result"]);
|
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 => {
|
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>;
|
var decoded = AVDecoder.Instance.Decode(t.Result.Item2) as IDictionary<string, object>;
|
||||||
if (!decoded.ContainsKey("result")) {
|
if (!decoded.ContainsKey("result")) {
|
||||||
return default(T);
|
return default;
|
||||||
}
|
}
|
||||||
return Conversion.To<T>(decoded["result"]);
|
return Conversion.To<T>(decoded["result"]);
|
||||||
});
|
});
|
||||||
|
|
|
@ -75,7 +75,7 @@ namespace LeanCloud.Storage.Internal
|
||||||
private const byte S42 = 10;
|
private const byte S42 = 10;
|
||||||
private const byte S43 = 15;
|
private const byte S43 = 15;
|
||||||
private const byte S44 = 21;
|
private const byte S44 = 21;
|
||||||
static private byte[] PADDING = new byte[] {
|
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,
|
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, 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
|
||||||
|
|
|
@ -570,7 +570,7 @@ string propertyName
|
||||||
// Get the JSON representation of the object.
|
// Get the JSON representation of the object.
|
||||||
currentOperations = StartSave();
|
currentOperations = StartSave();
|
||||||
|
|
||||||
sessionToken = AVUser.CurrentUser.SessionToken;
|
sessionToken = AVUser.CurrentUser?.SessionToken;
|
||||||
|
|
||||||
deepSaveTask = DeepSaveAsync(estimatedData, sessionToken, cancellationToken);
|
deepSaveTask = DeepSaveAsync(estimatedData, sessionToken, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
|
@ -654,10 +654,13 @@ namespace LeanCloud
|
||||||
|
|
||||||
internal AVQuery<T> WhereRelatedTo(AVObject parent, string key) {
|
internal AVQuery<T> WhereRelatedTo(AVObject parent, string key) {
|
||||||
MergeWhereClauses(new Dictionary<string, object> {
|
MergeWhereClauses(new Dictionary<string, object> {
|
||||||
{ key, new Dictionary<string, object>{ { "$relatedTo", new Dictionary<string, object> {
|
{
|
||||||
{ "object", parent},
|
"$relatedTo",
|
||||||
{ "key", key}
|
new Dictionary<string, object> {
|
||||||
} } } }
|
{ "object", parent },
|
||||||
|
{ "key", key }
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -269,96 +269,6 @@ namespace LeanCloud {
|
||||||
|
|
||||||
#endregion
|
#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 手机号登录
|
#region 手机号登录
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -430,6 +340,77 @@ namespace LeanCloud {
|
||||||
|
|
||||||
#endregion
|
#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 重置密码
|
#region 重置密码
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -552,7 +533,7 @@ namespace LeanCloud {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 关注某个用户
|
/// 关注某个用户
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="userObjectId">被关注的用户Id</param>
|
/// <param name="userObjectId">被关注的用户 Id</param>
|
||||||
/// <param name="data">关注的时候附加属性</param>
|
/// <param name="data">关注的时候附加属性</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public Task FollowAsync(string userObjectId, IDictionary<string, object> data) {
|
public Task FollowAsync(string userObjectId, IDictionary<string, object> data) {
|
||||||
|
@ -570,7 +551,7 @@ namespace LeanCloud {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 取关某一个用户
|
/// 取关某一个用户
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="userObjectId"></param>
|
/// <param name="userObjectId">用户 Id</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public Task UnfollowAsync(string userObjectId) {
|
public Task UnfollowAsync(string userObjectId) {
|
||||||
var command = new AVCommand {
|
var command = new AVCommand {
|
||||||
|
@ -631,6 +612,28 @@ namespace LeanCloud {
|
||||||
|
|
||||||
#endregion
|
#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) {
|
internal static async Task<AVUser> LogInWithParametersAsync(Dictionary<string, object> strs) {
|
||||||
IObjectState ret = await UserController.LogInWithParametersAsync("login", strs);
|
IObjectState ret = await UserController.LogInWithParametersAsync("login", strs);
|
||||||
|
|
Loading…
Reference in New Issue