@@ -3,7 +3,7 @@ import { render, screen, userEvent } from '@mongodb-js/testing-library-compass';
33import { expect } from 'chai' ;
44import sinon from 'sinon' ;
55import HadronDocument from 'hadron-document' ;
6- import { HadronElement , getNestedKeyPath } from './element' ;
6+ import { HadronElement , getNestedKeyPathForElement } from './element' ;
77import type { Element } from 'hadron-document' ;
88
99describe ( 'HadronElement' , function ( ) {
@@ -26,6 +26,82 @@ describe('HadronElement', function () {
2626 clipboardWriteTextStub . restore ( ) ;
2727 } ) ;
2828
29+ it ( 'can add to query and then remove from query' , function ( ) {
30+ const nestedDoc = new HadronDocument ( { user : { name : 'John' } } ) ;
31+ const nestedElement = nestedDoc . get ( 'user' ) ! . get ( 'name' ) ! ;
32+
33+ // Mock queryBar controller
34+ const mockQueryBar = {
35+ isInQuery : sinon . stub ( ) ,
36+ toggleQueryFilter : sinon . spy ( ) ,
37+ } ;
38+
39+ // Initially not in query
40+ mockQueryBar . isInQuery . returns ( false ) ;
41+
42+ const { rerender } = render (
43+ < HadronElement
44+ value = { nestedElement }
45+ editable = { true }
46+ editingEnabled = { true }
47+ lineNumberSize = { 1 }
48+ onAddElement = { ( ) => { } }
49+ queryBar = { mockQueryBar }
50+ />
51+ ) ;
52+
53+ // Open context menu - should show "Add to query"
54+ const elementNode = screen . getByTestId ( 'hadron-document-element' ) ;
55+ userEvent . click ( elementNode , { button : 2 } ) ;
56+
57+ expect ( screen . getByText ( 'Add to query' ) ) . to . exist ;
58+ expect ( screen . queryByText ( 'Remove from query' ) ) . to . not . exist ;
59+
60+ // Click "Add to query"
61+ userEvent . click ( screen . getByText ( 'Add to query' ) , undefined , {
62+ skipPointerEventsCheck : true ,
63+ } ) ;
64+
65+ // Verify toggleQueryFilter was called with correct parameters
66+ expect ( mockQueryBar . toggleQueryFilter ) . to . have . been . calledWith (
67+ 'user.name' ,
68+ nestedElement . generateObject ( )
69+ ) ;
70+
71+ // Now simulate that the field is in query
72+ mockQueryBar . isInQuery . returns ( true ) ;
73+
74+ // Re-render with updated queryBar state
75+ rerender (
76+ < HadronElement
77+ value = { nestedElement }
78+ editable = { true }
79+ editingEnabled = { true }
80+ lineNumberSize = { 1 }
81+ onAddElement = { ( ) => { } }
82+ queryBar = { mockQueryBar }
83+ />
84+ ) ;
85+
86+ // Open context menu again - should now show "Remove from query"
87+ userEvent . click ( elementNode , { button : 2 } ) ;
88+
89+ expect ( screen . getByText ( 'Remove from query' ) ) . to . exist ;
90+ expect ( screen . queryByText ( 'Add to query' ) ) . to . not . exist ;
91+
92+ // Click "Remove from query"
93+ userEvent . click ( screen . getByText ( 'Remove from query' ) , undefined , {
94+ skipPointerEventsCheck : true ,
95+ } ) ;
96+
97+ // Verify toggleQueryFilter was called again
98+ expect ( mockQueryBar . toggleQueryFilter ) . to . have . been . calledTwice ;
99+ expect ( mockQueryBar . toggleQueryFilter . secondCall ) . to . have . been . calledWith (
100+ 'user.name' ,
101+ nestedElement . generateObject ( )
102+ ) ;
103+ } ) ;
104+
29105 it ( 'copies field and value when "Copy field & value" is clicked' , function ( ) {
30106 render (
31107 < HadronElement
@@ -34,7 +110,6 @@ describe('HadronElement', function () {
34110 editingEnabled = { true }
35111 lineNumberSize = { 1 }
36112 onAddElement = { ( ) => { } }
37- onAddToQuery = { ( ) => { } }
38113 />
39114 ) ;
40115
@@ -60,7 +135,6 @@ describe('HadronElement', function () {
60135 editingEnabled = { true }
61136 lineNumberSize = { 1 }
62137 onAddElement = { ( ) => { } }
63- onAddToQuery = { ( ) => { } }
64138 />
65139 ) ;
66140
@@ -84,7 +158,6 @@ describe('HadronElement', function () {
84158 editingEnabled = { true }
85159 lineNumberSize = { 1 }
86160 onAddElement = { ( ) => { } }
87- onAddToQuery = { ( ) => { } }
88161 />
89162 ) ;
90163
@@ -110,7 +183,6 @@ describe('HadronElement', function () {
110183 editingEnabled = { true }
111184 lineNumberSize = { 1 }
112185 onAddElement = { ( ) => { } }
113- onAddToQuery = { ( ) => { } }
114186 />
115187 ) ;
116188
@@ -122,7 +194,7 @@ describe('HadronElement', function () {
122194 expect ( screen . queryByText ( 'Open URL in browser' ) ) . to . not . exist ;
123195 } ) ;
124196
125- it ( 'does not show "Add to query" when onAddToQuery is not provided' , function ( ) {
197+ it ( 'does not show "Add to query" when queryBar is not provided' , function ( ) {
126198 render (
127199 < HadronElement
128200 value = { element }
@@ -141,7 +213,10 @@ describe('HadronElement', function () {
141213 it ( 'calls the correct parameters when "Add to query" is clicked' , function ( ) {
142214 const nestedDoc = new HadronDocument ( { user : { name : 'John' } } ) ;
143215 const nestedElement = nestedDoc . get ( 'user' ) ! . get ( 'name' ) ! ;
144- const onAddToQuerySpy = sinon . spy ( ) ;
216+ const mockQueryBar = {
217+ isInQuery : sinon . stub ( ) . returns ( false ) ,
218+ toggleQueryFilter : sinon . spy ( ) ,
219+ } ;
145220
146221 render (
147222 < HadronElement
@@ -150,7 +225,7 @@ describe('HadronElement', function () {
150225 editingEnabled = { true }
151226 lineNumberSize = { 1 }
152227 onAddElement = { ( ) => { } }
153- onAddToQuery = { onAddToQuerySpy }
228+ queryBar = { mockQueryBar }
154229 />
155230 ) ;
156231
@@ -161,21 +236,21 @@ describe('HadronElement', function () {
161236 skipPointerEventsCheck : true ,
162237 } ) ;
163238
164- // Verify that onAddToQuery was called with the nested field path and element's generated object
165- expect ( onAddToQuerySpy ) . to . have . been . calledWith (
239+ // Verify that toggleQueryFilter was called with the nested field path and element's generated object
240+ expect ( mockQueryBar . toggleQueryFilter ) . to . have . been . calledWith (
166241 'user.name' ,
167242 nestedElement . generateObject ( )
168243 ) ;
169244 } ) ;
170245 } ) ;
171246
172- describe ( 'getNestedKeyPath ' , function ( ) {
247+ describe ( 'getNestedKeyPathForElement ' , function ( ) {
173248 it ( 'returns the field name for a top-level field' , function ( ) {
174249 const doc = new HadronDocument ( { field : 'value' } ) ;
175250 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
176251 const element = doc . elements . at ( 0 ) ! ;
177252
178- const result = getNestedKeyPath ( element ) ;
253+ const result = getNestedKeyPathForElement ( element ) ;
179254
180255 expect ( result ) . to . equal ( 'field' ) ;
181256 } ) ;
@@ -190,7 +265,7 @@ describe('HadronElement', function () {
190265 } ) ;
191266 const nameElement = doc . get ( 'user' ) ! . get ( 'profile' ) ! . get ( 'name' ) ! ;
192267
193- const result = getNestedKeyPath ( nameElement ) ;
268+ const result = getNestedKeyPathForElement ( nameElement ) ;
194269
195270 expect ( result ) . to . equal ( 'user.profile.name' ) ;
196271 } ) ;
@@ -201,7 +276,7 @@ describe('HadronElement', function () {
201276 } ) ;
202277 const nameElement = doc . get ( 'items' ) ! . elements ! . at ( 0 ) ! . get ( 'name' ) ! ;
203278
204- const result = getNestedKeyPath ( nameElement ) ;
279+ const result = getNestedKeyPathForElement ( nameElement ) ;
205280
206281 expect ( result ) . to . equal ( 'items.name' ) ;
207282 } ) ;
@@ -222,7 +297,7 @@ describe('HadronElement', function () {
222297 . get ( 'product' ) !
223298 . get ( 'name' ) ! ;
224299
225- const result = getNestedKeyPath ( nameElement ) ;
300+ const result = getNestedKeyPathForElement ( nameElement ) ;
226301
227302 expect ( result ) . to . equal ( 'orders.items.product.name' ) ;
228303 } ) ;
@@ -233,7 +308,7 @@ describe('HadronElement', function () {
233308 } ) ;
234309 const nameElement = doc . elements . get ( 'items' ) ! . at ( 0 ) ! . get ( 'name' ) ! ;
235310
236- const result = getNestedKeyPath ( nameElement ) ;
311+ const result = getNestedKeyPathForElement ( nameElement ) ;
237312
238313 expect ( result ) . to . equal ( 'items.name' ) ;
239314 } ) ;
@@ -257,7 +332,7 @@ describe('HadronElement', function () {
257332 . get ( 'level4' ) !
258333 . get ( 'value' ) ! ;
259334
260- const result = getNestedKeyPath ( valueElement ) ;
335+ const result = getNestedKeyPathForElement ( valueElement ) ;
261336
262337 expect ( result ) . to . equal ( 'level1.level2.level3.level4.value' ) ;
263338 } ) ;
@@ -275,7 +350,7 @@ describe('HadronElement', function () {
275350 . get ( 'field_with_underscores' ) !
276351 . get ( 'field.with.dots' ) ! ;
277352
278- const result = getNestedKeyPath ( dotsElement ) ;
353+ const result = getNestedKeyPathForElement ( dotsElement ) ;
279354
280355 expect ( result ) . to . equal (
281356 'field-with-dashes.field_with_underscores.field.with.dots'
@@ -290,7 +365,7 @@ describe('HadronElement', function () {
290365 } ) ;
291366 const numericElement = doc . get ( '123' ) ! . get ( '456' ) ! ;
292367
293- const result = getNestedKeyPath ( numericElement ) ;
368+ const result = getNestedKeyPathForElement ( numericElement ) ;
294369
295370 expect ( numericElement . value ) . to . equal ( 'value' ) ;
296371 expect ( result ) . to . equal ( '123.456' ) ;
@@ -301,7 +376,7 @@ describe('HadronElement', function () {
301376 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
302377 const emptyObjElement = doc . elements . at ( 0 ) ! ;
303378
304- const result = getNestedKeyPath ( emptyObjElement ) ;
379+ const result = getNestedKeyPathForElement ( emptyObjElement ) ;
305380
306381 expect ( result ) . to . equal ( 'emptyObj' ) ;
307382 } ) ;
0 commit comments