UNPKG

@sanity/sdk

Version:
162 lines (133 loc) 5.43 kB
import {createClient, type SanityClient} from '@sanity/client' import {Subject} from 'rxjs' import {beforeEach, describe, expect, it, vi} from 'vitest' import {getAuthMethodState, getTokenState} from '../auth/authStore' import {createSanityInstance, type SanityInstance} from '../store/createSanityInstance' import {getClient, getClientState} from './clientStore' // Mock dependencies vi.mock('@sanity/client') vi.mock('../auth/authStore') let instance: SanityInstance let authMethod$: Subject<'cookie' | 'localstorage' | undefined> beforeEach(() => { vi.resetAllMocks() // Initialize Subjects ONCE per test run before mocks use them authMethod$ = new Subject<'cookie' | 'localstorage' | undefined>() vi.mocked(getTokenState).mockReturnValue({ getCurrent: vi.fn().mockReturnValue('initial-token'), subscribe: vi.fn(), observable: new Subject(), }) vi.mocked(getAuthMethodState).mockReturnValue({ // Mock initial state value if needed by other parts of setup getCurrent: vi.fn().mockReturnValue(undefined), subscribe: vi.fn(), observable: authMethod$, // Consistently return the module-scope Subject }) vi.mocked(createClient).mockImplementation( (clientConfig) => ({config: () => clientConfig}) as SanityClient, ) instance = createSanityInstance({projectId: 'test-project', dataset: 'test-dataset'}) }) afterEach(() => { instance.dispose() }) describe('clientStore', () => { describe('getClient', () => { it('should create a client with default configuration', () => { const client = getClient(instance, {apiVersion: '2024-11-12'}) const defaultConfiguration = { useCdn: false, ignoreBrowserTokenWarning: true, allowReconfigure: false, requestTagPrefix: 'sanity.sdk', projectId: 'test-project', dataset: 'test-dataset', token: 'initial-token', } expect(vi.mocked(createClient)).toHaveBeenCalledWith({ ...defaultConfiguration, apiVersion: '2024-11-12', }) expect(client.config()).toEqual({ ...defaultConfiguration, apiVersion: '2024-11-12', }) }) it('should throw when using disallowed configuration keys', () => { expect(() => getClient(instance, { apiVersion: '2024-11-12', // @ts-expect-error Testing invalid key illegalKey: 'foo', }), ).toThrowError(/unsupported properties: illegalKey/) }) it('should reuse clients with identical configurations', () => { const options = {apiVersion: '2024-11-12', useCdn: true} const client1 = getClient(instance, options) const client2 = getClient(instance, options) expect(client1).toBe(client2) expect(vi.mocked(createClient)).toHaveBeenCalledTimes(1) }) it('should create new clients when configuration changes', () => { const client1 = getClient(instance, {apiVersion: '2024-11-12'}) const client2 = getClient(instance, {apiVersion: '2023-08-01'}) expect(client1).not.toBe(client2) expect(vi.mocked(createClient)).toHaveBeenCalledTimes(2) }) }) describe('token handling', () => { it('should reset clients when token changes', () => { // Initial client with first token const tokenState = getTokenState(instance) vi.mocked(tokenState.getCurrent).mockReturnValue('first-token') const client1 = getClient(instance, {apiVersion: '2024-11-12'}) // Simulate token change vi.mocked(tokenState.getCurrent).mockReturnValue('new-token') const token$ = tokenState.observable as Subject<string> token$.next('new-token') // New client should be created with new token const client2 = getClient(instance, {apiVersion: '2024-11-12'}) expect(client1).not.toBe(client2) expect(vi.mocked(createClient)).toHaveBeenCalledWith( expect.objectContaining({ token: 'new-token', }), ) }) }) describe('getClientState', () => { it('should provide a state source that emits client changes', async () => { // Get initial client state with a specific configuration const state = getClientState(instance, {apiVersion: '2024-11-12'}) // Get initial client const initialClient = state.getCurrent() expect(initialClient).toBeDefined() // Setup a spy to track emissions from the observable const nextSpy = vi.fn() const subscription = state.observable.subscribe(nextSpy) // Should have emitted once initially expect(nextSpy).toHaveBeenCalledTimes(1) expect(nextSpy).toHaveBeenCalledWith(initialClient) // Simulate token change const tokenState = getTokenState(instance) vi.mocked(tokenState.getCurrent).mockReturnValue('updated-token') const token$ = tokenState.observable as Subject<string> token$.next('updated-token') // Should emit a new client instance expect(nextSpy).toHaveBeenCalledTimes(2) // The new client should be different from the initial one const updatedClient = nextSpy.mock.calls[1][0] expect(updatedClient).not.toBe(initialClient) // The updated client should have the new token expect(updatedClient.config()).toEqual( expect.objectContaining({ token: 'updated-token', }), ) // Clean up subscription subscription.unsubscribe() }) }) })