Files
jinzhi/test/features/mall/mall_tab_config_test.dart
T
2026-09-08 14:27:32 +08:00

130 lines
3.9 KiB
Dart

import 'dart:convert';
import 'package:flutter_test/flutter_test.dart';
import 'package:jinzhi_flutter_app/features/mall/application/mall_tab_config.dart';
void main() {
test('builds the resident mall URL with Jinzhi attribution and theme', () {
const config = MallTabConfig(
enabled: true,
url: 'https://mall.example.com/home?campaign=gold',
adId: 'ad-1',
trackingId: 'tracking-1',
);
final uri = config.attributedUri(clickId: 'click-1', isDark: true)!;
expect(uri.queryParameters['campaign'], 'gold');
expect(uri.queryParameters['source_app'], 'jinzhi');
expect(uri.queryParameters['source_entry'], 'mall_tab');
expect(uri.queryParameters['ad_id'], 'ad-1');
expect(uri.queryParameters['tracking_id'], 'tracking-1');
expect(uri.queryParameters['click_id'], 'click-1');
expect(uri.queryParameters['isNight'], '1');
});
test('retains server open-mode metadata', () {
const resident = MallTabConfig(
enabled: true,
url: 'https://mall.example.com',
);
const nativeApp = MallTabConfig(
enabled: true,
url: 'https://mall.example.com',
openMode: 'native_app',
);
const external = MallTabConfig(
enabled: true,
url: 'https://mall.example.com',
openMode: 'external',
);
expect(resident.opensInApp, isTrue);
expect(nativeApp.opensInApp, isFalse);
expect(external.opensInApp, isFalse);
});
test('adds retail quote context to the mall URL for H5', () {
const config = MallTabConfig(
enabled: true,
url: 'https://mall.example.com/home',
);
final uri = config.attributedUri(
clickId: 'quote-click',
entry: MallEntryRequest.quoteRetailGold,
)!;
expect(uri.queryParameters['source_entry'], 'market_quote');
expect(uri.queryParameters['hook_type'], 'quote_cta');
expect(uri.queryParameters['entry_scene'], 'retail');
expect(uri.queryParameters['entry_metal'], 'au');
expect(uri.queryParameters['placement'], 'mall_tab');
});
test('shows the first-install promo only for a configured mall entry', () {
const configured = MallTabConfig(
enabled: true,
url: 'https://mall.example.com',
entryPromoEnabled: true,
entryBadgeText: '新人礼',
entryTipTitle: '新人礼:¥360 铂金订购券',
entryTipBody: '点击这里进商城',
);
const disabled = MallTabConfig(
enabled: true,
url: 'https://mall.example.com',
entryPromoEnabled: false,
entryTipTitle: '新人礼',
);
expect(configured.showsEntryBadge, isTrue);
expect(configured.showsEntryTip, isTrue);
expect(disabled.showsEntryBadge, isFalse);
expect(disabled.showsEntryTip, isFalse);
});
test('parses the server-provided mall entry promotion fields', () {
final creative = <int>[
..._stringField(9, 'https://mall.example.com'),
..._boolField(16, true),
..._stringField(17, '新人礼'),
..._stringField(18, '新人礼:¥360 铂金订购券'),
..._stringField(19, '点击这里进商城'),
];
final config = parseMallTabConfigResponse(<int>[
..._boolField(1, true),
..._bytesField(2, creative),
]);
expect(config.showsEntryBadge, isTrue);
expect(config.entryBadgeText, '新人礼');
expect(config.entryTipTitle, '新人礼:¥360 铂金订购券');
expect(config.entryTipBody, '点击这里进商城');
});
}
List<int> _stringField(int tag, String value) =>
_bytesField(tag, utf8.encode(value));
List<int> _bytesField(int tag, List<int> value) => <int>[
..._varint((tag << 3) | 2),
..._varint(value.length),
...value,
];
List<int> _boolField(int tag, bool value) => <int>[
..._varint(tag << 3),
value ? 1 : 0,
];
List<int> _varint(int value) {
final bytes = <int>[];
while (value > 127) {
bytes.add((value & 127) | 128);
value >>= 7;
}
bytes.add(value);
return bytes;
}