blob: b960a1be5692e2b6632604fcc284b2dd601debed [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.api.response;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.function.Consumer;
import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.command.QuotaEmailTemplateListCmd;
import org.apache.cloudstack.api.command.QuotaEmailTemplateUpdateCmd;
import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.cloudstack.quota.QuotaService;
import org.apache.cloudstack.quota.QuotaStatement;
import org.apache.cloudstack.quota.constant.QuotaConfig;
import org.apache.cloudstack.quota.constant.QuotaTypes;
import org.apache.cloudstack.quota.dao.QuotaBalanceDao;
import org.apache.cloudstack.quota.dao.QuotaCreditsDao;
import org.apache.cloudstack.quota.dao.QuotaEmailTemplatesDao;
import org.apache.cloudstack.quota.dao.QuotaTariffDao;
import org.apache.cloudstack.quota.dao.QuotaUsageDao;
import org.apache.cloudstack.quota.vo.QuotaBalanceVO;
import org.apache.cloudstack.quota.vo.QuotaCreditsVO;
import org.apache.cloudstack.quota.vo.QuotaEmailTemplatesVO;
import org.apache.cloudstack.quota.vo.QuotaTariffVO;
import org.apache.commons.lang3.time.DateUtils;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockedConstruction;
import org.mockito.Mockito;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.user.Account;
import com.cloud.user.AccountVO;
import com.cloud.user.dao.AccountDao;
import com.cloud.user.dao.UserDao;
import junit.framework.TestCase;
import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class QuotaResponseBuilderImplTest extends TestCase {
@Mock
QuotaTariffDao quotaTariffDaoMock;
@Mock
QuotaBalanceDao quotaBalanceDaoMock;
@Mock
QuotaCreditsDao quotaCreditsDaoMock;
@Mock
QuotaEmailTemplatesDao quotaEmailTemplateDaoMock;
@Mock
UserDao userDaoMock;
@Mock
QuotaService quotaServiceMock;
@Mock
AccountDao accountDaoMock;
@Mock
Consumer<String> consumerStringMock;
@Mock
QuotaTariffVO quotaTariffVoMock;
@Mock
QuotaStatement quotaStatementMock;
@Mock
DomainDao domainDaoMock;
@Mock
QuotaUsageDao quotaUsageDaoMock;
@InjectMocks
QuotaResponseBuilderImpl quotaResponseBuilderSpy = Mockito.spy(QuotaResponseBuilderImpl.class);
Date date = new Date();
@Mock
Account accountMock;
@Mock
DomainVO domainVOMock;
private void overrideDefaultQuotaEnabledConfigValue(final Object value) throws IllegalAccessException, NoSuchFieldException {
Field f = ConfigKey.class.getDeclaredField("_defaultValue");
f.setAccessible(true);
f.set(QuotaConfig.QuotaAccountEnabled, value);
}
private Calendar[] createPeriodForQuotaSummary() {
final Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR, 0);
return new Calendar[] {calendar, calendar};
}
private QuotaTariffVO makeTariffTestData() {
QuotaTariffVO tariffVO = new QuotaTariffVO();
tariffVO.setUsageType(QuotaTypes.IP_ADDRESS);
tariffVO.setUsageName("ip address");
tariffVO.setUsageUnit("IP-Month");
tariffVO.setCurrencyValue(BigDecimal.valueOf(100.19));
tariffVO.setEffectiveOn(new Date());
tariffVO.setUsageDiscriminator("");
return tariffVO;
}
@Test
public void testQuotaResponse() {
QuotaTariffVO tariffVO = makeTariffTestData();
QuotaTariffResponse response = quotaResponseBuilderSpy.createQuotaTariffResponse(tariffVO);
assertTrue(tariffVO.getUsageType() == response.getUsageType());
assertTrue(tariffVO.getCurrencyValue().equals(response.getTariffValue()));
}
@Test
public void testAddQuotaCredits() {
final long accountId = 2L;
final long domainId = 1L;
final double amount = 11.0;
final long updatedBy = 2L;
QuotaCreditsVO credit = new QuotaCreditsVO();
credit.setCredit(new BigDecimal(amount));
Mockito.when(quotaCreditsDaoMock.saveCredits(Mockito.any(QuotaCreditsVO.class))).thenReturn(credit);
Mockito.when(quotaBalanceDaoMock.lastQuotaBalance(Mockito.anyLong(), Mockito.anyLong(), Mockito.any(Date.class))).thenReturn(new BigDecimal(111));
Mockito.when(quotaServiceMock.computeAdjustedTime(Mockito.any(Date.class))).thenReturn(new Date());
AccountVO account = new AccountVO();
account.setState(Account.State.LOCKED);
Mockito.when(accountDaoMock.findById(Mockito.anyLong())).thenReturn(account);
QuotaCreditsResponse resp = quotaResponseBuilderSpy.addQuotaCredits(accountId, domainId, amount, updatedBy, true);
assertTrue(resp.getCredits().compareTo(credit.getCredit()) == 0);
}
@Test
public void testListQuotaEmailTemplates() {
QuotaEmailTemplateListCmd cmd = new QuotaEmailTemplateListCmd();
cmd.setTemplateName("some name");
List<QuotaEmailTemplatesVO> templates = new ArrayList<>();
QuotaEmailTemplatesVO template = new QuotaEmailTemplatesVO();
template.setTemplateName("template");
templates.add(template);
Mockito.when(quotaEmailTemplateDaoMock.listAllQuotaEmailTemplates(Mockito.anyString())).thenReturn(templates);
Assert.assertEquals(1, quotaResponseBuilderSpy.listQuotaEmailTemplates(cmd).size());
}
@Test
public void testUpdateQuotaEmailTemplate() {
QuotaEmailTemplateUpdateCmd cmd = new QuotaEmailTemplateUpdateCmd();
cmd.setTemplateBody("some body");
cmd.setTemplateName("some name");
cmd.setTemplateSubject("some subject");
List<QuotaEmailTemplatesVO> templates = new ArrayList<>();
Mockito.when(quotaEmailTemplateDaoMock.listAllQuotaEmailTemplates(Mockito.anyString())).thenReturn(templates);
Mockito.when(quotaEmailTemplateDaoMock.updateQuotaEmailTemplate(Mockito.any(QuotaEmailTemplatesVO.class))).thenReturn(true);
// invalid template test
assertFalse(quotaResponseBuilderSpy.updateQuotaEmailTemplate(cmd));
// valid template test
QuotaEmailTemplatesVO template = new QuotaEmailTemplatesVO();
template.setTemplateName("template");
templates.add(template);
assertTrue(quotaResponseBuilderSpy.updateQuotaEmailTemplate(cmd));
}
@Test
public void testCreateQuotaLastBalanceResponse() {
List<QuotaBalanceVO> quotaBalance = new ArrayList<>();
// null balance test
try {
quotaResponseBuilderSpy.createQuotaLastBalanceResponse(null, new Date());
} catch (InvalidParameterValueException e) {
assertTrue(e.getMessage().equals("There are no balance entries on or before the requested date."));
}
// empty balance test
try {
quotaResponseBuilderSpy.createQuotaLastBalanceResponse(quotaBalance, new Date());
} catch (InvalidParameterValueException e) {
assertTrue(e.getMessage().equals("There are no balance entries on or before the requested date."));
}
// valid balance test
QuotaBalanceVO entry = new QuotaBalanceVO();
entry.setAccountId(2L);
entry.setCreditBalance(new BigDecimal(100));
quotaBalance.add(entry);
quotaBalance.add(entry);
Mockito.lenient().when(quotaServiceMock.computeAdjustedTime(Mockito.any(Date.class))).thenReturn(new Date());
QuotaBalanceResponse resp = quotaResponseBuilderSpy.createQuotaLastBalanceResponse(quotaBalance, null);
assertTrue(resp.getStartQuota().compareTo(new BigDecimal(200)) == 0);
}
@Test
public void testStartOfNextDayWithoutParameters() {
Date nextDate = quotaResponseBuilderSpy.startOfNextDay();
LocalDateTime tomorrowAtStartOfTheDay = LocalDate.now().atStartOfDay().plusDays(1);
Date expectedNextDate = Date.from(tomorrowAtStartOfTheDay.atZone(ZoneId.systemDefault()).toInstant());
Assert.assertEquals(expectedNextDate, nextDate);
}
@Test
public void testStartOfNextDayWithParameter() {
Date anyDate = new Date(1242421545757532l);
Date nextDayDate = quotaResponseBuilderSpy.startOfNextDay(anyDate);
LocalDateTime nextDayLocalDateTimeAtStartOfTheDay = anyDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate().plusDays(1).atStartOfDay();
Date expectedNextDate = Date.from(nextDayLocalDateTimeAtStartOfTheDay.atZone(ZoneId.systemDefault()).toInstant());
Assert.assertEquals(expectedNextDate, nextDayDate);
}
@Test
public void validateStringsOnCreatingNewQuotaTariffTestNullValueDoNothing() {
quotaResponseBuilderSpy.validateStringsOnCreatingNewQuotaTariff(consumerStringMock, null);
Mockito.verify(consumerStringMock, Mockito.never()).accept(Mockito.anyString());
}
@Test
public void validateStringsOnCreatingNewQuotaTariffTestEmptyValueCallMethodWithNull() {
quotaResponseBuilderSpy.validateStringsOnCreatingNewQuotaTariff(consumerStringMock, "");
Mockito.verify(consumerStringMock).accept(null);
}
@Test
public void validateStringsOnCreatingNewQuotaTariffTestValueCallMethodWithValue() {
String value = "test";
quotaResponseBuilderSpy.validateStringsOnCreatingNewQuotaTariff(consumerStringMock, value);
Mockito.verify(consumerStringMock).accept(value);
}
@Test
public void validateValueOnCreatingNewQuotaTariffTestNullValueDoNothing() {
quotaResponseBuilderSpy.validateValueOnCreatingNewQuotaTariff(quotaTariffVoMock, null);
Mockito.verify(quotaTariffVoMock, Mockito.never()).setCurrencyValue(Mockito.any(BigDecimal.class));
}
@Test
public void validateValueOnCreatingNewQuotaTariffTestAnyValueIsSet() {
Double value = 0.0;
quotaResponseBuilderSpy.validateValueOnCreatingNewQuotaTariff(quotaTariffVoMock, value);
Mockito.verify(quotaTariffVoMock).setCurrencyValue(BigDecimal.valueOf(value));
}
@Test
public void validateEndDateOnCreatingNewQuotaTariffTestNullEndDateDoNothing() {
Date startDate = null;
Date endDate = null;
quotaResponseBuilderSpy.validateEndDateOnCreatingNewQuotaTariff(quotaTariffVoMock, startDate, endDate);
Mockito.verify(quotaTariffVoMock, Mockito.never()).setEndDate(Mockito.any(Date.class));
}
@Test (expected = InvalidParameterValueException.class)
public void validateEndDateOnCreatingNewQuotaTariffTestEndDateLessThanStartDateThrowInvalidParameterValueException() {
Date startDate = date;
Date endDate = DateUtils.addSeconds(startDate, -1);
quotaResponseBuilderSpy.validateEndDateOnCreatingNewQuotaTariff(quotaTariffVoMock, startDate, endDate);
}
@Test (expected = InvalidParameterValueException.class)
public void validateEndDateOnCreatingNewQuotaTariffTestEndDateLessThanNowThrowInvalidParameterValueException() {
Date startDate = DateUtils.addDays(date, -100);
Date endDate = DateUtils.addDays(new Date(), -1);
Mockito.doReturn(date).when(quotaServiceMock).computeAdjustedTime(Mockito.any(Date.class));
quotaResponseBuilderSpy.validateEndDateOnCreatingNewQuotaTariff(quotaTariffVoMock, startDate, endDate);
}
@Test
public void validateEndDateOnCreatingNewQuotaTariffTestSetValidEndDate() {
Date startDate = DateUtils.addDays(date, -100);
Date endDate = date;
Mockito.doReturn(DateUtils.addDays(date, -10)).when(quotaServiceMock).computeAdjustedTime(Mockito.any(Date.class));
quotaResponseBuilderSpy.validateEndDateOnCreatingNewQuotaTariff(quotaTariffVoMock, startDate, endDate);
Mockito.verify(quotaTariffVoMock).setEndDate(Mockito.any(Date.class));
}
@Test
public void getNewQuotaTariffObjectTestCreateFromCurrentQuotaTariff() throws Exception {
try (MockedConstruction<QuotaTariffVO> quotaTariffVOMockedConstruction = Mockito.mockConstruction(QuotaTariffVO.class, (mock,
context) -> {
})) {
QuotaTariffVO result = quotaResponseBuilderSpy.getNewQuotaTariffObject(quotaTariffVoMock, "", 0);
Assert.assertEquals(quotaTariffVOMockedConstruction.constructed().get(0), result);
}
}
@Test (expected = InvalidParameterValueException.class)
public void getNewQuotaTariffObjectTestSetInvalidUsageTypeThrowsInvalidParameterValueException() throws InvalidParameterValueException {
quotaResponseBuilderSpy.getNewQuotaTariffObject(null, "test", 0);
}
@Test
public void getNewQuotaTariffObjectTestReturnValidObject() throws InvalidParameterValueException {
String name = "test";
int usageType = 1;
QuotaTariffVO result = quotaResponseBuilderSpy.getNewQuotaTariffObject(null, name, usageType);
Assert.assertEquals(name, result.getName());
Assert.assertEquals(usageType, result.getUsageType());
}
@Test
public void persistNewQuotaTariffTestpersistNewQuotaTariff() {
Mockito.doReturn(quotaTariffVoMock).when(quotaResponseBuilderSpy).getNewQuotaTariffObject(Mockito.any(QuotaTariffVO.class), Mockito.anyString(), Mockito.anyInt());
Mockito.doNothing().when(quotaResponseBuilderSpy).validateEndDateOnCreatingNewQuotaTariff(Mockito.any(QuotaTariffVO.class), Mockito.any(Date.class), Mockito.any(Date.class));
Mockito.doNothing().when(quotaResponseBuilderSpy).validateValueOnCreatingNewQuotaTariff(Mockito.any(QuotaTariffVO.class), Mockito.anyDouble());
Mockito.doNothing().when(quotaResponseBuilderSpy).validateStringsOnCreatingNewQuotaTariff(Mockito.any(Consumer.class), Mockito.anyString());
Mockito.doReturn(quotaTariffVoMock).when(quotaTariffDaoMock).addQuotaTariff(Mockito.any(QuotaTariffVO.class));
quotaResponseBuilderSpy.persistNewQuotaTariff(quotaTariffVoMock, "", 1, date, 1l, date, 1.0, "", "");
Mockito.verify(quotaTariffDaoMock).addQuotaTariff(Mockito.any(QuotaTariffVO.class));
}
@Test (expected = ServerApiException.class)
public void deleteQuotaTariffTestQuotaDoesNotExistThrowsServerApiException() {
quotaResponseBuilderSpy.deleteQuotaTariff("");
}
@Test
public void deleteQuotaTariffTestUpdateRemoved() {
Mockito.doReturn(quotaTariffVoMock).when(quotaTariffDaoMock).findByUuid(Mockito.anyString());
Mockito.doReturn(true).when(quotaTariffDaoMock).updateQuotaTariff(Mockito.any(QuotaTariffVO.class));
Mockito.doReturn(new Date()).when(quotaServiceMock).computeAdjustedTime(Mockito.any(Date.class));
Assert.assertTrue(quotaResponseBuilderSpy.deleteQuotaTariff(""));
Mockito.verify(quotaTariffVoMock).setRemoved(Mockito.any(Date.class));
}
@Test
public void getQuotaSummaryResponseTestAccountIsNotNullQuotaIsDisabledShouldReturnFalse() throws NoSuchFieldException, IllegalAccessException {
Calendar[] period = createPeriodForQuotaSummary();
overrideDefaultQuotaEnabledConfigValue("false");
Mockito.doReturn(period).when(quotaStatementMock).getCurrentStatementTime();
Mockito.doReturn(domainVOMock).when(domainDaoMock).findById(Mockito.anyLong());
Mockito.doReturn(BigDecimal.ZERO).when(quotaBalanceDaoMock).lastQuotaBalance(Mockito.anyLong(), Mockito.anyLong(), Mockito.any(Date.class));
Mockito.doReturn(BigDecimal.ZERO).when(quotaUsageDaoMock).findTotalQuotaUsage(Mockito.anyLong(), Mockito.anyLong(), Mockito.isNull(), Mockito.any(Date.class), Mockito.any(Date.class));
QuotaSummaryResponse quotaSummaryResponse = quotaResponseBuilderSpy.getQuotaSummaryResponse(accountMock);
assertFalse(quotaSummaryResponse.getQuotaEnabled());
}
@Test
public void getQuotaSummaryResponseTestAccountIsNotNullQuotaIsEnabledShouldReturnTrue() throws NoSuchFieldException, IllegalAccessException {
Calendar[] period = createPeriodForQuotaSummary();
overrideDefaultQuotaEnabledConfigValue("true");
Mockito.doReturn(period).when(quotaStatementMock).getCurrentStatementTime();
Mockito.doReturn(domainVOMock).when(domainDaoMock).findById(Mockito.anyLong());
Mockito.doReturn(BigDecimal.ZERO).when(quotaBalanceDaoMock).lastQuotaBalance(Mockito.anyLong(), Mockito.anyLong(), Mockito.any(Date.class));
Mockito.doReturn(BigDecimal.ZERO).when(quotaUsageDaoMock).findTotalQuotaUsage(Mockito.anyLong(), Mockito.anyLong(), Mockito.isNull(), Mockito.any(Date.class), Mockito.any(Date.class));
QuotaSummaryResponse quotaSummaryResponse = quotaResponseBuilderSpy.getQuotaSummaryResponse(accountMock);
assertTrue(quotaSummaryResponse.getQuotaEnabled());
}
}