pull file
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
Close Stale Issues / close_stale_issues (push) Has been cancelled
repo-sync / repo-sync (push) Has been cancelled
auto-deploy-tencent-scf / pre-check (push) Has been cancelled
auto-deploy-tencent-scf / deploy serverless (push) Has been cancelled

This commit is contained in:
2026-02-11 23:32:56 +08:00
commit e519cac94e
656 changed files with 45058 additions and 0 deletions

View File

@@ -0,0 +1,38 @@
using FluentAssertions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Ray.BiliBiliTool.Agent.BiliBiliAgent.Dtos;
using Ray.BiliBiliTool.Agent.BiliBiliAgent.Interfaces;
using Ray.BiliBiliTool.Console;
namespace Ray.BiliBiliTool.Agent.FunctionalTests;
public class AccountApiTests
{
private readonly IAccountApi _api;
public AccountApiTests()
{
var envs = new List<string>
{
"--ENVIRONMENT=Development",
//"HTTP_PROXY=localhost:8888",
//"HTTPS_PROXY=localhost:8888"
};
IHost host = Program.CreateHost(envs.ToArray());
_api = host.Services.GetRequiredService<IAccountApi>();
}
[Fact]
public async Task GetCoinBalance_Normal_GetCoinBalance()
{
// Act
BiliApiResponse<CoinBalance> re = await _api.GetCoinBalanceAsync(null);
// Arrange
// Assert
re.Code.Should().Be(0);
re.Data.Money.Should().NotBeNull();
}
}

View File

@@ -0,0 +1,149 @@
using FluentAssertions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Ray.BiliBiliTool.Agent.BiliBiliAgent.Dtos;
using Ray.BiliBiliTool.Agent.BiliBiliAgent.Dtos.Article;
using Ray.BiliBiliTool.Agent.BiliBiliAgent.Interfaces;
using Ray.BiliBiliTool.Agent.BiliBiliAgent.Services;
using Ray.BiliBiliTool.Console;
namespace Ray.BiliBiliTool.Agent.FunctionalTests;
public class ArticleApiTests
{
private readonly IArticleApi _api;
private readonly BiliCookie _ck;
private readonly IWbiService _wbiService;
public ArticleApiTests()
{
var envs = new List<string>
{
"--ENVIRONMENT=Development",
//"HTTP_PROXY=localhost:8888",
//"HTTPS_PROXY=localhost:8888"
};
IHost host = Program.CreateHost(envs.ToArray());
_ck = host.Services.GetRequiredService<BiliCookie>();
_wbiService = host.Services.GetRequiredService<IWbiService>();
_api = host.Services.GetRequiredService<IArticleApi>();
}
#region SearchUpArticlesByUpIdAsync
[Fact]
public async Task SearchUpArticlesByUpIdAsync_InputId_GetResultSuccess()
{
// Arrange
var mid = 1585227649;
var req = new SearchArticlesByUpIdDto() { mid = mid };
await _wbiService.SetWridAsync(req, null);
// Act
BiliApiResponse<SearchUpArticlesResponse> re = await _api.SearchUpArticlesByUpIdAsync(req);
// Assert
re.Code.Should().Be(0);
re.Data.Count.Should().BeGreaterThan(0);
}
#endregion
#region SearchArticleInfoAsync
[Fact]
public async Task SearchArticleInfoAsync_ValidId_GetResultSuccess()
{
// Arrange
var cvid = 34150576;
// Act
var re = await _api.SearchArticleInfoAsync(cvid);
// Assert
re.Code.Should().Be(0);
re.Data.Mid.Should().BeGreaterThan(0);
re.Data.Like.Should().BeGreaterThanOrEqualTo(1);
}
[Fact]
public async Task SearchArticleInfoAsync_InvalidId_NoResult()
{
// Arrange
var cvid = 123;
// Act
var re = await _api.SearchArticleInfoAsync(cvid);
// Assert
re.Code.Should().Be(-404);
re.Data.Should().BeNull();
re.Message.Should().BeEquivalentTo("啥都木有");
}
#endregion
#region AddCoinForArticleAsync
[Fact]
public async Task AddCoinForArticleAsync_CoinSelf_Fail()
{
// Arrange
var selfCvId = 34150576; //todo
var req = new AddCoinForArticleRequest(selfCvId, long.Parse(_ck.UserId), _ck.BiliJct);
// Act
BiliBiliAgent.Dtos.BiliApiResponse re = await _api.AddCoinForArticleAsync(req, null);
// Assert
re.Code.Should().Be(34002);
re.Message.Should().BeEquivalentTo("up主不能自己投币");
}
[Fact]
public async Task AddCoinForArticleAsync_Normal_Success()
{
// Arrange
var cvId = 34049005; //todo
var upId = 25150765; //todo
var req = new AddCoinForArticleRequest(cvId, upId, _ck.BiliJct);
// Act
BiliBiliAgent.Dtos.BiliApiResponse re = await _api.AddCoinForArticleAsync(req, null);
// Assert
re.Code.Should()
.BeOneOf(
0, // 成功
34005 // 超过投币上限啦~
);
}
#endregion
#region LikeAsync
[Fact]
public async Task LikeAsync_AlreadyLike_GetResultSuccess()
{
// Arrange
var cvid = 34150576;
// Act
var re = await _api.LikeAsync(cvid, _ck.BiliJct, null);
// Assert
re.Code.Should()
.BeOneOf(
new List<int>
{
0,
65006, //已赞过
}
);
}
#endregion
}

