Public Access
refactor: tighten tray menu section handling
PR and Push Build/Test / build-and-test (push) Successful in 10m51s
PR and Push Build/Test / build-and-test (push) Successful in 10m51s
This commit is contained in:
@@ -13,22 +13,23 @@ public sealed class TaskbarIconTests
|
||||
{
|
||||
var menu = MeetingTaskbarMenuBuilder.Build(
|
||||
Status(),
|
||||
[Profile("default", "Ctrl+Alt+M"), Profile("english", "Ctrl+Alt+L")]);
|
||||
[Profile("default", "Ctrl+Alt+M"), Profile("english", "Ctrl+Alt+L")],
|
||||
[new MicrophoneDevice("integrated", "integrated microphone")],
|
||||
"integrated");
|
||||
|
||||
Assert.Equal(RecordingProcessState.Idle, menu.State);
|
||||
Assert.Contains(menu.Items, item =>
|
||||
item.Action == MeetingTaskbarAction.EditRules &&
|
||||
item.Text == "Open agent");
|
||||
Assert.Contains(menu.Items, item =>
|
||||
item.Action == MeetingTaskbarAction.StartRecording &&
|
||||
item.ProfileName == "default" &&
|
||||
item.Text == "Start meeting recording (default)\tCtrl+Alt+M");
|
||||
Assert.Contains(menu.Items, item =>
|
||||
item.Action == MeetingTaskbarAction.StartRecording &&
|
||||
item.ProfileName == "english" &&
|
||||
item.Text == "Start meeting recording (english)\tCtrl+Alt+L");
|
||||
Assert.DoesNotContain(menu.Items, item => item.Action == MeetingTaskbarAction.StopRecording);
|
||||
Assert.DoesNotContain(menu.Items, item => item.Action == MeetingTaskbarAction.AbortRecording);
|
||||
AssertMenuLayout(
|
||||
menu,
|
||||
("Open agent", MeetingTaskbarAction.EditRules, false),
|
||||
("Microphone", MeetingTaskbarAction.OpenSubmenu, true),
|
||||
("Start meeting recording (default)\tCtrl+Alt+M", MeetingTaskbarAction.StartRecording, false),
|
||||
("Start meeting recording (english)\tCtrl+Alt+L", MeetingTaskbarAction.StartRecording, false),
|
||||
("Exit", MeetingTaskbarAction.Exit, true));
|
||||
Assert.Equal(
|
||||
["default", "english"],
|
||||
menu.Items
|
||||
.Where(item => item.Action == MeetingTaskbarAction.StartRecording)
|
||||
.Select(item => item.ProfileName));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -69,45 +70,32 @@ public sealed class TaskbarIconTests
|
||||
"integrated");
|
||||
|
||||
Assert.Equal(RecordingProcessState.Recording, menu.State);
|
||||
Assert.Collection(
|
||||
menu.Items,
|
||||
item =>
|
||||
AssertMenuLayout(
|
||||
menu,
|
||||
("Open agent", MeetingTaskbarAction.EditRules, false),
|
||||
("Finish meeting", MeetingTaskbarAction.StopRecording, true),
|
||||
("Microphone", MeetingTaskbarAction.OpenSubmenu, true),
|
||||
("Cancel meeting recording and discard", MeetingTaskbarAction.AbortRecording, false),
|
||||
("Switch to english\tCtrl+Alt+L", MeetingTaskbarAction.SwitchProfile, false),
|
||||
("Exit", MeetingTaskbarAction.Exit, true));
|
||||
Assert.Equal(
|
||||
"english",
|
||||
Assert.Single(menu.Items, item => item.Action == MeetingTaskbarAction.SwitchProfile).ProfileName);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RecordingMenuKeepsFinishMeetingIsolatedWithoutMicrophones()
|
||||
{
|
||||
Assert.Equal("Open agent", item.Text);
|
||||
Assert.Equal(MeetingTaskbarAction.EditRules, item.Action);
|
||||
Assert.False(item.StartsSection);
|
||||
},
|
||||
item =>
|
||||
{
|
||||
Assert.Equal("Finish meeting", item.Text);
|
||||
Assert.Equal(MeetingTaskbarAction.StopRecording, item.Action);
|
||||
Assert.True(item.StartsSection);
|
||||
},
|
||||
item =>
|
||||
{
|
||||
Assert.Equal("Microphone", item.Text);
|
||||
Assert.Equal(MeetingTaskbarAction.OpenSubmenu, item.Action);
|
||||
Assert.True(item.StartsSection);
|
||||
},
|
||||
item =>
|
||||
{
|
||||
Assert.Equal("Cancel meeting recording and discard", item.Text);
|
||||
Assert.Equal(MeetingTaskbarAction.AbortRecording, item.Action);
|
||||
Assert.False(item.StartsSection);
|
||||
},
|
||||
item =>
|
||||
{
|
||||
Assert.Equal("Switch to english\tCtrl+Alt+L", item.Text);
|
||||
Assert.Equal(MeetingTaskbarAction.SwitchProfile, item.Action);
|
||||
Assert.Equal("english", item.ProfileName);
|
||||
Assert.False(item.StartsSection);
|
||||
},
|
||||
item =>
|
||||
{
|
||||
Assert.Equal("Exit", item.Text);
|
||||
Assert.Equal(MeetingTaskbarAction.Exit, item.Action);
|
||||
Assert.True(item.StartsSection);
|
||||
});
|
||||
var menu = MeetingTaskbarMenuBuilder.Build(
|
||||
Status(isRecording: true, state: RecordingProcessState.Recording, profile: "default"),
|
||||
[Profile("default")]);
|
||||
|
||||
AssertMenuLayout(
|
||||
menu,
|
||||
("Open agent", MeetingTaskbarAction.EditRules, false),
|
||||
("Finish meeting", MeetingTaskbarAction.StopRecording, true),
|
||||
("Cancel meeting recording and discard", MeetingTaskbarAction.AbortRecording, true),
|
||||
("Exit", MeetingTaskbarAction.Exit, true));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -200,6 +188,15 @@ public sealed class TaskbarIconTests
|
||||
});
|
||||
}
|
||||
|
||||
private static void AssertMenuLayout(
|
||||
MeetingTaskbarMenu menu,
|
||||
params (string Text, MeetingTaskbarAction Action, bool StartsSection)[] expected)
|
||||
{
|
||||
Assert.Equal(
|
||||
expected,
|
||||
menu.Items.Select(item => (item.Text, item.Action, item.StartsSection)));
|
||||
}
|
||||
|
||||
private static RecordingStatus Status(
|
||||
bool isRecording = false,
|
||||
RecordingProcessState state = RecordingProcessState.Idle,
|
||||
|
||||
@@ -113,15 +113,15 @@ public static class MeetingTaskbarMenuBuilder
|
||||
|
||||
private static void AddSection(
|
||||
List<MeetingTaskbarMenuItem> items,
|
||||
List<MeetingTaskbarMenuItem> section)
|
||||
IReadOnlyList<MeetingTaskbarMenuItem> section)
|
||||
{
|
||||
if (section.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
section[0] = section[0] with { StartsSection = true };
|
||||
items.AddRange(section);
|
||||
items.Add(section[0] with { StartsSection = true });
|
||||
items.AddRange(section.Skip(1));
|
||||
}
|
||||
|
||||
private static string BuildTooltip(RecordingStatus status)
|
||||
|
||||
@@ -7,3 +7,9 @@
|
||||
|
||||
- [x] 2.1 Review the touched menu builder and renderer for DRYness, SOLID design, and simplicity while preserving behavior.
|
||||
- [x] 2.2 Run focused taskbar-menu tests, the Windows application build, the full solution tests, and strict OpenSpec validation.
|
||||
|
||||
## 3. Refactor Follow-up
|
||||
|
||||
- [x] 3.1 Lock down idle section boundaries and active-recording layout when no microphone is available.
|
||||
- [x] 3.2 Remove the tray-menu section helper's hidden input mutation without changing rendered behavior.
|
||||
- [x] 3.3 Run focused and full verification, then validate the OpenSpec change strictly.
|
||||
|
||||
Reference in New Issue
Block a user