重构代码:重写WebHost基类,提高运行速度

This commit is contained in:
Argo-Surface 2019-01-18 01:10:19 +08:00
parent 2f4cb38d9b
commit f2ff717f29
11 changed files with 272 additions and 274 deletions

View File

@ -1,18 +0,0 @@
using System.Net.Http;
using Xunit;
namespace Bootstrap.Admin.Api
{
public class ApiWebHost : IClassFixture<BAWebHost>
{
protected HttpClient Client { get; }
public ApiWebHost(BAWebHost factory, bool login)
{
factory.ClientOptions.BaseAddress = new System.Uri($"http://localhost/api/");
Client = factory.CreateClient();
if (login) factory.LoginAsync(Client).GetAwaiter().GetResult();
}
}
}

View File

@ -12,20 +12,23 @@ using static Bootstrap.Admin.Controllers.Api.ExceptionsController;
namespace Bootstrap.Admin.Api
{
public class ApiTest : ApiWebHost
public class ApiTest : IClassFixture<BAWebHost>
{
private BAWebHost _factory;
private HttpClient _client;
public ApiTest(BAWebHost factory) : base(factory, true)
protected BAWebHost _host;
public ApiTest(BAWebHost factory)
{
_factory = factory;
_host = factory;
_client = factory.CreateClient();
}
[Fact]
public async void Users_Option_Ok()
{
var req = new HttpRequestMessage(HttpMethod.Options, "Users");
var resp = await Client.SendAsync(req);
var resp = await _client.SendAsync(req);
}
[Fact]
@ -33,7 +36,7 @@ namespace Bootstrap.Admin.Api
{
// 菜单 系统菜单 系统使用条件
var query = "Users?sort=DisplayName&order=asc&offset=0&limit=20&name=Admin&displayName=Administrator&_=1547628247338";
var qd = await Client.GetAsJsonAsync<QueryData<object>>(query);
var qd = await _client.GetAsJsonAsync<QueryData<object>>(query);
Assert.Single(qd.rows);
}
@ -44,15 +47,15 @@ namespace Bootstrap.Admin.Api
user.Delete(user.Retrieves().Where(usr => usr.UserName == "UnitTest-Delete").Select(usr => usr.Id));
var nusr = new User { UserName = "UnitTest-Delete", Password = "1", DisplayName = "DisplayName", ApprovedBy = "System", ApprovedTime = DateTime.Now, Description = "Desc", Icon = "default.jpg" };
var resp = await Client.PostAsJsonAsync<User, bool>("Users", nusr);
var resp = await _client.PostAsJsonAsync<User, bool>("Users", nusr);
Assert.True(resp);
nusr.Id = user.Retrieves().First(u => u.UserName == nusr.UserName).Id;
resp = await Client.PostAsJsonAsync<User, bool>("Users", nusr);
resp = await _client.PostAsJsonAsync<User, bool>("Users", nusr);
Assert.True(resp);
var ids = user.Retrieves().Where(d => d.UserName == nusr.UserName).Select(d => d.Id);
Assert.True(await Client.DeleteAsJsonAsync<IEnumerable<string>, bool>("Users", ids));
Assert.True(await _client.DeleteAsJsonAsync<IEnumerable<string>, bool>("Users", ids));
}
[Fact]
@ -60,11 +63,11 @@ namespace Bootstrap.Admin.Api
{
var rid = new Role().Retrieves().Where(r => r.RoleName == "Administrators").First().Id;
var ret = await Client.PostAsJsonAsync<string, IEnumerable<object>>($"Users/{rid}?type=role", string.Empty);
var ret = await _client.PostAsJsonAsync<string, IEnumerable<object>>($"Users/{rid}?type=role", string.Empty);
Assert.NotNull(ret);
var gid = new Group().Retrieves().Where(r => r.GroupName == "Admin").First().Id;
ret = await Client.PostAsJsonAsync<string, IEnumerable<object>>($"Users/{gid}?type=group", string.Empty);
ret = await _client.PostAsJsonAsync<string, IEnumerable<object>>($"Users/{gid}?type=group", string.Empty);
Assert.NotNull(ret);
}
@ -73,11 +76,11 @@ namespace Bootstrap.Admin.Api
{
var ids = new User().Retrieves().Where(u => u.UserName == "Admin").Select(u => u.Id);
var gid = new Group().Retrieves().Where(r => r.GroupName == "Admin").First().Id;
var ret = await Client.PutAsJsonAsync<IEnumerable<string>, bool>($"Users/{gid}?type=group", ids);
var ret = await _client.PutAsJsonAsync<IEnumerable<string>, bool>($"Users/{gid}?type=group", ids);
Assert.True(ret);
var rid = new Role().Retrieves().Where(r => r.RoleName == "Administrators").First().Id;
ret = await Client.PutAsJsonAsync<IEnumerable<string>, bool>($"Users/{rid}?type=role", ids);
ret = await _client.PutAsJsonAsync<IEnumerable<string>, bool>($"Users/{rid}?type=role", ids);
Assert.True(ret);
}
@ -88,39 +91,44 @@ namespace Bootstrap.Admin.Api
usr.Delete(usr.Retrieves().Where(u => u.UserName == usr.UserName).Select(u => u.Id));
Assert.True(usr.Save(usr));
// Add author
DbManager.Create().Execute("delete from NavigationRole where RoleID in (select ID from Roles where RoleName = 'Default');insert into NavigationRole select ID, (select ID from Roles where RoleName = 'Default') from Navigations");
// change theme
usr.UserStatus = UserStates.ChangeTheme;
var resp = await Client.PutAsJsonAsync<User, bool>("Users", usr);
var resp = await _client.PutAsJsonAsync<User, bool>("Users", usr);
Assert.False(resp);
// Login as new user
await _factory.LoginAsync(Client, "UnitTest-Change", "1");
resp = await Client.PutAsJsonAsync<User, bool>("Users", usr);
_host.Logout();
_host.Login("UnitTest-Change", "1");
_client = _host.CreateClient();
resp = await _client.PutAsJsonAsync<User, bool>("Users", usr);
Assert.True(resp);
// change password
usr.UserStatus = UserStates.ChangePassword;
usr.NewPassword = "1";
usr.Password = "1";
resp = await Client.PutAsJsonAsync<User, bool>("Users", usr);
resp = await _client.PutAsJsonAsync<User, bool>("Users", usr);
Assert.True(resp);
// change displayname
usr.UserStatus = UserStates.ChangeDisplayName;
resp = await Client.PutAsJsonAsync<User, bool>("Users", usr);
resp = await _client.PutAsJsonAsync<User, bool>("Users", usr);
Assert.True(resp);
// delete
usr.Delete(new string[] { usr.Id });
usr.Delete(usr.Retrieves().Where(u => u.UserName == usr.UserName).Select(u => u.Id));
await _factory.LoginAsync(Client);
_host.Logout();
_host.Login();
}
[Fact]
public async void Category_Get_Ok()
{
var cates = await Client.GetAsJsonAsync<IEnumerable<string>>("Category");
var cates = await _client.GetAsJsonAsync<IEnumerable<string>>("Category");
Assert.NotEmpty(cates);
}
@ -129,7 +137,7 @@ namespace Bootstrap.Admin.Api
{
// 菜单 系统菜单 系统使用条件
var query = "Dicts?sort=Category&order=asc&offset=0&limit=20&category=%E8%8F%9C%E5%8D%95&name=%E7%B3%BB%E7%BB%9F%E8%8F%9C%E5%8D%95&define=0&_=1547608210979";
var qd = await Client.GetAsJsonAsync<QueryData<BootstrapDict>>(query);
var qd = await _client.GetAsJsonAsync<QueryData<BootstrapDict>>(query);
Assert.Single(qd.rows);
}
@ -139,11 +147,11 @@ namespace Bootstrap.Admin.Api
var dict = new Dict();
dict.Delete(new Dict().RetrieveDicts().Where(d => d.Category == "UnitTest-Category").Select(d => d.Id));
var ret = await Client.PostAsJsonAsync<BootstrapDict, bool>("Dicts", new BootstrapDict() { Name = "UnitTest-Dict", Category = "UnitTest-Category", Code = "0", Define = 0 });
var ret = await _client.PostAsJsonAsync<BootstrapDict, bool>("Dicts", new BootstrapDict() { Name = "UnitTest-Dict", Category = "UnitTest-Category", Code = "0", Define = 0 });
Assert.True(ret);
var ids = dict.RetrieveDicts().Where(d => d.Name == "UnitTest-Dict").Select(d => d.Id);
Assert.True(await Client.DeleteAsJsonAsync<IEnumerable<string>, bool>("Dicts", ids));
Assert.True(await _client.DeleteAsJsonAsync<IEnumerable<string>, bool>("Dicts", ids));
}
[Fact]
@ -155,7 +163,7 @@ namespace Bootstrap.Admin.Api
// 菜单 系统菜单 系统使用条件
var query = "Exceptions?sort=LogTime&order=desc&offset=0&limit=20&StartTime=&EndTime=&_=1547610349796";
var qd = await Client.GetAsJsonAsync<QueryData<BootstrapDict>>(query);
var qd = await _client.GetAsJsonAsync<QueryData<BootstrapDict>>(query);
Assert.NotEmpty(qd.rows);
// clean
@ -165,13 +173,13 @@ namespace Bootstrap.Admin.Api
[Fact]
public async void Exceptions_Post_Ok()
{
var files = await Client.PostAsJsonAsync<string, IEnumerable<string>>("Exceptions", string.Empty);
var files = await _client.PostAsJsonAsync<string, IEnumerable<string>>("Exceptions", string.Empty);
Assert.NotNull(files);
var fileName = files.FirstOrDefault();
if (!string.IsNullOrEmpty(fileName))
{
var resp = await Client.PutAsJsonAsync<ExceptionFileQuery, string>("Exceptions", new ExceptionFileQuery() { FileName = fileName });
var resp = await _client.PutAsJsonAsync<ExceptionFileQuery, string>("Exceptions", new ExceptionFileQuery() { FileName = fileName });
Assert.NotNull(resp);
}
@ -184,7 +192,7 @@ namespace Bootstrap.Admin.Api
{
// 菜单 系统菜单 系统使用条件
var query = "Groups?sort=GroupName&order=asc&offset=0&limit=20&groupName=Admin&description=%E7%B3%BB%E7%BB%9F%E9%BB%98%E8%AE%A4%E7%BB%84&_=1547614230481";
var qd = await Client.GetAsJsonAsync<QueryData<Group>>(query);
var qd = await _client.GetAsJsonAsync<QueryData<Group>>(query);
Assert.Single(qd.rows);
}
@ -192,29 +200,29 @@ namespace Bootstrap.Admin.Api
public async void Groups_GetById_Ok()
{
var id = new Group().Retrieves().Where(gp => gp.GroupName == "Admin").First().Id;
var g = await Client.GetAsJsonAsync<Group>($"Groups/{id}");
var g = await _client.GetAsJsonAsync<Group>($"Groups/{id}");
Assert.Equal("Admin", g.GroupName);
}
[Fact]
public async void Groups_PostAndDelete_Ok()
{
var ret = await Client.PostAsJsonAsync<Group, bool>("Groups", new Group() { GroupName = "UnitTest-Group", Description = "UnitTest-Desc" });
var ret = await _client.PostAsJsonAsync<Group, bool>("Groups", new Group() { GroupName = "UnitTest-Group", Description = "UnitTest-Desc" });
Assert.True(ret);
var ids = new Group().Retrieves().Where(d => d.GroupName == "UnitTest-Group").Select(d => d.Id);
Assert.True(await Client.DeleteAsJsonAsync<IEnumerable<string>, bool>("Groups", ids));
Assert.True(await _client.DeleteAsJsonAsync<IEnumerable<string>, bool>("Groups", ids));
}
[Fact]
public async void Groups_PostById_Ok()
{
var uid = new User().Retrieves().Where(u => u.UserName == "Admin").First().Id;
var ret = await Client.PostAsJsonAsync<string, IEnumerable<Group>>($"Groups/{uid}?type=user", string.Empty);
var ret = await _client.PostAsJsonAsync<string, IEnumerable<Group>>($"Groups/{uid}?type=user", string.Empty);
Assert.NotEmpty(ret);
var rid = new Role().Retrieves().Where(r => r.RoleName == "Administrators").First().Id;
ret = await Client.PostAsJsonAsync<string, IEnumerable<Group>>($"Groups/{rid}?type=role", string.Empty);
ret = await _client.PostAsJsonAsync<string, IEnumerable<Group>>($"Groups/{rid}?type=role", string.Empty);
Assert.NotEmpty(ret);
}
@ -223,53 +231,53 @@ namespace Bootstrap.Admin.Api
{
var ids = new Group().Retrieves().Select(g => g.Id);
var uid = new User().Retrieves().Where(u => u.UserName == "Admin").First().Id;
var ret = await Client.PutAsJsonAsync<IEnumerable<string>, bool>($"Groups/{uid}?type=user", ids);
var ret = await _client.PutAsJsonAsync<IEnumerable<string>, bool>($"Groups/{uid}?type=user", ids);
Assert.True(ret);
var rid = new Role().Retrieves().Where(r => r.RoleName == "Administrators").First().Id;
ret = await Client.PutAsJsonAsync<IEnumerable<string>, bool>($"Groups/{rid}?type=role", ids);
ret = await _client.PutAsJsonAsync<IEnumerable<string>, bool>($"Groups/{rid}?type=role", ids);
Assert.True(ret);
}
[Fact]
public async void Interface_RetrieveDicts_Ok()
{
var ret = await Client.PostAsJsonAsync<string, IEnumerable<BootstrapDict>>("Interface/RetrieveDicts", "");
var ret = await _client.PostAsJsonAsync<string, IEnumerable<BootstrapDict>>("Interface/RetrieveDicts", "");
Assert.NotEmpty(ret);
}
[Fact]
public async void Interface_RetrieveRolesByUrl_Ok()
{
var ret = await Client.PostAsJsonAsync<string, IEnumerable<string>>("Interface/RetrieveRolesByUrl", "~/Admin/Index");
var ret = await _client.PostAsJsonAsync<string, IEnumerable<string>>("Interface/RetrieveRolesByUrl", "~/Admin/Index");
Assert.NotEmpty(ret);
}
[Fact]
public async void Interface_RetrieveRolesByUserName_Ok()
{
var ret = await Client.PostAsJsonAsync<string, IEnumerable<string>>("Interface/RetrieveRolesByUserName", "Admin");
var ret = await _client.PostAsJsonAsync<string, IEnumerable<string>>("Interface/RetrieveRolesByUserName", "Admin");
Assert.NotEmpty(ret);
}
[Fact]
public async void Interface_RetrieveUserByUserName_Ok()
{
var ret = await Client.PostAsJsonAsync<string, BootstrapUser>("Interface/RetrieveUserByUserName", "Admin");
var ret = await _client.PostAsJsonAsync<string, BootstrapUser>("Interface/RetrieveUserByUserName", "Admin");
Assert.Equal("Admin", ret.UserName);
}
[Fact]
public async void Interface_RetrieveAppMenus_Ok()
{
var ret = await Client.PostAsJsonAsync<AppMenuOption, IEnumerable<BootstrapMenu>>("Interface/RetrieveAppMenus", new AppMenuOption() { AppId = "0", UserName = "Admin", Url = "~/Admin/Index" });
var ret = await _client.PostAsJsonAsync<AppMenuOption, IEnumerable<BootstrapMenu>>("Interface/RetrieveAppMenus", new AppMenuOption() { AppId = "0", UserName = "Admin", Url = "~/Admin/Index" });
Assert.NotEmpty(ret);
}
[Fact]
public async void Login_Login_Ok()
{
var resq = await Client.PostAsJsonAsync("Login", new { userName = "Admin", password = "123789" });
var resq = await _client.PostAsJsonAsync("Login", new { userName = "Admin", password = "123789" });
var _token = await resq.Content.ReadAsStringAsync();
Assert.NotNull(_token);
}
@ -278,22 +286,28 @@ namespace Bootstrap.Admin.Api
public async void Login_Option_Ok()
{
var req = new HttpRequestMessage(HttpMethod.Options, "Login");
var resp = await Client.SendAsync(req);
var resp = await _client.SendAsync(req);
}
[Fact]
public async void Logs_Get_Ok()
{
var log = new Log() { CRUD = "UnitTest", ClientAgent = "UnitTest", ClientIp = "::1", RequestUrl = "~/UnitTest", UserName = "UnitTest" };
log.Save(log);
// 菜单 系统菜单 系统使用条件
var query = "Logs?sort=LogTime&order=desc&offset=0&limit=20&operateType=&OperateTimeStart=&OperateTimeEnd=&_=1547617573596";
var qd = await Client.GetAsJsonAsync<QueryData<Log>>(query);
var qd = await _client.GetAsJsonAsync<QueryData<Log>>(query);
Assert.NotEmpty(qd.rows);
// clean
DbManager.Create().Execute("Delete from Logs where CRUD = @0", log.CRUD);
}
[Fact]
public async void Logs_Post_Ok()
{
Client.DefaultRequestHeaders.Add("user-agent", "UnitTest");
var resp = await Client.PostAsJsonAsync<Log, bool>("Logs", new Log() { CRUD = "UnitTest", RequestUrl = "~/UnitTest" });
_client.DefaultRequestHeaders.Add("user-agent", "UnitTest");
var resp = await _client.PostAsJsonAsync<Log, bool>("Logs", new Log() { CRUD = "UnitTest", RequestUrl = "~/UnitTest" });
Assert.True(resp);
// clean
@ -305,19 +319,19 @@ namespace Bootstrap.Admin.Api
{
// 菜单 系统菜单 系统使用条件
var query = "Menus?sort=Order&order=asc&offset=0&limit=20&parentName=&name=%E5%90%8E%E5%8F%B0%E7%AE%A1%E7%90%86&category=0&isresource=0&_=1547619684999";
var qd = await Client.GetAsJsonAsync<QueryData<object>>(query);
var qd = await _client.GetAsJsonAsync<QueryData<object>>(query);
Assert.Single(qd.rows);
}
[Fact]
public async void Menus_PostAndDelete_Ok()
{
var ret = await Client.PostAsJsonAsync<BootstrapMenu, bool>("Menus", new BootstrapMenu() { Name = "UnitTest-Menu", Application = "0", Category = "0", ParentId = "0", Url = "#", Target = "_self", IsResource = 0 });
var ret = await _client.PostAsJsonAsync<BootstrapMenu, bool>("Menus", new BootstrapMenu() { Name = "UnitTest-Menu", Application = "0", Category = "0", ParentId = "0", Url = "#", Target = "_self", IsResource = 0 });
Assert.True(ret);
var menu = new Menu();
var ids = menu.RetrieveAllMenus("Admin").Where(d => d.Name == "UnitTest-Menu").Select(d => d.Id);
Assert.True(await Client.DeleteAsJsonAsync<IEnumerable<string>, bool>("Menus", ids));
Assert.True(await _client.DeleteAsJsonAsync<IEnumerable<string>, bool>("Menus", ids));
}
@ -325,11 +339,11 @@ namespace Bootstrap.Admin.Api
public async void Menus_PostById_Ok()
{
var uid = new User().Retrieves().Where(u => u.UserName == "Admin").First().Id;
var ret = await Client.PostAsJsonAsync<string, IEnumerable<object>>($"Menus/{uid}?type=user", string.Empty);
var ret = await _client.PostAsJsonAsync<string, IEnumerable<object>>($"Menus/{uid}?type=user", string.Empty);
Assert.NotEmpty(ret);
var rid = new Role().Retrieves().Where(r => r.RoleName == "Administrators").First().Id;
ret = await Client.PostAsJsonAsync<string, IEnumerable<object>>($"Menus/{rid}?type=role", string.Empty);
ret = await _client.PostAsJsonAsync<string, IEnumerable<object>>($"Menus/{rid}?type=role", string.Empty);
Assert.NotEmpty(ret);
}
@ -338,7 +352,7 @@ namespace Bootstrap.Admin.Api
{
var ids = new Menu().RetrieveAllMenus("Admin").Select(g => g.Id);
var rid = new Role().Retrieves().Where(r => r.RoleName == "Administrators").First().Id;
var ret = await Client.PutAsJsonAsync<IEnumerable<string>, bool>($"Menus/{rid}", ids);
var ret = await _client.PutAsJsonAsync<IEnumerable<string>, bool>($"Menus/{rid}", ids);
Assert.True(ret);
}
@ -349,14 +363,14 @@ namespace Bootstrap.Admin.Api
[InlineData("trash")]
public async void Messages_Get_Ok(string action)
{
var resp = await Client.GetAsJsonAsync<IEnumerable<Message>>($"Messages/{action}");
var resp = await _client.GetAsJsonAsync<IEnumerable<Message>>($"Messages/{action}");
Assert.NotNull(resp);
}
[Fact]
public async void Messages_GetCount_Ok()
{
var resp = await Client.GetAsJsonAsync<MessageCountModel>("Messages");
var resp = await _client.GetAsJsonAsync<MessageCountModel>("Messages");
Assert.NotNull(resp);
}
@ -365,11 +379,11 @@ namespace Bootstrap.Admin.Api
{
var nusr = InsertNewUser();
var resp = await Client.GetAsJsonAsync<IEnumerable<object>>("New");
var resp = await _client.GetAsJsonAsync<IEnumerable<object>>("New");
Assert.NotEmpty(resp);
// 删除新用户
nusr.Delete(nusr.Retrieves().Where(u => u.UserName == nusr.UserName).Select(u => u.Id));
DeleteUnitTestUser();
}
[Fact]
@ -380,7 +394,7 @@ namespace Bootstrap.Admin.Api
// Approve
nusr.UserStatus = UserStates.ApproveUser;
var resp = await Client.PutAsJsonAsync<User, bool>("New", nusr);
var resp = await _client.PutAsJsonAsync<User, bool>("New", nusr);
Assert.True(resp);
// 删除新用户
@ -389,11 +403,11 @@ namespace Bootstrap.Admin.Api
// Reject
nusr = InsertNewUser();
nusr.UserStatus = UserStates.RejectUser;
resp = await Client.PutAsJsonAsync<User, bool>("New", nusr);
resp = await _client.PutAsJsonAsync<User, bool>("New", nusr);
Assert.True(resp);
// 删除新用户
nusr.Delete(new string[] { nusr.Id });
DeleteUnitTestUser();
}
private User InsertNewUser()
@ -413,14 +427,14 @@ namespace Bootstrap.Admin.Api
[Fact]
public async void Notifications_Get_Ok()
{
var resp = await Client.GetAsJsonAsync<object>("Notifications");
var resp = await _client.GetAsJsonAsync<object>("Notifications");
Assert.NotNull(resp);
}
[Fact]
public async void Register_Get_Ok()
{
var resp = await Client.GetAsJsonAsync<bool>("Register?userName=Admin");
var resp = await _client.GetAsJsonAsync<bool>("Register?userName=Admin");
Assert.False(resp);
}
@ -429,7 +443,7 @@ namespace Bootstrap.Admin.Api
{
// register new user
var nusr = new User() { UserName = "UnitTest-RegisterController", DisplayName = "UnitTest", Password = "1", Description = "UnitTest" };
var resp = await Client.PostAsJsonAsync<User, bool>("Register", nusr);
var resp = await _client.PostAsJsonAsync<User, bool>("Register", nusr);
Assert.True(resp);
nusr.Delete(nusr.RetrieveNewUsers().Where(u => u.UserName == nusr.UserName).Select(u => u.Id));
@ -440,18 +454,18 @@ namespace Bootstrap.Admin.Api
{
// 菜单 系统菜单 系统使用条件
var query = "Roles?sort=RoleName&order=asc&offset=0&limit=20&roleName=Administrators&description=%E7%B3%BB%E7%BB%9F%E7%AE%A1%E7%90%86%E5%91%98&_=1547625202230";
var qd = await Client.GetAsJsonAsync<QueryData<Group>>(query);
var qd = await _client.GetAsJsonAsync<QueryData<Group>>(query);
Assert.Single(qd.rows);
}
[Fact]
public async void Roles_PostAndDelete_Ok()
{
var ret = await Client.PostAsJsonAsync<Role, bool>("Roles", new Role() { RoleName = "UnitTest-Role", Description = "UnitTest-Desc" });
var ret = await _client.PostAsJsonAsync<Role, bool>("Roles", new Role() { RoleName = "UnitTest-Role", Description = "UnitTest-Desc" });
Assert.True(ret);
var ids = new Role().Retrieves().Where(d => d.RoleName == "UnitTest-Role").Select(d => d.Id);
Assert.True(await Client.DeleteAsJsonAsync<IEnumerable<string>, bool>("Roles", ids));
Assert.True(await _client.DeleteAsJsonAsync<IEnumerable<string>, bool>("Roles", ids));
}
[Fact]
@ -461,13 +475,13 @@ namespace Bootstrap.Admin.Api
var gid = new Group().Retrieves().Where(g => g.GroupName == "Admin").First().Id;
var mid = new Menu().RetrieveAllMenus("Admin").Where(m => m.Url == "~/Admin/Index").First().Id;
var ret = await Client.PostAsJsonAsync<string, IEnumerable<object>>($"Roles/{uid}?type=user", string.Empty);
var ret = await _client.PostAsJsonAsync<string, IEnumerable<object>>($"Roles/{uid}?type=user", string.Empty);
Assert.NotEmpty(ret);
ret = await Client.PostAsJsonAsync<string, IEnumerable<object>>($"Roles/{gid}?type=group", string.Empty);
ret = await _client.PostAsJsonAsync<string, IEnumerable<object>>($"Roles/{gid}?type=group", string.Empty);
Assert.NotEmpty(ret);
ret = await Client.PostAsJsonAsync<string, IEnumerable<object>>($"Roles/{mid}?type=menu", string.Empty);
ret = await _client.PostAsJsonAsync<string, IEnumerable<object>>($"Roles/{mid}?type=menu", string.Empty);
Assert.NotEmpty(ret);
}
@ -479,20 +493,20 @@ namespace Bootstrap.Admin.Api
var mid = new Menu().RetrieveAllMenus("Admin").Where(m => m.Url == "~/Admin/Index").First().Id;
var ids = new Role().Retrieves().Select(r => r.Id);
var ret = await Client.PutAsJsonAsync<IEnumerable<string>, bool>($"Roles/{uid}?type=user", ids);
var ret = await _client.PutAsJsonAsync<IEnumerable<string>, bool>($"Roles/{uid}?type=user", ids);
Assert.True(ret);
ret = await Client.PutAsJsonAsync<IEnumerable<string>, bool>($"Roles/{gid}?type=group", ids);
ret = await _client.PutAsJsonAsync<IEnumerable<string>, bool>($"Roles/{gid}?type=group", ids);
Assert.True(ret);
ret = await Client.PutAsJsonAsync<IEnumerable<string>, bool>($"Roles/{mid}?type=menu", ids);
ret = await _client.PutAsJsonAsync<IEnumerable<string>, bool>($"Roles/{mid}?type=menu", ids);
Assert.True(ret);
}
[Fact]
public async void Settings_Get_Ok()
{
var resp = await Client.GetAsJsonAsync<IEnumerable<ICacheCorsItem>>("Settings");
var resp = await _client.GetAsJsonAsync<IEnumerable<ICacheCorsItem>>("Settings");
Assert.NotNull(resp);
}
@ -508,7 +522,7 @@ namespace Bootstrap.Admin.Api
Assert.True(dict.Save(new Dict() { Category = "UnitTest-Settings", Name = "UnitTest", Code = "0", Define = 0 }));
// 获得原来值
var resp = await Client.PostAsJsonAsync<BootstrapDict, bool>("Settings", new Dict() { Category = "UnitTest-Settings", Name = "UnitTest", Code = "UnitTest" });
var resp = await _client.PostAsJsonAsync<BootstrapDict, bool>("Settings", new Dict() { Category = "UnitTest-Settings", Name = "UnitTest", Code = "UnitTest" });
Assert.True(resp);
var code = dict.RetrieveDicts().FirstOrDefault(d => d.Category == "UnitTest-Settings").Code;
@ -522,7 +536,7 @@ namespace Bootstrap.Admin.Api
[Fact]
public async void Tasks_Get_Ok()
{
var resp = await Client.GetAsJsonAsync<IEnumerable<Task>>("Tasks");
var resp = await _client.GetAsJsonAsync<IEnumerable<Task>>("Tasks");
Assert.NotNull(resp);
}
}

