| 1 | import { plainToInstance } from 'class-transformer'; |
| 2 | import { validate } |
| 3 | import { describe, expect |
| 4 | |
| 5 | import { GetRepositoryContentsQueryDTO } |
| 6 | |
| 7 | /** Mirrors what the global `ValidationPipe({ transform: true })` does to `req.query`, whose values Express has already percent-decoded once. */ |
| 8 | async function validateQuery( |
| 9 | return validate(plainToInstance |
| 10 | } |
| 11 | |
| 12 | describe('GetRepositoryContentsQueryDTO', () |
| 13 | it('accepts an omitted path', |
| 14 | expect(await validateQuery |
| 15 | }); |
| 16 | |
| 17 | it('accepts a repository-relative directory', |
| 18 | // what "?path=src%2Fdeep" looks like by the time it reaches the pipe |
| 19 | expect(await validateQuery |
| 20 | }); |
| 21 | |
| 22 | it('rejects traversal, including the form that arrives from %2F', |
| 23 | for (const path |
| 24 | const errors = |
| 25 | expect(errors).toHaveLength |
| 26 | expect(errors[0] |
| 27 | } |
| 28 | }); |
| 29 | |
| 30 | it('rejects a NUL byte', |
| 31 | expect(await validateQuery |
| 32 | }); |
| 33 | |
| 34 | it('rejects a non-string path', |
| 35 | // "?path=a&path=b" gives Express an array |
| 36 | expect(await validateQuery |
| 37 | }); |
| 38 | }); |