Skip to content

Commit

Permalink
[SDK-1911] Always use UsernamePane when using custom resolver (auth0#…
Browse files Browse the repository at this point in the history
…1918)

* Always use UsernamePane when using custom resolver

* Add tests for connectionResolver filter
  • Loading branch information
Steve Hobbs authored Sep 11, 2020
1 parent f73f6f5 commit a00ed70
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 4 deletions.
32 changes: 31 additions & 1 deletion src/__tests__/connection/database/index.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import Immutable, { List, Map } from 'immutable';
import { databaseUsernameValue, initDatabase } from '../../../connection/database';
import {
databaseUsernameValue,
initDatabase,
databaseUsernameStyle
} from '../../../connection/database';

describe('database/index.js', () => {
describe('databaseUsernameValue', () => {
Expand Down Expand Up @@ -60,6 +64,32 @@ describe('database/index.js', () => {
});
});
});

describe('databaseUsernameStyle', () => {
beforeEach(() => {
jest.resetAllMocks();
});

it('it should resolve to "username" if a connectionResolver is present', () => {
const model = Immutable.fromJS({
core: {
connectionResolver: () => true,
transient: {
connections: {
database: [
{
requireUsername: false
}
]
}
}
}
});

expect(databaseUsernameStyle(model)).toBe('username');
});
});

describe('initDatabase', () => {
describe('calls initNS with the correct additionalSignUpFields', () => {
describe('uses the `storage` attribute', () => {
Expand Down
31 changes: 31 additions & 0 deletions src/__tests__/field/__snapshots__/login_pane.test.jsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,37 @@ exports[`LoginPane shows header when instructions is not empty 1`] = `
</div>
`;

exports[`LoginPane shows username pane when connectionResolver is specified, even if usernameStyle is email 1`] = `
<div>
<div
data-__type="username_pane"
data-i18n={Object {}}
data-lock={Object {}}
data-placeholder="usernameInputPlaceholder"
data-usernameStyle="email"
data-validateFormat={false}
/>
<div
data-__type="password_pane"
data-hidden={false}
data-i18n={Object {}}
data-lock={Object {}}
data-placeholder="passwordInputPlaceholder"
/>
<p
className="auth0-lock-alternative"
>
<a
className="auth0-lock-alternative-link"
href="forgotPasswordLink"
onClick={undefined}
>
forgotPasswordAction
</a>
</p>
</div>
`;

exports[`LoginPane shows username pane when user usernameStyle !== email 1`] = `
<div>
<div
Expand Down
12 changes: 11 additions & 1 deletion src/__tests__/field/login_pane.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ jest.mock('connection/database/actions');
const mockId = 1;
jest.mock('core/index', () => ({
id: () => mockId,
captcha: () => undefined
captcha: () => undefined,
connectionResolver: jest.fn()
}));

import LoginPane from 'connection/database/login_pane';
Expand All @@ -30,12 +31,17 @@ describe('LoginPane', () => {
usernameInputPlaceholder: 'usernameInputPlaceholder'
};
const databaseIndexMock = require('connection/database/index');
const coreMock = require('core/index');

beforeEach(() => {
databaseIndexMock.hasScreen.mockImplementation(() => true);
databaseIndexMock.forgotPasswordLink.mockImplementation(() => 'forgotPasswordLink');
});

afterEach(() => {
jest.resetAllMocks();
});

it('renders correctly', () => {
expectComponent(<LoginPane {...defaultProps} />).toMatchSnapshot();
});
Expand All @@ -45,6 +51,10 @@ describe('LoginPane', () => {
it('shows email pane when user usernameStyle === email', () => {
expectComponent(<LoginPane {...defaultProps} usernameStyle="email" />).toMatchSnapshot();
});
it('shows username pane when connectionResolver is specified, even if usernameStyle is email', () => {
coreMock.connectionResolver.mockImplementation(() => () => true);
expectComponent(<LoginPane {...defaultProps} usernameStyle="email" />).toMatchSnapshot();
});
it('shows username pane when user usernameStyle !== email', () => {
expectComponent(<LoginPane {...defaultProps} usernameStyle="any" />).toMatchSnapshot();
expectComponent(<LoginPane {...defaultProps} usernameStyle="username" />).toMatchSnapshot();
Expand Down
4 changes: 4 additions & 0 deletions src/connection/database/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,10 @@ export function databaseConnectionRequiresUsername(m) {

export function databaseUsernameStyle(m) {
if (l.hasSomeConnections(m, 'database')) {
if (l.connectionResolver(m)) {
return 'username';
}

return databaseConnectionRequiresUsername(m) ? get(m, 'usernameStyle', 'any') : 'email';
}

Expand Down
7 changes: 5 additions & 2 deletions src/connection/database/login_pane.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,13 @@ export default class LoginPane extends React.Component {

const headerText = instructions || null;
const header = headerText && <p>{headerText}</p>;
const resolver = l.connectionResolver(lock);

// Should never validate format on login because of custom db connection and import mode
// Should never validate format on login because of custom db connection and import mode.
// If a custom resolver is in use, always use UsernamePane without validating format,
// as the target connection (and this validation rules) could change by time the user hits 'submit'.
const fieldPane =
usernameStyle === 'email' ? (
usernameStyle === 'email' && resolver === undefined ? (
<EmailPane
i18n={i18n}
lock={lock}
Expand Down

0 comments on commit a00ed70

Please sign in to comment.