Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
adding tests
Browse files Browse the repository at this point in the history
Dante291 committed Nov 13, 2024
1 parent 75e2675 commit 3a3775d
Showing 10 changed files with 1,733 additions and 15 deletions.
1 change: 1 addition & 0 deletions lib/views/after_auth_screens/funds/campaigns_screen.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// TODO Implement this library.
2 changes: 0 additions & 2 deletions lib/views/after_auth_screens/funds/fund_pledges_screen.dart
Original file line number Diff line number Diff line change
@@ -303,7 +303,6 @@ class _PledgesScreenState extends State<PledgesScreen> {
/// **returns**:
/// * `Widget`: a list view of all pledges.
Widget _buildPledgesList(FundViewModel model) {
print(model.filteredPledges.length);
if (model.isFetchingPledges) {
return const Center(child: CircularProgressIndicator());
}
@@ -326,7 +325,6 @@ class _PledgesScreenState extends State<PledgesScreen> {
return ListView.builder(
itemCount: model.filteredPledges.length,
itemBuilder: (context, index) {
print(model.filteredPledges.length);
final pledge = model.filteredPledges[index];
return PledgeCard(
pledge: pledge,
2 changes: 1 addition & 1 deletion lib/widgets/pledge_card.dart
Original file line number Diff line number Diff line change
@@ -125,7 +125,7 @@ class PledgeCard extends StatelessWidget {
style: Theme.of(context).textTheme.bodySmall,
),
Text(
'\$${pledge.amount?.toStringAsFixed(2) ?? 'N/A'}',
'\$${pledge.amount!.toStringAsFixed(2)}',
style: Theme.of(context)
.textTheme
.titleLarge
86 changes: 74 additions & 12 deletions lib/widgets/update_pledge_dialogue_box.dart
Original file line number Diff line number Diff line change
@@ -44,6 +44,7 @@ class _UpdatePledgeDialogState extends State<UpdatePledgeDialog> {
super.initState();
_amountController =
TextEditingController(text: widget.pledge.amount?.toString() ?? '');
_amountController.addListener(_onAmountChanged);
_startDate = widget.pledge.startDate;
_endDate = widget.pledge.endDate;
_selectedPledgers = widget.pledge.pledgers ?? [];
@@ -56,6 +57,24 @@ class _UpdatePledgeDialogState extends State<UpdatePledgeDialog> {
_originalEndDate = widget.pledge.endDate;
}

/// Changes state if amout is changed.
///
/// **params**:
/// None
///
/// **returns**:
/// None
void _onAmountChanged() {
setState(() {});
}

@override
void dispose() {
_amountController.removeListener(_onAmountChanged);
_amountController.dispose();
super.dispose();
}

/// Checks if there are any changes in the current pledge details compared to the original values.
///
/// **params**:
@@ -64,14 +83,56 @@ class _UpdatePledgeDialogState extends State<UpdatePledgeDialog> {
/// **returns**:
/// * `bool`: `true` if any detail has changed, `false` otherwise.
bool _hasChanges() {
return _originalAmount != double.parse(_amountController.text) ||
double currentAmount = _originalAmount;
if (_amountController.text.isNotEmpty) {
try {
currentAmount = double.tryParse(_amountController.text) ?? 0;
} catch (e) {
// Handle invalid input gracefully if necessary
}
}

return currentAmount != _originalAmount ||
_originalCurrency != widget.model.donationCurrency ||
_originalPledgers.length != _selectedPledgers.length ||
_selectedPledgers.any((user) => !_originalPledgers.contains(user)) ||
_startDate != _originalStartDate ||
_endDate != _originalEndDate;
}

/// Method to get fields that are updated.
///
/// **params**:
/// None
///
/// **returns**:
/// * `Map<String, dynamic>`: Object which include fields which are changed.
Map<String, dynamic> _getChangedFields() {
final Map<String, dynamic> changes = {'id': widget.pledge.id};
try {
final double currentAmount = double.tryParse(_amountController.text) ?? 0;
if (currentAmount != _originalAmount) {
changes['amount'] = currentAmount;
}
} catch (e) {
// Handle parse error if needed
}
if (widget.model.donationCurrency != _originalCurrency) {
changes['currency'] = widget.model.donationCurrency;
}
if (_startDate != _originalStartDate && _startDate != null) {
changes['startDate'] = DateFormat('yyyy-MM-dd').format(_startDate!);
}
if (_endDate != _originalEndDate && _endDate != null) {
changes['endDate'] = DateFormat('yyyy-MM-dd').format(_endDate!);
}
if (_selectedPledgers.length != _originalPledgers.length ||
_selectedPledgers.any((user) => !_originalPledgers.contains(user))) {
changes['users'] = _selectedPledgers.map((user) => user.id).toList();
}
return changes;
}

@override
Widget build(BuildContext context) {
return AlertDialog(
@@ -177,6 +238,7 @@ class _UpdatePledgeDialogState extends State<UpdatePledgeDialog> {
),
Expanded(
child: TextFormField(
key: const Key('amount_field'),
controller: _amountController,
decoration: InputDecoration(
labelText: 'Amount',
@@ -187,7 +249,15 @@ class _UpdatePledgeDialogState extends State<UpdatePledgeDialog> {
if (value == null || value.isEmpty) {
return 'Please enter an amount';
}
return null;
final parsedValue = double.tryParse(value);
if (parsedValue == null) {
return 'Amount must be a number';
}
if (parsedValue <= 0) {
return 'Amount must be greater than zero';
}

return null; // Input is valid
},
),
),
@@ -252,22 +322,14 @@ class _UpdatePledgeDialogState extends State<UpdatePledgeDialog> {
child: const Text('Cancel'),
),
ElevatedButton(
key: const Key('update_btn'),
onPressed: _hasChanges()
? () {
if (_formKey.currentState!.validate() &&
_startDate != null &&
_endDate != null &&
_selectedPledgers.isNotEmpty) {
widget.onSubmit({
'id': widget.pledge.id,
'amount': double.parse(_amountController.text),
'startDate': DateFormat('yyyy-MM-dd').format(_startDate!),
'endDate': DateFormat('yyyy-MM-dd').format(_endDate!),
'users':
_selectedPledgers.map((user) => user.id).toList(),
'currency': widget.model.donationCurrency,
});
Navigator.of(context).pop();
widget.onSubmit(_getChangedFields());
} else {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Please fill all fields')),
252 changes: 252 additions & 0 deletions test/views/after_auth_screens/funds/fund_pledges_screen_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
// ignore_for_file: talawa_api_doc
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:talawa/models/funds/fund_campaign.dart';
import 'package:talawa/models/funds/fund_pledges.dart';
import 'package:talawa/models/user/user_info.dart';
import 'package:talawa/router.dart' as router;
import 'package:talawa/services/fund_service.dart';
import 'package:talawa/services/navigation_service.dart';
import 'package:talawa/services/size_config.dart';
import 'package:talawa/utils/app_localization.dart';
import 'package:talawa/view_model/after_auth_view_models/funds_view_models/fund_view_model.dart';
import 'package:talawa/views/after_auth_screens/funds/fund_pledges_screen.dart';
import 'package:talawa/widgets/pledge_card.dart';

import '../../../helpers/test_helpers.dart';
import '../../../helpers/test_locator.dart';

// Helper function to create test campaign
Campaign getTestCampaign() {
return Campaign(
id: "1",
name: "Test Campaign",
fundingGoal: 1000.0,
startDate: DateTime.now(),
endDate: DateTime.now().add(const Duration(days: 30)),
);
}

// Helper function to create test pledges
List<Pledge> getTestPledges() {
return [
Pledge(
id: "1",
amount: 100,
endDate: DateTime.now().add(const Duration(days: 15)),
pledgers: [User(firstName: 'John', lastName: 'Doe')],
),
Pledge(
id: "2",
amount: 200,
endDate: DateTime.now().add(const Duration(days: 20)),
pledgers: [User(firstName: 'Jane', lastName: 'Smith')],
),
];
}

Widget createPledgesScreen() {
return MaterialApp(
locale: const Locale('en'),
localizationsDelegates: [
const AppLocalizationsDelegate(isTest: true),
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
home: PledgesScreen(campaign: getTestCampaign()),
navigatorKey: locator<NavigationService>().navigatorKey,
onGenerateRoute: router.generateRoute,
);
}

void main() {
testSetupLocator();
setUpAll(() {
TestWidgetsFlutterBinding.ensureInitialized();

registerServices();
locator<SizeConfig>().test();
});

tearDownAll(() {
unregisterServices();
});

group('PledgesScreen Widget Tests', () {
testWidgets('Check if PledgesScreen shows up', (tester) async {
await tester.pumpWidget(createPledgesScreen());
await tester.pumpAndSettle();

expect(find.byType(PledgesScreen), findsOneWidget);
expect(find.text('Pledges for Test Campaign'), findsOneWidget);
});

testWidgets('Test tab buttons functionality', (tester) async {
await tester.pumpWidget(createPledgesScreen());
await tester.pumpAndSettle();

// Check if both tabs exist
expect(find.text('Pledged'), findsOneWidget);
expect(find.text('Raised'), findsOneWidget);

// Test tab switching
await tester.tap(find.text('Raised'));
await tester.pumpAndSettle();

// Verify color change or selection state
final raisedButton = tester.widget<Container>(
find
.ancestor(
of: find.text('Raised'),
matching: find.byType(Container),
)
.first,
);
expect(raisedButton.decoration, isA<BoxDecoration>());
});

testWidgets('Test search functionality', (tester) async {
final mockFundViewModel = FundViewModel();
// Setup mock data
mockFundViewModel.allPledges.addAll(getTestPledges());

await tester.pumpWidget(createPledgesScreen());
await tester.pumpAndSettle();

// Find and interact with search field
final searchField = find.byType(TextField).first;
expect(searchField, findsOneWidget);

await tester.enterText(searchField, 'John');
await tester.pumpAndSettle();
mockFundViewModel.allPledges.clear();
});

testWidgets('Test sort dropdown functionality', (tester) async {
await tester.pumpWidget(createPledgesScreen());
await tester.pumpAndSettle();

// Find dropdown
final dropdownButton = find.byType(DropdownButton<String>);
expect(dropdownButton, findsOneWidget);

// Open dropdown
await tester.tap(dropdownButton);
await tester.pumpAndSettle();

// Verify dropdown items
expect(find.text('End Date (Latest)'), findsWidgets);
expect(find.text('Amount (Highest)'), findsOneWidget);
});

testWidgets('Test add pledge functionality', (tester) async {
await tester.pumpWidget(createPledgesScreen());
await tester.pumpAndSettle();

// Find and tap FAB
final fabButton = find.byType(FloatingActionButton);
expect(fabButton, findsOneWidget);

await tester.tap(fabButton);
await tester.pumpAndSettle();

// Verify dialog appears
expect(find.text('Create Pledge'), findsOneWidget);
});

testWidgets('Test pledge list view when empty', (tester) async {
final mockFundViewModel = FundViewModel();
// Setup empty pledges
mockFundViewModel.allPledges.clear();

await tester.pumpWidget(createPledgesScreen());
await tester.pumpAndSettle();

expect(find.text('No pledges found.'), findsOneWidget);
});

testWidgets('Test progress indicator display', (tester) async {
final mockFundViewModel = FundViewModel();
// Setup mock data with specific values
mockFundViewModel.allPledges.addAll(getTestPledges());

await tester.pumpWidget(createPledgesScreen());
await tester.pumpAndSettle();

// Verify progress bar elements
expect(find.byType(Stack), findsWidgets);
expect(find.textContaining('%'), findsOneWidget);
expect(find.textContaining('Goal: \$'), findsOneWidget);
});

testWidgets('Test pledge card interactions', (tester) async {
final mockFundService = locator<FundService>();
final mockPledges = [
Pledge(
id: '1',
pledgers: [
User(
id: userConfig.currentUser.id,
firstName: 'John',
lastName: 'Doe',
),
],
amount: 100,
),
];

when(mockFundService.getPledgesByCampaign('1', orderBy: 'endDate_DESC'))
.thenAnswer((_) async => mockPledges);
await tester.pumpWidget(createPledgesScreen());
await tester.pumpAndSettle();

// Find pledge cards
expect(find.byType(PledgeCard), findsWidgets);

// Test update pledge
await tester.tap(find.byIcon(Icons.edit).first);
await tester.pumpAndSettle();

// Verify update dialog appears
expect(find.text('Update Pledge'), findsOneWidget);
});

testWidgets('Test delete pledge confirmation', (tester) async {
final mockFundService = locator<FundService>();
final mockPledges = [
Pledge(
id: '1',
pledgers: [
User(
id: userConfig.currentUser.id,
firstName: 'John',
lastName: 'Doe',
),
],
amount: 100,
),
];

when(mockFundService.getPledgesByCampaign('1', orderBy: 'endDate_DESC'))
.thenAnswer((_) async => mockPledges);

await tester.pumpWidget(createPledgesScreen());
await tester.pumpAndSettle();

// Find and tap delete button
await tester.tap(find.byIcon(Icons.delete).first);
await tester.pumpAndSettle();

// Verify delete confirmation dialog
expect(find.text('Delete Pledge'), findsOneWidget);
expect(
find.text('Are you sure you want to delete this pledge?'),
findsOneWidget,
);
expect(find.text('Cancel'), findsOneWidget);
expect(find.text('Delete'), findsWidgets);
});
});
}
142 changes: 142 additions & 0 deletions test/views/after_auth_screens/funds/fund_screen_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
// ignore_for_file: talawa_api_doc
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:talawa/models/funds/fund.dart';
import 'package:talawa/models/user/user_info.dart';
import 'package:talawa/router.dart' as router;
import 'package:talawa/services/fund_service.dart';
import 'package:talawa/services/navigation_service.dart';
import 'package:talawa/services/size_config.dart';
import 'package:talawa/utils/app_localization.dart';
import 'package:talawa/views/after_auth_screens/funds/fundraising_campaigns_screen.dart';
import 'package:talawa/views/after_auth_screens/funds/funds_screen.dart';

import '../../../helpers/test_helpers.dart';
import '../../../helpers/test_locator.dart';

Widget createFundScreen() {
return MaterialApp(
locale: const Locale('en'),
localizationsDelegates: [
const AppLocalizationsDelegate(isTest: true),
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
home: const FundScreen(),
navigatorKey: locator<NavigationService>().navigatorKey,
onGenerateRoute: router.generateRoute,
);
}

void main() {
testSetupLocator();
setUpAll(() {
TestWidgetsFlutterBinding.ensureInitialized();
registerServices();
locator<SizeConfig>().test();
});

tearDownAll(() {
unregisterServices();
});

group('FundScreen Widget Tests', () {
testWidgets('Check if FundScreen shows up', (tester) async {
await tester.pumpWidget(createFundScreen());
await tester.pumpAndSettle();

expect(find.byType(FundScreen), findsOneWidget);
expect(find.text('Funds'), findsOneWidget);
});

testWidgets('Test search functionality', (tester) async {
final mockFundService = locator<FundService>();
final mockFunds = [
Fund(
id: '1',
name: 'Test Fund',
creator: User(firstName: 'John', lastName: 'Doe'),
),
Fund(
id: '2',
name: 'Fund 2',
creator: User(firstName: 'John1', lastName: 'Doe2'),
),
];
when(mockFundService.getFunds(orderBy: 'createdAt_DESC'))
.thenAnswer((_) async => mockFunds);

await tester.pumpWidget(createFundScreen());
await tester.pumpAndSettle();

// Find and interact with search field
final searchField = find.byType(TextField).first;
expect(searchField, findsOneWidget);

await tester.enterText(searchField, 'Test');
await tester.pumpAndSettle();

// Verify that the filtered fund is displayed
expect(find.text('Test Fund'), findsOneWidget);
expect(find.text('Fund 2'), findsNothing);
});

testWidgets('Test sort dropdown functionality', (tester) async {
await tester.pumpWidget(createFundScreen());
await tester.pumpAndSettle();

// Find dropdown
final dropdownButton = find.byType(DropdownButton<String>);
expect(dropdownButton, findsOneWidget);

// Open dropdown
await tester.tap(dropdownButton);
await tester.pumpAndSettle();

// Verify dropdown items
expect(find.text('Newest'), findsWidgets);
expect(find.text('Oldest'), findsOneWidget);
});

testWidgets('Test fund list view when empty', (tester) async {
final mockFundService = locator<FundService>();
when(mockFundService.getFunds(orderBy: 'createdAt_DESC'))
.thenAnswer((_) async => []);
await tester.pumpWidget(createFundScreen());
await tester.pumpAndSettle();

expect(find.text('No funds in this organization.'), findsOneWidget);
});

testWidgets('Test fund card interactions', (tester) async {
final mockFundService = locator<FundService>();
final mockFund = Fund(
id: '1',
name: 'Test Fund',
creator: User(firstName: 'John', lastName: 'Doe'),
createdAt: DateTime.now(),
);

when(
mockFundService.getFunds(
orderBy: 'createdAt_DESC',
),
).thenAnswer((_) async => [mockFund]);

await tester.pumpWidget(createFundScreen());
await tester.pumpAndSettle();

// Find fund cards
expect(find.byType(FundCard), findsWidgets);

// Test navigate to campaigns screen
await tester.tap(find.byIcon(Icons.campaign).first);
await tester.pumpAndSettle();

// Verify campaigns screen is displayed
expect(find.byType(CampaignsScreen), findsOneWidget);
});
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
// ignore_for_file: talawa_api_doc
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:talawa/models/funds/fund_campaign.dart';
import 'package:talawa/router.dart' as router;
import 'package:talawa/services/fund_service.dart';
import 'package:talawa/services/navigation_service.dart';
import 'package:talawa/services/size_config.dart';
import 'package:talawa/utils/app_localization.dart';
import 'package:talawa/views/after_auth_screens/funds/fund_pledges_screen.dart';
import 'package:talawa/views/after_auth_screens/funds/fundraising_campaigns_screen.dart';

import '../../../helpers/test_helpers.dart';
import '../../../helpers/test_locator.dart';

Widget createCampaignsScreen() {
return MaterialApp(
locale: const Locale('en'),
localizationsDelegates: [
const AppLocalizationsDelegate(isTest: true),
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
home: const CampaignsScreen(
fundId: '1',
fundName: 'Test Fund',
),
navigatorKey: locator<NavigationService>().navigatorKey,
onGenerateRoute: router.generateRoute,
);
}

void main() {
testSetupLocator();
setUpAll(() {
TestWidgetsFlutterBinding.ensureInitialized();
registerServices();
locator<SizeConfig>().test();
});

tearDownAll(() {
unregisterServices();
});

group('CampaignsScreen Widget Tests', () {
testWidgets('Check if CampaignsScreen shows up', (tester) async {
await tester.pumpWidget(createCampaignsScreen());
await tester.pumpAndSettle();

expect(find.byType(CampaignsScreen), findsOneWidget);
expect(find.text('Campaigns'), findsOneWidget);
});

testWidgets('Test search functionality', (tester) async {
final mockFundService = locator<FundService>();
final mockCampaign = [
Campaign(
id: '1',
name: 'Test Campaign',
startDate: DateTime.now(),
endDate: DateTime.now().add(const Duration(days: 30)),
fundingGoal: 1000.0,
),
];
when(mockFundService.getCampaigns('1', orderBy: 'endDate_DESC'))
.thenAnswer((_) async => mockCampaign);

await tester.pumpWidget(createCampaignsScreen());
await tester.pumpAndSettle();

// Find and interact with search field
final searchField = find.byType(TextField).first;
expect(searchField, findsOneWidget);

await tester.enterText(searchField, 'Test');
await tester.pumpAndSettle();

// Verify that the filtered campaign is displayed
expect(find.text('Test Campaign'), findsOneWidget);
});

testWidgets('Test sort dropdown functionality', (tester) async {
await tester.pumpWidget(createCampaignsScreen());
await tester.pumpAndSettle();

// Find dropdown
final dropdownButton = find.byType(DropdownButton<String>);
expect(dropdownButton, findsOneWidget);

// Open dropdown
await tester.tap(dropdownButton);
await tester.pumpAndSettle();

// Verify dropdown items
expect(find.text('End Date (Latest)'), findsWidgets);
expect(find.text('End Date (Earliest)'), findsOneWidget);
expect(find.text('Amount (Highest)'), findsOneWidget);
expect(find.text('Amount (Lowest)'), findsOneWidget);
});

testWidgets('Test campaign list view when empty', (tester) async {
final mockFundService = locator<FundService>();

when(mockFundService.getCampaigns('1', orderBy: 'endDate_DESC'))
.thenAnswer((_) async => []);

await tester.pumpWidget(createCampaignsScreen());
await tester.pumpAndSettle();

expect(find.text('No campaigns for this fund.'), findsOneWidget);
});

testWidgets('Test campaign card interactions', (tester) async {
final mockFundService = locator<FundService>();
final mockCampaign = Campaign(
id: '1',
name: 'Test Campaign',
startDate: DateTime.now(),
endDate: DateTime.now().add(const Duration(days: 30)),
fundingGoal: 1000.0,
);

when(
mockFundService.getCampaigns(
'1',
orderBy: 'endDate_DESC',
),
).thenAnswer((_) async => [mockCampaign]);

await tester.pumpWidget(createCampaignsScreen());
await tester.pumpAndSettle();

// Find campaign cards
expect(find.byType(CampaignCard), findsWidgets);

// Test navigate to pledges screen
await tester.tap(find.byIcon(Icons.volunteer_activism).first);
await tester.pumpAndSettle();

// Verify pledges screen is displayed
expect(find.byType(PledgesScreen), findsOneWidget);
});
});
}
286 changes: 286 additions & 0 deletions test/widget_tests/widgets/add_pledge_dialogue_box_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,286 @@
// ignore_for_file: talawa_api_doc
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:talawa/models/user/user_info.dart';
import 'package:talawa/utils/app_localization.dart';
import 'package:talawa/view_model/after_auth_view_models/funds_view_models/fund_view_model.dart';
import 'package:talawa/widgets/add_pledge_dialogue_box.dart';

class MockFundViewModel extends Mock implements FundViewModel {
@override
String get donationCurrency => 'USD';

@override
String get donationCurrencySymbol => '\$';

@override
List<User> get orgMembersList => [
User(
id: '1',
firstName: 'John',
lastName: 'Doe',
),
User(
id: '2',
firstName: 'Jane',
lastName: 'Smith',
),
User(
id: '3',
firstName: 'Bob',
lastName: 'Johnson',
),
];
}

Widget createAddPledgeDialog({
required Function(Map<String, dynamic>) onSubmit,
required FundViewModel model,
required String campaignId,
}) {
return MaterialApp(
locale: const Locale('en'),
localizationsDelegates: [
const AppLocalizationsDelegate(isTest: true),
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
home: Scaffold(
body: Builder(
builder: (context) => TextButton(
onPressed: () {
showDialog(
context: context,
builder: (context) => AddPledgeDialog(
onSubmit: onSubmit,
model: model,
campaignId: campaignId,
),
);
},
child: const Text('Show Dialog'),
),
),
),
);
}

void main() {
late MockFundViewModel mockModel;
late Map<String, dynamic> submittedData;

setUp(() {
mockModel = MockFundViewModel();
submittedData = {};
});

group('AddPledgeDialog Widget Tests', () {
testWidgets('Dialog shows up with correct initial state',
(WidgetTester tester) async {
await tester.pumpWidget(
createAddPledgeDialog(
onSubmit: (data) => submittedData = data,
model: mockModel,
campaignId: '123',
),
);
await tester.pumpAndSettle();

// Open dialog
await tester.tap(find.text('Show Dialog'));
await tester.pumpAndSettle();

// Verify initial state
expect(find.text('Create Pledge'), findsOneWidget);
expect(find.text('Select Pledger:'), findsOneWidget);
expect(find.text('Select Start date'), findsOneWidget);
expect(find.text('Select End date'), findsOneWidget);
expect(find.text('Amount'), findsOneWidget);
expect(find.text('USD'), findsOneWidget);
});

testWidgets('Can select pledgers from popup menu',
(WidgetTester tester) async {
await tester.pumpWidget(
createAddPledgeDialog(
onSubmit: (data) => submittedData = data,
model: mockModel,
campaignId: '123',
),
);
await tester.pumpAndSettle();

// Open dialog
await tester.tap(find.text('Show Dialog'));
await tester.pumpAndSettle();

// Open pledger selection menu
await tester.tap(find.byIcon(Icons.add));
await tester.pumpAndSettle();

// Select a pledger
await tester.tap(find.text('John Doe').last);
await tester.pumpAndSettle();

// Verify pledger chip appears
expect(find.byType(Chip), findsOneWidget);
expect(find.text('John Doe'), findsOneWidget);
});

testWidgets('Can remove selected pledgers', (WidgetTester tester) async {
await tester.pumpWidget(
createAddPledgeDialog(
onSubmit: (data) => submittedData = data,
model: mockModel,
campaignId: '123',
),
);
await tester.pumpAndSettle();

// Open dialog
await tester.tap(find.text('Show Dialog'));
await tester.pumpAndSettle();

// Add a pledger
await tester.tap(find.byIcon(Icons.add));
await tester.pumpAndSettle();
await tester.tap(find.text('John Doe').last);
await tester.pumpAndSettle();

// Remove the pledger
await tester.tap(find.byIcon(Icons.cancel));
await tester.pumpAndSettle();

// Verify pledger is removed
expect(find.byType(Chip), findsNothing);
});

testWidgets('Can select dates', (WidgetTester tester) async {
await tester.pumpWidget(
createAddPledgeDialog(
onSubmit: (data) => submittedData = data,
model: mockModel,
campaignId: '123',
),
);
await tester.pumpAndSettle();

// Open dialog
await tester.tap(find.text('Show Dialog'));
await tester.pumpAndSettle();

// Select start date
await tester.tap(find.text('Select Start date'));
await tester.pumpAndSettle();
await tester.tap(find.text('OK'));
await tester.pumpAndSettle();

// Verify start date is selected
expect(find.text('Select Start date'), findsNothing);
expect(find.textContaining('Start:'), findsOneWidget);

// Select end date
await tester.tap(find.text('Select End date'));
await tester.pumpAndSettle();
await tester.tap(find.text('OK'));
await tester.pumpAndSettle();

// Verify end date is selected
expect(find.text('Select End date'), findsNothing);
expect(find.textContaining('End:'), findsOneWidget);
});

testWidgets('Form validation works correctly', (WidgetTester tester) async {
await tester.pumpWidget(
createAddPledgeDialog(
onSubmit: (data) => submittedData = data,
model: mockModel,
campaignId: '123',
),
);
await tester.pumpAndSettle();

// Open dialog
await tester.tap(find.text('Show Dialog'));
await tester.pumpAndSettle();

// Try to submit empty form
await tester.tap(find.text('Create'));
await tester.pumpAndSettle();

// Verify error message
expect(find.text('Please fill all fields'), findsOneWidget);
});

testWidgets('Can submit valid form', (WidgetTester tester) async {
await tester.pumpWidget(
createAddPledgeDialog(
onSubmit: (data) => submittedData = data,
model: mockModel,
campaignId: '123',
),
);
await tester.pumpAndSettle();

// Open dialog
await tester.tap(find.text('Show Dialog'));
await tester.pumpAndSettle();

// Fill form
// Add pledger
await tester.tap(find.byIcon(Icons.add));
await tester.pumpAndSettle();
await tester.tap(find.text('John Doe').last);
await tester.pumpAndSettle();

// Enter amount
await tester.enterText(find.byType(TextFormField), '100');

// Select dates
await tester.tap(find.text('Select Start date'));
await tester.pumpAndSettle();
await tester.tap(find.text('OK'));
await tester.pumpAndSettle();

await tester.tap(find.text('Select End date'));
await tester.pumpAndSettle();
await tester.tap(find.text('OK'));
await tester.pumpAndSettle();

// Submit form
await tester.tap(find.text('Create'));
await tester.pumpAndSettle();

// Verify form submission
expect(submittedData.isEmpty, false);
expect(submittedData['campaignId'], '123');
expect(submittedData['amount'], 100.0);
expect(submittedData['userIds'], ['1']);
expect(submittedData['currency'], 'USD');
});

testWidgets('Can cancel dialog', (WidgetTester tester) async {
await tester.pumpWidget(
createAddPledgeDialog(
onSubmit: (data) => submittedData = data,
model: mockModel,
campaignId: '123',
),
);
await tester.pumpAndSettle();

// Open dialog
await tester.tap(find.text('Show Dialog'));
await tester.pumpAndSettle();

// Cancel dialog
await tester.tap(find.text('Cancel'));
await tester.pumpAndSettle();

// Verify dialog is closed
expect(find.text('Create Pledge'), findsNothing);
});
});
}
179 changes: 179 additions & 0 deletions test/widget_tests/widgets/pledge_card_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
// ignore_for_file: talawa_api_doc
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:intl/intl.dart';
import 'package:talawa/models/funds/fund_pledges.dart';
import 'package:talawa/models/user/user_info.dart';
import 'package:talawa/services/size_config.dart';
import 'package:talawa/utils/app_localization.dart';
import 'package:talawa/widgets/pledge_card.dart';

import '../../helpers/test_helpers.dart';
import '../../helpers/test_locator.dart';

Widget createPledgeCard({
required Pledge pledge,
VoidCallback? onUpdate,
VoidCallback? onDelete,
}) {
return MaterialApp(
locale: const Locale('en'),
localizationsDelegates: [
const AppLocalizationsDelegate(isTest: true),
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
home: Scaffold(
body: PledgeCard(
pledge: pledge,
onUpdate: onUpdate ?? () {},
onDelete: onDelete ?? () {},
),
),
);
}

final mockPledge = Pledge(
id: '1',
amount: 1000,
startDate: DateTime(2024, 1, 1),
endDate: DateTime(2024, 12, 31),
pledgers: [
User(
id: '1',
firstName: 'John',
lastName: 'Doe',
),
User(
id: '2',
firstName: 'Jane',
lastName: 'Smith',
),
User(
id: '3',
firstName: 'Bob',
lastName: 'Johnson',
),
User(
id: '4',
firstName: 'Alice',
lastName: 'Brown',
),
],
);

void main() {
testSetupLocator();
setUpAll(() {
TestWidgetsFlutterBinding.ensureInitialized();
registerServices();
locator<SizeConfig>().test();
});

tearDownAll(() {
unregisterServices();
});
group('PledgeCard Widget Tests', () {
testWidgets('PledgeCard displays basic information correctly',
(WidgetTester tester) async {
await tester.pumpWidget(createPledgeCard(pledge: mockPledge));
await tester.pumpAndSettle();

// Verify header
expect(find.text('Pledge Group'), findsOneWidget);

// Verify amount information
expect(find.text('Pledged'), findsOneWidget);
expect(find.text('\$1000.00'), findsOneWidget);
expect(find.text('Donated'), findsOneWidget);
expect(find.text('\$0.00'), findsOneWidget);

// Verify dates
expect(find.text('Start Date'), findsOneWidget);
expect(find.text('End Date'), findsOneWidget);
expect(
find.text(DateFormat('MMM d, y').format(DateTime(2024, 1, 1))),
findsOneWidget,
);
expect(
find.text(DateFormat('MMM d, y').format(DateTime(2024, 12, 31))),
findsOneWidget,
);
});

testWidgets('PledgeCard displays correct number of pledgers',
(WidgetTester tester) async {
await tester.pumpWidget(createPledgeCard(pledge: mockPledge));
await tester.pumpAndSettle();

// Verify pledgers section
expect(find.text('Pledgers'), findsOneWidget);

// Should show first 3 pledgers
expect(find.text('John Doe'), findsOneWidget);
expect(find.text('Jane Smith'), findsOneWidget);
expect(find.text('Bob Johnson'), findsOneWidget);

// Should show +1 more chip for the remaining pledger
expect(find.text('+1 more'), findsOneWidget);
});

testWidgets('PledgeCard handles null dates correctly',
(WidgetTester tester) async {
final pledgeWithNullDates = Pledge(
id: '1',
amount: 1000,
startDate: null,
endDate: null,
pledgers: [],
);

await tester.pumpWidget(createPledgeCard(pledge: pledgeWithNullDates));
await tester.pumpAndSettle();

expect(find.text('N/A'), findsNWidgets(2));
});

testWidgets('PledgeCard handles empty pledgers list',
(WidgetTester tester) async {
final pledgeWithNoPledgers = Pledge(
id: '1',
amount: 1000,
startDate: DateTime.now(),
endDate: DateTime.now(),
pledgers: [],
);

await tester.pumpWidget(createPledgeCard(pledge: pledgeWithNoPledgers));
await tester.pumpAndSettle();

expect(find.byType(Chip), findsNothing);
});

testWidgets('Update and Delete buttons trigger callbacks',
(WidgetTester tester) async {
bool updatePressed = false;
bool deletePressed = false;

await tester.pumpWidget(
createPledgeCard(
pledge: mockPledge,
onUpdate: () => updatePressed = true,
onDelete: () => deletePressed = true,
),
);
await tester.pumpAndSettle();

// Test Update button
await tester.tap(find.text('Update'));
await tester.pumpAndSettle();
expect(updatePressed, true);

// Test Delete button
await tester.tap(find.text('Delete'));
await tester.pumpAndSettle();
expect(deletePressed, true);
});
});
}
652 changes: 652 additions & 0 deletions test/widget_tests/widgets/update_pledge_dialogue_box_test.dart

Large diffs are not rendered by default.

0 comments on commit 3a3775d

Please sign in to comment.