@rsweeten/dropbox-sync
Version:
Reusable Dropbox synchronization module with framework adapters
143 lines (125 loc) • 4.38 kB
text/typescript
import { createAuthMethods } from '../auth'
describe('createAuthMethods', () => {
const mockClient = {
auth: {
getAuthenticationUrl: jest
.fn()
.mockReturnValue('https://dropbox.com/auth'),
getAccessTokenFromCode: jest.fn().mockResolvedValue({
result: {
access_token: 'new-access-token',
refresh_token: 'new-refresh-token',
expires_in: 14400,
},
}),
},
}
const mockGetClient = jest.fn().mockReturnValue(mockClient)
const mockSetAccessToken = jest.fn()
const mockCredentials = {
clientId: 'test-client-id',
clientSecret: 'test-client-secret',
accessToken: 'test-access-token',
refreshToken: 'test-refresh-token',
}
beforeEach(() => {
jest.clearAllMocks()
// Mock fetch for refreshAccessToken method
global.fetch = jest.fn().mockResolvedValue({
ok: true,
json: jest.fn().mockResolvedValue({
access_token: 'refreshed-token',
refresh_token: 'new-refresh-token',
expires_in: 14400,
}),
})
})
it('should create auth methods object', () => {
const auth = createAuthMethods(
mockGetClient,
mockCredentials,
mockSetAccessToken
)
expect(auth).toHaveProperty('getAuthUrl')
expect(auth).toHaveProperty('exchangeCodeForToken')
expect(auth).toHaveProperty('refreshAccessToken')
})
it('should generate auth URL', async () => {
const auth = createAuthMethods(
mockGetClient,
mockCredentials,
mockSetAccessToken
)
const url = await auth.getAuthUrl(
'http://localhost/callback',
'test-state'
)
expect(mockGetClient).toHaveBeenCalled()
expect(mockClient.auth.getAuthenticationUrl).toHaveBeenCalledWith(
'http://localhost/callback',
'test-state',
'code',
'offline',
undefined,
undefined,
true
)
expect(url).toEqual('https://dropbox.com/auth')
})
it('should exchange code for token', async () => {
const auth = createAuthMethods(
mockGetClient,
mockCredentials,
mockSetAccessToken
)
const tokens = await auth.exchangeCodeForToken(
'auth-code',
'http://localhost/callback'
)
expect(mockGetClient).toHaveBeenCalled()
expect(mockClient.auth.getAccessTokenFromCode).toHaveBeenCalledWith(
'http://localhost/callback',
'auth-code'
)
expect(mockSetAccessToken).toHaveBeenCalledWith('new-access-token')
expect(tokens).toEqual({
accessToken: 'new-access-token',
refreshToken: 'new-refresh-token',
expiresAt: expect.any(Number),
})
})
it('should refresh access token', async () => {
const auth = createAuthMethods(
mockGetClient,
mockCredentials,
mockSetAccessToken
)
const tokens = await auth.refreshAccessToken()
expect(fetch).toHaveBeenCalledWith(
'https://api.dropboxapi.com/oauth2/token',
{
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: expect.stringContaining('grant_type=refresh_token'),
}
)
expect(mockSetAccessToken).toHaveBeenCalledWith('refreshed-token')
expect(tokens).toEqual({
accessToken: 'refreshed-token',
refreshToken: 'new-refresh-token',
expiresAt: expect.any(Number),
})
})
it('should throw error if refresh token is missing', async () => {
const auth = createAuthMethods(
mockGetClient,
{ clientId: 'test-id', clientSecret: 'test-secret' },
mockSetAccessToken
)
await expect(auth.refreshAccessToken()).rejects.toThrow(
'Refresh token, client ID, and client secret are required to refresh access token'
)
})
})