Files
notes/NotesTests/AudioNotePayloadTests.swift
T
rzen 86d74806c9 Add voice notes: on-device transcription, multi-language, watch capture
- Schema v2: Note.AudioInfo, .m4a sidecar next to the note JSON in iCloud
- AudioRecorderService (iOS/macOS) + SpeechAnalyzer transcription pipeline
  with enabled-language set and confidence-based auto-pick, re-transcribe menu
- Settings > Transcription > Languages with asset download/reserve handling
- watchOS app + accessory complication: one-button recorder, WCSession
  transferFile to phone, WatchInbox staging, direct-upsert ingestion
- Player UI, transcription status chips, quick-capture mic in notes list
- Version 0.2, changelog + README updated
2026-07-15 13:30:43 -04:00

84 lines
3.0 KiB
Swift

import Foundation
import Testing
@testable import Notes
struct AudioNotePayloadTests {
@Test func metadataRoundTrips() throws {
let payload = AudioNotePayload(
id: "01J8Z3M9K7QW2R4T6Y8B0C1D2E",
recordedAt: Date(timeIntervalSince1970: 1_700_000_000),
duration: 12.5,
timeZoneID: "Europe/Berlin"
)
let decoded = try #require(AudioNotePayload(metadata: payload.metadata()))
#expect(decoded == payload)
}
@Test func metadataRoundTripsWithoutTimeZone() throws {
let payload = AudioNotePayload(
id: "01J8Z3M9K7QW2R4T6Y8B0C1D2E",
recordedAt: Date(timeIntervalSince1970: 1_700_000_100),
duration: 4,
timeZoneID: nil
)
let dict = payload.metadata()
#expect(dict["tz"] == nil)
let decoded = try #require(AudioNotePayload(metadata: dict))
#expect(decoded == payload)
}
/// A survivable trip through actual plist serialization — the metadata really
/// crosses WatchConnectivity as a plist dictionary.
@Test func metadataSurvivesPlistSerialization() throws {
let payload = AudioNotePayload(
id: "01J8Z3M9K7QW2R4T6Y8B0C1D2E",
recordedAt: Date(timeIntervalSince1970: 1_700_000_050),
duration: 7.25,
timeZoneID: "America/Los_Angeles"
)
let data = try PropertyListSerialization.data(
fromPropertyList: payload.metadata(), format: .binary, options: 0)
let dict = try #require(
try PropertyListSerialization.propertyList(from: data, options: [], format: nil) as? [String: Any])
let decoded = try #require(AudioNotePayload(metadata: dict))
#expect(decoded.id == payload.id)
#expect(decoded.duration == payload.duration)
#expect(decoded.timeZoneID == payload.timeZoneID)
#expect(abs(decoded.recordedAt.timeIntervalSince(payload.recordedAt)) < 0.001)
}
@Test func decodeRejectsUnknownNewerVersion() {
var dict = AudioNotePayload(
id: "01J8Z3M9K7QW2R4T6Y8B0C1D2E",
recordedAt: Date(),
duration: 3,
timeZoneID: nil
).metadata()
dict["v"] = AudioNotePayload.currentVersion + 1
#expect(AudioNotePayload(metadata: dict) == nil)
}
@Test func decodeRejectsMissingVersion() {
let dict: [String: Any] = [
"id": "01J8Z3M9K7QW2R4T6Y8B0C1D2E",
"recordedAt": Date(),
"duration": 3.0,
]
#expect(AudioNotePayload(metadata: dict) == nil)
}
@Test func decodeRejectsMissingRequiredField() {
// Version present, but no duration.
let dict: [String: Any] = [
"v": AudioNotePayload.currentVersion,
"id": "01J8Z3M9K7QW2R4T6Y8B0C1D2E",
"recordedAt": Date(),
]
#expect(AudioNotePayload(metadata: dict) == nil)
}
@Test func decodeRejectsEmptyMetadata() {
#expect(AudioNotePayload(metadata: [:]) == nil)
}
}