Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: display required indicator only for non-empty labels and Improve test structure #762

Merged
merged 18 commits into from
Nov 20, 2023
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.
- Email-Password and Third-Party Email Password Recipes Enhancements as follows:
- Introduced the capability to utilize custom components by exposing inputComponent types.
- Allow setting default values in signup/signin form fields.
- Made 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.
porcellus marked this conversation as resolved.
Show resolved Hide resolved

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
68 changes: 34 additions & 34 deletions examples/for-tests/src/App.js
Original file line number Diff line number Diff line change
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 [];
porcellus marked this conversation as resolved.
Show resolved Hide resolved
}
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() !== "" && " *"}
rishabhpoddar marked this conversation as resolved.
Show resolved Hide resolved
</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
Loading