44 * (c) 2024 Feedzai, Rights Reserved.
55 */
66import React from "react" ;
7- import { useAutoId } from "src/hooks" ;
7+ import { useAutoId , generateFallbackId , generateUUIDFragment , initializeState } from "src/hooks" ;
88
9- function DemoComponent ( { value = null , prefix } : { value ?: string | null ; prefix ?: string } ) {
9+ function DemoComponent ( { value, prefix } : { value ?: string | null ; prefix ?: string } ) {
1010 const firstId = useAutoId ( value , prefix ) ;
1111 const secondId = useAutoId ( ) ;
1212 return (
@@ -21,88 +21,132 @@ function FallbackDemo({
2121 value = "feedzai-fallback-id" ,
2222 prefix,
2323} : {
24- value ?: string | null ;
24+ value ?: string ;
2525 prefix ?: string ;
2626} ) {
2727 const id = useAutoId ( value , prefix ) ;
2828 return < h1 id = { id } > Feedzai</ h1 > ;
2929}
3030
31+ describe ( "generateFallbackId" , ( ) => {
32+ it ( "generates a fallback ID" , ( ) => {
33+ const id = generateFallbackId ( ) ;
34+ expect ( id ) . to . exist ;
35+ expect ( typeof id ) . to . equal ( "string" ) ;
36+ } ) ;
37+ } ) ;
38+
39+ describe ( "generateUUIDFragment" , ( ) => {
40+ it ( "generates a UUID fragment" , ( ) => {
41+ const id = generateUUIDFragment ( ) ;
42+ expect ( id ) . to . exist ;
43+ expect ( typeof id ) . to . equal ( "string" ) ;
44+ expect ( id . length ) . to . equal ( 8 ) ;
45+ } ) ;
46+
47+ it ( "generates a UUID fragment of a given length" , ( ) => {
48+ const id = generateUUIDFragment ( 16 ) ;
49+ expect ( id ) . to . exist ;
50+ expect ( typeof id ) . to . equal ( "string" ) ;
51+ expect ( id . length ) . to . equal ( 16 ) ;
52+ } ) ;
53+ } ) ;
54+
55+ describe ( "initializeState" , ( ) => {
56+ it ( "generates a UUID fragment if no ID is provided" , ( ) => {
57+ // @ts -expect-error - This is a test for the fallback behavior
58+ const id = initializeState ( ) ;
59+ expect ( id ) . to . exist ;
60+ expect ( typeof id ) . to . equal ( "string" ) ;
61+ } ) ;
62+
63+ it ( "generates a UUID fragment of a given length if no ID is provided" , ( ) => {
64+ const id = initializeState ( undefined , { length : 16 } ) ;
65+ expect ( id ) . to . exist ;
66+ expect ( typeof id ) . to . equal ( "string" ) ;
67+ expect ( id . length ) . to . equal ( 16 ) ;
68+ } ) ;
69+
70+ it ( "returns the provided ID if it is a string" , ( ) => {
71+ const id = initializeState ( "feedzai-id" ) ;
72+ expect ( id ) . to . equal ( "feedzai-id" ) ;
73+ } ) ;
74+ } ) ;
75+
3176describe ( "useAutoId" , ( ) => {
32- context ( "React pre-useId" , ( ) => {
77+ it ( "generates a prefixed fallback ID" , ( ) => {
78+ cy . mount ( < DemoComponent prefix = "fdz-prefix" /> ) ;
79+
80+ console . log ( process . env . NODE_ENV ) ;
81+
82+ cy . findByText ( "A paragraph" )
83+ . invoke ( "attr" , "id" )
84+ . should ( "match" , / ^ f d z - p r e f i x - - : ? [ a - z 0 - 9 : ] + : ? $ / ) ;
85+ } ) ;
86+
87+ context ( "React <18 (no useId support)" , ( ) => {
3388 beforeEach ( ( ) => {
34- // Mock React.useId to be undefined
3589 cy . stub ( React , "useId" ) . as ( "useIdStub" ) . value ( undefined ) ;
3690 } ) ;
3791
38- it ( "should generate a unique ID value " , ( ) => {
92+ it ( "generates unique IDs using fallback generator " , ( ) => {
3993 cy . mount ( < DemoComponent /> ) ;
4094
4195 cy . findByText ( "A paragraph" )
4296 . invoke ( "attr" , "id" )
43- . then ( ( idOne ) => {
44- cy . findByText ( "An inline span element" ) . invoke ( "attr" , "id" ) . should ( "not.equal" , idOne ) ;
45- } ) ;
46- } ) ;
47-
48- it ( "should generate a prefixed unique ID value" , ( ) => {
49- const expected = "feedzai-a-prefix" ;
50- cy . mount ( < DemoComponent value = { undefined } prefix = { expected } /> ) ;
97+ . then ( ( firstId ) => {
98+ expect ( firstId ) . to . exist ;
5199
52- cy . findByText ( "A paragraph" ) . invoke ( "attr" , "id" ) . should ( "contain" , expected ) ;
100+ cy . findByText ( "An inline span element" )
101+ . invoke ( "attr" , "id" )
102+ . should ( "exist" )
103+ . and ( "not.equal" , firstId ) ;
104+ } ) ;
53105 } ) ;
54106
55- it ( "uses a fallback ID" , ( ) => {
107+ it ( "uses a static fallback ID if provided " , ( ) => {
56108 cy . mount ( < FallbackDemo /> ) ;
57109
58110 cy . findByText ( "Feedzai" ) . should ( "have.id" , "feedzai-fallback-id" ) ;
59111 } ) ;
60112
61- it ( "should return a prefixed fallback ID" , ( ) => {
62- cy . mount ( < FallbackDemo prefix = "js-prefix" value = "423696e5 " /> ) ;
113+ it ( "applies a prefix to the custom fallback ID" , ( ) => {
114+ cy . mount ( < FallbackDemo value = "423696e5" prefix = "js-prefix " /> ) ;
63115
64116 cy . findByText ( "Feedzai" ) . should ( "have.id" , "js-prefix--423696e5" ) ;
65117 } ) ;
66118 } ) ;
67119
68- context ( "React 18+ with useId" , ( ) => {
69- const GENERATED_ID = ":r0:" ;
70-
71- beforeEach ( ( ) => {
72- // Mock React.useId to return a predictable value
73- cy . stub ( React , "useId" ) . as ( "useIdStub" ) . returns ( GENERATED_ID ) ;
74- } ) ;
75-
76- it ( "should use React.useId for generating IDs" , ( ) => {
120+ context ( "React 18+ (with useId)" , ( ) => {
121+ it ( "uses React.useId to generate consistent IDs" , ( ) => {
77122 cy . mount ( < DemoComponent /> ) ;
78123
79- cy . findByText ( "A paragraph" ) . invoke ( "attr" , "id" ) . should ( "equal" , GENERATED_ID ) ;
80- cy . findByText ( "An inline span element" ) . invoke ( "attr" , "id" ) . should ( "equal" , GENERATED_ID ) ;
81- cy . get ( "@useIdStub" ) . should ( "be.calledTwice" ) ;
124+ cy . findByText ( "A paragraph" )
125+ . invoke ( "attr" , "id" )
126+ . should ( "match" , / ^ : ? [ a - z 0 - 9 : ] + : ? $ / ) ;
127+ cy . findByText ( "An inline span element" )
128+ . invoke ( "attr" , "id" )
129+ . should ( "match" , / ^ : ? [ a - z 0 - 9 : ] + : ? $ / ) ;
82130 } ) ;
83131
84- it ( "should generate a prefixed unique ID value using React.useId" , ( ) => {
85- const expected = "feedzai-a-prefix" ;
86- cy . mount ( < DemoComponent value = { undefined } prefix = { expected } /> ) ;
132+ it ( "applies prefix to ID generated by React.useId" , ( ) => {
133+ cy . mount ( < DemoComponent prefix = "fdz-js-prefix" /> ) ;
87134
88135 cy . findByText ( "A paragraph" )
89136 . invoke ( "attr" , "id" )
90- . should ( "equal" , `${ expected } --${ GENERATED_ID } ` ) ;
91- cy . get ( "@useIdStub" ) . should ( "be.called" ) ;
137+ . should ( "match" , / ^ f d z - j s - p r e f i x - - : ? [ a - z 0 - 9 : ] + : ? $ / ) ;
92138 } ) ;
93139
94- it ( "uses a fallback ID even when React.useId is available " , ( ) => {
140+ it ( "uses static fallback ID when explicitly provided " , ( ) => {
95141 cy . mount ( < FallbackDemo /> ) ;
96142
97143 cy . findByText ( "Feedzai" ) . should ( "have.id" , "feedzai-fallback-id" ) ;
98- cy . get ( "@useIdStub" ) . should ( "not.be.called" ) ;
99144 } ) ;
100145
101- it ( "should return a prefixed fallback ID and not use React. useId" , ( ) => {
102- cy . mount ( < FallbackDemo prefix = "js-prefix" value = "423696e5 " /> ) ;
146+ it ( "applies prefix to provided fallback ID (ignoring useId) " , ( ) => {
147+ cy . mount ( < FallbackDemo value = "423696e5" prefix = "fdz-js-prefix " /> ) ;
103148
104- cy . findByText ( "Feedzai" ) . should ( "have.id" , "js-prefix--423696e5" ) ;
105- cy . get ( "@useIdStub" ) . should ( "not.be.called" ) ;
149+ cy . findByText ( "Feedzai" ) . should ( "have.id" , "fdz-js-prefix--423696e5" ) ;
106150 } ) ;
107151 } ) ;
108152} ) ;
0 commit comments