Project Hub is a sharing platform mainly aimed at students of Code Institute looking to share their school projects and check out other students projects, but is open to everyone and all users are welcome.
Fully responsive navbar with links to:
- Home page
- Browse section
- Project submission
- Login section
- Profile page
Logo hyperlinked to home page:
Featured on all pages across the site.
Adapts to if user is authenticated or not (Disables Project submission and profile links and switches the Login/Logout link)
Navbar for non-authenticated users:
Navbar for authenticated users:
Purpose of feature: Provide users with an easy and straight-forward way to navigate the site
Featured on all pages across the site. The footer contains links to my personal GitHub account aswell as my LinkedIn account.
Purpose of feature: Provide users with a way to connect with me and check out my GitHub profile.
The project cards are used in various places across the page. They are hyperlinked to the page for that specific project and contains an image of the project if provided during project submission(else a default image not found image) aswell as the title and description provided during project submission
Purpose of feature: Provide users with a simple, concise and aesthetic UI component to access user submitted projects.
The Home page consists of:
- Hero section
- Hall of Fame section
- Recently Added section
- Browse by Category section
Hero section
The hero section features imagery appropriate for the site aswell as a call-to-action section allowing users to sign up or login, it also adapts to if user is authenticated or not:
Purpose of feature: Provide users with a welcoming landing page and highly visible way to sign up or login to the site.
Hall of Fame section
The Hall of Fame section features three cards displaying the three most liked posts on the site in order from left to right.
Purpose of feature: Provide users with a fast way to see which posts are popular.
Recently Added section
The Recently Added section features four cards displaying the four most recent posts on the site in order from left to right.
Purpose of feature: Provide users with a fast way to see which posts are new on the site.
Browse by Category section
The Browse by Category section features a bootstrap accordion with items for all the categories on the site. Inside each accordion item is a link to the browse page for that specific category. Each accordion item for Code Institute projects also has the description for that project taken from the Code Institute assessment criteria sections.
Purpose of feature: Provide users with a fast way to browse projects by category.
The Browse page consists of:
- Page header
- Sort by button
- Project cards
Page header
The page header displays the project category which the user is currently browsing.
Purpose of feature: Provide users with a highly visible way to know which category is currently being browsed.
Sort by button
The sort by button allows the user to sort the content displayed by: - Alphabetical order (A-Z) - Recently Added - Top rated(Most liked)
Purpose of feature: Provide users with an easy way to sort the content displayed based on the users interest.
The Project submission page consists of:
- Submission form
Submission form
The submission form lets the user provide info about a project to then post to the database.
The content which the user is able to post is:
- Title
- Category
- Description
- Project image
- Live link to project
- GitHub Repo link
Additional: The project image field can either be provided with an image from the users local machine or the "Generate from link" button can be toggled which will then on form submission generate a screenshot from the "live link to project" provided and use as the project image.
Purpose of feature: Provide users with a way to submit their projects to the site for others to see.
The Login page consists of:
- Login form
Login form
The login form allows the user to enter their credentials and authenticate to enter the sites authenticated state.
The login form also contains a link to the Sign up page in case the user is not already registered.
Purpose of feature: Provide users with a way to login to the site.
The Sign up page consists of:
- Sign up form
Sign up form
The Sign up form which is provided by django allows the user to enter credentials for registration on the site.
Through django it contains all the functionality for a secure registration and displays help text and error text to give the user feedback
The sign up form also contains a link to the Login page in case the user already has an account.
Purpose of feature: Provide users with a way to register an account on the site.
The Your profile page consists of:
- Profile info section
- Profile posts section
Profile info section
The profile info section contains following info about the profile:
- Username
- Number of posts
- Date which the user registered on
Purpose of feature: Provide users with a way to get a quick overview of their account.
Profile posts section
The profile posts section contains Project Cards displaying the posts which has been uploaded by the user. Below each card are buttons allowing the user to either delete the post or update the posts info.
Additional: The delete button displays a modal requiring the user to confirm the deletion of the post.
Purpose of feature: Provide users with a way to see their uploaded posts aswell as update or delete their posts as part of the CRUD(Create, read, update, delete) criteria.
The Profile page consists of:
- Profile info section
- Profile posts section
The profile page is a copy of the Your profile page but without the "Your profile" header and options to update or delete posts.
The purpose of this page is for users to view other profiles than their own.
Purpose of feature: Provide users with a way to see specific users and their posts.
The Project page consists of:
- Project image section
- Profile section
- Project info section
- Project links
- Readme section
- Like button
- Comment section
Project image section
The project image section displays the image provided during the project submission or a default image if no image was provided.
Purpose of feature: Provide users with an image of the project.
Profile section
The profile section contains the username hyperlinked to their Profile page aswell as Project cards below displaying their posts.
The profile section is only visible on medium screen sizes(bootstrap preset) or larger.
Additional: On medium screen sizes and smaller, the username, hyperlinked to the profile page of the post author is instead visible below the project title.
Purpose of feature: Provide users with a quick and easy way to see and visit specific users and a few of their posts.
Project info section
The project info section contains the project title and description provided during project submission.
Purpose of feature: Provide users with a way to read the provided info for a post.
Project links
The project links (Live link to project and GitHub repo link) are displayed below the project info section and provide the user a way to check out the project.
Purpose of feature: Provide users with a way to check out the project and it's associated GitHub repository.
Readme section
The Readme section allows the user to read the Readme.md file found on the GitHub repo link the author of the post provided during project submission.
Additional: If no GitHub repo link is provided or there is an error fetching the file, the readme section instead displays "Readme.md not available".
Purpose of feature: Provide users with a way to read the Readme.md file associated with the project.
Like button
The like button, placed on the right end of the screen in height with the project title, allows users to like or unlike a post.
Additional: The like button adapts to if the user is authenticated or not. If the user is not authenticated the like button is disabled and displays a tooltip on hover.
Purpose of feature: Provide users with a way to to like posts they find interesting.
Comment section
The comment section allows users to post comments on a post aswell as delete their own comments using the X button in the above image.
Additional: The delete button displays a modal requiring the user to confirm deletion of the comment.
Manual testing
Tests done with DEBUG = False in settings.py
Case: Accessing authorization required links without logging in:
Link | Expected Result | Actual Result | Resolved by |
---|---|---|---|
http://127.0.0.1:8000/profile_page/ | Redirect to home page | Server Error (500) | Check user authenticated in associated view |
http://127.0.0.1:8000/project_submission/ | Redirect to home page | Project submission page loaded | Check user authenticated in associated view |
http://127.0.0.1:8000/project_update/14/ | Redirect to home page | Project update page loaded | Check user authenticated and post author in associated view |
http://127.0.0.1:8000/delete_post/14/ | Redirect to home page | Server Error (500) | Check user authenticated and post author in associated view |
http://127.0.0.1:8000/post_comment/14/ | Redirect to home page | Server Error (500) | Check user authenticated in associated view |
http://127.0.0.1:8000/like_post/14/ | Redirect to home page | Server Error (500) | Check user authenticated in associated view |
http://127.0.0.1:8000/delete_comment/10/14/ | Redirect to home page | Server Error (500) | Check user authenticated and comment owner in associated view |
Case: Inserting invalid or no data during project submission:
Test | Expected Result | Actual Result | Resolved by |
---|---|---|---|
Upload file larger than 10MB | Error message | Server Error (500) | Write js script to validate inputs |
Upload file + toggle generate from link | Error message / Toggle not available when file uploaded | Post uploaded using image generated from link | Write js script to validate inputs |
Post using a non-GitHub repo link in field | Error message | Post uploaded successfully | Write js script to validate inputs |
Case: Inserting invalid or no data during update project:
Test | Expected Result | Actual Result | Resolved by |
---|---|---|---|
Upload file larger than 10MB | Error message | Server Error (500) | Write js script to validate inputs |
Upload file + toggle generate from link | Error message / Toggle not available when file uploaded | Post uploaded using image generated from link | Write js script to validate inputs |
Post using a non-GitHub repo link in field | Error message | Post uploaded successfully | Write js script to validate inputs |
Unit testing
Unit tests were written using PyTest and Selenium since Seleniums abillity to interact directly with the browser better reflects how the user actually would interact with the site. Tests were written with the AAA(Arrange, Act, Assert) principle in mind.
Unit test files:
1. test_noauth_protection.py
- Tests access to authorization required url routes when user is not authenticated
2. test_auth.py
- Tests sign up functionality
- Tests login functionality
- Tests access to profile page and project submission page when logged in
3. test_misc.py
- Tests access to login and signup page when already logged in
4. test_like_comment.py
- Tests like / unlike functionality
- Tests comment / delete comment functionality
5. test_submission_update.py
- Tests invalid inputs in submission form
- Tests invalid inputs in update project form
HTML & CSS
All html and css files ran through the Official W3C validator
CSS: All files valid
HTML: 100+ errors, all due to the use of Jinja templating
Python
All files ran through Code Institutes Python Linter
hub_main/views.py
Line | Error |
---|---|
77 | E501 line too long (138 > 79 characters) |
103 | E501 line too long (97 > 79 characters) |
137 | E501 line too long (138 > 79 characters) |
229 | E501 line too long (81 > 79 characters) |
287 | E501 line too long (93 > 79 characters) |
304 | E501 line too long (91 > 79 characters) |
314 | E501 line too long (93 > 79 characters) |
320 | E501 line too long (93 > 79 characters) |
hub_main/urls.py
Line | Error |
---|---|
6 | E501 line too long (96 > 79 characters) |
7 | E501 line too long (112 > 79 characters) |
8 | E501 line too long (94 > 79 characters) |
9 | E501 line too long (98 > 79 characters) |
10 | E501 line too long (110 > 79 characters) |
11 | E501 line too long (102 > 79 characters) |
12 | E501 line too long (127 > 79 characters) |
13 | E501 line too long (120 > 79 characters) |
14 | E501 line too long (90 > 79 characters) |
15 | E501 line too long (98 > 79 characters) |
hub_main/models.py
Line | Error |
---|---|
19 | E501 line too long (149 > 79 characters) |
21 | E501 line too long (91 > 79 characters) |
22 | E501 line too long (95 > 79 characters) |
25 | E501 line too long (91 > 79 characters) |
43 | E501 line too long (85 > 79 characters) |
hub_main/tests.py: All clear, no errors found
hub_main/apps.py: All clear, no errors found
hub_main/admin.py: All clear, no errors found
hub_main/tests/test_submission_update.py
Line | Error |
---|---|
14 | E501 line too long (86 > 79 characters) |
hub_main/tests/test_noauth_protection.py
Line | Error |
---|---|
14 | E501 line too long (86 > 79 characters) |
hub_main/tests/test_misc.py: All clear, no errors found
hub_main/tests/test_like_comment.py
Line | Error |
---|---|
14 | E501 line too long (82 > 79 characters) |
22 | E501 line too long (86 > 79 characters) |
23 | E501 line too long (81 > 79 characters) |
30 | E501 line too long (82 > 79 characters) |
38 | E501 line too long (86 > 79 characters) |
39 | E501 line too long (81 > 79 characters) |
46 | E501 line too long (81 > 79 characters) |
47 | E501 line too long (80 > 79 characters) |
64 | E501 line too long (102 > 79 characters) |
65 | E501 line too long (102 > 79 characters) |
68 | E501 line too long (82 > 79 characters) |
69 | E501 line too long (90 > 79 characters) |
hub_main/tests/test_auth.py
Line | Error |
---|---|
20 | E501 line too long (80 > 79 characters) |
21 | E501 line too long (82 > 79 characters) |
22 | E501 line too long (82 > 79 characters) |
29 | E501 line too long (81 > 79 characters) |
53 | E501 line too long (92 > 79 characters) |
62 | E501 line too long (107 > 79 characters) |
___hub_main/run_tests.py:___All clear, no errors found
hub_main/helper_functions.py
Line | Error |
---|---|
22 | E501 line too long (85 > 79 characters) |
members/views.py: All clear, no errors found
members/urls.py: All clear, no errors found
members/tests.py: All clear, no errors found
members/models.py: All clear, no errors found
members/apps.py: All clear, no errors found
members/admin.py: All clear, no errors found
Errors ignored since they make no impact on the functionality but might impact functionality if resolved.
JavaScript
All files run through the JSHint Linter
card_animations.js
Line | Warning |
---|---|
6 | Functions declared within loops referencing an outer scoped variable may lead to confusing semantics. (gsap, card) |
9 | Functions declared within loops referencing an outer scoped variable may lead to confusing semantics. (gsap, card) |
Error |
---|
var gsap not declared (declared in script tag in template) |
home_animations.js
Error |
---|
var gsap not declared (declared in script tag in template) |
option_animations.js
Line | Warning |
---|---|
5 | Functions declared within loops referencing an outer scoped variable may lead to confusing semantics. (gsap, option) |
8 | Functions declared within loops referencing an outer scoped variable may lead to confusing semantics. (gsap, option) |
Error |
---|
var gsap not declared (declared in script tag in template) |
load_github.js: No errors or warnings.
validate_inputs.js: No errors or warnings.
word_animations.js
Error |
---|
var gsap not declared (declared in script tag in template) |
Lighthouse
All pages were analyzed by Lighthouse: See reports
This project was deployed to Heroku using these steps:
1. Fork or clone this repository
2. Create a new Heroku app
3. Set the buildpacks to Python
4. Set the config vars for your database connection and api keys
4. Link the Heroku app to the repository
5. Click on deploy
Clone the project
git clone https://github.com/linx02/project-hub.git
Go to the project directory
cd project_hub
Install dependencies
pip3 install -r requirements.txt
Start the server
python3 manage.py runserver
Note that you will have to setup your own database and API connections using these steps:
- Create a file name "env.py" in the projects root directory.
- Copy and paste this code in the env.py file and replace values with your own:
import os
os.environ["DATABASE_URL"]=YOUR_DATABASE_URL
os.environ["SECRET_KEY"]=YOUR_SECRET_KEY
os.environ["CLOUDINARY_SECRET"]=YOUR_CLOUDINARY_SECRET
os.environ["THUMIO_AUTH"]=YOUR_THUMIO_AUTH_KEY
API's used:
GitHub' REST API: For fetching Readme.md file for Readme section in Project page.
Thum.io's URL API: For generating screenshots of provided links during project submission.
Libraries and frameworks:
Bootstrap: CSS framework used.
Django: Web framework used.
GreenSock's GSAP: For animations.
PyTest: For testing.
Selenium: For testing.
Data storing:
PostgreSQL: Database management system used.
Cloudinary: For storing image files in the cloud.
Media:
Freepik: For svg in the hero section.
Haikei: For background svg on the home page.
FontAwesome: For icons.