View File

@@ -0,0 +1,55 @@
using FluentAssertions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Ray.BiliBiliTool.Agent.BiliBiliAgent.Dtos;
using Ray.BiliBiliTool.Agent.BiliBiliAgent.Interfaces;
using Ray.BiliBiliTool.Console;
namespace Ray.BiliBiliTool.Agent.FunctionalTests;
public class ChargeApiTest
{
private readonly IChargeApi _target;
private readonly BiliCookie _ck;
public ChargeApiTest()
{
var envs = new List<string>
{
"--ENVIRONMENT=Development",
//"HTTP_PROXY=localhost:8888",
//"HTTPS_PROXY=localhost:8888"
};
IHost host = Program.CreateHost(envs.ToArray());
_ck = host.Services.GetRequiredService<BiliCookie>();
_target = host.Services.GetRequiredService<IChargeApi>();
}
#region ChargeV2Async
[Fact]
public async void ChargeV2Async_SendRequest_NotEnough()
{
// Arrange
var upId = 220893216;
var req = new ChargeRequest(2, upId, _ck.BiliJct);
// Act
BiliApiResponse<ChargeV2Response> re = await _target.ChargeV2Async(req, null);
// Assert
re.Code.Should().Be(0);
re.Data.Status.Should()
.BeOneOf(
-4, //bp.to.battery http failed, invalid args, errNo=800409904: B <20><><EFBFBD><EFBFBD><EFBFBD><EEB2BB>
4
);
}
#endregion
#region ChargeCommentAsync
#endregion
}

View File

