SecondaryMarketplaceAccessor extends AbstractMarketplaceAccessor<ParticipationDescriptor> { @Override public boolean hasUpdates() { try { final LastPublishedItem current = tenant.call(Zonky::getLastPublishedParticipationInfo); final LastPublishedItem previous = stateAccessor.apply(current); LOGGER.trace("Current is {}, previous is {}.", current, previous); return !Objects.equals(previous, current); } catch (final Exception ex) { LOGGER.debug("Zonky secondary marketplace status endpoint failed, forcing live marketplace check.", ex); return true; } } SecondaryMarketplaceAccessor(final PowerTenant tenant,
            final UnaryOperator<LastPublishedItem> stateAccessor); @Override Duration getForcedMarketplaceCheckInterval(); @Override Collection<ParticipationDescriptor> getMarketplace(); @Override boolean hasUpdates();  }
@Test void detectsUpdates() { final Zonky z = harmlessZonky(); when(z.getLastPublishedParticipationInfo()).thenReturn(mock(LastPublishedItemImpl.class)); final PowerTenant t = mockTenant(z); final AtomicReference<LastPublishedItem> state = new AtomicReference<>(null); final AbstractMarketplaceAccessor<ParticipationDescriptor> a = new SecondaryMarketplaceAccessor(t, state::getAndSet); assertThat(a.hasUpdates()).isTrue(); assertThat(a.hasUpdates()).isFalse(); }
@Test void failsDetection() { final Zonky z = harmlessZonky(); when(z.getLastPublishedParticipationInfo()).thenThrow(IllegalStateException.class); final PowerTenant t = mockTenant(z); final AtomicReference<LastPublishedItem> state = new AtomicReference<>(null); final AbstractMarketplaceAccessor<ParticipationDescriptor> a = new SecondaryMarketplaceAccessor(t, state::getAndSet); assertThat(a.hasUpdates()).isTrue(); assertThat(a.hasUpdates()).isTrue(); }