142 lines
5.8 KiB
C#
142 lines
5.8 KiB
C#
using FsCheck;
|
|
using FsCheck.Xunit;
|
|
using Infrastructure;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Xunit;
|
|
using ZR.Common;
|
|
|
|
namespace ZR.Tests
|
|
{
|
|
/// <summary>
|
|
/// COS URL 验证属性测试
|
|
/// **Feature: work-camera-2.0, Property 2: COS URL Validation**
|
|
/// **Validates: Requirements 3.3**
|
|
/// </summary>
|
|
public class CosUrlValidationPropertyTests : IClassFixture<TestFixture>
|
|
{
|
|
private const string ValidCosDomain = "https://miaoyu-1308826010.cos.ap-shanghai.myqcloud.com";
|
|
private const string ValidPrefix = "workfiles";
|
|
|
|
public CosUrlValidationPropertyTests(TestFixture fixture)
|
|
{
|
|
// 确保配置已初始化
|
|
}
|
|
|
|
/// <summary>
|
|
/// Property 2: COS URL Validation
|
|
///
|
|
/// *For any* URL submitted to the V3 interface, the system SHALL accept only URLs matching
|
|
/// the COS domain pattern `https://miaoyu-1308826010.cos.ap-shanghai.myqcloud.com/workfiles/...`
|
|
/// and reject all other URLs.
|
|
///
|
|
/// **Validates: Requirements 3.3**
|
|
/// </summary>
|
|
[Property(MaxTest = 100)]
|
|
public Property ValidCosUrls_AreAccepted()
|
|
{
|
|
// Generate valid COS URLs
|
|
var validUrlGen = from year in Gen.Choose(2020, 2030)
|
|
from month in Gen.Choose(1, 12)
|
|
from day in Gen.Choose(1, 28)
|
|
from category in Gen.Elements("当日照片", "参与人员/张三", "工作内容/设备检修", "部门/技术部")
|
|
from timestampPart in Gen.Choose(100000, 999999)
|
|
from random in Gen.Choose(1000, 9999)
|
|
from ext in Gen.Elements(".jpg", ".png", ".jpeg")
|
|
select $"{ValidCosDomain}/{ValidPrefix}/{year:D4}{month:D2}/{year:D4}{month:D2}{day:D2}/{category}/{timestampPart}_{random}{ext}";
|
|
|
|
return Prop.ForAll(
|
|
validUrlGen.ToArbitrary(),
|
|
url =>
|
|
{
|
|
var result = CosService.IsValidCosUrl(url);
|
|
return result.Label($"Valid COS URL should be accepted: {url}");
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// Property 2: COS URL Validation - Invalid domain URLs are rejected
|
|
///
|
|
/// *For any* URL with a different domain, the system SHALL reject it.
|
|
///
|
|
/// **Validates: Requirements 3.3**
|
|
/// </summary>
|
|
[Property(MaxTest = 100)]
|
|
public Property InvalidDomainUrls_AreRejected()
|
|
{
|
|
// Generate URLs with invalid domains
|
|
var invalidDomainGen = from domain in Gen.Elements(
|
|
"https://other-bucket.cos.ap-shanghai.myqcloud.com",
|
|
"https://example.com",
|
|
"http://miaoyu-1308826010.cos.ap-shanghai.myqcloud.com", // http instead of https
|
|
"https://miaoyu.cos.ap-shanghai.myqcloud.com",
|
|
"https://localhost:8080",
|
|
"https://192.168.1.1")
|
|
from path in Gen.Elements(
|
|
"/workfiles/202501/20250105/当日照片/test.jpg",
|
|
"/files/image.png",
|
|
"/test.jpg")
|
|
select domain + path;
|
|
|
|
return Prop.ForAll(
|
|
invalidDomainGen.ToArbitrary(),
|
|
url =>
|
|
{
|
|
var result = CosService.IsValidCosUrl(url);
|
|
return (!result).Label($"Invalid domain URL should be rejected: {url}");
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// Property 2: COS URL Validation - Invalid prefix URLs are rejected
|
|
///
|
|
/// *For any* URL with the correct domain but wrong prefix, the system SHALL reject it.
|
|
///
|
|
/// **Validates: Requirements 3.3**
|
|
/// </summary>
|
|
[Property(MaxTest = 100)]
|
|
public Property InvalidPrefixUrls_AreRejected()
|
|
{
|
|
// Generate URLs with invalid prefixes
|
|
var invalidPrefixGen = from prefix in Gen.Elements(
|
|
"files",
|
|
"images",
|
|
"uploads",
|
|
"data",
|
|
"work",
|
|
"workfile") // missing 's'
|
|
from path in Gen.Elements(
|
|
"/202501/20250105/当日照片/test.jpg",
|
|
"/test.jpg")
|
|
select $"{ValidCosDomain}/{prefix}{path}";
|
|
|
|
return Prop.ForAll(
|
|
invalidPrefixGen.ToArbitrary(),
|
|
url =>
|
|
{
|
|
var result = CosService.IsValidCosUrl(url);
|
|
return (!result).Label($"Invalid prefix URL should be rejected: {url}");
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// Property 2: COS URL Validation - Empty and null URLs are rejected
|
|
///
|
|
/// **Validates: Requirements 3.3**
|
|
/// </summary>
|
|
[Property(MaxTest = 100)]
|
|
public Property EmptyOrWhitespaceUrls_AreRejected()
|
|
{
|
|
// Generate empty or whitespace strings
|
|
var emptyGen = Gen.Elements("", " ", " ", "\t", "\n", "\r\n", " ");
|
|
|
|
return Prop.ForAll(
|
|
emptyGen.ToArbitrary(),
|
|
url =>
|
|
{
|
|
var result = CosService.IsValidCosUrl(url);
|
|
return (!result).Label($"Empty/whitespace URL should be rejected");
|
|
});
|
|
}
|
|
}
|
|
}
|