-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature(edit-comment-history) Implement edit comment and view comment…
… edit history functionality - write actions and reducer methods to edit comment - write actions and reducer methods to view comment edit history - write and style edit comment form component - write and style view edit history component - update single comment component to accomodate edit and edit history functionality - write tests - delivers[#166816082]
- Loading branch information
Showing
19 changed files
with
701 additions
and
60 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
27 changes: 27 additions & 0 deletions
27
src/components/EditCommentHistory/editCommentHistory.action.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import axiosUtil from '../../utils/axiosConfig'; | ||
import * as actionTypes from '../../actionTypes/index'; | ||
|
||
export const getCommentEditHistory = payload => { | ||
return { type: actionTypes.GET_COMMENT_EDIT_HISTORY, payload }; | ||
}; | ||
|
||
export const getCommentEditHistoryStart = () => { | ||
return { type: actionTypes.GET_COMMENT_EDIT_HISTORY_START }; | ||
}; | ||
|
||
export const cleanUpEditHistory = () => { | ||
return { type: actionTypes.CLEAN_UP_COMMENT_EDIT_HISTORY }; | ||
}; | ||
export const getEditHistoryRequest = (slug, commentId, token) => { | ||
return async dispatch => { | ||
dispatch(cleanUpEditHistory()); | ||
dispatch(getCommentEditHistoryStart()); | ||
const response = await axiosUtil.get( | ||
`articles/${slug}/comments/${commentId}/history`, | ||
{ | ||
headers: { Authorization: `Bearer ${token}` } | ||
} | ||
); | ||
dispatch(getCommentEditHistory(response.data.data)); | ||
}; | ||
}; |
25 changes: 25 additions & 0 deletions
25
src/components/EditCommentHistory/editCommentHistory.reducer.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import * as types from '../../actionTypes'; | ||
|
||
const commentEditHistoryReducer = (state = {}, action) => { | ||
switch (action.type) { | ||
case types.GET_COMMENT_EDIT_HISTORY_START: | ||
return { | ||
...state, | ||
isLoading: true | ||
}; | ||
case types.GET_COMMENT_EDIT_HISTORY: | ||
return { | ||
...state, | ||
history: action.payload, | ||
isLoading: false | ||
}; | ||
case types.CLEAN_UP_COMMENT_EDIT_HISTORY: | ||
return { | ||
...state, | ||
isLoading: false | ||
}; | ||
default: | ||
return state; | ||
} | ||
}; | ||
export default commentEditHistoryReducer; |
136 changes: 136 additions & 0 deletions
136
src/components/EditCommentHistory/editCommentHistory.spec.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
import React from 'react'; | ||
import '@babel/polyfill'; | ||
import mockAxios from 'axios'; | ||
import { shallow } from 'enzyme'; | ||
import editCommentHistoryReducer from './editCommentHistory.reducer'; | ||
import configureStore from 'redux-mock-store'; | ||
import thunk from 'redux-thunk'; | ||
import { getEditHistoryRequest } from './editCommentHistory.action'; | ||
import { EditCommentHistory } from './index.jsx'; | ||
import { | ||
GET_COMMENT_EDIT_HISTORY, | ||
GET_COMMENT_EDIT_HISTORY_START, | ||
CLEAN_UP_COMMENT_EDIT_HISTORY | ||
} from '../../actionTypes/index'; | ||
import Loader from '../LoadingIndicator/index.jsx'; | ||
|
||
const middlewares = [thunk]; | ||
const mockStore = configureStore(middlewares); | ||
|
||
const slug = 'How-To-Become-a-10x-Engineer'; | ||
const comment = 'Some new comment'; | ||
const token = 'jndmfdfdfdfkldk'; | ||
const response = { | ||
'6:00pm, 12th August 2030': 'previous comment', | ||
'6:01pm, 12th August 2030': 'another comment', | ||
'6:03pm, 12th August 2030': 'another comment' | ||
}; | ||
|
||
describe('Edit comment History actions tests', () => { | ||
let store; | ||
beforeEach(() => { | ||
store = mockStore({}); | ||
jest.resetAllMocks(); | ||
}); | ||
afterEach(() => { | ||
store.clearActions(); | ||
}); | ||
|
||
it('Should dispatch The UPDATE_COMMENT action', async () => { | ||
const mockData = { | ||
data: { | ||
data: { | ||
response | ||
} | ||
} | ||
}; | ||
|
||
mockAxios.get.mockResolvedValue({ | ||
data: mockData.data | ||
}); | ||
|
||
const expectedActions = [ | ||
{ type: 'CLEAN_UP_COMMENT_EDIT_HISTORY' }, | ||
{ type: 'GET_COMMENT_EDIT_HISTORY_START' }, | ||
{ | ||
type: 'GET_COMMENT_EDIT_HISTORY', | ||
payload: { | ||
response | ||
} | ||
} | ||
]; | ||
|
||
await store.dispatch(getEditHistoryRequest(slug, comment, token)); | ||
expect(store.getActions()).toEqual(expectedActions); | ||
}); | ||
}); | ||
|
||
describe('Get Comment Edit History Reducer Tests', () => { | ||
const initialState = {}; | ||
it('Should return a new state if it recieves a GET_COMMENT_EDIT_HISTORY_START action type', () => { | ||
const newState = editCommentHistoryReducer(initialState, { | ||
type: GET_COMMENT_EDIT_HISTORY_START, | ||
payload: {} | ||
}); | ||
expect(newState).toEqual({ | ||
isLoading: true | ||
}); | ||
}); | ||
|
||
it('Should return a new state if it recieves a GET_COMMENT_EDIT_HISTORY action type', () => { | ||
const newState = editCommentHistoryReducer(initialState, { | ||
type: GET_COMMENT_EDIT_HISTORY, | ||
payload: response | ||
}); | ||
expect(newState).toEqual({ | ||
isLoading: false, | ||
history: response | ||
}); | ||
}); | ||
|
||
it('Should return a new state if it recieves a CLEAN_UP_COMMENT_EDIT_HISTORY action type', () => { | ||
const newState = editCommentHistoryReducer(initialState, { | ||
type: CLEAN_UP_COMMENT_EDIT_HISTORY, | ||
payload: {} | ||
}); | ||
expect(newState).toEqual({ | ||
isLoading: false | ||
}); | ||
}); | ||
}); | ||
|
||
describe('EditCommentHistory Template', () => { | ||
it(`should render the EditCommentHistory Template when there is no edit history`, () => { | ||
const props = { | ||
commentHistory: { | ||
history: { | ||
commentEditHistory: {} | ||
} | ||
}, | ||
isLoading: false | ||
}; | ||
const component = shallow(<EditCommentHistory {...props} />); | ||
expect( | ||
component | ||
.find('.comment-edit-history') | ||
.contains( | ||
<h5 className="pt-5 text-center">This comment has no edit history</h5> | ||
) | ||
).toBeTruthy(); | ||
}); | ||
|
||
it(`should render the EditCommentHistory Template when the request is loading`, () => { | ||
const props = { | ||
commentHistory: { | ||
history: { | ||
commentEditHistory: { response } | ||
} | ||
}, | ||
isLoading: true | ||
}; | ||
const component = shallow(<EditCommentHistory {...props} />); | ||
expect( | ||
component.find('.comment-edit-history').contains(<Loader />) | ||
).toBeTruthy(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import React, { Component } from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import moment from 'moment'; | ||
import './style.scss'; | ||
import Loader from '../LoadingIndicator/index.jsx'; | ||
|
||
export class EditCommentHistory extends Component { | ||
render() { | ||
const { commentHistory, isLoading, lightTheme } = this.props; | ||
const additionalClass = lightTheme ? 'comment-body-light' : ''; | ||
const historyList = isLoading ? ( | ||
<Loader /> | ||
) : commentHistory && | ||
commentHistory.history && | ||
Object.keys(commentHistory.history.commentEditHistory).length > 1 ? ( | ||
Object.entries(commentHistory.history.commentEditHistory).map( | ||
(comment, i) => { | ||
return ( | ||
<div key={i} className={`comment-body ${additionalClass}`}> | ||
<span className={'w-100 d-block p-2'}>{comment[1]}</span> | ||
<span className={'w-100 d-block time-stamp text-right p-1'}> | ||
{moment(comment[0]).format('MMMM Do, YYYY, h:mm:ss a')} | ||
</span> | ||
</div> | ||
); | ||
} | ||
) | ||
) : ( | ||
<h5 className="pt-5 text-center">This comment has no edit history</h5> | ||
); | ||
return ( | ||
<> | ||
<div className="comment-edit-history">{historyList}</div> | ||
</> | ||
); | ||
} | ||
} | ||
|
||
EditCommentHistory.propTypes = { | ||
lightTheme: PropTypes.bool, | ||
commentHistory: PropTypes.object, | ||
slug: PropTypes.string, | ||
token: PropTypes.string, | ||
commentId: PropTypes.any, | ||
isLoading: PropTypes.bool | ||
}; | ||
|
||
export default EditCommentHistory; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
.comment-edit-history { | ||
height: 300px; | ||
width: 50vw; | ||
overflow: scroll; | ||
} | ||
.time-stamp { | ||
background-color: rgba(0, 0, 0, 0.64); | ||
border-top: 1px solid rgba(0, 0, 0, 0.125); | ||
font-size: 0.5em; | ||
} | ||
.comment-body { | ||
background: #161616; | ||
border: 1px solid grey; | ||
border-radius: 3px; | ||
color: inherit; | ||
min-height: 2em; | ||
margin-bottom: 7px; | ||
} | ||
.edit-functionality:hover { | ||
cursor: pointer; | ||
} | ||
.modal-main { | ||
top: 35% !important; | ||
} | ||
|
||
.comment-body-light { | ||
background: white !important; | ||
color: black !important; | ||
.time-stamp { | ||
background: rgba(0, 0, 0, 0.03) !important; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import axiosUtil from '../../utils/axiosConfig'; | ||
import * as actionTypes from '../../actionTypes/index'; | ||
|
||
export const updateComment = payload => { | ||
return { | ||
type: actionTypes.UPDATE_COMMENT, | ||
payload: { payload, isEdited: true } | ||
}; | ||
}; | ||
|
||
export const updateCommentRequest = (slug, commentId, comment, token) => { | ||
return async dispatch => { | ||
const response = await axiosUtil.patch( | ||
`articles/${slug}/comments/${commentId}/edit`, | ||
{ comment }, | ||
{ | ||
headers: { Authorization: `Bearer ${token}` } | ||
} | ||
); | ||
dispatch(updateComment(response.data.data)); | ||
}; | ||
}; |
Oops, something went wrong.