View File

@ -1,6 +1,11 @@
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.AspNetCore.Mvc.Testing.Handlers;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using UnitTest;
namespace Bootstrap.Admin
@ -13,17 +18,50 @@ namespace Bootstrap.Admin
/// <summary>
///
/// </summary>
public BAWebHost()
static BAWebHost()
{
// Copy license
TestHelper.CopyLicense();
}
public async Task<string> LoginAsync(HttpClient client, string userName = "Admin", string password = "123789")
public BAWebHost()
{
var r = await client.GetAsync("/Account/Logout");
var view = await r.Content.ReadAsStringAsync();
Login();
}
public new HttpClient CreateClient() => CreateClient("http://localhost/api/");
public HttpClient CreateClient(string baseAddress)
{
var client = CreateDefaultClient(new RedirectHandler(7), new CookieContainerHandler(cookie));
client.BaseAddress = new Uri(baseAddress);
return client;
}
private CookieContainer cookie = new CookieContainer();
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
base.ConfigureWebHost(builder);
var sqlConnectionStrings = "Data Source=.;Initial Catalog=UnitTest;User ID=sa;Password=sa";
builder.ConfigureAppConfiguration(app => app.AddInMemoryCollection(new KeyValuePair<string, string>[] {
new KeyValuePair<string, string>("ConnectionStrings:ba", sqlConnectionStrings)
}));
}
public string Login(string userName = "Admin", string password = "123789")
{
if (cookie.Count == 2) return "";
var client = CreateClient("http://localhost/Account/Login");
var r = client.GetAsync("");
r.Wait();
var tv = r.Result.Content.ReadAsStringAsync();
tv.Wait();
var tokenTag = "<input name=\"__RequestVerificationToken\" type=\"hidden\" value=\"";
var view = tv.Result;
var index = view.IndexOf(tokenTag);
view = view.Substring(index + tokenTag.Length);
index = view.IndexOf("\" /></form>");
@ -34,8 +72,17 @@ namespace Bootstrap.Admin
content.Add(new StringContent(password), "password");
content.Add(new StringContent("true"), "remember");
content.Add(new StringContent(antiToken), "__RequestVerificationToken");
var resp = await client.PostAsync("/Account/Login", content);
return await resp.Content.ReadAsStringAsync();
var resp = client.PostAsync("", content);
resp.Wait();
tv = resp.Result.Content.ReadAsStringAsync();
tv.Wait();
return tv.Result;
}
public void Logout()
{
cookie = new CookieContainer();
}
}
}

