[verified] Publish ReelBox source under GPLv3
This commit is contained in:
commit
db2b505ca3
445 files changed
+105274
No files matched your search
@@ -0,0 +1,153 @@
|
||||
// Mobile layout checks; optional captures are host-rendered, not device evidence.
|
||||
import 'dart:io';
|
||||
import 'dart:ui' as ui;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:reelbox/app.dart';
|
||||
import 'package:reelbox/data/api_service.dart';
|
||||
import 'package:reelbox/data/models.dart';
|
||||
import 'package:reelbox/state/app_state.dart';
|
||||
import 'package:reelbox/ui/library.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
class _LocalApi extends ApiService {
|
||||
@override
|
||||
Future<void> initialize({bool discover = true}) async {}
|
||||
@override
|
||||
Future<Map<String, dynamic>> home() async => {
|
||||
'genres': [],
|
||||
'actors': [],
|
||||
'countries': [],
|
||||
};
|
||||
@override
|
||||
Future<List<Map<String, dynamic>>> actors({
|
||||
int page = 1,
|
||||
String search = '',
|
||||
}) async => [];
|
||||
@override
|
||||
Future<List<Tag>> countries() async => [];
|
||||
}
|
||||
|
||||
void main() {
|
||||
for (final locale in ['en', 'fa']) {
|
||||
testWidgets(
|
||||
'mobile intro, privacy and useful settings remain reachable in $locale',
|
||||
(tester) async {
|
||||
tester.view.physicalSize = const Size(390, 844);
|
||||
tester.view.devicePixelRatio = 1;
|
||||
addTearDown(tester.view.resetPhysicalSize);
|
||||
addTearDown(tester.view.resetDevicePixelRatio);
|
||||
final output = Platform.environment['REELBOX_CLEANUP_SCREENSHOTS'];
|
||||
if (output != null) {
|
||||
await tester.runAsync(() async {
|
||||
final bytes = await File(
|
||||
Platform.environment['REELBOX_TEST_FONT'] ??
|
||||
'/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf',
|
||||
).readAsBytes();
|
||||
for (final name in ['Roboto', 'Ahem']) {
|
||||
await (FontLoader(
|
||||
name,
|
||||
)..addFont(Future.value(bytes.buffer.asByteData()))).load();
|
||||
}
|
||||
final icons = await File(
|
||||
Platform.environment['REELBOX_ICON_FONT'] ?? '/root/developer-tools/flutter/bin/cache/artifacts/material_fonts/MaterialIcons-Regular.otf',
|
||||
).readAsBytes();
|
||||
await (FontLoader(
|
||||
'MaterialIcons',
|
||||
)..addFont(Future.value(icons.buffer.asByteData()))).load();
|
||||
await Directory(output).create(recursive: true);
|
||||
});
|
||||
}
|
||||
SharedPreferences.setMockInitialValues({});
|
||||
final state = AppState(api: _LocalApi());
|
||||
addTearDown(state.dispose);
|
||||
await state.initialize(discover: false);
|
||||
await state.updateSettings(state.prefs.copyWith(locale: locale));
|
||||
final boundaryKey = GlobalKey();
|
||||
await tester.pumpWidget(
|
||||
RepaintBoundary(
|
||||
key: boundaryKey,
|
||||
child: MyApp(state: state),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
Future<void> capture(String name) async {
|
||||
expect(tester.takeException(), isNull);
|
||||
if (output == null) return;
|
||||
final boundary =
|
||||
boundaryKey.currentContext!.findRenderObject()!
|
||||
as RenderRepaintBoundary;
|
||||
await tester.runAsync(() async {
|
||||
final image = await boundary.toImage(pixelRatio: 2);
|
||||
final data = await image.toByteData(format: ui.ImageByteFormat.png);
|
||||
await File('$output/$name-$locale.png')
|
||||
.writeAsBytes(data!.buffer.asUint8List());
|
||||
image.dispose();
|
||||
});
|
||||
}
|
||||
|
||||
String label(String en, String fa) => locale == 'en' ? en : fa;
|
||||
Future<void> reveal(String text) async {
|
||||
final scrollable = find.byType(Scrollable).hitTestable().first;
|
||||
await tester.scrollUntilVisible(
|
||||
find.text(text),
|
||||
350,
|
||||
scrollable: scrollable,
|
||||
);
|
||||
await tester.ensureVisible(find.text(text));
|
||||
await tester.pumpAndSettle();
|
||||
}
|
||||
|
||||
expect(find.byType(FirstRunIntroPage), findsOneWidget);
|
||||
await capture('intro');
|
||||
await tester.tap(find.byKey(const Key('intro-skip')));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(
|
||||
find.descendant(
|
||||
of: find.byType(NavigationBar),
|
||||
matching: find.text(label('More', 'بیشتر')),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byType(MorePage), findsOneWidget);
|
||||
await capture('more');
|
||||
await reveal(label('Privacy & your data', 'حریم خصوصی و اطلاعات شما'));
|
||||
await tester.tap(
|
||||
find.text(label('Privacy & your data', 'حریم خصوصی و اطلاعات شما')),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
await capture('privacy-top');
|
||||
await reveal(label('Unencrypted media', 'رسانه بدون رمزنگاری'));
|
||||
expect(find.textContaining('HTTP'), findsWidgets);
|
||||
await capture('privacy-bottom');
|
||||
await tester.tap(find.byType(BackButton));
|
||||
await tester.pumpAndSettle();
|
||||
await reveal(label('Settings', 'تنظیمات'));
|
||||
await tester.tap(find.text(label('Settings', 'تنظیمات')));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byType(SettingsPage), findsOneWidget);
|
||||
expect(find.byKey(const Key('catalog-api-endpoint')), findsNothing);
|
||||
await capture('settings-top');
|
||||
final dataSaver = label('Data saver artwork', 'کاهش مصرف داده تصاویر');
|
||||
await reveal(dataSaver);
|
||||
await tester.tap(find.text(dataSaver));
|
||||
await tester.pumpAndSettle();
|
||||
expect(state.prefs.dataSaver, true);
|
||||
await reveal(label('Clear disposable cache', 'پاک کردن حافظه موقت'));
|
||||
expect(
|
||||
find.text(label('Export local library', 'خروجی کتابخانه محلی')),
|
||||
findsOneWidget,
|
||||
);
|
||||
expect(
|
||||
find.text(label('Import local library', 'ورود کتابخانه محلی')),
|
||||
findsOneWidget,
|
||||
);
|
||||
await capture('settings-data');
|
||||
await tester.pumpWidget(const SizedBox.shrink());
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user