暂时更改一部分Skill
This commit is contained in:
1 parent
84b28f9672
commit
6d4629e4ac
53 files changed
+5293
-10
No files matched your search
@@ -4,18 +4,97 @@ using Store.Management;
|
||||
using Store.Management.Views;
|
||||
using Store.Management.ViewModels;
|
||||
using Store.Management.Framework.Controls;
|
||||
using Store.Management.Api;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using Prism.Ioc;
|
||||
using Prism.Services.Dialogs;
|
||||
using DialogWindow = Store.Management.Framework.Controls.DialogWindow;
|
||||
class Program
|
||||
{
|
||||
[STAThread]
|
||||
static int Main()
|
||||
static int Main(string[] args)
|
||||
{
|
||||
var app = new App();
|
||||
var handler = new LoginHandler();
|
||||
using var httpClient = new HttpClient(handler);
|
||||
using var client = new StoreApiClient(new ApiClientOptions { BaseUrl = new Uri("http://localhost:14312/api/") }, httpClient);
|
||||
var app = new App(client);
|
||||
app.InitializeComponent();
|
||||
int exitCode = 0;
|
||||
app.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new Action(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
for (int attempt = 0; attempt < 100 && !app.Windows.OfType<DialogWindow>().Any(window => window.Content is LoginWindow && window.IsLoaded); attempt++)
|
||||
{
|
||||
await Task.Delay(20);
|
||||
}
|
||||
DialogWindow loginHost = app.Windows.OfType<DialogWindow>().Single(window => window.Content is LoginWindow);
|
||||
var login = (LoginWindow)loginHost.Content;
|
||||
LoginViewModel loginVm = (LoginViewModel)login.DataContext;
|
||||
if (args.Contains("--cancel-login") || args.Contains("--close-login"))
|
||||
{
|
||||
if (args.Contains("--close-login"))
|
||||
{
|
||||
loginHost.Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
loginVm.CancelCommand.Execute(null);
|
||||
}
|
||||
Check(!app.Windows.OfType<MainWindow>().Any(), "取消登录不得创建主窗口");
|
||||
Console.WriteLine("PASS: startup login cancellation/window-close shuts down without opening the main window.");
|
||||
return;
|
||||
}
|
||||
var userName = (System.Windows.Controls.TextBox)login.FindName("UserNameBox");
|
||||
var password = (System.Windows.Controls.PasswordBox)login.FindName("PasswordBox");
|
||||
var error = (System.Windows.Controls.TextBlock)login.FindName("ErrorText");
|
||||
foreach (string key in new[] { "PrimaryTextBrush", "SecondaryTextBrush", "RegionBrush", "BorderBrush", "DangerBrush", "ButtonPrimary" })
|
||||
{
|
||||
Check(login.TryFindResource(key) is not null, $"登录主题资源缺失:{key}");
|
||||
}
|
||||
Check(loginHost.IsVisible && loginHost.DataContext == login.DataContext, "Prism 弹窗与登录页面共享 ViewModel");
|
||||
Check(userName.MaxLength == LoginViewModel.InputMaxLength && password.MaxLength == LoginViewModel.InputMaxLength, "登录输入限长");
|
||||
await loginVm.LoginCommand.Execute();
|
||||
Check(error.Text == "请输入用户名。", "用户名校验");
|
||||
userName.Text = " admin ";
|
||||
await loginVm.LoginCommand.Execute();
|
||||
Check(error.Text == "请输入密码。", "密码校验");
|
||||
password.Password = "wrong";
|
||||
await loginVm.LoginCommand.Execute();
|
||||
Check(error.Text == "用户名或密码错误" && login.IsVisible, "失败后保留登录窗口");
|
||||
Check(password.Password.Length == 0, "失败后清空密码");
|
||||
Check(((System.Windows.Controls.Button)login.FindName("LoginButton")).IsEnabled && userName.IsEnabled && password.IsEnabled, "失败后恢复输入和提交");
|
||||
password.Password = " secret ";
|
||||
Check(ReferenceEquals(((System.Windows.Controls.Button)login.FindName("LoginButton")).Command, loginVm.LoginCommand), "登录按钮绑定 ViewModel 命令");
|
||||
var pending = loginVm.LoginCommand.Execute();
|
||||
Check(loginVm.LoadingStatus.IsLoading && !loginVm.CanEdit && !loginVm.LoginCommand.CanExecute(), "登录期间禁用输入与命令");
|
||||
await loginVm.LoginCommand.Execute();
|
||||
await pending;
|
||||
Check(handler.RequestCount == 2, "阻止重复提交");
|
||||
Check(client.Session.IsAuthenticated, "保存登录会话");
|
||||
await Dispatcher.Yield(DispatcherPriority.ApplicationIdle);
|
||||
Check(!loginHost.IsVisible && password.Password.Length == 0, "成功后关闭登录窗口并清空密码");
|
||||
IDialogService dialogs = app.Container.Resolve<IDialogService>();
|
||||
ButtonResult? closeResult = null;
|
||||
dialogs.Show(nameof(LoginWindow), new DialogParameters(), result => closeResult = result.Result);
|
||||
DialogWindow closingHost = app.Windows.OfType<DialogWindow>().Single();
|
||||
LoginWindow closingView = (LoginWindow)closingHost.Content;
|
||||
LoginViewModel closingVm = (LoginViewModel)closingView.DataContext;
|
||||
closingVm.UserName = "admin";
|
||||
var closingPassword = (System.Windows.Controls.PasswordBox)closingView.FindName("PasswordBox");
|
||||
closingPassword.Password = " secret ";
|
||||
int lateSuccessCount = 0;
|
||||
closingVm.RequestClose += result => { if (result.Result == ButtonResult.OK) lateSuccessCount++; };
|
||||
Task closingRequest = closingVm.LoginCommand.Execute();
|
||||
closingHost.Close();
|
||||
await closingRequest;
|
||||
Check(closeResult == ButtonResult.None && lateSuccessCount == 0 && closingPassword.Password.Length == 0, "关闭窗口取消登录且不触发迟到成功");
|
||||
Check(!closingVm.CanEdit && !closingVm.LoginCommand.CanExecute(), "关闭后不可再次登录");
|
||||
dialogs.Show(nameof(LoginWindow), new DialogParameters(), result => closeResult = result.Result);
|
||||
((LoginViewModel)app.Windows.OfType<DialogWindow>().Single().DataContext).CancelCommand.Execute(null);
|
||||
Check(closeResult == ButtonResult.Cancel, "登录取消返回 Prism Cancel");
|
||||
var page = (FrameworkTestPage)((MainWindow)app.MainWindow).Content;
|
||||
var vm = (FrameworkTestPageViewModel)page.DataContext;
|
||||
vm.TestIocCommand.Execute();
|
||||
@@ -60,4 +139,29 @@ class Program
|
||||
static void Check(bool success, string message) { if (!success) throw new Exception(message); }
|
||||
}
|
||||
|
||||
sealed class LoginHandler : HttpMessageHandler
|
||||
{
|
||||
public int RequestCount { get; private set; }
|
||||
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
|
||||
{
|
||||
RequestCount++;
|
||||
if (request.RequestUri?.AbsoluteUri != "http://localhost:14312/api/v1/Auth/Login")
|
||||
throw new Exception("登录路由错误");
|
||||
var body = System.Text.Json.JsonDocument.Parse(await request.Content!.ReadAsStringAsync(cancellationToken));
|
||||
if (body.RootElement.GetProperty("userName").GetString() != "admin")
|
||||
throw new Exception("用户名未去除首尾空格");
|
||||
await Task.Delay(30, cancellationToken);
|
||||
var submittedPassword = body.RootElement.GetProperty("password").GetString()!;
|
||||
if (!System.Text.RegularExpressions.Regex.IsMatch(submittedPassword, "^[0-9A-F]{32}$"))
|
||||
throw new Exception("密码必须为 32 位大写 MD5");
|
||||
var success = submittedPassword == "320BB1D43EC042096A83DBAC6DC9294A";
|
||||
return new HttpResponseMessage(HttpStatusCode.OK)
|
||||
{
|
||||
Content = new StringContent(success
|
||||
? "{\"code\":200,\"data\":{\"tokenType\":\"Bearer\",\"token\":\"test-token\",\"expiresInMinutes\":60}}"
|
||||
: "{\"code\":400,\"msg\":\"用户名或密码错误\"}", Encoding.UTF8, "application/json")
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user