@@ -0,0 +1,75 @@
using FluentAssertions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Ray.BiliBiliTool.Agent.BiliBiliAgent.Dtos;
using Ray.BiliBiliTool.Agent.BiliBiliAgent.Interfaces;
using Ray.BiliBiliTool.Console;
namespace Ray.BiliBiliTool.Agent.FunctionalTests;
public class DailyTaskApiTests
{
private readonly IDailyTaskApi _api;
private readonly BiliCookie _ck;
public DailyTaskApiTests()
{
var envs = new List<string>
{
"--ENVIRONMENT=Development",
//"HTTP_PROXY=localhost:8888",
//"HTTPS_PROXY=localhost:8888"
};
IHost host = Program.CreateHost(envs.ToArray());
_ck = host.Services.GetRequiredService<BiliCookie>();
_api = host.Services.GetRequiredService<IDailyTaskApi>();
}
[Fact]
public async Task GetDailyTaskRewardInfo_Normal_Success()
{
// Act
BiliApiResponse<DailyTaskInfo> re = await _api.GetDailyTaskRewardInfoAsync(null);
// Arrange
// Assert
re.Code.Should().Be(0);
re.Data.Should().NotBeNull();
}
[Fact]
public async Task GetDonateCoinExp_Normal_Success()
{
// Act
BiliApiResponse<int> re = await _api.GetDonateCoinExpAsync(null);
// Arrange
// Assert
re.Code.Should().Be(0);
re.Data.Should().BeGreaterThanOrEqualTo(0);
}
[Fact]
public async Task ReceiveVipPrivilege_Normal_Success()
{
// Act
BiliApiResponse re = await _api.ReceiveVipPrivilegeAsync(
(int)VipPrivilegeType.BCoinCoupon,
_ck.BiliJct,
null
);
// Arrange
// Assert
re.Code.Should()
.BeOneOf(
0,
73319, //todo: sort out meannings
69801 //你已领取过该权益
);
}
}

View File

@@ -0,0 +1,41 @@
using FluentAssertions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Ray.BiliBiliTool.Agent.BiliBiliAgent.Interfaces;
using Ray.BiliBiliTool.Console;
namespace Ray.BiliBiliTool.Agent.FunctionalTests;
public class HomeApiTests
{
private readonly IHomeApi _api;
private readonly BiliCookie _ck;
public HomeApiTests()
{
var envs = new List<string>
{
"--ENVIRONMENT=Development",
//"HTTP_PROXY=localhost:8888",
//"HTTPS_PROXY=localhost:8888"
};
IHost host = Program.CreateHost(envs.ToArray());
_ck = host.Services.GetRequiredService<BiliCookie>();
_api = host.Services.GetRequiredService<IHomeApi>();
}
[Fact]
public async Task GetHomePageAsync_Normal_Success()
{
// Act
HttpResponseMessage re = await _api.GetHomePageAsync(_ck.ToString());
// Arrange
var page = await re.Content.ReadAsStringAsync();
// Assert
re.IsSuccessStatusCode.Should().BeTrue();
page.Should().Contain("<title>哔哩哔哩 (゜-゜)つロ 干杯~-bilibili</title>");
}
}

View File

