From d3cae63dea7a3fc6c89059fbb8b4ed92f1728611 Mon Sep 17 00:00:00 2001 From: Johnny Irvin Date: Tue, 23 Aug 2022 00:13:34 -0400 Subject: [PATCH 1/6] Created FAQ page. - FAQ page added to navigation. - Navigation lowercase - Implements #57 --- website/__init__.py | 15 +++++++++++++++ website/templates/faq.pug | 18 ++++++++++++++++++ website/templates/layout.pug | 7 +++++-- 3 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 website/templates/faq.pug diff --git a/website/__init__.py b/website/__init__.py index 354cbf5..b772e00 100644 --- a/website/__init__.py +++ b/website/__init__.py @@ -133,6 +133,21 @@ def sitemap() -> str: response.mimetype = 'application/xml' return response +@app.route('/faq') +def faq() -> str: + """ + Returns the FAQ page. + + Returns: + str: The rendered template. + """ + questions: dict = { + } + return flask.render_template( + 'faq.pug', + questions=questions + ) + @app.errorhandler(404) def not_found(error: Exception) -> str: return flask.render_template('404.pug'), 404 diff --git a/website/templates/faq.pug b/website/templates/faq.pug new file mode 100644 index 0000000..18bc3f7 --- /dev/null +++ b/website/templates/faq.pug @@ -0,0 +1,18 @@ +extends layout.pug + +block title + title FAQ - Johnathan Irvin + +block content + h1 Frequently Asked Questions + + .toc: ul + // {% for question in questions.keys() %} + li: a(href="{{ '#'+question|escape }}") {{ question }} + // {% endfor %} + + // {% for question, answer in questions.items() %} + h2 {{ question }} + p {{ answer }} + // {% endfor %} + diff --git a/website/templates/layout.pug b/website/templates/layout.pug index 276044e..0fa13bb 100644 --- a/website/templates/layout.pug +++ b/website/templates/layout.pug @@ -4,8 +4,11 @@ block header .container: header.d-flex.flex-wrap.justify-content-between.align-items-center.py-3.mb-4.border-bottom a(href="/").flex.text-muted.text-decoration-none span.fs-4 Johnathan Irvin - a(href="{{ url_for('images') }}").flex.text-muted - span Images + .flex + a(href="{{ url_for('faq') }}").text-decoration-none.text-muted.p-2 + span faq + a(href="{{ url_for('images') }}").text-decoration-none.text-muted.p-2 + span images block body main#main.container From 290b5e24ffe3b9131c0c614fa84fcceee2bb2580 Mon Sep 17 00:00:00 2001 From: Johnny Irvin Date: Tue, 23 Aug 2022 00:16:13 -0400 Subject: [PATCH 2/6] Lowercase footer links to match navigation. - Thanks #57 --- website/templates/layout.pug | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/templates/layout.pug b/website/templates/layout.pug index 0fa13bb..f9367c7 100644 --- a/website/templates/layout.pug +++ b/website/templates/layout.pug @@ -30,6 +30,6 @@ block footer li.ms-3: a.text-muted(href="https://www.linkedin.com/in/johnnyirvin/" target="_blank") img(src="{{url_for('static', filename='img/linkedin.svg')}}", alt="LinkedIn") ul.nav.list-unstyled.d-flex.col-md-12.justify-content-start.d-flex - li.ms-3: a.text-muted(href="/rss.xml") RSS Feed + li.ms-3: a.text-muted(href="/rss.xml") rss feed li.ms-3: span | - li.ms-3: a.text-muted(href="/sitemap.xml") Sitemap + li.ms-3: a.text-muted(href="/sitemap.xml") sitemap From 7880ac3d2168feb52cfcc906453f58f610b890e5 Mon Sep 17 00:00:00 2001 From: Johnny Irvin Date: Tue, 23 Aug 2022 00:19:46 -0400 Subject: [PATCH 3/6] Document routes. --- website/__init__.py | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/website/__init__.py b/website/__init__.py index b772e00..cefe0c2 100644 --- a/website/__init__.py +++ b/website/__init__.py @@ -31,6 +31,12 @@ @app.route('/') def index() -> str: + """ + Render the index page. + + Returns: + str: The rendered index page. + """ return flask.render_template( 'index.pug', posts=sorted( @@ -77,6 +83,18 @@ def image(name: str) -> str: @app.route('/articles////') def article(year: int, month: int, day: int, description: str) -> str: + """ + Returns the article with the given description. + + Args: + year (int): The year of the article. + month (int): The month of the article. + day (int): The day of the article. + description (str): The description of the article. + + Returns: + str: The rendered template. + """ try: post = blog_repo.get(f"{year}/{month}/{day}/{description}") except Repository.NotFound: @@ -98,6 +116,12 @@ def article(year: int, month: int, day: int, description: str) -> str: @app.route('/rss') @app.route('/feed') def rss() -> str: + """ + Returns the RSS feed. + + Returns: + str: The rendered template. + """ sorted_items = sorted( blog_repo.get_all(), key=lambda post: post.date, @@ -119,6 +143,12 @@ def rss() -> str: @app.route('/sitemap.xml') @app.route('/sitemap') def sitemap() -> str: + """ + Returns a sitemap of the website. + + Returns: + str: The rendered template. + """ sorted_items = sorted( blog_repo.get_all(), key=lambda post: post.date, @@ -150,4 +180,10 @@ def faq() -> str: @app.errorhandler(404) def not_found(error: Exception) -> str: + """ + Returns the 404 page. + + Returns: + str: The rendered template. + """ return flask.render_template('404.pug'), 404 From abd5959432efc8768b295fb4257dcefc1ea40c63 Mon Sep 17 00:00:00 2001 From: Johnny Irvin Date: Tue, 23 Aug 2022 00:38:36 -0400 Subject: [PATCH 4/6] Implement FAQ markdown. - Closes #57 --- website/__init__.py | 10 ++++-- website/static/faq.md | 68 +++++++++++++++++++++++++++++++++++++++ website/templates/faq.pug | 14 ++------ 3 files changed, 77 insertions(+), 15 deletions(-) create mode 100644 website/static/faq.md diff --git a/website/__init__.py b/website/__init__.py index cefe0c2..0188f7a 100644 --- a/website/__init__.py +++ b/website/__init__.py @@ -163,6 +163,9 @@ def sitemap() -> str: response.mimetype = 'application/xml' return response + +with open('website/static/faq.md', 'r') as file: + QUESTION_MARKDOWN = file.read() @app.route('/faq') def faq() -> str: """ @@ -171,11 +174,12 @@ def faq() -> str: Returns: str: The rendered template. """ - questions: dict = { - } return flask.render_template( 'faq.pug', - questions=questions + content=markdown.markdown( + QUESTION_MARKDOWN, + extensions=['fenced_code', 'toc', 'tables'], + ) ) @app.errorhandler(404) diff --git a/website/static/faq.md b/website/static/faq.md new file mode 100644 index 0000000..7db4b8f --- /dev/null +++ b/website/static/faq.md @@ -0,0 +1,68 @@ +[TOC] + +## What experience do you have in the field of software development? + +I have written everything from the front-end user interfaces to the backend database and everything in between. I have spent time writing software multiples companies ranging from small to large. I have written software for several industries including cybersecurity, retail, and manufacturing. + +I have a passion for teaching and mentoring others. I have taught software development to dozens of people over the years. I have taught in both formal and informal settings. I have also written blog posts. + +## How did you get into software development? + +Since I was a toddler I have had an interest in computers. I attempted to take my toys and shove them into my parents' computer to "make them work." Despite many years, I've never been able to get a 3.5-inch floppy disk to work with any of my oddly shaped plastic toys. + +Later, when I was about seven years old, my father stole me away to the library. He showed me how to use the computers there. I was hooked. The library's computers had time limits. I wasn't able to explore them for more than half-an-hour. That day we went home with a book on QBasic. + +## What are your strengths and weaknesses? + +My biggest strength is providing creative solutions. I show promise in my attention to detail and dedication to my work. I also have experience leading teams, which has forced me into effective communication. + +My weaknesses include my occasional perfectionism, which can lead to me spending too much time on minor details, and my tendency to get bogged down in the details of a problem instead of seeing the big picture. + +## What salary are you looking for? + +A salary should be fair and commensurate with my experience and qualifications. The proposal should also reflect the company's budget and the current market value for my skill set. If the range on the provided contract or job description is too low, I will be sure to decline professionally. + +Contact me on Linkedin if you are interested in working with me. + +## Are you willing to relocate? + +Relocation is obsolete for software engineers. The industry has shifted to allow for work from home. These options eliminate the need for expensive relocations. + +The cost of living and working in different parts of the country can be expensive, and often requires a higher salary to maintain the same standard of living. This is especially true in larger metropolitan areas. + +The work from home options that are available for software engineers eliminates the need for costly relocations, and allows for a more flexible lifestyle. + +## When can you start? + +I need four weeks before starting a new employment. Two weeks for my current employer and two weeks for vacation. + +The vacation is a reward because life is too short to work all the time. + +## Describe a time when you had to overcome a challenge at work. + +I once took over a team of engineers on a code base written by a single junior engineer. Code was in a terrible state, the project was behind schedule, and feature delivery time was on a downward spiral. I had to work long hours for several months to get the team back on track. The frustrated customer became happy again. + +I was able to turn the team around by doing a few things: + +1. I sat down with the team and discussed the current and future state of the project. +2. I set up a daily stand-up meeting so that everyone could stay on the same page. +3. I instituted a code review process for all merges. +4. I worked closely with each team member, providing daily 1-on-1 guidance. +5. I consistently under-promised and over-delivered. +6. I implemented trunk-based development. +7. I reduced deployment cycles from 1 month to 1 week with intentions for daily deployments. +8. I automated end-to-end testings, eliminating multiple-day manual quality assurance tests. + +## Describe a time when you made a mistake at work and how you handled it. + +I dropped a production environment. + +I had just taken over a project with an "interesting" deployment strategy. It used a bunch of semi-manual jobs and required manual developer intervention. One of the extra jobs happened to be "drop production." + +I was in the process of releasing a new version to a production environment when I clicked the little devil. It was late, as most production deployments are. I was the only one in the office. I remember thinking, "Oh crap, I shouldn't have done that." + +Fortunately, I quickly got everything back up and running with some backups taken before I went into maintenance mode. Bonus, this software was in early beta. + +The meeting with my boss in the morning was interesting. I killed the button while my boss watched. + +It happens to the best of us. diff --git a/website/templates/faq.pug b/website/templates/faq.pug index 18bc3f7..5a4c787 100644 --- a/website/templates/faq.pug +++ b/website/templates/faq.pug @@ -4,15 +4,5 @@ block title title FAQ - Johnathan Irvin block content - h1 Frequently Asked Questions - - .toc: ul - // {% for question in questions.keys() %} - li: a(href="{{ '#'+question|escape }}") {{ question }} - // {% endfor %} - - // {% for question, answer in questions.items() %} - h2 {{ question }} - p {{ answer }} - // {% endfor %} - + h1.h1 Frequently Asked Questions + article {{ content }} From a353e7fa861750b4044141b9ee9c97c0476e755d Mon Sep 17 00:00:00 2001 From: Johnny Irvin Date: Tue, 23 Aug 2022 00:45:32 -0400 Subject: [PATCH 5/6] Update snapshots --- tests/snapshots/goodbye-cruel-world.snapshot.html | 8 +++++--- tests/snapshots/hello-world.snapshot.html | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/tests/snapshots/goodbye-cruel-world.snapshot.html b/tests/snapshots/goodbye-cruel-world.snapshot.html index 83ad750..f5aa65d 100644 --- a/tests/snapshots/goodbye-cruel-world.snapshot.html +++ b/tests/snapshots/goodbye-cruel-world.snapshot.html @@ -24,7 +24,9 @@
@@ -312,11 +314,11 @@

