| 1 |  |  | import 'async'; | 
            
                                                        
            
                                    
            
            
                | 2 |  |  | import 'assert'; | 
            
                                                        
            
                                    
            
            
                | 3 |  |  | import 'should'; | 
            
                                                        
            
                                    
            
            
                | 4 |  |  | import * as zlib from 'zlib'; | 
            
                                                        
            
                                    
            
            
                | 5 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 6 |  |  | import Sitemapper from '../../lib/assets/sitemapper.js'; | 
            
                                                        
            
                                    
            
            
                | 7 |  |  | import { SitemapperResponse } from '../../sitemapper'; | 
            
                                                        
            
                                    
            
            
                | 8 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 9 |  |  | describe('Sitemapper Advanced Tests', function () { | 
            
                                                        
            
                                    
            
            
                | 10 |  |  |   let sitemapper: Sitemapper; | 
            
                                                        
            
                                    
            
            
                | 11 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 12 |  |  |   beforeEach(() => { | 
            
                                                        
            
                                    
            
            
                | 13 |  |  |     sitemapper = new Sitemapper(); | 
            
                                                        
            
                                    
            
            
                | 14 |  |  |   }); | 
            
                                                        
            
                                    
            
            
                | 15 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 16 |  |  |   describe('decompressResponseBody', function () { | 
            
                                                        
            
                                    
            
            
                | 17 |  |  |     it('should correctly decompress gzipped content', async function () { | 
            
                                                        
            
                                    
            
            
                | 18 |  |  |       // Create a sample XML string | 
            
                                                        
            
                                    
            
            
                | 19 |  |  |       const xmlContent = | 
            
                                                        
            
                                    
            
            
                | 20 |  |  |         '<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"><url><loc>https://example.com</loc></url></urlset>'; | 
            
                                                        
            
                                    
            
            
                | 21 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 22 |  |  |       // Compress it with gzip | 
            
                                                        
            
                                    
            
            
                | 23 |  |  |       const compressed = zlib.gzipSync(Buffer.from(xmlContent)); | 
            
                                                        
            
                                    
            
            
                | 24 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 25 |  |  |       // Use the private decompressResponseBody method | 
            
                                                        
            
                                    
            
            
                | 26 |  |  |       const decompressed = await (sitemapper as any).decompressResponseBody( | 
            
                                                        
            
                                    
            
            
                | 27 |  |  |         compressed | 
            
                                                        
            
                                    
            
            
                | 28 |  |  |       ); | 
            
                                                        
            
                                    
            
            
                | 29 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 30 |  |  |       // Check the result | 
            
                                                        
            
                                    
            
            
                | 31 |  |  |       decompressed.toString().should.equal(xmlContent); | 
            
                                                        
            
                                    
            
            
                | 32 |  |  |     }); | 
            
                                                        
            
                                    
            
            
                | 33 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 34 |  |  |     it('should handle decompression errors gracefully', async function () { | 
            
                                                        
            
                                    
            
            
                | 35 |  |  |       // Create invalid gzip content | 
            
                                                        
            
                                    
            
            
                | 36 |  |  |       const invalidGzip = Buffer.from('This is not valid gzip content'); | 
            
                                                        
            
                                    
            
            
                | 37 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 38 |  |  |       try { | 
            
                                                        
            
                                    
            
            
                | 39 |  |  |         // This should throw an error | 
            
                                                        
            
                                    
            
            
                | 40 |  |  |         await (sitemapper as any).decompressResponseBody(invalidGzip); | 
            
                                                        
            
                                    
            
            
                | 41 |  |  |         // If we get here, the test should fail | 
            
                                                        
            
                                    
            
            
                | 42 |  |  |         false.should.be.true(); // Force test to fail if no error is thrown | 
            
                                                        
            
                                    
            
            
                | 43 |  |  |       } catch (error) { | 
            
                                                        
            
                                    
            
            
                | 44 |  |  |         // We should get an error, which is expected | 
            
                                                        
            
                                    
            
            
                | 45 |  |  |         (error as Error).should.be.an.instanceOf(Error); | 
            
                                                        
            
                                    
            
            
                | 46 |  |  |       } | 
            
                                                        
            
                                    
            
            
                | 47 |  |  |     }); | 
            
                                                        
            
                                    
            
            
                | 48 |  |  |   }); | 
            
                                                        
            
                                    
            
            
                | 49 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 50 |  |  |   describe('initializeTimeout', function () { | 
            
                                                        
            
                                    
            
            
                | 51 |  |  |     it('should set up a timeout that cancels a request', async function () { | 
            
                                                        
            
                                    
            
            
                | 52 |  |  |       // Create a mock requester with a cancel method | 
            
                                                        
            
                                    
            
            
                | 53 |  |  |       const mockRequester = { | 
            
                                                        
            
                                    
            
            
                | 54 |  |  |         cancel: function () { | 
            
                                                        
            
                                    
            
            
                | 55 |  |  |           this.canceled = true; | 
            
                                                        
            
                                    
            
            
                | 56 |  |  |         }, | 
            
                                                        
            
                                    
            
            
                | 57 |  |  |         canceled: false, | 
            
                                                        
            
                                    
            
            
                | 58 |  |  |       }; | 
            
                                                        
            
                                    
            
            
                | 59 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 60 |  |  |       // Set a very short timeout | 
            
                                                        
            
                                    
            
            
                | 61 |  |  |       sitemapper.timeout = 1; | 
            
                                                        
            
                                    
            
            
                | 62 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 63 |  |  |       // Call initializeTimeout | 
            
                                                        
            
                                    
            
            
                | 64 |  |  |       (sitemapper as any).initializeTimeout( | 
            
                                                        
            
                                    
            
            
                | 65 |  |  |         'https://example.com/timeout-test', | 
            
                                                        
            
                                    
            
            
                | 66 |  |  |         mockRequester | 
            
                                                        
            
                                    
            
            
                | 67 |  |  |       ); | 
            
                                                        
            
                                    
            
            
                | 68 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 69 |  |  |       // Wait for the timeout to trigger | 
            
                                                        
            
                                    
            
            
                | 70 |  |  |       await new Promise((resolve) => setTimeout(resolve, 10)); | 
            
                                                        
            
                                    
            
            
                | 71 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 72 |  |  |       // Check if cancel was called | 
            
                                                        
            
                                    
            
            
                | 73 |  |  |       mockRequester.canceled.should.be.true(); | 
            
                                                        
            
                                    
            
            
                | 74 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 75 |  |  |       // Clean up | 
            
                                                        
            
                                    
            
            
                | 76 |  |  |       clearTimeout( | 
            
                                                        
            
                                    
            
            
                | 77 |  |  |         (sitemapper as any).timeoutTable['https://example.com/timeout-test'] | 
            
                                                        
            
                                    
            
            
                | 78 |  |  |       ); | 
            
                                                        
            
                                    
            
            
                | 79 |  |  |     }); | 
            
                                                        
            
                                    
            
            
                | 80 |  |  |   }); | 
            
                                                        
            
                                    
            
            
                | 81 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 82 |  |  |   describe('parse error handling', function () { | 
            
                                                        
            
                                    
            
            
                | 83 |  |  |     it('should handle network errors during parse', async function () { | 
            
                                                        
            
                                    
            
            
                | 84 |  |  |       // Store original fetch implementation | 
            
                                                        
            
                                    
            
            
                | 85 |  |  |       const originalFetch = global.fetch; | 
            
                                                        
            
                                    
            
            
                | 86 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 87 |  |  |       // Mock fetch to throw a network error | 
            
                                                        
            
                                    
            
            
                | 88 |  |  |       (global as any).fetch = () => { | 
            
                                                        
            
                                    
            
            
                | 89 |  |  |         const error = new Error('HTTP Error occurred'); | 
            
                                                        
            
                                    
            
            
                | 90 |  |  |         error.name = 'HTTPError'; | 
            
                                                        
            
                                    
            
            
                | 91 |  |  |         throw error; | 
            
                                                        
            
                                    
            
            
                | 92 |  |  |       }; | 
            
                                                        
            
                                    
            
            
                | 93 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 94 |  |  |       try { | 
            
                                                        
            
                                    
            
            
                | 95 |  |  |         // Try to parse a URL | 
            
                                                        
            
                                    
            
            
                | 96 |  |  |         const result = await (sitemapper as any).parse( | 
            
                                                        
            
                                    
            
            
                | 97 |  |  |           'https://example.com/error-test' | 
            
                                                        
            
                                    
            
            
                | 98 |  |  |         ); | 
            
                                                        
            
                                    
            
            
                | 99 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 100 |  |  |         // Check the result | 
            
                                                        
            
                                    
            
            
                | 101 |  |  |         result.should.have.property('error').which.is.a.String(); | 
            
                                                        
            
                                    
            
            
                | 102 |  |  |         result.should.have.property('data').which.is.an.Object(); | 
            
                                                        
            
                                    
            
            
                | 103 |  |  |         (result.data as any).should.have | 
            
                                                        
            
                                    
            
            
                | 104 |  |  |           .property('name') | 
            
                                                        
            
                                    
            
            
                | 105 |  |  |           .which.is.equal('HTTPError'); | 
            
                                                        
            
                                    
            
            
                | 106 |  |  |       } finally { | 
            
                                                        
            
                                    
            
            
                | 107 |  |  |         // Restore the original fetch | 
            
                                                        
            
                                    
            
            
                | 108 |  |  |         (global as any).fetch = originalFetch; | 
            
                                                        
            
                                    
            
            
                | 109 |  |  |       } | 
            
                                                        
            
                                    
            
            
                | 110 |  |  |     }); | 
            
                                                        
            
                                    
            
            
                | 111 |  |  |   }); | 
            
                                                        
            
                                    
            
            
                | 112 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 113 |  |  |   describe('fetch with multiple sitemaps', function () { | 
            
                                                        
            
                                    
            
            
                | 114 |  |  |     it('should handle errors in some child sitemaps while succeeding with others', async function () { | 
            
                                                        
            
                                    
            
            
                | 115 |  |  |       this.timeout(10000); | 
            
                                                        
            
                                    
            
            
                | 116 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 117 |  |  |       // Create a mock parse method that returns a sitemapindex with mixed results | 
            
                                                        
            
                                    
            
            
                | 118 |  |  |       const originalParse = sitemapper.parse; | 
            
                                                        
            
                                    
            
            
                | 119 |  |  |       const originalCrawl = sitemapper.crawl; | 
            
                                                        
            
                                    
            
            
                | 120 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 121 |  |  |       // First call to parse returns sitemapindex with multiple sitemaps | 
            
                                                        
            
                                    
            
            
                | 122 |  |  |       let parseCallCount = 0; | 
            
                                                        
            
                                    
            
            
                | 123 |  |  |       sitemapper.parse = async () => { | 
            
                                                        
            
                                    
            
            
                | 124 |  |  |         parseCallCount++; | 
            
                                                        
            
                                    
            
            
                | 125 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 126 |  |  |         if (parseCallCount === 1) { | 
            
                                                        
            
                                    
            
            
                | 127 |  |  |           // First call returns a sitemapindex with two sitemaps | 
            
                                                        
            
                                    
            
            
                | 128 |  |  |           return { | 
            
                                                        
            
                                    
            
            
                | 129 |  |  |             data: { | 
            
                                                        
            
                                    
            
            
                | 130 |  |  |               sitemapindex: { | 
            
                                                        
            
                                    
            
            
                | 131 |  |  |                 sitemap: [ | 
            
                                                        
            
                                    
            
            
                | 132 |  |  |                   { loc: 'https://example.com/good-sitemap.xml' }, | 
            
                                                        
            
                                    
            
            
                | 133 |  |  |                   { loc: 'https://example.com/bad-sitemap.xml' }, | 
            
                                                        
            
                                    
            
            
                | 134 |  |  |                 ], | 
            
                                                        
            
                                    
            
            
                | 135 |  |  |               }, | 
            
                                                        
            
                                    
            
            
                | 136 |  |  |             }, | 
            
                                                        
            
                                    
            
            
                | 137 |  |  |           }; | 
            
                                                        
            
                                    
            
            
                | 138 |  |  |         } else if (parseCallCount === 2) { | 
            
                                                        
            
                                    
            
            
                | 139 |  |  |           // Second call (for good-sitemap) returns urlset | 
            
                                                        
            
                                    
            
            
                | 140 |  |  |           return { | 
            
                                                        
            
                                    
            
            
                | 141 |  |  |             data: { | 
            
                                                        
            
                                    
            
            
                | 142 |  |  |               urlset: { | 
            
                                                        
            
                                    
            
            
                | 143 |  |  |                 url: [ | 
            
                                                        
            
                                    
            
            
                | 144 |  |  |                   { loc: 'https://example.com/page1' }, | 
            
                                                        
            
                                    
            
            
                | 145 |  |  |                   { loc: 'https://example.com/page2' }, | 
            
                                                        
            
                                    
            
            
                | 146 |  |  |                 ], | 
            
                                                        
            
                                    
            
            
                | 147 |  |  |               }, | 
            
                                                        
            
                                    
            
            
                | 148 |  |  |             }, | 
            
                                                        
            
                                    
            
            
                | 149 |  |  |           }; | 
            
                                                        
            
                                    
            
            
                | 150 |  |  |         } else { | 
            
                                                        
            
                                    
            
            
                | 151 |  |  |           // Third call (for bad-sitemap) returns error | 
            
                                                        
            
                                    
            
            
                | 152 |  |  |           return { | 
            
                                                        
            
                                    
            
            
                | 153 |  |  |             error: 'Error occurred: ParseError', | 
            
                                                        
            
                                    
            
            
                | 154 |  |  |             data: { name: 'ParseError' }, | 
            
                                                        
            
                                    
            
            
                | 155 |  |  |           }; | 
            
                                                        
            
                                    
            
            
                | 156 |  |  |         } | 
            
                                                        
            
                                    
            
            
                | 157 |  |  |       }; | 
            
                                                        
            
                                    
            
            
                | 158 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 159 |  |  |       // Call fetch which will use our mocked methods | 
            
                                                        
            
                                    
            
            
                | 160 |  |  |       const result = await sitemapper.fetch( | 
            
                                                        
            
                                    
            
            
                | 161 |  |  |         'https://example.com/root-sitemap.xml' | 
            
                                                        
            
                                    
            
            
                | 162 |  |  |       ); | 
            
                                                        
            
                                    
            
            
                | 163 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 164 |  |  |       // Check the result | 
            
                                                        
            
                                    
            
            
                | 165 |  |  |       result.should.have.property('sites').which.is.an.Array(); | 
            
                                                        
            
                                    
            
            
                | 166 |  |  |       result.should.have.property('errors').which.is.an.Array(); | 
            
                                                        
            
                                    
            
            
                | 167 |  |  |       result.sites.length.should.equal(2); | 
            
                                                        
            
                                    
            
            
                | 168 |  |  |       result.errors.length.should.equal(1); | 
            
                                                        
            
                                    
            
            
                | 169 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 170 |  |  |       // Restore original methods | 
            
                                                        
            
                                    
            
            
                | 171 |  |  |       sitemapper.parse = originalParse; | 
            
                                                        
            
                                    
            
            
                | 172 |  |  |       sitemapper.crawl = originalCrawl; | 
            
                                                        
            
                                    
            
            
                | 173 |  |  |     }); | 
            
                                                        
            
                                    
            
            
                | 174 |  |  |   }); | 
            
                                                        
            
                                    
            
            
                | 175 |  |  | }); | 
            
                                                        
            
                                    
            
            
                | 176 |  |  |  |