@@ -0,0 +1,172 @@
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using FluentAssertions;
using Microsoft.Extensions.DependencyInjection;
using Ray.BiliBiliTool.Agent;
using Ray.BiliBiliTool.Agent.BiliBiliAgent.Dtos;
using Ray.BiliBiliTool.Agent.BiliBiliAgent.Dtos.Live;
using Ray.BiliBiliTool.Agent.BiliBiliAgent.Interfaces;
using Ray.BiliBiliTool.Agent.BiliBiliAgent.Services;
using Ray.BiliBiliTool.Console;
using Ray.BiliBiliTool.Infrastructure;
using Ray.BiliBiliTool.Infrastructure.Cookie;
using Xunit;
namespace BiliAgentTest
{
public class LiveApiTest
{
public LiveApiTest()
{
Program.CreateHost(new[] { "--ENVIRONMENT=Development" }); //ĬÈÏPrd»·¾³£¬ÕâÀïÖ¸¶¨ÎªDevºó£¬¿ÉÒÔ¶ÁÈ¡µ½Óû§»úÃÜÅäÖÃ
}
[Fact]
[Obsolete]
public void GetExchangeSilverStatus_Normal_Success()
{
using var scope = Global.ServiceProviderRoot.CreateScope();
var api = scope.ServiceProvider.GetRequiredService<ILiveApi>();
var ck = scope.ServiceProvider.GetRequiredService<CookieStrFactory<BiliCookie>>();
BiliApiResponse<ExchangeSilverStatusResponse> re = api.GetExchangeSilverStatus(
null
).Result;
if (ck.Count > 0)
{
Assert.True(re.Code == 0 && re.Message == "0");
Assert.True(re.Data.Silver >= 0);
}
else
{
Assert.False(re.Code != 0);
}
}
[Fact]
public void Silver2Coin_Normal_Success()
{
using var scope = Global.ServiceProviderRoot.CreateScope();
var ck = scope.ServiceProvider.GetRequiredService<CookieStrFactory<BiliCookie>>();
var api = scope.ServiceProvider.GetRequiredService<ILiveApi>();
var biliCookie = scope.ServiceProvider.GetRequiredService<BiliCookie>();
Silver2CoinRequest request = new(biliCookie.BiliJct);
BiliApiResponse<Silver2CoinResponse> re = api.Silver2Coin(request, null).Result;
if (re.Code == 0)
{
Assert.True(re.Data.Coin == 1);
}
else
{
Assert.False(string.IsNullOrWhiteSpace(re.Message));
}
}
[Fact]
public void GetLiveWalletStatus_Normal_Success()
{
using var scope = Global.ServiceProviderRoot.CreateScope();
var ck = scope.ServiceProvider.GetRequiredService<CookieStrFactory<BiliCookie>>();
var api = scope.ServiceProvider.GetRequiredService<ILiveApi>();
BiliApiResponse<LiveWalletStatusResponse> re = api.GetLiveWalletStatus(null).Result;
if (ck.Count > 0)
{
Assert.True(re.Code == 0 && re.Data.Silver_2_coin_left >= 0);
}
else
{
Assert.False(re.Code != 0);
}
}
[Fact]
public void GetMedalWall_Normal_Success()
{
using var scope = Global.ServiceProviderRoot.CreateScope();
var ck = scope.ServiceProvider.GetRequiredService<CookieStrFactory<BiliCookie>>();
var api = scope.ServiceProvider.GetRequiredService<ILiveApi>();
BiliApiResponse<MedalWallResponse> re = api.GetMedalWall("919174", null).Result;
Assert.NotEmpty(re.Data.List);
var md = re.Data.List[0];
Assert.NotNull(md);
Assert.False(String.IsNullOrEmpty(md.Link));
Assert.False(String.IsNullOrEmpty(md.Target_name));
Assert.NotNull(md.Medal_info);
Assert.False(String.IsNullOrEmpty(md.Medal_info.Medal_name));
Assert.True(md.Medal_info.Medal_id > 0);
}
[Fact]
public void WearMedalWall_Normal_Success()
{
using var scope = Global.ServiceProviderRoot.CreateScope();
var ck = scope.ServiceProvider.GetRequiredService<CookieStrFactory<BiliCookie>>();
var api = scope.ServiceProvider.GetRequiredService<ILiveApi>();
var biliCookie = scope.ServiceProvider.GetRequiredService<BiliCookie>();
// 猫雷粉丝牌
var request = new WearMedalWallRequest(biliCookie.BiliJct, 365421); //todo
BiliApiResponse re = api.WearMedalWall(request, null).Result;
Assert.True(re.Code == 0);
re.Code.Should().BeOneOf(0, 1500005);
}
[Fact]
public async Task GetSpaceInfo_Normal_Success()
{
using var scope = Global.ServiceProviderRoot.CreateScope();
var ck = scope.ServiceProvider.GetRequiredService<CookieStrFactory<BiliCookie>>();
var api = scope.ServiceProvider.GetRequiredService<IUpInfoApi>();
var wbiService = scope.ServiceProvider.GetRequiredService<IWbiService>();
var req = new GetSpaceInfoDto() { mid = 919174L };
BiliApiResponse<GetSpaceInfoResponse> re = api.GetSpaceInfo(
req,
ck.GetCookie(0).ToString()
).Result;
Assert.True(re.Code == 0);
Assert.NotNull(re.Data);
Assert.Equal(919174, re.Data.Mid);
Assert.NotNull(re.Data.Live_room);
Assert.Equal(3115258, re.Data.Live_room.Roomid);
Assert.False(String.IsNullOrEmpty(re.Data.Name));
Assert.False(String.IsNullOrEmpty(re.Data.Live_room.Title));
}
[Fact]
public void SendLiveDanmuku_Normal_Success()
{
using var scope = Global.ServiceProviderRoot.CreateScope();
var ck = scope.ServiceProvider.GetRequiredService<CookieStrFactory<BiliCookie>>();
var api = scope.ServiceProvider.GetRequiredService<ILiveApi>();
var biliCookie = scope.ServiceProvider.GetRequiredService<BiliCookie>();
var request = new SendLiveDanmukuRequest(biliCookie.BiliJct, 63666, "63666");
BiliApiResponse re = api.SendLiveDanmuku(request, null).Result;
Assert.True(re.Code == 0);
}
}
}

