You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
haoliang-net/tests/CncWebApi.Tests/TestDb.cs

132 lines
5.4 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using Dapper;
using MySqlConnector;
namespace CncWebApi.Tests
{
/// <summary>
/// WebApi层测试数据库辅助类
/// 与Service.Tests共享同一个cnc_test库
/// </summary>
public static class TestDb
{
/// <summary>测试库连接串</summary>
public static readonly string ConnectionString =
"Server=localhost;Database=cnc_test;Uid=root;Pwd=root;Charset=utf8mb4;SslMode=None;";
/// <summary>清空所有测试表并重置种子数据</summary>
public static void TruncateAll()
{
using (var conn = new MySqlConnection(ConnectionString))
{
var tables = new[]
{
"log_collect_raw",
"log_collector_heartbeat",
"cnc_worker_machine",
"cnc_production_segment",
"cnc_machine_daily_status",
"cnc_worker_daily_summary",
"cnc_daily_production",
"cnc_production_adjustment",
"cnc_alert",
"log_system",
"cnc_machine",
"cnc_collect_address",
"cnc_brand_field_mapping",
"cnc_screen_filter",
"cnc_screen_config",
"cnc_worker",
"cnc_sys_config",
"cnc_workshop",
"cnc_brand"
};
conn.Execute("SET FOREIGN_KEY_CHECKS = 0");
foreach (var table in tables)
{
conn.Execute($"DELETE FROM {table}");
conn.Execute($"ALTER TABLE {table} AUTO_INCREMENT = 1");
}
conn.Execute("SET FOREIGN_KEY_CHECKS = 1");
}
SeedData();
}
/// <summary>插入基础种子数据</summary>
public static void SeedData()
{
using (var conn = new MySqlConnection(ConnectionString))
{
conn.Execute(@"INSERT IGNORE INTO cnc_brand (id, brand_name, device_field, tags_path, is_enabled, created_at, updated_at)
VALUES (1, 'FANUC', 'device', 'tags', 1, NOW(), NOW())");
conn.Execute(@"INSERT IGNORE INTO cnc_workshop (id, name, sort_order, is_enabled, created_at, updated_at)
VALUES (1, 'A栋', 1, 1, NOW(), NOW()), (2, 'B栋', 2, 1, NOW(), NOW())");
conn.Execute(@"INSERT IGNORE INTO cnc_sys_config (config_key, config_value, value_type, description, updated_at)
VALUES ('admin_username', 'admin', 'string', '管理员用户名', NOW()),
('admin_password_hash', '$2a$11$dummyhashfortesting', 'string', '管理员密码哈希', NOW())");
}
}
/// <summary>设置真实BCrypt密码哈希</summary>
public static void SetRealPasswordHash(string plainPassword)
{
var hash = BCrypt.Net.BCrypt.HashPassword(plainPassword);
using (var conn = new MySqlConnection(ConnectionString))
{
conn.Execute("UPDATE cnc_sys_config SET config_value = @hash WHERE config_key = 'admin_password_hash'", new { hash });
}
}
/// <summary>执行SQL</summary>
public static int Execute(string sql, object param = null)
{
using (var conn = new MySqlConnection(ConnectionString))
{
return conn.Execute(sql, param);
}
}
/// <summary>查询单个值</summary>
public static T QuerySingle<T>(string sql, object param = null)
{
using (var conn = new MySqlConnection(ConnectionString))
{
return conn.QuerySingle<T>(sql, param);
}
}
/// <summary>查询可空单个值</summary>
public static T QueryFirstOrDefault<T>(string sql, object param = null)
{
using (var conn = new MySqlConnection(ConnectionString))
{
return conn.QueryFirstOrDefault<T>(sql, param);
}
}
/// <summary>生成有效JWT Token用于需要认证的Controller测试</summary>
public static string GenerateTestToken(string jwtSecret = "test-jwt-secret-key-for-unit-testing-2024")
{
const string headerJson = "{\"alg\":\"HS256\",\"typ\":\"JWT\"}";
long exp = DateTimeOffset.UtcNow.AddHours(8).ToUnixTimeSeconds();
string payloadJson = $"{{\"sub\":\"admin\",\"name\":\"admin\",\"exp\":{exp}}}";
string header = Base64UrlEncode(System.Text.Encoding.UTF8.GetBytes(headerJson));
string payload = Base64UrlEncode(System.Text.Encoding.UTF8.GetBytes(payloadJson));
string unsigned = header + "." + payload;
using (var hmac = new System.Security.Cryptography.HMACSHA256(System.Text.Encoding.UTF8.GetBytes(jwtSecret)))
{
var sig = hmac.ComputeHash(System.Text.Encoding.UTF8.GetBytes(unsigned));
string signature = Base64UrlEncode(sig);
return unsigned + "." + signature;
}
}
private static string Base64UrlEncode(byte[] input)
{
return Convert.ToBase64String(input).Replace("+", "-").Replace("/", "_").TrimEnd('=');
}
}
}