View File

@ -1,53 +0,0 @@
using System.Net.Http;
using Xunit;
namespace Bootstrap.Admin.Controllers
{
public class AccountTest : ControllerWebHost
{
private BAWebHost _factory;
public AccountTest(BAWebHost factory) : base(factory, "Account", false)
{
_factory = factory;
}
[Fact]
public async void Login_Fail()
{
// login
var r = await Client.GetAsync("Login");
Assert.True(r.IsSuccessStatusCode);
var content = await r.Content.ReadAsStringAsync();
Assert.Contains("登 陆", content);
}
[Fact]
public async void Login_Admin()
{
// login
var resp = await _factory.LoginAsync(Client);
Assert.Contains("注销", resp);
}
[Fact]
public async void Logout_Ok()
{
// logout
var r = await Client.GetAsync("Logout");
Assert.True(r.IsSuccessStatusCode);
var content = await r.Content.ReadAsStringAsync();
Assert.Contains("登 陆", content);
}
[Fact]
public async void AccessDenied_Ok()
{
// logout
var r = await Client.GetAsync("AccessDenied");
Assert.True(r.IsSuccessStatusCode);
var content = await r.Content.ReadAsStringAsync();
Assert.Contains("您无权访问本页面请联系网站管理员授权后再查看", content);
}
}
}

