From c1e20873b1a38fbabe9590e8d6de1af50aa4f439 Mon Sep 17 00:00:00 2001 From: sonika-shah <58761340+sonika-shah@users.noreply.github.com> Date: Sun, 22 Sep 2024 21:30:35 +0530 Subject: [PATCH] Fix #17929 : Fix team export issue (#17930) --- .../service/jdbi3/CollectionDAO.java | 6 +- .../service/jdbi3/TeamRepository.java | 5 +- .../resources/teams/TeamResourceTest.java | 55 ++++++++++++++++++- .../ui/playwright/e2e/Pages/Teams.spec.ts | 43 +++++++++++++++ 4 files changed, 104 insertions(+), 5 deletions(-) diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/CollectionDAO.java b/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/CollectionDAO.java index 7eec367c3f6..4c05409c40f 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/CollectionDAO.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/CollectionDAO.java @@ -32,6 +32,7 @@ import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.UUID; import java.util.stream.Collectors; import lombok.Builder; @@ -3237,7 +3238,8 @@ public interface CollectionDAO { } // Quoted name is stored in fullyQualifiedName column and not in the name column - beforeName = FullyQualifiedName.unquoteName(beforeName); + beforeName = + Optional.ofNullable(beforeName).map(FullyQualifiedName::unquoteName).orElse(null); return listBefore( getTableName(), filter.getQueryParams(), @@ -3281,7 +3283,7 @@ public interface CollectionDAO { } // Quoted name is stored in fullyQualifiedName column and not in the name column - afterName = FullyQualifiedName.unquoteName(afterName); + afterName = Optional.ofNullable(afterName).map(FullyQualifiedName::unquoteName).orElse(null); return listAfter( getTableName(), filter.getQueryParams(), diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/TeamRepository.java b/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/TeamRepository.java index 3f3c2cb8b28..ee6b3856915 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/TeamRepository.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/TeamRepository.java @@ -738,7 +738,7 @@ public class TeamRepository extends EntityRepository { } teams.addAll(list); for (Team teamEntry : list) { - listTeams(repository, teamEntry.getName(), teams, fields); + listTeams(repository, teamEntry.getFullyQualifiedName(), teams, fields); } return teams; } @@ -746,7 +746,8 @@ public class TeamRepository extends EntityRepository { public String exportCsv() throws IOException { TeamRepository repository = (TeamRepository) Entity.getEntityRepository(TEAM); final Fields fields = repository.getFields("owners,defaultRoles,parents,policies"); - return exportCsv(listTeams(repository, team.getName(), new ArrayList<>(), fields)); + return exportCsv( + listTeams(repository, team.getFullyQualifiedName(), new ArrayList<>(), fields)); } } diff --git a/openmetadata-service/src/test/java/org/openmetadata/service/resources/teams/TeamResourceTest.java b/openmetadata-service/src/test/java/org/openmetadata/service/resources/teams/TeamResourceTest.java index 993325d10ca..7748f9d9a51 100644 --- a/openmetadata-service/src/test/java/org/openmetadata/service/resources/teams/TeamResourceTest.java +++ b/openmetadata-service/src/test/java/org/openmetadata/service/resources/teams/TeamResourceTest.java @@ -891,7 +891,10 @@ public class TeamResourceTest extends EntityResourceTest { // Add new team x3 to existing rows String record3 = getRecord(3, GROUP, team.getName(), null, true, null, (List) null); - List newRecords = listOf(record3); + // Add new team containing dot character in name + String teamNameWithDotRecord = + getRecord("team.with.dot", GROUP, team.getName(), null, true, null, (List) null); + List newRecords = listOf(record3, teamNameWithDotRecord); testImportExport(team.getName(), TeamCsv.HEADERS, createRecords, updateRecords, newRecords); // Import to team111 a user with parent team1 - since team1 is not under team111 hierarchy, @@ -1221,4 +1224,54 @@ public class TeamResourceTest extends EntityResourceTest { defaultRoles, policies); } + + private String getRecord( + String teamName, + TeamType teamType, + String parent, + User owner, + Boolean isJoinable, + List defaultRoles, + List policies) { + return getRecord( + teamName, + teamType, + parent != null ? parent : "", + owner != null ? "user:" + owner.getName() : "", + isJoinable, + defaultRoles != null + ? defaultRoles.stream() + .flatMap(r -> Stream.of(r.getName())) + .collect(Collectors.joining(";")) + : "", + policies != null + ? policies.stream() + .flatMap(p -> Stream.of(p.getName())) + .collect(Collectors.joining(";")) + : ""); + } + + private String getRecord( + String teamName, + TeamType teamType, + String parent, + String owner, + Boolean isJoinable, + String defaultRoles, + String policies) { + // CSV Header + // "name", "displayName", "description", "teamType", "parents", "owners", "isJoinable", + // "defaultRoles", & "policies" + return String.format( + "x%s,displayName%s,description%s,%s,%s,%s,%s,%s,%s", + teamName, + teamName, + teamName, + teamType.value(), + parent, + owner, + isJoinable == null ? "" : isJoinable, + defaultRoles, + policies); + } } diff --git a/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Teams.spec.ts b/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Teams.spec.ts index 393eb932817..1d43dd213b4 100644 --- a/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Teams.spec.ts +++ b/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Teams.spec.ts @@ -447,4 +447,47 @@ test.describe('Teams Page', () => { await afterAction(); } }); + + test('Export team', async ({ page }) => { + const { apiContext } = await getApiContext(page); + const id = uuid(); + const team = new TeamClass({ + name: `pw%team.export-${id}`, + displayName: `pw team export ${id}`, + description: 'playwright team export description', + teamType: 'Department', + }); + + await team.create(apiContext); + + try { + await settingClick(page, GlobalSettingOptions.TEAMS); + await page.waitForLoadState('networkidle'); + + await searchTeam(page, team.responseData?.['displayName']); + + await page + .locator(`[data-row-key="${team.data.name}"]`) + .getByRole('link') + .click(); + + await page.waitForLoadState('networkidle'); + + await expect(page.getByTestId('team-heading')).toHaveText( + team.data.displayName + ); + + const downloadPromise = page.waitForEvent('download'); + + await page.getByTestId('manage-button').click(); + await page.getByTestId('export-details-container').click(); + await page.fill('#fileName', team.data.name); + await page.click('#submit-button'); + const download = await downloadPromise; + // Wait for the download process to complete and save the downloaded file somewhere. + await download.saveAs('downloads/' + download.suggestedFilename()); + } finally { + await team.delete(apiContext); + } + }); });