View File

@@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="xunit" />
<PackageReference Include="xunit.runner.visualstudio">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="coverlet.collector">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="FluentAssertions" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Ray.BiliBiliTool.Console\Ray.BiliBiliTool.Console.csproj" />
</ItemGroup>
<ItemGroup>
<Using Include="Xunit" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,108 @@
using FluentAssertions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Ray.BiliBiliTool.Agent.BiliBiliAgent.Dtos;
using Ray.BiliBiliTool.Agent.BiliBiliAgent.Dtos.Mall;
using Ray.BiliBiliTool.Agent.BiliBiliAgent.Dtos.VipTask;
using Ray.BiliBiliTool.Agent.BiliBiliAgent.Interfaces;
using Ray.BiliBiliTool.Console;
using Xunit.Abstractions;
namespace Ray.BiliBiliTool.Agent.FunctionalTests;
public class VipBigPointApiTest
{
private readonly IVipBigPointApi _api;
private readonly ITestOutputHelper _output;
private readonly BiliCookie _ck;
public VipBigPointApiTest(ITestOutputHelper output)
{
_output = output;
var envs = new List<string>
{
"--ENVIRONMENT=Development",
//"HTTP_PROXY=localhost:8888",
//"HTTPS_PROXY=localhost:8888"
};
IHost host = Program.CreateHost(envs.ToArray());
_ck = host.Services.GetRequiredService<BiliCookie>();
_api = host.Services.GetRequiredService<IVipBigPointApi>();
}
[Fact]
public async Task GetTaskListAsync_Normal_Success()
{
// Arrange
// Act
BiliApiResponse<VipBigPointCombine> re = await _api.GetCombineAsync(null);
// Assert
re.Code.Should().Be(0);
re.Data.Should().NotBeNull();
re.Data.Task_info.Modules.Should().HaveCountGreaterThan(0);
}
[Fact]
public async Task SignAsync_Normal_Success()
{
// Arrange
var req = new SignRequest() { csrf = _ck.BiliJct };
// Act
BiliApiResponse re = await _api.SignAsync(req, null);
_output.WriteLine(re.ToJsonStr());
// Assert
re.Code.Should().Be(0);
re.Message.Should().BeEquivalentTo("success");
}
[Fact]
public async Task GetVouchersInfoAsync_Normal_Success()
{
// Arrange
// Act
var re = await _api.GetVouchersInfoAsync(null);
// Assert
re.Code.Should().Be(0);
re.Data.List.Should().Contain(x => x.Type == 9);
}
[Fact]
public async Task GetVipExperienceAsync_Normal_Success()
{
// Arrange
var req = new VipExperienceRequest() { csrf = _ck.BiliJct };
// Act
BiliApiResponse re = await _api.ObtainVipExperienceAsync(req, null);
// Assert
re.Code.Should()
.BeOneOf(
new List<int>
{
0,
6034005, //任务未完成
69198, //用户经验已经领取
}
);
}
[Fact]
public async Task CompleteAsync_Normal_Success()
{
// Arrange
var req = new ReceiveOrCompleteTaskRequest("dress-view");
// Act
var re = await _api.CompleteAsync(req, null);
// Assert
re.Code.Should().Be(0);
}
}