View File

@ -1,47 +0,0 @@
using System.Net;
using System.Net.Http;
using Xunit;
namespace Bootstrap.Admin.Controllers
{
public class AdminTest : ControllerWebHost
{
public AdminTest(BAWebHost factory) : base(factory, "Admin", true)
{
}
[Theory]
[InlineData("Index", "欢迎使用后台管理")]
[InlineData("Users", "用户管理")]
[InlineData("Groups", "部门管理")]
[InlineData("Dicts", "字典表维护")]
[InlineData("Roles", "角色管理")]
[InlineData("Menus", "菜单管理")]
[InlineData("Logs", "系统日志")]
[InlineData("FAIcon", "图标集")]
[InlineData("IconView", "图标分类")]
[InlineData("Settings", "网站设置")]
[InlineData("Notifications", "通知管理")]
[InlineData("Profiles", "个人中心")]
[InlineData("Exceptions", "程序异常")]
[InlineData("Messages", "站内消息")]
[InlineData("Tasks", "任务管理")]
[InlineData("Mobile", "客户端测试")]
public async void View_Ok(string view, string text)
{
var r = await Client.GetAsync(view);
Assert.True(r.IsSuccessStatusCode);
var content = await r.Content.ReadAsStringAsync();
Assert.Contains(text, content);
}
[Fact]
public async void Error_Ok()
{
var r = await Client.GetAsync("Error");
Assert.False(r.IsSuccessStatusCode);
Assert.Equal(HttpStatusCode.InternalServerError, r.StatusCode);
}
}
}

