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

Created test for dashboard. #105

Merged
merged 1 commit into from
Feb 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,5 @@ build/

test/*.db
test/meta

*.db
6 changes: 3 additions & 3 deletions config.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@

import os

from utils import env
from distutils.util import strtobool
from utils import env, strtobool


# Application Name
#
Expand Down Expand Up @@ -105,4 +105,4 @@
'scope': 'user:login,name',
}

PASSCODE_LENGTH = env('MIN_PASSCODE_LENGTH', 6)
PASSCODE_LENGTH = env('MIN_PASSCODE_LENGTH', 6)
2 changes: 1 addition & 1 deletion console
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ if __name__ == "__main__":
exit()

if args.sync:
from config import META, DATABASE_URL
from config import DATABASE_URL, META
from elekto.models import meta
from elekto.models.sql import create_session
from elekto.models.utils import sync
Expand Down
19 changes: 11 additions & 8 deletions elekto/models/sql.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@
import uuid
import sqlalchemy as S

from sqlalchemy.orm import sessionmaker, scoped_session
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, scoped_session, declarative_base
from sqlalchemy.types import TypeDecorator, CHAR
from sqlalchemy import event

Expand Down Expand Up @@ -88,10 +87,11 @@ def update_schema(engine, schema_version):

if db_schema.has_table("election"):
if db_schema.has_table("schema_version"):
db_version = engine.execute('select version from schema_version').scalar()
if db_version is None:
""" intialize the table, if necessary """
engine.execute('insert into schema_version ( version ) values ( 2 )')
with engine.connect() as connection:
db_version = connection.execute(S.text('select version from schema_version')).scalar()
if db_version is None:
""" intialize the table, if necessary """
connection.execute(S.text('insert into schema_version ( version ) values ( 2 )'))
else:
""" new, empty db """
return schema_version
Expand All @@ -104,7 +104,7 @@ def update_schema(engine, schema_version):
db_version = update_schema_2(engine)
continue

return db_version;
return db_version


def update_schema_2(engine):
Expand All @@ -131,6 +131,9 @@ def update_schema_2(engine):

return 2

def drop_all(url: str):
engine = S.create_engine(url)
BASE.metadata.drop_all(bind=engine)

class UUID(TypeDecorator):
"""Platform-independent UUID type.
Expand Down Expand Up @@ -175,7 +178,7 @@ class Version(BASE):

@event.listens_for(Version.__table__, 'after_create')
def create_version(target, connection, **kwargs):
connection.execute(f"INSERT INTO schema_version ( version ) VALUES ( {schema_version} )")
connection.execute(S.text(f"INSERT INTO schema_version ( version ) VALUES ( {schema_version} )"))

class User(BASE):
"""
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ psycopg2==2.9.10
pycparser==2.22
pynacl==1.5.0
pytest==8.3.4
pytest-mock==3.14.0
python-dateutil==2.9.0.post0
python-dotenv==1.0.1
pytz==2024.2
Expand Down
62 changes: 62 additions & 0 deletions test/test_controllers_elections.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
from datetime import datetime, timedelta
from flask.testing import FlaskClient
import pytest
from pytest_mock import MockerFixture

from elekto import APP, SESSION, constants
from elekto.models import meta
from elekto.models.sql import User, drop_all, migrate

@pytest.fixture(scope="module", autouse=True)
def reset_db():
with APP.app_context():
drop_all(APP.config.get('DATABASE_URL'))


@pytest.fixture()
def client():
with APP.app_context():
migrate(APP.config.get('DATABASE_URL'))
yield APP.test_client()
SESSION.close()
drop_all(APP.config.get('DATABASE_URL'))

def test_dashboard(client: FlaskClient):
token="token"
with APP.app_context():
SESSION.add(User(username="carson",
name="Carson Weeks",
token=token,
token_expires_at=datetime.max))
SESSION.commit()
with client.session_transaction() as session:
session[constants.AUTH_STATE] = token
response = client.get("/app")
assert response.status_code == 200
assert b'Welcome! Carson Weeks' in response.data
assert b'Sit back and Relax, there is not to do yet.' in response.data

def test_unauthenticated_dashboard(client: FlaskClient):
with client.session_transaction() as session:
session[constants.AUTH_STATE] = None
response = client.get("/app")
assert response.status_code == 302

def test_elections_running_dashboard(client: FlaskClient, mocker: MockerFixture):
mocker.patch("elekto.meta.Election.where", return_value=[{"name": "Demo Election",
"organization": "kubernetes",
"start_datetime": datetime.min,
"end_datetime": datetime.max}])
token="token"
with APP.app_context():
SESSION.add(User(username="carson",
name="Carson Weeks",
token=token,
token_expires_at=datetime.max))
SESSION.commit()
with client.session_transaction() as session:
session[constants.AUTH_STATE] = token
response = client.get("/app")
assert response.status_code == 200
assert b"Demo Election" in response.data
assert not b"Sit back and Relax, there is not to do yet." in response.data
2 changes: 0 additions & 2 deletions test/test_core_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ def test_schulze_d():
}

result = schulze_d(candidates, ballots)
print(result)
assert result == expected_d

def test_schulze_p():
Expand Down Expand Up @@ -67,7 +66,6 @@ def test_schulze_p():
}

result = schulze_p(candidates, d)
print(result)
assert result == expected_p

def test_schulze_rank_simple():
Expand Down
10 changes: 8 additions & 2 deletions utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,15 @@
from dotenv import load_dotenv, set_key

# Load the custom environment file into the program
targetenv = '.env.testing' if os.getenv('TESTING') else '.env'
load_dotenv(os.path.join(os.path.dirname(__file__), targetenv))
isTesting = os.getenv('TESTING') or "PYTEST_VERSION" in os.environ
targetenv = ".env.testing" if isTesting else ".env"
load_dotenv(os.path.join(os.path.dirname(__file__), targetenv), override=True)

def strtobool(value: str) -> bool:
value = value.lower()
if value in ("y", "yes", "on", "1", "true", "t"):
return True
return False

def generate_app_key():
key = os.urandom(32).hex()
Expand Down