/**
* 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.model.SummaryRow;
import alfio.manager.system.ConfigurationManager;
import alfio.model.*;
import alfio.repository.*;
import alfio.repository.user.OrganizationRepository;
import alfio.util.TemplateManager;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.context.MessageSource;
import org.springframework.transaction.PlatformTransactionManager;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class TicketReservationManagerUnitTest {
private static final String TICKET_RESERVATION_ID = "abcdef";
private TicketReservationManager manager;
@Mock
private PromoCodeDiscountRepository promoCodeDiscountRepository;
@Mock
private TicketRepository ticketRepository;
@Mock
private TicketReservationRepository ticketReservationRepository;
@Mock
private EventRepository eventRepository;
@Mock
private TicketReservation reservation;
@Mock
private Event event;
@Mock
private Ticket ticket;
@Mock
private TicketCategory ticketCategory;
@Mock
private OrganizationRepository organizationRepository;
@Mock
private TicketCategoryRepository ticketCategoryRepository;
@Mock
private TicketCategoryDescriptionRepository ticketCategoryDescriptionRepository;
@Mock
private ConfigurationManager configurationManager;
@Mock
private PaymentManager paymentManager;
@Mock
private SpecialPriceRepository specialPriceRepository;
@Mock
private TransactionRepository transactionRepository;
@Mock
private NotificationManager notificationManager;
@Mock
private MessageSource messageSource;
@Mock
private TemplateManager templateManager;
@Mock
private PlatformTransactionManager transactionManager;
@Mock
private WaitingQueueManager waitingQueueManager;
@Mock
private PluginManager pluginManager;
@Mock
private FileUploadManager fileUploadManager;
@Mock
private TicketFieldRepository ticketFieldRepository;
@Mock
private AdditionalServiceRepository additionalServiceRepository;
@Mock
private AdditionalServiceItemRepository additionalServiceItemRepository;
@Mock
private AdditionalServiceTextRepository additionalServiceTextRepository;
@Mock
private InvoiceSequencesRepository invoiceSequencesRepository;
@Before
public void setUp() {
manager = new TicketReservationManager(eventRepository,
organizationRepository,
ticketRepository,
ticketReservationRepository,
ticketCategoryRepository,
ticketCategoryDescriptionRepository,
configurationManager,
paymentManager,
promoCodeDiscountRepository,
specialPriceRepository,
transactionRepository,
notificationManager,
messageSource,
templateManager,
transactionManager,
waitingQueueManager,
pluginManager,
fileUploadManager,
ticketFieldRepository,
additionalServiceRepository,
additionalServiceItemRepository,
additionalServiceTextRepository,
invoiceSequencesRepository);
}
@Test
public void calcReservationCostOnlyTickets() throws Exception {
when(event.isVatIncluded()).thenReturn(true, false);
when(event.getVatStatus()).thenReturn(PriceContainer.VatStatus.INCLUDED, PriceContainer.VatStatus.NOT_INCLUDED);
when(event.getVat()).thenReturn(BigDecimal.TEN);
when(eventRepository.findByReservationId(eq(TICKET_RESERVATION_ID))).thenReturn(event);
when(ticketReservationRepository.findReservationById(eq(TICKET_RESERVATION_ID))).thenReturn(reservation);
when(ticket.getSrcPriceCts()).thenReturn(10);
when(ticketRepository.findTicketsInReservation(eq(TICKET_RESERVATION_ID))).thenReturn(Collections.singletonList(ticket));
AdditionalServiceItemRepository additionalServiceItemRepository = mock(AdditionalServiceItemRepository.class);
when(additionalServiceItemRepository.findByReservationUuid(eq(TICKET_RESERVATION_ID))).thenReturn(Collections.emptyList());
TotalPrice included = manager.totalReservationCostWithVAT(TICKET_RESERVATION_ID);
assertEquals(10, included.getPriceWithVAT());
assertEquals(1, included.getVAT());
TotalPrice notIncluded = manager.totalReservationCostWithVAT(TICKET_RESERVATION_ID);
assertEquals(11, notIncluded.getPriceWithVAT());
assertEquals(1, notIncluded.getVAT());
}
@Test
public void calcReservationCostWithASVatIncludedInherited() {
initReservationWithAdditionalServices(true, AdditionalService.VatType.INHERITED, 10, 10);
//first: event price vat included, additional service VAT inherited
TotalPrice first = manager.totalReservationCostWithVAT(TICKET_RESERVATION_ID);
assertEquals(20, first.getPriceWithVAT());
assertEquals(2, first.getVAT());
}
@Test
public void calcReservationCostWithASVatIncludedASNoVat() {
initReservationWithAdditionalServices(true, AdditionalService.VatType.NONE, 10, 10);
//second: event price vat included, additional service VAT n/a
TotalPrice second = manager.totalReservationCostWithVAT(TICKET_RESERVATION_ID);
assertEquals(20, second.getPriceWithVAT());
assertEquals(1, second.getVAT());
}
@Test
public void calcReservationCostWithASVatNotIncludedASInherited() {
initReservationWithAdditionalServices(false, AdditionalService.VatType.INHERITED, 10, 10);
//third: event price vat not included, additional service VAT inherited
TotalPrice third = manager.totalReservationCostWithVAT(TICKET_RESERVATION_ID);
assertEquals(22, third.getPriceWithVAT());
assertEquals(2, third.getVAT());
}
@Test
public void calcReservationCostWithASVatNotIncludedASNone() {
initReservationWithAdditionalServices(false, AdditionalService.VatType.NONE, 10, 10);
//fourth: event price vat not included, additional service VAT n/a
TotalPrice fourth = manager.totalReservationCostWithVAT(TICKET_RESERVATION_ID);
assertEquals(21, fourth.getPriceWithVAT());
assertEquals(1, fourth.getVAT());
}
@Test
public void testExtractSummaryVatNotIncluded() {
initReservationWithTicket(1000, false);
List<SummaryRow> summaryRows = manager.extractSummary(TICKET_RESERVATION_ID, event, Locale.ENGLISH, null, new TotalPrice(1100, 100, 0, 0));
assertEquals(1, summaryRows.size());
assertEquals("10.00", summaryRows.get(0).getPrice());
}
@Test
public void testExtractSummaryVatIncluded() {
initReservationWithTicket(1000, true);
List<SummaryRow> summaryRows = manager.extractSummary(TICKET_RESERVATION_ID, event, Locale.ENGLISH, null, new TotalPrice(1000, 100, 0, 0));
assertEquals(1, summaryRows.size());
assertEquals("10.00", summaryRows.get(0).getPrice());
}
@Test
public void testExtractSummaryVatNotIncludedASInherited() {
initReservationWithAdditionalServices(false, AdditionalService.VatType.INHERITED, 1000, 1000);
List<SummaryRow> summaryRows = manager.extractSummary(TICKET_RESERVATION_ID, event, Locale.ENGLISH, null, new TotalPrice(2200, 200, 0, 0));
assertEquals(2, summaryRows.size());
summaryRows.forEach(r -> assertEquals(String.format("%s failed", r.getType()), "10.00", r.getPrice()));
}
@Test
public void testExtractSummaryVatIncludedASInherited() {
initReservationWithAdditionalServices(true, AdditionalService.VatType.INHERITED, 1000, 1000);
List<SummaryRow> summaryRows = manager.extractSummary(TICKET_RESERVATION_ID, event, Locale.ENGLISH, null, new TotalPrice(2000, 182, 0, 0));
assertEquals(2, summaryRows.size());
summaryRows.forEach(r -> assertEquals(String.format("%s failed", r.getType()), "10.00", r.getPrice()));
}
@Test
public void testExtractSummaryVatNotIncludedASNone() {
initReservationWithAdditionalServices(false, AdditionalService.VatType.NONE, 1000, 1000);
List<SummaryRow> summaryRows = manager.extractSummary(TICKET_RESERVATION_ID, event, Locale.ENGLISH, null, new TotalPrice(1000, 100, 0, 0));
assertEquals(2, summaryRows.size());
summaryRows.forEach(r -> assertEquals(String.format("%s failed", r.getType()), "10.00", r.getPrice()));
}
@Test
public void testExtractSummaryVatIncludedASNone() {
initReservationWithAdditionalServices(true, AdditionalService.VatType.NONE, 1000, 1000);
List<SummaryRow> summaryRows = manager.extractSummary(TICKET_RESERVATION_ID, event, Locale.ENGLISH, null, new TotalPrice(2000, 100, 0, 0));
assertEquals(2, summaryRows.size());
assertEquals("10.00", summaryRows.get(0).getPrice());
assertEquals("10.00", summaryRows.get(1).getPrice());
}
private void initReservationWithTicket(int ticketPaidPrice, boolean eventVatIncluded) {
when(event.isVatIncluded()).thenReturn(eventVatIncluded);
when(event.getVatStatus()).thenReturn(eventVatIncluded ? PriceContainer.VatStatus.INCLUDED : PriceContainer.VatStatus.NOT_INCLUDED);
when(event.getVat()).thenReturn(BigDecimal.TEN);
when(event.getId()).thenReturn(1);
when(eventRepository.findByReservationId(eq(TICKET_RESERVATION_ID))).thenReturn(event);
when(ticketReservationRepository.findReservationById(eq(TICKET_RESERVATION_ID))).thenReturn(reservation);
when(ticket.getSrcPriceCts()).thenReturn(ticketPaidPrice);
when(ticket.getCategoryId()).thenReturn(1);
when(ticketRepository.findTicketsInReservation(eq(TICKET_RESERVATION_ID))).thenReturn(Collections.singletonList(ticket));
when(ticketCategoryRepository.getById(eq(1), eq(1))).thenReturn(ticketCategory);
}
private void initReservationWithAdditionalServices(boolean eventVatIncluded, AdditionalService.VatType additionalServiceVatType, int ticketSrcPrice, int asSrcPrice) {
initReservationWithTicket(ticketSrcPrice, eventVatIncluded);
AdditionalServiceItem additionalServiceItem = mock(AdditionalServiceItem.class);
AdditionalService additionalService = mock(AdditionalService.class);
when(additionalServiceItemRepository.findByReservationUuid(eq(TICKET_RESERVATION_ID))).thenReturn(Collections.singletonList(additionalServiceItem));
when(additionalServiceItem.getAdditionalServiceId()).thenReturn(1);
when(additionalServiceRepository.getById(eq(1), eq(1))).thenReturn(additionalService);
when(additionalServiceItem.getSrcPriceCts()).thenReturn(asSrcPrice);
when(additionalService.getVatType()).thenReturn(additionalServiceVatType);
AdditionalServiceItemRepository additionalServiceItemRepository = mock(AdditionalServiceItemRepository.class);
when(additionalServiceItemRepository.findByReservationUuid(eq(TICKET_RESERVATION_ID))).thenReturn(Collections.emptyList());
AdditionalServiceText text = mock(AdditionalServiceText.class);
when(text.getId()).thenReturn(1);
when(text.getLocale()).thenReturn("en");
when(additionalServiceTextRepository.findBestMatchByLocaleAndType(anyInt(), eq("en"), eq(AdditionalServiceText.TextType.TITLE))).thenReturn(text);
}
}