import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:muning_menu_recommender/main.dart'; void main() { group('Muning Menu Recommender App Tests', () { testWidgets('App should start without crashing', ( WidgetTester tester, ) async { // Build our app and trigger a frame. await tester.pumpWidget( const ProviderScope(child: AmoriMenuRecommenderApp()), ); // Verify that the app starts expect(find.byType(MaterialApp), findsOneWidget); }); testWidgets('Splash screen should be displayed initially', ( WidgetTester tester, ) async { await tester.pumpWidget( const ProviderScope(child: AmoriMenuRecommenderApp()), ); // Should show splash screen initially expect(find.text('Muning Menu Recommender'), findsOneWidget); }); }); group('Black Box Testing - Equivalence Class Partitioning', () { test('Valid email format should pass validation', () { final validEmails = [ 'user@example.com', 'test.email@domain.co.id', 'user123@gmail.com', ]; for (final email in validEmails) { expect( _isValidEmail(email), true, reason: 'Email $email should be valid', ); } }); test('Invalid email format should fail validation', () { final invalidEmails = [ 'invalid-email', '@domain.com', 'user@', 'user.domain.com', '', ]; for (final email in invalidEmails) { expect( _isValidEmail(email), false, reason: 'Email $email should be invalid', ); } }); test('Valid password should pass validation', () { final validPasswords = ['password123', 'myPassword1', 'securePass2024']; for (final password in validPasswords) { expect( _isValidPassword(password), true, reason: 'Password should be valid', ); } }); test('Invalid password should fail validation', () { final invalidPasswords = [ '123', // Too short 'pass', // Too short '', // Empty 'password', // No numbers '12345678', // No letters ]; for (final password in invalidPasswords) { expect( _isValidPassword(password), false, reason: 'Password should be invalid', ); } }); }); group('Black Box Testing - Boundary Value Analysis', () { test('Budget range boundary values', () { // Test minimum boundary expect(_isValidBudget(10000), true); expect(_isValidBudget(9999), false); // Test maximum boundary expect(_isValidBudget(200000), true); expect(_isValidBudget(200001), false); // Test middle values expect(_isValidBudget(50000), true); expect(_isValidBudget(100000), true); }); test('OCR confidence threshold boundary values', () { // Test minimum acceptable confidence expect(_isAcceptableOCRConfidence(0.6), true); expect(_isAcceptableOCRConfidence(0.59), false); // Test maximum confidence expect(_isAcceptableOCRConfidence(1.0), true); expect(_isAcceptableOCRConfidence(1.01), false); }); }); group('Black Box Testing - Decision Table', () { test('User authentication decision table', () { // Test case 1: Valid email, valid password, terms accepted expect(_canUserRegister(true, true, true), true); // Test case 2: Valid email, valid password, terms not accepted expect(_canUserRegister(true, true, false), false); // Test case 3: Valid email, invalid password, terms accepted expect(_canUserRegister(true, false, true), false); // Test case 4: Invalid email, valid password, terms accepted expect(_canUserRegister(false, true, true), false); // Test case 5: All invalid expect(_canUserRegister(false, false, false), false); }); test('Menu recommendation decision table', () { // Test case 1: Has preferences, menu available, no allergies expect(_shouldRecommendMenu(true, true, false), true); // Test case 2: Has preferences, menu available, has allergies expect(_shouldRecommendMenu(true, true, true), false); // Test case 3: No preferences, menu available, no allergies expect(_shouldRecommendMenu(false, true, false), true); // Test case 4: Has preferences, menu not available, no allergies expect(_shouldRecommendMenu(true, false, false), false); }); }); } // Helper functions for testing bool _isValidEmail(String email) { return RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$').hasMatch(email); } bool _isValidPassword(String password) { if (password.length < 6) return false; if (!RegExp(r'^(?=.*[a-zA-Z])(?=.*\d)').hasMatch(password)) return false; return true; } bool _isValidBudget(int budget) { return budget >= 10000 && budget <= 200000; } bool _isAcceptableOCRConfidence(double confidence) { return confidence >= 0.6 && confidence <= 1.0; } bool _canUserRegister(bool validEmail, bool validPassword, bool termsAccepted) { return validEmail && validPassword && termsAccepted; } bool _shouldRecommendMenu( bool hasPreferences, bool menuAvailable, bool hasAllergies, ) { if (!menuAvailable) return false; if (hasAllergies) return false; return true; }