Java tutorial
/** * 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.TestConfiguration; import alfio.config.DataSourceConfiguration; import alfio.config.Initializer; import alfio.config.RepositoryConfiguration; import alfio.config.WebSecurityConfig; import alfio.manager.support.PaymentResult; import alfio.manager.system.ConfigurationManager; import alfio.manager.user.UserManager; import alfio.model.*; import alfio.model.modification.*; import alfio.model.result.Result; import alfio.model.system.ConfigurationKeys; import alfio.model.transaction.PaymentProxy; import alfio.repository.EventRepository; import alfio.repository.TicketCategoryRepository; import alfio.repository.TicketRepository; import alfio.repository.system.ConfigurationRepository; import alfio.repository.user.OrganizationRepository; import org.apache.commons.lang3.time.DateUtils; import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Triple; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.time.*; import java.util.*; import java.util.stream.Collectors; import static alfio.model.modification.DateTimeModification.fromZonedDateTime; import static alfio.test.util.IntegrationTestUtil.*; import static org.junit.Assert.*; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = { RepositoryConfiguration.class, DataSourceConfiguration.class, WebSecurityConfig.class, TestConfiguration.class }) @ActiveProfiles({ Initializer.PROFILE_DEV, Initializer.PROFILE_DISABLE_JOBS }) @Transactional public class WaitingQueueManagerIntegrationTest { private static final Map<String, String> DESCRIPTION = Collections.singletonMap("en", "desc"); @Autowired private OrganizationRepository organizationRepository; @Autowired private UserManager userManager; @Autowired private EventManager eventManager; @Autowired private WaitingQueueManager waitingQueueManager; @Autowired private ConfigurationManager configurationManager; @Autowired private EventStatisticsManager eventStatisticsManager; @Autowired private TicketReservationManager ticketReservationManager; @Autowired private TicketCategoryRepository ticketCategoryRepository; @Autowired private ConfigurationRepository configurationRepository; @Autowired private EventRepository eventRepository; @Autowired private TicketRepository ticketRepository; @BeforeClass public static void initEnv() { initSystemProperties(); } @Before public void init() { ensureMinimalConfiguration(configurationRepository); } private static CustomerName customerJohnDoe(Event event) { return new CustomerName("John Doe", "John", "Doe", event); } @Test public void testSubscribeDenied() { List<TicketCategoryModification> categories = getPreSalesTicketCategoryModifications(false, AVAILABLE_SEATS, true, 10); Pair<Event, String> pair = initEvent(categories, organizationRepository, userManager, eventManager, eventRepository); Event event = pair.getKey(); TicketCategory firstCategory = eventManager.loadTicketCategories(event).stream() .filter(t -> t.getName().equals("defaultFirst")).findFirst() .orElseThrow(IllegalStateException::new); configurationManager.saveCategoryConfiguration(firstCategory.getId(), event.getId(), Collections.singletonList(new ConfigurationModification(null, ConfigurationKeys.MAX_AMOUNT_OF_TICKETS_BY_RESERVATION.getValue(), "1")), pair.getRight() + "_owner"); configurationManager.saveSystemConfiguration(ConfigurationKeys.ENABLE_PRE_REGISTRATION, "true"); configurationManager.saveSystemConfiguration(ConfigurationKeys.ENABLE_WAITING_QUEUE, "true"); configurationRepository.insertEventLevel(event.getOrganizationId(), event.getId(), ConfigurationKeys.STOP_WAITING_QUEUE_SUBSCRIPTIONS.name(), "true", ""); //subscription should now be denied boolean result = waitingQueueManager.subscribe(event, customerJohnDoe(event), "john@doe.com", null, Locale.ENGLISH); assertFalse(result); } @Test public void testDistributeSeatsFirstCategoryIsUnbounded() throws Exception { List<TicketCategoryModification> categories = getPreSalesTicketCategoryModifications(false, AVAILABLE_SEATS, true, 10); Pair<Event, String> pair = initEvent(categories, organizationRepository, userManager, eventManager, eventRepository); Event event = pair.getKey(); TicketCategory firstCategory = eventManager.loadTicketCategories(event).stream() .filter(t -> t.getName().equals("defaultFirst")).findFirst() .orElseThrow(IllegalStateException::new); configurationManager.saveCategoryConfiguration(firstCategory.getId(), event.getId(), Collections.singletonList(new ConfigurationModification(null, ConfigurationKeys.MAX_AMOUNT_OF_TICKETS_BY_RESERVATION.getValue(), "1")), pair.getRight() + "_owner"); configurationManager.saveSystemConfiguration(ConfigurationKeys.ENABLE_PRE_REGISTRATION, "true"); configurationManager.saveSystemConfiguration(ConfigurationKeys.ENABLE_WAITING_QUEUE, "true"); boolean result = waitingQueueManager.subscribe(event, customerJohnDoe(event), "john@doe.com", null, Locale.ENGLISH); assertTrue(result); List<Triple<WaitingQueueSubscription, TicketReservationWithOptionalCodeModification, ZonedDateTime>> subscriptions = waitingQueueManager .distributeSeats(event).collect(Collectors.toList()); assertEquals(1, subscriptions.size()); Triple<WaitingQueueSubscription, TicketReservationWithOptionalCodeModification, ZonedDateTime> subscriptionDetail = subscriptions .get(0); assertEquals("john@doe.com", subscriptionDetail.getLeft().getEmailAddress()); TicketReservationWithOptionalCodeModification reservation = subscriptionDetail.getMiddle(); assertEquals(Integer.valueOf(firstCategory.getId()), reservation.getTicketCategoryId()); assertEquals(Integer.valueOf(1), reservation.getAmount()); assertTrue(subscriptionDetail.getRight().isAfter(ZonedDateTime.now())); } @Test public void testDistributeSeatsFirstCategoryIsBounded() throws Exception { List<TicketCategoryModification> categories = getPreSalesTicketCategoryModifications(true, 10, true, 10); Pair<Event, String> pair = initEvent(categories, organizationRepository, userManager, eventManager, eventRepository); Event event = pair.getKey(); TicketCategory firstCategory = eventManager.loadTicketCategories(event).stream() .filter(t -> t.getName().equals("defaultFirst")).findFirst() .orElseThrow(IllegalStateException::new); configurationManager.saveCategoryConfiguration(firstCategory.getId(), event.getId(), Collections.singletonList(new ConfigurationModification(null, ConfigurationKeys.MAX_AMOUNT_OF_TICKETS_BY_RESERVATION.getValue(), "1")), pair.getRight() + "_owner"); configurationManager.saveSystemConfiguration(ConfigurationKeys.ENABLE_PRE_REGISTRATION, "true"); configurationManager.saveSystemConfiguration(ConfigurationKeys.ENABLE_WAITING_QUEUE, "true"); boolean result = waitingQueueManager.subscribe(event, customerJohnDoe(event), "john@doe.com", null, Locale.ENGLISH); assertTrue(result); List<Triple<WaitingQueueSubscription, TicketReservationWithOptionalCodeModification, ZonedDateTime>> subscriptions = waitingQueueManager .distributeSeats(event).collect(Collectors.toList()); assertEquals(1, subscriptions.size()); Triple<WaitingQueueSubscription, TicketReservationWithOptionalCodeModification, ZonedDateTime> subscriptionDetail = subscriptions .get(0); assertEquals("john@doe.com", subscriptionDetail.getLeft().getEmailAddress()); TicketReservationWithOptionalCodeModification reservation = subscriptionDetail.getMiddle(); assertEquals(Integer.valueOf(firstCategory.getId()), reservation.getTicketCategoryId()); assertEquals(Integer.valueOf(1), reservation.getAmount()); assertTrue(subscriptionDetail.getRight().isAfter(ZonedDateTime.now())); } @Test public void testWaitingQueueForUnboundedCategory() { List<TicketCategoryModification> categories = Collections.singletonList(new TicketCategoryModification(null, "default", AVAILABLE_SEATS, new DateTimeModification(LocalDate.now(), LocalTime.now()), new DateTimeModification(LocalDate.now(), LocalTime.now()), DESCRIPTION, BigDecimal.TEN, false, "", false, null, null, null, null, null)); Event event = initEvent(categories, organizationRepository, userManager, eventManager, eventRepository) .getKey(); TicketCategory unbounded = ticketCategoryRepository.findByEventId(event.getId()).get(0); TicketReservationModification tr = new TicketReservationModification(); tr.setAmount(AVAILABLE_SEATS); tr.setTicketCategoryId(unbounded.getId()); TicketReservationWithOptionalCodeModification mod = new TicketReservationWithOptionalCodeModification(tr, Optional.empty()); String reservationId = ticketReservationManager.createTicketReservation(event, Collections.singletonList(mod), Collections.emptyList(), DateUtils.addDays(new Date(), 1), Optional.<String>empty(), Optional.<String>empty(), Locale.ENGLISH, false); TotalPrice reservationCost = ticketReservationManager.totalReservationCostWithVAT(reservationId); PaymentResult result = ticketReservationManager.confirm("", null, event, reservationId, "test@test.ch", new CustomerName("Full Name", "Full", "Name", event), Locale.ENGLISH, "", reservationCost, Optional.empty(), Optional.of(PaymentProxy.OFFLINE), false, null, null, null); assertTrue(result.isSuccessful()); assertEquals(0, eventRepository.findStatisticsFor(event.getId()).getDynamicAllocation()); } @Test public void testAssignTicketToWaitingQueueUnboundedCategory() { LocalDateTime start = LocalDateTime.now().minusMinutes(1); LocalDateTime end = LocalDateTime.now().plusMinutes(20); List<TicketCategoryModification> categories = Collections.singletonList(new TicketCategoryModification(null, "default", AVAILABLE_SEATS, new DateTimeModification(start.toLocalDate(), start.toLocalTime()), new DateTimeModification(end.toLocalDate(), end.toLocalTime()), DESCRIPTION, BigDecimal.TEN, false, "", false, null, null, null, null, null)); configurationManager.saveSystemConfiguration(ConfigurationKeys.ENABLE_WAITING_QUEUE, "true"); Event event = initEvent(categories, organizationRepository, userManager, eventManager, eventRepository) .getKey(); TicketCategory unbounded = ticketCategoryRepository.findByEventId(event.getId()).get(0); TicketReservationModification tr = new TicketReservationModification(); tr.setAmount(AVAILABLE_SEATS - 1); tr.setTicketCategoryId(unbounded.getId()); TicketReservationModification tr2 = new TicketReservationModification(); tr2.setAmount(1); tr2.setTicketCategoryId(unbounded.getId()); TicketReservationWithOptionalCodeModification multi = new TicketReservationWithOptionalCodeModification(tr, Optional.empty()); TicketReservationWithOptionalCodeModification single = new TicketReservationWithOptionalCodeModification( tr2, Optional.empty()); String reservationId = ticketReservationManager.createTicketReservation(event, Collections.singletonList(multi), Collections.emptyList(), DateUtils.addDays(new Date(), 1), Optional.empty(), Optional.empty(), Locale.ENGLISH, false); TotalPrice reservationCost = ticketReservationManager.totalReservationCostWithVAT(reservationId); PaymentResult result = ticketReservationManager.confirm("", null, event, reservationId, "test@test.ch", new CustomerName("Full Name", "Full", "Name", event), Locale.ENGLISH, "", reservationCost, Optional.empty(), Optional.of(PaymentProxy.OFFLINE), false, null, null, null); assertTrue(result.isSuccessful()); String reservationIdSingle = ticketReservationManager.createTicketReservation(event, Collections.singletonList(single), Collections.emptyList(), DateUtils.addDays(new Date(), 1), Optional.empty(), Optional.empty(), Locale.ENGLISH, false); TotalPrice reservationCostSingle = ticketReservationManager .totalReservationCostWithVAT(reservationIdSingle); PaymentResult resultSingle = ticketReservationManager.confirm("", null, event, reservationIdSingle, "test@test.ch", new CustomerName("Full Name", "Full", "Name", event), Locale.ENGLISH, "", reservationCostSingle, Optional.empty(), Optional.of(PaymentProxy.OFFLINE), false, null, null, null); assertTrue(resultSingle.isSuccessful()); assertEquals(0, eventRepository.findStatisticsFor(event.getId()).getDynamicAllocation()); assertTrue( waitingQueueManager.subscribe(event, customerJohnDoe(event), "john@doe.com", null, Locale.ENGLISH)); ticketReservationManager.deleteOfflinePayment(event, reservationIdSingle, false); List<Triple<WaitingQueueSubscription, TicketReservationWithOptionalCodeModification, ZonedDateTime>> subscriptions = waitingQueueManager .distributeSeats(event).collect(Collectors.toList()); assertEquals(1, subscriptions.size()); Triple<WaitingQueueSubscription, TicketReservationWithOptionalCodeModification, ZonedDateTime> subscriptionDetail = subscriptions .get(0); assertEquals("john@doe.com", subscriptionDetail.getLeft().getEmailAddress()); TicketReservationWithOptionalCodeModification reservation = subscriptionDetail.getMiddle(); assertEquals(Integer.valueOf(unbounded.getId()), reservation.getTicketCategoryId()); assertEquals(Integer.valueOf(1), reservation.getAmount()); assertTrue(subscriptionDetail.getRight().isAfter(ZonedDateTime.now())); } @Test public void testAssignTicketToWaitingQueueBoundedCategory() { LocalDateTime start = LocalDateTime.now().minusMinutes(2); LocalDateTime end = LocalDateTime.now().plusMinutes(20); List<TicketCategoryModification> categories = Collections.singletonList(new TicketCategoryModification(null, "default", AVAILABLE_SEATS, new DateTimeModification(start.toLocalDate(), start.toLocalTime()), new DateTimeModification(end.toLocalDate(), end.toLocalTime()), DESCRIPTION, BigDecimal.TEN, false, "", true, null, null, null, null, null)); configurationManager.saveSystemConfiguration(ConfigurationKeys.ENABLE_WAITING_QUEUE, "true"); Event event = initEvent(categories, organizationRepository, userManager, eventManager, eventRepository) .getKey(); TicketCategory bounded = ticketCategoryRepository.findByEventId(event.getId()).get(0); TicketReservationModification tr = new TicketReservationModification(); tr.setAmount(AVAILABLE_SEATS - 1); tr.setTicketCategoryId(bounded.getId()); TicketReservationModification tr2 = new TicketReservationModification(); tr2.setAmount(1); tr2.setTicketCategoryId(bounded.getId()); TicketReservationWithOptionalCodeModification multi = new TicketReservationWithOptionalCodeModification(tr, Optional.empty()); TicketReservationWithOptionalCodeModification single = new TicketReservationWithOptionalCodeModification( tr2, Optional.empty()); String reservationId = ticketReservationManager.createTicketReservation(event, Collections.singletonList(multi), Collections.emptyList(), DateUtils.addDays(new Date(), 1), Optional.empty(), Optional.empty(), Locale.ENGLISH, false); TotalPrice reservationCost = ticketReservationManager.totalReservationCostWithVAT(reservationId); PaymentResult result = ticketReservationManager.confirm("", null, event, reservationId, "test@test.ch", new CustomerName("Full Name", "Full", "Name", event), Locale.ENGLISH, "", reservationCost, Optional.empty(), Optional.of(PaymentProxy.OFFLINE), false, null, null, null); assertTrue(result.isSuccessful()); String reservationIdSingle = ticketReservationManager.createTicketReservation(event, Collections.singletonList(single), Collections.emptyList(), DateUtils.addDays(new Date(), 1), Optional.empty(), Optional.empty(), Locale.ENGLISH, false); TotalPrice reservationCostSingle = ticketReservationManager .totalReservationCostWithVAT(reservationIdSingle); PaymentResult resultSingle = ticketReservationManager.confirm("", null, event, reservationIdSingle, "test@test.ch", new CustomerName("Full Name", "Full", "Name", event), Locale.ENGLISH, "", reservationCostSingle, Optional.empty(), Optional.of(PaymentProxy.OFFLINE), false, null, null, null); assertTrue(resultSingle.isSuccessful()); assertEquals(0, eventRepository.findStatisticsFor(event.getId()).getDynamicAllocation()); assertTrue( waitingQueueManager.subscribe(event, customerJohnDoe(event), "john@doe.com", null, Locale.ENGLISH)); ticketReservationManager.deleteOfflinePayment(event, reservationIdSingle, false); List<Triple<WaitingQueueSubscription, TicketReservationWithOptionalCodeModification, ZonedDateTime>> subscriptions = waitingQueueManager .distributeSeats(event).collect(Collectors.toList()); assertEquals(1, subscriptions.size()); Triple<WaitingQueueSubscription, TicketReservationWithOptionalCodeModification, ZonedDateTime> subscriptionDetail = subscriptions .get(0); assertEquals("john@doe.com", subscriptionDetail.getLeft().getEmailAddress()); TicketReservationWithOptionalCodeModification reservation = subscriptionDetail.getMiddle(); assertEquals(Integer.valueOf(bounded.getId()), reservation.getTicketCategoryId()); assertEquals(Integer.valueOf(1), reservation.getAmount()); assertTrue(subscriptionDetail.getRight().isAfter(ZonedDateTime.now())); } @Test public void testAssignTicketToWaitingQueueUnboundedCategorySelected() { LocalDateTime start = LocalDateTime.now().minusHours(1); LocalDateTime end = LocalDateTime.now().plusHours(1); List<TicketCategoryModification> categories = Arrays.asList( new TicketCategoryModification(null, "default", AVAILABLE_SEATS, new DateTimeModification(start.toLocalDate(), start.toLocalTime()), new DateTimeModification(end.toLocalDate(), end.toLocalTime()), DESCRIPTION, BigDecimal.TEN, false, "", false, null, null, null, null, null), new TicketCategoryModification(null, "default2", AVAILABLE_SEATS, new DateTimeModification(start.toLocalDate(), start.toLocalTime()), new DateTimeModification(end.toLocalDate(), end.toLocalTime()), DESCRIPTION, BigDecimal.TEN, false, "", false, null, null, null, null, null)); configurationManager.saveSystemConfiguration(ConfigurationKeys.ENABLE_WAITING_QUEUE, "true"); Event event = initEvent(categories, organizationRepository, userManager, eventManager, eventRepository) .getKey(); List<TicketCategory> ticketCategories = ticketCategoryRepository.findByEventId(event.getId()); TicketCategory first = ticketCategories.get(0); TicketCategory second = ticketCategories.get(1); TicketReservationModification tr2 = new TicketReservationModification(); tr2.setAmount(1); tr2.setTicketCategoryId(second.getId()); TicketReservationModification tr3 = new TicketReservationModification(); tr3.setAmount(1); tr3.setTicketCategoryId(first.getId()); reserveTickets(event, first, AVAILABLE_SEATS - 2); String reservationIdSingleFirst = reserveTickets(event, second, 1); String reservationIdSingleSecond = reserveTickets(event, second, 1); assertEquals(0, eventRepository.findStatisticsFor(event.getId()).getDynamicAllocation()); assertTrue(waitingQueueManager.subscribe(event, customerJohnDoe(event), "john@doe.com", first.getId(), Locale.ENGLISH)); assertTrue(waitingQueueManager.subscribe(event, new CustomerName("John Doe 2", "John", "Doe 2", event), "john@doe2.com", second.getId(), Locale.ENGLISH)); ticketReservationManager.deleteOfflinePayment(event, reservationIdSingleFirst, false); ticketReservationManager.deleteOfflinePayment(event, reservationIdSingleSecond, false); List<Triple<WaitingQueueSubscription, TicketReservationWithOptionalCodeModification, ZonedDateTime>> subscriptions = waitingQueueManager .distributeSeats(event).collect(Collectors.toList()); assertEquals(2, subscriptions.size()); Triple<WaitingQueueSubscription, TicketReservationWithOptionalCodeModification, ZonedDateTime> subscriptionDetail = subscriptions .get(0); assertEquals("john@doe.com", subscriptionDetail.getLeft().getEmailAddress()); TicketReservationWithOptionalCodeModification reservation = subscriptionDetail.getMiddle(); assertEquals(Integer.valueOf(first.getId()), reservation.getTicketCategoryId()); assertEquals(Integer.valueOf(1), reservation.getAmount()); assertTrue(subscriptionDetail.getRight().isAfter(ZonedDateTime.now())); subscriptionDetail = subscriptions.get(1); assertEquals("john@doe2.com", subscriptionDetail.getLeft().getEmailAddress()); reservation = subscriptionDetail.getMiddle(); assertEquals(Integer.valueOf(second.getId()), reservation.getTicketCategoryId()); assertEquals(Integer.valueOf(1), reservation.getAmount()); assertTrue(subscriptionDetail.getRight().isAfter(ZonedDateTime.now())); } private String reserveTickets(Event event, TicketCategory category, int num) { TicketReservationModification tr = new TicketReservationModification(); tr.setAmount(num); tr.setTicketCategoryId(category.getId()); TicketReservationWithOptionalCodeModification tcm = new TicketReservationWithOptionalCodeModification(tr, Optional.empty()); String reservationId = ticketReservationManager.createTicketReservation(event, Collections.singletonList(tcm), Collections.emptyList(), DateUtils.addDays(new Date(), 1), Optional.empty(), Optional.empty(), Locale.ENGLISH, false); TotalPrice reservationCost = ticketReservationManager.totalReservationCostWithVAT(reservationId); PaymentResult result = ticketReservationManager.confirm("", null, event, reservationId, "test@test.ch", new CustomerName("Full Name", "Full", "Name", event), Locale.ENGLISH, "", reservationCost, Optional.empty(), Optional.of(PaymentProxy.OFFLINE), false, null, null, null); assertTrue(result.isSuccessful()); return reservationId; } @Test public void testNoPublicCategoryAvailable() { LocalDateTime start = LocalDateTime.now().minusHours(1); LocalDateTime end = LocalDateTime.now().plusHours(1); List<TicketCategoryModification> categories = Arrays.asList( new TicketCategoryModification(null, "default", 2, new DateTimeModification(start.toLocalDate(), start.toLocalTime()), new DateTimeModification(end.toLocalDate(), end.toLocalTime()), DESCRIPTION, BigDecimal.TEN, false, "", true, null, null, null, null, null), new TicketCategoryModification(null, "default2", 10, new DateTimeModification(start.toLocalDate(), start.toLocalTime()), new DateTimeModification(end.toLocalDate(), end.toLocalTime()), DESCRIPTION, BigDecimal.TEN, true, "", true, null, null, null, null, null)); configurationManager.saveSystemConfiguration(ConfigurationKeys.ENABLE_WAITING_QUEUE, "true"); Pair<Event, String> eventAndUsername = initEvent(categories, organizationRepository, userManager, eventManager, eventRepository); Event event = eventAndUsername.getKey(); List<TicketCategory> ticketCategories = ticketCategoryRepository.findByEventId(event.getId()); TicketCategory first = ticketCategories.stream().filter(tc -> !tc.isAccessRestricted()).findFirst() .orElseThrow(IllegalStateException::new); reserveTickets(event, first, 2); assertTrue( waitingQueueManager.subscribe(event, customerJohnDoe(event), "john@doe.com", null, Locale.ENGLISH)); assertTrue(waitingQueueManager.subscribe(event, new CustomerName("John Doe 2", "John", "Doe 2", event), "john@doe2.com", null, Locale.ENGLISH)); ZoneId zoneId = event.getZoneId(); Result<TicketCategory> ticketCategoryResult = eventManager.updateCategory(first.getId(), event, new TicketCategoryModification(first.getId(), first.getName(), 3, fromZonedDateTime(first.getInception(zoneId)), fromZonedDateTime(first.getExpiration(zoneId)), Collections.emptyMap(), first.getPrice(), false, "", true, null, null, null, null, null), eventAndUsername.getValue()); assertTrue(ticketCategoryResult.isSuccess()); assertEquals(1, ticketRepository.countReleasedTicketInCategory(event.getId(), first.getId()).intValue()); //now we should have an extra available ticket List<Triple<WaitingQueueSubscription, TicketReservationWithOptionalCodeModification, ZonedDateTime>> subscriptions = waitingQueueManager .distributeSeats(event).collect(Collectors.toList()); assertEquals(1, subscriptions.size()); } private List<TicketCategoryModification> getPreSalesTicketCategoryModifications(boolean firstBounded, int firstSeats, boolean lastBounded, int lastSeats) { LocalDateTime start = LocalDateTime.now().plusMinutes(4); return Arrays.asList( new TicketCategoryModification(null, "defaultFirst", firstSeats, new DateTimeModification(start.toLocalDate(), start.toLocalTime()), new DateTimeModification(LocalDate.now().plusDays(1), LocalTime.now()), DESCRIPTION, BigDecimal.TEN, false, "", firstBounded, null, null, null, null, null), new TicketCategoryModification(null, "defaultLast", lastSeats, new DateTimeModification(LocalDate.now().plusDays(1), LocalTime.now()), new DateTimeModification(LocalDate.now().plusDays(2), LocalTime.now()), DESCRIPTION, BigDecimal.TEN, false, "", lastBounded, null, null, null, null, null)); } }