diff --git a/CHANGELOG.md b/CHANGELOG.md index a0696cd5ef..bcb39fd1e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ way to update this template, but currently, we follow a pattern: ## Upcoming version 2020-XX-XX +- [fix] Remove unintended Lodash usage, unspecified window-scope calls and unused vars + [#1413](https://github.com/sharetribe/ftw-daily/pull/1413) - [add] Route-based code splitting. This is done against sharetribe-scripts v5.0.0 using Loadable components. Read more from the pull request. [#1411](https://github.com/sharetribe/ftw-daily/pull/1411) diff --git a/src/app.node.test.js b/src/app.node.test.js index e33e1c21d2..f949d2b568 100644 --- a/src/app.node.test.js +++ b/src/app.node.test.js @@ -3,11 +3,9 @@ */ import React from 'react'; -import ReactDOM from 'react-dom'; import ReactDOMServer from 'react-dom/server'; -import { Helmet } from 'react-helmet-async'; import forEach from 'lodash/forEach'; -import { ClientApp, ServerApp } from './app'; +import { ServerApp } from './app'; import configureStore from './store'; const render = (url, context) => { @@ -56,7 +54,7 @@ describe('Application - node environment', () => { }; forEach(urlRedirects, (redirectPath, url) => { const context = {}; - const { body } = render(url, context); + render(url, context); expect(context.url).toEqual(redirectPath); }); }); @@ -65,7 +63,7 @@ describe('Application - node environment', () => { const urlRedirects = { '/l': '/', '/u': '/' }; forEach(urlRedirects, (redirectPath, url) => { const context = {}; - const { body } = render(url, context); + render(url, context); expect(context.url).toEqual(redirectPath); }); }); diff --git a/src/components/FieldDateInput/FieldDateInput.test.js b/src/components/FieldDateInput/FieldDateInput.test.js deleted file mode 100644 index 562bada5d3..0000000000 --- a/src/components/FieldDateInput/FieldDateInput.test.js +++ /dev/null @@ -1,28 +0,0 @@ -import React from 'react'; - -// react-dates needs to be initialized before using any react-dates component -// Since this is currently only component using react-dates we can do it here -// https://github.com/airbnb/react-dates#initialize -import 'react-dates/initialize'; -import { renderDeep } from '../../util/test-helpers'; -import { DateInput } from './FieldDateInput'; - -const noop = () => null; - -describe('DateInput', () => { - it('TODO, wait react-dates to work with React 16.9 without warnings', () => { - expect('todo').toEqual('todo'); - }); - // it('matches snapshot', () => { - // const props = { - // name: 'bookingDate', - // onBlur: noop, - // onChange: noop, - // onFocus: noop, - // id: 'bookingDate', - // placeholderText: 'today', - // }; - // const tree = renderDeep(); - // expect(tree).toMatchSnapshot(); - // }); -}); diff --git a/src/components/FieldDateRangeInput/FieldDateRangeInput.test.js b/src/components/FieldDateRangeInput/FieldDateRangeInput.test.js deleted file mode 100644 index 63d5c4d135..0000000000 --- a/src/components/FieldDateRangeInput/FieldDateRangeInput.test.js +++ /dev/null @@ -1,33 +0,0 @@ -import React from 'react'; - -// react-dates needs to be initialized before using any react-dates component -// Since this is currently only component using react-dates we can do it here -// https://github.com/airbnb/react-dates#initialize -import 'react-dates/initialize'; -import { renderDeep } from '../../util/test-helpers'; -import { LINE_ITEM_NIGHT } from '../../util/types'; -import { DateRangeInput } from './FieldDateRangeInput'; - -const noop = () => null; - -describe('DateRangeInput', () => { - it('TODO, wait react-dates to work with React 16.9 without warnings', () => { - expect('todo').toEqual('todo'); - }); - - // it('matches snapshot', () => { - // const props = { - // unitType: LINE_ITEM_NIGHT, - // name: 'bookingDates', - // onBlur: noop, - // onChange: noop, - // onFocus: noop, - // startDateId: 'bookingStartDate', - // startDatePlaceholderText: 'today', - // endDateId: 'bookingEndDate', - // endDatePlaceholderText: 'tomorrow', - // }; - // const tree = renderDeep(); - // expect(tree).toMatchSnapshot(); - // }); -}); diff --git a/src/components/ManageListingCard/ManageListingCard.test.js b/src/components/ManageListingCard/ManageListingCard.test.js index 801eb87d55..696e1aa82a 100644 --- a/src/components/ManageListingCard/ManageListingCard.test.js +++ b/src/components/ManageListingCard/ManageListingCard.test.js @@ -1,6 +1,6 @@ import React from 'react'; import { renderShallow } from '../../util/test-helpers'; -import { createUser, createOwnListing, fakeIntl } from '../../util/test-data'; +import { createOwnListing, fakeIntl } from '../../util/test-data'; import { ManageListingCardComponent } from './ManageListingCard'; const noop = () => null; diff --git a/src/components/Map/DynamicGoogleMap.js b/src/components/Map/DynamicGoogleMap.js index d963f6cc6e..2078cb1e78 100644 --- a/src/components/Map/DynamicGoogleMap.js +++ b/src/components/Map/DynamicGoogleMap.js @@ -1,6 +1,5 @@ import React, { Component } from 'react'; import { number, object, shape, string } from 'prop-types'; -import classNames from 'classnames'; import { circlePolyline } from '../../util/maps'; import config from '../../config'; @@ -91,7 +90,7 @@ class DynamicGoogleMap extends Component { } : {}; - const marker = new window.google.maps.Marker({ + new window.google.maps.Marker({ position: center, map: this.map, title: address, diff --git a/src/components/NamedLink/NamedLink.test.js b/src/components/NamedLink/NamedLink.test.js index 9fa38779ca..5a40d4d866 100644 --- a/src/components/NamedLink/NamedLink.test.js +++ b/src/components/NamedLink/NamedLink.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { renderShallow, renderDeep } from '../../util/test-helpers'; +import { renderDeep } from '../../util/test-helpers'; import NamedLink, { NamedLinkComponent } from './NamedLink'; describe('NamedLinkComponent', () => { diff --git a/src/components/ResponsiveImage/ResponsiveImage.js b/src/components/ResponsiveImage/ResponsiveImage.js index f92881eaeb..e2429b818e 100644 --- a/src/components/ResponsiveImage/ResponsiveImage.js +++ b/src/components/ResponsiveImage/ResponsiveImage.js @@ -77,12 +77,11 @@ const ResponsiveImage = props => { const imgProps = { className: classes, - alt, srcSet, ...rest, }; - return ; + return {alt}; }; ResponsiveImage.defaultProps = { diff --git a/src/components/SearchMap/SearchMapWithGoogleMaps.js b/src/components/SearchMap/SearchMapWithGoogleMaps.js index a0b126b766..589112670d 100644 --- a/src/components/SearchMap/SearchMapWithGoogleMaps.js +++ b/src/components/SearchMap/SearchMapWithGoogleMaps.js @@ -1,7 +1,7 @@ import React, { Component } from 'react'; import ReactDOM from 'react-dom'; import invariant from 'invariant'; -import { arrayOf, func, node, number, oneOfType, shape, string } from 'prop-types'; +import { arrayOf, func, number, oneOfType, shape, string } from 'prop-types'; import isEqual from 'lodash/isEqual'; import classNames from 'classnames'; import { types as sdkTypes } from '../../util/sdkLoader'; @@ -152,7 +152,7 @@ class CustomOverlayView extends Component { ...getOffsetOverride(this.containerElement, this.props), }; const layoutStyles = getLayoutStyles(mapCanvasProjection, offset, this.props); - _.assign(this.containerElement.style, layoutStyles); + Object.assign(this.containerElement.style, layoutStyles); } draw() { @@ -515,11 +515,6 @@ class SearchMapWithGoogleMaps extends Component { const { id, className, - onMapLoad, - onMapMoveEnd, - center, - bounds, - zoom, listings, activeListingId, infoCardOpen, @@ -527,7 +522,6 @@ class SearchMapWithGoogleMaps extends Component { mapComponentRefreshToken, onListingInfoCardClicked, createURLToListing, - ...rest } = this.props; return (
{ onUpdateListing={noop} onImageUpload={noop} onRemoveListingImage={noop} - onManageDisableScrolling={noop} onPayoutDetailsFormChange={noop} onPayoutDetailsSubmit={noop} onUpdateImageOrder={noop} diff --git a/src/containers/InboxPage/InboxPage.test.js b/src/containers/InboxPage/InboxPage.test.js index 478dd6828b..0583f09891 100644 --- a/src/containers/InboxPage/InboxPage.test.js +++ b/src/containers/InboxPage/InboxPage.test.js @@ -1,5 +1,4 @@ import React from 'react'; -import { RoutesProvider } from '../../components'; import { renderShallow, renderDeep } from '../../util/test-helpers'; import { fakeIntl, @@ -9,7 +8,6 @@ import { createBooking, } from '../../util/test-data'; import { InboxPageComponent, InboxItem, txState } from './InboxPage'; -import routeConfiguration from '../../routeConfiguration'; import { TRANSITION_CONFIRM_PAYMENT } from '../../util/transaction'; import { LINE_ITEM_NIGHT } from '../../util/types'; diff --git a/src/containers/LandingPage/LandingPage.test.js b/src/containers/LandingPage/LandingPage.test.js index 7e7c95baf5..010a02ef72 100644 --- a/src/containers/LandingPage/LandingPage.test.js +++ b/src/containers/LandingPage/LandingPage.test.js @@ -2,8 +2,6 @@ import React from 'react'; import { fakeIntl } from '../../util/test-data'; import { renderShallow } from '../../util/test-helpers'; import { LandingPageComponent } from './LandingPage'; -import { RoutesProvider } from '../../components'; -import routeConfiguration from '../../routeConfiguration'; const noop = () => null; diff --git a/src/containers/ListingPage/ListingPage.test.js b/src/containers/ListingPage/ListingPage.test.js index 6a9b354ec9..4d01f69c2b 100644 --- a/src/containers/ListingPage/ListingPage.test.js +++ b/src/containers/ListingPage/ListingPage.test.js @@ -20,10 +20,6 @@ import { import { addMarketplaceEntities } from '../../ducks/marketplaceData.duck'; import { showListingRequest, showListingError, showListing } from './ListingPage.duck'; -// routeConfiguration needs to be imported before tests for ListingPageComponent can be made. -// Otherwise, ListingPage itself is not initialized correctly when routeConfiguration is imported -// (loadData call fails). -import routeConfiguration from '../../routeConfiguration'; import { ListingPageComponent } from './ListingPage'; import ActionBarMaybe from './ActionBarMaybe'; diff --git a/src/containers/ProfilePage/ProfilePage.test.js b/src/containers/ProfilePage/ProfilePage.test.js index f0c5457e33..41ebfad318 100644 --- a/src/containers/ProfilePage/ProfilePage.test.js +++ b/src/containers/ProfilePage/ProfilePage.test.js @@ -3,8 +3,6 @@ import { renderShallow } from '../../util/test-helpers'; import { createUser, fakeIntl, fakeViewport } from '../../util/test-data'; import { ProfilePageComponent } from './ProfilePage'; -const noop = () => null; - describe('ProfilePage', () => { it('matches snapshot', () => { const tree = renderShallow( diff --git a/src/containers/SearchPage/SearchPage.test.js b/src/containers/SearchPage/SearchPage.test.js index 9b7a35e452..7edc6a6ba2 100644 --- a/src/containers/SearchPage/SearchPage.test.js +++ b/src/containers/SearchPage/SearchPage.test.js @@ -1,19 +1,8 @@ import React from 'react'; import { renderShallow } from '../../util/test-helpers'; import { fakeIntl } from '../../util/test-data'; -import { types as sdkTypes } from '../../util/sdkLoader'; import { SearchPageComponent } from './SearchPage'; -import reducer, { - ADD_FILTER, - LOAD_LISTINGS, - addFilter, - callFetchListings, - initialState, - loadListings, - watchLoadListings, -} from './SearchPage.duck'; -const { LatLng } = sdkTypes; const noop = () => null; describe('SearchPageComponent', () => { diff --git a/src/default-location-searches.js b/src/default-location-searches.js index fd83cf7e7f..b5d666b896 100644 --- a/src/default-location-searches.js +++ b/src/default-location-searches.js @@ -7,7 +7,7 @@ const { LatLng, LatLngBounds } = sdkTypes; // // Each item in the array should be an object with a unique `id` (String) and a // `predictionPlace` (util.types.place) properties. -export default [ +const defaultLocations = [ { id: 'default-helsinki', predictionPlace: { @@ -44,3 +44,4 @@ export default [ }, }, ]; +export default defaultLocations; diff --git a/src/ducks/FlashNotification.duck.js b/src/ducks/FlashNotification.duck.js deleted file mode 100644 index 2d4d3ec063..0000000000 --- a/src/ducks/FlashNotification.duck.js +++ /dev/null @@ -1,51 +0,0 @@ -/** - * This file contains Action constants, Action creators, and reducer of global - * FlashMessages. Global actions can be used in multiple pages. - * We are following Ducks module proposition: - * https://github.com/erikras/ducks-modular-redux - */ - -import find from 'lodash/find'; -import findIndex from 'lodash/findIndex'; - -// Actions: system notifications -export const ADD_FLASH_NOTIFICATION = 'app/FlashNotification/ADD_NOTIFICATION'; -export const REMOVE_FLASH_NOTIFICATION = 'app/FlashNotification/REMOVE_NOTIFICATION'; - -const initialState = []; - -// Reducer -export default (state = initialState, action) => { - const { type, payload } = action; - switch (type) { - case ADD_FLASH_NOTIFICATION: - if (!find(state, n => n.content === payload.content && !n.isRead)) { - return state.concat([ - { id: payload.id, type: payload.type, content: payload.content, isRead: false }, - ]); - } - return state; - - case REMOVE_FLASH_NOTIFICATION: - return state.map(findIndex(state, msg => msg.id === payload.id), msg => - msg.set('isRead', true) - ); - - default: - return state; - } -}; - -// Action Creators -let nextMessageId = 1; - -export const addFlashNotification = (type, content) => { - const id = nextMessageId; - nextMessageId += 1; - return { - type: ADD_FLASH_NOTIFICATION, - payload: { id: `note_${id}`, type, content, isRead: false }, - }; -}; - -export const removeFlashNotification = id => ({ type: REMOVE_FLASH_NOTIFICATION, payload: { id } }); diff --git a/src/ducks/FlashNotification.test.js b/src/ducks/FlashNotification.test.js deleted file mode 100644 index 640fffd149..0000000000 --- a/src/ducks/FlashNotification.test.js +++ /dev/null @@ -1,49 +0,0 @@ -import reducer, { - ADD_FLASH_NOTIFICATION, - REMOVE_FLASH_NOTIFICATION, - addFlashNotification, - removeFlashNotification, -} from './FlashNotification.duck'; - -describe('FlashNotification', () => { - describe('actions', () => { - it('should create an action to add a filter', () => { - const content = 'Error message'; - const type = 'error'; - const expectedAction = { - type: ADD_FLASH_NOTIFICATION, - payload: { id: 'note_1', type, content, isRead: false }, - }; - const received = addFlashNotification(type, content); - expect(received).toEqual(expectedAction); - }); - - it('should create an action to remove a notification', () => { - const expectedAction = { type: REMOVE_FLASH_NOTIFICATION, payload: { id: 1 } }; - - expect(removeFlashNotification(1)).toEqual(expectedAction); - }); - }); - - describe('reducer', () => { - it('should return the initial state', () => { - const initial = reducer(undefined, {}); - expect(initial).toEqual([]); - }); - - it('should handle ADD_FLASH_NOTIFICATION', () => { - const addFlashNote1 = addFlashNotification('error', 'Run the tests'); - const addFlashNote2 = addFlashNotification('error', 'Run the tests again'); - const reduced = reducer([], addFlashNote1); - const reducedWithInitialContent = reducer([addFlashNote1.payload], addFlashNote2); - expect(reduced).toEqual([addFlashNote1.payload]); - expect(reducedWithInitialContent).toEqual([addFlashNote1.payload, addFlashNote2.payload]); - }); - - it('should handle duplicates ADD_FILTER', () => { - const addFlashNote = addFlashNotification('error', 'Run the tests'); - const reducedWithInitialContent = reducer([addFlashNote.payload], addFlashNote); - expect(reducedWithInitialContent).toEqual([addFlashNote.payload]); - }); - }); -}); diff --git a/src/ducks/index.js b/src/ducks/index.js index e9d298f71b..97363c2b2d 100644 --- a/src/ducks/index.js +++ b/src/ducks/index.js @@ -6,7 +6,6 @@ import Auth from './Auth.duck'; import EmailVerification from './EmailVerification.duck'; -import FlashNotification from './FlashNotification.duck'; import LocationFilter from './LocationFilter.duck'; import Routing from './Routing.duck'; import UI from './UI.duck'; @@ -19,7 +18,6 @@ import user from './user.duck'; export { Auth, EmailVerification, - FlashNotification, LocationFilter, Routing, UI, diff --git a/src/forms/EditListingPhotosForm/EditListingPhotosForm.test.js b/src/forms/EditListingPhotosForm/EditListingPhotosForm.test.js index b8cbbdb5a1..a162cdf1bb 100644 --- a/src/forms/EditListingPhotosForm/EditListingPhotosForm.test.js +++ b/src/forms/EditListingPhotosForm/EditListingPhotosForm.test.js @@ -21,7 +21,6 @@ describe('EditListingPhotosForm', () => { ready={false} updateInProgress={false} disabled={false} - ready={false} onRemoveImage={noop} /> ); diff --git a/src/util/data.test.js b/src/util/data.test.js index 189817fa57..63ef11fa08 100644 --- a/src/util/data.test.js +++ b/src/util/data.test.js @@ -4,8 +4,6 @@ import { combinedResourceObjects, updatedEntities, denormalisedEntities, - arrayToFormValues, - formValuesToArray, humanizeLineItemCode, } from './data'; diff --git a/src/util/googleMaps.js b/src/util/googleMaps.js index ed16966fe4..c8e51d392b 100644 --- a/src/util/googleMaps.js +++ b/src/util/googleMaps.js @@ -259,10 +259,10 @@ export const getLayoutStyles = (mapCanvasProjection, offset, props) => { }; if (props.bounds) { - const bounds = ensureOfType(props.bounds, google.maps.LatLngBounds, createLatLngBounds); + const bounds = ensureOfType(props.bounds, window.google.maps.LatLngBounds, createLatLngBounds); return getLayoutStylesByBounds(mapCanvasProjection, offset, bounds); } else { - const position = ensureOfType(props.position, google.maps.LatLng, createLatLng); + const position = ensureOfType(props.position, window.google.maps.LatLng, createLatLng); return getLayoutStylesByPosition(mapCanvasProjection, offset, position); } }; diff --git a/src/util/richText.test.js b/src/util/richText.test.js index 32f83a9bfa..10b8c45d43 100644 --- a/src/util/richText.test.js +++ b/src/util/richText.test.js @@ -226,7 +226,7 @@ describe('richText', () => { // Chars one​/​two​/​three - count until exhaustion… // expect(wrapper.html()).toEqual( - `Chars one${slashWithZWSP}two${slashWithZWSP}three - count until exhaustion…` + `Chars one${slashWithZWSP}two${slashWithZWSP}three - count until exhaustion…` ); }); @@ -238,7 +238,7 @@ describe('richText', () => { // Chars one​/​two​/​three​,​ count until exhaustion… // expect(wrapper.html()).toEqual( - `Chars one${slashWithZWSP}two${slashWithZWSP}three${commaWithZWSP} count until exhaustion…` + `Chars one${slashWithZWSP}two${slashWithZWSP}three${commaWithZWSP} count until exhaustion…` ); }); @@ -255,7 +255,7 @@ describe('richText', () => { // Chars one​/​two​/​three - count until exhaustion… and a random link: http://www.example.com // expect(wrapper.html()).toEqual( - `Chars one${slashWithZWSP}two${slashWithZWSP}three - count until exhaustion… and a random link: http://www.example.com` + `Chars one${slashWithZWSP}two${slashWithZWSP}three - count until exhaustion… and a random link: http://www.example.com` ); }); it('should add link inside non-whitespace-sequence (http://example.com)', () => { @@ -266,7 +266,7 @@ describe('richText', () => { // Link: (http://example.com) // expect(wrapper.html()).toEqual( - `Link: (http://example.com)` + `Link: (http://example.com)` ); }); it('should not add span around a string if no linkify option is given', () => { @@ -282,7 +282,7 @@ describe('richText', () => { // Chars one​/​two​/​three - count until exhaustion… and a random link: http:​/​​/​www.example.com // expect(wrapper.html()).toEqual( - `Chars one${slashWithZWSP}two${slashWithZWSP}three - count until exhaustion… and a random link: http://www.example.com` + `Chars one${slashWithZWSP}two${slashWithZWSP}three - count until exhaustion… and a random link: http://www.example.com` ); }); }); diff --git a/src/util/routes.test.js b/src/util/routes.test.js index f8d22ecb73..82dd4cf8a4 100644 --- a/src/util/routes.test.js +++ b/src/util/routes.test.js @@ -1,8 +1,4 @@ -import React from 'react'; -import { arrayOf } from 'prop-types'; -import { RoutesProvider } from '../components'; import routeConfiguration from '../routeConfiguration'; -import { renderDeep, renderShallow } from './test-helpers'; import { createResourceLocatorString, findRouteByRouteName, canonicalRoutePath } from './routes'; describe('util/routes.js', () => { diff --git a/src/util/validators.test.js b/src/util/validators.test.js index 83f2f88302..13e84d584f 100644 --- a/src/util/validators.test.js +++ b/src/util/validators.test.js @@ -208,10 +208,6 @@ describe('validators', () => { expect(requiredWithMinLength('')).toEqual('required'); }); it('should fail on composed minLength (4) and required: empty string. Error: minLength', () => { - const requiredWithMinLength = composeValidators( - minLength('minLength', 4), - required('required') - ); expect(validateLength('')).toEqual('minLength'); }); });