Commit b48f3b14 authored by Barbora Kompišová's avatar Barbora Kompišová
Browse files

incomplete tests

parent 92612e43
Loading
Loading
Loading
Loading
+635 −6
Original line number Original line Diff line number Diff line
from portal.tools.logging import log
from portal.tools.logging import log
from portal.database.models import User
from portal.database.models import User, Course, Role, Group, Project, Submission

import pytest
from sqlalchemy import exc
import datetime


'''
# will be removed later, when javascript functionality is added
# will be removed later, when javascript functionality is added
def test_empty(app):
def test_empty(app):
    with app.test_client() as client:
    with app.test_client() as client:
        resp = client.get('/')
        resp = client.get('/')
        assert resp.status_code == 200
        assert resp.status_code == 200
        assert ('JavaScript' in resp.data.decode())
        assert ('JavaScript' in resp.data.decode())

'''

'''
def test_logging_levels():
def test_logging_levels():
    log.debug("debug level - should be displayed")
    log.debug("debug level - should be displayed")
    log.info("info level - should be displayed")
    log.info("info level - should be displayed")
'''




# Entity constraints & creation
def test_user_create_valid(session):
def test_user_create_valid(session):
    user = User(uco=123, email='foo', xlogin='xfoo')
    user = User(uco=123, email='foo', username='xfoo')
    session.add(user)
    session.flush()

    users = User.query.all()
    assert len(users) == 1
    assert user in users


def test_user_create_duplicate_email(session):
    user1 = User(uco=123, email='foo', username='xfoo')
    user2 = User(uco=456, email='foo', username='xfoo2')

    session.add_all([user1, user2])
    with pytest.raises(exc.IntegrityError):
        session.flush()


def user_update_duplicate_username(session):
    user1 = User(uco=123, email='foo', username='xfoo')
    user2 = User(uco=456, email='bar', username='xbar')
    session.add_all([user1, user2])
    session.flush()

    user2.username = user1.username
    with pytest.raises(exc.IntegrityError):
        session.flush()


def user_update_duplicate_uco(session):
    user1 = User(uco=123, email='foo', username='xfoo')
    user2 = User(uco=456, email='bar', username='xbar')
    session.add_all([user1, user2])
    session.flush()

    user2.uco = user1.uco
    with pytest.raises(exc.IntegrityError):
        session.flush()


def user_update_duplicate_email(session):
    user1 = User(uco=123, email='foo', username='xfoo')
    user2 = User(uco=456, email='bar', username='xbar')
    session.add_all([user1, user2])
    session.flush()

    user2.email = user1.email
    with pytest.raises(exc.IntegrityError):
        session.flush()


def test_course_create_valid(session):
    course = Course(name="C++", codename="PB161")
    session.add(course)
    session.flush()

    courses = Course.query.all()
    assert len(courses) == 1
    assert course in courses


def test_course_update_duplicate_name(session):
    course1 = Course(name="C++", codename="PB161")
    course2 = Course(name="C", codename="PB071")
    session.add_all([course1, course2])
    session.flush()

    course2.name = course1.name
    with pytest.raises(exc.IntegrityError):
        session.flush()


def test_course_update_duplicate_codename(session):
    course1 = Course(name="C++", codename="PB161")
    course2 = Course(name="C", codename="PB071")
    session.add_all([course1, course2])
    session.flush()

    course2.codename = course1.codename
    with pytest.raises(exc.IntegrityError):
        session.flush()


def test_group_create_valid(session):
    course = Course(name="C++", codename="PB161")
    group = Group(course=course, name="g1")
    # session.add(course)  # unnecessary, relationship takes care of persisting the linked Course entity
    session.add(group)
    session.flush()

    groups = Group.query.all()
    assert len(groups) == 1
    assert group in groups
    assert groups[0].course == course


