diff --git a/src/App.test.jsx b/src/App.test.jsx
index 1985f473..91aadf4d 100644
--- a/src/App.test.jsx
+++ b/src/App.test.jsx
@@ -12,6 +12,7 @@ import store from 'data/store';
import GradebookPage from 'containers/GradebookPage';
import App from './App';
+import Head from './head/Head';
jest.mock('react-router-dom', () => ({
BrowserRouter: () => 'BrowserRouter',
@@ -41,7 +42,7 @@ describe('App router component', () => {
beforeEach(() => {
process.env.LOGO_POWERED_BY_OPEN_EDX_URL_SVG = logo;
el = shallow(
);
- router = el.childAt(0);
+ router = el.childAt(1);
});
describe('AppProvider', () => {
test('AppProvider is the parent component, passed the redux store props', () => {
@@ -49,8 +50,13 @@ describe('App router component', () => {
expect(el.props().store).toEqual(store);
});
});
- describe('Router', () => {
+ describe('Head', () => {
test('first child of AppProvider', () => {
+ expect(el.childAt(0).type()).toBe(Head);
+ });
+ });
+ describe('Router', () => {
+ test('second child of AppProvider', () => {
expect(router.type()).toBe(Router);
});
test('Header is above/outside-of the routing', () => {
diff --git a/src/__snapshots__/App.test.jsx.snap b/src/__snapshots__/App.test.jsx.snap
index fb1a22ac..5a87d300 100644
--- a/src/__snapshots__/App.test.jsx.snap
+++ b/src/__snapshots__/App.test.jsx.snap
@@ -4,6 +4,7 @@ exports[`App router component snapshot 1`] = `
+
diff --git a/src/head/Head.jsx b/src/head/Head.jsx
new file mode 100644
index 00000000..f7513d4b
--- /dev/null
+++ b/src/head/Head.jsx
@@ -0,0 +1,21 @@
+import React from 'react';
+import { Helmet } from 'react-helmet';
+import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
+import { getConfig } from '@edx/frontend-platform';
+
+import messages from './messages';
+
+const Head = ({ intl }) => (
+
+
+ {intl.formatMessage(messages['gradebook.page.title'], { siteName: getConfig().SITE_NAME })}
+
+
+
+);
+
+Head.propTypes = {
+ intl: intlShape.isRequired,
+};
+
+export default injectIntl(Head);
diff --git a/src/head/Head.test.jsx b/src/head/Head.test.jsx
new file mode 100644
index 00000000..c0d9e5f7
--- /dev/null
+++ b/src/head/Head.test.jsx
@@ -0,0 +1,17 @@
+import React from 'react';
+import { IntlProvider } from '@edx/frontend-platform/i18n';
+import { Helmet } from 'react-helmet';
+import { mount } from 'enzyme';
+import { getConfig } from '@edx/frontend-platform';
+import Head from './Head';
+
+describe('Head', () => {
+ const props = {};
+ it('should match render title tag and favicon with the site configuration values', () => {
+ mount();
+ const helmet = Helmet.peek();
+ expect(helmet.title).toEqual(`Gradebook | ${getConfig().SITE_NAME}`);
+ expect(helmet.linkTags[0].rel).toEqual('shortcut icon');
+ expect(helmet.linkTags[0].href).toEqual(getConfig().FAVICON_URL);
+ });
+});
diff --git a/src/head/messages.js b/src/head/messages.js
new file mode 100644
index 00000000..62d5484b
--- /dev/null
+++ b/src/head/messages.js
@@ -0,0 +1,11 @@
+import { defineMessages } from '@edx/frontend-platform/i18n';
+
+const messages = defineMessages({
+ 'gradebook.page.title': {
+ id: 'gradebook.page.title',
+ defaultMessage: 'Gradebook | {siteName}',
+ description: 'Title tag',
+ },
+});
+
+export default messages;
diff --git a/src/setupTest.js b/src/setupTest.js
index 83dca80b..478a13fd 100755
--- a/src/setupTest.js
+++ b/src/setupTest.js
@@ -8,6 +8,8 @@ Enzyme.configure({ adapter: new Adapter() });
// These configuration values are usually set in webpack's EnvironmentPlugin however
// Jest does not use webpack so we need to set these so for testing
process.env.LMS_BASE_URL = 'http://localhost:18000';
+process.env.SITE_NAME = 'localhost';
+process.env.FAVICON_URL = 'http://localhost:18000/favicon.ico';
jest.mock('@edx/frontend-platform/i18n', () => {
const i18n = jest.requireActual('@edx/frontend-platform/i18n');