test_class.file: server/src/test/java/io/spine/server/delivery/CatchUpStationTest.java
test_class.identifier: CatchUpStationTest
test_class.superclass: extends AbstractStationTest
test_case.body: @Test
      @DisplayName("deduplicate and deliver all matching `CATCH_UP` messages " +
              "if the respective `CatchUpJob` is completed, " +
              "keeping the `CATCH_UP` messages in their storage for a bit longer")
      void deduplicateAndDeliverWhenJobCompleted() {
          InboxMessage toCatchUp = catchingUp(targetOne, type);
          InboxMessage moreToCatchUp = catchingUp(targetOne, type);
          InboxMessage toDeliver = toDeliver(targetOne, type);
          InboxMessage duplicateToCatchUp = copyWithNewId(toCatchUp);
          InboxMessage duplicateToDeliver = copyWithStatus(copyWithNewId(toCatchUp), TO_DELIVER);
          Conveyor conveyor = new Conveyor(
                  ImmutableList.of(toCatchUp, moreToCatchUp, toDeliver,
                                   duplicateToCatchUp, duplicateToDeliver),
                  new DeliveredMessages()
          );
  
          CatchUp job = catchUpJob(type, COMPLETED, currentTime(), ImmutableList.of(targetOne));
          MemoizingAction action = MemoizingAction.empty();
          CatchUpStation station = new CatchUpStation(action, ImmutableList.of(job));
          Station.Result result = station.process(conveyor);
          assertDeliveredCount(result, 2);
  
          Collection<InboxMessage> deliveredMessages = checkNotNull(action.passedMessages());
          assertContainsExactly(deliveredMessages,
                                // expected:
                                toCatchUp,
                                moreToCatchUp
          );
  
          Map<InboxMessageId, InboxMessage> remaindersById =
                  stream(conveyor.iterator()).collect(toMap(InboxMessage::getId, message -> message));
          assertThat(remaindersById).hasSize(3);
  
          assertKeptForLonger(toCatchUp.getId(), remaindersById);
          assertKeptForLonger(moreToCatchUp.getId(), remaindersById);
          assertNotKeptForLonger(toDeliver.getId(), remaindersById);
      }
test_case.class_method_signature: CatchUpStationTest.deduplicateAndDeliverWhenJobCompleted()
test_case.full_signature: @Test @DisplayName("deduplicate and deliver all matching `CATCH_UP` messages " + "if the respective `CatchUpJob` is completed, " + "keeping the `CATCH_UP` messages in their storage for a bit longer") void deduplicateAndDeliverWhenJobCompleted()
test_case.identifier: deduplicateAndDeliverWhenJobCompleted
test_case.invocations: catchingUp catchingUp toDeliver copyWithNewId copyWithStatus copyWithNewId of catchUpJob currentTime of empty of process assertDeliveredCount checkNotNull passedMessages assertContainsExactly collect stream iterator toMap hasSize assertThat assertKeptForLonger getId assertKeptForLonger getId assertNotKeptForLonger getId
test_case.modifiers: @Test @DisplayName("deduplicate and deliver all matching `CATCH_UP` messages " + "if the respective `CatchUpJob` is completed, " + "keeping the `CATCH_UP` messages in their storage for a bit longer")
test_case.parameters: ()
test_case.return: void
test_case.signature: void deduplicateAndDeliverWhenJobCompleted()
focal_class.declarator: HOW_LONG_TO_KEEP = Durations.fromMillis(1000)
focal_class.modifier: private static final
focal_class.original_string: private static final Duration HOW_LONG_TO_KEEP = Durations.fromMillis(1000);
focal_class.type: Duration
focal_class.var_name: HOW_LONG_TO_KEEP
focal_class.declarator: COMPARATOR = new CatchUpMessageComparator()
focal_class.modifier: private static final
focal_class.original_string: private static final Comparator<InboxMessage> COMPARATOR = new CatchUpMessageComparator();
focal_class.type: Comparator<InboxMessage>
focal_class.var_name: COMPARATOR
focal_class.declarator: action
focal_class.modifier: private final
focal_class.original_string: private final DeliveryAction action;
focal_class.type: DeliveryAction
focal_class.var_name: action
focal_class.declarator: jobs
focal_class.modifier: private final
focal_class.original_string: private final Iterable<CatchUp> jobs;
focal_class.type: Iterable<CatchUp>
focal_class.var_name: jobs
focal_class.file: server/src/main/java/io/spine/server/delivery/CatchUpStation.java
focal_class.identifier: CatchUpStation
focal_class.class_method_signature: CatchUpStation.CatchUpStation(DeliveryAction action, Iterable<CatchUp> jobs)
focal_class.full_signature:   CatchUpStation(DeliveryAction action, Iterable<CatchUp> jobs)
focal_class.identifier: CatchUpStation
focal_class.parameters: (DeliveryAction action, Iterable<CatchUp> jobs)
focal_class.signature:  CatchUpStation(DeliveryAction action, Iterable<CatchUp> jobs)
focal_class.class_method_signature: CatchUpStation.process(Conveyor conveyor)
focal_class.full_signature: @Override public final Result process(Conveyor conveyor)
focal_class.identifier: process
focal_class.modifiers: @Override public final
focal_class.parameters: (Conveyor conveyor)
focal_class.return: Result
focal_class.signature: Result process(Conveyor conveyor)
focal_class.class_method_signature: CatchUpStation.dispatch(Collection<InboxMessage> messages, Conveyor conveyor)
focal_class.full_signature: private Result dispatch(Collection<InboxMessage> messages, Conveyor conveyor)
focal_class.identifier: dispatch
focal_class.modifiers: private
focal_class.parameters: (Collection<InboxMessage> messages, Conveyor conveyor)
focal_class.return: Result
focal_class.signature: Result dispatch(Collection<InboxMessage> messages, Conveyor conveyor)
focal_class.superclass: extends Station
focal_method.body: @Override
      public final Result process(Conveyor conveyor) {
          JobFilter jobFilter = new JobFilter(jobs, conveyor);
          Collection<InboxMessage> toDispatch = jobFilter.messagesToDispatch();
          return dispatch(toDispatch, conveyor);
      }
focal_method.class_method_signature: CatchUpStation.process(Conveyor conveyor)
focal_method.full_signature: @Override public final Result process(Conveyor conveyor)
focal_method.identifier: process
focal_method.invocations: messagesToDispatch dispatch
focal_method.modifiers: @Override public final
focal_method.parameters: (Conveyor conveyor)
focal_method.return: Result
focal_method.signature: Result process(Conveyor conveyor)