/** * This file is part of alf.io. * * alf.io is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * alf.io is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with alf.io. If not, see <http://www.gnu.org/licenses/>. */ package alfio.manager; import alfio.manager.plugin.PluginManager; import alfio.manager.system.ConfigurationManager; import alfio.model.Event; import alfio.model.Ticket; import alfio.model.WaitingQueueSubscription; import alfio.model.modification.TicketReservationWithOptionalCodeModification; import alfio.model.system.Configuration; import alfio.repository.TicketCategoryRepository; import alfio.repository.TicketRepository; import alfio.repository.WaitingQueueRepository; import alfio.repository.user.OrganizationRepository; import alfio.util.TemplateManager; import com.insightfullogic.lambdabehave.JunitSuiteRunner; import org.apache.commons.lang3.tuple.Triple; import org.junit.runner.RunWith; import org.springframework.context.MessageSource; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import java.time.ZoneId; import java.time.ZonedDateTime; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.stream.Stream; import static alfio.model.system.ConfigurationKeys.ENABLE_PRE_REGISTRATION; import static com.insightfullogic.lambdabehave.Suite.describe; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.*; @RunWith(JunitSuiteRunner.class) public class WaitingQueueManagerTest {{ describe("basicOperations", it -> { WaitingQueueRepository waitingQueueRepository = it.usesMock(WaitingQueueRepository.class); EventStatisticsManager eventStatisticsManager = it.usesMock(EventStatisticsManager.class); TicketRepository ticketRepository = it.usesMock(TicketRepository.class); TicketCategoryRepository ticketCategoryRepository = it.usesMock(TicketCategoryRepository.class); ConfigurationManager configurationManager = it.usesMock(ConfigurationManager.class); NamedParameterJdbcTemplate jdbc = it.usesMock(NamedParameterJdbcTemplate.class); NotificationManager notificationManager = it.usesMock(NotificationManager.class); TemplateManager templateManager = it.usesMock(TemplateManager.class); MessageSource messageSource = it.usesMock(MessageSource.class); OrganizationRepository organizationRepository = it.usesMock(OrganizationRepository.class); PluginManager pluginManager = it.usesMock(PluginManager.class); WaitingQueueManager manager = new WaitingQueueManager(waitingQueueRepository, ticketRepository, ticketCategoryRepository, configurationManager, eventStatisticsManager, jdbc, notificationManager, templateManager, messageSource, organizationRepository, pluginManager); String reservationId = "reservation-id"; it.should("handle a reservation confirmation", expect -> { manager.fireReservationConfirmed(reservationId); verify(waitingQueueRepository).updateStatusByReservationId(eq(reservationId), eq(WaitingQueueSubscription.Status.ACQUIRED.toString())); }); it.should("handle a reservation expiration", expect -> { manager.fireReservationExpired(reservationId); verify(waitingQueueRepository).updateStatusByReservationId(eq(reservationId), eq(WaitingQueueSubscription.Status.EXPIRED.toString())); }); it.should("handle a bulk cancellation", expect -> { List<String> reservationIds = Arrays.asList(reservationId, "id2"); manager.cleanExpiredReservations(reservationIds); verify(waitingQueueRepository).bulkUpdateExpiredReservations(eq(reservationIds)); }); it.should("revert tickets to free if there isn't any subscriber", expect -> { Event event = it.usesMock(Event.class); int eventId = 1; when(event.getId()).thenReturn(eventId); when(waitingQueueRepository.countWaitingPeople(eq(eventId))).thenReturn(0); when(ticketRepository.countWaiting(eq(eventId))).thenReturn(1); manager.distributeSeats(event); verify(waitingQueueRepository).countWaitingPeople(eq(eventId)); verify(ticketRepository).countWaiting(eq(eventId)); verify(ticketRepository).revertToFree(eq(eventId)); }); it.should("do nothing if there are 0 subscribers and 0 waiting tickets", expect -> { Event event = it.usesMock(Event.class); int eventId = 1; when(event.getId()).thenReturn(eventId); when(waitingQueueRepository.countWaitingPeople(eq(eventId))).thenReturn(0); when(ticketRepository.countWaiting(eq(eventId))).thenReturn(0); manager.distributeSeats(event); verify(waitingQueueRepository).countWaitingPeople(eq(eventId)); verify(ticketRepository).countWaiting(eq(eventId)); verify(ticketRepository, never()).revertToFree(eq(eventId)); }); it.should("process pre-reservations if there are 0 waiting tickets 1 or more subscribers", expect -> { Event event = it.usesMock(Event.class); int eventId = 1; when(event.getId()).thenReturn(eventId); when(event.getZoneId()).thenReturn(ZoneId.systemDefault()); when(waitingQueueRepository.countWaitingPeople(eq(eventId))).thenReturn(1); when(ticketRepository.countWaiting(eq(eventId))).thenReturn(0); when(configurationManager.getBooleanConfigValue(Configuration.from(event.getOrganizationId(), event.getId(), ENABLE_PRE_REGISTRATION), false)).thenReturn(true); Ticket ticket = it.usesMock(Ticket.class); when(ticketRepository.selectWaitingTicketsForUpdate(eventId, Ticket.TicketStatus.PRE_RESERVED.name(), 1)).thenReturn(Collections.singletonList(ticket)); WaitingQueueSubscription subscription = it.usesMock(WaitingQueueSubscription.class); when(waitingQueueRepository.loadWaiting(eventId, 1)).thenReturn(Collections.singletonList(subscription)); Stream<Triple<WaitingQueueSubscription, TicketReservationWithOptionalCodeModification, ZonedDateTime>> stream = manager.distributeSeats(event); expect.that(stream.count()).is(1L); verify(waitingQueueRepository).countWaitingPeople(eq(eventId)); verify(ticketRepository).countWaiting(eq(eventId)); verify(ticketRepository, never()).revertToFree(eq(eventId)); }); it.completesWith(() -> verifyNoMoreInteractions(waitingQueueRepository, eventStatisticsManager, ticketRepository)); }); }}