cyberhybridhub/server/test/integration/trading_config_db_test.dart

80 lines
2.1 KiB
Dart

@Tags(['integration', 'postgres'])
library;
import 'package:cyberhybridhub_server/trading/trading_config.dart';
import 'package:test/test.dart';
import '../helpers/fixture_loader.dart';
import '../helpers/test_db.dart';
void main() {
TestDb? testDb;
setUpAll(() async {
testDb = await TestDb.open();
});
tearDown(() async {
if (testDb != null) {
await testDb!.truncateTradingTables();
}
});
tearDownAll(() async {
await testDb?.close();
});
test('resolveEffectiveConfig merges template and user override', () async {
if (testDb == null) {
markTestSkipped('Set DATABASE_URL or TEST_DATABASE_URL for integration tests');
return;
}
const String uid = 'trading-config-merge-uid';
await testDb!.seedUser(uid);
final FixtureLoader fixtures = FixtureLoader();
final Map<String, dynamic> partialOverride = <String, dynamic>{
'rules': <Map<String, dynamic>>[
<String, dynamic>{
'id': 'dip_confirm',
'threshold_pct': -2.5,
},
],
'data_inputs': <Map<String, dynamic>>[
<String, dynamic>{
'id': 'primary_watchlist',
'symbols': <String>['SPY'],
},
],
};
// Ensure fixture file is present (smoke for layout).
await fixtures.loadJson('trading_config_default.json');
await testDb!.tradingConfigDb.upsertUserConfig(
firebaseUid: uid,
templateName: 'default_paper_watchlist',
config: partialOverride,
enabled: true,
);
final EffectiveTradingConfig? effective =
await testDb!.tradingConfigDb.resolveEffectiveConfig(uid);
expect(effective, isNotNull);
expect(effective!.enabled, isTrue);
expect(effective.dataInputs.single.symbols, <String>['SPY']);
expect(effective.dataInputs.single.metrics,
containsAll(<String>['last_trade', 'daily_bar', 'prev_close']));
final TradingRuleConfig rule =
effective.rules.singleWhere((TradingRuleConfig r) => r.id == 'dip_confirm');
expect(rule.thresholdPct, -2.5);
expect(
rule.questionTemplate,
contains('Swipe +10'),
);
expect(effective.guardrails.maxOrdersPerDay, 3);
});
}