Add integration tests

This commit is contained in:
Chi Vinh Le
2018-08-28 01:35:13 +02:00
parent 99e34979d1
commit 9945c099a7
15 changed files with 3759 additions and 13 deletions
@@ -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? &lt;button&gt;Sign Up&lt;/button&gt;
</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? &lt;button&gt;Sign Up&lt;/button&gt;
</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? &lt;button&gt;Sign Up&lt;/button&gt;
</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? &lt;button&gt;Sign Up&lt;/button&gt;
</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? &lt;button&gt;Sign Up&lt;/button&gt;
</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? &lt;button&gt;Sign Up&lt;/button&gt;
</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? &lt;button&gt;Sign Up&lt;/button&gt;
</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? &lt;button&gt;Sign Up&lt;/button&gt;
</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? &lt;button&gt;Sign Up&lt;/button&gt;
</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();
});
+140
View File
@@ -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();
});
+191
View File
@@ -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.
*/
+4
View File
@@ -0,0 +1,4 @@
/** A promisified animation frame. */
export default function animationFrame() {
return new Promise(resolve => requestAnimationFrame(resolve));
}
+1
View File
@@ -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";
-1
View File
@@ -16,7 +16,6 @@ signIn-passwordTextField =
signIn-forgotYourPassword = Forgot your password?
signIn-noAccountSignUp = Don't have an account? <button>Sign Up</button>
## Sign Up
-1
View File
@@ -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.