@rsweeten/dropbox-sync
Version:
Reusable Dropbox synchronization module with framework adapters
129 lines (109 loc) • 4.73 kB
text/typescript
import { createDropboxSyncClient } from '../client'
import { createAuthMethods } from '../auth'
import { createSyncMethods } from '../sync'
import { createSocketMethods } from '../socket'
// First setup all the mocks before importing the actual code
let dropboxInstanceCreated = false
// Mock the auth module to return a mock auth object that requires client initialization
jest.mock('../auth', () => ({
createAuthMethods: jest.fn().mockImplementation((getClient) => ({
mockAuth: true,
getAuthUrl: jest.fn().mockImplementation((redirectUri) => {
// This will force the getClient() function to be called
getClient()
return Promise.resolve('https://dropbox.com/oauth')
}),
})),
}))
jest.mock('../sync', () => ({
createSyncMethods: jest.fn().mockReturnValue({ mockSync: true }),
}))
jest.mock('../socket', () => ({
createSocketMethods: jest.fn().mockReturnValue({ mockSocket: true }),
}))
// Mock Dropbox constructor and track constructor options
interface DropboxOptions {
accessToken?: string
clientId?: string
}
const mockDropboxOptions: DropboxOptions[] = []
const mockDropboxClient = {
auth: {
getAuthenticationUrl: jest.fn(),
getAccessTokenFromCode: jest.fn(),
},
filesListFolder: jest.fn(),
filesUpload: jest.fn(),
filesDownload: jest.fn(),
}
// Mock the Dropbox class
jest.mock('dropbox', () => {
return {
Dropbox: jest.fn().mockImplementation((options: DropboxOptions) => {
mockDropboxOptions.push(options)
dropboxInstanceCreated = true
return mockDropboxClient
}),
}
})
describe('createDropboxSyncClient', () => {
beforeEach(() => {
jest.clearAllMocks()
mockDropboxOptions.length = 0
dropboxInstanceCreated = false
})
it('should create a client with accessToken', async () => {
const credentials = { clientId: 'test-id', accessToken: 'test-token' }
const client = createDropboxSyncClient(credentials)
expect(client).toHaveProperty('auth')
expect(client).toHaveProperty('sync')
expect(client).toHaveProperty('socket')
// Force client instantiation by calling getAuthUrl which calls getClient internally
await client.auth.getAuthUrl('https://example.com/callback')
// Check that Dropbox was constructed with the correct options
expect(dropboxInstanceCreated).toBe(true)
expect(mockDropboxOptions.length).toBe(1)
expect(mockDropboxOptions[0]).toEqual({ accessToken: 'test-token' })
expect(createAuthMethods).toHaveBeenCalled()
expect(createSyncMethods).toHaveBeenCalled()
expect(createSocketMethods).toHaveBeenCalled()
})
it('should create a client with clientId when accessToken is not provided', async () => {
const credentials = { clientId: 'test-id' }
const client = createDropboxSyncClient(credentials)
expect(client).toHaveProperty('auth')
expect(client).toHaveProperty('sync')
expect(client).toHaveProperty('socket')
// Force client instantiation by calling getAuthUrl which calls getClient internally
await client.auth.getAuthUrl('https://example.com/callback')
// Check that Dropbox was constructed with the correct options
expect(dropboxInstanceCreated).toBe(true)
expect(mockDropboxOptions.length).toBe(1)
expect(mockDropboxOptions[0]).toEqual({ clientId: 'test-id' })
expect(createAuthMethods).toHaveBeenCalled()
expect(createSyncMethods).toHaveBeenCalled()
expect(createSocketMethods).toHaveBeenCalled()
})
it('should throw error if neither clientId nor accessToken is provided', async () => {
// Mock the auth implementation for this test specifically
;(createAuthMethods as jest.Mock).mockImplementationOnce(
(getClient) => ({
getAuthUrl: jest.fn().mockImplementation(() => {
// This will throw when called with empty credentials
try {
getClient()
} catch (error) {
return Promise.reject(error)
}
return Promise.resolve('https://dropbox.com/oauth')
}),
})
)
const credentials = {} as any
const client = createDropboxSyncClient(credentials)
// This should throw when getClient() is called inside getAuthUrl
await expect(
client.auth.getAuthUrl('https://example.com/callback')
).rejects.toThrow('Either clientId or accessToken must be provided')
})
})