mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-12-07 04:56:49 +00:00
Test cases for custom workflows related to glossaryTermApprovalWorkflow
This commit is contained in:
parent
fdacf4a32f
commit
557a52f507
@ -2494,6 +2494,216 @@ public class GlossaryTermResourceTest extends EntityResourceTest<GlossaryTerm, C
|
||||
patchWorkflowDefinition("GlossaryTermApprovalWorkflow", resetPatchJson);
|
||||
}
|
||||
|
||||
@Test
|
||||
void test_MultipleReviewerApprovalThreshold(TestInfo test) throws Exception {
|
||||
// Test 1: Multiple reviewer approval with threshold of 2
|
||||
// Create two reviewers
|
||||
EntityReference reviewer1 = USER1.getEntityReference();
|
||||
EntityReference reviewer2 = USER2.getEntityReference();
|
||||
List<EntityReference> reviewers = Arrays.asList(reviewer1, reviewer2);
|
||||
|
||||
// Patch workflow to set approval threshold to 2 BEFORE creating entities
|
||||
// Node at index 12 is "ApproveGlossaryTerm" userApprovalTask
|
||||
String patchOp =
|
||||
"[{\"op\":\"replace\",\"path\":\"/nodes/12/config/approvalThreshold\",\"value\":2}]";
|
||||
patchWorkflowDefinition("GlossaryTermApprovalWorkflow", patchOp);
|
||||
|
||||
// Create glossary with reviewers
|
||||
Glossary glossary = createGlossary(test, reviewers, null);
|
||||
|
||||
// Create glossary term with reviewers
|
||||
CreateGlossaryTerm createRequest =
|
||||
createRequest(getEntityName(test))
|
||||
.withDescription("Test term for multi-approval")
|
||||
.withGlossary(glossary.getFullyQualifiedName())
|
||||
.withReviewers(reviewers)
|
||||
.withSynonyms(null)
|
||||
.withRelatedTerms(null);
|
||||
GlossaryTerm term = createEntity(createRequest, ADMIN_AUTH_HEADERS);
|
||||
|
||||
// Term should be in DRAFT status initially
|
||||
assertEquals(Status.DRAFT, term.getStatus());
|
||||
|
||||
// Wait for workflow to process and task to be created
|
||||
waitForTaskToBeCreated(term.getFullyQualifiedName());
|
||||
|
||||
// After workflow processing, term should be IN_REVIEW
|
||||
assertEquals(Status.IN_REVIEW, getEntity(term.getId(), ADMIN_AUTH_HEADERS).getStatus());
|
||||
|
||||
// Get the task
|
||||
String entityLink =
|
||||
new MessageParser.EntityLink(Entity.GLOSSARY_TERM, term.getFullyQualifiedName())
|
||||
.getLinkString();
|
||||
ThreadList threads =
|
||||
taskTest.listTasks(entityLink, null, null, null, 100, authHeaders(reviewer1.getName()));
|
||||
assertFalse(threads.getData().isEmpty());
|
||||
Thread task = threads.getData().getFirst();
|
||||
int taskId = task.getTask().getId();
|
||||
|
||||
// First reviewer approves
|
||||
ResolveTask resolveTask = new ResolveTask().withNewValue(Status.APPROVED.value());
|
||||
taskTest.resolveTask(taskId, resolveTask, authHeaders(reviewer1.getName()));
|
||||
|
||||
// After first approval, term should still be IN_REVIEW
|
||||
java.lang.Thread.sleep(2000); // Wait for async processing
|
||||
GlossaryTerm termAfterFirstApproval = getEntity(term.getId(), ADMIN_AUTH_HEADERS);
|
||||
assertEquals(Status.IN_REVIEW, termAfterFirstApproval.getStatus());
|
||||
|
||||
// Second reviewer approves
|
||||
taskTest.resolveTask(taskId, resolveTask, authHeaders(reviewer2.getName()));
|
||||
|
||||
// After second approval, term should be APPROVED
|
||||
java.lang.Thread.sleep(2000); // Wait for async processing
|
||||
GlossaryTerm termAfterSecondApproval = getEntity(term.getId(), ADMIN_AUTH_HEADERS);
|
||||
assertEquals(Status.APPROVED, termAfterSecondApproval.getStatus());
|
||||
|
||||
// Reset workflow back to threshold of 1
|
||||
patchOp = "[{\"op\":\"replace\",\"path\":\"/nodes/12/config/approvalThreshold\",\"value\":1}]";
|
||||
patchWorkflowDefinition("GlossaryTermApprovalWorkflow", patchOp);
|
||||
}
|
||||
|
||||
@Test
|
||||
void test_RollbackOnRejection(TestInfo test) throws Exception {
|
||||
// Test 2: Rollback on rejection scenario
|
||||
EntityReference reviewer = USER1.getEntityReference();
|
||||
List<EntityReference> reviewers = List.of(reviewer);
|
||||
|
||||
// Create glossary with reviewer
|
||||
Glossary glossary = createGlossary(test, reviewers, null);
|
||||
|
||||
// Create glossary term
|
||||
String initialDescription = "Initial approved description";
|
||||
CreateGlossaryTerm createRequest =
|
||||
createRequest(getEntityName(test))
|
||||
.withDescription(initialDescription)
|
||||
.withGlossary(glossary.getFullyQualifiedName())
|
||||
.withReviewers(reviewers)
|
||||
.withSynonyms(null)
|
||||
.withRelatedTerms(null);
|
||||
GlossaryTerm term = createEntity(createRequest, ADMIN_AUTH_HEADERS);
|
||||
|
||||
// Wait for task and approve it
|
||||
waitForTaskToBeCreated(term.getFullyQualifiedName());
|
||||
String entityLink =
|
||||
new MessageParser.EntityLink(Entity.GLOSSARY_TERM, term.getFullyQualifiedName())
|
||||
.getLinkString();
|
||||
ThreadList threads =
|
||||
taskTest.listTasks(entityLink, null, null, null, 100, authHeaders(reviewer.getName()));
|
||||
Thread task = threads.getData().getFirst();
|
||||
int taskId = task.getTask().getId();
|
||||
|
||||
ResolveTask approveTask = new ResolveTask().withNewValue(Status.APPROVED.value());
|
||||
taskTest.resolveTask(taskId, approveTask, authHeaders(reviewer.getName()));
|
||||
|
||||
java.lang.Thread.sleep(2000);
|
||||
GlossaryTerm approvedTerm = getEntity(term.getId(), ADMIN_AUTH_HEADERS);
|
||||
assertEquals(Status.APPROVED, approvedTerm.getStatus());
|
||||
double version1 = approvedTerm.getVersion();
|
||||
|
||||
// Update term with non-reviewer (should trigger workflow)
|
||||
String updatedDescription = "Updated description by non-reviewer";
|
||||
String origJson = JsonUtils.pojoToJson(approvedTerm);
|
||||
approvedTerm.setDescription(updatedDescription);
|
||||
GlossaryTerm updatedTerm =
|
||||
patchEntityUsingFqn(approvedTerm.getFullyQualifiedName(), origJson, approvedTerm, authHeaders(USER2.getName()));
|
||||
|
||||
// Wait for new task to be created for the update
|
||||
waitForDetailedTaskToBeCreated(term.getFullyQualifiedName(), 60000L);
|
||||
|
||||
// Get the new task
|
||||
threads =
|
||||
taskTest.listTasks(entityLink, null, null, null, 100, authHeaders(reviewer.getName()));
|
||||
Thread updateTask = threads.getData().getFirst();
|
||||
int updateTaskId = updateTask.getTask().getId();
|
||||
|
||||
// Reject the changes
|
||||
ResolveTask rejectTask = new ResolveTask().withNewValue(Status.REJECTED.value());
|
||||
taskTest.resolveTask(updateTaskId, rejectTask, authHeaders(reviewer.getName()));
|
||||
|
||||
java.lang.Thread.sleep(2000);
|
||||
GlossaryTerm rolledBackTerm = getEntity(term.getId(), ADMIN_AUTH_HEADERS);
|
||||
|
||||
// Verify rollback: description should be back to initial, status should be approved
|
||||
assertEquals(initialDescription, rolledBackTerm.getDescription());
|
||||
assertEquals(Status.APPROVED, rolledBackTerm.getStatus());
|
||||
// Version should be bumped for audit trail
|
||||
assertTrue(
|
||||
rolledBackTerm.getVersion() > version1, "Version should be incremented for audit trail");
|
||||
}
|
||||
|
||||
@Test
|
||||
void test_ReviewerSuggestionApplication(TestInfo test) throws Exception {
|
||||
// Test 3: Reviewer suggestion application
|
||||
EntityReference reviewer = USER1.getEntityReference();
|
||||
List<EntityReference> reviewers = List.of(reviewer);
|
||||
|
||||
// Create glossary with reviewer
|
||||
Glossary glossary = createGlossary(test, reviewers, null);
|
||||
|
||||
// Create glossary term
|
||||
String initialDescription = "Initial description";
|
||||
CreateGlossaryTerm createRequest =
|
||||
createRequest(getEntityName(test))
|
||||
.withDescription(initialDescription)
|
||||
.withGlossary(glossary.getFullyQualifiedName())
|
||||
.withReviewers(reviewers)
|
||||
.withSynonyms(null)
|
||||
.withRelatedTerms(null);
|
||||
GlossaryTerm term = createEntity(createRequest, ADMIN_AUTH_HEADERS);
|
||||
|
||||
// Wait for task to be created
|
||||
waitForTaskToBeCreated(term.getFullyQualifiedName());
|
||||
|
||||
// Get the task
|
||||
String entityLink =
|
||||
new MessageParser.EntityLink(Entity.GLOSSARY_TERM, term.getFullyQualifiedName())
|
||||
.getLinkString();
|
||||
ThreadList threads =
|
||||
taskTest.listTasks(entityLink, null, null, null, 100, authHeaders(reviewer.getName()));
|
||||
Thread task = threads.getData().getFirst();
|
||||
int taskId = task.getTask().getId();
|
||||
|
||||
// Approve initially
|
||||
ResolveTask approveTask = new ResolveTask().withNewValue(Status.APPROVED.value());
|
||||
taskTest.resolveTask(taskId, approveTask, authHeaders(reviewer.getName()));
|
||||
|
||||
java.lang.Thread.sleep(2000);
|
||||
GlossaryTerm approvedTerm = getEntity(term.getId(), ADMIN_AUTH_HEADERS);
|
||||
assertEquals(Status.APPROVED, approvedTerm.getStatus());
|
||||
|
||||
// Update term to trigger a new approval workflow
|
||||
String updateDescription = "Updated description for review";
|
||||
String origJson = JsonUtils.pojoToJson(approvedTerm);
|
||||
approvedTerm.setDescription(updateDescription);
|
||||
GlossaryTerm updatedTerm =
|
||||
patchEntityUsingFqn(approvedTerm.getFullyQualifiedName(), origJson, approvedTerm, authHeaders(USER2.getName()));
|
||||
|
||||
// Wait for detailed task to be created
|
||||
waitForDetailedTaskToBeCreated(term.getFullyQualifiedName(), 60000L);
|
||||
|
||||
// Get the new task
|
||||
threads =
|
||||
taskTest.listTasks(entityLink, null, null, null, 100, authHeaders(reviewer.getName()));
|
||||
Thread updateTask = threads.getData().getFirst();
|
||||
int updateTaskId = updateTask.getTask().getId();
|
||||
|
||||
// Reviewer suggests changes and approves with modifications
|
||||
String suggestedDescription = "Multi Approver Term Updated By Reviewer [Don't update Further]";
|
||||
String resolveValue =
|
||||
String.format("Description: <p>%s</p>\nstatus: approved", suggestedDescription);
|
||||
ResolveTask resolveWithSuggestion = new ResolveTask().withNewValue(resolveValue);
|
||||
taskTest.resolveTask(updateTaskId, resolveWithSuggestion, authHeaders(reviewer.getName()));
|
||||
|
||||
java.lang.Thread.sleep(2000);
|
||||
GlossaryTerm finalTerm = getEntity(term.getId(), ADMIN_AUTH_HEADERS);
|
||||
|
||||
// Verify the term has the suggested description and is approved
|
||||
assertEquals(Status.APPROVED, finalTerm.getStatus());
|
||||
assertTrue(
|
||||
finalTerm.getDescription().contains(suggestedDescription),
|
||||
"Term should have the reviewer's suggested description");
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to receive move entity message via WebSocket
|
||||
*/
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user