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 @@
-
Johnathan IrvinImages +
Johnathan Irvin +
@@ -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 @@
-
Johnathan IrvinImages +
Johnathan Irvin +
@@ -61,11 +63,11 @@

Conclusion

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 diff --git a/website/__init__.py b/website/__init__.py index 354cbf5..0188f7a 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, @@ -133,6 +163,31 @@ 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: + """ + Returns the FAQ page. + + Returns: + str: The rendered template. + """ + return flask.render_template( + 'faq.pug', + content=markdown.markdown( + QUESTION_MARKDOWN, + extensions=['fenced_code', 'toc', 'tables'], + ) + ) + @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 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 new file mode 100644 index 0000000..5a4c787 --- /dev/null +++ b/website/templates/faq.pug @@ -0,0 +1,8 @@ +extends layout.pug + +block title + title FAQ - Johnathan Irvin + +block content + h1.h1 Frequently Asked Questions + article {{ content }} diff --git a/website/templates/layout.pug b/website/templates/layout.pug index 276044e..f9367c7 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 @@ -27,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