def test_group_update_duplicate_name_1(session):
    course = Course(name="C++", codename="PB161")
    group1 = Group(course=course, name="g1")
    group2 = Group(course=course, name="g2")
    session.add_all([group1, group2])
    session.flush()

    group2.name = group1.name
    with pytest.raises(exc.IntegrityError):
        session.flush()


def test_group_update_duplicate_name_2(session):
    course1 = Course(name="C++", codename="PB161")
    course2 = Course(name="C", codename="PB071")
    group1 = Group(course=course1, name="g1")
    group2 = Group(course=course2, name="g1")
    session.add_all([group1, group2])
    session.flush()

    group2.course = group1.course
    with pytest.raises(exc.IntegrityError):
        session.flush()


def test_project_create_valid(session):
    course = Course(name="C++", codename="PB161")
    project = Project(course=course, name="p1", test_files_source="git repo")
    session.add(project)
    session.flush()

    projects = Project.query.all()
    assert len(projects) == 1
    assert project in projects
    assert projects[0].course == course


def test_project_update_duplicate_name_1(session):
    course = Course(name="C++", codename="PB161")
    project1 = Project(course=course, name="p1", test_files_source="git repo")
    project2 = Project(course=course, name="p2", test_files_source="git repo")
    session.add_all([project1, project2])
    session.flush()

    project2.name = project1.name
    with pytest.raises(exc.IntegrityError):
        session.flush()


def test_project_update_duplicate_name_2(session):
    course1 = Course(name="C++", codename="PB161")
    course2 = Course(name="C", codename="PB071")
    project1 = Project(course=course1, name="p1", test_files_source="git repo")
    project2 = Project(course=course2, name="p1", test_files_source="git repo")
    session.add_all([project1, project2])
    session.flush()

    project2.course = project1.course
    with pytest.raises(exc.IntegrityError):
        session.flush()


def test_role_create_valid(session):
    course = Course(name="C++", codename="PB161")
    role = Role(course=course, name='student')
    session.add(role)
    session.flush()

    roles = Role.query.all()
    assert len(roles) == 1
    assert role in roles
    assert roles[0].course == course


def test_role_create_duplicate_name(session):
    course = Course(name="C++", codename="PB161")
    role1 = Role(course=course, name='student')
    role2 = Role(course=course, name='student')
    session.add(course)
    with pytest.raises(exc.IntegrityError):
        session.flush()


def test_role_update_duplicate_name_1(session):
    course = Course(name="C++", codename="PB161")
    role1 = Role(course=course, name="p1")
    role2 = Role(course=course, name="p2")
    session.add_all([role1, role2])
    session.flush()

    role2.name = role1.name
    with pytest.raises(exc.IntegrityError):
        session.flush()


def test_role_update_duplicate_name_2(session):
    course1 = Course(name="C++", codename="PB161")
    course2 = Course(name="C", codename="PB071")
    role1 = Role(course=course1, name="p1")
    role2 = Role(course=course2, name="p1")
    session.add_all([role1, role2])
    session.flush()

    role2.course = role1.course
    with pytest.raises(exc.IntegrityError):
        session.flush()


def test_submission_create_valid(session):
    user = User(uco=123, email='foo', username='xfoo')
    course = Course(name="C++", codename="PB161")
    project = Project(course=course, name="p1", test_files_source="git repo")
    submission = Submission(user=user, project=project, processing_scheduled_for=datetime.datetime.now(), parameters="")
    session.add(submission)
    session.flush()

    submissions = Submission.query.all()
    assert len(submissions) == 1
    assert submission in submissions
    assert submissions[0].user == user


def test_submission_update_user(session):
    user1 = User(uco=123, email='foo', username='xfoo')
    user2 = User(uco=456, email='bar', username='xbar')
    course = Course(name="C++", codename="PB161")
    project = Project(course=course, name="p1", test_files_source="git repo")
    submission = Submission(user=user1, project=project, processing_scheduled_for=datetime.datetime.now(), parameters="")

    session.add_all([submission, user2])
    session.flush()

    submission.user = user2
    with pytest.raises(exc.SQLAlchemyError):
        session.flush()


