|
1 |
| -import {type SanityClient} from '@sanity/client' |
| 1 | +import {type SanityClient, type SanityUser as SanityUserFromClient} from '@sanity/client' |
2 | 2 | import {delay, filter, firstValueFrom, Observable, of} from 'rxjs'
|
3 | 3 | import {beforeEach, describe, expect, it, vi} from 'vitest'
|
4 | 4 |
|
5 |
| -import {getClientState} from '../client/clientStore' |
| 5 | +import {getClient, getClientState} from '../client/clientStore' |
6 | 6 | import {createSanityInstance} from '../store/createSanityInstance'
|
7 | 7 | import {type StateSource} from '../store/createStateSourceAction'
|
8 | 8 | import {type GetUsersOptions, type SanityUser, type SanityUserResponse} from './types'
|
9 |
| -import {getUsersState, loadMoreUsers, resolveUsers} from './usersStore' |
| 9 | +import {getUsersState, getUserState, loadMoreUsers, resolveUser, resolveUsers} from './usersStore' |
10 | 10 |
|
11 | 11 | vi.mock('./usersConstants', async (importOriginal) => ({
|
12 | 12 | ...(await importOriginal<typeof import('./usersConstants')>()),
|
@@ -64,13 +64,19 @@ describe('usersStore', () => {
|
64 | 64 | beforeEach(() => {
|
65 | 65 | request = vi.fn().mockReturnValue(of(mockResponse).pipe(delay(0)))
|
66 | 66 |
|
67 |
| - vi.mocked(getClientState).mockReturnValue({ |
68 |
| - observable: of({ |
69 |
| - observable: { |
70 |
| - request, |
71 |
| - }, |
72 |
| - } as SanityClient), |
73 |
| - } as StateSource<SanityClient>) |
| 67 | + vi.mocked(getClientState).mockImplementation(() => { |
| 68 | + const client = { |
| 69 | + observable: {request}, |
| 70 | + } as unknown as SanityClient |
| 71 | + return { |
| 72 | + observable: of(client), |
| 73 | + } as StateSource<SanityClient> |
| 74 | + }) |
| 75 | + vi.mocked(getClient).mockReturnValue({ |
| 76 | + observable: { |
| 77 | + request, |
| 78 | + }, |
| 79 | + } as unknown as SanityClient) |
74 | 80 | })
|
75 | 81 |
|
76 | 82 | it('initializes users state and cleans up after unsubscribe', async () => {
|
@@ -391,4 +397,108 @@ describe('usersStore', () => {
|
391 | 397 | unsubscribe2()
|
392 | 398 | instance.dispose()
|
393 | 399 | })
|
| 400 | + |
| 401 | + describe('getUserState', () => { |
| 402 | + beforeEach(() => { |
| 403 | + // Clear all mocks between tests |
| 404 | + vi.clearAllMocks() |
| 405 | + }) |
| 406 | + |
| 407 | + it('fetches a single user with a project-scoped ID', async () => { |
| 408 | + const instance = createSanityInstance({projectId: 'test', dataset: 'test'}) |
| 409 | + const projectUserId = 'p12345' |
| 410 | + const mockProjectUser: SanityUserFromClient = { |
| 411 | + id: projectUserId, |
| 412 | + displayName: 'Project User', |
| 413 | + createdAt: '2023-01-01T00:00:00Z', |
| 414 | + updatedAt: '2023-01-01T00:00:00Z', |
| 415 | + isCurrentUser: false, |
| 416 | + projectId: 'project1', |
| 417 | + familyName: null, |
| 418 | + givenName: null, |
| 419 | + middleName: null, |
| 420 | + imageUrl: null, |
| 421 | + } |
| 422 | + |
| 423 | + const specificRequest = vi.fn().mockReturnValue(of(mockProjectUser).pipe(delay(0))) |
| 424 | + vi.mocked(getClient).mockReturnValue({ |
| 425 | + observable: { |
| 426 | + request: specificRequest, |
| 427 | + }, |
| 428 | + } as unknown as SanityClient) |
| 429 | + |
| 430 | + const user$ = getUserState(instance, {userId: projectUserId, projectId: 'project1'}) |
| 431 | + |
| 432 | + const result = await firstValueFrom(user$.pipe(filter((i) => i !== undefined))) |
| 433 | + |
| 434 | + expect(getClient).toHaveBeenCalledWith( |
| 435 | + instance, |
| 436 | + expect.objectContaining({ |
| 437 | + projectId: 'project1', |
| 438 | + useProjectHostname: true, |
| 439 | + }), |
| 440 | + ) |
| 441 | + expect(specificRequest).toHaveBeenCalledWith({ |
| 442 | + method: 'GET', |
| 443 | + uri: `/users/${projectUserId}`, |
| 444 | + }) |
| 445 | + |
| 446 | + const expectedUser: SanityUser = { |
| 447 | + sanityUserId: projectUserId, |
| 448 | + profile: { |
| 449 | + id: projectUserId, |
| 450 | + displayName: 'Project User', |
| 451 | + familyName: undefined, |
| 452 | + givenName: undefined, |
| 453 | + middleName: undefined, |
| 454 | + imageUrl: undefined, |
| 455 | + createdAt: '2023-01-01T00:00:00Z', |
| 456 | + updatedAt: '2023-01-01T00:00:00Z', |
| 457 | + isCurrentUser: false, |
| 458 | + email: '', |
| 459 | + provider: '', |
| 460 | + }, |
| 461 | + memberships: [], |
| 462 | + } |
| 463 | + expect(result).toEqual(expectedUser) |
| 464 | + |
| 465 | + instance.dispose() |
| 466 | + }) |
| 467 | + |
| 468 | + it('fetches a single user with a global-scoped ID', async () => { |
| 469 | + const instance = createSanityInstance({ |
| 470 | + projectId: 'test', |
| 471 | + dataset: 'test', |
| 472 | + }) |
| 473 | + const globalUserId = 'g12345' |
| 474 | + const mockGlobalUser: SanityUser = { |
| 475 | + sanityUserId: globalUserId, |
| 476 | + profile: { |
| 477 | + id: 'profile-g1', |
| 478 | + displayName: 'Global User', |
| 479 | + |
| 480 | + provider: 'google', |
| 481 | + createdAt: '2023-01-01T00:00:00Z', |
| 482 | + }, |
| 483 | + memberships: [], |
| 484 | + } |
| 485 | + const mockGlobalUserResponse: SanityUserResponse = { |
| 486 | + data: [mockGlobalUser], |
| 487 | + totalCount: 1, |
| 488 | + nextCursor: null, |
| 489 | + } |
| 490 | + |
| 491 | + // Mock the request to return the global user response |
| 492 | + vi.mocked(request).mockReturnValue(of(mockGlobalUserResponse)) |
| 493 | + |
| 494 | + const result = await resolveUser(instance, { |
| 495 | + userId: globalUserId, |
| 496 | + projectId: 'project1', |
| 497 | + }) |
| 498 | + |
| 499 | + expect(result).toEqual(mockGlobalUser) |
| 500 | + |
| 501 | + instance.dispose() |
| 502 | + }) |
| 503 | + }) |
394 | 504 | })
|
0 commit comments