From 986fd4832d3c8735c7c5046324737677622aca7d Mon Sep 17 00:00:00 2001 From: valentinogiardino Date: Mon, 9 Dec 2024 10:55:30 -0300 Subject: [PATCH] #30874 add integration tests --- .../business/api/JobQueueManagerAPITest.java | 218 ++++++++++++++++++ .../PostgresJobQueueIntegrationTest.java | 90 ++++++++ .../ContentImportResourceIntegrationTest.java | 102 +++++++- 3 files changed, 409 insertions(+), 1 deletion(-) diff --git a/dotcms-integration/src/test/java/com/dotcms/jobs/business/api/JobQueueManagerAPITest.java b/dotcms-integration/src/test/java/com/dotcms/jobs/business/api/JobQueueManagerAPITest.java index 09d25aabb0ad..d8f306f733b9 100644 --- a/dotcms-integration/src/test/java/com/dotcms/jobs/business/api/JobQueueManagerAPITest.java +++ b/dotcms-integration/src/test/java/com/dotcms/jobs/business/api/JobQueueManagerAPITest.java @@ -253,6 +253,224 @@ public void test_getJobs() throws DotDataException, JobQueueDataException { verify(mockJobQueue).getJobs(1, 10); } + + /** + * Method to test: getJobs for a particular queue in JobQueueManagerAPI + * Given Scenario: Valid page and pageSize parameters are provided + * ExpectedResult: Correct list of jobs is retrieved from the job queue + */ + @Test + public void test_getJobsFromQueue() throws DotDataException, JobQueueDataException { + + // Prepare test data + Job job1 = mock(Job.class); + Job job2 = mock(Job.class); + List expectedJobs = Arrays.asList(job1, job2); + final var paginatedResult = JobPaginatedResult.builder() + .jobs(expectedJobs) + .total(2) + .page(1) + .pageSize(10) + .build(); + + // Mock the behavior of jobQueue.getJobs + when(mockJobQueue.getJobs("testQueue",1, 10)).thenReturn(paginatedResult); + + // Call the method under test + final var actualResult = jobQueueManagerAPI.getJobs("testQueue", 1, 10); + + // Verify the results + assertEquals(expectedJobs, actualResult.jobs()); + verify(mockJobQueue).getJobs("testQueue", 1, 10); + } + + + /** + * Method to test: getActiveJobs for a particular queue in JobQueueManagerAPI + * Given Scenario: Valid page and pageSize parameters are provided + * ExpectedResult: Correct list of jobs is retrieved from the job queue + */ + @Test + public void test_getActiveJobsFromQueue() throws DotDataException, JobQueueDataException { + + // Prepare test data + Job job1 = mock(Job.class); + Job job2 = mock(Job.class); + List expectedJobs = Arrays.asList(job1, job2); + final var paginatedResult = JobPaginatedResult.builder() + .jobs(expectedJobs) + .total(2) + .page(1) + .pageSize(10) + .build(); + + // Mock the behavior of jobQueue.getJobs + when(mockJobQueue.getActiveJobs("testQueue",1, 10)).thenReturn(paginatedResult); + + // Call the method under test + final var actualResult = jobQueueManagerAPI.getActiveJobs("testQueue", 1, 10); + + // Verify the results + assertEquals(expectedJobs, actualResult.jobs()); + verify(mockJobQueue).getActiveJobs("testQueue", 1, 10); + } + + + /** + * Method to test: getCompletedJobs for a particular queue in JobQueueManagerAPI + * Given Scenario: Valid page and pageSize parameters are provided + * ExpectedResult: Correct list of jobs is retrieved from the job queue + */ + @Test + public void test_getCompletedJobsFromQueue() throws DotDataException, JobQueueDataException { + + // Prepare test data + Job job1 = mock(Job.class); + Job job2 = mock(Job.class); + List expectedJobs = Arrays.asList(job1, job2); + final var paginatedResult = JobPaginatedResult.builder() + .jobs(expectedJobs) + .total(2) + .page(1) + .pageSize(10) + .build(); + + // Mock the behavior of jobQueue.getJobs + when(mockJobQueue.getCompletedJobs("testQueue",1, 10)).thenReturn(paginatedResult); + + // Call the method under test + final var actualResult = jobQueueManagerAPI.getCompletedJobs("testQueue", 1, 10); + + // Verify the results + assertEquals(expectedJobs, actualResult.jobs()); + verify(mockJobQueue).getCompletedJobs("testQueue", 1, 10); + } + + + /** + * Method to test: getCanceledJobs for a particular queue in JobQueueManagerAPI + * Given Scenario: Valid page and pageSize parameters are provided + * ExpectedResult: Correct list of jobs is retrieved from the job queue + */ + @Test + public void test_getCanceledJobsFromQueue() throws DotDataException, JobQueueDataException { + + // Prepare test data + Job job1 = mock(Job.class); + Job job2 = mock(Job.class); + List expectedJobs = Arrays.asList(job1, job2); + final var paginatedResult = JobPaginatedResult.builder() + .jobs(expectedJobs) + .total(2) + .page(1) + .pageSize(10) + .build(); + + // Mock the behavior of jobQueue.getJobs + when(mockJobQueue.getCanceledJobs("testQueue",1, 10)).thenReturn(paginatedResult); + + // Call the method under test + final var actualResult = jobQueueManagerAPI.getCanceledJobs("testQueue", 1, 10); + + // Verify the results + assertEquals(expectedJobs, actualResult.jobs()); + verify(mockJobQueue).getCanceledJobs("testQueue", 1, 10); + } + + + /** + * Method to test: getFailedJobs for a particular queue in JobQueueManagerAPI + * Given Scenario: Valid page and pageSize parameters are provided + * ExpectedResult: Correct list of jobs is retrieved from the job queue + */ + @Test + public void test_getFailedJobsFromQueue() throws DotDataException, JobQueueDataException { + + // Prepare test data + Job job1 = mock(Job.class); + Job job2 = mock(Job.class); + List expectedJobs = Arrays.asList(job1, job2); + final var paginatedResult = JobPaginatedResult.builder() + .jobs(expectedJobs) + .total(2) + .page(1) + .pageSize(10) + .build(); + + // Mock the behavior of jobQueue.getJobs + when(mockJobQueue.getFailedJobs("testQueue",1, 10)).thenReturn(paginatedResult); + + // Call the method under test + final var actualResult = jobQueueManagerAPI.getFailedJobs("testQueue", 1, 10); + + // Verify the results + assertEquals(expectedJobs, actualResult.jobs()); + verify(mockJobQueue).getFailedJobs("testQueue", 1, 10); + } + + + /** + * Method to test: getAbandonedJobs for a particular queue in JobQueueManagerAPI + * Given Scenario: Valid page and pageSize parameters are provided + * ExpectedResult: Correct list of jobs is retrieved from the job queue + */ + @Test + public void test_getAbandonedJobsFromQueue() throws DotDataException, JobQueueDataException { + + // Prepare test data + Job job1 = mock(Job.class); + Job job2 = mock(Job.class); + List expectedJobs = Arrays.asList(job1, job2); + final var paginatedResult = JobPaginatedResult.builder() + .jobs(expectedJobs) + .total(2) + .page(1) + .pageSize(10) + .build(); + + // Mock the behavior of jobQueue.getJobs + when(mockJobQueue.getAbandonedJobs("testQueue",1, 10)).thenReturn(paginatedResult); + + // Call the method under test + final var actualResult = jobQueueManagerAPI.getAbandonedJobs("testQueue", 1, 10); + + // Verify the results + assertEquals(expectedJobs, actualResult.jobs()); + verify(mockJobQueue).getAbandonedJobs("testQueue", 1, 10); + } + + + /** + * Method to test: getSuccessfulJobs for a particular queue in JobQueueManagerAPI + * Given Scenario: Valid page and pageSize parameters are provided + * ExpectedResult: Correct list of jobs is retrieved from the job queue + */ + @Test + public void test_getSuccessfulJobsFromQueue() throws DotDataException, JobQueueDataException { + + // Prepare test data + Job job1 = mock(Job.class); + Job job2 = mock(Job.class); + List expectedJobs = Arrays.asList(job1, job2); + final var paginatedResult = JobPaginatedResult.builder() + .jobs(expectedJobs) + .total(2) + .page(1) + .pageSize(10) + .build(); + + // Mock the behavior of jobQueue.getJobs + when(mockJobQueue.getSuccessfulJobs("testQueue",1, 10)).thenReturn(paginatedResult); + + // Call the method under test + final var actualResult = jobQueueManagerAPI.getSuccessfulJobs("testQueue", 1, 10); + + // Verify the results + assertEquals(expectedJobs, actualResult.jobs()); + verify(mockJobQueue).getSuccessfulJobs("testQueue", 1, 10); + } + + /** * Method to test: start in JobQueueManagerAPI * Given Scenario: JobQueueManagerAPI is not started diff --git a/dotcms-integration/src/test/java/com/dotcms/jobs/business/queue/PostgresJobQueueIntegrationTest.java b/dotcms-integration/src/test/java/com/dotcms/jobs/business/queue/PostgresJobQueueIntegrationTest.java index a180cb5ea32d..daa2a25ae624 100644 --- a/dotcms-integration/src/test/java/com/dotcms/jobs/business/queue/PostgresJobQueueIntegrationTest.java +++ b/dotcms-integration/src/test/java/com/dotcms/jobs/business/queue/PostgresJobQueueIntegrationTest.java @@ -99,6 +99,96 @@ void test_getActiveJobsForQueue() throws JobQueueException { assertEquals(5, result.total()); } + + /** + * Method to test: getSuccessfulJobs in PostgresJobQueue for queue + * Given Scenario: Multiple successful jobs are created + * ExpectedResult: All successful jobs are retrieved correctly + */ + @Test + void test_getSuccessfulJobsForQueue() throws JobQueueException { + + String queueName = "testQueue"; + for (int i = 0; i < 5; i++) { + String jobId = jobQueue.createJob(queueName, new HashMap<>()); + Job job = jobQueue.getJob(jobId); + Job completedJob = job.markAsSuccessful(null); + jobQueue.updateJobStatus(completedJob); + } + + JobPaginatedResult result = jobQueue.getSuccessfulJobs(queueName, 1, 10); + assertEquals(5, result.jobs().size()); + assertEquals(5, result.total()); + } + + + /** + * Method to test: getFailedJobs in PostgresJobQueue for queue + * Given Scenario: Multiple failed jobs are created + * ExpectedResult: All failed jobs are retrieved correctly + */ + @Test + void test_getFailedJobsForQueue() throws JobQueueException { + + String queueName = "testQueue"; + for (int i = 0; i < 5; i++) { + String jobId = jobQueue.createJob(queueName, new HashMap<>()); + Job job = jobQueue.getJob(jobId); + Job failedJob = Job.builder().from(job) + .state(JobState.FAILED) + .build(); + jobQueue.updateJobStatus(failedJob); + } + + JobPaginatedResult result = jobQueue.getFailedJobs(queueName, 1, 10); + assertEquals(5, result.jobs().size()); + assertEquals(5, result.total()); + } + + /** + * Method to test: getCanceledJobs in PostgresJobQueue for queue + * Given Scenario: Multiple canceled jobs are created + * ExpectedResult: All canceled jobs are retrieved correctly + */ + @Test + void test_getCanceledJobsForQueue() throws JobQueueException { + + String queueName = "testQueue"; + for (int i = 0; i < 5; i++) { + String jobId = jobQueue.createJob(queueName, new HashMap<>()); + Job job = jobQueue.getJob(jobId); + Job completedJob = job.markAsCanceled(null); + jobQueue.updateJobStatus(completedJob); + } + + JobPaginatedResult result = jobQueue.getCanceledJobs(queueName, 1, 10); + assertEquals(5, result.jobs().size()); + assertEquals(5, result.total()); + } + + /** + * Method to test: getAbandonedJobs in PostgresJobQueue for queue + * Given Scenario: Multiple abandoned jobs are created + * ExpectedResult: All abandoned jobs are retrieved correctly + */ + @Test + void test_getAbandonedJobsForQueue() throws JobQueueException { + + String queueName = "testQueue"; + for (int i = 0; i < 5; i++) { + String jobId = jobQueue.createJob(queueName, new HashMap<>()); + Job job = jobQueue.getJob(jobId); + Job failedJob = Job.builder().from(job) + .state(JobState.ABANDONED) + .build(); + jobQueue.updateJobStatus(failedJob); + } + + JobPaginatedResult result = jobQueue.getAbandonedJobs(queueName, 1, 10); + assertEquals(5, result.jobs().size()); + assertEquals(5, result.total()); + } + /** * Method to test: getActiveJobs in PostgresJobQueue Given Scenario: Multiple active jobs are * created ExpectedResult: All active jobs are retrieved correctly diff --git a/dotcms-integration/src/test/java/com/dotcms/rest/api/v1/content/dotimport/ContentImportResourceIntegrationTest.java b/dotcms-integration/src/test/java/com/dotcms/rest/api/v1/content/dotimport/ContentImportResourceIntegrationTest.java index 398d918fa8cb..b82b4aae4d30 100644 --- a/dotcms-integration/src/test/java/com/dotcms/rest/api/v1/content/dotimport/ContentImportResourceIntegrationTest.java +++ b/dotcms-integration/src/test/java/com/dotcms/rest/api/v1/content/dotimport/ContentImportResourceIntegrationTest.java @@ -1,6 +1,7 @@ package com.dotcms.rest.api.v1.content.dotimport; import static com.dotmarketing.portlets.workflows.business.SystemWorkflowConstants.WORKFLOW_PUBLISH_ACTION_ID; +import static org.junit.Assert.assertThrows; import static org.junit.jupiter.api.Assertions.*; import com.dotcms.Junit5WeldBaseTest; @@ -9,13 +10,17 @@ import com.dotcms.datagen.TestDataUtils; import com.dotcms.datagen.TestUserUtils; import com.dotcms.jobs.business.job.Job; +import com.dotcms.jobs.business.job.JobPaginatedResult; +import com.dotcms.jobs.business.job.JobState; import com.dotcms.jobs.business.util.JobUtil; import com.dotcms.mock.response.MockHttpResponse; import com.dotcms.rest.ResponseEntityView; +import com.dotcms.rest.api.v1.job.SSEMonitorUtil; import com.dotcms.rest.exception.ValidationException; import com.dotcms.util.IntegrationTestInitService; import com.dotmarketing.beans.Host; import com.dotmarketing.business.APILocator; +import com.dotmarketing.exception.DoesNotExistException; import com.dotmarketing.exception.DotDataException; import com.dotmarketing.portlets.languagesmanager.model.Language; import com.dotmarketing.util.Constants; @@ -41,6 +46,7 @@ * Tests the ContentImportResource API endpoints for various scenarios. */ @EnableWeld +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) public class ContentImportResourceIntegrationTest extends Junit5WeldBaseTest { private static User adminUser; @@ -62,6 +68,9 @@ public class ContentImportResourceIntegrationTest extends Junit5WeldBaseTest { @Inject ContentImportHelper contentImportHelper; + @Inject + SSEMonitorUtil sseMonitorUtil; + @BeforeAll static void setUp() throws Exception { IntegrationTestInitService.getInstance().init(); @@ -81,7 +90,7 @@ static void setUp() throws Exception { @BeforeEach void prepare() { - importResource = new ContentImportResource(contentImportHelper); + importResource = new ContentImportResource(contentImportHelper, sseMonitorUtil); } @AfterAll @@ -94,6 +103,76 @@ static void cleanup() { ContentTypeDataGen.remove(contentType); } + + /** + * Given scenario: call cancel Job with an invalid job id + * Expected result: we should get a DoesNotExistException + */ + @Test + @Order(1) + void testCancelNonExistingJob(){ + assertThrows(DoesNotExistException.class, () -> importResource.cancelJob(request, response, "nonExisting" )); + } + + /** + * Given scenario: call get Active Job + * Expected result: A JobPaginatedResult is returned + */ + @Test + @Order(2) + void testGetActiveJobs() { + // Call the activeJobs endpoint + ResponseEntityView result = importResource.activeJobs(request, response, 1, 20); + validateJobPaginatedResult(result, 0); + } + + @Test + @Order(3) + void testCreateAndListActiveJobs() throws DotDataException, IOException { + //Create valid import job + ContentImportForm form = createContentImportForm(contentType.name(), String.valueOf(defaultLanguage.getId()), WORKFLOW_PUBLISH_ACTION_ID, List.of(fieldId)); + ContentImportParams params = createContentImportParams(csvFile, form); + Response importContentResponse = importResource.importContent(request, response, params); + + // Call the activeJobs endpoint + ResponseEntityView result = importResource.activeJobs(request, response, 1, 20); + + // Validate result + validateJobPaginatedResult(result, 1); + } + + @Test + @Order(4) + void testGetCancelJobs() { + // Call the activeJobs endpoint + ResponseEntityView result = importResource.canceledJobs(request, response, 1, 20); + validateJobPaginatedResult(result, 0); + } + + @Test + @Order(5) + void testCreateThenCancelThenListCanceledJobs() throws DotDataException, IOException { + //Create valid import job + ContentImportForm form = createContentImportForm(contentType.name(), String.valueOf(defaultLanguage.getId()), WORKFLOW_PUBLISH_ACTION_ID, List.of(fieldId)); + ContentImportParams params = createContentImportParams(csvFile, form); + Response importContentResponse = importResource.importContent(request, response, params); + + // Retrieve the job ID from the response entity + Object importContentResponseEntity = importContentResponse.getEntity(); + assertNotNull(importContentResponseEntity, "Response entity should not be null"); + assertInstanceOf(ResponseEntityView.class, importContentResponseEntity, "Entity should be of type ResponseEntityView"); + @SuppressWarnings("unchecked") + ResponseEntityView responseEntityView = (ResponseEntityView) importContentResponseEntity; + + // Cancel the job + importResource.cancelJob(request, response, responseEntityView.getEntity()); + + // Call the canceledJobs endpoint + ResponseEntityView result = importResource.canceledJobs(request, response, 1, 20); + // Validate result + validateJobPaginatedResult(result, 1); + } + /** * Scenario: Import content with all parameters being passed (csv file, content type, language, workflow action, and fields). *

@@ -432,6 +511,27 @@ public void test_import_content_validate_missing_form() throws IOException { assertThrows(ValidationException.class, () -> importResource.validateContentImport(request, response, params)); } + + private void validateJobPaginatedResult(ResponseEntityView result, long expectedTotalJobs) { + assertNotNull(result, "Response should not be null"); + + JobPaginatedResult entity = result.getEntity(); + assertNotNull(entity, "JobPaginatedResult should not be null"); + + // Validate the properties of JobPaginatedResult + assertEquals(1, entity.page(), "Current page should be 1"); + assertEquals(20, entity.pageSize(), "Page size should be 20"); + + // Check that the total number of jobs is as expected (this can be adjusted based on your test setup) + //assertTrue(expectedTotalJobs <= entity.jobs().size(), "Total number of jobs should match expected value"); + assertEquals(expectedTotalJobs, entity.jobs().size(), "Total number of jobs should match expected value"); + + // Check that the jobs list is not null and has the expected number of jobs + var jobs = entity.jobs(); + assertNotNull(jobs, "Jobs list should not be null"); + assertTrue(jobs.size() <= entity.pageSize(), "Number of jobs should not exceed page size"); + } + /** * Validates the response and job parameters from a content import operation. *