import 'dart:convert'; import 'package:flutter_test/flutter_test.dart'; import 'package:gametime/application/application.dart'; import 'package:gametime/domain/domain.dart'; import 'package:gametime/infrastructure/remote/remote.dart'; import 'package:http/http.dart' as http; import 'package:http/testing.dart'; void main() { test( 'sendShare maps local workout pack payload to server pack contract', () async { Map? capturedBody; final api = HttpRemoteShareApi( HttpApiClient( baseUrl: Uri.parse('http://api.example.test'), client: MockClient((request) async { capturedBody = _jsonMap(request.body); expect(request.method, 'POST'); expect(request.url.path, '/shares'); expect(request.headers['authorization'], 'Bearer token-1'); return http.Response( jsonEncode({ 'shareId': 'share-1', 'recipientUserIds': ['user-2'], 'unresolvedEmails': const [], }), 201, ); }), ), ); await api.sendShare( resourceType: ShareResourceType.pack, payload: const { 'name': 'Pack reprise', 'workouts': [ {'id': 'template-1', 'name': 'Séance 1'}, {'id': 'template-2', 'name': 'Séance 2'}, ], }, recipientEmails: const ['friend@example.com'], token: 'token-1', ); expect(capturedBody, { 'shareKind': 'pack', 'packName': 'Pack reprise', 'items': [ { 'resourceType': 'workoutTemplate', 'payload': {'id': 'template-1', 'name': 'Séance 1'}, }, { 'resourceType': 'workoutTemplate', 'payload': {'id': 'template-2', 'name': 'Séance 2'}, }, ], 'recipientEmails': ['friend@example.com'], }); }, ); test( 'fetchInbox maps server pack payload without resourceType to local pack', () async { final api = HttpRemoteShareApi( HttpApiClient( baseUrl: Uri.parse('http://api.example.test'), client: MockClient((request) async { expect(request.method, 'GET'); expect(request.url.path, '/shares/inbox'); return http.Response( jsonEncode({ 'items': [ { 'shareId': 'share-pack-1', 'senderUserId': 'sender-1', 'shareKind': 'pack', 'packName': 'Pack été', 'resourceType': null, 'payload': { 'items': [ { 'resourceType': 'workoutTemplate', 'payload': {'id': 'template-1', 'name': 'Séance 1'}, }, ], }, 'status': 'pending', 'createdAt': '2026-07-17T12:00:00.000Z', 'respondedAt': null, }, ], }), 200, ); }), ), ); final items = await api.fetchInbox('token-1'); final payload = _jsonMap(items.single.payloadJson); expect(items.single.resourceType, ShareResourceType.pack); expect(payload, { 'name': 'Pack été', 'workouts': [ {'id': 'template-1', 'name': 'Séance 1'}, ], }); }, ); test( 'acceptShare returns every created resource from server packs', () async { final api = HttpRemoteShareApi( HttpApiClient( baseUrl: Uri.parse('http://api.example.test'), client: MockClient((request) async { expect(request.method, 'POST'); expect(request.url.path, '/shares/share-pack-1/accept'); return http.Response( jsonEncode({ 'createdResources': [ _createdResourceJson( resourceType: 'program', clientId: 'program-1', serverId: 'server-program-1', ), _createdResourceJson( resourceType: 'workoutTemplate', clientId: 'template-1', serverId: 'server-template-1', ), ], }), 200, ); }), ), ); final resources = await api.acceptShare('share-pack-1', 'token-1'); expect(resources.map((item) => item.resourceType), [ SyncResourceType.program, SyncResourceType.workoutTemplate, ]); expect(resources.map((item) => item.clientId), [ 'program-1', 'template-1', ]); }, ); } Map _createdResourceJson({ required String resourceType, required String clientId, required String serverId, }) { return { 'resourceType': resourceType, 'clientId': clientId, 'serverId': serverId, 'schemaVersion': 1, 'clientUpdatedAt': '2026-07-17T12:00:00.000Z', 'serverUpdatedAt': '2026-07-17T12:01:00.000Z', 'deletedAt': null, 'payload': {'id': clientId}, }; } Map _jsonMap(String source) { final decoded = jsonDecode(source); return Map.from(decoded as Map); }