Ocideck/test/image_service_test.dart
Brenno de Winter dd2e91d61b Initial commit: OciDeck Marp presentation builder
Flutter desktop app for building Marp presentations via structured
slide editors, with live preview, fullscreen presenter, and PDF/PPTX
export. Includes Makefile quality gate, CI workflow, and full test suite.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 23:28:39 +02:00

124 lines
4.2 KiB
Dart

import 'dart:typed_data';
import 'dart:io';
import 'package:flutter_test/flutter_test.dart';
import 'package:ocideck/models/slide.dart';
import 'package:ocideck/services/image_service.dart';
import 'package:path/path.dart' as p;
void main() {
late Directory tmp;
final service = ImageService();
setUp(() => tmp = Directory.systemTemp.createTempSync('ocideck_img'));
tearDown(() => tmp.deleteSync(recursive: true));
group('resolve', () {
test('returns empty for an empty path', () {
expect(service.resolve('', '/project'), '');
});
test('returns absolute paths unchanged', () {
expect(service.resolve('/abs/pic.png', '/project'), '/abs/pic.png');
});
test('joins relative paths with the project path', () {
expect(
service.resolve('images/pic.png', '/project'),
p.join('/project', 'images/pic.png'),
);
});
});
group('copyImagesToProject', () {
test(
'copies an absolute image into images/ and rewrites the path',
() async {
final src = File(p.join(tmp.path, 'photo.png'))
..writeAsBytesSync([1, 2]);
final project = Directory(p.join(tmp.path, 'project'))..createSync();
final out = await service.copyImagesToProject([
Slide.create(SlideType.image).copyWith(imagePath: src.path),
], project.path);
expect(out.single.imagePath, 'images/photo.png');
expect(
File(p.join(project.path, 'images', 'photo.png')).existsSync(),
isTrue,
);
},
);
test('leaves already-relative image paths unchanged', () async {
final project = Directory(p.join(tmp.path, 'project'))..createSync();
final out = await service.copyImagesToProject([
Slide.create(SlideType.image).copyWith(imagePath: 'images/keep.png'),
], project.path);
expect(out.single.imagePath, 'images/keep.png');
});
test('leaves the path unchanged when the source file is missing', () async {
final project = Directory(p.join(tmp.path, 'project'))..createSync();
final missing = p.join(tmp.path, 'does_not_exist.png');
final out = await service.copyImagesToProject([
Slide.create(SlideType.image).copyWith(imagePath: missing),
], project.path);
expect(out.single.imagePath, missing);
});
test('copies the second image of a twoImages slide', () async {
final a = File(p.join(tmp.path, 'a.png'))..writeAsBytesSync([1]);
final b = File(p.join(tmp.path, 'b.png'))..writeAsBytesSync([2]);
final project = Directory(p.join(tmp.path, 'project'))..createSync();
final out = await service.copyImagesToProject([
Slide.create(
SlideType.twoImages,
).copyWith(imagePath: a.path, imagePath2: b.path),
], project.path);
expect(out.single.imagePath, 'images/a.png');
expect(out.single.imagePath2, 'images/b.png');
});
});
group('copyMediaToProject', () {
test(
'copies absolute video/audio into media/ and rewrites paths',
() async {
final vid = File(p.join(tmp.path, 'clip.mp4'))..writeAsBytesSync([1]);
final aud = File(p.join(tmp.path, 'sound.mp3'))..writeAsBytesSync([2]);
final project = Directory(p.join(tmp.path, 'project'))..createSync();
final out = await service.copyMediaToProject([
Slide.create(
SlideType.video,
).copyWith(videoPath: vid.path, audioPath: aud.path),
], project.path);
expect(out.single.videoPath, 'media/clip.mp4');
expect(out.single.audioPath, 'media/sound.mp3');
expect(
File(p.join(project.path, 'media', 'clip.mp4')).existsSync(),
isTrue,
);
},
);
});
group('copyImageToClipboard', () {
test('returns false for an empty path', () async {
expect(await service.copyImageToClipboard(''), isFalse);
});
test('returns false for a non-existent file', () async {
final missing = p.join(tmp.path, 'nope.png');
expect(await service.copyImageToClipboard(missing), isFalse);
});
test('copyImageBytesToClipboard returns false for empty bytes', () async {
expect(await service.copyImageBytesToClipboard(Uint8List(0)), isFalse);
});
});
}