View File

@ -1,18 +0,0 @@
using System.Net.Http;
using Xunit;
namespace Bootstrap.Admin.Controllers
{
public class ControllerWebHost : IClassFixture<BAWebHost>
{
protected HttpClient Client { get; }
public ControllerWebHost(BAWebHost factory, string controller, bool login)
{
factory.ClientOptions.BaseAddress = new System.Uri($"http://localhost/{controller}/");
Client = factory.CreateClient();
if (login) factory.LoginAsync(Client).GetAwaiter().GetResult();
}
}
}

View File

@ -1,37 +0,0 @@
using System.Net.Http;
using Xunit;
namespace Bootstrap.Admin.Controllers
{
public class HomeTest : ControllerWebHost
{
public HomeTest(BAWebHost factory) : base(factory, "Home", true)
{
}
[Theory]
[InlineData(0)]
[InlineData(404)]
[InlineData(500)]
public async void Error_Ok(int errorCode)
{
var r = await Client.GetAsync($"Error/{errorCode}");
Assert.True(r.IsSuccessStatusCode);
var content = await r.Content.ReadAsStringAsync();
if (errorCode == 0)
{
Assert.Contains("未处理服务器内部错误", content);
}
else if (errorCode == 404)
{
Assert.Contains("请求资源未找到", content);
}
else
{
Assert.Contains("服务器内部错误", content);
}
}
}
}

