X-Git-Url: https://git.giacomolli.uk/onechat/blobdiff_plain/5dbb2e42e88e78bfc79b473b5b1dc466d8dbbf62..HEAD:/voice_transcriber_test.go?ds=sidebyside diff --git a/voice_transcriber_test.go b/voice_transcriber_test.go index 58df9ea..c04d091 100644 --- a/voice_transcriber_test.go +++ b/voice_transcriber_test.go @@ -29,6 +29,7 @@ printf ' A made-up voice transcript.\n' > "$output.txt" printf 'private speech in process output' printf 'private speech in process errors' >&2 `) + data := []byte("made-up audio") text := transcriber.Text(t.Context(), store, data) require.Contains(t, text, "[voice ") @@ -57,10 +58,20 @@ func TestVoiceFailuresKeepStoredAudioAndSafeMarkers(t *testing.T) { name string script string }{ - {name: "failed process does not expose its errors", script: "echo secret-speech >&2; exit 1"}, - {name: "missing transcript gets a marker", script: "exit 0"}, - {name: "empty transcript gets a marker", script: "while [ \"$1\" != --output-file ]; do shift; done; shift; touch \"$1.txt\""}, + { + name: "failed process does not expose its errors", + script: "echo secret-speech >&2; exit 1", + }, + { + name: "missing transcript gets a marker", + script: "exit 0", + }, + { + name: "empty transcript gets a marker", + script: "while [ \"$1\" != --output-file ]; do shift; done; shift; touch \"$1.txt\"", + }, } + for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { store, transcriber := voiceTestInput(t, tc.script) @@ -107,6 +118,49 @@ func TestVoiceUnavailableAndStorageFailuresDoNotStopIntake(t *testing.T) { require.Equal(t, "(voice not stored)", transcriber.Text(t.Context(), store, []byte("audio"))) } +func TestVoiceBackupsKeepAudioButNotTemporaryTranscripts(t *testing.T) { + root := t.TempDir() + store := &VoiceStore{dir: filepath.Join(root, voiceDirName)} + name, err := store.Save([]byte("made-up backed-up audio")) + require.NoError(t, err) + + temp := filepath.Join(store.dir, ".transcript-in-progress") + require.NoError(t, os.Mkdir(temp, 0o700)) + require.NoError(t, os.WriteFile(filepath.Join(temp, "text.txt"), []byte("private temporary text"), 0o600)) + + target := t.TempDir() + require.NoError(t, backupCopy(t.Context(), root, target, filepath.Join(t.TempDir(), "backup.tar.gz"))) + require.FileExists(t, filepath.Join(target, voiceDirName, name)) + require.NoDirExists(t, filepath.Join(target, voiceDirName, ".transcript-in-progress")) + + archive := filepath.Join(t.TempDir(), "voice.tar.gz") + _, err = backupArchive(t.Context(), target, archive) + require.NoError(t, err) + + restored := t.TempDir() + require.NoError(t, backupExtract(t.Context(), archive, restored)) + + audio, err := os.ReadFile(filepath.Join(restored, voiceDirName, name)) + require.NoError(t, err) + require.Equal(t, []byte("made-up backed-up audio"), audio) + + info, err := os.Stat(filepath.Join(restored, voiceDirName, name)) + require.NoError(t, err) + require.Equal(t, os.FileMode(0o600), info.Mode().Perm()) +} + +func TestVoiceConfigReadsExplicitLocalPaths(t *testing.T) { + dir := t.TempDir() + configWriteTest(t, dir, `{"voice":{"transcriber":"local-whisper","model":"model.bin"}}`) + + config, err := loadConfig(dir) + require.NoError(t, err) + require.Equal(t, VoiceConfig{ + Transcriber: "local-whisper", + Model: "model.bin", + }, config.Voice) +} + func TestVoiceLookupHonorsExplicitThenNixThenPath(t *testing.T) { _, transcriber := voiceTestInput(t, "exit 0") valid := transcriber.config @@ -138,8 +192,11 @@ func TestVoiceLookupHonorsExplicitThenNixThenPath(t *testing.T) { available: true, }, { - name: "invalid explicit executable does not fall back", - config: VoiceConfig{Transcriber: "missing", Model: valid.Model}, + name: "invalid explicit executable does not fall back", + config: VoiceConfig{ + Transcriber: "missing", + Model: valid.Model, + }, program: valid.Transcriber, }, { @@ -153,6 +210,7 @@ func TestVoiceLookupHonorsExplicitThenNixThenPath(t *testing.T) { program: valid.Transcriber, }, } + for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { program, model, err := voiceLookup(tc.config, tc.program, tc.model)