Compare commits

..

68 Commits

Author SHA1 Message Date
David Joy
9667a5cee4 fix: exporting logo and better proptypes 2019-07-03 15:42:48 -04:00
David Joy
9df6e12174 refactor: dev server, config, and babel the build
BREAKING CHANGE: Defensive breaking change as this drastically changes the repo and how it gets consumed.
2019-07-03 11:10:59 -04:00
AlasdairSwan
31e255ebe9 Merge pull request #44 from edx/alasdair/remove-paragon
perf(paragon): remove paragon to reduce bundle size
2019-06-21 11:14:29 -04:00
AlasdairSwan
349f83f686 perf(paragon): remove paragon to reduce bundle size 2019-06-21 11:11:01 -04:00
David Joy
e0c205ce14 fix: non deprecated use of hyperlink (#43) 2019-06-21 09:56:05 -04:00
albemarle
81398c8cfd Merge pull request #42 from edx/albemarle/different-diff
fix(i18n): make detect_changed_source_translations work for both push and pull jobs
2019-06-11 13:51:08 -04:00
albemarle
3fcd76b455 fix(i18n): make detect_changed_source_translations work for both push and pull jobs 2019-06-11 13:34:27 -04:00
edX Transifex Bot
a8f57aa553 fix(i18n): update translations 2019-06-09 16:32:55 -04:00
David Joy
f32b0c8dcf Merge pull request #40 from edx/djoy/upgrade_i18n
fix: upgrade frontend-i18n library
2019-06-07 11:12:41 -04:00
David Joy
fb1f5c2d50 fix: delete old i18n concat file 2019-06-07 10:53:50 -04:00
David Joy
1a51d992cd Update .gitignore 2019-06-07 10:07:30 -04:00
David Joy
e9c28163d9 fix: upgrade frontend-i18n library 2019-06-07 08:58:38 -04:00
AlasdairSwan
6db2d70e97 Merge pull request #37 from edx/alasdair/update-link-sections-to-accept-arrays
fix(linkprops): update link props
2019-06-04 09:03:27 -04:00
AlasdairSwan
3ab4adf10b fix(linkprops): update link props
BREAKING CHANGE move to link arrays and remove strings from component (and thus the need for i18n)
2019-06-03 15:57:30 -04:00
edX Transifex Bot
a482325eac fix(i18n): update translations 2019-06-02 17:33:12 -04:00
Douglas Hall
d919d1a577 Merge pull request #38 from edx/douglashall/finish_i18n_refactoring
fix: modify babelrc for i18n
2019-05-31 14:17:28 -04:00
Douglas Hall
4b3a91138d fix: modify babelrc for i18n 2019-05-31 14:11:48 -04:00
David Joy
7680ad3393 Merge pull request #36 from edx/djoy/is-es5
fix: adding es check
2019-05-28 13:33:09 -04:00
David Joy
061b41bee8 fix: adding es check 2019-05-28 09:42:04 -04:00
Douglas Hall
cacae4789f fix: move to @edx/frontend-i18n dependency (#35)
fix: move to @edx/frontend-i18n dependency
2019-05-24 14:20:22 -04:00
Douglas Hall
adceca6b53 fix: move to @edx/frontend-i18n dependency
BREAKING CHANGE: consumers will now be required to supply @edx/frontend-i18n instead of react-intl
2019-05-24 12:06:17 -04:00
Douglas Hall
ab61fd35eb Merge pull request #34 from edx/douglashall/reduce_bundle_size
fix: remove paragon from bundle
2019-05-23 14:34:38 -04:00
Douglas Hall
4d739f2962 fix: remove paragon from bundle
BREAKING CHANGE: Now requires containing app to provide `@edx/paragon`.
2019-05-23 14:28:28 -04:00
albemarle
28a6c85bc0 Merge pull request #30 from edx/aehsan/prod-277/update_the_edx_icp_license
Updated ICP license in footer
2019-05-22 14:01:36 -04:00
adeelehsan
6125988bbd Updated ICP license in footer 2019-05-22 00:33:19 +05:00
edX Transifex Bot
9eeccc63cb fix(i18n): update translations 2019-05-19 17:33:41 -04:00
Robert Raposa
2f33c6718b Merge pull request #31 from edx/robrap/ARCH-748-fix-i18n-jobs
fix(i18n): fix i18n make targets
2019-05-16 13:20:46 -04:00
Adam Stankiewicz
89397fcfdb Merge pull request #32 from edx/astankiewicz/downgrade-query-string
fix(query-string): downgrade query-string to version 5 for es5
2019-05-16 12:57:21 -04:00
Adam Stankiewicz
278b4b1473 fix(query-string): downgrade query-string to version 5 for es5 2019-05-16 09:44:44 -07:00
Robert Raposa
7ff9039bb7 fix(i18n): fix i18n make targets
ARCH-748
2019-05-16 12:27:27 -04:00
Chris Pappas
0cf3164901 Merge pull request #28 from edx/cpappas/ENT-1888
fix: updating enterprise marketing link logic
2019-05-10 16:55:50 -04:00
Christopher Pappas
bf8020dfac fix: updating business marketing footer
fix: adding https:// to business marketing link

fix: fixing marketing link for business

fix: fixing marketing link for business
2019-05-10 15:49:40 -04:00
Adam Butterworth
f2a13b8c8e fix: move dependencies out of footer 2019-05-10 08:27:18 -06:00
Adam Butterworth
3dd9b25d11 fix: move peerDependencies to dependencies 2019-05-10 10:24:23 -04:00
Adam Butterworth
21d7fe04e3 fix: move dependencies out of footer 2019-05-10 10:14:37 -04:00
AlasdairSwan
46d464d515 Merge pull request #27 from edx/alasdair/add-language-selector
Alasdair/add language selector
2019-05-08 13:42:52 -04:00
AlasdairSwan
85ed8fbff4 feat(langselect): add optional language selector 2019-05-08 13:38:01 -04:00
AlasdairSwan
d6adfec189 Merge pull request #25 from edx/alasdair/update-social-media-link-approach
fix(sociallinks): update link props
2019-05-07 12:53:21 -04:00
AlasdairSwan
8b1943356e fix(sociallinks): update link props
BREAKING CHANGE will not render social links unless array is passed in
2019-05-07 12:17:42 -04:00
AlasdairSwan
5aae6e8336 Merge pull request #26 from edx/alasdair/version-bump
fix(version): trivial update to minor version bump
2019-05-07 12:12:33 -04:00
AlasdairSwan
ae18ad45b9 fix(version): trivial update to minor version bump 2019-05-07 11:56:32 -04:00
AlasdairSwan
0e15bb7e55 Merge pull request #24 from edx/alasdair/revert-social-media-links
Revert social media links PR
2019-05-07 11:30:02 -04:00
AlasdairSwan
ff664b9d3b Revert social media links PR 2019-05-07 11:24:04 -04:00
AlasdairSwan
da91fb6392 Merge pull request #23 from edx/alasdair/fontawesome-svg-and-social-link-array-prop
fix(sociallinks): array for social props BREAKING CHANGE: props change
2019-05-07 10:29:25 -04:00
AlasdairSwan
f265c7daa6 fix(sociallinks): array for social props BREAKING CHANGE: props change 2019-05-06 15:08:50 -04:00
albemarle
3037e4d8a6 Merge pull request #22 from edx/albemarle/i18n-travis
build: validate i18n
2019-05-06 10:20:20 -04:00
albemarle
b2a7696c0e build: validate i18n 2019-05-03 15:32:30 -04:00
albemarle
6dc8f64ccb Merge pull request #19 from edx/albemarle/more-i18n
fix(i18n): use up-to-date i18n-concat.js
2019-04-09 15:46:31 -04:00
albemarle
0453d7fbaa fix(i18n): use up-to-date i18n-concat.js 2019-04-09 15:38:46 -04:00
Robert Raposa
fa6d38f422 Merge pull request #18 from edx/albemarle/check-changes
fix(i18n): add detect_changed_source_translations target to stop jobs erroring
2019-04-05 16:52:44 -04:00
albemarle
9f3e945d4e fix(i18n): add detect_changed_source_translations target to stop jobs erroring 2019-04-05 16:42:50 -04:00
edX Transifex Bot
429d19291d fix(i18n): update translations 2019-04-05 16:21:24 -04:00
Matt Tuchfarber
e27bc8de39 Merge pull request #16 from edx/tuchfarber/remove_translation_fail
fix: remove incorrect translation files
2019-04-05 15:38:56 -04:00
Matt Tuchfarber
cd0b84c223 fix: remove incorrect translation files
Remove translation files that were generated by an incorrect transifex
config
2019-04-05 15:33:23 -04:00
Matt Tuchfarber
26810c99e6 Merge pull request #15 from edx/tuchfarber/make_umd_build
Generate builds so they can be used in server rendered apps
2019-04-05 15:20:44 -04:00
Matt Tuchfarber
2fb8ea2608 Generate builds so they can be used in server rendered apps
Current build uses window everywhere, thus breaking server rendered apps
2019-04-05 12:34:52 -04:00
albemarle
16c6da229b Merge pull request #14 from edx/tuchfarber/fix_i18n_quoting
Fix i18n paths
2019-04-04 15:26:50 -04:00
Matt Tuchfarber
fb8de7a59c Fix i18n paths 2019-04-04 15:13:55 -04:00
Robert Raposa
21a9e6c5e1 Merge pull request #13 from edx/robrap/ARCH-460-change-file-ext
fix: update file extension
2019-03-21 14:52:25 -04:00
Robert Raposa
9475888392 fix: update file extension 2019-03-21 14:45:35 -04:00
Robert Raposa
c069f20716 Merge pull request #12 from edx/robrap/ARCH-460-add-empty-language
ARCH-460: fix: add empty language files
2019-03-20 17:14:10 -04:00
Robert Raposa
46772ecc0e fix: add empty language files
ARCH-460
2019-03-20 17:03:47 -04:00
edX Transifex Bot
ca09a07c62 fix(i18n): update translations 2019-03-20 16:36:53 -04:00
Robert Raposa
66f6832887 Merge pull request #9 from edx/robrap/ARCH-460-i18n
ARCH-460: feat: initial localization of footer
2019-03-20 13:16:42 -04:00
Robert Raposa
8f35487558 feat: initial localization of footer
BREAKING CHANGE: Now requires containing app to use `react-intl`. See
update to README for details.

ARCH-460
2019-03-20 12:37:11 -04:00
Adam Butterworth
349a458617 Merge pull request #8 from edx/abutterworth/unique-ids
fix: add unique ids to Icon components
2019-03-08 14:00:06 -05:00
Adam Butterworth
abe3d03f58 fix: update snapshot to reflect new ids 2019-03-08 12:44:00 -05:00
Adam Butterworth
7af4b71faa fix: add unique ids to Icon components 2019-03-08 12:35:35 -05:00
30 changed files with 9643 additions and 12983 deletions

View File

@@ -1,44 +1,23 @@
{ {
"presets": [
[
"@babel/preset-env",
{
"modules": false
},
],
"@babel/preset-react"
],
"plugins": [
["@babel/plugin-proposal-object-rest-spread", {}, "object-rest-spread"],
["@babel/plugin-proposal-class-properties", {}, "class-properties"]
],
"env": { "env": {
"development": {
"presets": [
["env", {
"targets": {
"browsers": ["last 2 versions", "ie 11"]
}
}],
"babel-preset-react"
],
"plugins": [
"transform-object-rest-spread"
]
},
"test": { "test": {
"presets": [ "presets": [
["env", { "@babel/preset-env",
"targets": { "@babel/preset-react"
"browsers": ["last 2 versions", "ie 11"]
}
}],
"babel-preset-react"
], ],
"plugins": [
"rewire",
"transform-object-rest-spread"
]
},
"production": {
"presets": [
["env", {
"targets": {
"browsers": ["last 2 versions", "ie 11"]
}
}],
"babel-preset-react"
],
"plugins": [
"transform-object-rest-spread"
]
} }
} }
} }

View File

@@ -5,8 +5,7 @@
"error", "error",
{ {
"devDependencies": [ "devDependencies": [
"webpack.config.js", "src/lib/setupTest.js",
"src/tests/setupTest.js",
"**/*.test.jsx", "**/*.test.jsx",
"**/*.test.js" "**/*.test.js"
] ]

1
.gitignore vendored
View File

@@ -3,3 +3,4 @@ dist
node_modules node_modules
.idea/ .idea/
/.cache

3
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,3 @@
{
"restructuredtext.confPath": ""
}

16
Makefile Executable file
View File

@@ -0,0 +1,16 @@
requirements:
npm install
# This target is used by Travis.
validate-no-uncommitted-package-lock-changes:
# Checking for package-lock.json changes...
git diff --exit-code package-lock.json
build:
rm -rf ./dist
./node_modules/.bin/babel src --out-dir dist --source-maps --ignore **/*.test.jsx,**/*.stories.jsx,**/__mocks__,**/__snapshots__,**/setupTest.js --copy-files
rm -rf ./dist/example
rm -rf dist/**/*.test.jsx
rm -rf dist/**/__snapshots__
rm -rf dist/**/__mocks__
rm -rf dist/lib/setupTest.js

View File

@@ -4,11 +4,7 @@ frontend-component-footer
|Build Status| |Coveralls| |npm_version| |npm_downloads| |license| |Build Status| |Coveralls| |npm_version| |npm_downloads| |license|
|semantic-release| |semantic-release|
frontend-component-footer is a library containing a site footer frontend-component-footer is a library containing a site footer component for use when building edX frontend applications.
component for use when building edX frontend applications.
At this time, this componenet is hard-coded to match the legacy LMS site footer, including all of its links.
Note: As implemented, it should really be called the ``frontend-component-lms-footer``.
Usage Usage
----- -----
@@ -18,9 +14,11 @@ To install frontend-component-footer into your project::
npm i --save @edx/frontend-component-footer npm i --save @edx/frontend-component-footer
The component expects properties specifying the various URLs that are The component expects properties specifying the various URLs that are
linked in the footer. See the sample app in src/index.jsx for an example linked in the footer. See the sample app in `src/example/index.jsx <src/example/index.jsx>`__ for an example
of how the SiteFooter component can be specified. of how the SiteFooter component can be specified.
The distribution
Development Development
----------- -----------

View File

@@ -1,15 +0,0 @@
// This is the common Webpack config. The dev and prod Webpack configs both
// inherit config defined here.
const path = require('path');
module.exports = {
entry: {
app: path.resolve(__dirname, '../src/index.jsx'),
},
output: {
path: path.resolve(__dirname, '../dist'),
},
resolve: {
extensions: ['.js', '.jsx'],
},
};

View File

@@ -1,115 +0,0 @@
// This is the dev Webpack config. All settings here should prefer a fast build
// time at the expense of creating larger, unoptimized bundles.
const Merge = require('webpack-merge');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
const commonConfig = require('./webpack.common.config.js');
module.exports = Merge.smart(commonConfig, {
mode: 'development',
entry: [
// enable react's custom hot dev client so we get errors reported in the browser
require.resolve('react-dev-utils/webpackHotDevClient'),
path.resolve(__dirname, '../src/index.jsx'),
],
module: {
// Specify file-by-file rules to Webpack. Some file-types need a particular kind of loader.
rules: [
// The babel-loader transforms newer ES2015+ syntax to older ES5 for older browsers.
// Babel is configured with the .babelrc file at the root of the project.
{
test: /\.(js|jsx)$/,
include: [
path.resolve(__dirname, '../src'),
],
loader: 'babel-loader',
options: {
// Caches result of loader to the filesystem. Future builds will attempt to read from the
// cache to avoid needing to run the expensive recompilation process on each run.
cacheDirectory: true,
},
},
// We are not extracting CSS from the javascript bundles in development because extracting
// prevents hot-reloading from working, it increases build time, and we don't care about
// flash-of-unstyled-content issues in development.
{
test: /(.scss|.css)$/,
use: [
'style-loader', // creates style nodes from JS strings
{
loader: 'css-loader', // translates CSS into CommonJS
options: {
sourceMap: true,
},
},
{
loader: 'sass-loader', // compiles Sass to CSS
options: {
sourceMap: true,
includePaths: [
path.join(__dirname, '../node_modules'),
path.join(__dirname, '../src'),
],
},
},
],
},
// Webpack, by default, uses the url-loader for images and fonts that are required/included by
// files it processes, which just base64 encodes them and inlines them in the javascript
// bundles. This makes the javascript bundles ginormous and defeats caching so we will use the
// file-loader instead to copy the files directly to the output directory.
{
test: /\.(woff2?|ttf|svg|eot)(\?v=\d+\.\d+\.\d+)?$/,
loader: 'file-loader',
},
{
test: /\.(jpe?g|png|gif|ico)(\?v=\d+\.\d+\.\d+)?$/,
use: [
'file-loader',
{
loader: 'image-webpack-loader',
options: {
optimizationlevel: 7,
mozjpeg: {
progressive: true,
},
gifsicle: {
interlaced: false,
},
pngquant: {
quality: '65-90',
speed: 4,
},
},
},
],
},
],
},
// Specify additional processing or side-effects done on the Webpack output bundles as a whole.
plugins: [
// Generates an HTML file in the output directory.
new HtmlWebpackPlugin({
inject: true, // Appends script tags linking to the webpack bundles at the end of the body
template: path.resolve(__dirname, '../public/index.html'),
}),
new webpack.EnvironmentPlugin({
NODE_ENV: 'development',
}),
// when the --hot option is not passed in as part of the command
// the HotModuleReplacementPlugin has to be specified in the Webpack configuration
// https://webpack.js.org/configuration/dev-server/#devserver-hot
new webpack.HotModuleReplacementPlugin(),
],
// This configures webpack-dev-server which serves bundles from memory and provides live
// reloading.
devServer: {
host: '0.0.0.0',
port: 3000,
historyApiFallback: true,
hot: true,
inline: true,
},
});

View File

@@ -1,58 +0,0 @@
// This is the prod Webpack config. All settings here should prefer smaller,
// optimized bundles at the expense of a longer build time.
const Merge = require('webpack-merge');
const commonConfig = require('./webpack.common.config.js');
const path = require('path');
const CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = Merge.smart(commonConfig, {
mode: 'production',
devtool: 'source-map',
entry: './src/lib/index.js',
output: {
path: path.resolve(__dirname, '../dist'),
library: 'frontend-component-footer',
libraryTarget: 'umd',
},
resolve: {
extensions: ['.js', '.jsx'],
alias: {
react: path.resolve(__dirname, './node_modules/react'),
'react-dom': path.resolve(__dirname, './node_modules/react-dom'),
},
},
externals: {
react: {
commonjs: 'react',
commonjs2: 'react',
amd: 'React',
root: 'React',
},
'react-dom': {
commonjs: 'react-dom',
commonjs2: 'react-dom',
amd: 'ReactDOM',
root: 'ReactDOM',
},
},
plugins: [
// Cleans the dist directory before each build
new CleanWebpackPlugin(['dist'], {
root: path.join(__dirname, '../'),
}),
],
module: {
rules: [
{
test: /\.(js|jsx)$/,
include: [
path.resolve(__dirname, '../src/lib'),
],
exclude: /(node_modules)/,
use: [
{ loader: 'babel-loader' },
],
},
],
},
});

18377
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -2,13 +2,13 @@
"name": "@edx/frontend-component-footer", "name": "@edx/frontend-component-footer",
"version": "1.0.0-semantically-released", "version": "1.0.0-semantically-released",
"description": "Site footer component for use when building edX frontend applications", "description": "Site footer component for use when building edX frontend applications",
"main": "dist/main.js", "main": "dist/index.js",
"module": "dist/main.js", "module": "dist/index.js",
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"
}, },
"scripts": { "scripts": {
"build": "NODE_ENV=production BABEL_ENV=production webpack --config=config/webpack.prod.config.js", "build": "make build",
"gc": "commit", "gc": "commit",
"commitmsg": "commitlint -e $GIT_PARAMS", "commitmsg": "commitlint -e $GIT_PARAMS",
"coveralls": "cat ./coverage/lcov.info | coveralls", "coveralls": "cat ./coverage/lcov.info | coveralls",
@@ -16,11 +16,10 @@
"precommit": "npm run lint", "precommit": "npm run lint",
"prepublishOnly": "npm run build", "prepublishOnly": "npm run build",
"semantic-release": "semantic-release", "semantic-release": "semantic-release",
"start": "NODE_ENV=development BABEL_ENV=development node_modules/.bin/webpack-dev-server --config=config/webpack.dev.config.js --progress", "start": "./node_modules/.bin/parcel src/example/index.html",
"test": "jest --coverage", "test": "jest --coverage",
"snapshot": "jest --updateSnapshot", "snapshot": "jest --updateSnapshot",
"travis-deploy-once": "travis-deploy-once", "travis-deploy-once": "travis-deploy-once"
"watch": "watch 'npm run build' ./src"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
@@ -33,71 +32,65 @@
}, },
"homepage": "https://github.com/edx/frontend-component-footer#readme", "homepage": "https://github.com/edx/frontend-component-footer#readme",
"devDependencies": { "devDependencies": {
"@babel/cli": "^7.4.4",
"@babel/core": "^7.4.5",
"@babel/plugin-proposal-class-properties": "^7.4.4",
"@babel/plugin-proposal-object-rest-spread": "^7.4.4",
"@babel/preset-env": "^7.4.5",
"@babel/preset-react": "^7.0.0",
"@commitlint/cli": "^7.1.2", "@commitlint/cli": "^7.1.2",
"@commitlint/config-angular": "^6.0.2", "@commitlint/config-angular": "^6.0.2",
"@commitlint/prompt": "^6.0.2", "@commitlint/prompt": "^6.0.2",
"@commitlint/prompt-cli": "^6.0.2", "@commitlint/prompt-cli": "^6.0.2",
"babel-cli": "^6.26.0", "@edx/frontend-i18n": "^3.0.0",
"babel-core": "^6.26.3", "@fortawesome/fontawesome-svg-core": "^1.2.17",
"babel-loader": "^7.1.5", "@fortawesome/free-brands-svg-icons": "^5.8.1",
"babel-plugin-rewire": "^1.2.0", "@fortawesome/free-regular-svg-icons": "^5.8.1",
"babel-plugin-transform-object-rest-spread": "^6.26.0", "@fortawesome/free-solid-svg-icons": "^5.8.1",
"babel-preset-env": "^1.7.0", "@fortawesome/react-fontawesome": "^0.1.4",
"babel-preset-react": "^6.24.1", "babel-jest": "^24.8.0",
"clean-webpack-plugin": "^0.1.19",
"coveralls": "^3.0.0", "coveralls": "^3.0.0",
"css-loader": "^0.28.9",
"@edx/paragon": "^3.8.0",
"enzyme": "^3.3.0", "enzyme": "^3.3.0",
"enzyme-adapter-react-16": "^1.1.1", "enzyme-adapter-react-16": "^1.1.1",
"eslint": "^5.2.0", "eslint": "^6.0.1",
"eslint-config-edx": "^4.0.4", "eslint-config-edx": "^4.0.4",
"eslint-plugin-jsx-a11y": "^6.1.2", "eslint-plugin-jsx-a11y": "^6.1.2",
"file-loader": "^1.1.9", "glob": "^7.1.3",
"html-webpack-plugin": "^3.2.0",
"image-webpack-loader": "^4.2.0",
"husky": "^0.14.3", "husky": "^0.14.3",
"jest": "23.6.0", "jest": "^24.8.0",
"node-sass": "^4.7.2", "parcel-bundler": "^1.12.3",
"prop-types": "^15.5.10", "prop-types": "^15.7.2",
"react": "^16.4.2", "react": "^16.8.6",
"react-dom": "^16.2.0",
"react-dev-utils": "^5.0.0", "react-dev-utils": "^5.0.0",
"react-dom": "^16.8.6",
"react-test-renderer": "^16.6.0", "react-test-renderer": "^16.6.0",
"sass-loader": "^6.0.6", "reactifex": "^1.1.1",
"sass": "^1.22.1",
"semantic-release": "^15.1.7", "semantic-release": "^15.1.7",
"source-map-loader": "^0.2.1", "travis-deploy-once": "^5.0.0"
"style-loader": "^0.20.2",
"travis-deploy-once": "^5.0.0",
"watch": "^1.0.2",
"webpack": "^4.19.1",
"webpack-cli": "^3.1.0",
"webpack-dev-server": "^3.1.9",
"webpack-merge": "^4.2.1"
}, },
"peerDependencies": { "sass": {
"@edx/paragon": "^3.8.0", "includePaths": [
"clean-webpack-plugin": "^0.1.19", "./node_modules"
"html-webpack-plugin": "^3.2.0", ]
"prop-types": "^15.5.10", },
"react": "^16.4.2", "dependencies": {
"react-dom": "^16.2.0", "@edx/paragon": "^6.0.2",
"webpack": "^4.19.1", "lodash.pick": "^4.4.0",
"webpack-merge": "^4.2.1" "query-string": "^5.1.1"
}, },
"jest": { "jest": {
"setupFiles": [ "setupFiles": [
"./src/tests/setupTest.js" "./src/lib/setupTest.js"
], ],
"collectCoverageFrom": [ "collectCoverageFrom": [
"src/lib/**/*.{js,jsx}", "src/lib/**/*.{js,jsx}",
"!src/tests/setupTest.js", "!src/lib/setupTest.js",
"!src/index.js", "!src/lib/index.js",
"!**/node_modules/**", "!**/node_modules/**"
"!**/tests/**"
], ],
"moduleNameMapper": { "moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js", "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/src/lib/__mocks__/fileMock.js",
"\\.(css|scss)$": "identity-obj-proxy" "\\.(css|scss)$": "identity-obj-proxy"
} }
} }

View File

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

192
src/config/index.jsx Normal file
View File

@@ -0,0 +1,192 @@
/* eslint-disable */
import React from 'react';
import pick from 'lodash.pick';
import FooterLogo from './edx-footer.png';
/* TODO: This file is incomplete/non-functional. It needs some thougth about how to get
* messages/intl into it so that we can localize our titles here. I think the right answer is
* for this file to directly import messages.js (next door) and be passed the app's `intl`
* object, as shown below. Then it can call formatMessage on `intl`. Also, the JSX below
* should be evaluated with the IntlProvider when it's actually rendered by the footer, so
* that _should_ work.
*/
let config = {
MARKETING_SITE_BASE_URL: null,
};
let intl = null;
function validateConfiguration(newConfig) {
Object.keys(config).forEach((key) => {
if (newConfig[key] === undefined) {
throw new Error(`Footer configuration error: ${key} is required.`);
}
});
}
export function getDefaultConfiguration(newConfig, newIntl) {
validateConfiguration(newConfig);
config = pick(newConfig, Object.keys(config));
intl = newIntl;
const edXLinks = [
{
title: 'About',
url: `${config.MARKETING_SITE_BASE_URL}/about-us`,
},
{
title: 'edX for Business',
url: config.ENTERPRISE_MARKETING_URL,
queryParams: {
utm_campaign: config.ENTERPRISE_MARKETING_UTM_CAMPAIGN,
utm_medium: config.ENTERPRISE_MARKETING_FOOTER_UTM_MEDIUM,
utm_source: config.ENTERPRISE_MARKETING_UTM_SOURCE,
},
},
{
title: 'Affiliates',
url: `${config.MARKETING_SITE_BASE_URL}/affiliate-program`,
},
{
title: 'Open edX',
url: `${config.OPEN_SOURCE_URL}`,
},
{
title: 'Careers',
url: `${config.MARKETING_SITE_BASE_URL}/careers`,
},
{
title: 'News',
url: `${config.MARKETING_SITE_BASE_URL}/news-announcements`,
},
];
const legalLinks = [
{
title: 'Terms of Service & Honor Code',
url: `${config.MARKETING_SITE_BASE_URL}/edx-terms-service`,
},
{
title: 'Privacy Policy',
url: `${config.MARKETING_SITE_BASE_URL}/edx-privacy-policy`,
},
{
title: 'Accessibility Policy',
url: `${config.MARKETING_SITE_BASE_URL}/accessibility`,
},
{
title: 'Trademark Policy',
url: `${config.MARKETING_SITE_BASE_URL}/trademarks`,
},
{
title: 'Sitemap',
url: `${config.MARKETING_SITE_BASE_URL}/sitemap`,
},
];
const connectLinks = [
{
title: 'Blog',
url: `${config.MARKETING_SITE_BASE_URL}/blog`,
},
{
title: 'Contact Us',
url: `${config.LMS_BASE_URL}/support/contact_us`,
},
{
title: 'Help Center',
url: config.SUPPORT_URL,
},
{
title: 'Media Kit',
url: `${config.MARKETING_SITE_BASE_URL}/media-kit`,
},
{
title: 'Donate',
url: `${config.MARKETING_SITE_BASE_URL}/donate`,
},
];
const socialLinks = [
{
title: 'Facebook',
url: config.FACEBOOK_URL,
icon: <FontAwesomeIcon icon={faFacebookSquare} className="social-icon" size="2x" />,
screenReaderText: 'Like edX on Facebook',
},
{
title: 'Twitter',
url: config.TWITTER_URL,
icon: <FontAwesomeIcon icon={faTwitterSquare} className="social-icon" size="2x" />,
screenReaderText: 'Follow edX on Twitter',
},
{
title: 'Youtube',
url: config.YOU_TUBE_URL,
icon: <FontAwesomeIcon icon={faYoutubeSquare} className="social-icon" size="2x" />,
screenReaderText: 'Subscribe to the edX YouTube channel',
},
{
title: 'LinkedIn',
url: config.LINKED_IN_URL,
icon: <FontAwesomeIcon icon={faLinkedin} className="social-icon" size="2x" />,
screenReaderText: 'Follow edX on LinkedIn',
},
{
title: 'Reddit',
url: config.REDDIT_URL,
icon: <FontAwesomeIcon icon={faRedditSquare} className="social-icon" size="2x" />,
screenReaderText: 'Subscribe to the edX subreddit',
},
];
const copyright = <FormattedMessage
id="footer.site-footer.copyright-text"
defaultMessage="{copyrightSymbol} {startDate}{endDate} {siteName} Inc."
values={{
copyrightSymbol: '©',
startDate: '2012',
endDate: `${new Date().getFullYear()}`,
siteName,
}}
description="Footer copyright text with copyright symbol and dates"
/>
const trademark = <FormattedMessage
id="footer.site-footer.trademark-text"
defaultMessage="EdX, Open edX, and MicroMasters are registered trademarks of edX Inc. | 深圳市恒宇博科技有限公司 {icpLicense}"
values={{ icpLicense: <a href="http://www.beian.miit.gov.cn">粤ICP备17044299号-2</a> }}
description="Footer trademark text"
/>
return {
ariaLabel: "Page Footer",
siteLogo: FooterLogo,
marketingSiteBaseUrl: config.MARKETING_SITE_BASE_URL,
linkSectionOne: edXLinks,
linkSectionTwo: legalLinks,
linkSectionThree: connectLinks,
socialLinks,
showMobileLinks: true,
appleAppStore: {
url: config.APPLE_APP_STORE_URL,
altText: "Download the edX mobile app from the Apple App Store",
},
googlePlayUrl: {
url: config.GOOGLE_PLAY_URL,
altText: "Download the edX mobile app from Google Play",
},
supportedLanguages: [],
languageForm: null,
copyright,
trademark,
}
};
export default getDefaultConfiguration;

91
src/config/messages.js Normal file
View File

@@ -0,0 +1,91 @@
import { defineMessages } from '@edx/frontend-i18n';
const messages = defineMessages({
'footer.site-footer.site-logo.alt-text': {
id: 'footer.site-footer.site-logo.alt-text',
defaultMessage: '{siteName} logo',
description: 'The alt description of the site logo',
},
'footer.site-footer.site-logo.aria-label': {
id: 'footer.site-footer.site-logo.aria-label',
defaultMessage: '{siteName} Home',
description: 'Aria label for the site logo which goes to the marketing site',
},
'footer.site-footer.facebook.title': {
id: 'footer.site-footer.facebook.title',
defaultMessage: 'Facebook',
description: 'Facebook button title',
},
'footer.site-footer.facebook.screen-reader-text': {
id: 'footer.site-footer.facebook.screen-reader-text',
defaultMessage: 'Like {siteName} on Facebook',
description: 'Facebook button screen reader text',
},
'footer.site-footer.twitter.title': {
id: 'footer.site-footer.twitter.title',
defaultMessage: 'Twitter',
description: 'Twitter button title',
},
'footer.site-footer.twitter.screen-reader-text': {
id: 'footer.site-footer.twitter.screen-reader-text',
defaultMessage: 'Follow {siteName} on Twitter',
description: 'Twitter button screen reader text',
},
'footer.site-footer.youtube.title': {
id: 'footer.site-footer.youtube.title',
defaultMessage: 'Youtube',
description: 'Youtube button title',
},
'footer.site-footer.youtube.screen-reader-text': {
id: 'footer.site-footer.youtube.screen-reader-text',
defaultMessage: 'Subscribe to the {siteName} YouTube channel',
description: 'Youtube button screen reader text',
},
'footer.site-footer.linkedin.title': {
id: 'footer.site-footer.linkedin.title',
defaultMessage: 'LinkedIn',
description: 'LinkedIn button title',
},
'footer.site-footer.linkedin.screen-reader-text': {
id: 'footer.site-footer.linkedin.screen-reader-text',
defaultMessage: 'Follow {siteName} on LinkedIn',
description: 'LinkedIn button screen reader text',
},
'footer.site-footer.google-plus.title': {
id: 'footer.site-footer.google-plus.title',
defaultMessage: 'Google+',
description: 'Google+ button title',
},
'footer.site-footer.google-plus.screen-reader-text': {
id: 'footer.site-footer.google-plus.screen-reader-text',
defaultMessage: 'Follow {siteName} on Google+',
description: 'Google+ button screen reader text',
},
'footer.site-footer.reddit.title': {
id: 'footer.site-footer.reddit.title',
defaultMessage: 'Reddit',
description: 'Reddit button title',
},
'footer.site-footer.reddit.screen-reader-text': {
id: 'footer.site-footer.reddit.screen-reader-text',
defaultMessage: 'Subscribe to the {siteName} subreddit',
description: 'Reddit button screen reader text',
},
'footer.site-footer.apple-app-store.alt-text': {
id: 'footer.site-footer.apple-app-store.alt-text',
defaultMessage: 'Download the {siteName} mobile app from the Apple App Store',
description: 'Apple App Store button alt description',
},
'footer.site-footer.google-play.alt-text': {
id: 'footer.site-footer.google-play.alt-text',
defaultMessage: 'Download the {siteName} mobile app from Google Play',
description: 'Google Play button alt description',
},
'footer.site-footer.footer.aria-label': {
id: 'footer.site-footer.footer.aria-label',
defaultMessage: 'Page Footer',
description: 'Aria label for the footer',
},
});
export default messages;

View File

@@ -1,11 +1,12 @@
<!doctype html> <!doctype html>
<html lang="en-us"> <html lang="en-us">
<head> <head>
<title>Footer | edX</title> <title>Example Footer</title>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>
<script src="./index.js"></script>
</body> </body>
</html> </html>

183
src/example/index.js Normal file
View File

@@ -0,0 +1,183 @@
import React from 'react';
import { render } from 'react-dom';
/* eslint-disable import/no-extraneous-dependencies */
import {
faFacebookSquare,
faTwitterSquare,
faYoutubeSquare,
faLinkedin,
faRedditSquare,
} from '@fortawesome/free-brands-svg-icons';
import { faLanguage } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
/* eslint-enable import/no-extraneous-dependencies */
import SiteFooter from '../lib/';
import './index.scss';
import FooterLogo from '../config/edx-footer.png';
const edXLinks = [
{
title: 'About',
url: 'https://www.example.com/about-us',
},
{
title: 'edX for Business',
url: 'https://business.edx.org',
queryParams: { utm_test: 'utm_test_value' },
},
{
title: 'Affiliates',
url: 'https://www.example.com/affiliate-program',
},
{
title: 'Open edX',
url: 'https://www.example.com/open',
},
{
title: 'Careers',
url: 'https://www.example.com/careers',
},
{
title: 'News',
url: 'https://www.example.com/news-announcements',
},
];
const legalLinks = [
{
title: 'Terms of Service & Honor Code',
url: 'https://www.example.com/terms-of-service',
},
{
title: 'Privacy Policy',
url: 'https://www.example.com/privacy-policy',
},
{
title: 'Accessibility Policy',
url: 'https://www.example.com/accessibility',
},
{
title: 'Trademark Policy',
url: 'https://www.example.com/trademarks',
},
{
title: 'Sitemap',
url: 'https://www.example.com/sitemap',
},
];
const connectLinks = [
{
title: 'Blog',
url: 'https://www.example.com/blog',
},
{
title: 'Contact Us',
url: 'https://www.example.com/contact',
},
{
title: 'Help Center',
url: 'https://www.example.com/support',
},
{
title: 'Media Kit',
url: 'https://www.example.com/media-kit',
},
{
title: 'Donate',
url: 'https://www.example.com/donate',
},
];
const socialLinks = [
{
title: 'Facebook',
url: 'https://www.facebook.com',
icon: <FontAwesomeIcon icon={faFacebookSquare} className="social-icon" size="2x" />,
screenReaderText: 'Like edX on Facebook',
},
{
title: 'Twitter',
url: 'https://www.twitter.com',
icon: <FontAwesomeIcon icon={faTwitterSquare} className="social-icon" size="2x" />,
screenReaderText: 'Follow edX on Twitter',
},
{
title: 'Youtube',
url: 'https://www.youtube.com',
icon: <FontAwesomeIcon icon={faYoutubeSquare} className="social-icon" size="2x" />,
screenReaderText: 'Subscribe to the edX YouTube channel',
},
{
title: 'LinkedIn',
url: 'https://www.linkedin.com',
icon: <FontAwesomeIcon icon={faLinkedin} className="social-icon" size="2x" />,
screenReaderText: 'Follow edX on LinkedIn',
},
{
title: 'Reddit',
url: 'https://reddit.com',
icon: <FontAwesomeIcon icon={faRedditSquare} className="social-icon" size="2x" />,
screenReaderText: 'Subscribe to the edX subreddit',
},
];
const App = () => (
<SiteFooter
siteLogo={{
src: FooterLogo,
altText: 'edx Logo',
ariaLabel: 'edX Home',
}}
ariaLabel="Page Footer"
marketingSiteBaseUrl="https://www.example.com"
appleAppStore={{
url: 'https://store.apple.com',
altText: 'Download the edX mobile app from the Apple App Store',
}}
googlePlay={{
url: 'https://play.google.com',
altText: 'Download the edX mobile app from Google Play',
}}
handleAllTrackEvents={() => {}}
linkSectionOne={{
title: 'edX',
linkList: edXLinks,
}}
linkSectionTwo={{
title: 'Legal',
linkList: legalLinks,
}}
linkSectionThree={{
title: 'Connect',
linkList: connectLinks,
}}
socialLinks={socialLinks}
supportedLanguages={[
{
label: 'English',
value: 'en',
}, {
label: 'español',
value: 'es-419',
},
]}
languageForm={{
activeLanguage: 'en',
screenReaderLabel: 'Choose Language',
submitLabel: 'Apply',
icon: <FontAwesomeIcon icon={faLanguage} size="2x" className="text-primary" />,
onLanguageSelected: () => {},
}}
copyright="© 20122019 edX Inc."
trademark={(
<React.Fragment>EdX, Open edX, and MicroMasters are registered trademarks of edX Inc. | 深圳市恒宇博科技有限公司 <a href="http://www.beian.miit.gov.cn">粤ICP备17044299号-2</a></React.Fragment>
)}
/>
);
render(<App />, document.getElementById('root'));

2
src/example/index.scss Normal file
View File

@@ -0,0 +1,2 @@
@import "~@edx/paragon/scss/edx/theme";
@import '../lib/SiteFooter.scss';

5
src/index.js Normal file
View File

@@ -0,0 +1,5 @@
import SiteFooter from './lib';
export { default as FooterLogo } from './config/edx-footer.png';
export { default as config } from './config';
export default SiteFooter;

View File

@@ -1,29 +0,0 @@
import React from 'react';
import { render } from 'react-dom';
import SiteFooter from './lib';
import './index.scss';
import FooterLogo from './edx-footer.png';
const App = () => (
<SiteFooter
siteName="edX"
siteLogo={FooterLogo}
marketingSiteBaseUrl="https://www.example.com"
supportUrl="https://www.example.com/support"
contactUrl="https://www.example.com/contact"
openSourceUrl="https://www.example.com/open"
termsOfServiceUrl="https://www.example.com/terms-of-service"
privacyPolicyUrl="https://www.example.com/privacy-policy"
facebookUrl="https://www.facebook.com"
twitterUrl="https://www.twitter.com"
youTubeUrl="https://www.youtube.com"
linkedInUrl="https://www.linkedin.com"
googlePlusUrl="https://plus.google.com"
redditUrl="https://reddit.com"
appleAppStoreUrl="https://store.apple.com"
googlePlayUrl="https://play.google.com"
/>
);
render(<App />, document.getElementById('root'));

View File

@@ -1,4 +0,0 @@
@import "~@edx/edx-bootstrap/sass/edx/theme";
@import "~bootstrap/scss/bootstrap";
@import './lib/scss/_site-footer.scss';

260
src/lib/SiteFooter.jsx Normal file
View File

@@ -0,0 +1,260 @@
import React from 'react';
import PropTypes from 'prop-types';
import qs from 'query-string';
export const EVENT_NAMES = {
FOOTER_LINK: 'edx.bi.footer.link',
};
export default class SiteFooter extends React.Component {
constructor(props) {
super(props);
this.externalLinkClickHandler = this.externalLinkClickHandler.bind(this);
this.applyLanguageSelection = this.applyLanguageSelection.bind(this);
}
applyLanguageSelection(event) {
event.preventDefault();
const languageCode = event.target.elements['site-footer-language-select'].value;
const { languageForm: { onLanguageSelected } } = this.props;
onLanguageSelected(languageCode);
}
externalLinkClickHandler(event) {
const label = event.currentTarget.getAttribute('href');
const eventName = EVENT_NAMES.FOOTER_LINK;
const properties = {
category: 'outbound_link',
label,
};
this.props.handleAllTrackEvents(eventName, properties);
}
formatUrl(linkData) {
const {
queryParams,
url,
} = linkData;
return queryParams ? `${url}/?${qs.stringify(queryParams)}` : url;
}
renderLinkList({ title, linkList }) {
if (linkList.length > 0) {
return (
<React.Fragment>
<h2>{title}</h2>
<ul className="list-unstyled p-0 m-0">
{linkList.map(link => (
<li key={link.url}>
<a href={this.formatUrl(link)}>{link.title}</a>
</li>
))}
</ul>
</React.Fragment>
);
}
return null;
}
renderMobileLinks() {
const {
showMobileLinks,
appleAppStore,
googlePlay,
} = this.props;
if (showMobileLinks) {
return (
<ul className="d-flex flex-row justify-content-between list-unstyled max-width-264 p-0 mb-5">
<li>
<a href={appleAppStore.url} rel="noopener noreferrer" target="_blank" onClick={this.externalLinkClickHandler}>
<img
className="max-height-39"
alt={appleAppStore.altText}
src="https://prod-edxapp.edx-cdn.org/static/images/app/app_store_badge_135x40.d0558d910630.svg"
/>
</a>
</li>
<li>
<a href={googlePlay.url} rel="noopener noreferrer" target="_blank" onClick={this.externalLinkClickHandler}>
<img
className="max-height-39"
alt={googlePlay.altText}
src="https://prod-edxapp.edx-cdn.org/static/images/app/google_play_badge_45.6ea466e328da.png"
/>
</a>
</li>
</ul>
);
}
return null;
}
render() {
const {
ariaLabel,
linkSectionOne,
linkSectionTwo,
linkSectionThree,
siteLogo,
socialLinks,
supportedLanguages,
languageForm,
marketingSiteBaseUrl,
copyright,
trademark,
} = this.props;
const showLanguageSelector = supportedLanguages.length > 0 &&
languageForm;
return (
<footer
role="contentinfo"
aria-label={ariaLabel}
className="footer d-flex justify-content-center border-top py-3 px-4"
>
<div className="max-width-1180 d-grid">
<div className="area-1">
<a
href={marketingSiteBaseUrl}
aria-label={siteLogo.ariaLabel}
>
<img src={siteLogo.src} alt={siteLogo.altText} />
</a>
{showLanguageSelector &&
<div className="i18n d-flex mt-2">
<form
className="d-flex align-items-start"
onSubmit={this.applyLanguageSelection}
>
{/* eslint-disable-next-line jsx-a11y/label-has-for */}
<label htmlFor="site-footer-language-select">
{languageForm.icon}
<div className="sr-only">{languageForm.screenReaderLabel}</div>
</label>
<select
id="site-footer-language-select"
className="mx-2 mt-1"
name="site-footer-language-select"
defaultValue={languageForm.activeLanguage}
>
{supportedLanguages.map(({ value, label }) =>
<option key={value} value={value}>{label}</option>)}
</select>
<button className="mt-1" type="submit">{languageForm.submitLabel}</button>
</form>
</div>
}
</div>
<div className="area-2">{this.renderLinkList(linkSectionOne)}</div>
<div className="area-3">{this.renderLinkList(linkSectionTwo)}</div>
<div className="area-4">{this.renderLinkList(linkSectionThree)}</div>
<div className="area-5">
{socialLinks.length > 0 &&
<ul className="d-flex flex-row justify-content-between list-unstyled max-width-222 p-0 mb-4">
{socialLinks.map(link => (
<li key={link.url}>
<a
href={link.url}
title={link.title}
rel="noopener noreferrer"
target="_blank"
onClick={this.externalLinkClickHandler}
>
{link.icon}
<span className="sr-only">{link.screenReaderText}</span>
</a>
</li>
))}
</ul>
}
{this.renderMobileLinks()}
<p>
{copyright}
<br />
{trademark}
</p>
</div>
</div>
</footer>
);
}
}
const linkSectionShape = PropTypes.shape({
title: PropTypes.string,
linkList: PropTypes.arrayOf(PropTypes.shape({
title: PropTypes.string.isRequired,
url: PropTypes.string.isRequired,
queryParams: PropTypes.shape({}),
})),
});
SiteFooter.propTypes = {
ariaLabel: PropTypes.string.isRequired,
siteLogo: PropTypes.shape({
src: PropTypes.node,
altText: PropTypes.string,
ariaLabel: PropTypes.string,
}).isRequired,
marketingSiteBaseUrl: PropTypes.string,
linkSectionOne: linkSectionShape,
linkSectionTwo: linkSectionShape,
linkSectionThree: linkSectionShape,
socialLinks: PropTypes.arrayOf(PropTypes.shape({
title: PropTypes.string.isRequired,
url: PropTypes.string.isRequired,
icon: PropTypes.element.isRequired,
screenReaderText: PropTypes.string.isRequired,
})),
showMobileLinks: PropTypes.bool,
appleAppStore: PropTypes.shape({
url: PropTypes.string,
altText: PropTypes.string,
}),
googlePlay: PropTypes.shape({
url: PropTypes.string,
altText: PropTypes.string,
}),
supportedLanguages: PropTypes.arrayOf(PropTypes.shape({
label: PropTypes.string.isRequired,
value: PropTypes.string.isRequired,
})),
languageForm: PropTypes.shape({
screenReaderLabel: PropTypes.string.isRequired,
submitLabel: PropTypes.string.isRequired,
onLanguageSelected: PropTypes.func.isRequired,
icon: PropTypes.node.isRequired,
activeLanguage: PropTypes.string,
}),
copyright: PropTypes.oneOfType([
PropTypes.string,
PropTypes.node,
]),
trademark: PropTypes.oneOfType([
PropTypes.string,
PropTypes.node,
]),
handleAllTrackEvents: PropTypes.func.isRequired,
};
const linkSectionDefault = {
title: null,
linkList: [],
};
SiteFooter.defaultProps = {
marketingSiteBaseUrl: null,
linkSectionOne: linkSectionDefault,
linkSectionTwo: linkSectionDefault,
linkSectionThree: linkSectionDefault,
socialLinks: [],
showMobileLinks: false,
appleAppStore: null,
googlePlay: null,
supportedLanguages: [],
languageForm: null,
copyright: null,
trademark: null,
};

348
src/lib/SiteFooter.test.jsx Normal file
View File

@@ -0,0 +1,348 @@
import React from 'react';
import renderer from 'react-test-renderer';
import { mount } from 'enzyme';
import {
faFacebookSquare,
faTwitterSquare,
faYoutubeSquare,
faLinkedin,
faRedditSquare,
} from '@fortawesome/free-brands-svg-icons';
import { faLanguage } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import FooterLogo from '../config/edx-footer.png';
import SiteFooter, { EVENT_NAMES } from './SiteFooter';
const edXLinks = [
{
title: 'About',
url: 'https://www.example.com/about-us',
},
{
title: 'edX for Business',
url: 'https://business.edx.org',
queryParams: { utm_test: 'utm_test_value' },
},
{
title: 'Affiliates',
url: 'https://www.example.com/affiliate-program',
},
{
title: 'Open edX',
url: 'https://www.example.com/open',
},
{
title: 'Careers',
url: 'https://www.example.com/careers',
},
{
title: 'News',
url: 'https://www.example.com/news-announcements',
},
];
const legalLinks = [
{
title: 'Terms of Service & Honor Code',
url: 'https://www.example.com/terms-of-service',
},
{
title: 'Privacy Policy',
url: 'https://www.example.com/privacy-policy',
},
{
title: 'Accessibility Policy',
url: 'https://www.example.com/accessibility',
},
{
title: 'Trademark Policy',
url: 'https://www.example.com/trademarks',
},
{
title: 'Sitemap',
url: 'https://www.example.com/sitemap',
},
];
const connectLinks = [
{
title: 'Blog',
url: 'https://www.example.com/blog',
},
{
title: 'Contact Us',
url: 'https://www.example.com/contact',
},
{
title: 'Help Center',
url: 'https://www.example.com/support',
},
{
title: 'Media Kit',
url: 'https://www.example.com/media-kit',
},
{
title: 'Donate',
url: 'https://www.example.com/donate',
},
];
const socialLinks = [
{
title: 'Facebook',
url: 'https://www.facebook.com',
icon: <FontAwesomeIcon icon={faFacebookSquare} className="social-icon" size="2x" />,
screenReaderText: 'Like edX on Facebook',
},
{
title: 'Twitter',
url: 'https://www.twitter.com',
icon: <FontAwesomeIcon icon={faTwitterSquare} className="social-icon" size="2x" />,
screenReaderText: 'Follow edX on Twitter',
},
{
title: 'Youtube',
url: 'https://www.youtube.com',
icon: <FontAwesomeIcon icon={faYoutubeSquare} className="social-icon" size="2x" />,
screenReaderText: 'Subscribe to the edX YouTube channel',
},
{
title: 'LinkedIn',
url: 'https://www.linkedin.com',
icon: <FontAwesomeIcon icon={faLinkedin} className="social-icon" size="2x" />,
screenReaderText: 'Follow edX on LinkedIn',
},
{
title: 'Reddit',
url: 'https://reddit.com',
icon: <FontAwesomeIcon icon={faRedditSquare} className="social-icon" size="2x" />,
screenReaderText: 'Subscribe to the edX subreddit',
},
];
const supportedLanguages = [
{
label: 'English',
value: 'en',
}, {
label: 'español',
value: 'es-419',
},
];
const languageForm = {
activeLanguage: 'en',
screenReaderLabel: 'Choose Language',
submitLabel: 'Apply',
icon: <FontAwesomeIcon icon={faLanguage} size="2x" className="text-primary" />,
onLanguageSelected: () => {},
};
const completeSiteFooterComponent = mockHandleAllTrackEvents =>
(
<SiteFooter
siteLogo={{
src: FooterLogo,
altText: 'edx Logo',
ariaLabel: 'edX Home',
}}
ariaLabel="Page Footer"
marketingSiteBaseUrl="https://www.example.com"
appleAppStore={{
url: 'https://store.apple.com',
altText: 'Download the edX mobile app from the Apple App Store',
}}
googlePlay={{
url: 'https://play.google.com',
altText: 'Download the edX mobile app from Google Play',
}}
handleAllTrackEvents={mockHandleAllTrackEvents}
linkSectionOne={{
title: 'edX',
linkList: edXLinks,
}}
linkSectionTwo={{
title: 'Legal',
linkList: legalLinks,
}}
linkSectionThree={{
title: 'Connect',
linkList: connectLinks,
}}
socialLinks={socialLinks}
supportedLanguages={supportedLanguages}
languageForm={languageForm}
copyright="© 20122019 edX Inc."
trademark={(
<React.Fragment>EdX, Open edX, and MicroMasters are registered trademarks of edX Inc. | 深圳市恒宇博科技有限公司 <a href="http://www.beian.miit.gov.cn">粤ICP备17044299号-2</a></React.Fragment>
)}
/>
);
describe('<SiteFooter />', () => {
describe('renders correctly', () => {
it('renders with social and mobile links', () => {
const mockHandleAllTrackEvents = jest.fn();
const tree = renderer
.create(completeSiteFooterComponent(mockHandleAllTrackEvents))
.toJSON();
expect(tree).toMatchSnapshot();
});
it('does not render social links', () => {
const tree = renderer
.create((
<SiteFooter
siteLogo={{
src: FooterLogo,
altText: 'edx Logo',
ariaLabel: 'edX Home',
}}
ariaLabel="Page Footer"
marketingSiteBaseUrl="https://www.example.com"
appleAppStore={{
url: 'https://store.apple.com',
altText: 'Download the edX mobile app from the Apple App Store',
}}
googlePlay={{
url: 'https://play.google.com',
altText: 'Download the edX mobile app from Google Play',
}}
handleAllTrackEvents={jest.fn()}
linkSectionOne={{
title: 'edX',
linkList: edXLinks,
}}
linkSectionTwo={{
title: 'Legal',
linkList: legalLinks,
}}
linkSectionThree={{
title: 'Connect',
linkList: connectLinks,
}}
supportedLanguages={supportedLanguages}
languageForm={languageForm}
copyright="© 20122019 edX Inc."
trademark={(
<React.Fragment>EdX, Open edX, and MicroMasters are registered trademarks of edX Inc. | 深圳市恒宇博科技有限公司 <a href="http://www.beian.miit.gov.cn">粤ICP备17044299号-2</a></React.Fragment>
)}
/>
)).toJSON();
expect(tree).toMatchSnapshot();
});
it('does not render mobile links', () => {
const tree = renderer
.create((
<SiteFooter
siteLogo={{
src: FooterLogo,
altText: 'edx Logo',
ariaLabel: 'edX Home',
}}
ariaLabel="Page Footer"
marketingSiteBaseUrl="https://www.example.com"
appleAppStore={{
url: 'https://store.apple.com',
altText: 'Download the edX mobile app from the Apple App Store',
}}
googlePlay={{
url: 'https://play.google.com',
altText: 'Download the edX mobile app from Google Play',
}}
handleAllTrackEvents={jest.fn()}
linkSectionOne={{
title: 'edX',
linkList: edXLinks,
}}
linkSectionTwo={{
title: 'Legal',
linkList: legalLinks,
}}
linkSectionThree={{
title: 'Connect',
linkList: connectLinks,
}}
socialLinks={socialLinks}
supportedLanguages={supportedLanguages}
languageForm={languageForm}
copyright="© 20122019 edX Inc."
trademark={(
<React.Fragment>EdX, Open edX, and MicroMasters are registered trademarks of edX Inc. | 深圳市恒宇博科技有限公司 <a href="http://www.beian.miit.gov.cn">粤ICP备17044299号-2</a></React.Fragment>
)}
showMobileLinks={false}
/>
)).toJSON();
expect(tree).toMatchSnapshot();
});
it('does not render language selector', () => {
const tree = renderer
.create((
<SiteFooter
siteLogo={{
src: FooterLogo,
altText: 'edx Logo',
ariaLabel: 'edX Home',
}}
ariaLabel="Page Footer"
marketingSiteBaseUrl="https://www.example.com"
appleAppStore={{
url: 'https://store.apple.com',
altText: 'Download the edX mobile app from the Apple App Store',
}}
googlePlay={{
url: 'https://play.google.com',
altText: 'Download the edX mobile app from Google Play',
}}
handleAllTrackEvents={jest.fn()}
linkSectionOne={{
title: 'edX',
linkList: edXLinks,
}}
linkSectionTwo={{
title: 'Legal',
linkList: legalLinks,
}}
linkSectionThree={{
title: 'Connect',
linkList: connectLinks,
}}
socialLinks={socialLinks}
supportedLanguages={supportedLanguages}
copyright="© 20122019 edX Inc."
trademark={(
<React.Fragment>EdX, Open edX, and MicroMasters are registered trademarks of edX Inc. | 深圳市恒宇博科技有限公司 <a href="http://www.beian.miit.gov.cn">粤ICP备17044299号-2</a></React.Fragment>
)}
/>
)).toJSON();
expect(tree).toMatchSnapshot();
});
});
describe('handles analytics', () => {
it('calls handleAllTrackEvents prop when external links clicked', () => {
const mockHandleAllTrackEvents = jest.fn();
const footer = mount((completeSiteFooterComponent(mockHandleAllTrackEvents)));
const externalLinks = footer.find("a[target='_blank']");
expect(externalLinks.length).toEqual(socialLinks.length + 2);
externalLinks.forEach((externalLink) => {
const callIndex = mockHandleAllTrackEvents.mock.calls.length;
externalLink.simulate('click');
expect(mockHandleAllTrackEvents.mock.calls[callIndex]).toEqual([
EVENT_NAMES.FOOTER_LINK,
{
category: 'outbound_link',
label: externalLink.prop('href'),
},
]);
});
});
});
});

View File

@@ -0,0 +1,1503 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<SiteFooter /> renders correctly does not render language selector 1`] = `
<footer
aria-label="Page Footer"
className="footer d-flex justify-content-center border-top py-3 px-4"
role="contentinfo"
>
<div
className="max-width-1180 d-grid"
>
<div
className="area-1"
>
<a
aria-label="edX Home"
href="https://www.example.com"
>
<img
alt="edx Logo"
src="test-file-stub"
/>
</a>
</div>
<div
className="area-2"
>
<h2>
edX
</h2>
<ul
className="list-unstyled p-0 m-0"
>
<li>
<a
href="https://www.example.com/about-us"
>
About
</a>
</li>
<li>
<a
href="https://business.edx.org/?utm_test=utm_test_value"
>
edX for Business
</a>
</li>
<li>
<a
href="https://www.example.com/affiliate-program"
>
Affiliates
</a>
</li>
<li>
<a
href="https://www.example.com/open"
>
Open edX
</a>
</li>
<li>
<a
href="https://www.example.com/careers"
>
Careers
</a>
</li>
<li>
<a
href="https://www.example.com/news-announcements"
>
News
</a>
</li>
</ul>
</div>
<div
className="area-3"
>
<h2>
Legal
</h2>
<ul
className="list-unstyled p-0 m-0"
>
<li>
<a
href="https://www.example.com/terms-of-service"
>
Terms of Service & Honor Code
</a>
</li>
<li>
<a
href="https://www.example.com/privacy-policy"
>
Privacy Policy
</a>
</li>
<li>
<a
href="https://www.example.com/accessibility"
>
Accessibility Policy
</a>
</li>
<li>
<a
href="https://www.example.com/trademarks"
>
Trademark Policy
</a>
</li>
<li>
<a
href="https://www.example.com/sitemap"
>
Sitemap
</a>
</li>
</ul>
</div>
<div
className="area-4"
>
<h2>
Connect
</h2>
<ul
className="list-unstyled p-0 m-0"
>
<li>
<a
href="https://www.example.com/blog"
>
Blog
</a>
</li>
<li>
<a
href="https://www.example.com/contact"
>
Contact Us
</a>
</li>
<li>
<a
href="https://www.example.com/support"
>
Help Center
</a>
</li>
<li>
<a
href="https://www.example.com/media-kit"
>
Media Kit
</a>
</li>
<li>
<a
href="https://www.example.com/donate"
>
Donate
</a>
</li>
</ul>
</div>
<div
className="area-5"
>
<ul
className="d-flex flex-row justify-content-between list-unstyled max-width-222 p-0 mb-4"
>
<li>
<a
href="https://www.facebook.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="Facebook"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-facebook-square fa-w-14 fa-2x social-icon"
data-icon="facebook-square"
data-prefix="fab"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 448 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M448 80v352c0 26.5-21.5 48-48 48h-85.3V302.8h60.6l8.7-67.6h-69.3V192c0-19.6 5.4-32.9 33.5-32.9H384V98.7c-6.2-.8-27.4-2.7-52.2-2.7-51.6 0-87 31.5-87 89.4v49.9H184v67.6h60.9V480H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48z"
fill="currentColor"
style={Object {}}
/>
</svg>
<span
className="sr-only"
>
Like edX on Facebook
</span>
</a>
</li>
<li>
<a
href="https://www.twitter.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="Twitter"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-twitter-square fa-w-14 fa-2x social-icon"
data-icon="twitter-square"
data-prefix="fab"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 448 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-48.9 158.8c.2 2.8.2 5.7.2 8.5 0 86.7-66 186.6-186.6 186.6-37.2 0-71.7-10.8-100.7-29.4 5.3.6 10.4.8 15.8.8 30.7 0 58.9-10.4 81.4-28-28.8-.6-53-19.5-61.3-45.5 10.1 1.5 19.2 1.5 29.6-1.2-30-6.1-52.5-32.5-52.5-64.4v-.8c8.7 4.9 18.9 7.9 29.6 8.3a65.447 65.447 0 0 1-29.2-54.6c0-12.2 3.2-23.4 8.9-33.1 32.3 39.8 80.8 65.8 135.2 68.6-9.3-44.5 24-80.6 64-80.6 18.9 0 35.9 7.9 47.9 20.7 14.8-2.8 29-8.3 41.6-15.8-4.9 15.2-15.2 28-28.8 36.1 13.2-1.4 26-5.1 37.8-10.2-8.9 13.1-20.1 24.7-32.9 34z"
fill="currentColor"
style={Object {}}
/>
</svg>
<span
className="sr-only"
>
Follow edX on Twitter
</span>
</a>
</li>
<li>
<a
href="https://www.youtube.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="Youtube"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-youtube-square fa-w-14 fa-2x social-icon"
data-icon="youtube-square"
data-prefix="fab"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 448 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M186.8 202.1l95.2 54.1-95.2 54.1V202.1zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-42 176.3s0-59.6-7.6-88.2c-4.2-15.8-16.5-28.2-32.2-32.4C337.9 128 224 128 224 128s-113.9 0-142.2 7.7c-15.7 4.2-28 16.6-32.2 32.4-7.6 28.5-7.6 88.2-7.6 88.2s0 59.6 7.6 88.2c4.2 15.8 16.5 27.7 32.2 31.9C110.1 384 224 384 224 384s113.9 0 142.2-7.7c15.7-4.2 28-16.1 32.2-31.9 7.6-28.5 7.6-88.1 7.6-88.1z"
fill="currentColor"
style={Object {}}
/>
</svg>
<span
className="sr-only"
>
Subscribe to the edX YouTube channel
</span>
</a>
</li>
<li>
<a
href="https://www.linkedin.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="LinkedIn"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-linkedin fa-w-14 fa-2x social-icon"
data-icon="linkedin"
data-prefix="fab"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 448 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M416 32H31.9C14.3 32 0 46.5 0 64.3v383.4C0 465.5 14.3 480 31.9 480H416c17.6 0 32-14.5 32-32.3V64.3c0-17.8-14.4-32.3-32-32.3zM135.4 416H69V202.2h66.5V416zm-33.2-243c-21.3 0-38.5-17.3-38.5-38.5S80.9 96 102.2 96c21.2 0 38.5 17.3 38.5 38.5 0 21.3-17.2 38.5-38.5 38.5zm282.1 243h-66.4V312c0-24.8-.5-56.7-34.5-56.7-34.6 0-39.9 27-39.9 54.9V416h-66.4V202.2h63.7v29.2h.9c8.9-16.8 30.6-34.5 62.9-34.5 67.2 0 79.7 44.3 79.7 101.9V416z"
fill="currentColor"
style={Object {}}
/>
</svg>
<span
className="sr-only"
>
Follow edX on LinkedIn
</span>
</a>
</li>
<li>
<a
href="https://reddit.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="Reddit"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-reddit-square fa-w-14 fa-2x social-icon"
data-icon="reddit-square"
data-prefix="fab"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 448 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M283.2 345.5c2.7 2.7 2.7 6.8 0 9.2-24.5 24.5-93.8 24.6-118.4 0-2.7-2.4-2.7-6.5 0-9.2 2.4-2.4 6.5-2.4 8.9 0 18.7 19.2 81 19.6 100.5 0 2.4-2.3 6.6-2.3 9 0zm-91.3-53.8c0-14.9-11.9-26.8-26.5-26.8-14.9 0-26.8 11.9-26.8 26.8 0 14.6 11.9 26.5 26.8 26.5 14.6 0 26.5-11.9 26.5-26.5zm90.7-26.8c-14.6 0-26.5 11.9-26.5 26.8 0 14.6 11.9 26.5 26.5 26.5 14.9 0 26.8-11.9 26.8-26.5 0-14.9-11.9-26.8-26.8-26.8zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-99.7 140.6c-10.1 0-19 4.2-25.6 10.7-24.1-16.7-56.5-27.4-92.5-28.6l18.7-84.2 59.5 13.4c0 14.6 11.9 26.5 26.5 26.5 14.9 0 26.8-12.2 26.8-26.8 0-14.6-11.9-26.8-26.8-26.8-10.4 0-19.3 6.2-23.8 14.9l-65.7-14.6c-3.3-.9-6.5 1.5-7.4 4.8l-20.5 92.8c-35.7 1.5-67.8 12.2-91.9 28.9-6.5-6.8-15.8-11-25.9-11-37.5 0-49.8 50.4-15.5 67.5-1.2 5.4-1.8 11-1.8 16.7 0 56.5 63.7 102.3 141.9 102.3 78.5 0 142.2-45.8 142.2-102.3 0-5.7-.6-11.6-2.1-17 33.6-17.2 21.2-67.2-16.1-67.2z"
fill="currentColor"
style={Object {}}
/>
</svg>
<span
className="sr-only"
>
Subscribe to the edX subreddit
</span>
</a>
</li>
</ul>
<ul
className="d-flex flex-row justify-content-between list-unstyled max-width-264 p-0 mb-5"
>
<li>
<a
href="https://store.apple.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
>
<img
alt="Download the edX mobile app from the Apple App Store"
className="max-height-39"
src="https://prod-edxapp.edx-cdn.org/static/images/app/app_store_badge_135x40.d0558d910630.svg"
/>
</a>
</li>
<li>
<a
href="https://play.google.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
>
<img
alt="Download the edX mobile app from Google Play"
className="max-height-39"
src="https://prod-edxapp.edx-cdn.org/static/images/app/google_play_badge_45.6ea466e328da.png"
/>
</a>
</li>
</ul>
<p>
© 20122019 edX Inc.
<br />
EdX, Open edX, and MicroMasters are registered trademarks of edX Inc. | 深圳市恒宇博科技有限公司
<a
href="http://www.beian.miit.gov.cn"
>
粤ICP备17044299号-2
</a>
</p>
</div>
</div>
</footer>
`;
exports[`<SiteFooter /> renders correctly does not render mobile links 1`] = `
<footer
aria-label="Page Footer"
className="footer d-flex justify-content-center border-top py-3 px-4"
role="contentinfo"
>
<div
className="max-width-1180 d-grid"
>
<div
className="area-1"
>
<a
aria-label="edX Home"
href="https://www.example.com"
>
<img
alt="edx Logo"
src="test-file-stub"
/>
</a>
<div
className="i18n d-flex mt-2"
>
<form
className="d-flex align-items-start"
onSubmit={[Function]}
>
<label
htmlFor="site-footer-language-select"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-language fa-w-20 fa-2x text-primary"
data-icon="language"
data-prefix="fas"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 640 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M152.1 236.2c-3.5-12.1-7.8-33.2-7.8-33.2h-.5s-4.3 21.1-7.8 33.2l-11.1 37.5H163zM616 96H336v320h280c13.3 0 24-10.7 24-24V120c0-13.3-10.7-24-24-24zm-24 120c0 6.6-5.4 12-12 12h-11.4c-6.9 23.6-21.7 47.4-42.7 69.9 8.4 6.4 17.1 12.5 26.1 18 5.5 3.4 7.3 10.5 4.1 16.2l-7.9 13.9c-3.4 5.9-10.9 7.8-16.7 4.3-12.6-7.8-24.5-16.1-35.4-24.9-10.9 8.7-22.7 17.1-35.4 24.9-5.8 3.5-13.3 1.6-16.7-4.3l-7.9-13.9c-3.2-5.6-1.4-12.8 4.2-16.2 9.3-5.7 18-11.7 26.1-18-7.9-8.4-14.9-17-21-25.7-4-5.7-2.2-13.6 3.7-17.1l6.5-3.9 7.3-4.3c5.4-3.2 12.4-1.7 16 3.4 5 7 10.8 14 17.4 20.9 13.5-14.2 23.8-28.9 30-43.2H412c-6.6 0-12-5.4-12-12v-16c0-6.6 5.4-12 12-12h64v-16c0-6.6 5.4-12 12-12h16c6.6 0 12 5.4 12 12v16h64c6.6 0 12 5.4 12 12zM0 120v272c0 13.3 10.7 24 24 24h280V96H24c-13.3 0-24 10.7-24 24zm58.9 216.1L116.4 167c1.7-4.9 6.2-8.1 11.4-8.1h32.5c5.1 0 9.7 3.3 11.4 8.1l57.5 169.1c2.6 7.8-3.1 15.9-11.4 15.9h-22.9a12 12 0 0 1-11.5-8.6l-9.4-31.9h-60.2l-9.1 31.8c-1.5 5.1-6.2 8.7-11.5 8.7H70.3c-8.2 0-14-8.1-11.4-15.9z"
fill="currentColor"
style={Object {}}
/>
</svg>
<div
className="sr-only"
>
Choose Language
</div>
</label>
<select
className="mx-2 mt-1"
defaultValue="en"
id="site-footer-language-select"
name="site-footer-language-select"
>
<option
value="en"
>
English
</option>
<option
value="es-419"
>
español
</option>
</select>
<button
className="mt-1"
type="submit"
>
Apply
</button>
</form>
</div>
</div>
<div
className="area-2"
>
<h2>
edX
</h2>
<ul
className="list-unstyled p-0 m-0"
>
<li>
<a
href="https://www.example.com/about-us"
>
About
</a>
</li>
<li>
<a
href="https://business.edx.org/?utm_test=utm_test_value"
>
edX for Business
</a>
</li>
<li>
<a
href="https://www.example.com/affiliate-program"
>
Affiliates
</a>
</li>
<li>
<a
href="https://www.example.com/open"
>
Open edX
</a>
</li>
<li>
<a
href="https://www.example.com/careers"
>
Careers
</a>
</li>
<li>
<a
href="https://www.example.com/news-announcements"
>
News
</a>
</li>
</ul>
</div>
<div
className="area-3"
>
<h2>
Legal
</h2>
<ul
className="list-unstyled p-0 m-0"
>
<li>
<a
href="https://www.example.com/terms-of-service"
>
Terms of Service & Honor Code
</a>
</li>
<li>
<a
href="https://www.example.com/privacy-policy"
>
Privacy Policy
</a>
</li>
<li>
<a
href="https://www.example.com/accessibility"
>
Accessibility Policy
</a>
</li>
<li>
<a
href="https://www.example.com/trademarks"
>
Trademark Policy
</a>
</li>
<li>
<a
href="https://www.example.com/sitemap"
>
Sitemap
</a>
</li>
</ul>
</div>
<div
className="area-4"
>
<h2>
Connect
</h2>
<ul
className="list-unstyled p-0 m-0"
>
<li>
<a
href="https://www.example.com/blog"
>
Blog
</a>
</li>
<li>
<a
href="https://www.example.com/contact"
>
Contact Us
</a>
</li>
<li>
<a
href="https://www.example.com/support"
>
Help Center
</a>
</li>
<li>
<a
href="https://www.example.com/media-kit"
>
Media Kit
</a>
</li>
<li>
<a
href="https://www.example.com/donate"
>
Donate
</a>
</li>
</ul>
</div>
<div
className="area-5"
>
<ul
className="d-flex flex-row justify-content-between list-unstyled max-width-222 p-0 mb-4"
>
<li>
<a
href="https://www.facebook.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="Facebook"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-facebook-square fa-w-14 fa-2x social-icon"
data-icon="facebook-square"
data-prefix="fab"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 448 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M448 80v352c0 26.5-21.5 48-48 48h-85.3V302.8h60.6l8.7-67.6h-69.3V192c0-19.6 5.4-32.9 33.5-32.9H384V98.7c-6.2-.8-27.4-2.7-52.2-2.7-51.6 0-87 31.5-87 89.4v49.9H184v67.6h60.9V480H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48z"
fill="currentColor"
style={Object {}}
/>
</svg>
<span
className="sr-only"
>
Like edX on Facebook
</span>
</a>
</li>
<li>
<a
href="https://www.twitter.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="Twitter"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-twitter-square fa-w-14 fa-2x social-icon"
data-icon="twitter-square"
data-prefix="fab"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 448 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-48.9 158.8c.2 2.8.2 5.7.2 8.5 0 86.7-66 186.6-186.6 186.6-37.2 0-71.7-10.8-100.7-29.4 5.3.6 10.4.8 15.8.8 30.7 0 58.9-10.4 81.4-28-28.8-.6-53-19.5-61.3-45.5 10.1 1.5 19.2 1.5 29.6-1.2-30-6.1-52.5-32.5-52.5-64.4v-.8c8.7 4.9 18.9 7.9 29.6 8.3a65.447 65.447 0 0 1-29.2-54.6c0-12.2 3.2-23.4 8.9-33.1 32.3 39.8 80.8 65.8 135.2 68.6-9.3-44.5 24-80.6 64-80.6 18.9 0 35.9 7.9 47.9 20.7 14.8-2.8 29-8.3 41.6-15.8-4.9 15.2-15.2 28-28.8 36.1 13.2-1.4 26-5.1 37.8-10.2-8.9 13.1-20.1 24.7-32.9 34z"
fill="currentColor"
style={Object {}}
/>
</svg>
<span
className="sr-only"
>
Follow edX on Twitter
</span>
</a>
</li>
<li>
<a
href="https://www.youtube.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="Youtube"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-youtube-square fa-w-14 fa-2x social-icon"
data-icon="youtube-square"
data-prefix="fab"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 448 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M186.8 202.1l95.2 54.1-95.2 54.1V202.1zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-42 176.3s0-59.6-7.6-88.2c-4.2-15.8-16.5-28.2-32.2-32.4C337.9 128 224 128 224 128s-113.9 0-142.2 7.7c-15.7 4.2-28 16.6-32.2 32.4-7.6 28.5-7.6 88.2-7.6 88.2s0 59.6 7.6 88.2c4.2 15.8 16.5 27.7 32.2 31.9C110.1 384 224 384 224 384s113.9 0 142.2-7.7c15.7-4.2 28-16.1 32.2-31.9 7.6-28.5 7.6-88.1 7.6-88.1z"
fill="currentColor"
style={Object {}}
/>
</svg>
<span
className="sr-only"
>
Subscribe to the edX YouTube channel
</span>
</a>
</li>
<li>
<a
href="https://www.linkedin.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="LinkedIn"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-linkedin fa-w-14 fa-2x social-icon"
data-icon="linkedin"
data-prefix="fab"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 448 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M416 32H31.9C14.3 32 0 46.5 0 64.3v383.4C0 465.5 14.3 480 31.9 480H416c17.6 0 32-14.5 32-32.3V64.3c0-17.8-14.4-32.3-32-32.3zM135.4 416H69V202.2h66.5V416zm-33.2-243c-21.3 0-38.5-17.3-38.5-38.5S80.9 96 102.2 96c21.2 0 38.5 17.3 38.5 38.5 0 21.3-17.2 38.5-38.5 38.5zm282.1 243h-66.4V312c0-24.8-.5-56.7-34.5-56.7-34.6 0-39.9 27-39.9 54.9V416h-66.4V202.2h63.7v29.2h.9c8.9-16.8 30.6-34.5 62.9-34.5 67.2 0 79.7 44.3 79.7 101.9V416z"
fill="currentColor"
style={Object {}}
/>
</svg>
<span
className="sr-only"
>
Follow edX on LinkedIn
</span>
</a>
</li>
<li>
<a
href="https://reddit.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="Reddit"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-reddit-square fa-w-14 fa-2x social-icon"
data-icon="reddit-square"
data-prefix="fab"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 448 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M283.2 345.5c2.7 2.7 2.7 6.8 0 9.2-24.5 24.5-93.8 24.6-118.4 0-2.7-2.4-2.7-6.5 0-9.2 2.4-2.4 6.5-2.4 8.9 0 18.7 19.2 81 19.6 100.5 0 2.4-2.3 6.6-2.3 9 0zm-91.3-53.8c0-14.9-11.9-26.8-26.5-26.8-14.9 0-26.8 11.9-26.8 26.8 0 14.6 11.9 26.5 26.8 26.5 14.6 0 26.5-11.9 26.5-26.5zm90.7-26.8c-14.6 0-26.5 11.9-26.5 26.8 0 14.6 11.9 26.5 26.5 26.5 14.9 0 26.8-11.9 26.8-26.5 0-14.9-11.9-26.8-26.8-26.8zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-99.7 140.6c-10.1 0-19 4.2-25.6 10.7-24.1-16.7-56.5-27.4-92.5-28.6l18.7-84.2 59.5 13.4c0 14.6 11.9 26.5 26.5 26.5 14.9 0 26.8-12.2 26.8-26.8 0-14.6-11.9-26.8-26.8-26.8-10.4 0-19.3 6.2-23.8 14.9l-65.7-14.6c-3.3-.9-6.5 1.5-7.4 4.8l-20.5 92.8c-35.7 1.5-67.8 12.2-91.9 28.9-6.5-6.8-15.8-11-25.9-11-37.5 0-49.8 50.4-15.5 67.5-1.2 5.4-1.8 11-1.8 16.7 0 56.5 63.7 102.3 141.9 102.3 78.5 0 142.2-45.8 142.2-102.3 0-5.7-.6-11.6-2.1-17 33.6-17.2 21.2-67.2-16.1-67.2z"
fill="currentColor"
style={Object {}}
/>
</svg>
<span
className="sr-only"
>
Subscribe to the edX subreddit
</span>
</a>
</li>
</ul>
<p>
© 20122019 edX Inc.
<br />
EdX, Open edX, and MicroMasters are registered trademarks of edX Inc. | 深圳市恒宇博科技有限公司
<a
href="http://www.beian.miit.gov.cn"
>
粤ICP备17044299号-2
</a>
</p>
</div>
</div>
</footer>
`;
exports[`<SiteFooter /> renders correctly does not render social links 1`] = `
<footer
aria-label="Page Footer"
className="footer d-flex justify-content-center border-top py-3 px-4"
role="contentinfo"
>
<div
className="max-width-1180 d-grid"
>
<div
className="area-1"
>
<a
aria-label="edX Home"
href="https://www.example.com"
>
<img
alt="edx Logo"
src="test-file-stub"
/>
</a>
<div
className="i18n d-flex mt-2"
>
<form
className="d-flex align-items-start"
onSubmit={[Function]}
>
<label
htmlFor="site-footer-language-select"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-language fa-w-20 fa-2x text-primary"
data-icon="language"
data-prefix="fas"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 640 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M152.1 236.2c-3.5-12.1-7.8-33.2-7.8-33.2h-.5s-4.3 21.1-7.8 33.2l-11.1 37.5H163zM616 96H336v320h280c13.3 0 24-10.7 24-24V120c0-13.3-10.7-24-24-24zm-24 120c0 6.6-5.4 12-12 12h-11.4c-6.9 23.6-21.7 47.4-42.7 69.9 8.4 6.4 17.1 12.5 26.1 18 5.5 3.4 7.3 10.5 4.1 16.2l-7.9 13.9c-3.4 5.9-10.9 7.8-16.7 4.3-12.6-7.8-24.5-16.1-35.4-24.9-10.9 8.7-22.7 17.1-35.4 24.9-5.8 3.5-13.3 1.6-16.7-4.3l-7.9-13.9c-3.2-5.6-1.4-12.8 4.2-16.2 9.3-5.7 18-11.7 26.1-18-7.9-8.4-14.9-17-21-25.7-4-5.7-2.2-13.6 3.7-17.1l6.5-3.9 7.3-4.3c5.4-3.2 12.4-1.7 16 3.4 5 7 10.8 14 17.4 20.9 13.5-14.2 23.8-28.9 30-43.2H412c-6.6 0-12-5.4-12-12v-16c0-6.6 5.4-12 12-12h64v-16c0-6.6 5.4-12 12-12h16c6.6 0 12 5.4 12 12v16h64c6.6 0 12 5.4 12 12zM0 120v272c0 13.3 10.7 24 24 24h280V96H24c-13.3 0-24 10.7-24 24zm58.9 216.1L116.4 167c1.7-4.9 6.2-8.1 11.4-8.1h32.5c5.1 0 9.7 3.3 11.4 8.1l57.5 169.1c2.6 7.8-3.1 15.9-11.4 15.9h-22.9a12 12 0 0 1-11.5-8.6l-9.4-31.9h-60.2l-9.1 31.8c-1.5 5.1-6.2 8.7-11.5 8.7H70.3c-8.2 0-14-8.1-11.4-15.9z"
fill="currentColor"
style={Object {}}
/>
</svg>
<div
className="sr-only"
>
Choose Language
</div>
</label>
<select
className="mx-2 mt-1"
defaultValue="en"
id="site-footer-language-select"
name="site-footer-language-select"
>
<option
value="en"
>
English
</option>
<option
value="es-419"
>
español
</option>
</select>
<button
className="mt-1"
type="submit"
>
Apply
</button>
</form>
</div>
</div>
<div
className="area-2"
>
<h2>
edX
</h2>
<ul
className="list-unstyled p-0 m-0"
>
<li>
<a
href="https://www.example.com/about-us"
>
About
</a>
</li>
<li>
<a
href="https://business.edx.org/?utm_test=utm_test_value"
>
edX for Business
</a>
</li>
<li>
<a
href="https://www.example.com/affiliate-program"
>
Affiliates
</a>
</li>
<li>
<a
href="https://www.example.com/open"
>
Open edX
</a>
</li>
<li>
<a
href="https://www.example.com/careers"
>
Careers
</a>
</li>
<li>
<a
href="https://www.example.com/news-announcements"
>
News
</a>
</li>
</ul>
</div>
<div
className="area-3"
>
<h2>
Legal
</h2>
<ul
className="list-unstyled p-0 m-0"
>
<li>
<a
href="https://www.example.com/terms-of-service"
>
Terms of Service & Honor Code
</a>
</li>
<li>
<a
href="https://www.example.com/privacy-policy"
>
Privacy Policy
</a>
</li>
<li>
<a
href="https://www.example.com/accessibility"
>
Accessibility Policy
</a>
</li>
<li>
<a
href="https://www.example.com/trademarks"
>
Trademark Policy
</a>
</li>
<li>
<a
href="https://www.example.com/sitemap"
>
Sitemap
</a>
</li>
</ul>
</div>
<div
className="area-4"
>
<h2>
Connect
</h2>
<ul
className="list-unstyled p-0 m-0"
>
<li>
<a
href="https://www.example.com/blog"
>
Blog
</a>
</li>
<li>
<a
href="https://www.example.com/contact"
>
Contact Us
</a>
</li>
<li>
<a
href="https://www.example.com/support"
>
Help Center
</a>
</li>
<li>
<a
href="https://www.example.com/media-kit"
>
Media Kit
</a>
</li>
<li>
<a
href="https://www.example.com/donate"
>
Donate
</a>
</li>
</ul>
</div>
<div
className="area-5"
>
<ul
className="d-flex flex-row justify-content-between list-unstyled max-width-264 p-0 mb-5"
>
<li>
<a
href="https://store.apple.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
>
<img
alt="Download the edX mobile app from the Apple App Store"
className="max-height-39"
src="https://prod-edxapp.edx-cdn.org/static/images/app/app_store_badge_135x40.d0558d910630.svg"
/>
</a>
</li>
<li>
<a
href="https://play.google.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
>
<img
alt="Download the edX mobile app from Google Play"
className="max-height-39"
src="https://prod-edxapp.edx-cdn.org/static/images/app/google_play_badge_45.6ea466e328da.png"
/>
</a>
</li>
</ul>
<p>
© 20122019 edX Inc.
<br />
EdX, Open edX, and MicroMasters are registered trademarks of edX Inc. | 深圳市恒宇博科技有限公司
<a
href="http://www.beian.miit.gov.cn"
>
粤ICP备17044299号-2
</a>
</p>
</div>
</div>
</footer>
`;
exports[`<SiteFooter /> renders correctly renders with social and mobile links 1`] = `
<footer
aria-label="Page Footer"
className="footer d-flex justify-content-center border-top py-3 px-4"
role="contentinfo"
>
<div
className="max-width-1180 d-grid"
>
<div
className="area-1"
>
<a
aria-label="edX Home"
href="https://www.example.com"
>
<img
alt="edx Logo"
src="test-file-stub"
/>
</a>
<div
className="i18n d-flex mt-2"
>
<form
className="d-flex align-items-start"
onSubmit={[Function]}
>
<label
htmlFor="site-footer-language-select"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-language fa-w-20 fa-2x text-primary"
data-icon="language"
data-prefix="fas"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 640 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M152.1 236.2c-3.5-12.1-7.8-33.2-7.8-33.2h-.5s-4.3 21.1-7.8 33.2l-11.1 37.5H163zM616 96H336v320h280c13.3 0 24-10.7 24-24V120c0-13.3-10.7-24-24-24zm-24 120c0 6.6-5.4 12-12 12h-11.4c-6.9 23.6-21.7 47.4-42.7 69.9 8.4 6.4 17.1 12.5 26.1 18 5.5 3.4 7.3 10.5 4.1 16.2l-7.9 13.9c-3.4 5.9-10.9 7.8-16.7 4.3-12.6-7.8-24.5-16.1-35.4-24.9-10.9 8.7-22.7 17.1-35.4 24.9-5.8 3.5-13.3 1.6-16.7-4.3l-7.9-13.9c-3.2-5.6-1.4-12.8 4.2-16.2 9.3-5.7 18-11.7 26.1-18-7.9-8.4-14.9-17-21-25.7-4-5.7-2.2-13.6 3.7-17.1l6.5-3.9 7.3-4.3c5.4-3.2 12.4-1.7 16 3.4 5 7 10.8 14 17.4 20.9 13.5-14.2 23.8-28.9 30-43.2H412c-6.6 0-12-5.4-12-12v-16c0-6.6 5.4-12 12-12h64v-16c0-6.6 5.4-12 12-12h16c6.6 0 12 5.4 12 12v16h64c6.6 0 12 5.4 12 12zM0 120v272c0 13.3 10.7 24 24 24h280V96H24c-13.3 0-24 10.7-24 24zm58.9 216.1L116.4 167c1.7-4.9 6.2-8.1 11.4-8.1h32.5c5.1 0 9.7 3.3 11.4 8.1l57.5 169.1c2.6 7.8-3.1 15.9-11.4 15.9h-22.9a12 12 0 0 1-11.5-8.6l-9.4-31.9h-60.2l-9.1 31.8c-1.5 5.1-6.2 8.7-11.5 8.7H70.3c-8.2 0-14-8.1-11.4-15.9z"
fill="currentColor"
style={Object {}}
/>
</svg>
<div
className="sr-only"
>
Choose Language
</div>
</label>
<select
className="mx-2 mt-1"
defaultValue="en"
id="site-footer-language-select"
name="site-footer-language-select"
>
<option
value="en"
>
English
</option>
<option
value="es-419"
>
español
</option>
</select>
<button
className="mt-1"
type="submit"
>
Apply
</button>
</form>
</div>
</div>
<div
className="area-2"
>
<h2>
edX
</h2>
<ul
className="list-unstyled p-0 m-0"
>
<li>
<a
href="https://www.example.com/about-us"
>
About
</a>
</li>
<li>
<a
href="https://business.edx.org/?utm_test=utm_test_value"
>
edX for Business
</a>
</li>
<li>
<a
href="https://www.example.com/affiliate-program"
>
Affiliates
</a>
</li>
<li>
<a
href="https://www.example.com/open"
>
Open edX
</a>
</li>
<li>
<a
href="https://www.example.com/careers"
>
Careers
</a>
</li>
<li>
<a
href="https://www.example.com/news-announcements"
>
News
</a>
</li>
</ul>
</div>
<div
className="area-3"
>
<h2>
Legal
</h2>
<ul
className="list-unstyled p-0 m-0"
>
<li>
<a
href="https://www.example.com/terms-of-service"
>
Terms of Service & Honor Code
</a>
</li>
<li>
<a
href="https://www.example.com/privacy-policy"
>
Privacy Policy
</a>
</li>
<li>
<a
href="https://www.example.com/accessibility"
>
Accessibility Policy
</a>
</li>
<li>
<a
href="https://www.example.com/trademarks"
>
Trademark Policy
</a>
</li>
<li>
<a
href="https://www.example.com/sitemap"
>
Sitemap
</a>
</li>
</ul>
</div>
<div
className="area-4"
>
<h2>
Connect
</h2>
<ul
className="list-unstyled p-0 m-0"
>
<li>
<a
href="https://www.example.com/blog"
>
Blog
</a>
</li>
<li>
<a
href="https://www.example.com/contact"
>
Contact Us
</a>
</li>
<li>
<a
href="https://www.example.com/support"
>
Help Center
</a>
</li>
<li>
<a
href="https://www.example.com/media-kit"
>
Media Kit
</a>
</li>
<li>
<a
href="https://www.example.com/donate"
>
Donate
</a>
</li>
</ul>
</div>
<div
className="area-5"
>
<ul
className="d-flex flex-row justify-content-between list-unstyled max-width-222 p-0 mb-4"
>
<li>
<a
href="https://www.facebook.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="Facebook"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-facebook-square fa-w-14 fa-2x social-icon"
data-icon="facebook-square"
data-prefix="fab"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 448 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M448 80v352c0 26.5-21.5 48-48 48h-85.3V302.8h60.6l8.7-67.6h-69.3V192c0-19.6 5.4-32.9 33.5-32.9H384V98.7c-6.2-.8-27.4-2.7-52.2-2.7-51.6 0-87 31.5-87 89.4v49.9H184v67.6h60.9V480H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48z"
fill="currentColor"
style={Object {}}
/>
</svg>
<span
className="sr-only"
>
Like edX on Facebook
</span>
</a>
</li>
<li>
<a
href="https://www.twitter.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="Twitter"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-twitter-square fa-w-14 fa-2x social-icon"
data-icon="twitter-square"
data-prefix="fab"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 448 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-48.9 158.8c.2 2.8.2 5.7.2 8.5 0 86.7-66 186.6-186.6 186.6-37.2 0-71.7-10.8-100.7-29.4 5.3.6 10.4.8 15.8.8 30.7 0 58.9-10.4 81.4-28-28.8-.6-53-19.5-61.3-45.5 10.1 1.5 19.2 1.5 29.6-1.2-30-6.1-52.5-32.5-52.5-64.4v-.8c8.7 4.9 18.9 7.9 29.6 8.3a65.447 65.447 0 0 1-29.2-54.6c0-12.2 3.2-23.4 8.9-33.1 32.3 39.8 80.8 65.8 135.2 68.6-9.3-44.5 24-80.6 64-80.6 18.9 0 35.9 7.9 47.9 20.7 14.8-2.8 29-8.3 41.6-15.8-4.9 15.2-15.2 28-28.8 36.1 13.2-1.4 26-5.1 37.8-10.2-8.9 13.1-20.1 24.7-32.9 34z"
fill="currentColor"
style={Object {}}
/>
</svg>
<span
className="sr-only"
>
Follow edX on Twitter
</span>
</a>
</li>
<li>
<a
href="https://www.youtube.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="Youtube"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-youtube-square fa-w-14 fa-2x social-icon"
data-icon="youtube-square"
data-prefix="fab"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 448 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M186.8 202.1l95.2 54.1-95.2 54.1V202.1zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-42 176.3s0-59.6-7.6-88.2c-4.2-15.8-16.5-28.2-32.2-32.4C337.9 128 224 128 224 128s-113.9 0-142.2 7.7c-15.7 4.2-28 16.6-32.2 32.4-7.6 28.5-7.6 88.2-7.6 88.2s0 59.6 7.6 88.2c4.2 15.8 16.5 27.7 32.2 31.9C110.1 384 224 384 224 384s113.9 0 142.2-7.7c15.7-4.2 28-16.1 32.2-31.9 7.6-28.5 7.6-88.1 7.6-88.1z"
fill="currentColor"
style={Object {}}
/>
</svg>
<span
className="sr-only"
>
Subscribe to the edX YouTube channel
</span>
</a>
</li>
<li>
<a
href="https://www.linkedin.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="LinkedIn"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-linkedin fa-w-14 fa-2x social-icon"
data-icon="linkedin"
data-prefix="fab"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 448 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M416 32H31.9C14.3 32 0 46.5 0 64.3v383.4C0 465.5 14.3 480 31.9 480H416c17.6 0 32-14.5 32-32.3V64.3c0-17.8-14.4-32.3-32-32.3zM135.4 416H69V202.2h66.5V416zm-33.2-243c-21.3 0-38.5-17.3-38.5-38.5S80.9 96 102.2 96c21.2 0 38.5 17.3 38.5 38.5 0 21.3-17.2 38.5-38.5 38.5zm282.1 243h-66.4V312c0-24.8-.5-56.7-34.5-56.7-34.6 0-39.9 27-39.9 54.9V416h-66.4V202.2h63.7v29.2h.9c8.9-16.8 30.6-34.5 62.9-34.5 67.2 0 79.7 44.3 79.7 101.9V416z"
fill="currentColor"
style={Object {}}
/>
</svg>
<span
className="sr-only"
>
Follow edX on LinkedIn
</span>
</a>
</li>
<li>
<a
href="https://reddit.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="Reddit"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-reddit-square fa-w-14 fa-2x social-icon"
data-icon="reddit-square"
data-prefix="fab"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 448 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M283.2 345.5c2.7 2.7 2.7 6.8 0 9.2-24.5 24.5-93.8 24.6-118.4 0-2.7-2.4-2.7-6.5 0-9.2 2.4-2.4 6.5-2.4 8.9 0 18.7 19.2 81 19.6 100.5 0 2.4-2.3 6.6-2.3 9 0zm-91.3-53.8c0-14.9-11.9-26.8-26.5-26.8-14.9 0-26.8 11.9-26.8 26.8 0 14.6 11.9 26.5 26.8 26.5 14.6 0 26.5-11.9 26.5-26.5zm90.7-26.8c-14.6 0-26.5 11.9-26.5 26.8 0 14.6 11.9 26.5 26.5 26.5 14.9 0 26.8-11.9 26.8-26.5 0-14.9-11.9-26.8-26.8-26.8zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-99.7 140.6c-10.1 0-19 4.2-25.6 10.7-24.1-16.7-56.5-27.4-92.5-28.6l18.7-84.2 59.5 13.4c0 14.6 11.9 26.5 26.5 26.5 14.9 0 26.8-12.2 26.8-26.8 0-14.6-11.9-26.8-26.8-26.8-10.4 0-19.3 6.2-23.8 14.9l-65.7-14.6c-3.3-.9-6.5 1.5-7.4 4.8l-20.5 92.8c-35.7 1.5-67.8 12.2-91.9 28.9-6.5-6.8-15.8-11-25.9-11-37.5 0-49.8 50.4-15.5 67.5-1.2 5.4-1.8 11-1.8 16.7 0 56.5 63.7 102.3 141.9 102.3 78.5 0 142.2-45.8 142.2-102.3 0-5.7-.6-11.6-2.1-17 33.6-17.2 21.2-67.2-16.1-67.2z"
fill="currentColor"
style={Object {}}
/>
</svg>
<span
className="sr-only"
>
Subscribe to the edX subreddit
</span>
</a>
</li>
</ul>
<ul
className="d-flex flex-row justify-content-between list-unstyled max-width-264 p-0 mb-5"
>
<li>
<a
href="https://store.apple.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
>
<img
alt="Download the edX mobile app from the Apple App Store"
className="max-height-39"
src="https://prod-edxapp.edx-cdn.org/static/images/app/app_store_badge_135x40.d0558d910630.svg"
/>
</a>
</li>
<li>
<a
href="https://play.google.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
>
<img
alt="Download the edX mobile app from Google Play"
className="max-height-39"
src="https://prod-edxapp.edx-cdn.org/static/images/app/google_play_badge_45.6ea466e328da.png"
/>
</a>
</li>
</ul>
<p>
© 20122019 edX Inc.
<br />
EdX, Open edX, and MicroMasters are registered trademarks of edX Inc. | 深圳市恒宇博科技有限公司
<a
href="http://www.beian.miit.gov.cn"
>
粤ICP备17044299号-2
</a>
</p>
</div>
</div>
</footer>
`;

View File

@@ -1,112 +0,0 @@
import React from 'react';
import renderer from 'react-test-renderer';
import { mount } from 'enzyme';
import FooterLogo from '../../../edx-footer.png';
import SiteFooter, { EVENT_NAMES } from './index';
const completeSiteFooterComponent = mockHandleAllTrackEvents =>
(<SiteFooter
siteName="example"
siteLogo={FooterLogo}
marketingSiteBaseUrl="https://www.example.com"
supportUrl="https://www.example.com/support"
contactUrl="https://www.example.com/contact"
openSourceUrl="https://www.example.com/open"
termsOfServiceUrl="https://www.example.com/terms-of-service"
privacyPolicyUrl="https://www.example.com/privacy-policy"
facebookUrl="https://www.facebook.com"
twitterUrl="https://www.twitter.com"
youTubeUrl="https://www.youtube.com"
linkedInUrl="https://www.linkedin.com"
googlePlusUrl="https://plus.google.com"
redditUrl="https://reddit.com"
appleAppStoreUrl="https://store.apple.com"
googlePlayUrl="https://play.google.com"
handleAllTrackEvents={mockHandleAllTrackEvents}
/>);
describe('<SiteFooter />', () => {
describe('renders correctly', () => {
it('renders with social and mobile links', () => {
const mockHandleAllTrackEvents = jest.fn();
const tree = renderer
.create(completeSiteFooterComponent(mockHandleAllTrackEvents))
.toJSON();
expect(tree).toMatchSnapshot();
});
it('does not render social links', () => {
const tree = renderer
.create(<SiteFooter
siteName="example"
siteLogo={FooterLogo}
marketingSiteBaseUrl="https://www.example.com"
supportUrl="https://www.example.com/support"
contactUrl="https://www.example.com/contact"
openSourceUrl="https://www.example.com/open"
termsOfServiceUrl="https://www.example.com/terms-of-service"
privacyPolicyUrl="https://www.example.com/privacy-policy"
facebookUrl="https://www.facebook.com"
twitterUrl="https://www.twitter.com"
youTubeUrl="https://www.youtube.com"
linkedInUrl="https://www.linkedin.com"
googlePlusUrl="https://plus.google.com"
redditUrl="https://reddit.com"
appleAppStoreUrl="https://store.apple.com"
googlePlayUrl="https://play.google.com"
handleAllTrackEvents={jest.fn()}
showSocialLinks={false}
/>)
.toJSON();
expect(tree).toMatchSnapshot();
});
it('does not render mobile links', () => {
const tree = renderer
.create(<SiteFooter
siteName="example"
siteLogo={FooterLogo}
marketingSiteBaseUrl="https://www.example.com"
supportUrl="https://www.example.com/support"
contactUrl="https://www.example.com/contact"
openSourceUrl="https://www.example.com/open"
termsOfServiceUrl="https://www.example.com/terms-of-service"
privacyPolicyUrl="https://www.example.com/privacy-policy"
facebookUrl="https://www.facebook.com"
twitterUrl="https://www.twitter.com"
youTubeUrl="https://www.youtube.com"
linkedInUrl="https://www.linkedin.com"
googlePlusUrl="https://plus.google.com"
redditUrl="https://reddit.com"
appleAppStoreUrl="https://store.apple.com"
googlePlayUrl="https://play.google.com"
handleAllTrackEvents={jest.fn()}
showMobileLinks={false}
/>)
.toJSON();
expect(tree).toMatchSnapshot();
});
});
describe('handles analytics', () => {
it('calls handleAllTrackEvents prop when external links clicked', () => {
const mockHandleAllTrackEvents = jest.fn();
const footer = mount((completeSiteFooterComponent(mockHandleAllTrackEvents)));
const externalLinks = footer.find("a[target='_blank']");
expect(externalLinks).toHaveLength(8);
externalLinks.forEach((externalLink) => {
const callIndex = mockHandleAllTrackEvents.mock.calls.length;
externalLink.simulate('click');
expect(mockHandleAllTrackEvents.mock.calls[callIndex]).toEqual([
EVENT_NAMES.FOOTER_LINK,
{
category: 'outbound_link',
label: externalLink.prop('href'),
},
]);
});
});
});
});

View File

@@ -1,877 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<SiteFooter /> renders correctly does not render mobile links 1`] = `
<footer
aria-label="Page Footer"
className="footer d-flex justify-content-center border-top py-3 px-4"
role="contentinfo"
>
<div
className="max-width-1180 d-grid"
>
<div
className="area-1"
>
<a
aria-label="example Home"
href="https://www.example.com/"
onClick={[Function]}
target="_self"
>
<img
alt="example logo"
src="test-file-stub"
/>
</a>
</div>
<div
className="area-2"
>
<h2>
example
</h2>
<ul
className="list-unstyled p-0 m-0"
>
<li>
<a
href="https://www.example.com/about-us"
>
About
</a>
</li>
<li>
<a
href="https://www.example.com/enterprise"
>
example
for Business
</a>
</li>
<li>
<a
href="https://www.example.com/affiliate-program"
>
Affiliates
</a>
</li>
<li>
<a
href="https://www.example.com/open"
>
Open
example
</a>
</li>
<li>
<a
href="https://www.example.com/careers"
>
Careers
</a>
</li>
<li>
<a
href="https://www.example.com/news-announcements"
>
News
</a>
</li>
</ul>
</div>
<div
className="area-3"
>
<h2>
Legal
</h2>
<ul
className="list-unstyled p-0 m-0"
>
<li>
<a
href="https://www.example.com/terms-of-service"
>
Terms of Service & Honor Code
</a>
</li>
<li>
<a
href="https://www.example.com/privacy-policy"
>
Privacy Policy
</a>
</li>
<li>
<a
href="https://www.example.com/accessibility"
>
Accessibility Policy
</a>
</li>
<li>
<a
href="https://www.example.com/trademarks"
>
Trademark Policy
</a>
</li>
<li>
<a
href="https://www.example.com/sitemap"
>
Sitemap
</a>
</li>
</ul>
</div>
<div
className="area-4"
>
<h2>
Connect
</h2>
<ul
className="list-unstyled p-0 m-0"
>
<li>
<a
href="https://www.example.com/blog"
>
Blog
</a>
</li>
<li>
<a
href="https://www.example.com/contact"
>
Contact Us
</a>
</li>
<li>
<a
href="https://www.example.com/support"
>
Help Center
</a>
</li>
<li>
<a
href="https://www.example.com/media-kit"
>
Media Kit
</a>
</li>
<li>
<a
href="https://www.example.com/donate"
>
Donate
</a>
</li>
</ul>
</div>
<div
className="area-5"
>
<ul
className="d-flex flex-row justify-content-between list-unstyled max-width-222 p-0 mb-4"
>
<li>
<a
href="https://www.facebook.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="Facebook"
>
<span
aria-hidden={true}
className="fa fa-facebook-square fa-2x"
id="Icon1"
/>
<span
className="sr-only"
>
Like example on Facebook
</span>
</a>
</li>
<li>
<a
href="https://www.twitter.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="Twitter"
>
<span
aria-hidden={true}
className="fa fa-twitter-square fa-2x"
id="Icon1"
/>
<span
className="sr-only"
>
Follow example on Twitter
</span>
</a>
</li>
<li>
<a
href="https://www.youtube.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="Youtube"
>
<span
aria-hidden={true}
className="fa fa-youtube-square fa-2x"
id="Icon1"
/>
<span
className="sr-only"
>
Subscribe to the example YouTube channel
</span>
</a>
</li>
<li>
<a
href="https://www.linkedin.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="LinkedIn"
>
<span
aria-hidden={true}
className="fa fa-linkedin-square fa-2x"
id="Icon1"
/>
<span
className="sr-only"
>
Follow example on LinkedIn
</span>
</a>
</li>
<li>
<a
href="https://plus.google.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="Google+"
>
<span
aria-hidden={true}
className="fa fa-google-plus-square fa-2x"
id="Icon1"
/>
<span
className="sr-only"
>
Follow example on Google+
</span>
</a>
</li>
<li>
<a
href="https://reddit.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="Reddit"
>
<span
aria-hidden={true}
className="fa fa-reddit-square fa-2x"
id="Icon1"
/>
<span
className="sr-only"
>
Subscribe to the example subreddit
</span>
</a>
</li>
</ul>
<p>
© 2012
2019
example
Inc.
<br />
EdX, Open edX, and MicroMasters are registered trademarks of edX Inc. | 粤ICP备17044299号-2
</p>
</div>
</div>
</footer>
`;
exports[`<SiteFooter /> renders correctly does not render social links 1`] = `
<footer
aria-label="Page Footer"
className="footer d-flex justify-content-center border-top py-3 px-4"
role="contentinfo"
>
<div
className="max-width-1180 d-grid"
>
<div
className="area-1"
>
<a
aria-label="example Home"
href="https://www.example.com/"
onClick={[Function]}
target="_self"
>
<img
alt="example logo"
src="test-file-stub"
/>
</a>
</div>
<div
className="area-2"
>
<h2>
example
</h2>
<ul
className="list-unstyled p-0 m-0"
>
<li>
<a
href="https://www.example.com/about-us"
>
About
</a>
</li>
<li>
<a
href="https://www.example.com/enterprise"
>
example
for Business
</a>
</li>
<li>
<a
href="https://www.example.com/affiliate-program"
>
Affiliates
</a>
</li>
<li>
<a
href="https://www.example.com/open"
>
Open
example
</a>
</li>
<li>
<a
href="https://www.example.com/careers"
>
Careers
</a>
</li>
<li>
<a
href="https://www.example.com/news-announcements"
>
News
</a>
</li>
</ul>
</div>
<div
className="area-3"
>
<h2>
Legal
</h2>
<ul
className="list-unstyled p-0 m-0"
>
<li>
<a
href="https://www.example.com/terms-of-service"
>
Terms of Service & Honor Code
</a>
</li>
<li>
<a
href="https://www.example.com/privacy-policy"
>
Privacy Policy
</a>
</li>
<li>
<a
href="https://www.example.com/accessibility"
>
Accessibility Policy
</a>
</li>
<li>
<a
href="https://www.example.com/trademarks"
>
Trademark Policy
</a>
</li>
<li>
<a
href="https://www.example.com/sitemap"
>
Sitemap
</a>
</li>
</ul>
</div>
<div
className="area-4"
>
<h2>
Connect
</h2>
<ul
className="list-unstyled p-0 m-0"
>
<li>
<a
href="https://www.example.com/blog"
>
Blog
</a>
</li>
<li>
<a
href="https://www.example.com/contact"
>
Contact Us
</a>
</li>
<li>
<a
href="https://www.example.com/support"
>
Help Center
</a>
</li>
<li>
<a
href="https://www.example.com/media-kit"
>
Media Kit
</a>
</li>
<li>
<a
href="https://www.example.com/donate"
>
Donate
</a>
</li>
</ul>
</div>
<div
className="area-5"
>
<ul
className="d-flex flex-row justify-content-between list-unstyled max-width-264 p-0 mb-5"
>
<li>
<a
href="https://store.apple.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
>
<img
alt="Download the example mobile app from the Apple App Store"
className="max-height-39"
src="https://prod-edxapp.edx-cdn.org/static/images/app/app_store_badge_135x40.d0558d910630.svg"
/>
</a>
</li>
<li>
<a
href="https://play.google.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
>
<img
alt="Download the example mobile app from Google Play"
className="max-height-39"
src="https://prod-edxapp.edx-cdn.org/static/images/app/google_play_badge_45.6ea466e328da.png"
/>
</a>
</li>
</ul>
<p>
© 2012
2019
example
Inc.
<br />
EdX, Open edX, and MicroMasters are registered trademarks of edX Inc. | 粤ICP备17044299号-2
</p>
</div>
</div>
</footer>
`;
exports[`<SiteFooter /> renders correctly renders with social and mobile links 1`] = `
<footer
aria-label="Page Footer"
className="footer d-flex justify-content-center border-top py-3 px-4"
role="contentinfo"
>
<div
className="max-width-1180 d-grid"
>
<div
className="area-1"
>
<a
aria-label="example Home"
href="https://www.example.com/"
onClick={[Function]}
target="_self"
>
<img
alt="example logo"
src="test-file-stub"
/>
</a>
</div>
<div
className="area-2"
>
<h2>
example
</h2>
<ul
className="list-unstyled p-0 m-0"
>
<li>
<a
href="https://www.example.com/about-us"
>
About
</a>
</li>
<li>
<a
href="https://www.example.com/enterprise"
>
example
for Business
</a>
</li>
<li>
<a
href="https://www.example.com/affiliate-program"
>
Affiliates
</a>
</li>
<li>
<a
href="https://www.example.com/open"
>
Open
example
</a>
</li>
<li>
<a
href="https://www.example.com/careers"
>
Careers
</a>
</li>
<li>
<a
href="https://www.example.com/news-announcements"
>
News
</a>
</li>
</ul>
</div>
<div
className="area-3"
>
<h2>
Legal
</h2>
<ul
className="list-unstyled p-0 m-0"
>
<li>
<a
href="https://www.example.com/terms-of-service"
>
Terms of Service & Honor Code
</a>
</li>
<li>
<a
href="https://www.example.com/privacy-policy"
>
Privacy Policy
</a>
</li>
<li>
<a
href="https://www.example.com/accessibility"
>
Accessibility Policy
</a>
</li>
<li>
<a
href="https://www.example.com/trademarks"
>
Trademark Policy
</a>
</li>
<li>
<a
href="https://www.example.com/sitemap"
>
Sitemap
</a>
</li>
</ul>
</div>
<div
className="area-4"
>
<h2>
Connect
</h2>
<ul
className="list-unstyled p-0 m-0"
>
<li>
<a
href="https://www.example.com/blog"
>
Blog
</a>
</li>
<li>
<a
href="https://www.example.com/contact"
>
Contact Us
</a>
</li>
<li>
<a
href="https://www.example.com/support"
>
Help Center
</a>
</li>
<li>
<a
href="https://www.example.com/media-kit"
>
Media Kit
</a>
</li>
<li>
<a
href="https://www.example.com/donate"
>
Donate
</a>
</li>
</ul>
</div>
<div
className="area-5"
>
<ul
className="d-flex flex-row justify-content-between list-unstyled max-width-222 p-0 mb-4"
>
<li>
<a
href="https://www.facebook.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="Facebook"
>
<span
aria-hidden={true}
className="fa fa-facebook-square fa-2x"
id="Icon1"
/>
<span
className="sr-only"
>
Like example on Facebook
</span>
</a>
</li>
<li>
<a
href="https://www.twitter.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="Twitter"
>
<span
aria-hidden={true}
className="fa fa-twitter-square fa-2x"
id="Icon1"
/>
<span
className="sr-only"
>
Follow example on Twitter
</span>
</a>
</li>
<li>
<a
href="https://www.youtube.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="Youtube"
>
<span
aria-hidden={true}
className="fa fa-youtube-square fa-2x"
id="Icon1"
/>
<span
className="sr-only"
>
Subscribe to the example YouTube channel
</span>
</a>
</li>
<li>
<a
href="https://www.linkedin.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="LinkedIn"
>
<span
aria-hidden={true}
className="fa fa-linkedin-square fa-2x"
id="Icon1"
/>
<span
className="sr-only"
>
Follow example on LinkedIn
</span>
</a>
</li>
<li>
<a
href="https://plus.google.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="Google+"
>
<span
aria-hidden={true}
className="fa fa-google-plus-square fa-2x"
id="Icon1"
/>
<span
className="sr-only"
>
Follow example on Google+
</span>
</a>
</li>
<li>
<a
href="https://reddit.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="Reddit"
>
<span
aria-hidden={true}
className="fa fa-reddit-square fa-2x"
id="Icon1"
/>
<span
className="sr-only"
>
Subscribe to the example subreddit
</span>
</a>
</li>
</ul>
<ul
className="d-flex flex-row justify-content-between list-unstyled max-width-264 p-0 mb-5"
>
<li>
<a
href="https://store.apple.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
>
<img
alt="Download the example mobile app from the Apple App Store"
className="max-height-39"
src="https://prod-edxapp.edx-cdn.org/static/images/app/app_store_badge_135x40.d0558d910630.svg"
/>
</a>
</li>
<li>
<a
href="https://play.google.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
>
<img
alt="Download the example mobile app from Google Play"
className="max-height-39"
src="https://prod-edxapp.edx-cdn.org/static/images/app/google_play_badge_45.6ea466e328da.png"
/>
</a>
</li>
</ul>
<p>
© 2012
2019
example
Inc.
<br />
EdX, Open edX, and MicroMasters are registered trademarks of edX Inc. | 粤ICP备17044299号-2
</p>
</div>
</div>
</footer>
`;

