200 lines
6.1 KiB
Python
200 lines
6.1 KiB
Python
import datetime
|
|
|
|
import pandas as pd
|
|
import pytest
|
|
from flask import current_app
|
|
|
|
from app.base.mode import ModeGroups
|
|
from app.base.utils import is_allowed_extensions, order_by_column_name, paginate_models
|
|
from app.coordinator.exceptions import InvalidNameOrTypeHeaderException
|
|
from app.coordinator.utils import (
|
|
check_columns,
|
|
generate_csv,
|
|
generate_range_dates,
|
|
get_duration_time,
|
|
map_project_supervisors,
|
|
parse_csv,
|
|
)
|
|
from app.dependencies import db
|
|
from app.students.models import Group, Student
|
|
|
|
|
|
def test_is_allowed_extensions(test_app) -> None:
|
|
with test_app.app_context():
|
|
for ext in current_app.config.get("ALLOWED_EXTENSIONS"):
|
|
assert is_allowed_extensions(f"file.{ext}") is True
|
|
|
|
|
|
def test_is_allowed_extensions_with_invalid_extensions(test_app) -> None:
|
|
with test_app.app_context():
|
|
assert is_allowed_extensions("file.invalid_ext") is False
|
|
assert is_allowed_extensions("file") is False
|
|
|
|
|
|
def test_order_by_column_name_ascending_mode(test_app) -> None:
|
|
with test_app.app_context():
|
|
query = order_by_column_name(Student.query, "index", "desc")
|
|
assert 'ORDER BY students."index"' in str(query)
|
|
|
|
|
|
def test_order_by_column_name_descending_mode(test_app) -> None:
|
|
with test_app.app_context():
|
|
query = order_by_column_name(Student.query, "index", "desc")
|
|
assert 'ORDER BY students."index" DESC' in str(query)
|
|
|
|
|
|
def test_paginate_models(test_app_ctx_with_db) -> None:
|
|
with test_app_ctx_with_db:
|
|
st = Student(
|
|
index=123456,
|
|
first_name="Dominic",
|
|
last_name="Smith",
|
|
email="xxx@gmail.com",
|
|
)
|
|
st1 = Student(
|
|
index=123457,
|
|
first_name="John",
|
|
last_name="Newton",
|
|
email="zzz@gmail.com",
|
|
)
|
|
db.session.add_all([st, st1])
|
|
db.session.commit()
|
|
result = paginate_models(1, Student.query, 1)
|
|
|
|
items = result.get("items", [])
|
|
max_pages = result.get("max_pages", 0)
|
|
|
|
assert len(items) == 1
|
|
assert max_pages == 2
|
|
|
|
|
|
def test_check_columns() -> None:
|
|
dummy_data = {
|
|
"NAZWISKO": ["Smith"],
|
|
"IMIE": ["Dominic"],
|
|
"INDEKS": [343433],
|
|
"EMAIL": ["domsmi@gmail.com"],
|
|
}
|
|
df = pd.DataFrame(data=dummy_data)
|
|
assert check_columns(df) is True
|
|
|
|
|
|
def test_check_columns_with_invalid_column_names() -> None:
|
|
dummy_data = {"col1": [1, 2], "col2": [2, 3]}
|
|
df = pd.DataFrame(data=dummy_data)
|
|
assert check_columns(df) is False
|
|
|
|
|
|
def test_check_columns_with_invalid_column_types() -> None:
|
|
dummy_data = {
|
|
"NAZWISKO": [999],
|
|
"IMIE": ["Dominic"],
|
|
"INDEKS": [343433],
|
|
"EMAIL": ["domsmi@gmail.com"],
|
|
}
|
|
df = pd.DataFrame(data=dummy_data)
|
|
assert check_columns(df) is False
|
|
|
|
|
|
def get_path_to_fake_data(filename: str) -> str:
|
|
base_dir = current_app.config.get("BASE_DIR", "/")
|
|
return base_dir / "tests" / "data" / filename
|
|
|
|
|
|
def test_parse_csv(test_app) -> None:
|
|
with test_app.app_context():
|
|
with open(get_path_to_fake_data("students.csv")) as f:
|
|
students = sorted(list(parse_csv(f, 1)), key=lambda s: s.index)
|
|
indexes = [452790 + i for i in range(3)]
|
|
assert len(students) == len(indexes)
|
|
for st, idx in zip(students, indexes):
|
|
assert st.index == idx
|
|
|
|
|
|
def test_parse_csv_with_invalid_column_header_name_in_csv_file(test_app) -> None:
|
|
with test_app.app_context():
|
|
with open(get_path_to_fake_data("students_column_name.csv")) as f:
|
|
with pytest.raises(InvalidNameOrTypeHeaderException):
|
|
parse_csv(f, 1)
|
|
|
|
|
|
def test_parse_csv_with_invalid_column_type_in_csv_file(test_app) -> None:
|
|
with test_app.app_context():
|
|
with open(get_path_to_fake_data("students_column_type.csv")) as f:
|
|
with pytest.raises(InvalidNameOrTypeHeaderException):
|
|
parse_csv(f, 1)
|
|
|
|
|
|
def test_generate_range_dates() -> None:
|
|
start_date = datetime.datetime(2022, 2, 2, 8, 0, 0, 0)
|
|
end_date = datetime.datetime(2022, 2, 2, 12, 0, 0, 0)
|
|
step = 30
|
|
expected_dates_amount = (end_date - start_date).total_seconds() / 60.0 / step
|
|
dates = list(generate_range_dates(start_date, end_date, step))
|
|
|
|
assert expected_dates_amount == len(dates)
|
|
|
|
for date in dates:
|
|
assert start_date <= date < end_date
|
|
|
|
|
|
def test_generate_csv() -> None:
|
|
students_data = [
|
|
{
|
|
"first_name": "Dominic",
|
|
"last_name": "Smith",
|
|
"email": "xxe@gmail.com",
|
|
"index": 123456,
|
|
},
|
|
{
|
|
"first_name": "Matthew",
|
|
"last_name": "Cash",
|
|
"email": "zze@gmail.com",
|
|
"index": 123455,
|
|
},
|
|
{
|
|
"first_name": "Martin",
|
|
"last_name": "Rose",
|
|
"email": "nne@gmail.com",
|
|
"index": 123446,
|
|
},
|
|
]
|
|
|
|
students = [Student(**data) for data in students_data]
|
|
gr1 = Group(name="new-project")
|
|
gr2 = Group(name="system-pri")
|
|
gr1.students.append(students[0])
|
|
gr1.students.append(students[1])
|
|
gr2.students.append(students[2])
|
|
|
|
students_and_groups = [
|
|
(students[0], gr1),
|
|
(students[1], gr1),
|
|
(students[2], gr2),
|
|
]
|
|
generated_csv = generate_csv(students_and_groups)
|
|
for data in students_data:
|
|
for value in data.values():
|
|
assert str(value) in generated_csv
|
|
|
|
|
|
def test_map_project_supervisors() -> None:
|
|
project_supervisors_id = [(1, 2), (2, 3), (3, 7)]
|
|
groups = []
|
|
for i in range(3):
|
|
for _, ps_id in project_supervisors_id:
|
|
groups.append(Group(project_supervisor_id=ps_id))
|
|
|
|
mapped_ps = map_project_supervisors(
|
|
sorted(groups, key=lambda g: g.project_supervisor_id)
|
|
)
|
|
for expected_id, ps_id in project_supervisors_id:
|
|
assert mapped_ps[ps_id] == expected_id
|
|
|
|
|
|
def test_get_duration_time() -> None:
|
|
assert get_duration_time(ModeGroups.STATIONARY.value) == 30
|
|
assert get_duration_time(ModeGroups.NON_STATIONARY.value) == 20
|
|
assert get_duration_time(ModeGroups.ENGLISH_SPEAKING_STATIONARY.value) == 30
|
|
assert get_duration_time("invalid value") is None
|