@Tags(['alpaca']) library; import 'package:cyberhybridhub_server/alpaca/alpaca_assets_client.dart'; import 'package:cyberhybridhub_server/alpaca/alpaca_env.dart'; import 'package:cyberhybridhub_server/alpaca/alpaca_models.dart'; import 'package:dotenv/dotenv.dart'; import 'package:test/test.dart'; void main() { late AlpacaEnv env; AlpacaAssetsClient? client; setUpAll(() { final DotEnv dotenv = DotEnv(includePlatformEnvironment: true) ..load(['.env']); const List alpacaKeys = [ 'ALPACA_API_KEY_ID', 'ALPACA_API_SECRET_KEY', 'ALPACA_TRADING_BASE_URL', 'ALPACA_DATA_BASE_URL', 'ALPACA_DATA_FEED', 'ALPACA_ALLOW_LIVE', ]; final Map envMap = { for (final String key in alpacaKeys) if (dotenv[key] != null && dotenv[key]!.isNotEmpty) key: dotenv[key]!, }; env = AlpacaEnv.fromMap(envMap); if (env.hasCredentials) { client = AlpacaAssetsClient(env: env); } }); tearDownAll(() { client?.close(); }); test('live listActiveTradable returns >100 us_equity assets', () async { if (!env.hasCredentials) { markTestSkipped( 'Set ALPACA_API_KEY_ID and ALPACA_API_SECRET_KEY in server/.env', ); return; } final List assets = await client!.listActiveTradable(); // Alpaca's live US-equity catalog has thousands of entries; >100 is a // safe lower bound that catches "we got an empty/auth-error payload" // without being brittle. expect(assets.length, greaterThan(100)); expect( assets.every((AlpacaAsset a) => a.assetClass == 'us_equity'), isTrue, reason: 'asset_class=us_equity filter should be enforced server-side', ); expect( assets.every((AlpacaAsset a) => a.status == 'active'), isTrue, reason: 'status=active filter should be enforced server-side', ); }); }