diff --git a/src/api/admin/admin.controller.js b/src/api/admin/admin.controller.js index fd0fae7..4ee4bc0 100644 --- a/src/api/admin/admin.controller.js +++ b/src/api/admin/admin.controller.js @@ -1,4 +1,5 @@ const { mainSeed } = require('../../tasks/seed/seed'); +const { fetchVideosJob } = require('../../helpers/fetchData'); async function seed(req, res, next) { try { @@ -9,6 +10,23 @@ async function seed(req, res, next) { } } +async function fetchVideos(req, res, next) { + try { + const { message: info, error } = await fetchVideosJob(); + + const status = error ? 500 : 200; + const message = error || info; + + res.status(status).json({ + status, + message, + }); + } catch (error) { + next(error); + } +} + module.exports = { seed, + fetchVideos, }; diff --git a/src/api/admin/admin.routes.js b/src/api/admin/admin.routes.js index 5a30cd3..48a1bf6 100644 --- a/src/api/admin/admin.routes.js +++ b/src/api/admin/admin.routes.js @@ -1,6 +1,7 @@ const router = require('express').Router(); -const { seed } = require('./admin.controller'); +const { seed, fetchVideos } = require('./admin.controller'); router.post('/seed', seed); +router.post('/fetch-videos', fetchVideos); module.exports = router; diff --git a/src/api/admin/admin.test.js b/src/api/admin/admin.test.js index 24e2549..37e33a8 100644 --- a/src/api/admin/admin.test.js +++ b/src/api/admin/admin.test.js @@ -18,3 +18,11 @@ describe('POST /admin/seed', () => { .expect(200, done); }); }); + +describe('POST /admin/fetch-videos', () => { + it('Should respond with a 200 status code', done => { + request(app) + .post('/admin/fetch-videos') + .expect(200, done); + }); +}); diff --git a/src/helpers/fetchData.js b/src/helpers/fetchData.js index c5adda4..67f2b7f 100644 --- a/src/helpers/fetchData.js +++ b/src/helpers/fetchData.js @@ -1,6 +1,5 @@ /* eslint-disable no-console */ const fetch = require('node-fetch'); -const { red, green } = require('colors/safe'); const Video = require('../api/videos/videos.model'); const { YOUTUBE_API_KEY, YOUTUBE_CHANNEL_ID } = require('../config'); @@ -14,53 +13,88 @@ async function fetchLatestYoutubeVideos({ maxResults, publishedAfter }) { const { items, error } = await resp.json(); if (error) { - error.errors.forEach(({ reason }) => { - console.error(`[fetch-error] ${reason}`); - }); - return []; + // Test this line! + const errors = error.errors.map(err => err.reason).join(', '); + return { + error: errors, + }; } - if (items) { - return items.map(({ id: { videoId: videoID }, snippet: { title: name, publishedAt: date, description, thumbnails: { high: { url: thumbnail } } } }) => { - return { - name, - date, - description, - url: `https://www.youtube.com/watch?v=${videoID}`, - videoID, - thumbnail, - }; - }); + if (!items) { + return []; } - return []; - } catch (err) { - console.error(`[error]: ${err}`); - return []; + + return items.map(({ id: { videoId: videoID }, snippet: { title: name, publishedAt: date, description, thumbnails: { high: { url: thumbnail } } } }) => { + return { + name, + date, + description, + url: `https://www.youtube.com/watch?v=${videoID}`, + videoID, + thumbnail, + }; + }); + } catch (error) { + return { + error, + }; } } async function fetchVideosJob() { try { - const video = await Video.findOne({}).sort({ date: -1 }); + const video = await Video.findOne({}).sort({ + date: -1, + }); // Check if db has at least one video - if (video) { - // Transforms date format to the Youtube-API standard. - const lastDate = video.date.toISOString(); + if (!video) { + return { + message: `Video database is empty.`, + }; + } + + // Transforms date format to the Youtube-API standard. + const lastDate = video.date.toISOString(); + const fetchedVideos = await fetchLatestYoutubeVideos({ + publishedAfter: lastDate, + }); + + if (fetchedVideos.error) { + return { + error: `Fetch error: ${fetchedVideos.error}.`, + }; + } + + if (fetchedVideos.length === 0) { + return { + message: `Youtube API returned an empty array.`, + }; + } - const fetchedVideos = await fetchLatestYoutubeVideos({ publishedAfter: lastDate }); + let savedVideos = 0; - if (fetchedVideos.length > 0) { - fetchedVideos.forEach(async newVideo => { - if (newVideo.date !== lastDate) { - const { name } = await new Video(newVideo).save(); - console.log(green(`[cron-job] Added new video from Youtube: ${name}, at ${new Date().toISOString()}`)); - } - }); + fetchedVideos.forEach(async newVideo => { + if (newVideo.date !== lastDate) { + savedVideos += 1; + await new Video(newVideo).save(); } + }); + if (savedVideos === 0) { + return { + message: `Video DB up to date.`, + }; } - } catch (err) { - console.error(red(`[cron-job-error] ${err}`)); + return { + message: `Saved ${savedVideos} new videos`, + }; + } catch (error) { + return { + error, + }; } } -module.exports = { fetchLatestYoutubeVideos, fetchVideosJob }; +module.exports = { + fetchLatestYoutubeVideos, + fetchVideosJob, +};