@@ -7,7 +7,7 @@ import {insecureRandomId} from '../utils/ids'
7
7
import { getProjectionState } from './getProjectionState'
8
8
import { type ProjectionStoreState } from './projectionStore'
9
9
import { subscribeToStateAndFetchBatches } from './subscribeToStateAndFetchBatches'
10
- import { STABLE_EMPTY_PROJECTION } from './util'
10
+ import { PROJECTION_STATE_CLEAR_DELAY , STABLE_EMPTY_PROJECTION } from './util'
11
11
12
12
vi . mock ( '../utils/ids' , async ( importOriginal ) => {
13
13
const util = await importOriginal < typeof import ( '../utils/ids' ) > ( )
@@ -30,10 +30,12 @@ describe('getProjectionState', () => {
30
30
} )
31
31
32
32
instance = createSanityInstance ( { projectId : 'exampleProject' , dataset : 'exampleDataset' } )
33
+ vi . useFakeTimers ( ) // Enable fake timers for each test
33
34
} )
34
35
35
36
afterEach ( ( ) => {
36
37
instance . dispose ( )
38
+ vi . useRealTimers ( ) // Restore real timers after each test
37
39
} )
38
40
39
41
it ( 'returns a state source that emits when the projection value changes' , ( ) => {
@@ -70,27 +72,33 @@ describe('getProjectionState', () => {
70
72
const projectionState = getProjectionState ( instance , { projection, ...docHandle } )
71
73
72
74
expect ( state . get ( ) . subscriptions ) . toEqual ( { } )
73
- vi . mocked ( insecureRandomId )
74
- . mockImplementationOnce ( ( ) => 'pseudoRandomId1' )
75
- . mockImplementationOnce ( ( ) => 'pseudoRandomId2' )
75
+ vi . mocked ( insecureRandomId ) . mockImplementationOnce ( ( ) => 'pseudoRandomId1' )
76
76
77
77
const unsubscribe1 = projectionState . subscribe ( vi . fn ( ) )
78
- const unsubscribe2 = projectionState . subscribe ( vi . fn ( ) )
79
78
80
79
expect ( state . get ( ) . subscriptions ) . toEqual ( {
81
- exampleId : { pseudoRandomId1 : true , pseudoRandomId2 : true } ,
80
+ exampleId : { pseudoRandomId1 : true } ,
82
81
} )
83
82
expect ( state . get ( ) . documentProjections ) . toEqual ( {
84
83
exampleId : projection ,
85
84
} )
86
85
87
- unsubscribe2 ( )
86
+ // Unsubscribe the last one - state should NOT clear immediately
87
+ unsubscribe1 ( )
88
88
expect ( state . get ( ) . subscriptions ) . toEqual ( {
89
89
exampleId : { pseudoRandomId1 : true } ,
90
90
} )
91
+ // Projection data might also remain initially
92
+ expect ( state . get ( ) . documentProjections ) . toEqual ( {
93
+ exampleId : projection ,
94
+ } )
91
95
92
- unsubscribe1 ( )
96
+ // Advance timers past the clear delay
97
+ vi . advanceTimersByTime ( PROJECTION_STATE_CLEAR_DELAY )
98
+
99
+ // NOW the state related to this document should be cleared
93
100
expect ( state . get ( ) . subscriptions ) . toEqual ( { } )
101
+ expect ( state . get ( ) . documentProjections ) . toEqual ( { exampleId : projection } )
94
102
} )
95
103
96
104
it ( 'resets to pending false on unsubscribe if the subscription is the last one' , ( ) => {
@@ -101,24 +109,35 @@ describe('getProjectionState', () => {
101
109
} ) )
102
110
103
111
const unsubscribe1 = projectionState . subscribe ( vi . fn ( ) )
104
- const unsubscribe2 = projectionState . subscribe ( vi . fn ( ) )
105
112
106
113
expect ( state . get ( ) . values [ docHandle . documentId ] ) . toEqual ( {
107
114
data : { field : 'Foo' } ,
108
115
isPending : true ,
109
116
} )
110
117
118
+ // Unsubscribe one - pending state remains
111
119
unsubscribe1 ( )
112
120
expect ( state . get ( ) . values [ docHandle . documentId ] ) . toEqual ( {
113
121
data : { field : 'Foo' } ,
114
122
isPending : true ,
115
123
} )
116
124
117
- unsubscribe2 ( )
118
- expect ( state . get ( ) . subscriptions ) . toEqual ( { } )
125
+ // Unsubscribe the last one - pending state should NOT reset immediately
126
+ expect ( Object . keys ( state . get ( ) . subscriptions [ 'exampleId' ] || { } ) . length ) . toBeGreaterThan ( 0 )
119
127
expect ( state . get ( ) . values [ docHandle . documentId ] ) . toEqual ( {
120
128
data : { field : 'Foo' } ,
121
- isPending : false ,
129
+ isPending : true , // Still pending
122
130
} )
131
+
132
+ // Advance timers past the clear delay
133
+ vi . advanceTimersByTime ( PROJECTION_STATE_CLEAR_DELAY )
134
+
135
+ // NOW the pending state should be reset
136
+ expect ( state . get ( ) . values [ docHandle . documentId ] ) . toEqual ( {
137
+ data : { field : 'Foo' } ,
138
+ isPending : false , // Reset to false
139
+ } )
140
+ // And subscriptions should be cleared now
141
+ expect ( state . get ( ) . subscriptions ) . toEqual ( { } )
123
142
} )
124
143
} )
0 commit comments