3eeb314dc2
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
78 lines
3.0 KiB
C#
78 lines
3.0 KiB
C#
using System.Net;
|
|
using System.Text.Json;
|
|
using Microsoft.Extensions.Options;
|
|
using ROLAC.API.Services.Notifications;
|
|
using Xunit;
|
|
|
|
namespace ROLAC.API.Tests.Services.Notifications;
|
|
|
|
public class LineMessageChannelTests
|
|
{
|
|
// Captures the outgoing request and returns a canned response.
|
|
private sealed class CapturingHandler : HttpMessageHandler
|
|
{
|
|
public HttpRequestMessage? LastRequest { get; private set; }
|
|
public string? LastBody { get; private set; }
|
|
public HttpStatusCode StatusCode { get; set; } = HttpStatusCode.OK;
|
|
public string ResponseBody { get; set; } = "{}";
|
|
|
|
protected override async Task<HttpResponseMessage> SendAsync(
|
|
HttpRequestMessage request, CancellationToken cancellationToken)
|
|
{
|
|
LastRequest = request;
|
|
LastBody = request.Content is null ? null : await request.Content.ReadAsStringAsync(cancellationToken);
|
|
return new HttpResponseMessage(StatusCode) { Content = new StringContent(ResponseBody) };
|
|
}
|
|
}
|
|
|
|
private static LineMessageChannel BuildChannel(CapturingHandler handler)
|
|
{
|
|
var http = new HttpClient(handler);
|
|
var options = Options.Create(new LineOptions { ChannelAccessToken = "tok", ChannelSecret = "sec" });
|
|
return new LineMessageChannel(http, options);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task PushToUserAsync_PostsTextMessage_WithBearerToken()
|
|
{
|
|
var handler = new CapturingHandler();
|
|
var channel = BuildChannel(handler);
|
|
|
|
var result = await channel.PushToUserAsync("U123", "hello");
|
|
|
|
Assert.True(result.Success);
|
|
Assert.Equal("https://api.line.me/v2/bot/message/push", handler.LastRequest!.RequestUri!.ToString());
|
|
Assert.Equal("Bearer", handler.LastRequest.Headers.Authorization!.Scheme);
|
|
Assert.Equal("tok", handler.LastRequest.Headers.Authorization.Parameter);
|
|
|
|
using var doc = JsonDocument.Parse(handler.LastBody!);
|
|
Assert.Equal("U123", doc.RootElement.GetProperty("to").GetString());
|
|
Assert.Equal("hello", doc.RootElement.GetProperty("messages")[0].GetProperty("text").GetString());
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ReplyAsync_PostsToReplyEndpoint_WithReplyToken()
|
|
{
|
|
var handler = new CapturingHandler();
|
|
var channel = BuildChannel(handler);
|
|
|
|
await channel.ReplyAsync("RTOKEN", "hi back");
|
|
|
|
Assert.Equal("https://api.line.me/v2/bot/message/reply", handler.LastRequest!.RequestUri!.ToString());
|
|
using var doc = JsonDocument.Parse(handler.LastBody!);
|
|
Assert.Equal("RTOKEN", doc.RootElement.GetProperty("replyToken").GetString());
|
|
}
|
|
|
|
[Fact]
|
|
public async Task PushToUserAsync_ReturnsFailure_OnNonSuccessStatus()
|
|
{
|
|
var handler = new CapturingHandler { StatusCode = HttpStatusCode.TooManyRequests, ResponseBody = "quota" };
|
|
var channel = BuildChannel(handler);
|
|
|
|
var result = await channel.PushToUserAsync("U123", "hello");
|
|
|
|
Assert.False(result.Success);
|
|
Assert.Contains("429", result.Error);
|
|
}
|
|
}
|