Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tests #52

Open
wants to merge 28 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
d3df9ea
Updated Api-Key, created copy.env
Hgersten-hash Jun 9, 2022
8a92805
Created links for other pages in website and added them to index.html
Hgersten-hash Jun 9, 2022
ec55866
Added links for other pages to index.html
Hgersten-hash Jun 9, 2022
78b4f2d
Made header for Projects page
Hgersten-hash Jun 10, 2022
3edf9d5
Added project information dynamically using jinja and json
Hgersten-hash Jun 10, 2022
7e91ac0
Added project videos to projects page
Hgersten-hash Jun 10, 2022
2e1357e
Updated about me info
Hgersten-hash Jun 12, 2022
139f5fd
Added resume, css animations to resume page
Hgersten-hash Jun 14, 2022
555ffb1
Added contact card
Hgersten-hash Jun 15, 2022
4c9e0cb
Revert "Added resume, css animations to resume page"
Hgersten-hash Jun 15, 2022
ff25cc7
Revert "Revert "Added resume, css animations to resume page""
Hgersten-hash Jun 15, 2022
2dc01f1
Revert "Added contact card"
Hgersten-hash Jun 15, 2022
ddb2b1e
Added contact page
Hgersten-hash Jun 15, 2022
42616ab
Added js for menu in contact
Hgersten-hash Jun 15, 2022
a9d9204
Added link to js for contact.html
Hgersten-hash Jun 15, 2022
c7676d8
Fixed css styling on contact page
Hgersten-hash Jun 19, 2022
b622f38
Automated Deployment with Script
Hgersten-hash Jun 20, 2022
a1e834d
Added db with post/get methods and a testing script
Hgersten-hash Jun 26, 2022
2cc8200
Added html and js for timeline page
Hgersten-hash Jun 27, 2022
17cd1d5
Updated URL for timeline.js
Hgersten-hash Jun 27, 2022
5805c81
Switched from tmux to myportfolio.service
Hgersten-hash Jun 27, 2022
bf83bbd
Attempting to add DELETE endpoint for db
Hgersten-hash Jun 29, 2022
6209783
Fixed Delete endpoint
Hgersten-hash Jun 29, 2022
f022875
wrote tests for GET endpoint in tests_db.py
mmiah00 Jun 30, 2022
3c4301d
working on integration tests, added tests for the home page
mmiah00 Jun 30, 2022
70a6889
added tests for GET and POST for /api/timeline and to test timeline page
mmiah00 Jun 30, 2022
903a432
wrote tests for malformed inputs for timeline posts
mmiah00 Jul 1, 2022
76fdcc6
edited test cases for homepage
mmiah00 Jul 2, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 125 additions & 2 deletions app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,41 @@
import json
from flask import Flask, render_template, request
from dotenv import load_dotenv
from peewee import *
import datetime
from playhouse.shortcuts import model_to_dict

load_dotenv() # Loads the environment variables from the .env file

app = Flask(__name__) # Initializes a Flask app

os.getenv("API_KEY") # Obtains the value of the .env variable containing the Google Maps API key
if os.getenv("TESTING") == "true":
print("Running in test mode")
mydb = SqliteDatabase('file:memory?mode=memory&cache=shared', uri=True)
else:
#creates database
mydb = MySQLDatabase(os.getenv("MYSQL_DATABASE"),
user=os.getenv("MYSQL_USER"),
password=os.getenv("MYSQL_PASSWORD"),
host=os.getenv("MYSQL_HOST"),
port=3306
)
print(mydb)

#creates table for timeline post
class TimelinePost(Model):
name = CharField()
email = CharField()
content = TextField()
created_at = DateTimeField(default=datetime.datetime.now)

class Meta:
database = mydb

mydb.connect()
mydb.create_tables([TimelinePost])

# os.getenv("API_KEY") # Obtains the value of the .env variable containing the Google Maps API key

# Route for the landing page
@app.route('/')
Expand All @@ -32,11 +61,39 @@ def profile(name):
else:
return index()


# Route for the projects page
@app.route('/projects')
def projects():

data = load_profiles_from_json('projects.json')
info1 = data['portfolio']
info2 = data['strace']
info3 = data['qa']
info4 = data['weather']
return render_template('projects.html', info1=info1, info2 = info2, info3 = info3, info4= info4,url=os.getenv("URL"))

# Route for the contact page
@app.route('/contact')
def contact():

return render_template('contact.html', url=os.getenv("URL"))

# Route for the resume page
@app.route('/resume')
def resume():

return render_template('resume.html', url=os.getenv("URL"))

@app.route('/timeline')
def timeline():
return render_template('timeline.html', title="Timeline")

# Route for handling 404 errors
@app.errorhandler(404)
def not_found(e):
"""
Redirects any invalid URL to the landing page.
Serves the projects page.
"""
return render_template("index.html")

Expand All @@ -54,3 +111,69 @@ def load_profiles_from_json(filename) -> dict:
# UTF-8 encoding is used to parse apostrophes correctly
with open(path, "r", encoding='utf8') as file:
return json.load(file)

