Skip to content

Commit 16fdb74

Browse files
committed
Clean and test
1 parent 1dac66f commit 16fdb74

File tree

5 files changed

+219
-3
lines changed

5 files changed

+219
-3
lines changed

packages/bolt-connection/test/connection-provider/authorization-provider.test.js renamed to packages/bolt-connection/test/connection-provider/authentication-provider.test.js

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,41 @@ describe('AuthenticationProvider', () => {
454454
expect(connection.connect).not.toHaveBeenCalledWith(USER_AGENT, auth)
455455
})
456456

457+
it('should not call connection connect with the supplied auth and skipReAuth=true', async () => {
458+
const auth = { scheme: 'bearer', credentials: 'my token' }
459+
const authTokenProvider = jest.fn(() => toRenewableToken({}))
460+
const authenticationProvider = createAuthenticationProvider(authTokenProvider)
461+
const connection = mockConnection({ supportsReAuth, authToken: { ...auth } })
462+
463+
await authenticationProvider.authenticate({ connection, auth, skipReAuth: true })
464+
465+
expect(connection.connect).not.toHaveBeenCalledWith(USER_AGENT, auth)
466+
})
467+
468+
if (supportsReAuth) {
469+
it('should call connection connect with the supplied auth if forceReAuth=true', async () => {
470+
const auth = { scheme: 'bearer', credentials: 'my token' }
471+
const authTokenProvider = jest.fn(() => toRenewableToken({}))
472+
const authenticationProvider = createAuthenticationProvider(authTokenProvider)
473+
const connection = mockConnection({ supportsReAuth, authToken: { scheme: 'bearer', credentials: 'other' } })
474+
475+
await authenticationProvider.authenticate({ connection, auth, forceReAuth: true })
476+
477+
expect(connection.connect).toHaveBeenCalledWith(USER_AGENT, auth, false)
478+
})
479+
} else {
480+
it('should not call connection connect with the supplied auth if forceReAuth=true', async () => {
481+
const auth = { scheme: 'bearer', credentials: 'my token' }
482+
const authTokenProvider = jest.fn(() => toRenewableToken({}))
483+
const authenticationProvider = createAuthenticationProvider(authTokenProvider)
484+
const connection = mockConnection({ supportsReAuth, authToken: { ...auth } })
485+
486+
await authenticationProvider.authenticate({ connection, auth, forceReAuth: true })
487+
488+
expect(connection.connect).not.toHaveBeenCalledWith(USER_AGENT, auth)
489+
})
490+
}
491+
457492
it('should return the connection', async () => {
458493
const auth = { scheme: 'bearer', credentials: 'my token' }
459494
const authTokenProvider = jest.fn(() => toRenewableToken({}))
@@ -520,6 +555,33 @@ describe('AuthenticationProvider', () => {
520555

521556
await expect(authenticationProvider.authenticate({ connection, auth })).rejects.toThrow(error)
522557
})
558+
559+
it.each([
560+
[true, true],
561+
[false, false],
562+
[undefined, false],
563+
[null, false]
564+
])('should redirect `waitReAuth=%s` as `%s` to the connection.connect()', async (waitReAuth, expectedWaitForReAuth) => {
565+
const auth = { scheme: 'bearer', credentials: 'my token' }
566+
const authTokenProvider = jest.fn(() => toRenewableToken({}))
567+
const authenticationProvider = createAuthenticationProvider(authTokenProvider)
568+
const connection = mockConnection({ supportsReAuth, authToken: { scheme: 'bearer', credentials: 'other' } })
569+
570+
await authenticationProvider.authenticate({ connection, auth, waitReAuth })
571+
572+
expect(connection.connect).toHaveBeenCalledWith(USER_AGENT, auth, expectedWaitForReAuth)
573+
})
574+
575+
it('should not call connect when skipReAuth=true', async () => {
576+
const auth = { scheme: 'bearer', credentials: 'my token' }
577+
const authTokenProvider = jest.fn(() => toRenewableToken({}))
578+
const authenticationProvider = createAuthenticationProvider(authTokenProvider)
579+
const connection = mockConnection({ supportsReAuth, authToken: { scheme: 'bearer', credentials: 'other' } })
580+
581+
await authenticationProvider.authenticate({ connection, auth, skipReAuth: true })
582+
583+
expect(connection.connect).not.toBeCalled()
584+
})
523585
})
524586

