import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:im_webview_app/config/app_config.dart'; import 'package:im_webview_app/main.dart'; void main() { test('creates the WebView shell app widget', () { expect( const ImWebViewApp(shellBranding: ShellBranding.fallback), isA(), ); }); test('exposes bootstrap H5 URL as Flutter shell lines', () { final lines = AppConfig.h5Lines; expect(lines, isNotEmpty); expect(lines.first.label, '线路1'); expect(Uri.parse(lines.first.url).scheme, 'https'); expect(Uri.parse(lines.first.url).path, '/'); }); test('uses current non-local service origin as default H5 line', () { final urls = AppConfig.defaultH5LineUrlsForBaseUri( Uri.parse('https://app.example.com/shell/index.html?from=local#hash'), ); expect(urls, ['https://app.example.com/']); }); test('preserves current service port when building default H5 line', () { final urls = AppConfig.defaultH5LineUrlsForBaseUri( Uri.parse('https://chat.example.com:8443/app/'), ); expect(urls, ['https://chat.example.com:8443/']); }); test('keeps fixed bootstrap H5 line for local browser access', () { final urls = AppConfig.defaultH5LineUrlsForBaseUri( Uri.parse('http://localhost:3000/'), ); expect(urls, ['https://h5-test.imharry.work/']); }); test('keeps fixed bootstrap H5 line for loopback browser access', () { final urls = AppConfig.defaultH5LineUrlsForBaseUri( Uri.parse('http://127.0.0.1:3000/'), ); expect(urls, ['https://h5-test.imharry.work/']); }); test('keeps fixed bootstrap H5 line for native app access', () { final urls = AppConfig.defaultH5LineUrlsForBaseUri( Uri.parse('file:///android_asset/flutter_assets/'), ); expect(urls, ['https://h5-test.imharry.work/']); }); test('uses fixed client config query parameters', () { expect(AppConfig.clientConfigQueryPayload, { 'device': 'h5', 'serialNo': 'h5-domain', }); expect( AppConfig.clientConfigQueryUris.first.path, '/client_config/query', ); }); test('builds client config query APIs from current service origin', () { final uris = AppConfig.clientConfigQueryUrisForHomeUri( Uri.parse('https://app.example.com/app/index.html?from=local#hash'), ); expect( uris.map((uri) => uri.toString()), [ 'https://app.example.com/client_config/query', 'https://app.example.com/api/user/client_config/query', ], ); }); test('splits client config resourceUrl into indexed H5 lines', () { final lines = AppConfig.h5LinesFromResourceUrl( 'line-one.example\nhttps://line-two.example/app\n\nline-three.example', ); expect(lines.map((line) => line.label), ['线路1', '线路2', '线路3']); expect(Uri.parse(lines[0].url).host, 'line-one.example'); expect(Uri.parse(lines[1].url).host, 'line-two.example'); expect(Uri.parse(lines[1].url).path, '/app'); expect(Uri.parse(lines[2].url).host, 'line-three.example'); }); test('splits literal backslash-n resourceUrl values', () { final lines = AppConfig.h5LinesFromResourceUrl( r'line-one.example\n*.line-two.example\nline-three.example', wildcardFactory: () => 'abcdefghijklmnop', ); expect(lines.map((line) => line.label), ['线路1', '线路2', '线路3']); expect(Uri.parse(lines[0].url).host, 'line-one.example'); expect(Uri.parse(lines[1].url).host, 'abcdefghijklmnop.line-two.example'); expect(Uri.parse(lines[2].url).host, 'line-three.example'); }); test('expands wildcard H5 domains with a 16 character label', () { final lines = AppConfig.h5LinesFromResourceUrl( '*.albzyuxq.vip', wildcardFactory: () => 'abcdefghijklmnop', ); final host = Uri.parse(lines.single.url).host; expect(host, 'abcdefghijklmnop.albzyuxq.vip'); expect(host.split('.').first.length, 16); }); test('detects only H5 login routes for shell line switch display', () { expect(AppConfig.isLoginPageUrl('https://line-one.example/login'), isTrue); expect( AppConfig.isLoginPageUrl('https://line-one.example/app/login'), isTrue); expect( AppConfig.isLoginPageUrl('https://line-one.example/#/login'), isTrue); expect(AppConfig.isLoginPageUrl('https://line-one.example/'), isFalse); expect( AppConfig.isLoginPageUrl('https://line-one.example/contact'), isFalse); expect( AppConfig.isLoginPageUrl('https://line-one.example/getCode'), isFalse); }); }