@@ -21,9 +21,11 @@ import 'package:flutter_test/flutter_test.dart';
2121import 'package:mockito/mockito.dart' ;
2222import 'package:provider/provider.dart' ;
2323import 'package:wger/l10n/generated/app_localizations.dart' ;
24+ import 'package:wger/models/measurements/measurement_entry.dart' ;
2425import 'package:wger/providers/measurement.dart' ;
2526import 'package:wger/providers/nutrition.dart' ;
2627import 'package:wger/screens/measurement_entries_screen.dart' ;
28+ import 'package:wger/widgets/measurements/forms.dart' ;
2729
2830import '../../test_data/measurements.dart' ;
2931import '../nutrition/nutritional_plan_form_test.mocks.dart' ;
@@ -99,4 +101,118 @@ void main() {
99101 expect (find.text ('10.9.2022 08:00' ), findsWidgets);
100102 expect (find.text ('5.10.2022 07:30' ), findsWidgets);
101103 });
104+
105+ group ('MeasurementEntryForm time format consistency' , () {
106+ Widget createFormScreen ({
107+ String locale = 'en' ,
108+ MeasurementEntry ? entry,
109+ }) {
110+ when (mockMeasurementProvider.categories).thenReturn (getMeasurementCategories ());
111+ return ChangeNotifierProvider <MeasurementProvider >(
112+ create: (context) => mockMeasurementProvider,
113+ child: MaterialApp (
114+ locale: Locale (locale),
115+ localizationsDelegates: AppLocalizations .localizationsDelegates,
116+ supportedLocales: AppLocalizations .supportedLocales,
117+ home: Scaffold (
118+ body: SingleChildScrollView (
119+ child: MeasurementEntryForm (1 , entry),
120+ ),
121+ ),
122+ ),
123+ );
124+ }
125+
126+ testWidgets ('Time field uses 24h format (HH:mm) for new entries - EN' , (
127+ WidgetTester tester,
128+ ) async {
129+ await tester.pumpWidget (createFormScreen (locale: 'en' ));
130+ await tester.pumpAndSettle ();
131+
132+ // The time field should contain a time in HH:mm format (24h),
133+ // not AM/PM format, to stay consistent with DateFormat.Hm parsing
134+ final timeField = find.byWidgetPredicate (
135+ (widget) => widget is TextFormField && widget.controller? .text != null ,
136+ );
137+ expect (timeField, findsWidgets);
138+
139+ // Find the time controller text - it should match HH:mm pattern
140+ final timeFields = tester.widgetList <TextFormField >(timeField);
141+ final timeWidget = timeFields.where ((w) {
142+ final text = w.controller? .text ?? '' ;
143+ // Time field contains a colon but no slash (date has slashes)
144+ return text.contains (':' ) && ! text.contains ('/' ) && ! text.contains ('.' );
145+ });
146+ expect (timeWidget, isNotEmpty, reason: 'Should find a time field with HH:mm format' );
147+
148+ final timeText = timeWidget.first.controller! .text;
149+ // Verify it does NOT contain AM/PM
150+ expect (
151+ timeText.contains ('AM' ),
152+ isFalse,
153+ reason: 'Time should be 24h format, not 12h with AM' ,
154+ );
155+ expect (
156+ timeText.contains ('PM' ),
157+ isFalse,
158+ reason: 'Time should be 24h format, not 12h with PM' ,
159+ );
160+ // Verify it matches HH:mm pattern
161+ expect (
162+ RegExp (r'^\d{1,2}:\d{2}$' ).hasMatch (timeText),
163+ isTrue,
164+ reason: 'Time "$timeText " should match HH:mm pattern' ,
165+ );
166+ });
167+
168+ testWidgets ('Time field uses 24h format for existing entries with PM time' , (
169+ WidgetTester tester,
170+ ) async {
171+ // Use an entry with a PM time (18:30) to verify it's not shown as "6:30 PM"
172+ final pmEntry = MeasurementEntry (
173+ id: 10 ,
174+ category: 1 ,
175+ date: DateTime (2023 , 6 , 15 , 18 , 30 ),
176+ value: 25 ,
177+ notes: '' ,
178+ );
179+ await tester.pumpWidget (createFormScreen (locale: 'en' , entry: pmEntry));
180+ await tester.pumpAndSettle ();
181+
182+ // Should find "18:30" not "6:30 PM"
183+ final allTextFields = tester.widgetList <TextFormField >(find.byType (TextFormField ));
184+ final timeTexts = allTextFields
185+ .map ((w) => w.controller? .text ?? '' )
186+ .where ((t) => t.contains (':' ) && ! t.contains ('/' ) && ! t.contains ('.' ));
187+
188+ expect (timeTexts, isNotEmpty);
189+ final timeText = timeTexts.first;
190+ expect (
191+ timeText,
192+ equals ('18:30' ),
193+ reason: 'PM time should be displayed as 18:30, not 6:30 PM' ,
194+ );
195+ });
196+
197+ testWidgets ('Time field uses 24h format - DE locale' , (WidgetTester tester) async {
198+ final entry = MeasurementEntry (
199+ id: 10 ,
200+ category: 1 ,
201+ date: DateTime (2023 , 6 , 15 , 14 , 45 ),
202+ value: 25 ,
203+ notes: '' ,
204+ );
205+ await tester.pumpWidget (createFormScreen (locale: 'de' , entry: entry));
206+ await tester.pumpAndSettle ();
207+
208+ final allTextFields = tester.widgetList <TextFormField >(find.byType (TextFormField ));
209+ final timeTexts = allTextFields
210+ .map ((w) => w.controller? .text ?? '' )
211+ .where ((t) => t.contains (':' ) && ! t.contains ('/' ) && ! t.contains ('.' ));
212+
213+ expect (timeTexts, isNotEmpty);
214+ final timeText = timeTexts.first;
215+ expect (timeText, equals ('14:45' ));
216+ });
217+ });
102218}
0 commit comments