# updated_at is changing; all entities share this behaviour
def test_updated_at(session):
    import time

    user = User(uco=123, email='foo', username='xfoo')
    session.add(user)
    session.add(user)
    session.commit()
    session.flush()
    assert user.created_at == user.updated_at

    time.sleep(2)
    user.name = "bar"
    session.flush()
    assert user.created_at < user.updated_at


# Relationships testing
# Course
def test_relation_course_group_create_duplicate_group_assign(session):
    course = Course(name="C++", codename="PB161")
    group = Group(course=course, name="g1")
    course.groups.append(group)
    session.add(course)
    session.add(group)
    session.flush()

    assert group.id is not None
    course_from_db = Course.query.filter_by(name="C++").first()
    assert group in course_from_db.groups
    assert len(course_from_db.groups) == 1


def test_relation_course_group_update_add_group(session):
    course = Course(name="C++", codename="PB161")
    group1 = Group(course=course, name="g1")
    session.add(course)
    session.add(group1)
    session.flush()

    group2 = Group(course=course, name="g2")
    assert group2.id is None
    session.add(group2)
    session.flush()
    assert group2.id is not None
    assert group2.id != group1.id

    assert len(Group.query.all()) == 2
    assert group2 in Group.query.all()
    course_from_db = Course.query.filter_by(name="C++").first()
    assert len(course_from_db.groups) == 2
    assert group1 in course_from_db.groups
    assert group2 in course_from_db.groups


# TODO remove this test? this should not be available, does not make sense
def test_relation_course_group_update_swap_group(session):
    course1 = Course(name="C++", codename="PB161")
    course2 = Course(name="C", codename="PB071")
    group = Group(course=course1, name="g1")
    session.add(course1)
    session.add(course2)
    session.add(group)
    session.flush()

    group.course = course2
    session.add(group)
    session.flush()

    assert len(course1.groups) == 0
    assert group in course2.groups
    assert len(course2.groups) == 1


def test_relation_course_group_delete_course(session):
    # propagating delete from parent entity (course) to child entity (group) by deleting the owning entity
    course1 = Course(name="C++", codename="PB161")
    course2 = Course(name="C", codename="PB071")
    group1 = Group(course=course1, name="g1")
    group2 = Group(course=course1, name="g2")
    group3 = Group(course=course2, name="g3")

    session.add_all([group1, group2, group3])
    session.flush()
    assert len(Group.query.all()) == 3
    assert len(Course.query.all()) == 2

    session.delete(course1)
    session.flush()
    assert len(Group.query.all()) == 1
    assert len(Course.query.all()) == 1


def test_relation_course_group_delete_group_from_course(session):
    # propagating delete from parent entity (course) to child entity (group) by deleting an item in parent collection
    course = Course(name="C++", codename="PB161")
    group1 = Group(course=course, name="g1")
    group2 = Group(course=course, name="g2")

    session.add_all([group1, group2])
    session.flush()
    assert len(Group.query.all()) == 2

    del course.groups[0]
    session.flush()
    assert len(Group.query.all()) == 1
    assert len(course.groups) == 1


def test_relation_course_group_delete_group_entity(session):
    course = Course(name="C++", codename="PB161")
    group1 = Group(course=course, name="g1")
    group2 = Group(course=course, name="g2")
    session.add(group1)
    session.add(group2)
    session.flush()

    session.delete(group1)
    # flush may not be necessary: ensures the appropriate change in FOREIGN_KEY on group,
    # but NOT the group collection present in course
    session.flush()
    # expire forces reloading of accessed attributes of 'course'.
    # See docs.sqlalchemy.org/en/latest/orm/session_basics.html
    # and http://docs.sqlalchemy.org/en/latest/orm/session_state_management.html#session-expire
    session.expire(course)
    assert group2 in course.groups
    assert len(course.groups) == 1