View File

@@ -1,273 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Hyperlink, Icon } from '@edx/paragon';
const EVENT_NAMES = {
FOOTER_LINK: 'edx.bi.footer.link',
};
class SiteFooter extends React.Component {
constructor(props) {
super(props);
this.externalLinkClickHandler = this.externalLinkClickHandler.bind(this);
}
externalLinkClickHandler(event) {
const label = event.currentTarget.getAttribute('href');
const eventName = EVENT_NAMES.FOOTER_LINK;
const properties = {
category: 'outbound_link',
label,
};
this.props.handleAllTrackEvents(eventName, properties);
}
renderSiteLogo() {
return (
<img src={this.props.siteLogo} alt={`${this.props.siteName} logo`} />
);
}
renderMarketingSiteUrl(path) {
return `${this.props.marketingSiteBaseUrl}${path}`;
}
renderSocialLinks() {
const {
siteName,
showSocialLinks,
facebookUrl,
twitterUrl,
youTubeUrl,
linkedInUrl,
googlePlusUrl,
redditUrl,
} = this.props;
let socialLinks = null;
if (showSocialLinks) {
socialLinks = (
<ul
className="d-flex flex-row justify-content-between list-unstyled max-width-222 p-0 mb-4"
>
{/* TODO: Use Paragon HyperLink with Icon. */}
{/* Would need to add rel to paragon if we still need it. */}
<li>
<a
href={facebookUrl}
title="Facebook"
rel="noopener noreferrer"
target="_blank"
onClick={this.externalLinkClickHandler}
>
<Icon className={['fa', 'fa-facebook-square', 'fa-2x']} screenReaderText={`Like ${siteName} on Facebook`} />
</a>
</li>
<li>
<a
href={twitterUrl}
title="Twitter"
rel="noopener noreferrer"
target="_blank"
onClick={this.externalLinkClickHandler}
>
<Icon className={['fa', 'fa-twitter-square', 'fa-2x']} screenReaderText={`Follow ${siteName} on Twitter`} />
</a>
</li>
<li>
<a
href={youTubeUrl}
title="Youtube"
rel="noopener noreferrer"
target="_blank"
onClick={this.externalLinkClickHandler}
>
<Icon className={['fa', 'fa-youtube-square', 'fa-2x']} screenReaderText={`Subscribe to the ${siteName} YouTube channel`} />
</a>
</li>
<li>
<a
href={linkedInUrl}
title="LinkedIn"
rel="noopener noreferrer"
target="_blank"
onClick={this.externalLinkClickHandler}
>
<Icon className={['fa', 'fa-linkedin-square', 'fa-2x']} screenReaderText={`Follow ${siteName} on LinkedIn`} />
</a>
</li>
<li>
<a
href={googlePlusUrl}
title="Google+"
rel="noopener noreferrer"
target="_blank"
onClick={this.externalLinkClickHandler}
>
<Icon className={['fa', 'fa-google-plus-square', 'fa-2x']} screenReaderText={`Follow ${siteName} on Google+`} />
</a>
</li>
<li>
<a
href={redditUrl}
title="Reddit"
rel="noopener noreferrer"
target="_blank"
onClick={this.externalLinkClickHandler}
>
<Icon className={['fa', 'fa-reddit-square', 'fa-2x']} screenReaderText={`Subscribe to the ${siteName} subreddit`} />
</a>
</li>
</ul>
);
}
return socialLinks;
}
renderMobileLinks() {
const {
siteName,
showMobileLinks,
appleAppStoreUrl,
googlePlayUrl,
} = this.props;
let mobileLinks = null;
if (showMobileLinks) {
mobileLinks = (
<ul className="d-flex flex-row justify-content-between list-unstyled max-width-264 p-0 mb-5">
<li>
<a href={appleAppStoreUrl} rel="noopener noreferrer" target="_blank" onClick={this.externalLinkClickHandler}>
<img
className="max-height-39"
alt={`Download the ${siteName} mobile app from the Apple App Store`}
src="https://prod-edxapp.edx-cdn.org/static/images/app/app_store_badge_135x40.d0558d910630.svg"
/>
</a>
</li>
<li>
<a href={googlePlayUrl} rel="noopener noreferrer" target="_blank" onClick={this.externalLinkClickHandler}>
<img
className="max-height-39"
alt={`Download the ${siteName} mobile app from Google Play`}
src="https://prod-edxapp.edx-cdn.org/static/images/app/google_play_badge_45.6ea466e328da.png"
/>
</a>
</li>
</ul>
);
}
return mobileLinks;
}
render() {
const {
siteName,
openSourceUrl,
termsOfServiceUrl,
privacyPolicyUrl,
contactUrl,
supportUrl,
} = this.props;
return (
<footer
role="contentinfo"
aria-label="Page Footer"
className="footer d-flex justify-content-center border-top py-3 px-4"
>
<div className="max-width-1180 d-grid">
<div className="area-1">
<Hyperlink destination={this.renderMarketingSiteUrl('/')} content={this.renderSiteLogo()} aria-label={`${siteName} Home`} />
</div>
<div className="area-2">
<h2>{siteName}</h2>
<ul className="list-unstyled p-0 m-0">
<li><a href={this.renderMarketingSiteUrl('/about-us')}>About</a></li>
<li><a href={this.renderMarketingSiteUrl('/enterprise')}>{siteName} for Business</a></li>
<li><a href={this.renderMarketingSiteUrl('/affiliate-program')}>Affiliates</a></li>
<li><a href={openSourceUrl}>Open {siteName}</a></li>
<li><a href={this.renderMarketingSiteUrl('/careers')}>Careers</a></li>
<li><a href={this.renderMarketingSiteUrl('/news-announcements')}>News</a></li>
</ul>
</div>
<div className="area-3">
<h2>Legal</h2>
<ul className="list-unstyled p-0 m-0">
<li><a href={termsOfServiceUrl}>Terms of Service & Honor Code</a></li>
<li><a href={privacyPolicyUrl}>Privacy Policy</a></li>
<li><a href={this.renderMarketingSiteUrl('/accessibility')}>Accessibility Policy</a></li>
<li><a href={this.renderMarketingSiteUrl('/trademarks')}>Trademark Policy</a></li>
<li><a href={this.renderMarketingSiteUrl('/sitemap')}>Sitemap</a></li>
</ul>
</div>
<div className="area-4">
<h2>Connect</h2>
<ul className="list-unstyled p-0 m-0">
<li><a href={this.renderMarketingSiteUrl('/blog')}>Blog</a></li>
<li><a href={contactUrl}>Contact Us</a></li>
<li><a href={supportUrl}>Help Center</a></li>
<li><a href={this.renderMarketingSiteUrl('/media-kit')}>Media Kit</a></li>
<li><a href={this.renderMarketingSiteUrl('/donate')}>Donate</a></li>
</ul>
</div>
<div className="area-5">
{this.renderSocialLinks()}
{this.renderMobileLinks()}
<p>
© 2012{(new Date().getFullYear())} {siteName} Inc.
<br />
EdX, Open edX, and MicroMasters are registered trademarks of edX Inc.
| 粤ICP备17044299号-2
</p>
</div>
</div>
</footer>
);
}
}
SiteFooter.propTypes = {
siteName: PropTypes.string,
siteLogo: PropTypes.node,
marketingSiteBaseUrl: PropTypes.string,
supportUrl: PropTypes.string,
contactUrl: PropTypes.string,
openSourceUrl: PropTypes.string,
termsOfServiceUrl: PropTypes.string,
privacyPolicyUrl: PropTypes.string,
showSocialLinks: PropTypes.bool,
facebookUrl: PropTypes.string,
twitterUrl: PropTypes.string,
youTubeUrl: PropTypes.string,
linkedInUrl: PropTypes.string,
googlePlusUrl: PropTypes.string,
redditUrl: PropTypes.string,
showMobileLinks: PropTypes.bool,
appleAppStoreUrl: PropTypes.string,
googlePlayUrl: PropTypes.string,
handleAllTrackEvents: PropTypes.func.isRequired,
};
SiteFooter.defaultProps = {
siteName: null,
siteLogo: null,
marketingSiteBaseUrl: null,
supportUrl: null,
contactUrl: null,
openSourceUrl: null,
termsOfServiceUrl: null,
privacyPolicyUrl: null,
showSocialLinks: true,
facebookUrl: null,
twitterUrl: null,
youTubeUrl: null,
linkedInUrl: null,
googlePlusUrl: null,
redditUrl: null,
showMobileLinks: true,
appleAppStoreUrl: null,
googlePlayUrl: null,
};
export default SiteFooter;
export { EVENT_NAMES };

View File

@@ -1,3 +1,3 @@
import SiteFooter from './components/SiteFooter'; import SiteFooter from './SiteFooter';
export default SiteFooter; export default SiteFooter;