mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-10-25 15:55:15 +00:00
test(ui): e2e tests for recently viewed (#12506)
This commit is contained in:
parent
0c6435ae9b
commit
2260b8da32
@ -1207,7 +1207,7 @@ export const followAndOwnTheEntity = (termObj) => {
|
||||
|
||||
// Check followed entity on mydata page
|
||||
cy.get('[data-testid="following-data-container"]')
|
||||
.find(`[data-testid="Following data-${termObj.displayName}"]`)
|
||||
.find(`[data-testid="following-${termObj.displayName}"]`)
|
||||
.should('be.visible');
|
||||
|
||||
// Check owned entity
|
||||
|
||||
@ -132,6 +132,7 @@ export const SEARCH_ENTITY_MLMODEL = {
|
||||
term: 'eta_predictions',
|
||||
entity: MYDATA_SUMMARY_OPTIONS.mlmodels,
|
||||
serviceName: 'mlflow_svc',
|
||||
displayName: 'ETA Predictions',
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright 2023 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 {
|
||||
interceptURL,
|
||||
verifyResponseStatusCode,
|
||||
visitEntityDetailsPage,
|
||||
} from '../../common/common';
|
||||
import {
|
||||
SEARCH_ENTITY_DASHBOARD,
|
||||
SEARCH_ENTITY_MLMODEL,
|
||||
SEARCH_ENTITY_PIPELINE,
|
||||
SEARCH_ENTITY_TABLE,
|
||||
SEARCH_ENTITY_TOPIC,
|
||||
} from '../../constants/constants';
|
||||
|
||||
// eslint-disable-next-line spaced-comment
|
||||
/// <reference types="cypress" />
|
||||
|
||||
// Update list if we support this for other entities too
|
||||
const FOLLOWING_ENTITIES = [
|
||||
SEARCH_ENTITY_TABLE.table_2,
|
||||
SEARCH_ENTITY_DASHBOARD.dashboard_1,
|
||||
SEARCH_ENTITY_TOPIC.topic_1,
|
||||
SEARCH_ENTITY_PIPELINE.pipeline_1,
|
||||
SEARCH_ENTITY_MLMODEL.mlmodel_2,
|
||||
];
|
||||
|
||||
const followEntity = ({ term, serviceName, entity }, isUnfollow) => {
|
||||
visitEntityDetailsPage(term, serviceName, entity);
|
||||
|
||||
interceptURL(
|
||||
isUnfollow ? 'DELETE' : 'PUT',
|
||||
isUnfollow ? '/api/v1/*/*/followers/*' : '/api/v1/*/*/followers',
|
||||
'waitAfterFollow'
|
||||
);
|
||||
cy.get('[data-testid="entity-follow-button"]')
|
||||
.scrollIntoView()
|
||||
.should('be.visible')
|
||||
.click();
|
||||
|
||||
verifyResponseStatusCode('@waitAfterFollow', 200);
|
||||
};
|
||||
|
||||
describe('Following data assets', () => {
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
});
|
||||
|
||||
it('following section should be present', () => {
|
||||
cy.get('[data-testid="following-data-container"]')
|
||||
.scrollIntoView()
|
||||
.should('be.visible');
|
||||
|
||||
cy.get('[data-testid="following-data-container"]').contains(
|
||||
'You have not followed anything yet.'
|
||||
);
|
||||
cy.get(
|
||||
`[data-testid="following-data-container"] .right-panel-list-item`
|
||||
).should('have.length', 0);
|
||||
});
|
||||
|
||||
// Follow entity
|
||||
FOLLOWING_ENTITIES.map((entity, index) => {
|
||||
it(`following section should have ${entity.term} followed`, () => {
|
||||
followEntity(entity);
|
||||
|
||||
interceptURL(
|
||||
'GET',
|
||||
'/api/v1/feed?type=Announcement&activeAnnouncement=true',
|
||||
'getAnnoucemenets'
|
||||
);
|
||||
|
||||
cy.clickOnLogo();
|
||||
verifyResponseStatusCode('@getAnnoucemenets', 200);
|
||||
|
||||
cy.get(`[data-testid="following-${entity.displayName}"]`).should(
|
||||
'be.visible'
|
||||
);
|
||||
|
||||
// Checking count of following
|
||||
cy.get(`[data-testid="following-data"]`).should('contain', index + 1);
|
||||
});
|
||||
});
|
||||
|
||||
// UnFollow entity
|
||||
FOLLOWING_ENTITIES.map((entity, index) => {
|
||||
it(`unfollowing entity ${entity.term} should removed from following section`, () => {
|
||||
followEntity(entity, true);
|
||||
|
||||
interceptURL(
|
||||
'GET',
|
||||
'/api/v1/feed?type=Announcement&activeAnnouncement=true',
|
||||
'getAnnoucemenets'
|
||||
);
|
||||
|
||||
cy.clickOnLogo();
|
||||
verifyResponseStatusCode('@getAnnoucemenets', 200);
|
||||
|
||||
cy.get(`[data-testid="following-${entity.displayName}"]`).should(
|
||||
'not.exist'
|
||||
);
|
||||
|
||||
if (index === FOLLOWING_ENTITIES.length - 1) {
|
||||
// Checking count of following
|
||||
cy.get(`[data-testid="following-data"]`).should('not.exist');
|
||||
} else {
|
||||
// Checking count of following
|
||||
cy.get(`[data-testid="following-data"]`).should(
|
||||
'contain',
|
||||
FOLLOWING_ENTITIES.length - (index + 1)
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 2023 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 {
|
||||
interceptURL,
|
||||
verifyResponseStatusCode,
|
||||
visitEntityDetailsPage,
|
||||
} from '../../common/common';
|
||||
import {
|
||||
SEARCH_ENTITY_DASHBOARD,
|
||||
SEARCH_ENTITY_MLMODEL,
|
||||
SEARCH_ENTITY_PIPELINE,
|
||||
SEARCH_ENTITY_TABLE,
|
||||
SEARCH_ENTITY_TOPIC,
|
||||
} from '../../constants/constants';
|
||||
|
||||
// eslint-disable-next-line spaced-comment
|
||||
/// <reference types="cypress" />
|
||||
|
||||
// Update list if we support this for other entities too
|
||||
const RECENTLY_VIEW_ENTITIES = [
|
||||
SEARCH_ENTITY_TABLE.table_2,
|
||||
SEARCH_ENTITY_DASHBOARD.dashboard_1,
|
||||
SEARCH_ENTITY_TOPIC.topic_1,
|
||||
SEARCH_ENTITY_PIPELINE.pipeline_1,
|
||||
SEARCH_ENTITY_MLMODEL.mlmodel_2,
|
||||
];
|
||||
|
||||
describe('Recently viwed data assets', () => {
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
});
|
||||
|
||||
it('recently view section should be present', () => {
|
||||
cy.get('[data-testid="recently-viewed-container"]')
|
||||
.scrollIntoView()
|
||||
.should('be.visible');
|
||||
|
||||
cy.get(
|
||||
`[data-testid="recently-viewed-container"] .right-panel-list-item`
|
||||
).should('have.length', 0);
|
||||
});
|
||||
|
||||
it(`recently view section should have at max list of 5 entity`, () => {
|
||||
RECENTLY_VIEW_ENTITIES.map((entity, index) => {
|
||||
visitEntityDetailsPage(entity.term, entity.serviceName, entity.entity);
|
||||
|
||||
interceptURL(
|
||||
'GET',
|
||||
'/api/v1/feed?type=Announcement&activeAnnouncement=true',
|
||||
'getAnnoucemenets'
|
||||
);
|
||||
|
||||
cy.clickOnLogo();
|
||||
verifyResponseStatusCode('@getAnnoucemenets', 200);
|
||||
|
||||
cy.get(
|
||||
`[data-testid="recently-viewed-container"] [title="${entity.displayName}"]`
|
||||
).should('be.visible');
|
||||
|
||||
// Checking count since we will only show max 5 not more than that
|
||||
cy.get(
|
||||
`[data-testid="recently-viewed-container"] .right-panel-list-item`
|
||||
).should('have.length', index > 4 ? 5 : index + 1);
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -125,7 +125,7 @@ const RightSidebar = ({
|
||||
headerTextLabel={t('label.following')}
|
||||
loading={isLoadingOwnedData}
|
||||
noDataPlaceholder={t('message.not-followed-anything')}
|
||||
testIDText="Following data"
|
||||
testIDText="following"
|
||||
/>
|
||||
</div>
|
||||
<div className="p-md" data-testid="recently-viewed-container">
|
||||
|
||||
@ -77,7 +77,6 @@ import { ResourceEntity } from '../PermissionProvider/PermissionProvider.interfa
|
||||
import { PipeLineDetailsProp } from './PipelineDetails.interface';
|
||||
|
||||
const PipelineDetails = ({
|
||||
followers,
|
||||
pipelineDetails,
|
||||
fetchPipeline,
|
||||
descriptionUpdateHandler,
|
||||
@ -93,6 +92,7 @@ const PipelineDetails = ({
|
||||
const { tab } = useParams<{ tab: EntityTabs }>();
|
||||
const { t } = useTranslation();
|
||||
const { postFeed, deleteFeed, updateFeed } = useActivityFeedProvider();
|
||||
const userID = getCurrentUserId();
|
||||
const {
|
||||
deleted,
|
||||
owner,
|
||||
@ -102,6 +102,7 @@ const PipelineDetails = ({
|
||||
tier,
|
||||
tags,
|
||||
entityFqn,
|
||||
followers,
|
||||
} = useMemo(() => {
|
||||
return {
|
||||
deleted: pipelineDetails.deleted,
|
||||
@ -114,6 +115,7 @@ const PipelineDetails = ({
|
||||
tags: getTagsWithoutTier(pipelineDetails.tags ?? []),
|
||||
entityName: getEntityName(pipelineDetails),
|
||||
entityFqn: pipelineDetails.fullyQualifiedName ?? '',
|
||||
followers: pipelineDetails.followers ?? [],
|
||||
};
|
||||
}, [pipelineDetails]);
|
||||
|
||||
@ -193,8 +195,8 @@ const PipelineDetails = ({
|
||||
}, [pipelineDetails.id]);
|
||||
|
||||
const isFollowing = useMemo(
|
||||
() => followers.some(({ id }: { id: string }) => id === getCurrentUserId()),
|
||||
[followers]
|
||||
() => followers.some(({ id }: { id: string }) => id === userID),
|
||||
[followers, userID]
|
||||
);
|
||||
|
||||
const onTaskUpdate = async (taskDescription: string) => {
|
||||
@ -297,13 +299,13 @@ const PipelineDetails = ({
|
||||
}
|
||||
};
|
||||
|
||||
const followPipeline = async () => {
|
||||
const followPipeline = useCallback(async () => {
|
||||
if (isFollowing) {
|
||||
await unFollowPipelineHandler(getEntityFeedCount);
|
||||
} else {
|
||||
await followPipelineHandler(getEntityFeedCount);
|
||||
}
|
||||
};
|
||||
}, [isFollowing, followPipelineHandler, unFollowPipelineHandler]);
|
||||
|
||||
const onThreadLinkSelect = (link: string, threadType?: ThreadType) => {
|
||||
setThreadLink(link);
|
||||
|
||||
@ -13,13 +13,11 @@
|
||||
|
||||
import { Operation } from 'fast-json-patch';
|
||||
import { Pipeline } from '../../generated/entity/data/pipeline';
|
||||
import { EntityReference } from '../../generated/type/entityReference';
|
||||
import { Paging } from '../../generated/type/paging';
|
||||
|
||||
export interface PipeLineDetailsProp {
|
||||
pipelineFQN: string;
|
||||
pipelineDetails: Pipeline;
|
||||
followers: Array<EntityReference>;
|
||||
paging: Paging;
|
||||
fetchPipeline: () => void;
|
||||
followPipelineHandler: (fetchCount: () => void) => Promise<void>;
|
||||
|
||||
@ -33,7 +33,6 @@ import {
|
||||
import { getVersionPath } from '../../constants/constants';
|
||||
import { EntityType } from '../../enums/entity.enum';
|
||||
import { Pipeline } from '../../generated/entity/data/pipeline';
|
||||
import { EntityReference } from '../../generated/type/entityReference';
|
||||
import { Paging } from '../../generated/type/paging';
|
||||
import {
|
||||
addToRecentViewed,
|
||||
@ -59,7 +58,6 @@ const PipelineDetailsPage = () => {
|
||||
);
|
||||
|
||||
const [isLoading, setLoading] = useState<boolean>(true);
|
||||
const [followers, setFollowers] = useState<Array<EntityReference>>([]);
|
||||
|
||||
const [isError, setIsError] = useState(false);
|
||||
|
||||
@ -71,6 +69,8 @@ const PipelineDetailsPage = () => {
|
||||
|
||||
const { getEntityPermissionByFqn } = usePermissionProvider();
|
||||
|
||||
const { followers = [] } = pipelineDetails;
|
||||
|
||||
const fetchResourcePermission = async (entityFqn: string) => {
|
||||
setLoading(true);
|
||||
try {
|
||||
@ -143,39 +143,53 @@ const PipelineDetailsPage = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const followPipeline = async (fetchCount: () => void) => {
|
||||
try {
|
||||
const res = await addFollower(pipelineId, USERId);
|
||||
const { newValue } = res.changeDescription.fieldsAdded[0];
|
||||
setFollowers([...followers, ...newValue]);
|
||||
fetchCount();
|
||||
} catch (error) {
|
||||
showErrorToast(
|
||||
error as AxiosError,
|
||||
t('server.entity-follow-error', {
|
||||
entity: getEntityName(pipelineDetails),
|
||||
})
|
||||
);
|
||||
}
|
||||
};
|
||||
const followPipeline = useCallback(
|
||||
async (fetchCount: () => void) => {
|
||||
try {
|
||||
const res = await addFollower(pipelineId, USERId);
|
||||
const { newValue } = res.changeDescription.fieldsAdded[0];
|
||||
const newFollowers = [...(followers ?? []), ...newValue];
|
||||
setPipelineDetails((prev) => {
|
||||
return { ...prev, followers: newFollowers };
|
||||
});
|
||||
|
||||
const unFollowPipeline = async (fetchCount: () => void) => {
|
||||
try {
|
||||
const res = await removeFollower(pipelineId, USERId);
|
||||
const { oldValue } = res.changeDescription.fieldsDeleted[0];
|
||||
setFollowers(
|
||||
followers.filter((follower) => follower.id !== oldValue[0].id)
|
||||
);
|
||||
fetchCount();
|
||||
} catch (error) {
|
||||
showErrorToast(
|
||||
error as AxiosError,
|
||||
t('server.entity-unfollow-error', {
|
||||
entity: getEntityName(pipelineDetails),
|
||||
})
|
||||
);
|
||||
}
|
||||
};
|
||||
fetchCount();
|
||||
} catch (error) {
|
||||
showErrorToast(
|
||||
error as AxiosError,
|
||||
t('server.entity-follow-error', {
|
||||
entity: getEntityName(pipelineDetails),
|
||||
})
|
||||
);
|
||||
}
|
||||
},
|
||||
[followers, USERId]
|
||||
);
|
||||
|
||||
const unFollowPipeline = useCallback(
|
||||
async (fetchCount: () => void) => {
|
||||
try {
|
||||
const res = await removeFollower(pipelineId, USERId);
|
||||
const { oldValue } = res.changeDescription.fieldsDeleted[0];
|
||||
setPipelineDetails((prev) => ({
|
||||
...prev,
|
||||
followers: followers.filter(
|
||||
(follower) => follower.id !== oldValue[0].id
|
||||
),
|
||||
}));
|
||||
|
||||
fetchCount();
|
||||
} catch (error) {
|
||||
showErrorToast(
|
||||
error as AxiosError,
|
||||
t('server.entity-unfollow-error', {
|
||||
entity: getEntityName(pipelineDetails),
|
||||
})
|
||||
);
|
||||
}
|
||||
},
|
||||
[followers, USERId]
|
||||
);
|
||||
|
||||
const descriptionUpdateHandler = async (updatedPipeline: Pipeline) => {
|
||||
try {
|
||||
@ -261,7 +275,6 @@ const PipelineDetailsPage = () => {
|
||||
descriptionUpdateHandler={descriptionUpdateHandler}
|
||||
fetchPipeline={() => fetchPipelineDetail(pipelineFQN)}
|
||||
followPipelineHandler={followPipeline}
|
||||
followers={followers}
|
||||
paging={paging}
|
||||
pipelineDetails={pipelineDetails}
|
||||
pipelineFQN={pipelineFQN}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user