Next Sprint

diff --git a/tests/snapshots/hello-world.snapshot.html b/tests/snapshots/hello-world.snapshot.html index 91cf1cc..0c25524 100644 --- a/tests/snapshots/hello-world.snapshot.html +++ b/tests/snapshots/hello-world.snapshot.html @@ -24,7 +24,9 @@
@@ -61,11 +63,11 @@

Conclusion

From 3eb05083d996fffa1d18fa6c995902de78a79614 Mon Sep 17 00:00:00 2001 From: Johnny Irvin Date: Tue, 23 Aug 2022 00:50:12 -0400 Subject: [PATCH 6/6] Test FAQ - Relates to #57 --- tests/test_integrations/test_faq.py | 56 +++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 tests/test_integrations/test_faq.py diff --git a/tests/test_integrations/test_faq.py b/tests/test_integrations/test_faq.py new file mode 100644 index 0000000..9b5cc75 --- /dev/null +++ b/tests/test_integrations/test_faq.py @@ -0,0 +1,56 @@ +# Copyright (c) 2022 Johnathan P. Irvin +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +import pytest + + +def test_faq(client): + """ + Test the FAQ page. + + Args: + client (test_client): The test client. + """ + response = client.get('/faq') + + assert response.status_code == 200 + assert 'Frequently Asked Questions' in response.text + +@pytest.mark.parametrize('question', [ + "What experience do you have in the field of software development?", + "How did you get into software development?", + "What are your strengths and weaknesses?", + "What salary are you looking for?", + "Are you willing to relocate?", + "When can you start?", + "Describe a time when you had to overcome a challenge at work.", + "Describe a time when you made a mistake at work and how you handled it.", +]) +def test_faq_questions(client, question: str): + """ + Test the FAQ questions. + + Args: + client (test_client): The test client. + question (str): The question to test. + """ + response = client.get('/faq') + + assert question in response.text