def test_relation_course_role_update_add_role(session):
    course = Course(name="C++", codename="PB161")
    role1 = Role(course=course, name='student')
    session.add(role1)
    session.flush()

    role2 = Role(course=course, name='teacher')
    # role2 is added to the session automatically because of cascade=save-update on course
    session.flush()

    roles = Role.query.all()
    assert len(roles) == 2
    assert role1 in roles
    assert role2 in roles
    assert len(Course.query.all()[0].roles) == 2


def test_relation_course_role_update_swap_role(session):
    course1 = Course(name="C++", codename="PB161")
    course2 = Course(name="C", codename="PB071")
    role = Role(course=course1, name='student')
    session.add(role)
    session.flush()
    assert role in course1.roles
    assert role not in course2.roles

    course2.roles.append(role)
    session.flush()

    assert len(Role.query.all()) == 1
    assert len(course1.roles) == 0
    assert len(course2.roles) == 1


def test_relation_course_role_update_null_course(session):
    course = Course(name="C++", codename="PB161")
    role1 = Role(course=course, name='student')
    role2 = Role(course=course, name='teacher')
    session.add(role1)
    session.flush()
    assert len(course.roles) == 2

    role1.course = None
    session.flush()

    assert role2 in course.roles
    assert len(course.roles) == 1


def test_relation_course_role_delete_course(session):
    course1 = Course(name="C++", codename="PB161")
    course2 = Course(name="C", codename="PB071")
    role1 = Role(course=course1, name='teacher')
    role2 = Role(course=course1, name='student')
    role3 = Role(course=course2, name='teacher')

    session.add_all([role1, role2, role3])
    session.flush()

    session.delete(course1)
    session.flush()
    assert len(Course.query.all()) == 1
    assert len(Role.query.all()) == 1
    assert role3 in course2.roles


def test_relation_course_role_delete_role_from_course(session):
    course1 = Course(name="C++", codename="PB161")
    role1 = Role(course=course1, name='student')
    role2 = Role(course=course1, name='teacher')
    session.add_all([role1, role2])
    session.flush()

    del course1.roles[1]
    session.flush()
    assert len(course1.roles) == 1
    assert len(Role.query.all()) == 1


def test_relation_course_role_delete_role_entity(session):
    course = Course(name="C++", codename="PB161")
    role1 = Role(course=course, name='student')
    role2 = Role(course=course, name='teacher')
    session.add_all([role1, role2])
    session.flush()

    session.delete(role2)
    session.flush()
    session.expire(course)

    assert len(Role.query.all()) == 1
    assert len(course.roles) == 1


def test_relation_course_project_update_add_project(session):
    course = Course(name="C++", codename="PB161")
    project1 = Project(course=course, name="p1", test_files_source="git repo")
    session.add(project1)
    session.flush()
    assert len(course.projects) == 1
    assert project1 in course.projects

    project2 = Project(course=course, name="p2", test_files_source="git repo")
    session.add(project2)
    session.flush()

    assert len(Project.query.all()) == 2
    assert len(course.projects) == 2
    assert project2 in course.projects


def test_relation_course_project_update_swap_project_from_project(session):
    course1 = Course(name="C++", codename="PB161")
    course2 = Course(name="C", codename="PB071")

    project = Project(course=course1, name="p1", test_files_source="git repo")
    session.add_all([project, course2])
    session.flush()
    assert project in course1.projects
    assert len(course2.projects) == 0

    project.course = course2
    session.flush()

    assert project in course2.projects
    assert len(course1.projects) == 0


def test_relation_course_project_update_swap_project_from_course(session):
    course1 = Course(name="C++", codename="PB161")
    course2 = Course(name="C", codename="PB071")

    project = Project(course=course1, name="p1", test_files_source="git repo")
    session.add_all([project, course2])
    session.flush()
    assert project in course1.projects
    assert len(course2.projects) == 0

    course2.projects.append(project)
    session.flush()

    assert project in course2.projects
    assert len(course1.projects) == 0


