@@ -174,6 +174,43 @@ async function failWriteSucceed({ file, watchedFile }) {
174174
175175tmpdir . refresh ( ) ;
176176
177+ function createGlobFileStructure ( nameOfTheDir ) {
178+ const rootDir = tmpdir . resolve ( nameOfTheDir ) ;
179+ mkdirSync ( rootDir ) ;
180+
181+ const rootDirGlob = path . resolve ( rootDir , '**/*.js' ) ;
182+ const directory1 = path . join ( rootDir , 'directory1' ) ;
183+ const directory2 = path . join ( rootDir , 'directory2' ) ;
184+
185+ mkdirSync ( directory1 ) ;
186+ mkdirSync ( directory2 ) ;
187+
188+ const tmpJsFile1 = createTmpFile ( '' , '.js' , directory1 ) ;
189+ const tmpJsFile2 = createTmpFile ( '' , '.js' , directory1 ) ;
190+ const tmpJsFile3 = createTmpFile ( '' , '.js' , directory2 ) ;
191+ const tmpJsFile4 = createTmpFile ( '' , '.js' , directory2 ) ;
192+ const tmpJsFile5 = createTmpFile ( '' , '.js' , directory2 ) ;
193+
194+ const mainJsFile = createTmpFile ( 'console.log(\'running\')' , '.js' , rootDir ) ;
195+ const watchedFiles = [ tmpJsFile1 , tmpJsFile2 , tmpJsFile3 , tmpJsFile4 , tmpJsFile5 ] ;
196+
197+
198+ return { rootDir, rootDirGlob, mainJsFile, watchedFiles }
199+ }
200+
201+ function expectRepeatedCompletes ( mainJsFile , n ) {
202+ const expectedStdout = [ ] ;
203+ for ( let i = 0 ; i < n ; i ++ ) {
204+ if ( i !== 0 ) {
205+ expectedStdout . push ( `Restarting ${ inspect ( ( mainJsFile ) ) } ` ) ;
206+ }
207+ expectedStdout . push ( 'running' ) ;
208+ expectedStdout . push ( `Completed running ${ inspect ( mainJsFile ) } . Waiting for file changes before restarting...` ) ;
209+ }
210+ return expectedStdout ;
211+ }
212+
213+
177214describe ( 'watch mode' , { concurrency : ! process . env . TEST_PARALLEL , timeout : 60_000 } , ( ) => {
178215 it ( 'should watch changes to a file' , async ( ) => {
179216 const file = createTmpFile ( ) ;
@@ -899,48 +936,78 @@ process.on('message', (message) => {
899936 } ) ;
900937
901938 it ( 'should watch files from a given glob pattern --watch-path=./**/*.js' , async ( ) => {
939+ const {
940+ rootDirGlob,
941+ mainJsFile,
942+ watchedFiles
943+ } = createGlobFileStructure ( 'globtestdir-1' ) ;
902944
903- const tmpDirForGlobTest = tmpdir . resolve ( 'glob-test-dir' ) ;
904- mkdirSync ( tmpDirForGlobTest ) ;
945+ const args = [ '--watch-path' , rootDirGlob , mainJsFile ] ;
946+
947+ const { stderr, stdout } = await runWriteSucceed ( {
948+ args,
949+ watchedFile : watchedFiles ,
950+ } ) ;
905951
906- const globPattern = path . resolve ( tmpDirForGlobTest , '**/*.js' ) ;
952+ assert . strictEqual ( stderr , '' ) ;
953+ assert . deepStrictEqual ( stdout , expectRepeatedCompletes ( mainJsFile , 6 ) ) ;
954+ } ) ;
907955
908- const directory1 = path . join ( tmpDirForGlobTest , 'directory1' ) ;
909- const directory2 = path . join ( tmpDirForGlobTest , 'directory2' ) ;
956+ it ( 'should not be able to watch glob pattern paths without read access to the directory' , async ( ) => {
957+ const {
958+ rootDirGlob,
959+ mainJsFile,
960+ watchedFiles
961+ } = createGlobFileStructure ( 'globtestdir-2' ) ;
910962
911- mkdirSync ( directory1 ) ;
912- mkdirSync ( directory2 ) ;
963+ const args = [ '--permission' , '--watch-path' , rootDirGlob , mainJsFile ] ;
964+
965+ const { stderr, stdout } = await runWriteSucceed ( {
966+ args,
967+ watchedFile : watchedFiles
968+ } ) ;
913969
914- const tmpJsFile1 = createTmpFile ( '' , '.js' , directory1 ) ;
915- const tmpJsFile2 = createTmpFile ( '' , '.js' , directory1 ) ;
916- const tmpJsFile3 = createTmpFile ( '' , '.js' , directory2 ) ;
917- const tmpJsFile4 = createTmpFile ( '' , '.js' , directory2 ) ;
918- const tmpJsFile5 = createTmpFile ( '' , '.js' , directory2 ) ;
970+ assert . match ( stderr , / E R R _ A C C E S S _ D E N I E D / ) ;
971+ assert . deepStrictEqual ( stdout , [ ] ) ;
972+ } ) ;
973+
974+ it ( 'should not be able to watch glob pattern paths with partial read access' , async ( ) => {
975+ const {
976+ rootDir,
977+ rootDirGlob,
978+ mainJsFile,
979+ watchedFiles
980+ } = createGlobFileStructure ( 'globtestdir-3' ) ;
981+
982+ const allowedSubDirectory = path . join ( rootDir , 'directory1' ) ;
983+ const args = [ '--permission' , '--allow-fs-read' , allowedSubDirectory , '--watch-path' , rootDirGlob , mainJsFile ] ;
984+
985+ const { stderr, stdout } = await runWriteSucceed ( {
986+ args,
987+ watchedFile : watchedFiles
988+ } ) ;
919989
920- const mainJsFile = createTmpFile ( 'console.log(\'running\')' , '.js' , tmpDirForGlobTest ) ;
990+ assert . match ( stderr , / E R R _ A C C E S S _ D E N I E D / ) ;
991+ assert . deepStrictEqual ( stdout , [ ] ) ;
992+ } ) ;
921993
922- const args = [ '--watch-path' , globPattern , mainJsFile ] ;
923- const watchedFiles = [ tmpJsFile1 , tmpJsFile2 , tmpJsFile3 , tmpJsFile4 , tmpJsFile5 ] ;
994+ it ( 'should be able to watch glob pattern paths with full read access to the directory' , async ( ) => {
995+ const {
996+ rootDir,
997+ rootDirGlob,
998+ mainJsFile,
999+ watchedFiles
1000+ } = createGlobFileStructure ( 'globtestdir-4' ) ;
9241001
1002+ const args = [ '--permission' , '--allow-fs-read' , rootDir , '--watch-path' , rootDirGlob , mainJsFile ] ;
1003+
9251004 const { stderr, stdout } = await runWriteSucceed ( {
9261005 args,
927- watchedFile : watchedFiles ,
1006+ watchedFile : watchedFiles
9281007 } ) ;
9291008
930- function expectRepeatedCompletes ( n ) {
931- const expectedStdout = [ ] ;
932- for ( let i = 0 ; i < n ; i ++ ) {
933- if ( i !== 0 ) {
934- expectedStdout . push ( `Restarting ${ inspect ( ( mainJsFile ) ) } ` ) ;
935- }
936- expectedStdout . push ( 'running' ) ;
937- expectedStdout . push ( `Completed running ${ inspect ( mainJsFile ) } . Waiting for file changes before restarting...` ) ;
938- }
939- return expectedStdout ;
940- }
941-
9421009 assert . strictEqual ( stderr , '' ) ;
943- assert . deepStrictEqual ( stdout , expectRepeatedCompletes ( 6 ) ) ;
944-
1010+ assert . deepStrictEqual ( stdout , expectRepeatedCompletes ( mainJsFile , 6 ) ) ;
9451011 } ) ;
1012+
9461013} ) ;
0 commit comments