import 'package:test/test.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:angel3_container/angel3_container.dart'; import 'package:angel3_event_bus/event_bus.dart'; import 'package:angel3_mq/mq.dart'; import 'package:angel3_queue/src/queue.dart'; import 'package:angel3_queue/src/job_queueing_event.dart'; import 'package:angel3_queue/src/job_queued_event.dart'; import 'package:angel3_queue/src/should_queue_after_commit.dart'; //import 'package:angel3_queue/src/invalid_payload_exception.dart'; import 'queue_test.mocks.dart'; @GenerateMocks([Container, EventBus, MQClient, TransactionManager]) void main() { late MockContainer container; late MockEventBus eventBus; late MockMQClient mq; late TestQueue queue; setUpAll(() { provideDummy(MockEventBus()); }); setUp(() { container = MockContainer(); eventBus = MockEventBus(); mq = MockMQClient(); queue = TestQueue(container, eventBus, mq); // Inject the other mocks into the queue // queue.container = container; // queue.mq = mq; when(container.has()).thenReturn(true); when(container.has()).thenReturn(false); when(container.make()).thenReturn(eventBus); // Setup for EventBus mock when(eventBus.fire(any)).thenAnswer((_) => Future.value()); // // Setup for MQClient mock // when(mq.sendMessage( // message: any, // exchangeName: any, // routingKey: any, // )).thenAnswer((_) => Future.value()); }); test('pushOn calls push with correct arguments', () async { final result = await queue.pushOn('test_queue', 'test_job', 'test_data'); expect(result, equals('pushed')); }); test('laterOn calls later with correct arguments', () async { final result = await queue.laterOn( 'test_queue', Duration(minutes: 5), 'test_job', 'test_data'); expect(result, equals('pushed later')); }); test('bulk pushes multiple jobs', () async { await queue.bulk(['job1', 'job2', 'job3'], 'test_data', 'test_queue'); expect(queue.pushedJobs.length, equals(3)); expect(queue.pushedJobs, containsAll(['job1', 'job2', 'job3'])); }); test('createPayload throws InvalidPayloadException for invalid job', () { expect(() => queue.createPayload({}, 'test_queue'), throwsA(isA())); }); test('shouldDispatchAfterCommit returns correct value', () { expect( queue.shouldDispatchAfterCommit(MockShouldQueueAfterCommit()), isTrue); expect(queue.shouldDispatchAfterCommit({}), isFalse); queue.dispatchAfterCommit = true; expect(queue.shouldDispatchAfterCommit({}), isTrue); }); test('enqueueUsing publishes message and fires events', () async { when(container.has()).thenReturn(false); await queue.enqueueUsing( 'test_job', 'test_payload', 'test_queue', null, (payload, queue, delay) async => 'job_id', ); // Verify that events were fired verify(eventBus.fire(any)).called(2); // More specific verification verify(eventBus.fire(argThat(isA()))).called(1); verify(eventBus.fire(argThat(isA()))).called(1); // Verify that message was sent verify(mq.sendMessage( message: argThat(isA()), exchangeName: '', routingKey: 'test_queue', )).called(1); }); } class TestQueue extends Queue { List pushedJobs = []; TestQueue(Container container, EventBus eventBus, MQClient mq) : super(container, eventBus, mq); @override Future push(dynamic job, [dynamic data = '', String? queue]) async { pushedJobs.add(job); return 'pushed'; } @override Future later(Duration delay, dynamic job, [dynamic data = '', String? queue]) async { return 'pushed later'; } @override Future createPayload(dynamic job, String queue, [dynamic data = '']) async { if (job is Map && job.isEmpty) { throw InvalidPayloadException('Invalid job: empty map'); } return 'valid payload'; } @override bool shouldDispatchAfterCommit(dynamic job) { if (job is ShouldQueueAfterCommit) { return true; } return dispatchAfterCommit; } @override Future enqueueUsing( dynamic job, String payload, String? queue, Duration? delay, Future Function(String, String?, Duration?) callback, ) async { await raiseJobQueueingEvent(queue, job, payload, delay); final result = await callback(payload, queue, delay); await raiseJobQueuedEvent(queue, result, job, payload, delay); mq.sendMessage( message: Message( id: 'test-id', headers: {}, payload: payload, timestamp: DateTime.now().toIso8601String(), ), exchangeName: '', routingKey: queue ?? 'default', ); return result; } } // class DummyEventBus implements EventBus { // List firedEvents = []; // @override // Future fire(AppEvent event) async { // firedEvents.add(event); // } // @override // dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); // } class InvalidPayloadException implements Exception { final String message; InvalidPayloadException(this.message); @override String toString() => 'InvalidPayloadException: $message'; } class MockShouldQueueAfterCommit implements ShouldQueueAfterCommit {}