test(client): 出入库状态多选语义与默认仓库填充回归用例
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -2,13 +2,18 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:jiu_client/core/api/api_client.dart';
|
||||
import 'package:jiu_client/core/auth/auth_state.dart';
|
||||
import 'package:jiu_client/core/theme/themes.dart';
|
||||
import 'package:jiu_client/models/product_option.dart';
|
||||
import 'package:jiu_client/models/stock_in.dart';
|
||||
import 'package:jiu_client/models/warehouse.dart';
|
||||
import 'package:jiu_client/providers/stock_in_provider.dart';
|
||||
import 'package:jiu_client/providers/warehouse_provider.dart';
|
||||
import 'package:jiu_client/providers/product_option_provider.dart';
|
||||
import 'package:jiu_client/repositories/stock_in_repository.dart';
|
||||
import 'package:jiu_client/screens/stock_in/stock_in_form_screen.dart';
|
||||
import 'package:jiu_client/widgets/ds/grid_combo_cell.dart';
|
||||
|
||||
class _FakeWarehouses extends WarehouseListNotifier {
|
||||
@override
|
||||
@@ -16,6 +21,23 @@ class _FakeWarehouses extends WarehouseListNotifier {
|
||||
const [Warehouse(id: 1, name: '主仓', isDefault: true)];
|
||||
}
|
||||
|
||||
/// 可配置仓库列表的假 notifier(T5 默认仓填充回归用)。
|
||||
class _ConfigurableWarehouses extends WarehouseListNotifier {
|
||||
final List<Warehouse> _list;
|
||||
_ConfigurableWarehouses(this._list);
|
||||
@override
|
||||
Future<List<Warehouse>> build() async => _list;
|
||||
}
|
||||
|
||||
/// 编辑模式假仓库:get() 返回固定单据(供 _loadEditOrder 消费)。
|
||||
class _FakeStockInRepoForEdit extends StockInRepository {
|
||||
final StockInOrder order;
|
||||
_FakeStockInRepoForEdit(this.order) : super(ApiClient(token: 't'));
|
||||
|
||||
@override
|
||||
Future<StockInOrder> get(int id) async => order;
|
||||
}
|
||||
|
||||
class _FakeNames extends ProductNameListNotifier {
|
||||
@override
|
||||
Future<List<ProductNameOption>> build() async => const [
|
||||
@@ -85,4 +107,102 @@ void main() {
|
||||
expect(find.text('选择商品名称'), findsNothing,
|
||||
reason: 'hint should be replaced by the picked name');
|
||||
});
|
||||
|
||||
// ── T5:新建入库单默认填充默认仓库(2026-07-14)──────────────────────
|
||||
//
|
||||
// _initWarehouseDefault 语义:仓库列表加载完成后,
|
||||
// isDefault 的仓 优先;无默认时仅剩 1 个仓才取它;否则保持未选(null)。
|
||||
// 编辑模式不受影响(_loadEditOrder 已从单据自身仓库回填)。
|
||||
|
||||
int? _warehouseSelectedId(WidgetTester tester) => tester
|
||||
.widgetList<GridComboCell>(find.byType(GridComboCell))
|
||||
.firstWhere((c) => c.hint == '选择仓库…')
|
||||
.selectedId;
|
||||
|
||||
Future<void> _pumpForm(WidgetTester tester, List<Override> overrides,
|
||||
{int? editOrderId}) async {
|
||||
tester.view.physicalSize = const Size(1400, 1000);
|
||||
tester.view.devicePixelRatio = 1.0;
|
||||
addTearDown(tester.view.resetPhysicalSize);
|
||||
await tester.pumpWidget(ProviderScope(
|
||||
overrides: overrides,
|
||||
child: MaterialApp(
|
||||
theme: buildTheme('a'),
|
||||
home: Scaffold(body: StockInFormScreen(editOrderId: editOrderId)),
|
||||
),
|
||||
));
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 100));
|
||||
// _initWarehouseDefault / _loadEditOrder 都是异步(await provider.future),
|
||||
// 多 pump 几拍确保 setState 落地。
|
||||
await tester.pump(const Duration(milliseconds: 100));
|
||||
}
|
||||
|
||||
testWidgets('新建入库单:有默认仓(isDefault=true)时自动选中默认仓',
|
||||
(tester) async {
|
||||
await _pumpForm(tester, [
|
||||
warehouseListProvider.overrideWith(() => _FakeWarehouses()), // 主仓 isDefault
|
||||
productNameListProvider.overrideWith(() => _FakeNames()),
|
||||
productSeriesListProvider.overrideWith(() => _FakeSeries()),
|
||||
productSpecListProvider.overrideWith(() => _FakeSpecs()),
|
||||
isReadonlyProvider.overrideWithValue(false),
|
||||
]);
|
||||
expect(_warehouseSelectedId(tester), 1);
|
||||
});
|
||||
|
||||
testWidgets('新建入库单:无默认仓且多仓时保持未选', (tester) async {
|
||||
await _pumpForm(tester, [
|
||||
warehouseListProvider.overrideWith(() => _ConfigurableWarehouses(const [
|
||||
Warehouse(id: 1, name: '主仓', isDefault: false),
|
||||
Warehouse(id: 2, name: '分仓', isDefault: false),
|
||||
])),
|
||||
productNameListProvider.overrideWith(() => _FakeNames()),
|
||||
productSeriesListProvider.overrideWith(() => _FakeSeries()),
|
||||
productSpecListProvider.overrideWith(() => _FakeSpecs()),
|
||||
isReadonlyProvider.overrideWithValue(false),
|
||||
]);
|
||||
expect(_warehouseSelectedId(tester), isNull);
|
||||
});
|
||||
|
||||
testWidgets('新建入库单:无默认仓但仅有 1 个仓时自动选中该仓', (tester) async {
|
||||
await _pumpForm(tester, [
|
||||
warehouseListProvider.overrideWith(() => _ConfigurableWarehouses(const [
|
||||
Warehouse(id: 7, name: '唯一仓', isDefault: false),
|
||||
])),
|
||||
productNameListProvider.overrideWith(() => _FakeNames()),
|
||||
productSeriesListProvider.overrideWith(() => _FakeSeries()),
|
||||
productSpecListProvider.overrideWith(() => _FakeSpecs()),
|
||||
isReadonlyProvider.overrideWithValue(false),
|
||||
]);
|
||||
expect(_warehouseSelectedId(tester), 7);
|
||||
});
|
||||
|
||||
testWidgets('编辑模式:不被默认仓覆盖,仍显示单据原仓库', (tester) async {
|
||||
const order = StockInOrder(
|
||||
id: 99,
|
||||
orderNo: 'SI2024010099',
|
||||
warehouseId: 2, // 单据原仓库 = 分仓(非默认仓)
|
||||
status: 'draft',
|
||||
items: [],
|
||||
);
|
||||
await _pumpForm(
|
||||
tester,
|
||||
[
|
||||
// 主仓(id=1)isDefault=true,若默认仓填充逻辑误在编辑模式生效会把它选中,
|
||||
// 但单据自身仓库是 id=2,回归断言二者不一致时以单据为准。
|
||||
warehouseListProvider.overrideWith(() => _ConfigurableWarehouses(const [
|
||||
Warehouse(id: 1, name: '主仓', isDefault: true),
|
||||
Warehouse(id: 2, name: '分仓', isDefault: false),
|
||||
])),
|
||||
stockInRepositoryProvider
|
||||
.overrideWithValue(_FakeStockInRepoForEdit(order)),
|
||||
productNameListProvider.overrideWith(() => _FakeNames()),
|
||||
productSeriesListProvider.overrideWith(() => _FakeSeries()),
|
||||
productSpecListProvider.overrideWith(() => _FakeSpecs()),
|
||||
isReadonlyProvider.overrideWithValue(false),
|
||||
],
|
||||
editOrderId: 99,
|
||||
);
|
||||
expect(_warehouseSelectedId(tester), 2);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user