it("should let you favorite and unfavorite dashboards", async () => { const store = await createTestStore(); store.pushPath("/dashboards"); const app = mount(store.getAppContainer()); await store.waitForActions([FETCH_DASHBOARDS]); click( app .find(DashboardListItem) .first() .find(".Icon-staroutline"), ); await store.waitForActions([SET_FAVORITED]); click(app.find(ListFilterWidget)); click(app.find(".TestPopover").find('h4[children="Favorites"]')); click( app .find(DashboardListItem) .first() .find(".Icon-star") .first(), ); await store.waitForActions([SET_FAVORITED]); expect(app.find(EmptyState).length).toBe(1); });
it("forces you to choose the FK field manually if there is no field with Field Name special type", async () => { const { store, fieldApp } = await initFieldApp({ fieldId: USER_ID_FK_ID }); // Set FK id to `Reviews -> ID` with a direct metadata update call const field = getMetadata(store.getState()).fields[USER_ID_FK_ID] await store.dispatch(updateField({ ...field.getPlainObject(), fk_target_field_id: 31 })); const section = fieldApp.find(FieldRemapping) const mappingTypePicker = section.find(Select); expect(mappingTypePicker.text()).toBe('Use original value') click(mappingTypePicker); const pickerOptions = mappingTypePicker.find(TestPopover).find("li"); expect(pickerOptions.length).toBe(2); const useFKButton = pickerOptions.at(1).children().first() click(useFKButton); store.waitForActions([UPDATE_FIELD_DIMENSION, FETCH_TABLE_METADATA]) // TODO: Figure out a way to avoid using delay – the use of delays may lead to occasional CI failures await delay(500); expect(section.find(RemappingNamingTip).length).toBe(1) dispatchBrowserEvent('mousedown', { e: { target: document.documentElement }}) await delay(300); // delay needed because of setState in FieldApp; app.update() does not work for whatever reason expect(section.find(".text-danger").length).toBe(1) // warning that you should choose a column })
it("lets you open and close the revisions screen", async () => { if (!dashboardId) throw new Error( "Test fails because previous tests failed to create a dashboard", ); const store = await createTestStore(); const dashboardUrl = Urls.dashboard(dashboardId); store.pushPath(dashboardUrl); const app = mount(store.getAppContainer()); await store.waitForActions([FETCH_DASHBOARD]); click(app.find(".Icon.Icon-pencil")); await store.waitForActions([SET_EDITING_DASHBOARD]); click(app.find(".Icon.Icon-history")); await store.waitForActions([FETCH_REVISIONS]); const modal = app.find(DashboardHistoryModal); expect(modal.length).toBe(1); expect(store.getPath()).toBe(`${dashboardUrl}/history`); click(modal.find(".Icon.Icon-close")); await store.waitForActions([BROWSER_HISTORY_PUSH]); expect(store.getPath()).toBe(`/dashboard/${dashboardId}`); });
it("should show you scheduling step if you select \"Let me choose when Metabase syncs and scans\"", async () => { // we can conveniently test returning to database settings now as well const connectionStep = app.find(DatabaseConnectionStep) click(connectionStep.find("h3")) expect(connectionStep.find('.SetupStep--active').length).toBe(1) const letUserControlSchedulingToggle = connectionStep .find(FormField) .filterWhere((f) => f.props().fieldName === "let-user-control-scheduling") .find(Toggle); expect(letUserControlSchedulingToggle.length).toBe(1); expect(letUserControlSchedulingToggle.prop('value')).toBe(false); click(letUserControlSchedulingToggle); expect(letUserControlSchedulingToggle.prop('value')).toBe(true); const nextButton = connectionStep.find('button[children="Next"]') clickButton(nextButton); await store.waitForActions([SET_DATABASE_DETAILS]) const schedulingStep = app.find(DatabaseSchedulingStep); expect(schedulingStep.find('.SetupStep--active').length).toBe(1) // disable the deep analysis const syncOptions = schedulingStep.find(SyncOption); const syncOptionsNever = syncOptions.at(1); click(syncOptionsNever) // proceed to tracking preferences step again const nextButton2 = schedulingStep.find('button[children="Next"]') clickButton(nextButton2); await store.waitForActions([SET_DATABASE_DETAILS]) })
it("lets you change to 'Use foreign key' and change the target for field with fk", async () => { const { store, fieldApp } = await initFieldApp({ fieldId: USER_ID_FK_ID }); const section = fieldApp.find(FieldRemapping) const mappingTypePicker = section.find(Select); expect(mappingTypePicker.text()).toBe('Use original value') click(mappingTypePicker); const pickerOptions = mappingTypePicker.find(TestPopover).find("li"); expect(pickerOptions.length).toBe(2); const useFKButton = pickerOptions.at(1).children().first() click(useFKButton); store.waitForActions([UPDATE_FIELD_DIMENSION, FETCH_TABLE_METADATA]) // TODO: Figure out a way to avoid using delay – the use of delays may lead to occasional CI failures await delay(500); const fkFieldSelect = section.find(SelectButton); expect(fkFieldSelect.text()).toBe("Name"); click(fkFieldSelect); const sourceField = fkFieldSelect.parent().find(TestPopover) .find(".List-item") .filterWhere(li => /Source/.test(li.text())) .first().children().first(); click(sourceField) store.waitForActions([FETCH_TABLE_METADATA]) // TODO: Figure out a way to avoid using delay – the use of delays may lead to occasional CI failures await delay(500); expect(fkFieldSelect.text()).toBe("Source"); })
it("it should render the proper configuration form", async () => { const store = await createTestStore(); store.pushPath("/admin/settings"); const app = mount(store.getAppContainer()); await store.waitForActions([INITIALIZE_SETTINGS]); const settingsWrapper = app.find(SettingsEditorApp); const authListItem = settingsWrapper.find( 'span[children="Authentication"]', ); click(authListItem); expect(settingsWrapper.find(SettingsAuthenticationOptions).length).toBe(1); // test google const googleConfigButton = settingsWrapper.find(".Button").first(); click(googleConfigButton); expect(settingsWrapper.find(SettingsSingleSignOnForm).length).toBe(1); store.goBack(); // test ldap const ldapConfigButton = settingsWrapper.find(".Button").last(); click(ldapConfigButton); expect(settingsWrapper.find(SettingsLdapForm).length).toBe(1); });
it("lets you start a question from a metric", async () => { useSharedNormalLogin() const store = await createTestStore() store.pushPath(Urls.newQuestion()); const app = mount(store.getAppContainer()); await store.waitForActions([DETERMINE_OPTIONS]); click(app.find(NewQueryOption).filterWhere((c) => c.prop('title') === "Metrics")) await store.waitForActions(FETCH_DATABASES); await store.waitForActions([SET_REQUEST_STATE]); expect(store.getPath()).toBe("/question/new/metric") const entitySearch = app.find(EntitySearch) const viewByCreator = entitySearch.find(SearchGroupingOption).last() expect(viewByCreator.text()).toBe("Creator"); click(viewByCreator) expect(store.getPath()).toBe("/question/new/metric?grouping=creator") const group = entitySearch.find(SearchResultsGroup) expect(group.prop('groupName')).toBe("Bobby Tables") const metricSearchResult = group.find(SearchResultListItem) .filterWhere((item) => /A Metric/.test(item.text())) click(metricSearchResult.childAt(0)) await store.waitForActions([INITIALIZE_QB, QUERY_COMPLETED]); await delay(100); // Trying to address random CI failures with a small delay expect( app.find(AggregationWidget).find(".View-section-aggregation").text() ).toBe("A Metric") })
async function runSharedQuestionTests(store, questionUrl, apiRegex) { store.pushPath(questionUrl); const app = mount(store.getAppContainer()) await store.waitForActions([ADD_PARAM_VALUES]); // Loading the query results is done in PublicQuestion itself so we have to listen to API request instead of Redux action await waitForRequestToComplete("GET", apiRegex) // use `update()` because of setState expect(app.update().find(Scalar).text()).toBe(COUNT_ALL + "sql parametrized"); // manually click parameter (sadly the query results loading happens inline again) click(app.find(Parameters).find("a").first()); click(app.find(CategoryWidget).find('li[children="Doohickey"]')); await waitForRequestToComplete("GET", apiRegex) expect(app.update().find(Scalar).text()).toBe(COUNT_DOOHICKEY + "sql parametrized"); // set parameter via url store.pushPath("/"); // simulate a page reload by visiting other page store.pushPath(questionUrl + "?category=Gadget"); await waitForRequestToComplete("GET", apiRegex) // use `update()` because of setState expect(app.update().find(Scalar).text()).toBe(COUNT_GADGET + "sql parametrized"); }
it("should show validation error if you enable scheduling toggle and enter invalid db connection info", async () => { MetabaseApi.db_create = async db => { await delay(10); return { ...db, id: 10 }; }; const store = await createTestStore(); store.pushPath("/admin/databases"); const app = mount(store.getAppContainer()); await store.waitForActions([FETCH_DATABASES]); const listAppBeforeAdd = app.find(DatabaseListApp); const addDbButton = listAppBeforeAdd .find(".Button.Button--primary") .first(); click(addDbButton); const dbDetailsForm = app.find(DatabaseEditApp); expect(dbDetailsForm.length).toBe(1); await store.waitForActions([INITIALIZE_DATABASE]); expect( dbDetailsForm.find('button[children="Save"]').props().disabled, ).toBe(true); const updateInputValue = (name, value) => setInputValue(dbDetailsForm.find(`input[name="${name}"]`), value); updateInputValue("name", "Test db name"); updateInputValue("dbname", "test_postgres_db"); updateInputValue("user", "uberadmin"); const letUserControlSchedulingField = dbDetailsForm .find(FormField) .filterWhere( f => f.props().fieldName === "let-user-control-scheduling", ); expect(letUserControlSchedulingField.length).toBe(1); expect(letUserControlSchedulingField.find(Toggle).props().value).toBe( false, ); click(letUserControlSchedulingField.find(Toggle)); const nextStepButton = dbDetailsForm.find('button[children="Next"]'); expect(nextStepButton.props().disabled).toBe(false); clickButton(nextStepButton); await store.waitForActions([ VALIDATE_DATABASE_STARTED, VALIDATE_DATABASE_FAILED, ]); expect(app.find(FormMessage).text()).toMatch( /Couldn't connect to the database./, ); });
it("lets you change field visibility", async () => { const { store, fieldApp } = await initFieldApp({ fieldId: CREATED_AT_ID }); const visibilitySelect = fieldApp.find(FieldVisibilityPicker); click(visibilitySelect); click(visibilitySelect.find(TestPopover).find("li").at(1).children().first()); await store.waitForActions([UPDATE_FIELD]) })
it("should load create pulse", async () => { store.pushPath("/pulse/create"); const app = mount(store.connectContainer(<PulseEditApp />)); await store.waitForActions([SET_EDITING_PULSE,FETCH_CARDS]); // no previews yet expect(app.find(PulseCardPreview).length).toBe(0) // set name to 'foo' setInputValue(app.find("input").first(), "foo") // email channel should be enabled expect(app.find(Toggle).first().props().value).toBe(true); // add count card app.find(CardPicker).first().props().onChange(questionCount.id()) await store.waitForActions([FETCH_PULSE_CARD_PREVIEW]); // add raw card app.find(CardPicker).first().props().onChange(questionRaw.id()) await store.waitForActions([FETCH_PULSE_CARD_PREVIEW]); let previews = app.find(PulseCardPreview); expect(previews.length).toBe(2) // NOTE: check text content since enzyme doesn't doesn't seem to work well with dangerouslySetInnerHTML expect(previews.at(0).text()).toBe("count12,805") expect(previews.at(0).find(".Icon-attachment").length).toBe(1) expect(previews.at(1).text()).toBe("tableThis question will be added as a file attachment") expect(previews.at(1).find(".Icon-attachment").length).toBe(0) // toggle email channel off click(app.find(Toggle).first()) previews = app.find(PulseCardPreview); expect(previews.at(0).text()).toBe("count12,805") expect(previews.at(0).find(".Icon-attachment").length).toBe(0) expect(previews.at(1).text()).toBe("tableThis question won't be included in your Pulse") expect(previews.at(1).find(".Icon-attachment").length).toBe(0) // toggle email channel on click(app.find(Toggle).first()) // save const saveButton = app.find(".PulseEdit-footer .Button").first(); expect(saveButton.hasClass("Button--primary")).toBe(true) click(saveButton) await store.waitForActions([SAVE_EDITING_PULSE]); const [pulse] = await PulseApi.list(); expect(pulse.name).toBe("foo"); expect(pulse.cards[0].id).toBe(questionCount.id()); expect(pulse.cards[1].id).toBe(questionRaw.id()); expect(pulse.channels[0].channel_type).toBe("email"); expect(pulse.channels[0].enabled).toBe(true); })
it("lets you disable the binning", async () => { const breakoutWidget = qb.find(BreakoutWidget).first(); click(breakoutWidget.find(FieldName).children().first()) const breakoutPopover = qb.find("#BreakoutPopover") const subtotalFieldButton = breakoutPopover.find(FieldList).find('.List-item--selected h4[children="100 bins"]') expect(subtotalFieldButton.length).toBe(1); click(subtotalFieldButton); click(qb.find(DimensionPicker).find('a[children="Don\'t bin"]')); });
it("lets you add ID field as a filter", async () => { const filterSection = qb.find('.GuiBuilder-filtered-by'); const addFilterButton = filterSection.find('.AddButton'); click(addFilterButton); const filterPopover = filterSection.find(FilterPopover); const ratingFieldButton = filterPopover.find(FieldList).find('h4[children="ID"]') expect(ratingFieldButton.length).toBe(1); click(ratingFieldButton) })
it("lets you change the type to 'No special type'", async () => { const { store, fieldApp } = await initFieldApp({ fieldId: CREATED_AT_ID }); const picker = fieldApp.find(SpecialTypeAndTargetPicker) const typeSelect = picker.find(Select).at(0) click(typeSelect); const noSpecialTypeButton = typeSelect.find(TestPopover).find("li").last().children().first() click(noSpecialTypeButton); await store.waitForActions([UPDATE_FIELD]) expect(picker.text()).toMatch(/Select a special type/); })
it("should properly increment and decrement object deteail", async () => { const store = await createTestStore(); const newQuestion = Question.create({ databaseId: 1, tableId: 1, metadata: getMetadata(store.getState()), }) .query() .addFilter(["=", ["field-id", 2], 2]) .question() .setDisplayName("Object Detail"); const savedQuestion = await createSavedQuestion(newQuestion); store.pushPath(savedQuestion.getUrl()); const app = mount(store.getAppContainer()); await store.waitForActions([INITIALIZE_QB, QUERY_COMPLETED]); await delay(100); // Trying to address random CI failures with a small delay expect(app.find(".ObjectDetail h1").text()).toEqual("2"); const previousObjectTrigger = app.find(".Icon.Icon-backArrow"); click(previousObjectTrigger); await store.waitForActions([QUERY_COMPLETED]); await delay(100); // Trying to address random CI failures with a small delay expect(app.find(".ObjectDetail h1").text()).toEqual("1"); const nextObjectTrigger = app.find(".Icon.Icon-forwardArrow"); click(nextObjectTrigger); await store.waitForActions([QUERY_COMPLETED]); await delay(100); // Trying to address random CI failures with a small delay expect(app.find(".ObjectDetail h1").text()).toEqual("2"); // test keyboard shortcuts // left arrow dispatchBrowserEvent("keydown", { key: "ArrowLeft" }); await store.waitForActions([QUERY_COMPLETED]); await delay(100); // Trying to address random CI failures with a small delay expect(app.find(".ObjectDetail h1").text()).toEqual("1"); // left arrow dispatchBrowserEvent("keydown", { key: "ArrowRight" }); await store.waitForActions([QUERY_COMPLETED]); await delay(100); // Trying to address random CI failures with a small delay expect(app.find(".ObjectDetail h1").text()).toEqual("2"); });
it("lets you switch back to Use original value after changing to some other value", async () => { const { store, fieldApp } = await initFieldApp({ fieldId: USER_ID_FK_ID }); const section = fieldApp.find(FieldRemapping) const mappingTypePicker = section.find(Select); expect(mappingTypePicker.text()).toBe('Use foreign key') click(mappingTypePicker); const pickerOptions = mappingTypePicker.find(TestPopover).find("li"); const useOriginalValue = pickerOptions.first().children().first() click(useOriginalValue); store.waitForActions([DELETE_FIELD_DIMENSION, FETCH_TABLE_METADATA]); })
it("lets you add Rating field as a filter", async () => { // TODO Atte Keinänen 7/13/17: Extracting GuiQueryEditor's contents to smaller React components // would make testing with selectors more natural const filterSection = qb.find('.GuiBuilder-filtered-by'); const addFilterButton = filterSection.find('.AddButton'); click(addFilterButton); const filterPopover = filterSection.find(FilterPopover); const ratingFieldButton = filterPopover.find(FieldList).find('h4[children="Rating"]') expect(ratingFieldButton.length).toBe(1); click(ratingFieldButton); })
it("should let you archive and unarchive dashboards", async () => { const store = await createTestStore(); store.pushPath("/dashboards") const app = mount(store.getAppContainer()); await store.waitForActions([FETCH_DASHBOARDS]) click(app.find(DashboardListItem).first().find(".Icon-archive")); await store.waitForActions([SET_ARCHIVED]) click(app.find(".Icon-viewArchive")) await store.waitForActions([FETCH_ARCHIVE]) expect(app.find(ArchivedItem).length).toBeGreaterThan(0) });
it("lets you change the binning strategy to 100 bins", async () => { const breakoutWidget = qb.find(BreakoutWidget).first(); click(breakoutWidget.find(FieldName).children().first()) const breakoutPopover = qb.find("#BreakoutPopover") const subtotalFieldButton = breakoutPopover.find(FieldList).find('.List-item--selected h4[children="Auto binned"]') expect(subtotalFieldButton.length).toBe(1); click(subtotalFieldButton) click(qb.find(DimensionPicker).find('a[children="100 bins"]')); await store.waitForActions([SET_DATASET_QUERY]) expect(breakoutWidget.text()).toBe("Total: 100 bins"); });
it("lets you group by Latitude with the 'Bin every 1 degree'", async () => { const breakoutWidget = qb.find(BreakoutWidget).first(); click(breakoutWidget.find(FieldName).children().first()) const breakoutPopover = qb.find("#BreakoutPopover") const subtotalFieldButton = breakoutPopover.find(FieldList).find('.List-item--selected h4[children="Auto binned"]') expect(subtotalFieldButton.length).toBe(1); click(subtotalFieldButton); click(qb.find(DimensionPicker).find('a[children="Bin every 1 degree"]')); await store.waitForActions([SET_DATASET_QUERY]) expect(breakoutWidget.text()).toBe("Latitude: 1°"); });
it("lets you group by Total with the default binning option", async () => { const breakoutSection = qb.find('.GuiBuilder-groupedBy'); const addBreakoutButton = breakoutSection.find('.AddButton'); click(addBreakoutButton); const breakoutPopover = breakoutSection.find("#BreakoutPopover") const subtotalFieldButton = breakoutPopover.find(FieldList).find('h4[children="Total"]') expect(subtotalFieldButton.length).toBe(1); click(subtotalFieldButton); await store.waitForActions([SET_DATASET_QUERY]) const breakoutWidget = qb.find(BreakoutWidget).first(); expect(breakoutWidget.text()).toBe("Total: Auto binned"); });
it("lets you change title and description", async () => { const name = "Customer Feedback Analysis"; const description = "For seeing the usual response times, feedback topics, our response rate, how often customers are directed to our knowledge base instead of providing a customized response"; // Create a dashboard programmatically const dashboard = await DashboardApi.create({ name, description }); dashboardId = dashboard.id; const store = await createTestStore(); store.pushPath(Urls.dashboard(dashboardId)); const app = mount(store.getAppContainer()); await store.waitForActions([FETCH_DASHBOARD]); // Test dashboard renaming click(app.find(".Icon.Icon-pencil")); await store.waitForActions([SET_EDITING_DASHBOARD]); const headerInputs = app.find(".Header-title input"); setInputValue(headerInputs.first(), "Customer Analysis Paralysis"); setInputValue(headerInputs.at(1), ""); clickButton(app.find(EditBar).find(".Button--primary.Button")); await store.waitForActions([SAVE_DASHBOARD_AND_CARDS, FETCH_DASHBOARD]); await delay(500); expect(app.find(DashboardHeader).text()).toMatch( /Customer Analysis Paralysis/, ); });
it("should not block deletes", async () => { MetabaseApi.db_delete = async () => await delay(10); const store = await createTestStore(); store.pushPath("/admin/databases"); const app = mount(store.getAppContainer()); await store.waitForActions([FETCH_DATABASES]); const wrapper = app.find(DatabaseListApp); const dbCount = wrapper.find("tr").length; const deleteButton = wrapper.find(".Button.Button--danger").first(); click(deleteButton); const deleteModal = wrapper.find(".test-modal"); setInputValue(deleteModal.find(".Form-input"), "DELETE"); clickButton(deleteModal.find(".Button.Button--danger")); // test that the modal is gone expect(wrapper.find(".test-modal").length).toEqual(0); // we should now have a disabled db row during delete expect(wrapper.find("tr.disabled").length).toEqual(1); // db delete finishes await store.waitForActions([DELETE_DATABASE]); // there should be no disabled db rows now expect(wrapper.find("tr.disabled").length).toEqual(0); // we should now have one database less in the list expect(wrapper.find("tr").length).toEqual(dbCount - 1); });
it("lets you remove the added filter", async () => { const filterWidget = qb.find(FilterWidget); click(filterWidget.find(".Icon-close")) await store.waitForActions([SET_DATASET_QUERY]) expect(qb.find(FilterWidget).length).toBe(0); })
it("lets you update the filter to 'ID is between 1 or 100'", async () => { const filterWidget = qb.find(FilterWidget); click(filterWidget.find(FieldName)) const filterPopover = qb.find(FilterPopover); const operatorSelector = filterPopover.find(OperatorSelector); clickButton(operatorSelector.find('button[children="Between"]')); const betweenInputs = filterPopover.find("textarea"); expect(betweenInputs.length).toBe(2); expect(betweenInputs.at(0).props().value).toBe("10, 11"); setInputValue(betweenInputs.at(1), "asdasd") const updateFilterButton = filterPopover.find('button[children="Update filter"]') expect(updateFilterButton.props().className).toMatch(/disabled/); setInputValue(betweenInputs.at(0), "1") setInputValue(betweenInputs.at(1), "100") clickButton(updateFilterButton); await store.waitForActions([SET_DATASET_QUERY]) expect(qb.find(FilterPopover).length).toBe(0); expect(filterWidget.text()).toBe("ID between1100"); });
it("shows metrics for the current table, excluding the retired ones", async () => { const url = Question.create({ databaseId: DATABASE_ID, tableId: ORDERS_TABLE_ID, metadata, }) .query() .question() .getUrl(); const store = await createTestStore(); store.pushPath(url); const app = mount(store.getAppContainer()); await store.waitForActions([ INITIALIZE_QB, QUERY_COMPLETED, LOAD_TABLE_METADATA, ]); const actionsWidget = app.find(ActionsWidget); click(actionsWidget.childAt(0)); expect(actionsWidget.find('strong[children="A Metric"]').length).toBe(1); });
it("should change the user's password to random password", async () => { expect.assertions(3); let newPassword; mock.get("/api/user/42", (req, res) => res.json({ id: 42, ...MOCK_USER }), ); mock.put("/api/user/42/password", (req, res) => { expect(Object.keys(req.json())).toEqual(["password"]); newPassword = req.json().password; return res.json({ id: 42, ...MOCK_USER }); }); const { wrapper } = mountWithStore( <UserPasswordResetModal params={{ userId: 42 }} />, ); const resetButton = await wrapper.async.find(".Button--danger"); expect(resetButton.length).toBe(1); clickButton(resetButton); const showPasswordLink = await wrapper.async.find(".link"); click(showPasswordLink); const passwordReveal = await wrapper.async.find("input"); expect(passwordReveal.props().value).toBe(newPassword); });
it("should let you create a dashboard when there are no existing dashboards", async () => { const store = await createTestStore(); store.pushPath("/dashboards"); const app = mount(store.getAppContainer()); await store.waitForActions([FETCH_DASHBOARDS]); // // Create a new dashboard in the empty state (EmptyState react component) click(app.find(".Button.Button--primary")); // click(app.find(".Icon.Icon-add")) const modal = app.find(CreateDashboardModal); setInputValue( modal.find('input[name="name"]'), "Customer Feedback Analysis", ); setInputValue( modal.find('input[name="description"]'), "For seeing the usual response times, feedback topics, our response rate, how often customers are directed to our knowledge base instead of providing a customized response", ); clickButton(modal.find(".Button--primary")); // should navigate to dashboard page await store.waitForActions(FETCH_DASHBOARD); expect(app.find(Dashboard).length).toBe(1); });
it("should advance through steps properly", () => { const wrapper = shallow(<NewUserOnboardingModal />); const nextButton = wrapper.find("a"); expect(wrapper.state().step).toEqual(1); click(nextButton); expect(wrapper.state().step).toEqual(2); });
it("lets you add 'Rating is Perfecto' filter", async () => { const { store, qb } = await initQBWithReviewsTable(); // open filter popover const filterSection = qb.find(".GuiBuilder-filtered-by"); const newFilterButton = filterSection.find(".AddButton"); click(newFilterButton); // choose the field to be filtered const filterPopover = filterSection.find(FilterPopover); const ratingFieldButton = filterPopover .find(FieldList) .find('h4[children="Rating Description"]'); expect(ratingFieldButton.length).toBe(1); click(ratingFieldButton); // check that field values seem correct const fieldItems = filterPopover.find("li"); expect(fieldItems.length).toBe(5); expect(fieldItems.first().text()).toBe("Awful"); expect(fieldItems.last().text()).toBe("Perfecto"); // select the last item (Perfecto) const widgetFieldItem = fieldItems.last(); const widgetCheckbox = widgetFieldItem.find(CheckBox); expect(widgetCheckbox.props().checked).toBe(false); click(widgetFieldItem.children().first()); expect(widgetCheckbox.props().checked).toBe(true); // add the filter const addFilterButton = filterPopover.find( 'button[children="Add filter"]', ); clickButton(addFilterButton); await store.waitForActions([SET_DATASET_QUERY]); // validate the filter text value expect(qb.find(FilterPopover).length).toBe(0); const filterWidget = qb.find(FilterWidget); expect(filterWidget.length).toBe(1); expect(filterWidget.text()).toBe( "Rating Description is equal toPerfecto", ); });