@@ -16,18 +16,25 @@ const defaultProps = {
1616
1717describe ( 'CopyToClipboard' , ( ) => {
1818 const originalNavigatorClipboard = global . navigator . clipboard ;
19+ const originalNavigatorPermissions = global . navigator . permissions ;
1920
2021 beforeEach ( ( ) => {
2122 Object . assign ( global . navigator , {
2223 clipboard : {
2324 writeText : ( text : string ) =>
2425 new Promise < void > ( ( resolve , reject ) => ( text . includes ( 'error' ) ? reject ( ) : resolve ( ) ) ) ,
2526 } ,
27+ permissions : {
28+ query : jest . fn ( ) . mockResolvedValue ( { state : 'granted' } ) ,
29+ } ,
2630 } ) ;
2731 } ) ;
2832
2933 afterEach ( ( ) => {
30- Object . assign ( global . navigator , { clipboard : originalNavigatorClipboard } ) ;
34+ Object . assign ( global . navigator , {
35+ clipboard : originalNavigatorClipboard ,
36+ permissions : originalNavigatorPermissions ,
37+ } ) ;
3138 } ) ;
3239
3340 test ( 'renders a normal button with button text and aria-label and no text to copy' , ( ) => {
@@ -220,4 +227,60 @@ describe('CopyToClipboard', () => {
220227 } ) ;
221228 } ) ;
222229 } ) ;
230+
231+ describe ( 'permissions API behavior' , ( ) => {
232+ test ( 'shows error state when clipboard-write permission is denied' , async ( ) => {
233+ Object . assign ( global . navigator , {
234+ permissions : {
235+ query : jest . fn ( ) . mockResolvedValue ( { state : 'denied' } ) ,
236+ } ,
237+ } ) ;
238+
239+ const { container } = render ( < CopyToClipboard { ...defaultProps } /> ) ;
240+ const wrapper = createWrapper ( container ) . findCopyToClipboard ( ) ! ;
241+
242+ wrapper . findCopyButton ( ) . click ( ) ;
243+ await waitFor ( ( ) =>
244+ expect ( wrapper . findStatusText ( ) ! . getElement ( ) . textContent ) . toBe ( 'Failed to copy to clipboard' )
245+ ) ;
246+ } ) ;
247+
248+ test ( 'shows success state when clipboard-write permission is granted' , async ( ) => {
249+ Object . assign ( global . navigator , {
250+ permissions : {
251+ query : jest . fn ( ) . mockResolvedValue ( { state : 'granted' } ) ,
252+ } ,
253+ } ) ;
254+
255+ const { container } = render ( < CopyToClipboard { ...defaultProps } /> ) ;
256+ const wrapper = createWrapper ( container ) . findCopyToClipboard ( ) ! ;
257+
258+ wrapper . findCopyButton ( ) . click ( ) ;
259+ await waitFor ( ( ) => expect ( wrapper . findStatusText ( ) ! . getElement ( ) . textContent ) . toBe ( 'Copied to clipboard' ) ) ;
260+ } ) ;
261+
262+ test ( 'defaults to success state when permissions API is not available' , async ( ) => {
263+ Object . assign ( global . navigator , { permissions : undefined } ) ;
264+
265+ const { container } = render ( < CopyToClipboard { ...defaultProps } /> ) ;
266+ const wrapper = createWrapper ( container ) . findCopyToClipboard ( ) ! ;
267+
268+ wrapper . findCopyButton ( ) . click ( ) ;
269+ await waitFor ( ( ) => expect ( wrapper . findStatusText ( ) ! . getElement ( ) . textContent ) . toBe ( 'Copied to clipboard' ) ) ;
270+ } ) ;
271+
272+ test ( 'defaults to success state when permissions query fails' , async ( ) => {
273+ Object . assign ( global . navigator , {
274+ permissions : {
275+ query : jest . fn ( ) . mockRejectedValue ( new Error ( 'Permission query failed' ) ) ,
276+ } ,
277+ } ) ;
278+
279+ const { container } = render ( < CopyToClipboard { ...defaultProps } /> ) ;
280+ const wrapper = createWrapper ( container ) . findCopyToClipboard ( ) ! ;
281+
282+ wrapper . findCopyButton ( ) . click ( ) ;
283+ await waitFor ( ( ) => expect ( wrapper . findStatusText ( ) ! . getElement ( ) . textContent ) . toBe ( 'Copied to clipboard' ) ) ;
284+ } ) ;
285+ } ) ;
223286} ) ;
0 commit comments