Skip to content

Commit

Permalink
fix: display required indicator only for non-empty labels and Improve…
Browse files Browse the repository at this point in the history
… test structure (#762)

* Show required sign only if label is valid

* Better func names & consistent return type

* Use assert instead of throw error

* Consistent tests description

* Remove unecessary code

* Add correct version number

* Update changelog, add thirdparty example

* Minor fox

* Read from testContext

* Refactor tests to ensure its easy to maintain different configurations

* Update third party tests

* Clean up

* Minor copy update

* Trim the label text

* Add build

* Handle if label is not supplied

* Highlight var in changelog, minor update

* Update custom payload to test for trimmed-version label
  • Loading branch information
amitbadala authored Nov 20, 2023
1 parent b43bf9b commit 45dd28c
Show file tree
Hide file tree
Showing 12 changed files with 161 additions and 148 deletions.
43 changes: 39 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html)

## [0.36.0] - 2023-10-30
## [0.35.7] - 2023-11-16

### Added

- Introduced the capability to utilize custom components in the Email-Password based recipes' signup form fields by exposing inputComponent types.
- Implemented the functionality to assign default values to the form fields in the Email-Password based recipes.
- Simplified onChange prop usage in inputComponent - id attribute removed.
- EmailPassword and ThirdPartyEmailPassword recipe enhancements:
- Introduced the capability to utilize custom components by exposing `inputComponent` types.
- Allow setting default values in signup/signin form fields.
- Made the `onChange` prop in `inputComponent` simpler by removing the need for an `id` attribute.
- Added a feature to customize the "Field is not optional" error message for each form field with the `nonOptionalErrorMsg` prop.

Following is an example of how to use above features.

Expand All @@ -24,6 +26,7 @@ EmailPassword.init({
id: "select-dropdown",
label: "Select Option",
getDefaultValue: () => "option 2",
nonOptionalErrorMsg: "Select dropdown is required",
inputComponent: ({ value, name, onChange }) => (
<select
value={value}
Expand All @@ -43,6 +46,38 @@ EmailPassword.init({
},
},
});

ThirdPartyEmailPassword.init({
signInAndUpFeature: {
signUpForm: {
formFields: [
{
id: "terms",
label: "",
optional: false,
getDefaultValue: () => "true",
nonOptionalErrorMsg: "You must accept the terms and conditions",
inputComponent: ({ name, onChange, value }) => (
<div
style={{
display: "flex",
alignItems: "center",
justifyContent: "left",
}}>
<input
value={value}
checked={value === "true"}
name={name}
type="checkbox"
onChange={(e) => onChange(e.target.checked.toString())}></input>
<span style={{ marginLeft: 5 }}>I agree to the terms and conditions</span>
</div>
),
},
],
},
},
});
```

## [0.35.6] - 2023-10-16
Expand Down
70 changes: 35 additions & 35 deletions examples/for-tests/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ const customFields = [
},
{
id: "terms",
label: "",
label: " ",
optional: false,
nonOptionalErrorMsg: "You must accept the terms and conditions",
inputComponent: ({ name, onChange }) => (
Expand Down Expand Up @@ -713,32 +713,29 @@ function getEmailVerificationConfigs({ disableDefaultUI }) {
});
}

function getFormFields() {
if (localStorage.getItem("SHOW_INCORRECT_FIELDS") === "YES") {
if (localStorage.getItem("INCORRECT_ONCHANGE") === "YES") {
// since page-error blocks all the other errors
// use this filter to test specific error
function getSignUpFormFields(formType) {
switch (formType) {
case "INCORRECT_FIELDS":
return incorrectFormFields;
case "INCORRECT_ONCHANGE":
return incorrectFormFields.filter(({ id }) => id === "terms");
} else if (localStorage.getItem("INCORRECT_NON_OPTIONAL_ERROR_MSG") === "YES") {
case "INCORRECT_NON_OPTIONAL_ERROR_MSG":
return incorrectFormFields.filter(({ id }) => id === "city");
} else if (localStorage.getItem("INCORRECT_GETDEFAULT") === "YES") {
case "INCORRECT_GETDEFAULT":
return incorrectFormFields.filter(({ id }) => id === "country");
}
return incorrectFormFields;
} else if (localStorage.getItem("SHOW_CUSTOM_FIELDS_WITH_DEFAULT_VALUES") === "YES") {
return formFieldsWithDefault;
} else if (localStorage.getItem("SHOW_CUSTOM_FIELDS") === "YES") {
return customFields;
case "CUSTOM_FIELDS_WITH_DEFAULT_VALUES":
return formFieldsWithDefault;
case "CUSTOM_FIELDS":
return customFields;
default:
return formFields;
}
return formFields;
}

function getSignInFormFields() {
let showDefaultFields = localStorage.getItem("SHOW_SIGNIN_DEFAULT_FIELDS");
let showFieldsWithNonOptionalErrMsg = localStorage.getItem("SHOW_SIGNIN_WITH_NON_OPTIONAL_ERROR_MESSAGE");
if (showDefaultFields === "YES") {
return {
formFields: [
function getSignInFormFields(formType) {
switch (formType) {
case "DEFAULT_FIELDS":
return [
{
id: "email",
getDefaultValue: () => "[email protected]",
Expand All @@ -747,22 +744,20 @@ function getSignInFormFields() {
id: "password",
getDefaultValue: () => "fakepassword123",
},
],
};
} else if (showFieldsWithNonOptionalErrMsg === "YES") {
return {
formFields: [
];
case "FIELDS_WITH_NON_OPTIONAL_ERROR_MESSAGE":
return [
{
id: "email",
nonOptionalErrorMsg: "Please add email",
},
],
};
];
default:
return;
}
return {};
}

function getEmailPasswordConfigs({ disableDefaultUI }) {
function getEmailPasswordConfigs({ disableDefaultUI, formFieldType }) {
return EmailPassword.init({
style: `
[data-supertokens~=container] {
Expand Down Expand Up @@ -842,13 +837,13 @@ function getEmailPasswordConfigs({ disableDefaultUI }) {
defaultToSignUp,
signInForm: {
style: theme,
...getSignInFormFields(),
formFields: getSignInFormFields(formFieldType.signIn),
},
signUpForm: {
style: theme,
privacyPolicyLink: "https://supertokens.com/legal/privacy-policy",
termsOfServiceLink: "https://supertokens.com/legal/terms-and-conditions",
formFields: getFormFields(),
formFields: getSignUpFormFields(formFieldType.signUp),
},
},
});
Expand Down Expand Up @@ -1192,7 +1187,12 @@ function getThirdPartyConfigs({ staticProviderList, disableDefaultUI, thirdParty
});
}

