package org.killbill.billing.entitlement.api;
import java.util.UUID;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.LocalDate;
import org.killbill.billing.GuicyKillbillTestSuiteNoDB;
import org.killbill.billing.account.api.Account;
import org.killbill.billing.account.api.AccountApiException;
import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.entitlement.EntitlementTestSuiteNoDB;
import org.killbill.billing.mock.MockAccountBuilder;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import static org.testng.Assert.assertTrue;
public class TestEntitlementDateHelper extends EntitlementTestSuiteNoDB {
private EntitlementDateHelper dateHelper;
@BeforeMethod(groups = "fast")
public void beforeMethod() throws Exception {
super.beforeMethod();
dateHelper = new EntitlementDateHelper();
clock.resetDeltaFromReality();
}
@Test(groups = "fast")
public void testWithAccountInUtc() throws AccountApiException, EntitlementApiException {
final LocalDate initialDate = new LocalDate(2013, 8, 7);
clock.setDay(initialDate.plusDays(1));
final DateTime referenceDateTime = new DateTime(2013, 1, 1, 15, 43, 25, 0, DateTimeZone.UTC);
createAccount(DateTimeZone.UTC, referenceDateTime);
final DateTime targetDate = dateHelper.fromLocalDateAndReferenceTime(initialDate, clock.getUTCNow(), internalCallContext);
final DateTime expectedDate = new DateTime(2013, 8, 7, 15, 43, 25, 0, DateTimeZone.UTC);
Assert.assertEquals(targetDate, expectedDate);
}
@Test(groups = "fast")
public void testWithAccountInUtcMinus8() throws AccountApiException, EntitlementApiException {
final LocalDate inputDate = new LocalDate(2013, 8, 7);
clock.setDay(inputDate.plusDays(3));
final DateTimeZone timeZoneUtcMinus8 = DateTimeZone.forOffsetHours(-8);
final DateTime referenceDateTime = new DateTime(2013, 1, 1, 1, 28, 10, 0, DateTimeZone.UTC);
createAccount(timeZoneUtcMinus8, referenceDateTime);
final DateTime targetDate = dateHelper.fromLocalDateAndReferenceTime(inputDate, clock.getUTCNow(), internalCallContext);
Assert.assertEquals(new LocalDate(targetDate, timeZoneUtcMinus8), inputDate);
Assert.assertEquals(targetDate.toLocalTime(), referenceDateTime.toLocalTime());
Assert.assertEquals(targetDate, new DateTime(2013, 8, 8, 1, 28, 10, 0, DateTimeZone.UTC));
}
@Test(groups = "fast")
public void testWithAccountInUtcPlus5() throws AccountApiException, EntitlementApiException {
final LocalDate inputDate = new LocalDate(2013, 8, 7);
clock.setDay(inputDate.plusDays(1));
final DateTimeZone timeZoneUtcPlus5 = DateTimeZone.forOffsetHours(+5);
final DateTime referenceDateTime = new DateTime(2013, 1, 1, 20, 28, 10, 0, DateTimeZone.UTC);
createAccount(timeZoneUtcPlus5, referenceDateTime);
final DateTime targetDate = dateHelper.fromLocalDateAndReferenceTime(inputDate, clock.getUTCNow(), internalCallContext);
Assert.assertEquals(new LocalDate(targetDate, timeZoneUtcPlus5), inputDate);
Assert.assertEquals(targetDate.toLocalTime(), referenceDateTime.toLocalTime());
Assert.assertEquals(targetDate, new DateTime(2013, 8, 6, 20, 28, 10, 0, DateTimeZone.UTC));
}
@Test(groups = "fast")
public void testIsBeforeOrEqualsToday() throws AccountApiException {
clock.setTime(new DateTime(2013, 8, 7, 3, 28, 10, 0, DateTimeZone.UTC));
final DateTimeZone timeZoneUtcMinus8 = DateTimeZone.forOffsetHours(-8);
createAccount(timeZoneUtcMinus8, clock.getUTCNow());
final DateTime inputDateEquals = new DateTime(2013, 8, 6, 23, 28, 10, 0, timeZoneUtcMinus8);
assertTrue(inputDateEquals.compareTo(clock.getUTCNow()) > 0);
assertTrue(isBeforeOrEqualsToday(inputDateEquals, timeZoneUtcMinus8, internalCallContext));
}
private boolean isBeforeOrEqualsToday(final DateTime inputDate, final DateTimeZone accountTimeZone, final InternalTenantContext internalTenantContext) {
final LocalDate localDateNowInAccountTimezone = clock.getToday(accountTimeZone);
final LocalDate targetDateInAccountTimezone = internalTenantContext.toLocalDate(inputDate);
return targetDateInAccountTimezone.compareTo(localDateNowInAccountTimezone) <= 0;
}
private void createAccount(final DateTimeZone dateTimeZone, final DateTime referenceDateTime) throws AccountApiException {
final Account accountData = new MockAccountBuilder().externalKey(UUID.randomUUID().toString())
.timeZone(dateTimeZone)
.referenceTime(referenceDateTime)
.createdDate(referenceDateTime)
.build();
GuicyKillbillTestSuiteNoDB.createMockAccount(accountData,
accountUserApi,
accountInternalApi,
immutableAccountInternalApi,
nonEntityDao,
clock,
internalCallContextFactory,
callContext,
internalCallContext);
}
}