Skip to content

Commit

Permalink
Move app inside an app factory - setup tests
Browse files Browse the repository at this point in the history
  • Loading branch information
sondregronas committed Aug 6, 2023
1 parent 0290122 commit 73c69c0
Show file tree
Hide file tree
Showing 5 changed files with 207 additions and 152 deletions.
40 changes: 40 additions & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: CI

on:
push:
branches:
- main

pull_request:
branches:
- main

jobs:
test:
strategy:
max-parallel: 6
matrix:
os: [ ubuntu-latest ]
python-version: [ 3.7, 3.8, 3.9, '3.10', '3.11' ]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

- name: Install Python dependencies
run: |
python -m pip install --upgrade pip
pip install pytest pytest-cov
- name: Run unit tests
run: |
pip install -r requirements.txt
python -m pytest tests/ --cov=FeideUtstyrbase --cov-report=xml
- uses: codecov/codecov-action@v3
with:
file: ./coverage.xml
16 changes: 0 additions & 16 deletions BookingSystem/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@
from logging import Logger, StreamHandler, Formatter, FileHandler
from pathlib import Path

import flask
from dotenv import load_dotenv
from flask_session import Session
from werkzeug.middleware.proxy_fix import ProxyFix

dotenv_path = Path('.env')
if dotenv_path.exists():
Expand All @@ -20,19 +17,6 @@
KIOSK_FQDN = os.getenv('KIOSK_FQDN')
API_TOKEN = os.getenv('API_TOKEN')

# Flask app setup
app = flask.Flask(__name__, template_folder='templates', static_folder='static')
app.secret_key = os.getenv('SECRET_KEY')
app.config['SESSION_TYPE'] = 'filesystem'
app.config['PERMANENT_SESSION_LIFETIME'] = 3600
if os.getenv('DEBUG') == 'True':
app.debug = True

# We're behind a reverse proxy, so we need to fix the scheme and host
app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1, x_host=1)

Session(app)

# Logger setup
logger = Logger(__name__)
logger.setLevel('DEBUG')
Expand Down
271 changes: 136 additions & 135 deletions BookingSystem/app.py
Original file line number Diff line number Diff line change
@@ -1,158 +1,159 @@
import os
from datetime import datetime

import flask
from dateutil import parser
from flask_session import Session
from werkzeug.middleware.proxy_fix import ProxyFix

import api
import feide
import groups
import inventory
import mail
import user
from __init__ import app, logger, KIOSK_FQDN, LABEL_SERVER
from __init__ import logger, KIOSK_FQDN, LABEL_SERVER
from db import init_db, add_admin
from utils import login_required

app.register_blueprint(api.api)
app.register_blueprint(feide.feide)

def create_app() -> flask.Flask:
# Flask app setup
app = flask.Flask(__name__, template_folder='templates', static_folder='static')
app.secret_key = os.getenv('SECRET_KEY')
app.config['SESSION_TYPE'] = 'filesystem'
app.config['PERMANENT_SESSION_LIFETIME'] = 3600
if os.getenv('DEBUG') == 'True':
app.debug = True

# We're behind a reverse proxy, so we need to fix the scheme and host
app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1, x_host=1)

Session(app)

app.register_blueprint(api.api)
app.register_blueprint(feide.feide)

@app.template_filter('strftime')
def _jinja2_filter_datetime(date, fmt='%d.%m.%Y') -> str:
return parser.parse(date).strftime(fmt)

@app.template_filter('strfunixtime')
def _jinja2_filter_strftime(date, fmt='%d.%m.%Y') -> str:
return datetime.fromtimestamp(float(date)).strftime(fmt)

@app.errorhandler(401)
def unauthorized(e) -> flask.Response:
logger.warning(f'Unauthorized access: {flask.request.url} from {flask.request.remote_addr}')
return flask.redirect(flask.url_for('login'))

