forked from Manuel/meeting-assistant
ci: consolidate platform pipelines and test prerequisites on macOS support
This commit is contained in:
1 parent
1b19b08f2e
commit
728e66dd72
76 files changed
+7477
-239
No files matched your search
@@ -0,0 +1,129 @@
|
||||
using MeetingAssistant.Calendar;
|
||||
using MeetingAssistant.MacOs;
|
||||
using MeetingAssistant.Notifications;
|
||||
using MeetingAssistant.Recording;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
|
||||
namespace MeetingAssistant.Tests;
|
||||
|
||||
public sealed class MacOsUserPromptTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("yes", true)]
|
||||
[InlineData("no", false)]
|
||||
public async Task ApprovalWaitsForAnExplicitDesktopDecision(string action, bool approved)
|
||||
{
|
||||
using var lifetime = new TestApplicationLifetime();
|
||||
using var store = CreateStore(lifetime);
|
||||
IAgentApprovalPromptService prompts = new MacOsAgentApprovalPromptService(store);
|
||||
var decision = prompts.ConfirmAsync(new AgentApprovalPrompt("Project requested", "Associate Alpha?",
|
||||
TimeSpan.FromMinutes(10)), CancellationToken.None);
|
||||
Assert.False(decision.IsCompleted);
|
||||
var request = Assert.Single(store.List());
|
||||
Assert.Equal("agent-approval", request.Kind);
|
||||
Assert.Equal(["yes", "no"], request.Actions.Select(item => item.Id));
|
||||
Assert.Equal(DesktopUserRequestRespondResult.Accepted, await store.RespondAsync(request.Id, action));
|
||||
Assert.Equal(approved, await decision);
|
||||
Assert.Empty(store.List());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InactivityPromptReturnsImmediatelyAndOffersPauseWithOriginLifetime()
|
||||
{
|
||||
using var lifetime = new TestApplicationLifetime();
|
||||
using var origin = new CancellationTokenSource();
|
||||
var clock = new ManualDesktopRequestTimeProvider();
|
||||
using var store = new DesktopUserRequestStore(clock, lifetime, NullLogger<DesktopUserRequestStore>.Instance);
|
||||
IMeetingInactivityPromptService prompts = new MacOsMeetingInactivityPromptService(store);
|
||||
MeetingInactivityPromptResponse? received = null;
|
||||
CancellationToken receivedToken = default;
|
||||
var showing = prompts.ShowStopPromptAsync(
|
||||
new MeetingInactivityPromptRequest(TimeSpan.FromMinutes(2), clock.GetUtcNow(), 1, TimeSpan.FromMinutes(2)),
|
||||
(response, token) =>
|
||||
{
|
||||
received = response;
|
||||
receivedToken = token;
|
||||
return Task.CompletedTask;
|
||||
}, origin.Token);
|
||||
Assert.True(showing.IsCompletedSuccessfully);
|
||||
var request = Assert.Single(store.List());
|
||||
Assert.Equal("meeting-inactivity", request.Kind);
|
||||
Assert.Equal(["stop", "continue", "pause"], request.Actions.Select(item => item.Id));
|
||||
Assert.Equal(DateTimeOffset.Parse("2026-10-03T10:01:00Z"), request.ExpiresAt);
|
||||
Assert.Equal(DesktopUserRequestRespondResult.Accepted, await store.RespondAsync(request.Id, "pause"));
|
||||
Assert.Equal(MeetingInactivityPromptResponse.Pause, received);
|
||||
Assert.Equal(origin.Token, receivedToken);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true, "attach-metadata", MeetingStartPromptResponse.AttachMetadataToCurrentMeeting)]
|
||||
[InlineData(false, "skip", MeetingStartPromptResponse.Skip)]
|
||||
public async Task CalendarPromptReturnsImmediatelyAndPreservesOfferedActions(bool canAttach, string action, MeetingStartPromptResponse expected)
|
||||
{
|
||||
using var lifetime = new TestApplicationLifetime();
|
||||
var clock = new ManualDesktopRequestTimeProvider();
|
||||
using var store = new DesktopUserRequestStore(clock, lifetime, NullLogger<DesktopUserRequestStore>.Instance);
|
||||
IMeetingStartPromptService prompts = new MacOsMeetingStartPromptService(store, clock);
|
||||
var meeting = new CalendarMeeting("event-1", "Alpha planning", clock.GetUtcNow(), clock.GetUtcNow().AddMinutes(2));
|
||||
MeetingStartPromptResponse? received = null;
|
||||
var showing = prompts.ShowPromptAsync(new MeetingStartPromptRequest(meeting, canAttach),
|
||||
(response, _) => { received = response; return Task.CompletedTask; }, CancellationToken.None);
|
||||
Assert.True(showing.IsCompletedSuccessfully);
|
||||
var request = Assert.Single(store.List());
|
||||
Assert.Equal("meeting-start", request.Kind);
|
||||
Assert.Contains("Alpha planning", request.Message);
|
||||
Assert.Equal(DateTimeOffset.Parse("2026-10-03T10:02:00Z"), request.ExpiresAt);
|
||||
Assert.Equal(canAttach, request.Actions.Any(item => item.Id == "attach-metadata"));
|
||||
Assert.Equal(DesktopUserRequestRespondResult.Accepted, await store.RespondAsync(request.Id, action));
|
||||
Assert.Equal(expected, received);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(false)]
|
||||
[InlineData(true)]
|
||||
public async Task ApprovalExpirationOrOriginCancellationNeverGrantsConsent(bool cancelOrigin)
|
||||
{
|
||||
using var lifetime = new TestApplicationLifetime();
|
||||
using var origin = new CancellationTokenSource();
|
||||
var clock = new ManualDesktopRequestTimeProvider();
|
||||
using var store = new DesktopUserRequestStore(clock, lifetime, NullLogger<DesktopUserRequestStore>.Instance);
|
||||
IAgentApprovalPromptService prompts = new MacOsAgentApprovalPromptService(store);
|
||||
var decision = prompts.ConfirmAsync(new AgentApprovalPrompt("Workflow requested", "Update matching rule?",
|
||||
TimeSpan.FromMinutes(10)), origin.Token);
|
||||
var request = Assert.Single(store.List());
|
||||
if (cancelOrigin)
|
||||
{
|
||||
await origin.CancelAsync();
|
||||
await Assert.ThrowsAnyAsync<OperationCanceledException>(() => decision);
|
||||
}
|
||||
else
|
||||
{
|
||||
clock.Advance(TimeSpan.FromMinutes(10));
|
||||
Assert.False(await decision);
|
||||
}
|
||||
Assert.Empty(store.List());
|
||||
Assert.Equal(DesktopUserRequestRespondResult.NoLongerPending, await store.RespondAsync(request.Id, "yes"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task DismissingInactivityLeavesUnrelatedApprovalPending()
|
||||
{
|
||||
using var lifetime = new TestApplicationLifetime();
|
||||
using var store = CreateStore(lifetime);
|
||||
IAgentApprovalPromptService approvals = new MacOsAgentApprovalPromptService(store);
|
||||
var decision = approvals.ConfirmAsync(new AgentApprovalPrompt("Project requested", "Associate Alpha?",
|
||||
TimeSpan.FromMinutes(10)), CancellationToken.None);
|
||||
var approval = Assert.Single(store.List());
|
||||
IMeetingInactivityPromptService inactivity = new MacOsMeetingInactivityPromptService(store);
|
||||
await inactivity.ShowStopPromptAsync(new MeetingInactivityPromptRequest(TimeSpan.FromMinutes(2),
|
||||
DateTimeOffset.UtcNow, 1, TimeSpan.FromMinutes(2)), (_, _) => Task.CompletedTask, CancellationToken.None);
|
||||
Assert.Equal(2, store.List().Count);
|
||||
await inactivity.DismissAllAsync(CancellationToken.None);
|
||||
Assert.Equal(approval.Id, Assert.Single(store.List()).Id);
|
||||
await store.RespondAsync(approval.Id, "no");
|
||||
Assert.False(await decision);
|
||||
}
|
||||
|
||||
private static DesktopUserRequestStore CreateStore(TestApplicationLifetime lifetime) => new(
|
||||
TimeProvider.System, lifetime, NullLogger<DesktopUserRequestStore>.Instance);
|
||||
}
|
||||
Reference in new issue
Block a user