diff --git a/src/__tests__/ui/box/container.test.jsx b/src/__tests__/ui/box/container.test.jsx index e248a1875..2695650e9 100644 --- a/src/__tests__/ui/box/container.test.jsx +++ b/src/__tests__/ui/box/container.test.jsx @@ -9,6 +9,10 @@ jest.mock('store/index', () => ({ jest.mock('ui/box/chrome', () => mockComponent('chrome')); +jest.mock('connection/database/index', () => ({ + databaseUsernameValue: jest.fn() +})); + const mockEvent = { preventDefault: () => {} }; @@ -75,14 +79,25 @@ describe('Container', () => { describe('with a custom `connectionResolver`', () => { let connectionResolverMock; let setResolvedConnectionMock; + let databaseUsernameValueMock; beforeEach(() => { connectionResolverMock = jest.fn(); setResolvedConnectionMock = jest.fn(); + databaseUsernameValueMock = require('connection/database/index').databaseUsernameValue; + + // Set default return value for databaseUsernameValue mock + databaseUsernameValueMock.mockReturnValue('peter_picked@pickledpepper.com'); + require('core/index').connectionResolver = () => connectionResolverMock; require('core/index').setResolvedConnection = setResolvedConnectionMock; }); + afterEach(() => { + // Reset mock between tests and restore default return value + databaseUsernameValueMock.mockReset().mockReturnValue('peter_picked@pickledpepper.com'); + }); + it('calls `connectionResolver` onSubmit', () => { const c = getContainer(); c.handleSubmit(mockEvent); @@ -110,6 +125,54 @@ describe('Container', () => { expect(mock.calls.length).toBe(1); expect(mock.calls[0]).toMatchSnapshot(); }); + + it('prioritizes email over username on signUp screen', () => { + databaseUsernameValueMock.mockReturnValue('test@example.com'); + + const c = getContainer({ screenName: 'main.signUp' }); + c.handleSubmit(mockEvent); + + // Should call databaseUsernameValue with emailFirst: true + expect(databaseUsernameValueMock).toHaveBeenCalledWith( + expect.anything(), + { emailFirst: true } + ); + + // connectionResolver should receive the email value + const { mock } = connectionResolverMock; + expect(mock.calls[0][0]).toBe('test@example.com'); + }); + + it('prioritizes username over email on login screen', () => { + databaseUsernameValueMock.mockReturnValue('testuser'); + + const c = getContainer({ screenName: 'main.login' }); + c.handleSubmit(mockEvent); + + // Should call databaseUsernameValue with empty options (default behavior) + expect(databaseUsernameValueMock).toHaveBeenCalledWith( + expect.anything(), + {} + ); + + // connectionResolver should receive the username value + const { mock } = connectionResolverMock; + expect(mock.calls[0][0]).toBe('testuser'); + }); + + it('uses default behavior when screenName is not main.signUp', () => { + databaseUsernameValueMock.mockReturnValue('defaultvalue'); + + const c = getContainer({ screenName: 'forgotPassword' }); + c.handleSubmit(mockEvent); + + // Should call databaseUsernameValue with empty options (default behavior) + expect(databaseUsernameValueMock).toHaveBeenCalledWith( + expect.anything(), + {} + ); + }); + }); describe('when suppressSubmitOverlay is true', () => { diff --git a/src/ui/box/container.jsx b/src/ui/box/container.jsx index 66fbf0e51..5d8b8ba5e 100644 --- a/src/ui/box/container.jsx +++ b/src/ui/box/container.jsx @@ -5,6 +5,7 @@ import { CloseButton } from './button'; import * as l from '../../core/index'; import * as c from '../../field/index'; import { swap, updateEntity } from '../../store/index'; +import { databaseUsernameValue } from '../../connection/database/index'; const badgeSvg = ( @@ -69,7 +70,7 @@ export default class Container extends React.Component { this.state = { isOpen: false }; } checkConnectionResolver(done) { - const { contentProps } = this.props; + const { contentProps, screenName } = this.props; const lock = contentProps.model; const connectionResolver = l.connectionResolver(lock); if (!connectionResolver) { @@ -77,7 +78,12 @@ export default class Container extends React.Component { } const { connections, id } = lock.get('client').toJS(); const context = { connections, id }; - const userInputValue = c.getFieldValue(lock, 'username') || c.getFieldValue(lock, 'email'); + + // On signUp screen, use emailFirst option to prioritize email over username + // On login screen, use default behavior (username first) + const isSignUpScreen = screenName === 'main.signUp'; + const userInputValue = databaseUsernameValue(lock, isSignUpScreen ? { emailFirst: true } : {}); + connectionResolver(userInputValue, context, resolvedConnection => { swap(updateEntity, 'lock', l.id(lock), m => l.setResolvedConnection(m, resolvedConnection)); done();