forked from Manuel/meeting-assistant
feat(macos): enable meeting integrations
This commit is contained in:
@@ -4,8 +4,6 @@ using MeetingAssistant.Speakers;
|
||||
using MeetingAssistant.Workflow;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
|
||||
#pragma warning disable CA1416
|
||||
|
||||
@@ -117,11 +115,7 @@ public sealed class MeetingScreenshotServiceTests
|
||||
var croppedPath = Assert.Single(Directory.GetFiles(
|
||||
Path.Combine(Path.GetDirectoryName(fixture.Artifacts.AssistantContextPath)!, "Attachments"),
|
||||
"*-cropped.png"));
|
||||
using (var cropped = new Bitmap(croppedPath))
|
||||
{
|
||||
Assert.Equal(2, cropped.Width);
|
||||
Assert.Equal(2, cropped.Height);
|
||||
}
|
||||
Assert.Equal((2, 2), PngTestFixture.ReadDimensions(await File.ReadAllBytesAsync(croppedPath)));
|
||||
|
||||
var context = await File.ReadAllTextAsync(fixture.Artifacts.AssistantContextPath);
|
||||
var screenshotIndex = context.IndexOf("![Screenshot 00:00:10]", StringComparison.Ordinal);
|
||||
@@ -133,6 +127,38 @@ public sealed class MeetingScreenshotServiceTests
|
||||
Assert.Contains("Shared screen text", context);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CaptureKeepsSuccessfulOcrTextWhenCropperRejectsCoordinates()
|
||||
{
|
||||
var fixture = await ScreenshotFixture.CreateAsync(options =>
|
||||
{
|
||||
options.Screenshots.Ocr.Enabled = true;
|
||||
});
|
||||
var ocr = new CapturingScreenshotOcrClient(
|
||||
"Readable text survives.",
|
||||
new ScreenshotCropCoordinates(99, 99, 10, 10));
|
||||
var service = fixture.CreateService(
|
||||
new FixedScreenshotCapture(CreatePngBytes(4, 4)),
|
||||
ocr,
|
||||
screenshotImageCropper: new RejectingScreenshotImageCropper());
|
||||
|
||||
await service.CaptureAsync(
|
||||
fixture.Artifacts,
|
||||
DateTimeOffset.Parse("2026-05-26T10:00:00+02:00"),
|
||||
DateTimeOffset.Parse("2026-05-26T10:00:10+02:00"),
|
||||
fixture.Options,
|
||||
CancellationToken.None);
|
||||
await service.WaitForPendingOcrAsync(
|
||||
fixture.Artifacts,
|
||||
TimeSpan.FromSeconds(5),
|
||||
CancellationToken.None);
|
||||
|
||||
var context = await File.ReadAllTextAsync(fixture.Artifacts.AssistantContextPath);
|
||||
Assert.Contains("Readable text survives.", context);
|
||||
Assert.DoesNotContain("_OCR failed", context);
|
||||
Assert.DoesNotContain("![Cropped screenshot]", context);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CaptureAddsOcrAttendeesToMeetingNoteThroughCanonicalizer()
|
||||
{
|
||||
@@ -454,7 +480,8 @@ public sealed class MeetingScreenshotServiceTests
|
||||
IActiveWindowScreenshotCapture capture,
|
||||
IScreenshotOcrClient ocrClient,
|
||||
ISpeakerIdentityAttendeeCanonicalizer? attendeeCanonicalizer = null,
|
||||
IMeetingWorkflowEngine? meetingWorkflowEngine = null)
|
||||
IMeetingWorkflowEngine? meetingWorkflowEngine = null,
|
||||
IScreenshotImageCropper? screenshotImageCropper = null)
|
||||
{
|
||||
return new MeetingScreenshotService(
|
||||
capture,
|
||||
@@ -462,12 +489,28 @@ public sealed class MeetingScreenshotServiceTests
|
||||
NoteStore,
|
||||
attendeeCanonicalizer ?? PassthroughSpeakerIdentityAttendeeCanonicalizer.Instance,
|
||||
ocrClient,
|
||||
screenshotImageCropper ??
|
||||
capture as IScreenshotImageCropper ??
|
||||
new UnavailableScreenshotImageCropper(),
|
||||
NullLogger<MeetingScreenshotService>.Instance,
|
||||
meetingWorkflowEngine);
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class FixedScreenshotCapture : IActiveWindowScreenshotCapture
|
||||
private sealed class RejectingScreenshotImageCropper : IScreenshotImageCropper
|
||||
{
|
||||
public Task<string?> SaveCroppedScreenshotAsync(
|
||||
string screenshotPath,
|
||||
ScreenshotCropCoordinates crop,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
throw new InvalidDataException("The crop is outside image bounds.");
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class FixedScreenshotCapture :
|
||||
IActiveWindowScreenshotCapture,
|
||||
IScreenshotImageCropper
|
||||
{
|
||||
private readonly byte[] bytes;
|
||||
|
||||
@@ -480,6 +523,21 @@ public sealed class MeetingScreenshotServiceTests
|
||||
{
|
||||
return Task.FromResult(new ActiveWindowScreenshot(bytes, "Demo Window"));
|
||||
}
|
||||
|
||||
public async Task<string?> SaveCroppedScreenshotAsync(
|
||||
string screenshotPath,
|
||||
ScreenshotCropCoordinates crop,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var croppedPath = Path.Combine(
|
||||
Path.GetDirectoryName(screenshotPath)!,
|
||||
$"{Path.GetFileNameWithoutExtension(screenshotPath)}-cropped.png");
|
||||
await File.WriteAllBytesAsync(
|
||||
croppedPath,
|
||||
PngTestFixture.Solid(2, 2),
|
||||
cancellationToken);
|
||||
return croppedPath;
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class CapturingScreenshotOcrClient : IScreenshotOcrClient
|
||||
@@ -614,15 +672,7 @@ public sealed class MeetingScreenshotServiceTests
|
||||
|
||||
private static byte[] CreatePngBytes(int width, int height)
|
||||
{
|
||||
using var bitmap = new Bitmap(width, height);
|
||||
using (var graphics = Graphics.FromImage(bitmap))
|
||||
{
|
||||
graphics.Clear(Color.White);
|
||||
}
|
||||
|
||||
using var stream = new MemoryStream();
|
||||
bitmap.Save(stream, ImageFormat.Png);
|
||||
return stream.ToArray();
|
||||
return PngTestFixture.Solid(width, height);
|
||||
}
|
||||
|
||||
private static string ExtractScreenshotOcrId(string context)
|
||||
|
||||
Reference in New Issue
Block a user