mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-12-27 07:28:30 +00:00
* fix Domain inheritance issue after team removal * add backend test and fix logic * added playwright test * update domain on reload * fix test * fix test --------- Co-authored-by: Shrushti Polekar <shrushtipolekar@gmail.com>
This commit is contained in:
parent
2177bc2e03
commit
56b1719494
@ -1062,8 +1062,12 @@ public class UserRepository extends EntityRepository<User> {
|
||||
|
||||
List<EntityReference> origDomains =
|
||||
EntityUtil.populateEntityReferences(listOrEmptyMutable(original.getDomains()));
|
||||
// Skip domains inherited from teams,they are handled in setInheritedFields().
|
||||
List<EntityReference> updatedDomains =
|
||||
EntityUtil.populateEntityReferences(listOrEmptyMutable(updated.getDomains()));
|
||||
EntityUtil.populateEntityReferences(listOrEmptyMutable(updated.getDomains())).stream()
|
||||
.filter(domain -> domain.getInherited() == null || !domain.getInherited())
|
||||
.collect(Collectors.toList());
|
||||
updated.setDomains(updatedDomains);
|
||||
|
||||
// Remove Domains for the user
|
||||
deleteTo(original.getId(), USER, Relationship.HAS, Entity.DOMAIN);
|
||||
|
||||
@ -1705,6 +1705,91 @@ public class UserResourceTest extends EntityResourceTest<User, CreateUser> {
|
||||
assertEquals(PIIMasker.MASKED_MAIL, noEmailUser.getEmail());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdateUser_RemovesInheritedDomainsFromRemovedTeams(TestInfo test)
|
||||
throws HttpResponseException {
|
||||
TeamResourceTest teamResourceTest = new TeamResourceTest();
|
||||
|
||||
// Create team1 with domain1
|
||||
CreateTeam createTeam1 =
|
||||
teamResourceTest.createRequest(test).withDomains(List.of(DOMAIN.getFullyQualifiedName()));
|
||||
Team team1 = teamResourceTest.createEntity(createTeam1, ADMIN_AUTH_HEADERS);
|
||||
|
||||
// Create team2 with domain2
|
||||
CreateTeam createTeam2 =
|
||||
teamResourceTest
|
||||
.createRequest(test, 1)
|
||||
.withDomains(List.of(DOMAIN1.getFullyQualifiedName()));
|
||||
Team team2 = teamResourceTest.createEntity(createTeam2, ADMIN_AUTH_HEADERS);
|
||||
|
||||
// Create user with both teams
|
||||
CreateUser create = createRequest(test).withTeams(listOf(team1.getId(), team2.getId()));
|
||||
User user = createEntity(create, ADMIN_AUTH_HEADERS);
|
||||
|
||||
// Verify user has both domains inherited from the teams
|
||||
User createdUser = getEntity(user.getId(), FIELD_DOMAINS, ADMIN_AUTH_HEADERS);
|
||||
assertNotNull(createdUser.getDomains());
|
||||
assertEquals(2, createdUser.getDomains().size());
|
||||
|
||||
// Check that both domains are inherited
|
||||
List<EntityReference> domains = createdUser.getDomains();
|
||||
boolean hasDomain1 =
|
||||
domains.stream().anyMatch(d -> d.getId().equals(DOMAIN.getId()) && d.getInherited());
|
||||
boolean hasDomain2 =
|
||||
domains.stream().anyMatch(d -> d.getId().equals(DOMAIN1.getId()) && d.getInherited());
|
||||
assertTrue(hasDomain1, "User should inherit domain from team1");
|
||||
assertTrue(hasDomain2, "User should inherit domain from team2");
|
||||
|
||||
// Scenario 1: Remove team2 from user - domain2 should be removed as well
|
||||
String userJson = JsonUtils.pojoToJson(createdUser);
|
||||
createdUser.setTeams(List.of(team1.getEntityReference()));
|
||||
|
||||
// Update user to only have team1
|
||||
User updatedUser = patchEntity(createdUser.getId(), userJson, createdUser, ADMIN_AUTH_HEADERS);
|
||||
updatedUser = getEntity(updatedUser.getId(), FIELD_DOMAINS, ADMIN_AUTH_HEADERS);
|
||||
|
||||
// Verify that domain2 is no longer in the domains list
|
||||
assertEquals(1, updatedUser.getDomains().size());
|
||||
assertEquals(DOMAIN.getId(), updatedUser.getDomains().get(0).getId());
|
||||
assertTrue(updatedUser.getDomains().get(0).getInherited());
|
||||
|
||||
// Scenario 2: Create team3 with the same domain as team1 (domain1)
|
||||
// and verify that when one team is removed, domain remains inherited
|
||||
CreateTeam createTeam3 =
|
||||
teamResourceTest
|
||||
.createRequest(test, 2)
|
||||
.withDomains(List.of(DOMAIN.getFullyQualifiedName()));
|
||||
Team team3 = teamResourceTest.createEntity(createTeam3, ADMIN_AUTH_HEADERS);
|
||||
|
||||
// Add user to both teams that have the same domain
|
||||
userJson = JsonUtils.pojoToJson(updatedUser);
|
||||
updatedUser.setTeams(List.of(team1.getEntityReference(), team3.getEntityReference()));
|
||||
|
||||
User userWithBothTeams =
|
||||
patchEntity(updatedUser.getId(), userJson, updatedUser, ADMIN_AUTH_HEADERS);
|
||||
userWithBothTeams = getEntity(userWithBothTeams.getId(), FIELD_DOMAINS, ADMIN_AUTH_HEADERS);
|
||||
|
||||
// Still should have just domain1
|
||||
assertEquals(1, userWithBothTeams.getDomains().size());
|
||||
assertEquals(DOMAIN.getId(), userWithBothTeams.getDomains().get(0).getId());
|
||||
assertTrue(userWithBothTeams.getDomains().get(0).getInherited());
|
||||
|
||||
// Remove team1, but keep team3 - domain1 should still be inherited from team3
|
||||
userJson = JsonUtils.pojoToJson(userWithBothTeams);
|
||||
userWithBothTeams.setTeams(List.of(team3.getEntityReference()));
|
||||
|
||||
User userWithTeam3 =
|
||||
patchEntity(userWithBothTeams.getId(), userJson, userWithBothTeams, ADMIN_AUTH_HEADERS);
|
||||
userWithTeam3 = getEntity(userWithTeam3.getId(), FIELD_DOMAINS, ADMIN_AUTH_HEADERS);
|
||||
|
||||
// Should still have domain1 inherited from team3
|
||||
assertEquals(1, userWithTeam3.getDomains().size());
|
||||
assertEquals(DOMAIN.getId(), userWithTeam3.getDomains().get(0).getId());
|
||||
assertTrue(
|
||||
userWithTeam3.getDomains().get(0).getInherited(),
|
||||
"Domain should still be marked as inherited");
|
||||
}
|
||||
|
||||
private DecodedJWT decodedJWT(String token) {
|
||||
DecodedJWT jwt;
|
||||
try {
|
||||
|
||||
@ -109,6 +109,102 @@ test.describe('User with different Roles', () => {
|
||||
);
|
||||
});
|
||||
|
||||
test('Create team with domain and verify visibility of inherited domain in user profile after team removal', async ({
|
||||
adminPage,
|
||||
}) => {
|
||||
await redirectToUserPage(adminPage);
|
||||
await adminPage.waitForLoadState('networkidle');
|
||||
|
||||
await expect(adminPage.getByTestId('user-profile-teams')).toBeVisible();
|
||||
|
||||
await adminPage.getByTestId('edit-teams-button').click();
|
||||
|
||||
await expect(adminPage.getByTestId('team-select')).toBeVisible();
|
||||
|
||||
await adminPage.getByTestId('team-select').click();
|
||||
|
||||
await adminPage.waitForSelector('.ant-tree-select-dropdown', {
|
||||
state: 'visible',
|
||||
});
|
||||
|
||||
await adminPage.getByText(team.responseData.displayName).click();
|
||||
|
||||
const updateTeamsResponse = adminPage.waitForResponse(
|
||||
(response) =>
|
||||
response.url().includes('/api/v1/users/') &&
|
||||
response.request().method() === 'PATCH'
|
||||
);
|
||||
|
||||
await adminPage.getByTestId('teams-edit-save-btn').click();
|
||||
|
||||
await updateTeamsResponse;
|
||||
|
||||
await expect(adminPage.getByTestId('user-profile-teams')).toContainText(
|
||||
team.responseData.displayName
|
||||
);
|
||||
|
||||
await adminPage.getByText(team.responseData.displayName).first().click();
|
||||
|
||||
await adminPage.waitForLoadState('networkidle');
|
||||
|
||||
const domainResponse = adminPage.waitForResponse((response) =>
|
||||
response.url().includes('/api/v1/domains/hierarchy')
|
||||
);
|
||||
|
||||
await adminPage.getByTestId('add-domain').click();
|
||||
|
||||
await domainResponse;
|
||||
|
||||
await adminPage.getByText(domain.responseData.displayName).click();
|
||||
|
||||
const teamsResponse = adminPage.waitForResponse(
|
||||
(response) =>
|
||||
response.url().includes('/api/v1/teams/') &&
|
||||
response.request().method() === 'PATCH'
|
||||
);
|
||||
|
||||
await adminPage.getByText('Update').click();
|
||||
|
||||
await teamsResponse;
|
||||
|
||||
await redirectToUserPage(adminPage);
|
||||
|
||||
await adminPage.waitForLoadState('networkidle');
|
||||
|
||||
await expect(adminPage.getByTestId('user-profile-teams')).toContainText(
|
||||
team.responseData.displayName
|
||||
);
|
||||
|
||||
await expect(
|
||||
adminPage.locator('[data-testid="header-domain-container"]')
|
||||
).toContainText(domain.responseData.displayName);
|
||||
|
||||
await adminPage.getByTestId('edit-teams-button').click();
|
||||
|
||||
await adminPage.getByTestId('team-select').click();
|
||||
|
||||
await adminPage.waitForSelector('.ant-tree-select-dropdown', {
|
||||
state: 'visible',
|
||||
});
|
||||
|
||||
await adminPage
|
||||
.locator('[title="' + team.responseData.displayName + '"]')
|
||||
.first()
|
||||
.click();
|
||||
|
||||
const userProfileResponse = adminPage.waitForResponse((response) =>
|
||||
response.url().includes('/api/v1/users/')
|
||||
);
|
||||
|
||||
await adminPage.getByTestId('teams-edit-save-btn').click({ force: true });
|
||||
|
||||
await userProfileResponse;
|
||||
|
||||
await expect(
|
||||
adminPage.locator('[data-testid="header-domain-container"]')
|
||||
).not.toContainText(domain.responseData.displayName);
|
||||
});
|
||||
|
||||
test('User can search for a domain', async ({ adminPage }) => {
|
||||
await redirectToUserPage(adminPage);
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ export const redirectToUserPage = async (page: Page) => {
|
||||
await page.getByTestId('dropdown-profile').click();
|
||||
|
||||
// Hover on the profile avatar to close the name tooltip
|
||||
await page.getByTestId('profile-avatar').hover();
|
||||
await page.getByTestId('profile-avatar').first().hover();
|
||||
|
||||
await page.waitForSelector('.profile-dropdown', { state: 'visible' });
|
||||
|
||||
|
||||
@ -128,6 +128,13 @@ const UserPage = () => {
|
||||
roles: response.roles,
|
||||
isAdmin: response.isAdmin,
|
||||
};
|
||||
} else if (key === 'teams') {
|
||||
// Handle teams update - this affects inherited domains
|
||||
updatedKeyData = {
|
||||
[key]: response[key],
|
||||
// Also update domains since they are inherited from teams
|
||||
domains: response.domains,
|
||||
};
|
||||
} else {
|
||||
updatedKeyData = { [key]: response[key] };
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user