@app.errorhandler(403)
def unauthorized(e) -> flask.Response:
flask.session.clear()
logger.warning(f'Unauthorized access: {flask.request.url} from {flask.request.remote_addr}')
return flask.redirect(flask.url_for('login'))

@app.route('/')
@login_required()
def index() -> str:
if flask.session.get("user").is_admin:
return flask.render_template('index_admin.html', overdue_items=inventory.get_all_overdue())
return flask.render_template('index_student.html', all_groups=groups.get_all())

@app.route('/login')
def login() -> str | flask.Response:
if KIOSK_FQDN and flask.request.headers.get('Host') == KIOSK_FQDN:
flask.session['method'] = 'kiosk'
r = flask.request.referrer
if r and r != flask.url_for('login'):
return flask.redirect(r)
return flask.redirect(flask.url_for('index'))
return flask.render_template('login.html')

@app.route('/register')
@login_required()
def register() -> flask.Response:
user = flask.session.get("user")
if user.is_admin and not user.exists:
add_admin(flask.session.get("user").__dict__)

@app.template_filter('strftime')
def _jinja2_filter_datetime(date, fmt='%d.%m.%Y') -> str:
return parser.parse(date).strftime(fmt)


@app.template_filter('strfunixtime')
def _jinja2_filter_strftime(date, fmt='%d.%m.%Y') -> str:
return datetime.fromtimestamp(float(date)).strftime(fmt)


@app.errorhandler(401)
def unauthorized(e) -> flask.Response:
logger.warning(f'Unauthorized access: {flask.request.url} from {flask.request.remote_addr}')
return flask.redirect(flask.url_for('login'))


@app.errorhandler(403)
def unauthorized(e) -> flask.Response:
flask.session.clear()
logger.warning(f'Unauthorized access: {flask.request.url} from {flask.request.remote_addr}')
return flask.redirect(flask.url_for('login'))


@app.route('/')
@login_required()
def index() -> str:
if flask.session.get("user").is_admin:
return flask.render_template('index_admin.html', overdue_items=inventory.get_all_overdue())
return flask.render_template('index_student.html', all_groups=groups.get_all())


@app.route('/login')
def login() -> str | flask.Response:
if KIOSK_FQDN and flask.request.headers.get('Host') == KIOSK_FQDN:
flask.session['method'] = 'kiosk'
r = flask.request.referrer
if r and r != flask.url_for('login'):
return flask.redirect(r)
return flask.redirect(flask.url_for('index'))
return flask.render_template('login.html')


@app.route('/register')
@login_required()
def register() -> flask.Response:
user = flask.session.get("user")
if user.is_admin and not user.exists:
add_admin(flask.session.get("user").__dict__)

return flask.redirect(flask.url_for('index'))


@app.route('/logout')
def logout() -> flask.Response:
flask.session.clear()
return flask.redirect(flask.url_for('index'))


@app.route('/admin')
@login_required(admin_only=True)
def admin_settings() -> str:
return flask.render_template('admin_settings.html', all_groups=groups.get_all(),
all_categories=inventory.all_categories(),
all_emails=mail.get_all_emails(),
last_sent=mail.get_last_sent())


@app.route('/audits')
@login_required(admin_only=True)
def audits() -> str:
"""All audits in data/audits.log"""
log = open('data/audits.log', 'r').readlines()
log = [{
'timestamp': audit.split('|')[0].strip(),
'event': audit.split('|')[1].split(' - ')[0].strip(),
'message': ''.join(audit.split(' - ')[1:]).strip()
} for audit in log if audit.strip()]
return flask.render_template('audits.html', audits=log)


@app.route('/inventar')
@login_required(admin_only=True)
def inventar() -> str:
return flask.render_template('inventar.html', items=inventory.get_all())


@app.route('/inventar/add')
@login_required(admin_only=True)
def inventar_add() -> str:
return flask.render_template('inventar_add.html', categories=inventory.all_categories())


