Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 61 additions & 64 deletions src/course-unit/CourseUnit.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -305,38 +305,36 @@ describe('<CourseUnit />', () => {
const user = userEvent.setup();
render(<RootWrapper />);

await waitFor(async () => {
const iframe = screen.getByTitle(xblockContainerIframeMessages.xblockIframeTitle.defaultMessage);
expect(iframe).toHaveAttribute(
'aria-label',
xblockContainerIframeMessages.xblockIframeLabel.defaultMessage
.replace('{xblockCount}', courseVerticalChildrenMock.children.length),
);

simulatePostMessageEvent(messageTypes.deleteXBlock, {
usageId: courseVerticalChildrenMock.children[0].block_id,
});
const iframe = await screen.findByTitle(xblockContainerIframeMessages.xblockIframeTitle.defaultMessage);
expect(iframe).toHaveAttribute(
'aria-label',
xblockContainerIframeMessages.xblockIframeLabel.defaultMessage
.replace('{xblockCount}', courseVerticalChildrenMock.children.length),
);

expect(screen.getByText(/Delete this component?/i)).toBeInTheDocument();
expect(screen.getByText(/Deleting this component is permanent and cannot be undone./i)).toBeInTheDocument();
simulatePostMessageEvent(messageTypes.deleteXBlock, {
usageId: courseVerticalChildrenMock.children[0].block_id,
});

const dialog = screen.getByRole('dialog');
expect(dialog).toBeInTheDocument();
expect(await screen.findByText(/Delete this component?/i)).toBeInTheDocument();
expect(await screen.findByText(/Deleting this component is permanent and cannot be undone./i)).toBeInTheDocument();

// Find the Cancel and Delete buttons within the iframe by their specific classes
const cancelButton = await within(dialog).findByRole('button', { name: /Cancel/i });
const deleteButton = await within(dialog).findByRole('button', { name: /Delete/i });
const dialog = await screen.findByRole('dialog');
expect(dialog).toBeInTheDocument();

expect(cancelButton).toBeInTheDocument();
// Find the Cancel and Delete buttons within the iframe by their specific classes
const cancelButton = await within(dialog).findByRole('button', { name: /Cancel/i });
const deleteButton = await within(dialog).findByRole('button', { name: /Delete/i });

simulatePostMessageEvent(messageTypes.deleteXBlock, {
usageId: courseVerticalChildrenMock.children[0].block_id,
});
expect(cancelButton).toBeInTheDocument();

expect(screen.getByRole('dialog')).toBeInTheDocument();
await user.click(deleteButton);
simulatePostMessageEvent(messageTypes.deleteXBlock, {
usageId: courseVerticalChildrenMock.children[0].block_id,
});

expect(await screen.findByRole('dialog')).toBeInTheDocument();
await user.click(deleteButton);

axiosMock
.onPost(getXBlockBaseApiUrl(blockId), {
publish: PUBLISH_TYPES.makePublic,
Expand All @@ -355,17 +353,17 @@ describe('<CourseUnit />', () => {
});
await executeThunk(editCourseUnitVisibilityAndData(blockId, PUBLISH_TYPES.makePublic, true), store.dispatch);

await waitFor(() => {
// check if the sidebar status is Published and Live
expect(screen.getByText(legacySidebarMessages.sidebarTitlePublishedAndLive.defaultMessage)).toBeInTheDocument();
expect(screen.getByText(
unitInfoMessages.publishLastPublished.defaultMessage
.replace('{publishedOn}', courseSectionVerticalMock.xblock_info.published_on)
.replace('{publishedBy}', userName),
)).toBeInTheDocument();
expect(screen.queryByRole('button', { name: legacySidebarMessages.actionButtonPublishTitle.defaultMessage })).not.toBeInTheDocument();
expect(screen.getByText(unitDisplayName)).toBeInTheDocument();
});
// check if the sidebar status is Published and Live
expect(await screen.findByText(
legacySidebarMessages.sidebarTitlePublishedAndLive.defaultMessage,
)).toBeInTheDocument();
expect(await screen.findByText(
unitInfoMessages.publishLastPublished.defaultMessage
.replace('{publishedOn}', courseSectionVerticalMock.xblock_info.published_on)
.replace('{publishedBy}', userName),
)).toBeInTheDocument();
expect(screen.queryByRole('button', { name: legacySidebarMessages.actionButtonPublishTitle.defaultMessage })).not.toBeInTheDocument();
expect(await screen.findByText(unitDisplayName)).toBeInTheDocument();

axiosMock
.onDelete(getXBlockBaseApiUrl(courseVerticalChildrenMock.children[0].block_id))
Expand Down Expand Up @@ -397,35 +395,34 @@ describe('<CourseUnit />', () => {
.reply(200, courseSectionVerticalMock);
await executeThunk(editCourseUnitVisibilityAndData(blockId, PUBLISH_TYPES.makePublic, true), store.dispatch);

await waitFor(() => {
const iframe = screen.getByTitle(xblockContainerIframeMessages.xblockIframeTitle.defaultMessage);
expect(iframe).toHaveAttribute(
'aria-label',
xblockContainerIframeMessages.xblockIframeLabel.defaultMessage
.replace('{xblockCount}', updatedCourseVerticalChildren.length),
);
// after removing the xblock, the sidebar status changes to Draft (unpublished changes)
expect(screen.getByText(
legacySidebarMessages.sidebarTitleDraftUnpublishedChanges.defaultMessage,
)).toBeInTheDocument();
expect(screen.getByText(legacySidebarMessages.releaseStatusTitle.defaultMessage)).toBeInTheDocument();
expect(screen.getByText(unitInfoMessages.visibilityVisibleToTitle.defaultMessage)).toBeInTheDocument();
expect(screen.getByText(unitInfoMessages.visibilityCheckboxTitle.defaultMessage)).toBeInTheDocument();
expect(screen.getByText(legacySidebarMessages.actionButtonPublishTitle.defaultMessage)).toBeInTheDocument();
expect(screen.getByText(
legacySidebarMessages.actionButtonDiscardChangesTitle.defaultMessage,
)).toBeInTheDocument();
expect(screen.getByText(courseSectionVerticalMock.xblock_info.release_date)).toBeInTheDocument();
expect(screen.getByText(
unitInfoMessages.publishInfoDraftSaved.defaultMessage
.replace('{editedOn}', courseSectionVerticalMock.xblock_info.edited_on)
.replace('{editedBy}', courseSectionVerticalMock.xblock_info.edited_by),
)).toBeInTheDocument();
expect(screen.getByText(
legacySidebarMessages.releaseInfoWithSection.defaultMessage
.replace('{sectionName}', courseSectionVerticalMock.xblock_info.release_date_from),
)).toBeInTheDocument();
});
expect(await screen.findByTitle(
xblockContainerIframeMessages.xblockIframeTitle.defaultMessage,
)).toHaveAttribute(
'aria-label',
xblockContainerIframeMessages.xblockIframeLabel.defaultMessage
.replace('{xblockCount}', updatedCourseVerticalChildren.length),
);
// after removing the xblock, the sidebar status changes to Draft (unpublished changes)
expect(await screen.findByText(
legacySidebarMessages.sidebarTitleDraftUnpublishedChanges.defaultMessage,
)).toBeInTheDocument();
expect(await screen.findByText(legacySidebarMessages.releaseStatusTitle.defaultMessage)).toBeInTheDocument();
expect(await screen.findByText(unitInfoMessages.visibilityVisibleToTitle.defaultMessage)).toBeInTheDocument();
expect(await screen.findByText(unitInfoMessages.visibilityCheckboxTitle.defaultMessage)).toBeInTheDocument();
expect(await screen.findByText(legacySidebarMessages.actionButtonPublishTitle.defaultMessage)).toBeInTheDocument();
expect(await screen.findByText(
legacySidebarMessages.actionButtonDiscardChangesTitle.defaultMessage,
)).toBeInTheDocument();
expect(await screen.findByText(courseSectionVerticalMock.xblock_info.release_date)).toBeInTheDocument();
expect(await screen.findByText(
unitInfoMessages.publishInfoDraftSaved.defaultMessage
.replace('{editedOn}', courseSectionVerticalMock.xblock_info.edited_on)
.replace('{editedBy}', courseSectionVerticalMock.xblock_info.edited_by),
)).toBeInTheDocument();
expect(await screen.findByText(
legacySidebarMessages.releaseInfoWithSection.defaultMessage
.replace('{sectionName}', courseSectionVerticalMock.xblock_info.release_date_from),
)).toBeInTheDocument();
});

it('checks if the xblock unlink is called when the corresponding unlink button is clicked', async () => {
Expand Down
6 changes: 6 additions & 0 deletions src/generic/upstream-info-icon/UpstreamInfoIcon.scss
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,9 @@
height: 18px;
}
}

.upstream-info-tooltip {
.tooltip-inner {
background-color: var(--pgn-color-primary-700);
}
}
22 changes: 11 additions & 11 deletions src/generic/upstream-info-icon/UpstreamInfoIcon.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ describe('<UpstreamInfoIcon>', () => {
downstreamCustomized: [],
upstreamName: 'Upstream',
});
expect(screen.getByTitle('This item is linked to a library item.')).toBeInTheDocument();
expect(screen.queryByTitle('The linked library object has updates available.')).not.toBeInTheDocument();
expect(screen.getByTitle('This item is linked to a library item')).toBeInTheDocument();
expect(screen.queryByTitle('The linked library object has updates available')).not.toBeInTheDocument();
});

it('should render with broken link', () => {
Expand All @@ -37,8 +37,8 @@ describe('<UpstreamInfoIcon>', () => {
downstreamCustomized: [],
upstreamName: 'Upstream',
});
expect(screen.getByTitle('This item is linked to a library item.')).toBeInTheDocument();
expect(screen.getByTitle('The referenced library or library object is not available.')).toBeInTheDocument();
expect(screen.getByTitle('This item is linked to a library item')).toBeInTheDocument();
expect(screen.getByTitle('The referenced library or library object is not available')).toBeInTheDocument();
});

it('should render with ready to sync link and opens the sync modal', async () => {
Expand All @@ -50,9 +50,9 @@ describe('<UpstreamInfoIcon>', () => {
upstreamName: 'Upstream',
});

const icon = screen.getByTitle('This item is linked to a library item.');
const icon = screen.getByTitle('This item is linked to a library item');
expect(icon).toBeInTheDocument();
expect(screen.getByTitle('The linked library object has updates available.')).toBeInTheDocument();
expect(screen.getByTitle('The linked library object has updates available')).toBeInTheDocument();

fireEvent.click(icon);
await waitFor(() => expect(mockOpenSyncModal).toHaveBeenCalled());
Expand All @@ -67,8 +67,8 @@ describe('<UpstreamInfoIcon>', () => {
upstreamName: 'Upstream',
});

expect(screen.getByTitle('This item is linked to a library item.')).toBeInTheDocument();
expect(screen.getByTitle('This library reference has course overrides applied.')).toBeInTheDocument();
expect(screen.getByTitle('This item is linked to a library item')).toBeInTheDocument();
expect(screen.getByTitle('This library reference has course overrides applied')).toBeInTheDocument();
});

it('should render with ready to sync and course overrides', () => {
Expand All @@ -80,9 +80,9 @@ describe('<UpstreamInfoIcon>', () => {
upstreamName: 'Upstream',
});

expect(screen.getByTitle('This item is linked to a library item.')).toBeInTheDocument();
expect(screen.queryByTitle('This library reference has course overrides applied.')).not.toBeInTheDocument();
expect(screen.getByTitle('The linked library object has updates available.')).toBeInTheDocument();
expect(screen.getByTitle('This item is linked to a library item')).toBeInTheDocument();
expect(screen.queryByTitle('This library reference has course overrides applied')).not.toBeInTheDocument();
expect(screen.getByTitle('The linked library object has updates available')).toBeInTheDocument();
});

it('should render null without upstream', () => {
Expand Down
2 changes: 1 addition & 1 deletion src/generic/upstream-info-icon/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ const UpstreamInfoIconContent = ({
key={`upstream-icon-${upstreamInfo.upstreamRef}`}
placement="top"
overlay={(
<Tooltip id={`upstream-icon-tooltip-${upstreamInfo.upstreamRef}`}>
<Tooltip className="upstream-info-tooltip" id={`upstream-icon-tooltip-${upstreamInfo.upstreamRef}`}>
{tooltipMessage}
</Tooltip>
)}
Expand Down
10 changes: 5 additions & 5 deletions src/generic/upstream-info-icon/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,27 @@ import { defineMessages } from '@edx/frontend-platform/i18n';

const messages = defineMessages({
upstreamLinkOk: {
defaultMessage: 'This item is linked to a library item.',
defaultMessage: 'This item is linked to a library item',
id: 'upstream-icon.ok',
description: 'Hint and aria-label for the upstream icon when the link is valid.',
},
upstreamLinkError: {
defaultMessage: 'The referenced library or library object is not available.',
defaultMessage: 'The referenced library or library object is not available',
id: 'upstream-icon.error',
description: 'Hint and aria-label for the upstream icon when the link is broken.',
},
upstreamLinkReadyToSyncAriaLabel: {
defaultMessage: 'The linked library object has updates available.',
defaultMessage: 'The linked library object has updates available',
id: 'upstream-icon.ready-to-sync.aria-label',
description: 'Hint and aria-label for the upstream icon when the link is ready to sync.',
},
upstreamLinkReadyToSyncTooltip: {
defaultMessage: 'The linked <b>{upstreamName}</b> has updates available.',
defaultMessage: 'The linked <b>{upstreamName}</b> has updates available',
id: 'upstream-icon.ready-to-sync.tooltip',
description: 'Tooltip text for the upstream icon when the link is ready to sync.',
},
upstreamLinkOverridesAriaLabel: {
defaultMessage: 'This library reference has course overrides applied.',
defaultMessage: 'This library reference has course overrides applied',
id: 'upstream-icon.course-overrides.aria-label',
description: 'Hint and aria-label for the upstream icon when the link has course overrides.',
},
Expand Down