From 01a603b8d491290b7b6ff915d9486035bc7b8edb Mon Sep 17 00:00:00 2001 From: Jean Jacques Avril Date: Sat, 4 Jan 2025 17:41:12 +0000 Subject: [PATCH] Test Server Endpoints --- backend-dart/lib/common/response_helpers.dart | 2 +- backend-dart/lib/common/secure_hash.dart | 1 - .../data/database_provider.dart | 3 +- backend-dart/test/extensions.dart | 48 ++++++ backend-dart/test/server_test.dart | 152 ++++++++++++++++++ 5 files changed, 203 insertions(+), 3 deletions(-) create mode 100644 backend-dart/test/extensions.dart create mode 100644 backend-dart/test/server_test.dart diff --git a/backend-dart/lib/common/response_helpers.dart b/backend-dart/lib/common/response_helpers.dart index 5ca8cd7..d24ee6e 100644 --- a/backend-dart/lib/common/response_helpers.dart +++ b/backend-dart/lib/common/response_helpers.dart @@ -57,7 +57,7 @@ class ResponseHelpers { static Response fromError(IError error) { // Print error to console - print('Error: ${error.code.name} - ${error.message}'); + print('ErrorResponse: ${error.code.name} - ${error.message}'); //print(error.stackTrace); return Response( mapErrorCodeToHttpStatus(error.code), diff --git a/backend-dart/lib/common/secure_hash.dart b/backend-dart/lib/common/secure_hash.dart index 016d0e0..ab74bf6 100644 --- a/backend-dart/lib/common/secure_hash.dart +++ b/backend-dart/lib/common/secure_hash.dart @@ -5,6 +5,5 @@ import 'package:crypto/crypto.dart'; String generateSecureHash(String input) { final bytes = utf8.encode(input); final hash = sha256.convert(bytes); - print(hash); return hash.toString(); } diff --git a/backend-dart/lib/infrastructure/data/database_provider.dart b/backend-dart/lib/infrastructure/data/database_provider.dart index 3653a01..2349076 100644 --- a/backend-dart/lib/infrastructure/data/database_provider.dart +++ b/backend-dart/lib/infrastructure/data/database_provider.dart @@ -1,7 +1,8 @@ +import 'package:backend_dart/domain/data/database.dart'; import 'package:backend_dart/infrastructure/data/prisma_database.dart'; import 'package:riverpod/riverpod.dart'; -final databaseProvider = Provider((ref) { +final databaseProvider = Provider((ref) { // Hier die Datenbankverbindung initialisieren final database = PrismaDatabase(); return database; diff --git a/backend-dart/test/extensions.dart b/backend-dart/test/extensions.dart new file mode 100644 index 0000000..10759dd --- /dev/null +++ b/backend-dart/test/extensions.dart @@ -0,0 +1,48 @@ +// get nullable +import 'dart:convert'; + +import 'package:backend_dart/domain/entities/user.dart'; +import 'package:backend_dart/domain/errors/error.dart'; +import 'package:fpdart/fpdart.dart'; +import 'package:shelf/shelf.dart'; +import 'package:test/test.dart'; + +extension NullableGet on TaskEither { +// !THIS IS ONLY FOR TESTING PURPOSES! + Future get get { + return match((e) => null, identity).run(); + } +} + +String? extractSessionTokenFromCookie(String? token) { + if (token == null) return null; + final parts = token.split('='); + if (parts[0] == 'session_token' && parts[1].isNotEmpty) { + return parts[1]; + } + return null; +} + +Future createLoggedInToken( + User? user, + Handler handler, { + String password = 'password', +}) async { + if (user == null) { + fail('User creation failed'); + } + final responseLogin = await handler(Request( + 'POST', + Uri.parse('http://localhost/api/auth/login'), + headers: { + 'Content-Type': 'application/json', + }, + body: jsonEncode( + { + 'email': user.email, + 'password': password, + }, + ), + )); + return extractSessionTokenFromCookie(responseLogin.headers['Set-Cookie']); +} diff --git a/backend-dart/test/server_test.dart b/backend-dart/test/server_test.dart new file mode 100644 index 0000000..44023f1 --- /dev/null +++ b/backend-dart/test/server_test.dart @@ -0,0 +1,152 @@ +import 'dart:convert'; + +import 'package:backend_dart/application/service/dto/user_dto.dart'; +import 'package:backend_dart/domain/entities/user.dart'; +import 'package:backend_dart/domain/errors/error.dart'; +import 'package:backend_dart/infrastructure/data/database_provider.dart'; +import 'package:backend_dart/interfaces/http/router.dart'; +import 'package:fpdart/fpdart.dart'; +import 'package:riverpod/riverpod.dart'; +import 'package:shelf/shelf.dart'; +import 'package:test/test.dart'; + +import 'extensions.dart'; +import 'mocks/mock_database.dart'; + +void main() { + late MockDatabase database; + late Handler testHandler; + + late TaskEither defaultUser; + setUpAll( + () async { + database = MockDatabase(); + final container = ProviderContainer( + overrides: [ + // Add any overrides here + databaseProvider.overrideWithValue(database), + ], + ); + // Load the router from the router file + testHandler = Pipeline() + .addMiddleware(logRequests()) // Logs all incoming requests + .addHandler(getRouter(container).call); + }, + ); + + setUp( + () async { + database.clear(); // Clear the database before each test + defaultUser = database.users.create(UserCreate( + email: 'user@example.com', + password: 'password', + name: 'John Doe1', + )); + }, + ); + + test('Check health', () async { + final response = + await testHandler(Request('GET', Uri.parse('http://localhost/health'))); + expect(response.statusCode, 200, reason: 'Server health is abnormal'); + }); + + test('Login', () async { + final user = await defaultUser.get; + + if (user == null) { + fail('User creation failed'); + } + + final responseLogin = await testHandler(Request( + 'POST', + Uri.parse('http://localhost/api/auth/login'), + headers: { + 'Content-Type': 'application/json', + }, + body: jsonEncode( + { + 'email': user.email, + 'password': 'password', + }, + ), + )); + expect(responseLogin.statusCode, 200, reason: 'Login failed'); + expect(responseLogin.headers['Set-Cookie'], isNotNull, + reason: 'Cookies not found'); + expect(extractSessionTokenFromCookie(responseLogin.headers['Set-Cookie']), + isNotEmpty, + reason: 'Session token not found'); + }); + + test('Logout', () async { + final token = await createLoggedInToken(await defaultUser.get, testHandler); + + if (token == null) { + fail('User creation failed'); + } + + final responseLogout = await testHandler(Request( + 'POST', + Uri.parse('http://localhost/api/auth/logout'), + headers: { + 'Content-Type': 'application/json', + 'Cookie': 'session_token=$token', + }, + )); + expect(responseLogout.statusCode, 200, reason: 'Logout failed'); + final responseLogout2 = await testHandler(Request( + 'POST', + Uri.parse('http://localhost/api/auth/logout'), + headers: { + 'Content-Type': 'application/json', + 'Cookie': 'session_token=$token', + }, + )); + expect(responseLogout2.statusCode, 401, reason: 'Logout should fail'); + }); + + test('CreateUser', () async { + final token = await createLoggedInToken(await defaultUser.get, testHandler); + + final userCreate = UserCreateDto( + email: 'user@example.com', + password: 'password', + name: 'John Doe1', + ); + + final responseCreate = await testHandler(Request( + 'POST', + Uri.parse('http://localhost/api/users/'), + headers: { + 'Content-Type': 'application/json', + 'Cookie': 'session_token=$token', + }, + body: jsonEncode(userCreate.toJson()), + )); + expect(responseCreate.statusCode, 200, reason: 'User creation failed'); + }); + + test('GetUser', () async { + final token = await createLoggedInToken(await defaultUser.get, testHandler); + final newUser = await database.users + .create(UserCreate( + email: 'user@example.com', + password: 'password', + name: 'John Doe1', + )) + .get; + + if (newUser == null) { + fail('User creation failed'); + } + final responseCreate = await testHandler(Request( + 'GET', + Uri.parse('http://localhost/api/users/${newUser.id}'), + headers: { + 'Cookie': 'session_token=$token', + }, + )); + expect(responseCreate.statusCode, 200, reason: 'User creation failed'); + }); +}