mirror of
https://github.com/Ujwal223/FocusGram.git
synced 2026-05-28 09:51:25 +02:00
Progress SAve- downloader,blur,ghost mode(Partially) works
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
import 'package:focusgram/services/injection_manager.dart';
|
||||
import 'package:focusgram/services/adblock/adblock_content_blocker_loader.dart';
|
||||
import 'package:focusgram/services/session_manager.dart';
|
||||
import 'package:focusgram/services/settings_service.dart';
|
||||
|
||||
class _FakeJsEvaluator implements JsEvaluator {
|
||||
final List<String> sources = [];
|
||||
|
||||
@override
|
||||
Future<void> evaluateJavascript({required String source}) async {
|
||||
sources.add(source);
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
setUp(() {
|
||||
SharedPreferences.setMockInitialValues({});
|
||||
});
|
||||
|
||||
test(
|
||||
'v2AdBlockerDomEnabled(true) does NOT trigger sponsored-post JS injection (handled by V2 engine)',
|
||||
() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final sm = SessionManager();
|
||||
final fakeEval = _FakeJsEvaluator();
|
||||
|
||||
final mgr = InjectionManager.forTest(
|
||||
jsEvaluator: fakeEval,
|
||||
prefs: prefs,
|
||||
sessionManager: sm,
|
||||
);
|
||||
|
||||
final settings = SettingsService();
|
||||
await settings.init();
|
||||
await settings.setV2AdBlockerDomEnabled(true);
|
||||
|
||||
expect(settings.v2AdBlockerDomEnabled, isTrue);
|
||||
|
||||
mgr.setSettingsService(settings);
|
||||
await mgr.runAllPostLoadInjections('https://www.instagram.com/');
|
||||
|
||||
// Verify that sponsored posts JS injection is NOT triggered by InjectionManager
|
||||
// (it's handled by the V2 DOM Ad Blocker engine instead)
|
||||
final sponsoredPostsInjected = fakeEval.sources.any(
|
||||
(s) => s.contains('hideSponsoredPosts') || s.contains('Sponsored'),
|
||||
);
|
||||
|
||||
expect(
|
||||
sponsoredPostsInjected,
|
||||
isFalse,
|
||||
reason:
|
||||
'Sponsored posts blocking is now handled by V2 DOM Ad Blocker, not JS injection',
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
'adblock parser extracts strict host rules and ignores allow/cosmetic rules',
|
||||
() {
|
||||
final hosts = AdblockContentBlockerLoader.parseHostsFromFilterText('''
|
||||
! comment
|
||||
[Adblock Plus 2.0]
|
||||
||ads.example.com^
|
||||
||tracker.example.net/path.js\$third-party
|
||||
@@||allowed.example.com^
|
||||
example.com##.sponsored
|
||||
||wild*.example.com^
|
||||
||bad,domain.example^
|
||||
||sub.adguard.example.org^\$script,third-party
|
||||
''');
|
||||
|
||||
expect(
|
||||
hosts,
|
||||
containsAll({
|
||||
'ads.example.com',
|
||||
'tracker.example.net',
|
||||
'sub.adguard.example.org',
|
||||
}),
|
||||
);
|
||||
expect(hosts, isNot(contains('allowed.example.com')));
|
||||
expect(hosts, isNot(contains('wild*.example.com')));
|
||||
expect(hosts, isNot(contains('bad,domain.example')));
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:focusgram/services/injection_manager.dart';
|
||||
import 'package:focusgram/services/session_manager.dart';
|
||||
import 'package:focusgram/services/settings_service.dart';
|
||||
|
||||
class _FakeJsEvaluator implements JsEvaluator {
|
||||
final List<String> sources = [];
|
||||
|
||||
@override
|
||||
Future<void> evaluateJavascript({required String source}) async {
|
||||
sources.add(source);
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
setUp(() {
|
||||
SharedPreferences.setMockInitialValues({});
|
||||
});
|
||||
|
||||
test(
|
||||
'does NOT inject hideSuggestedPosts JS even when legacy setting is true',
|
||||
() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final sm = SessionManager();
|
||||
final fakeEval = _FakeJsEvaluator();
|
||||
|
||||
final mgr = InjectionManager.forTest(
|
||||
jsEvaluator: fakeEval,
|
||||
prefs: prefs,
|
||||
sessionManager: sm,
|
||||
);
|
||||
|
||||
final settings = SettingsService();
|
||||
await settings.init();
|
||||
await settings.setHideSuggestedPosts(true);
|
||||
|
||||
mgr.setSettingsService(settings);
|
||||
|
||||
await mgr.runAllPostLoadInjections('https://www.instagram.com/');
|
||||
|
||||
final any = fakeEval.sources.any((s) => s.contains('hideSuggestedPosts'));
|
||||
expect(any, isFalse);
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
'does NOT inject hideSuggestedPosts JS when settings.hideSuggestedPosts=false',
|
||||
() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final sm = SessionManager();
|
||||
final fakeEval = _FakeJsEvaluator();
|
||||
|
||||
final mgr = InjectionManager.forTest(
|
||||
jsEvaluator: fakeEval,
|
||||
prefs: prefs,
|
||||
sessionManager: sm,
|
||||
);
|
||||
|
||||
final settings = SettingsService();
|
||||
await settings.init();
|
||||
await settings.setHideSuggestedPosts(false);
|
||||
|
||||
mgr.setSettingsService(settings);
|
||||
|
||||
await mgr.runAllPostLoadInjections('https://www.instagram.com/');
|
||||
|
||||
final any = fakeEval.sources.any((s) => s.contains('hideSuggestedPosts'));
|
||||
expect(any, isFalse);
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
'injects video downloader JS only when settings.videoDownloadEnabled=true',
|
||||
() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final sm = SessionManager();
|
||||
final fakeEval = _FakeJsEvaluator();
|
||||
|
||||
final mgr = InjectionManager.forTest(
|
||||
jsEvaluator: fakeEval,
|
||||
prefs: prefs,
|
||||
sessionManager: sm,
|
||||
);
|
||||
|
||||
final settings = SettingsService();
|
||||
await settings.init();
|
||||
await settings.setVideoDownloadEnabled(true);
|
||||
|
||||
mgr.setSettingsService(settings);
|
||||
|
||||
await mgr.runAllPostLoadInjections('https://www.instagram.com/');
|
||||
|
||||
final any = fakeEval.sources.any(
|
||||
(s) => s.contains('__fgMediaDownloadRunning'),
|
||||
);
|
||||
expect(any, isTrue);
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
'does NOT inject video downloader JS when settings.videoDownloadEnabled=false',
|
||||
() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final sm = SessionManager();
|
||||
final fakeEval = _FakeJsEvaluator();
|
||||
|
||||
final mgr = InjectionManager.forTest(
|
||||
jsEvaluator: fakeEval,
|
||||
prefs: prefs,
|
||||
sessionManager: sm,
|
||||
);
|
||||
|
||||
final settings = SettingsService();
|
||||
await settings.init();
|
||||
await settings.setVideoDownloadEnabled(false);
|
||||
|
||||
mgr.setSettingsService(settings);
|
||||
|
||||
await mgr.runAllPostLoadInjections('https://www.instagram.com/');
|
||||
|
||||
final any = fakeEval.sources.any(
|
||||
(s) => s.contains('__fgMediaDownloadRunning'),
|
||||
);
|
||||
expect(any, isFalse);
|
||||
},
|
||||
);
|
||||
|
||||
test('injects home feed scroll lock flag when enabled', () async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final sm = SessionManager();
|
||||
final fakeEval = _FakeJsEvaluator();
|
||||
|
||||
final mgr = InjectionManager.forTest(
|
||||
jsEvaluator: fakeEval,
|
||||
prefs: prefs,
|
||||
sessionManager: sm,
|
||||
);
|
||||
|
||||
final settings = SettingsService();
|
||||
await settings.init();
|
||||
await settings.setBlockHomeFeedScrollInternal(true);
|
||||
|
||||
mgr.setSettingsService(settings);
|
||||
|
||||
await mgr.runAllPostLoadInjections('https://www.instagram.com/');
|
||||
|
||||
final any = fakeEval.sources.any(
|
||||
(s) => s.contains('window.__fgBlockHomeFeedScroll = true;'),
|
||||
);
|
||||
expect(any, isTrue);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:focusgram/services/injection_controller.dart';
|
||||
|
||||
void main() {
|
||||
group('InjectionController reels blocker', () {
|
||||
test('includes strict reels blocker JS when sessionActive=false', () {
|
||||
final js = InjectionController.buildInjectionJS(
|
||||
sessionActive: false,
|
||||
blurExplore: false,
|
||||
blurReels: false,
|
||||
tapToUnblur: false,
|
||||
enableTextSelection: false,
|
||||
hideSuggestedPosts: false,
|
||||
hideSponsoredPosts: false,
|
||||
hideLikeCounts: false,
|
||||
hideFollowerCounts: false,
|
||||
hideExploreTab: false,
|
||||
hideReelsTab: false,
|
||||
hideShopTab: false,
|
||||
disableReelsEntirely: false,
|
||||
blockHomeFeedScroll: false,
|
||||
);
|
||||
|
||||
expect(js, contains('window.__fgReelsBlockPatched'));
|
||||
expect(js, contains("window.location.href = '/reels/?fg=blocked';"));
|
||||
});
|
||||
|
||||
test(
|
||||
'does NOT include strict reels blocker JS when sessionActive=true',
|
||||
() {
|
||||
final js = InjectionController.buildInjectionJS(
|
||||
sessionActive: true,
|
||||
blurExplore: false,
|
||||
blurReels: false,
|
||||
tapToUnblur: false,
|
||||
enableTextSelection: false,
|
||||
hideSuggestedPosts: false,
|
||||
hideSponsoredPosts: false,
|
||||
hideLikeCounts: false,
|
||||
hideFollowerCounts: false,
|
||||
hideExploreTab: false,
|
||||
hideReelsTab: false,
|
||||
hideShopTab: false,
|
||||
disableReelsEntirely: false,
|
||||
blockHomeFeedScroll: false,
|
||||
);
|
||||
|
||||
expect(js, isNot(contains('window.__fgReelsBlockPatched')));
|
||||
expect(
|
||||
js,
|
||||
isNot(contains("window.location.href = '/reels/?fg=blocked';")),
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:focusgram/services/screen_time_service.dart';
|
||||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
setUp(() {
|
||||
SharedPreferences.setMockInitialValues({});
|
||||
});
|
||||
|
||||
test('init loads persisted secondsByDate', () async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setString(
|
||||
ScreenTimeService.prefKey,
|
||||
'{"2026-01-01": 42, "2026-01-02": 7}',
|
||||
);
|
||||
|
||||
final s = ScreenTimeService();
|
||||
await s.init();
|
||||
|
||||
expect(s.secondsByDate['2026-01-01'], 42);
|
||||
expect(s.secondsByDate['2026-01-02'], 7);
|
||||
});
|
||||
|
||||
test('resetAll clears stored data and in-memory map', () async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setString(ScreenTimeService.prefKey, '{"2026-01-01": 42}');
|
||||
|
||||
final s = ScreenTimeService();
|
||||
await s.init();
|
||||
expect(s.secondsByDate.isNotEmpty, isTrue);
|
||||
|
||||
await s.resetAll();
|
||||
expect(s.secondsByDate, isEmpty);
|
||||
|
||||
final raw = prefs.getString(ScreenTimeService.prefKey);
|
||||
expect(raw, isNull);
|
||||
});
|
||||
|
||||
test('startTracking increments today seconds and stopTracking persists', () async {
|
||||
final s = ScreenTimeService();
|
||||
await s.init();
|
||||
|
||||
final beforeTodayKey = DateTime.now();
|
||||
final todayKey =
|
||||
'${beforeTodayKey.year.toString().padLeft(4, '0')}-'
|
||||
'${beforeTodayKey.month.toString().padLeft(2, '0')}-'
|
||||
'${beforeTodayKey.day.toString().padLeft(2, '0')}';
|
||||
|
||||
s.startTracking();
|
||||
|
||||
// Wait ~2 seconds (test is unit-ish; still acceptable).
|
||||
await Future<void>.delayed(const Duration(seconds: 2));
|
||||
|
||||
s.stopTracking();
|
||||
|
||||
expect(s.secondsByDate[todayKey], isNotNull);
|
||||
expect(s.secondsByDate[todayKey]!, greaterThanOrEqualTo(2));
|
||||
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final stored = prefs.getString(ScreenTimeService.prefKey);
|
||||
expect(stored, isNotNull);
|
||||
expect(stored, contains(todayKey));
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:focusgram/services/settings_service.dart';
|
||||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
setUp(() {
|
||||
SharedPreferences.setMockInitialValues({});
|
||||
});
|
||||
|
||||
group('SettingsService — Phase 2 Extras', () {
|
||||
test('defaults are OFF for video download/hide suggested', () async {
|
||||
final s = SettingsService();
|
||||
await s.init();
|
||||
|
||||
expect(s.videoDownloadEnabled, isFalse);
|
||||
expect(s.hideSuggestedPosts, isFalse);
|
||||
});
|
||||
|
||||
test('setVideoDownloadEnabled persists', () async {
|
||||
final s = SettingsService();
|
||||
await s.init();
|
||||
|
||||
await s.setVideoDownloadEnabled(true);
|
||||
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
expect(s.videoDownloadEnabled, isTrue);
|
||||
expect(prefs.getBool('video_download_enabled'), isTrue);
|
||||
});
|
||||
|
||||
test('setHideSuggestedPosts persists', () async {
|
||||
final s = SettingsService();
|
||||
await s.init();
|
||||
|
||||
await s.setHideSuggestedPosts(true);
|
||||
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
expect(s.hideSuggestedPosts, isTrue);
|
||||
expect(prefs.getBool('hide_suggested_posts'), isTrue);
|
||||
});
|
||||
});
|
||||
|
||||
group('SettingsService — minimal mode', () {
|
||||
test(
|
||||
'home feed scroll can be disabled while minimal mode stays on',
|
||||
() async {
|
||||
final s = SettingsService();
|
||||
await s.init();
|
||||
|
||||
await s.setMinimalModeEnabled(true);
|
||||
await s.setBlockHomeFeedScrollInternal(false);
|
||||
|
||||
expect(s.minimalModeEnabled, isTrue);
|
||||
expect(s.blockHomeFeedScroll, isFalse);
|
||||
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
expect(prefs.getBool('internal_block_home_feed_scroll'), isFalse);
|
||||
expect(prefs.getBool('minimal_mode_enabled'), isTrue);
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
'minimal mode turns off when all child features are disabled',
|
||||
() async {
|
||||
final s = SettingsService();
|
||||
await s.init();
|
||||
|
||||
await s.setMinimalModeEnabled(true);
|
||||
await s.setBlurExplore(false);
|
||||
await s.setBlockHomeFeedScrollInternal(false);
|
||||
await s.setDisableReelsEntirelyInternal(false);
|
||||
await s.setDisableExploreEntirelyInternal(false);
|
||||
|
||||
expect(s.minimalModeEnabled, isFalse);
|
||||
expect(s.blurExplore, isFalse);
|
||||
expect(s.blockHomeFeedScroll, isFalse);
|
||||
expect(s.disableReelsEntirely, isFalse);
|
||||
expect(s.disableExploreEntirely, isFalse);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
group('SettingsService — v2 filtering split', () {
|
||||
test(
|
||||
'ad blocker and suggested posts toggles persist independently',
|
||||
() async {
|
||||
final s = SettingsService();
|
||||
await s.init();
|
||||
|
||||
await s.setV2AdBlockerDomEnabled(true);
|
||||
await s.setContentSuggestedEnabled(true);
|
||||
await s.setV2AdBlockerDomEnabled(false);
|
||||
|
||||
expect(s.v2AdBlockerDomEnabled, isFalse);
|
||||
expect(s.contentSuggested, isTrue);
|
||||
expect(s.v2ContentHiderEnabled, isTrue);
|
||||
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
expect(prefs.getBool('v2_adblock_dom_enabled'), isFalse);
|
||||
expect(prefs.getBool('content_suggested'), isTrue);
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user