1+ import React from 'react' ;
2+ import NavigationButtons from '../../components/NavigationButtons' ;
3+ import mockNextRouter , { MockRouter } from '../plugins/mockNextRouterUtils' ;
4+
5+ interface NavigationButtonsProps {
6+ prevLabel ?: string ;
7+ prevURL ?: string ;
8+ nextLabel ?: string ;
9+ nextURL ?: string ;
10+ }
11+
12+ const defaultProps : NavigationButtonsProps = {
13+ prevLabel : 'Previous Page' ,
14+ prevURL : '/previous' ,
15+ nextLabel : 'Next Page' ,
16+ nextURL : '/next' ,
17+ } ;
18+
19+ describe ( 'NavigationButtons Component' , ( ) => {
20+ let mockRouter : MockRouter ;
21+
22+ beforeEach ( ( ) => {
23+ mockRouter = mockNextRouter ( ) ;
24+ } ) ;
25+
26+ it ( 'should render both navigation buttons correctly' , ( ) => {
27+ cy . mount ( < NavigationButtons { ...defaultProps } /> ) ;
28+
29+ // Check if both buttons are rendered
30+ cy . get ( '[data-test="nav-button-prev"]' ) . should ( 'exist' ) ;
31+ cy . get ( '[data-test="nav-button-next"]' ) . should ( 'exist' ) ;
32+
33+ // Check previous button content
34+ cy . get ( '[data-test="nav-button-prev"]' )
35+ . within ( ( ) => {
36+ cy . get ( '[data-test="nav-button-text"]' ) . should ( 'have.text' , 'Go Back' ) ;
37+ cy . get ( '[data-test="nav-button-label"]' ) . should ( 'have.text' , defaultProps . prevLabel ) ;
38+ cy . get ( '[data-test="nav-button-icon"]' ) . should ( 'exist' ) ;
39+ } ) ;
40+
41+ // Check next button content
42+ cy . get ( '[data-test="nav-button-next"]' )
43+ . within ( ( ) => {
44+ cy . get ( '[data-test="nav-button-text"]' ) . should ( 'have.text' , 'Up Next' ) ;
45+ cy . get ( '[data-test="nav-button-label"]' ) . should ( 'have.text' , defaultProps . nextLabel ) ;
46+ cy . get ( '[data-test="nav-button-icon"]' ) . should ( 'exist' ) ;
47+ } ) ;
48+ } ) ;
49+
50+ it ( 'should render only previous button when next props are missing' , ( ) => {
51+ const propsWithOnlyPrev : NavigationButtonsProps = {
52+ prevLabel : 'Previous Page' ,
53+ prevURL : '/previous' ,
54+ } ;
55+
56+ cy . mount ( < NavigationButtons { ...propsWithOnlyPrev } /> ) ;
57+
58+ // Previous button should exist and be functional
59+ cy . get ( '[data-test="nav-button-prev"]' ) . should ( 'exist' ) ;
60+ cy . get ( '[data-test="nav-button-prev"]' )
61+ . within ( ( ) => {
62+ cy . get ( '[data-test="nav-button-text"]' ) . should ( 'have.text' , 'Go Back' ) ;
63+ cy . get ( '[data-test="nav-button-label"]' ) . should ( 'have.text' , propsWithOnlyPrev . prevLabel ) ;
64+ } ) ;
65+
66+ // Next button should be a placeholder div
67+ cy . get ( '[data-test="nav-button-next"]' ) . should ( 'not.exist' ) ;
68+ cy . get ( '[class*="w-1/2"]' ) . should ( 'have.length' , 2 ) ;
69+ } ) ;
70+
71+ it ( 'should render only next button when prev props are missing' , ( ) => {
72+ const propsWithOnlyNext : NavigationButtonsProps = {
73+ nextLabel : 'Next Page' ,
74+ nextURL : '/next' ,
75+ } ;
76+
77+ cy . mount ( < NavigationButtons { ...propsWithOnlyNext } /> ) ;
78+
79+ // Next button should exist and be functional
80+ cy . get ( '[data-test="nav-button-next"]' ) . should ( 'exist' ) ;
81+ cy . get ( '[data-test="nav-button-next"]' )
82+ . within ( ( ) => {
83+ cy . get ( '[data-test="nav-button-text"]' ) . should ( 'have.text' , 'Up Next' ) ;
84+ cy . get ( '[data-test="nav-button-label"]' ) . should ( 'have.text' , propsWithOnlyNext . nextLabel ) ;
85+ } ) ;
86+
87+ // Previous button should be a placeholder div
88+ cy . get ( '[data-test="nav-button-prev"]' ) . should ( 'not.exist' ) ;
89+ cy . get ( '[class*="w-1/2"]' ) . should ( 'have.length' , 2 ) ;
90+ } ) ;
91+
92+ it ( 'should render placeholder divs when no props are provided' , ( ) => {
93+ cy . mount ( < NavigationButtons /> ) ;
94+
95+ // No navigation buttons should be rendered
96+ cy . get ( '[data-test="nav-button-prev"]' ) . should ( 'not.exist' ) ;
97+ cy . get ( '[data-test="nav-button-next"]' ) . should ( 'not.exist' ) ;
98+
99+ // Should have two placeholder divs
100+ cy . get ( '[class*="w-1/2"]' ) . should ( 'have.length' , 2 ) ;
101+ } ) ;
102+
103+ it ( 'should apply correct styling classes' , ( ) => {
104+ cy . mount ( < NavigationButtons { ...defaultProps } /> ) ;
105+
106+ // Check container styling
107+ cy . get ( '.mb-4.flex.flex-row.gap-4' ) . should ( 'exist' ) ;
108+
109+ // Check card styling
110+ cy . get ( '.h-full.cursor-pointer.border-gray-200.p-4.text-center.shadow-md' ) . should ( 'exist' ) ;
111+
112+ // Check button styling
113+ cy . get ( '.w-full.gap-5.p-0.text-\\[18px\\].hover\\:bg-transparent' ) . should ( 'exist' ) ;
114+
115+ // Check text styling
116+ cy . get ( '.font-bold.uppercase.text-primary' ) . should ( 'exist' ) ;
117+ cy . get ( '.text-base.font-medium.text-slate-600' ) . should ( 'exist' ) ;
118+ } ) ;
119+
120+ it ( 'should handle hover effects correctly' , ( ) => {
121+ cy . mount ( < NavigationButtons { ...defaultProps } /> ) ;
122+
123+ // Check hover classes are applied
124+ cy . get ( '.hover\\:border-gray-300.hover\\:shadow-lg' ) . should ( 'exist' ) ;
125+ cy . get ( '.dark\\:shadow-xl.dark\\:hover\\:shadow-lg.dark\\:drop-shadow-lg' ) . should ( 'exist' ) ;
126+ } ) ;
127+
128+ it ( 'should handle dark mode styling' , ( ) => {
129+ cy . mount ( < NavigationButtons { ...defaultProps } /> ) ;
130+
131+ // Check dark mode classes
132+ cy . get ( '.dark\\:text-slate-300' ) . should ( 'exist' ) ;
133+ cy . get ( '.dark\\:shadow-xl.dark\\:hover\\:shadow-lg.dark\\:drop-shadow-lg' ) . should ( 'exist' ) ;
134+ } ) ;
135+
136+ it ( 'should render with correct responsive classes' , ( ) => {
137+ cy . mount ( < NavigationButtons { ...defaultProps } /> ) ;
138+
139+ // Check responsive text alignment
140+ cy . get ( '.text-center.lg\\:text-left' ) . should ( 'exist' ) ;
141+ } ) ;
142+
143+ it ( 'should handle empty string props gracefully' , ( ) => {
144+ const emptyProps : NavigationButtonsProps = {
145+ prevLabel : '' ,
146+ prevURL : '' ,
147+ nextLabel : '' ,
148+ nextURL : '' ,
149+ } ;
150+
151+ cy . mount ( < NavigationButtons { ...emptyProps } /> ) ;
152+
153+ // Should render placeholder divs when props are empty strings
154+ cy . get ( '[data-test="nav-button-prev"]' ) . should ( 'not.exist' ) ;
155+ cy . get ( '[data-test="nav-button-next"]' ) . should ( 'not.exist' ) ;
156+ cy . get ( '[class*="w-1/2"]' ) . should ( 'have.length' , 2 ) ;
157+ } ) ;
158+
159+ it ( 'should handle mixed valid and invalid props' , ( ) => {
160+ const mixedProps : NavigationButtonsProps = {
161+ prevLabel : 'Valid Previous' ,
162+ prevURL : '/valid-prev' ,
163+ nextLabel : '' , // Invalid
164+ nextURL : '' , // Invalid
165+ } ;
166+
167+ cy . mount ( < NavigationButtons { ...mixedProps } /> ) ;
168+
169+ // Previous button should be rendered
170+ cy . get ( '[data-test="nav-button-prev"]' ) . should ( 'exist' ) ;
171+ cy . get ( '[data-test="nav-button-prev"]' )
172+ . within ( ( ) => {
173+ cy . get ( '[data-test="nav-button-label"]' ) . should ( 'have.text' , mixedProps . prevLabel ) ;
174+ } ) ;
175+
176+ // Next button should not be rendered (placeholder div instead)
177+ cy . get ( '[data-test="nav-button-next"]' ) . should ( 'not.exist' ) ;
178+ } ) ;
179+ } ) ;
0 commit comments