def test_relation_course_project_update_null_course(session):
    course = Course(name="C++", codename="PB161")
    project1 = Project(course=course, name="p1", test_files_source="git repo")
    project2 = Project(course=course, name="p2", test_files_source="git repo")
    session.add_all([project1, project2])
    session.flush()

    assert len(course.projects) == 2
    assert project1 in course.projects

    project1.course = None
    session.flush()

    assert len(course.projects) == 1
    assert project2 in course.projects


def test_relation_course_project_delete_course(session):
    course1 = Course(name="C++", codename="PB161")
    course2 = Course(name="C", codename="PB071")
    project1 = Project(course=course1, name="p1", test_files_source="git repo")
    project2 = Project(course=course1, name="p2", test_files_source="git repo")
    project3 = Project(course=course2, name="p3", test_files_source="git repo")

    session.add_all([project1, project2, project3])
    session.flush()

    session.delete(course1)
    session.flush()
    assert len(Course.query.all()) == 1
    assert len(Project.query.all()) == 1
    assert project3 in course2.projects


def test_relation_course_project_delete_project_from_course(session):
    course1 = Course(name="C++", codename="PB161")
    course2 = Course(name="C", codename="PB071")
    project1 = Project(course=course1, name="p1", test_files_source="git repo")
    project2 = Project(course=course1, name="p2", test_files_source="git repo")
    project3 = Project(course=course2, name="p3", test_files_source="git repo")

    session.add_all([project1, project2, project3])
    session.flush()

    del course1.projects[1]
    session.flush()

    assert len(course1.projects) == 1
    assert project1 in course1.projects
    assert len(Project.query.all()) == 2


def test_relation_course_project_delete_project_entity(session):
    course1 = Course(name="C++", codename="PB161")
    course2 = Course(name="C", codename="PB071")
    project1 = Project(course=course1, name="p1", test_files_source="git repo")
    project2 = Project(course=course1, name="p2", test_files_source="git repo")
    project3 = Project(course=course2, name="p3", test_files_source="git repo")

    session.add_all([project1, project2, project3])
    session.flush()

    session.delete(project2)
    session.flush()
    session.expire(course1)

    assert len(course1.projects) == 1
    assert project1 in course1.projects
    assert len(Project.query.all()) == 2


# user-role-course
def test_relation_user_role(session):
    user1 = User(uco=123, email="foo", username="xfoo")
    user2 = User(uco=456, email="bar", username="xbar")
    course1 = Course(name="C++", codename="PB161")
    course2 = Course(name="C", codename="PB071")
    role1 = Role(course=course1, name='teacher')
    role2 = Role(course=course2, name='teacher')
    role1.users.append(user1)
    role1.users.append(user2)
    role2.users.append(user1)

    session.add_all([role1, role2])
    session.flush()

    assert len(Role.query.all()) == 2
    assert role1 in user1.roles
    assert role1 in user2.roles
    assert course1 in user1.courses
    assert course1 in user2.courses
    assert role2 in user1.roles
    assert role2 not in user2.roles
    assert course2 in user1.courses
    assert course2 not in user2.courses


def test_relation_user_roles_add_role_same_course(session):
    user = User(uco=123, email="foo", username="xfoo")
    course = Course(name="C++", codename="PB161")
    role1 = Role(course=course, name='student')
    role2 = Role(course=course, name='teacher')
    # a user may have several roles in a course
    session.add_all([role1, role2, user])
    session.flush()

    role1.users.append(user)
    session.flush()

    assert len(user.roles) == 1
    assert len(role1.users) == 1
    assert len(role2.users) == 0
    assert role1 in user.roles
    assert len(user.courses) == 1


    role2.users.append(user)
    session.flush()
    session.expire(user)


    assert len(user.roles) == 2
    assert len(user.courses) == 1
    assert user in role2.users
    assert user in role1.users
    assert role2 in user.roles