525587
describe.each([false])('and connection is authenticated with different token (supportsReAuth=%s)', (supportsReAuth) => {
@@ -534,6 +596,17 @@ describe('AuthenticationProvider', () => {
534596
expect(connection.connect).not.toHaveBeenCalledWith(USER_AGENT, auth)
535597
})
536598

599+
it('should not call connection connect with the supplied auth and forceReAuth=true', async () => {
600+
const auth = { scheme: 'bearer', credentials: 'my token' }
601+
const authTokenProvider = jest.fn(() => toRenewableToken({}))
602+
const authenticationProvider = createAuthenticationProvider(authTokenProvider)
603+
const connection = mockConnection({ supportsReAuth, authToken: { ...auth, credentials: 'other' } })
604+
605+
await authenticationProvider.authenticate({ connection, auth, forceReAuth: true })
606+
607+
expect(connection.connect).not.toHaveBeenCalledWith(USER_AGENT, auth)
608+
})
609+
537610
it('should return the connection', async () => {
538611
const auth = { scheme: 'bearer', credentials: 'my token' }
539612
const authTokenProvider = jest.fn(() => toRenewableToken({}))

packages/bolt-connection/test/connection-provider/connection-provider-direct.test.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,24 @@ describe('constructor', () => {
334334
`The connection ${connection.id} is not valid because of an error ${error.code} '${error.message}'`
335335
)
336336
})
337+
338+
it.each([
339+
true,
340+
false
341+
])('should call authenticationProvider.authenticate with skipReAuth=%s', async (skipReAuth) => {
342+
const connection = new FakeConnection(server0)
343+
const auth = {}
344+
connection.creationTimestamp = Date.now()
345+
346+
const { validateOnAcquire, authenticationProviderHook } = setup()
347+
348+
await expect(validateOnAcquire({ auth, skipReAuth }, connection)).resolves.toBe(true)
349+
350+
expect(authenticationProviderHook.authenticate).toHaveBeenCalledWith({
351+
connection, auth, skipReAuth
352+
})
353+
})
354+
337355
it('should return false when connection is closed and within the lifetime', async () => {
338356
const connection = new FakeConnection(server0)
339357
connection.creationTimestamp = Date.now()

packages/bolt-connection/test/connection-provider/connection-provider-routing.test.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3174,6 +3174,24 @@ describe.each([
31743174
`The connection ${connection.id} is not valid because of an error ${error.code} '${error.message}'`
31753175
)
31763176
})
3177+
3178+
it.each([
3179+
true,
3180+
false
3181+
])('should call authenticationProvider.authenticate with skipReAuth=%s', async (skipReAuth) => {
3182+
const connection = new FakeConnection(server0)
3183+
const auth = {}
3184+
connection.creationTimestamp = Date.now()
3185+
3186+
const { validateOnAcquire, authenticationProviderHook } = setup()
3187+
3188+
await expect(validateOnAcquire({ auth, skipReAuth }, connection)).resolves.toBe(true)
3189+
3190+
expect(authenticationProviderHook.authenticate).toHaveBeenCalledWith({
3191+
connection, auth, skipReAuth
3192+
})
3193+
})
3194+
31773195
it('should return false when connection is closed and within the lifetime', async () => {
31783196
const connection = new FakeConnection(server0)
31793197
connection.creationTimestamp = Date.now()

packages/bolt-connection/test/connection/connection-channel.test.js

Lines changed: 108 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
import ChannelConnection from '../../src/connection/connection-channel'
2121
import { int, internal, newError } from 'neo4j-driver-core'
22-
2322
const {
2423
serverAddress: { ServerAddress },
2524
logger: { Logger }
@@ -164,6 +163,114 @@ describe('ChannelConnection', () => {
164163
expect(protocol.login).toHaveBeenCalledWith({ authToken, flush: true })
165164
expect(connection.authToken).toEqual(authToken)
166165
})
166+
167+
describe('when waitReAuth=true', () => {
168+
it('should wait for login complete', async () => {
169+
const authToken = {
170+
scheme: 'none'
171+
}
172+
173+
const onCompleteObservers = []
174+
const protocol = {
175+
initialize: jest.fn(observer => observer.onComplete({})),
176+
logoff: jest.fn(() => undefined),
177+
login: jest.fn(({ onComplete }) => onCompleteObservers.push(onComplete)),
178+
initialized: true,
179+
supportsLogoff: true
180+
}
181+
182+
const protocolSupplier = () => protocol
183+
const connection = spyOnConnectionChannel({ protocolSupplier })
184+
185+
const connectionPromise = connection.connect('userAgent', authToken, true)
186+
187+
const isPending = await Promise.race([connectionPromise, Promise.resolve(true)])
188+
expect(isPending).toEqual(true)
189+
expect(onCompleteObservers.length).toEqual(1)
190+
191+
expect(protocol.initialize).not.toHaveBeenCalled()
192+
expect(protocol.logoff).toHaveBeenCalled()
193+
expect(protocol.login).toHaveBeenCalledWith(expect.objectContaining({
194+
authToken,
195+
flush: true
196+
}))
197+
198+
expect(connection.authToken).toEqual(authToken)
199+
200+
onCompleteObservers.forEach(onComplete => onComplete({}))
201+
await expect(connectionPromise).resolves.toBe(connection)
202+
})
203+
204+
it('should notify logoff errors', async () => {
205+
const authToken = {
206+
scheme: 'none'
207+
}
208+
209+
const onLogoffErrors = []
210+
const protocol = {
211+
initialize: jest.fn(observer => observer.onComplete({})),
212+
logoff: jest.fn(({ onError }) => onLogoffErrors.push(onError)),
213+
login: jest.fn(() => undefined),
214+
initialized: true,
215+
supportsLogoff: true
216+
}
217+
218+
const protocolSupplier = () => protocol
219+
const connection = spyOnConnectionChannel({ protocolSupplier })
220+
221+
const connectionPromise = connection.connect('userAgent', authToken, true)
222+
223+
const isPending = await Promise.race([connectionPromise, Promise.resolve(true)])
224+
expect(isPending).toEqual(true)
225+
expect(onLogoffErrors.length).toEqual(1)
226+
227+
expect(protocol.initialize).not.toHaveBeenCalled()
228+
expect(protocol.logoff).toHaveBeenCalled()
229+
expect(protocol.login).toHaveBeenCalledWith(expect.objectContaining({
230+
authToken,
231+
flush: true
232+
}))
233+
234+
const expectedError = newError('something wrong is not right.')
235+
onLogoffErrors.forEach(onError => onError(expectedError))
236+
await expect(connectionPromise).rejects.toBe(expectedError)
237+
})
238+
239+
it('should notify login errors', async () => {
240+
const authToken = {
241+
scheme: 'none'
242+
}
243+
244+
const onLoginErrors = []
245+
const protocol = {
246+
initialize: jest.fn(observer => observer.onComplete({})),
247+
logoff: jest.fn(() => undefined),
248+
login: jest.fn(({ onError }) => onLoginErrors.push(onError)),
249+
initialized: true,
250+
supportsLogoff: true
251+
}
252+
253+
const protocolSupplier = () => protocol
254+
const connection = spyOnConnectionChannel({ protocolSupplier })
255+
256+
const connectionPromise = connection.connect('userAgent', authToken, true)
257+
258+
const isPending = await Promise.race([connectionPromise, Promise.resolve(true)])
259+
expect(isPending).toEqual(true)
260+
expect(onLoginErrors.length).toEqual(1)
261+
262+
expect(protocol.initialize).not.toHaveBeenCalled()
263+
expect(protocol.logoff).toHaveBeenCalled()
264+
expect(protocol.login).toHaveBeenCalledWith(expect.objectContaining({
265+
authToken,
266+
flush: true
267+
}))
268+
269+
const expectedError = newError('something wrong is not right.')
270+
onLoginErrors.forEach(onError => onError(expectedError))
271+
await expect(connectionPromise).rejects.toBe(expectedError)
272+
})
273+
})
167274
})
168275

169276
describe('when protocol does not support re-auth', () => {

packages/core/src/auth-token-manager.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import { util } from './internal'
2424
/**
2525
* Interface for the piece of software responsible for keeping track of current active {@link AuthToken} across the driver.
2626
* @interface
27-
* @since 5.6
27+
* @since 5.7
2828
*/
2929
export default class AuthTokenManager {
3030
/**
@@ -44,7 +44,7 @@ export default class AuthTokenManager {
4444
/**
4545
* Interface which defines an {@link AuthToken} with an expiry data time associated
4646
* @interface
47-
* @since 5.6
47+
* @since 5.7
4848
*/
4949
export class TemporalAuthData {
5050
public readonly token: AuthToken

0 commit comments

Comments
 (0)