mirror of
https://github.com/wassname/talk.git
synced 2026-07-25 13:30:59 +08:00
Add integration tests
This commit is contained in:
@@ -124,6 +124,7 @@ const SignIn: StatelessComponent<SignInForm> = props => {
|
||||
<Flex justifyContent="flex-end">
|
||||
<Localized id="signIn-forgotYourPassword">
|
||||
<Button
|
||||
id="signIn-gotoForgotPasswordButton"
|
||||
variant="underlined"
|
||||
color="primary"
|
||||
size="small"
|
||||
@@ -154,6 +155,7 @@ const SignIn: StatelessComponent<SignInForm> = props => {
|
||||
id="signIn-noAccountSignUp"
|
||||
button={
|
||||
<Button
|
||||
id="signIn-gotoSignUpButton"
|
||||
variant="underlined"
|
||||
size="small"
|
||||
color="primary"
|
||||
|
||||
@@ -229,6 +229,7 @@ const SignUp: StatelessComponent<SignUpForm> = props => {
|
||||
id="signUp-accountAvailableSignIn"
|
||||
button={
|
||||
<Button
|
||||
id="signUp-gotoSignInButton"
|
||||
variant="underlined"
|
||||
size="small"
|
||||
color="primary"
|
||||
|
||||
@@ -7,17 +7,8 @@ import resizePopup from "../dom/resizePopup";
|
||||
* when this is mounted or updated.
|
||||
*/
|
||||
export default class AutoHeightContainer extends Component {
|
||||
private timeout: any = null;
|
||||
|
||||
private updateWindowSizeCallback = () => {
|
||||
clearTimeout(this.timeout);
|
||||
this.timeout = setTimeout(() => {
|
||||
resizePopup();
|
||||
}, 0);
|
||||
};
|
||||
|
||||
private updateWindowSize() {
|
||||
window.requestAnimationFrame(this.updateWindowSizeCallback);
|
||||
window.requestAnimationFrame(() => setTimeout(resizePopup, 0));
|
||||
}
|
||||
|
||||
public componentDidMount() {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { pick } from "lodash";
|
||||
import { Environment } from "relay-runtime";
|
||||
|
||||
import { TalkContext } from "talk-framework/lib/bootstrap";
|
||||
@@ -12,7 +13,10 @@ export async function commit(
|
||||
{ rest, postMessage }: TalkContext
|
||||
) {
|
||||
try {
|
||||
const result = await signUp(rest, input);
|
||||
const result = await signUp(
|
||||
rest,
|
||||
pick(input, "email", "password", "username")
|
||||
);
|
||||
postMessage.send("setAuthToken", result.token, window.opener);
|
||||
window.close();
|
||||
} catch (err) {
|
||||
|
||||
@@ -0,0 +1,971 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`accepts correct password 1`] = `
|
||||
<div
|
||||
className="App-root"
|
||||
>
|
||||
<form
|
||||
autoComplete="off"
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<div
|
||||
className="HorizontalGutter-root HorizontalGutter-double"
|
||||
>
|
||||
<h1
|
||||
className="Typography-root Typography-heading1 Typography-colorTextPrimary Typography-alignCenter"
|
||||
>
|
||||
Sign in to join the conversation
|
||||
</h1>
|
||||
<div
|
||||
className="HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
|
||||
>
|
||||
Email Address
|
||||
</label>
|
||||
<input
|
||||
className="TextField-root TextField-colorRegular TextField-fullWidth"
|
||||
disabled={false}
|
||||
name="email"
|
||||
onChange={[Function]}
|
||||
placeholder="Email Address"
|
||||
type="text"
|
||||
value="hans@test.com"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
|
||||
>
|
||||
Password
|
||||
</label>
|
||||
<input
|
||||
className="TextField-root TextField-colorRegular TextField-fullWidth"
|
||||
disabled={false}
|
||||
name="password"
|
||||
onChange={[Function]}
|
||||
placeholder="Password"
|
||||
type="password"
|
||||
value="testtest"
|
||||
/>
|
||||
<div
|
||||
className="Flex-root Flex-flex Flex-justifyFlexEnd"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantUnderlined"
|
||||
disabled={false}
|
||||
id="signIn-gotoForgotPasswordButton"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Forgot your password?
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeLarge Button-colorPrimary Button-variantFilled Button-fullWidth"
|
||||
disabled={false}
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="submit"
|
||||
>
|
||||
Sign in and join the conversation
|
||||
</button>
|
||||
<div
|
||||
className="Flex-root Flex-flex Flex-justifyCenter"
|
||||
>
|
||||
<div
|
||||
className="Flex-root Typography-root Typography-bodyCopy Typography-colorTextPrimary Flex-flex"
|
||||
>
|
||||
<span>
|
||||
Don't have an account? <button>Sign Up</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`accepts valid email 1`] = `
|
||||
<div
|
||||
className="App-root"
|
||||
>
|
||||
<form
|
||||
autoComplete="off"
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<div
|
||||
className="HorizontalGutter-root HorizontalGutter-double"
|
||||
>
|
||||
<h1
|
||||
className="Typography-root Typography-heading1 Typography-colorTextPrimary Typography-alignCenter"
|
||||
>
|
||||
Sign in to join the conversation
|
||||
</h1>
|
||||
<div
|
||||
className="HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
|
||||
>
|
||||
Email Address
|
||||
</label>
|
||||
<input
|
||||
className="TextField-root TextField-colorRegular TextField-fullWidth"
|
||||
disabled={false}
|
||||
name="email"
|
||||
onChange={[Function]}
|
||||
placeholder="Email Address"
|
||||
type="text"
|
||||
value="hans@test.com"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
|
||||
>
|
||||
Password
|
||||
</label>
|
||||
<input
|
||||
className="TextField-root TextField-colorError TextField-fullWidth"
|
||||
disabled={false}
|
||||
name="password"
|
||||
onChange={[Function]}
|
||||
placeholder="Password"
|
||||
type="password"
|
||||
value=""
|
||||
/>
|
||||
<div
|
||||
className="ValidationMessage-root ValidationMessage-colorError ValidationMessage-fullWidth"
|
||||
>
|
||||
<span
|
||||
className="Icon-root ValidationMessage-icon Icon-sm"
|
||||
>
|
||||
warning
|
||||
</span>
|
||||
<span>
|
||||
This field is required.
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
className="Flex-root Flex-flex Flex-justifyFlexEnd"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantUnderlined"
|
||||
disabled={false}
|
||||
id="signIn-gotoForgotPasswordButton"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Forgot your password?
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeLarge Button-colorPrimary Button-variantFilled Button-fullWidth"
|
||||
disabled={false}
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="submit"
|
||||
>
|
||||
Sign in and join the conversation
|
||||
</button>
|
||||
<div
|
||||
className="Flex-root Flex-flex Flex-justifyCenter"
|
||||
>
|
||||
<div
|
||||
className="Flex-root Typography-root Typography-bodyCopy Typography-colorTextPrimary Flex-flex"
|
||||
>
|
||||
<span>
|
||||
Don't have an account? <button>Sign Up</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`checks for invalid email 1`] = `
|
||||
<div
|
||||
className="App-root"
|
||||
>
|
||||
<form
|
||||
autoComplete="off"
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<div
|
||||
className="HorizontalGutter-root HorizontalGutter-double"
|
||||
>
|
||||
<h1
|
||||
className="Typography-root Typography-heading1 Typography-colorTextPrimary Typography-alignCenter"
|
||||
>
|
||||
Sign in to join the conversation
|
||||
</h1>
|
||||
<div
|
||||
className="HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
|
||||
>
|
||||
Email Address
|
||||
</label>
|
||||
<input
|
||||
className="TextField-root TextField-colorError TextField-fullWidth"
|
||||
disabled={false}
|
||||
name="email"
|
||||
onChange={[Function]}
|
||||
placeholder="Email Address"
|
||||
type="text"
|
||||
value="invalid-email"
|
||||
/>
|
||||
<div
|
||||
className="ValidationMessage-root ValidationMessage-colorError ValidationMessage-fullWidth"
|
||||
>
|
||||
<span
|
||||
className="Icon-root ValidationMessage-icon Icon-sm"
|
||||
>
|
||||
warning
|
||||
</span>
|
||||
<span>
|
||||
Please enter a valid email address.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
|
||||
>
|
||||
Password
|
||||
</label>
|
||||
<input
|
||||
className="TextField-root TextField-colorError TextField-fullWidth"
|
||||
disabled={false}
|
||||
name="password"
|
||||
onChange={[Function]}
|
||||
placeholder="Password"
|
||||
type="password"
|
||||
value=""
|
||||
/>
|
||||
<div
|
||||
className="ValidationMessage-root ValidationMessage-colorError ValidationMessage-fullWidth"
|
||||
>
|
||||
<span
|
||||
className="Icon-root ValidationMessage-icon Icon-sm"
|
||||
>
|
||||
warning
|
||||
</span>
|
||||
<span>
|
||||
This field is required.
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
className="Flex-root Flex-flex Flex-justifyFlexEnd"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantUnderlined"
|
||||
disabled={false}
|
||||
id="signIn-gotoForgotPasswordButton"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Forgot your password?
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeLarge Button-colorPrimary Button-variantFilled Button-fullWidth"
|
||||
disabled={false}
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="submit"
|
||||
>
|
||||
Sign in and join the conversation
|
||||
</button>
|
||||
<div
|
||||
className="Flex-root Flex-flex Flex-justifyCenter"
|
||||
>
|
||||
<div
|
||||
className="Flex-root Typography-root Typography-bodyCopy Typography-colorTextPrimary Flex-flex"
|
||||
>
|
||||
<span>
|
||||
Don't have an account? <button>Sign Up</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders sign in form 1`] = `
|
||||
<div
|
||||
className="App-root"
|
||||
>
|
||||
<form
|
||||
autoComplete="off"
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<div
|
||||
className="HorizontalGutter-root HorizontalGutter-double"
|
||||
>
|
||||
<h1
|
||||
className="Typography-root Typography-heading1 Typography-colorTextPrimary Typography-alignCenter"
|
||||
>
|
||||
Sign in to join the conversation
|
||||
</h1>
|
||||
<div
|
||||
className="HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
|
||||
>
|
||||
Email Address
|
||||
</label>
|
||||
<input
|
||||
className="TextField-root TextField-colorRegular TextField-fullWidth"
|
||||
disabled={false}
|
||||
name="email"
|
||||
onChange={[Function]}
|
||||
placeholder="Email Address"
|
||||
type="text"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
|
||||
>
|
||||
Password
|
||||
</label>
|
||||
<input
|
||||
className="TextField-root TextField-colorRegular TextField-fullWidth"
|
||||
disabled={false}
|
||||
name="password"
|
||||
onChange={[Function]}
|
||||
placeholder="Password"
|
||||
type="password"
|
||||
value=""
|
||||
/>
|
||||
<div
|
||||
className="Flex-root Flex-flex Flex-justifyFlexEnd"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantUnderlined"
|
||||
disabled={false}
|
||||
id="signIn-gotoForgotPasswordButton"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Forgot your password?
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeLarge Button-colorPrimary Button-variantFilled Button-fullWidth"
|
||||
disabled={false}
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="submit"
|
||||
>
|
||||
Sign in and join the conversation
|
||||
</button>
|
||||
<div
|
||||
className="Flex-root Flex-flex Flex-justifyCenter"
|
||||
>
|
||||
<div
|
||||
className="Flex-root Typography-root Typography-bodyCopy Typography-colorTextPrimary Flex-flex"
|
||||
>
|
||||
<span>
|
||||
Don't have an account? <button>Sign Up</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`shows error when submitting empty form 1`] = `
|
||||
<div
|
||||
className="App-root"
|
||||
>
|
||||
<form
|
||||
autoComplete="off"
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<div
|
||||
className="HorizontalGutter-root HorizontalGutter-double"
|
||||
>
|
||||
<h1
|
||||
className="Typography-root Typography-heading1 Typography-colorTextPrimary Typography-alignCenter"
|
||||
>
|
||||
Sign in to join the conversation
|
||||
</h1>
|
||||
<div
|
||||
className="HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
|
||||
>
|
||||
Email Address
|
||||
</label>
|
||||
<input
|
||||
className="TextField-root TextField-colorError TextField-fullWidth"
|
||||
disabled={false}
|
||||
name="email"
|
||||
onChange={[Function]}
|
||||
placeholder="Email Address"
|
||||
type="text"
|
||||
value=""
|
||||
/>
|
||||
<div
|
||||
className="ValidationMessage-root ValidationMessage-colorError ValidationMessage-fullWidth"
|
||||
>
|
||||
<span
|
||||
className="Icon-root ValidationMessage-icon Icon-sm"
|
||||
>
|
||||
warning
|
||||
</span>
|
||||
<span>
|
||||
This field is required.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
|
||||
>
|
||||
Password
|
||||
</label>
|
||||
<input
|
||||
className="TextField-root TextField-colorError TextField-fullWidth"
|
||||
disabled={false}
|
||||
name="password"
|
||||
onChange={[Function]}
|
||||
placeholder="Password"
|
||||
type="password"
|
||||
value=""
|
||||
/>
|
||||
<div
|
||||
className="ValidationMessage-root ValidationMessage-colorError ValidationMessage-fullWidth"
|
||||
>
|
||||
<span
|
||||
className="Icon-root ValidationMessage-icon Icon-sm"
|
||||
>
|
||||
warning
|
||||
</span>
|
||||
<span>
|
||||
This field is required.
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
className="Flex-root Flex-flex Flex-justifyFlexEnd"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantUnderlined"
|
||||
disabled={false}
|
||||
id="signIn-gotoForgotPasswordButton"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Forgot your password?
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeLarge Button-colorPrimary Button-variantFilled Button-fullWidth"
|
||||
disabled={false}
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="submit"
|
||||
>
|
||||
Sign in and join the conversation
|
||||
</button>
|
||||
<div
|
||||
className="Flex-root Flex-flex Flex-justifyCenter"
|
||||
>
|
||||
<div
|
||||
className="Flex-root Typography-root Typography-bodyCopy Typography-colorTextPrimary Flex-flex"
|
||||
>
|
||||
<span>
|
||||
Don't have an account? <button>Sign Up</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`shows server error 1`] = `
|
||||
<div
|
||||
className="App-root"
|
||||
>
|
||||
<form
|
||||
autoComplete="off"
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<div
|
||||
className="HorizontalGutter-root HorizontalGutter-double"
|
||||
>
|
||||
<h1
|
||||
className="Typography-root Typography-heading1 Typography-colorTextPrimary Typography-alignCenter"
|
||||
>
|
||||
Sign in to join the conversation
|
||||
</h1>
|
||||
<div
|
||||
className="HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
|
||||
>
|
||||
Email Address
|
||||
</label>
|
||||
<input
|
||||
className="TextField-root TextField-colorRegular TextField-fullWidth"
|
||||
disabled={true}
|
||||
name="email"
|
||||
onChange={[Function]}
|
||||
placeholder="Email Address"
|
||||
type="text"
|
||||
value="hans@test.com"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
|
||||
>
|
||||
Password
|
||||
</label>
|
||||
<input
|
||||
className="TextField-root TextField-colorRegular TextField-fullWidth"
|
||||
disabled={true}
|
||||
name="password"
|
||||
onChange={[Function]}
|
||||
placeholder="Password"
|
||||
type="password"
|
||||
value="testtest"
|
||||
/>
|
||||
<div
|
||||
className="Flex-root Flex-flex Flex-justifyFlexEnd"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantUnderlined Button-disabled"
|
||||
disabled={true}
|
||||
id="signIn-gotoForgotPasswordButton"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Forgot your password?
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeLarge Button-colorPrimary Button-variantFilled Button-fullWidth Button-disabled"
|
||||
disabled={true}
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="submit"
|
||||
>
|
||||
Sign in and join the conversation
|
||||
</button>
|
||||
<div
|
||||
className="Flex-root Flex-flex Flex-justifyCenter"
|
||||
>
|
||||
<div
|
||||
className="Flex-root Typography-root Typography-bodyCopy Typography-colorTextPrimary Flex-flex"
|
||||
>
|
||||
<span>
|
||||
Don't have an account? <button>Sign Up</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`shows server error 2`] = `
|
||||
<div
|
||||
className="App-root"
|
||||
>
|
||||
<form
|
||||
autoComplete="off"
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<div
|
||||
className="HorizontalGutter-root HorizontalGutter-double"
|
||||
>
|
||||
<h1
|
||||
className="Typography-root Typography-heading1 Typography-colorTextPrimary Typography-alignCenter"
|
||||
>
|
||||
Sign in to join the conversation
|
||||
</h1>
|
||||
<div
|
||||
className="CallOut-root CallOut-colorError CallOut-fullWidth"
|
||||
>
|
||||
Server Error
|
||||
</div>
|
||||
<div
|
||||
className="HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
|
||||
>
|
||||
Email Address
|
||||
</label>
|
||||
<input
|
||||
className="TextField-root TextField-colorRegular TextField-fullWidth"
|
||||
disabled={false}
|
||||
name="email"
|
||||
onChange={[Function]}
|
||||
placeholder="Email Address"
|
||||
type="text"
|
||||
value="hans@test.com"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
|
||||
>
|
||||
Password
|
||||
</label>
|
||||
<input
|
||||
className="TextField-root TextField-colorRegular TextField-fullWidth"
|
||||
disabled={false}
|
||||
name="password"
|
||||
onChange={[Function]}
|
||||
placeholder="Password"
|
||||
type="password"
|
||||
value="testtest"
|
||||
/>
|
||||
<div
|
||||
className="Flex-root Flex-flex Flex-justifyFlexEnd"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantUnderlined"
|
||||
disabled={false}
|
||||
id="signIn-gotoForgotPasswordButton"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Forgot your password?
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeLarge Button-colorPrimary Button-variantFilled Button-fullWidth"
|
||||
disabled={false}
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="submit"
|
||||
>
|
||||
Sign in and join the conversation
|
||||
</button>
|
||||
<div
|
||||
className="Flex-root Flex-flex Flex-justifyCenter"
|
||||
>
|
||||
<div
|
||||
className="Flex-root Typography-root Typography-bodyCopy Typography-colorTextPrimary Flex-flex"
|
||||
>
|
||||
<span>
|
||||
Don't have an account? <button>Sign Up</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`submits form successfully 1`] = `
|
||||
<div
|
||||
className="App-root"
|
||||
>
|
||||
<form
|
||||
autoComplete="off"
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<div
|
||||
className="HorizontalGutter-root HorizontalGutter-double"
|
||||
>
|
||||
<h1
|
||||
className="Typography-root Typography-heading1 Typography-colorTextPrimary Typography-alignCenter"
|
||||
>
|
||||
Sign in to join the conversation
|
||||
</h1>
|
||||
<div
|
||||
className="CallOut-root CallOut-colorError CallOut-fullWidth"
|
||||
>
|
||||
Server Error
|
||||
</div>
|
||||
<div
|
||||
className="HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
|
||||
>
|
||||
Email Address
|
||||
</label>
|
||||
<input
|
||||
className="TextField-root TextField-colorRegular TextField-fullWidth"
|
||||
disabled={true}
|
||||
name="email"
|
||||
onChange={[Function]}
|
||||
placeholder="Email Address"
|
||||
type="text"
|
||||
value="hans@test.com"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
|
||||
>
|
||||
Password
|
||||
</label>
|
||||
<input
|
||||
className="TextField-root TextField-colorRegular TextField-fullWidth"
|
||||
disabled={true}
|
||||
name="password"
|
||||
onChange={[Function]}
|
||||
placeholder="Password"
|
||||
type="password"
|
||||
value="testtest"
|
||||
/>
|
||||
<div
|
||||
className="Flex-root Flex-flex Flex-justifyFlexEnd"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantUnderlined Button-disabled"
|
||||
disabled={true}
|
||||
id="signIn-gotoForgotPasswordButton"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Forgot your password?
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeLarge Button-colorPrimary Button-variantFilled Button-fullWidth Button-disabled"
|
||||
disabled={true}
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="submit"
|
||||
>
|
||||
Sign in and join the conversation
|
||||
</button>
|
||||
<div
|
||||
className="Flex-root Flex-flex Flex-justifyCenter"
|
||||
>
|
||||
<div
|
||||
className="Flex-root Typography-root Typography-bodyCopy Typography-colorTextPrimary Flex-flex"
|
||||
>
|
||||
<span>
|
||||
Don't have an account? <button>Sign Up</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`submits form successfully 2`] = `
|
||||
<div
|
||||
className="App-root"
|
||||
>
|
||||
<form
|
||||
autoComplete="off"
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<div
|
||||
className="HorizontalGutter-root HorizontalGutter-double"
|
||||
>
|
||||
<h1
|
||||
className="Typography-root Typography-heading1 Typography-colorTextPrimary Typography-alignCenter"
|
||||
>
|
||||
Sign in to join the conversation
|
||||
</h1>
|
||||
<div
|
||||
className="HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
|
||||
>
|
||||
Email Address
|
||||
</label>
|
||||
<input
|
||||
className="TextField-root TextField-colorRegular TextField-fullWidth"
|
||||
disabled={false}
|
||||
name="email"
|
||||
onChange={[Function]}
|
||||
placeholder="Email Address"
|
||||
type="text"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
|
||||
>
|
||||
Password
|
||||
</label>
|
||||
<input
|
||||
className="TextField-root TextField-colorRegular TextField-fullWidth"
|
||||
disabled={false}
|
||||
name="password"
|
||||
onChange={[Function]}
|
||||
placeholder="Password"
|
||||
type="password"
|
||||
value=""
|
||||
/>
|
||||
<div
|
||||
className="Flex-root Flex-flex Flex-justifyFlexEnd"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantUnderlined"
|
||||
disabled={false}
|
||||
id="signIn-gotoForgotPasswordButton"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Forgot your password?
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeLarge Button-colorPrimary Button-variantFilled Button-fullWidth"
|
||||
disabled={false}
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="submit"
|
||||
>
|
||||
Sign in and join the conversation
|
||||
</button>
|
||||
<div
|
||||
className="Flex-root Flex-flex Flex-justifyCenter"
|
||||
>
|
||||
<div
|
||||
className="Flex-root Typography-root Typography-bodyCopy Typography-colorTextPrimary Flex-flex"
|
||||
>
|
||||
<span>
|
||||
Don't have an account? <button>Sign Up</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
`;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,28 @@
|
||||
import { IResolvers } from "graphql-tools";
|
||||
import { Environment, RecordProxy, RecordSourceProxy } from "relay-runtime";
|
||||
import { createRelayEnvironment } from "talk-framework/testHelpers";
|
||||
|
||||
interface CreateEnvironmentParams {
|
||||
logNetwork?: boolean;
|
||||
resolvers?: IResolvers<any, any>;
|
||||
initLocalState?: (
|
||||
local: RecordProxy,
|
||||
source: RecordSourceProxy,
|
||||
environment: Environment
|
||||
) => void;
|
||||
}
|
||||
|
||||
export default function createEnvironment(params: CreateEnvironmentParams) {
|
||||
return createRelayEnvironment({
|
||||
network: {
|
||||
logNetwork: params.logNetwork,
|
||||
resolvers: params.resolvers || {},
|
||||
projectName: "tenant",
|
||||
},
|
||||
initLocalState: (localRecord, source, environment) => {
|
||||
if (params.initLocalState) {
|
||||
params.initLocalState(localRecord, source, environment);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
// Enable after this is solved: https://github.com/projectfluent/fluent.js/issues/280
|
||||
|
||||
import React from "react";
|
||||
import TestRenderer from "react-test-renderer";
|
||||
import { RecordProxy } from "relay-runtime";
|
||||
|
||||
import AppContainer from "talk-auth/containers/AppContainer";
|
||||
import { TalkContext, TalkContextProvider } from "talk-framework/lib/bootstrap";
|
||||
import { PostMessageService } from "talk-framework/lib/postMessage";
|
||||
import { RestClient } from "talk-framework/lib/rest";
|
||||
import { createInMemoryStorage } from "talk-framework/lib/storage";
|
||||
|
||||
import createEnvironment from "./createEnvironment";
|
||||
|
||||
const environment = createEnvironment({
|
||||
initLocalState: (localRecord: RecordProxy) => {
|
||||
localRecord.setValue("SIGN_IN", "view");
|
||||
},
|
||||
});
|
||||
|
||||
const context: TalkContext = {
|
||||
relayEnvironment: environment,
|
||||
localeBundles: [],
|
||||
localStorage: createInMemoryStorage(),
|
||||
sessionStorage: createInMemoryStorage(),
|
||||
rest: new RestClient("http://localhost/api"),
|
||||
postMessage: new PostMessageService(),
|
||||
};
|
||||
|
||||
const testRenderer = TestRenderer.create(
|
||||
<TalkContextProvider value={context}>
|
||||
<AppContainer />
|
||||
</TalkContextProvider>
|
||||
);
|
||||
|
||||
it("renders sign in form", async () => {
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("navigates to sign up form", async () => {
|
||||
testRenderer.root
|
||||
.findByProps({ id: "signIn-gotoSignUpButton" })
|
||||
.props.onClick();
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("navigates to sign in form", async () => {
|
||||
testRenderer.root
|
||||
.findByProps({ id: "signUp-gotoSignInButton" })
|
||||
.props.onClick();
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("navigates to forgot password form", async () => {
|
||||
testRenderer.root
|
||||
.findByProps({ id: "signIn-gotoForgotPasswordButton" })
|
||||
.props.onClick();
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
@@ -0,0 +1,140 @@
|
||||
import React from "react";
|
||||
import TestRenderer, { ReactTestInstance } from "react-test-renderer";
|
||||
import { RecordProxy } from "relay-runtime";
|
||||
import sinon from "sinon";
|
||||
|
||||
import AppContainer from "talk-auth/containers/AppContainer";
|
||||
import { animationFrame, timeout } from "talk-common/utils";
|
||||
import { TalkContext, TalkContextProvider } from "talk-framework/lib/bootstrap";
|
||||
import { PostMessageService } from "talk-framework/lib/postMessage";
|
||||
import { RestClient } from "talk-framework/lib/rest";
|
||||
import { createInMemoryStorage } from "talk-framework/lib/storage";
|
||||
|
||||
import createEnvironment from "./createEnvironment";
|
||||
|
||||
const environment = createEnvironment({
|
||||
initLocalState: (localRecord: RecordProxy) => {
|
||||
localRecord.setValue("SIGN_IN", "view");
|
||||
},
|
||||
});
|
||||
|
||||
const context: TalkContext = {
|
||||
relayEnvironment: environment,
|
||||
localeBundles: [],
|
||||
localStorage: createInMemoryStorage(),
|
||||
sessionStorage: createInMemoryStorage(),
|
||||
rest: new RestClient("http://localhost/api"),
|
||||
postMessage: new PostMessageService(),
|
||||
};
|
||||
|
||||
const testRenderer = TestRenderer.create(
|
||||
<TalkContextProvider value={context}>
|
||||
<AppContainer />
|
||||
</TalkContextProvider>
|
||||
);
|
||||
|
||||
const inputPredicate = (name: string) => (n: ReactTestInstance) => {
|
||||
return n.props.name === name && n.props.onChange;
|
||||
};
|
||||
|
||||
const form = testRenderer.root.findByType("form");
|
||||
|
||||
it("renders sign in form", async () => {
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("shows error when submitting empty form", async () => {
|
||||
form.props.onSubmit();
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("checks for invalid email", async () => {
|
||||
form
|
||||
.find(inputPredicate("email"))
|
||||
.props.onChange({ target: { value: "invalid-email" } });
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("accepts valid email", async () => {
|
||||
form
|
||||
.find(inputPredicate("email"))
|
||||
.props.onChange({ target: { value: "hans@test.com" } });
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("accepts correct password", async () => {
|
||||
form
|
||||
.find(inputPredicate("password"))
|
||||
.props.onChange({ target: { value: "testtest" } });
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("shows server error", async () => {
|
||||
const windowMock = sinon.mock(window);
|
||||
windowMock.expects("resizeTo");
|
||||
|
||||
const error = new Error("Server Error");
|
||||
const restMock = sinon.mock(context.rest);
|
||||
restMock
|
||||
.expects("fetch")
|
||||
.withArgs("/tenant/auth/local", {
|
||||
method: "POST",
|
||||
body: {
|
||||
email: "hans@test.com",
|
||||
password: "testtest",
|
||||
},
|
||||
})
|
||||
.once()
|
||||
.throws(error);
|
||||
|
||||
const postMessageMock = sinon.mock(context.postMessage);
|
||||
postMessageMock
|
||||
.expects("send")
|
||||
.withArgs("authError", error.toString(), window.opener)
|
||||
.once();
|
||||
|
||||
form.props.onSubmit();
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
// popup resize will be triggered if we wait for the animation frame first.
|
||||
await animationFrame();
|
||||
await timeout();
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
restMock.verify();
|
||||
postMessageMock.verify();
|
||||
windowMock.verify();
|
||||
});
|
||||
|
||||
it("submits form successfully", async () => {
|
||||
const windowMock = sinon.mock(window);
|
||||
windowMock.expects("close").once();
|
||||
windowMock.expects("resizeTo");
|
||||
|
||||
const restMock = sinon.mock(context.rest);
|
||||
restMock
|
||||
.expects("fetch")
|
||||
.withArgs("/tenant/auth/local", {
|
||||
method: "POST",
|
||||
body: {
|
||||
email: "hans@test.com",
|
||||
password: "testtest",
|
||||
},
|
||||
})
|
||||
.once()
|
||||
.returns({ token: "auth-token" });
|
||||
|
||||
const postMessageMock = sinon.mock(context.postMessage);
|
||||
postMessageMock
|
||||
.expects("send")
|
||||
.withArgs("setAuthToken", "auth-token", window.opener)
|
||||
.once();
|
||||
|
||||
form.props.onSubmit();
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
// popup resize will be triggered if we wait for the animation frame first.
|
||||
await animationFrame();
|
||||
await timeout();
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
restMock.verify();
|
||||
postMessageMock.verify();
|
||||
windowMock.verify();
|
||||
});
|
||||
@@ -0,0 +1,191 @@
|
||||
import React from "react";
|
||||
import TestRenderer, { ReactTestInstance } from "react-test-renderer";
|
||||
import { RecordProxy } from "relay-runtime";
|
||||
import sinon from "sinon";
|
||||
|
||||
import AppContainer from "talk-auth/containers/AppContainer";
|
||||
import { animationFrame, timeout } from "talk-common/utils";
|
||||
import { TalkContext, TalkContextProvider } from "talk-framework/lib/bootstrap";
|
||||
import { PostMessageService } from "talk-framework/lib/postMessage";
|
||||
import { RestClient } from "talk-framework/lib/rest";
|
||||
import { createInMemoryStorage } from "talk-framework/lib/storage";
|
||||
|
||||
import createEnvironment from "./createEnvironment";
|
||||
|
||||
const environment = createEnvironment({
|
||||
initLocalState: (localRecord: RecordProxy) => {
|
||||
localRecord.setValue("SIGN_UP", "view");
|
||||
},
|
||||
});
|
||||
|
||||
const context: TalkContext = {
|
||||
relayEnvironment: environment,
|
||||
localeBundles: [],
|
||||
localStorage: createInMemoryStorage(),
|
||||
sessionStorage: createInMemoryStorage(),
|
||||
rest: new RestClient("http://localhost/api"),
|
||||
postMessage: new PostMessageService(),
|
||||
};
|
||||
|
||||
const testRenderer = TestRenderer.create(
|
||||
<TalkContextProvider value={context}>
|
||||
<AppContainer />
|
||||
</TalkContextProvider>
|
||||
);
|
||||
|
||||
const inputPredicate = (name: string) => (n: ReactTestInstance) => {
|
||||
return n.props.name === name && n.props.onChange;
|
||||
};
|
||||
|
||||
const form = testRenderer.root.findByType("form");
|
||||
|
||||
it("renders sign up form", async () => {
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("shows error when submitting empty form", async () => {
|
||||
form.props.onSubmit();
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("checks for invalid email", async () => {
|
||||
form
|
||||
.find(inputPredicate("email"))
|
||||
.props.onChange({ target: { value: "invalid-email" } });
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("accepts valid email", async () => {
|
||||
form
|
||||
.find(inputPredicate("email"))
|
||||
.props.onChange({ target: { value: "hans@test.com" } });
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("checks for too short username", async () => {
|
||||
form
|
||||
.find(inputPredicate("username"))
|
||||
.props.onChange({ target: { value: "u" } });
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("checks for too long username", async () => {
|
||||
form
|
||||
.find(inputPredicate("username"))
|
||||
.props.onChange({ target: { value: "a".repeat(100) } });
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("checks for invalid characters in username", async () => {
|
||||
form
|
||||
.find(inputPredicate("username"))
|
||||
.props.onChange({ target: { value: "$%$§$%$§%" } });
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("accepts valid username", async () => {
|
||||
form
|
||||
.find(inputPredicate("username"))
|
||||
.props.onChange({ target: { value: "hans" } });
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("checks for too short password", async () => {
|
||||
form
|
||||
.find(inputPredicate("password"))
|
||||
.props.onChange({ target: { value: "pass" } });
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("accepts correct password", async () => {
|
||||
form
|
||||
.find(inputPredicate("password"))
|
||||
.props.onChange({ target: { value: "testtest" } });
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("checks for wrong password confirmation", async () => {
|
||||
form
|
||||
.find(inputPredicate("confirmPassword"))
|
||||
.props.onChange({ target: { value: "not-matching" } });
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("accepts correct password confirmation", async () => {
|
||||
form
|
||||
.find(inputPredicate("confirmPassword"))
|
||||
.props.onChange({ target: { value: "testtest" } });
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("shows server error", async () => {
|
||||
const windowMock = sinon.mock(window);
|
||||
windowMock.expects("resizeTo");
|
||||
|
||||
const error = new Error("Server Error");
|
||||
const restMock = sinon.mock(context.rest);
|
||||
restMock
|
||||
.expects("fetch")
|
||||
.withArgs("/tenant/auth/local/signup", {
|
||||
method: "POST",
|
||||
body: {
|
||||
username: "hans",
|
||||
email: "hans@test.com",
|
||||
password: "testtest",
|
||||
},
|
||||
})
|
||||
.once()
|
||||
.throws(error);
|
||||
|
||||
const postMessageMock = sinon.mock(context.postMessage);
|
||||
postMessageMock
|
||||
.expects("send")
|
||||
.withArgs("authError", error.toString(), window.opener)
|
||||
.once();
|
||||
|
||||
form.props.onSubmit();
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
// popup resize will be triggered if we wait for the animation frame first.
|
||||
await animationFrame();
|
||||
await timeout();
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
restMock.verify();
|
||||
postMessageMock.verify();
|
||||
windowMock.verify();
|
||||
});
|
||||
|
||||
it("submits form successfully", async () => {
|
||||
const windowMock = sinon.mock(window);
|
||||
windowMock.expects("close").once();
|
||||
windowMock.expects("resizeTo");
|
||||
|
||||
const restMock = sinon.mock(context.rest);
|
||||
restMock
|
||||
.expects("fetch")
|
||||
.withArgs("/tenant/auth/local/signup", {
|
||||
method: "POST",
|
||||
body: {
|
||||
username: "hans",
|
||||
email: "hans@test.com",
|
||||
password: "testtest",
|
||||
},
|
||||
})
|
||||
.once()
|
||||
.returns({ token: "auth-token" });
|
||||
|
||||
const postMessageMock = sinon.mock(context.postMessage);
|
||||
postMessageMock
|
||||
.expects("send")
|
||||
.withArgs("setAuthToken", "auth-token", window.opener)
|
||||
.once();
|
||||
|
||||
form.props.onSubmit();
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
// popup resize will be triggered if we wait for the animation frame first.
|
||||
await animationFrame();
|
||||
await timeout();
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
restMock.verify();
|
||||
postMessageMock.verify();
|
||||
windowMock.verify();
|
||||
});
|
||||
@@ -5,6 +5,7 @@ import { withStyles } from "talk-ui/hocs";
|
||||
import * as styles from "./TextField.css";
|
||||
|
||||
export interface TextFieldProps {
|
||||
id?: string;
|
||||
/**
|
||||
* The content value of the component.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
/** A promisified animation frame. */
|
||||
export default function animationFrame() {
|
||||
return new Promise(resolve => requestAnimationFrame(resolve));
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
export { default as timeout } from "./timeout";
|
||||
export { default as animationFrame } from "./animationFrame";
|
||||
export { default as pascalCase } from "./pascalCase";
|
||||
export { default as oncePerFrame } from "./oncePerFrame";
|
||||
|
||||
@@ -16,7 +16,6 @@ signIn-passwordTextField =
|
||||
|
||||
signIn-forgotYourPassword = Forgot your password?
|
||||
|
||||
signIn-noAccountSignUp = Don't have an account? <button>Sign Up</button>
|
||||
|
||||
## Sign Up
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
framework-validation-required = This field is required.
|
||||
framework-validation-tooShort = The field must contain at least {$minLength} characters.
|
||||
framework-validation-passwordTooShort = Password must contain at least {$minLength} characters.
|
||||
framework-validation-usernameTooShort = Username must contain at least {$minLength} characters.
|
||||
framework-validation-usernameTooLong = Usernames cannot be longer than {$maxLength} characters.
|
||||
framework-validation-invalidCharacters = Invalid characters. Try again.
|
||||
|
||||
Reference in New Issue
Block a user