|
1 | | -import { afterEach, beforeEach, describe, expect, it } from 'vitest'; |
| 1 | +import * as fs from 'fs'; |
| 2 | +import * as path from 'path'; |
| 3 | +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; |
2 | 4 | import * as util from '../../src/config/util'; |
3 | 5 |
|
4 | 6 | describe('util', () => { |
@@ -334,4 +336,134 @@ describe('util', () => { |
334 | 336 | expect(util.detectActiveBundler()).toBe('webpack'); |
335 | 337 | }); |
336 | 338 | }); |
| 339 | + |
| 340 | + describe('findMiddlewareFile', () => { |
| 341 | + vi.mock('../../src/config/util', async () => { |
| 342 | + const actual = await vi.importActual('../../src/config/util'); |
| 343 | + return { |
| 344 | + ...actual, |
| 345 | + getNextjsVersion: vi.fn(), |
| 346 | + }; |
| 347 | + }); |
| 348 | + |
| 349 | + let originalCwd: string; |
| 350 | + let testDir: string; |
| 351 | + |
| 352 | + beforeEach(() => { |
| 353 | + originalCwd = process.cwd(); |
| 354 | + testDir = path.join(__dirname, '.test-middleware-temp'); |
| 355 | + |
| 356 | + // Create test directory |
| 357 | + if (!fs.existsSync(testDir)) { |
| 358 | + fs.mkdirSync(testDir, { recursive: true }); |
| 359 | + } |
| 360 | + |
| 361 | + process.chdir(testDir); |
| 362 | + }); |
| 363 | + |
| 364 | + afterEach(() => { |
| 365 | + process.chdir(originalCwd); |
| 366 | + |
| 367 | + // Clean up test directory |
| 368 | + if (fs.existsSync(testDir)) { |
| 369 | + fs.rmSync(testDir, { recursive: true, force: true }); |
| 370 | + } |
| 371 | + |
| 372 | + vi.clearAllMocks(); |
| 373 | + }); |
| 374 | + |
| 375 | + describe('Next.js <16 (middleware)', () => { |
| 376 | + beforeEach(() => { |
| 377 | + vi.mocked(util.getNextjsVersion).mockReturnValue('15.0.0'); |
| 378 | + }); |
| 379 | + |
| 380 | + it('should find middleware.ts in root directory', () => { |
| 381 | + fs.writeFileSync(path.join(testDir, 'middleware.ts'), 'export default function middleware() {}'); |
| 382 | + |
| 383 | + const result = util.findMiddlewareFile(); |
| 384 | + |
| 385 | + expect(result).toBeDefined(); |
| 386 | + expect(result?.path).toContain('middleware.ts'); |
| 387 | + expect(result?.contents).toBe('export default function middleware() {}'); |
| 388 | + }); |
| 389 | + |
| 390 | + it('should find middleware.js in root directory', () => { |
| 391 | + fs.writeFileSync(path.join(testDir, 'middleware.js'), 'module.exports = function middleware() {}'); |
| 392 | + |
| 393 | + const result = util.findMiddlewareFile(); |
| 394 | + |
| 395 | + expect(result).toBeDefined(); |
| 396 | + expect(result?.path).toContain('middleware.js'); |
| 397 | + expect(result?.contents).toBe('module.exports = function middleware() {}'); |
| 398 | + }); |
| 399 | + |
| 400 | + it('should find middleware.ts in src directory', () => { |
| 401 | + fs.mkdirSync(path.join(testDir, 'src'), { recursive: true }); |
| 402 | + fs.writeFileSync(path.join(testDir, 'src', 'middleware.ts'), 'export default function middleware() {}'); |
| 403 | + |
| 404 | + const result = util.findMiddlewareFile(); |
| 405 | + |
| 406 | + expect(result).toBeDefined(); |
| 407 | + expect(result?.path).toContain(path.join('src', 'middleware.ts')); |
| 408 | + expect(result?.contents).toBe('export default function middleware() {}'); |
| 409 | + }); |
| 410 | + |
| 411 | + it('should prefer root over src directory', () => { |
| 412 | + fs.mkdirSync(path.join(testDir, 'src'), { recursive: true }); |
| 413 | + fs.writeFileSync(path.join(testDir, 'middleware.ts'), 'root middleware'); |
| 414 | + fs.writeFileSync(path.join(testDir, 'src', 'middleware.ts'), 'src middleware'); |
| 415 | + |
| 416 | + const result = util.findMiddlewareFile(); |
| 417 | + |
| 418 | + expect(result).toBeDefined(); |
| 419 | + expect(result?.contents).toBe('root middleware'); |
| 420 | + }); |
| 421 | + |
| 422 | + it('should prefer .ts over .js extension', () => { |
| 423 | + fs.writeFileSync(path.join(testDir, 'middleware.ts'), 'typescript middleware'); |
| 424 | + fs.writeFileSync(path.join(testDir, 'middleware.js'), 'javascript middleware'); |
| 425 | + |
| 426 | + const result = util.findMiddlewareFile(); |
| 427 | + |
| 428 | + expect(result).toBeDefined(); |
| 429 | + expect(result?.contents).toBe('typescript middleware'); |
| 430 | + }); |
| 431 | + |
| 432 | + it('should NOT find proxy.ts on Next.js <16', () => { |
| 433 | + fs.writeFileSync(path.join(testDir, 'proxy.ts'), 'export default function proxy() {}'); |
| 434 | + |
| 435 | + const result = util.findMiddlewareFile(); |
| 436 | + |
| 437 | + expect(result).toBeUndefined(); |
| 438 | + }); |
| 439 | + |
| 440 | + it('should return undefined when no middleware file exists', () => { |
| 441 | + const result = util.findMiddlewareFile(); |
| 442 | + |
| 443 | + expect(result).toBeUndefined(); |
| 444 | + }); |
| 445 | + }); |
| 446 | + |
| 447 | + // Note: Tests for Next.js 16+ (proxy) behavior would require mocking getNextjsVersion, |
| 448 | + // which is challenging in this test setup due to module imports. |
| 449 | + // The logic is the same as middleware tests but with 'proxy' instead of 'middleware'. |
| 450 | + |
| 451 | + describe('edge cases', () => { |
| 452 | + beforeEach(() => { |
| 453 | + vi.mocked(util.getNextjsVersion).mockReturnValue('15.0.0'); |
| 454 | + }); |
| 455 | + |
| 456 | + it('should handle when getNextjsVersion returns undefined', () => { |
| 457 | + vi.mocked(util.getNextjsVersion).mockReturnValue(undefined); |
| 458 | + |
| 459 | + fs.writeFileSync(path.join(testDir, 'middleware.ts'), 'export default function middleware() {}'); |
| 460 | + |
| 461 | + const result = util.findMiddlewareFile(); |
| 462 | + |
| 463 | + // Should default to 'middleware' when version is unknown |
| 464 | + expect(result).toBeDefined(); |
| 465 | + expect(result?.path).toContain('middleware.ts'); |
| 466 | + }); |
| 467 | + }); |
| 468 | + }); |
337 | 469 | }); |
0 commit comments