diff --git a/src/course-unit/CourseUnit.test.jsx b/src/course-unit/CourseUnit.test.jsx
index 8dd56ea40..ca28391ef 100644
--- a/src/course-unit/CourseUnit.test.jsx
+++ b/src/course-unit/CourseUnit.test.jsx
@@ -305,38 +305,36 @@ describe('', () => {
const user = userEvent.setup();
render();
- await waitFor(async () => {
- const iframe = screen.getByTitle(xblockContainerIframeMessages.xblockIframeTitle.defaultMessage);
- expect(iframe).toHaveAttribute(
- 'aria-label',
- xblockContainerIframeMessages.xblockIframeLabel.defaultMessage
- .replace('{xblockCount}', courseVerticalChildrenMock.children.length),
- );
+ const iframe = await screen.findByTitle(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,
- });
-
- expect(screen.getByText(/Delete this component?/i)).toBeInTheDocument();
- expect(screen.getByText(/Deleting this component is permanent and cannot be undone./i)).toBeInTheDocument();
-
- const dialog = screen.getByRole('dialog');
- expect(dialog).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 });
-
- expect(cancelButton).toBeInTheDocument();
-
- simulatePostMessageEvent(messageTypes.deleteXBlock, {
- usageId: courseVerticalChildrenMock.children[0].block_id,
- });
-
- expect(screen.getByRole('dialog')).toBeInTheDocument();
- await user.click(deleteButton);
+ simulatePostMessageEvent(messageTypes.deleteXBlock, {
+ usageId: courseVerticalChildrenMock.children[0].block_id,
});
+ expect(await screen.findByText(/Delete this component?/i)).toBeInTheDocument();
+ expect(await screen.findByText(/Deleting this component is permanent and cannot be undone./i)).toBeInTheDocument();
+
+ const dialog = await screen.findByRole('dialog');
+ expect(dialog).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 });
+
+ expect(cancelButton).toBeInTheDocument();
+
+ 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,
@@ -355,17 +353,17 @@ describe('', () => {
});
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))
@@ -397,35 +395,34 @@ describe('', () => {
.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 () => {
diff --git a/src/generic/upstream-info-icon/UpstreamInfoIcon.scss b/src/generic/upstream-info-icon/UpstreamInfoIcon.scss
index f15194984..0f498fc77 100644
--- a/src/generic/upstream-info-icon/UpstreamInfoIcon.scss
+++ b/src/generic/upstream-info-icon/UpstreamInfoIcon.scss
@@ -45,3 +45,9 @@
height: 18px;
}
}
+
+.upstream-info-tooltip {
+ .tooltip-inner {
+ background-color: var(--pgn-color-primary-700);
+ }
+}
diff --git a/src/generic/upstream-info-icon/UpstreamInfoIcon.test.tsx b/src/generic/upstream-info-icon/UpstreamInfoIcon.test.tsx
index ba5efad0a..06b4fa61d 100644
--- a/src/generic/upstream-info-icon/UpstreamInfoIcon.test.tsx
+++ b/src/generic/upstream-info-icon/UpstreamInfoIcon.test.tsx
@@ -25,8 +25,8 @@ describe('', () => {
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', () => {
@@ -37,8 +37,8 @@ describe('', () => {
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 () => {
@@ -50,9 +50,9 @@ describe('', () => {
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());
@@ -67,8 +67,8 @@ describe('', () => {
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', () => {
@@ -80,9 +80,9 @@ describe('', () => {
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', () => {
diff --git a/src/generic/upstream-info-icon/index.tsx b/src/generic/upstream-info-icon/index.tsx
index ec93a5bd6..80173e5bd 100644
--- a/src/generic/upstream-info-icon/index.tsx
+++ b/src/generic/upstream-info-icon/index.tsx
@@ -84,7 +84,7 @@ const UpstreamInfoIconContent = ({
key={`upstream-icon-${upstreamInfo.upstreamRef}`}
placement="top"
overlay={(
-
+
{tooltipMessage}
)}
diff --git a/src/generic/upstream-info-icon/messages.ts b/src/generic/upstream-info-icon/messages.ts
index ac844a64e..63710e4b7 100644
--- a/src/generic/upstream-info-icon/messages.ts
+++ b/src/generic/upstream-info-icon/messages.ts
@@ -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 {upstreamName} has updates available.',
+ defaultMessage: 'The linked {upstreamName} 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.',
},