格式化代码
This commit is contained in:
138
test/unit/domain/repositories/album_repository_test.dart
Normal file
138
test/unit/domain/repositories/album_repository_test.dart
Normal file
@@ -0,0 +1,138 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import '../../../../bin/domain/entities/album.dart';
|
||||
import '../../../../bin/domain/repositories/album_repository.dart';
|
||||
|
||||
void main() {
|
||||
late Directory tempDir;
|
||||
late AlbumRepository repository;
|
||||
|
||||
setUp(() async {
|
||||
// Create a temporary directory for each test
|
||||
tempDir = await Directory.systemTemp.createTemp('album_repo_test_');
|
||||
repository = AlbumRepository(basePath: tempDir.path);
|
||||
});
|
||||
|
||||
tearDown(() async {
|
||||
// Clean up the temporary directory
|
||||
if (await tempDir.exists()) {
|
||||
await tempDir.delete(recursive: true);
|
||||
}
|
||||
});
|
||||
|
||||
group('getAllAlbums', () {
|
||||
test('should return empty list when directory does not exist', () async {
|
||||
final repo = AlbumRepository(
|
||||
basePath: '/nonexistent/path/that/does/not/exist',
|
||||
);
|
||||
final albums = await repo.getAllAlbums();
|
||||
expect(albums, isEmpty);
|
||||
});
|
||||
|
||||
test('should return empty list when directory is empty', () async {
|
||||
final albums = await repository.getAllAlbums();
|
||||
expect(albums, isEmpty);
|
||||
});
|
||||
|
||||
test('should return albums for each subdirectory', () async {
|
||||
// Create test directories
|
||||
await Directory(p.join(tempDir.path, 'vacation')).create();
|
||||
await Directory(p.join(tempDir.path, 'birthday')).create();
|
||||
await Directory(p.join(tempDir.path, 'family')).create();
|
||||
|
||||
final albums = await repository.getAllAlbums();
|
||||
|
||||
expect(albums.length, 3);
|
||||
expect(
|
||||
albums.map((a) => a.name),
|
||||
containsAll(['vacation', 'birthday', 'family']),
|
||||
);
|
||||
});
|
||||
|
||||
test('should not include files as albums', () async {
|
||||
// Create a directory and a file
|
||||
await Directory(p.join(tempDir.path, 'vacation')).create();
|
||||
await File(p.join(tempDir.path, 'somefile.txt')).writeAsString('test');
|
||||
|
||||
final albums = await repository.getAllAlbums();
|
||||
|
||||
expect(albums.length, 1);
|
||||
expect(albums.first.name, 'vacation');
|
||||
});
|
||||
|
||||
test('should generate consistent id from directory name', () async {
|
||||
await Directory(p.join(tempDir.path, 'test_album')).create();
|
||||
|
||||
final albums1 = await repository.getAllAlbums();
|
||||
final albums2 = await repository.getAllAlbums();
|
||||
|
||||
expect(albums1.first.id, albums2.first.id);
|
||||
expect(albums1.first.id, 'test_album'.hashCode);
|
||||
});
|
||||
|
||||
test('should set createdAt and updatedAt from directory stat', () async {
|
||||
await Directory(p.join(tempDir.path, 'recent')).create();
|
||||
|
||||
final albums = await repository.getAllAlbums();
|
||||
|
||||
expect(albums.first.createdAt, isA<DateTime>());
|
||||
expect(albums.first.updatedAt, isA<DateTime>());
|
||||
});
|
||||
|
||||
test('should return Album objects', () async {
|
||||
await Directory(p.join(tempDir.path, 'my_album')).create();
|
||||
|
||||
final albums = await repository.getAllAlbums();
|
||||
|
||||
expect(albums.first, isA<Album>());
|
||||
expect(albums.first.id, isA<int>());
|
||||
expect(albums.first.name, 'my_album');
|
||||
});
|
||||
});
|
||||
|
||||
group('getAlbumById', () {
|
||||
test('should return null when directory does not exist', () async {
|
||||
final repo = AlbumRepository(basePath: '/nonexistent/path');
|
||||
final album = await repo.getAlbumById(123);
|
||||
expect(album, isNull);
|
||||
});
|
||||
|
||||
test('should return null when no albums match the id', () async {
|
||||
await Directory(p.join(tempDir.path, 'album1')).create();
|
||||
|
||||
final album = await repository.getAlbumById(999999);
|
||||
|
||||
expect(album, isNull);
|
||||
});
|
||||
|
||||
test('should return album when id matches', () async {
|
||||
await Directory(p.join(tempDir.path, 'target_album')).create();
|
||||
|
||||
final allAlbums = await repository.getAllAlbums();
|
||||
final targetId = allAlbums.first.id;
|
||||
|
||||
final album = await repository.getAlbumById(targetId);
|
||||
|
||||
expect(album, isNotNull);
|
||||
expect(album!.name, 'target_album');
|
||||
expect(album.id, targetId);
|
||||
});
|
||||
|
||||
test('should return correct album among multiple albums', () async {
|
||||
await Directory(p.join(tempDir.path, 'alpha')).create();
|
||||
await Directory(p.join(tempDir.path, 'beta')).create();
|
||||
await Directory(p.join(tempDir.path, 'gamma')).create();
|
||||
|
||||
final allAlbums = await repository.getAllAlbums();
|
||||
final betaAlbum = allAlbums.firstWhere((a) => a.name == 'beta');
|
||||
|
||||
final album = await repository.getAlbumById(betaAlbum.id);
|
||||
|
||||
expect(album, isNotNull);
|
||||
expect(album!.name, 'beta');
|
||||
});
|
||||
});
|
||||
}
|
||||
613
test/unit/domain/repositories/photo_repository_test.dart
Normal file
613
test/unit/domain/repositories/photo_repository_test.dart
Normal file
@@ -0,0 +1,613 @@
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import '../../../../bin/domain/repositories/photo_repository.dart';
|
||||
|
||||
void main() {
|
||||
late Directory tempDir;
|
||||
late PhotoRepository repository;
|
||||
|
||||
setUp(() async {
|
||||
tempDir = await Directory.systemTemp.createTemp('photo_repo_test_');
|
||||
repository = PhotoRepository(tempDir.path);
|
||||
});
|
||||
|
||||
tearDown(() async {
|
||||
if (await tempDir.exists()) {
|
||||
await tempDir.delete(recursive: true);
|
||||
}
|
||||
});
|
||||
|
||||
// ===== Helper methods to create test image files =====
|
||||
|
||||
/// Create a minimal valid PNG file (1x1 pixel, IHDR at known position)
|
||||
File _createTestPng(
|
||||
Directory dir,
|
||||
String name, {
|
||||
int width = 100,
|
||||
int height = 200,
|
||||
}) {
|
||||
final buffer = BytesBuilder();
|
||||
|
||||
// PNG signature (8 bytes)
|
||||
buffer.addByte(0x89);
|
||||
buffer.addByte(0x50);
|
||||
buffer.addByte(0x4E);
|
||||
buffer.addByte(0x47);
|
||||
buffer.addByte(0x0D);
|
||||
buffer.addByte(0x0A);
|
||||
buffer.addByte(0x1A);
|
||||
buffer.addByte(0x0A);
|
||||
|
||||
// IHDR chunk length (4 bytes) - 13 bytes of data
|
||||
buffer.addByte(0x00);
|
||||
buffer.addByte(0x00);
|
||||
buffer.addByte(0x00);
|
||||
buffer.addByte(0x0D);
|
||||
|
||||
// IHDR chunk type
|
||||
buffer.addByte(0x49);
|
||||
buffer.addByte(0x48);
|
||||
buffer.addByte(0x44);
|
||||
buffer.addByte(0x52);
|
||||
|
||||
// Width (4 bytes, big-endian)
|
||||
buffer.addByte((width >> 24) & 0xFF);
|
||||
buffer.addByte((width >> 16) & 0xFF);
|
||||
buffer.addByte((width >> 8) & 0xFF);
|
||||
buffer.addByte(width & 0xFF);
|
||||
|
||||
// Height (4 bytes, big-endian)
|
||||
buffer.addByte((height >> 24) & 0xFF);
|
||||
buffer.addByte((height >> 16) & 0xFF);
|
||||
buffer.addByte((height >> 8) & 0xFF);
|
||||
buffer.addByte(height & 0xFF);
|
||||
|
||||
// Rest of IHDR
|
||||
buffer.addByte(0x08);
|
||||
buffer.addByte(0x02);
|
||||
buffer.addByte(0x00);
|
||||
buffer.addByte(0x00);
|
||||
buffer.addByte(0x00);
|
||||
|
||||
// CRC (dummy)
|
||||
buffer.addByte(0x00);
|
||||
buffer.addByte(0x00);
|
||||
buffer.addByte(0x00);
|
||||
buffer.addByte(0x00);
|
||||
|
||||
// IEND
|
||||
buffer.addByte(0x00);
|
||||
buffer.addByte(0x00);
|
||||
buffer.addByte(0x00);
|
||||
buffer.addByte(0x00);
|
||||
buffer.addByte(0x49);
|
||||
buffer.addByte(0x45);
|
||||
buffer.addByte(0x4E);
|
||||
buffer.addByte(0x44);
|
||||
buffer.addByte(0xAE);
|
||||
buffer.addByte(0x42);
|
||||
buffer.addByte(0x60);
|
||||
buffer.addByte(0x82);
|
||||
|
||||
final file = File(p.join(dir.path, name));
|
||||
file.writeAsBytesSync(buffer.toBytes());
|
||||
return file;
|
||||
}
|
||||
|
||||
/// Create a minimal valid GIF file
|
||||
File _createTestGif(
|
||||
Directory dir,
|
||||
String name, {
|
||||
int width = 150,
|
||||
int height = 250,
|
||||
}) {
|
||||
final buffer = BytesBuilder();
|
||||
|
||||
// GIF89a header
|
||||
buffer.addByte(0x47);
|
||||
buffer.addByte(0x49);
|
||||
buffer.addByte(0x46);
|
||||
buffer.addByte(0x38);
|
||||
buffer.addByte(0x39);
|
||||
buffer.addByte(0x61);
|
||||
|
||||
// Width (little-endian)
|
||||
buffer.addByte(width & 0xFF);
|
||||
buffer.addByte((width >> 8) & 0xFF);
|
||||
|
||||
// Height (little-endian)
|
||||
buffer.addByte(height & 0xFF);
|
||||
buffer.addByte((height >> 8) & 0xFF);
|
||||
|
||||
buffer.addByte(0x00);
|
||||
buffer.addByte(0x00);
|
||||
buffer.addByte(0x00);
|
||||
buffer.addByte(0x3B);
|
||||
|
||||
final file = File(p.join(dir.path, name));
|
||||
file.writeAsBytesSync(buffer.toBytes());
|
||||
return file;
|
||||
}
|
||||
|
||||
/// Create a minimal valid BMP file
|
||||
File _createTestBmp(
|
||||
Directory dir,
|
||||
String name, {
|
||||
int width = 300,
|
||||
int height = 400,
|
||||
}) {
|
||||
final buffer = BytesBuilder();
|
||||
|
||||
buffer.addByte(0x42);
|
||||
buffer.addByte(0x4D);
|
||||
|
||||
final fileSize = 54 + width * height * 3;
|
||||
buffer.addByte(fileSize & 0xFF);
|
||||
buffer.addByte((fileSize >> 8) & 0xFF);
|
||||
buffer.addByte((fileSize >> 16) & 0xFF);
|
||||
buffer.addByte((fileSize >> 24) & 0xFF);
|
||||
|
||||
// Reserved
|
||||
buffer.addByte(0x00);
|
||||
buffer.addByte(0x00);
|
||||
buffer.addByte(0x00);
|
||||
buffer.addByte(0x00);
|
||||
|
||||
// Offset to pixel data
|
||||
buffer.addByte(0x36);
|
||||
buffer.addByte(0x00);
|
||||
buffer.addByte(0x00);
|
||||
buffer.addByte(0x00);
|
||||
|
||||
// DIB header
|
||||
buffer.addByte(0x28);
|
||||
buffer.addByte(0x00);
|
||||
buffer.addByte(0x00);
|
||||
buffer.addByte(0x00);
|
||||
|
||||
// Width (little-endian)
|
||||
buffer.addByte(width & 0xFF);
|
||||
buffer.addByte((width >> 8) & 0xFF);
|
||||
buffer.addByte((width >> 16) & 0xFF);
|
||||
buffer.addByte((width >> 24) & 0xFF);
|
||||
|
||||
// Height (little-endian)
|
||||
buffer.addByte(height & 0xFF);
|
||||
buffer.addByte((height >> 8) & 0xFF);
|
||||
buffer.addByte((height >> 16) & 0xFF);
|
||||
buffer.addByte((height >> 24) & 0xFF);
|
||||
|
||||
// Planes, bits per pixel
|
||||
buffer.addByte(0x01);
|
||||
buffer.addByte(0x00);
|
||||
buffer.addByte(0x18);
|
||||
buffer.addByte(0x00);
|
||||
|
||||
// Compression (0)
|
||||
buffer.addByte(0x00);
|
||||
buffer.addByte(0x00);
|
||||
buffer.addByte(0x00);
|
||||
buffer.addByte(0x00);
|
||||
|
||||
// Padding
|
||||
for (var i = 0; i < 24; i++) {
|
||||
buffer.addByte(0x00);
|
||||
}
|
||||
|
||||
final file = File(p.join(dir.path, name));
|
||||
file.writeAsBytesSync(buffer.toBytes());
|
||||
return file;
|
||||
}
|
||||
|
||||
/// Create a minimal valid WebP VP8 (lossy) file
|
||||
File _createTestWebpVp8(
|
||||
Directory dir,
|
||||
String name, {
|
||||
int width = 120,
|
||||
int height = 80,
|
||||
}) {
|
||||
final buffer = BytesBuilder();
|
||||
|
||||
// RIFF
|
||||
buffer.addByte(0x52);
|
||||
buffer.addByte(0x49);
|
||||
buffer.addByte(0x46);
|
||||
buffer.addByte(0x46);
|
||||
|
||||
// File size (placeholder)
|
||||
buffer.addByte(0x20);
|
||||
buffer.addByte(0x00);
|
||||
buffer.addByte(0x00);
|
||||
buffer.addByte(0x00);
|
||||
|
||||
// WEBP
|
||||
buffer.addByte(0x57);
|
||||
buffer.addByte(0x45);
|
||||
buffer.addByte(0x42);
|
||||
buffer.addByte(0x50);
|
||||
|
||||
// VP8
|
||||
buffer.addByte(0x56);
|
||||
buffer.addByte(0x50);
|
||||
buffer.addByte(0x38);
|
||||
buffer.addByte(0x20);
|
||||
|
||||
// Chunk size
|
||||
buffer.addByte(0x10);
|
||||
buffer.addByte(0x00);
|
||||
buffer.addByte(0x00);
|
||||
buffer.addByte(0x00);
|
||||
|
||||
// Frame tag bytes (positions 20-21)
|
||||
buffer.addByte(0x00);
|
||||
buffer.addByte(0x00);
|
||||
|
||||
// Key check: (data[23] << 8) | data[22] == 0x9D01 (positions 22-23)
|
||||
buffer.addByte(0x01);
|
||||
buffer.addByte(0x9D);
|
||||
|
||||
// Padding before width/height (positions 24-25)
|
||||
buffer.addByte(0x00);
|
||||
buffer.addByte(0x00);
|
||||
|
||||
// Width (little-endian)
|
||||
buffer.addByte(width & 0xFF);
|
||||
buffer.addByte((width >> 8) & 0xFF);
|
||||
|
||||
// Height (little-endian)
|
||||
buffer.addByte(height & 0xFF);
|
||||
buffer.addByte((height >> 8) & 0xFF);
|
||||
|
||||
final file = File(p.join(dir.path, name));
|
||||
file.writeAsBytesSync(buffer.toBytes());
|
||||
return file;
|
||||
}
|
||||
|
||||
// ===== Tests =====
|
||||
|
||||
group('getPhotosByAlbumId', () {
|
||||
test(
|
||||
'should return empty list when base directory does not exist',
|
||||
() async {
|
||||
final repo = PhotoRepository('/nonexistent/path');
|
||||
final photos = await repo.getPhotosByAlbumId(123);
|
||||
expect(photos, isEmpty);
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
'should return empty list when album directory does not exist',
|
||||
() async {
|
||||
final photos = await repository.getPhotosByAlbumId(
|
||||
'nonexistent'.hashCode,
|
||||
);
|
||||
expect(photos, isEmpty);
|
||||
},
|
||||
);
|
||||
|
||||
test('should return photos for a valid album directory', () async {
|
||||
final albumDir = await Directory(
|
||||
p.join(tempDir.path, 'my_album'),
|
||||
).create();
|
||||
_createTestPng(albumDir, 'photo1.png', width: 100, height: 200);
|
||||
_createTestGif(albumDir, 'photo2.gif', width: 150, height: 250);
|
||||
|
||||
final albumId = 'my_album'.hashCode;
|
||||
final photos = await repository.getPhotosByAlbumId(albumId);
|
||||
|
||||
expect(photos.length, 2);
|
||||
expect(
|
||||
photos.map((p) => p.fileName),
|
||||
containsAll(['photo1.png', 'photo2.gif']),
|
||||
);
|
||||
});
|
||||
|
||||
test('should not include non-image files', () async {
|
||||
final albumDir = await Directory(p.join(tempDir.path, 'mixed')).create();
|
||||
_createTestPng(albumDir, 'image.png');
|
||||
File(p.join(albumDir.path, 'document.txt')).writeAsString('not an image');
|
||||
File(p.join(albumDir.path, 'readme.md')).writeAsString('# Readme');
|
||||
|
||||
final albumId = 'mixed'.hashCode;
|
||||
final photos = await repository.getPhotosByAlbumId(albumId);
|
||||
|
||||
expect(photos.length, 1);
|
||||
expect(photos.first.fileName, 'image.png');
|
||||
});
|
||||
|
||||
test('should parse PNG dimensions correctly', () async {
|
||||
final albumDir = await Directory(
|
||||
p.join(tempDir.path, 'png_test'),
|
||||
).create();
|
||||
_createTestPng(albumDir, 'test.png', width: 640, height: 480);
|
||||
|
||||
final albumId = 'png_test'.hashCode;
|
||||
final photos = await repository.getPhotosByAlbumId(albumId);
|
||||
|
||||
expect(photos.length, 1);
|
||||
expect(photos.first.width, 640);
|
||||
expect(photos.first.height, 480);
|
||||
expect(photos.first.mimeType, 'image/png');
|
||||
});
|
||||
|
||||
test('should parse GIF dimensions correctly', () async {
|
||||
final albumDir = await Directory(
|
||||
p.join(tempDir.path, 'gif_test'),
|
||||
).create();
|
||||
_createTestGif(albumDir, 'test.gif', width: 320, height: 240);
|
||||
|
||||
final albumId = 'gif_test'.hashCode;
|
||||
final photos = await repository.getPhotosByAlbumId(albumId);
|
||||
|
||||
expect(photos.length, 1);
|
||||
expect(photos.first.width, 320);
|
||||
expect(photos.first.height, 240);
|
||||
expect(photos.first.mimeType, 'image/gif');
|
||||
});
|
||||
|
||||
test('should parse BMP dimensions correctly', () async {
|
||||
final albumDir = await Directory(
|
||||
p.join(tempDir.path, 'bmp_test'),
|
||||
).create();
|
||||
_createTestBmp(albumDir, 'test.bmp', width: 800, height: 600);
|
||||
|
||||
final albumId = 'bmp_test'.hashCode;
|
||||
final photos = await repository.getPhotosByAlbumId(albumId);
|
||||
|
||||
expect(photos.length, 1);
|
||||
expect(photos.first.width, 800);
|
||||
expect(photos.first.height, 600);
|
||||
expect(photos.first.mimeType, 'image/bmp');
|
||||
});
|
||||
|
||||
test('should handle WebP VP8 dimensions', () async {
|
||||
final albumDir = await Directory(
|
||||
p.join(tempDir.path, 'webp_test'),
|
||||
).create();
|
||||
_createTestWebpVp8(albumDir, 'test.webp', width: 1920, height: 1080);
|
||||
|
||||
final albumId = 'webp_test'.hashCode;
|
||||
final photos = await repository.getPhotosByAlbumId(albumId);
|
||||
|
||||
expect(photos.length, 1);
|
||||
expect(photos.first.width, 1920);
|
||||
expect(photos.first.height, 1080);
|
||||
expect(photos.first.mimeType, 'image/webp');
|
||||
});
|
||||
|
||||
test('should return null dimensions for video files', () async {
|
||||
final albumDir = await Directory(
|
||||
p.join(tempDir.path, 'video_test'),
|
||||
).create();
|
||||
File(
|
||||
p.join(albumDir.path, 'clip.mp4'),
|
||||
).writeAsBytesSync(List.filled(100, 0));
|
||||
|
||||
final albumId = 'video_test'.hashCode;
|
||||
final photos = await repository.getPhotosByAlbumId(albumId);
|
||||
|
||||
expect(photos.length, 1);
|
||||
expect(photos.first.width, isNull);
|
||||
expect(photos.first.height, isNull);
|
||||
expect(photos.first.mimeType, 'video/mp4');
|
||||
});
|
||||
|
||||
test('should include video files in results', () async {
|
||||
final albumDir = await Directory(
|
||||
p.join(tempDir.path, 'video_album'),
|
||||
).create();
|
||||
File(
|
||||
p.join(albumDir.path, 'movie.mp4'),
|
||||
).writeAsBytesSync(List.filled(100, 0));
|
||||
|
||||
final albumId = 'video_album'.hashCode;
|
||||
final photos = await repository.getPhotosByAlbumId(albumId);
|
||||
|
||||
expect(photos.length, 1);
|
||||
expect(photos.first.fileName, 'movie.mp4');
|
||||
});
|
||||
|
||||
test('should set correct photo metadata', () async {
|
||||
final albumDir = await Directory(
|
||||
p.join(tempDir.path, 'meta_test'),
|
||||
).create();
|
||||
_createTestPng(albumDir, 'test.png', width: 100, height: 100);
|
||||
|
||||
final albumId = 'meta_test'.hashCode;
|
||||
final photos = await repository.getPhotosByAlbumId(albumId);
|
||||
|
||||
expect(photos.first.albumId, albumId);
|
||||
expect(photos.first.fileName, 'test.png');
|
||||
expect(photos.first.fileSize, greaterThan(0));
|
||||
expect(photos.first.createdAt, isA<DateTime>());
|
||||
});
|
||||
});
|
||||
|
||||
group('getPhotoById', () {
|
||||
test('should return null when base directory does not exist', () async {
|
||||
final repo = PhotoRepository('/nonexistent/path');
|
||||
final photo = await repo.getPhotoById(123);
|
||||
expect(photo, isNull);
|
||||
});
|
||||
|
||||
test('should return null when photo does not exist', () async {
|
||||
final photo = await repository.getPhotoById(999999);
|
||||
expect(photo, isNull);
|
||||
});
|
||||
|
||||
test('should return photo when id matches', () async {
|
||||
final albumDir = await Directory(
|
||||
p.join(tempDir.path, 'find_album'),
|
||||
).create();
|
||||
_createTestPng(albumDir, 'unique.png', width: 50, height: 50);
|
||||
|
||||
final allPhotos = await repository.getPhotosByAlbumId(
|
||||
'find_album'.hashCode,
|
||||
);
|
||||
final targetId = allPhotos.first.id;
|
||||
|
||||
final photo = await repository.getPhotoById(targetId);
|
||||
|
||||
expect(photo, isNotNull);
|
||||
expect(photo!.fileName, 'unique.png');
|
||||
expect(photo.width, 50);
|
||||
expect(photo.height, 50);
|
||||
});
|
||||
|
||||
test('should parse dimensions when retrieving by id', () async {
|
||||
final albumDir = await Directory(
|
||||
p.join(tempDir.path, 'dims_album'),
|
||||
).create();
|
||||
_createTestBmp(albumDir, 'dims.bmp', width: 1024, height: 768);
|
||||
|
||||
final allPhotos = await repository.getPhotosByAlbumId(
|
||||
'dims_album'.hashCode,
|
||||
);
|
||||
final targetId = allPhotos.first.id;
|
||||
|
||||
final photo = await repository.getPhotoById(targetId);
|
||||
|
||||
expect(photo, isNotNull);
|
||||
expect(photo!.width, 1024);
|
||||
expect(photo.height, 768);
|
||||
});
|
||||
});
|
||||
|
||||
group('mime type detection', () {
|
||||
test('should detect jpg/jpeg as image/jpeg', () async {
|
||||
final albumDir = await Directory(
|
||||
p.join(tempDir.path, 'mime_jpg'),
|
||||
).create();
|
||||
File(p.join(albumDir.path, 'test.jpg')).writeAsBytesSync([0xFF, 0xD8]);
|
||||
File(p.join(albumDir.path, 'test2.jpeg')).writeAsBytesSync([0xFF, 0xD8]);
|
||||
|
||||
final photos = await repository.getPhotosByAlbumId('mime_jpg'.hashCode);
|
||||
expect(photos.length, 2);
|
||||
expect(photos.every((p) => p.mimeType == 'image/jpeg'), isTrue);
|
||||
});
|
||||
|
||||
test('should detect png as image/png', () async {
|
||||
final albumDir = await Directory(
|
||||
p.join(tempDir.path, 'mime_png'),
|
||||
).create();
|
||||
File(
|
||||
p.join(albumDir.path, 'test.png'),
|
||||
).writeAsBytesSync(List.filled(100, 0));
|
||||
|
||||
final photos = await repository.getPhotosByAlbumId('mime_png'.hashCode);
|
||||
expect(photos.first.mimeType, 'image/png');
|
||||
});
|
||||
|
||||
test('should detect webp as image/webp', () async {
|
||||
final albumDir = await Directory(
|
||||
p.join(tempDir.path, 'mime_webp'),
|
||||
).create();
|
||||
File(
|
||||
p.join(albumDir.path, 'test.webp'),
|
||||
).writeAsBytesSync(List.filled(100, 0));
|
||||
|
||||
final photos = await repository.getPhotosByAlbumId('mime_webp'.hashCode);
|
||||
expect(photos.first.mimeType, 'image/webp');
|
||||
});
|
||||
|
||||
test('should detect mp4 as video/mp4', () async {
|
||||
final albumDir = await Directory(
|
||||
p.join(tempDir.path, 'mime_mp4'),
|
||||
).create();
|
||||
File(
|
||||
p.join(albumDir.path, 'test.mp4'),
|
||||
).writeAsBytesSync(List.filled(100, 0));
|
||||
|
||||
final photos = await repository.getPhotosByAlbumId('mime_mp4'.hashCode);
|
||||
expect(photos.first.mimeType, 'video/mp4');
|
||||
});
|
||||
|
||||
test('should detect avi as video/avi', () async {
|
||||
final albumDir = await Directory(
|
||||
p.join(tempDir.path, 'mime_avi'),
|
||||
).create();
|
||||
File(
|
||||
p.join(albumDir.path, 'test.avi'),
|
||||
).writeAsBytesSync(List.filled(100, 0));
|
||||
|
||||
final photos = await repository.getPhotosByAlbumId('mime_avi'.hashCode);
|
||||
expect(photos.first.mimeType, 'video/avi');
|
||||
});
|
||||
|
||||
test('should detect mov as video/quicktime', () async {
|
||||
final albumDir = await Directory(
|
||||
p.join(tempDir.path, 'mime_mov'),
|
||||
).create();
|
||||
File(
|
||||
p.join(albumDir.path, 'test.mov'),
|
||||
).writeAsBytesSync(List.filled(100, 0));
|
||||
|
||||
final photos = await repository.getPhotosByAlbumId('mime_mov'.hashCode);
|
||||
expect(photos.first.mimeType, 'video/quicktime');
|
||||
});
|
||||
|
||||
test('should detect mkv as video/x-matroska', () async {
|
||||
final albumDir = await Directory(
|
||||
p.join(tempDir.path, 'mime_mkv'),
|
||||
).create();
|
||||
File(
|
||||
p.join(albumDir.path, 'test.mkv'),
|
||||
).writeAsBytesSync(List.filled(100, 0));
|
||||
|
||||
final photos = await repository.getPhotosByAlbumId('mime_mkv'.hashCode);
|
||||
expect(photos.first.mimeType, 'video/x-matroska');
|
||||
});
|
||||
});
|
||||
|
||||
group('supported file extensions', () {
|
||||
test('should recognize all image extensions', () async {
|
||||
final albumDir = await Directory(
|
||||
p.join(tempDir.path, 'ext_test'),
|
||||
).create();
|
||||
final extensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp'];
|
||||
|
||||
for (final ext in extensions) {
|
||||
File(
|
||||
p.join(albumDir.path, 'file$ext'),
|
||||
).writeAsBytesSync(List.filled(10, 0));
|
||||
}
|
||||
|
||||
final photos = await repository.getPhotosByAlbumId('ext_test'.hashCode);
|
||||
expect(photos.length, extensions.length);
|
||||
});
|
||||
|
||||
test('should recognize all video extensions', () async {
|
||||
final albumDir = await Directory(
|
||||
p.join(tempDir.path, 'ext_video'),
|
||||
).create();
|
||||
final extensions = ['.mp4', '.avi', '.mov', '.mkv'];
|
||||
|
||||
for (final ext in extensions) {
|
||||
File(
|
||||
p.join(albumDir.path, 'video$ext'),
|
||||
).writeAsBytesSync(List.filled(10, 0));
|
||||
}
|
||||
|
||||
final photos = await repository.getPhotosByAlbumId('ext_video'.hashCode);
|
||||
expect(photos.length, extensions.length);
|
||||
});
|
||||
|
||||
test('should ignore unsupported extensions', () async {
|
||||
final albumDir = await Directory(
|
||||
p.join(tempDir.path, 'ext_ignore'),
|
||||
).create();
|
||||
_createTestPng(albumDir, 'valid.png');
|
||||
File(p.join(albumDir.path, 'skip.txt')).writeAsString('text');
|
||||
File(p.join(albumDir.path, 'skip.pdf')).writeAsBytesSync([]);
|
||||
File(p.join(albumDir.path, 'skip.exe')).writeAsBytesSync([]);
|
||||
|
||||
final photos = await repository.getPhotosByAlbumId('ext_ignore'.hashCode);
|
||||
expect(photos.length, 1);
|
||||
expect(photos.first.fileName, 'valid.png');
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user