cyberhybridhub/server/test/integration/trade_orders_db_test.dart

123 lines
3.1 KiB
Dart

@Tags(['integration', 'postgres'])
library;
import 'package:cyberhybridhub_server/trading/trade_orders_db.dart';
import 'package:postgres/postgres.dart';
import 'package:test/test.dart';
import 'package:uuid/uuid.dart';
import '../helpers/test_db.dart';
void main() {
const Uuid uuid = Uuid();
TestDb? testDb;
setUpAll(() async {
testDb = await TestDb.open();
});
tearDown(() async {
if (testDb != null) {
await testDb!.truncateTradingTables();
}
});
tearDownAll(() async {
await testDb?.close();
});
test('duplicate client_order_id returns existing row without second insert',
() async {
if (testDb == null) {
markTestSkipped('Set DATABASE_URL or TEST_DATABASE_URL for integration tests');
return;
}
const String uid = 'trade-orders-idempotency-uid';
await testDb!.seedUser(uid);
final String clientOrderId = 'test-${uuid.v4()}';
final TradeOrder first = await testDb!.tradeOrdersDb.insertOrder(
firebaseUid: uid,
clientOrderId: clientOrderId,
symbol: 'SPY',
side: 'buy',
orderType: 'market',
status: 'pending',
notionalUsd: 10,
ruleId: 'dip_confirm',
);
final TradeOrder second = await testDb!.tradeOrdersDb.insertOrder(
firebaseUid: uid,
clientOrderId: clientOrderId,
symbol: 'SPY',
side: 'buy',
orderType: 'market',
status: 'pending',
notionalUsd: 99,
);
expect(second.id, first.id);
expect(second.notionalUsd, 10);
final Result count = await testDb!.connection.execute(
Sql.named(
'SELECT COUNT(*)::int FROM trade_orders WHERE client_order_id = @id',
),
parameters: <String, dynamic>{'id': clientOrderId},
);
expect((count.first[0]! as num).toInt(), 1);
});
test('raw insert with duplicate client_order_id raises unique violation',
() async {
if (testDb == null) {
markTestSkipped('Set DATABASE_URL or TEST_DATABASE_URL for integration tests');
return;
}
const String uid = 'trade-orders-unique-uid';
await testDb!.seedUser(uid);
final String clientOrderId = 'dup-${uuid.v4()}';
final String orderId = uuid.v4();
await testDb!.connection.execute(
Sql.named(
'''
INSERT INTO trade_orders (
id, firebase_uid, client_order_id, symbol, side, order_type, status
) VALUES (
@id::uuid, @uid, @client_order_id, 'SPY', 'buy', 'market', 'pending'
)
''',
),
parameters: <String, dynamic>{
'id': orderId,
'uid': uid,
'client_order_id': clientOrderId,
},
);
await expectLater(
testDb!.connection.execute(
Sql.named(
'''
INSERT INTO trade_orders (
id, firebase_uid, client_order_id, symbol, side, order_type, status
) VALUES (
@id::uuid, @uid, @client_order_id, 'SPY', 'buy', 'market', 'pending'
)
''',
),
parameters: <String, dynamic>{
'id': uuid.v4(),
'uid': uid,
'client_order_id': clientOrderId,
},
),
throwsA(isA<ServerException>()),
);
});
}