From 6f0f6296e4b0684bfc468fc77ce8e8ab82ca19d5 Mon Sep 17 00:00:00 2001
From: Raymond Zhou <56318341+rayzhou-bit@users.noreply.github.com>
Date: Tue, 1 Mar 2022 11:32:03 -0500
Subject: [PATCH] test: cms api tests + extra lint (#25)
---
.../components/EditorFooter/index.test.jsx | 10 +-
.../EditorHeader/HeaderTitle.test.jsx | 4 +-
.../components/EditorHeader/hooks.test.js | 2 +-
src/editors/components/EditorHeader/index.jsx | 4 +-
.../components/EditorHeader/index.test.jsx | 5 +-
src/editors/data/services/cms/api.test.js | 137 ++++++++++--------
src/editors/data/services/cms/urls.test.js | 2 +-
7 files changed, 91 insertions(+), 73 deletions(-)
diff --git a/src/editors/components/EditorFooter/index.test.jsx b/src/editors/components/EditorFooter/index.test.jsx
index 3711cc87d..c9e36fffd 100644
--- a/src/editors/components/EditorFooter/index.test.jsx
+++ b/src/editors/components/EditorFooter/index.test.jsx
@@ -23,11 +23,11 @@ jest.mock('../../data/redux', () => ({
}));
jest.mock('.', () => ({
- __esModule: true, // Use it when dealing with esModules
- ...jest.requireActual('./index'),
- handleCancelClicked: jest.fn(args => ({ handleCancelClicked: args })),
- handleSaveClicked: jest.fn(args => ({ handleSaveClicked: args })),
- }
+ __esModule: true, // Use it when dealing with esModules
+ ...jest.requireActual('./index'),
+ handleCancelClicked: jest.fn(args => ({ handleCancelClicked: args })),
+ handleSaveClicked: jest.fn(args => ({ handleSaveClicked: args })),
+}
));
jest.mock('../../hooks', () => ({
diff --git a/src/editors/components/EditorHeader/HeaderTitle.test.jsx b/src/editors/components/EditorHeader/HeaderTitle.test.jsx
index 6ff64689a..88bd1e4fd 100644
--- a/src/editors/components/EditorHeader/HeaderTitle.test.jsx
+++ b/src/editors/components/EditorHeader/HeaderTitle.test.jsx
@@ -57,11 +57,11 @@ describe('HeaderTitle', () => {
expect(shallow()).toMatchSnapshot();
});
test('initialized', () => {
- localTitleHooks.mockReturnValue(hookProps);
+ localTitleHooks.mockReturnValue(localTitleHooksProps);
expect(shallow()).toMatchSnapshot();
});
test('editing', () => {
- localTitleHooks.mockReturnValue({ ...hookProps, isEditing: true });
+ localTitleHooks.mockReturnValue({ ...localTitleHooksProps, isEditing: true });
expect(shallow()).toMatchSnapshot();
});
});
diff --git a/src/editors/components/EditorHeader/hooks.test.js b/src/editors/components/EditorHeader/hooks.test.js
index a6f182150..3acaa4dac 100644
--- a/src/editors/components/EditorHeader/hooks.test.js
+++ b/src/editors/components/EditorHeader/hooks.test.js
@@ -132,7 +132,7 @@ describe('EditorHeader hooks', () => {
expect(output.startEditing).toEqual(values.startEditing);
expect(output.stopEditing).toEqual(values.stopEditing);
});
- it('returns localTitle, updateTitle, and handleChange, tied to the localTitle hook', () => {
+ it('returns localTitle, updateTitle, and handleChange, tied to the localTitle hook', () => {
expect(output.updateTitle).toEqual({
setBlockTitle,
stopEditing: values.stopEditing,
diff --git a/src/editors/components/EditorHeader/index.jsx b/src/editors/components/EditorHeader/index.jsx
index f94db3baa..5d91810b8 100644
--- a/src/editors/components/EditorHeader/index.jsx
+++ b/src/editors/components/EditorHeader/index.jsx
@@ -2,7 +2,9 @@ import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
-import { ActionRow, IconButton, Icon, ModalDialog } from '@edx/paragon';
+import {
+ ActionRow, IconButton, Icon, ModalDialog,
+} from '@edx/paragon';
import { Close } from '@edx/paragon/icons';
import { selectors } from '../../data/redux';
diff --git a/src/editors/components/EditorHeader/index.test.jsx b/src/editors/components/EditorHeader/index.test.jsx
index d599e27d9..c17490c61 100644
--- a/src/editors/components/EditorHeader/index.test.jsx
+++ b/src/editors/components/EditorHeader/index.test.jsx
@@ -31,9 +31,8 @@ describe('Editor Header index', () => {
returnUrl: 'TeST-ReTurNurL',
};
const { EditorHeader } = module;
- let el;
- el = shallow();
-
+ const el = shallow();
+
describe('behavior', () => {
test('IconButton onClick calls navigateCallback', () => {
const iconButtonControl = el.find(IconButton);
diff --git a/src/editors/data/services/cms/api.test.js b/src/editors/data/services/cms/api.test.js
index 9c92412d5..94d81306d 100644
--- a/src/editors/data/services/cms/api.test.js
+++ b/src/editors/data/services/cms/api.test.js
@@ -1,66 +1,83 @@
-import axios from 'axios'; // eslint-disable-line import/no-extraneous-dependencies
-import { fetchBlockById, fetchUnitById, saveBlock } from './api';
+import {
+ fetchBlockById, fetchByUnitId, normalizeContent, saveBlock,
+} from './api';
+import * as urls from './urls';
+import { get, post } from './utils';
-const get = jest.spyOn(axios, 'get');
-const post = jest.spyOn(axios, 'post');
+jest.mock('./urls', () => ({
+ block: jest.fn().mockName('urls.block'),
+ blockAncestor: jest.fn().mockName('urls.blockAncestor'),
+}));
+
+jest.mock('./utils', () => ({
+ get: jest.fn().mockName('get'),
+ post: jest.fn().mockName('post'),
+}));
-const saveFunctionsGet = {
- setValue: jest.fn(),
- setError: jest.fn(),
- setLoading: jest.fn(),
-};
-const saveFunctionsSave = {
- setResponse: jest.fn(),
- setInProgress: jest.fn(),
-};
const blockId = 'coursev1:2uX@4345432';
+const content = 'Im baby palo santo ugh celiac fashion axe. La croix lo-fi venmo whatever. Beard man braid migas single-origin coffee forage ramps.';
+const courseId = 'demo2uX';
const studioEndpointUrl = 'hortus.coa';
+const title = 'remember this needs to go into metadata to save';
-test('fetchBlockById 404', () => {
- get.mockRejectedValue({ response: { status: 404 } });
- fetchBlockById(saveFunctionsGet, blockId, studioEndpointUrl);
- expect(saveFunctionsGet.setLoading).toHaveBeenCalled();
- expect(saveFunctionsGet.setError).toHaveBeenCalled();
-});
-test('fetchBlockById 403', () => {
- get.mockRejectedValue({ response: { status: 403 } });
- fetchBlockById(saveFunctionsGet, blockId, studioEndpointUrl);
- expect(saveFunctionsGet.setLoading).toHaveBeenCalled();
- expect(saveFunctionsGet.setError).toHaveBeenCalled();
-});
-test('fetchBlockById 408', () => {
- get.mockRejectedValue({ response: { status: 408 } });
- fetchBlockById(saveFunctionsGet, blockId, studioEndpointUrl);
- expect(saveFunctionsGet.setLoading).toHaveBeenCalled();
- expect(saveFunctionsGet.setError).toHaveBeenCalled();
-});
-test('fetchBlockById 404', () => {
- get.mockRejectedValue({ response: { status: 404 } });
- fetchBlockById(saveFunctionsGet, blockId, studioEndpointUrl);
- expect(saveFunctionsGet.setLoading).toHaveBeenCalled();
- expect(saveFunctionsGet.setError).toHaveBeenCalled();
-});
-test('fetchUnitById 401', () => {
- get.mockRejectedValue({ response: { status: 401 } });
- fetchUnitById(saveFunctionsGet, blockId, studioEndpointUrl);
- expect(saveFunctionsGet.setLoading).toHaveBeenCalled();
- expect(saveFunctionsGet.setError).toHaveBeenCalled();
-});
-test('fetchUnitById 404', () => {
- get.mockRejectedValue({ response: { status: 404 } });
- fetchUnitById(saveFunctionsGet, blockId, studioEndpointUrl);
- expect(saveFunctionsGet.setLoading).toHaveBeenCalled();
- expect(saveFunctionsGet.setError).toHaveBeenCalled();
-});
-test('saveBlock 408', () => {
- post.mockRejectedValue({ response: { status: 408 } });
- saveBlock(blockId, 'html', 'demo2uX', studioEndpointUrl, 'Im baby palo santo ugh celiac fashion axe. La croix lo-fi venmo whatever. Beard man braid migas single-origin coffee forage ramps.', saveFunctionsSave);
- expect(saveFunctionsSave.setInProgress).toHaveBeenCalled();
- expect(saveFunctionsSave.setResponse).toHaveBeenCalled();
-});
-test('saveBlock 404', () => {
- post.mockRejectedValue({ response: { status: 404 } });
- saveBlock(blockId, 'html', 'demo2uX', studioEndpointUrl, 'Im baby palo santo ugh celiac fashion axe. La croix lo-fi venmo whatever. Beard man braid migas single-origin coffee forage ramps.', saveFunctionsSave);
- expect(saveFunctionsSave.setInProgress).toHaveBeenCalled();
- expect(saveFunctionsSave.setResponse).toHaveBeenCalled();
+describe('cms api', () => {
+ describe('fetchBlockId', () => {
+ it('should call get with url.blocks', () => {
+ fetchBlockById({ blockId, studioEndpointUrl });
+ expect(get).toHaveBeenCalledWith(urls.block({ blockId, studioEndpointUrl }));
+ });
+ });
+
+ describe('fetchByUnitId', () => {
+ it('should call get with url.blockAncestor', () => {
+ fetchByUnitId({ blockId, studioEndpointUrl });
+ expect(get).toHaveBeenCalledWith(urls.blockAncestor({ studioEndpointUrl, blockId }));
+ });
+ });
+
+ describe('normalizeContent', () => {
+ test('return value for blockType: html', () => {
+ expect(normalizeContent({
+ blockId,
+ blockType: 'html',
+ content,
+ courseId,
+ title,
+ })).toEqual({
+ category: 'html',
+ couseKey: courseId,
+ data: content,
+ has_changes: true,
+ id: blockId,
+ metadata: { display_name: title },
+ });
+ });
+ test('throw error for invalid blockType', () => {
+ expect(() => { normalizeContent({ blockType: 'somethingINVALID' }); })
+ .toThrow(TypeError);
+ });
+ });
+
+ describe('saveBlock', () => {
+ it('should call post with urls.block and normalizeContent', () => {
+ saveBlock({
+ blockId,
+ blockType: 'html',
+ content,
+ courseId,
+ studioEndpointUrl,
+ title,
+ });
+ expect(post).toHaveBeenCalledWith(
+ urls.block({ studioEndpointUrl }),
+ normalizeContent({
+ blockType: 'html',
+ content,
+ blockId,
+ courseId,
+ title,
+ }),
+ );
+ });
+ });
});
diff --git a/src/editors/data/services/cms/urls.test.js b/src/editors/data/services/cms/urls.test.js
index 5e3e20b46..190728fd0 100644
--- a/src/editors/data/services/cms/urls.test.js
+++ b/src/editors/data/services/cms/urls.test.js
@@ -34,4 +34,4 @@ describe('cms url methods', () => {
.toEqual(`${block({ studioEndpointUrl, blockId })}?fields=ancestorInfo`);
});
});
-});
\ No newline at end of file
+});