A whole lot of stuff
This commit is contained in:
parent
faf319322a
commit
ad850d2be6
50 changed files with 3013 additions and 213 deletions
69
test/ad_free_upsell_dialog_test.dart
Normal file
69
test/ad_free_upsell_dialog_test.dart
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import 'package:fuel_tax_tracker/services/app_state.dart';
|
||||
import 'package:fuel_tax_tracker/widgets/ad_free_upsell_dialog.dart';
|
||||
|
||||
/// Covers the "remove ads for a year" upsell shown right after a user
|
||||
/// watches the app's one ad placement — see `AppState.syncNow`'s
|
||||
/// `onAdWatched` hook, wired up in main.dart. Tested here as a standalone
|
||||
/// dialog function, matching backup_reminder_test.dart's convention.
|
||||
void main() {
|
||||
Future<void> openDialog(WidgetTester tester, AppState appState) async {
|
||||
await tester.pumpWidget(
|
||||
ChangeNotifierProvider.value(
|
||||
value: appState,
|
||||
child: MaterialApp(
|
||||
home: Builder(
|
||||
builder: (context) => ElevatedButton(
|
||||
onPressed: () => showAdFreeUpsellDialog(context),
|
||||
child: const Text('open'),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.tap(find.text('open'));
|
||||
await tester.pumpAndSettle();
|
||||
}
|
||||
|
||||
testWidgets('shows the pitch with both actions', (tester) async {
|
||||
await openDialog(tester, AppState());
|
||||
|
||||
expect(find.text('Tired of Ads?'), findsOneWidget);
|
||||
expect(find.text('Not Now'), findsOneWidget);
|
||||
expect(find.text('Remove Ads'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('falls back to generic copy when no price is loaded yet', (tester) async {
|
||||
await openDialog(tester, AppState());
|
||||
|
||||
expect(find.textContaining('a single one-time purchase'), findsOneWidget);
|
||||
expect(find.textContaining('\$'), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('Not Now closes the dialog without navigating anywhere', (tester) async {
|
||||
await openDialog(tester, AppState());
|
||||
|
||||
await tester.tap(find.text('Not Now'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('Tired of Ads?'), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('Remove Ads closes the dialog and starts the purchase flow', (tester) async {
|
||||
final appState = AppState();
|
||||
await openDialog(tester, appState);
|
||||
|
||||
await tester.tap(find.text('Remove Ads'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('Tired of Ads?'), findsNothing, reason: 'dialog closed');
|
||||
// buyAdFreeYear() delegates to PurchaseService, which — with no real
|
||||
// store connection in tests — surfaces its failure through
|
||||
// AppState.purchaseError rather than throwing, so tapping through is
|
||||
// enough to confirm the button actually invoked it without crashing.
|
||||
expect(appState.purchaseError, isNotNull);
|
||||
});
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue