Skip to content
This repository has been archived by the owner on Sep 7, 2023. It is now read-only.

Commit

Permalink
Merge pull request #7 from ESKYoung/add_cron_page
Browse files Browse the repository at this point in the history
Add cron page to application
  • Loading branch information
ESKYoung committed Oct 18, 2020
2 parents 2625dba + cc690a9 commit c085506
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 24 deletions.
3 changes: 3 additions & 0 deletions .envrc
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ export FLASK_APP=main.py
# Define the hashing key here if using locally. If using on Heroku, define it in config vars
# export HASH_KEY=

# Define HTML pages
export HTML_CRON=cron.html

# Define the CountAPI URL
export URL_COUNTAPI=https://api.countapi.xyz/hit/shields-io-visitor-counter

Expand Down
10 changes: 5 additions & 5 deletions .secrets.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"files": null,
"lines": null
},
"generated_at": "2020-10-17T11:10:15Z",
"generated_at": "2020-10-18T09:20:33Z",
"plugins_used": [
{
"name": "AWSKeyDetector"
Expand Down Expand Up @@ -63,28 +63,28 @@
"hashed_secret": "65b5658c038dcc7b3f9ee80669c0f26ac1441d05",
"is_secret": true,
"is_verified": false,
"line_number": 55,
"line_number": 58,
"type": "Hex High Entropy String"
},
{
"hashed_secret": "5e18621e95bc4b9b75d7d5b097929ecfc9494078",
"is_secret": true,
"is_verified": false,
"line_number": 56,
"line_number": 59,
"type": "Hex High Entropy String"
},
{
"hashed_secret": "2b2718d1211a6b3c6ae4ef13c63469cb1eafa6c7",
"is_secret": true,
"is_verified": false,
"line_number": 57,
"line_number": 60,
"type": "Hex High Entropy String"
},
{
"hashed_secret": "186df42ce44b6dc5a79c097baf114cf67eb9a13b",
"is_secret": true,
"is_verified": false,
"line_number": 58,
"line_number": 61,
"type": "Hex High Entropy String"
}
]
Expand Down
16 changes: 14 additions & 2 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from datetime import datetime, timedelta
from flask import Flask, Response, redirect, request
from typing import Dict, Optional, Tuple, Union
from flask import Flask, Response, redirect, render_template, request
from typing import Any, Dict, Optional, Tuple, Union
from urllib.parse import SplitResult, urlsplit, urlunsplit
import hashlib
import os
Expand All @@ -12,6 +12,7 @@
DEFAULT_SHIELDS_IO_COLOR = os.getenv("DEFAULT_SHIELDS_IO_COLOR")
GITHUB_REPOSITORY = os.getenv("GITHUB_REPOSITORY")
HASH_KEY = os.getenv("HASH_KEY")
HTML_CRON = os.getenv("HTML_CRON")
URL_COUNTAPI = os.getenv("URL_COUNTAPI").rstrip("/")
URL_SHIELDS_IO = os.getenv("URL_SHIELDS_IO").rstrip("/")

Expand Down Expand Up @@ -175,5 +176,16 @@ def get_shields_io_badge() -> Union[Response, Tuple[str, int]]:
return Response(response=svg, content_type="image/svg+xml", headers=headers)


@app.route("/cron")
def cron_page() -> Tuple[Any, int]:
"""Add a page for cron jobs to wake up the application.
Returns:
A HTTP no content status code.
"""
return render_template(HTML_CRON)


if __name__ == '__main__':
app.run()
11 changes: 11 additions & 0 deletions templates/cron.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello &#128075</title>
</head>
<body>
<h1>I'm awake! &#128075</h1>

</body>
</html>
50 changes: 33 additions & 17 deletions tests/test_main.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from datetime import timedelta
from http import HTTPStatus
from hypothesis import example, given, settings
from hypothesis.strategies import characters, dictionaries, one_of, text
from flask import request
from flask import render_template, request
from main import (
app, combine_url_and_query, compile_shields_io_url, get_page_count, get_page_hash, redirect_to_github_repository
app, combine_url_and_query, compile_shields_io_url, cron_page, get_page_count, get_page_hash,
redirect_to_github_repository
)
from string import printable
from typing import Any, Dict, Union
Expand All @@ -20,6 +22,7 @@
DEFAULT_SHIELDS_IO_LABEL = os.getenv("DEFAULT_SHIELDS_IO_LABEL")
DEFAULT_SHIELDS_IO_COLOR = os.getenv("DEFAULT_SHIELDS_IO_COLOR")
GITHUB_REPOSITORY = os.getenv("GITHUB_REPOSITORY")
HTML_CRON = os.getenv("HTML_CRON")
URL_COUNTAPI = os.getenv("URL_COUNTAPI").rstrip("/")
URL_SHIELDS_IO = os.getenv("URL_SHIELDS_IO").rstrip("/")

Expand Down Expand Up @@ -138,9 +141,9 @@ def json(self):

# Define the MockResponse attributes if the URL stub is whitespace or otherwise empty
if args[0].rstrip(" /") != URL_COUNTAPI:
return MockResponse({"value": 100}, 200)
return MockResponse({"value": HTTPStatus.CONTINUE}, HTTPStatus.OK)
else:
return MockResponse(None, 404)
return MockResponse(None, HTTPStatus.NOT_FOUND)


@given(test_input=one_of(characters(whitelist_categories="P"), STRATEGY_TEST_INPUT))
Expand All @@ -152,7 +155,7 @@ def test_get_page_count_returns_correctly_with_working_countapi(patch_requests_g

# Call the get_page_count function, and assert the returned value is correct
if test_input.rstrip(" /"):
assert get_page_count(test_input) == 100
assert get_page_count(test_input) == HTTPStatus.CONTINUE
else:
assert get_page_count(test_input) is None

Expand Down Expand Up @@ -346,7 +349,7 @@ def test_assertionerror_handling_if_get_page_count_fails(self, mocker, test_inpu

@given(test_input_query=STRATEGY_TEST_INPUT_QUERY)
def test_exception_handling_from_get_page_hash(self, mocker, test_input_query: dict) -> None:
"""Test other exception handling by get_page_hash raises a HTTP 405 status code."""
"""Test other exception handling by get_page_hash raises a HTTP 500 status code."""

# Patch the get_page_hash, and get_page_count functions
_ = mocker.patch("main.get_page_hash", side_effect=Exception())
Expand All @@ -355,15 +358,13 @@ def test_exception_handling_from_get_page_hash(self, mocker, test_input_query: d
# Set up the app test client
client = app.test_client()

# Get the /badge page of the app
_ = client.get("/badge", query_string={"page": "example", **test_input_query})

# Assert a HTTP 405 status code is returned
assert client.post("/badge").status_code == 405
# Get the /badge page of the app, and assert it returns a HTTP 500 status code
get_client = client.get("/badge", query_string={"page": "example", **test_input_query})
assert get_client.status_code == HTTPStatus.INTERNAL_SERVER_ERROR

@given(test_input_query=STRATEGY_TEST_INPUT_QUERY)
def test_exception_handling_from_get_page_count(self, mocker, test_input_query: dict) -> None:
"""Test other exception handling by get_page_count raises a HTTP 405 status code."""
"""Test other exception handling by get_page_count raises a HTTP 500 status code."""

# Patch the get_page_hash, and get_page_count functions
_ = mocker.patch("main.get_page_hash")
Expand All @@ -372,11 +373,9 @@ def test_exception_handling_from_get_page_count(self, mocker, test_input_query:
# Set up the app test client
client = app.test_client()

# Get the /badge page of the app
_ = client.get("/badge", query_string={"page": "example", **test_input_query})

# Assert a HTTP 405 status code is returned
assert client.post("/badge").status_code == 405
# Get the /badge page of the app, and assert it returns a HTTP 500 status code
get_client = client.get("/badge", query_string={"page": "example", **test_input_query})
assert get_client.status_code == HTTPStatus.INTERNAL_SERVER_ERROR

@given(test_input_page=STRATEGY_TEST_INPUT_PAGE, test_input_label=STRATEGY_TEST_INPUT,
test_input_color=STRATEGY_TEST_INPUT, test_input_query=STRATEGY_TEST_INPUT_QUERY)
Expand Down Expand Up @@ -435,3 +434,20 @@ def test_flask_response_is_called_correctly(self, mocker, test_input_page: str,
headers={"Cache-Control": "no-cache,max-age=0,no-store,s-maxage=0,proxy-revalidate",
"Expires": mock_expiry_time.strftime("%a, %d %b %Y %H:%M:%S GMT")}
)


class TestCronPage:

def test_returns_correct_status_code(self) -> None:
"""Test the cron_page function returns correctly."""
with app.test_request_context(path="/cron"):
assert cron_page() == render_template(HTML_CRON)

def test_returns_correctly(self) -> None:
"""Test calling the /cron slug returns correctly."""

# Set up the app test client
client = app.test_client()

# Get the /cron page of the app, and assert returns a HTTP 200 status code
assert client.get("/cron").status_code == HTTPStatus.OK

0 comments on commit c085506

Please sign in to comment.