import 'dart:async'; import 'dart:developer'; import 'package:dio/dio.dart'; import 'package:eatvio_app/core/locator_service.dart'; import 'package:eatvio_app/core/utils/date_time_utils.dart'; import 'package:eatvio_app/core/websockets/ws_service.dart'; import 'package:eatvio_app/features/auth/models/credentials_model.dart'; import 'package:eatvio_app/features/auth/services/reset_password_service.dart'; import 'package:eatvio_app/features/blog_post_create/services/blog_post_service.dart'; import 'package:eatvio_app/features/calendar/services/calendar_service.dart'; import 'package:eatvio_app/features/chat/services/chat_service.dart'; import 'package:eatvio_app/features/consultant/become_consultant/services/consultant_service.dart'; import 'package:eatvio_app/features/consultations/services/consultation_service.dart'; import 'package:eatvio_app/features/create_diet/services/create_diet_service.dart'; import 'package:eatvio_app/features/create_plan/services/create_plan_service.dart'; import 'package:eatvio_app/features/create_recipe/models/recipe_model.dart'; import 'package:eatvio_app/features/create_recipe/models/step.dart'; import 'package:eatvio_app/features/create_recipe/reporitories/recipe_repository.dart'; import 'package:eatvio_app/features/diets/services/diet_service.dart'; import 'package:eatvio_app/features/feed/services/feed_service.dart'; import 'package:eatvio_app/features/glossary/services/glossary_service.dart'; import 'package:eatvio_app/features/menu/services/blocked_users_service.dart'; import 'package:eatvio_app/features/my_diets/services/my_diets_service.dart'; import 'package:eatvio_app/features/my_finance/services/cards_service.dart'; import 'package:eatvio_app/features/my_plans/services/my_plans_service.dart'; import 'package:eatvio_app/features/notifications/service/notifications_service.dart'; import 'package:eatvio_app/features/plans/services/plan_service.dart'; import 'package:eatvio_app/features/plans/services/plans_service.dart'; import 'package:eatvio_app/features/profile/services/profile_service.dart'; import 'package:eatvio_app/features/create_recipe/services/recipe_service.dart'; import 'package:eatvio_app/features/auth/services/auth_service.dart'; import 'package:eatvio_app/features/diary/services/diary_service.dart'; import 'package:eatvio_app/features/recipe/services/about_recipe_service.dart'; import 'package:eatvio_app/features/recipe/services/my_recipes_service.dart'; import 'package:eatvio_app/features/registration/services/registration_service.dart'; import 'package:eatvio_app/features/settings/services/settings_service.dart'; import 'package:eatvio_app/core/env_config.dart'; class TestResult { final bool success; final String? error; TestResult(this.success, [this.error]); } sealed class TestCases { String get name => throw UnimplementedError(); Future run({required String baseUrl}) async => throw UnimplementedError(); } class CreateRecipeTask implements TestCases { @override String get name => 'api/recipes/create'; @override Future run({required String baseUrl}) async { try { final dio = sl(); final recipeRepository = RecipeRepository(recipeService: CreateRecipeService(dio, baseUrl: baseUrl)); await recipeRepository.publishRecipe( const RecipeModel( title: 'Title', state: 'active', activeCookTime: 10, image: null, description: 'desc', type: 'first_meals', servings: 10, energyPerServing: 10, steps: [Step(description: 'desc')], ), ); } on DioException catch (e) { final res = e.response; if (res != null && (res.statusCode == null || res.statusCode! < 200 || res.statusCode! >= 300)) { return TestResult(false, 'DioError: statusCode=${res.statusCode}\n${res.data}'); } return TestResult(false, e.toString()); } catch (e, stack) { return TestResult(false, '$e\n$stack'); } return TestResult(true); } } class Test850task implements TestCases { @override String get name => 'task #850'; @override Future run({required String baseUrl}) async { try { final dio = sl(); final feedService = FeedService(dio, baseUrl: baseUrl); final profileService = ProfileService(dio, baseUrl: baseUrl); final dietsService = DietService(dio, baseUrl: baseUrl); final dietsPaginationModel = await feedService.getDiets(page: 1); final chosenDietsPaginationModel = await profileService.getChosenDiets(); final lastChosenDiet = chosenDietsPaginationModel.diets.firstOrNull; final today = DateTime.now(); final yesterday = today.subtract(const Duration(days: 1)); final tomorrow = today.add(const Duration(days: 1)); for (final diet in dietsPaginationModel.data) { if (!diet.author.authorIsMe) { if (lastChosenDiet?.state == 'started' || lastChosenDiet?.state == 'inited') { try { await dietsService.cancelDiet(id: lastChosenDiet?.dietId ?? 0); } catch (e, stack) { log('unexpected error7: $e'); return TestResult(false, '$e\n$stack'); } await Future.delayed(const Duration(seconds: 3)); } try { await dietsService.startDiet(id: diet.id, body: {'date': yesterday.format('yyyy-MM-dd')}); return TestResult(false, 'Expected error but got success'); } catch (e) { log('expect ot have error: $e'); } try { await dietsService.startDiet(id: diet.id, body: {'date': today.format('yyyy-MM-dd')}); } catch (e, stack) { log('unexpected error2: $e'); return TestResult(false, '$e\n$stack'); } try { await dietsService.cancelDiet(id: diet.id); } catch (e, stack) { log('unexpected error3: $e'); return TestResult(false, '$e\n$stack'); } await Future.delayed(const Duration(seconds: 3)); try { await dietsService.startDiet(id: diet.id, body: {'date': tomorrow.format('yyyy-MM-dd')}); } catch (e, stack) { log('unexpected error4: $e'); return TestResult(false, '$e\n$stack'); } try { await dietsService.cancelDiet(id: diet.id); } catch (e) { log('unexpected error5: $e'); } break; } } return TestResult(true); } catch (e, stack) { log('unexpected error6: $e'); return TestResult(false, '$e\n$stack'); } } } // ChatService class GetChatRoomPreviews implements TestCases { @override String get name => '/api/chat/index'; @override Future run({required String baseUrl}) async { try { // get all of needed services // final dio = sl(); // final chatService = ChatService(dio, baseUrl: baseUrl); // await chatService.getChatRooms(); return TestResult(true); } catch (e) { return TestResult(false, e.toString()); } } } class GetChatRoom implements TestCases { @override String get name => '/api/chat/show/{id}'; @override Future run({required String baseUrl}) async { try { // final dio = sl(); // final chatService = ChatService(dio, baseUrl: baseUrl); // final chatRoomsModels = await chatService.getChatRoomPreviews(); // await chatService.getChatRoom(id: chatRoomsModels.chatRooms.firstOrNull?.id ?? ''); return TestResult(true); } catch (e) { return TestResult(false, e.toString()); } } } class SendMessage implements TestCases { @override String get name => '/api/chat/{id}/message/send'; @override Future run({required String baseUrl}) async { try { // final dio = sl(); // final chatService = ChatService(dio, baseUrl: baseUrl); // final chatRoomsModels = await chatService.getChatRoomPreviews(); // await chatService.sendMessage(id: chatRoomsModels.chatRooms.firstOrNull?.id ?? '', data: 'test message'); return TestResult(true); } catch (e) { return TestResult(false, e.toString()); } } } class GetChatMessages implements TestCases { @override String get name => '/api/chat/show/{id}/messages?page={page}'; @override Future run({required String baseUrl}) async { try { // final dio = sl(); // final chatService = ChatService(dio, baseUrl: baseUrl); // final chatRoomsModels = await chatService.getChatRoomPreviews(); // await chatService.getChatMessages(id: chatRoomsModels.chatRooms.firstOrNull?.id ?? '', page: 1); return TestResult(true); } catch (e) { return TestResult(false, e.toString()); } } } class GetChatRoomIdByUserSlug implements TestCases { @override String get name => '/api/chat/get_by_user/{user}'; @override Future run({required String baseUrl}) async { try { final dio = sl(); final chatService = ChatService(dio, baseUrl: baseUrl); final consultantService = FeedService(dio, baseUrl: baseUrl); final profileService = ProfileService(dio, baseUrl: baseUrl); final myProfile = await profileService.getMyProfile(); final consultantsModel = await consultantService.getConsultants(); for (var consultant in consultantsModel.data) { if (consultant.slug != myProfile.slug) { await chatService.getChatRoomIdByUserSlug(user: consultant.slug); break; } } return TestResult(true); } catch (e) { return TestResult(false, e.toString()); } } } // FeedService class GetBlogPostList implements TestCases { @override String get name => '/api/blogPosts/index'; @override Future run({required String baseUrl}) async { try { final dio = sl(); final feedService = FeedService(dio, baseUrl: baseUrl); await feedService.getBlogPostList(page: 1); return TestResult(true); } catch (e) { return TestResult(false, e.toString()); } } } class GetRecipes implements TestCases { @override String get name => '/api/recipes/index'; @override Future run({required String baseUrl}) async { try { final dio = sl(); final feedService = FeedService(dio, baseUrl: baseUrl); final recipeService = CreateRecipeService(dio, baseUrl: baseUrl); final tagsModel = await recipeService.getTags(); final tags = tagsModel.data; final tagsIds = tags.map((e) => e.id).toList(); await feedService.getRecipes(page: 1, tags: tagsIds, query: null); return TestResult(true); } catch (e) { return TestResult(false, e.toString()); } } } class GetDiets implements TestCases { @override String get name => '/api/diets/index'; @override Future run({required String baseUrl}) async { try { final dio = sl(); final feedService = FeedService(dio, baseUrl: baseUrl); await feedService.getDiets(page: 1, query: null); return TestResult(true); } catch (e) { return TestResult(false, e.toString()); } } } class GetPlans implements TestCases { @override String get name => '/api/plans/index'; @override Future run({required String baseUrl}) async { try { final dio = sl(); final feedService = FeedService(dio, baseUrl: baseUrl); await feedService.getPlans(page: 1, query: null); return TestResult(true); } catch (e) { return TestResult(false, e.toString()); } } } class GetBlogPostComments implements TestCases { @override String get name => '/api/blogPosts/{id}/comments/show'; @override Future run({required String baseUrl}) async { try { final dio = sl(); final feedService = FeedService(dio, baseUrl: baseUrl); final blogPostsModel = await feedService.getBlogPostList(page: 1, query: null); final blogPosts = blogPostsModel.feedBlogPostList; await feedService.getBlogPostComments(id: blogPosts.first.id.toString()); return TestResult(true); } catch (e) { return TestResult(false, e.toString()); } } } class SendBlogPostComment implements TestCases { @override String get name => '/api/blogPosts/{id}/comment/create'; @override Future run({required String baseUrl}) async { try { final dio = sl(); final feedService = FeedService(dio, baseUrl: baseUrl); final blogPostsModel = await feedService.getBlogPostList(page: 1, query: null); final blogPosts = blogPostsModel.feedBlogPostList; await feedService.sendBlogPostComment(id: blogPosts.first.id.toString(), body: 'auto test message'); return TestResult(true); } catch (e) { return TestResult(false, e.toString()); } } } class GetDietsComments implements TestCases { @override String get name => '/api/diets/{id}/comments/show'; @override Future run({required String baseUrl}) async { try { final dio = sl(); final feedService = FeedService(dio, baseUrl: baseUrl); final dietsModel = await feedService.getDiets(page: 1, query: null); final diets = dietsModel.data; await feedService.getDietsComments(id: diets.first.id.toString()); return TestResult(true); } catch (e) { return TestResult(false, e.toString()); } } } class SendDietsComment implements TestCases { @override String get name => '/api/diets/{id}/comment/create'; @override Future run({required String baseUrl}) async { try { final dio = sl(); final feedService = FeedService(dio, baseUrl: baseUrl); final dietsModel = await feedService.getDiets(page: 1, query: null); final diets = dietsModel.data; await feedService.sendDietsComment(id: diets.first.id.toString(), body: 'auto test message'); return TestResult(true); } catch (e) { return TestResult(false, e.toString()); } } } class GetPlansComments implements TestCases { @override String get name => '/api/plans/{slug}/comments/show'; @override Future run({required String baseUrl}) async { try { final dio = sl(); final feedService = FeedService(dio, baseUrl: baseUrl); final plansModel = await feedService.getPlans(page: 1, query: null); final plans = plansModel.data; await feedService.getPlansComments(slug: plans.first.slug); return TestResult(true); } catch (e) { return TestResult(false, e.toString()); } } } class SendPlansComment implements TestCases { @override String get name => '/api/plans/{slug}/comment/create'; @override Future run({required String baseUrl}) async { try { final dio = sl(); final feedService = FeedService(dio, baseUrl: baseUrl); final plansModel = await feedService.getPlans(page: 1, query: null); final plans = plansModel.data; await feedService.sendPlansComment(slug: plans.first.slug, body: 'auto test message'); return TestResult(true); } catch (e) { return TestResult(false, e.toString()); } } } class GetRecipesComments implements TestCases { @override String get name => '/api/recipes/{id}/comments/show'; @override Future run({required String baseUrl}) async { try { final dio = sl(); final feedService = FeedService(dio, baseUrl: baseUrl); final recipeService = CreateRecipeService(dio, baseUrl: baseUrl); final tagsModel = await recipeService.getTags(); final tags = tagsModel.data; final tagsIds = tags.map((e) => e.id).toList(); final recipesModel = await feedService.getRecipes(page: 1, tags: tagsIds, query: null); final recipes = recipesModel.recipesList; await feedService.getRecipesComments(id: recipes.first.id.toString()); return TestResult(true); } catch (e) { return TestResult(false, e.toString()); } } } // AuthService class AuthServiceTest implements TestCases { @override String get name => 'AuthService: getTokenByCredentials'; @override Future run({required String baseUrl}) async { try { final dio = sl(); final authService = AuthService(dio, baseUrl: baseUrl); // Use dummy credentials, expecting failure but no crash await authService.getTokenByCredentials( credentials: CredentialsModel(email: EnvConfig.testEmail, password: EnvConfig.testPassword), ); return TestResult(false, 'Should not succeed'); } catch (e) { return TestResult(true, 'Exception expected for dummy credentials'); } } } // DiaryService class DiaryServiceTest implements TestCases { @override String get name => 'DiaryService: getDiaryIndexByDate'; @override Future run({required String baseUrl}) async { try { final dio = sl(); final diaryService = DiaryService(dio, baseUrl: baseUrl); await diaryService.getDiaryIndexByDate(date: '2023-01-01'); return TestResult(true); } catch (e) { return TestResult(false, e.toString()); } } } // BlockedUserService class BlockedUserServiceTest implements TestCases { @override String get name => 'BlockedUserService: getBlockedUsers'; @override Future run({required String baseUrl}) async { try { final dio = sl(); final blockedUserService = BlockedUserService(dio, baseUrl: baseUrl); await blockedUserService.getBlockedUsers(); return TestResult(true); } catch (e) { return TestResult(false, e.toString()); } } } // PlanService class PlanServiceTest implements TestCases { @override String get name => 'PlanService: getPlan'; @override Future run({required String baseUrl}) async { try { final dio = sl(); final planService = PlanService(dio, baseUrl: baseUrl); // Use a dummy slug, expecting failure but no crash await planService.getPlan('dummy-slug'); return TestResult(false, 'Should not succeed'); } catch (e) { return TestResult(true, 'Exception expected for dummy slug'); } } } // AboutRecipeService class AboutRecipeServiceTest implements TestCases { @override String get name => 'AboutRecipeService: getRecipe'; @override Future run({required String baseUrl}) async { try { final dio = sl(); final aboutRecipeService = AboutRecipeService(dio, baseUrl: baseUrl); await aboutRecipeService.getRecipe('dummy-id'); return TestResult(false, 'Expected failure but got success'); } catch (e) { return TestResult(true, 'Exception expected for dummy id'); } } } // BlogPostService class BlogPostServiceTest implements TestCases { @override String get name => 'BlogPostService: createBlogPost'; @override Future run({required String baseUrl}) async { try { final dio = sl(); final blogPostService = BlogPostService(dio, baseUrl: baseUrl); // Use empty FormData, expecting failure but no crash await blogPostService.createBlogPost(formData: FormData()); return TestResult(false, 'Expected failure but got success'); } catch (e) { return TestResult(true, 'Exception expected for empty FormData'); } } } // CalendarService class CalendarServiceTest implements TestCases { @override String get name => 'CalendarService: getCalendar'; @override Future run({required String baseUrl}) async { try { final dio = sl(); final calendarService = CalendarService(dio, baseUrl: baseUrl); await calendarService.getCalendar(); return TestResult(true); } catch (e) { return TestResult(false, e.toString()); } } } // CardsService class CardsServiceTest implements TestCases { @override String get name => 'CardsService: getCards'; @override Future run({required String baseUrl}) async { try { final dio = sl(); final cardsService = CardsService(dio, baseUrl: baseUrl); await cardsService.getCards(); return TestResult(true); } catch (e) { return TestResult(false, e.toString()); } } } // ConsultantService class ConsultantServiceTest implements TestCases { @override String get name => 'ConsultantService: getMyRequestStatus'; @override Future run({required String baseUrl}) async { try { final dio = sl(); final consultantService = ConsultantService(dio, baseUrl: baseUrl); await consultantService.getMyRequestStatus(slug: 'dummy-slug'); return TestResult(false, 'Expected failure but got success'); } catch (e) { return TestResult(true, 'Exception expected for dummy slug'); } } } // ConsultationService class ConsultationServiceTest implements TestCases { @override String get name => 'ConsultationService: getConsultations'; @override Future run({required String baseUrl}) async { try { final dio = sl(); final consultationService = ConsultationService(dio); await consultationService.getConsultations(); return TestResult(true); } catch (e) { return TestResult(false, e.toString()); } } } // CreateDietService class CreateDietServiceTest implements TestCases { @override String get name => 'CreateDietService: getDietPortionsNutrition'; @override Future run({required String baseUrl}) async { try { final dio = sl(); final createDietService = CreateDietService(dio, baseUrl: baseUrl); await createDietService.getDietPortionsNutrition(diet: 0); return TestResult(false, 'Expected failure but got success'); } catch (e) { return TestResult(true, 'Exception expected for diet: 0'); } } } // CreatePlanService class CreatePlanServiceTest implements TestCases { @override String get name => 'CreatePlanService: createPlan'; @override Future run({required String baseUrl}) async { try { final dio = sl(); final createPlanService = CreatePlanService(dio, baseUrl: baseUrl); await createPlanService.createPlan(formData: FormData()); return TestResult(false, 'Expected failure but got success'); } catch (e) { return TestResult(true, 'Exception expected for empty FormData'); } } } // GlossaryService class GlossaryServiceTest implements TestCases { @override String get name => 'GlossaryService: getGlossaryByQuery'; @override Future run({required String baseUrl}) async { try { final dio = sl(); final glossaryService = GlossaryService(dio, baseUrl: baseUrl); await glossaryService.getGlossaryByQuery(query: 'test'); return TestResult(true); } catch (e) { return TestResult(false, e.toString()); } } } // MyDietsService class MyDietsServiceTest implements TestCases { @override String get name => 'MyDietsService: getDiets'; @override Future run({required String baseUrl}) async { try { final dio = sl(); final myDietsService = MyDietsService(dio, baseUrl: baseUrl); await myDietsService.getDiets(page: 1); return TestResult(true); } catch (e) { return TestResult(false, e.toString()); } } } // MyPlansService class MyPlansServiceTest implements TestCases { @override String get name => 'MyPlansService: getPlans'; @override Future run({required String baseUrl}) async { try { final dio = sl(); final myPlansService = MyPlansService(dio, baseUrl: baseUrl); await myPlansService.getPlans(page: 1); return TestResult(true); } catch (e) { return TestResult(false, e.toString()); } } } // MyRecipesService class MyRecipesServiceTest implements TestCases { @override String get name => 'MyRecipesService: getMyRecipes'; @override Future run({required String baseUrl}) async { try { final dio = sl(); final myRecipesService = MyRecipesService(dio, baseUrl: baseUrl); await myRecipesService.getMyRecipes(); return TestResult(true); } catch (e) { return TestResult(false, e.toString()); } } } // NotificationsService class NotificationsServiceTest implements TestCases { @override String get name => 'NotificationsService: getNotifications'; @override Future run({required String baseUrl}) async { try { final dio = sl(); final notificationsService = NotificationsService(dio); await notificationsService.getNotifications(page: 1); return TestResult(true); } catch (e) { return TestResult(false, e.toString()); } } } // PlansService class PlansServiceTest implements TestCases { @override String get name => 'PlansService: getPlansBySlug'; @override Future run({required String baseUrl}) async { try { final dio = sl(); final plansService = PlansService(dio, baseUrl: baseUrl); await plansService.getPlansBySlug(author: 'dummy-author'); return TestResult(false, 'Expected failure but got success'); } catch (e) { return TestResult(true, 'Exception expected for dummy author'); } } } // ProfileService class ProfileServiceTest implements TestCases { @override String get name => 'ProfileService: getMyProfile'; @override Future run({required String baseUrl}) async { try { final dio = sl(); final profileService = ProfileService(dio, baseUrl: baseUrl); await profileService.getMyProfile(); return TestResult(true); } catch (e) { return TestResult(false, e.toString()); } } } // RegistrationService class RegistrationServiceTest implements TestCases { @override String get name => 'RegistrationService: getLocationsByAddress'; @override Future run({required String baseUrl}) async { try { final dio = sl(); final registrationService = RegistrationService(dio, baseUrl: baseUrl); await registrationService.getLocationsByAddress(query: 'test'); return TestResult(true); } catch (e) { return TestResult(false, e.toString()); } } } // ResetPasswordService class ResetPasswordServiceTest implements TestCases { @override String get name => 'ResetPasswordService: sendEmailCodeForPasswordChange'; @override Future run({required String baseUrl}) async { try { final dio = sl(); final resetPasswordService = ResetPasswordService(dio, baseUrl: baseUrl); await resetPasswordService.sendEmailCodeForPasswordChange(data: {'email': 'test@example.com'}); return TestResult(false, 'Expected failure but got success'); } catch (e) { return TestResult(true, 'Exception expected for test@example.com'); } } } // SettingsService class SettingsServiceTest implements TestCases { @override String get name => 'SettingsService: getProfileSettings'; @override Future run({required String baseUrl}) async { try { final dio = sl(); final settingsService = SettingsService(dio, baseUrl: baseUrl); await settingsService.getProfileSettings(); return TestResult(true); } catch (e) { return TestResult(false, e.toString()); } } } // WsService class WsServiceTest implements TestCases { @override String get name => 'WsService: getWebsocket'; @override Future run({required String baseUrl}) async { try { final dio = sl(); final wsService = WsService(dio, baseUrl: baseUrl); await wsService.getWebsocket(); return TestResult(true); } catch (e) { return TestResult(false, e.toString()); } } }