diff --git a/package.json b/package.json index 2220db3..c410e6a 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,9 @@ "lint": "eslint ./app.js routes", "format": "eslint --fix . bin --ignore public node_modules", "test:integration": "jest test/integration", - "test:integration:watch": "jest test/integration --watch" + "test:integration:watch": "jest test/integration --watch", + "test:unit": "jest test/unit", + "test:unit:watch": "jest test/unit --watch" }, "engines": { "node": ">=8.4.0" diff --git a/test/unit/index.test.js b/test/unit/index.test.js new file mode 100644 index 0000000..98a05c0 --- /dev/null +++ b/test/unit/index.test.js @@ -0,0 +1,92 @@ +/* global describe, test, beforeAll, afterEach, jest, expect */ +const { getCourses, getCourse, getCoursesByCategory, getLesson } = require('../../routes/courses') +const { getSettings } = require('../../routes/settings') +const { mockCourse, mockCategory } = require('./mocks/index') + +jest.mock('../../services/contentful') +const contentful = require('../../services/contentful') + +const req = {} +const res = { + locals: { + currentLocale: { + code: 'en-US' + }, + currentApi: { + id: 'cda' + } + } +} + +beforeAll(() => { + contentful.getCourses.mockImplementation(() => [mockCourse]) + contentful.getCourse.mockImplementation(() => mockCourse) + + contentful.getCategories.mockImplementation(() => [mockCategory]) + + contentful.getCoursesByCategory.mockImplementation(() => []) + res.render = jest.fn() + res.cookie = jest.fn() + req.cookies = { visitedLessons: [] } +}) + +afterEach(() => { + res.render.mockClear() + res.render.mockReset() +}) + +describe('Courses', () => { + test('it should courses list once', async () => { + await getCourses(req, res) + expect(res.render.mock.calls[0][0]).toBe('courses') + expect(res.render.mock.calls[0][1].title).toBe('All Courses (1)') + expect(res.render.mock.calls[0][1].courses.length).toBe(1) + expect(res.render.mock.calls.length).toBe(1) + }) + + test('it should render single course once', async () => { + req.params = {slug: 'slug', lslug: 'lessonSlug'} + await getCourse(req, res) + expect(res.render.mock.calls[0][0]).toBe('course') + expect(res.render.mock.calls[0][1].title).toBe(mockCourse.fields.title) + expect(res.render.mock.calls[0][1].course.sys.id).toBe(mockCourse.sys.id) + expect(res.render.mock.calls[0][1].lesson.sys.id).toBe(mockCourse.fields.lessons[0].sys.id) + expect(res.render.mock.calls.length).toBe(1) + }) + test('it should render list of courses by categories', async () => { + req.params = {slug: 'slug', lslug: 'lslug', category: 'categorySlug'} + await getCoursesByCategory(req, res) + expect(res.render.mock.calls[0][0]).toBe('courses') + expect(res.render.mock.calls[0][1].title).toBe(`${mockCategory.fields.title} (0)`) + expect(res.render.mock.calls.length).toBe(1) + }) +}) + +describe('Lessons', () => { + test('it should render a lesson', async () => { + req.params = { cslug: 'courseSlug', lslug: 'lessonSlug' } + await getLesson(req, res) + expect(res.render.mock.calls[0][0]).toBe('course') + expect(res.render.mock.calls[0][1].title).toBe('Course title | Lesson title') + expect(res.render.mock.calls[0][1].course.sys.id).toBe(mockCourse.sys.id) + expect(res.render.mock.calls[0][1].lesson.sys.id).toBe(mockCourse.fields.lessons[0].sys.id) + expect(res.render.mock.calls.length).toBe(1) + }) +}) + +describe('Settings', () => { + test('It should render settings', async () => { + res.locals = { + settings: { + space: 'spaceId', + cda: 'cda', + cpa: 'cpa', + editorialFeatures: false + } + } + await getSettings(req, res) + expect(res.render.mock.calls[0][0]).toBe('settings') + expect(res.render.mock.calls[0][1].title).toBe('Settings') + expect(res.render.mock.calls[0][1].settings).toBe(res.locals.settings) + }) +}) diff --git a/test/unit/mocks/index.js b/test/unit/mocks/index.js new file mode 100644 index 0000000..b6c75a9 --- /dev/null +++ b/test/unit/mocks/index.js @@ -0,0 +1,24 @@ +const mockCourse = { + sys: { id: 'courseId' }, + fields: { + title: 'Course title', + lessons: [ + { sys: {id: 'lessonId'}, fields: { slug: 'lessonSlug', title: 'Lesson title' } } + ] + } +} + +const mockCategory = { + sys: { + id: 'categoryId' + }, + fields: { + slug: 'categorySlug', + title: 'categoryTitle' + } +} + +module.exports = { + mockCourse, + mockCategory +}