Skip to content

Commit 41bad64

Browse files
committed
test(app): add tests for filename sanitization and invalid regex handling
- 5 tests for ProtocolGenerator filename sanitization (/, :, \, NUL) - 2 tests for MeetingDetector graceful handling of invalid regex patterns
1 parent ae89d7c commit 41bad64

File tree

2 files changed

+65
-0
lines changed

2 files changed

+65
-0
lines changed

app/MeetingTranscriber/Tests/MeetingDetectorTests.swift

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,4 +400,38 @@ final class MeetingDetectorTests: XCTestCase {
400400
// Should be detectable again immediately (no cooldown)
401401
XCTAssertNotNil(detector.checkOnce())
402402
}
403+
404+
// MARK: - Invalid Regex Graceful Handling
405+
406+
func testInvalidMeetingRegexSkippedGracefully() {
407+
// Invalid regex should be silently skipped, not crash
408+
let badPattern = AppMeetingPattern(
409+
appName: "BadApp",
410+
ownerNames: ["BadApp"],
411+
meetingPatterns: ["[invalid(regex"],
412+
idlePatterns: [],
413+
)
414+
let detector = MeetingDetector(patterns: [badPattern])
415+
// Should not crash, and no windows match
416+
detector.windowListProvider = {
417+
[makeWindow(owner: "BadApp", name: "Some Title")]
418+
}
419+
XCTAssertNil(detector.checkOnce())
420+
}
421+
422+
func testMixedValidAndInvalidRegexKeepsValid() {
423+
// Valid patterns still work even if some are invalid
424+
let mixedPattern = AppMeetingPattern(
425+
appName: "Microsoft Teams",
426+
ownerNames: ["Microsoft Teams"],
427+
meetingPatterns: ["[bad(", ".*\\| Microsoft Teams$"],
428+
idlePatterns: [],
429+
)
430+
let detector = MeetingDetector(patterns: [mixedPattern], confirmationCount: 1)
431+
detector.windowListProvider = {
432+
[makeWindow(owner: "Microsoft Teams", name: "Standup | Microsoft Teams")]
433+
}
434+
// Valid regex should still match
435+
XCTAssertNotNil(detector.checkOnce())
436+
}
403437
}

app/MeetingTranscriber/Tests/ProtocolGeneratorTests.swift

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,37 @@ final class ProtocolGeneratorTests: XCTestCase {
100100
XCTAssertTrue(txt.hasSuffix(".txt"))
101101
}
102102

103+
// MARK: - Filename Sanitization
104+
105+
func testFilenameSanitizesSlashes() {
106+
let name = ProtocolGenerator.filename(title: "Code/Review", ext: "md")
107+
XCTAssertFalse(name.contains("/"))
108+
XCTAssertTrue(name.contains("codereview"))
109+
}
110+
111+
func testFilenameSanitizesColons() {
112+
let name = ProtocolGenerator.filename(title: "Meeting: Planning", ext: "md")
113+
XCTAssertFalse(name.contains(":"))
114+
XCTAssertTrue(name.contains("meeting_planning"))
115+
}
116+
117+
func testFilenameSanitizesBackslashes() {
118+
let name = ProtocolGenerator.filename(title: "Path\\Name", ext: "md")
119+
XCTAssertFalse(name.contains("\\"))
120+
XCTAssertTrue(name.contains("pathname"))
121+
}
122+
123+
func testFilenameSanitizesNullBytes() {
124+
let name = ProtocolGenerator.filename(title: "Test\0Title", ext: "md")
125+
XCTAssertFalse(name.contains("\0"))
126+
XCTAssertTrue(name.contains("testtitle"))
127+
}
128+
129+
func testFilenameSanitizesMultipleForbiddenChars() {
130+
let name = ProtocolGenerator.filename(title: "A/B:C\\D", ext: "txt")
131+
XCTAssertTrue(name.hasSuffix("_abcd.txt"))
132+
}
133+
103134
// MARK: - File Save Operations
104135

105136
func testSaveTranscript() throws {

0 commit comments

Comments
 (0)