初始化项目

This commit is contained in:
2026-03-12 21:24:49 +08:00
commit c2b9c5d4c0
67 changed files with 8659 additions and 0 deletions

179
test/server_test.dart Normal file
View File

@@ -0,0 +1,179 @@
import 'dart:io';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:test/test.dart';
void main() {
final port = '8080';
final host = 'http://localhost:$port';
late Process p;
setUp(() async {
p = await Process.start(
'dart',
['run', 'bin/server.dart'],
environment: {'PORT': port},
);
// Wait for server to start (give it some time to initialize)
await Future.delayed(const Duration(seconds: 3));
});
tearDown(() async {
p.kill();
// Wait for process to exit
try {
await p.exitCode.timeout(const Duration(seconds: 5), onTimeout: () => 0);
} catch (_) {}
});
group('Root endpoint', () {
test('GET / returns Hello World', () async {
final response = await http.get(Uri.parse('$host/'));
expect(response.statusCode, 200);
expect(response.body, 'Hello, World!\n');
});
});
group('Echo endpoint', () {
test('GET /echo/<message> returns the message', () async {
final response = await http.get(Uri.parse('$host/echo/hello'));
expect(response.statusCode, 200);
expect(response.body, 'hello\n');
});
test('GET /echo/<message> with special characters', () async {
final response = await http.get(Uri.parse('$host/echo/test%20message'));
expect(response.statusCode, 200);
expect(response.body, contains('test'));
});
});
group('Album endpoints', () {
test('GET /album returns list of albums', () async {
final response = await http.get(Uri.parse('$host/album'));
expect(response.statusCode, 200);
expect(response.headers['content-type'], contains('application/json'));
final albums = jsonDecode(response.body) as List;
expect(albums, isA<List>());
if (albums.isNotEmpty) {
expect(albums.first, containsPair('id', isA<int>()));
expect(albums.first, containsPair('name', isA<String>()));
}
});
test('GET /album/<id> with invalid id returns 400', () async {
final response = await http.get(Uri.parse('$host/album/invalid_id'));
expect(response.statusCode, 400);
expect(response.body, contains('Invalid album id'));
});
test('GET /album/<id> with non-existent id returns 404', () async {
final response = await http.get(Uri.parse('$host/album/999999'));
expect(response.statusCode, 404);
expect(response.body, contains('Album not found'));
});
test('GET /album/<id>/photo with invalid id returns 400', () async {
final response = await http.get(Uri.parse('$host/album/invalid_id/photo'));
expect(response.statusCode, 400);
expect(response.body, contains('Invalid album id'));
});
test('GET /album/<id>/photo with valid id returns photos', () async {
// First get the list to find a valid album id
final listResponse = await http.get(Uri.parse('$host/album'));
expect(listResponse.statusCode, 200);
final albums = jsonDecode(listResponse.body) as List;
// Skip test if no albums exist
if (albums.isEmpty) {
return;
}
final album = albums.first as Map<String, dynamic>;
final albumId = album['id'];
final response = await http.get(Uri.parse('$host/album/$albumId/photo'));
expect(response.statusCode, 200);
expect(response.headers['content-type'], contains('application/json'));
final photos = jsonDecode(response.body) as List;
expect(photos, isA<List>());
});
});
group('Photo endpoints', () {
test('GET /photo/<id> with invalid id returns 400', () async {
final response = await http.get(Uri.parse('$host/photo/abc'));
expect(response.statusCode, 400);
expect(response.body, contains('Invalid photo id'));
});
test('GET /photo/<id> with non-existent id returns 404', () async {
// Use a hash that won't match any file
final response = await http.get(Uri.parse('$host/photo/12345'));
expect(response.statusCode, 404);
expect(response.body, contains('Photo not found'));
});
test('GET /photo/<id>/file with invalid id returns 400', () async {
final response = await http.get(Uri.parse('$host/photo/abc/file'));
expect(response.statusCode, 400);
expect(response.body, contains('Invalid photo id'));
});
test('GET /photo/<id>/file with non-existent id returns 404', () async {
// Use a hash that won't match any file
final response = await http.get(Uri.parse('$host/photo/12345/file'));
expect(response.statusCode, 404);
expect(response.body, contains('Photo not found'));
});
test('GET /photo/<id>/file with valid id returns file', () async {
// First get a valid photo id from an album
final albumResponse = await http.get(Uri.parse('$host/album'));
expect(albumResponse.statusCode, 200);
final albums = jsonDecode(albumResponse.body) as List;
// Skip test if no albums exist
if (albums.isEmpty) {
return;
}
final album = albums.first as Map<String, dynamic>;
final albumId = album['id'];
final photosResponse = await http.get(
Uri.parse('$host/album/$albumId/photo'),
);
expect(photosResponse.statusCode, 200);
final photos = jsonDecode(photosResponse.body) as List;
// Skip test if no photos exist
if (photos.isEmpty) {
return;
}
final photo = photos.first as Map<String, dynamic>;
final photoId = photo['id'];
final response = await http.get(
Uri.parse('$host/photo/$photoId/file'),
);
expect(response.statusCode, 200);
expect(response.contentLength, greaterThan(0));
});
});
group('404 handling', () {
test('Unknown route returns 404', () async {
final response = await http.get(Uri.parse('$host/foobar'));
expect(response.statusCode, 404);
});
test('Unknown nested route returns 404', () async {
final response = await http.get(Uri.parse('$host/api/v1/unknown'));
expect(response.statusCode, 404);
});
});
}