Merge branch 'master' into flags-locales

This commit is contained in:
Wyatt Johnson
2017-10-04 10:36:42 -06:00
48 changed files with 1080 additions and 638 deletions
+10 -4
View File
@@ -1,9 +1,8 @@
{
"presets": [
"es2015"
["es2015", {modules: false}]
],
"plugins": [
"add-module-exports",
"transform-class-properties",
"transform-decorators-legacy",
"transform-object-assign",
@@ -11,5 +10,12 @@
"transform-async-to-generator",
"transform-react-jsx",
"syntax-dynamic-import"
]
}
],
"env": {
"test": {
"plugins": [
["transform-es2015-modules-commonjs", "dynamic-import-node"]
]
}
}
}
-14
View File
@@ -1,14 +0,0 @@
{
"presets": [
"es2015"
],
"plugins": [
"add-module-exports",
"transform-class-properties",
"transform-decorators-legacy",
"transform-object-assign",
"transform-object-rest-spread",
"transform-async-to-generator",
"transform-react-jsx"
]
}
@@ -8,7 +8,7 @@ import styles from './QuestionBoxBuilder.css';
class QuestionBoxBuilder extends React.Component {
constructor() {
super();
this.state = {
loading: true
};
@@ -17,9 +17,9 @@ class QuestionBoxBuilder extends React.Component {
componentWillMount() {
this.loadEditor();
}
async loadEditor() {
const MarkdownEditor = await import('coral-framework/components/MarkdownEditor');
const {default: MarkdownEditor} = await import('coral-framework/components/MarkdownEditor');
return this.setState({
loading : false,
@@ -79,17 +79,17 @@ class QuestionBoxBuilder extends React.Component {
</ul>
<QuestionBox
className={styles.qb}
className={styles.qb}
enable={true}
icon={questionBoxIcon}
icon={questionBoxIcon}
content={questionBoxContent}
/>
<MarkdownEditor
<MarkdownEditor
value={questionBoxContent}
onChange={(value) => handleChange({}, {questionBoxContent: value})}
/>
</div>
);
}
+92 -95
View File
@@ -2,101 +2,98 @@ import URLSearchParams from 'url-search-params';
import Stream from './Stream';
import StreamInterface from './StreamInterface';
// This function should return value of window.Coral
const Coral = {};
const Talk = (Coral.Talk = {});
export class Talk {
/**
* Render a Talk stream
* @param {HTMLElement} el - Element to render the stream in
* @param {Object} opts - Configuration options for talk
* @param {String} opts.talk - Talk base URL
* @param {String} [opts.title] - Title of Stream (rendered in iframe)
* @param {String} [opts.asset_url] - Asset URL
* @param {String} [opts.asset_id] - Asset ID
* @param {String} [opts.auth_token] - (optional) A jwt representing the session
* @return {Object}
*
* Example:
* ```
* const embed = Talk.render(document.getElementById('talkStreamEmbed'), opts);
*
* // trigger a login with optional token.
* embed.login(token);
*
* // trigger a logout.
* embed.logout();
*
* // listen to events (in this case all events).
* embed.on('**', function(value) {
* console.log(this.event, value);
* });
* ```
*/
Talk.render = (el, opts) => {
if (!el) {
throw new Error('Please provide Coral.Talk.render() the HTMLElement you want to render Talk in.');
}
if (typeof el !== 'object') {
throw new Error(`Coral.Talk.render() expected HTMLElement but got ${el} (${typeof el})`);
}
opts = opts || {};
// TODO: infer this URL without explicit user input (if possible, may have to be added at build/render time of this script)
if (!opts.talk) {
throw new Error(
'Coral.Talk.render() expects opts.talk as the Talk Base URL'
);
}
// Ensure el has an id, as pym can't directly accept the HTMLElement.
if (!el.id) {
el.id = `_${Math.random()}`;
}
// Compose the query to send down to the Talk API so it knows what to load.
const query = {};
// Parse the url parameters to extract some of the information.
const urlParams = new URLSearchParams(window.location.search);
if (urlParams.get('commentId')) {
query.comment_id = urlParams.get('commentId');
}
// Extract the asset id from the options.
if (opts.asset_id) {
query.asset_id = opts.asset_id;
}
// Extract the asset url.
if (opts.asset_url) {
query.asset_url = opts.asset_url;
} else if (!opts.asset_id) {
// The asset url was not provided and the asset id was also not provided,
// we need to infer the asset url from details on the page.
try {
query.asset_url = document.querySelector('link[rel="canonical"]').href;
} catch (e) {
console.warn(
'This page does not include a canonical link tag. Talk has inferred this asset_url from the window object. Query params have been stripped, which may cause a single thread to be present across multiple pages.'
);
if (!window.location.origin) {
window.location.origin = `${window.location.protocol}//${window.location.hostname}${window.location.port ? `:${window.location.port}` : ''}`;
}
query.asset_url = window.location.origin + window.location.pathname;
/**
* Render a Talk stream
* @param {HTMLElement} el - Element to render the stream in
* @param {Object} opts - Configuration options for talk
* @param {String} opts.talk - Talk base URL
* @param {String} [opts.title] - Title of Stream (rendered in iframe)
* @param {String} [opts.asset_url] - Asset URL
* @param {String} [opts.asset_id] - Asset ID
* @param {String} [opts.auth_token] - (optional) A jwt representing the session
* @return {Object}
*
* Example:
* ```
* const embed = Talk.render(document.getElementById('talkStreamEmbed'), opts);
*
* // trigger a login with optional token.
* embed.login(token);
*
* // trigger a logout.
* embed.logout();
*
* // listen to events (in this case all events).
* embed.on('**', function(value) {
* console.log(this.event, value);
* });
* ```
*/
static render(el, opts) {
if (!el) {
throw new Error('Please provide Coral.Talk.render() the HTMLElement you want to render Talk in.');
}
if (typeof el !== 'object') {
throw new Error(`Coral.Talk.render() expected HTMLElement but got ${el} (${typeof el})`);
}
opts = opts || {};
// TODO: infer this URL without explicit user input (if possible, may have to be added at build/render time of this script)
if (!opts.talk) {
throw new Error(
'Coral.Talk.render() expects opts.talk as the Talk Base URL'
);
}
// Ensure el has an id, as pym can't directly accept the HTMLElement.
if (!el.id) {
el.id = `_${Math.random()}`;
}
// Compose the query to send down to the Talk API so it knows what to load.
const query = {};
// Parse the url parameters to extract some of the information.
const urlParams = new URLSearchParams(window.location.search);
if (urlParams.get('commentId')) {
query.comment_id = urlParams.get('commentId');
}
// Extract the asset id from the options.
if (opts.asset_id) {
query.asset_id = opts.asset_id;
}
// Extract the asset url.
if (opts.asset_url) {
query.asset_url = opts.asset_url;
} else if (!opts.asset_id) {
// The asset url was not provided and the asset id was also not provided,
// we need to infer the asset url from details on the page.
try {
query.asset_url = document.querySelector('link[rel="canonical"]').href;
} catch (e) {
console.warn(
'This page does not include a canonical link tag. Talk has inferred this asset_url from the window object. Query params have been stripped, which may cause a single thread to be present across multiple pages.'
);
if (!window.location.origin) {
window.location.origin = `${window.location.protocol}//${window.location.hostname}${window.location.port ? `:${window.location.port}` : ''}`;
}
query.asset_url = window.location.origin + window.location.pathname;
}
}
// Create the new Stream.
const stream = new Stream(el, opts.talk, query, opts);
// Return the public interface for the stream.
return new StreamInterface(stream);
}
// Create the new Stream.
const stream = new Stream(el, opts.talk, query, opts);
// Return the public interface for the stream.
return new StreamInterface(stream);
};
export default Coral;
}
@@ -1,6 +1,5 @@
import React from 'react';
import {shallow} from 'enzyme';
import {expect} from 'chai';
import Markdown from '../Markdown';
const render = (props) => shallow(<Markdown {...props} />);
@@ -9,12 +8,12 @@ describe('Markdown', () => {
it('should convert Markdown to html', () => {
const wrapper = render({content: '*test*'});
const html = wrapper.html();
expect(html).to.contain('<em>');
expect(html).toMatch('<em>');
});
it('should set target="_parent" for links', () => {
const wrapper = render({content: '[link](https://coralproject.net)'});
const html = wrapper.html();
expect(html).to.contain('target="_parent"');
expect(html).toMatch('target="_parent"');
});
});
@@ -21,7 +21,7 @@ module.exports = function(source) {
this.cacheable();
const config = this.exec(source, this.resourcePath);
const plugins = getPluginList(config).map((plugin) => `{
module: require('${plugin}/client'),
module: require('${plugin}/client').default,
name: '${plugin}'
}`);
+1 -2
View File
@@ -1,4 +1,4 @@
import ApolloClient, {addTypename, IntrospectionFragmentMatcher, createNetworkInterface} from 'apollo-client';
import ApolloClient, {IntrospectionFragmentMatcher, createNetworkInterface} from 'apollo-client';
import {SubscriptionClient, addGraphQLSubscriptions} from 'subscriptions-transport-ws';
import MessageTypes from 'subscriptions-transport-ws/dist/message-types';
@@ -64,7 +64,6 @@ export function createClient(options = {}) {
connectToDevTools: true,
addTypename: true,
fragmentMatcher: new IntrospectionFragmentMatcher({introspectionQueryResultData: introspectionData}),
queryTransformer: addTypename,
dataIdFromObject: (result) => {
if (result.id && result.__typename) { // eslint-disable-line no-underscore-dangle
return `${result.__typename}_${result.id}`; // eslint-disable-line no-underscore-dangle
@@ -1,26 +0,0 @@
import React from 'react';
import {shallow} from 'enzyme';
import {expect} from 'chai';
import CommentBox from '../CommentBox';
describe('CommentBox', () => {
let comment;
let render;
beforeEach(() => {
comment = {};
const postItem = (item) => {
comment.posted = item;
return Promise.resolve(4);
};
render = shallow(<CommentBox
postItem={postItem}
updateItem={(e) => comment.text = e.target.value}
item_id={'1'}
comments={['1', '2', '3']}/>);
});
it('should render the CommentBox appropriately', () => {
expect(render.contains('<div class="CommentBox"')).to.be.true;
expect(render.contains('<button class="postCommentButton"')).to.be.true;
});
});
+1 -5
View File
@@ -1,5 +1 @@
import reducer from './reducer';
export default {
reducer
};
export {default as reducer} from './reducer';
+13 -14
View File
@@ -1,15 +1,14 @@
export default {
username: {
offensive: 'USERNAME_OFFENSIVE',
nolike: 'USERNAME_NOLIKE',
impersonating: 'USERNAME_IMPERSONATING',
spam: 'USERNAME_SPAM',
other: 'USERNAME_OTHER'
},
comment: {
offensive: 'COMMENT_OFFENSIVE',
spam: 'COMMENT_SPAM',
noagree: 'COMMENT_NOAGREE',
other: 'COMMENT_OTHER'
}
export const username = {
offensive: 'USERNAME_OFFENSIVE',
nolike: 'USERNAME_NOLIKE',
impersonating: 'USERNAME_IMPERSONATING',
spam: 'USERNAME_SPAM',
other: 'USERNAME_OTHER'
};
export const comment = {
offensive: 'COMMENT_OFFENSIVE',
spam: 'COMMENT_SPAM',
noagree: 'COMMENT_NOAGREE',
other: 'COMMENT_OTHER'
};
@@ -1,29 +1,36 @@
import React from 'react';
import {shallow} from 'enzyme';
import {expect} from 'chai';
import InfoBox from '../InfoBox';
import renderer from 'react-test-renderer';
const render = (props) => shallow(<InfoBox {...props} />);
describe('InfoBox', () => {
it('renders correctly', () => {
const tree = renderer.create(
<InfoBox content='test' enable/>
).toJSON();
expect(tree).toMatchSnapshot();
});
it('should render hidden InfoBox', () => {
const wrapper = render();
const className = wrapper.prop('className');
expect(className).to.include('-info');
expect(className).to.include('hidden');
expect(className).toMatch('-info');
expect(className).toMatch('hidden');
});
it('should render enabled InfoBox', () => {
const wrapper = render({enable: true});
const className = wrapper.prop('className');
expect(className).to.include('-info');
expect(className).to.not.include('hidden');
expect(className).toMatch('-info');
expect(className).not.toMatch('hidden');
});
it('should render Markdown', () => {
const wrapper = render({content: 'x'});
const Markddown = wrapper.find('Markdown');
expect(Markddown).to.have.length(1);
expect(Markddown.prop('content')).to.equal('x');
expect(Markddown).toHaveLength(1);
expect(Markddown.prop('content')).toEqual('x');
});
});
@@ -0,0 +1,16 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`InfoBox renders correctly 1`] = `
<div
className="talk-plugin-infobox-info "
>
<div
dangerouslySetInnerHTML={
Object {
"__html": "<p>test</p>
",
}
}
/>
</div>
`;
+39
View File
@@ -0,0 +1,39 @@
const path = require('path');
const {pluginsPath} = require('./plugins');
const buildTargets = [
'coral-admin',
'coral-docs'
];
const buildEmbeds = [
'stream'
];
// jest.config.js
module.exports = {
testMatch: ['**/client/**/__tests__/**/*.js?(x)'],
setupTestFrameworkScriptFile: '<rootDir>/test/client/setupJest.js',
modulePaths: [
'<rootDir>/plugins',
'<rootDir>/client',
...buildTargets.map((target) => path.join('<rootDir>', 'client', target, 'src')),
...buildEmbeds.map((embed) => path.join('<rootDir>', 'client', `coral-embed-${embed}`, 'src')),
],
moduleFileExtensions: ['js', 'jsx', 'json', 'yaml', 'yml'],
moduleDirectories: ['node_modules'],
transform: {
'^.+\\.jsx?$': 'babel-jest',
'\\.ya?ml$': '<rootDir>/test/client/yamlTransformer.js'
},
moduleNameMapper: {
'^plugin-api\\/(.*)$': '<rootDir>/plugin-api/$1',
'^plugins\\/(.*)$': '<rootDir>/plugins/$1',
'^pluginsConfig$': pluginsPath,
'\\.(scss|css|less)$': 'identity-obj-proxy',
'\\.(gif|ttf|eot|svg)$': '<rootDir>/test/client/fileMock.js'
}
};
+12 -4
View File
@@ -14,7 +14,8 @@
"build-watch": "WEBPACK=TRUE NODE_ENV=development webpack --progress --config webpack.config.js --watch",
"lint": "eslint --ext=.js --ext=.json bin/* .",
"lint-fix": "yarn lint --fix",
"test": "TEST_MODE=unit NODE_ENV=test mocha -R ${MOCHA_REPORTER:-spec}",
"jest-watch": "TEST_MODE=unit NODE_ENV=test jest --watch",
"test": "TEST_MODE=unit NODE_ENV=test jest && TEST_MODE=unit NODE_ENV=test mocha -R ${MOCHA_REPORTER:-spec}",
"test-cover": "TEST_MODE=unit NODE_ENV=test istanbul cover _mocha --report text --check-coverage -- -R spec",
"heroku-postbuild": "./bin/cli plugins reconcile && yarn build",
"generate-introspection": "WEBPACK=TRUE NODE_ENV=test ./scripts/generateIntrospectionResult.js"
@@ -63,7 +64,6 @@
"babel-core": "^6.26.0",
"babel-eslint": "^7.2.1",
"babel-loader": "^7.1.2",
"babel-plugin-add-module-exports": "^0.2.1",
"babel-plugin-syntax-dynamic-import": "^6.18.0",
"babel-plugin-transform-async-to-generator": "^6.16.0",
"babel-plugin-transform-class-properties": "^6.23.0",
@@ -160,6 +160,7 @@
"react-redux": "^4.4.5",
"react-router": "^3.0.0",
"react-tagsinput": "^3.17.0",
"react-test-renderer": "15.5",
"react-toastify": "^1.5.0",
"react-transition-group": "^1.1.3",
"recompose": "^0.23.1",
@@ -180,17 +181,24 @@
"url-search-params": "^0.9.0",
"uuid": "^3.1.0",
"webpack": "^2.3.1",
"webpack-sources": "^1.0.1",
"yaml-loader": "^0.4.0",
"yamljs": "^0.2.10"
},
"devDependencies": {
"@coralproject/eslint-config-talk": "^0.0.3",
"@coralproject/eslint-config-talk": "^0.0.4",
"babel-jest": "^21.2.0",
"babel-plugin-dynamic-import-node": "^1.1.0",
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.0",
"chai": "^3.5.0",
"chai-as-promised": "^6.0.0",
"chai-http": "^3.0.0",
"enzyme": "^2.9.1",
"enzyme": "^3.0.0",
"enzyme-adapter-react-15": "^1.0.0",
"eslint": "^4.5.0",
"eslint-plugin-mocha": "^4.11.0",
"identity-obj-proxy": "^3.0.0",
"jest": "^21.2.1",
"mocha": "^3.1.2",
"mocha-junit-reporter": "^1.12.1",
"nodemon": "^1.11.0",
-14
View File
@@ -1,14 +0,0 @@
{
"presets": [
"es2015"
],
"plugins": [
"add-module-exports",
"transform-class-properties",
"transform-decorators-legacy",
"transform-object-assign",
"transform-object-rest-spread",
"transform-async-to-generator",
"transform-react-jsx"
]
}
-14
View File
@@ -1,14 +0,0 @@
{
"presets": [
"es2015"
],
"plugins": [
"add-module-exports",
"transform-class-properties",
"transform-decorators-legacy",
"transform-object-assign",
"transform-object-rest-spread",
"transform-async-to-generator",
"transform-react-jsx"
]
}
@@ -1,14 +0,0 @@
{
"presets": [
"es2015"
],
"plugins": [
"add-module-exports",
"transform-class-properties",
"transform-decorators-legacy",
"transform-object-assign",
"transform-object-rest-spread",
"transform-async-to-generator",
"transform-react-jsx"
]
}
@@ -1,14 +0,0 @@
{
"presets": [
"es2015"
],
"plugins": [
"add-module-exports",
"transform-class-properties",
"transform-decorators-legacy",
"transform-object-assign",
"transform-object-rest-spread",
"transform-async-to-generator",
"transform-react-jsx"
]
}
@@ -1,14 +0,0 @@
{
"presets": [
"es2015"
],
"plugins": [
"add-module-exports",
"transform-class-properties",
"transform-decorators-legacy",
"transform-object-assign",
"transform-object-rest-spread",
"transform-async-to-generator",
"transform-react-jsx"
]
}
@@ -1,14 +0,0 @@
{
"presets": [
"es2015"
],
"plugins": [
"add-module-exports",
"transform-class-properties",
"transform-decorators-legacy",
"transform-object-assign",
"transform-object-rest-spread",
"transform-async-to-generator",
"transform-react-jsx"
]
}
@@ -3,7 +3,7 @@ import cn from 'classnames';
import styles from './ModTag.css';
import {t} from 'plugin-api/beta/client/services';
import {Icon} from 'plugin-api/beta/client/components/ui';
import * as notification from 'coral-admin/src/services/notification';
import {getErrorMessages} from 'plugin-api/beta/client/utils';
export default class ModTag extends React.Component {
constructor() {
@@ -32,10 +32,10 @@ export default class ModTag extends React.Component {
postTag = async () => {
try {
await this.props.postTag();
notification.success(t('talk-plugin-featured-comments.notify_self_featured', this.props.comment.user.username));
this.props.notify('success', t('talk-plugin-featured-comments.notify_self_featured', this.props.comment.user.username));
}
catch(err) {
notification.showMutationErrors(err);
this.props.notify('error', getErrorMessages(err));
}
}
@@ -1,7 +1,7 @@
import React from 'react';
import Comment from '../containers/Comment';
import LoadMore from './LoadMore';
import {forEachError} from 'plugin-api/beta/client/utils';
import {getErrorMessages} from 'plugin-api/beta/client/utils';
class TabPane extends React.Component {
state = {
@@ -16,7 +16,7 @@ class TabPane extends React.Component {
})
.catch((error) => {
this.setState({loadingState: 'error'});
forEachError(error, ({msg}) => {this.props.addNotification('error', msg);});
this.props.notify('error', getErrorMessages(error));
});
}
@@ -1,6 +1,13 @@
import ModTag from '../components/ModTag';
import {withTags} from 'plugin-api/beta/client/hocs';
import {gql} from 'react-apollo';
import {withTags, connect} from 'plugin-api/beta/client/hocs';
import {gql, compose} from 'react-apollo';
import {bindActionCreators} from 'redux';
import {notify} from 'plugin-api/beta/client/actions/notification';
const mapDispatchToProps = (dispatch) =>
bindActionCreators({
notify,
}, dispatch);
const fragments = {
comment: gql`
@@ -11,6 +18,10 @@ const fragments = {
}
`
};
const enhance = compose(
withTags('featured', {fragments}),
connect(null, mapDispatchToProps),
);
export default withTags('featured', {fragments})(ModTag);
export default enhance(ModTag);
@@ -4,7 +4,7 @@ import {compose, gql} from 'react-apollo';
import TabPane from '../components/TabPane';
import {withFragments, connect} from 'plugin-api/beta/client/hocs';
import Comment from '../containers/Comment';
import {addNotification} from 'plugin-api/beta/client/actions/notification';
import {notify} from 'plugin-api/beta/client/actions/notification';
import {viewComment} from 'coral-embed-stream/src/actions/stream';
import {appendNewNodes, getDefinitionName} from 'plugin-api/beta/client/utils';
import update from 'immutability-helper';
@@ -81,7 +81,7 @@ const LOAD_MORE_QUERY = gql`
const mapDispatchToProps = (dispatch) =>
bindActionCreators({
viewComment,
addNotification,
notify,
}, dispatch);
const enhance = compose(
@@ -1,14 +0,0 @@
{
"presets": [
"es2015"
],
"plugins": [
"add-module-exports",
"transform-class-properties",
"transform-decorators-legacy",
"transform-object-assign",
"transform-object-rest-spread",
"transform-async-to-generator",
"transform-react-jsx"
]
}
@@ -1,14 +0,0 @@
{
"presets": [
"es2015"
],
"plugins": [
"add-module-exports",
"transform-class-properties",
"transform-decorators-legacy",
"transform-object-assign",
"transform-object-rest-spread",
"transform-async-to-generator",
"transform-react-jsx"
]
}
-14
View File
@@ -1,14 +0,0 @@
{
"presets": [
"es2015"
],
"plugins": [
"add-module-exports",
"transform-class-properties",
"transform-decorators-legacy",
"transform-object-assign",
"transform-object-rest-spread",
"transform-async-to-generator",
"transform-react-jsx"
]
}
-14
View File
@@ -1,14 +0,0 @@
{
"presets": [
"es2015"
],
"plugins": [
"add-module-exports",
"transform-class-properties",
"transform-decorators-legacy",
"transform-object-assign",
"transform-object-rest-spread",
"transform-async-to-generator",
"transform-react-jsx"
]
}
@@ -1,14 +0,0 @@
{
"presets": [
"es2015"
],
"plugins": [
"add-module-exports",
"transform-class-properties",
"transform-decorators-legacy",
"transform-object-assign",
"transform-object-rest-spread",
"transform-async-to-generator",
"transform-react-jsx"
]
}
@@ -1,14 +0,0 @@
{
"presets": [
"es2015"
],
"plugins": [
"add-module-exports",
"transform-class-properties",
"transform-decorators-legacy",
"transform-object-assign",
"transform-object-rest-spread",
"transform-async-to-generator",
"transform-react-jsx"
]
}
@@ -1,14 +0,0 @@
{
"presets": [
"es2015"
],
"plugins": [
"add-module-exports",
"transform-class-properties",
"transform-decorators-legacy",
"transform-object-assign",
"transform-object-rest-spread",
"transform-async-to-generator",
"transform-react-jsx"
]
}
@@ -1,14 +0,0 @@
{
"presets": [
"es2015"
],
"plugins": [
"add-module-exports",
"transform-class-properties",
"transform-decorators-legacy",
"transform-object-assign",
"transform-object-rest-spread",
"transform-async-to-generator",
"transform-react-jsx"
]
}
@@ -1,14 +0,0 @@
{
"presets": [
"es2015"
],
"plugins": [
"add-module-exports",
"transform-class-properties",
"transform-decorators-legacy",
"transform-object-assign",
"transform-object-rest-spread",
"transform-async-to-generator",
"transform-react-jsx"
]
}
@@ -1,14 +0,0 @@
{
"presets": [
"es2015"
],
"plugins": [
"add-module-exports",
"transform-class-properties",
"transform-decorators-legacy",
"transform-object-assign",
"transform-object-rest-spread",
"transform-async-to-generator",
"transform-react-jsx"
]
}
@@ -1,14 +0,0 @@
{
"presets": [
"es2015"
],
"plugins": [
"add-module-exports",
"transform-class-properties",
"transform-decorators-legacy",
"transform-object-assign",
"transform-object-rest-spread",
"transform-async-to-generator",
"transform-react-jsx"
]
}
@@ -1,14 +0,0 @@
{
"presets": [
"es2015"
],
"plugins": [
"add-module-exports",
"transform-class-properties",
"transform-decorators-legacy",
"transform-object-assign",
"transform-object-rest-spread",
"transform-async-to-generator",
"transform-react-jsx"
]
}
@@ -1,14 +0,0 @@
{
"presets": [
"es2015"
],
"plugins": [
"add-module-exports",
"transform-class-properties",
"transform-decorators-legacy",
"transform-object-assign",
"transform-object-rest-spread",
"transform-async-to-generator",
"transform-react-jsx"
]
}
@@ -1,14 +0,0 @@
{
"presets": [
"es2015"
],
"plugins": [
"add-module-exports",
"transform-class-properties",
"transform-decorators-legacy",
"transform-object-assign",
"transform-object-rest-spread",
"transform-async-to-generator",
"transform-react-jsx"
]
}
@@ -1,14 +0,0 @@
{
"presets": [
"es2015"
],
"plugins": [
"add-module-exports",
"transform-class-properties",
"transform-decorators-legacy",
"transform-object-assign",
"transform-object-rest-spread",
"transform-async-to-generator",
"transform-react-jsx"
]
}
@@ -1,14 +0,0 @@
{
"presets": [
"es2015"
],
"plugins": [
"add-module-exports",
"transform-class-properties",
"transform-decorators-legacy",
"transform-object-assign",
"transform-object-rest-spread",
"transform-async-to-generator",
"transform-react-jsx"
]
}
@@ -1,14 +0,0 @@
{
"presets": [
"es2015"
],
"plugins": [
"add-module-exports",
"transform-class-properties",
"transform-decorators-legacy",
"transform-object-assign",
"transform-object-rest-spread",
"transform-async-to-generator",
"transform-react-jsx"
]
}
@@ -1,14 +0,0 @@
{
"presets": [
"es2015"
],
"plugins": [
"add-module-exports",
"transform-class-properties",
"transform-decorators-legacy",
"transform-object-assign",
"transform-object-rest-spread",
"transform-async-to-generator",
"transform-react-jsx"
]
}
@@ -1,14 +0,0 @@
{
"presets": [
"es2015"
],
"plugins": [
"add-module-exports",
"transform-class-properties",
"transform-decorators-legacy",
"transform-object-assign",
"transform-object-rest-spread",
"transform-async-to-generator",
"transform-react-jsx"
]
}
+3
View File
@@ -0,0 +1,3 @@
{
"extends": "@coralproject/eslint-config-talk/client"
}
+1
View File
@@ -0,0 +1 @@
module.exports = 'test-file-stub';
+38
View File
@@ -0,0 +1,38 @@
import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-15';
Enzyme.configure({adapter: new Adapter()});
// Storage Mock
// TODO: Some places in our code (e.g. translations) has a hardcoded dependency
// to the local storage. Fixing it and we can remove this global mock.
function storageMock() {
let storage = {};
return {
setItem: function(key, value) {
storage[key] = value || '';
},
getItem: function(key) {
return key in storage ? storage[key] : null;
},
removeItem: function(key) {
delete storage[key];
},
get length() {
return Object.keys(storage).length;
},
key: function(i) {
let keys = Object.keys(storage);
return keys[i] || null;
}
};
}
// mock the localStorage
window.localStorage = storageMock();
// mock the sessionStorage
window.sessionStorage = storageMock();
+8
View File
@@ -0,0 +1,8 @@
const yaml = require('yamljs');
module.exports = {
process(src) {
const data = yaml.parse(src);
return `module.exports = ${JSON.stringify(data)};`;
},
};
+801 -96
View File
File diff suppressed because it is too large Load Diff