Skip to content

Commit

Permalink
Add config option to create to control whether a new option is select…
Browse files Browse the repository at this point in the history
…ed or not

If the creation of the new option in production code is dependent on some other service--like inserting the new option in a database--there is a potential for that operation to fail.  When writing a unit test to verify how that failure is handled, it may not be desirable to select the new option given to `create` if the insert into the database failed.

This commit introduces a new option in the `CreateConfig` object called `autoSelect` that will enable or disable the automatic selection of the new option.

See issue #35 for more details.
  • Loading branch information
fgs-dbudwin committed Jul 23, 2020
1 parent b115858 commit 7ec3873
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 6 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ expect(getByRole("form")).toHaveFormValues({ food: "papaya" });
`create` take an optional `config` parameter:

- `config.createOptionText` can be used when [creating elements with a custom label text, using the `formatCreateLabel` prop](https://react-select.com/props#creatable-props).
- `config.autoSelect` is used to automatically select the newly created option, it defaults to `true`.
- `config.container` can be used when the `react-select` dropdown is rendered in a portal using `menuPortalTarget`.

### `clearFirst(input: HTMLElement): Promise<void>`
Expand Down
24 changes: 23 additions & 1 deletion src/__tests__/select-event.test.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import "@testing-library/jest-dom/extend-expect";

import { fireEvent, render } from "@testing-library/react";

import React from "react";
import { render, fireEvent } from "@testing-library/react";
import Select from "react-select";
import selectEvent from "..";

let Async: any;
let Creatable: any;
let AsyncCreatable: any;
Expand Down Expand Up @@ -124,6 +127,13 @@ describe("The select event helpers", () => {
expect(form).toHaveFormValues({ food: "papaya" });
});

it("types in and adds a new option but does not select it by default", async () => {
const { form, input } = renderForm(<Creatable {...defaultProps} />);
expect(form).toHaveFormValues({ food: "" });
await selectEvent.create(input, "papaya", { autoSelect: false });
expect(form).toHaveFormValues({ food: "" });
});

it("types in and adds a new option with custom create label when searching by fixed string", async () => {
const { form, input } = renderForm(
<Creatable {...defaultProps} formatCreateLabel={() => "Add new option"} />
Expand Down Expand Up @@ -377,6 +387,18 @@ describe("The select event helpers", () => {
expect(form).toHaveFormValues({ food: "papaya" });
});

it("types in and adds a new option but does not select it by default", async () => {
const { form, input } = renderForm(
<Creatable {...defaultProps} menuPortalTarget={document.body} />
);
expect(form).toHaveFormValues({ food: "" });
await selectEvent.create(input, "papaya", {
autoSelect: false,
container: document.body,
});
expect(form).toHaveFormValues({ food: "" });
});

it("clears the first item in a multi-select dropdown", async () => {
const { form, input } = renderForm(
<Creatable
Expand Down
14 changes: 9 additions & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/** Simulate user events on react-select dropdowns */

import {
fireEvent,
findByText,
findAllByText,
findByText,
fireEvent,
waitFor,
} from "@testing-library/dom";

Expand Down Expand Up @@ -84,6 +84,7 @@ export const select = async (
};

interface CreateConfig extends Config {
autoSelect?: boolean;
createOptionText?: string | RegExp;
}
/**
Expand All @@ -94,21 +95,24 @@ interface CreateConfig extends Config {
* @param {Object} config Optional config options
* @param {HTMLElement} config.container A container for the react-select and its dropdown (defaults to the react-select container)
* Useful when rending the dropdown to a portal using react-select's `menuPortalTarget`
* @param {boolean} config.autoSelect Whether to automatically select the newly created option or not
* @param {String|RegExp} config.createOptionText Custom label for the "create new ..." option in the menu (string or regexp)
*/
export const create = async (
input: HTMLElement,
option: string,
config: CreateConfig = {}
{ autoSelect = true, ...config }: CreateConfig = {}
) => {
const createOptionText = config.createOptionText || /^Create "/;
openMenu(input);
type(input, option);

fireEvent.change(input, { target: { value: option } });
await select(input, createOptionText, config);

await findByText(getReactSelectContainerFromInput(input), option);
if (autoSelect) {
await select(input, createOptionText, config);
await findByText(getReactSelectContainerFromInput(input), option);
}
};

/**
Expand Down

0 comments on commit 7ec3873

Please sign in to comment.