#create GET endpoint to retrieve timeline posts by create_at descending
@app.route('/api/timeline_post', methods=['GET'])
def get_time_line_post():
return {
'timeline_posts': [
model_to_dict(p)
for p in
TimelinePost.select().order_by(TimelinePost.created_at.desc())
]
}

#add POST route for timeline post, DELETE attempt 2
@app.route('/api/timeline_post', methods=['POST']) #'DELETE'])
# if request.method =='POST':
def post_time_line_post():
name = request.form.get('name')
email = request.form.get('email')
content = request.form.get('content')

error_message = ""

if name == None or name == "":
error_message += "Invalid name\n"

if email == None or email == "" or (not ("@" in email and ".com" in email)):
error_message += "Invalid email\n"

if content == None or content == "":
error_message += "Invalid content\n"

if error_message != "":
return error_message, 400

timeline_post = TimelinePost.create(name=name, email=email, content=content)

return model_to_dict(timeline_post)
# elif request.method =='DELETE':
# def delete_time_line_post():
# nid = request.form['id']
# obj=TimelinePost.get(TimelinePost.id==nid)
# obj.delete_instance()

# return "Done"

# DELETE attempt 3
# @app.route('/api/timeline_post', methods=['DELETE'])
# def delete_time_line_post():
# nid = request.form['id']
# obj=TimelinePost.get(TimelinePost.id==nid)
# obj.delete_instance()

# return "Done"

# Delete attempt 1
@app.route('/api/timeline_post/<int:nid>', methods=['DELETE'])
def delete_time_line_post(nid):
try:
obj=TimelinePost.get(TimelinePost.id==nid)
obj.delete_instance()
return get_time_line_post()
# return "Done"
except TypeError:
from traceback import format_exec
print(format_exec())
# print("deleted result")
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/static/img/809177.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions app/static/img/contact.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file added app/static/img/indexbckrd.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/static/pdfs/Hanna-Gersten-Resume.pdf
Binary file not shown.
Binary file added app/static/pdfs/NYUCert.pdf
Binary file not shown.
5 changes: 5 additions & 0 deletions app/static/scripts/contact.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
function menuOnClick() {
document.getElementById("menu-bar").classList.toggle("change");
document.getElementById("nav").classList.toggle("change");
document.getElementById("menu-bg").classList.toggle("change-bg");
}
2 changes: 1 addition & 1 deletion app/static/scripts/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ function setup() {
// Function for adding a text flicker animation for the landing page description
function textFlicker() {
// Define values for the wordFlick function
let words = ['Aspiring Production Engineers', 'MLH Fellows', 'Python Enthusiasts'],
let words = ['Aspiring Software Engineer', 'Tech Enthusiast'],
part,
i = 0,
offset = 0,
Expand Down
5 changes: 5 additions & 0 deletions app/static/scripts/projects.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
function menuOnClick() {
document.getElementById("menu-bar").classList.toggle("change");
document.getElementById("nav").classList.toggle("change");
document.getElementById("menu-bg").classList.toggle("change-bg");
}
5 changes: 5 additions & 0 deletions app/static/scripts/resume.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
function menuOnClick() {
document.getElementById("menu-bar").classList.toggle("change");
document.getElementById("nav").classList.toggle("change");
document.getElementById("menu-bg").classList.toggle("change-bg");
}
56 changes: 56 additions & 0 deletions app/static/scripts/timeline.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// ul = document.getElementById('timeline-posts');
// list = document.createDocumentFragment();

fetch('../api/timeline_post')
.then((response) =>{return response.json()})
.then(data => {appendData(data)});

function appendData(data){
for(var i=0; i<data.timeline_posts.length; i+=1){
let timeline_post = data.timeline_posts[i];
let timelinediv = document.getElementById('timeline-posts');
let name = document.createElement('name');
let email = document.createElement('email');
let content = document.createElement('content');
let created_at = document.createElement('created_at');
// var div = document.createElement("div");

// div.innerHTML = `Name: ${timeline_post.name}
// Email: ${timeline_post.email}
// content: ${timeline_post.content}
// created_at: ${timeline_post.created_at}`;
name.innerHTML = `Name: ${timeline_post.name} <br />`;
email.innerHTML = `Email: ${timeline_post.email} <br />`;
content.innerHTML = `Content: ${timeline_post.content} <br />`;
created_at.innerHTML = `Created at: ${timeline_post.created_at} <br /><br />`;

timelinediv.appendChild(name);
timelinediv.appendChild(email);
timelinediv.appendChild(content);
timelinediv.appendChild(created_at);

// list.appendChild(li);
};
}
// ul.appendChild(list);


const form = document.getElementById('form');

form.addEventListener('submit', function(e) {
e.preventDefault();
const data = new FormData();
data.append("name", document.getElementById("user_name").value);
data.append("email", document.getElementById("user_email").value);
data.append("content", document.getElementById("user_content").value);
fetch('../api/timeline_post', {
method: 'POST',
body: data,
})
location.reload();
})

// var mainContainer = document.getElementById('timeline-posts');
// list = document.createDocumentFragment();


Loading