@app.route('/inventar/edit/<item_id>')
@login_required(admin_only=True)
def edit_item(item_id: str) -> str:
return flask.render_template('inventar_edit.html', item=inventory.get(item_id),
categories=inventory.all_categories())


@app.route('/inventar/print/<item_id>')
@login_required(admin_only=True)
def print_item(item_id: str) -> str:
return flask.render_template('inventar_print.html', item=inventory.get(item_id))


@app.route('/booking')
@login_required(admin_only=True)
def booking() -> str:
return flask.render_template('booking.html',
all_users=user.get_all_active_users(),
all_items=inventory.get_all())


@app.route('/innlevering')
@login_required(admin_only=True)
def innlevering() -> str:
return flask.render_template('innlevering.html',
unavailable_items=inventory.get_all_unavailable())


@app.route('/etikettserver')
@login_required(admin_only=True)
def labelserver() -> str:
return flask.render_template('labelserver.html', labelserver_url=LABEL_SERVER)


@app.route('/ansvarsavtale')
def responsibility() -> str:
return flask.render_template('responsibility.html')

@app.route('/logout')
def logout() -> flask.Response:
flask.session.clear()
return flask.redirect(flask.url_for('index'))

@app.route('/personvern')
def privacy() -> str:
return flask.render_template('privacy.html')
@app.route('/admin')
@login_required(admin_only=True)
def admin_settings() -> str:
return flask.render_template('admin_settings.html', all_groups=groups.get_all(),
all_categories=inventory.all_categories(),
all_emails=mail.get_all_emails(),
last_sent=mail.get_last_sent())

@app.route('/audits')
@login_required(admin_only=True)
def audits() -> str:
"""All audits in data/audits.log"""
log = open('data/audits.log', 'r').readlines()
log = [{
'timestamp': audit.split('|')[0].strip(),
'event': audit.split('|')[1].split(' - ')[0].strip(),
'message': ''.join(audit.split(' - ')[1:]).strip()
} for audit in log if audit.strip()]
return flask.render_template('audits.html', audits=log)

@app.route('/inventar')
@login_required(admin_only=True)
def inventar() -> str:
return flask.render_template('inventar.html', items=inventory.get_all())

@app.route('/inventar/add')
@login_required(admin_only=True)
def inventar_add() -> str:
return flask.render_template('inventar_add.html', categories=inventory.all_categories())

@app.route('/inventar/edit/<item_id>')
@login_required(admin_only=True)
def edit_item(item_id: str) -> str:
return flask.render_template('inventar_edit.html', item=inventory.get(item_id),
categories=inventory.all_categories())

@app.route('/inventar/print/<item_id>')
@login_required(admin_only=True)
def print_item(item_id: str) -> str:
return flask.render_template('inventar_print.html', item=inventory.get(item_id))

@app.route('/booking')
@login_required(admin_only=True)
def booking() -> str:
return flask.render_template('booking.html',
all_users=user.get_all_active_users(),
all_items=inventory.get_all())

@app.route('/innlevering')
@login_required(admin_only=True)
def innlevering() -> str:
return flask.render_template('innlevering.html',
unavailable_items=inventory.get_all_unavailable())

@app.route('/etikettserver')
@login_required(admin_only=True)
def labelserver() -> str:
return flask.render_template('labelserver.html', labelserver_url=LABEL_SERVER)

@app.route('/ansvarsavtale')
def responsibility() -> str:
return flask.render_template('responsibility.html')

@app.route('/personvern')
def privacy() -> str:
return flask.render_template('privacy.html')

return app


if __name__ == '__main__':
init_db()
app.run(host='0.0.0.0')
create_app().run(host='0.0.0.0')
2 changes: 1 addition & 1 deletion BookingSystem/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@


def read_sql_query(sql_name) -> str:
return Path(f'sql/{sql_name}').read_text()
return Path(f'{Path(__file__).parent}/sql/{sql_name}').read_text()


def add_admin(data_dict: dict) -> None:
Expand Down
Loading

0 comments on commit 73c69c0

Please sign in to comment.