Skip to content

Commit

Permalink
Create Change Events on import and update in es (#18953)
Browse files Browse the repository at this point in the history
* Create Change Events on import and update in es

* add glossary tests

* minor test cleanup

* Make Change Event Update Async

* Fix Test case

---------

Co-authored-by: karanh37 <karanh37@gmail.com>
Co-authored-by: Sriharsha Chintalapani <harshach@users.noreply.github.com>
  • Loading branch information
3 people authored Dec 9, 2024
1 parent de0889d commit 5263858
Show file tree
Hide file tree
Showing 8 changed files with 293 additions and 123 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import static org.openmetadata.csv.CsvUtil.fieldToExtensionStrings;
import static org.openmetadata.csv.CsvUtil.fieldToInternalArray;
import static org.openmetadata.csv.CsvUtil.recordToString;
import static org.openmetadata.service.events.ChangeEventHandler.copyChangeEvent;

import com.fasterxml.jackson.databind.JsonNode;
import com.networknt.schema.JsonSchema;
Expand Down Expand Up @@ -60,7 +61,9 @@
import org.openmetadata.common.utils.CommonUtil;
import org.openmetadata.schema.EntityInterface;
import org.openmetadata.schema.type.ApiStatus;
import org.openmetadata.schema.type.ChangeEvent;
import org.openmetadata.schema.type.EntityReference;
import org.openmetadata.schema.type.EventType;
import org.openmetadata.schema.type.Include;
import org.openmetadata.schema.type.TagLabel;
import org.openmetadata.schema.type.TagLabel.TagSource;
Expand All @@ -72,7 +75,9 @@
import org.openmetadata.schema.type.customProperties.TableConfig;
import org.openmetadata.service.Entity;
import org.openmetadata.service.TypeRegistry;
import org.openmetadata.service.formatter.util.FormatterUtil;
import org.openmetadata.service.jdbi3.EntityRepository;
import org.openmetadata.service.util.AsyncService;
import org.openmetadata.service.util.EntityUtil;
import org.openmetadata.service.util.JsonUtils;
import org.openmetadata.service.util.RestUtil.PutResponse;
Expand Down Expand Up @@ -721,6 +726,9 @@ protected void createEntity(CSVPrinter resultsPrinter, CSVRecord csvRecord, T en
repository.prepareInternal(entity, false);
PutResponse<T> response = repository.createOrUpdate(null, entity);
responseStatus = response.getStatus();
AsyncService.getInstance()
.getExecutorService()
.submit(() -> createChangeEventAndUpdateInES(response, importedBy));
} catch (Exception ex) {
importFailure(resultsPrinter, ex.getMessage(), csvRecord);
importResult.setStatus(ApiStatus.FAILURE);
Expand All @@ -744,6 +752,20 @@ protected void createEntity(CSVPrinter resultsPrinter, CSVRecord csvRecord, T en
}
}

private void createChangeEventAndUpdateInES(PutResponse<T> response, String importedBy) {
if (!response.getChangeType().equals(EventType.ENTITY_NO_CHANGE)) {
ChangeEvent changeEvent =
FormatterUtil.createChangeEventForEntity(
importedBy, response.getChangeType(), response.getEntity());
Object entity = changeEvent.getEntity();
changeEvent = copyChangeEvent(changeEvent);
changeEvent.setEntity(JsonUtils.pojoToMaskedJson(entity));
// Change Event and Update in Es
Entity.getCollectionDAO().changeEventDAO().insert(JsonUtils.pojoToJson(changeEvent));
Entity.getSearchRepository().updateEntity(response.getEntity().getEntityReference());
}
}

@Transaction
protected void createUserEntity(CSVPrinter resultsPrinter, CSVRecord csvRecord, T entity)
throws IOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public Void process(
return null;
}

private static ChangeEvent copyChangeEvent(ChangeEvent changeEvent) {
public static ChangeEvent copyChangeEvent(ChangeEvent changeEvent) {
return new ChangeEvent()
.withId(changeEvent.getId())
.withEventType(changeEvent.getEventType())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ private static ChangeEvent extractChangeEvent(
return null;
}

private static ChangeEvent createChangeEventForEntity(
public static ChangeEvent createChangeEventForEntity(
String updateBy, EventType eventType, EntityInterface entityInterface) {
return getChangeEvent(
updateBy, eventType, entityInterface.getEntityReference().getType(), entityInterface)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ public static class PutResponse<T> {
@Getter private T entity;
private ChangeEvent changeEvent;
@Getter private final Response.Status status;
private final EventType changeType;
@Getter private final EventType changeType;

/**
* Response.Status.CREATED when PUT operation creates a new entity or Response.Status.OK when PUT operation updates
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -934,8 +934,25 @@ void testGlossaryImportExport() throws IOException {
List<String> newRecords =
listOf(
",g3,dsp0,dsc0,h1;h2;h3,,term0;http://term0,PII.Sensitive,,,Approved,\"\"\"glossaryTermTableCol1Cp:row_1_col1_Value,,\"\";\"\"glossaryTermTableCol3Cp:row_1_col1_Value,row_1_col2_Value,row_1_col3_Value|row_2_col1_Value,row_2_col2_Value,row_2_col3_Value\"\"\"");
testImportExport(
glossary.getName(), GlossaryCsv.HEADERS, createRecords, updateRecords, newRecords);
Awaitility.await()
.atMost(Duration.ofMillis(120 * 1000L))
.pollInterval(Duration.ofMillis(2000L))
.ignoreExceptions()
.until(
() -> {
try {
testImportExport(

Check failure on line 944 in openmetadata-service/src/test/java/org/openmetadata/service/resources/glossary/GlossaryResourceTest.java

View workflow job for this annotation

GitHub Actions / Test Report

GlossaryResourceTest.testGlossaryImportExport

Condition with Lambda expression in org.openmetadata.service.resources.glossary.GlossaryResourceTest was not fulfilled within 2 minutes.
Raw output
org.awaitility.core.ConditionTimeoutException: Condition with Lambda expression in org.openmetadata.service.resources.glossary.GlossaryResourceTest was not fulfilled within 2 minutes.
	at org.awaitility.core.ConditionAwaiter.await(ConditionAwaiter.java:167)
	at org.awaitility.core.CallableCondition.await(CallableCondition.java:78)
	at org.awaitility.core.CallableCondition.await(CallableCondition.java:26)
	at org.awaitility.core.ConditionFactory.until(ConditionFactory.java:1006)
	at org.awaitility.core.ConditionFactory.until(ConditionFactory.java:975)
	at org.openmetadata.service.resources.glossary.GlossaryResourceTest.testGlossaryImportExport(GlossaryResourceTest.java:941)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:569)
	at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:727)
	at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
	at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:156)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:147)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:86)
	at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(InterceptingExecutableInvoker.java:103)
	at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:93)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
	at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:92)
	at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:86)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:217)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:213)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:138)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:147)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:127)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:90)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:55)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:102)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:54)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
	at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
	at org.apache.maven.surefire.junitplatform.LazyLauncher.execute(LazyLauncher.java:56)
	at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.execute(JUnitPlatformProvider.java:184)
	at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invokeAllTests(JUnitPlatformProvider.java:148)
	at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invoke(JUnitPlatformProvider.java:120)
	at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:385)
	at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:162)
	at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:507)
	at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:495)
Caused by: org.opentest4j.AssertionFailedError: expected: <status,details,parent,name*,displayName,description,synonyms,relatedTerms,references,tags,reviewers,owner,glossaryStatus,extension
success,Entity created,,g1,dsp1,"dsc1,1",h1;h2;h3,,term1;http://term1,PII.None,user:user_-.glossaryresourcetest,user:user_-.glossaryresourcetest,Approved,"glossaryTermDateCp:18-09-2024;glossaryTermDateTimeCp:18-09-2024 01:09:34;glossaryTermDurationCp:PT5H30M10S;glossaryTermEmailCp:admin@open-metadata.org;glossaryTermEntRefCp:team:""team_'-.&()[]쳅GlossaryResourceTestl"";glossaryTermEntRefListCp:user:""user_-.glossaryresourcetest""|user:""user_-.glossaryresourcetestb"""
success,Entity created,,g2,dsp2,dsc3,h1;h3;h3,,term2;https://term2,PII.NonSensitive,,user:user_-.glossaryresourcetest,Approved,"glossaryTermEnumCpMulti:val3|val2|val1|val4|val5;glossaryTermEnumCpSingle:single1;glossaryTermIntegerCp:7777;glossaryTermMarkdownCp:# Sample Markdown Text;glossaryTermNumberCp:123456;""glossaryTermQueryCp:select col,row from table where id ='30';"";glossaryTermStringCp:sample string content;glossaryTermTimeCp:10:08:45;glossaryTermTimeIntervalCp:1726142300000:17261420000;glossaryTermTimestampCp:1726142400000"
success,Entity created,importExportTest.g1,g11,dsp2,dsc11,h1;h3;h3,,,,user:user_-.glossaryresourcetest,team:team_'-.&()[]쳅GlossaryResourceTestl,Draft,
> but was: <status,details,parent,name*,displayName,description,synonyms,relatedTerms,references,tags,reviewers,owner,glossaryStatus,extension
success,Entity updated,,g1,dsp1,"dsc1,1",h1;h2;h3,,term1;http://term1,PII.None,user:user_-.glossaryresourcetest,user:user_-.glossaryresourcetest,Approved,"glossaryTermDateCp:18-09-2024;glossaryTermDateTimeCp:18-09-2024 01:09:34;glossaryTermDurationCp:PT5H30M10S;glossaryTermEmailCp:admin@open-metadata.org;glossaryTermEntRefCp:team:""team_'-.&()[]쳅GlossaryResourceTestl"";glossaryTermEntRefListCp:user:""user_-.glossaryresourcetest""|user:""user_-.glossaryresourcetestb"""
success,Entity updated,,g2,dsp2,dsc3,h1;h3;h3,,term2;https://term2,PII.NonSensitive,,user:user_-.glossaryresourcetest,Approved,"glossaryTermEnumCpMulti:val3|val2|val1|val4|val5;glossaryTermEnumCpSingle:single1;glossaryTermIntegerCp:7777;glossaryTermMarkdownCp:# Sample Markdown Text;glossaryTermNumberCp:123456;""glossaryTermQueryCp:select col,row from table where id ='30';"";glossaryTermStringCp:sample string content;glossaryTermTimeCp:10:08:45;glossaryTermTimeIntervalCp:1726142300000:17261420000;glossaryTermTimestampCp:1726142400000"
success,Entity updated,importExportTest.g1,g11,dsp2,dsc11,h1;h3;h3,,,,user:user_-.glossaryresourcetest,team:team_'-.&()[]쳅GlossaryResourceTestl,Draft,
>
	at org.junit.jupiter.api.AssertionFailureBuilder.build(AssertionFailureBuilder.java:151)
	at org.junit.jupiter.api.AssertionFailureBuilder.buildAndThrow(AssertionFailureBuilder.java:132)
	at org.junit.jupiter.api.AssertEquals.failNotEqual(AssertEquals.java:197)
	at org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:182)
	at org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:177)
	at org.junit.jupiter.api.Assertions.assertEquals(Assertions.java:1145)
	at org.openmetadata.service.resources.EntityResourceTest.importCsvAndValidate(EntityResourceTest.java:4191)
	at org.openmetadata.service.resources.EntityResourceTest.testImportExport(EntityResourceTest.java:4223)
	at org.openmetadata.service.resources.glossary.GlossaryResourceTest.lambda$testGlossaryImportExport$12(GlossaryResourceTest.java:944)
	at org.awaitility.core.CallableCondition$ConditionEvaluationWrapper.eval(CallableCondition.java:99)
	at org.awaitility.core.ConditionAwaiter$ConditionPoller.call(ConditionAwaiter.java:248)
	at org.awaitility.core.ConditionAwaiter$ConditionPoller.call(ConditionAwaiter.java:235)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
	at java.base/java.lang.Thread.run(Thread.java:840)
glossary.getName(),
GlossaryCsv.HEADERS,
createRecords,
updateRecords,
newRecords);
return true;
} catch (Exception e) {
// Return false to retry
return false;
}
});
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,11 @@ import {
createGlossaryTerms,
createTagTaskForGlossary,
deleteGlossaryOrGlossaryTerm,
descriptionBox,
deselectColumns,
dragAndDropColumn,
dragAndDropTerm,
filterStatus,
getEscapedTermFqn,
goToAssetsTab,
openColumnDropdown,
renameGlossaryTerm,
Expand All @@ -63,6 +63,8 @@ import {
selectColumns,
toggleAllColumnsSelection,
updateGlossaryTermDataFromTree,
updateGlossaryTermOwners,
updateGlossaryTermReviewers,
validateGlossaryTerm,
verifyAllColumns,
verifyColumnsVisibility,
Expand Down Expand Up @@ -126,7 +128,7 @@ test.describe('Glossary tests', () => {
await verifyTaskCreated(
page1,
glossary1.data.fullyQualifiedName,
glossary1.data.terms[0].data
glossary1.data.terms[0].data.name
);

await approveGlossaryTermTask(page1, glossary1.data.terms[0].data);
Expand Down Expand Up @@ -183,7 +185,7 @@ test.describe('Glossary tests', () => {
await verifyTaskCreated(
page1,
glossary2.data.fullyQualifiedName,
glossary2.data.terms[0].data
glossary2.data.terms[0].data.name
);

await approveGlossaryTermTask(page1, glossary2.data.terms[0].data);
Expand Down Expand Up @@ -304,126 +306,63 @@ test.describe('Glossary tests', () => {
const { page, afterAction, apiContext } = await performAdminLogin(browser);
const glossary1 = new Glossary();
const glossaryTerm1 = new GlossaryTerm(glossary1);
await glossary1.create(apiContext);
await glossaryTerm1.create(apiContext);

const testtag = `Test tag ${uuid()}`;

await redirectToHomePage(page);
await sidebarClick(page, SidebarItem.GLOSSARY);

await page.click('[data-testid="add-classification"]');

await expect(page.getByRole('dialog')).toBeVisible();

await page.getByTestId('name').fill(testtag);
await page.locator(descriptionBox).fill('Test Description');
const owner1 = new UserClass();
const reviewer1 = new UserClass();

const glossaryTermResponse = page.waitForResponse('/api/v1/glossaryTerms');
await page.click('[data-testid="save-glossary-term"]');
await glossaryTermResponse;

await page.click('[data-testid="expand-icon"]');

await expect(page.getByText(testtag)).toBeVisible();

await page.getByTestId('edit-button').last().click();
try {
await glossary1.create(apiContext);
await glossaryTerm1.create(apiContext);
await owner1.create(apiContext);
await reviewer1.create(apiContext);
await await redirectToHomePage(page);
await sidebarClick(page, SidebarItem.GLOSSARY);
await selectActiveGlossary(page, glossary1.data.displayName);

await expect(page.getByRole('dialog')).toBeVisible();
await updateGlossaryTermOwners(page, glossaryTerm1.data, [
{
name: `${owner1.data.firstName}${owner1.data.lastName}`,
type: 'user',
},
]);

await page
.getByTestId('edit-glossary-modal')
.getByTestId('add-owner')
.click();
await updateGlossaryTermReviewers(page, glossaryTerm1.data, [
{
name: `${reviewer1.data.firstName}${reviewer1.data.lastName}`,
type: 'user',
},
]);

await expect(page.getByTestId('select-owner-tabs')).toBeVisible();
await openColumnDropdown(page);
const checkboxLabels = ['Reviewer'];
await selectColumns(page, checkboxLabels);
await clickSaveButton(page);
await verifyColumnsVisibility(page, checkboxLabels, true);

await page.waitForSelector('[data-testid="loader"]', { state: 'detached' });
const escapedFqn = getEscapedTermFqn(glossaryTerm1.data);
const termRow = page.locator(`[data-row-key="${escapedFqn}"]`);

await expect(page.getByRole('listitem', { name: 'admin' })).toHaveClass(
/active/
);
// Verify the Reviewer
const reviewerSelector = `td:nth-child(3) a[data-testid="owner-link"]`;
const reviewerText = await termRow
.locator(reviewerSelector)
.textContent();

const searchUser = page.waitForResponse(
`/api/v1/search/query?q=*${encodeURIComponent(
user1.responseData.displayName
)}*`
);
await page
.getByTestId(`owner-select-users-search-bar`)
.fill(user1.responseData.displayName);
await searchUser;

await page
.getByRole('listitem', {
name: user1.responseData.displayName,
exact: true,
})
.click();
await page.getByTestId('selectable-list-update-btn').click();

await expect(
page.getByRole('link', { name: user1.responseData.displayName })
).toBeVisible();

await page
.getByTestId('edit-glossary-modal')
.getByTestId('add-reviewers')
.click();

await expect(
page
.getByRole('tooltip', { name: 'Selected Reviewers Teams' })
.getByTestId('select-owner-tabs')
).toBeVisible();

const userListResponse = page.waitForResponse(
'/api/v1/users?limit=*&isBot=false*'
);
await page.getByRole('tab', { name: 'Users' }).click();
await userListResponse;
expect(reviewerText).toBe(
`${reviewer1.data.firstName}${reviewer1.data.lastName}`
);

await page.waitForSelector('[data-testid="loader"]', { state: 'detached' });
// Verify the Owner
const ownerSelector = `td:nth-child(4) a[data-testid="owner-link"]`;
const ownerText = await termRow.locator(ownerSelector).textContent();

const searchUserReviewer = page.waitForResponse(
`/api/v1/search/query?q=*${encodeURIComponent(
user2.responseData.displayName
)}*`
);
await page
.getByTestId(`owner-select-users-search-bar`)
.fill(user2.responseData.displayName);
await searchUserReviewer;

await page
.getByRole('listitem', {
name: user2.responseData.displayName,
exact: true,
})
.click();

await page.getByTestId('selectable-list-update-btn').click();

await page.click('[data-testid="save-glossary-term"]');
await glossaryTermResponse;

await expect(
page.getByRole('link', { name: user1.responseData.displayName })
).toBeVisible();

await openColumnDropdown(page);
const checkboxLabels = ['Reviewer'];
await selectColumns(page, checkboxLabels);
await clickSaveButton(page);
await verifyColumnsVisibility(page, checkboxLabels, true);

await expect(
page.getByRole('link', { name: user2.responseData.displayName })
).toBeVisible();

await glossaryTerm1.delete(apiContext);
await glossary1.delete(apiContext);
await afterAction();
expect(ownerText).toBe(`${owner1.data.firstName}${owner1.data.lastName}`);
} finally {
await glossaryTerm1.delete(apiContext);
await glossary1.delete(apiContext);
await owner1.delete(apiContext);
await reviewer1.delete(apiContext);
await afterAction();
}
});

test('Add and Remove Assets', async ({ browser }) => {
Expand Down
Loading

0 comments on commit 5263858

Please sign in to comment.