@@ -50,7 +50,7 @@ describe('Feed', () => {
5050 const feed = new Feed ( 'feed5' , 'XML Feed' )
5151 . setAuthor ( 'Feed Author' )
5252 . addSelfLink ( '/feed' , 'navigation' )
53- . addStartLink ( '/' ) ;
53+ . addNavigationLink ( 'start' , '/' ) ;
5454
5555 const entry = new Entry ( 'entry1' , 'Entry 1' )
5656 . setAuthor ( 'Entry Author' )
@@ -100,4 +100,124 @@ describe('Feed', () => {
100100 const xml = feed . toXml ( { baseUrl } ) ;
101101 expect ( xml ) . toContain ( 'pse:count="10"' ) ;
102102 } ) ;
103+
104+ describe ( 'Navigation Links' , ( ) => {
105+ it ( 'should add a single navigation link' , ( ) => {
106+ const feed = new Feed ( 'nav1' , 'Navigation Test' ) ;
107+ feed . addNavigationLink ( 'start' , '/root' ) ;
108+
109+ const startLink = feed . getNavigationLink ( 'start' ) ;
110+ expect ( startLink ) . toBeDefined ( ) ;
111+ expect ( startLink ?. rel ) . toBe ( 'start' ) ;
112+ expect ( startLink ?. href ) . toBe ( '/root' ) ;
113+ expect ( startLink ?. type ) . toBe ( 'application/atom+xml;profile=opds-catalog;kind=navigation' ) ;
114+ } ) ;
115+
116+ it ( 'should replace existing navigation link with same rel' , ( ) => {
117+ const feed = new Feed ( 'nav2' , 'Replace Test' ) ;
118+ feed . addNavigationLink ( 'next' , '/page2' ) ;
119+ feed . addNavigationLink ( 'next' , '/page3' ) ;
120+
121+ const nextLinks = feed . getLinks ( ) . filter ( link => link . rel === 'next' ) ;
122+ expect ( nextLinks ) . toHaveLength ( 1 ) ;
123+ expect ( nextLinks [ 0 ] . href ) . toBe ( '/page3' ) ;
124+ } ) ;
125+
126+ it ( 'should add multiple navigation links at once' , ( ) => {
127+ const feed = new Feed ( 'nav3' , 'Multiple Links Test' ) ;
128+ feed . addNavigationLinks ( {
129+ start : '/root' ,
130+ previous : '/page1' ,
131+ next : '/page3' ,
132+ first : '/page1' ,
133+ last : '/page10'
134+ } ) ;
135+
136+ expect ( feed . getNavigationLink ( 'start' ) ?. href ) . toBe ( '/root' ) ;
137+ expect ( feed . getNavigationLink ( 'previous' ) ?. href ) . toBe ( '/page1' ) ;
138+ expect ( feed . getNavigationLink ( 'next' ) ?. href ) . toBe ( '/page3' ) ;
139+ expect ( feed . getNavigationLink ( 'first' ) ?. href ) . toBe ( '/page1' ) ;
140+ expect ( feed . getNavigationLink ( 'last' ) ?. href ) . toBe ( '/page10' ) ;
141+ } ) ;
142+
143+ it ( 'should skip undefined values in addNavigationLinks' , ( ) => {
144+ const feed = new Feed ( 'nav4' , 'Skip Undefined Test' ) ;
145+ feed . addNavigationLinks ( {
146+ start : '/root' ,
147+ previous : undefined ,
148+ next : '/page3'
149+ } ) ;
150+
151+ expect ( feed . getNavigationLink ( 'start' ) ) . toBeDefined ( ) ;
152+ expect ( feed . getNavigationLink ( 'previous' ) ) . toBeUndefined ( ) ;
153+ expect ( feed . getNavigationLink ( 'next' ) ) . toBeDefined ( ) ;
154+ } ) ;
155+
156+ it ( 'should return undefined for non-existent navigation links' , ( ) => {
157+ const feed = new Feed ( 'nav5' , 'Non-existent Test' ) ;
158+ expect ( feed . getNavigationLink ( 'next' ) ) . toBeUndefined ( ) ;
159+ } ) ;
160+
161+ it ( 'should chain navigation link methods' , ( ) => {
162+ const feed = new Feed ( 'nav6' , 'Chaining Test' )
163+ . addNavigationLink ( 'start' , '/root' )
164+ . addNavigationLinks ( {
165+ previous : '/page1' ,
166+ next : '/page3'
167+ } ) ;
168+
169+ expect ( feed . getNavigationLink ( 'start' ) ) . toBeDefined ( ) ;
170+ expect ( feed . getNavigationLink ( 'previous' ) ) . toBeDefined ( ) ;
171+ expect ( feed . getNavigationLink ( 'next' ) ) . toBeDefined ( ) ;
172+ } ) ;
173+
174+ it ( 'should generate correct XML for navigation links' , ( ) => {
175+ const feed = new Feed ( 'nav7' , 'XML Navigation Test' ) ;
176+ feed . addNavigationLinks ( {
177+ start : '/root' ,
178+ next : '/page2' ,
179+ previous : '/page1'
180+ } ) ;
181+
182+ const xml = feed . toXml ( { baseUrl } ) ;
183+ expect ( xml ) . toContain ( 'rel="start"' ) ;
184+ expect ( xml ) . toContain ( 'rel="next"' ) ;
185+ expect ( xml ) . toContain ( 'rel="previous"' ) ;
186+ expect ( xml ) . toContain ( `href="${ baseUrl } /root"` ) ;
187+ expect ( xml ) . toContain ( `href="${ baseUrl } /page2"` ) ;
188+ expect ( xml ) . toContain ( `href="${ baseUrl } /page1"` ) ;
189+ expect ( xml ) . toContain ( 'type="application/atom+xml;profile=opds-catalog;kind=navigation"' ) ;
190+ } ) ;
191+
192+ it ( 'should handle replacement in addNavigationLinks' , ( ) => {
193+ const feed = new Feed ( 'nav8' , 'Replacement Test' ) ;
194+ feed . addNavigationLink ( 'next' , '/page2' ) ;
195+ feed . addNavigationLinks ( {
196+ next : '/page3' ,
197+ last : '/page10'
198+ } ) ;
199+
200+ const nextLinks = feed . getLinks ( ) . filter ( link => link . rel === 'next' ) ;
201+ expect ( nextLinks ) . toHaveLength ( 1 ) ;
202+ expect ( nextLinks [ 0 ] . href ) . toBe ( '/page3' ) ;
203+ expect ( feed . getNavigationLink ( 'last' ) ?. href ) . toBe ( '/page10' ) ;
204+ } ) ;
205+ } ) ;
206+
207+ describe ( 'Self Links' , ( ) => {
208+ it ( 'should get self link' , ( ) => {
209+ const feed = new Feed ( 'self1' , 'Self Link Test' ) ;
210+ feed . addSelfLink ( '/feed' , 'navigation' ) ;
211+
212+ const selfLink = feed . getSelfLink ( ) ;
213+ expect ( selfLink ) . toBeDefined ( ) ;
214+ expect ( selfLink ?. rel ) . toBe ( 'self' ) ;
215+ expect ( selfLink ?. href ) . toBe ( '/feed' ) ;
216+ } ) ;
217+
218+ it ( 'should return undefined when no self link exists' , ( ) => {
219+ const feed = new Feed ( 'self2' , 'No Self Link Test' ) ;
220+ expect ( feed . getSelfLink ( ) ) . toBeUndefined ( ) ;
221+ } ) ;
222+ } ) ;
103223} ) ;
0 commit comments