An application to create and vote on polls, written in Typescript.
- Polling App
- Table of Contents
- Technology Used
- Setup
- Development Server
- Testing
- Deployment
- Other Commands
- Auth
- Api Design
- Frontend
- React
- Redux
- Redux-Saga
- styled components
- Ant Design
- Axios
- Backend
- Express
- Passport (Github & JWT auth)
- LokiJS
- Testing
- Jest
- SuperTest
- TestCafe
- To install dependencies run:
yarn
oryarn install
- In order for the github authentication to work, you must
- Follow github's tutorial for creating an OAuth app
- You will then be provided with a clientId and a clientSecret.
- You must then set the following environment variables in order for the app
to run in both development and production.
Note thePOLLING_APP_URL
must match theHomepage URL
provided when creating your GitHub OAuth appCLIENT_ID=YourGitHubProvidedClientId Client_SECRET=YoutGitHubProvidedClientSecret SECRET_KEY=ASecretKeyGeneratedByYou POLLING_APP_URL=http://127.0.0.1:8000
- Dotenv is set up, so create a file in the root directory called
dev.env
and store the env variables in there as shown above. They will be loaded into your code automatically.
- Dotenv is set up, so create a file in the root directory called
- To start the server run:
yarn start
By default server will run on port 8000, you can change this by setting aPORT
environment variable.
Note that the server restarts on changes in the working directory and browser hot reloads - Visit
localhost:8000
to see the website
-
To execute unit/integration tests with jest, run:
yarn test
-
To execute end-to-end tests using testcafe, first ensure development server is running and run:
yarn testcafe
- Add the github account you'd like to use for testing to
dev.env
file in the format shown below
Probably best not to use your real github account especially if you share passwords between multiple accounts.
TEST_USERNAME=YourGithubUsername TEST_PASSWORD=YourPassword
- Add the github account you'd like to use for testing to
On the deployment server, run yarn build
to bundle all the front end
code using webpack, and compile the server to javascript.
Run yarn start:prod
to run the server.
- To start Storybook run:
yarn run storybook
- hasn't been kept up to date though - To launch a debug Chrome instance, run:
yarn start chrome
Attach to port9222
using your debugger and you can debug in your IDE now!
Allows you to login using your github account and then redirects to your previous location.
Logs you out and removes cookies.
If logged in will display your user data stored in the databse.
All routes go through /api/
, eg: localhost:8000/api/polls
{
description: string,
pollId: string,
pollName: string,
voteLimit: number,
creator: User,
options: [
{
optionId: string,
value: string,
votes: []
},
{
optionId: string,
value: string,
votes: []
},
{
optionId: string,
value: string,
votes: []
},
{
optionId: string,
value: string,
votes: []
}
],
isOpen: boolean,
totalVotes: number,
optionVoteLimit: number,
namespace: string
}
{
displayName?: string,
id: string,
userName: string,
photos: [
{
value: string
}
]
}
Create a new poll. If no namespace is provided, it will be created in /public
{
poll: {
pollName: string,
description: string,
options: string[],
voteLimit: int,
optionVoteLimit: int,
namespace?: string
}
}
Response code: 201
Description: Succesfully created a new poll in public.
Returns:
{
poll: Poll
}
Gets a list of existing polls and their information.
N/A
Response code: 200
Description: Got a list of polls
Returns:
{
polls: Poll[]
}
Create a new poll. If no namespace is provided, it will be created in the url provided namespace.
{
poll: {
pollName: string,
description: string,
options: string[],
voteLimit: int,
optionVoteLimit: int,
namespace?: string
}
}
Response code: 201
Description: Succesfully created a new poll in public.
Returns:
{
poll: Poll
}
Gets a specific poll.
N/A
Response code: 200
Description: Got a poll
Returns:
{
polls: Poll
}
Response Code: 400
Description: Poll probably wasn't found
Returns: N/A
Updates a specific poll
- You are only required to enter in the information that you wish to change.
- Id can not be changed, it can only be used for identification.
- You will only be able to update polls that you have created.
- If you provide an option without an optionId, a new option will be created.
- If you prived an option with an optionId but without a value, the option specfied will be deleted.
{
description?: string,
pollName?: string,
voteLimit?: integer,
optionVoteLimit?: integer,
options?: [
{ optionId: string, value: string },
{ optionId: string, value: "" }, // --> This option will be removed
{ optionId: "", value: "new option!" } // -> This option will be added
]
}
Response Code: 200
Description: Succesfully updated poll information
Returns:
{
poll: Poll
}
Response Code: 400
Description: Failed to update poll, maybe syntax is invalid or poll with id
doesn't exist
Returns: N/A
Response Code: 401
Description: Unauthorized, either you are not logged in or you are trying to
modify a poll that you did not create.
Returns: N/A
Gets the data for a specific poll
N/A
Response Code: 200
Description: Got specific poll information
Returns:
{
poll: Poll
}
Response Code: 400
Description: Failed to get poll information, poll with that id might not exist
Returns: N/A
Deletes a specific poll
- You can only delete polls that you created
N/A
Response Code: 200
Description: Succesfully deleted poll
Returns: N/A
Response Code: 400
Description: Failed to delete poll, maybe the poll with that id doesn't exist
Returns: N/A
Response Code: 401
Description: Unauthorized, either you are trying to delete a poll you didn't
create, or JWT is invalid.
Returns: N/A
Casts a vote on an option within a specific poll and returns the updated poll.
{
optionId: string
}
Response Code: 200
Description: Succesfully voted for option in poll
Returns:
{
poll: Poll
}
Response Code: 400
Description: Vote was rejected, could be invalid optionId, poll not found, or you don't have any votes remaining.
Returns: N/A
Response Code: 401
Description: Unauthorized, you are not logged in or JWT is invalid
Returns: N/A
Rmoves a vote on an option within a specific poll and returns the updated poll.
If the user does not have any votes on the option chosen, a 400 error will be returned.
{
optionId: string
}
Response Code: 200
Description: Succesfully removed a vote on an option in a poll.
Returns:
{
poll: Poll
}
Response Code: 400
Description: Vote was rejected, could be invalid optionId, poll not found, or you don't have any votes to remove.
Returns: N/A
Response Code: 401
Description: Unauthorized, you are not logged in or JWT is invalid
Returns: N/A
Sets a poll as open (users are able to vote on it) and returns the updated poll.
N/A
Response Code: 200
Description: Poll was successfully set to open
Returns:
{
poll: Poll
}
Response Code: 401
Description: Unauthorized, you are not logged in or JWT is invalid
Returns: N/A
Sets a poll as closed (users will be unable to vote on it) and returns the updated poll.
N/A
Response Code: 200
Description: Poll was successfully set to closed
Returns:
{
poll: Poll
}
Response Code: 401
Description: Unauthorized, you are not logged in or JWT is invalid
Returns: N/A
Gets an array of all existing users, or if query is provided,
returns an array of specified users data.
For example users?ids=25291974&ids=43615036
N/A
Response Code: 200
Description: Got users
Returns:
{
users: User[]
}
Gets an existing user by id
N/A
Response Code: 200
Description: Got a user
Returns:
{
user: User
}
Gets the currently logged in user's data
N/A
Response Code: 200
Description: Got a user
Returns:
{
user: User
}
Response Code: 401
Description: Unauthorized, not logged in or JWT is invalid
Returns: N/A