function getThirdPartyEmailPasswordConfigs({ staticProviderList, disableDefaultUI, thirdPartyRedirectURL }) {
function getThirdPartyEmailPasswordConfigs({
staticProviderList,
disableDefaultUI,
thirdPartyRedirectURL,
formFieldType,
}) {
let providers = [
ThirdParty.Github.init(),
ThirdParty.Google.init(),
Expand Down Expand Up @@ -1372,10 +1372,10 @@ function getThirdPartyEmailPasswordConfigs({ staticProviderList, disableDefaultU
signInAndUpFeature: {
disableDefaultUI,
signInForm: {
...getSignInFormFields(),
formFields: getSignInFormFields(formFieldType.signIn),
},
signUpForm: {
formFields: getFormFields(),
formFields: getSignUpFormFields(formFieldType.signUp),
privacyPolicyLink: "https://supertokens.com/legal/privacy-policy",
termsOfServiceLink: "https://supertokens.com/legal/terms-and-conditions",
},
Expand Down
4 changes: 4 additions & 0 deletions examples/for-tests/src/testContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ export function getTestContext() {
staticProviderList: localStorage.getItem("staticProviderList"),
mockTenantId: localStorage.getItem("mockTenantId"),
clientType: localStorage.getItem("clientType") || undefined,
formFieldType: {
signIn: localStorage.getItem("SIGNIN_SETTING_TYPE"),
signUp: localStorage.getItem("SIGNUP_SETTING_TYPE"),
},
};
return ret;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/build/emailpassword-shared7.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/build/version.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/ts/recipe/emailpassword/components/library/label.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export default function Label({ value, showIsRequired }: LabelProps): JSX.Elemen
return (
<div data-supertokens="label">
{t(value)}
{showIsRequired && " *"}
{showIsRequired && value && value.trim() !== "" && " *"}
</div>
);
}
2 changes: 1 addition & 1 deletion lib/ts/version.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@
* License for the specific language governing permissions and limitations
* under the License.
*/
export const package_version = "0.36.0";
export const package_version = "0.35.7";
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "supertokens-auth-react",
"version": "0.36.0",
"version": "0.35.7",
"description": "ReactJS SDK that provides login functionality with SuperTokens.",
"main": "./index.js",
"engines": {
Expand Down
38 changes: 11 additions & 27 deletions test/end-to-end/signin.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -671,9 +671,9 @@ describe("SuperTokens SignIn", function () {
});
});

describe("SignIn default field tests", function () {
describe("Default fields", function () {
it("Should contain email and password fields prefilled", async function () {
await page.evaluate(() => window.localStorage.setItem("SHOW_SIGNIN_DEFAULT_FIELDS", "YES"));
await page.evaluate(() => window.localStorage.setItem("SIGNIN_SETTING_TYPE", "DEFAULT_FIELDS"));

await page.reload({
waitUntil: "domcontentloaded",
Expand All @@ -694,7 +694,7 @@ describe("SuperTokens SignIn", function () {
});

it("Should have default values in the signin request payload", async function () {
await page.evaluate(() => window.localStorage.setItem("SHOW_SIGNIN_DEFAULT_FIELDS", "YES"));
await page.evaluate(() => window.localStorage.setItem("SIGNIN_SETTING_TYPE", "DEFAULT_FIELDS"));

await page.reload({
waitUntil: "domcontentloaded",
Expand All @@ -714,11 +714,8 @@ describe("SuperTokens SignIn", function () {
const postData = JSON.parse(request.postData());
expectedDefautlValues.forEach(({ id, value }) => {
let findFormData = postData.formFields.find((inputData) => inputData.id === id);
if (findFormData) {
assert.strictEqual(findFormData["value"], value, `Mismatch in payload for key: ${id}`);
} else {
throw new Error("Field not found in req.data");
}
assert.ok(findFormData, "Field not found in req.data");
assert.strictEqual(findFormData["value"], value, `Mismatch in payload for key: ${id}`);
});
interceptionPassed = true;
return request.respond({
Expand Down Expand Up @@ -748,24 +745,16 @@ describe("SuperTokens SignIn", function () {
page.off("request", requestHandler);
await page.setRequestInterception(false);
}

if (assertionError) {
throw assertionError;
}

if (!interceptionPassed) {
throw new Error("test failed");
}
assert.ok(!assertionError, assertionError?.message);
assert.ok(interceptionPassed, "Test Failed");
});
});

describe("Check if nonOptionalErrorMsg works as expected", function () {
it("Check on blank form submit nonOptionalErrorMsg gets displayed as expected", async function () {
await page.evaluate(() => localStorage.removeItem("SHOW_SIGNIN_DEFAULT_FIELDS"));

describe("nonOptionalErrorMsg", function () {
it("Should be displayed on a blank form submit", async function () {
// set cookie and reload which loads the form with custom field
await page.evaluate(() =>
window.localStorage.setItem("SHOW_SIGNIN_WITH_NON_OPTIONAL_ERROR_MESSAGE", "YES")
window.localStorage.setItem("SIGNIN_SETTING_TYPE", "FIELDS_WITH_NON_OPTIONAL_ERROR_MESSAGE")
);
await page.reload({
waitUntil: "domcontentloaded",
Expand All @@ -782,8 +771,6 @@ describe("SuperTokens SignIn", function () {
request.continue();
}
};

await page.setRequestInterception(true);
page.on("request", requestHandler);

try {
Expand All @@ -794,12 +781,9 @@ describe("SuperTokens SignIn", function () {
assert.deepStrictEqual(formFieldErrors, ["Please add email", "Field is not optional"]);
} finally {
page.off("request", requestHandler);
await page.setRequestInterception(false);
}

if (apiCallMade) {
throw new Error("Empty form making API request to signin");
}
assert.ok(!apiCallMade, "Empty form making API request to signin");
});
});
});
Expand Down
Loading

0 comments on commit 45dd28c

Please sign in to comment.