mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-10-21 15:02:21 +02:00
146 lines
4.5 KiB
Dart
146 lines
4.5 KiB
Dart
import 'dart:io';
|
|
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:spotiflac_android/services/ffmpeg_support.dart';
|
|
|
|
void main() {
|
|
late Directory directory;
|
|
setUp(() async {
|
|
directory = await Directory.systemTemp.createTemp('ffmpeg-promotion-');
|
|
});
|
|
tearDown(() async => directory.delete(recursive: true));
|
|
|
|
Future<File> write(String name, String data) =>
|
|
File('${directory.path}/$name').writeAsString(data);
|
|
|
|
test(
|
|
'metadata promotion publishes the complete output and removes staging',
|
|
() async {
|
|
final target = await write('song.opus', 'original');
|
|
final temp = await write('temp.opus', 'tagged');
|
|
expect(
|
|
await FFmpegOutput.promote(
|
|
temp.path,
|
|
target.path,
|
|
onError: (e) => fail('$e'),
|
|
),
|
|
isTrue,
|
|
);
|
|
expect(await target.readAsString(), 'tagged');
|
|
expect(await directory.list().map((file) => file.path).toList(), [
|
|
target.path,
|
|
]);
|
|
},
|
|
);
|
|
|
|
test('an empty successful temp output cannot replace the original', () async {
|
|
final target = await write('song.opus', 'original');
|
|
final temp = await write('temp.opus', '');
|
|
expect(
|
|
await FFmpegOutput.promote(
|
|
temp.path,
|
|
target.path,
|
|
onError: (e) => fail('$e'),
|
|
),
|
|
isFalse,
|
|
);
|
|
expect(await target.readAsString(), 'original');
|
|
expect(await directory.list().map((file) => file.path).toList(), [
|
|
target.path,
|
|
]);
|
|
});
|
|
|
|
test('missing temp output reports missing and keeps the original', () async {
|
|
final target = await write('song.opus', 'original');
|
|
var missing = false;
|
|
expect(
|
|
await FFmpegOutput.promote(
|
|
'${directory.path}/missing.opus',
|
|
target.path,
|
|
onMissing: () => missing = true,
|
|
onError: (e) => fail('$e'),
|
|
),
|
|
isFalse,
|
|
);
|
|
expect(missing, isTrue);
|
|
expect(await target.readAsString(), 'original');
|
|
});
|
|
|
|
test('a failed publication restores the original from its backup', () async {
|
|
final target = await write('song.flac', 'original');
|
|
final staging = await write('temp.flac', 'converted');
|
|
final blocked = await Directory('${directory.path}/blocked.flac').create();
|
|
await File('${blocked.path}/keep').writeAsString('untouched');
|
|
Object? error;
|
|
var restoredBeforeCallback = false;
|
|
expect(
|
|
await FFmpegOutput.finalize(
|
|
plan: FFmpegOutputPlan(
|
|
workingPath: staging.path,
|
|
finalPath: blocked.path,
|
|
),
|
|
inputPath: target.path,
|
|
deleteOriginal: true,
|
|
onError: (e) {
|
|
error = e;
|
|
restoredBeforeCallback =
|
|
target.readAsStringSync() == 'original' && !staging.existsSync();
|
|
},
|
|
),
|
|
isNull,
|
|
);
|
|
expect(error, isA<FileSystemException>());
|
|
expect(restoredBeforeCallback, isTrue);
|
|
expect(await target.readAsString(), 'original');
|
|
expect(await File('${blocked.path}/keep').readAsString(), 'untouched');
|
|
expect(await staging.exists(), isFalse);
|
|
expect(await directory.list().length, 2);
|
|
});
|
|
|
|
test('promotion reports publication errors after staging cleanup', () async {
|
|
final target = await Directory('${directory.path}/blocked.opus').create();
|
|
final original = await File(
|
|
'${target.path}/keep',
|
|
).writeAsString('original');
|
|
final temp = await write('temp.opus', 'tagged');
|
|
Object? error;
|
|
var stagingRemained = true;
|
|
expect(
|
|
await FFmpegOutput.promote(
|
|
temp.path,
|
|
target.path,
|
|
onError: (e) {
|
|
error = e;
|
|
stagingRemained = directory.listSync().any(
|
|
(entry) => entry.path.contains('.spotiflac-staging-'),
|
|
);
|
|
},
|
|
),
|
|
isFalse,
|
|
);
|
|
expect(error, isA<FileSystemException>());
|
|
expect(stagingRemained, isFalse);
|
|
expect(await original.readAsString(), 'original');
|
|
expect(await temp.exists(), isFalse);
|
|
expect(await directory.list().length, 1);
|
|
});
|
|
|
|
test('a staging reservation failure preserves both existing files', () async {
|
|
final parent = await write('parent', 'keep parent');
|
|
final temp = await write('temp.opus', 'tagged');
|
|
Object? error;
|
|
expect(
|
|
await FFmpegOutput.promote(
|
|
temp.path,
|
|
'${parent.path}/song.opus',
|
|
onError: (e) => error = e,
|
|
),
|
|
isFalse,
|
|
);
|
|
expect(error, isA<FileSystemException>());
|
|
expect(await parent.readAsString(), 'keep parent');
|
|
expect(await temp.exists(), isFalse);
|
|
expect(await directory.list().length, 1);
|
|
});
|
|
}
|