diff --git a/packages/netlify-cms-backend-test/src/__tests__/implementation.spec.js b/packages/netlify-cms-backend-test/src/__tests__/implementation.spec.js index 39a2f7ff..d6f5dfb3 100644 --- a/packages/netlify-cms-backend-test/src/__tests__/implementation.spec.js +++ b/packages/netlify-cms-backend-test/src/__tests__/implementation.spec.js @@ -104,8 +104,8 @@ describe('test backend implementation', () => { const backend = new TestBackend(); - const slug = encodeURIComponent('dir1/dir2/some-post.md'); - const path = `posts/${decodeURIComponent(slug)}`; + const slug = 'dir1/dir2/some-post.md'; + const path = `posts/${slug}`; const entry = { path, raw: 'content', slug }; await backend.persistEntry(entry, [], { newEntry: true }); @@ -138,8 +138,8 @@ describe('test backend implementation', () => { const backend = new TestBackend(); - const slug = encodeURIComponent('dir1/dir2/some-post.md'); - const path = `posts/${decodeURIComponent(slug)}`; + const slug = 'dir1/dir2/some-post.md'; + const path = `posts/${slug}`; const entry = { path, raw: 'new content', slug }; await backend.persistEntry(entry, [], { newEntry: false }); diff --git a/packages/netlify-cms-core/src/components/App/App.js b/packages/netlify-cms-core/src/components/App/App.js index 2a57a5f9..46ca82a0 100644 --- a/packages/netlify-cms-core/src/components/App/App.js +++ b/packages/netlify-cms-core/src/components/App/App.js @@ -190,7 +190,7 @@ class App extends React.Component { path="/collections/:name/new" render={props => } /> - + } diff --git a/packages/netlify-cms-core/src/components/Collection/Entries/EntryCard.js b/packages/netlify-cms-core/src/components/Collection/Entries/EntryCard.js index 81f06076..c882267f 100644 --- a/packages/netlify-cms-core/src/components/Collection/Entries/EntryCard.js +++ b/packages/netlify-cms-core/src/components/Collection/Entries/EntryCard.js @@ -94,8 +94,7 @@ const EntryCard = ({ const label = entry.get('label'); const entryData = entry.get('data'); const defaultTitle = label || entryData.get(inferedFields.titleField); - const slug = entry.get('slug'); - const path = `/collections/${collection.get('name')}/entries/${encodeURIComponent(slug)}`; + const path = `/collections/${collection.get('name')}/entries/${entry.get('slug')}`; const summary = collection.get('summary'); const date = parseDateFromEntry(entry, collection) || null; const identifier = entryData.get(selectIdentifier(collection)); diff --git a/packages/netlify-cms-core/src/components/Editor/Editor.js b/packages/netlify-cms-core/src/components/Editor/Editor.js index d9f16ec3..0c1bc309 100644 --- a/packages/netlify-cms-core/src/components/Editor/Editor.js +++ b/packages/netlify-cms-core/src/components/Editor/Editor.js @@ -40,7 +40,7 @@ const navigateCollection = collectionPath => history.push(`/collections/${collec const navigateToCollection = collectionName => navigateCollection(collectionName); const navigateToNewEntry = collectionName => navigateCollection(`${collectionName}/new`); const navigateToEntry = (collectionName, slug) => - navigateCollection(`${collectionName}/entries/${encodeURIComponent(slug)}`); + navigateCollection(`${collectionName}/entries/${slug}`); export class Editor extends React.Component { static propTypes = { @@ -435,7 +435,7 @@ export class Editor extends React.Component { function mapStateToProps(state, ownProps) { const { collections, entryDraft, auth, config, entries, globalUI } = state; - const slug = ownProps.match.params.slug && decodeURIComponent(ownProps.match.params.slug); + const slug = ownProps.match.params[0]; const collection = collections.get(ownProps.match.params.name); const collectionName = collection.get('name'); const newEntry = ownProps.newRecord === true; diff --git a/packages/netlify-cms-core/src/components/Editor/EditorControlPane/PathPreview.js b/packages/netlify-cms-core/src/components/Editor/EditorControlPane/PathPreview.js deleted file mode 100644 index e3c791a9..00000000 --- a/packages/netlify-cms-core/src/components/Editor/EditorControlPane/PathPreview.js +++ /dev/null @@ -1,47 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import { connect } from 'react-redux'; -import { translate } from 'react-polyglot'; -import styled from '@emotion/styled'; -import { colors, transitions } from 'netlify-cms-ui-default'; -import { selectDraftPath } from 'Selectors/entryDraft'; - -const PathLabel = styled.label` - color: ${colors.text}; - display: inline-block; - font-size: 12px; - font-weight: 600; - border: 0; - padding-left: 5px; - transition: all ${transitions.main}; - position: relative; -`; - -export const PathPreview = ({ value }) => { - return {value}; -}; - -PathPreview.propTypes = { - value: PropTypes.string.isRequired, - t: PropTypes.func.isRequired, -}; - -const mapStateToProps = (state, ownProps) => { - const collection = ownProps.collection; - const entry = ownProps.entry; - const newRecord = entry.get('newRecord'); - - const value = newRecord ? selectDraftPath(state, collection, entry) : entry.get('path'); - - return { value }; -}; - -const ConnectedPathPreview = connect(mapStateToProps)(translate()(PathPreview)); - -ConnectedPathPreview.propTypes = { - collection: ImmutablePropTypes.map.isRequired, - entry: ImmutablePropTypes.map.isRequired, -}; - -export default ConnectedPathPreview; diff --git a/packages/netlify-cms-core/src/components/Editor/EditorControlPane/__tests__/PathPreview.spec.js b/packages/netlify-cms-core/src/components/Editor/EditorControlPane/__tests__/PathPreview.spec.js deleted file mode 100644 index 1468b6e1..00000000 --- a/packages/netlify-cms-core/src/components/Editor/EditorControlPane/__tests__/PathPreview.spec.js +++ /dev/null @@ -1,84 +0,0 @@ -import React from 'react'; -import { Map } from 'immutable'; -import { createStore } from 'redux'; -import { Provider } from 'react-redux'; -import { render } from '@testing-library/react'; -import ConnectedPathPreview, { PathPreview } from '../PathPreview'; - -jest.mock('Reducers', () => { - return () => ({}); -}); -jest.mock('Selectors/entryDraft'); -jest.mock('react-polyglot', () => { - return { - translate: () => Component => props => key)} />, - }; -}); - -describe('PathPreview', () => { - it('should render successfully and match snapshot', () => { - const props = { - value: 'posts/2019/index.md', - t: jest.fn(key => key), - }; - const { asFragment } = render(); - - expect(asFragment()).toMatchSnapshot(); - }); -}); - -function renderWithRedux(ui, { initialState, store = createStore(() => ({}), initialState) } = {}) { - return { - ...render({ui}), - store, - }; -} - -describe('ConnectedPathPreview', () => { - const { selectDraftPath } = require('Selectors/entryDraft'); - - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('should use existing path when newRecord is false', () => { - const props = { - collection: Map({ - name: 'posts', - }), - entry: Map({ - newRecord: false, - data: {}, - path: 'existing-path/index.md', - }), - }; - const { asFragment, getByTestId } = renderWithRedux(); - - expect(selectDraftPath).toHaveBeenCalledTimes(0); - - expect(getByTestId('site_path-preview')).toHaveTextContent('existing-path/index.md'); - - expect(asFragment()).toMatchSnapshot(); - }); - - it('should evaluate preview path when newRecord is true', () => { - selectDraftPath.mockReturnValue('preview-path/index.md'); - const props = { - collection: Map({ - name: 'posts', - }), - entry: Map({ - newRecord: true, - data: {}, - }), - }; - const { asFragment, getByTestId } = renderWithRedux(); - - expect(selectDraftPath).toHaveBeenCalledTimes(1); - expect(selectDraftPath).toHaveBeenCalledWith({}, props.collection, props.entry); - - expect(getByTestId('site_path-preview')).toHaveTextContent('preview-path/index.md'); - - expect(asFragment()).toMatchSnapshot(); - }); -}); diff --git a/packages/netlify-cms-core/src/components/Editor/EditorControlPane/__tests__/__snapshots__/PathPreview.spec.js.snap b/packages/netlify-cms-core/src/components/Editor/EditorControlPane/__tests__/__snapshots__/PathPreview.spec.js.snap deleted file mode 100644 index b2b6c1e6..00000000 --- a/packages/netlify-cms-core/src/components/Editor/EditorControlPane/__tests__/__snapshots__/PathPreview.spec.js.snap +++ /dev/null @@ -1,70 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`ConnectedPathPreview should evaluate preview path when newRecord is true 1`] = ` - - .emotion-0 { - color: #798291; - display: inline-block; - font-size: 12px; - font-weight: 600; - border: 0; - padding-left: 5px; - -webkit-transition: all .2s ease; - transition: all .2s ease; - position: relative; -} - - - -`; - -exports[`ConnectedPathPreview should use existing path when newRecord is false 1`] = ` - - .emotion-0 { - color: #798291; - display: inline-block; - font-size: 12px; - font-weight: 600; - border: 0; - padding-left: 5px; - -webkit-transition: all .2s ease; - transition: all .2s ease; - position: relative; -} - - - -`; - -exports[`PathPreview should render successfully and match snapshot 1`] = ` - - .emotion-0 { - color: #798291; - display: inline-block; - font-size: 12px; - font-weight: 600; - border: 0; - padding-left: 5px; - -webkit-transition: all .2s ease; - transition: all .2s ease; - position: relative; -} - - - -`; diff --git a/packages/netlify-cms-core/src/components/Editor/withWorkflow.js b/packages/netlify-cms-core/src/components/Editor/withWorkflow.js index c7e6d72f..cccf1552 100644 --- a/packages/netlify-cms-core/src/components/Editor/withWorkflow.js +++ b/packages/netlify-cms-core/src/components/Editor/withWorkflow.js @@ -14,7 +14,7 @@ function mapStateToProps(state, ownProps) { showDelete: !ownProps.newEntry && selectAllowDeletion(collection), }; if (isEditorialWorkflow) { - const slug = ownProps.match.params.slug && decodeURIComponent(ownProps.match.params.slug); + const slug = ownProps.match.params[0]; const unpublishedEntry = selectUnpublishedEntry(state, collection.get('name'), slug); if (unpublishedEntry) { returnObj.unpublishedEntry = true; diff --git a/packages/netlify-cms-core/src/components/Workflow/WorkflowList.js b/packages/netlify-cms-core/src/components/Workflow/WorkflowList.js index 851ce678..352839cf 100644 --- a/packages/netlify-cms-core/src/components/Workflow/WorkflowList.js +++ b/packages/netlify-cms-core/src/components/Workflow/WorkflowList.js @@ -205,10 +205,7 @@ class WorkflowList extends React.Component { {entries.map(entry => { const timestamp = moment(entry.getIn(['metaData', 'timeStamp'])).format('MMMM D'); const slug = entry.get('slug'); - const editLink = `collections/${entry.getIn([ - 'metaData', - 'collection', - ])}/entries/${encodeURIComponent(slug)}`; + const editLink = `collections/${entry.getIn(['metaData', 'collection'])}/entries/${slug}`; const ownStatus = entry.getIn(['metaData', 'status']); const collection = entry.getIn(['metaData', 'collection']); const isModification = entry.get('isModification');