From 25c000c31d580d83654c642aa9561baa9588c439 Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Sun, 16 Aug 2020 09:30:07 -0700 Subject: [PATCH 01/28] =?UTF-8?q?=F0=9F=93=A6=20Bump=20Version=20-=20Bump?= =?UTF-8?q?=20version=20to=20v1.6.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6c16623..70cfa7d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "gh-jobs", - "version": "1.5.0", + "version": "1.6.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 08d0bcd..0818518 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gh-jobs", - "version": "1.5.0", + "version": "1.6.0", "description": "A MERN application bootstrapped with create-mern-application.", "main": "build/index.js", "scripts": { From e88efb833ef044cea3ca718540010bd5bdc81628 Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Sun, 16 Aug 2020 09:30:41 -0700 Subject: [PATCH 02/28] =?UTF-8?q?=F0=9F=93=9D=20CHANGELOG=20-=20Add=20v.1.?= =?UTF-8?q?6.0=20to=20CHANGELOG?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 823337a..2070699 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.6.0] - _Unreleased_ + +### Added + +### Changed + +### Removed + +### Fixed + ## [1.5.0] - 2020-08-15 ### ⏹️ Button Redesign From 068666fe9fc61da8f3b31df96edc8a01c3750e1b Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Sun, 16 Aug 2020 09:45:52 -0700 Subject: [PATCH 03/28] =?UTF-8?q?=F0=9F=99=88=20Hide=20Hidden=20Jobs=20in?= =?UTF-8?q?=20Search=20by=20Default=20#79=20-=20Modify=20'initializeApplic?= =?UTF-8?q?ation()'=20logic?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/client/redux/thunks.ts | 54 ++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/src/client/redux/thunks.ts b/src/client/redux/thunks.ts index ecd127f..bdb8d95 100644 --- a/src/client/redux/thunks.ts +++ b/src/client/redux/thunks.ts @@ -188,6 +188,8 @@ export const signup = (): AppThunk => async (dispatch, getState) => { export const initializeApplication = (): AppThunk => async (dispatch) => { try { dispatch(setIsLoading(true)); + + // * Reset State to Defaults dispatch(displayNotification("", "default")); dispatch(setError(null, null)); dispatch(setCurrentJobs([])); @@ -199,42 +201,48 @@ export const initializeApplication = (): AppThunk => async (dispatch) => { dispatch(setModalContent("")); dispatch(setModalTitle("")); - // * Establish Job Data - dispatch(setIsLoading(true)); - - const jobsResult = (await fetchServerData("/jobs", "GET")) as - | GetJobsErrorResponse - | GetJobsSuccessResponse; - - if (isError(jobsResult)) { - dispatch(displayNotification(jobsResult.error, "error")); - dispatch(setIsLoading(false)); - return; - } - - dispatch(setJobs(jobsResult)); - dispatch(setCurrentPage(1)); - dispatch(setTotalPages(Math.ceil(jobsResult.length / 5))); - dispatch(setCurrentJobs(jobsResult)); - // * Establish User Authentication const userResponse = await fetch("/user/me"); + let userId = ""; if (userResponse.status === 200) { + // * User is authenticated const user: ServerResponseUser = await userResponse.json(); - const nonHiddenJobs = jobsResult.filter( - (job: Job) => user.hiddenJobs.indexOf(job.id) < 0 - ); + userId = user._id; dispatch(setName(user.name)); dispatch(setEmail(user.email)); dispatch(setSavedJobs(user.savedJobs)); dispatch(setHiddenJobs(user.hiddenJobs)); dispatch(setIsLoggedIn(true)); - dispatch(setCurrentJobs(nonHiddenJobs)); - dispatch(setTotalPages(Math.ceil(nonHiddenJobs.length / 5))); } + + // * Establish Job Data + const jobsResult = (await fetchServerData( + "/jobs", + "POST", + JSON.stringify({ userId }) + )) as GetJobsErrorResponse | GetJobsSuccessResponse; + + if (isError(jobsResult)) { + dispatch(displayNotification(jobsResult.error, "error")); + dispatch(setIsLoading(false)); + return; + } + + // ? Needed? Or on BE? + // const nonHiddenJobs = jobsResult.filter( + // (job: Job) => user.hiddenJobs.indexOf(job.id) < 0 + // ); + + // dispatch(setCurrentJobs(nonHiddenJobs)); + // dispatch(setTotalPages(Math.ceil(nonHiddenJobs.length / 5))); + + dispatch(setJobs(jobsResult)); + dispatch(setCurrentPage(1)); + dispatch(setTotalPages(Math.ceil(jobsResult.length / 5))); + dispatch(setCurrentJobs(jobsResult)); dispatch(setIsLoading(false)); } catch (error) { console.error(error); From 12943bf137057104a1200db09ee142ed87a3d618 Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Mon, 17 Aug 2020 08:08:05 -0700 Subject: [PATCH 04/28] =?UTF-8?q?=F0=9F=99=88=20Hide=20Hidden=20Jobs=20in?= =?UTF-8?q?=20Search=20by=20Default=20#79=20-=20Adjust=20'JobController'?= =?UTF-8?q?=20for=20'/jobs'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/client/redux/thunks.ts | 2 + src/server/controllers/job.ts | 85 +++++++++++++++-------------------- src/server/util.ts | 34 ++++++++++++++ 3 files changed, 73 insertions(+), 48 deletions(-) diff --git a/src/client/redux/thunks.ts b/src/client/redux/thunks.ts index bdb8d95..44760c3 100644 --- a/src/client/redux/thunks.ts +++ b/src/client/redux/thunks.ts @@ -137,6 +137,8 @@ export const logIn = (): AppThunk => async (dispatch, getState) => { return; } + // TODO - Make call to get jobs (now they will be filtered) + dispatch(setIsLoggedIn(true)); dispatch(setEmail(response.email)); dispatch(setName(response.name)); diff --git a/src/server/controllers/job.ts b/src/server/controllers/job.ts index 0ef0e37..c012911 100644 --- a/src/server/controllers/job.ts +++ b/src/server/controllers/job.ts @@ -7,7 +7,7 @@ import path from "path"; import JobModel from "../models/Job"; -import { getAllJobsFromAPI, isError, unique } from "../util"; +import { unique, rehydrateJobsDB } from "../util"; import { GetJobsErrorResponse, @@ -15,8 +15,9 @@ import { Job, GetJobDetailsErrorResponse, GetJobDetailsSuccessResponse, - GitHubJob, + JobDocument, } from "../types"; +import User from "../models/User"; /** * Job Controller. @@ -29,40 +30,39 @@ class JobController { } public initializeRoutes(): void { - this.router.get( + this.router.post( "/jobs", async ( req: Request, res: Response ): Promise> => { try { - const currentJobs = await JobModel.find({}); + // * Get User Information + const userId: string = req.body.userId; + let user = null; + let hiddenJobs: string[] = []; + if (userId !== "") { + user = await User.findById(userId); + hiddenJobs = user.hiddenJobs; + } + + // * Get Job Information + let dbJobs: JobDocument[] = await JobModel.find({}); // * No Jobs exist in DB - if (currentJobs.length === 0) { - const result = await getAllJobsFromAPI(); + if (dbJobs.length === 0) { + const rehydrationResult = await rehydrateJobsDB(); - if (isError(result)) { - return res.status(500).send(result); + // TODO - Check for this in a different way + if (rehydrationResult !== true) { + return res.status(500).send(rehydrationResult); } - await Promise.all( - result.map(async (job: GitHubJob) => { - const newJobObject: Job = { - ...job, - listingDate: job.created_at, - }; - const newJob = new JobModel(newJobObject); - await newJob.save(); - return; - }) - ); - - const dbJobs = await JobModel.find({}); - return res.send(dbJobs); + // * Set dbJobs to new jobs + dbJobs = await JobModel.find({}); } else { - // * Jobs exist in DB - const { createdAt } = currentJobs[0]; + // * Jobs exist in DB, but we need to ensure they are not stale jobs (from yesterday) + const { createdAt } = dbJobs[0]; const isWithinToday = isWithinInterval(new Date(createdAt), { start: startOfToday(), @@ -71,35 +71,24 @@ class JobController { if (!isWithinToday) { // * Jobs are stale. Get new jobs. - const result = await getAllJobsFromAPI(); + const rehydration2Result = await rehydrateJobsDB(); - if (isError(result)) { - return res.status(500).send(result); + // TODO - Check for this in a different way + if (rehydration2Result !== true) { + return res.status(500).send(rehydration2Result); } - // * Drop the current database of Jobs - await JobModel.collection.drop(); - - // * Create new Job entries - await Promise.all( - result.map(async (job: GitHubJob) => { - const newJobObject: Job = { - ...job, - listingDate: job.created_at, - }; - const newJob = new JobModel(newJobObject); - await newJob.save(); - return; - }) - ); - - const dbJobs = await JobModel.find({}); - return res.send(dbJobs); - } else { - // * Jobs are fine, send that. - return res.send(currentJobs); + // * Set dbJobs to new jobs + dbJobs = await JobModel.find({}); } } + + // * Ensure that the user's hiddenJobs do not show in results + const filteredDBJobs: JobDocument[] = dbJobs.filter( + (jobDocument: JobDocument) => hiddenJobs.indexOf(jobDocument.id) < 0 + ); + + return res.send(filteredDBJobs); } catch (error) { if (process.env.NODE_ENV !== "test") { console.error(error); diff --git a/src/server/util.ts b/src/server/util.ts index d4f7942..eeff00b 100644 --- a/src/server/util.ts +++ b/src/server/util.ts @@ -1,9 +1,12 @@ import nfetch from "node-fetch"; +import JobModel from "./models/Job"; + import { GetJobsErrorResponse, GetJobsSuccessResponse, GitHubJob, + Job, } from "./types"; /** @@ -87,3 +90,34 @@ export const isError = ( // eslint-disable-next-line export const unique = (arr: any[]): any[] => [...new Set(arr)]; + +export const rehydrateJobsDB = async (): Promise< + GetJobsErrorResponse | true +> => { + try { + const result = await getAllJobsFromAPI(); + + if (isError(result)) { + return result; + } + // * Drop the current database of Jobs + await JobModel.collection.drop(); + + // * Create new Job entries + await Promise.all( + result.map(async (job: GitHubJob) => { + const newJobObject: Job = { + ...job, + listingDate: job.created_at, + }; + const newJob = new JobModel(newJobObject); + await newJob.save(); + return; + }) + ); + + return true; + } catch (error) { + console.error(error); + } +}; From ffa511c2afe2ed3afd990002f28f905c7e9fd0f6 Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Mon, 17 Aug 2020 08:19:23 -0700 Subject: [PATCH 05/28] =?UTF-8?q?=F0=9F=99=88=20Hide=20Hidden=20Jobs=20in?= =?UTF-8?q?=20Search=20by=20Default=20#79=20-=20FE=20-=20Add=20'id'=20to?= =?UTF-8?q?=20'UserState'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/client/redux/actionTypes.ts | 1 + src/client/redux/actions/user.ts | 6 ++++++ src/client/redux/reducers/user.ts | 3 +++ src/client/redux/thunks.ts | 9 +++++++-- src/client/types.ts | 1 + 5 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/client/redux/actionTypes.ts b/src/client/redux/actionTypes.ts index 7858d86..eba082d 100644 --- a/src/client/redux/actionTypes.ts +++ b/src/client/redux/actionTypes.ts @@ -24,6 +24,7 @@ export const SET_EDIT_NAME = "SET_EDIT_NAME"; export const SET_EMAIL = "SET_EMAIL"; export const SET_HIDDEN_JOBS = "SET_HIDDEN_JOBS"; export const SET_HIDDEN_JOBS_DETAILS = "SET_HIDDEN_JOBS_DETAILS"; +export const SET_ID = "SET_ID"; export const SET_IS_EDITING_PROFILE = "SET_IS_EDITING_PROFILE"; export const SET_IS_LOGGED_IN = "SET_IS_LOGGED_IN"; export const SET_NAME = "SET_NAME"; diff --git a/src/client/redux/actions/user.ts b/src/client/redux/actions/user.ts index 75ae5f8..979abdd 100644 --- a/src/client/redux/actions/user.ts +++ b/src/client/redux/actions/user.ts @@ -3,6 +3,7 @@ import { SET_EMAIL, SET_HIDDEN_JOBS, SET_HIDDEN_JOBS_DETAILS, + SET_ID, SET_IS_EDITING_PROFILE, SET_IS_LOGGED_IN, SET_NAME, @@ -38,6 +39,11 @@ export const setHiddenJobsDetails = (hiddenJobsDetails: Job[]): UserAction => ({ payload: { hiddenJobsDetails }, }); +export const setId = (id: string): UserAction => ({ + type: SET_ID, + payload: { id }, +}); + export const setIsEditingProfile = (isEditingProfile: boolean): UserAction => ({ type: SET_IS_EDITING_PROFILE, payload: { isEditingProfile }, diff --git a/src/client/redux/reducers/user.ts b/src/client/redux/reducers/user.ts index 5911427..92cd3cb 100644 --- a/src/client/redux/reducers/user.ts +++ b/src/client/redux/reducers/user.ts @@ -3,6 +3,7 @@ import { SET_EMAIL, SET_HIDDEN_JOBS, SET_HIDDEN_JOBS_DETAILS, + SET_ID, SET_IS_EDITING_PROFILE, SET_IS_LOGGED_IN, SET_NAME, @@ -23,6 +24,7 @@ export const initialState: UserState = { email: "", hiddenJobs: [], hiddenJobsDetails: [], + id: "", isEditingProfile: false, isLoggedIn: false, name: "", @@ -50,6 +52,7 @@ const reducer = (state = initialState, action: UserAction): UserState => { case SET_EMAIL: case SET_HIDDEN_JOBS: case SET_HIDDEN_JOBS_DETAILS: + case SET_ID: case SET_IS_EDITING_PROFILE: case SET_IS_LOGGED_IN: case SET_NAME: diff --git a/src/client/redux/thunks.ts b/src/client/redux/thunks.ts index 44760c3..8b9c2ec 100644 --- a/src/client/redux/thunks.ts +++ b/src/client/redux/thunks.ts @@ -30,6 +30,7 @@ import { setSavedJobsTotalPages, setHiddenJobs, setHiddenJobsDetails, + setId, } from "./actions/user"; import { fetchServerData, isError } from "../util"; @@ -142,6 +143,7 @@ export const logIn = (): AppThunk => async (dispatch, getState) => { dispatch(setIsLoggedIn(true)); dispatch(setEmail(response.email)); dispatch(setName(response.name)); + dispatch(setId(response._id)); dispatch(setSavedJobs(response.savedJobs)); dispatch(setHiddenJobs(response.hiddenJobs)); @@ -215,6 +217,7 @@ export const initializeApplication = (): AppThunk => async (dispatch) => { dispatch(setName(user.name)); dispatch(setEmail(user.email)); + dispatch(setId(userId)); dispatch(setSavedJobs(user.savedJobs)); dispatch(setHiddenJobs(user.hiddenJobs)); dispatch(setIsLoggedIn(true)); @@ -269,10 +272,11 @@ export const logOut = (): AppThunk => async (dispatch) => { return; } + dispatch(displayNotification("", "default")); dispatch(setConfirmPassword("")); dispatch(setEmail("")); - dispatch(displayNotification("", "default")); dispatch(setName("")); + dispatch(setId("")); dispatch(setPassword("")); dispatch(setSavedJobs([])); dispatch(setHiddenJobs([])); @@ -301,9 +305,10 @@ export const logOutAll = (): AppThunk => async (dispatch) => { } dispatch(setConfirmPassword("")); - dispatch(setEmail("")); dispatch(displayNotification("", "default")); + dispatch(setEmail("")); dispatch(setName("")); + dispatch(setId("")); dispatch(setPassword("")); dispatch(setSavedJobs([])); dispatch(setHiddenJobs([])); diff --git a/src/client/types.ts b/src/client/types.ts index dcd3753..2ab192a 100644 --- a/src/client/types.ts +++ b/src/client/types.ts @@ -295,6 +295,7 @@ export interface UserState { email: string; hiddenJobs: string[]; hiddenJobsDetails: Job[]; + id: string; isEditingProfile: boolean; isLoggedIn: false; name: string; From c2f84a47c01b1538f6eb6a2344c80a2c5e712d40 Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Mon, 17 Aug 2020 08:21:45 -0700 Subject: [PATCH 06/28] =?UTF-8?q?=F0=9F=99=88=20Hide=20Hidden=20Jobs=20in?= =?UTF-8?q?=20Search=20by=20Default=20#79=20-=20FE=20-=20Adjust=20thunk=20?= =?UTF-8?q?to=20send=20'userId'=20to=20'/jobs/search'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/client/redux/thunks.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/client/redux/thunks.ts b/src/client/redux/thunks.ts index 8b9c2ec..5762275 100644 --- a/src/client/redux/thunks.ts +++ b/src/client/redux/thunks.ts @@ -72,6 +72,7 @@ export const searchJobs = ( const state: RootState = getState(); const { contract, fullTime, locationSearch } = state.application; + const { id } = state.user; const locationsSearches = locationOptions.filter( (location: LocationOption) => location.value !== "" @@ -85,7 +86,7 @@ export const searchJobs = ( }); } - let url = `/jobs/search?full_time=${encodeURI( + let url = `/jobs/search?userId=${encodeURI(id)}&full_time=${encodeURI( fullTime.toString() )}&contract=${encodeURI(contract.toString())}&description=${encodeURI( search From c6df9aaa15ba7baf4958884f2a4df2e378af7e0e Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Mon, 17 Aug 2020 08:30:19 -0700 Subject: [PATCH 07/28] =?UTF-8?q?=F0=9F=99=88=20Hide=20Hidden=20Jobs=20in?= =?UTF-8?q?=20Search=20by=20Default=20#79=20-=20BE=20-=20Adjust=20'JobCont?= =?UTF-8?q?roller'=20for=20'/jobs/search'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/server/controllers/job.ts | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/server/controllers/job.ts b/src/server/controllers/job.ts index c012911..5f235dd 100644 --- a/src/server/controllers/job.ts +++ b/src/server/controllers/job.ts @@ -115,6 +115,7 @@ class JobController { location3, location4, location5, + userId, } = req.query; const isLocationSearch = @@ -159,8 +160,19 @@ class JobController { ); const uniqueResults: Job[] = unique(jobs); + let finalResults = uniqueResults; + + // * Filter by non-hidden jobs + if (userId) { + // * Get User Information + const user = await User.findById(userId); + const hiddenJobs: string[] = user.hiddenJobs; + finalResults = uniqueResults.filter( + (job: Job) => hiddenJobs.indexOf(job.id) < 0 + ); + } - return res.send(uniqueResults); + return res.send(finalResults); } // * Make Searches @@ -192,8 +204,19 @@ class JobController { ]; const uniqueResults: Job[] = unique(searchResults); + let finalResults = uniqueResults; + + // * Filter by non-hidden jobs + if (userId) { + // * Get User Information + const user = await User.findById(userId); + const hiddenJobs: string[] = user.hiddenJobs; + finalResults = uniqueResults.filter( + (job: Job) => hiddenJobs.indexOf(job.id) < 0 + ); + } - return res.send(uniqueResults); + return res.send(finalResults); } catch (error) { if (process.env.NODE_ENV !== "test") { console.error(error); From 252319566fd1ef3b066674085537536b113e6553 Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Mon, 17 Aug 2020 08:32:17 -0700 Subject: [PATCH 08/28] =?UTF-8?q?=F0=9F=99=88=20Hide=20Hidden=20Jobs=20in?= =?UTF-8?q?=20Search=20by=20Default=20#79=20-=20Adjust=20'/jobs'=20stub?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cypress/integration/applicationError.spec.js | 2 +- cypress/integration/details.spec.js | 2 +- cypress/integration/directPageAccess.spec.js | 2 +- cypress/integration/hiddenJobs.spec.js | 4 ++-- cypress/integration/login.spec.js | 4 ++-- cypress/integration/notification.spec.js | 2 +- cypress/integration/optionsPanel.spec.js | 2 +- cypress/integration/pagination.spec.js | 10 +++++----- cypress/integration/profile.spec.js | 2 +- cypress/integration/savedJobs.spec.js | 4 ++-- cypress/integration/search.spec.js | 6 +++--- cypress/integration/signup.spec.js | 4 ++-- 12 files changed, 22 insertions(+), 22 deletions(-) diff --git a/cypress/integration/applicationError.spec.js b/cypress/integration/applicationError.spec.js index ad19df7..9066d35 100644 --- a/cypress/integration/applicationError.spec.js +++ b/cypress/integration/applicationError.spec.js @@ -10,7 +10,7 @@ context("Application Error", () => { cy.fixture("jobs50").then((jobsJson) => { cy.server(); cy.route({ - method: "GET", + method: "POST", url: "/jobs", status: 200, response: jobsJson, diff --git a/cypress/integration/details.spec.js b/cypress/integration/details.spec.js index a209950..ee43985 100644 --- a/cypress/integration/details.spec.js +++ b/cypress/integration/details.spec.js @@ -6,7 +6,7 @@ context("Details", () => { cy.fixture("jobDetails").then((jobDetails) => { cy.server(); cy.route({ - method: "GET", + method: "POST", url: "/jobs", status: 200, response: jobsJson, diff --git a/cypress/integration/directPageAccess.spec.js b/cypress/integration/directPageAccess.spec.js index 3437edb..38cb4a8 100644 --- a/cypress/integration/directPageAccess.spec.js +++ b/cypress/integration/directPageAccess.spec.js @@ -5,7 +5,7 @@ context("Details", () => { cy.fixture("jobs50").then((jobsJson) => { cy.server(); cy.route({ - method: "GET", + method: "POST", url: "/jobs", status: 200, response: jobsJson, diff --git a/cypress/integration/hiddenJobs.spec.js b/cypress/integration/hiddenJobs.spec.js index fc83232..08c5d6b 100644 --- a/cypress/integration/hiddenJobs.spec.js +++ b/cypress/integration/hiddenJobs.spec.js @@ -6,7 +6,7 @@ context("Hidden Jobs", () => { cy.fixture("hiddenDetails").then((hiddenDetailsJson) => { cy.server(); cy.route({ - method: "GET", + method: "POST", url: "/jobs", status: 200, response: jobsJson, @@ -230,7 +230,7 @@ context("Hidden Jobs - No Results", () => { cy.fixture("jobs50").then((jobsJson) => { cy.server(); cy.route({ - method: "GET", + method: "POST", url: "/jobs", status: 200, response: jobsJson, diff --git a/cypress/integration/login.spec.js b/cypress/integration/login.spec.js index fae6a31..50901bb 100644 --- a/cypress/integration/login.spec.js +++ b/cypress/integration/login.spec.js @@ -6,7 +6,7 @@ context("Login - Success", () => { cy.fixture("login").then((loginJson) => { cy.server(); cy.route({ - method: "GET", + method: "POST", url: "/jobs", status: 200, response: jobsJson, @@ -48,7 +48,7 @@ context("Login - Error", () => { cy.fixture("jobs50").then((jobsJson) => { cy.server(); cy.route({ - method: "GET", + method: "POST", url: "/jobs", status: 200, response: jobsJson, diff --git a/cypress/integration/notification.spec.js b/cypress/integration/notification.spec.js index 9405d86..599b8f6 100644 --- a/cypress/integration/notification.spec.js +++ b/cypress/integration/notification.spec.js @@ -5,7 +5,7 @@ context("Notification", () => { cy.fixture("jobs50").then((jobsJson) => { cy.server(); cy.route({ - method: "GET", + method: "POST", url: "/jobs", status: 200, response: jobsJson, diff --git a/cypress/integration/optionsPanel.spec.js b/cypress/integration/optionsPanel.spec.js index 3d60ecb..292b54e 100644 --- a/cypress/integration/optionsPanel.spec.js +++ b/cypress/integration/optionsPanel.spec.js @@ -8,7 +8,7 @@ context("Options Panel", () => { cy.fixture("jobsSearch3").then((jobsSearch3Json) => { cy.server(); cy.route({ - method: "GET", + method: "POST", url: "/jobs", status: 200, response: jobsJson, diff --git a/cypress/integration/pagination.spec.js b/cypress/integration/pagination.spec.js index 71f7856..9a001da 100644 --- a/cypress/integration/pagination.spec.js +++ b/cypress/integration/pagination.spec.js @@ -5,7 +5,7 @@ context("Pagination", () => { cy.fixture("jobs50").then((jobsJson) => { cy.server(); cy.route({ - method: "GET", + method: "POST", url: "/jobs", status: 200, response: jobsJson, @@ -258,7 +258,7 @@ context("Pagination - 1 Page", () => { cy.fixture("jobs5").then((jobsJson) => { cy.server(); cy.route({ - method: "GET", + method: "POST", url: "/jobs", status: 200, response: jobsJson, @@ -296,7 +296,7 @@ context("Pagination - 2 Pages", () => { cy.fixture("jobs10").then((jobsJson) => { cy.server(); cy.route({ - method: "GET", + method: "POST", url: "/jobs", status: 200, response: jobsJson, @@ -334,7 +334,7 @@ context("Pagination - 3 Pages", () => { cy.fixture("jobs15").then((jobsJson) => { cy.server(); cy.route({ - method: "GET", + method: "POST", url: "/jobs", status: 200, response: jobsJson, @@ -374,7 +374,7 @@ context("Pagination - 4 Pages", () => { cy.fixture("jobs20").then((jobsJson) => { cy.server(); cy.route({ - method: "GET", + method: "POST", url: "/jobs", status: 200, response: jobsJson, diff --git a/cypress/integration/profile.spec.js b/cypress/integration/profile.spec.js index 145fe49..ec6eec3 100644 --- a/cypress/integration/profile.spec.js +++ b/cypress/integration/profile.spec.js @@ -5,7 +5,7 @@ context("Profile", () => { cy.fixture("jobs50").then((jobsJson) => { cy.server(); cy.route({ - method: "GET", + method: "POST", url: "/jobs", status: 200, response: jobsJson, diff --git a/cypress/integration/savedJobs.spec.js b/cypress/integration/savedJobs.spec.js index a31070a..a10df3f 100644 --- a/cypress/integration/savedJobs.spec.js +++ b/cypress/integration/savedJobs.spec.js @@ -6,7 +6,7 @@ context("Saved Jobs", () => { cy.fixture("savedDetails").then((savedDetailsJson) => { cy.server(); cy.route({ - method: "GET", + method: "POST", url: "/jobs", status: 200, response: jobsJson, @@ -145,7 +145,7 @@ context("Saved Jobs - No Results", () => { cy.fixture("jobs50").then((jobsJson) => { cy.server(); cy.route({ - method: "GET", + method: "POST", url: "/jobs", status: 200, response: jobsJson, diff --git a/cypress/integration/search.spec.js b/cypress/integration/search.spec.js index 5ef1957..d9f9faf 100644 --- a/cypress/integration/search.spec.js +++ b/cypress/integration/search.spec.js @@ -6,7 +6,7 @@ context("Search", () => { cy.fixture("jobsSearch1").then((searchJson) => { cy.server(); cy.route({ - method: "GET", + method: "POST", url: "/jobs", status: 200, response: jobsJson, @@ -56,7 +56,7 @@ context("Search - No Results", () => { beforeEach(() => { cy.server(); cy.route({ - method: "GET", + method: "POST", url: "/jobs", status: 200, response: [], @@ -88,7 +88,7 @@ context("Search - Loading Indicator", () => { cy.fixture("jobs50").then((jobsJson) => { cy.server(); cy.route({ - method: "GET", + method: "POST", url: "/jobs", status: 200, response: jobsJson, diff --git a/cypress/integration/signup.spec.js b/cypress/integration/signup.spec.js index 88de989..0d7e931 100644 --- a/cypress/integration/signup.spec.js +++ b/cypress/integration/signup.spec.js @@ -6,7 +6,7 @@ context("Signup - Success", () => { cy.fixture("signup").then((signupJson) => { cy.server(); cy.route({ - method: "GET", + method: "POST", url: "/jobs", status: 200, response: jobsJson, @@ -53,7 +53,7 @@ context("Signup - Error", () => { cy.fixture("jobs50").then((jobsJson) => { cy.server(); cy.route({ - method: "GET", + method: "POST", url: "/jobs", status: 200, response: jobsJson, From 3a071187f5d91a12b270acdbf9a9afd4e0417c41 Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Mon, 17 Aug 2020 08:35:38 -0700 Subject: [PATCH 09/28] =?UTF-8?q?=F0=9F=99=88=20Hide=20Hidden=20Jobs=20in?= =?UTF-8?q?=20Search=20by=20Default=20#79=20-=20Adjust=20'/jobs/search'=20?= =?UTF-8?q?stub?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cypress/integration/applicationError.spec.js | 2 +- cypress/integration/optionsPanel.spec.js | 12 ++++++------ cypress/integration/pagination.spec.js | 2 +- cypress/integration/search.spec.js | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/cypress/integration/applicationError.spec.js b/cypress/integration/applicationError.spec.js index 9066d35..c03f2ef 100644 --- a/cypress/integration/applicationError.spec.js +++ b/cypress/integration/applicationError.spec.js @@ -18,7 +18,7 @@ context("Application Error", () => { }); cy.route({ method: "GET", - url: "/jobs/search?full_time=false&contract=false&description=react", + url: "/jobs/search?userId=&full_time=false&contract=false&description=react", status: 200, response: {}, delay: 1000, diff --git a/cypress/integration/optionsPanel.spec.js b/cypress/integration/optionsPanel.spec.js index 292b54e..2f253cb 100644 --- a/cypress/integration/optionsPanel.spec.js +++ b/cypress/integration/optionsPanel.spec.js @@ -16,7 +16,7 @@ context("Options Panel", () => { cy.route({ method: "GET", url: - "/jobs/search?full_time=true&contract=false&description=developer", + "/jobs/search?userId=&full_time=true&contract=false&description=developer", status: 200, delay: 1000, response: jobsSearch2Json, @@ -24,7 +24,7 @@ context("Options Panel", () => { cy.route({ method: "GET", url: - "/jobs/search?full_time=false&contract=false&description=&location1=Los Angeles", + "/jobs/search?userId=&full_time=false&contract=false&description=&location1=Los Angeles", status: 200, delay: 1000, response: jobsSearch1Json, @@ -32,7 +32,7 @@ context("Options Panel", () => { cy.route({ method: "GET", url: - "/jobs/search?full_time=false&contract=false&description=&location1=Chicago", + "/jobs/search?userId=&full_time=false&contract=false&description=&location1=Chicago", status: 200, delay: 1000, response: jobsSearch1Json, @@ -40,7 +40,7 @@ context("Options Panel", () => { cy.route({ method: "GET", url: - "/jobs/search?full_time=false&contract=false&description=developer", + "/jobs/search?userId=&full_time=false&contract=false&description=developer", status: 200, delay: 1000, response: jobsSearch1Json, @@ -48,7 +48,7 @@ context("Options Panel", () => { cy.route({ method: "GET", url: - "/jobs/search?full_time=false&contract=false&description=&location1=Los Angeles", + "/jobs/search?userId=&full_time=false&contract=false&description=&location1=Los Angeles", status: 200, delay: 1000, response: jobsSearch1Json, @@ -56,7 +56,7 @@ context("Options Panel", () => { cy.route({ method: "GET", url: - "/jobs/search?full_time=false&contract=true&description=developer", + "/jobs/search?userId=&full_time=false&contract=true&description=developer", status: 200, delay: 1000, response: jobsSearch3Json, diff --git a/cypress/integration/pagination.spec.js b/cypress/integration/pagination.spec.js index 9a001da..fb1c734 100644 --- a/cypress/integration/pagination.spec.js +++ b/cypress/integration/pagination.spec.js @@ -213,7 +213,7 @@ context("Pagination", () => { cy.server(); cy.route({ method: "GET", - url: "/jobs/search?full_time=false&contract=false&description=&location1=Chicago", + url: "/jobs/search?userId=&full_time=false&contract=false&description=&location1=Chicago", status: 200, response: jobsJson, }); diff --git a/cypress/integration/search.spec.js b/cypress/integration/search.spec.js index d9f9faf..9c03c53 100644 --- a/cypress/integration/search.spec.js +++ b/cypress/integration/search.spec.js @@ -14,7 +14,7 @@ context("Search", () => { }); cy.route({ method: "GET", - url: "/jobs/search?full_time=false&contract=false&description=developer", + url: "/jobs/search?userId=&full_time=false&contract=false&description=developer", status: 200, response: searchJson, delay: 1000, @@ -64,7 +64,7 @@ context("Search - No Results", () => { }); cy.route({ method: "GET", - url: "/jobs/search?full_time=false&contract=false&description=developer", + url: "/jobs/search?userId=&full_time=false&contract=false&description=developer", status: 200, response: [], delay: 1000, From b57947ad28d66aec22976348c51c913145e03de2 Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Mon, 17 Aug 2020 08:43:27 -0700 Subject: [PATCH 10/28] =?UTF-8?q?=F0=9F=99=88=20Hide=20Hidden=20Jobs=20in?= =?UTF-8?q?=20Search=20by=20Default=20#79=20-=20Adjust=20thunk=20to=20get?= =?UTF-8?q?=20jobs=20on=20login?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/client/redux/thunks.ts | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/client/redux/thunks.ts b/src/client/redux/thunks.ts index 5762275..192a10f 100644 --- a/src/client/redux/thunks.ts +++ b/src/client/redux/thunks.ts @@ -139,9 +139,22 @@ export const logIn = (): AppThunk => async (dispatch, getState) => { return; } - // TODO - Make call to get jobs (now they will be filtered) + // * Establish Job Data + const jobsResult = (await fetchServerData( + "/jobs", + "POST", + JSON.stringify({ userId: response._id }) + )) as GetJobsErrorResponse | GetJobsSuccessResponse; + + if (isError(jobsResult)) { + dispatch(displayNotification(jobsResult.error, "error")); + dispatch(setIsLoading(false)); + return; + } dispatch(setIsLoggedIn(true)); + dispatch(setCurrentJobs(jobsResult)); + dispatch(setTotalPages(Math.ceil(jobsResult.length / 5))); dispatch(setEmail(response.email)); dispatch(setName(response.name)); dispatch(setId(response._id)); @@ -237,14 +250,6 @@ export const initializeApplication = (): AppThunk => async (dispatch) => { return; } - // ? Needed? Or on BE? - // const nonHiddenJobs = jobsResult.filter( - // (job: Job) => user.hiddenJobs.indexOf(job.id) < 0 - // ); - - // dispatch(setCurrentJobs(nonHiddenJobs)); - // dispatch(setTotalPages(Math.ceil(nonHiddenJobs.length / 5))); - dispatch(setJobs(jobsResult)); dispatch(setCurrentPage(1)); dispatch(setTotalPages(Math.ceil(jobsResult.length / 5))); From 962420d3a87f8d3520f5d5de69eeb48367639764 Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Mon, 17 Aug 2020 08:51:39 -0700 Subject: [PATCH 11/28] =?UTF-8?q?=F0=9F=99=88=20Hide=20Hidden=20Jobs=20in?= =?UTF-8?q?=20Search=20by=20Default=20#79=20-=20Add=20call=20to=20get=20jo?= =?UTF-8?q?bs=20on=20Log=20Out=20and=20Log=20Out=20All?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/client/redux/thunks.ts | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/client/redux/thunks.ts b/src/client/redux/thunks.ts index 192a10f..97001ac 100644 --- a/src/client/redux/thunks.ts +++ b/src/client/redux/thunks.ts @@ -278,7 +278,22 @@ export const logOut = (): AppThunk => async (dispatch) => { return; } + // * Establish Job Data + const jobsResult = (await fetchServerData( + "/jobs", + "POST", + JSON.stringify({ userId: "" }) + )) as GetJobsErrorResponse | GetJobsSuccessResponse; + + if (isError(jobsResult)) { + dispatch(displayNotification(jobsResult.error, "error")); + dispatch(setIsLoading(false)); + return; + } + dispatch(displayNotification("", "default")); + dispatch(setCurrentJobs(jobsResult)); + dispatch(setTotalPages(Math.ceil(jobsResult.length / 5))); dispatch(setConfirmPassword("")); dispatch(setEmail("")); dispatch(setName("")); @@ -310,8 +325,23 @@ export const logOutAll = (): AppThunk => async (dispatch) => { return; } + // * Establish Job Data + const jobsResult = (await fetchServerData( + "/jobs", + "POST", + JSON.stringify({ userId: "" }) + )) as GetJobsErrorResponse | GetJobsSuccessResponse; + + if (isError(jobsResult)) { + dispatch(displayNotification(jobsResult.error, "error")); + dispatch(setIsLoading(false)); + return; + } + dispatch(setConfirmPassword("")); dispatch(displayNotification("", "default")); + dispatch(setCurrentJobs(jobsResult)); + dispatch(setTotalPages(Math.ceil(jobsResult.length / 5))); dispatch(setEmail("")); dispatch(setName("")); dispatch(setId("")); From 0378229281c22c869694bb3a12732f837af88ff2 Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Mon, 17 Aug 2020 09:07:56 -0700 Subject: [PATCH 12/28] =?UTF-8?q?=F0=9F=99=88=20Hide=20Hidden=20Jobs=20in?= =?UTF-8?q?=20Search=20by=20Default=20#79=20-=20Fix=20Test=20for=20HiddenJ?= =?UTF-8?q?obs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cypress/integration/hiddenJobs.spec.js | 39 ++++++++++++++++---------- cypress/integration/jobDetails.json | 0 2 files changed, 24 insertions(+), 15 deletions(-) create mode 100644 cypress/integration/jobDetails.json diff --git a/cypress/integration/hiddenJobs.spec.js b/cypress/integration/hiddenJobs.spec.js index 08c5d6b..06ca798 100644 --- a/cypress/integration/hiddenJobs.spec.js +++ b/cypress/integration/hiddenJobs.spec.js @@ -4,20 +4,29 @@ context("Hidden Jobs", () => { beforeEach(() => { cy.fixture("jobs50").then((jobsJson) => { cy.fixture("hiddenDetails").then((hiddenDetailsJson) => { - cy.server(); - cy.route({ - method: "POST", - url: "/jobs", - status: 200, - response: jobsJson, - delay: 1000, - }); - cy.route({ - method: "GET", - url: "/user/hiddenJobsDetails", - status: 200, - response: hiddenDetailsJson, - delay: 1000, + cy.fixture("jobDetails").then((jobDetailsJson) => { + cy.server(); + cy.route({ + method: "POST", + url: "/jobs", + status: 200, + response: jobsJson, + delay: 1000, + }); + cy.route({ + method: "GET", + url: "/user/hiddenJobsDetails", + status: 200, + response: hiddenDetailsJson, + delay: 1000, + }); + cy.route({ + method: "GET", + url: "/jobs/f1884b46-ecb4-473c-81f5-08d9bf2ab3bb", + status: 200, + response: jobDetailsJson, + delay: 1000, + }); }); }); }); @@ -254,7 +263,7 @@ context("Hidden Jobs - No Results", () => { cy.get("#nav-profile").click(); cy.get("#view-hidden-jobs").click(); - assert.equal(cy.state("requests").length, 3); + assert.equal(cy.state("requests").length, 4); }); it("Should display correct text", () => { diff --git a/cypress/integration/jobDetails.json b/cypress/integration/jobDetails.json new file mode 100644 index 0000000..e69de29 From df275033b3ab01368486f6b4007f9a90484e720e Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Mon, 17 Aug 2020 09:13:06 -0700 Subject: [PATCH 13/28] =?UTF-8?q?=F0=9F=99=88=20Hide=20Hidden=20Jobs=20in?= =?UTF-8?q?=20Search=20by=20Default=20#79=20-=20Fix=20Test=20for=20Saved?= =?UTF-8?q?=20Jobs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cypress/integration/savedJobs.spec.js | 39 ++++++++++++++++----------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/cypress/integration/savedJobs.spec.js b/cypress/integration/savedJobs.spec.js index a10df3f..108147e 100644 --- a/cypress/integration/savedJobs.spec.js +++ b/cypress/integration/savedJobs.spec.js @@ -4,20 +4,29 @@ context("Saved Jobs", () => { beforeEach(() => { cy.fixture("jobs50").then((jobsJson) => { cy.fixture("savedDetails").then((savedDetailsJson) => { - cy.server(); - cy.route({ - method: "POST", - url: "/jobs", - status: 200, - response: jobsJson, - delay: 1000, - }); - cy.route({ - method: "GET", - url: "/user/savedJobsDetails", - status: 200, - response: savedDetailsJson, - delay: 1000, + cy.fixture("jobDetails").then((jobDetailsJson) => { + cy.server(); + cy.route({ + method: "POST", + url: "/jobs", + status: 200, + response: jobsJson, + delay: 1000, + }); + cy.route({ + method: "GET", + url: "/user/savedJobsDetails", + status: 200, + response: savedDetailsJson, + delay: 1000, + }); + cy.route({ + method: "GET", + url: "/jobs/f1884b46-ecb4-473c-81f5-08d9bf2ab3bb", + status: 200, + response: jobDetailsJson, + delay: 1000, + }); }); }); }); @@ -169,7 +178,7 @@ context("Saved Jobs - No Results", () => { cy.get("#nav-profile").click(); cy.get("#view-saved-jobs").click(); - assert.equal(cy.state("requests").length, 3); + assert.equal(cy.state("requests").length, 4); }); it("Should display correct text", () => { From 7bbd78dbfa6a17fa72ece83aba21ecba4f5cf9d9 Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Mon, 17 Aug 2020 09:27:54 -0700 Subject: [PATCH 14/28] =?UTF-8?q?=F0=9F=99=88=20Hide=20Hidden=20Jobs=20in?= =?UTF-8?q?=20Search=20by=20Default=20#79=20-=20Fix=20Test=20for=20Direct?= =?UTF-8?q?=20Page=20Access?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cypress/integration/directPageAccess.spec.js | 25 +++++++++++++------- cypress/integration/jobDetails.json | 0 2 files changed, 17 insertions(+), 8 deletions(-) delete mode 100644 cypress/integration/jobDetails.json diff --git a/cypress/integration/directPageAccess.spec.js b/cypress/integration/directPageAccess.spec.js index 38cb4a8..8f1d065 100644 --- a/cypress/integration/directPageAccess.spec.js +++ b/cypress/integration/directPageAccess.spec.js @@ -1,15 +1,24 @@ /// -context("Details", () => { +context("Direct Page Access", () => { beforeEach(() => { cy.fixture("jobs50").then((jobsJson) => { - cy.server(); - cy.route({ - method: "POST", - url: "/jobs", - status: 200, - response: jobsJson, - delay: 1000, + cy.fixture("jobDetails").then((jobDetailsJson) => { + cy.server(); + cy.route({ + method: "POST", + url: "/jobs", + status: 200, + response: jobsJson, + delay: 1000, + }); + cy.route({ + method: "GET", + url: "/jobs/f1884b46-ecb4-473c-81f5-08d9bf2ab3bb", + status: 200, + response: jobDetailsJson, + delay: 1000, + }); }); }); }); diff --git a/cypress/integration/jobDetails.json b/cypress/integration/jobDetails.json deleted file mode 100644 index e69de29..0000000 From 5a67792b51f89fa38620a496d88972b061ee3383 Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Mon, 17 Aug 2020 09:28:03 -0700 Subject: [PATCH 15/28] =?UTF-8?q?=F0=9F=99=88=20Hide=20Hidden=20Jobs=20in?= =?UTF-8?q?=20Search=20by=20Default=20#79=20-=20Add=20stringified=20loggin?= =?UTF-8?q?g=20for=20host?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/server/app.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/server/app.ts b/src/server/app.ts index 4062a38..8c10af4 100644 --- a/src/server/app.ts +++ b/src/server/app.ts @@ -85,10 +85,16 @@ class App { // ? Use this.app.all? console.log( - chalk.blueBright.inverse({ - host: req.headers.host, - referrer: req.headers.referer, - }) + chalk.blueBright.inverse( + JSON.stringify( + { + host: req.headers.host, + referrer: req.headers.referer, + }, + null, + 2 + ) + ) ); res.sendFile(path.join(__dirname, "../dist/index.html")); }); From a47b89e6e316935b08f410b5e3ceee76ae0c1371 Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Mon, 17 Aug 2020 09:44:21 -0700 Subject: [PATCH 16/28] =?UTF-8?q?=F0=9F=99=88=20Hide=20Hidden=20Jobs=20in?= =?UTF-8?q?=20Search=20by=20Default=20#79=20-=20Add=20test=20cases?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cypress/integration/hiddenJobs.spec.js | 23 +++++++++++++++++++ cypress/integration/search.spec.js | 31 ++++++++++++++++++++++++-- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/cypress/integration/hiddenJobs.spec.js b/cypress/integration/hiddenJobs.spec.js index 06ca798..4ff92f8 100644 --- a/cypress/integration/hiddenJobs.spec.js +++ b/cypress/integration/hiddenJobs.spec.js @@ -232,6 +232,29 @@ context("Hidden Jobs", () => { cy.get("#show-job-72de09f2-5bc6-489f-be90-3d38e505e20a").click(); cy.get("#show-job-cc20d9f2-0102-4785-8253-66093d3ca5c0").click(); }); + + // ! Unable to do with current implementation + // * If you don't stub it, the real db may not contain that job listing anymore + // * If you do stub it, you can't conditionally send a smaller list of jobs each time it hits /user/hiddenJobDetails + it.skip("Should not display hidden jobs in currentJobs", () => { + // * Hide a job + cy.get("#hide-job-f1884b46-ecb4-473c-81f5-08d9bf2ab3bb").click(); + // * Log User out + cy.get("#nav-profile").click(); + cy.get("#settings").click(); + cy.get("#log-out").click(); + + cy.get("#f1884b46-ecb4-473c-81f5-08d9bf2ab3bb").should("exist"); + + // * Log In + cy.get("#nav-login").click(); + cy.get("#email").type("bobtest@email.com"); + cy.get("#password").type("Red123456!!!"); + cy.get("#log-in").click(); + cy.wait(500); + + cy.get("#f1884b46-ecb4-473c-81f5-08d9bf2ab3bb").should("not.exist"); + }); }); context("Hidden Jobs - No Results", () => { diff --git a/cypress/integration/search.spec.js b/cypress/integration/search.spec.js index 9c03c53..9ed1673 100644 --- a/cypress/integration/search.spec.js +++ b/cypress/integration/search.spec.js @@ -14,7 +14,8 @@ context("Search", () => { }); cy.route({ method: "GET", - url: "/jobs/search?userId=&full_time=false&contract=false&description=developer", + url: + "/jobs/search?userId=&full_time=false&contract=false&description=developer", status: 200, response: searchJson, delay: 1000, @@ -50,6 +51,31 @@ context("Search", () => { cy.get("#search").type("{enter}"); cy.get('[data-cy="orbit-container"]').should("be.visible"); }); + + // ! Unable to do with current implementation + // * If you don't stub it, the real db may not contain that job listing anymore + // * If you do stub it, you can't conditionally send a smaller list of jobs each time it hits /user/hiddenJobDetails + it.skip("Should not display hidden jobs in currentJobs on search", () => { + // * Hide a job + cy.get("#hide-job-f1884b46-ecb4-473c-81f5-08d9bf2ab3bb").click(); + // * Log User out + cy.get("#nav-profile").click(); + cy.get("#settings").click(); + cy.get("#log-out").click(); + + cy.get("#f1884b46-ecb4-473c-81f5-08d9bf2ab3bb").should("exist"); + + // * Log In + cy.get("#nav-login").click(); + cy.get("#email").type("bobtest@email.com"); + cy.get("#password").type("Red123456!!!"); + cy.get("#log-in").click(); + cy.wait(500); + + cy.get("#f1884b46-ecb4-473c-81f5-08d9bf2ab3bb").should("not.exist"); + + // * Do search + }); }); context("Search - No Results", () => { @@ -64,7 +90,8 @@ context("Search - No Results", () => { }); cy.route({ method: "GET", - url: "/jobs/search?userId=&full_time=false&contract=false&description=developer", + url: + "/jobs/search?userId=&full_time=false&contract=false&description=developer", status: 200, response: [], delay: 1000, From 4d44ccb77e85aa236fe062b2a4b19168a27dd55c Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Mon, 17 Aug 2020 09:56:54 -0700 Subject: [PATCH 17/28] =?UTF-8?q?=E2=9C=8F=EF=B8=8F=20Single=20`ErrorRespo?= =?UTF-8?q?nse`=20Type=20#88=20-=20BE=20-=20Adjust=20Types?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/server/controllers/job.ts | 9 ++++----- src/server/controllers/user.ts | 23 ++++++----------------- src/server/types.ts | 18 +----------------- src/server/util.ts | 19 ++++++------------- 4 files changed, 17 insertions(+), 52 deletions(-) diff --git a/src/server/controllers/job.ts b/src/server/controllers/job.ts index 5f235dd..073a76d 100644 --- a/src/server/controllers/job.ts +++ b/src/server/controllers/job.ts @@ -10,10 +10,9 @@ import JobModel from "../models/Job"; import { unique, rehydrateJobsDB } from "../util"; import { - GetJobsErrorResponse, + ErrorResponse, GetJobsSuccessResponse, Job, - GetJobDetailsErrorResponse, GetJobDetailsSuccessResponse, JobDocument, } from "../types"; @@ -35,7 +34,7 @@ class JobController { async ( req: Request, res: Response - ): Promise> => { + ): Promise> => { try { // * Get User Information const userId: string = req.body.userId; @@ -104,7 +103,7 @@ class JobController { async ( req: Request, res: Response - ): Promise> => { + ): Promise> => { try { const { contract, @@ -232,7 +231,7 @@ class JobController { req: Request, res: Response ): Promise | void> => { if (!req.headers.referer) { return res.sendFile(path.join(__dirname, "../../dist/index.html")); diff --git a/src/server/controllers/user.ts b/src/server/controllers/user.ts index e4e006d..2218e66 100644 --- a/src/server/controllers/user.ts +++ b/src/server/controllers/user.ts @@ -12,15 +12,13 @@ import { AuthenticatedRequest, EditHiddenJobsMethod, EditSavedJobsMethod, - GetHiddenJobsDetailsErrorResponse, + ErrorResponse, GetHiddenJobsDetailsSuccessResponse, - GetSavedJobsDetailsErrorResponse, GetSavedJobsDetailsSuccessResponse, - PatchSavedJobErrorResponse, + Job, PatchSavedJobSuccessResponse, Token, UserDocument, - Job, } from "../types"; /** @@ -216,9 +214,7 @@ class UserController { async ( req: AuthenticatedRequest, res: Response - ): Promise< - Response - > => { + ): Promise> => { try { const method: EditSavedJobsMethod = req.body.method; const id: string = req.body.id; @@ -259,9 +255,7 @@ class UserController { async ( req: AuthenticatedRequest, res: Response - ): Promise< - Response - > => { + ): Promise> => { try { const method: EditHiddenJobsMethod = req.body.method; const id: string = req.body.id; @@ -303,9 +297,7 @@ class UserController { req: AuthenticatedRequest, res: Response ): Promise< - Response< - GetSavedJobsDetailsErrorResponse | GetSavedJobsDetailsSuccessResponse - > + Response > => { try { const { savedJobs } = req.user; @@ -347,10 +339,7 @@ class UserController { req: AuthenticatedRequest, res: Response ): Promise< - Response< - | GetHiddenJobsDetailsErrorResponse - | GetHiddenJobsDetailsSuccessResponse - > + Response > => { try { const { hiddenJobs } = req.user; diff --git a/src/server/types.ts b/src/server/types.ts index 1c2a006..8f30d67 100644 --- a/src/server/types.ts +++ b/src/server/types.ts @@ -15,28 +15,16 @@ export type EditHiddenJobsMethod = "ADD" | "REMOVE"; export type EditSavedJobsMethod = "ADD" | "REMOVE"; -export interface GetJobDetailsErrorResponse { +export interface ErrorResponse { error: string; } export type GetJobDetailsSuccessResponse = Job; -export interface GetJobsErrorResponse { - error: string; -} - export type GetJobsSuccessResponse = GitHubJob[]; -export interface GetHiddenJobsDetailsErrorResponse { - error: string; -} - export type GetHiddenJobsDetailsSuccessResponse = Job[]; -export interface GetSavedJobsDetailsErrorResponse { - error: string; -} - export type GetSavedJobsDetailsSuccessResponse = Job[]; export interface GitHubJob { @@ -87,10 +75,6 @@ export interface JobDocument extends Document { export type JobType = "Contract" | "Full Time"; -export interface PatchSavedJobErrorResponse { - error: string; -} - export interface PatchSavedJobSuccessResponse { createdAt: string; email: string; diff --git a/src/server/util.ts b/src/server/util.ts index eeff00b..0893dde 100644 --- a/src/server/util.ts +++ b/src/server/util.ts @@ -2,12 +2,7 @@ import nfetch from "node-fetch"; import JobModel from "./models/Job"; -import { - GetJobsErrorResponse, - GetJobsSuccessResponse, - GitHubJob, - Job, -} from "./types"; +import { ErrorResponse, GetJobsSuccessResponse, GitHubJob, Job } from "./types"; /** * Check if MongoDB is running locally. Stops application from continuing if false. @@ -53,7 +48,7 @@ export const createSearchURL = ( }; export const getAllJobsFromAPI = async (): Promise< - GetJobsErrorResponse | GetJobsSuccessResponse + ErrorResponse | GetJobsSuccessResponse > => { const jobs: GitHubJob[] = []; let jobsInBatch = null; @@ -83,17 +78,15 @@ export const getAllJobsFromAPI = async (): Promise< }; export const isError = ( - result: GetJobsErrorResponse | GetJobsSuccessResponse -): result is GetJobsErrorResponse => { - return (result as GetJobsErrorResponse).error !== undefined; + result: ErrorResponse | GetJobsSuccessResponse +): result is ErrorResponse => { + return (result as ErrorResponse).error !== undefined; }; // eslint-disable-next-line export const unique = (arr: any[]): any[] => [...new Set(arr)]; -export const rehydrateJobsDB = async (): Promise< - GetJobsErrorResponse | true -> => { +export const rehydrateJobsDB = async (): Promise => { try { const result = await getAllJobsFromAPI(); From 083a7cfefeee121f8b39731b1e8654186ab8ed26 Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Mon, 17 Aug 2020 10:02:45 -0700 Subject: [PATCH 18/28] =?UTF-8?q?=E2=9C=8F=EF=B8=8F=20Single=20`ErrorRespo?= =?UTF-8?q?nse`=20Type=20#88=20-=20FE=20-=20Adjust=20Types?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/client/redux/thunks.ts | 35 +++++++++++------------------ src/client/types.ts | 46 +++++--------------------------------- src/client/util.ts | 18 +++++---------- 3 files changed, 24 insertions(+), 75 deletions(-) diff --git a/src/client/redux/thunks.ts b/src/client/redux/thunks.ts index 97001ac..9b4fe89 100644 --- a/src/client/redux/thunks.ts +++ b/src/client/redux/thunks.ts @@ -35,30 +35,23 @@ import { import { fetchServerData, isError } from "../util"; import { - AddHiddenJobErrorResponse, AddHiddenJobSuccessResponse, - AddSavedJobErrorResponse, AddSavedJobSuccessResponse, AppThunk, DeleteProfileResponse, EditProfileResponse, - GetHiddenJobsDetailsErrorResponse, + ErrorResponse, GetHiddenJobsDetailsSuccessResponse, - GetJobsErrorResponse, GetJobsSuccessResponse, - GetSavedJobsDetailsErrorResponse, GetSavedJobsDetailsSuccessResponse, Job, LocationOption, LoginResponse, - RemoveHiddenJobErrorResponse, RemoveHiddenJobSuccessResponse, - RemoveSavedJobErrorResponse, RemoveSavedJobSuccessResponse, ResetPasswordResponse, RootState, ServerResponseUser, - SignupErrorResponse, SignupSuccessResponse, } from "../types"; @@ -97,7 +90,7 @@ export const searchJobs = ( }); const data = (await fetchServerData(url, "GET")) as - | GetJobsErrorResponse + | ErrorResponse | GetJobsSuccessResponse; if (isError(data)) { @@ -144,7 +137,7 @@ export const logIn = (): AppThunk => async (dispatch, getState) => { "/jobs", "POST", JSON.stringify({ userId: response._id }) - )) as GetJobsErrorResponse | GetJobsSuccessResponse; + )) as ErrorResponse | GetJobsSuccessResponse; if (isError(jobsResult)) { dispatch(displayNotification(jobsResult.error, "error")); @@ -178,9 +171,7 @@ export const signup = (): AppThunk => async (dispatch, getState) => { } // TODO - Modify - const result: - | SignupErrorResponse - | SignupSuccessResponse = await fetchServerData( + const result: ErrorResponse | SignupSuccessResponse = await fetchServerData( "/user", "POST", JSON.stringify({ confirmPassword, email, name, password }) @@ -242,7 +233,7 @@ export const initializeApplication = (): AppThunk => async (dispatch) => { "/jobs", "POST", JSON.stringify({ userId }) - )) as GetJobsErrorResponse | GetJobsSuccessResponse; + )) as ErrorResponse | GetJobsSuccessResponse; if (isError(jobsResult)) { dispatch(displayNotification(jobsResult.error, "error")); @@ -283,7 +274,7 @@ export const logOut = (): AppThunk => async (dispatch) => { "/jobs", "POST", JSON.stringify({ userId: "" }) - )) as GetJobsErrorResponse | GetJobsSuccessResponse; + )) as ErrorResponse | GetJobsSuccessResponse; if (isError(jobsResult)) { dispatch(displayNotification(jobsResult.error, "error")); @@ -330,7 +321,7 @@ export const logOutAll = (): AppThunk => async (dispatch) => { "/jobs", "POST", JSON.stringify({ userId: "" }) - )) as GetJobsErrorResponse | GetJobsSuccessResponse; + )) as ErrorResponse | GetJobsSuccessResponse; if (isError(jobsResult)) { dispatch(displayNotification(jobsResult.error, "error")); @@ -476,7 +467,7 @@ export const addHiddenJob = (id: string): AppThunk => async ( const { currentJobs } = state.application; // TODO - Modify const result: - | AddHiddenJobErrorResponse + | ErrorResponse | AddHiddenJobSuccessResponse = await fetchServerData( "/user/hiddenJobs", "PATCH", @@ -510,7 +501,7 @@ export const addSavedJob = (id: string): AppThunk => async (dispatch) => { try { // TODO - Modify const result: - | AddSavedJobErrorResponse + | ErrorResponse | AddSavedJobSuccessResponse = await fetchServerData( "/user/savedJobs", "PATCH", @@ -542,7 +533,7 @@ export const removeHiddenJob = (id: string): AppThunk => async (dispatch) => { try { // TODO - Modify const result: - | RemoveHiddenJobErrorResponse + | ErrorResponse | RemoveHiddenJobSuccessResponse = await fetchServerData( "/user/hiddenJobs", "PATCH", @@ -572,7 +563,7 @@ export const removeSavedJob = (id: string): AppThunk => async (dispatch) => { try { // TODO - Modify const result: - | RemoveSavedJobErrorResponse + | ErrorResponse | RemoveSavedJobSuccessResponse = await fetchServerData( "/user/savedJobs", "PATCH", @@ -643,7 +634,7 @@ export const getSavedJobsDetails = (): AppThunk => async (dispatch) => { try { const result: - | GetSavedJobsDetailsErrorResponse + | ErrorResponse | GetSavedJobsDetailsSuccessResponse = await fetchServerData( `/user/savedJobsDetails`, "GET" @@ -670,7 +661,7 @@ export const getHiddenJobsDetails = (): AppThunk => async (dispatch) => { try { const result: - | GetHiddenJobsDetailsErrorResponse + | ErrorResponse | GetHiddenJobsDetailsSuccessResponse = await fetchServerData( `/user/hiddenJobsDetails`, "GET" diff --git a/src/client/types.ts b/src/client/types.ts index 2ab192a..f967c28 100644 --- a/src/client/types.ts +++ b/src/client/types.ts @@ -1,10 +1,6 @@ import { Action } from "redux"; import { ThunkAction } from "redux-thunk"; -export interface AddHiddenJobErrorResponse { - error: string; -} - export interface AddHiddenJobSuccessResponse { createdAt: string; email: string; @@ -16,10 +12,6 @@ export interface AddHiddenJobSuccessResponse { _id: string; } -export interface AddSavedJobErrorResponse { - error: string; -} - export interface AddSavedJobSuccessResponse { createdAt: string; email: string; @@ -69,32 +61,20 @@ export type ButtonStyle = "primary" | "secondary" | "danger"; export type ButtonType = "button" | "reset" | "submit"; -export type DeleteProfileResponse = ServerResponseError & ServerResponseUser; +export type DeleteProfileResponse = ErrorResponse & ServerResponseUser; -export type EditProfileResponse = ServerResponseError & ServerResponseUser; +export type EditProfileResponse = ErrorResponse & ServerResponseUser; -export interface GetJobDetailsErrorResponse { +export interface ErrorResponse { error: string; } export type GetJobDetailsSuccessResponse = Job; -export interface GetJobsErrorResponse { - error: string; -} - export type GetJobsSuccessResponse = Job[]; -export interface GetHiddenJobsDetailsErrorResponse { - error: string; -} - export type GetHiddenJobsDetailsSuccessResponse = Job[]; -export interface GetSavedJobsDetailsErrorResponse { - error: string; -} - export type GetSavedJobsDetailsSuccessResponse = Job[]; export type InputAutoComplete = @@ -188,7 +168,7 @@ export interface LocationOption { value: string; } -export type LoginResponse = ServerResponseError & ServerResponseUser; +export type LoginResponse = ErrorResponse & ServerResponseUser; export interface ModalAction { type: string; @@ -212,10 +192,6 @@ export type NotificationType = export type PaginationNavigationType = "left" | "right"; -export interface RemoveHiddenJobErrorResponse { - error: string; -} - export interface RemoveHiddenJobSuccessResponse { createdAt: string; email: string; @@ -227,10 +203,6 @@ export interface RemoveHiddenJobSuccessResponse { _id: string; } -export interface RemoveSavedJobErrorResponse { - error: string; -} - export interface RemoveSavedJobSuccessResponse { createdAt: string; email: string; @@ -244,7 +216,7 @@ export interface RemoveSavedJobSuccessResponse { export type RequestMethod = "DELETE" | "GET" | "PATCH" | "POST"; -export type ResetPasswordResponse = ServerResponseError & ServerResponseUser; +export type ResetPasswordResponse = ErrorResponse & ServerResponseUser; export type RootState = { application: ApplicationState; @@ -254,10 +226,6 @@ export type RootState = { export type SearchType = "description" | "location"; -export interface ServerResponseError { - error: string; -} - export interface ServerResponseUser { createdAt: string; email: string; @@ -269,10 +237,6 @@ export interface ServerResponseUser { _id: string; } -export interface SignupErrorResponse { - error: string; -} - export interface SignupSuccessResponse { createdAt: string; email: string; diff --git a/src/client/util.ts b/src/client/util.ts index 9db4e22..eeba46d 100644 --- a/src/client/util.ts +++ b/src/client/util.ts @@ -1,14 +1,11 @@ import { createBrowserHistory } from "history"; import { + ErrorResponse, RequestMethod, - GetJobDetailsErrorResponse, GetJobDetailsSuccessResponse, - GetJobsErrorResponse, GetJobsSuccessResponse, - AddSavedJobErrorResponse, AddSavedJobSuccessResponse, - SignupErrorResponse, SignupSuccessResponse, } from "./types"; @@ -89,16 +86,13 @@ export const saveState = (state: any): void => { export const isError = ( result: - | GetJobsErrorResponse - | GetJobsSuccessResponse - | GetJobDetailsErrorResponse - | GetJobDetailsSuccessResponse - | AddSavedJobErrorResponse | AddSavedJobSuccessResponse - | SignupErrorResponse + | ErrorResponse + | GetJobDetailsSuccessResponse + | GetJobsSuccessResponse | SignupSuccessResponse -): result is GetJobsErrorResponse => { - return (result as GetJobsErrorResponse).error !== undefined; +): result is ErrorResponse => { + return (result as ErrorResponse).error !== undefined; }; export const history = createBrowserHistory(); From f04f1477fde4cbde3554f7102453e53078c2557f Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Mon, 17 Aug 2020 11:22:08 -0700 Subject: [PATCH 19/28] =?UTF-8?q?=F0=9F=93=84=20Search=20Returns=20More=20?= =?UTF-8?q?Jobs=20than=20Exist=20in=20DB=20#85=20-=20BE=20-=20Edit=20'uniq?= =?UTF-8?q?ue()'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/server/util.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/server/util.ts b/src/server/util.ts index 0893dde..069c57a 100644 --- a/src/server/util.ts +++ b/src/server/util.ts @@ -84,7 +84,10 @@ export const isError = ( }; // eslint-disable-next-line -export const unique = (arr: any[]): any[] => [...new Set(arr)]; +export const unique = (arr: any[]): any[] => + [...new Set(arr.map((item) => JSON.stringify(item)))].map((item) => + JSON.parse(item) + ); export const rehydrateJobsDB = async (): Promise => { try { From 9121eb988cdc287d2b17e7efbef946990d4f3370 Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Mon, 17 Aug 2020 11:22:34 -0700 Subject: [PATCH 20/28] =?UTF-8?q?=F0=9F=93=84=20Search=20Returns=20More=20?= =?UTF-8?q?Jobs=20than=20Exist=20in=20DB=20#85=20-=20FE=20-=20Remove=20unu?= =?UTF-8?q?sed=20util=20functions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/client/util.ts | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/src/client/util.ts b/src/client/util.ts index eeba46d..cf88855 100644 --- a/src/client/util.ts +++ b/src/client/util.ts @@ -27,32 +27,6 @@ export const fetchServerData = async ( return data; }; -// TODO - Remove -// eslint-disable-next-line -export const groupBy = (arr: any[], key: any): any => - arr.reduce( - (acc, item) => ((acc[item[key]] = [...(acc[item[key]] || []), item]), acc), - {} - ); - -// TODO - Remove -// eslint-disable-next-line -export const unique = (arr: any[]): any[] => [...new Set(arr)]; - -// TODO - Remove -export const validURL = (str: string): boolean => { - const pattern = new RegExp( - "^(https?:\\/\\/)?" + // protocol - "((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|" + // domain name - "((\\d{1,3}\\.){3}\\d{1,3}))" + // OR ip (v4) address - "(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*" + // port and path - "(\\?[;&a-z\\d%_.~+=-]*)?" + // query string - "(\\#[-a-z\\d_]*)?$", - "i" - ); // fragment locator - return !!pattern.test(str); -}; - /** * Loads the state of the application from localStorage if present. * @returns {object} From d1dfea600c0519161c1e018e4882e0c46ee220d1 Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Mon, 17 Aug 2020 12:10:08 -0700 Subject: [PATCH 21/28] =?UTF-8?q?=F0=9F=8C=90=20Access=20Details=20with=20?= =?UTF-8?q?Direct=20URL=20#80=20-=20FE=20-=20Change=20URL=20for=20'Details?= =?UTF-8?q?'=20page?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/client/App.tsx | 2 +- src/client/components/JobCard/JobCard.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client/App.tsx b/src/client/App.tsx index ad67819..12c4c81 100644 --- a/src/client/App.tsx +++ b/src/client/App.tsx @@ -56,7 +56,7 @@ const App: React.SFC = (props: AppProps) => { - +
diff --git a/src/client/components/JobCard/JobCard.tsx b/src/client/components/JobCard/JobCard.tsx index a2409f9..8c199f6 100644 --- a/src/client/components/JobCard/JobCard.tsx +++ b/src/client/components/JobCard/JobCard.tsx @@ -91,7 +91,7 @@ const JobCard: React.SFC = (props: JobCardProps) => { handleClearJobDetails()} - to={`/jobs/${job.id}`} + to={`/jobDetails/${job.id}`} > {job.title} From 22681d2f45e51fb793fba45705c24a0cb4b04887 Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Mon, 17 Aug 2020 12:11:07 -0700 Subject: [PATCH 22/28] =?UTF-8?q?=F0=9F=8C=90=20Access=20Details=20with=20?= =?UTF-8?q?Direct=20URL=20#80=20-=20Adjust=20stubs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cypress/integration/applicationError.spec.js | 2 +- cypress/integration/details.spec.js | 2 +- cypress/integration/directPageAccess.spec.js | 4 ++-- cypress/integration/hiddenJobs.spec.js | 2 +- cypress/integration/savedJobs.spec.js | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cypress/integration/applicationError.spec.js b/cypress/integration/applicationError.spec.js index c03f2ef..f89febe 100644 --- a/cypress/integration/applicationError.spec.js +++ b/cypress/integration/applicationError.spec.js @@ -25,7 +25,7 @@ context("Application Error", () => { }); cy.route({ method: "GET", - url: "/jobs/f1884b46-ecb4-473c-81f5-08d9bf2ab3bb", + url: "/jobDetails/f1884b46-ecb4-473c-81f5-08d9bf2ab3bb", status: 200, response: {}, delay: 1000, diff --git a/cypress/integration/details.spec.js b/cypress/integration/details.spec.js index ee43985..10a20b6 100644 --- a/cypress/integration/details.spec.js +++ b/cypress/integration/details.spec.js @@ -14,7 +14,7 @@ context("Details", () => { }); cy.route({ method: "GET", - url: "/jobs/f1884b46-ecb4-473c-81f5-08d9bf2ab3bb", + url: "/jobDetails/f1884b46-ecb4-473c-81f5-08d9bf2ab3bb", status: 200, response: jobDetails, delay: 1000, diff --git a/cypress/integration/directPageAccess.spec.js b/cypress/integration/directPageAccess.spec.js index 8f1d065..54aff9c 100644 --- a/cypress/integration/directPageAccess.spec.js +++ b/cypress/integration/directPageAccess.spec.js @@ -14,7 +14,7 @@ context("Direct Page Access", () => { }); cy.route({ method: "GET", - url: "/jobs/f1884b46-ecb4-473c-81f5-08d9bf2ab3bb", + url: "/jobDetails/f1884b46-ecb4-473c-81f5-08d9bf2ab3bb", status: 200, response: jobDetailsJson, delay: 1000, @@ -38,7 +38,7 @@ context("Direct Page Access", () => { }); it("Should be able to access '/jobs/:id' directly", () => { - cy.visit("http://localhost:3000/jobs/f1884b46-ecb4-473c-81f5-08d9bf2ab3bb"); + cy.visit("http://localhost:3000/jobDetails/f1884b46-ecb4-473c-81f5-08d9bf2ab3bb"); cy.wait(500); cy.get("h2").should("have.text", "Cloud DevOps Engineer"); diff --git a/cypress/integration/hiddenJobs.spec.js b/cypress/integration/hiddenJobs.spec.js index 4ff92f8..d4abb30 100644 --- a/cypress/integration/hiddenJobs.spec.js +++ b/cypress/integration/hiddenJobs.spec.js @@ -22,7 +22,7 @@ context("Hidden Jobs", () => { }); cy.route({ method: "GET", - url: "/jobs/f1884b46-ecb4-473c-81f5-08d9bf2ab3bb", + url: "/jobDetails/f1884b46-ecb4-473c-81f5-08d9bf2ab3bb", status: 200, response: jobDetailsJson, delay: 1000, diff --git a/cypress/integration/savedJobs.spec.js b/cypress/integration/savedJobs.spec.js index 108147e..094bedb 100644 --- a/cypress/integration/savedJobs.spec.js +++ b/cypress/integration/savedJobs.spec.js @@ -22,7 +22,7 @@ context("Saved Jobs", () => { }); cy.route({ method: "GET", - url: "/jobs/f1884b46-ecb4-473c-81f5-08d9bf2ab3bb", + url: "/jobDetails/f1884b46-ecb4-473c-81f5-08d9bf2ab3bb", status: 200, response: jobDetailsJson, delay: 1000, From 95931678ae46cd57d99fc16a5aa8b38965da809f Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Mon, 17 Aug 2020 12:11:45 -0700 Subject: [PATCH 23/28] =?UTF-8?q?=F0=9F=8C=90=20Access=20Details=20with=20?= =?UTF-8?q?Direct=20URL=20#80=20-=20Adjust=20test=20title?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cypress/integration/directPageAccess.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cypress/integration/directPageAccess.spec.js b/cypress/integration/directPageAccess.spec.js index 54aff9c..070d502 100644 --- a/cypress/integration/directPageAccess.spec.js +++ b/cypress/integration/directPageAccess.spec.js @@ -37,7 +37,7 @@ context("Direct Page Access", () => { cy.get("h1").should("have.text", "Create Account"); }); - it("Should be able to access '/jobs/:id' directly", () => { + it("Should be able to access '/jobDetails/:id' directly", () => { cy.visit("http://localhost:3000/jobDetails/f1884b46-ecb4-473c-81f5-08d9bf2ab3bb"); cy.wait(500); From e159140337769c1df912c5cbab2fc9b42a1aa6e9 Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Mon, 17 Aug 2020 14:10:09 -0700 Subject: [PATCH 24/28] =?UTF-8?q?=F0=9F=8C=90=20Access=20Details=20with=20?= =?UTF-8?q?Direct=20URL=20#80=20-=20Fix=20Tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cypress/integration/applicationError.spec.js | 2 +- cypress/integration/details.spec.js | 2 +- cypress/integration/directPageAccess.spec.js | 4 ++-- cypress/integration/hiddenJobs.spec.js | 2 +- cypress/integration/savedJobs.spec.js | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cypress/integration/applicationError.spec.js b/cypress/integration/applicationError.spec.js index f89febe..c03f2ef 100644 --- a/cypress/integration/applicationError.spec.js +++ b/cypress/integration/applicationError.spec.js @@ -25,7 +25,7 @@ context("Application Error", () => { }); cy.route({ method: "GET", - url: "/jobDetails/f1884b46-ecb4-473c-81f5-08d9bf2ab3bb", + url: "/jobs/f1884b46-ecb4-473c-81f5-08d9bf2ab3bb", status: 200, response: {}, delay: 1000, diff --git a/cypress/integration/details.spec.js b/cypress/integration/details.spec.js index 10a20b6..ee43985 100644 --- a/cypress/integration/details.spec.js +++ b/cypress/integration/details.spec.js @@ -14,7 +14,7 @@ context("Details", () => { }); cy.route({ method: "GET", - url: "/jobDetails/f1884b46-ecb4-473c-81f5-08d9bf2ab3bb", + url: "/jobs/f1884b46-ecb4-473c-81f5-08d9bf2ab3bb", status: 200, response: jobDetails, delay: 1000, diff --git a/cypress/integration/directPageAccess.spec.js b/cypress/integration/directPageAccess.spec.js index 070d502..ab04b6a 100644 --- a/cypress/integration/directPageAccess.spec.js +++ b/cypress/integration/directPageAccess.spec.js @@ -14,7 +14,7 @@ context("Direct Page Access", () => { }); cy.route({ method: "GET", - url: "/jobDetails/f1884b46-ecb4-473c-81f5-08d9bf2ab3bb", + url: "/jobs/f1884b46-ecb4-473c-81f5-08d9bf2ab3bb", status: 200, response: jobDetailsJson, delay: 1000, @@ -38,7 +38,7 @@ context("Direct Page Access", () => { }); it("Should be able to access '/jobDetails/:id' directly", () => { - cy.visit("http://localhost:3000/jobDetails/f1884b46-ecb4-473c-81f5-08d9bf2ab3bb"); + cy.visit("http://localhost:3000/jobs/f1884b46-ecb4-473c-81f5-08d9bf2ab3bb"); cy.wait(500); cy.get("h2").should("have.text", "Cloud DevOps Engineer"); diff --git a/cypress/integration/hiddenJobs.spec.js b/cypress/integration/hiddenJobs.spec.js index d4abb30..4ff92f8 100644 --- a/cypress/integration/hiddenJobs.spec.js +++ b/cypress/integration/hiddenJobs.spec.js @@ -22,7 +22,7 @@ context("Hidden Jobs", () => { }); cy.route({ method: "GET", - url: "/jobDetails/f1884b46-ecb4-473c-81f5-08d9bf2ab3bb", + url: "/jobs/f1884b46-ecb4-473c-81f5-08d9bf2ab3bb", status: 200, response: jobDetailsJson, delay: 1000, diff --git a/cypress/integration/savedJobs.spec.js b/cypress/integration/savedJobs.spec.js index 094bedb..108147e 100644 --- a/cypress/integration/savedJobs.spec.js +++ b/cypress/integration/savedJobs.spec.js @@ -22,7 +22,7 @@ context("Saved Jobs", () => { }); cy.route({ method: "GET", - url: "/jobDetails/f1884b46-ecb4-473c-81f5-08d9bf2ab3bb", + url: "/jobs/f1884b46-ecb4-473c-81f5-08d9bf2ab3bb", status: 200, response: jobDetailsJson, delay: 1000, From e8529dffeae9fe4ea7726c1aa7c752a7070b78f4 Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Mon, 17 Aug 2020 14:25:16 -0700 Subject: [PATCH 25/28] =?UTF-8?q?=F0=9F=8C=90=20Access=20Details=20with=20?= =?UTF-8?q?Direct=20URL=20#80=20-=20Fix=20Test=20Again?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cypress/integration/directPageAccess.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cypress/integration/directPageAccess.spec.js b/cypress/integration/directPageAccess.spec.js index ab04b6a..7027ee8 100644 --- a/cypress/integration/directPageAccess.spec.js +++ b/cypress/integration/directPageAccess.spec.js @@ -38,7 +38,7 @@ context("Direct Page Access", () => { }); it("Should be able to access '/jobDetails/:id' directly", () => { - cy.visit("http://localhost:3000/jobs/f1884b46-ecb4-473c-81f5-08d9bf2ab3bb"); + cy.visit("http://localhost:3000/jobDetails/f1884b46-ecb4-473c-81f5-08d9bf2ab3bb"); cy.wait(500); cy.get("h2").should("have.text", "Cloud DevOps Engineer"); From 587eed5d3598e8b8e11e8ac373153a4d27a2383b Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Mon, 17 Aug 2020 14:30:21 -0700 Subject: [PATCH 26/28] =?UTF-8?q?=F0=9F=94=A5=20Remove=20Template=20Config?= =?UTF-8?q?=20#93=20-=20Remove=20File?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- template-tsconfig.json | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 template-tsconfig.json diff --git a/template-tsconfig.json b/template-tsconfig.json deleted file mode 100644 index 1554740..0000000 --- a/template-tsconfig.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "compilerOptions": { - "jsx": "preserve", - "target": "ESNext", - "module": "ESNext", - "moduleResolution": "node", - "outDir": "./dist", - "strict": true, - "esModuleInterop": true, - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true, - "resolveJsonModule": true - }, - "include": ["./src/**/*", "./index.d.ts"] -} From f478cb23de115ef22535b1552d5e21114b5d3da2 Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Mon, 17 Aug 2020 14:51:55 -0700 Subject: [PATCH 27/28] =?UTF-8?q?=F0=9F=8E=A8=20ProfileAccountStats=20Widt?= =?UTF-8?q?h=20#83=20-=20Adjust=20Style?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/client/components/Profile/Profile-styled.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/components/Profile/Profile-styled.tsx b/src/client/components/Profile/Profile-styled.tsx index ba2d6f7..11bd5ee 100644 --- a/src/client/components/Profile/Profile-styled.tsx +++ b/src/client/components/Profile/Profile-styled.tsx @@ -84,7 +84,7 @@ const ProfileAccountStatsContainer = styled.div` @media only screen and (max-width: 820px) { margin-bottom: 50px; margin-top: 100px; - width: 100%; + width: auto; } `; From bcafad0357f3886dbbb8b645020d4cade72d6f4b Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Mon, 17 Aug 2020 16:01:27 -0700 Subject: [PATCH 28/28] =?UTF-8?q?=F0=9F=93=9D=20CHANGELOG=20-=20Update=20C?= =?UTF-8?q?HANGELOG?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2070699..1aa9955 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,16 +5,27 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [1.6.0] - _Unreleased_ +## [1.6.0] - 2020-08-17 + +### 🐛 Bug Fixeroo ### Added ### Changed +- Hide hidden jobs in search results - [#79](https://github.com/alexlee-dev/gh-jobs/issues/79) +- Single `ErrorResponse` type for error responses - [#88](https://github.com/alexlee-dev/gh-jobs/issues/88) + ### Removed +- Template Configuration - [#93](https://github.com/alexlee-dev/gh-jobs/issues/93) + ### Fixed +- `unique()` function not working as expected, resulting in search results containing more entires than jobs in DB - [#85](https://github.com/alexlee-dev/gh-jobs/issues/85) +- Now able to access `Details` page with a direct url - [#80](https://github.com/alexlee-dev/gh-jobs/issues/80) +- `ProfileAccountStats` container width spilling out on mobile - [#93](https://github.com/alexlee-dev/gh-jobs/issues/93) + ## [1.5.0] - 2020-08-15 ### ⏹️ Button Redesign