MotorSignal-App/test/durable_verification_queue_...

64 lines
2.1 KiB
Dart

import 'package:flutter_test/flutter_test.dart';
import 'package:motorcycle_dash/services/billing/billing_models.dart';
import 'package:motorcycle_dash/services/billing/durable_verification_queue.dart';
import 'package:motorcycle_dash/services/billing/product_catalog.dart';
void main() {
group('InMemoryVerificationQueue', () {
test('enqueues, dequeues, and records backoff properly', () async {
final queue = InMemoryVerificationQueue();
expect(await queue.loadQueue(), isEmpty);
const purchase = StorePurchase(
purchaseId: 'order_1',
productId: ProductCatalog.proMonthly,
status: StorePurchaseStatus.purchased,
transactionDate: '2026-09-01T12:00:00Z',
purchaseToken: 'raw_token_secret_123',
purchaseTokenHash: 'hash_123',
);
await queue.enqueue(purchase);
var items = await queue.loadQueue();
expect(items.length, 1);
expect(items.first.purchaseId, 'order_1');
expect(items.first.productId, ProductCatalog.proMonthly);
expect(items.first.purchaseToken, 'raw_token_secret_123');
expect(items.first.attemptCount, 0);
// Duplicate enqueue is idempotent
await queue.enqueue(purchase);
items = await queue.loadQueue();
expect(items.length, 1);
// Record retry
await queue.recordRetry(
'order_1',
backoffDelay: const Duration(seconds: 30),
);
items = await queue.loadQueue();
expect(items.first.attemptCount, 1);
expect(items.first.nextRetryAt.isAfter(items.first.queuedAt), isTrue);
// Dequeue
await queue.dequeue('order_1');
items = await queue.loadQueue();
expect(items, isEmpty);
});
test('ignores purchase with null or empty token', () async {
final queue = InMemoryVerificationQueue();
const purchase = StorePurchase(
purchaseId: 'order_2',
productId: ProductCatalog.proLifetime,
status: StorePurchaseStatus.purchased,
transactionDate: '2026-09-01T12:00:00Z',
purchaseToken: null,
);
await queue.enqueue(purchase);
expect(await queue.loadQueue(), isEmpty);
});
});
}