@testing-library/react#queryByTestId JavaScript Examples
The following examples show how to use
@testing-library/react#queryByTestId.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: CommentList.test.js From viade_en1b with MIT License | 6 votes |
describe("CommentList component", () => {
let wrapper;
beforeEach(() => {
const comment = <Comment author="alvarogarinf" text="This is a test" date="2020-4-29"></Comment>;
const { container } = render(
<CommentList comments={[comment]}></CommentList>
);
wrapper = container;
});
describe("renders correctly", () => {
test("comments", () => {
waitForElement(() => {
expect(queryByTestId(wrapper, "comments")).not.toBeNull();
});
});
});
});
Example #2
Source File: CourseAuthoringPage.test.jsx From frontend-app-course-authoring with GNU Affero General Public License v3.0 | 6 votes |
describe('DiscussionsSettings', () => {
beforeEach(() => {
initializeMockApp({
authenticatedUser: {
userId: 3,
username: 'abc123',
administrator: true,
roles: [],
},
});
store = initializeStore();
axiosMock = new MockAdapter(getAuthenticatedHttpClient());
});
test('renders permission error in case of 403', async () => {
await mockStore();
renderComponent();
expect(queryByTestId(container, 'permissionDeniedAlert')).toBeInTheDocument();
});
});
Example #3
Source File: UploadButton.test.js From viade_en1b with MIT License | 6 votes |
describe("State is resetet when the prop 'reset' is provided", () => {
test("state resets for single file button", () => {
rerenderFunc(<UploadButton onChange={(e) => e} text="No file selected" reset></UploadButton>);
waitForElement(() => {
expect(queryByTestId(uploadButton, "upload-button-label").textContent).toBe("No file selected");
});
});
test("state resets for multiple file button", () => {
});
});
Example #4
Source File: UploadButton.test.js From viade_en1b with MIT License | 6 votes |
describe("Upload an element to a single file button", () => {
test("label changes accordingly with the name of the file uploaded in single file button", () => {
let filename = "test.png";
let mockFile = new File(["test"], filename, {type: "image/png"});
Object.defineProperty(input, "files", {
value: [mockFile]
});
fireEvent.change(input);
waitForElement(() => {
expect(queryByTestId(uploadButton, "upload-button-label").textContent).toBe(filename);
});
});
test("label changes accordingly with the name of the file uploaded in multiple file button", () => {
let mockFile1 = new File(["test1"], "filename1.png", {type: "image/png"});
let mockFile2 = new File(["test2"], "filename2.png", {type: "image/png"});
let mockFile3 = new File(["test3"], "filename3.png", {type: "image/png"});
let myRef = React.createRef();
rerenderFunc(<UploadButton text="No images" ref={myRef} onChange={(e) => e} multiple></UploadButton>);
waitForElement(() => {
Object.defineProperty(input, "files", {
value: [mockFile1, mockFile2, mockFile3]
});
fireEvent.change(input);
expect(queryByTestId(uploadButton, "upload-button-label").textContent).toBe("3 files selected");
});
});
});
Example #5
Source File: UploadButton.test.js From viade_en1b with MIT License | 6 votes |
describe("Everything is rendered correctly", () => {
test("label is correctly displayed when there are no files selected for a single file button", () => {
waitForElement(() => {
expect(queryByTestId(uploadButton, "upload-button-label").textContent).toBe("No images selected");
});
});
test("label is correctly displayed when there are no files selected for a multple file button", () => {
rerenderFunc(<UploadButton multiple text="No files selected" onChange={(e) => e}></UploadButton>);
waitForElement(() => {
expect(queryByTestId(uploadButton, "upload-button-label").textContent).toBe("No files selected");
});
});
});
Example #6
Source File: Settings.test.js From viade_en1b with MIT License | 6 votes |
describe("Settings Component", () => {
test("Component renders correctly", () => {
expect(queryByTestId(wrapper, "settings-title")).not.toBeNull();
expect(queryByTestId(wrapper, "settings-language")).not.toBeNull();
expect(queryByTestId(wrapper, "settings-language-english")).toBeNull();
expect(queryByTestId(wrapper, "settings-language-spanish")).toBeNull();
expect(queryByTestId(wrapper, "settings-language-dropdown")).not.toBeNull();
});
beforeEach(() => {
let dropdown = queryByTestId(wrapper, "settings-language-dropdown");
fireEvent.click(dropdown);
});
describe("Change theme function", () => {
test("english", () => {
waitForDomChange(() => {
let language = queryByTestId(wrapper, "settings-language-english");
expect(language).not.toBeNull();
fireEvent.click(language);
expect(myMockLanguage).toBeCalled();
});
});
test("spanish", () => {
waitForDomChange(() => {
let language = queryByTestId(wrapper, "settings-language-spanish");
expect(language).not.toBeNull();
fireEvent.click(language);
expect(myMockLanguage).toBeCalled();
});
});
});
});
Example #7
Source File: PageNotFound.test.js From viade_en1b with MIT License | 6 votes |
describe("PageNotFound Component", () => {
describe("Component renders", () => {
let wrapper;
beforeEach(() => {
const { container, rerenders } = render(
<IntlProvider key={"en"} locale={"en"} messages={locales["en"]}>
<PageNotFound />
</IntlProvider>
);
wrapper = container;
});
test("Renders without errors", () => {
expect(queryByTestId(wrapper, "page-not-found-container")).not.toBeNull();
});
});
});
Example #8
Source File: Notifications.test.js From viade_en1b with MIT License | 6 votes |
describe("Notifications component", () => {
let component;
beforeAll(() => {
const {container, rerender} = render(<IntlProvider messages={locales["en"]} locale="en"><Notifications></Notifications></IntlProvider>);
component = container;
});
describe("renders correctly", () => {
test("div", () => {
expect(queryByTestId(component, "notifications-div")).not.toBeNull();
});
test("list", () => {
waitForElement(() => {
expect(queryByTestId(component, "notifications-list")).not.toBeNull();
});
});
});
});
Example #9
Source File: Notification.test.js From viade_en1b with MIT License | 6 votes |
describe("Notification component", () => {
const mockNot = {
text: "Esto es una prueba"
};
let component;
beforeEach(() => {
const {container, rerender} = render(<Notification notification={mockNot}></Notification>);
component = container;
});
describe("renders correctly", () => {
test("card", () => {
expect(component).not.toBe(null);
expect(queryByTestId(component, "notification-card")).not.toBe(null);
});
});
test("content", () => {
waitForElement(() => {
expect(queryByTestId(component, "notification-card-text").innerHTML).toBe(mockNot.text);
});
});
});
Example #10
Source File: Modal.test.js From viade_en1b with MIT License | 6 votes |
describe("Buttons are rendered with different settings", () => {
test("render save button but not cancel button", () => {
rerenderFunc(
<ViadeModal title="Title" onOpen={mock} saveText="Save"></ViadeModal>
);
waitForElement(() => {
fireEvent.click(queryByTestId(modal, "modalButton"));
waitForDomChange(() => {
expect(queryByTestId(modal, "modalSaveButton")).not.toBeNull();
expect(queryByTestId(modal, "modalCancelButton")).toBeNull();
expect(queryByTestId(modal, "modalSaveButton")).toBe("Save");
});
});
});
test("render cancel button but not save button", () => {
rerenderFunc(
<ViadeModal title="Title" onOpen={mock} CancelText="Cancel"></ViadeModal>
);
waitForElement(() => {
fireEvent.click(queryByTestId(modal, "modalButton"));
waitForDomChange(() => {
expect(queryByTestId(modal, "modalCancelButton")).not.toBeNull();
expect(queryByTestId(modal, "modalSaveButton")).toBeNull();
expect(queryByTestId(modal, "modalCancelButton")).toBe("Cancel");
});
});
});
});
Example #11
Source File: Login.test.js From viade_en1b with MIT License | 6 votes |
describe("login component", () => {
test("renders the header correctly", async () => {
const text = "Login";
waitForElement(() => {
expect(queryByTestId(rendered, "login-header")).toEqual("Login");
expect(queryByTestId(rendered, "login-header")).not.toBeNull();
});
});
test("pop up opens up", () => {
waitForElement(() => {
global.open = jest.fn();
fireEvent.click(queryByText(rendered, "Login here!"));
expect(global.open).toBeCalled();
});
});
});
Example #12
Source File: Footer.test.js From viade_en1b with MIT License | 6 votes |
describe("Footer component", () => {
let wrapper;
beforeEach(() => {
const { container } = render(
<IntlProvider key={"en"} locale={"en"} messages={locales["en"]}>
<Footer></Footer>
</IntlProvider>
);
wrapper = container;
});
describe("renders correctly", () => {
test("footer", () => {
waitForElement(() => {
expect(queryByTestId(wrapper, "footer")).toBeNull();
});
});
test("team", () => {
waitForElement(() => {
expect(queryByTestId(wrapper, "footer-team")).toBeNull();
});
});
test("github", () => {
waitForElement(() => {
expect(queryByTestId(wrapper, "footer-github")).not.toBeNull();
});
});
test("react", () => {
waitForElement(() => {
expect(queryByTestId(wrapper, "footer-react")).not.toBeNull();
});
});
});
});
Example #13
Source File: MyMap.test.js From viade_en1b with MIT License | 6 votes |
describe("MyMap Component", () => {
let wrapper;
let wrapperb;
beforeEach(() => {
const props = {
center: [[43.360976539, -5.831938919]],
positions: []
};
wrapper = myMap(props.center, props.positions);
wrapperb = <MyMap center={props.center} positions={props.positions}></MyMap>;
});
test("Component renders correctly", () => {
waitForElement(() => {
expect(wrapperb.prop("positions")).not.toBeNull();
expect(wrapperb.prop("center")).not.toBeNull();
expect(queryByTestId(wrapper, "mymap-container")).not.toBeNull();
expect(queryByTestId(wrapper, "mymap-map")).not.toBeNull();
expect(queryByTestId(wrapper, "mymap-tilelayer")).not.toBeNull();
expect(queryByTestId(wrapper, "mymap-polyline")).not.toBeNull();
});
});
});
Example #14
Source File: Comment.test.js From viade_en1b with MIT License | 6 votes |
describe("Comment component", () => {
let wrapper;
beforeEach(() => {
const { container } = render(
<Comment author="alvarogarinf" text="This is a test" date="2020-4-29"></Comment>
);
wrapper = container;
});
describe("renders correctly", () => {
test("comment", () => {
waitForElement(() => {
expect(queryByTestId(wrapper, "comment")).not.toBeNull();
});
});
test("date", () => {
waitForElement(() => {
expect(queryByTestId(wrapper, "date")).not.toBeNull();
});
});
test("text", () => {
waitForElement(() => {
expect(queryByTestId(wrapper, "text")).not.toBeNull();
});
});
test("text", () => {
waitForElement(() => {
expect(queryByTestId(wrapper, "text")).not.toBeNull();
});
});
});
});
Example #15
Source File: NotificationsList.test.js From viade_en1b with MIT License | 5 votes |
describe("Notifications list component", () => {
const mockWebId = "http://piratillajudoka.inrupt.net/profile/card#me";
const mockLoad = jest.fn();
let component;
beforeEach(() => {
const { container, rerender } = render(<IntlProvider messages={locales["en"]} locale="en"><NotificationsList userWebId={mockWebId} loadRoutes={mockLoad}></NotificationsList></IntlProvider>);
component = container;
});
describe("renders correctly", () => {
test("div", () => {
expect(component).not.toBeNull();
expect(queryByTestId(component, "notificationslist-div")).not.toBeNull();
});
test("list", () => {
expect(component).not.toBeNull();
expect(queryByTestId(component, "notificationslist-divcomponent")).not.toBeNull();
});
test("button", () => {
expect(component).not.toBeNull();
waitForElement(() => {
expect(queryByTestId(component, "notificationslist-button")).not.toBeNull();
});
});
});
test("notifications", () => {
waitForElement(() => {
expect(queryAllByTestId(component, "notification")).not.toBeNull();
});
});
test("click", () => {
waitForElement(() => {
fireEvent.click(queryByTestId(component, "notificationslist-button"));
expect(mockLoad).toBeCalled();
});
});
});
Example #16
Source File: BbbSettings.test.jsx From frontend-app-course-authoring with GNU Affero General Public License v3.0 | 5 votes |
describe('BBB Settings', () => {
beforeEach(async () => {
initializeMockApp({
authenticatedUser: {
userId: 3,
username: 'abc123',
administrator: false,
roles: [],
},
});
store = initializeStore(initialState);
axiosMock = new MockAdapter(getAuthenticatedHttpClient());
history.push(liveSettingsUrl);
});
test('Plan dropdown to be visible and enabled in UI', async () => {
await mockStore({ emailSharing: true });
renderComponent();
const spinner = getByRole(container, 'status');
await waitForElementToBeRemoved(spinner);
expect(queryByTestId(container, 'plansDropDown')).toBeInTheDocument();
expect(container.querySelector('select[name="tierType"]')).not.toBeDisabled();
});
it('Plan dropdown should display correct number of options', async () => {
await mockStore({ emailSharing: true });
renderComponent();
const spinner = getByRole(container, 'status');
await waitForElementToBeRemoved(spinner);
const dropDown = queryByTestId(container, 'plansDropDown');
expect(getAllByRole(dropDown, 'option').length).toBe(3);
});
test('Connect to support and PII sharing message is visible and plans selection is disabled, When pii sharing is disabled, ',
async () => {
await mockStore({ piiSharingAllowed: false });
renderComponent();
const spinner = getByRole(container, 'status');
await waitForElementToBeRemoved(spinner);
const requestPiiText = queryByTestId(container, 'request-pii-sharing');
const helpRequestPiiText = queryByTestId(container, 'help-request-pii-sharing');
expect(requestPiiText).toHaveTextContent(
messages.requestPiiSharingEnableForBbb.defaultMessage.replaceAll('{provider}', 'BigBlueButton'),
);
expect(helpRequestPiiText).toHaveTextContent(messages.piiSharingEnableHelpTextBbb.defaultMessage);
expect(container.querySelector('select[name="tierType"]')).toBeDisabled();
});
test('free plans message is visible when free plan is selected', async () => {
await mockStore({ emailSharing: true, isFreeTier: true });
renderComponent();
const spinner = getByRole(container, 'status');
await waitForElementToBeRemoved(spinner);
const dropDown = container.querySelector('select[name="tierType"]');
userEvent.selectOptions(
dropDown,
getByRole(dropDown, 'option', { name: 'Free' }),
);
expect(queryByTestId(container, 'free-plan-message')).toBeInTheDocument();
expect(queryByTestId(container, 'free-plan-message')).toHaveTextContent(messages.freePlanMessage.defaultMessage);
});
});
Example #17
Source File: FeaturesTable.test.jsx From frontend-app-course-authoring with GNU Affero General Public License v3.0 | 5 votes |
describe('FeaturesTable', () => {
let apps;
let features;
let container;
beforeEach(() => {
apps = [
{
externalLinks: {},
featureIds: ['discussion-page', 'embedded-course-sections', 'wcag-2.1'],
hasFullSupport: false,
id: 'legacy',
},
{
externalLinks: {},
featureIds: ['discussion-page', 'basic-configuration'],
hasFullSupport: false,
id: 'piazza',
}];
features = [
{ id: 'discussion-page', featureSupportType: 'basic' },
{ id: 'embedded-course-sections', featureSupportType: 'full' },
{ id: 'wcag-2.1', featureSupportType: 'partial' },
{ id: 'basic-configuration', featureSupportType: 'common' },
];
const wrapper = render(
<IntlProvider locale="en">
<FeaturesTable
apps={apps}
features={features}
/>
</IntlProvider>,
);
container = wrapper.container;
});
test('displays a table, a thead, a tbody', () => {
expect(container.querySelectorAll('table')).toHaveLength(1);
expect(container.querySelectorAll('table > thead')).toHaveLength(1);
expect(container.querySelectorAll('table > tbody')).toHaveLength(1);
});
test('displays a row for each available feature', () => {
expect(container.querySelectorAll('tbody > tr')).toHaveLength(8);
});
test('apps columns receive a check for each feature they support', () => {
features.forEach((feature) => {
apps.forEach(app => {
if (app.featureIds.includes(feature.id)) {
const columnId = `${app.id}-${feature.id.replaceAll('.', '-')}`;
const columnCell = queryByTestId(container, columnId);
expect(columnCell.querySelector('#check-icon')).toBeInTheDocument();
}
});
});
});
test('apps columns receive a dash for each unsupported feature', () => {
features.forEach((feature) => {
apps.forEach(app => {
if (!app.featureIds.includes(feature.id)) {
const columnId = `${app.id}-${feature.id.replaceAll('.', '-')}`;
const columnCell = queryByTestId(container, columnId);
expect(columnCell.querySelector('#remove-icon')).toBeInTheDocument();
}
});
});
});
});
Example #18
Source File: DiscussionsSettings.test.jsx From frontend-app-course-authoring with GNU Affero General Public License v3.0 | 5 votes |
describe.each([
{ piiSharingAllowed: false },
{ piiSharingAllowed: true },
])('PII sharing fields test', ({ piiSharingAllowed }) => {
const enablePIISharing = false;
beforeEach(() => {
initializeMockApp({
authenticatedUser: {
userId: 3,
username: 'abc123',
administrator: true,
roles: [],
},
});
store = initializeStore({
models: {
courseDetails: {
[courseId]: {},
},
},
});
axiosMock = new MockAdapter(getAuthenticatedHttpClient());
// Leave the DiscussionsSettings route after the test.
history.push(`/course/${courseId}/pages-and-resources`);
axiosMock.onGet(getDiscussionsProvidersUrl(courseId))
.reply(200, generateProvidersApiResponse(false));
axiosMock.onGet(getDiscussionsSettingsUrl(courseId))
.reply(200, generatePiazzaApiResponse(piiSharingAllowed));
renderComponent();
});
test(`${piiSharingAllowed ? 'shows PII share username/email field when piiSharingAllowed is true'
: 'hides PII share username/email field when piiSharingAllowed is false'}`, async () => {
history.push(`/course/${courseId}/pages-and-resources/discussion`);
// This is an important line that ensures the spinner has been removed - and thus our main
// content has been loaded - prior to proceeding with our expectations.
await waitForElementToBeRemoved(screen.getByRole('status'));
userEvent.click(queryByLabelText(container, 'Select Piazza'));
userEvent.click(queryByText(container, messages.nextButton.defaultMessage));
await waitForElementToBeRemoved(screen.getByRole('status'));
if (enablePIISharing) {
expect(queryByTestId(container, 'piiSharingFields')).toBeInTheDocument();
} else {
expect(queryByTestId(container, 'piiSharingFields')).not.toBeInTheDocument();
}
});
});
Example #19
Source File: DiscussionsSettings.test.jsx From frontend-app-course-authoring with GNU Affero General Public License v3.0 | 5 votes |
describe.each([
{ isAdmin: false, isAdminOnlyConfig: false },
{ isAdmin: false, isAdminOnlyConfig: true },
{ isAdmin: true, isAdminOnlyConfig: false },
{ isAdmin: true, isAdminOnlyConfig: true },
])('LTI Admin only config test', ({ isAdmin, isAdminOnlyConfig }) => {
beforeEach(() => {
initializeMockApp({
authenticatedUser: {
userId: 3,
username: 'abc123',
administrator: isAdmin,
roles: [],
},
});
store = initializeStore({
models: {
courseDetails: {
[courseId]: {},
},
},
});
axiosMock = new MockAdapter(getAuthenticatedHttpClient());
// Leave the DiscussionsSettings route after the test.
history.push(`/course/${courseId}/pages-and-resources`);
axiosMock.onGet(getDiscussionsProvidersUrl(courseId))
.reply(200, generateProvidersApiResponse(isAdminOnlyConfig));
axiosMock.onGet(getDiscussionsSettingsUrl(courseId))
.reply(200, generatePiazzaApiResponse(true));
renderComponent();
});
test(`successfully advances to settings step for lti when adminOnlyConfig=${isAdminOnlyConfig} and user ${isAdmin ? 'is' : 'is not'} admin `, async () => {
const showLTIConfig = isAdmin;
history.push(`/course/${courseId}/pages-and-resources/discussion`);
// This is an important line that ensures the spinner has been removed - and thus our main
// content has been loaded - prior to proceeding with our expectations.
await waitForElementToBeRemoved(screen.getByRole('status'));
userEvent.click(queryByLabelText(container, 'Select Piazza'));
userEvent.click(queryByText(container, messages.nextButton.defaultMessage));
await waitForElementToBeRemoved(screen.getByRole('status'));
if (showLTIConfig) {
expect(queryByText(container, ltiMessages.formInstructions.defaultMessage)).toBeInTheDocument();
expect(queryByTestId(container, 'ltiConfigFields')).toBeInTheDocument();
} else {
expect(queryByText(container, ltiMessages.formInstructions.defaultMessage)).not.toBeInTheDocument();
expect(queryByTestId(container, 'ltiConfigFields')).not.toBeInTheDocument();
}
});
});
Example #20
Source File: App.test.js From viade_en1b with MIT License | 5 votes |
describe("App Component", () => {
test("Component renders correctly", () => {
expect(queryByTestId(wrapper, "theApp")).not.toBeNull();
expect(queryByTestId(wrapper, "theNavBar")).toBeNull();
});
});
Example #21
Source File: Comments.test.js From viade_en1b with MIT License | 5 votes |
describe("Comments component", () => {
let wrapper;
beforeEach(() => {
const { container } = render(
<IntlProvider key={"en"} locale={"en"} messages={locales["en"]}>
<Comments userWebId='1'></Comments>
</IntlProvider>
);
wrapper = container;
});
describe("renders correctly", () => {
test("comments general", () => {
waitForElement(() => {
expect(queryByTestId(wrapper, "general-component")).not.toBeNull();
});
});
test("comments modal", () => {
waitForElement(() => {
expect(queryByTestId(wrapper, "Modal-component")).not.toBeNull();
});
});
test("comment form", () => {
waitForElement(() => {
expect(queryByTestId(wrapper, "form-component")).not.toBeNull();
});
});
test("comment text area", () => {
waitForElement(() => {
expect(queryByTestId(wrapper, "textarea-component")).not.toBeNull();
});
});
test("comments button", () => {
waitForElement(() => {
expect(queryByTestId(wrapper, "Leave-Cooment-text")).not.toBeNull();
});
});
});
});
Example #22
Source File: MyRoutes.test.js From viade_en1b with MIT License | 5 votes |
describe("Everything is rendered correctly", () => {
test("routes are rendered", () => {
waitForElement(() => {
expect(queryByTestId(myRoutes, "myRoutes-route-list")).not.toBeNull();
expect(queryByTestId(myRoutes, "myRoutes-route-details")).not.toBeNull();
});
});
});
Example #23
Source File: Slideshow.test.js From viade_en1b with MIT License | 5 votes |
describe("The slideshow render correctly", () => {
test("buttons are rendered when having some pictures to show", () => {
waitForElement(() => {
expect(queryByTestId(slideshowWithPictures, "previous")).not.toBeNull();
expect(queryByTestId(slideshowWithPictures, "next")).not.toBeNull();
});
});
test("buttons are not rendered when having no pictures to show", () => {
waitForElement(() => {
expect(queryByTestId(slideshowNoPictures, "previous")).toBeNull();
expect(queryByTestId(slideshowNoPictures, "next")).toBeNull();
});
});
test("images are rendered in the slideshow with pictures", () => {
waitForElement(() => {
expect(
queryByTestId(slideshowWithPictures, "current-image-slideshow")
).not.toBeNull();
});
});
test("images are not rendered in the slideshow with no pictures", () => {
waitForElement(() => {
expect(
queryByTestId(slideshowNoPictures, "current-image-slideshow")
).toBeNull();
});
});
test("buttons have the correct functionality", () => {
waitForElement(() => {
const nextButton = queryByTestId(slideshowWithPictures, "next");
const previousButton = queryByTestId(slideshowWithPictures, "next");
fireEvent.click(nextButton);
expect(nextButton).toBeDisabled();
fireEvent.click(previousButton);
expect(previousButton).toBeDisabled();
});
});
});
Example #24
Source File: Modal.test.js From viade_en1b with MIT License | 5 votes |
describe("All renders correctly with normal settings", () => {
test("title is rendered", () => {
fireEvent.click(queryByTestId(modal, "modalButton"));
waitForDomChange(() => {
expect(queryByTestId(modal, "modalTitle").textContent).not.toBeNull();
expect(queryByTestId(modal, "modalTitle").textContent).toBe("Submitted");
});
});
test("children are rendered", () => {
let paragraph = <p>Hello there!</p>;
rerenderFunc(
<ViadeModal onOpen={mock} title="Submit">
{paragraph}
</ViadeModal>
);
waitForElement(() => {
expect(paragraph).toBeInTheDocument();
});
});
test("buttons are rendered", () => {
fireEvent.click(queryByTestId(modal, "modalButton"));
waitForDomChange(() => {
expect(queryByTestId(modal, "modalSaveButton")).not.toBeNull();
expect(queryByTestId(modal, "modalSaveButton")).toBe("Save");
expect(queryByTestId(modal, "modalCloseButton")).not.toBeNull();
expect(queryByTestId(modal, "modalCloseButton")).toBe("Close");
});
});
test("on save function is triggered", () => {
fireEvent.click(queryByTestId(modal, "modalButton"));
waitForDomChange(() => {
expect(queryByTestId(modal, "modalCloseButton")).not.toBeNull();
expect(queryByTestId(modal, "modalCloseButton")).toBe("Close");
expect(queryByTestId(modal, "modalSaveButton")).not.toBeNull();
expect(queryByTestId(modal, "modalSaveButton")).toBe("Save");
fireEvent.click(queryByTestId(modal, "modalSaveButton"));
expect(mock).toBeCalled();
});
});
});
Example #25
Source File: NavBar.test.js From viade_en1b with MIT License | 5 votes |
describe("Navbar is correctly rendered", () => {
test("all buttons are rendered", () => {
waitForElement(() => {
expect(queryByTestId(rendered, "navbar-my-routes")).not.toBeNull();
expect(queryByTestId(rendered, "navbar-upload-route")).not.toBeNull();
expect(queryByTestId(rendered, "navbar-my-profile")).not.toBeNull();
expect(queryByTestId(rendered, "navbar-logout")).not.toBeNull();
expect(queryByTestId(rendered, "navbar-brand")).not.toBeNull();
expect(queryByTestId(rendered, "navbar-settings")).not.toBeNull();
expect(queryByTestId(rendered, "navbar-dashboard")).not.toBeNull();
expect(queryByTestId(rendered, "navbar-notifications")).not.toBeNull();
expect(queryByTestId(rendered, "navbar-groups")).not.toBeNull();
});
});
test("redirections work", () => {
waitForElement(() => {
let routes = queryByTestId(rendered, "navbar-my-routes");
let upload = queryByTestId(rendered, "navbar-upload-route");
let profile = queryByTestId(rendered, "navbar-my-profile");
let brand = queryByTestId(rendered, "navbar-brand");
let logout = queryByTestId(rendered, "navbar-logout");
let settings = queryByTestId(rendered, "navbar-settings");
let dashboard = queryByTestId(rendered, "navbar-dashboard");
let notifications = queryByTestId(rendered, "navbar-notifications");
let groups = queryByTestId(rendered, "navbar-groups");
fireEvent.click(groups);
expect(getCurrentPage()).toEqual("groups");
fireEvent.click(notifications);
expect(getCurrentPage()).toEqual("notifications");
fireEvent.click(routes);
expect(getCurrentPage()).toEqual("routes");
fireEvent.click(upload);
expect(getCurrentPage()).toEqual("upload");
fireEvent.click(profile);
expect(getCurrentPage()).toEqual("profile");
fireEvent.click(brand);
expect(getCurrentPage()).toEqual("dashboard");
fireEvent.click(logout);
expect(getCurrentPage()).toEqual("");
fireEvent.click(settings);
expect(getCurrentPage()).toEqual("settings");
fireEvent.click(dashboard);
expect(getCurrentPage()).toEqual("dashboard");
});
});
});
Example #26
Source File: DiscussionsSettings.test.jsx From frontend-app-course-authoring with GNU Affero General Public License v3.0 | 4 votes |
describe('DiscussionsSettings', () => {
beforeEach(() => {
initializeMockApp({
authenticatedUser: {
userId: 3,
username: 'abc123',
administrator: true,
roles: [],
},
});
store = initializeStore({
models: {
courseDetails: {
[courseId]: {
start: Date(),
},
},
},
});
axiosMock = new MockAdapter(getAuthenticatedHttpClient());
// Leave the DiscussionsSettings route after the test.
history.push(`/course/${courseId}/pages-and-resources`);
});
describe('with successful network connections', () => {
beforeEach(() => {
axiosMock.onGet(getDiscussionsProvidersUrl(courseId))
.reply(200, generateProvidersApiResponse(false));
axiosMock.onGet(getDiscussionsSettingsUrl(courseId))
.reply(200, generatePiazzaApiResponse(true));
renderComponent();
});
test('sets selection step from routes', async () => {
history.push(`/course/${courseId}/pages-and-resources/discussion`);
// This is an important line that ensures the spinner has been removed - and thus our main
// content has been loaded - prior to proceeding with our expectations.
await waitForElementToBeRemoved(screen.getByRole('status'));
expect(queryByTestId(container, 'appList')).toBeInTheDocument();
expect(queryByTestId(container, 'appConfigForm')).not.toBeInTheDocument();
});
test('sets settings step from routes', async () => {
history.push(`/course/${courseId}/pages-and-resources/discussion/configure/piazza`);
// This is an important line that ensures the spinner has been removed - and thus our main
// content has been loaded - prior to proceeding with our expectations.
await waitForElementToBeRemoved(screen.getByRole('status'));
expect(queryByTestId(container, 'appList')).not.toBeInTheDocument();
expect(queryByTestId(container, 'appConfigForm')).toBeInTheDocument();
});
test('successfully advances to settings step for lti', async () => {
history.push(`/course/${courseId}/pages-and-resources/discussion`);
// This is an important line that ensures the spinner has been removed - and thus our main
// content has been loaded - prior to proceeding with our expectations.
await waitForElementToBeRemoved(screen.getByRole('status'));
userEvent.click(queryByLabelText(container, 'Select Piazza'));
userEvent.click(queryByText(container, messages.nextButton.defaultMessage));
await waitForElementToBeRemoved(screen.getByRole('status'));
expect(queryByTestId(container, 'appList')).not.toBeInTheDocument();
expect(queryByTestId(container, 'appConfigForm')).toBeInTheDocument();
expect(queryByTestId(container, 'ltiConfigForm')).toBeInTheDocument();
expect(queryByTestId(container, 'legacyConfigForm')).not.toBeInTheDocument();
});
test('successfully advances to settings step for legacy', async () => {
axiosMock.onGet(getDiscussionsProvidersUrl(courseId)).reply(200, generateProvidersApiResponse(false, 'legacy'));
axiosMock.onGet(getDiscussionsSettingsUrl(courseId)).reply(200, legacyApiResponse);
renderComponent();
history.push(`/course/${courseId}/pages-and-resources/discussion`);
// This is an important line that ensures the spinner has been removed - and thus our main
// content has been loaded - prior to proceeding with our expectations.
await waitForElementToBeRemoved(screen.getByRole('status'));
userEvent.click(queryByLabelText(container, 'Select edX'));
userEvent.click(queryByText(container, messages.nextButton.defaultMessage));
await waitForElementToBeRemoved(screen.getByRole('status'));
expect(queryByTestId(container, 'appList')).not.toBeInTheDocument();
expect(queryByTestId(container, 'appConfigForm')).toBeInTheDocument();
expect(queryByTestId(container, 'ltiConfigForm')).not.toBeInTheDocument();
expect(queryByTestId(container, 'legacyConfigForm')).toBeInTheDocument();
});
test('successfully goes back to first step', async () => {
history.push(`/course/${courseId}/pages-and-resources/discussion/configure/piazza`);
// This is an important line that ensures the spinner has been removed - and thus our main
// content has been loaded - prior to proceeding with our expectations.
await waitForElementToBeRemoved(screen.getByRole('status'));
expect(queryByTestId(container, 'appConfigForm')).toBeInTheDocument();
userEvent.click(queryByText(container, appMessages.backButton.defaultMessage));
expect(queryByTestId(container, 'appList')).toBeInTheDocument();
expect(queryByTestId(container, 'appConfigForm')).not.toBeInTheDocument();
});
test('successfully closes the modal', async () => {
history.push(`/course/${courseId}/pages-and-resources/discussion`);
// This is an important line that ensures the spinner has been removed - and thus our main
// content has been loaded - prior to proceeding with our expectations.
await waitForElementToBeRemoved(screen.getByRole('status'));
expect(queryByTestId(container, 'appList')).toBeInTheDocument();
userEvent.click(queryByLabelText(container, 'Close'));
expect(queryByTestId(container, 'appList')).not.toBeInTheDocument();
expect(queryByTestId(container, 'appConfigForm')).not.toBeInTheDocument();
expect(window.location.pathname).toEqual(`/course/${courseId}/pages-and-resources`);
});
test('successfully submit the modal', async () => {
history.push(`/course/${courseId}/pages-and-resources/discussion`);
axiosMock.onPost(getDiscussionsSettingsUrl(courseId)).reply(200, generatePiazzaApiResponse(true));
// This is an important line that ensures the spinner has been removed - and thus our main
// content has been loaded - prior to proceeding with our expectations.
await waitForElementToBeRemoved(screen.getByRole('status'));
userEvent.click(queryByLabelText(container, 'Select Piazza'));
userEvent.click(getByRole(container, 'button', { name: 'Next' }));
userEvent.click(await findByRole(container, 'button', { name: 'Save' }));
// This is an important line that ensures the Close button has been removed, which implies that
// the full screen modal has been closed following our click of Apply. Once this has happened,
// then it's safe to proceed with our expectations.
await waitForElementToBeRemoved(queryByRole(container, 'button', { name: 'Close' }));
await waitFor(() => expect(window.location.pathname).toEqual(`/course/${courseId}/pages-and-resources`));
});
test('requires confirmation if changing provider', async () => {
axiosMock.onGet(`${getConfig().LMS_BASE_URL}/api/courses/v1/courses/${courseId}?username=abc123`).reply(200, courseDetailResponse);
await executeThunk(fetchCourseDetail(courseId), store.dispatch);
history.push(`/course/${courseId}/pages-and-resources/discussion`);
// This is an important line that ensures the spinner has been removed - and thus our main
// content has been loaded - prior to proceeding with our expectations.
await waitForElementToBeRemoved(screen.getByRole('status'));
userEvent.click(getByRole(container, 'checkbox', { name: 'Select Discourse' }));
userEvent.click(getByRole(container, 'button', { name: 'Next' }));
await findByRole(container, 'button', { name: 'Save' });
userEvent.type(getByRole(container, 'textbox', { name: 'Consumer Key' }), 'key');
userEvent.type(getByRole(container, 'textbox', { name: 'Consumer Secret' }), 'secret');
userEvent.type(getByRole(container, 'textbox', { name: 'Launch URL' }), 'http://example.test');
userEvent.click(getByRole(container, 'button', { name: 'Save' }));
await waitFor(() => expect(getByRole(container, 'dialog', { name: 'OK' })).toBeInTheDocument());
});
test('can cancel confirmation', async () => {
axiosMock.onGet(`${getConfig().LMS_BASE_URL}/api/courses/v1/courses/${courseId}?username=abc123`).reply(200, courseDetailResponse);
await executeThunk(fetchCourseDetail(courseId), store.dispatch);
history.push(`/course/${courseId}/pages-and-resources/discussion`);
// This is an important line that ensures the spinner has been removed - and thus our main
// content has been loaded - prior to proceeding with our expectations.
await waitForElementToBeRemoved(screen.getByRole('status'));
const discourseBox = getByRole(container, 'checkbox', { name: 'Select Discourse' });
expect(discourseBox).not.toBeDisabled();
userEvent.click(discourseBox);
userEvent.click(getByRole(container, 'button', { name: 'Next' }));
await waitForElementToBeRemoved(screen.getByRole('status'));
expect(getByRole(container, 'heading', { name: 'Discourse' })).toBeInTheDocument();
userEvent.type(getByRole(container, 'textbox', { name: 'Consumer Key' }), 'a');
userEvent.type(getByRole(container, 'textbox', { name: 'Consumer Secret' }), 'secret');
userEvent.type(getByRole(container, 'textbox', { name: 'Launch URL' }), 'http://example.test');
userEvent.click(getByRole(container, 'button', { name: 'Save' }));
await waitFor(() => expect(getByRole(container, 'dialog', { name: 'OK' })).toBeInTheDocument());
userEvent.click(getByRole(container, 'button', { name: 'Cancel' }));
expect(queryByRole(container, 'dialog', { name: 'Confirm' })).not.toBeInTheDocument();
expect(queryByRole(container, 'dialog', { name: 'Configure discussion' }));
});
});
describe('with network error fetchProviders API requests', () => {
beforeEach(() => {
// Expedient way of getting SUPPORT_URL into config.
setConfig({
...getConfig(),
SUPPORT_URL: 'http://support.edx.org',
});
axiosMock.onGet(getDiscussionsProvidersUrl(courseId)).networkError();
axiosMock.onGet(getDiscussionsSettingsUrl(courseId)).networkError();
renderComponent();
});
test('shows connection error alert', async () => {
history.push(`/course/${courseId}/pages-and-resources/discussion`);
// This is an important line that ensures the spinner has been removed - and thus our main
// content has been loaded - prior to proceeding with our expectations.
await waitForElementToBeRemoved(screen.getByRole('status'));
const alert = queryByRole(container, 'alert');
expect(alert).toBeInTheDocument();
expect(alert.textContent).toEqual(expect.stringContaining('We encountered a technical error when loading this page.'));
expect(alert.innerHTML).toEqual(expect.stringContaining(getConfig().SUPPORT_URL));
});
});
describe('with network error postAppConfig API requests', () => {
beforeEach(() => {
// Expedient way of getting SUPPORT_URL into config.
setConfig({
...getConfig(),
SUPPORT_URL: 'http://support.edx.org',
});
axiosMock.onGet(getDiscussionsProvidersUrl(courseId))
.reply(200, generateProvidersApiResponse());
axiosMock.onGet(getDiscussionsSettingsUrl(courseId))
.reply(200, piazzaApiResponse);
axiosMock.onPost(getDiscussionsSettingsUrl(courseId)).networkError();
renderComponent();
});
test('shows connection error alert at top of form', async () => {
history.push(`/course/${courseId}/pages-and-resources/discussion/configure/piazza`);
// This is an important line that ensures the spinner has been removed - and thus our main
// content has been loaded - prior to proceeding with our expectations.
await waitForElementToBeRemoved(screen.getByRole('status'));
// Apply causes an async action to take place
act(() => {
userEvent.click(queryByText(container, appMessages.saveButton.defaultMessage));
});
await waitFor(() => expect(axiosMock.history.post.length).toBe(1));
expect(queryByTestId(container, 'appConfigForm')).toBeInTheDocument();
const alert = await findByRole(container, 'alert');
expect(alert).toBeInTheDocument();
expect(alert.textContent).toEqual(expect.stringContaining('We encountered a technical error when applying changes.'));
expect(alert.innerHTML).toEqual(expect.stringContaining(getConfig().SUPPORT_URL));
});
});
describe('with permission denied error for fetchProviders API requests', () => {
beforeEach(() => {
axiosMock.onGet(getDiscussionsProvidersUrl(courseId)).reply(403);
axiosMock.onGet(getDiscussionsSettingsUrl(courseId)).reply(403);
renderComponent();
});
test('shows permission denied alert', async () => {
history.push(`/course/${courseId}/pages-and-resources/discussion`);
// This is an important line that ensures the spinner has been removed - and thus our main
// content has been loaded - prior to proceeding with our expectations.
await waitForElementToBeRemoved(screen.getByRole('status'));
const alert = queryByRole(container, 'alert');
expect(alert).toBeInTheDocument();
expect(alert.textContent).toEqual(expect.stringContaining('You are not authorized to view this page.'));
});
});
describe('with permission denied error for postAppConfig API requests', () => {
beforeEach(() => {
axiosMock.onGet(getDiscussionsProvidersUrl(courseId))
.reply(200, generateProvidersApiResponse());
axiosMock.onGet(getDiscussionsSettingsUrl(courseId)).reply(200, piazzaApiResponse);
axiosMock.onPost(getDiscussionsSettingsUrl(courseId)).reply(403);
renderComponent();
});
test('shows permission denied alert at top of form', async () => {
history.push(`/course/${courseId}/pages-and-resources/discussion/configure/piazza`);
// This is an important line that ensures the spinner has been removed - and thus our main
// content has been loaded - prior to proceeding with our expectations.
await waitForElementToBeRemoved(screen.getByRole('status'));
userEvent.click(getByRole(container, 'button', { name: 'Save' }));
await waitFor(() => expect(axiosMock.history.post.length).toBe(1));
expect(queryByTestId(container, 'appList')).not.toBeInTheDocument();
expect(queryByTestId(container, 'appConfigForm')).not.toBeInTheDocument();
// We don't technically leave the route in this case, though the modal is hidden.
expect(window.location.pathname).toEqual(`/course/${courseId}/pages-and-resources/discussion/configure/piazza`);
const alert = await findByRole(container, 'alert');
expect(alert).toBeInTheDocument();
expect(alert.textContent).toEqual(expect.stringContaining('You are not authorized to view this page.'));
});
});
});
Example #27
Source File: OpenedXConfigForm.test.jsx From frontend-app-course-authoring with GNU Affero General Public License v3.0 | 4 votes |
describe('OpenedXConfigForm', () => {
let axiosMock;
let store;
let container;
beforeEach(async () => {
initializeMockApp({
authenticatedUser: {
userId: 3,
username: 'abc123',
administrator: true,
roles: [],
},
});
axiosMock = new MockAdapter(getAuthenticatedHttpClient());
store = initializeStore();
});
afterEach(() => {
axiosMock.reset();
});
const createComponent = (onSubmit = jest.fn(), formRef = createRef(), legacy = true) => {
const wrapper = render(
<AppProvider store={store}>
<IntlProvider locale="en">
<OpenedXConfigForm
onSubmit={onSubmit}
formRef={formRef}
legacy={legacy}
/>
</IntlProvider>
</AppProvider>,
);
container = wrapper.container;
return container;
};
const mockStore = async (mockResponse) => {
axiosMock.onGet(getDiscussionsProvidersUrl(courseId)).reply(200, generateProvidersApiResponse());
axiosMock.onGet(getDiscussionsSettingsUrl(courseId)).reply(200, mockResponse);
await executeThunk(fetchProviders(courseId), store.dispatch);
await executeThunk(fetchDiscussionSettings(courseId), store.dispatch);
store.dispatch(selectApp({ appId: 'legacy' }));
};
test('title rendering', async () => {
await mockStore(legacyApiResponse);
createComponent();
expect(container.querySelector('h3')).toHaveTextContent('edX');
});
test('new Open edX provider config', async () => {
await mockStore({ ...legacyApiResponse, enable_in_context: true });
createComponent(jest.fn(), createRef(), false);
expect(queryByText(container, messages.visibilityInContext.defaultMessage)).toBeInTheDocument();
expect(queryByText(container, messages.gradedUnitPagesLabel.defaultMessage)).toBeInTheDocument();
expect(queryByText(container, messages.groupInContextSubsectionLabel.defaultMessage)).toBeInTheDocument();
expect(queryByText(container, messages.allowUnitLevelVisibilityLabel.defaultMessage)).toBeInTheDocument();
});
test('calls onSubmit when the formRef is submitted', async () => {
const formRef = createRef();
const handleSubmit = jest.fn();
await mockStore(legacyApiResponse);
createComponent(handleSubmit, formRef);
await act(async () => {
formRef.current.submit();
});
expect(handleSubmit).toHaveBeenCalledWith(
// Because we use defaultAppConfig as the initialValues of the form, and we haven't changed
// any of the form inputs, this exact object shape is returned back to us, so we're reusing
// it here. It's not supposed to be 'the same object', it just happens to be.
{
...defaultAppConfig(),
divideByCohorts: false,
divisionScheme: DivisionSchemes.COHORT,
},
);
});
test('default field states are correct, including removal of folded sub-fields', async () => {
await mockStore({
...legacyApiResponse,
plugin_configuration: {
...legacyApiResponse.plugin_configuration,
reported_content_email_notifications_flag: true,
divided_course_wide_discussions: [],
},
});
createComponent();
const { divideDiscussionIds } = defaultAppConfig(['13f106c6-6735-4e84-b097-0456cff55960', 'course']);
// DivisionByGroupFields
expect(container.querySelector('#divideByCohorts')).toBeInTheDocument();
expect(container.querySelector('#divideByCohorts')).not.toBeChecked();
expect(container.querySelector('#divideCourseTopicsByCohorts')).not.toBeInTheDocument();
divideDiscussionIds.forEach(id => expect(
container.querySelector(`#checkbox-${id}`),
).not.toBeInTheDocument());
// AnonymousPostingFields
expect(
container.querySelector('#allowAnonymousPostsPeers'),
).toBeInTheDocument();
expect(container.querySelector('#allowAnonymousPostsPeers')).not.toBeChecked();
// ReportedContentEmailNotifications
expect(container.querySelector('#reportedContentEmailNotifications')).toBeInTheDocument();
expect(container.querySelector('#reportedContentEmailNotifications')).not.toBeChecked();
// BlackoutDatesField
expect(queryByText(container, messages.blackoutDatesLabel.defaultMessage)).toBeInTheDocument();
});
test('folded sub-fields are in the DOM when parents are enabled', async () => {
await mockStore({
...legacyApiResponse,
plugin_configuration: {
...legacyApiResponse.plugin_configuration,
allow_anonymous: true,
reported_content_email_notifications: true,
reported_content_email_notifications_flag: true,
always_divide_inline_discussions: true,
divided_course_wide_discussions: [],
},
});
createComponent();
const { divideDiscussionIds } = defaultAppConfig(['13f106c6-6735-4e84-b097-0456cff55960', 'course']);
// DivisionByGroupFields
expect(container.querySelector('#divideByCohorts')).toBeInTheDocument();
expect(container.querySelector('#divideByCohorts')).toBeChecked();
expect(
container.querySelector('#divideCourseTopicsByCohorts'),
).toBeInTheDocument();
expect(
container.querySelector('#divideCourseTopicsByCohorts'),
).not.toBeChecked();
divideDiscussionIds.forEach(id => expect(
container.querySelector(`#checkbox-${id}`),
).not.toBeInTheDocument());
// AnonymousPostingFields
expect(
container.querySelector('#allowAnonymousPostsPeers'),
).toBeInTheDocument();
expect(
container.querySelector('#allowAnonymousPostsPeers'),
).not.toBeChecked();
// ReportedContentEmailNotifications
expect(container.querySelector('#reportedContentEmailNotifications')).toBeInTheDocument();
expect(container.querySelector('#reportedContentEmailNotifications')).toBeChecked();
});
test('folded discussion topics are in the DOM when divideByCohorts and divideCourseWideTopics are enabled',
async () => {
await mockStore({
...legacyApiResponse,
plugin_configuration: {
...legacyApiResponse.plugin_configuration,
allow_anonymous: true,
reported_content_email_notifications: true,
reported_content_email_notifications_flag: true,
always_divide_inline_discussions: true,
divided_course_wide_discussions: ['13f106c6-6735-4e84-b097-0456cff55960', 'course'],
},
});
createComponent();
const { divideDiscussionIds } = defaultAppConfig(['13f106c6-6735-4e84-b097-0456cff55960', 'course']);
// DivisionByGroupFields
expect(container.querySelector('#divideByCohorts')).toBeInTheDocument();
expect(container.querySelector('#divideByCohorts')).toBeChecked();
expect(container.querySelector('#divideCourseTopicsByCohorts')).toBeInTheDocument();
expect(container.querySelector('#divideCourseTopicsByCohorts')).toBeChecked();
divideDiscussionIds.forEach(id => {
expect(container.querySelector(`#checkbox-${id}`)).toBeInTheDocument();
expect(container.querySelector(`#checkbox-${id}`)).toBeChecked();
});
});
const updateTopicName = async (topicId, topicName) => {
const topicCard = queryByTestId(container, topicId);
await act(async () => { userEvent.click(queryByLabelText(topicCard, 'Expand')); });
const topicInput = topicCard.querySelector('input');
topicInput.focus();
await act(async () => { fireEvent.change(topicInput, { target: { value: topicName } }); });
topicInput.blur();
return topicCard;
};
const assertTopicNameRequiredValidation = (topicCard, expectExists = true) => {
const error = queryByText(topicCard, messages.discussionTopicRequired.defaultMessage);
if (expectExists) { expect(error).toBeInTheDocument(); } else { expect(error).not.toBeInTheDocument(); }
};
const assertDuplicateTopicNameValidation = async (topicCard, expectExists = true) => {
const error = queryByText(topicCard, messages.discussionTopicNameAlreadyExist.defaultMessage);
if (expectExists) { expect(error).toBeInTheDocument(); } else { expect(error).not.toBeInTheDocument(); }
};
const assertHasErrorValidation = (expectExists = true) => {
expect(store.getState().discussions.hasValidationError).toBe(expectExists);
};
test('show required error on field when leaving empty topic name',
async () => {
await mockStore(legacyApiResponse);
createComponent();
const topicCard = await updateTopicName('13f106c6-6735-4e84-b097-0456cff55960', '');
await waitForElementToBeRemoved(queryByText(topicCard, messages.addTopicHelpText.defaultMessage));
assertTopicNameRequiredValidation(topicCard);
assertHasErrorValidation();
});
test('check field is not collapsible in case of error', async () => {
await mockStore(legacyApiResponse);
createComponent();
const topicCard = await updateTopicName('13f106c6-6735-4e84-b097-0456cff55960', '');
const collapseButton = queryByLabelText(topicCard, 'Collapse');
await act(async () => userEvent.click(collapseButton));
expect(collapseButton).toBeInTheDocument();
});
describe('Duplicate validation test cases', () => {
let topicCard;
let duplicateTopicCard;
beforeEach(async () => {
await mockStore(legacyApiResponse);
createComponent();
topicCard = await updateTopicName('course', 'edx');
duplicateTopicCard = await updateTopicName('13f106c6-6735-4e84-b097-0456cff55960', 'EDX');
});
test('show duplicate errors on fields when passing duplicate topic name', async () => {
await assertDuplicateTopicNameValidation(topicCard);
await assertDuplicateTopicNameValidation(duplicateTopicCard);
assertHasErrorValidation();
});
test('check duplicate error is removed on fields when name is fixed', async () => {
const duplicateTopicInput = duplicateTopicCard.querySelector('input');
duplicateTopicInput.focus();
await act(async () => { userEvent.type(duplicateTopicInput, 'valid'); });
duplicateTopicInput.blur();
await waitForElementToBeRemoved(
queryAllByText(topicCard, messages.discussionTopicNameAlreadyExist.defaultMessage),
);
await assertDuplicateTopicNameValidation(duplicateTopicCard, false);
await assertDuplicateTopicNameValidation(topicCard, false);
assertHasErrorValidation(false);
});
test('check duplicate error is removed on deleting duplicate topic', async () => {
await act(async () => {
userEvent.click(
queryByLabelText(duplicateTopicCard, messages.deleteAltText.defaultMessage, { selector: 'button' }),
);
});
await act(async () => {
userEvent.click(
queryByRole(container, 'button', { name: messages.deleteButton.defaultMessage }),
);
});
await waitForElementToBeRemoved(queryByText(topicCard, messages.discussionTopicNameAlreadyExist.defaultMessage));
expect(duplicateTopicCard).not.toBeInTheDocument();
await assertDuplicateTopicNameValidation(topicCard, false);
assertHasErrorValidation(false);
});
});
});
Example #28
Source File: DiscussionTopics.test.jsx From frontend-app-course-authoring with GNU Affero General Public License v3.0 | 4 votes |
describe('DiscussionTopics', () => {
let axiosMock;
let store;
let container;
beforeEach(() => {
initializeMockApp({
authenticatedUser: {
userId: 3,
username: 'abc123',
administrator: true,
roles: [],
},
});
axiosMock = new MockAdapter(getAuthenticatedHttpClient());
store = initializeStore();
});
afterEach(() => {
axiosMock.reset();
});
const createComponent = (data) => {
const wrapper = render(
<AppProvider store={store}>
<IntlProvider locale="en">
<OpenedXConfigFormProvider value={contextValue}>
<Formik initialValues={data}>
<DiscussionTopics />
</Formik>
</OpenedXConfigFormProvider>
</IntlProvider>
</AppProvider>,
);
container = wrapper.container;
};
const mockStore = async (mockResponse) => {
axiosMock.onGet(getDiscussionsProvidersUrl(courseId)).reply(200, mockResponse);
await executeThunk(fetchProviders(courseId), store.dispatch);
};
test('renders each discussion topic correctly', async () => {
await mockStore(legacyApiResponse);
createComponent(appConfig);
await waitFor(() => {
expect(queryAllByTestId(container, 'course')).toHaveLength(1);
expect(queryAllByTestId(container, '13f106c6-6735-4e84-b097-0456cff55960')).toHaveLength(1);
});
});
test('renders discussion topic heading, label and helping text', async () => {
await mockStore(legacyApiResponse);
createComponent(appConfig);
await waitFor(() => {
expect(queryByText(container, messages.discussionTopics.defaultMessage)).toBeInTheDocument();
expect(queryByText(container, messages.discussionTopicsLabel.defaultMessage)).toBeInTheDocument();
expect(queryByText(container, messages.discussionTopicsHelp.defaultMessage)).toBeInTheDocument();
});
});
test('add topic button is rendered correctly', async () => {
await mockStore(legacyApiResponse);
createComponent(appConfig);
await waitFor(() => {
expect(queryByText(container, messages.addTopicButton.defaultMessage, { selector: 'button' }))
.toBeInTheDocument();
});
});
test('calls "onClick" callback when add topic button is clicked', async () => {
await mockStore(legacyApiResponse);
createComponent(appConfig);
const addTopicButton = queryByText(container, messages.addTopicButton.defaultMessage, { selector: 'button' });
await waitFor(async () => {
expect(queryByText(container, messages.configureAdditionalTopic.defaultMessage)).not.toBeInTheDocument();
await act(async () => fireEvent.click(addTopicButton));
expect(queryByText(container, messages.configureAdditionalTopic.defaultMessage)).toBeInTheDocument();
});
});
test('updates discussion topic name', async () => {
await mockStore(legacyApiResponse);
createComponent(appConfig);
const topicCard = queryByTestId(container, '13f106c6-6735-4e84-b097-0456cff55960');
await act(async () => userEvent.click(queryByLabelText(topicCard, 'Expand')));
await act(async () => {
fireEvent.change(topicCard.querySelector('input'), { target: { value: 'new name' } });
});
await act(async () => userEvent.click(queryByLabelText(topicCard, 'Collapse')));
expect(queryByText(topicCard, 'new name')).toBeInTheDocument();
});
});
Example #29
Source File: TopicItem.test.jsx From frontend-app-course-authoring with GNU Affero General Public License v3.0 | 4 votes |
describe('TopicItem', () => {
let axiosMock;
let store;
let container;
beforeEach(() => {
initializeMockApp({
authenticatedUser: {
userId: 3,
username: 'abc123',
administrator: true,
roles: [],
},
});
axiosMock = new MockAdapter(getAuthenticatedHttpClient());
store = initializeStore();
});
afterEach(() => {
axiosMock.reset();
});
const createComponent = (props) => {
const wrapper = render(
<AppProvider store={store}>
<IntlProvider locale="en">
<Formik initialValues={appConfig}>
<TopicItem {...props} />
</Formik>
</IntlProvider>
</AppProvider>,
);
container = wrapper.container;
};
const mockStore = async (mockResponse) => {
axiosMock.onGet(getDiscussionsProvidersUrl(courseId)).reply(200, mockResponse);
await executeThunk(fetchProviders(courseId), store.dispatch);
};
test('displays a collapsible card for discussion topic', async () => {
await mockStore(legacyApiResponse);
createComponent(generalTopic);
expect(queryAllByTestId(container, 'course')).toHaveLength(1);
});
test('displays collapse view of general discussion topic', async () => {
await mockStore(legacyApiResponse);
createComponent(generalTopic);
const generalTopicNode = queryByTestId(container, 'course');
expect(queryByLabelText(generalTopicNode, 'Expand')).toBeInTheDocument();
expect(queryByLabelText(generalTopicNode, 'Collapse')).not.toBeInTheDocument();
expect(queryByText(generalTopicNode, 'General')).toBeInTheDocument();
});
test('displays expand view of general discussion topic', async () => {
await mockStore(legacyApiResponse);
createComponent(generalTopic);
const generalTopicNode = queryByTestId(container, 'course');
userEvent.click(queryByLabelText(generalTopicNode, 'Expand'));
expect(queryByLabelText(generalTopicNode, 'Expand')).not.toBeInTheDocument();
expect(queryByLabelText(generalTopicNode, 'Collapse')).toBeInTheDocument();
expect(queryByRole(generalTopicNode, 'button', { name: 'Delete Topic' })).not.toBeInTheDocument();
expect(generalTopicNode.querySelector('input')).toBeInTheDocument();
});
test('displays expand view of additional discussion topic', async () => {
await mockStore(legacyApiResponse);
createComponent(additionalTopic);
const topicCard = queryByTestId(container, '13f106c6-6735-4e84-b097-0456cff55960');
userEvent.click(queryByLabelText(topicCard, 'Expand'));
expect(queryByLabelText(topicCard, 'Expand')).not.toBeInTheDocument();
expect(queryByLabelText(topicCard, 'Collapse')).toBeInTheDocument();
expect(queryByRole(topicCard, 'button', { name: 'Delete Topic' })).toBeInTheDocument();
expect(topicCard.querySelector('input')).toBeInTheDocument();
});
test('renders delete topic popup with providerName, label, helping text, a delete and a cancel button', async () => {
await mockStore(legacyApiResponse);
createComponent(additionalTopic);
const topicCard = queryByTestId(container, '13f106c6-6735-4e84-b097-0456cff55960');
userEvent.click(queryByLabelText(topicCard, 'Expand'));
userEvent.click(queryByRole(topicCard, 'button', { name: 'Delete Topic' }));
expect(queryAllByText(container, messages.discussionTopicDeletionLabel.defaultMessage)).toHaveLength(1);
expect(queryByText(container, messages.discussionTopicDeletionLabel.defaultMessage)).toBeInTheDocument();
expect(queryByText(container, messages.discussionTopicDeletionHelp.defaultMessage)).toBeInTheDocument();
expect(queryByText(container, messages.discussionTopicDeletionHelp.defaultMessage)).toBeInTheDocument();
expect(queryByText(container, messages.deleteButton.defaultMessage)).toBeInTheDocument();
expect(queryByText(container, messages.cancelButton.defaultMessage)).toBeInTheDocument();
});
test('shows help text on field focus', async () => {
await mockStore(legacyApiResponse);
createComponent(additionalTopic);
const topicCard = queryByTestId(container, '13f106c6-6735-4e84-b097-0456cff55960');
userEvent.click(queryByLabelText(topicCard, 'Expand'));
topicCard.querySelector('input').focus();
expect(queryByText(topicCard, messages.addTopicHelpText.defaultMessage)).toBeInTheDocument();
});
});