feat(app): 完成 P0 钱包解锁、下载落盘与手机号登录
This commit is contained in:
1 parent
de941c841c
commit
136ee74618
47 files changed
+3264
-70
No files matched your search
@@ -4,7 +4,12 @@ import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:fruitshorts/core/data/models/drama.dart';
|
||||
import 'package:fruitshorts/core/data/models/play_ticket.dart';
|
||||
import 'package:fruitshorts/core/data/models/player_port.dart';
|
||||
import 'package:fruitshorts/core/data/models/download_license.dart';
|
||||
import 'package:fruitshorts/core/data/models/download_policy.dart';
|
||||
import 'package:fruitshorts/core/data/repositories/download_repository.dart';
|
||||
import 'package:fruitshorts/core/data/services/android_picture_in_picture.dart';
|
||||
import 'package:fruitshorts/core/data/services/download_controller.dart';
|
||||
import 'package:fruitshorts/core/data/services/download_storage.dart';
|
||||
import 'package:fruitshorts/core/data/services/playback_session.dart';
|
||||
import 'package:fruitshorts/pages/player/player_logic.dart';
|
||||
import 'package:fruitshorts/pages/player/player_view.dart';
|
||||
@@ -116,6 +121,34 @@ void main() {
|
||||
});
|
||||
});
|
||||
|
||||
test('should_play_local_file_without_ticket_when_episode_is_downloaded',
|
||||
() async {
|
||||
final playback = FakePlaybackRepository();
|
||||
final downloads = DownloadController(
|
||||
_EmptyDownloadRepository(),
|
||||
storage: _LocalStorage(),
|
||||
);
|
||||
await downloads.restore();
|
||||
final drama = _drama('signal');
|
||||
final logic = PlayerLogic(
|
||||
history: FakeWatchHistory(),
|
||||
playback: playback,
|
||||
pictureInPicture: _pip(),
|
||||
downloads: downloads,
|
||||
);
|
||||
logic.attach(
|
||||
PlayerPage(drama: drama, initialIndex: 0),
|
||||
isMounted: () => true,
|
||||
);
|
||||
|
||||
logic.start(factory: _RecordingFactory().create, coordinator: PlaybackCoordinator());
|
||||
await pumpEventQueue();
|
||||
await logic.session.playbackSettled;
|
||||
|
||||
expect(playback.requests, isEmpty);
|
||||
expect(logic.sessionEpisodes.first.videoUrl, 'file:///local/signal-1.mp4');
|
||||
});
|
||||
|
||||
group('surface flags', () {
|
||||
test('should_set_immersive_when_picture_in_picture_callback_fires', () async {
|
||||
final factory = _RecordingFactory();
|
||||
@@ -430,6 +463,75 @@ void main() {
|
||||
});
|
||||
}
|
||||
|
||||
class _LocalStorage implements DownloadStorage {
|
||||
@override
|
||||
Future<Map<String, String>> restore() async => {
|
||||
'signal-1': 'file:///local/signal-1.mp4',
|
||||
};
|
||||
|
||||
@override
|
||||
Future<String?> localPathFor(String episodeId) async =>
|
||||
episodeId == 'signal-1' ? 'file:///local/signal-1.mp4' : null;
|
||||
|
||||
@override
|
||||
Future<DownloadedMedia> download({
|
||||
required String episodeId,
|
||||
required String url,
|
||||
DownloadProgress? onProgress,
|
||||
}) async => throw UnimplementedError();
|
||||
|
||||
@override
|
||||
Future<void> delete(String episodeId) async {}
|
||||
|
||||
@override
|
||||
Future<void> clear() async {}
|
||||
}
|
||||
|
||||
class _EmptyDownloadRepository implements DownloadRepository {
|
||||
@override
|
||||
Future<DownloadPolicy> fetchPolicy() async => const DownloadPolicy(
|
||||
maxPerDevice: 20,
|
||||
licenseDays: 30,
|
||||
wifiOnly: false,
|
||||
maxQuality: 'AUTO',
|
||||
maxStorageBytes: 0,
|
||||
used: 0,
|
||||
remaining: 20,
|
||||
expirePolicyText: '',
|
||||
);
|
||||
|
||||
@override
|
||||
Future<List<DownloadLicense>> list() async => const [];
|
||||
|
||||
@override
|
||||
Future<DownloadLicense> grant(String episodeId, {String? quality}) async =>
|
||||
throw UnimplementedError();
|
||||
|
||||
@override
|
||||
Future<void> updateSettings({bool? wifiOnly, String? maxQuality}) async {}
|
||||
|
||||
@override
|
||||
Future<DownloadLicense> refreshUrl(String episodeId) async =>
|
||||
throw UnimplementedError();
|
||||
|
||||
@override
|
||||
Future<DownloadLicense> reportProgress(
|
||||
String episodeId, {
|
||||
String? deviceId,
|
||||
String? status,
|
||||
int? progressPercent,
|
||||
int? downloadedBytes,
|
||||
int? totalBytes,
|
||||
String? errorMsg,
|
||||
}) async => throw UnimplementedError();
|
||||
|
||||
@override
|
||||
Future<void> remove(String episodeId) async {}
|
||||
|
||||
@override
|
||||
Future<int> clear() async => 0;
|
||||
}
|
||||
|
||||
/// Counts native-style allocations so leaks are visible to a test.
|
||||
class _RecordingFactory {
|
||||
final List<_RecordingPlayer> created = [];
|
||||
|
||||
Reference in new issue
Block a user