@@ -94,22 +94,22 @@ describe('OnyxKeys', () => {
9494
9595 describe ( 'isCollectionMember' , ( ) => {
9696 it ( 'should return true for collection member keys' , ( ) => {
97- expect ( OnyxKeys . isCollectionMember ( 'test_123' ) ) . toBe ( true ) ;
98- expect ( OnyxKeys . isCollectionMember ( 'test_level_456' ) ) . toBe ( true ) ;
99- expect ( OnyxKeys . isCollectionMember ( 'test_level_last_789' ) ) . toBe ( true ) ;
100- expect ( OnyxKeys . isCollectionMember ( 'test_ -1_something' ) ) . toBe ( true ) ;
101- expect ( OnyxKeys . isCollectionMember ( 'routes_abc' ) ) . toBe ( true ) ;
97+ expect ( OnyxKeys . isCollectionMember ( ` ${ ONYXKEYS . COLLECTION . TEST_KEY } 123` ) ) . toBe ( true ) ;
98+ expect ( OnyxKeys . isCollectionMember ( ` ${ ONYXKEYS . COLLECTION . TEST_LEVEL_KEY } 456` ) ) . toBe ( true ) ;
99+ expect ( OnyxKeys . isCollectionMember ( ` ${ ONYXKEYS . COLLECTION . TEST_LEVEL_LAST_KEY } 789` ) ) . toBe ( true ) ;
100+ expect ( OnyxKeys . isCollectionMember ( ` ${ ONYXKEYS . COLLECTION . TEST_KEY } -1_something` ) ) . toBe ( true ) ;
101+ expect ( OnyxKeys . isCollectionMember ( ` ${ ONYXKEYS . COLLECTION . ROUTES } abc` ) ) . toBe ( true ) ;
102102 } ) ;
103103
104104 it ( 'should return false for collection keys themselves' , ( ) => {
105- expect ( OnyxKeys . isCollectionMember ( 'test_' ) ) . toBe ( false ) ;
106- expect ( OnyxKeys . isCollectionMember ( 'test_level_' ) ) . toBe ( false ) ;
107- expect ( OnyxKeys . isCollectionMember ( 'test_level_last_' ) ) . toBe ( false ) ;
108- expect ( OnyxKeys . isCollectionMember ( 'routes_' ) ) . toBe ( false ) ;
105+ expect ( OnyxKeys . isCollectionMember ( ONYXKEYS . COLLECTION . TEST_KEY ) ) . toBe ( false ) ;
106+ expect ( OnyxKeys . isCollectionMember ( ONYXKEYS . COLLECTION . TEST_LEVEL_KEY ) ) . toBe ( false ) ;
107+ expect ( OnyxKeys . isCollectionMember ( ONYXKEYS . COLLECTION . TEST_LEVEL_LAST_KEY ) ) . toBe ( false ) ;
108+ expect ( OnyxKeys . isCollectionMember ( ONYXKEYS . COLLECTION . ROUTES ) ) . toBe ( false ) ;
109109 } ) ;
110110
111111 it ( 'should return false for non-collection keys' , ( ) => {
112- expect ( OnyxKeys . isCollectionMember ( 'test' ) ) . toBe ( false ) ;
112+ expect ( OnyxKeys . isCollectionMember ( ONYXKEYS . TEST_KEY ) ) . toBe ( false ) ;
113113 expect ( OnyxKeys . isCollectionMember ( 'someRegularKey' ) ) . toBe ( false ) ;
114114 expect ( OnyxKeys . isCollectionMember ( 'notACollection' ) ) . toBe ( false ) ;
115115 expect ( OnyxKeys . isCollectionMember ( '' ) ) . toBe ( false ) ;
@@ -122,6 +122,205 @@ describe('OnyxKeys', () => {
122122 } ) ;
123123 } ) ;
124124
125+ describe ( 'isCollectionKey' , ( ) => {
126+ it ( 'should return true for registered collection keys' , ( ) => {
127+ expect ( OnyxKeys . isCollectionKey ( ONYXKEYS . COLLECTION . TEST_KEY ) ) . toBe ( true ) ;
128+ expect ( OnyxKeys . isCollectionKey ( ONYXKEYS . COLLECTION . TEST_LEVEL_KEY ) ) . toBe ( true ) ;
129+ expect ( OnyxKeys . isCollectionKey ( ONYXKEYS . COLLECTION . ROUTES ) ) . toBe ( true ) ;
130+ } ) ;
131+
132+ it ( 'should return false for non-collection keys' , ( ) => {
133+ expect ( OnyxKeys . isCollectionKey ( ONYXKEYS . TEST_KEY ) ) . toBe ( false ) ;
134+ expect ( OnyxKeys . isCollectionKey ( '' ) ) . toBe ( false ) ;
135+ } ) ;
136+
137+ it ( 'should return false for collection member keys' , ( ) => {
138+ expect ( OnyxKeys . isCollectionKey ( `${ ONYXKEYS . COLLECTION . TEST_KEY } 123` ) ) . toBe ( false ) ;
139+ expect ( OnyxKeys . isCollectionKey ( `${ ONYXKEYS . COLLECTION . ROUTES } abc` ) ) . toBe ( false ) ;
140+ } ) ;
141+ } ) ;
142+
143+ describe ( 'isCollectionMemberKey' , ( ) => {
144+ it ( 'should return true when key starts with collection key and is longer' , ( ) => {
145+ expect ( OnyxKeys . isCollectionMemberKey ( ONYXKEYS . COLLECTION . TEST_KEY , `${ ONYXKEYS . COLLECTION . TEST_KEY } 123` ) ) . toBe ( true ) ;
146+ expect ( OnyxKeys . isCollectionMemberKey ( ONYXKEYS . COLLECTION . TEST_LEVEL_KEY , `${ ONYXKEYS . COLLECTION . TEST_LEVEL_KEY } 456` ) ) . toBe ( true ) ;
147+ expect ( OnyxKeys . isCollectionMemberKey ( ONYXKEYS . COLLECTION . ROUTES , `${ ONYXKEYS . COLLECTION . ROUTES } abc` ) ) . toBe ( true ) ;
148+ } ) ;
149+
150+ it ( 'should return false when key equals the collection key exactly' , ( ) => {
151+ expect ( OnyxKeys . isCollectionMemberKey ( ONYXKEYS . COLLECTION . TEST_KEY , ONYXKEYS . COLLECTION . TEST_KEY ) ) . toBe ( false ) ;
152+ expect ( OnyxKeys . isCollectionMemberKey ( ONYXKEYS . COLLECTION . ROUTES , ONYXKEYS . COLLECTION . ROUTES ) ) . toBe ( false ) ;
153+ } ) ;
154+
155+ it ( 'should return false when key does not start with collection key' , ( ) => {
156+ expect ( OnyxKeys . isCollectionMemberKey ( ONYXKEYS . COLLECTION . TEST_KEY , `${ ONYXKEYS . COLLECTION . ROUTES } 123` ) ) . toBe ( false ) ;
157+ expect ( OnyxKeys . isCollectionMemberKey ( ONYXKEYS . COLLECTION . TEST_LEVEL_KEY , `${ ONYXKEYS . COLLECTION . TEST_KEY } 123` ) ) . toBe ( false ) ;
158+ } ) ;
159+ } ) ;
160+
161+ describe ( 'isKeyMatch' , ( ) => {
162+ it ( 'should match exact non-collection keys' , ( ) => {
163+ expect ( OnyxKeys . isKeyMatch ( ONYXKEYS . TEST_KEY , ONYXKEYS . TEST_KEY ) ) . toBe ( true ) ;
164+ } ) ;
165+
166+ it ( 'should not match different non-collection keys' , ( ) => {
167+ expect ( OnyxKeys . isKeyMatch ( ONYXKEYS . TEST_KEY , ONYXKEYS . RAM_ONLY_KEY ) ) . toBe ( false ) ;
168+ } ) ;
169+
170+ it ( 'should match collection key as prefix of member key' , ( ) => {
171+ expect ( OnyxKeys . isKeyMatch ( ONYXKEYS . COLLECTION . TEST_KEY , `${ ONYXKEYS . COLLECTION . TEST_KEY } 123` ) ) . toBe ( true ) ;
172+ expect ( OnyxKeys . isKeyMatch ( ONYXKEYS . COLLECTION . ROUTES , `${ ONYXKEYS . COLLECTION . ROUTES } abc` ) ) . toBe ( true ) ;
173+ } ) ;
174+
175+ it ( 'should match collection key against itself' , ( ) => {
176+ expect ( OnyxKeys . isKeyMatch ( ONYXKEYS . COLLECTION . TEST_KEY , ONYXKEYS . COLLECTION . TEST_KEY ) ) . toBe ( true ) ;
177+ } ) ;
178+
179+ it ( 'should not match collection key against unrelated key' , ( ) => {
180+ expect ( OnyxKeys . isKeyMatch ( ONYXKEYS . COLLECTION . TEST_KEY , `${ ONYXKEYS . COLLECTION . ROUTES } 123` ) ) . toBe ( false ) ;
181+ } ) ;
182+ } ) ;
183+
184+ describe ( 'getCollectionKeys' , ( ) => {
185+ it ( 'should return the set of registered collection keys' , ( ) => {
186+ const keys = OnyxKeys . getCollectionKeys ( ) ;
187+ expect ( keys . has ( ONYXKEYS . COLLECTION . TEST_KEY ) ) . toBe ( true ) ;
188+ expect ( keys . has ( ONYXKEYS . COLLECTION . ROUTES ) ) . toBe ( true ) ;
189+ expect ( keys . has ( ONYXKEYS . COLLECTION . RAM_ONLY_COLLECTION ) ) . toBe ( true ) ;
190+ } ) ;
191+
192+ it ( 'should not contain non-collection keys' , ( ) => {
193+ const keys = OnyxKeys . getCollectionKeys ( ) ;
194+ expect ( keys . has ( ONYXKEYS . TEST_KEY ) ) . toBe ( false ) ;
195+ expect ( keys . has ( ONYXKEYS . RAM_ONLY_KEY ) ) . toBe ( false ) ;
196+ } ) ;
197+ } ) ;
198+
199+ describe ( 'registerMemberKey / deregisterMemberKey / getMembersOfCollection' , ( ) => {
200+ it ( 'should register a member key and make it retrievable via getMembersOfCollection' , ( ) => {
201+ const memberKey = `${ ONYXKEYS . COLLECTION . TEST_KEY } newKey1` ;
202+ OnyxKeys . registerMemberKey ( memberKey ) ;
203+
204+ const members = OnyxKeys . getMembersOfCollection ( ONYXKEYS . COLLECTION . TEST_KEY ) ;
205+ expect ( members ) . toBeDefined ( ) ;
206+ expect ( members ?. has ( memberKey ) ) . toBe ( true ) ;
207+
208+ // Clean up
209+ OnyxKeys . deregisterMemberKey ( memberKey ) ;
210+ } ) ;
211+
212+ it ( 'should populate the reverse lookup so getCollectionKey returns O(1)' , ( ) => {
213+ const memberKey = `${ ONYXKEYS . COLLECTION . ROUTES } xyz` ;
214+ OnyxKeys . registerMemberKey ( memberKey ) ;
215+
216+ expect ( OnyxKeys . getCollectionKey ( memberKey ) ) . toBe ( ONYXKEYS . COLLECTION . ROUTES ) ;
217+
218+ // Clean up
219+ OnyxKeys . deregisterMemberKey ( memberKey ) ;
220+ } ) ;
221+
222+ it ( 'should not register keys that do not belong to any collection' , ( ) => {
223+ OnyxKeys . registerMemberKey ( 'unknownKey' ) ;
224+
225+ expect ( OnyxKeys . getCollectionKey ( 'unknownKey' ) ) . toBeUndefined ( ) ;
226+ expect ( OnyxKeys . getMembersOfCollection ( 'unknownKey' ) ) . toBeUndefined ( ) ;
227+ } ) ;
228+
229+ it ( 'should deregister a member key from both forward and reverse maps' , ( ) => {
230+ const memberKey = `${ ONYXKEYS . COLLECTION . TEST_KEY } toRemove` ;
231+ OnyxKeys . registerMemberKey ( memberKey ) ;
232+ expect ( OnyxKeys . getMembersOfCollection ( ONYXKEYS . COLLECTION . TEST_KEY ) ?. has ( memberKey ) ) . toBe ( true ) ;
233+
234+ OnyxKeys . deregisterMemberKey ( memberKey ) ;
235+ expect ( OnyxKeys . getMembersOfCollection ( ONYXKEYS . COLLECTION . TEST_KEY ) ?. has ( memberKey ) ) . toBeFalsy ( ) ;
236+ } ) ;
237+
238+ it ( 'should handle registering the same key twice without duplicates' , ( ) => {
239+ const memberKey = `${ ONYXKEYS . COLLECTION . TEST_KEY } duplicate` ;
240+ OnyxKeys . registerMemberKey ( memberKey ) ;
241+ OnyxKeys . registerMemberKey ( memberKey ) ;
242+
243+ const members = OnyxKeys . getMembersOfCollection ( ONYXKEYS . COLLECTION . TEST_KEY ) ;
244+ const count = Array . from ( members ?? [ ] ) . filter ( ( k ) => k === memberKey ) . length ;
245+ expect ( count ) . toBe ( 1 ) ;
246+
247+ // Clean up
248+ OnyxKeys . deregisterMemberKey ( memberKey ) ;
249+ } ) ;
250+
251+ it ( 'should register multiple members and return all via getMembersOfCollection' , ( ) => {
252+ const key1 = `${ ONYXKEYS . COLLECTION . ROUTES } a` ;
253+ const key2 = `${ ONYXKEYS . COLLECTION . ROUTES } b` ;
254+ const key3 = `${ ONYXKEYS . COLLECTION . ROUTES } c` ;
255+
256+ OnyxKeys . registerMemberKey ( key1 ) ;
257+ OnyxKeys . registerMemberKey ( key2 ) ;
258+ OnyxKeys . registerMemberKey ( key3 ) ;
259+
260+ const members = OnyxKeys . getMembersOfCollection ( ONYXKEYS . COLLECTION . ROUTES ) ;
261+ expect ( members ) . toBeDefined ( ) ;
262+ expect ( members ?. size ) . toBe ( 3 ) ;
263+ expect ( members ?. has ( key1 ) ) . toBe ( true ) ;
264+ expect ( members ?. has ( key2 ) ) . toBe ( true ) ;
265+ expect ( members ?. has ( key3 ) ) . toBe ( true ) ;
266+
267+ // Clean up
268+ OnyxKeys . deregisterMemberKey ( key1 ) ;
269+ OnyxKeys . deregisterMemberKey ( key2 ) ;
270+ OnyxKeys . deregisterMemberKey ( key3 ) ;
271+ } ) ;
272+
273+ it ( 'should only remove the deregistered member and keep the rest' , ( ) => {
274+ const key1 = `${ ONYXKEYS . COLLECTION . ROUTES } keep1` ;
275+ const key2 = `${ ONYXKEYS . COLLECTION . ROUTES } remove` ;
276+ const key3 = `${ ONYXKEYS . COLLECTION . ROUTES } keep2` ;
277+
278+ OnyxKeys . registerMemberKey ( key1 ) ;
279+ OnyxKeys . registerMemberKey ( key2 ) ;
280+ OnyxKeys . registerMemberKey ( key3 ) ;
281+
282+ OnyxKeys . deregisterMemberKey ( key2 ) ;
283+
284+ const members = OnyxKeys . getMembersOfCollection ( ONYXKEYS . COLLECTION . ROUTES ) ;
285+ expect ( members ?. size ) . toBe ( 2 ) ;
286+ expect ( members ?. has ( key1 ) ) . toBe ( true ) ;
287+ expect ( members ?. has ( key2 ) ) . toBe ( false ) ;
288+ expect ( members ?. has ( key3 ) ) . toBe ( true ) ;
289+
290+ // Clean up
291+ OnyxKeys . deregisterMemberKey ( key1 ) ;
292+ OnyxKeys . deregisterMemberKey ( key3 ) ;
293+ } ) ;
294+
295+ it ( 'should track members across different collections independently' , ( ) => {
296+ const testKey = `${ ONYXKEYS . COLLECTION . TEST_KEY } member1` ;
297+ const routeKey = `${ ONYXKEYS . COLLECTION . ROUTES } member1` ;
298+
299+ OnyxKeys . registerMemberKey ( testKey ) ;
300+ OnyxKeys . registerMemberKey ( routeKey ) ;
301+
302+ const testMembers = OnyxKeys . getMembersOfCollection ( ONYXKEYS . COLLECTION . TEST_KEY ) ;
303+ const routeMembers = OnyxKeys . getMembersOfCollection ( ONYXKEYS . COLLECTION . ROUTES ) ;
304+
305+ expect ( testMembers ?. size ) . toBe ( 1 ) ;
306+ expect ( testMembers ?. has ( testKey ) ) . toBe ( true ) ;
307+ expect ( testMembers ?. has ( routeKey ) ) . toBe ( false ) ;
308+ expect ( routeMembers ?. size ) . toBe ( 1 ) ;
309+ expect ( routeMembers ?. has ( routeKey ) ) . toBe ( true ) ;
310+ expect ( routeMembers ?. has ( testKey ) ) . toBe ( false ) ;
311+
312+ // Clean up
313+ OnyxKeys . deregisterMemberKey ( testKey ) ;
314+ OnyxKeys . deregisterMemberKey ( routeKey ) ;
315+ } ) ;
316+
317+ it ( 'should handle deregistering a key that was never registered' , ( ) => {
318+ expect ( ( ) => {
319+ OnyxKeys . deregisterMemberKey ( `${ ONYXKEYS . COLLECTION . TEST_KEY } neverRegistered` ) ;
320+ } ) . not . toThrow ( ) ;
321+ } ) ;
322+ } ) ;
323+
125324 describe ( 'isRamOnlyKey' , ( ) => {
126325 it ( 'should return true for RAM-only key' , ( ) => {
127326 expect ( OnyxKeys . isRamOnlyKey ( ONYXKEYS . RAM_ONLY_KEY ) ) . toBeTruthy ( ) ;
0 commit comments