Тема и общие виджеты (AssetIcon, ServiceMark, HelpTip, глоссарий), верхняя панель TopNav и вкладки Аналитики вместо NavSidebar, иконки PWA. Экраны: портфели, создание брокерского счёта, ручное событие, правка инструмента, Обзор карточками по скоупам и таблица активов, пересчёт метрик с опросом /metrics/status. design-system.md обновлён.
96 lines
2.9 KiB
Dart
96 lines
2.9 KiB
Dart
import 'package:fintracker_api/fintracker_api.dart';
|
||
import 'package:fintracker_app/core/cache/cached.dart';
|
||
import 'package:fintracker_app/features/accounts/providers.dart';
|
||
import 'package:fintracker_app/features/portfolios/portfolios_page.dart';
|
||
import 'package:fintracker_app/features/portfolios/providers.dart';
|
||
import 'package:flutter/material.dart';
|
||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||
import 'package:flutter_test/flutter_test.dart';
|
||
|
||
AccountOut _account(int id, String name, AccountKind kind) => AccountOut(
|
||
id: id,
|
||
kind: kind,
|
||
source_: 'test',
|
||
sourceId: 'acc-$id',
|
||
broker: null,
|
||
name: name,
|
||
currency: 'RUB',
|
||
role: AccountRole.investment,
|
||
includeInNetWorth: true,
|
||
mirrorOfAccountId: null,
|
||
primaryEventSource: null,
|
||
archived: false,
|
||
disabled: false,
|
||
openedAt: null,
|
||
balance: null,
|
||
balanceAsOf: null,
|
||
startBalance: null,
|
||
creditLimit: null,
|
||
);
|
||
|
||
Widget _app(List<PortfolioOut> portfolios, List<AccountOut> accounts) =>
|
||
ProviderScope(
|
||
overrides: [
|
||
portfolioListProvider.overrideWith((ref) async => portfolios),
|
||
accountsProvider.overrideWith((ref) async => Cached(accounts)),
|
||
],
|
||
child: const MaterialApp(home: PortfoliosPage()),
|
||
);
|
||
|
||
void main() {
|
||
testWidgets('an empty list explains what a portfolio is', (tester) async {
|
||
await tester.pumpWidget(_app(const [], const []));
|
||
await tester.pumpAndSettle();
|
||
|
||
expect(find.textContaining('Портфелей пока нет'), findsOneWidget);
|
||
expect(find.text('Новый портфель'), findsOneWidget);
|
||
});
|
||
|
||
testWidgets('a portfolio shows its accounts by name', (tester) async {
|
||
await tester.pumpWidget(
|
||
_app(
|
||
[
|
||
PortfolioOut(
|
||
id: 1,
|
||
name: 'Основной',
|
||
baseCurrency: 'RUB',
|
||
accountIds: [10, 11],
|
||
),
|
||
],
|
||
[
|
||
_account(10, 'Брокер А', AccountKind.broker),
|
||
_account(11, 'Брокер Б', AccountKind.broker),
|
||
],
|
||
),
|
||
);
|
||
await tester.pumpAndSettle();
|
||
|
||
expect(find.text('Основной'), findsOneWidget);
|
||
expect(find.text('2 счёта: Брокер А, Брокер Б'), findsOneWidget);
|
||
});
|
||
|
||
testWidgets('the new-portfolio dialog needs a name and lists brokers first', (
|
||
tester,
|
||
) async {
|
||
await tester.pumpWidget(
|
||
_app(const [], [
|
||
_account(1, 'Карта', AccountKind.zmCard),
|
||
_account(2, 'Брокер', AccountKind.broker),
|
||
]),
|
||
);
|
||
await tester.pumpAndSettle();
|
||
|
||
await tester.tap(find.text('Новый портфель'));
|
||
await tester.pumpAndSettle();
|
||
|
||
final titles = tester
|
||
.widgetList<CheckboxListTile>(find.byType(CheckboxListTile))
|
||
.toList();
|
||
expect((titles.first.title as Text).data, 'Брокер');
|
||
|
||
await tester.tap(find.text('Сохранить'));
|
||
await tester.pumpAndSettle();
|
||
expect(find.text('Обязательное поле'), findsOneWidget);
|
||
});
|
||
}
|