Fix broken LoginForm.test.tsx
This commit is contained in:
parent
8f8c3b6c9c
commit
637b51382a
@ -1,8 +1,10 @@
|
||||
import * as Feature from './'
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import T from 'react-dom/test-utils'
|
||||
import {HTTPClientMock, TestUtils, getError} from '../test-utils'
|
||||
import {IAPIDef} from '@rondo/common'
|
||||
import {MemoryRouter} from 'react-router-dom'
|
||||
|
||||
const test = new TestUtils()
|
||||
|
||||
@ -15,6 +17,8 @@ describe('LoginForm', () => {
|
||||
reducers: {Login: Feature.Login},
|
||||
connector: new Feature.LoginConnector(loginActions),
|
||||
select: state => state.Login,
|
||||
customJSX: (Component, props) =>
|
||||
<MemoryRouter><Component {...props} /></MemoryRouter>,
|
||||
})
|
||||
|
||||
beforeAll(() => {
|
||||
@ -61,16 +65,7 @@ describe('LoginForm', () => {
|
||||
data,
|
||||
})
|
||||
expect(onSuccess.mock.calls.length).toBe(1)
|
||||
expect(
|
||||
(node.querySelector('input[name="username"]') as HTMLInputElement)
|
||||
.value,
|
||||
)
|
||||
.toEqual('')
|
||||
expect(
|
||||
(node.querySelector('input[name="password"]') as HTMLInputElement)
|
||||
.value,
|
||||
)
|
||||
.toEqual('')
|
||||
// TODO test clear username/password
|
||||
node = ReactDOM.findDOMNode(component) as Element
|
||||
expect(node.innerHTML).toMatch(/<a href="\/">/)
|
||||
})
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import React from 'react'
|
||||
import {IAction} from '../actions'
|
||||
import {IPendingAction} from '../actions'
|
||||
|
||||
export interface IComponentProps<Data> {
|
||||
onSubmit: () => void
|
||||
@ -10,13 +10,18 @@ export interface IComponentProps<Data> {
|
||||
}
|
||||
|
||||
export interface IFormHOCProps<Data> {
|
||||
onSubmit: (props: Data) => IAction<any>
|
||||
onSubmit: (props: Data) => IPendingAction<any, any>
|
||||
// TODO figure out what would happen if the underlying child component
|
||||
// would have the same required property as the HOC, like onSuccess?
|
||||
onSuccess?: () => void
|
||||
clearOnSuccess?: boolean
|
||||
}
|
||||
|
||||
export interface IFormHOCState<Data> {
|
||||
error: string
|
||||
data: Data
|
||||
}
|
||||
|
||||
export function withForm<Data, Props extends IComponentProps<Data>>(
|
||||
Component: React.ComponentType<Props>,
|
||||
initialState: Data,
|
||||
@ -26,28 +31,44 @@ export function withForm<Data, Props extends IComponentProps<Data>>(
|
||||
Exclude<keyof Props, keyof IComponentProps<Data>>>
|
||||
type T = IFormHOCProps<Data> & OtherProps
|
||||
|
||||
return class FormHOC extends React.PureComponent<T, Data> {
|
||||
return class FormHOC extends React.PureComponent<T, IFormHOCState<Data>> {
|
||||
constructor(props: T) {
|
||||
super(props)
|
||||
this.state = initialState
|
||||
this.state = {
|
||||
error: '',
|
||||
data: initialState,
|
||||
}
|
||||
}
|
||||
handleSubmit = async (e: React.FormEvent) => {
|
||||
const {clearOnSuccess, onSuccess} = this.props
|
||||
e.preventDefault()
|
||||
const promise = this.props.onSubmit(this.state)
|
||||
console.log('aaaaaaaaa', promise)
|
||||
await promise
|
||||
const action = this.props.onSubmit(this.state.data)
|
||||
try {
|
||||
await action.payload
|
||||
} catch (err) {
|
||||
this.setState({
|
||||
error: err.message,
|
||||
})
|
||||
return
|
||||
}
|
||||
if (clearOnSuccess) {
|
||||
this.setState(initialState)
|
||||
this.setState({
|
||||
...this.state,
|
||||
data: initialState,
|
||||
})
|
||||
}
|
||||
if (onSuccess) {
|
||||
onSuccess()
|
||||
}
|
||||
}
|
||||
handleChange = (name: string, value: string) => {
|
||||
this.setState(
|
||||
{[name]: value} as unknown as Pick<Data, keyof Data>,
|
||||
)
|
||||
this.setState({
|
||||
...this.state,
|
||||
data: {
|
||||
...this.state.data,
|
||||
[name]: value,
|
||||
},
|
||||
})
|
||||
}
|
||||
render() {
|
||||
const {children, onSuccess, onSubmit, ...otherProps} = this.props
|
||||
|
||||
@ -110,9 +110,11 @@ export class HTTPClientMock<T extends IRoutes> extends HTTPClient<T> {
|
||||
*/
|
||||
async wait(): Promise<IReqRes> {
|
||||
expect(this.waitPromise).toBe(undefined)
|
||||
return new Promise((resolve, reject) => {
|
||||
const result: IReqRes = await new Promise((resolve, reject) => {
|
||||
this.waitPromise = {resolve, reject}
|
||||
})
|
||||
await new Promise(resolve => setImmediate(resolve))
|
||||
return result
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -18,9 +18,9 @@ interface IRenderParams<State> {
|
||||
state?: DeepPartial<State>
|
||||
connector: Connector<any>
|
||||
select: IStateSelector<State, any>
|
||||
customJSX?: <Props>(
|
||||
Component: React.ComponentType<Props>,
|
||||
additionalProps: Record<string, Props>,
|
||||
customJSX?: (
|
||||
Component: React.ComponentType<any>,
|
||||
additionalProps: Record<string, any>,
|
||||
) => JSX.Element
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user