View File

@ -0,0 +1,116 @@
using System.Net;
using System.Net.Http;
using Xunit;
namespace Bootstrap.Admin.Controllers
{
public class ControllersTest : IClassFixture<BAWebHost>
{
private HttpClient _client;
private BAWebHost _host;
public ControllersTest(BAWebHost factory)
{
_host = factory;
_client = factory.CreateClient();
}
[Fact]
public async void Login_Fail()
{
// login
_host.Logout();
_client = _host.CreateClient();
var r = await _client.GetAsync("/Account/Login");
Assert.True(r.IsSuccessStatusCode);
var content = await r.Content.ReadAsStringAsync();
Assert.Contains("登 陆", content);
}
[Fact]
public void Login_Admin()
{
// login
_host.Logout();
var resp = _host.Login();
Assert.Contains("注销", resp);
}
[Fact]
public async void Logout_Ok()
{
// logout
var r = await _client.GetAsync("/Account/Logout");
Assert.True(r.IsSuccessStatusCode);
var content = await r.Content.ReadAsStringAsync();
Assert.Contains("登 陆", content);
}
[Fact]
public async void AccessDenied_Ok()
{
// logout
var r = await _client.GetAsync("/Account/AccessDenied");
Assert.True(r.IsSuccessStatusCode);
var content = await r.Content.ReadAsStringAsync();
Assert.Contains("您无权访问本页面请联系网站管理员授权后再查看", content);
}
[Theory]
[InlineData(0)]
[InlineData(404)]
[InlineData(500)]
public async void Home_Error_Ok(int errorCode)
{
var r = await _client.GetAsync($"/Home/Error/{errorCode}");
Assert.True(r.IsSuccessStatusCode);
var content = await r.Content.ReadAsStringAsync();
if (errorCode == 0)
{
Assert.Contains("未处理服务器内部错误", content);
}
else if (errorCode == 404)
{
Assert.Contains("请求资源未找到", content);
}
else
{
Assert.Contains("服务器内部错误", content);
}
}
[Theory]
[InlineData("Index", "欢迎使用后台管理")]
[InlineData("Users", "用户管理")]
[InlineData("Groups", "部门管理")]
[InlineData("Dicts", "字典表维护")]
[InlineData("Roles", "角色管理")]
[InlineData("Menus", "菜单管理")]
[InlineData("Logs", "系统日志")]
[InlineData("FAIcon", "图标集")]
[InlineData("IconView", "图标分类")]
[InlineData("Settings", "网站设置")]
[InlineData("Notifications", "通知管理")]
[InlineData("Profiles", "个人中心")]
[InlineData("Exceptions", "程序异常")]
[InlineData("Messages", "站内消息")]
[InlineData("Tasks", "任务管理")]
[InlineData("Mobile", "客户端测试")]
public async void View_Ok(string view, string text)
{
var r = await _client.GetAsync($"/Admin/{view}");
Assert.True(r.IsSuccessStatusCode);
var content = await r.Content.ReadAsStringAsync();
Assert.Contains(text, content);
}
[Fact]
public async void Admin_Error_Ok()
{
var r = await _client.GetAsync("/Admin/Error");
Assert.False(r.IsSuccessStatusCode);
Assert.Equal(HttpStatusCode.InternalServerError, r.StatusCode);
}
}
}

