Skip to content

Commit

Permalink
immer signup (keybase#20966)
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisnojima authored Nov 14, 2019
1 parent 56f7476 commit ca2ac8a
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 137 deletions.
44 changes: 23 additions & 21 deletions shared/actions/__tests__/signup.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,23 @@ const makeTypedState = (signupState: Types.State): TypedState => ({signup: signu

describe('goBackAndClearErrors', () => {
it('errors get cleaned and we go back a level', () => {
const state = Constants.makeState({
const state = {
...Constants.makeState(),
devicenameError: 'bad name',
emailError: 'bad email',
inviteCodeError: 'bad invite',
nameError: 'bad name',
signupError: new RPCError('bad signup', 0),
usernameError: 'bad username',
})
}

const action = SignupGen.createGoBackAndClearErrors()
const nextState = {signup: reducer(state, action)}
expect(nextState.signup.devicenameError).toEqual('')
expect(nextState.signup.emailError).toEqual('')
expect(nextState.signup.inviteCodeError).toEqual('')
expect(nextState.signup.nameError).toEqual('')
expect(nextState.signup.signupError).toEqual(null)
expect(nextState.signup.signupError).toEqual(undefined)
expect(nextState.signup.usernameError).toEqual('')
expect(_testing.goBackAndClearErrors()).toEqual(RouteTreeGen.createNavigateUp())
})
Expand Down Expand Up @@ -68,7 +69,7 @@ describe('requestAutoInvite', () => {

describe('requestInvite', () => {
it('ignores if theres an error', () => {
const state = Constants.makeState({devicenameError: 'has an error'})
const state = {...Constants.makeState(), devicenameError: 'has an error'}
const action = SignupGen.createRequestInvite({email: '[email protected]', name: 'name'})
const nextState = makeTypedState(reducer(state, action))
expect(_testing.showInviteSuccessOnNoErrors(nextState)).toEqual(false)
Expand Down Expand Up @@ -161,7 +162,7 @@ describe('checkInviteCode', () => {

describe('checkUsername', () => {
it("ignores if there's an error", () => {
const state = Constants.makeState({inviteCodeError: 'invite error'})
const state = {...Constants.makeState(), inviteCodeError: 'invite error'}
expect(_testing.checkUsername(makeTypedState(state), null as any, testLogger)).resolves.toEqual(false)
})

Expand All @@ -183,7 +184,7 @@ describe('checkUsername', () => {

describe('checkedUsername', () => {
it("ignores if username doesn't match", () => {
const state = Constants.makeState({username: 'username'})
const state = {...Constants.makeState(), username: 'username'}
const action = SignupGen.createCheckedUsername({
error: 'another problem',
username: 'different username',
Expand All @@ -194,7 +195,7 @@ describe('checkedUsername', () => {
})

it('shows error', () => {
const state = Constants.makeState({username: 'username'})
const state = {...Constants.makeState(), username: 'username'}
const action = SignupGen.createCheckedUsername({
error: 'another problem',
username: state.username,
Expand All @@ -204,7 +205,7 @@ describe('checkedUsername', () => {
})

it('shows device name page on success', () => {
const state = Constants.makeState({username: 'username'})
const state = {...Constants.makeState(), username: 'username'}
const action = SignupGen.createCheckedUsername({
error: '',
username: state.username,
Expand Down Expand Up @@ -265,15 +266,15 @@ describe('deviceScreen', () => {
})

it("ignores if devicename doesn't match", () => {
const state = Constants.makeState({devicename: 'a device'})
const state = {...Constants.makeState(), devicename: 'a device'}
const action = SignupGen.createCheckedDevicename({devicename: 'different name', error: 'an error'})
const nextState = makeTypedState(reducer(state, action))
// doesn't update
expect(nextState).toEqual(makeTypedState(state))
})

it('shows error', () => {
const state = Constants.makeState({devicename: 'devicename'})
const state = {...Constants.makeState(), devicename: 'devicename'}
const action = SignupGen.createCheckedDevicename({devicename: 'devicename', error: 'an error'})
const nextState = makeTypedState(reducer(makeTypedState(state).signup, action))
expect(nextState.signup.devicename).toEqual(action.payload.devicename)
Expand All @@ -283,51 +284,52 @@ describe('deviceScreen', () => {

describe('actually sign up', () => {
it('bails on devicenameError', () => {
const state = Constants.makeState({devicenameError: 'error'})
const state = {...Constants.makeState(), devicenameError: 'error'}
expect(_testing.reallySignupOnNoErrors(makeTypedState(state)).next().value).toBeUndefined()
})
it('bails on emailError', () => {
const state = Constants.makeState({emailError: 'error'})
const state = {...Constants.makeState(), emailError: 'error'}
expect(_testing.reallySignupOnNoErrors(makeTypedState(state)).next().value).toBeUndefined()
})
it('bails on inviteCodeError', () => {
const state = Constants.makeState({inviteCodeError: 'error'})
const state = {...Constants.makeState(), inviteCodeError: 'error'}
expect(_testing.reallySignupOnNoErrors(makeTypedState(state)).next().value).toBeUndefined()
})
it('bails on nameError', () => {
const state = Constants.makeState({nameError: 'error'})
const state = {...Constants.makeState(), nameError: 'error'}
expect(_testing.reallySignupOnNoErrors(makeTypedState(state)).next().value).toBeUndefined()
})
it('bails on usernameError', () => {
const state = Constants.makeState({usernameError: 'error'})
const state = {...Constants.makeState(), usernameError: 'error'}
expect(_testing.reallySignupOnNoErrors(makeTypedState(state)).next().value).toBeUndefined()
})
it('bails on signupError', () => {
const state = Constants.makeState({signupError: new RPCError('error', 0)})
const state = {...Constants.makeState(), signupError: new RPCError('error', 0)}
expect(_testing.reallySignupOnNoErrors(makeTypedState(state)).next().value).toBeUndefined()
})

const validSignup = Constants.makeState({
const validSignup = {
...Constants.makeState(),
devicename: 'a valid devicename',
inviteCode: '1234566',
username: 'testuser',
})
}

const signupError = new Error('Missing data for signup')

it('bails on missing devicename', () => {
expect(() =>
_testing.reallySignupOnNoErrors(makeTypedState(validSignup.set('devicename', ''))).next()
_testing.reallySignupOnNoErrors(makeTypedState({...validSignup, devicename: ''})).next()
).toThrow(signupError)
})
it('bails on missing inviteCode', () => {
expect(() =>
_testing.reallySignupOnNoErrors(makeTypedState(validSignup.set('inviteCode', ''))).next()
_testing.reallySignupOnNoErrors(makeTypedState({...validSignup, inviteCode: ''})).next()
).toThrow(signupError)
})
it('bails on missing username', () => {
expect(() =>
_testing.reallySignupOnNoErrors(makeTypedState(validSignup.set('username', ''))).next()
_testing.reallySignupOnNoErrors(makeTypedState({...validSignup, username: ''})).next()
).toThrow(signupError)
})
it('updates error', () => {
Expand Down
28 changes: 12 additions & 16 deletions shared/constants/signup.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
import * as I from 'immutable'
import * as Types from './types/signup'
import {isAndroid, isIOS, isDarwin, isWindows, isLinux, isMobile} from './platform'
import * as Platforms from '../constants/platform'
import HiddenString from '../util/hidden-string'

export const maxUsernameLength = 16
export const usernameHint =
'Usernames must be 2-16 characters, and can only contain letters, numbers, and underscores.'

const devicename =
(isAndroid && 'My Android Device') ||
(isIOS && 'My iOS Device') ||
(isDarwin && 'My Mac Device') ||
(isWindows && 'My Windows Device') ||
(isLinux && 'My Linux Device') ||
(isMobile ? 'Mobile Device' : 'Home Computer')

export const noEmail = 'NOEMAIL'
export const waitingKey = 'signup:waiting'

export const makeState = I.Record<Types._State>({
devicename,
const defaultDevicename =
(Platforms.isAndroid && 'My Android Device') ||
(Platforms.isIOS && 'My iOS Device') ||
(Platforms.isDarwin && 'My Mac Device') ||
(Platforms.isWindows && 'My Windows Device') ||
(Platforms.isLinux && 'My Linux Device') ||
(Platforms.isMobile ? 'Mobile Device' : 'Home Computer')

export const makeState = (): Types.State => ({
devicename: defaultDevicename,
devicenameError: '',
email: '',
emailError: '',
Expand All @@ -30,10 +29,7 @@ export const makeState = I.Record<Types._State>({
nameError: '',
password: new HiddenString(''),
passwordError: new HiddenString(''),
signupError: null,
username: '',
usernameError: '',
usernameTaken: '',
})

export const waitingKey = 'signup:waiting'
9 changes: 3 additions & 6 deletions shared/constants/types/signup.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import * as I from 'immutable'
import HiddenString from '../../util/hidden-string'
import {RPCError} from '../../util/errors'

export type AutoInviteRequestState = 'NotRequested' | 'Requested' | 'Done'

export type _State = {
export type State = Readonly<{
devicename: string
devicenameError: string
email: string
Expand All @@ -17,10 +16,8 @@ export type _State = {
nameError: string
password: HiddenString
passwordError: HiddenString
signupError: RPCError | null
signupError?: RPCError
username: string
usernameError: string
usernameTaken: string
}

export type State = I.RecordOf<_State>
}>
Loading

0 comments on commit ca2ac8a

Please sign in to comment.