import 'dart:convert'; import 'dart:io'; import 'package:http/http.dart' as http; import 'package:test/test.dart'; void main() { final port = '9090'; final host = 'http://localhost:$port'; late Process p; String? authToken; Future getAuthToken() async { if (authToken != null) return authToken; final regResponse = await http.post( Uri.parse('$host/reg'), headers: {'Content-Type': 'application/json'}, body: jsonEncode({'login': 'testuser', 'password': 'testpass'}), ); final loginResponse = await http.post( Uri.parse('$host/login'), headers: {'Content-Type': 'application/json'}, body: jsonEncode({'login': 'testuser', 'password': 'testpass'}), ); if (loginResponse.statusCode == 200) { final data = jsonDecode(loginResponse.body) as Map; authToken = data['token']; } return authToken; } setUpAll(() async { stdout.writeln("Starting server..."); p = await Process.start( 'dart', ['run', 'bin/server.dart'], environment: {'PORT': port}, ); // Wait for server to be ready for (int i = 0; i < 30; i++) { try { final response = await http.get(Uri.parse('$host/')); if (response.statusCode == 200) break; } catch (e) { // Server not ready yet } await Future.delayed(Duration(seconds: 1)); } stdout.writeln("Server ready"); }); tearDownAll(() { p.kill(); }); group('Root endpoint', () { test('GET / - Root endpoint', () async { final response = await http.get(Uri.parse('$host/')); expect(response.statusCode, 200); expect(response.body, contains('Family Safety Tracker API')); }); test('GET /nonexistent - 404', () async { final response = await http.get(Uri.parse('$host/nonexistent')); expect(response.statusCode, 404); }); }); group('User registration', () { test('POST /reg - Register new user', () async { final response = await http.post( Uri.parse('$host/reg'), headers: {'Content-Type': 'application/json'}, body: jsonEncode({'login': 'newuser', 'password': 'newpass'}), ); expect(response.statusCode, 201); final data = jsonDecode(response.body); expect(data['login'], 'newuser'); }); }); group('Authentication', () { test('POST /login - Valid credentials', () async { await getAuthToken(); expect(authToken, isNotEmpty); }); test('POST /login - Invalid credentials', () async { final response = await http.post( Uri.parse('$host/login'), headers: {'Content-Type': 'application/json'}, body: jsonEncode({'login': 'testuser', 'password': 'wrongpass'}), ); expect(response.statusCode, 401); }); }); group('Geo operations', () { test('POST /share - Create share link', () async { await getAuthToken(); final response = await http.post( Uri.parse('$host/share'), headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer $authToken', }, body: jsonEncode({'x': 40.7128, 'y': -74.006}), ); expect(response.statusCode, 201); final data = jsonDecode(response.body); expect(data['share_id'], isA()); }); test('POST /share - No auth token', () async { final response = await http.post( Uri.parse('$host/share'), headers: {'Content-Type': 'application/json'}, body: jsonEncode({'x': 40.7128, 'y': -74.006}), ); expect(response.statusCode, 401); }); }); group('Watch endpoint', () { test('GET /watch - Invalid share link', () async { final response = await http.get( Uri.parse('$host/watch?unique_id=invalid-uuid'), ); expect(response.statusCode, 404); }); }); }