Implement meeting assistant v1

This commit is contained in:
2026-05-20 02:06:16 +02:00
parent 90df1edc03
commit 0297bcc0f6
120 changed files with 11883 additions and 180 deletions
@@ -0,0 +1,72 @@
using MeetingAssistant.MeetingNotes;
namespace MeetingAssistant.Tests;
public sealed class OutlookMeetingCandidateSelectorTests
{
[Fact]
public void SelectIgnoresOverlappingMeetingThatEndsInLessThanFiveMinutes()
{
var now = new DateTime(2026, 5, 20, 10, 0, 0);
var selected = OutlookMeetingCandidateSelector.Select(
[
new Candidate(now.AddMinutes(-25), now.AddMinutes(4))
],
now,
candidate => candidate.Start,
candidate => candidate.End);
Assert.Null(selected);
}
[Fact]
public void SelectPrefersSingleGoodOverlappingMeetingOverUpcomingMeeting()
{
var now = new DateTime(2026, 5, 20, 10, 0, 0);
var overlap = new Candidate(now.AddMinutes(-10), now.AddMinutes(30));
var upcoming = new Candidate(now.AddMinutes(3), now.AddMinutes(33));
var selected = OutlookMeetingCandidateSelector.Select(
[upcoming, overlap],
now,
candidate => candidate.Start,
candidate => candidate.End);
Assert.Same(overlap, selected);
}
[Fact]
public void SelectUsesSingleTeamsMeetingStartingWithinFiveMinutesWhenNoGoodOverlapExists()
{
var now = new DateTime(2026, 5, 20, 10, 0, 0);
var endingOverlap = new Candidate(now.AddMinutes(-25), now.AddMinutes(2));
var upcoming = new Candidate(now.AddMinutes(5), now.AddMinutes(35));
var selected = OutlookMeetingCandidateSelector.Select(
[endingOverlap, upcoming],
now,
candidate => candidate.Start,
candidate => candidate.End);
Assert.Same(upcoming, selected);
}
[Fact]
public void SelectRejectsAmbiguousUpcomingMeetings()
{
var now = new DateTime(2026, 5, 20, 10, 0, 0);
var selected = OutlookMeetingCandidateSelector.Select(
[
new Candidate(now.AddMinutes(2), now.AddMinutes(32)),
new Candidate(now.AddMinutes(4), now.AddMinutes(34))
],
now,
candidate => candidate.Start,
candidate => candidate.End);
Assert.Null(selected);
}
private sealed record Candidate(DateTime Start, DateTime End);
}