mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-10-31 18:48:35 +00:00
* minor(#16099): when adding team give user option to configure the isJoinable field * chore: add helper text for public team field * test: add test for create team * fix: playwright test
This commit is contained in:
parent
cd5d8dfa06
commit
870bb8c3f2
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright 2024 Collate.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import test, { expect } from '@playwright/test';
|
||||
import { GlobalSettingOptions } from '../../constant/settings';
|
||||
import { redirectToHomePage } from '../../utils/common';
|
||||
import { settingClick } from '../../utils/sidebar';
|
||||
import { createTeam, hardDeleteTeam } from '../../utils/team';
|
||||
|
||||
// use the admin user to login
|
||||
test.use({ storageState: 'playwright/.auth/admin.json' });
|
||||
|
||||
test.describe('Teams Page', () => {
|
||||
test.beforeEach('Visit Home Page', async ({ page }) => {
|
||||
await redirectToHomePage(page);
|
||||
});
|
||||
|
||||
test('Create a new public team', async ({ page }) => {
|
||||
await settingClick(page, GlobalSettingOptions.TEAMS);
|
||||
|
||||
await page.waitForSelector('[data-testid="add-team"]');
|
||||
|
||||
await page.getByTestId('add-team').click();
|
||||
|
||||
const publicTeam = await createTeam(page, true);
|
||||
|
||||
await page.getByRole('link', { name: publicTeam.displayName }).click();
|
||||
|
||||
await page
|
||||
.getByTestId('team-details-collapse')
|
||||
.getByTestId('manage-button')
|
||||
.click();
|
||||
|
||||
await expect(page.locator('button[role="switch"]')).toHaveAttribute(
|
||||
'aria-checked',
|
||||
'true'
|
||||
);
|
||||
|
||||
await page.click('body'); // Equivalent to clicking outside
|
||||
|
||||
await hardDeleteTeam(page);
|
||||
});
|
||||
|
||||
test('Create a new private team', async ({ page }) => {
|
||||
await settingClick(page, GlobalSettingOptions.TEAMS);
|
||||
|
||||
await page.waitForSelector('[data-testid="add-team"]');
|
||||
|
||||
await page.getByTestId('add-team').click();
|
||||
|
||||
const publicTeam = await createTeam(page);
|
||||
|
||||
await page.getByRole('link', { name: publicTeam.displayName }).click();
|
||||
|
||||
await page
|
||||
.getByTestId('team-details-collapse')
|
||||
.getByTestId('manage-button')
|
||||
.click();
|
||||
|
||||
await expect(page.locator('button[role="switch"]')).toHaveAttribute(
|
||||
'aria-checked',
|
||||
'false'
|
||||
);
|
||||
|
||||
await page.click('body'); // Equivalent to clicking outside
|
||||
|
||||
await hardDeleteTeam(page);
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 2024 Collate.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { expect, Page } from '@playwright/test';
|
||||
import { uuid } from './common';
|
||||
|
||||
export const createTeam = async (page: Page, isPublic?: boolean) => {
|
||||
const teamData = {
|
||||
name: `pwteam-${uuid()}`,
|
||||
displayName: `PW ${uuid()}`,
|
||||
email: `pwteam${uuid()}@example.com`,
|
||||
description: 'This is a PW team',
|
||||
};
|
||||
|
||||
await page.waitForSelector('[role="dialog"].ant-modal');
|
||||
|
||||
await expect(page.locator('[role="dialog"].ant-modal')).toBeVisible();
|
||||
|
||||
await page.fill('[data-testid="name"]', teamData.name);
|
||||
await page.fill('[data-testid="display-name"]', teamData.displayName);
|
||||
await page.fill('[data-testid="email"]', teamData.email);
|
||||
|
||||
if (isPublic) {
|
||||
await page.getByTestId('isJoinable-switch-button').click();
|
||||
}
|
||||
|
||||
await page
|
||||
.locator('.toastui-editor-md-container > .toastui-editor > .ProseMirror')
|
||||
.isVisible();
|
||||
await page
|
||||
.locator('.toastui-editor-md-container > .toastui-editor > .ProseMirror')
|
||||
.fill(teamData.description);
|
||||
|
||||
const createTeamResponse = page.waitForResponse('/api/v1/teams');
|
||||
|
||||
await page.locator('button[type="submit"]').click();
|
||||
|
||||
await createTeamResponse;
|
||||
|
||||
return teamData;
|
||||
};
|
||||
|
||||
export const hardDeleteTeam = async (page: Page) => {
|
||||
await page
|
||||
.getByTestId('team-details-collapse')
|
||||
.getByTestId('manage-button')
|
||||
.click();
|
||||
await page.getByTestId('delete-button').click();
|
||||
|
||||
await page.waitForSelector('[role="dialog"].ant-modal');
|
||||
|
||||
await expect(page.locator('[role="dialog"].ant-modal')).toBeVisible();
|
||||
|
||||
await page.click('[data-testid="hard-delete-option"]');
|
||||
await page.check('[data-testid="hard-delete"]');
|
||||
await page.fill('[data-testid="confirmation-text-input"]', 'DELETE');
|
||||
|
||||
const deleteResponse = page.waitForResponse(
|
||||
'/api/v1/teams/*?hardDelete=true&recursive=true'
|
||||
);
|
||||
|
||||
await page.click('[data-testid="confirm-button"]');
|
||||
|
||||
await deleteResponse;
|
||||
|
||||
await expect(page.locator('.Toastify__toast-body')).toHaveText(
|
||||
/deleted successfully!/
|
||||
);
|
||||
|
||||
await page.click('.Toastify__close-button');
|
||||
};
|
||||
@ -10,7 +10,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { render } from '@testing-library/react';
|
||||
import { act, fireEvent, render } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { TeamType } from '../../generated/entity/teams/team';
|
||||
import AddTeamForm from './AddTeamForm';
|
||||
@ -38,5 +38,114 @@ describe('AddTeamForm component', () => {
|
||||
expect(getByTestId('email')).toBeInTheDocument();
|
||||
expect(getByTestId('editor')).toBeInTheDocument();
|
||||
expect(getByTestId('team-selector')).toBeInTheDocument();
|
||||
expect(getByTestId('isJoinable-switch-button')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should call onCancel function when cancel button is clicked', () => {
|
||||
const { getByText } = render(
|
||||
<AddTeamForm
|
||||
visible
|
||||
isLoading={false}
|
||||
parentTeamType={TeamType.Organization}
|
||||
onCancel={mockCancel}
|
||||
onSave={mockSave}
|
||||
/>
|
||||
);
|
||||
|
||||
getByText('Cancel').click();
|
||||
|
||||
expect(mockCancel).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should call onSave function when save button is clicked', async () => {
|
||||
const { getByText, getByTestId } = render(
|
||||
<AddTeamForm
|
||||
visible
|
||||
isLoading={false}
|
||||
parentTeamType={TeamType.Organization}
|
||||
onCancel={mockCancel}
|
||||
onSave={mockSave}
|
||||
/>
|
||||
);
|
||||
|
||||
// input name
|
||||
const nameInput = getByTestId('name');
|
||||
await act(async () => {
|
||||
fireEvent.change(nameInput, { target: { value: 'test' } });
|
||||
});
|
||||
|
||||
// input displayName
|
||||
const displayNameInput = getByTestId('display-name');
|
||||
await act(async () => {
|
||||
fireEvent.change(displayNameInput, { target: { value: 'Test Team' } });
|
||||
});
|
||||
|
||||
// input email
|
||||
const emailInput = getByTestId('email');
|
||||
await act(async () => {
|
||||
fireEvent.change(emailInput, { target: { value: 'testteam@gmail.com' } });
|
||||
});
|
||||
|
||||
// make team joinable
|
||||
const isJoinableSwitch = getByTestId('isJoinable-switch-button');
|
||||
await act(async () => {
|
||||
fireEvent.click(isJoinableSwitch);
|
||||
});
|
||||
|
||||
// save form
|
||||
const saveButton = getByText('label.save');
|
||||
|
||||
await act(async () => {
|
||||
fireEvent.click(saveButton);
|
||||
});
|
||||
|
||||
expect(mockSave).toHaveBeenCalledWith({
|
||||
name: 'test',
|
||||
displayName: 'Test Team',
|
||||
email: 'testteam@gmail.com',
|
||||
description: '',
|
||||
isJoinable: true,
|
||||
teamType: 'Group',
|
||||
});
|
||||
});
|
||||
|
||||
it('should call onSave function when save button is clicked with isJoinable default value', async () => {
|
||||
const { getByText, getByTestId } = render(
|
||||
<AddTeamForm
|
||||
visible
|
||||
isLoading={false}
|
||||
parentTeamType={TeamType.Organization}
|
||||
onCancel={mockCancel}
|
||||
onSave={mockSave}
|
||||
/>
|
||||
);
|
||||
|
||||
// input name
|
||||
const nameInput = getByTestId('name');
|
||||
await act(async () => {
|
||||
fireEvent.change(nameInput, { target: { value: 'test' } });
|
||||
});
|
||||
|
||||
// input displayName
|
||||
const displayNameInput = getByTestId('display-name');
|
||||
await act(async () => {
|
||||
fireEvent.change(displayNameInput, { target: { value: 'Test Team' } });
|
||||
});
|
||||
|
||||
// save form
|
||||
const saveButton = getByText('label.save');
|
||||
|
||||
await act(async () => {
|
||||
fireEvent.click(saveButton);
|
||||
});
|
||||
|
||||
expect(mockSave).toHaveBeenCalledWith({
|
||||
name: 'test',
|
||||
displayName: 'Test Team',
|
||||
email: undefined,
|
||||
description: '',
|
||||
isJoinable: false,
|
||||
teamType: 'Group',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -21,7 +21,13 @@ import { EditorContentRef } from '../../components/common/RichTextEditor/RichTex
|
||||
import { VALIDATION_MESSAGES } from '../../constants/constants';
|
||||
import { ENTITY_NAME_REGEX } from '../../constants/regex.constants';
|
||||
import { Team, TeamType } from '../../generated/entity/teams/team';
|
||||
import {
|
||||
FieldProp,
|
||||
FieldTypes,
|
||||
FormItemLayout,
|
||||
} from '../../interface/FormUtils.interface';
|
||||
import { getTeams } from '../../rest/teamsAPI';
|
||||
import { getField } from '../../utils/formUtils';
|
||||
import { getTeamOptionsFromType } from '../../utils/TeamUtils';
|
||||
import { showErrorToast } from '../../utils/ToastUtils';
|
||||
import { AddTeamFormType } from './AddTeamForm.interface';
|
||||
@ -65,6 +71,19 @@ const AddTeamForm: React.FC<AddTeamFormType> = ({
|
||||
}
|
||||
};
|
||||
|
||||
const isJoinableField: FieldProp = {
|
||||
name: 'isJoinable',
|
||||
label: t('label.public-team'),
|
||||
type: FieldTypes.SWITCH,
|
||||
required: false,
|
||||
props: {
|
||||
'data-testid': 'isJoinable-switch-button',
|
||||
},
|
||||
id: 'isJoinable-switch-button',
|
||||
formItemLayout: FormItemLayout.HORIZONTAL,
|
||||
helperText: t('message.access-to-collaborate'),
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (visible) {
|
||||
fetchAllTeams();
|
||||
@ -82,6 +101,7 @@ const AddTeamForm: React.FC<AddTeamFormType> = ({
|
||||
type: 'primary',
|
||||
htmlType: 'submit',
|
||||
}}
|
||||
okText={t('label.save')}
|
||||
open={visible}
|
||||
title={t('label.add-entity', { entity: t('label.team') })}
|
||||
width={750}
|
||||
@ -90,6 +110,7 @@ const AddTeamForm: React.FC<AddTeamFormType> = ({
|
||||
id="add-team-form"
|
||||
initialValues={{
|
||||
teamType: TeamType.Group,
|
||||
isJoinable: false,
|
||||
}}
|
||||
layout="vertical"
|
||||
name="add-team-nest-messages"
|
||||
@ -166,6 +187,7 @@ const AddTeamForm: React.FC<AddTeamFormType> = ({
|
||||
placeholder={t('message.select-team')}
|
||||
/>
|
||||
</Form.Item>
|
||||
{getField(isJoinableField)}
|
||||
<Form.Item
|
||||
label={t('label.description')}
|
||||
name="description"
|
||||
|
||||
@ -268,6 +268,7 @@ const TeamsPage = () => {
|
||||
teamType: data.teamType as TeamType,
|
||||
parents: fqn ? [selectedTeam.id] : undefined,
|
||||
email: data.email || undefined,
|
||||
isJoinable: data.isJoinable,
|
||||
};
|
||||
const res = await createTeam(teamData);
|
||||
if (res) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user