| 
									
										
										
										
											2018-12-06 11:18:56 +00:00
										 |  |  | const readdirp = require('readdirp-walk'); | 
					
						
							|  |  |  | const { has, isEmpty, isNumber } = require('lodash'); | 
					
						
							|  |  |  | const ora = require('ora'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const { parseMarkdown } = require('../../challenge-md-parser'); | 
					
						
							|  |  |  | const { challengeRoot, checkFrontmatter } = require('./md-testing-utils'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const scrimbaUrlRE = /^https:\/\/scrimba\.com\//; | 
					
						
							|  |  |  | const requiredProps = ['title', 'id', 'challengeType']; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const spinner = ora('Checking challenge markdown formatting').start(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | readdirp({ root: challengeRoot, directoryFilter: '!_meta' }) | 
					
						
							|  |  |  |   .on('data', file => | 
					
						
							|  |  |  |     Promise.all([ | 
					
						
							|  |  |  |       isChallengeParseable(file), | 
					
						
							|  |  |  |       checkFrontmatter(file, { | 
					
						
							|  |  |  |         validator: challengeFrontmatterValidator(file) | 
					
						
							|  |  |  |       }) | 
					
						
							|  |  |  |     ]).catch(err => { | 
					
						
							|  |  |  |       console.info(`
 | 
					
						
							|  |  |  |   the following error occured when testing | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ${file.fullPath} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     `);
 | 
					
						
							|  |  |  |       console.error(err); | 
					
						
							|  |  |  |       // eslint-disable-next-line no-process-exit
 | 
					
						
							|  |  |  |       process.exit(1); | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  |   ) | 
					
						
							|  |  |  |   .on('end', () => spinner.stop()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const challengeFrontmatterValidator = file => frontmatter => { | 
					
						
							|  |  |  |   const { fullPath } = file; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const hasRequiredProperties = requiredProps | 
					
						
							|  |  |  |     .map( | 
					
						
							|  |  |  |       prop => | 
					
						
							|  |  |  |         has(frontmatter, prop) && | 
					
						
							|  |  |  |         (!isEmpty(frontmatter[prop]) || isNumber(frontmatter[prop])) | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     .every(bool => bool); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!hasRequiredProperties) { | 
					
						
							|  |  |  |     console.log(`${fullPath} is missing required frontmatter
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ${JSON.stringify(frontmatter, null, 2)} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Required properties are: ${JSON.stringify(requiredProps, null, 2)} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     `);
 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   const { videoUrl } = frontmatter; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   let validVideoUrl = false; | 
					
						
							|  |  |  |   if (isEmpty(videoUrl)) { | 
					
						
							|  |  |  |     validVideoUrl = true; | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     validVideoUrl = scrimbaUrlRE.test(videoUrl); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!validVideoUrl) { | 
					
						
							|  |  |  |       console.log(`
 | 
					
						
							|  |  |  |   ${fullPath} contains an invalid videoUrl | 
					
						
							|  |  |  | `);
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return hasRequiredProperties && validVideoUrl; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function isChallengeParseable(file) { | 
					
						
							|  |  |  |   const { stat, fullPath } = file; | 
					
						
							| 
									
										
										
										
											2019-02-19 01:59:12 +03:00
										 |  |  |   if (!stat.isFile() || /_meta/.test(fullPath)) { | 
					
						
							| 
									
										
										
										
											2018-12-06 11:18:56 +00:00
										 |  |  |     return Promise.resolve(true); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return parseMarkdown(fullPath); | 
					
						
							|  |  |  | } |