diff --git a/fineract-core/src/test/java/org/apache/fineract/infrastructure/core/service/MathUtilTest.java b/fineract-core/src/test/java/org/apache/fineract/infrastructure/core/service/MathUtilTest.java new file mode 100644 index 00000000000..9e2ed4f88ff --- /dev/null +++ b/fineract-core/src/test/java/org/apache/fineract/infrastructure/core/service/MathUtilTest.java @@ -0,0 +1,145 @@ +/** + * 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.fineract.infrastructure.core.service; + +import java.math.BigDecimal; +import java.math.MathContext; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertNull; +import org.junit.jupiter.api.Test; + +class MathUtilTest { + + @Test + void nullToDefaultReturnsDefaultWhenValueNull() { + Long result = MathUtil.nullToDefault(null, 5L); + assertEquals(5L, result); + } + + @Test + void nullToDefaultReturnsValueWhenNotNull() { + Long result = MathUtil.nullToDefault(10L, 5L); + assertEquals(10L, result); + } + + @Test + void nullToZeroLongReturnsZeroWhenNull() { + Long result = MathUtil.nullToZero((Long) null); + assertEquals(0L, result); + } + + @Test + void zeroToNullReturnsNullWhenZero() { + Long result = MathUtil.zeroToNull(0L); + assertNull(result); + } + + @Test + void negativeToZeroReturnsZeroForNegativeValue() { + Long result = MathUtil.negativeToZero(-10L); + assertEquals(0L, result); + } + + @Test + void negativeToZeroReturnsSameValueForPositive() { + Long result = MathUtil.negativeToZero(20L); + assertEquals(20L, result); + } + + @Test + void isGreaterThanZeroReturnsTrueForPositive() { + assertTrue(MathUtil.isGreaterThanZero(5L)); + } + + @Test + void isLessThanZeroReturnsTrueForNegative() { + assertTrue(MathUtil.isLessThanZero(-5L)); + } + + @Test + void addHandlesNullValues() { + Long result = MathUtil.add(null, 10L); + assertEquals(10L, result); + } + + @Test + void addReturnsSumOfValues() { + Long result = MathUtil.add(10L, 20L); + assertEquals(30L, result); + } + + @Test + void subtractReturnsCorrectDifference() { + Long result = MathUtil.subtract(20L, 5L); + assertEquals(15L, result); + } + + @Test + void absReturnsPositiveValue() { + Long result = MathUtil.abs(-25L); + assertEquals(25L, result); + } + + @Test + void bigDecimalAddReturnsCorrectSum() { + BigDecimal result = MathUtil.add(new BigDecimal("10.5"), new BigDecimal("5.5"), new MathContext(10)); + + assertEquals(new BigDecimal("16.0"), result); + } + + @Test + void bigDecimalSubtractReturnsCorrectDifference() { + BigDecimal result = MathUtil.subtract(new BigDecimal("20"), new BigDecimal("5"), new MathContext(10)); + + assertEquals(new BigDecimal("15"), result); + } + + @Test + void percentageOfCalculatesCorrectValue() { + BigDecimal value = new BigDecimal("200"); + BigDecimal percentage = new BigDecimal("10"); + + BigDecimal result = MathUtil.percentageOf(value, percentage, new MathContext(10)); + + assertEquals(0, result.compareTo(new BigDecimal("20"))); + } + + @Test + void percentageOfReturnsZeroWhenValueZero() { + BigDecimal result = MathUtil.percentageOf(BigDecimal.ZERO, new BigDecimal("10"), new MathContext(10)); + assertEquals(BigDecimal.ZERO, result); + } + + @Test + void stripTrailingZerosRemovesExtraZeros() { + BigDecimal value = new BigDecimal("10.5000"); + + BigDecimal result = MathUtil.stripTrailingZeros(value); + + assertEquals(new BigDecimal("10.5"), result); + } + + @Test + void stripTrailingZerosReturnsNullWhenInputNull() { + assertNull(MathUtil.stripTrailingZeros(null)); + } + +} diff --git a/fineract-core/src/test/java/org/apache/fineract/util/StreamResponseUtilTest.java b/fineract-core/src/test/java/org/apache/fineract/util/StreamResponseUtilTest.java new file mode 100644 index 00000000000..b1a95af567f --- /dev/null +++ b/fineract-core/src/test/java/org/apache/fineract/util/StreamResponseUtilTest.java @@ -0,0 +1,137 @@ +/** + * 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.fineract.util; + +import jakarta.ws.rs.container.AsyncResponse; +import jakarta.ws.rs.core.HttpHeaders; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.StreamingOutput; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.util.concurrent.Future; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +class StreamResponseUtilTest { + + @Test + void okReturnsResponseWithoutContentDispositionWhenDispositionTypeEmpty() { + + InputStream stream = new ByteArrayInputStream("test".getBytes()); + + StreamResponseUtil.StreamResponseData data = StreamResponseUtil.StreamResponseData.builder().stream(stream).type("text/plain") + .fileName("file.txt").build(); + + Response response = StreamResponseUtil.ok(data); + + Assertions.assertEquals("text/plain", response.getMediaType().toString()); + Assertions.assertNull(response.getHeaderString(HttpHeaders.CONTENT_DISPOSITION)); + } + + @Test + void okReturnsResponseWithContentDispositionWhenDispositionTypePresent() { + + InputStream stream = new ByteArrayInputStream("test".getBytes()); + + StreamResponseUtil.StreamResponseData data = StreamResponseUtil.StreamResponseData.builder().stream(stream).type("text/plain") + .fileName("file.txt").dispositionType(StreamResponseUtil.DISPOSITION_TYPE_ATTACHMENT).build(); + + Response response = StreamResponseUtil.ok(data); + + Assertions.assertEquals("text/plain", response.getMediaType().toString()); + + String header = response.getHeaderString(HttpHeaders.CONTENT_DISPOSITION); + + Assertions.assertNotNull(header); + Assertions.assertTrue(header.contains(StreamResponseUtil.DISPOSITION_TYPE_ATTACHMENT)); + Assertions.assertTrue(header.contains("file.txt")); + } + + @Test + void okAsyncResponseWithoutDisposition() throws Exception { + + AsyncResponse asyncResponse = Mockito.mock(AsyncResponse.class); + + InputStream stream = new ByteArrayInputStream("test".getBytes()); + + StreamResponseUtil.StreamResponseData data = StreamResponseUtil.StreamResponseData.builder().stream(stream).type("text/plain") + .build(); + + Future future = StreamResponseUtil.ok(asyncResponse, data); + + future.get(); + + Mockito.verify(asyncResponse).resume(Mockito.any(Response.class)); + } + + @Test + void okAsyncResponseWithDisposition() throws Exception { + + AsyncResponse asyncResponse = Mockito.mock(AsyncResponse.class); + + InputStream stream = new ByteArrayInputStream("test".getBytes()); + + StreamResponseUtil.StreamResponseData data = StreamResponseUtil.StreamResponseData.builder().stream(stream).type("text/plain") + .fileName("file.txt").dispositionType(StreamResponseUtil.DISPOSITION_TYPE_INLINE).build(); + + Future future = StreamResponseUtil.ok(asyncResponse, data); + + future.get(); + + Mockito.verify(asyncResponse).resume(Mockito.any(Response.class)); + } + + @Test + void okHeaderContainsCorrectFilename() { + + InputStream stream = new ByteArrayInputStream("hello".getBytes()); + + StreamResponseUtil.StreamResponseData data = StreamResponseUtil.StreamResponseData.builder().stream(stream).type("text/plain") + .fileName("example.txt").dispositionType(StreamResponseUtil.DISPOSITION_TYPE_ATTACHMENT).build(); + + Response response = StreamResponseUtil.ok(data); + + String header = response.getHeaderString(HttpHeaders.CONTENT_DISPOSITION); + + Assertions.assertTrue(header.contains("attachment")); + Assertions.assertTrue(header.contains("example.txt")); + } + + @Test + void okStreamingOutputWritesStreamData() throws Exception { + + byte[] content = "stream-content".getBytes(); + InputStream stream = new ByteArrayInputStream(content); + + StreamResponseUtil.StreamResponseData data = StreamResponseUtil.StreamResponseData.builder().stream(stream).type("text/plain") + .build(); + + Response response = StreamResponseUtil.ok(data); + + StreamingOutput streamingOutput = (StreamingOutput) response.getEntity(); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + + streamingOutput.write(out); + + Assertions.assertArrayEquals(content, out.toByteArray()); + } +}