| // 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()); |
| } |
| } |