feat(block2): publish my seeds to the network (completes publish->discover)
The other half of the market: share your marked lots as offers. - VarietyRepository.shareableLots(): non-private lots WITH their id (stable, updatable offer id) + the variety label. Private lots never leave the device. - OffersCubit.publishLots(): maps each via OfferMapper and publishes, tagged with the coarse area + signed by the derived key; counts acceptances; no-op offline or with no area. - Market screen: a 'share my seeds' action (online only) — publishes, then re-discovers to show them; 'mark some seeds first' when nothing's shared. - i18n en/es/pt. 14 tests green (repo query, cubit publish, market UI); analyzer clean for new code.
This commit is contained in:
parent
cb5f55e146
commit
f8f73c4153
12 changed files with 284 additions and 5 deletions
|
|
@ -2,6 +2,7 @@ import 'dart:async';
|
|||
|
||||
import 'package:commons_core/commons_core.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:tane/data/variety_repository.dart';
|
||||
import 'package:tane/db/enums.dart';
|
||||
import 'package:tane/services/offer_mapper.dart';
|
||||
import 'package:tane/state/offers_cubit.dart';
|
||||
|
|
@ -129,6 +130,72 @@ void main() {
|
|||
await cubit.close();
|
||||
});
|
||||
|
||||
test('publishLots publishes each shared lot and counts acceptances',
|
||||
() async {
|
||||
final transport = FakeOfferTransport();
|
||||
final cubit = OffersCubit(transport);
|
||||
final count = await cubit.publishLots(
|
||||
const [
|
||||
ShareableLot(
|
||||
lotId: 'lot-1',
|
||||
summary: 'Tomate',
|
||||
offerStatus: OfferStatus.shared,
|
||||
category: 'Solanaceae',
|
||||
),
|
||||
ShareableLot(
|
||||
lotId: 'lot-2',
|
||||
summary: 'Judía',
|
||||
offerStatus: OfferStatus.exchange,
|
||||
),
|
||||
],
|
||||
authorPubkeyHex: 'ab' * 32,
|
||||
areaGeohash: 'sp3e9',
|
||||
);
|
||||
expect(count, 2);
|
||||
expect(cubit.state.publishing, isFalse);
|
||||
|
||||
await cubit.discover('sp3');
|
||||
await pumpEventQueue();
|
||||
expect(cubit.state.offers, hasLength(2));
|
||||
await cubit.close();
|
||||
});
|
||||
|
||||
test('publishLots is a no-op offline or with no area', () async {
|
||||
final offline = OffersCubit(null);
|
||||
expect(
|
||||
await offline.publishLots(
|
||||
const [
|
||||
ShareableLot(
|
||||
lotId: 'x',
|
||||
summary: 'x',
|
||||
offerStatus: OfferStatus.shared,
|
||||
),
|
||||
],
|
||||
authorPubkeyHex: 'ab' * 32,
|
||||
areaGeohash: 'sp3e9',
|
||||
),
|
||||
0,
|
||||
);
|
||||
await offline.close();
|
||||
|
||||
final noArea = OffersCubit(FakeOfferTransport());
|
||||
expect(
|
||||
await noArea.publishLots(
|
||||
const [
|
||||
ShareableLot(
|
||||
lotId: 'x',
|
||||
summary: 'x',
|
||||
offerStatus: OfferStatus.shared,
|
||||
),
|
||||
],
|
||||
authorPubkeyHex: 'ab' * 32,
|
||||
areaGeohash: '',
|
||||
),
|
||||
0,
|
||||
);
|
||||
await noArea.close();
|
||||
});
|
||||
|
||||
test('offline (no transport): degrades gracefully, never throws', () async {
|
||||
final cubit = OffersCubit(null);
|
||||
expect(cubit.isOnline, isFalse);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue