diff --git a/__mocks__/FriendsListMock.js b/__mocks__/FriendsListMock.js new file mode 100644 index 0000000..034a93a --- /dev/null +++ b/__mocks__/FriendsListMock.js @@ -0,0 +1,40 @@ +import readFileSync from "fs"; +import path from "path"; +import { act } from "@testing-library/react"; + +const friends = [ + { + friend_profile_image: "", + friend_username: "animecody", + friend_bio: "DBZ all day bby", + friends_id: 8, + }, + { + friend_profile_image: "", + friend_username: "JDawg", + friend_bio: "Ask me about my pizza", + friends_id: 9, + }, + { + friend_profile_image: "", + friend_username: "Buddy", + friend_bio: "Pizza without cheese, sauce, and toppings is just bread", + friends_id: 10, + }, +]; + +// const friendos = JSON.parse( +// readFileSync(path.join(__dirname, "res.json")).toString() +// ); + +export const _friends = friends; + +const mock = { + friends: jest.fn(() => { + return { + then: (callback) => act(() => callback([friends])), + }; + }), +}; + +export default mock; diff --git a/src/components/users/FriendsComp/FriendOnList.test.js b/src/components/users/FriendsComp/FriendOnList.test.js index 917d52c..ce375a0 100644 --- a/src/components/users/FriendsComp/FriendOnList.test.js +++ b/src/components/users/FriendsComp/FriendOnList.test.js @@ -1,88 +1,101 @@ -import React from 'react'; -import { render, fireEvent, cleanup, waitFor } from '@testing-library/react'; -import '@testing-library/jest-dom/extend-expect'; -import { findFirstProp } from '../../../utils/reduxTestingFunctions' -import FriendOnList from './FriendOnList'; +import React from "react"; +import { render, fireEvent, cleanup, waitFor } from "@testing-library/react"; +import "@testing-library/jest-dom/extend-expect"; +import { findFirstProp } from "../../../utils/reduxTestingFunctions"; +import FriendOnList from "./FriendOnList"; describe("FriendOnList", () => { - - afterEach(cleanup); - - const friend = { - friend_profile_image: "", - friend_username: "animecody", - friend_bio: "DBZ all day bby", - friends_id: 8 - }; - const deleteUserMessage = `Are you sure you want to remove ${friend.friend_username} from your friends list?`; - const removeFriend = id => { - console.log(`${id} was removed`) - }; - - it('renders text & values from props', () => { - const { getByText, getAllByText } = render(); - - const removeText = findFirstProp("Remove", getByText, getAllByText); - const bioText = findFirstProp("DBZ all day bby", getByText, getAllByText); - const usernameText = findFirstProp("animecody", getByText, getAllByText); - - expect(removeText).toBeInTheDocument(); - expect(bioText).toBeInTheDocument(); - expect(usernameText).toBeInTheDocument(); - }); - - it('remove onClick toggles modalon', async () => { - const { getByText, getAllByText } = render(); - const removeText = findFirstProp("Remove", getByText, getAllByText); - - fireEvent.click(removeText); - - const delMessage = await waitFor(() => getByText(new RegExp(deleteUserMessage, "i"))) - const okButton = getByText(/ok/i); - const cancelButton = getByText(/cancel/i); - - expect(delMessage).toBeVisible(); - expect(okButton).toBeInTheDocument(); - expect(cancelButton).toBeInTheDocument(); - }) - - it('modal cancel button onClick toggles modal off', async () => { - const { getByText, getAllByText } = render(); - const removeText = findFirstProp("Remove", getByText, getAllByText); - - fireEvent.click(removeText); - - const delMessage = await waitFor(() => getByText(new RegExp(deleteUserMessage, "i"))) - const cancelButton = getByText(/cancel/i); - const okButton = getByText(/ok/i); - - expect(delMessage).toBeVisible(); - expect(cancelButton).toBeInTheDocument(); - expect(okButton).toBeInTheDocument(); - - fireEvent.click(cancelButton); - - await waitFor(() => delMessage) - expect(cancelButton).not.toBeInTheDocument(); - expect(okButton).not.toBeInTheDocument(); - }) - - it('modal OK button runs remove function from props', async () => { - const { getByText, getAllByText } = render(); - const removeText = findFirstProp("Remove", getByText, getAllByText); - console.log = jest.fn(); - - fireEvent.click(removeText); - - const delMessage = await waitFor(() => getByText(new RegExp(deleteUserMessage, "i"))) - const cancelButton = getByText(/cancel/i); - const okButton = getByText(/ok/i); - - expect(delMessage).toBeVisible(); - expect(cancelButton).toBeInTheDocument(); - expect(okButton).toBeInTheDocument(); - - fireEvent.click(okButton); - await expect(console.log).toHaveBeenCalledWith("8 was removed") - }) -}) + afterEach(cleanup); + + const friend = { + friend_profile_image: "", + friend_username: "animecody", + friend_bio: "DBZ all day bby", + friends_id: 8, + }; + const deleteUserMessage = `Are you sure you want to remove ${friend.friend_username} from your friends list?`; + const removeFriend = (id) => { + console.log(`${id} was removed`); + }; + + it("renders text & values from props", () => { + const { getByText, getAllByText } = render( + + ); + + const removeText = findFirstProp("Remove", getByText, getAllByText); + const bioText = findFirstProp("DBZ all day bby", getByText, getAllByText); + const usernameText = findFirstProp("animecody", getByText, getAllByText); + + expect(removeText).toBeInTheDocument(); + expect(bioText).toBeInTheDocument(); + expect(usernameText).toBeInTheDocument(); + }); + + it("remove onClick toggles modalon", async () => { + const { getByText, getAllByText } = render( + + ); + const removeText = findFirstProp("Remove", getByText, getAllByText); + + fireEvent.click(removeText); + + const delMessage = await waitFor(() => + getByText(new RegExp(deleteUserMessage, "i")) + ); + const okButton = getByText(/ok/i); + const cancelButton = getByText(/cancel/i); + + expect(delMessage).toBeVisible(); + expect(okButton).toBeInTheDocument(); + expect(cancelButton).toBeInTheDocument(); + }); + + it("modal cancel button onClick toggles modal off", async () => { + const { getByText, getAllByText } = render( + + ); + const removeText = findFirstProp("Remove", getByText, getAllByText); + + fireEvent.click(removeText); + + const delMessage = await waitFor(() => + getByText(new RegExp(deleteUserMessage, "i")) + ); + const cancelButton = getByText(/cancel/i); + const okButton = getByText(/ok/i); + + expect(delMessage).toBeVisible(); + expect(cancelButton).toBeInTheDocument(); + expect(okButton).toBeInTheDocument(); + + fireEvent.click(cancelButton); + + await waitFor(() => delMessage); + expect(cancelButton).not.toBeInTheDocument(); + expect(okButton).not.toBeInTheDocument(); + }); + + it("modal OK button runs remove function from props", async () => { + const { getByText, getAllByText } = render( + + ); + const removeText = findFirstProp("Remove", getByText, getAllByText); + console.log = jest.fn(); + + fireEvent.click(removeText); + + const delMessage = await waitFor(() => + getByText(new RegExp(deleteUserMessage, "i")) + ); + const cancelButton = getByText(/cancel/i); + const okButton = getByText(/ok/i); + + expect(delMessage).toBeVisible(); + expect(cancelButton).toBeInTheDocument(); + expect(okButton).toBeInTheDocument(); + + fireEvent.click(okButton); + await expect(console.log).toHaveBeenCalledWith("8 was removed"); + }); +}); diff --git a/src/components/users/FriendsComp/FriendsList.js b/src/components/users/FriendsComp/FriendsList.js index 6a07e7c..d571d12 100644 --- a/src/components/users/FriendsComp/FriendsList.js +++ b/src/components/users/FriendsComp/FriendsList.js @@ -14,7 +14,7 @@ export default function FriendsList(props) { const [itemLength, setItemLength] = useState(0); const [currentData, setCurrentData] = useState([]); let user = useSelector(({ user }) => user); - user = props.user ? props.user : user + user = props.user ? props.user : user; const dispatch = useDispatch(); const handlePageChange = (pageNumber) => { @@ -59,7 +59,9 @@ export default function FriendsList(props) { return user.friends.length != 0 ? (
-

{user.username}'s Friends

+

+ {user.username}'s Friends +

{currentData.map((friend) => { return ( diff --git a/src/components/users/FriendsComp/FriendsList.test.js b/src/components/users/FriendsComp/FriendsList.test.js new file mode 100644 index 0000000..53a4f31 --- /dev/null +++ b/src/components/users/FriendsComp/FriendsList.test.js @@ -0,0 +1,147 @@ +import React from "react"; +import renderer from "react-test-renderer"; +import configureStore from "redux-mock-store"; +import { Provider } from "react-redux"; +import thunk from "redux-thunk"; +import { + render, + fireEvent, + cleanup, + waitFor, + act, +} from "@testing-library/react"; +import "@testing-library/jest-dom/extend-expect"; +import FriendsList from "./FriendsList"; +import FriendOnList from "./FriendOnList"; + +jest.mock("../../../redux/actions/userActions"); +const mockStore = configureStore(); + +describe("FriendsList", () => { + let store; + let component; + let friendOnListcomponent; + + let friendsArray = [ + { + friend_profile_image: "", + friend_username: "animecody", + friend_bio: "DBZ all day bby", + friends_id: 8, + }, + { + friend_profile_image: "", + friend_username: "JDawg", + friend_bio: "Ask me about my pizza", + friends_id: 9, + }, + { + friend_profile_image: "", + friend_username: "Buddy", + friend_bio: "Pizza without cheese, sauce, and toppings is just bread", + friends_id: 10, + }, + ]; + + beforeEach(() => { + store = mockStore({ + user: { + username: "SteadyFreddie", + friends: [ + { + id: 1, + friend_profile_image: "image", + friend_username: "animecody", + friend_bio: "DBZ all day bby", + friends_id: 8, + }, + { + id: 2, + friend_profile_image: "image", + friend_username: "JDawg", + friends_bio: "Ask me about my pizza", + friend_id: 9, + }, + { + id: 3, + friend_profile_image: "image", + friend_username: "Buddy", + friend_bio: + "Pizza without cheese, sauce, and toppings is just bread", + friends_id: 10, + }, + ], + }, + }); + + store.dispatch = jest.fn(); + console.log(store.dispatch.mock, "mock"); + + component = renderer.create( + + + {/* */} + + ); + }); + // friendOnListcomponent = renderer.create( + // + + // + // ); + // console.log(friendOnListcomponent); + + it("expect length of friends to be 3", async () => { + let children = component.toJSON().children.map((children) => children); + console.log(children); + expect(children.length).toBe(3); + }); + + // const friends = [ + // { + // friend_profile_image: "", + // friend_username: "animecody", + // friend_bio: "DBZ all day bby", + // friends_id: 8, + // }, + // { + // friend_profile_image: "", + // friend_username: "JDawg", + // friend_bio: "Ask me about my pizza", + // friends_id: 9, + // }, + // { + // friend_profile_image: "", + // friend_username: "Buddy", + // friend_bio: "Pizza without cheese, sauce, and toppings is just bread", + // friends_id: 10, + // }, + // ]; + + // const removeFriend = (); + + // it("adds 2 + 2", () => { + // expect(2 + 2).toBe(5); + // }); + + // let newFriends = []; + // const removeFriend = (id) => { + // newFriends = friends.filter((keep) => { + // keep.id != id; + // }); + // }; + + // const deleteFriendModal = `Are you sure you want to remove ${friends[1].friend_username} from your friends list?`; + + // it("test initial friends length", () => { + // expect(friends.length).toBe(3); + // }); + // }); + + // test("Friendslist", async () => { + // const { getByTestId } = render(); + + // const friendsLIST = getByTestId("friendsListTestId"); + // expect(friendsLIST.children.length).toEqual(3); + // }); +}); diff --git a/src/components/users/promotions/UserPromos.js b/src/components/users/promotions/UserPromos.js index 394c22a..df9ee97 100644 --- a/src/components/users/promotions/UserPromos.js +++ b/src/components/users/promotions/UserPromos.js @@ -1,9 +1,11 @@ -import React, { useEffect } from "react"; +import React, { useEffect, useState } from "react"; import { useSelector, useDispatch } from "react-redux"; -import { Item, Label, Icon } from "semantic-ui-react"; +import { Item, Label, Icon, Button, Confirm } from "semantic-ui-react"; import Moment from "react-moment"; +import "../FriendsComp/FriendsList.css"; import { getUserPromos, + deleteUserPromo, locationByUser, } from "../../../redux/actions/userActions"; @@ -12,16 +14,22 @@ export default function UserPromos() { const savedPromos = useSelector(({ user }) => user.savedPromos); const location = useSelector((state) => state.location); const dispatch = useDispatch(); + const [modalVisibility, setModalVisibility] = useState(false); + + const removeSavedPromo = (id) => { + dispatch(deleteUserPromo(user, id)); + }; useEffect(() => { dispatch(getUserPromos(user.id)); - }, []); + }, [savedPromos.length]); return (

{user.username}'s Saved Promotions

{savedPromos.map((promotion) => { + console.log(promotion); return ( @@ -41,6 +49,32 @@ export default function UserPromos() { + + setModalVisibility(false)} + onConfirm={() => { + removeSavedPromo(promotion.id); + setModalVisibility(false); + }} + /> ); })} diff --git a/src/redux/actions/userActions.js b/src/redux/actions/userActions.js index 213434f..45d904c 100644 --- a/src/redux/actions/userActions.js +++ b/src/redux/actions/userActions.js @@ -189,7 +189,7 @@ export const userDeleteEvent = (id, user) => (dispatch) => { // Reviews export const reviewsByUser = (id) => (dispatch) => { - dispatch({type: types.USER_REVIEW_START, payload: true}) + dispatch({ type: types.USER_REVIEW_START, payload: true }); API.get(`/reviews/users/${id}`) .then((res) => { dispatch({ @@ -286,11 +286,25 @@ export const getUserPromos = (id) => (dispatch) => { export const addUserPromo = (user_id, promo_id) => (dispatch) => { let postData = { user_id, promo_id }; API.post("/savedPromos", postData) + .then((res) => {}) + .catch((err) => { + console.log(err); + }); +}; + +export const deleteUserPromo = (user, promo_id) => (dispatch) => { + dispatch({ type: types.DELETE_USER_PROMOS_START, payload: true }); + API.delete(`/savedPromos/${promo_id}`) .then((res) => { + let newUserPromo = user.savedPromos.filter((keep) => keep.id != promo_id); + dispatch({ + type: types.DELETE_USER_PROMOS_SUCCESS, + payload: newUserPromo, + }); }) .catch((err) => { - // Errors on actions need to be handeled some other way than - // console.log(err); + console.log(err); + dispatch({ type: types.DELETE_USER_PROMOS_FAIL, payload: false }); }); }; diff --git a/src/redux/reducers/userReducer.js b/src/redux/reducers/userReducer.js index 791aa4c..ab245db 100644 --- a/src/redux/reducers/userReducer.js +++ b/src/redux/reducers/userReducer.js @@ -23,6 +23,7 @@ export const userReducer = (state = initialState, { type, payload }) => { case types.GET_USER_FRIENDS_START: case types.DELETE_USER_FRIENDS_START: case types.ADD_USER_FRIEND_START: + case types.DELETE_USER_PROMOS_START: return { // TESTED ...state, @@ -146,6 +147,16 @@ export const userReducer = (state = initialState, { type, payload }) => { ...state, bio: payload, }; + case types.DELETE_USER_PROMOS_SUCCESS: + return { + ...state, + savedPromos: payload, + }; + case types.DELETE_USER_PROMOS_FAIL: + return { + ...state, + isLoading: payload, + }; default: // TESTED return state; diff --git a/src/redux/types/userTypes.js b/src/redux/types/userTypes.js index 71380ea..5cb53e0 100644 --- a/src/redux/types/userTypes.js +++ b/src/redux/types/userTypes.js @@ -66,3 +66,6 @@ export const ADD_USER_FRIEND_FAIL = "ADD_USER_FRIEND_FAIL"; //USER PROMOS export const GET_USER_PROMOS = "GET_USER_PROMOS"; export const ADD_USER_PROMOS = "ADD_USER_PROMOS"; +export const DELETE_USER_PROMOS_START = "DELETE_USER_PROMOS_START"; +export const DELETE_USER_PROMOS_SUCCESS = "DELETE_USER_PROMOS_SUCCESS"; +export const DELETE_USER_PROMOS_FAIL = "DELETE_USER_PROMOS_FAIL";