View File

@@ -0,0 +1,43 @@
using FluentAssertions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Ray.BiliBiliTool.Agent.BiliBiliAgent.Dtos;
using Ray.BiliBiliTool.Agent.BiliBiliAgent.Dtos.ViewMall;
using Ray.BiliBiliTool.Agent.BiliBiliAgent.Interfaces;
using Ray.BiliBiliTool.Console;
namespace Ray.BiliBiliTool.Agent.FunctionalTests;
public class VipMallApiTests
{
private readonly IVipMallApi _api;
private readonly BiliCookie _ck;
public VipMallApiTests()
{
var envs = new List<string>
{
"--ENVIRONMENT=Development",
//"HTTP_PROXY=localhost:8888",
//"HTTPS_PROXY=localhost:8888"
};
IHost host = Program.CreateHost(envs.ToArray());
_ck = host.Services.GetRequiredService<BiliCookie>();
_api = host.Services.GetRequiredService<IVipMallApi>();
}
[Fact]
public async Task ViewVipMallAsync_Normal_Success()
{
// Arrange
var req = new ViewVipMallRequest() { Csrf = _ck.BiliJct };
// Act
BiliApiResponse re = await _api.ViewVipMallAsync(req, null);
// Assert
re.Code.Should().Be(0);
re.Message.Should().BeEquivalentTo("SUCCESS");
}
}

View File

@@ -0,0 +1,78 @@
using FluentAssertions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Ray.BiliBiliTool.Agent.BiliBiliAgent.Dtos;
using Ray.BiliBiliTool.Agent.BiliBiliAgent.Dtos.Video;
using Ray.BiliBiliTool.Agent.BiliBiliAgent.Services;
using Ray.BiliBiliTool.Console;
namespace Ray.BiliBiliTool.Agent.FunctionalTests;
public class WbiServiceTest
{
private readonly IWbiService _target;
public WbiServiceTest()
{
var envs = new List<string>
{
"--ENVIRONMENT=Development",
//"HTTP_PROXY=localhost:8888",
//"HTTPS_PROXY=localhost:8888"
};
IHost host = Program.CreateHost(envs.ToArray());
_target = host.Services.GetRequiredService<IWbiService>();
}
[Fact]
public async void SetWridAsync_SendRequest_SetWridSuccess()
{
// Arrange
var upId = 1585227649;
var req = new SearchVideosByUpIdDto()
{
mid = upId,
ps = 30,
tid = 0,
pn = 1,
keyword = "",
order = "pubdate",
platform = "web",
web_location = 1550101,
order_avoided = "true",
};
// Act
await _target.SetWridAsync(req, null);
// Assert
req.w_rid.Should().NotBeNullOrWhiteSpace();
req.wts.Should().NotBe(0);
}
[Fact]
public void EncWbi_InputParams_GetCorrectWbiResult()
{
// Arrange
var wbiDto = new WbiImg()
{
img_url = "https://i0.hdslb.com/bfs/wbi/653657f524a547ac981ded72ea172057.png",
sub_url = "https://i0.hdslb.com/bfs/wbi/6e4909c702f846728e64f6007736a338.png",
};
var dic = new Dictionary<string, string>()
{
{ "foo", "114" },
{ "bar", "514" },
{ "baz", "1919810" },
};
var timeSpan = 1684746387;
var expectResult = "d3cbd2a2316089117134038bf4caf442";
// Act
var re = _target.EncWbi(dic, wbiDto.ImgKey, wbiDto.SubKey, timeSpan);
// Assert
re.w_rid.Should().BeEquivalentTo(expectResult);
re.wts.Should().Be(timeSpan);
}
}