mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-08-21 19:59:24 +00:00
Merge branch 'main' into org
This commit is contained in:
commit
3da9ae46b6
2
.github/workflows/ai_pr_title_review.yml
vendored
2
.github/workflows/ai_pr_title_review.yml
vendored
@ -87,7 +87,7 @@ jobs:
|
|||||||
- name: AI PR Title Analysis
|
- name: AI PR Title Analysis
|
||||||
if: steps.actor.outputs.is_repo_dev == 'true'
|
if: steps.actor.outputs.is_repo_dev == 'true'
|
||||||
id: ai-title-analysis
|
id: ai-title-analysis
|
||||||
uses: actions/ai-inference@d645f067d89ee1d5d736a5990e327e504d1c5a4a # v1.1.0
|
uses: actions/ai-inference@9693b137b6566bb66055a713613bf4f0493701eb # v1.2.3
|
||||||
with:
|
with:
|
||||||
model: openai/gpt-4o
|
model: openai/gpt-4o
|
||||||
system-prompt-file: ".github/config/system-prompt.txt"
|
system-prompt-file: ".github/config/system-prompt.txt"
|
||||||
|
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@ -16,7 +16,7 @@ on:
|
|||||||
# This ensures that jobs are grouped by the workflow and branch, allowing for cancellation of
|
# This ensures that jobs are grouped by the workflow and branch, allowing for cancellation of
|
||||||
# in-progress jobs when a new commit is pushed to the same branch or a new pull request is opened.
|
# in-progress jobs when a new commit is pushed to the same branch or a new pull request is opened.
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref_name || github.ref }}
|
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.number || github.ref_name || github.ref }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
@ -147,7 +147,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Generate OpenAPI documentation
|
- name: Generate OpenAPI documentation
|
||||||
run: ./gradlew :stirling-pdf:generateOpenApiDocs
|
run: ./gradlew :stirling-pdf:generateOpenApiDocs
|
||||||
|
|
||||||
- name: Upload OpenAPI Documentation
|
- name: Upload OpenAPI Documentation
|
||||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||||
with:
|
with:
|
||||||
|
6
.github/workflows/check_properties.yml
vendored
6
.github/workflows/check_properties.yml
vendored
@ -15,7 +15,7 @@ on:
|
|||||||
# This ensures that jobs are grouped by the workflow and branch, allowing for cancellation of
|
# This ensures that jobs are grouped by the workflow and branch, allowing for cancellation of
|
||||||
# in-progress jobs when a new commit is pushed to the same branch or a new pull request is opened.
|
# in-progress jobs when a new commit is pushed to the same branch or a new pull request is opened.
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref_name || github.ref }}
|
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.number || github.ref_name || github.ref }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
@ -127,7 +127,7 @@ jobs:
|
|||||||
|
|
||||||
// Filter for relevant files based on the PR changes
|
// Filter for relevant files based on the PR changes
|
||||||
const changedFiles = files
|
const changedFiles = files
|
||||||
.filter(file =>
|
.filter(file =>
|
||||||
file.status !== "removed" &&
|
file.status !== "removed" &&
|
||||||
/^app\/core\/src\/main\/resources\/messages_[a-zA-Z_]{2}_[a-zA-Z_]{2,7}\.properties$/.test(file.filename)
|
/^app\/core\/src\/main\/resources\/messages_[a-zA-Z_]{2}_[a-zA-Z_]{2,7}\.properties$/.test(file.filename)
|
||||||
)
|
)
|
||||||
@ -289,4 +289,4 @@ jobs:
|
|||||||
rm -rf pr-branch
|
rm -rf pr-branch
|
||||||
rm -f pr-branch-messages_en_GB.properties main-branch-messages_en_GB.properties changed_files.txt result.txt
|
rm -f pr-branch-messages_en_GB.properties main-branch-messages_en_GB.properties changed_files.txt result.txt
|
||||||
echo "Cleanup complete."
|
echo "Cleanup complete."
|
||||||
continue-on-error: true # Ensure cleanup runs even if previous steps fail
|
continue-on-error: true # Ensure cleanup runs even if previous steps fail
|
||||||
|
14
.github/workflows/pre_commit.yml
vendored
14
.github/workflows/pre_commit.yml
vendored
@ -2,8 +2,9 @@ name: Pre-commit
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
schedule:
|
push:
|
||||||
- cron: "0 0 * * 1"
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
@ -46,6 +47,15 @@ jobs:
|
|||||||
- run: pre-commit run --all-files -c .pre-commit-config.yaml
|
- run: pre-commit run --all-files -c .pre-commit-config.yaml
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
|
|
||||||
|
- name: Set up JDK
|
||||||
|
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
|
||||||
|
with:
|
||||||
|
java-version: 17
|
||||||
|
distribution: "temurin"
|
||||||
|
|
||||||
|
- name: Build with Gradle
|
||||||
|
run: ./gradlew clean build
|
||||||
|
|
||||||
- name: git add
|
- name: git add
|
||||||
run: |
|
run: |
|
||||||
git add .
|
git add .
|
||||||
|
2
.github/workflows/scorecards.yml
vendored
2
.github/workflows/scorecards.yml
vendored
@ -74,6 +74,6 @@ jobs:
|
|||||||
|
|
||||||
# Upload the results to GitHub's code scanning dashboard.
|
# Upload the results to GitHub's code scanning dashboard.
|
||||||
- name: "Upload to code-scanning"
|
- name: "Upload to code-scanning"
|
||||||
uses: github/codeql-action/upload-sarif@d6bbdef45e766d081b84a2def353b0055f728d3e # v3.29.3
|
uses: github/codeql-action/upload-sarif@51f77329afa6477de8c49fc9c7046c15b9a4e79d # v3.29.5
|
||||||
with:
|
with:
|
||||||
sarif_file: results.sarif
|
sarif_file: results.sarif
|
||||||
|
2
.github/workflows/sonarqube.yml
vendored
2
.github/workflows/sonarqube.yml
vendored
@ -18,7 +18,7 @@ on:
|
|||||||
# This ensures that jobs are grouped by the workflow and branch, allowing for cancellation of
|
# This ensures that jobs are grouped by the workflow and branch, allowing for cancellation of
|
||||||
# in-progress jobs when a new commit is pushed to the same branch or a new pull request is opened.
|
# in-progress jobs when a new commit is pushed to the same branch or a new pull request is opened.
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref_name || github.ref }}
|
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.number || github.ref_name || github.ref }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
repos:
|
repos:
|
||||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||||
rev: v0.12.0
|
rev: v0.12.7
|
||||||
hooks:
|
hooks:
|
||||||
- id: ruff
|
- id: ruff
|
||||||
args:
|
args:
|
||||||
@ -22,7 +22,7 @@ repos:
|
|||||||
files: \.(html|css|js|py|md)$
|
files: \.(html|css|js|py|md)$
|
||||||
exclude: (.vscode|.devcontainer|app/core/src/main/resources|app/proprietary/src/main/resources|Dockerfile|.*/pdfjs.*|.*/thirdParty.*|bootstrap.*|.*\.min\..*|.*diff\.js)
|
exclude: (.vscode|.devcontainer|app/core/src/main/resources|app/proprietary/src/main/resources|Dockerfile|.*/pdfjs.*|.*/thirdParty.*|bootstrap.*|.*\.min\..*|.*diff\.js)
|
||||||
- repo: https://github.com/gitleaks/gitleaks
|
- repo: https://github.com/gitleaks/gitleaks
|
||||||
rev: v8.27.2
|
rev: v8.28.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: gitleaks
|
- id: gitleaks
|
||||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
@ -43,4 +43,4 @@ repos:
|
|||||||
# - stylelint-config-standard@38.0.0
|
# - stylelint-config-standard@38.0.0
|
||||||
# - "@stylistic/stylelint-plugin@3.1.3"
|
# - "@stylistic/stylelint-plugin@3.1.3"
|
||||||
# files: \.(css)$
|
# files: \.(css)$
|
||||||
# args: [--fix]
|
# args: [--fix]
|
||||||
|
@ -78,7 +78,7 @@ RUN echo "@main https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/a
|
|||||||
# URW Base 35 fonts for better PDF rendering
|
# URW Base 35 fonts for better PDF rendering
|
||||||
font-urw-base35 && \
|
font-urw-base35 && \
|
||||||
python3 -m venv /opt/venv && \
|
python3 -m venv /opt/venv && \
|
||||||
/opt/venv/bin/pip install --upgrade pip setuptools && \
|
/opt/venv/bin/pip install --no-cache-dir --upgrade pip setuptools && \
|
||||||
/opt/venv/bin/pip install --no-cache-dir --upgrade unoserver weasyprint && \
|
/opt/venv/bin/pip install --no-cache-dir --upgrade unoserver weasyprint && \
|
||||||
ln -s /usr/lib/libreoffice/program/uno.py /opt/venv/lib/python3.12/site-packages/ && \
|
ln -s /usr/lib/libreoffice/program/uno.py /opt/venv/lib/python3.12/site-packages/ && \
|
||||||
ln -s /usr/lib/libreoffice/program/unohelper.py /opt/venv/lib/python3.12/site-packages/ && \
|
ln -s /usr/lib/libreoffice/program/unohelper.py /opt/venv/lib/python3.12/site-packages/ && \
|
||||||
@ -89,7 +89,6 @@ RUN echo "@main https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/a
|
|||||||
ln -s /usr/share/fontconfig/conf.avail/69-urw-*.conf /etc/fonts/conf.d/ && \
|
ln -s /usr/share/fontconfig/conf.avail/69-urw-*.conf /etc/fonts/conf.d/ && \
|
||||||
fc-cache -f -v && \
|
fc-cache -f -v && \
|
||||||
chmod +x /scripts/* && \
|
chmod +x /scripts/* && \
|
||||||
chmod +x /scripts/init.sh && \
|
|
||||||
# User permissions
|
# User permissions
|
||||||
addgroup -S stirlingpdfgroup && adduser -S stirlingpdfuser -G stirlingpdfgroup && \
|
addgroup -S stirlingpdfgroup && adduser -S stirlingpdfuser -G stirlingpdfgroup && \
|
||||||
chown -R stirlingpdfuser:stirlingpdfgroup $HOME /scripts /usr/share/fonts/opentype/noto /configs /customFiles /pipeline /tmp/stirling-pdf && \
|
chown -R stirlingpdfuser:stirlingpdfgroup $HOME /scripts /usr/share/fonts/opentype/noto /configs /customFiles /pipeline /tmp/stirling-pdf && \
|
||||||
|
@ -36,7 +36,7 @@ ENV SETUPTOOLS_USE_DISTUTILS=local \
|
|||||||
# Installation der benötigten Python-Pakete
|
# Installation der benötigten Python-Pakete
|
||||||
RUN python3 -m venv --system-site-packages /opt/venv \
|
RUN python3 -m venv --system-site-packages /opt/venv \
|
||||||
&& . /opt/venv/bin/activate \
|
&& . /opt/venv/bin/activate \
|
||||||
&& pip install --upgrade pip setuptools \
|
&& pip install --no-cache-dir --upgrade pip setuptools \
|
||||||
&& pip install --no-cache-dir WeasyPrint pdf2image pillow unoserver opencv-python-headless pre-commit
|
&& pip install --no-cache-dir WeasyPrint pdf2image pillow unoserver opencv-python-headless pre-commit
|
||||||
|
|
||||||
# Füge den venv-Pfad zur globalen PATH-Variable hinzu, damit die Tools verfügbar sind
|
# Füge den venv-Pfad zur globalen PATH-Variable hinzu, damit die Tools verfügbar sind
|
||||||
@ -54,8 +54,7 @@ RUN echo "devuser ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/devuser \
|
|||||||
# Setze das Arbeitsverzeichnis (wird später per Bind-Mount überschrieben)
|
# Setze das Arbeitsverzeichnis (wird später per Bind-Mount überschrieben)
|
||||||
WORKDIR /workspace
|
WORKDIR /workspace
|
||||||
|
|
||||||
RUN chmod +x /workspace/.devcontainer/git-init.sh
|
RUN chmod +x /workspace/.devcontainer/git-init.sh /workspace/.devcontainer/init-setup.sh
|
||||||
RUN sudo chmod +x /workspace/.devcontainer/init-setup.sh
|
|
||||||
|
|
||||||
# Wechsel zum Nicht‑Root Benutzer
|
# Wechsel zum Nicht‑Root Benutzer
|
||||||
USER devuser
|
USER devuser
|
||||||
|
@ -91,7 +91,7 @@ RUN echo "@main https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/a
|
|||||||
py3-pillow@testing \
|
py3-pillow@testing \
|
||||||
py3-pdf2image@testing && \
|
py3-pdf2image@testing && \
|
||||||
python3 -m venv /opt/venv && \
|
python3 -m venv /opt/venv && \
|
||||||
/opt/venv/bin/pip install --upgrade pip setuptools && \
|
/opt/venv/bin/pip install --no-cache-dir --upgrade pip setuptools && \
|
||||||
/opt/venv/bin/pip install --no-cache-dir --upgrade unoserver weasyprint && \
|
/opt/venv/bin/pip install --no-cache-dir --upgrade unoserver weasyprint && \
|
||||||
ln -s /usr/lib/libreoffice/program/uno.py /opt/venv/lib/python3.12/site-packages/ && \
|
ln -s /usr/lib/libreoffice/program/uno.py /opt/venv/lib/python3.12/site-packages/ && \
|
||||||
ln -s /usr/lib/libreoffice/program/unohelper.py /opt/venv/lib/python3.12/site-packages/ && \
|
ln -s /usr/lib/libreoffice/program/unohelper.py /opt/venv/lib/python3.12/site-packages/ && \
|
||||||
@ -102,7 +102,6 @@ RUN echo "@main https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/a
|
|||||||
ln -s /usr/share/fontconfig/conf.avail/69-urw-*.conf /etc/fonts/conf.d/ && \
|
ln -s /usr/share/fontconfig/conf.avail/69-urw-*.conf /etc/fonts/conf.d/ && \
|
||||||
fc-cache -f -v && \
|
fc-cache -f -v && \
|
||||||
chmod +x /scripts/* && \
|
chmod +x /scripts/* && \
|
||||||
chmod +x /scripts/init.sh && \
|
|
||||||
# User permissions
|
# User permissions
|
||||||
addgroup -S stirlingpdfgroup && adduser -S stirlingpdfuser -G stirlingpdfgroup && \
|
addgroup -S stirlingpdfgroup && adduser -S stirlingpdfuser -G stirlingpdfgroup && \
|
||||||
chown -R stirlingpdfuser:stirlingpdfgroup $HOME /scripts /usr/share/fonts/opentype/noto /configs /customFiles /pipeline /tmp/stirling-pdf && \
|
chown -R stirlingpdfuser:stirlingpdfgroup $HOME /scripts /usr/share/fonts/opentype/noto /configs /customFiles /pipeline /tmp/stirling-pdf && \
|
||||||
|
@ -152,7 +152,7 @@ Stirling-PDF currently supports 40 languages!
|
|||||||
| Swedish (Svenska) (sv_SE) |  |
|
| Swedish (Svenska) (sv_SE) |  |
|
||||||
| Thai (ไทย) (th_TH) |  |
|
| Thai (ไทย) (th_TH) |  |
|
||||||
| Tibetan (བོད་ཡིག་) (bo_CN) |  |
|
| Tibetan (བོད་ཡིག་) (bo_CN) |  |
|
||||||
| Traditional Chinese (繁體中文) (zh_TW) |  |
|
| Traditional Chinese (繁體中文) (zh_TW) |  |
|
||||||
| Turkish (Türkçe) (tr_TR) |  |
|
| Turkish (Türkçe) (tr_TR) |  |
|
||||||
| Ukrainian (Українська) (uk_UA) |  |
|
| Ukrainian (Українська) (uk_UA) |  |
|
||||||
| Vietnamese (Tiếng Việt) (vi_VN) |  |
|
| Vietnamese (Tiếng Việt) (vi_VN) |  |
|
||||||
|
@ -4,7 +4,7 @@ bootRun {
|
|||||||
}
|
}
|
||||||
spotless {
|
spotless {
|
||||||
java {
|
java {
|
||||||
target sourceSets.main.allJava
|
target 'src/**/java/**/*.java'
|
||||||
googleJavaFormat(googleJavaFormatVersion).aosp().reorderImports(false)
|
googleJavaFormat(googleJavaFormatVersion).aosp().reorderImports(false)
|
||||||
|
|
||||||
importOrder("java", "javax", "org", "com", "net", "io", "jakarta", "lombok", "me", "stirling")
|
importOrder("java", "javax", "org", "com", "net", "io", "jakarta", "lombok", "me", "stirling")
|
||||||
@ -13,6 +13,18 @@ spotless {
|
|||||||
leadingTabsToSpaces()
|
leadingTabsToSpaces()
|
||||||
endWithNewline()
|
endWithNewline()
|
||||||
}
|
}
|
||||||
|
yaml {
|
||||||
|
target '**/*.yml', '**/*.yaml'
|
||||||
|
trimTrailingWhitespace()
|
||||||
|
leadingTabsToSpaces()
|
||||||
|
endWithNewline()
|
||||||
|
}
|
||||||
|
format 'gradle', {
|
||||||
|
target '**/gradle/*.gradle', '**/*.gradle'
|
||||||
|
trimTrailingWhitespace()
|
||||||
|
leadingTabsToSpaces()
|
||||||
|
endWithNewline()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
api 'org.springframework.boot:spring-boot-starter-web'
|
api 'org.springframework.boot:spring-boot-starter-web'
|
||||||
|
@ -7,24 +7,19 @@ import static org.mockito.ArgumentMatchers.any;
|
|||||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
import static org.mockito.ArgumentMatchers.anyLong;
|
import static org.mockito.ArgumentMatchers.anyLong;
|
||||||
import static org.mockito.ArgumentMatchers.anyString;
|
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import org.aspectj.lang.ProceedingJoinPoint;
|
import org.aspectj.lang.ProceedingJoinPoint;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.Captor;
|
import org.mockito.Captor;
|
||||||
import org.mockito.InjectMocks;
|
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
@ -45,62 +40,44 @@ class AutoJobPostMappingIntegrationTest {
|
|||||||
|
|
||||||
private AutoJobAspect autoJobAspect;
|
private AutoJobAspect autoJobAspect;
|
||||||
|
|
||||||
@Mock
|
@Mock private JobExecutorService jobExecutorService;
|
||||||
private JobExecutorService jobExecutorService;
|
|
||||||
|
|
||||||
@Mock
|
@Mock private HttpServletRequest request;
|
||||||
private HttpServletRequest request;
|
|
||||||
|
|
||||||
@Mock
|
@Mock private FileOrUploadService fileOrUploadService;
|
||||||
private FileOrUploadService fileOrUploadService;
|
|
||||||
|
|
||||||
@Mock
|
@Mock private FileStorage fileStorage;
|
||||||
private FileStorage fileStorage;
|
|
||||||
|
|
||||||
|
@Mock private ResourceMonitor resourceMonitor;
|
||||||
|
|
||||||
@Mock
|
@Mock private JobQueue jobQueue;
|
||||||
private ResourceMonitor resourceMonitor;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private JobQueue jobQueue;
|
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setUp() {
|
void setUp() {
|
||||||
autoJobAspect = new AutoJobAspect(
|
autoJobAspect =
|
||||||
jobExecutorService,
|
new AutoJobAspect(jobExecutorService, request, fileOrUploadService, fileStorage);
|
||||||
request,
|
|
||||||
fileOrUploadService,
|
|
||||||
fileStorage
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Mock
|
@Mock private ProceedingJoinPoint joinPoint;
|
||||||
private ProceedingJoinPoint joinPoint;
|
|
||||||
|
|
||||||
@Mock
|
@Mock private AutoJobPostMapping autoJobPostMapping;
|
||||||
private AutoJobPostMapping autoJobPostMapping;
|
|
||||||
|
|
||||||
@Captor
|
@Captor private ArgumentCaptor<Supplier<Object>> workCaptor;
|
||||||
private ArgumentCaptor<Supplier<Object>> workCaptor;
|
|
||||||
|
|
||||||
@Captor
|
@Captor private ArgumentCaptor<Boolean> asyncCaptor;
|
||||||
private ArgumentCaptor<Boolean> asyncCaptor;
|
|
||||||
|
|
||||||
@Captor
|
@Captor private ArgumentCaptor<Long> timeoutCaptor;
|
||||||
private ArgumentCaptor<Long> timeoutCaptor;
|
|
||||||
|
|
||||||
@Captor
|
@Captor private ArgumentCaptor<Boolean> queueableCaptor;
|
||||||
private ArgumentCaptor<Boolean> queueableCaptor;
|
|
||||||
|
|
||||||
@Captor
|
@Captor private ArgumentCaptor<Integer> resourceWeightCaptor;
|
||||||
private ArgumentCaptor<Integer> resourceWeightCaptor;
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldExecuteWithCustomParameters() throws Throwable {
|
void shouldExecuteWithCustomParameters() throws Throwable {
|
||||||
// Given
|
// Given
|
||||||
PDFFile pdfFile = new PDFFile();
|
PDFFile pdfFile = new PDFFile();
|
||||||
pdfFile.setFileId("test-file-id");
|
pdfFile.setFileId("test-file-id");
|
||||||
Object[] args = new Object[] { pdfFile };
|
Object[] args = new Object[] {pdfFile};
|
||||||
|
|
||||||
when(joinPoint.getArgs()).thenReturn(args);
|
when(joinPoint.getArgs()).thenReturn(args);
|
||||||
when(request.getParameter("async")).thenReturn("true");
|
when(request.getParameter("async")).thenReturn("true");
|
||||||
@ -113,9 +90,8 @@ class AutoJobPostMappingIntegrationTest {
|
|||||||
MultipartFile mockFile = mock(MultipartFile.class);
|
MultipartFile mockFile = mock(MultipartFile.class);
|
||||||
when(fileStorage.retrieveFile("test-file-id")).thenReturn(mockFile);
|
when(fileStorage.retrieveFile("test-file-id")).thenReturn(mockFile);
|
||||||
|
|
||||||
|
|
||||||
when(jobExecutorService.runJobGeneric(
|
when(jobExecutorService.runJobGeneric(
|
||||||
anyBoolean(), any(Supplier.class), anyLong(), anyBoolean(), anyInt()))
|
anyBoolean(), any(Supplier.class), anyLong(), anyBoolean(), anyInt()))
|
||||||
.thenReturn(ResponseEntity.ok("success"));
|
.thenReturn(ResponseEntity.ok("success"));
|
||||||
|
|
||||||
// When
|
// When
|
||||||
@ -124,12 +100,13 @@ class AutoJobPostMappingIntegrationTest {
|
|||||||
// Then
|
// Then
|
||||||
assertEquals(ResponseEntity.ok("success"), result);
|
assertEquals(ResponseEntity.ok("success"), result);
|
||||||
|
|
||||||
verify(jobExecutorService).runJobGeneric(
|
verify(jobExecutorService)
|
||||||
asyncCaptor.capture(),
|
.runJobGeneric(
|
||||||
workCaptor.capture(),
|
asyncCaptor.capture(),
|
||||||
timeoutCaptor.capture(),
|
workCaptor.capture(),
|
||||||
queueableCaptor.capture(),
|
timeoutCaptor.capture(),
|
||||||
resourceWeightCaptor.capture());
|
queueableCaptor.capture(),
|
||||||
|
resourceWeightCaptor.capture());
|
||||||
|
|
||||||
assertTrue(asyncCaptor.getValue(), "Async should be true");
|
assertTrue(asyncCaptor.getValue(), "Async should be true");
|
||||||
assertEquals(60000L, timeoutCaptor.getValue(), "Timeout should be 60000ms");
|
assertEquals(60000L, timeoutCaptor.getValue(), "Timeout should be 60000ms");
|
||||||
@ -158,11 +135,12 @@ class AutoJobPostMappingIntegrationTest {
|
|||||||
|
|
||||||
// Mock jobExecutorService to execute the work immediately
|
// Mock jobExecutorService to execute the work immediately
|
||||||
when(jobExecutorService.runJobGeneric(
|
when(jobExecutorService.runJobGeneric(
|
||||||
anyBoolean(), any(Supplier.class), anyLong(), anyBoolean(), anyInt()))
|
anyBoolean(), any(Supplier.class), anyLong(), anyBoolean(), anyInt()))
|
||||||
.thenAnswer(invocation -> {
|
.thenAnswer(
|
||||||
Supplier<Object> work = invocation.getArgument(1);
|
invocation -> {
|
||||||
return work.get();
|
Supplier<Object> work = invocation.getArgument(1);
|
||||||
});
|
return work.get();
|
||||||
|
});
|
||||||
|
|
||||||
// When
|
// When
|
||||||
Object result = autoJobAspect.wrapWithJobExecution(joinPoint, autoJobPostMapping);
|
Object result = autoJobAspect.wrapWithJobExecution(joinPoint, autoJobPostMapping);
|
||||||
@ -179,7 +157,7 @@ class AutoJobPostMappingIntegrationTest {
|
|||||||
// Given
|
// Given
|
||||||
PDFFile pdfFile = new PDFFile();
|
PDFFile pdfFile = new PDFFile();
|
||||||
pdfFile.setFileInput(mock(MultipartFile.class));
|
pdfFile.setFileInput(mock(MultipartFile.class));
|
||||||
Object[] args = new Object[] { pdfFile };
|
Object[] args = new Object[] {pdfFile};
|
||||||
|
|
||||||
when(joinPoint.getArgs()).thenReturn(args);
|
when(joinPoint.getArgs()).thenReturn(args);
|
||||||
when(request.getParameter("async")).thenReturn("true");
|
when(request.getParameter("async")).thenReturn("true");
|
||||||
@ -190,14 +168,16 @@ class AutoJobPostMappingIntegrationTest {
|
|||||||
|
|
||||||
// Mock job executor to return a successful response
|
// Mock job executor to return a successful response
|
||||||
when(jobExecutorService.runJobGeneric(
|
when(jobExecutorService.runJobGeneric(
|
||||||
anyBoolean(), any(Supplier.class), anyLong(), anyBoolean(), anyInt()))
|
anyBoolean(), any(Supplier.class), anyLong(), anyBoolean(), anyInt()))
|
||||||
.thenReturn(ResponseEntity.ok("success"));
|
.thenReturn(ResponseEntity.ok("success"));
|
||||||
|
|
||||||
// When
|
// When
|
||||||
autoJobAspect.wrapWithJobExecution(joinPoint, autoJobPostMapping);
|
autoJobAspect.wrapWithJobExecution(joinPoint, autoJobPostMapping);
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
assertEquals("stored-file-id", pdfFile.getFileId(),
|
assertEquals(
|
||||||
|
"stored-file-id",
|
||||||
|
pdfFile.getFileId(),
|
||||||
"FileId should be set to the stored file id");
|
"FileId should be set to the stored file id");
|
||||||
assertNotNull(pdfFile.getFileInput(), "FileInput should be replaced with persistent file");
|
assertNotNull(pdfFile.getFileInput(), "FileInput should be replaced with persistent file");
|
||||||
|
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
package stirling.software.common.service;
|
package stirling.software.common.service;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
import static org.mockito.Mockito.*;
|
|
||||||
import static org.mockito.AdditionalAnswers.*;
|
import static org.mockito.AdditionalAnswers.*;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
@ -21,14 +20,11 @@ import org.springframework.web.multipart.MultipartFile;
|
|||||||
|
|
||||||
class FileStorageTest {
|
class FileStorageTest {
|
||||||
|
|
||||||
@TempDir
|
@TempDir Path tempDir;
|
||||||
Path tempDir;
|
|
||||||
|
|
||||||
@Mock
|
@Mock private FileOrUploadService fileOrUploadService;
|
||||||
private FileOrUploadService fileOrUploadService;
|
|
||||||
|
|
||||||
@InjectMocks
|
@InjectMocks private FileStorage fileStorage;
|
||||||
private FileStorage fileStorage;
|
|
||||||
|
|
||||||
private MultipartFile mockFile;
|
private MultipartFile mockFile;
|
||||||
|
|
||||||
@ -50,11 +46,14 @@ class FileStorageTest {
|
|||||||
when(mockFile.getBytes()).thenReturn(fileContent);
|
when(mockFile.getBytes()).thenReturn(fileContent);
|
||||||
|
|
||||||
// Set up mock to handle transferTo by writing the file
|
// Set up mock to handle transferTo by writing the file
|
||||||
doAnswer(invocation -> {
|
doAnswer(
|
||||||
java.io.File file = invocation.getArgument(0);
|
invocation -> {
|
||||||
Files.write(file.toPath(), fileContent);
|
java.io.File file = invocation.getArgument(0);
|
||||||
return null;
|
Files.write(file.toPath(), fileContent);
|
||||||
}).when(mockFile).transferTo(any(java.io.File.class));
|
return null;
|
||||||
|
})
|
||||||
|
.when(mockFile)
|
||||||
|
.transferTo(any(java.io.File.class));
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
String fileId = fileStorage.storeFile(mockFile);
|
String fileId = fileStorage.storeFile(mockFile);
|
||||||
@ -90,7 +89,7 @@ class FileStorageTest {
|
|||||||
|
|
||||||
MultipartFile expectedFile = mock(MultipartFile.class);
|
MultipartFile expectedFile = mock(MultipartFile.class);
|
||||||
when(fileOrUploadService.toMockMultipartFile(eq(fileId), eq(fileContent)))
|
when(fileOrUploadService.toMockMultipartFile(eq(fileId), eq(fileContent)))
|
||||||
.thenReturn(expectedFile);
|
.thenReturn(expectedFile);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
MultipartFile result = fileStorage.retrieveFile(fileId);
|
MultipartFile result = fileStorage.retrieveFile(fileId);
|
||||||
|
@ -4,14 +4,9 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
|||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
|
||||||
import static org.mockito.ArgumentMatchers.anyLong;
|
import static org.mockito.ArgumentMatchers.anyLong;
|
||||||
import static org.mockito.ArgumentMatchers.anyString;
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.doAnswer;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.never;
|
|
||||||
import static org.mockito.Mockito.times;
|
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
@ -30,11 +25,9 @@ import org.mockito.Mockito;
|
|||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.test.util.ReflectionTestUtils;
|
|
||||||
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import stirling.software.common.model.job.JobProgress;
|
|
||||||
import stirling.software.common.model.job.JobResponse;
|
import stirling.software.common.model.job.JobResponse;
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
@ -42,36 +35,31 @@ class JobExecutorServiceTest {
|
|||||||
|
|
||||||
private JobExecutorService jobExecutorService;
|
private JobExecutorService jobExecutorService;
|
||||||
|
|
||||||
@Mock
|
@Mock private TaskManager taskManager;
|
||||||
private TaskManager taskManager;
|
|
||||||
|
|
||||||
@Mock
|
@Mock private FileStorage fileStorage;
|
||||||
private FileStorage fileStorage;
|
|
||||||
|
|
||||||
@Mock
|
@Mock private HttpServletRequest request;
|
||||||
private HttpServletRequest request;
|
|
||||||
|
|
||||||
@Mock
|
@Mock private ResourceMonitor resourceMonitor;
|
||||||
private ResourceMonitor resourceMonitor;
|
|
||||||
|
|
||||||
@Mock
|
@Mock private JobQueue jobQueue;
|
||||||
private JobQueue jobQueue;
|
|
||||||
|
|
||||||
@Captor
|
@Captor private ArgumentCaptor<String> jobIdCaptor;
|
||||||
private ArgumentCaptor<String> jobIdCaptor;
|
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setUp() {
|
void setUp() {
|
||||||
// Initialize the service manually with all its dependencies
|
// Initialize the service manually with all its dependencies
|
||||||
jobExecutorService = new JobExecutorService(
|
jobExecutorService =
|
||||||
taskManager,
|
new JobExecutorService(
|
||||||
fileStorage,
|
taskManager,
|
||||||
request,
|
fileStorage,
|
||||||
resourceMonitor,
|
request,
|
||||||
jobQueue,
|
resourceMonitor,
|
||||||
30000L, // asyncRequestTimeoutMs
|
jobQueue,
|
||||||
"30m" // sessionTimeout
|
30000L, // asyncRequestTimeoutMs
|
||||||
);
|
"30m" // sessionTimeout
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -109,13 +97,13 @@ class JobExecutorServiceTest {
|
|||||||
verify(taskManager).createTask(jobIdCaptor.capture());
|
verify(taskManager).createTask(jobIdCaptor.capture());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldHandleSyncJobError() {
|
void shouldHandleSyncJobError() {
|
||||||
// Given
|
// Given
|
||||||
Supplier<Object> work = () -> {
|
Supplier<Object> work =
|
||||||
throw new RuntimeException("Test error");
|
() -> {
|
||||||
};
|
throw new RuntimeException("Test error");
|
||||||
|
};
|
||||||
|
|
||||||
// When
|
// When
|
||||||
ResponseEntity<?> response = jobExecutorService.runJobGeneric(false, work);
|
ResponseEntity<?> response = jobExecutorService.runJobGeneric(false, work);
|
||||||
@ -141,8 +129,7 @@ class JobExecutorServiceTest {
|
|||||||
when(jobQueue.queueJob(anyString(), eq(80), any(), anyLong())).thenReturn(future);
|
when(jobQueue.queueJob(anyString(), eq(80), any(), anyLong())).thenReturn(future);
|
||||||
|
|
||||||
// When
|
// When
|
||||||
ResponseEntity<?> response = jobExecutorService.runJobGeneric(
|
ResponseEntity<?> response = jobExecutorService.runJobGeneric(true, work, 5000, true, 80);
|
||||||
true, work, 5000, true, 80);
|
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
@ -160,8 +147,9 @@ class JobExecutorServiceTest {
|
|||||||
long customTimeout = 60000L;
|
long customTimeout = 60000L;
|
||||||
|
|
||||||
// Use reflection to access the private executeWithTimeout method
|
// Use reflection to access the private executeWithTimeout method
|
||||||
java.lang.reflect.Method executeMethod = JobExecutorService.class
|
java.lang.reflect.Method executeMethod =
|
||||||
.getDeclaredMethod("executeWithTimeout", Supplier.class, long.class);
|
JobExecutorService.class.getDeclaredMethod(
|
||||||
|
"executeWithTimeout", Supplier.class, long.class);
|
||||||
executeMethod.setAccessible(true);
|
executeMethod.setAccessible(true);
|
||||||
|
|
||||||
// Create a spy on the JobExecutorService to verify method calls
|
// Create a spy on the JobExecutorService to verify method calls
|
||||||
@ -177,19 +165,21 @@ class JobExecutorServiceTest {
|
|||||||
@Test
|
@Test
|
||||||
void shouldHandleTimeout() throws Exception {
|
void shouldHandleTimeout() throws Exception {
|
||||||
// Given
|
// Given
|
||||||
Supplier<Object> work = () -> {
|
Supplier<Object> work =
|
||||||
try {
|
() -> {
|
||||||
Thread.sleep(100); // Simulate long-running job
|
try {
|
||||||
return "test-result";
|
Thread.sleep(100); // Simulate long-running job
|
||||||
} catch (InterruptedException e) {
|
return "test-result";
|
||||||
Thread.currentThread().interrupt();
|
} catch (InterruptedException e) {
|
||||||
throw new RuntimeException(e);
|
Thread.currentThread().interrupt();
|
||||||
}
|
throw new RuntimeException(e);
|
||||||
};
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Use reflection to access the private executeWithTimeout method
|
// Use reflection to access the private executeWithTimeout method
|
||||||
java.lang.reflect.Method executeMethod = JobExecutorService.class
|
java.lang.reflect.Method executeMethod =
|
||||||
.getDeclaredMethod("executeWithTimeout", Supplier.class, long.class);
|
JobExecutorService.class.getDeclaredMethod(
|
||||||
|
"executeWithTimeout", Supplier.class, long.class);
|
||||||
executeMethod.setAccessible(true);
|
executeMethod.setAccessible(true);
|
||||||
|
|
||||||
// When/Then
|
// When/Then
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
package stirling.software.common.service;
|
package stirling.software.common.service;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
import static org.mockito.Mockito.lenient;
|
import static org.mockito.Mockito.lenient;
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -17,7 +15,6 @@ import org.junit.jupiter.api.extension.ExtendWith;
|
|||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
import stirling.software.common.model.job.JobProgress;
|
|
||||||
import stirling.software.common.service.ResourceMonitor.ResourceStatus;
|
import stirling.software.common.service.ResourceMonitor.ResourceStatus;
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
@ -25,16 +22,17 @@ class JobQueueTest {
|
|||||||
|
|
||||||
private JobQueue jobQueue;
|
private JobQueue jobQueue;
|
||||||
|
|
||||||
@Mock
|
@Mock private ResourceMonitor resourceMonitor;
|
||||||
private ResourceMonitor resourceMonitor;
|
|
||||||
|
|
||||||
|
private final AtomicReference<ResourceStatus> statusRef =
|
||||||
private final AtomicReference<ResourceStatus> statusRef = new AtomicReference<>(ResourceStatus.OK);
|
new AtomicReference<>(ResourceStatus.OK);
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setUp() {
|
void setUp() {
|
||||||
// Mark stubbing as lenient to avoid UnnecessaryStubbingException
|
// Mark stubbing as lenient to avoid UnnecessaryStubbingException
|
||||||
lenient().when(resourceMonitor.calculateDynamicQueueCapacity(anyInt(), anyInt())).thenReturn(10);
|
lenient()
|
||||||
|
.when(resourceMonitor.calculateDynamicQueueCapacity(anyInt(), anyInt()))
|
||||||
|
.thenReturn(10);
|
||||||
lenient().when(resourceMonitor.getCurrentStatus()).thenReturn(statusRef);
|
lenient().when(resourceMonitor.getCurrentStatus()).thenReturn(statusRef);
|
||||||
|
|
||||||
// Initialize JobQueue with mocked ResourceMonitor
|
// Initialize JobQueue with mocked ResourceMonitor
|
||||||
@ -50,7 +48,6 @@ class JobQueueTest {
|
|||||||
|
|
||||||
jobQueue.queueJob(jobId, resourceWeight, work, timeoutMs);
|
jobQueue.queueJob(jobId, resourceWeight, work, timeoutMs);
|
||||||
|
|
||||||
|
|
||||||
assertTrue(jobQueue.isJobQueued(jobId));
|
assertTrue(jobQueue.isJobQueued(jobId));
|
||||||
assertEquals(1, jobQueue.getTotalQueuedJobs());
|
assertEquals(1, jobQueue.getTotalQueuedJobs());
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,10 @@
|
|||||||
package stirling.software.common.service;
|
package stirling.software.common.service;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import java.lang.management.MemoryMXBean;
|
import java.lang.management.MemoryMXBean;
|
||||||
import java.lang.management.MemoryUsage;
|
|
||||||
import java.lang.management.OperatingSystemMXBean;
|
import java.lang.management.OperatingSystemMXBean;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
@ -30,20 +26,19 @@ import stirling.software.common.service.ResourceMonitor.ResourceStatus;
|
|||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class ResourceMonitorTest {
|
class ResourceMonitorTest {
|
||||||
|
|
||||||
@InjectMocks
|
@InjectMocks private ResourceMonitor resourceMonitor;
|
||||||
private ResourceMonitor resourceMonitor;
|
|
||||||
|
|
||||||
@Mock
|
@Mock private OperatingSystemMXBean osMXBean;
|
||||||
private OperatingSystemMXBean osMXBean;
|
|
||||||
|
|
||||||
@Mock
|
@Mock private MemoryMXBean memoryMXBean;
|
||||||
private MemoryMXBean memoryMXBean;
|
|
||||||
|
|
||||||
@Spy
|
@Spy
|
||||||
private AtomicReference<ResourceStatus> currentStatus = new AtomicReference<>(ResourceStatus.OK);
|
private AtomicReference<ResourceStatus> currentStatus =
|
||||||
|
new AtomicReference<>(ResourceStatus.OK);
|
||||||
|
|
||||||
@Spy
|
@Spy
|
||||||
private AtomicReference<ResourceMetrics> latestMetrics = new AtomicReference<>(new ResourceMetrics());
|
private AtomicReference<ResourceMetrics> latestMetrics =
|
||||||
|
new AtomicReference<>(new ResourceMetrics());
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setUp() {
|
void setUp() {
|
||||||
@ -92,23 +87,26 @@ class ResourceMonitorTest {
|
|||||||
assertEquals(3, capacity, "With CRITICAL status, capacity should be reduced to 30%");
|
assertEquals(3, capacity, "With CRITICAL status, capacity should be reduced to 30%");
|
||||||
|
|
||||||
// Test minimum capacity enforcement
|
// Test minimum capacity enforcement
|
||||||
assertEquals(minCapacity, resourceMonitor.calculateDynamicQueueCapacity(1, minCapacity),
|
assertEquals(
|
||||||
|
minCapacity,
|
||||||
|
resourceMonitor.calculateDynamicQueueCapacity(1, minCapacity),
|
||||||
"Should never go below minimum capacity");
|
"Should never go below minimum capacity");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
@CsvSource({
|
@CsvSource({
|
||||||
"10, OK, false", // Light job, OK status
|
"10, OK, false", // Light job, OK status
|
||||||
"10, WARNING, false", // Light job, WARNING status
|
"10, WARNING, false", // Light job, WARNING status
|
||||||
"10, CRITICAL, true", // Light job, CRITICAL status
|
"10, CRITICAL, true", // Light job, CRITICAL status
|
||||||
"30, OK, false", // Medium job, OK status
|
"30, OK, false", // Medium job, OK status
|
||||||
"30, WARNING, true", // Medium job, WARNING status
|
"30, WARNING, true", // Medium job, WARNING status
|
||||||
"30, CRITICAL, true", // Medium job, CRITICAL status
|
"30, CRITICAL, true", // Medium job, CRITICAL status
|
||||||
"80, OK, true", // Heavy job, OK status
|
"80, OK, true", // Heavy job, OK status
|
||||||
"80, WARNING, true", // Heavy job, WARNING status
|
"80, WARNING, true", // Heavy job, WARNING status
|
||||||
"80, CRITICAL, true" // Heavy job, CRITICAL status
|
"80, CRITICAL, true" // Heavy job, CRITICAL status
|
||||||
})
|
})
|
||||||
void shouldQueueJobBasedOnWeightAndStatus(int weight, ResourceStatus status, boolean shouldQueue) {
|
void shouldQueueJobBasedOnWeightAndStatus(
|
||||||
|
int weight, ResourceStatus status, boolean shouldQueue) {
|
||||||
// Given
|
// Given
|
||||||
currentStatus.set(status);
|
currentStatus.set(status);
|
||||||
|
|
||||||
@ -116,8 +114,11 @@ class ResourceMonitorTest {
|
|||||||
boolean result = resourceMonitor.shouldQueueJob(weight);
|
boolean result = resourceMonitor.shouldQueueJob(weight);
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
assertEquals(shouldQueue, result,
|
assertEquals(
|
||||||
String.format("For weight %d and status %s, shouldQueue should be %s",
|
shouldQueue,
|
||||||
|
result,
|
||||||
|
String.format(
|
||||||
|
"For weight %d and status %s, shouldQueue should be %s",
|
||||||
weight, status, shouldQueue));
|
weight, status, shouldQueue));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,7 +132,9 @@ class ResourceMonitorTest {
|
|||||||
ResourceMetrics freshMetrics = new ResourceMetrics(0.5, 0.5, 1024, 2048, 4096, now);
|
ResourceMetrics freshMetrics = new ResourceMetrics(0.5, 0.5, 1024, 2048, 4096, now);
|
||||||
|
|
||||||
// When/Then
|
// When/Then
|
||||||
assertTrue(staleMetrics.isStale(5000), "Metrics from 6 seconds ago should be stale with 5s threshold");
|
assertTrue(
|
||||||
|
staleMetrics.isStale(5000),
|
||||||
|
"Metrics from 6 seconds ago should be stale with 5s threshold");
|
||||||
assertFalse(freshMetrics.isStale(5000), "Fresh metrics should not be stale");
|
assertFalse(freshMetrics.isStale(5000), "Fresh metrics should not be stale");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ import static org.mockito.Mockito.*;
|
|||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
@ -22,11 +21,9 @@ import stirling.software.common.model.job.ResultFile;
|
|||||||
|
|
||||||
class TaskManagerTest {
|
class TaskManagerTest {
|
||||||
|
|
||||||
@Mock
|
@Mock private FileStorage fileStorage;
|
||||||
private FileStorage fileStorage;
|
|
||||||
|
|
||||||
@InjectMocks
|
@InjectMocks private TaskManager taskManager;
|
||||||
private TaskManager taskManager;
|
|
||||||
|
|
||||||
private AutoCloseable closeable;
|
private AutoCloseable closeable;
|
||||||
|
|
||||||
@ -234,18 +231,20 @@ class TaskManagerTest {
|
|||||||
ReflectionTestUtils.setField(oldJob, "complete", true);
|
ReflectionTestUtils.setField(oldJob, "complete", true);
|
||||||
|
|
||||||
// Create a ResultFile and set it using the new approach
|
// Create a ResultFile and set it using the new approach
|
||||||
ResultFile resultFile = ResultFile.builder()
|
ResultFile resultFile =
|
||||||
.fileId("file-id")
|
ResultFile.builder()
|
||||||
.fileName("test.pdf")
|
.fileId("file-id")
|
||||||
.contentType("application/pdf")
|
.fileName("test.pdf")
|
||||||
.fileSize(1024L)
|
.contentType("application/pdf")
|
||||||
.build();
|
.fileSize(1024L)
|
||||||
|
.build();
|
||||||
ReflectionTestUtils.setField(oldJob, "resultFiles", java.util.List.of(resultFile));
|
ReflectionTestUtils.setField(oldJob, "resultFiles", java.util.List.of(resultFile));
|
||||||
|
|
||||||
when(fileStorage.deleteFile("file-id")).thenReturn(true);
|
when(fileStorage.deleteFile("file-id")).thenReturn(true);
|
||||||
|
|
||||||
// Obtain access to the private jobResults map
|
// Obtain access to the private jobResults map
|
||||||
Map<String, JobResult> jobResultsMap = (Map<String, JobResult>) ReflectionTestUtils.getField(taskManager, "jobResults");
|
Map<String, JobResult> jobResultsMap =
|
||||||
|
(Map<String, JobResult>) ReflectionTestUtils.getField(taskManager, "jobResults");
|
||||||
|
|
||||||
// 3. Create an active job
|
// 3. Create an active job
|
||||||
String activeJobId = "active-job";
|
String activeJobId = "active-job";
|
||||||
|
@ -12,7 +12,6 @@ import java.nio.file.Path;
|
|||||||
import java.nio.file.attribute.FileTime;
|
import java.nio.file.attribute.FileTime;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
@ -30,31 +29,22 @@ import stirling.software.common.model.ApplicationProperties;
|
|||||||
import stirling.software.common.util.TempFileManager;
|
import stirling.software.common.util.TempFileManager;
|
||||||
import stirling.software.common.util.TempFileRegistry;
|
import stirling.software.common.util.TempFileRegistry;
|
||||||
|
|
||||||
/**
|
/** Tests for the TempFileCleanupService, focusing on its pattern-matching and cleanup logic. */
|
||||||
* Tests for the TempFileCleanupService, focusing on its pattern-matching and cleanup logic.
|
|
||||||
*/
|
|
||||||
public class TempFileCleanupServiceTest {
|
public class TempFileCleanupServiceTest {
|
||||||
|
|
||||||
@TempDir
|
@TempDir Path tempDir;
|
||||||
Path tempDir;
|
|
||||||
|
|
||||||
@Mock
|
@Mock private TempFileRegistry registry;
|
||||||
private TempFileRegistry registry;
|
|
||||||
|
|
||||||
@Mock
|
@Mock private TempFileManager tempFileManager;
|
||||||
private TempFileManager tempFileManager;
|
|
||||||
|
|
||||||
@Mock
|
@Mock private ApplicationProperties applicationProperties;
|
||||||
private ApplicationProperties applicationProperties;
|
|
||||||
|
|
||||||
@Mock
|
@Mock private ApplicationProperties.System system;
|
||||||
private ApplicationProperties.System system;
|
|
||||||
|
|
||||||
@Mock
|
@Mock private ApplicationProperties.TempFileManagement tempFileManagement;
|
||||||
private ApplicationProperties.TempFileManagement tempFileManagement;
|
|
||||||
|
|
||||||
@InjectMocks
|
@InjectMocks private TempFileCleanupService cleanupService;
|
||||||
private TempFileCleanupService cleanupService;
|
|
||||||
|
|
||||||
private Path systemTempDir;
|
private Path systemTempDir;
|
||||||
private Path customTempDir;
|
private Path customTempDir;
|
||||||
@ -124,7 +114,8 @@ public class TempFileCleanupServiceTest {
|
|||||||
|
|
||||||
// Files that should be preserved
|
// Files that should be preserved
|
||||||
Path jettyFile1 = Files.createFile(systemTempDir.resolve("jetty-123.tmp"));
|
Path jettyFile1 = Files.createFile(systemTempDir.resolve("jetty-123.tmp"));
|
||||||
Path jettyFile2 = Files.createFile(systemTempDir.resolve("something-with-jetty-inside.tmp"));
|
Path jettyFile2 =
|
||||||
|
Files.createFile(systemTempDir.resolve("something-with-jetty-inside.tmp"));
|
||||||
Path regularFile = Files.createFile(systemTempDir.resolve("important.txt"));
|
Path regularFile = Files.createFile(systemTempDir.resolve("important.txt"));
|
||||||
|
|
||||||
// Create a nested directory with temp files
|
// Create a nested directory with temp files
|
||||||
@ -143,19 +134,29 @@ public class TempFileCleanupServiceTest {
|
|||||||
// Use MockedStatic to mock Files operations
|
// Use MockedStatic to mock Files operations
|
||||||
try (MockedStatic<Files> mockedFiles = mockStatic(Files.class)) {
|
try (MockedStatic<Files> mockedFiles = mockStatic(Files.class)) {
|
||||||
// Mock Files.list for each directory we'll process
|
// Mock Files.list for each directory we'll process
|
||||||
mockedFiles.when(() -> Files.list(eq(systemTempDir)))
|
mockedFiles
|
||||||
.thenReturn(Stream.of(
|
.when(() -> Files.list(eq(systemTempDir)))
|
||||||
ourTempFile1, ourTempFile2, oldTempFile, sysTempFile1,
|
.thenReturn(
|
||||||
jettyFile1, jettyFile2, regularFile, emptyFile, nestedDir));
|
Stream.of(
|
||||||
|
ourTempFile1,
|
||||||
|
ourTempFile2,
|
||||||
|
oldTempFile,
|
||||||
|
sysTempFile1,
|
||||||
|
jettyFile1,
|
||||||
|
jettyFile2,
|
||||||
|
regularFile,
|
||||||
|
emptyFile,
|
||||||
|
nestedDir));
|
||||||
|
|
||||||
mockedFiles.when(() -> Files.list(eq(customTempDir)))
|
mockedFiles
|
||||||
|
.when(() -> Files.list(eq(customTempDir)))
|
||||||
.thenReturn(Stream.of(ourTempFile3, ourTempFile4, sysTempFile2, sysTempFile3));
|
.thenReturn(Stream.of(ourTempFile3, ourTempFile4, sysTempFile2, sysTempFile3));
|
||||||
|
|
||||||
mockedFiles.when(() -> Files.list(eq(libreOfficeTempDir)))
|
mockedFiles
|
||||||
|
.when(() -> Files.list(eq(libreOfficeTempDir)))
|
||||||
.thenReturn(Stream.of(ourTempFile5));
|
.thenReturn(Stream.of(ourTempFile5));
|
||||||
|
|
||||||
mockedFiles.when(() -> Files.list(eq(nestedDir)))
|
mockedFiles.when(() -> Files.list(eq(nestedDir))).thenReturn(Stream.of(nestedTempFile));
|
||||||
.thenReturn(Stream.of(nestedTempFile));
|
|
||||||
|
|
||||||
// Configure Files.isDirectory for each path
|
// Configure Files.isDirectory for each path
|
||||||
mockedFiles.when(() -> Files.isDirectory(eq(nestedDir))).thenReturn(true);
|
mockedFiles.when(() -> Files.isDirectory(eq(nestedDir))).thenReturn(true);
|
||||||
@ -165,48 +166,59 @@ public class TempFileCleanupServiceTest {
|
|||||||
mockedFiles.when(() -> Files.exists(any(Path.class))).thenReturn(true);
|
mockedFiles.when(() -> Files.exists(any(Path.class))).thenReturn(true);
|
||||||
|
|
||||||
// Configure Files.getLastModifiedTime to return different times based on file names
|
// Configure Files.getLastModifiedTime to return different times based on file names
|
||||||
mockedFiles.when(() -> Files.getLastModifiedTime(any(Path.class)))
|
mockedFiles
|
||||||
.thenAnswer(invocation -> {
|
.when(() -> Files.getLastModifiedTime(any(Path.class)))
|
||||||
Path path = invocation.getArgument(0);
|
.thenAnswer(
|
||||||
String fileName = path.getFileName().toString();
|
invocation -> {
|
||||||
|
Path path = invocation.getArgument(0);
|
||||||
|
String fileName = path.getFileName().toString();
|
||||||
|
|
||||||
// For files with "old" in the name, return a timestamp older than maxAgeMillis
|
// For files with "old" in the name, return a timestamp older than
|
||||||
if (fileName.contains("old")) {
|
// maxAgeMillis
|
||||||
return FileTime.fromMillis(System.currentTimeMillis() - 5000000);
|
if (fileName.contains("old")) {
|
||||||
}
|
return FileTime.fromMillis(
|
||||||
// For empty.tmp file, return a timestamp older than 5 minutes (for empty file test)
|
System.currentTimeMillis() - 5000000);
|
||||||
else if (fileName.equals("empty.tmp")) {
|
}
|
||||||
return FileTime.fromMillis(System.currentTimeMillis() - 6 * 60 * 1000);
|
// For empty.tmp file, return a timestamp older than 5 minutes (for
|
||||||
}
|
// empty file test)
|
||||||
// For all other files, return a recent timestamp
|
else if (fileName.equals("empty.tmp")) {
|
||||||
else {
|
return FileTime.fromMillis(
|
||||||
return FileTime.fromMillis(System.currentTimeMillis() - 60000); // 1 minute ago
|
System.currentTimeMillis() - 6 * 60 * 1000);
|
||||||
}
|
}
|
||||||
});
|
// For all other files, return a recent timestamp
|
||||||
|
else {
|
||||||
|
return FileTime.fromMillis(
|
||||||
|
System.currentTimeMillis() - 60000); // 1 minute ago
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Configure Files.size to return different sizes based on file names
|
// Configure Files.size to return different sizes based on file names
|
||||||
mockedFiles.when(() -> Files.size(any(Path.class)))
|
mockedFiles
|
||||||
.thenAnswer(invocation -> {
|
.when(() -> Files.size(any(Path.class)))
|
||||||
Path path = invocation.getArgument(0);
|
.thenAnswer(
|
||||||
String fileName = path.getFileName().toString();
|
invocation -> {
|
||||||
|
Path path = invocation.getArgument(0);
|
||||||
|
String fileName = path.getFileName().toString();
|
||||||
|
|
||||||
// Return 0 bytes for the empty file
|
// Return 0 bytes for the empty file
|
||||||
if (fileName.equals("empty.tmp")) {
|
if (fileName.equals("empty.tmp")) {
|
||||||
return 0L;
|
return 0L;
|
||||||
}
|
}
|
||||||
// Return normal size for all other files
|
// Return normal size for all other files
|
||||||
else {
|
else {
|
||||||
return 1024L; // 1 KB
|
return 1024L; // 1 KB
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// For deleteIfExists, track which files would be deleted
|
// For deleteIfExists, track which files would be deleted
|
||||||
mockedFiles.when(() -> Files.deleteIfExists(any(Path.class)))
|
mockedFiles
|
||||||
.thenAnswer(invocation -> {
|
.when(() -> Files.deleteIfExists(any(Path.class)))
|
||||||
Path path = invocation.getArgument(0);
|
.thenAnswer(
|
||||||
deletedFiles.add(path);
|
invocation -> {
|
||||||
return true;
|
Path path = invocation.getArgument(0);
|
||||||
});
|
deletedFiles.add(path);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
// Act - set containerMode to false for this test
|
// Act - set containerMode to false for this test
|
||||||
invokeCleanupDirectoryStreaming(systemTempDir, false, 0, 3600000);
|
invokeCleanupDirectoryStreaming(systemTempDir, false, 0, 3600000);
|
||||||
@ -218,20 +230,33 @@ public class TempFileCleanupServiceTest {
|
|||||||
assertTrue(deletedFiles.contains(emptyFile), "Empty file should be deleted");
|
assertTrue(deletedFiles.contains(emptyFile), "Empty file should be deleted");
|
||||||
|
|
||||||
// Regular temp files should not be deleted because they're too new
|
// Regular temp files should not be deleted because they're too new
|
||||||
assertFalse(deletedFiles.contains(ourTempFile1), "Recent temp file should be preserved");
|
assertFalse(
|
||||||
assertFalse(deletedFiles.contains(ourTempFile2), "Recent temp file should be preserved");
|
deletedFiles.contains(ourTempFile1), "Recent temp file should be preserved");
|
||||||
assertFalse(deletedFiles.contains(ourTempFile3), "Recent temp file should be preserved");
|
assertFalse(
|
||||||
assertFalse(deletedFiles.contains(ourTempFile4), "Recent temp file should be preserved");
|
deletedFiles.contains(ourTempFile2), "Recent temp file should be preserved");
|
||||||
assertFalse(deletedFiles.contains(ourTempFile5), "Recent temp file should be preserved");
|
assertFalse(
|
||||||
|
deletedFiles.contains(ourTempFile3), "Recent temp file should be preserved");
|
||||||
|
assertFalse(
|
||||||
|
deletedFiles.contains(ourTempFile4), "Recent temp file should be preserved");
|
||||||
|
assertFalse(
|
||||||
|
deletedFiles.contains(ourTempFile5), "Recent temp file should be preserved");
|
||||||
|
|
||||||
// System temp files should not be deleted in non-container mode
|
// System temp files should not be deleted in non-container mode
|
||||||
assertFalse(deletedFiles.contains(sysTempFile1), "System temp file should be preserved in non-container mode");
|
assertFalse(
|
||||||
assertFalse(deletedFiles.contains(sysTempFile2), "System temp file should be preserved in non-container mode");
|
deletedFiles.contains(sysTempFile1),
|
||||||
assertFalse(deletedFiles.contains(sysTempFile3), "System temp file should be preserved in non-container mode");
|
"System temp file should be preserved in non-container mode");
|
||||||
|
assertFalse(
|
||||||
|
deletedFiles.contains(sysTempFile2),
|
||||||
|
"System temp file should be preserved in non-container mode");
|
||||||
|
assertFalse(
|
||||||
|
deletedFiles.contains(sysTempFile3),
|
||||||
|
"System temp file should be preserved in non-container mode");
|
||||||
|
|
||||||
// Jetty files and regular files should never be deleted
|
// Jetty files and regular files should never be deleted
|
||||||
assertFalse(deletedFiles.contains(jettyFile1), "Jetty file should be preserved");
|
assertFalse(deletedFiles.contains(jettyFile1), "Jetty file should be preserved");
|
||||||
assertFalse(deletedFiles.contains(jettyFile2), "File with jetty in name should be preserved");
|
assertFalse(
|
||||||
|
deletedFiles.contains(jettyFile2),
|
||||||
|
"File with jetty in name should be preserved");
|
||||||
assertFalse(deletedFiles.contains(regularFile), "Regular file should be preserved");
|
assertFalse(deletedFiles.contains(regularFile), "Regular file should be preserved");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -252,7 +277,8 @@ public class TempFileCleanupServiceTest {
|
|||||||
// Use MockedStatic to mock Files operations
|
// Use MockedStatic to mock Files operations
|
||||||
try (MockedStatic<Files> mockedFiles = mockStatic(Files.class)) {
|
try (MockedStatic<Files> mockedFiles = mockStatic(Files.class)) {
|
||||||
// Mock Files.list for systemTempDir
|
// Mock Files.list for systemTempDir
|
||||||
mockedFiles.when(() -> Files.list(eq(systemTempDir)))
|
mockedFiles
|
||||||
|
.when(() -> Files.list(eq(systemTempDir)))
|
||||||
.thenReturn(Stream.of(ourTempFile, sysTempFile, regularFile));
|
.thenReturn(Stream.of(ourTempFile, sysTempFile, regularFile));
|
||||||
|
|
||||||
// Configure Files.isDirectory
|
// Configure Files.isDirectory
|
||||||
@ -262,28 +288,37 @@ public class TempFileCleanupServiceTest {
|
|||||||
mockedFiles.when(() -> Files.exists(any(Path.class))).thenReturn(true);
|
mockedFiles.when(() -> Files.exists(any(Path.class))).thenReturn(true);
|
||||||
|
|
||||||
// Configure Files.getLastModifiedTime to return recent timestamps
|
// Configure Files.getLastModifiedTime to return recent timestamps
|
||||||
mockedFiles.when(() -> Files.getLastModifiedTime(any(Path.class)))
|
mockedFiles
|
||||||
.thenReturn(FileTime.fromMillis(System.currentTimeMillis() - 60000)); // 1 minute ago
|
.when(() -> Files.getLastModifiedTime(any(Path.class)))
|
||||||
|
.thenReturn(
|
||||||
|
FileTime.fromMillis(
|
||||||
|
System.currentTimeMillis() - 60000)); // 1 minute ago
|
||||||
|
|
||||||
// Configure Files.size to return normal size
|
// Configure Files.size to return normal size
|
||||||
mockedFiles.when(() -> Files.size(any(Path.class)))
|
mockedFiles.when(() -> Files.size(any(Path.class))).thenReturn(1024L); // 1 KB
|
||||||
.thenReturn(1024L); // 1 KB
|
|
||||||
|
|
||||||
// For deleteIfExists, track which files would be deleted
|
// For deleteIfExists, track which files would be deleted
|
||||||
mockedFiles.when(() -> Files.deleteIfExists(any(Path.class)))
|
mockedFiles
|
||||||
.thenAnswer(invocation -> {
|
.when(() -> Files.deleteIfExists(any(Path.class)))
|
||||||
Path path = invocation.getArgument(0);
|
.thenAnswer(
|
||||||
deletedFiles.add(path);
|
invocation -> {
|
||||||
return true;
|
Path path = invocation.getArgument(0);
|
||||||
});
|
deletedFiles.add(path);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
// Act - set containerMode to true and maxAgeMillis to 0 for container startup cleanup
|
// Act - set containerMode to true and maxAgeMillis to 0 for container startup cleanup
|
||||||
invokeCleanupDirectoryStreaming(systemTempDir, true, 0, 0);
|
invokeCleanupDirectoryStreaming(systemTempDir, true, 0, 0);
|
||||||
|
|
||||||
// Assert - In container mode, both our temp files and system temp files should be deleted
|
// Assert - In container mode, both our temp files and system temp files should be
|
||||||
|
// deleted
|
||||||
// regardless of age (when maxAgeMillis is 0)
|
// regardless of age (when maxAgeMillis is 0)
|
||||||
assertTrue(deletedFiles.contains(ourTempFile), "Our temp file should be deleted in container mode");
|
assertTrue(
|
||||||
assertTrue(deletedFiles.contains(sysTempFile), "System temp file should be deleted in container mode");
|
deletedFiles.contains(ourTempFile),
|
||||||
|
"Our temp file should be deleted in container mode");
|
||||||
|
assertTrue(
|
||||||
|
deletedFiles.contains(sysTempFile),
|
||||||
|
"System temp file should be deleted in container mode");
|
||||||
assertFalse(deletedFiles.contains(regularFile), "Regular file should be preserved");
|
assertFalse(deletedFiles.contains(regularFile), "Regular file should be preserved");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -303,7 +338,8 @@ public class TempFileCleanupServiceTest {
|
|||||||
// Use MockedStatic to mock Files operations
|
// Use MockedStatic to mock Files operations
|
||||||
try (MockedStatic<Files> mockedFiles = mockStatic(Files.class)) {
|
try (MockedStatic<Files> mockedFiles = mockStatic(Files.class)) {
|
||||||
// Mock Files.list for systemTempDir
|
// Mock Files.list for systemTempDir
|
||||||
mockedFiles.when(() -> Files.list(eq(systemTempDir)))
|
mockedFiles
|
||||||
|
.when(() -> Files.list(eq(systemTempDir)))
|
||||||
.thenReturn(Stream.of(emptyFile, recentEmptyFile));
|
.thenReturn(Stream.of(emptyFile, recentEmptyFile));
|
||||||
|
|
||||||
// Configure Files.isDirectory
|
// Configure Files.isDirectory
|
||||||
@ -313,39 +349,46 @@ public class TempFileCleanupServiceTest {
|
|||||||
mockedFiles.when(() -> Files.exists(any(Path.class))).thenReturn(true);
|
mockedFiles.when(() -> Files.exists(any(Path.class))).thenReturn(true);
|
||||||
|
|
||||||
// Configure Files.getLastModifiedTime to return different times based on file names
|
// Configure Files.getLastModifiedTime to return different times based on file names
|
||||||
mockedFiles.when(() -> Files.getLastModifiedTime(any(Path.class)))
|
mockedFiles
|
||||||
.thenAnswer(invocation -> {
|
.when(() -> Files.getLastModifiedTime(any(Path.class)))
|
||||||
Path path = invocation.getArgument(0);
|
.thenAnswer(
|
||||||
String fileName = path.getFileName().toString();
|
invocation -> {
|
||||||
|
Path path = invocation.getArgument(0);
|
||||||
|
String fileName = path.getFileName().toString();
|
||||||
|
|
||||||
if (fileName.equals("empty.tmp")) {
|
if (fileName.equals("empty.tmp")) {
|
||||||
// More than 5 minutes old
|
// More than 5 minutes old
|
||||||
return FileTime.fromMillis(System.currentTimeMillis() - 6 * 60 * 1000);
|
return FileTime.fromMillis(
|
||||||
} else {
|
System.currentTimeMillis() - 6 * 60 * 1000);
|
||||||
// Less than 5 minutes old
|
} else {
|
||||||
return FileTime.fromMillis(System.currentTimeMillis() - 2 * 60 * 1000);
|
// Less than 5 minutes old
|
||||||
}
|
return FileTime.fromMillis(
|
||||||
});
|
System.currentTimeMillis() - 2 * 60 * 1000);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Configure Files.size to return 0 for empty files
|
// Configure Files.size to return 0 for empty files
|
||||||
mockedFiles.when(() -> Files.size(any(Path.class)))
|
mockedFiles.when(() -> Files.size(any(Path.class))).thenReturn(0L);
|
||||||
.thenReturn(0L);
|
|
||||||
|
|
||||||
// For deleteIfExists, track which files would be deleted
|
// For deleteIfExists, track which files would be deleted
|
||||||
mockedFiles.when(() -> Files.deleteIfExists(any(Path.class)))
|
mockedFiles
|
||||||
.thenAnswer(invocation -> {
|
.when(() -> Files.deleteIfExists(any(Path.class)))
|
||||||
Path path = invocation.getArgument(0);
|
.thenAnswer(
|
||||||
deletedFiles.add(path);
|
invocation -> {
|
||||||
return true;
|
Path path = invocation.getArgument(0);
|
||||||
});
|
deletedFiles.add(path);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
invokeCleanupDirectoryStreaming(systemTempDir, false, 0, 3600000);
|
invokeCleanupDirectoryStreaming(systemTempDir, false, 0, 3600000);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
assertTrue(deletedFiles.contains(emptyFile),
|
assertTrue(
|
||||||
|
deletedFiles.contains(emptyFile),
|
||||||
"Empty file older than 5 minutes should be deleted");
|
"Empty file older than 5 minutes should be deleted");
|
||||||
assertFalse(deletedFiles.contains(recentEmptyFile),
|
assertFalse(
|
||||||
|
deletedFiles.contains(recentEmptyFile),
|
||||||
"Empty file newer than 5 minutes should not be deleted");
|
"Empty file newer than 5 minutes should not be deleted");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -370,17 +413,13 @@ public class TempFileCleanupServiceTest {
|
|||||||
// Use MockedStatic to mock Files operations
|
// Use MockedStatic to mock Files operations
|
||||||
try (MockedStatic<Files> mockedFiles = mockStatic(Files.class)) {
|
try (MockedStatic<Files> mockedFiles = mockStatic(Files.class)) {
|
||||||
// Mock Files.list for each directory
|
// Mock Files.list for each directory
|
||||||
mockedFiles.when(() -> Files.list(eq(systemTempDir)))
|
mockedFiles.when(() -> Files.list(eq(systemTempDir))).thenReturn(Stream.of(dir1));
|
||||||
.thenReturn(Stream.of(dir1));
|
|
||||||
|
|
||||||
mockedFiles.when(() -> Files.list(eq(dir1)))
|
mockedFiles.when(() -> Files.list(eq(dir1))).thenReturn(Stream.of(tempFile1, dir2));
|
||||||
.thenReturn(Stream.of(tempFile1, dir2));
|
|
||||||
|
|
||||||
mockedFiles.when(() -> Files.list(eq(dir2)))
|
mockedFiles.when(() -> Files.list(eq(dir2))).thenReturn(Stream.of(tempFile2, dir3));
|
||||||
.thenReturn(Stream.of(tempFile2, dir3));
|
|
||||||
|
|
||||||
mockedFiles.when(() -> Files.list(eq(dir3)))
|
mockedFiles.when(() -> Files.list(eq(dir3))).thenReturn(Stream.of(tempFile3));
|
||||||
.thenReturn(Stream.of(tempFile3));
|
|
||||||
|
|
||||||
// Configure Files.isDirectory for each path
|
// Configure Files.isDirectory for each path
|
||||||
mockedFiles.when(() -> Files.isDirectory(eq(dir1))).thenReturn(true);
|
mockedFiles.when(() -> Files.isDirectory(eq(dir1))).thenReturn(true);
|
||||||
@ -394,31 +433,35 @@ public class TempFileCleanupServiceTest {
|
|||||||
mockedFiles.when(() -> Files.exists(any(Path.class))).thenReturn(true);
|
mockedFiles.when(() -> Files.exists(any(Path.class))).thenReturn(true);
|
||||||
|
|
||||||
// Configure Files.getLastModifiedTime to return different times based on file names
|
// Configure Files.getLastModifiedTime to return different times based on file names
|
||||||
mockedFiles.when(() -> Files.getLastModifiedTime(any(Path.class)))
|
mockedFiles
|
||||||
.thenAnswer(invocation -> {
|
.when(() -> Files.getLastModifiedTime(any(Path.class)))
|
||||||
Path path = invocation.getArgument(0);
|
.thenAnswer(
|
||||||
String fileName = path.getFileName().toString();
|
invocation -> {
|
||||||
|
Path path = invocation.getArgument(0);
|
||||||
|
String fileName = path.getFileName().toString();
|
||||||
|
|
||||||
if (fileName.contains("old")) {
|
if (fileName.contains("old")) {
|
||||||
// Old file
|
// Old file
|
||||||
return FileTime.fromMillis(System.currentTimeMillis() - 5000000);
|
return FileTime.fromMillis(
|
||||||
} else {
|
System.currentTimeMillis() - 5000000);
|
||||||
// Recent file
|
} else {
|
||||||
return FileTime.fromMillis(System.currentTimeMillis() - 60000);
|
// Recent file
|
||||||
}
|
return FileTime.fromMillis(System.currentTimeMillis() - 60000);
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Configure Files.size to return normal size
|
// Configure Files.size to return normal size
|
||||||
mockedFiles.when(() -> Files.size(any(Path.class)))
|
mockedFiles.when(() -> Files.size(any(Path.class))).thenReturn(1024L);
|
||||||
.thenReturn(1024L);
|
|
||||||
|
|
||||||
// For deleteIfExists, track which files would be deleted
|
// For deleteIfExists, track which files would be deleted
|
||||||
mockedFiles.when(() -> Files.deleteIfExists(any(Path.class)))
|
mockedFiles
|
||||||
.thenAnswer(invocation -> {
|
.when(() -> Files.deleteIfExists(any(Path.class)))
|
||||||
Path path = invocation.getArgument(0);
|
.thenAnswer(
|
||||||
deletedFiles.add(path);
|
invocation -> {
|
||||||
return true;
|
Path path = invocation.getArgument(0);
|
||||||
});
|
deletedFiles.add(path);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
invokeCleanupDirectoryStreaming(systemTempDir, false, 0, 3600000);
|
invokeCleanupDirectoryStreaming(systemTempDir, false, 0, 3600000);
|
||||||
@ -430,14 +473,15 @@ public class TempFileCleanupServiceTest {
|
|||||||
// Assert
|
// Assert
|
||||||
assertFalse(deletedFiles.contains(tempFile1), "Recent temp file should be preserved");
|
assertFalse(deletedFiles.contains(tempFile1), "Recent temp file should be preserved");
|
||||||
assertFalse(deletedFiles.contains(tempFile2), "Recent temp file should be preserved");
|
assertFalse(deletedFiles.contains(tempFile2), "Recent temp file should be preserved");
|
||||||
assertTrue(deletedFiles.contains(tempFile3), "Old temp file in nested directory should be deleted");
|
assertTrue(
|
||||||
|
deletedFiles.contains(tempFile3),
|
||||||
|
"Old temp file in nested directory should be deleted");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Helper method to invoke the private cleanupDirectoryStreaming method using reflection */
|
||||||
* Helper method to invoke the private cleanupDirectoryStreaming method using reflection
|
private void invokeCleanupDirectoryStreaming(
|
||||||
*/
|
Path directory, boolean containerMode, int depth, long maxAgeMillis)
|
||||||
private void invokeCleanupDirectoryStreaming(Path directory, boolean containerMode, int depth, long maxAgeMillis)
|
|
||||||
throws IOException {
|
throws IOException {
|
||||||
try {
|
try {
|
||||||
// Create a consumer that tracks deleted files
|
// Create a consumer that tracks deleted files
|
||||||
@ -445,13 +489,26 @@ public class TempFileCleanupServiceTest {
|
|||||||
Consumer<Path> deleteCallback = path -> deleteCount.incrementAndGet();
|
Consumer<Path> deleteCallback = path -> deleteCount.incrementAndGet();
|
||||||
|
|
||||||
// Get the method with updated signature
|
// Get the method with updated signature
|
||||||
var method = TempFileCleanupService.class.getDeclaredMethod(
|
var method =
|
||||||
"cleanupDirectoryStreaming",
|
TempFileCleanupService.class.getDeclaredMethod(
|
||||||
Path.class, boolean.class, int.class, long.class, boolean.class, Consumer.class);
|
"cleanupDirectoryStreaming",
|
||||||
|
Path.class,
|
||||||
|
boolean.class,
|
||||||
|
int.class,
|
||||||
|
long.class,
|
||||||
|
boolean.class,
|
||||||
|
Consumer.class);
|
||||||
method.setAccessible(true);
|
method.setAccessible(true);
|
||||||
|
|
||||||
// Invoke the method with appropriate parameters
|
// Invoke the method with appropriate parameters
|
||||||
method.invoke(cleanupService, directory, containerMode, depth, maxAgeMillis, false, deleteCallback);
|
method.invoke(
|
||||||
|
cleanupService,
|
||||||
|
directory,
|
||||||
|
containerMode,
|
||||||
|
depth,
|
||||||
|
maxAgeMillis,
|
||||||
|
false,
|
||||||
|
deleteCallback);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException("Error invoking cleanupDirectoryStreaming", e);
|
throw new RuntimeException("Error invoking cleanupDirectoryStreaming", e);
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,5 @@
|
|||||||
package stirling.software.common.util;
|
package stirling.software.common.util;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import org.junit.jupiter.api.AfterEach;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.mockito.MockedStatic;
|
|
||||||
import org.mockito.Mockito;
|
|
||||||
import stirling.software.common.util.ProcessExecutor.ProcessExecutorResult;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
@ -19,6 +10,18 @@ import static org.mockito.Mockito.times;
|
|||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.mockito.MockedStatic;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
|
||||||
|
import stirling.software.common.util.ProcessExecutor.ProcessExecutorResult;
|
||||||
|
|
||||||
class CheckProgramInstallTest {
|
class CheckProgramInstallTest {
|
||||||
|
|
||||||
private MockedStatic<ProcessExecutor> mockProcessExecutor;
|
private MockedStatic<ProcessExecutor> mockProcessExecutor;
|
||||||
|
@ -23,15 +23,19 @@ class CustomHtmlSanitizerTest {
|
|||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setUp() {
|
void setUp() {
|
||||||
SsrfProtectionService mockSsrfProtectionService = mock(SsrfProtectionService.class);
|
SsrfProtectionService mockSsrfProtectionService = mock(SsrfProtectionService.class);
|
||||||
stirling.software.common.model.ApplicationProperties mockApplicationProperties = mock(stirling.software.common.model.ApplicationProperties.class);
|
stirling.software.common.model.ApplicationProperties mockApplicationProperties =
|
||||||
stirling.software.common.model.ApplicationProperties.System mockSystem = mock(stirling.software.common.model.ApplicationProperties.System.class);
|
mock(stirling.software.common.model.ApplicationProperties.class);
|
||||||
|
stirling.software.common.model.ApplicationProperties.System mockSystem =
|
||||||
|
mock(stirling.software.common.model.ApplicationProperties.System.class);
|
||||||
|
|
||||||
// Allow all URLs by default for basic tests
|
// Allow all URLs by default for basic tests
|
||||||
when(mockSsrfProtectionService.isUrlAllowed(org.mockito.ArgumentMatchers.anyString())).thenReturn(true);
|
when(mockSsrfProtectionService.isUrlAllowed(org.mockito.ArgumentMatchers.anyString()))
|
||||||
|
.thenReturn(true);
|
||||||
when(mockApplicationProperties.getSystem()).thenReturn(mockSystem);
|
when(mockApplicationProperties.getSystem()).thenReturn(mockSystem);
|
||||||
when(mockSystem.getDisableSanitize()).thenReturn(false); // Enable sanitization for tests
|
when(mockSystem.getDisableSanitize()).thenReturn(false); // Enable sanitization for tests
|
||||||
|
|
||||||
customHtmlSanitizer = new CustomHtmlSanitizer(mockSsrfProtectionService, mockApplicationProperties);
|
customHtmlSanitizer =
|
||||||
|
new CustomHtmlSanitizer(mockSsrfProtectionService, mockApplicationProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -19,6 +19,7 @@ import org.junit.jupiter.api.io.TempDir;
|
|||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
import stirling.software.common.configuration.RuntimePathConfig;
|
import stirling.software.common.configuration.RuntimePathConfig;
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
@ -1,15 +1,14 @@
|
|||||||
package stirling.software.common.util;
|
package stirling.software.common.util;
|
||||||
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
import static org.mockito.ArgumentMatchers.anyString;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
@ -24,14 +23,18 @@ public class FileToPdfTest {
|
|||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setUp() {
|
void setUp() {
|
||||||
SsrfProtectionService mockSsrfProtectionService = mock(SsrfProtectionService.class);
|
SsrfProtectionService mockSsrfProtectionService = mock(SsrfProtectionService.class);
|
||||||
stirling.software.common.model.ApplicationProperties mockApplicationProperties = mock(stirling.software.common.model.ApplicationProperties.class);
|
stirling.software.common.model.ApplicationProperties mockApplicationProperties =
|
||||||
stirling.software.common.model.ApplicationProperties.System mockSystem = mock(stirling.software.common.model.ApplicationProperties.System.class);
|
mock(stirling.software.common.model.ApplicationProperties.class);
|
||||||
|
stirling.software.common.model.ApplicationProperties.System mockSystem =
|
||||||
|
mock(stirling.software.common.model.ApplicationProperties.System.class);
|
||||||
|
|
||||||
when(mockSsrfProtectionService.isUrlAllowed(org.mockito.ArgumentMatchers.anyString())).thenReturn(true);
|
when(mockSsrfProtectionService.isUrlAllowed(org.mockito.ArgumentMatchers.anyString()))
|
||||||
|
.thenReturn(true);
|
||||||
when(mockApplicationProperties.getSystem()).thenReturn(mockSystem);
|
when(mockApplicationProperties.getSystem()).thenReturn(mockSystem);
|
||||||
when(mockSystem.getDisableSanitize()).thenReturn(false);
|
when(mockSystem.getDisableSanitize()).thenReturn(false);
|
||||||
|
|
||||||
customHtmlSanitizer = new CustomHtmlSanitizer(mockSsrfProtectionService, mockApplicationProperties);
|
customHtmlSanitizer =
|
||||||
|
new CustomHtmlSanitizer(mockSsrfProtectionService, mockApplicationProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -48,8 +51,8 @@ public class FileToPdfTest {
|
|||||||
// Mock the temp file creation to return real temp files
|
// Mock the temp file creation to return real temp files
|
||||||
try {
|
try {
|
||||||
when(tempFileManager.createTempFile(anyString()))
|
when(tempFileManager.createTempFile(anyString()))
|
||||||
.thenReturn(Files.createTempFile("test", ".pdf").toFile())
|
.thenReturn(Files.createTempFile("test", ".pdf").toFile())
|
||||||
.thenReturn(Files.createTempFile("test", ".html").toFile());
|
.thenReturn(Files.createTempFile("test", ".html").toFile());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
@ -60,7 +63,12 @@ public class FileToPdfTest {
|
|||||||
Exception.class,
|
Exception.class,
|
||||||
() ->
|
() ->
|
||||||
FileToPdf.convertHtmlToPdf(
|
FileToPdf.convertHtmlToPdf(
|
||||||
"/path/", request, fileBytes, fileName, tempFileManager, customHtmlSanitizer));
|
"/path/",
|
||||||
|
request,
|
||||||
|
fileBytes,
|
||||||
|
fileName,
|
||||||
|
tempFileManager,
|
||||||
|
customHtmlSanitizer));
|
||||||
assertNotNull(thrown);
|
assertNotNull(thrown);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,21 +1,23 @@
|
|||||||
package stirling.software.common.util;
|
package stirling.software.common.util;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import org.junit.jupiter.api.Assertions;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.jupiter.params.provider.Arguments;
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
import org.junit.jupiter.params.provider.MethodSource;
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
import stirling.software.common.model.enumeration.UsernameAttribute;
|
import stirling.software.common.model.enumeration.UsernameAttribute;
|
||||||
import stirling.software.common.model.oauth2.GitHubProvider;
|
import stirling.software.common.model.oauth2.GitHubProvider;
|
||||||
import stirling.software.common.model.oauth2.GoogleProvider;
|
import stirling.software.common.model.oauth2.GoogleProvider;
|
||||||
import stirling.software.common.model.oauth2.Provider;
|
import stirling.software.common.model.oauth2.Provider;
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class ProviderUtilsTest {
|
class ProviderUtilsTest {
|
||||||
@ -40,7 +42,7 @@ class ProviderUtilsTest {
|
|||||||
public static Stream<Arguments> providerParams() {
|
public static Stream<Arguments> providerParams() {
|
||||||
Provider generic = null;
|
Provider generic = null;
|
||||||
var google =
|
var google =
|
||||||
new GoogleProvider(null, "clientSecret", List.of("scope"), UsernameAttribute.EMAIL);
|
new GoogleProvider(null, "clientSecret", List.of("scope"), UsernameAttribute.EMAIL);
|
||||||
var github = new GitHubProvider("clientId", "", List.of("scope"), UsernameAttribute.LOGIN);
|
var github = new GitHubProvider("clientId", "", List.of("scope"), UsernameAttribute.LOGIN);
|
||||||
|
|
||||||
return Stream.of(Arguments.of(generic), Arguments.of(google), Arguments.of(github));
|
return Stream.of(Arguments.of(generic), Arguments.of(google), Arguments.of(github));
|
||||||
|
@ -42,7 +42,6 @@ class SpringContextHolderTest {
|
|||||||
verify(mockApplicationContext).getBean(TestBean.class);
|
verify(mockApplicationContext).getBean(TestBean.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGetBean_ApplicationContextNotSet() {
|
void testGetBean_ApplicationContextNotSet() {
|
||||||
// Don't set application context
|
// Don't set application context
|
||||||
@ -58,7 +57,8 @@ class SpringContextHolderTest {
|
|||||||
void testGetBean_BeanNotFound() {
|
void testGetBean_BeanNotFound() {
|
||||||
// Arrange
|
// Arrange
|
||||||
contextHolder.setApplicationContext(mockApplicationContext);
|
contextHolder.setApplicationContext(mockApplicationContext);
|
||||||
when(mockApplicationContext.getBean(TestBean.class)).thenThrow(new org.springframework.beans.BeansException("Bean not found") {});
|
when(mockApplicationContext.getBean(TestBean.class))
|
||||||
|
.thenThrow(new org.springframework.beans.BeansException("Bean not found") {});
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
TestBean result = SpringContextHolder.getBean(TestBean.class);
|
TestBean result = SpringContextHolder.getBean(TestBean.class);
|
||||||
@ -68,6 +68,5 @@ class SpringContextHolderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Simple test class
|
// Simple test class
|
||||||
private static class TestBean {
|
private static class TestBean {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
package stirling.software.common.util.misc;
|
package stirling.software.common.util.misc;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import stirling.software.common.model.api.misc.HighContrastColorCombination;
|
|
||||||
import stirling.software.common.model.api.misc.ReplaceAndInvert;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import stirling.software.common.model.api.misc.HighContrastColorCombination;
|
||||||
|
import stirling.software.common.model.api.misc.ReplaceAndInvert;
|
||||||
|
|
||||||
class HighContrastColorReplaceDeciderTest {
|
class HighContrastColorReplaceDeciderTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -26,6 +26,7 @@ import org.junit.jupiter.api.Test;
|
|||||||
import org.springframework.core.io.InputStreamResource;
|
import org.springframework.core.io.InputStreamResource;
|
||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import stirling.software.common.model.api.misc.ReplaceAndInvert;
|
import stirling.software.common.model.api.misc.ReplaceAndInvert;
|
||||||
|
|
||||||
class InvertFullColorStrategyTest {
|
class InvertFullColorStrategyTest {
|
||||||
|
@ -9,6 +9,7 @@ import org.junit.jupiter.api.Test;
|
|||||||
import org.springframework.core.io.InputStreamResource;
|
import org.springframework.core.io.InputStreamResource;
|
||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import stirling.software.common.model.api.misc.ReplaceAndInvert;
|
import stirling.software.common.model.api.misc.ReplaceAndInvert;
|
||||||
|
|
||||||
class ReplaceAndInvertColorStrategyTest {
|
class ReplaceAndInvertColorStrategyTest {
|
||||||
|
@ -1,14 +1,17 @@
|
|||||||
package stirling.software.common.util.propertyeditor;
|
package stirling.software.common.util.propertyeditor;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import stirling.software.common.model.api.security.RedactionArea;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import stirling.software.common.model.api.security.RedactionArea;
|
||||||
|
|
||||||
class StringToArrayListPropertyEditorTest {
|
class StringToArrayListPropertyEditorTest {
|
||||||
|
|
||||||
private StringToArrayListPropertyEditor editor;
|
private StringToArrayListPropertyEditor editor;
|
||||||
|
@ -14,7 +14,7 @@ configurations {
|
|||||||
|
|
||||||
spotless {
|
spotless {
|
||||||
java {
|
java {
|
||||||
target sourceSets.main.allJava
|
target 'src/**/java/**/*.java'
|
||||||
googleJavaFormat(googleJavaFormatVersion).aosp().reorderImports(false)
|
googleJavaFormat(googleJavaFormatVersion).aosp().reorderImports(false)
|
||||||
|
|
||||||
importOrder("java", "javax", "org", "com", "net", "io", "jakarta", "lombok", "me", "stirling")
|
importOrder("java", "javax", "org", "com", "net", "io", "jakarta", "lombok", "me", "stirling")
|
||||||
@ -23,6 +23,18 @@ spotless {
|
|||||||
leadingTabsToSpaces()
|
leadingTabsToSpaces()
|
||||||
endWithNewline()
|
endWithNewline()
|
||||||
}
|
}
|
||||||
|
yaml {
|
||||||
|
target '**/*.yml', '**/*.yaml'
|
||||||
|
trimTrailingWhitespace()
|
||||||
|
leadingTabsToSpaces()
|
||||||
|
endWithNewline()
|
||||||
|
}
|
||||||
|
format 'gradle', {
|
||||||
|
target '**/gradle/*.gradle', '**/*.gradle'
|
||||||
|
trimTrailingWhitespace()
|
||||||
|
leadingTabsToSpaces()
|
||||||
|
endWithNewline()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@ -62,7 +74,7 @@ dependencies {
|
|||||||
exclude group: 'com.google.code.gson', module: 'gson'
|
exclude group: 'com.google.code.gson', module: 'gson'
|
||||||
}
|
}
|
||||||
implementation 'org.apache.pdfbox:jbig2-imageio:3.0.4'
|
implementation 'org.apache.pdfbox:jbig2-imageio:3.0.4'
|
||||||
implementation 'com.opencsv:opencsv:5.11.2' // https://mvnrepository.com/artifact/com.opencsv/opencsv
|
implementation 'com.opencsv:opencsv:5.12.0' // https://mvnrepository.com/artifact/com.opencsv/opencsv
|
||||||
|
|
||||||
// Batik
|
// Batik
|
||||||
implementation 'org.apache.xmlgraphics:batik-all:1.19'
|
implementation 'org.apache.xmlgraphics:batik-all:1.19'
|
||||||
|
@ -70,9 +70,17 @@ public class StampController {
|
|||||||
String stampType = request.getStampType();
|
String stampType = request.getStampType();
|
||||||
String stampText = request.getStampText();
|
String stampText = request.getStampText();
|
||||||
MultipartFile stampImage = request.getStampImage();
|
MultipartFile stampImage = request.getStampImage();
|
||||||
String stampImageName = stampImage.getOriginalFilename();
|
if ("image".equalsIgnoreCase(stampType)) {
|
||||||
if (stampImageName.contains("..") || stampImageName.startsWith("/")) {
|
if (stampImage == null) {
|
||||||
throw new IllegalArgumentException("Invalid stamp image file path");
|
throw new IllegalArgumentException(
|
||||||
|
"Stamp image file must be provided when stamp type is 'image'");
|
||||||
|
}
|
||||||
|
String stampImageName = stampImage.getOriginalFilename();
|
||||||
|
if (stampImageName == null
|
||||||
|
|| stampImageName.contains("..")
|
||||||
|
|| stampImageName.startsWith("/")) {
|
||||||
|
throw new IllegalArgumentException("Invalid stamp image file path");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
String alphabet = request.getAlphabet();
|
String alphabet = request.getAlphabet();
|
||||||
float fontSize = request.getFontSize();
|
float fontSize = request.getFontSize();
|
||||||
|
@ -108,9 +108,13 @@ public class PipelineProcessor {
|
|||||||
if (inputFileTypes == null) {
|
if (inputFileTypes == null) {
|
||||||
inputFileTypes = new ArrayList<String>(Arrays.asList("ALL"));
|
inputFileTypes = new ArrayList<String>(Arrays.asList("ALL"));
|
||||||
}
|
}
|
||||||
if (!operation.matches("^[a-zA-Z0-9_-]+$")) {
|
|
||||||
throw new IllegalArgumentException("Invalid operation value received.");
|
if (!apiDocService.isValidOperation(operation, parameters)) {
|
||||||
|
log.error("Invalid operation or parameters: o:{} p:{}", operation, parameters);
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Invalid operation: " + operation + " with parameters: " + parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
String url = getBaseUrl() + operation;
|
String url = getBaseUrl() + operation;
|
||||||
List<Resource> newOutputFiles = new ArrayList<>();
|
List<Resource> newOutputFiles = new ArrayList<>();
|
||||||
if (!isMultiInputOperation) {
|
if (!isMultiInputOperation) {
|
||||||
@ -136,7 +140,7 @@ public class PipelineProcessor {
|
|||||||
// skip
|
// skip
|
||||||
// this
|
// this
|
||||||
// file
|
// file
|
||||||
if (operation.startsWith("filter-")
|
if (operation.startsWith("/api/v1/filter/filter-")
|
||||||
&& (response.getBody() == null
|
&& (response.getBody() == null
|
||||||
|| response.getBody().length == 0)) {
|
|| response.getBody().length == 0)) {
|
||||||
filtersApplied = true;
|
filtersApplied = true;
|
||||||
|
@ -1282,7 +1282,7 @@ merge.header=Több PDF egyesítése (2+)
|
|||||||
merge.sortByName=Rendezés név szerint
|
merge.sortByName=Rendezés név szerint
|
||||||
merge.sortByDate=Rendezés dátum szerint
|
merge.sortByDate=Rendezés dátum szerint
|
||||||
merge.removeCertSign=Digitális aláírás eltávolítása az egyesített fájlban?
|
merge.removeCertSign=Digitális aláírás eltávolítása az egyesített fájlban?
|
||||||
merge.generateToc=Generate table of contents in the merged file?
|
merge.generateToc=Tartalomjegyzék létrehozása az egyesített fájlban?
|
||||||
merge.submit=Egyesítés
|
merge.submit=Egyesítés
|
||||||
|
|
||||||
|
|
||||||
|
@ -260,7 +260,7 @@ disabledCurrentUserMessage=無法停用目前使用者
|
|||||||
downgradeCurrentUserLongMessage=無法降級目前使用者的角色。因此,將不會顯示目前使用者。
|
downgradeCurrentUserLongMessage=無法降級目前使用者的角色。因此,將不會顯示目前使用者。
|
||||||
userAlreadyExistsOAuthMessage=使用者已經以 OAuth2 使用者身份存在。
|
userAlreadyExistsOAuthMessage=使用者已經以 OAuth2 使用者身份存在。
|
||||||
userAlreadyExistsWebMessage=使用者已經以網頁使用者身份存在。
|
userAlreadyExistsWebMessage=使用者已經以網頁使用者身份存在。
|
||||||
invalidRoleMessage=Invalid role.
|
invalidRoleMessage=無效的角色。
|
||||||
error=錯誤
|
error=錯誤
|
||||||
oops=哎呀!
|
oops=哎呀!
|
||||||
help=說明
|
help=說明
|
||||||
@ -273,7 +273,7 @@ color=顏色
|
|||||||
sponsor=贊助
|
sponsor=贊助
|
||||||
info=資訊
|
info=資訊
|
||||||
pro=專業版
|
pro=專業版
|
||||||
proFeatures=Pro Features
|
proFeatures=專業版功能
|
||||||
page=頁面
|
page=頁面
|
||||||
pages=頁面
|
pages=頁面
|
||||||
loading=載入中...
|
loading=載入中...
|
||||||
|
@ -45,77 +45,77 @@
|
|||||||
{
|
{
|
||||||
"moduleName": "com.fasterxml.jackson.core:jackson-annotations",
|
"moduleName": "com.fasterxml.jackson.core:jackson-annotations",
|
||||||
"moduleUrl": "https://github.com/FasterXML/jackson",
|
"moduleUrl": "https://github.com/FasterXML/jackson",
|
||||||
"moduleVersion": "2.19.1",
|
"moduleVersion": "2.19.2",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "com.fasterxml.jackson.core:jackson-core",
|
"moduleName": "com.fasterxml.jackson.core:jackson-core",
|
||||||
"moduleUrl": "https://github.com/FasterXML/jackson-core",
|
"moduleUrl": "https://github.com/FasterXML/jackson-core",
|
||||||
"moduleVersion": "2.19.1",
|
"moduleVersion": "2.19.2",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "com.fasterxml.jackson.core:jackson-databind",
|
"moduleName": "com.fasterxml.jackson.core:jackson-databind",
|
||||||
"moduleUrl": "https://github.com/FasterXML/jackson",
|
"moduleUrl": "https://github.com/FasterXML/jackson",
|
||||||
"moduleVersion": "2.19.1",
|
"moduleVersion": "2.19.2",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml",
|
"moduleName": "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml",
|
||||||
"moduleUrl": "https://github.com/FasterXML/jackson-dataformats-text",
|
"moduleUrl": "https://github.com/FasterXML/jackson-dataformats-text",
|
||||||
"moduleVersion": "2.19.1",
|
"moduleVersion": "2.19.2",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "com.fasterxml.jackson.datatype:jackson-datatype-jdk8",
|
"moduleName": "com.fasterxml.jackson.datatype:jackson-datatype-jdk8",
|
||||||
"moduleUrl": "https://github.com/FasterXML/jackson-modules-java8/jackson-datatype-jdk8",
|
"moduleUrl": "https://github.com/FasterXML/jackson-modules-java8/jackson-datatype-jdk8",
|
||||||
"moduleVersion": "2.19.1",
|
"moduleVersion": "2.19.2",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "com.fasterxml.jackson.datatype:jackson-datatype-jsr310",
|
"moduleName": "com.fasterxml.jackson.datatype:jackson-datatype-jsr310",
|
||||||
"moduleUrl": "https://github.com/FasterXML/jackson-modules-java8/jackson-datatype-jsr310",
|
"moduleUrl": "https://github.com/FasterXML/jackson-modules-java8/jackson-datatype-jsr310",
|
||||||
"moduleVersion": "2.19.1",
|
"moduleVersion": "2.19.2",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "com.fasterxml.jackson.jakarta.rs:jackson-jakarta-rs-base",
|
"moduleName": "com.fasterxml.jackson.jakarta.rs:jackson-jakarta-rs-base",
|
||||||
"moduleUrl": "https://github.com/FasterXML/jackson-jakarta-rs-providers/jackson-jakarta-rs-base",
|
"moduleUrl": "https://github.com/FasterXML/jackson-jakarta-rs-providers/jackson-jakarta-rs-base",
|
||||||
"moduleVersion": "2.19.1",
|
"moduleVersion": "2.19.2",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "com.fasterxml.jackson.jakarta.rs:jackson-jakarta-rs-json-provider",
|
"moduleName": "com.fasterxml.jackson.jakarta.rs:jackson-jakarta-rs-json-provider",
|
||||||
"moduleUrl": "https://github.com/FasterXML/jackson-jakarta-rs-providers/jackson-jakarta-rs-json-provider",
|
"moduleUrl": "https://github.com/FasterXML/jackson-jakarta-rs-providers/jackson-jakarta-rs-json-provider",
|
||||||
"moduleVersion": "2.19.1",
|
"moduleVersion": "2.19.2",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "com.fasterxml.jackson.module:jackson-module-jakarta-xmlbind-annotations",
|
"moduleName": "com.fasterxml.jackson.module:jackson-module-jakarta-xmlbind-annotations",
|
||||||
"moduleUrl": "https://github.com/FasterXML/jackson-modules-base",
|
"moduleUrl": "https://github.com/FasterXML/jackson-modules-base",
|
||||||
"moduleVersion": "2.19.1",
|
"moduleVersion": "2.19.2",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "com.fasterxml.jackson.module:jackson-module-parameter-names",
|
"moduleName": "com.fasterxml.jackson.module:jackson-module-parameter-names",
|
||||||
"moduleUrl": "https://github.com/FasterXML/jackson-modules-java8/jackson-module-parameter-names",
|
"moduleUrl": "https://github.com/FasterXML/jackson-modules-java8/jackson-module-parameter-names",
|
||||||
"moduleVersion": "2.19.1",
|
"moduleVersion": "2.19.2",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "com.fasterxml.jackson:jackson-bom",
|
"moduleName": "com.fasterxml.jackson:jackson-bom",
|
||||||
"moduleUrl": "https://github.com/FasterXML/jackson-bom",
|
"moduleUrl": "https://github.com/FasterXML/jackson-bom",
|
||||||
"moduleVersion": "2.19.1",
|
"moduleVersion": "2.19.2",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
@ -199,13 +199,6 @@
|
|||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"moduleName": "com.google.protobuf:protobuf-java",
|
|
||||||
"moduleUrl": "https://developers.google.com/protocol-buffers/",
|
|
||||||
"moduleVersion": "4.31.0",
|
|
||||||
"moduleLicense": "BSD-3-Clause",
|
|
||||||
"moduleLicenseUrl": "https://opensource.org/licenses/BSD-3-Clause"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"moduleName": "com.google.zxing:core",
|
"moduleName": "com.google.zxing:core",
|
||||||
"moduleUrl": "https://github.com/zxing/zxing/core",
|
"moduleUrl": "https://github.com/zxing/zxing/core",
|
||||||
@ -277,7 +270,7 @@
|
|||||||
{
|
{
|
||||||
"moduleName": "com.opencsv:opencsv",
|
"moduleName": "com.opencsv:opencsv",
|
||||||
"moduleUrl": "http://opencsv.sf.net",
|
"moduleUrl": "http://opencsv.sf.net",
|
||||||
"moduleVersion": "5.11.2",
|
"moduleVersion": "5.12.0",
|
||||||
"moduleLicense": "Apache 2",
|
"moduleLicense": "Apache 2",
|
||||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
@ -498,7 +491,7 @@
|
|||||||
{
|
{
|
||||||
"moduleName": "com.zaxxer:HikariCP",
|
"moduleName": "com.zaxxer:HikariCP",
|
||||||
"moduleUrl": "https://github.com/brettwooldridge/HikariCP",
|
"moduleUrl": "https://github.com/brettwooldridge/HikariCP",
|
||||||
"moduleVersion": "6.3.0",
|
"moduleVersion": "6.3.1",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
@ -553,77 +546,71 @@
|
|||||||
{
|
{
|
||||||
"moduleName": "io.micrometer:micrometer-commons",
|
"moduleName": "io.micrometer:micrometer-commons",
|
||||||
"moduleUrl": "https://github.com/micrometer-metrics/micrometer",
|
"moduleUrl": "https://github.com/micrometer-metrics/micrometer",
|
||||||
"moduleVersion": "1.15.1",
|
"moduleVersion": "1.15.2",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "io.micrometer:micrometer-core",
|
"moduleName": "io.micrometer:micrometer-core",
|
||||||
"moduleUrl": "https://github.com/micrometer-metrics/micrometer",
|
"moduleUrl": "https://github.com/micrometer-metrics/micrometer",
|
||||||
"moduleVersion": "1.15.1",
|
"moduleVersion": "1.15.2",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "io.micrometer:micrometer-jakarta9",
|
"moduleName": "io.micrometer:micrometer-jakarta9",
|
||||||
"moduleUrl": "https://github.com/micrometer-metrics/micrometer",
|
"moduleUrl": "https://github.com/micrometer-metrics/micrometer",
|
||||||
"moduleVersion": "1.15.1",
|
"moduleVersion": "1.15.2",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "io.micrometer:micrometer-observation",
|
"moduleName": "io.micrometer:micrometer-observation",
|
||||||
"moduleUrl": "https://github.com/micrometer-metrics/micrometer",
|
"moduleUrl": "https://github.com/micrometer-metrics/micrometer",
|
||||||
"moduleVersion": "1.15.1",
|
"moduleVersion": "1.15.2",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "io.micrometer:micrometer-registry-prometheus",
|
"moduleName": "io.micrometer:micrometer-registry-prometheus",
|
||||||
"moduleUrl": "https://github.com/micrometer-metrics/micrometer",
|
"moduleUrl": "https://github.com/micrometer-metrics/micrometer",
|
||||||
"moduleVersion": "1.15.1",
|
"moduleVersion": "1.15.2",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "io.prometheus:prometheus-metrics-config",
|
"moduleName": "io.prometheus:prometheus-metrics-config",
|
||||||
"moduleVersion": "1.3.8",
|
"moduleVersion": "1.3.10",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "io.prometheus:prometheus-metrics-core",
|
"moduleName": "io.prometheus:prometheus-metrics-core",
|
||||||
"moduleVersion": "1.3.8",
|
"moduleVersion": "1.3.10",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "io.prometheus:prometheus-metrics-exposition-formats",
|
"moduleName": "io.prometheus:prometheus-metrics-exposition-formats",
|
||||||
"moduleVersion": "1.3.8",
|
"moduleVersion": "1.3.10",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
|
||||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"moduleName": "io.prometheus:prometheus-metrics-exposition-formats-no-protobuf",
|
|
||||||
"moduleVersion": "1.3.8",
|
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "io.prometheus:prometheus-metrics-exposition-textformats",
|
"moduleName": "io.prometheus:prometheus-metrics-exposition-textformats",
|
||||||
"moduleVersion": "1.3.8",
|
"moduleVersion": "1.3.10",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "io.prometheus:prometheus-metrics-model",
|
"moduleName": "io.prometheus:prometheus-metrics-model",
|
||||||
"moduleVersion": "1.3.8",
|
"moduleVersion": "1.3.10",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "io.prometheus:prometheus-metrics-tracer-common",
|
"moduleName": "io.prometheus:prometheus-metrics-tracer-common",
|
||||||
"moduleVersion": "1.3.8",
|
"moduleVersion": "1.3.10",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
@ -925,7 +912,7 @@
|
|||||||
{
|
{
|
||||||
"moduleName": "org.apache.tomcat.embed:tomcat-embed-el",
|
"moduleName": "org.apache.tomcat.embed:tomcat-embed-el",
|
||||||
"moduleUrl": "https://tomcat.apache.org/",
|
"moduleUrl": "https://tomcat.apache.org/",
|
||||||
"moduleVersion": "10.1.42",
|
"moduleVersion": "10.1.43",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
@ -1034,182 +1021,182 @@
|
|||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty.ee10.websocket:jetty-ee10-websocket-jakarta-client",
|
"moduleName": "org.eclipse.jetty.ee10.websocket:jetty-ee10-websocket-jakarta-client",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.22",
|
"moduleVersion": "12.0.23",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty.ee10.websocket:jetty-ee10-websocket-jakarta-common",
|
"moduleName": "org.eclipse.jetty.ee10.websocket:jetty-ee10-websocket-jakarta-common",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.22",
|
"moduleVersion": "12.0.23",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty.ee10.websocket:jetty-ee10-websocket-jakarta-server",
|
"moduleName": "org.eclipse.jetty.ee10.websocket:jetty-ee10-websocket-jakarta-server",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.22",
|
"moduleVersion": "12.0.23",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty.ee10.websocket:jetty-ee10-websocket-jetty-server",
|
"moduleName": "org.eclipse.jetty.ee10.websocket:jetty-ee10-websocket-jetty-server",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.22",
|
"moduleVersion": "12.0.23",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty.ee10.websocket:jetty-ee10-websocket-servlet",
|
"moduleName": "org.eclipse.jetty.ee10.websocket:jetty-ee10-websocket-servlet",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.22",
|
"moduleVersion": "12.0.23",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty.ee10:jetty-ee10-annotations",
|
"moduleName": "org.eclipse.jetty.ee10:jetty-ee10-annotations",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.22",
|
"moduleVersion": "12.0.23",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty.ee10:jetty-ee10-plus",
|
"moduleName": "org.eclipse.jetty.ee10:jetty-ee10-plus",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.22",
|
"moduleVersion": "12.0.23",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty.ee10:jetty-ee10-servlet",
|
"moduleName": "org.eclipse.jetty.ee10:jetty-ee10-servlet",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.22",
|
"moduleVersion": "12.0.23",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty.ee10:jetty-ee10-servlets",
|
"moduleName": "org.eclipse.jetty.ee10:jetty-ee10-servlets",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.22",
|
"moduleVersion": "12.0.23",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty.ee10:jetty-ee10-webapp",
|
"moduleName": "org.eclipse.jetty.ee10:jetty-ee10-webapp",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.22",
|
"moduleVersion": "12.0.23",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty.websocket:jetty-websocket-core-client",
|
"moduleName": "org.eclipse.jetty.websocket:jetty-websocket-core-client",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.22",
|
"moduleVersion": "12.0.23",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty.websocket:jetty-websocket-core-common",
|
"moduleName": "org.eclipse.jetty.websocket:jetty-websocket-core-common",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.22",
|
"moduleVersion": "12.0.23",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty.websocket:jetty-websocket-core-server",
|
"moduleName": "org.eclipse.jetty.websocket:jetty-websocket-core-server",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.22",
|
"moduleVersion": "12.0.23",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty.websocket:jetty-websocket-jetty-api",
|
"moduleName": "org.eclipse.jetty.websocket:jetty-websocket-jetty-api",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.22",
|
"moduleVersion": "12.0.23",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty.websocket:jetty-websocket-jetty-common",
|
"moduleName": "org.eclipse.jetty.websocket:jetty-websocket-jetty-common",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.22",
|
"moduleVersion": "12.0.23",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty:jetty-alpn-client",
|
"moduleName": "org.eclipse.jetty:jetty-alpn-client",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.22",
|
"moduleVersion": "12.0.23",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty:jetty-client",
|
"moduleName": "org.eclipse.jetty:jetty-client",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.22",
|
"moduleVersion": "12.0.23",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty:jetty-ee",
|
"moduleName": "org.eclipse.jetty:jetty-ee",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.22",
|
"moduleVersion": "12.0.23",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty:jetty-http",
|
"moduleName": "org.eclipse.jetty:jetty-http",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.22",
|
"moduleVersion": "12.0.23",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty:jetty-io",
|
"moduleName": "org.eclipse.jetty:jetty-io",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.22",
|
"moduleVersion": "12.0.23",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty:jetty-plus",
|
"moduleName": "org.eclipse.jetty:jetty-plus",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.22",
|
"moduleVersion": "12.0.23",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty:jetty-security",
|
"moduleName": "org.eclipse.jetty:jetty-security",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.22",
|
"moduleVersion": "12.0.23",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty:jetty-server",
|
"moduleName": "org.eclipse.jetty:jetty-server",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.22",
|
"moduleVersion": "12.0.23",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty:jetty-session",
|
"moduleName": "org.eclipse.jetty:jetty-session",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.22",
|
"moduleVersion": "12.0.23",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty:jetty-util",
|
"moduleName": "org.eclipse.jetty:jetty-util",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.22",
|
"moduleVersion": "12.0.23",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty:jetty-xml",
|
"moduleName": "org.eclipse.jetty:jetty-xml",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.22",
|
"moduleVersion": "12.0.23",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
@ -1251,7 +1238,7 @@
|
|||||||
{
|
{
|
||||||
"moduleName": "org.hibernate.orm:hibernate-core",
|
"moduleName": "org.hibernate.orm:hibernate-core",
|
||||||
"moduleUrl": "https://www.hibernate.org/orm/6.6",
|
"moduleUrl": "https://www.hibernate.org/orm/6.6",
|
||||||
"moduleVersion": "6.6.18.Final",
|
"moduleVersion": "6.6.22.Final",
|
||||||
"moduleLicense": "GNU Library General Public License v2.1 or later",
|
"moduleLicense": "GNU Library General Public License v2.1 or later",
|
||||||
"moduleLicenseUrl": "https://www.opensource.org/licenses/LGPL-2.1"
|
"moduleLicenseUrl": "https://www.opensource.org/licenses/LGPL-2.1"
|
||||||
},
|
},
|
||||||
@ -1468,196 +1455,196 @@
|
|||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot",
|
"moduleName": "org.springframework.boot:spring-boot",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.5.3",
|
"moduleVersion": "3.5.4",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-actuator",
|
"moduleName": "org.springframework.boot:spring-boot-actuator",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.5.3",
|
"moduleVersion": "3.5.4",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-actuator-autoconfigure",
|
"moduleName": "org.springframework.boot:spring-boot-actuator-autoconfigure",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.5.3",
|
"moduleVersion": "3.5.4",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-autoconfigure",
|
"moduleName": "org.springframework.boot:spring-boot-autoconfigure",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.5.3",
|
"moduleVersion": "3.5.4",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-starter",
|
"moduleName": "org.springframework.boot:spring-boot-starter",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.5.3",
|
"moduleVersion": "3.5.4",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-starter-actuator",
|
"moduleName": "org.springframework.boot:spring-boot-starter-actuator",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.5.3",
|
"moduleVersion": "3.5.4",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-starter-aop",
|
"moduleName": "org.springframework.boot:spring-boot-starter-aop",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.5.3",
|
"moduleVersion": "3.5.4",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-starter-data-jpa",
|
"moduleName": "org.springframework.boot:spring-boot-starter-data-jpa",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.5.3",
|
"moduleVersion": "3.5.4",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-starter-jdbc",
|
"moduleName": "org.springframework.boot:spring-boot-starter-jdbc",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.5.3",
|
"moduleVersion": "3.5.4",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-starter-jetty",
|
"moduleName": "org.springframework.boot:spring-boot-starter-jetty",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.5.3",
|
"moduleVersion": "3.5.4",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-starter-json",
|
"moduleName": "org.springframework.boot:spring-boot-starter-json",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.5.3",
|
"moduleVersion": "3.5.4",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-starter-logging",
|
"moduleName": "org.springframework.boot:spring-boot-starter-logging",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.5.3",
|
"moduleVersion": "3.5.4",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-starter-mail",
|
"moduleName": "org.springframework.boot:spring-boot-starter-mail",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.5.3",
|
"moduleVersion": "3.5.4",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-starter-oauth2-client",
|
"moduleName": "org.springframework.boot:spring-boot-starter-oauth2-client",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.5.3",
|
"moduleVersion": "3.5.4",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-starter-security",
|
"moduleName": "org.springframework.boot:spring-boot-starter-security",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.5.3",
|
"moduleVersion": "3.5.4",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-starter-thymeleaf",
|
"moduleName": "org.springframework.boot:spring-boot-starter-thymeleaf",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.5.3",
|
"moduleVersion": "3.5.4",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-starter-validation",
|
"moduleName": "org.springframework.boot:spring-boot-starter-validation",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.5.3",
|
"moduleVersion": "3.5.4",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-starter-web",
|
"moduleName": "org.springframework.boot:spring-boot-starter-web",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.5.3",
|
"moduleVersion": "3.5.4",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.data:spring-data-commons",
|
"moduleName": "org.springframework.data:spring-data-commons",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-data",
|
"moduleUrl": "https://spring.io/projects/spring-data",
|
||||||
"moduleVersion": "3.5.1",
|
"moduleVersion": "3.5.2",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.data:spring-data-jpa",
|
"moduleName": "org.springframework.data:spring-data-jpa",
|
||||||
"moduleUrl": "https://projects.spring.io/spring-data-jpa",
|
"moduleUrl": "https://projects.spring.io/spring-data-jpa",
|
||||||
"moduleVersion": "3.5.1",
|
"moduleVersion": "3.5.2",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.security:spring-security-config",
|
"moduleName": "org.springframework.security:spring-security-config",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-security",
|
"moduleUrl": "https://spring.io/projects/spring-security",
|
||||||
"moduleVersion": "6.5.1",
|
"moduleVersion": "6.5.2",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.security:spring-security-core",
|
"moduleName": "org.springframework.security:spring-security-core",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-security",
|
"moduleUrl": "https://spring.io/projects/spring-security",
|
||||||
"moduleVersion": "6.5.1",
|
"moduleVersion": "6.5.2",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.security:spring-security-crypto",
|
"moduleName": "org.springframework.security:spring-security-crypto",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-security",
|
"moduleUrl": "https://spring.io/projects/spring-security",
|
||||||
"moduleVersion": "6.5.1",
|
"moduleVersion": "6.5.2",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.security:spring-security-oauth2-client",
|
"moduleName": "org.springframework.security:spring-security-oauth2-client",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-security",
|
"moduleUrl": "https://spring.io/projects/spring-security",
|
||||||
"moduleVersion": "6.5.1",
|
"moduleVersion": "6.5.2",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.security:spring-security-oauth2-core",
|
"moduleName": "org.springframework.security:spring-security-oauth2-core",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-security",
|
"moduleUrl": "https://spring.io/projects/spring-security",
|
||||||
"moduleVersion": "6.5.1",
|
"moduleVersion": "6.5.2",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.security:spring-security-oauth2-jose",
|
"moduleName": "org.springframework.security:spring-security-oauth2-jose",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-security",
|
"moduleUrl": "https://spring.io/projects/spring-security",
|
||||||
"moduleVersion": "6.5.1",
|
"moduleVersion": "6.5.2",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.security:spring-security-saml2-service-provider",
|
"moduleName": "org.springframework.security:spring-security-saml2-service-provider",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-security",
|
"moduleUrl": "https://spring.io/projects/spring-security",
|
||||||
"moduleVersion": "6.5.1",
|
"moduleVersion": "6.5.2",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.security:spring-security-web",
|
"moduleName": "org.springframework.security:spring-security-web",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-security",
|
"moduleUrl": "https://spring.io/projects/spring-security",
|
||||||
"moduleVersion": "6.5.1",
|
"moduleVersion": "6.5.2",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
@ -1671,91 +1658,91 @@
|
|||||||
{
|
{
|
||||||
"moduleName": "org.springframework:spring-aop",
|
"moduleName": "org.springframework:spring-aop",
|
||||||
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
||||||
"moduleVersion": "6.2.8",
|
"moduleVersion": "6.2.9",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework:spring-aspects",
|
"moduleName": "org.springframework:spring-aspects",
|
||||||
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
||||||
"moduleVersion": "6.2.8",
|
"moduleVersion": "6.2.9",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework:spring-beans",
|
"moduleName": "org.springframework:spring-beans",
|
||||||
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
||||||
"moduleVersion": "6.2.8",
|
"moduleVersion": "6.2.9",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework:spring-context",
|
"moduleName": "org.springframework:spring-context",
|
||||||
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
||||||
"moduleVersion": "6.2.8",
|
"moduleVersion": "6.2.9",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework:spring-context-support",
|
"moduleName": "org.springframework:spring-context-support",
|
||||||
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
||||||
"moduleVersion": "6.2.8",
|
"moduleVersion": "6.2.9",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework:spring-core",
|
"moduleName": "org.springframework:spring-core",
|
||||||
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
||||||
"moduleVersion": "6.2.8",
|
"moduleVersion": "6.2.9",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework:spring-expression",
|
"moduleName": "org.springframework:spring-expression",
|
||||||
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
||||||
"moduleVersion": "6.2.8",
|
"moduleVersion": "6.2.9",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework:spring-jcl",
|
"moduleName": "org.springframework:spring-jcl",
|
||||||
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
||||||
"moduleVersion": "6.2.8",
|
"moduleVersion": "6.2.9",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework:spring-jdbc",
|
"moduleName": "org.springframework:spring-jdbc",
|
||||||
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
||||||
"moduleVersion": "6.2.8",
|
"moduleVersion": "6.2.9",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework:spring-orm",
|
"moduleName": "org.springframework:spring-orm",
|
||||||
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
||||||
"moduleVersion": "6.2.8",
|
"moduleVersion": "6.2.9",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework:spring-tx",
|
"moduleName": "org.springframework:spring-tx",
|
||||||
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
||||||
"moduleVersion": "6.2.8",
|
"moduleVersion": "6.2.9",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework:spring-web",
|
"moduleName": "org.springframework:spring-web",
|
||||||
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
||||||
"moduleVersion": "6.2.8",
|
"moduleVersion": "6.2.9",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework:spring-webmvc",
|
"moduleName": "org.springframework:spring-webmvc",
|
||||||
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
||||||
"moduleVersion": "6.2.8",
|
"moduleVersion": "6.2.9",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* Main bookmark container styles */
|
/* Main bookmark container styles */
|
||||||
.bookmark-editor {
|
.bookmark-editor {
|
||||||
margin-top: 20px;
|
margin-bottom: 20px;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
border: 1px solid var(--border-color, #ced4da);
|
border: 1px solid var(--border-color, #ced4da);
|
||||||
border-radius: 0.25rem;
|
border-radius: 0.25rem;
|
||||||
@ -273,4 +273,4 @@
|
|||||||
--text-muted: var(--md-sys-color-on-surface-variant, #adb5bd);
|
--text-muted: var(--md-sys-color-on-surface-variant, #adb5bd);
|
||||||
--bg-empty: var(--md-sys-color-surface-container-low, #24282e);
|
--bg-empty: var(--md-sys-color-surface-container-low, #24282e);
|
||||||
--border-empty: var(--md-sys-color-outline, #495057);
|
--border-empty: var(--md-sys-color-outline, #495057);
|
||||||
}
|
}
|
||||||
|
@ -36,14 +36,11 @@ import stirling.software.common.service.CustomPDFDocumentFactory;
|
|||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class EditTableOfContentsControllerTest {
|
class EditTableOfContentsControllerTest {
|
||||||
|
|
||||||
@Mock
|
@Mock private CustomPDFDocumentFactory pdfDocumentFactory;
|
||||||
private CustomPDFDocumentFactory pdfDocumentFactory;
|
|
||||||
|
|
||||||
@Mock
|
@Mock private ObjectMapper objectMapper;
|
||||||
private ObjectMapper objectMapper;
|
|
||||||
|
|
||||||
@InjectMocks
|
@InjectMocks private EditTableOfContentsController editTableOfContentsController;
|
||||||
private EditTableOfContentsController editTableOfContentsController;
|
|
||||||
|
|
||||||
private MockMultipartFile mockFile;
|
private MockMultipartFile mockFile;
|
||||||
private PDDocument mockDocument;
|
private PDDocument mockDocument;
|
||||||
@ -56,7 +53,9 @@ class EditTableOfContentsControllerTest {
|
|||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setUp() {
|
void setUp() {
|
||||||
mockFile = new MockMultipartFile("file", "test.pdf", "application/pdf", "PDF content".getBytes());
|
mockFile =
|
||||||
|
new MockMultipartFile(
|
||||||
|
"file", "test.pdf", "application/pdf", "PDF content".getBytes());
|
||||||
mockDocument = mock(PDDocument.class);
|
mockDocument = mock(PDDocument.class);
|
||||||
mockCatalog = mock(PDDocumentCatalog.class);
|
mockCatalog = mock(PDDocumentCatalog.class);
|
||||||
mockPages = mock(PDPageTree.class);
|
mockPages = mock(PDPageTree.class);
|
||||||
@ -149,7 +148,8 @@ class EditTableOfContentsControllerTest {
|
|||||||
assertEquals(1, parentBookmark.get("pageNumber"));
|
assertEquals(1, parentBookmark.get("pageNumber"));
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
List<Map<String, Object>> children = (List<Map<String, Object>>) parentBookmark.get("children");
|
List<Map<String, Object>> children =
|
||||||
|
(List<Map<String, Object>>) parentBookmark.get("children");
|
||||||
assertEquals(1, children.size());
|
assertEquals(1, children.size());
|
||||||
|
|
||||||
Map<String, Object> childBookmark = children.get(0);
|
Map<String, Object> childBookmark = children.get(0);
|
||||||
@ -202,17 +202,21 @@ class EditTableOfContentsControllerTest {
|
|||||||
bookmarks.add(bookmark);
|
bookmarks.add(bookmark);
|
||||||
|
|
||||||
when(pdfDocumentFactory.load(mockFile)).thenReturn(mockDocument);
|
when(pdfDocumentFactory.load(mockFile)).thenReturn(mockDocument);
|
||||||
when(objectMapper.readValue(eq(request.getBookmarkData()), any(TypeReference.class))).thenReturn(bookmarks);
|
when(objectMapper.readValue(eq(request.getBookmarkData()), any(TypeReference.class)))
|
||||||
|
.thenReturn(bookmarks);
|
||||||
when(mockDocument.getDocumentCatalog()).thenReturn(mockCatalog);
|
when(mockDocument.getDocumentCatalog()).thenReturn(mockCatalog);
|
||||||
when(mockDocument.getNumberOfPages()).thenReturn(5);
|
when(mockDocument.getNumberOfPages()).thenReturn(5);
|
||||||
when(mockDocument.getPage(0)).thenReturn(mockPage1);
|
when(mockDocument.getPage(0)).thenReturn(mockPage1);
|
||||||
|
|
||||||
// Mock saving behavior
|
// Mock saving behavior
|
||||||
doAnswer(invocation -> {
|
doAnswer(
|
||||||
ByteArrayOutputStream baos = invocation.getArgument(0);
|
invocation -> {
|
||||||
baos.write("mocked pdf content".getBytes());
|
ByteArrayOutputStream baos = invocation.getArgument(0);
|
||||||
return null;
|
baos.write("mocked pdf content".getBytes());
|
||||||
}).when(mockDocument).save(any(ByteArrayOutputStream.class));
|
return null;
|
||||||
|
})
|
||||||
|
.when(mockDocument)
|
||||||
|
.save(any(ByteArrayOutputStream.class));
|
||||||
|
|
||||||
// When
|
// When
|
||||||
ResponseEntity<byte[]> result = editTableOfContentsController.editTableOfContents(request);
|
ResponseEntity<byte[]> result = editTableOfContentsController.editTableOfContents(request);
|
||||||
@ -221,7 +225,8 @@ class EditTableOfContentsControllerTest {
|
|||||||
assertNotNull(result);
|
assertNotNull(result);
|
||||||
assertNotNull(result.getBody());
|
assertNotNull(result.getBody());
|
||||||
|
|
||||||
ArgumentCaptor<PDDocumentOutline> outlineCaptor = ArgumentCaptor.forClass(PDDocumentOutline.class);
|
ArgumentCaptor<PDDocumentOutline> outlineCaptor =
|
||||||
|
ArgumentCaptor.forClass(PDDocumentOutline.class);
|
||||||
verify(mockCatalog).setDocumentOutline(outlineCaptor.capture());
|
verify(mockCatalog).setDocumentOutline(outlineCaptor.capture());
|
||||||
|
|
||||||
PDDocumentOutline capturedOutline = outlineCaptor.getValue();
|
PDDocumentOutline capturedOutline = outlineCaptor.getValue();
|
||||||
@ -236,7 +241,8 @@ class EditTableOfContentsControllerTest {
|
|||||||
EditTableOfContentsRequest request = new EditTableOfContentsRequest();
|
EditTableOfContentsRequest request = new EditTableOfContentsRequest();
|
||||||
request.setFileInput(mockFile);
|
request.setFileInput(mockFile);
|
||||||
|
|
||||||
String bookmarkJson = "[{\"title\":\"Chapter 1\",\"pageNumber\":1,\"children\":[{\"title\":\"Section 1.1\",\"pageNumber\":2,\"children\":[]}]}]";
|
String bookmarkJson =
|
||||||
|
"[{\"title\":\"Chapter 1\",\"pageNumber\":1,\"children\":[{\"title\":\"Section 1.1\",\"pageNumber\":2,\"children\":[]}]}]";
|
||||||
request.setBookmarkData(bookmarkJson);
|
request.setBookmarkData(bookmarkJson);
|
||||||
|
|
||||||
List<BookmarkItem> bookmarks = new ArrayList<>();
|
List<BookmarkItem> bookmarks = new ArrayList<>();
|
||||||
@ -255,17 +261,21 @@ class EditTableOfContentsControllerTest {
|
|||||||
bookmarks.add(parentBookmark);
|
bookmarks.add(parentBookmark);
|
||||||
|
|
||||||
when(pdfDocumentFactory.load(mockFile)).thenReturn(mockDocument);
|
when(pdfDocumentFactory.load(mockFile)).thenReturn(mockDocument);
|
||||||
when(objectMapper.readValue(eq(bookmarkJson), any(TypeReference.class))).thenReturn(bookmarks);
|
when(objectMapper.readValue(eq(bookmarkJson), any(TypeReference.class)))
|
||||||
|
.thenReturn(bookmarks);
|
||||||
when(mockDocument.getDocumentCatalog()).thenReturn(mockCatalog);
|
when(mockDocument.getDocumentCatalog()).thenReturn(mockCatalog);
|
||||||
when(mockDocument.getNumberOfPages()).thenReturn(5);
|
when(mockDocument.getNumberOfPages()).thenReturn(5);
|
||||||
when(mockDocument.getPage(0)).thenReturn(mockPage1);
|
when(mockDocument.getPage(0)).thenReturn(mockPage1);
|
||||||
when(mockDocument.getPage(1)).thenReturn(mockPage2);
|
when(mockDocument.getPage(1)).thenReturn(mockPage2);
|
||||||
|
|
||||||
doAnswer(invocation -> {
|
doAnswer(
|
||||||
ByteArrayOutputStream baos = invocation.getArgument(0);
|
invocation -> {
|
||||||
baos.write("mocked pdf content".getBytes());
|
ByteArrayOutputStream baos = invocation.getArgument(0);
|
||||||
return null;
|
baos.write("mocked pdf content".getBytes());
|
||||||
}).when(mockDocument).save(any(ByteArrayOutputStream.class));
|
return null;
|
||||||
|
})
|
||||||
|
.when(mockDocument)
|
||||||
|
.save(any(ByteArrayOutputStream.class));
|
||||||
|
|
||||||
// When
|
// When
|
||||||
ResponseEntity<byte[]> result = editTableOfContentsController.editTableOfContents(request);
|
ResponseEntity<byte[]> result = editTableOfContentsController.editTableOfContents(request);
|
||||||
@ -281,7 +291,8 @@ class EditTableOfContentsControllerTest {
|
|||||||
// Given
|
// Given
|
||||||
EditTableOfContentsRequest request = new EditTableOfContentsRequest();
|
EditTableOfContentsRequest request = new EditTableOfContentsRequest();
|
||||||
request.setFileInput(mockFile);
|
request.setFileInput(mockFile);
|
||||||
request.setBookmarkData("[{\"title\":\"Chapter 1\",\"pageNumber\":-5,\"children\":[]},{\"title\":\"Chapter 2\",\"pageNumber\":100,\"children\":[]}]");
|
request.setBookmarkData(
|
||||||
|
"[{\"title\":\"Chapter 1\",\"pageNumber\":-5,\"children\":[]},{\"title\":\"Chapter 2\",\"pageNumber\":100,\"children\":[]}]");
|
||||||
|
|
||||||
List<BookmarkItem> bookmarks = new ArrayList<>();
|
List<BookmarkItem> bookmarks = new ArrayList<>();
|
||||||
|
|
||||||
@ -299,17 +310,21 @@ class EditTableOfContentsControllerTest {
|
|||||||
bookmarks.add(bookmark2);
|
bookmarks.add(bookmark2);
|
||||||
|
|
||||||
when(pdfDocumentFactory.load(mockFile)).thenReturn(mockDocument);
|
when(pdfDocumentFactory.load(mockFile)).thenReturn(mockDocument);
|
||||||
when(objectMapper.readValue(eq(request.getBookmarkData()), any(TypeReference.class))).thenReturn(bookmarks);
|
when(objectMapper.readValue(eq(request.getBookmarkData()), any(TypeReference.class)))
|
||||||
|
.thenReturn(bookmarks);
|
||||||
when(mockDocument.getDocumentCatalog()).thenReturn(mockCatalog);
|
when(mockDocument.getDocumentCatalog()).thenReturn(mockCatalog);
|
||||||
when(mockDocument.getNumberOfPages()).thenReturn(5);
|
when(mockDocument.getNumberOfPages()).thenReturn(5);
|
||||||
when(mockDocument.getPage(0)).thenReturn(mockPage1); // For negative page number
|
when(mockDocument.getPage(0)).thenReturn(mockPage1); // For negative page number
|
||||||
when(mockDocument.getPage(4)).thenReturn(mockPage2); // For page number exceeding bounds
|
when(mockDocument.getPage(4)).thenReturn(mockPage2); // For page number exceeding bounds
|
||||||
|
|
||||||
doAnswer(invocation -> {
|
doAnswer(
|
||||||
ByteArrayOutputStream baos = invocation.getArgument(0);
|
invocation -> {
|
||||||
baos.write("mocked pdf content".getBytes());
|
ByteArrayOutputStream baos = invocation.getArgument(0);
|
||||||
return null;
|
baos.write("mocked pdf content".getBytes());
|
||||||
}).when(mockDocument).save(any(ByteArrayOutputStream.class));
|
return null;
|
||||||
|
})
|
||||||
|
.when(mockDocument)
|
||||||
|
.save(any(ByteArrayOutputStream.class));
|
||||||
|
|
||||||
// When
|
// When
|
||||||
ResponseEntity<byte[]> result = editTableOfContentsController.editTableOfContents(request);
|
ResponseEntity<byte[]> result = editTableOfContentsController.editTableOfContents(request);
|
||||||
@ -332,16 +347,20 @@ class EditTableOfContentsControllerTest {
|
|||||||
when(mockDocument.getPage(2)).thenReturn(mockPage1); // 0-indexed
|
when(mockDocument.getPage(2)).thenReturn(mockPage1); // 0-indexed
|
||||||
|
|
||||||
// When
|
// When
|
||||||
Method createOutlineItemMethod = EditTableOfContentsController.class.getDeclaredMethod("createOutlineItem", PDDocument.class, BookmarkItem.class);
|
Method createOutlineItemMethod =
|
||||||
|
EditTableOfContentsController.class.getDeclaredMethod(
|
||||||
|
"createOutlineItem", PDDocument.class, BookmarkItem.class);
|
||||||
createOutlineItemMethod.setAccessible(true);
|
createOutlineItemMethod.setAccessible(true);
|
||||||
PDOutlineItem result = (PDOutlineItem) createOutlineItemMethod.invoke(editTableOfContentsController, mockDocument, bookmark);
|
PDOutlineItem result =
|
||||||
|
(PDOutlineItem)
|
||||||
|
createOutlineItemMethod.invoke(
|
||||||
|
editTableOfContentsController, mockDocument, bookmark);
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
assertNotNull(result);
|
assertNotNull(result);
|
||||||
verify(mockDocument).getPage(2);
|
verify(mockDocument).getPage(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testBookmarkItem_GettersAndSetters() {
|
void testBookmarkItem_GettersAndSetters() {
|
||||||
// Given
|
// Given
|
||||||
@ -365,18 +384,24 @@ class EditTableOfContentsControllerTest {
|
|||||||
EditTableOfContentsRequest request = new EditTableOfContentsRequest();
|
EditTableOfContentsRequest request = new EditTableOfContentsRequest();
|
||||||
request.setFileInput(mockFile);
|
request.setFileInput(mockFile);
|
||||||
|
|
||||||
when(pdfDocumentFactory.load(mockFile)).thenThrow(new RuntimeException("Failed to load PDF"));
|
when(pdfDocumentFactory.load(mockFile))
|
||||||
|
.thenThrow(new RuntimeException("Failed to load PDF"));
|
||||||
|
|
||||||
// When & Then
|
// When & Then
|
||||||
assertThrows(RuntimeException.class, () -> editTableOfContentsController.editTableOfContents(request));
|
assertThrows(
|
||||||
|
RuntimeException.class,
|
||||||
|
() -> editTableOfContentsController.editTableOfContents(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testExtractBookmarks_IOExceptionDuringLoad_ThrowsException() throws Exception {
|
void testExtractBookmarks_IOExceptionDuringLoad_ThrowsException() throws Exception {
|
||||||
// Given
|
// Given
|
||||||
when(pdfDocumentFactory.load(mockFile)).thenThrow(new RuntimeException("Failed to load PDF"));
|
when(pdfDocumentFactory.load(mockFile))
|
||||||
|
.thenThrow(new RuntimeException("Failed to load PDF"));
|
||||||
|
|
||||||
// When & Then
|
// When & Then
|
||||||
assertThrows(RuntimeException.class, () -> editTableOfContentsController.extractBookmarks(mockFile));
|
assertThrows(
|
||||||
|
RuntimeException.class,
|
||||||
|
() -> editTableOfContentsController.extractBookmarks(mockFile));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,11 +29,9 @@ import stirling.software.common.service.CustomPDFDocumentFactory;
|
|||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class MergeControllerTest {
|
class MergeControllerTest {
|
||||||
|
|
||||||
@Mock
|
@Mock private CustomPDFDocumentFactory pdfDocumentFactory;
|
||||||
private CustomPDFDocumentFactory pdfDocumentFactory;
|
|
||||||
|
|
||||||
@InjectMocks
|
@InjectMocks private MergeController mergeController;
|
||||||
private MergeController mergeController;
|
|
||||||
|
|
||||||
private MockMultipartFile mockFile1;
|
private MockMultipartFile mockFile1;
|
||||||
private MockMultipartFile mockFile2;
|
private MockMultipartFile mockFile2;
|
||||||
@ -47,9 +45,15 @@ class MergeControllerTest {
|
|||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setUp() {
|
void setUp() {
|
||||||
mockFile1 = new MockMultipartFile("file1", "document1.pdf", "application/pdf", "PDF content 1".getBytes());
|
mockFile1 =
|
||||||
mockFile2 = new MockMultipartFile("file2", "document2.pdf", "application/pdf", "PDF content 2".getBytes());
|
new MockMultipartFile(
|
||||||
mockFile3 = new MockMultipartFile("file3", "chapter3.pdf", "application/pdf", "PDF content 3".getBytes());
|
"file1", "document1.pdf", "application/pdf", "PDF content 1".getBytes());
|
||||||
|
mockFile2 =
|
||||||
|
new MockMultipartFile(
|
||||||
|
"file2", "document2.pdf", "application/pdf", "PDF content 2".getBytes());
|
||||||
|
mockFile3 =
|
||||||
|
new MockMultipartFile(
|
||||||
|
"file3", "chapter3.pdf", "application/pdf", "PDF content 3".getBytes());
|
||||||
|
|
||||||
mockDocument = mock(PDDocument.class);
|
mockDocument = mock(PDDocument.class);
|
||||||
mockMergedDocument = mock(PDDocument.class);
|
mockMergedDocument = mock(PDDocument.class);
|
||||||
@ -85,12 +89,15 @@ class MergeControllerTest {
|
|||||||
when(doc3.getNumberOfPages()).thenReturn(2);
|
when(doc3.getNumberOfPages()).thenReturn(2);
|
||||||
|
|
||||||
// When
|
// When
|
||||||
Method addTableOfContentsMethod = MergeController.class.getDeclaredMethod("addTableOfContents", PDDocument.class, MultipartFile[].class);
|
Method addTableOfContentsMethod =
|
||||||
|
MergeController.class.getDeclaredMethod(
|
||||||
|
"addTableOfContents", PDDocument.class, MultipartFile[].class);
|
||||||
addTableOfContentsMethod.setAccessible(true);
|
addTableOfContentsMethod.setAccessible(true);
|
||||||
addTableOfContentsMethod.invoke(mergeController, mockMergedDocument, files);
|
addTableOfContentsMethod.invoke(mergeController, mockMergedDocument, files);
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
ArgumentCaptor<PDDocumentOutline> outlineCaptor = ArgumentCaptor.forClass(PDDocumentOutline.class);
|
ArgumentCaptor<PDDocumentOutline> outlineCaptor =
|
||||||
|
ArgumentCaptor.forClass(PDDocumentOutline.class);
|
||||||
verify(mockCatalog).setDocumentOutline(outlineCaptor.capture());
|
verify(mockCatalog).setDocumentOutline(outlineCaptor.capture());
|
||||||
|
|
||||||
PDDocumentOutline capturedOutline = outlineCaptor.getValue();
|
PDDocumentOutline capturedOutline = outlineCaptor.getValue();
|
||||||
@ -121,7 +128,9 @@ class MergeControllerTest {
|
|||||||
when(doc1.getNumberOfPages()).thenReturn(3);
|
when(doc1.getNumberOfPages()).thenReturn(3);
|
||||||
|
|
||||||
// When
|
// When
|
||||||
Method addTableOfContentsMethod = MergeController.class.getDeclaredMethod("addTableOfContents", PDDocument.class, MultipartFile[].class);
|
Method addTableOfContentsMethod =
|
||||||
|
MergeController.class.getDeclaredMethod(
|
||||||
|
"addTableOfContents", PDDocument.class, MultipartFile[].class);
|
||||||
addTableOfContentsMethod.setAccessible(true);
|
addTableOfContentsMethod.setAccessible(true);
|
||||||
addTableOfContentsMethod.invoke(mergeController, mockMergedDocument, files);
|
addTableOfContentsMethod.invoke(mergeController, mockMergedDocument, files);
|
||||||
|
|
||||||
@ -138,7 +147,9 @@ class MergeControllerTest {
|
|||||||
when(mockMergedDocument.getDocumentCatalog()).thenReturn(mockCatalog);
|
when(mockMergedDocument.getDocumentCatalog()).thenReturn(mockCatalog);
|
||||||
|
|
||||||
// When
|
// When
|
||||||
Method addTableOfContentsMethod = MergeController.class.getDeclaredMethod("addTableOfContents", PDDocument.class, MultipartFile[].class);
|
Method addTableOfContentsMethod =
|
||||||
|
MergeController.class.getDeclaredMethod(
|
||||||
|
"addTableOfContents", PDDocument.class, MultipartFile[].class);
|
||||||
addTableOfContentsMethod.setAccessible(true);
|
addTableOfContentsMethod.setAccessible(true);
|
||||||
addTableOfContentsMethod.invoke(mergeController, mockMergedDocument, files);
|
addTableOfContentsMethod.invoke(mergeController, mockMergedDocument, files);
|
||||||
|
|
||||||
@ -155,7 +166,8 @@ class MergeControllerTest {
|
|||||||
|
|
||||||
when(mockMergedDocument.getDocumentCatalog()).thenReturn(mockCatalog);
|
when(mockMergedDocument.getDocumentCatalog()).thenReturn(mockCatalog);
|
||||||
when(mockMergedDocument.getNumberOfPages()).thenReturn(4);
|
when(mockMergedDocument.getNumberOfPages()).thenReturn(4);
|
||||||
when(mockMergedDocument.getPage(anyInt())).thenReturn(mockPage1); // Use anyInt() to avoid stubbing conflicts
|
when(mockMergedDocument.getPage(anyInt()))
|
||||||
|
.thenReturn(mockPage1); // Use anyInt() to avoid stubbing conflicts
|
||||||
|
|
||||||
// First document loads successfully
|
// First document loads successfully
|
||||||
PDDocument doc1 = mock(PDDocument.class);
|
PDDocument doc1 = mock(PDDocument.class);
|
||||||
@ -163,16 +175,18 @@ class MergeControllerTest {
|
|||||||
when(doc1.getNumberOfPages()).thenReturn(2);
|
when(doc1.getNumberOfPages()).thenReturn(2);
|
||||||
|
|
||||||
// Second document throws IOException
|
// Second document throws IOException
|
||||||
when(pdfDocumentFactory.load(mockFile2)).thenThrow(new IOException("Failed to load document"));
|
when(pdfDocumentFactory.load(mockFile2))
|
||||||
|
.thenThrow(new IOException("Failed to load document"));
|
||||||
|
|
||||||
// When
|
// When
|
||||||
Method addTableOfContentsMethod = MergeController.class.getDeclaredMethod("addTableOfContents", PDDocument.class, MultipartFile[].class);
|
Method addTableOfContentsMethod =
|
||||||
|
MergeController.class.getDeclaredMethod(
|
||||||
|
"addTableOfContents", PDDocument.class, MultipartFile[].class);
|
||||||
addTableOfContentsMethod.setAccessible(true);
|
addTableOfContentsMethod.setAccessible(true);
|
||||||
|
|
||||||
// Should not throw exception
|
// Should not throw exception
|
||||||
assertDoesNotThrow(() ->
|
assertDoesNotThrow(
|
||||||
addTableOfContentsMethod.invoke(mergeController, mockMergedDocument, files)
|
() -> addTableOfContentsMethod.invoke(mergeController, mockMergedDocument, files));
|
||||||
);
|
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
verify(mockCatalog).setDocumentOutline(any(PDDocumentOutline.class));
|
verify(mockCatalog).setDocumentOutline(any(PDDocumentOutline.class));
|
||||||
@ -184,7 +198,9 @@ class MergeControllerTest {
|
|||||||
@Test
|
@Test
|
||||||
void testAddTableOfContents_FilenameWithoutExtension_UsesFullName() throws Exception {
|
void testAddTableOfContents_FilenameWithoutExtension_UsesFullName() throws Exception {
|
||||||
// Given
|
// Given
|
||||||
MockMultipartFile fileWithoutExtension = new MockMultipartFile("file", "document_no_ext", "application/pdf", "PDF content".getBytes());
|
MockMultipartFile fileWithoutExtension =
|
||||||
|
new MockMultipartFile(
|
||||||
|
"file", "document_no_ext", "application/pdf", "PDF content".getBytes());
|
||||||
MultipartFile[] files = {fileWithoutExtension};
|
MultipartFile[] files = {fileWithoutExtension};
|
||||||
|
|
||||||
when(mockMergedDocument.getDocumentCatalog()).thenReturn(mockCatalog);
|
when(mockMergedDocument.getDocumentCatalog()).thenReturn(mockCatalog);
|
||||||
@ -196,7 +212,9 @@ class MergeControllerTest {
|
|||||||
when(doc.getNumberOfPages()).thenReturn(1);
|
when(doc.getNumberOfPages()).thenReturn(1);
|
||||||
|
|
||||||
// When
|
// When
|
||||||
Method addTableOfContentsMethod = MergeController.class.getDeclaredMethod("addTableOfContents", PDDocument.class, MultipartFile[].class);
|
Method addTableOfContentsMethod =
|
||||||
|
MergeController.class.getDeclaredMethod(
|
||||||
|
"addTableOfContents", PDDocument.class, MultipartFile[].class);
|
||||||
addTableOfContentsMethod.setAccessible(true);
|
addTableOfContentsMethod.setAccessible(true);
|
||||||
addTableOfContentsMethod.invoke(mergeController, mockMergedDocument, files);
|
addTableOfContentsMethod.invoke(mergeController, mockMergedDocument, files);
|
||||||
|
|
||||||
@ -218,13 +236,14 @@ class MergeControllerTest {
|
|||||||
when(doc1.getNumberOfPages()).thenReturn(3);
|
when(doc1.getNumberOfPages()).thenReturn(3);
|
||||||
|
|
||||||
// When
|
// When
|
||||||
Method addTableOfContentsMethod = MergeController.class.getDeclaredMethod("addTableOfContents", PDDocument.class, MultipartFile[].class);
|
Method addTableOfContentsMethod =
|
||||||
|
MergeController.class.getDeclaredMethod(
|
||||||
|
"addTableOfContents", PDDocument.class, MultipartFile[].class);
|
||||||
addTableOfContentsMethod.setAccessible(true);
|
addTableOfContentsMethod.setAccessible(true);
|
||||||
|
|
||||||
// Should not throw exception
|
// Should not throw exception
|
||||||
assertDoesNotThrow(() ->
|
assertDoesNotThrow(
|
||||||
addTableOfContentsMethod.invoke(mergeController, mockMergedDocument, files)
|
() -> addTableOfContentsMethod.invoke(mergeController, mockMergedDocument, files));
|
||||||
);
|
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
verify(mockCatalog).setDocumentOutline(any(PDDocumentOutline.class));
|
verify(mockCatalog).setDocumentOutline(any(PDDocumentOutline.class));
|
||||||
@ -275,5 +294,4 @@ class MergeControllerTest {
|
|||||||
assertEquals(mockMergedDocument, result);
|
assertEquals(mockMergedDocument, result);
|
||||||
verify(mockMergedDocument, never()).addPage(any(PDPage.class));
|
verify(mockMergedDocument, never()).addPage(any(PDPage.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,6 @@ import static org.junit.jupiter.api.Assertions.*;
|
|||||||
import static org.mockito.ArgumentMatchers.*;
|
import static org.mockito.ArgumentMatchers.*;
|
||||||
import static org.mockito.Mockito.*;
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
import org.mockito.MockedStatic;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -15,6 +13,7 @@ import org.junit.jupiter.api.Test;
|
|||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.mockito.InjectMocks;
|
import org.mockito.InjectMocks;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockedStatic;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
@ -29,14 +28,11 @@ import stirling.software.common.util.WebResponseUtils;
|
|||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class AttachmentControllerTest {
|
class AttachmentControllerTest {
|
||||||
|
|
||||||
@Mock
|
@Mock private CustomPDFDocumentFactory pdfDocumentFactory;
|
||||||
private CustomPDFDocumentFactory pdfDocumentFactory;
|
|
||||||
|
|
||||||
@Mock
|
@Mock private AttachmentServiceInterface pdfAttachmentService;
|
||||||
private AttachmentServiceInterface pdfAttachmentService;
|
|
||||||
|
|
||||||
@InjectMocks
|
@InjectMocks private AttachmentController attachmentController;
|
||||||
private AttachmentController attachmentController;
|
|
||||||
|
|
||||||
private MockMultipartFile pdfFile;
|
private MockMultipartFile pdfFile;
|
||||||
private MockMultipartFile attachment1;
|
private MockMultipartFile attachment1;
|
||||||
@ -47,9 +43,15 @@ class AttachmentControllerTest {
|
|||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setUp() {
|
void setUp() {
|
||||||
pdfFile = new MockMultipartFile("fileInput", "test.pdf", "application/pdf", "PDF content".getBytes());
|
pdfFile =
|
||||||
attachment1 = new MockMultipartFile("attachment1", "file1.txt", "text/plain", "File 1 content".getBytes());
|
new MockMultipartFile(
|
||||||
attachment2 = new MockMultipartFile("attachment2", "file2.jpg", "image/jpeg", "Image content".getBytes());
|
"fileInput", "test.pdf", "application/pdf", "PDF content".getBytes());
|
||||||
|
attachment1 =
|
||||||
|
new MockMultipartFile(
|
||||||
|
"attachment1", "file1.txt", "text/plain", "File 1 content".getBytes());
|
||||||
|
attachment2 =
|
||||||
|
new MockMultipartFile(
|
||||||
|
"attachment2", "file2.jpg", "image/jpeg", "Image content".getBytes());
|
||||||
request = new AddAttachmentRequest();
|
request = new AddAttachmentRequest();
|
||||||
mockDocument = mock(PDDocument.class);
|
mockDocument = mock(PDDocument.class);
|
||||||
modifiedMockDocument = mock(PDDocument.class);
|
modifiedMockDocument = mock(PDDocument.class);
|
||||||
@ -60,13 +62,21 @@ class AttachmentControllerTest {
|
|||||||
List<MultipartFile> attachments = List.of(attachment1, attachment2);
|
List<MultipartFile> attachments = List.of(attachment1, attachment2);
|
||||||
request.setAttachments(attachments);
|
request.setAttachments(attachments);
|
||||||
request.setFileInput(pdfFile);
|
request.setFileInput(pdfFile);
|
||||||
ResponseEntity<byte[]> expectedResponse = ResponseEntity.ok("modified PDF content".getBytes());
|
ResponseEntity<byte[]> expectedResponse =
|
||||||
|
ResponseEntity.ok("modified PDF content".getBytes());
|
||||||
|
|
||||||
when(pdfDocumentFactory.load(pdfFile, false)).thenReturn(mockDocument);
|
when(pdfDocumentFactory.load(pdfFile, false)).thenReturn(mockDocument);
|
||||||
when(pdfAttachmentService.addAttachment(mockDocument, attachments)).thenReturn(modifiedMockDocument);
|
when(pdfAttachmentService.addAttachment(mockDocument, attachments))
|
||||||
|
.thenReturn(modifiedMockDocument);
|
||||||
|
|
||||||
try (MockedStatic<WebResponseUtils> mockedWebResponseUtils = mockStatic(WebResponseUtils.class)) {
|
try (MockedStatic<WebResponseUtils> mockedWebResponseUtils =
|
||||||
mockedWebResponseUtils.when(() -> WebResponseUtils.pdfDocToWebResponse(eq(modifiedMockDocument), eq("test_with_attachments.pdf")))
|
mockStatic(WebResponseUtils.class)) {
|
||||||
|
mockedWebResponseUtils
|
||||||
|
.when(
|
||||||
|
() ->
|
||||||
|
WebResponseUtils.pdfDocToWebResponse(
|
||||||
|
eq(modifiedMockDocument),
|
||||||
|
eq("test_with_attachments.pdf")))
|
||||||
.thenReturn(expectedResponse);
|
.thenReturn(expectedResponse);
|
||||||
|
|
||||||
ResponseEntity<byte[]> response = attachmentController.addAttachments(request);
|
ResponseEntity<byte[]> response = attachmentController.addAttachments(request);
|
||||||
@ -84,13 +94,21 @@ class AttachmentControllerTest {
|
|||||||
List<MultipartFile> attachments = List.of(attachment1);
|
List<MultipartFile> attachments = List.of(attachment1);
|
||||||
request.setAttachments(attachments);
|
request.setAttachments(attachments);
|
||||||
request.setFileInput(pdfFile);
|
request.setFileInput(pdfFile);
|
||||||
ResponseEntity<byte[]> expectedResponse = ResponseEntity.ok("modified PDF content".getBytes());
|
ResponseEntity<byte[]> expectedResponse =
|
||||||
|
ResponseEntity.ok("modified PDF content".getBytes());
|
||||||
|
|
||||||
when(pdfDocumentFactory.load(pdfFile, false)).thenReturn(mockDocument);
|
when(pdfDocumentFactory.load(pdfFile, false)).thenReturn(mockDocument);
|
||||||
when(pdfAttachmentService.addAttachment(mockDocument, attachments)).thenReturn(modifiedMockDocument);
|
when(pdfAttachmentService.addAttachment(mockDocument, attachments))
|
||||||
|
.thenReturn(modifiedMockDocument);
|
||||||
|
|
||||||
try (MockedStatic<WebResponseUtils> mockedWebResponseUtils = mockStatic(WebResponseUtils.class)) {
|
try (MockedStatic<WebResponseUtils> mockedWebResponseUtils =
|
||||||
mockedWebResponseUtils.when(() -> WebResponseUtils.pdfDocToWebResponse(eq(modifiedMockDocument), eq("test_with_attachments.pdf")))
|
mockStatic(WebResponseUtils.class)) {
|
||||||
|
mockedWebResponseUtils
|
||||||
|
.when(
|
||||||
|
() ->
|
||||||
|
WebResponseUtils.pdfDocToWebResponse(
|
||||||
|
eq(modifiedMockDocument),
|
||||||
|
eq("test_with_attachments.pdf")))
|
||||||
.thenReturn(expectedResponse);
|
.thenReturn(expectedResponse);
|
||||||
|
|
||||||
ResponseEntity<byte[]> response = attachmentController.addAttachments(request);
|
ResponseEntity<byte[]> response = attachmentController.addAttachments(request);
|
||||||
|
@ -20,11 +20,11 @@ import org.springframework.http.ResponseEntity;
|
|||||||
|
|
||||||
import jakarta.servlet.ServletContext;
|
import jakarta.servlet.ServletContext;
|
||||||
|
|
||||||
import stirling.software.common.service.UserServiceInterface;
|
|
||||||
import stirling.software.SPDF.model.PipelineConfig;
|
import stirling.software.SPDF.model.PipelineConfig;
|
||||||
import stirling.software.SPDF.model.PipelineOperation;
|
import stirling.software.SPDF.model.PipelineOperation;
|
||||||
import stirling.software.SPDF.model.PipelineResult;
|
import stirling.software.SPDF.model.PipelineResult;
|
||||||
import stirling.software.SPDF.service.ApiDocService;
|
import stirling.software.SPDF.service.ApiDocService;
|
||||||
|
import stirling.software.common.service.UserServiceInterface;
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class PipelineProcessorTest {
|
class PipelineProcessorTest {
|
||||||
@ -45,23 +45,26 @@ class PipelineProcessorTest {
|
|||||||
@Test
|
@Test
|
||||||
void runPipelineWithFilterSetsFlag() throws Exception {
|
void runPipelineWithFilterSetsFlag() throws Exception {
|
||||||
PipelineOperation op = new PipelineOperation();
|
PipelineOperation op = new PipelineOperation();
|
||||||
op.setOperation("filter-page-count");
|
op.setOperation("/api/v1/filter/filter-page-count");
|
||||||
op.setParameters(Map.of());
|
op.setParameters(Map.of());
|
||||||
PipelineConfig config = new PipelineConfig();
|
PipelineConfig config = new PipelineConfig();
|
||||||
config.setOperations(List.of(op));
|
config.setOperations(List.of(op));
|
||||||
|
|
||||||
Resource file = new ByteArrayResource("data".getBytes()) {
|
Resource file =
|
||||||
@Override
|
new ByteArrayResource("data".getBytes()) {
|
||||||
public String getFilename() {
|
@Override
|
||||||
return "test.pdf";
|
public String getFilename() {
|
||||||
}
|
return "test.pdf";
|
||||||
};
|
}
|
||||||
|
};
|
||||||
|
|
||||||
List<Resource> files = List.of(file);
|
List<Resource> files = List.of(file);
|
||||||
|
|
||||||
when(apiDocService.isMultiInput("filter-page-count")).thenReturn(false);
|
when(apiDocService.isMultiInput("/api/v1/filter/filter-page-count")).thenReturn(false);
|
||||||
when(apiDocService.getExtensionTypes(false, "filter-page-count"))
|
when(apiDocService.getExtensionTypes(false, "/api/v1/filter/filter-page-count"))
|
||||||
.thenReturn(List.of("pdf"));
|
.thenReturn(List.of("pdf"));
|
||||||
|
when(apiDocService.isValidOperation(eq("/api/v1/filter/filter-page-count"), anyMap()))
|
||||||
|
.thenReturn(true);
|
||||||
|
|
||||||
doReturn(new ResponseEntity<>(new byte[0], HttpStatus.OK))
|
doReturn(new ResponseEntity<>(new byte[0], HttpStatus.OK))
|
||||||
.when(pipelineProcessor)
|
.when(pipelineProcessor)
|
||||||
|
@ -1,15 +1,17 @@
|
|||||||
package stirling.software.SPDF.service;
|
package stirling.software.SPDF.service;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
class AttachmentServiceTest {
|
class AttachmentServiceTest {
|
||||||
|
|
||||||
@ -27,8 +29,8 @@ class AttachmentServiceTest {
|
|||||||
var attachments = List.of(mock(MultipartFile.class));
|
var attachments = List.of(mock(MultipartFile.class));
|
||||||
|
|
||||||
when(attachments.get(0).getOriginalFilename()).thenReturn("test.txt");
|
when(attachments.get(0).getOriginalFilename()).thenReturn("test.txt");
|
||||||
when(attachments.get(0).getInputStream()).thenReturn(
|
when(attachments.get(0).getInputStream())
|
||||||
new ByteArrayInputStream("Test content".getBytes()));
|
.thenReturn(new ByteArrayInputStream("Test content".getBytes()));
|
||||||
when(attachments.get(0).getSize()).thenReturn(12L);
|
when(attachments.get(0).getSize()).thenReturn(12L);
|
||||||
when(attachments.get(0).getContentType()).thenReturn("text/plain");
|
when(attachments.get(0).getContentType()).thenReturn("text/plain");
|
||||||
|
|
||||||
@ -49,14 +51,14 @@ class AttachmentServiceTest {
|
|||||||
var attachments = List.of(attachment1, attachment2);
|
var attachments = List.of(attachment1, attachment2);
|
||||||
|
|
||||||
when(attachment1.getOriginalFilename()).thenReturn("document.pdf");
|
when(attachment1.getOriginalFilename()).thenReturn("document.pdf");
|
||||||
when(attachment1.getInputStream()).thenReturn(
|
when(attachment1.getInputStream())
|
||||||
new ByteArrayInputStream("PDF content".getBytes()));
|
.thenReturn(new ByteArrayInputStream("PDF content".getBytes()));
|
||||||
when(attachment1.getSize()).thenReturn(15L);
|
when(attachment1.getSize()).thenReturn(15L);
|
||||||
when(attachment1.getContentType()).thenReturn("application/pdf");
|
when(attachment1.getContentType()).thenReturn("application/pdf");
|
||||||
|
|
||||||
when(attachment2.getOriginalFilename()).thenReturn("image.jpg");
|
when(attachment2.getOriginalFilename()).thenReturn("image.jpg");
|
||||||
when(attachment2.getInputStream()).thenReturn(
|
when(attachment2.getInputStream())
|
||||||
new ByteArrayInputStream("Image content".getBytes()));
|
.thenReturn(new ByteArrayInputStream("Image content".getBytes()));
|
||||||
when(attachment2.getSize()).thenReturn(20L);
|
when(attachment2.getSize()).thenReturn(20L);
|
||||||
when(attachment2.getContentType()).thenReturn("image/jpeg");
|
when(attachment2.getContentType()).thenReturn("image/jpeg");
|
||||||
|
|
||||||
@ -74,8 +76,8 @@ class AttachmentServiceTest {
|
|||||||
var attachments = List.of(mock(MultipartFile.class));
|
var attachments = List.of(mock(MultipartFile.class));
|
||||||
|
|
||||||
when(attachments.get(0).getOriginalFilename()).thenReturn("image.jpg");
|
when(attachments.get(0).getOriginalFilename()).thenReturn("image.jpg");
|
||||||
when(attachments.get(0).getInputStream()).thenReturn(
|
when(attachments.get(0).getInputStream())
|
||||||
new ByteArrayInputStream("Image content".getBytes()));
|
.thenReturn(new ByteArrayInputStream("Image content".getBytes()));
|
||||||
when(attachments.get(0).getSize()).thenReturn(25L);
|
when(attachments.get(0).getSize()).thenReturn(25L);
|
||||||
when(attachments.get(0).getContentType()).thenReturn("");
|
when(attachments.get(0).getContentType()).thenReturn("");
|
||||||
|
|
||||||
|
@ -17,8 +17,8 @@ import org.junit.jupiter.api.Test;
|
|||||||
import org.junit.jupiter.api.io.TempDir;
|
import org.junit.jupiter.api.io.TempDir;
|
||||||
import org.mockito.MockedStatic;
|
import org.mockito.MockedStatic;
|
||||||
|
|
||||||
import stirling.software.common.configuration.InstallationPathConfig;
|
|
||||||
import stirling.software.SPDF.model.SignatureFile;
|
import stirling.software.SPDF.model.SignatureFile;
|
||||||
|
import stirling.software.common.configuration.InstallationPathConfig;
|
||||||
|
|
||||||
class SignatureServiceTest {
|
class SignatureServiceTest {
|
||||||
|
|
||||||
|
@ -12,36 +12,28 @@ import org.mockito.Mock;
|
|||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.mock.web.MockHttpServletRequest;
|
|
||||||
import org.springframework.mock.web.MockHttpSession;
|
import org.springframework.mock.web.MockHttpSession;
|
||||||
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpSession;
|
|
||||||
|
|
||||||
import stirling.software.common.model.job.JobResult;
|
import stirling.software.common.model.job.JobResult;
|
||||||
import stirling.software.common.model.job.JobStats;
|
|
||||||
import stirling.software.common.model.job.ResultFile;
|
|
||||||
import stirling.software.common.service.FileStorage;
|
import stirling.software.common.service.FileStorage;
|
||||||
import stirling.software.common.service.JobQueue;
|
import stirling.software.common.service.JobQueue;
|
||||||
import stirling.software.common.service.TaskManager;
|
import stirling.software.common.service.TaskManager;
|
||||||
|
|
||||||
class JobControllerTest {
|
class JobControllerTest {
|
||||||
|
|
||||||
@Mock
|
@Mock private TaskManager taskManager;
|
||||||
private TaskManager taskManager;
|
|
||||||
|
|
||||||
@Mock
|
@Mock private FileStorage fileStorage;
|
||||||
private FileStorage fileStorage;
|
|
||||||
|
|
||||||
@Mock
|
@Mock private JobQueue jobQueue;
|
||||||
private JobQueue jobQueue;
|
|
||||||
|
|
||||||
@Mock
|
@Mock private HttpServletRequest request;
|
||||||
private HttpServletRequest request;
|
|
||||||
|
|
||||||
private MockHttpSession session;
|
private MockHttpSession session;
|
||||||
|
|
||||||
@InjectMocks
|
@InjectMocks private JobController controller;
|
||||||
private JobController controller;
|
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setUp() {
|
void setUp() {
|
||||||
@ -139,7 +131,8 @@ class JobControllerTest {
|
|||||||
|
|
||||||
JobResult mockResult = new JobResult();
|
JobResult mockResult = new JobResult();
|
||||||
mockResult.setJobId(jobId);
|
mockResult.setJobId(jobId);
|
||||||
mockResult.completeWithSingleFile(fileId, originalFileName, contentType, fileContent.length);
|
mockResult.completeWithSingleFile(
|
||||||
|
fileId, originalFileName, contentType, fileContent.length);
|
||||||
|
|
||||||
when(taskManager.getJobResult(jobId)).thenReturn(mockResult);
|
when(taskManager.getJobResult(jobId)).thenReturn(mockResult);
|
||||||
when(fileStorage.retrieveBytes(fileId)).thenReturn(fileContent);
|
when(fileStorage.retrieveBytes(fileId)).thenReturn(fileContent);
|
||||||
@ -150,7 +143,8 @@ class JobControllerTest {
|
|||||||
// Assert
|
// Assert
|
||||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
assertEquals(contentType, response.getHeaders().getFirst("Content-Type"));
|
assertEquals(contentType, response.getHeaders().getFirst("Content-Type"));
|
||||||
assertTrue(response.getHeaders().getFirst("Content-Disposition").contains(originalFileName));
|
assertTrue(
|
||||||
|
response.getHeaders().getFirst("Content-Disposition").contains(originalFileName));
|
||||||
assertEquals(fileContent, response.getBody());
|
assertEquals(fileContent, response.getBody());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,45 +223,45 @@ class JobControllerTest {
|
|||||||
assertTrue(response.getBody().toString().contains("Error retrieving file"));
|
assertTrue(response.getBody().toString().contains("Error retrieving file"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @Test void testGetJobStats() { // Arrange JobStats mockStats =
|
* @Test void testGetJobStats() { // Arrange JobStats mockStats =
|
||||||
* JobStats.builder() .totalJobs(10) .activeJobs(3) .completedJobs(7) .build();
|
* JobStats.builder() .totalJobs(10) .activeJobs(3) .completedJobs(7) .build();
|
||||||
*
|
*
|
||||||
* when(taskManager.getJobStats()).thenReturn(mockStats);
|
* when(taskManager.getJobStats()).thenReturn(mockStats);
|
||||||
*
|
*
|
||||||
* // Act ResponseEntity<?> response = controller.getJobStats();
|
* // Act ResponseEntity<?> response = controller.getJobStats();
|
||||||
*
|
*
|
||||||
* // Assert assertEquals(HttpStatus.OK, response.getStatusCode());
|
* // Assert assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
* assertEquals(mockStats, response.getBody()); }
|
* assertEquals(mockStats, response.getBody()); }
|
||||||
*
|
*
|
||||||
* @Test void testCleanupOldJobs() { // Arrange when(taskManager.getJobStats())
|
* @Test void testCleanupOldJobs() { // Arrange when(taskManager.getJobStats())
|
||||||
* .thenReturn(JobStats.builder().totalJobs(10).build())
|
* .thenReturn(JobStats.builder().totalJobs(10).build())
|
||||||
* .thenReturn(JobStats.builder().totalJobs(7).build());
|
* .thenReturn(JobStats.builder().totalJobs(7).build());
|
||||||
*
|
*
|
||||||
* // Act ResponseEntity<?> response = controller.cleanupOldJobs();
|
* // Act ResponseEntity<?> response = controller.cleanupOldJobs();
|
||||||
*
|
*
|
||||||
* // Assert assertEquals(HttpStatus.OK, response.getStatusCode());
|
* // Assert assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
*
|
*
|
||||||
* @SuppressWarnings("unchecked") Map<String, Object> responseBody =
|
* @SuppressWarnings("unchecked") Map<String, Object> responseBody =
|
||||||
* (Map<String, Object>) response.getBody(); assertEquals("Cleanup complete",
|
* (Map<String, Object>) response.getBody(); assertEquals("Cleanup complete",
|
||||||
* responseBody.get("message")); assertEquals(3,
|
* responseBody.get("message")); assertEquals(3,
|
||||||
* responseBody.get("removedJobs")); assertEquals(7,
|
* responseBody.get("removedJobs")); assertEquals(7,
|
||||||
* responseBody.get("remainingJobs"));
|
* responseBody.get("remainingJobs"));
|
||||||
*
|
*
|
||||||
* verify(taskManager).cleanupOldJobs(); }
|
* verify(taskManager).cleanupOldJobs(); }
|
||||||
*
|
*
|
||||||
* @Test void testGetQueueStats() { // Arrange Map<String, Object>
|
* @Test void testGetQueueStats() { // Arrange Map<String, Object>
|
||||||
* mockQueueStats = Map.of( "queuedJobs", 5, "queueCapacity", 10,
|
* mockQueueStats = Map.of( "queuedJobs", 5, "queueCapacity", 10,
|
||||||
* "resourceStatus", "OK" );
|
* "resourceStatus", "OK" );
|
||||||
*
|
*
|
||||||
* when(jobQueue.getQueueStats()).thenReturn(mockQueueStats);
|
* when(jobQueue.getQueueStats()).thenReturn(mockQueueStats);
|
||||||
*
|
*
|
||||||
* // Act ResponseEntity<?> response = controller.getQueueStats();
|
* // Act ResponseEntity<?> response = controller.getQueueStats();
|
||||||
*
|
*
|
||||||
* // Assert assertEquals(HttpStatus.OK, response.getStatusCode());
|
* // Assert assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
* assertEquals(mockQueueStats, response.getBody());
|
* assertEquals(mockQueueStats, response.getBody());
|
||||||
* verify(jobQueue).getQueueStats(); }
|
* verify(jobQueue).getQueueStats(); }
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
void testCancelJob_InQueue() {
|
void testCancelJob_InQueue() {
|
||||||
// Arrange
|
// Arrange
|
||||||
|
@ -5,8 +5,8 @@ bootRun {
|
|||||||
enabled = false
|
enabled = false
|
||||||
}
|
}
|
||||||
spotless {
|
spotless {
|
||||||
java {
|
java {
|
||||||
target sourceSets.main.allJava
|
target 'src/**/java/**/*.java'
|
||||||
googleJavaFormat(googleJavaFormatVersion).aosp().reorderImports(false)
|
googleJavaFormat(googleJavaFormatVersion).aosp().reorderImports(false)
|
||||||
|
|
||||||
importOrder("java", "javax", "org", "com", "net", "io", "jakarta", "lombok", "me", "stirling")
|
importOrder("java", "javax", "org", "com", "net", "io", "jakarta", "lombok", "me", "stirling")
|
||||||
@ -15,6 +15,18 @@ spotless {
|
|||||||
leadingTabsToSpaces()
|
leadingTabsToSpaces()
|
||||||
endWithNewline()
|
endWithNewline()
|
||||||
}
|
}
|
||||||
|
yaml {
|
||||||
|
target '**/*.yml', '**/*.yaml'
|
||||||
|
trimTrailingWhitespace()
|
||||||
|
leadingTabsToSpaces()
|
||||||
|
endWithNewline()
|
||||||
|
}
|
||||||
|
format 'gradle', {
|
||||||
|
target '**/gradle/*.gradle', '**/*.gradle'
|
||||||
|
trimTrailingWhitespace()
|
||||||
|
leadingTabsToSpaces()
|
||||||
|
endWithNewline()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation project(':common')
|
implementation project(':common')
|
||||||
|
@ -1,17 +1,20 @@
|
|||||||
package stirling.software.proprietary.security;
|
package stirling.software.proprietary.security;
|
||||||
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import static org.mockito.Mockito.*;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.mockito.InjectMocks;
|
import org.mockito.InjectMocks;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.Mockito;
|
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
|
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import stirling.software.common.model.ApplicationProperties;
|
import stirling.software.common.model.ApplicationProperties;
|
||||||
import static org.mockito.Mockito.*;
|
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class CustomLogoutSuccessHandlerTest {
|
class CustomLogoutSuccessHandlerTest {
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
package stirling.software.proprietary.security.configuration;
|
package stirling.software.proprietary.security.configuration;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
@ -8,10 +12,9 @@ import org.junit.jupiter.params.ParameterizedTest;
|
|||||||
import org.junit.jupiter.params.provider.ValueSource;
|
import org.junit.jupiter.params.provider.ValueSource;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
import stirling.software.common.model.ApplicationProperties;
|
import stirling.software.common.model.ApplicationProperties;
|
||||||
import stirling.software.common.model.exception.UnsupportedProviderException;
|
import stirling.software.common.model.exception.UnsupportedProviderException;
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class DatabaseConfigTest {
|
class DatabaseConfigTest {
|
||||||
|
@ -2,8 +2,10 @@ package stirling.software.proprietary.security.service;
|
|||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
import static org.junit.jupiter.api.Assertions.fail;
|
||||||
import jakarta.mail.MessagingException;
|
import static org.mockito.Mockito.mock;
|
||||||
import jakarta.mail.internet.MimeMessage;
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.mockito.InjectMocks;
|
import org.mockito.InjectMocks;
|
||||||
@ -17,9 +19,6 @@ import jakarta.mail.internet.MimeMessage;
|
|||||||
|
|
||||||
import stirling.software.common.model.ApplicationProperties;
|
import stirling.software.common.model.ApplicationProperties;
|
||||||
import stirling.software.proprietary.security.model.api.Email;
|
import stirling.software.proprietary.security.model.api.Email;
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
public class EmailServiceTest {
|
public class EmailServiceTest {
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
package stirling.software.proprietary.security.service;
|
package stirling.software.proprietary.security.service;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.mockito.InjectMocks;
|
import org.mockito.InjectMocks;
|
||||||
@ -18,8 +23,7 @@ import static org.mockito.Mockito.when;
|
|||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class TeamServiceTest {
|
class TeamServiceTest {
|
||||||
|
|
||||||
@Mock
|
@Mock private TeamRepository teamRepository;
|
||||||
private TeamRepository teamRepository;
|
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private OrganizationService organizationService;
|
private OrganizationService organizationService;
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
package stirling.software.proprietary.security.service;
|
package stirling.software.proprietary.security.service;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
@ -11,10 +16,9 @@ import org.mockito.Mock;
|
|||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
import org.springframework.context.MessageSource;
|
import org.springframework.context.MessageSource;
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
|
||||||
import stirling.software.common.model.ApplicationProperties;
|
import stirling.software.common.model.ApplicationProperties;
|
||||||
import stirling.software.common.model.enumeration.Role;
|
import stirling.software.common.model.enumeration.Role;
|
||||||
import stirling.software.common.model.exception.UnsupportedProviderException;
|
|
||||||
import stirling.software.proprietary.model.Team;
|
import stirling.software.proprietary.model.Team;
|
||||||
import stirling.software.proprietary.security.database.repository.AuthorityRepository;
|
import stirling.software.proprietary.security.database.repository.AuthorityRepository;
|
||||||
import stirling.software.proprietary.security.database.repository.UserRepository;
|
import stirling.software.proprietary.security.database.repository.UserRepository;
|
||||||
@ -22,42 +26,27 @@ import stirling.software.proprietary.security.model.AuthenticationType;
|
|||||||
import stirling.software.proprietary.security.model.User;
|
import stirling.software.proprietary.security.model.User;
|
||||||
import stirling.software.proprietary.security.repository.TeamRepository;
|
import stirling.software.proprietary.security.repository.TeamRepository;
|
||||||
import stirling.software.proprietary.security.session.SessionPersistentRegistry;
|
import stirling.software.proprietary.security.session.SessionPersistentRegistry;
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
|
||||||
import static org.mockito.ArgumentMatchers.anyLong;
|
|
||||||
import static org.mockito.ArgumentMatchers.anyString;
|
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
|
||||||
import static org.mockito.Mockito.*;
|
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class UserServiceTest {
|
class UserServiceTest {
|
||||||
|
|
||||||
@Mock
|
@Mock private UserRepository userRepository;
|
||||||
private UserRepository userRepository;
|
|
||||||
|
|
||||||
@Mock
|
@Mock private TeamRepository teamRepository;
|
||||||
private TeamRepository teamRepository;
|
|
||||||
|
|
||||||
@Mock
|
@Mock private AuthorityRepository authorityRepository;
|
||||||
private AuthorityRepository authorityRepository;
|
|
||||||
|
|
||||||
@Mock
|
@Mock private PasswordEncoder passwordEncoder;
|
||||||
private PasswordEncoder passwordEncoder;
|
|
||||||
|
|
||||||
@Mock
|
@Mock private MessageSource messageSource;
|
||||||
private MessageSource messageSource;
|
|
||||||
|
|
||||||
@Mock
|
@Mock private SessionPersistentRegistry sessionPersistentRegistry;
|
||||||
private SessionPersistentRegistry sessionPersistentRegistry;
|
|
||||||
|
|
||||||
@Mock
|
@Mock private DatabaseServiceInterface databaseService;
|
||||||
private DatabaseServiceInterface databaseService;
|
|
||||||
|
|
||||||
@Mock
|
@Mock private ApplicationProperties.Security.OAUTH2 oauth2Properties;
|
||||||
private ApplicationProperties.Security.OAUTH2 oauth2Properties;
|
|
||||||
|
|
||||||
@InjectMocks
|
@InjectMocks private UserService userService;
|
||||||
private UserService userService;
|
|
||||||
|
|
||||||
private Team mockTeam;
|
private Team mockTeam;
|
||||||
private User mockUser;
|
private User mockUser;
|
||||||
@ -146,10 +135,10 @@ class UserServiceTest {
|
|||||||
AuthenticationType authType = AuthenticationType.WEB;
|
AuthenticationType authType = AuthenticationType.WEB;
|
||||||
|
|
||||||
// When & Then
|
// When & Then
|
||||||
IllegalArgumentException exception = assertThrows(
|
IllegalArgumentException exception =
|
||||||
IllegalArgumentException.class,
|
assertThrows(
|
||||||
() -> userService.saveUser(invalidUsername, authType)
|
IllegalArgumentException.class,
|
||||||
);
|
() -> userService.saveUser(invalidUsername, authType));
|
||||||
|
|
||||||
verify(userRepository, never()).save(any(User.class));
|
verify(userRepository, never()).save(any(User.class));
|
||||||
verify(databaseService, never()).exportDatabase();
|
verify(databaseService, never()).exportDatabase();
|
||||||
@ -221,10 +210,10 @@ class UserServiceTest {
|
|||||||
AuthenticationType authType = AuthenticationType.WEB;
|
AuthenticationType authType = AuthenticationType.WEB;
|
||||||
|
|
||||||
// When & Then
|
// When & Then
|
||||||
IllegalArgumentException exception = assertThrows(
|
IllegalArgumentException exception =
|
||||||
IllegalArgumentException.class,
|
assertThrows(
|
||||||
() -> userService.saveUser(reservedUsername, authType)
|
IllegalArgumentException.class,
|
||||||
);
|
() -> userService.saveUser(reservedUsername, authType));
|
||||||
|
|
||||||
verify(userRepository, never()).save(any(User.class));
|
verify(userRepository, never()).save(any(User.class));
|
||||||
verify(databaseService, never()).exportDatabase();
|
verify(databaseService, never()).exportDatabase();
|
||||||
@ -237,10 +226,10 @@ class UserServiceTest {
|
|||||||
AuthenticationType authType = AuthenticationType.WEB;
|
AuthenticationType authType = AuthenticationType.WEB;
|
||||||
|
|
||||||
// When & Then
|
// When & Then
|
||||||
IllegalArgumentException exception = assertThrows(
|
IllegalArgumentException exception =
|
||||||
IllegalArgumentException.class,
|
assertThrows(
|
||||||
() -> userService.saveUser(anonymousUsername, authType)
|
IllegalArgumentException.class,
|
||||||
);
|
() -> userService.saveUser(anonymousUsername, authType));
|
||||||
|
|
||||||
verify(userRepository, never()).save(any(User.class));
|
verify(userRepository, never()).save(any(User.class));
|
||||||
verify(databaseService, never()).exportDatabase();
|
verify(databaseService, never()).exportDatabase();
|
||||||
@ -313,5 +302,4 @@ class UserServiceTest {
|
|||||||
verify(userRepository).save(any(User.class));
|
verify(userRepository).save(any(User.class));
|
||||||
verify(databaseService).exportDatabase();
|
verify(databaseService).exportDatabase();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
32
build.gradle
32
build.gradle
@ -2,10 +2,10 @@ plugins {
|
|||||||
id "java"
|
id "java"
|
||||||
id "jacoco"
|
id "jacoco"
|
||||||
id "io.spring.dependency-management" version "1.1.7"
|
id "io.spring.dependency-management" version "1.1.7"
|
||||||
id "org.springframework.boot" version "3.5.3"
|
id "org.springframework.boot" version "3.5.4"
|
||||||
id "org.springdoc.openapi-gradle-plugin" version "1.9.0"
|
id "org.springdoc.openapi-gradle-plugin" version "1.9.0"
|
||||||
id "io.swagger.swaggerhub" version "1.3.2"
|
id "io.swagger.swaggerhub" version "1.3.2"
|
||||||
id "edu.sc.seis.launch4j" version "3.0.6"
|
id "edu.sc.seis.launch4j" version "3.0.7"
|
||||||
id "com.diffplug.spotless" version "7.2.1"
|
id "com.diffplug.spotless" version "7.2.1"
|
||||||
id "com.github.jk1.dependency-license-report" version "2.9"
|
id "com.github.jk1.dependency-license-report" version "2.9"
|
||||||
//id "nebula.lint" version "19.0.3"
|
//id "nebula.lint" version "19.0.3"
|
||||||
@ -21,7 +21,7 @@ import java.nio.file.Files
|
|||||||
import java.time.Year
|
import java.time.Year
|
||||||
|
|
||||||
ext {
|
ext {
|
||||||
springBootVersion = "3.5.3"
|
springBootVersion = "3.5.4"
|
||||||
pdfboxVersion = "3.0.5"
|
pdfboxVersion = "3.0.5"
|
||||||
imageioVersion = "3.12.0"
|
imageioVersion = "3.12.0"
|
||||||
lombokVersion = "1.18.38"
|
lombokVersion = "1.18.38"
|
||||||
@ -29,7 +29,7 @@ ext {
|
|||||||
springSecuritySamlVersion = "6.5.2"
|
springSecuritySamlVersion = "6.5.2"
|
||||||
openSamlVersion = "4.3.2"
|
openSamlVersion = "4.3.2"
|
||||||
commonmarkVersion = "0.25.0"
|
commonmarkVersion = "0.25.0"
|
||||||
googleJavaFormatVersion = "1.27.0"
|
googleJavaFormatVersion = "1.28.0"
|
||||||
tempJrePath = null
|
tempJrePath = null
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,9 +158,9 @@ subprojects {
|
|||||||
useJUnitPlatform()
|
useJUnitPlatform()
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.named("processResources") {
|
tasks.named("processResources") {
|
||||||
dependsOn(rootProject.tasks.writeVersion)
|
dependsOn(rootProject.tasks.writeVersion)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name == 'stirling-pdf') {
|
if (name == 'stirling-pdf') {
|
||||||
apply plugin: 'org.springdoc.openapi-gradle-plugin'
|
apply plugin: 'org.springdoc.openapi-gradle-plugin'
|
||||||
@ -528,16 +528,14 @@ launch4j {
|
|||||||
}
|
}
|
||||||
|
|
||||||
spotless {
|
spotless {
|
||||||
java {
|
yaml {
|
||||||
target sourceSets.main.allJava
|
target '*.yml', '*.yaml'
|
||||||
target project(':common').sourceSets.main.allJava
|
trimTrailingWhitespace()
|
||||||
target project(':proprietary').sourceSets.main.allJava
|
leadingTabsToSpaces()
|
||||||
target project(':stirling-pdf').sourceSets.main.allJava
|
endWithNewline()
|
||||||
|
}
|
||||||
googleJavaFormat(googleJavaFormatVersion).aosp().reorderImports(false)
|
format 'gradle', {
|
||||||
|
target 'build.gradle', 'settings.gradle', 'gradle/*.gradle', 'gradle/**/*.gradle'
|
||||||
importOrder("java", "javax", "org", "com", "net", "io", "jakarta", "lombok", "me", "stirling")
|
|
||||||
toggleOffOn()
|
|
||||||
trimTrailingWhitespace()
|
trimTrailingWhitespace()
|
||||||
leadingTabsToSpaces()
|
leadingTabsToSpaces()
|
||||||
endWithNewline()
|
endWithNewline()
|
||||||
|
@ -1026,8 +1026,7 @@ ignore = [
|
|||||||
|
|
||||||
[zh_TW]
|
[zh_TW]
|
||||||
ignore = [
|
ignore = [
|
||||||
'lang.dzo',
|
|
||||||
'lang.iku',
|
|
||||||
'lang.que',
|
|
||||||
'language.direction',
|
'language.direction',
|
||||||
|
'poweredBy',
|
||||||
|
'showJS.tags',
|
||||||
]
|
]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user