View File

@ -1,18 +1,12 @@
using Xunit;
using System.Linq;
using Xunit;
namespace Bootstrap.DataAccess
{
public class DictsTest : IClassFixture<BootstrapAdminStartup>
{
[Fact]
public void Delete_Ok()
{
var dict = new Dict();
Assert.True(dict.Delete(new string[] { "64", "65" }));
}
[Fact]
public void Save_Ok()
public void SaveAndDelete_Ok()
{
var dict = new Dict()
{
@ -22,6 +16,7 @@ namespace Bootstrap.DataAccess
Define = 1
};
Assert.True(dict.Save(dict));
Assert.True(dict.Delete(dict.RetrieveDicts().Where(d => d.Category == dict.Category).Select(d => d.Id)));
}
[Fact]
@ -35,6 +30,7 @@ namespace Bootstrap.DataAccess
Define = 1
};
Assert.True(dict.SaveSettings(dict));
dict.Delete(dict.RetrieveDicts().Where(d => d.Category == dict.Category).Select(d => d.Id));
}
[Fact]

View File

@ -1,4 +1,5 @@
using Xunit;
using System.Linq;
using Xunit;
namespace Bootstrap.DataAccess
{
@ -12,24 +13,21 @@ namespace Bootstrap.DataAccess
}
[Fact]
public void Save_Ok()
public void SaveAndDelete_Ok()
{
Group g = new Group() { GroupName = "UnitTest", Description = "UnitTestSave" };
Assert.True(g.Save(g));
}
[Fact]
public void Delete_Ok()
{
Group g = new Group();
Assert.True(g.Delete(new string[] { "12", "13" }));
var ids = g.Retrieves().Where(t => t.GroupName == "UnitTest").Select(t => t.Id);
Assert.True(g.Delete(ids));
}
[Fact]
public void RetrievesByRoleId_Ok()
{
Group p = new Group();
var groups = p.RetrievesByRoleId("1");
var groups = p.RetrievesByRoleId(new Role().Retrieves().Where(r => r.RoleName == "Administrators").First().Id);
Assert.NotEmpty(groups);
}
[Fact]

View File

@ -6,7 +6,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="2.2.0" />
<PackageReference Include="Microsoft.Data.Sqlite" Version="2.2.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />