[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,174 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:reelbox/data/api_service.dart';
|
||||
import 'package:reelbox/data/home_banners.dart';
|
||||
|
||||
class BannerApi extends ApiService {
|
||||
String? requested;
|
||||
dynamic response;
|
||||
bool fail = false;
|
||||
@override
|
||||
Future<dynamic> get(String path, {Map<String, dynamic>? query}) async {
|
||||
requested = path;
|
||||
if (fail) throw const ApiException('Offline');
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
test('real trusted transport preserves configured ads without restoring vendor feeds', () async {
|
||||
final server = await HttpServer.bind(InternetAddress.loopbackIPv4, 0);
|
||||
addTearDown(() => server.close(force: true));
|
||||
final paths = <String>[];
|
||||
server.listen((request) async {
|
||||
paths.add(request.uri.path);
|
||||
request.response.headers.contentType = ContentType.json;
|
||||
request.response.write(
|
||||
jsonEncode({
|
||||
'banners': [
|
||||
{
|
||||
'title_en': 'Fixture sponsor',
|
||||
'target_url': 'https://sponsor.example/offer',
|
||||
},
|
||||
{
|
||||
'title_en': 'Melodybox fixture',
|
||||
'target_url': 'https://vendor.example/',
|
||||
},
|
||||
{
|
||||
'title_en': 'Blocked link',
|
||||
'target_url': 'https://t.me/OtherChannel',
|
||||
},
|
||||
],
|
||||
}),
|
||||
);
|
||||
await request.response.close();
|
||||
});
|
||||
final api = ApiService(baseUrl: 'http://127.0.0.1:${server.port}/api/');
|
||||
final banners = await HomeBannerService(api).load();
|
||||
expect(paths, ['/api/banners/']);
|
||||
expect(banners, hasLength(2));
|
||||
expect(banners.first, HomeBanner.telegram);
|
||||
expect(banners.last.title(false), 'Fixture sponsor');
|
||||
expect(banners.last.isAdvertisement, isTrue);
|
||||
});
|
||||
test(
|
||||
'unsafe ads are skipped independently and config work is bounded',
|
||||
() async {
|
||||
final api = BannerApi();
|
||||
final valid = {
|
||||
'title_en': 'Fixture sponsor',
|
||||
'target_url': 'https://sponsor.example/',
|
||||
};
|
||||
for (final target in [
|
||||
'http://sponsor.example/',
|
||||
'javascript:alert(1)',
|
||||
'//sponsor.example/',
|
||||
'https://user:pass@sponsor.example/',
|
||||
'https://sponsor.example:444/',
|
||||
'https://sponsor.example/ bad',
|
||||
'https://sponsor.example/\\\\evil',
|
||||
'https://',
|
||||
'https://t.me/OtherChannel',
|
||||
'https://sponsor.example/app.apk',
|
||||
'https://sponsor.example/%0aevil',
|
||||
'https://-bad.example/',
|
||||
'https://bad..example/',
|
||||
'https://bad.example./',
|
||||
'https://sponsor.example/%zz',
|
||||
'https://sponsor.example/${'x' * 2048}',
|
||||
]) {
|
||||
api.response = {
|
||||
'banners': [
|
||||
{...valid, 'target_url': target},
|
||||
valid,
|
||||
],
|
||||
};
|
||||
final banners = await HomeBannerService(api).load();
|
||||
expect(banners, hasLength(2), reason: target);
|
||||
expect(banners.last.target.toString(), 'https://sponsor.example/');
|
||||
}
|
||||
for (final invalid in [
|
||||
null,
|
||||
true,
|
||||
4,
|
||||
[],
|
||||
{},
|
||||
{'banners': {}},
|
||||
{
|
||||
'banners': [null, 7, true, {}],
|
||||
},
|
||||
]) {
|
||||
api.response = invalid;
|
||||
expect(await HomeBannerService(api).load(), [HomeBanner.telegram]);
|
||||
}
|
||||
api.response = {
|
||||
'banners': [
|
||||
{...valid, 'title_en': 'x' * 81},
|
||||
{...valid, 'title_en': 'bad\u202etext'},
|
||||
{...valid, 'subtitle_en': 'x' * 181},
|
||||
{...valid, 'title_en': 5},
|
||||
{...valid, 'image_url': 'http://sponsor.example/image.jpg'},
|
||||
valid,
|
||||
],
|
||||
};
|
||||
expect(await HomeBannerService(api).load(), hasLength(2));
|
||||
api.response = {'banners': List.filled(1000, valid)};
|
||||
expect(await HomeBannerService(api).load(), hasLength(6));
|
||||
api.response = {
|
||||
'banners': [...List.filled(20, {}), valid],
|
||||
};
|
||||
expect(await HomeBannerService(api).load(), [HomeBanner.telegram]);
|
||||
},
|
||||
);
|
||||
test(
|
||||
'configured bilingual ads append after Telegram with optional image',
|
||||
() async {
|
||||
final api = BannerApi()
|
||||
..response = {
|
||||
'banners': [
|
||||
{
|
||||
'title_en': 'Test sponsor',
|
||||
'title_fa': 'حامی آزمایشی',
|
||||
'subtitle_en': 'Fixture only',
|
||||
'subtitle_fa': 'فقط دادهٔ آزمایشی',
|
||||
'target_url': 'https://sponsor.example/offer?ref=reelbox',
|
||||
'image_url': 'https://sponsor.example/banner.jpg',
|
||||
},
|
||||
{
|
||||
'title_en': 'Text sponsor',
|
||||
'target_url': 'https://sponsor.example/text',
|
||||
},
|
||||
],
|
||||
};
|
||||
final banners = await HomeBannerService(api).load();
|
||||
expect(banners, hasLength(3));
|
||||
expect(banners.first, same(HomeBanner.telegram));
|
||||
expect(banners[1].isAdvertisement, isTrue);
|
||||
expect(banners[1].title(true), 'حامی آزمایشی');
|
||||
expect(banners[1].subtitle(true), 'فقط دادهٔ آزمایشی');
|
||||
expect(banners[1].image.toString(), 'https://sponsor.example/banner.jpg');
|
||||
expect(banners.last.title(true), 'Text sponsor');
|
||||
expect(banners.last.image, isNull);
|
||||
},
|
||||
);
|
||||
test(
|
||||
'default Telegram banner survives missing config and API failures',
|
||||
() async {
|
||||
final api = BannerApi();
|
||||
final service = HomeBannerService(api);
|
||||
for (final fail in [false, true]) {
|
||||
api.fail = fail;
|
||||
final banners = await service.load();
|
||||
expect(banners, hasLength(1));
|
||||
expect(banners.single.target.toString(), 'https://t.me/ReelBoxApp');
|
||||
expect(banners.single.title(false), 'ReelBox updates');
|
||||
expect(banners.single.subtitle(false), 'Updates and announcements');
|
||||
expect(banners.single.title(true), 'تازههای ریلباکس');
|
||||
expect(banners.single.isAdvertisement, isFalse);
|
||||
}
|
||||
expect(api.requested, 'banners/');
|
||||
},
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user