From 4991b3f7110ff24414b4481d86dc8ec0b0871ee4 Mon Sep 17 00:00:00 2001 From: Aron Buzogany <108480125+AronBuzogany@users.noreply.github.com> Date: Sat, 24 Feb 2024 10:49:13 +0100 Subject: [PATCH] Workflows/backend/linting isnt applied recursively (#25) * Fixes #24 * linting: added docs and removed trailing whitespaces * fixed: linting * added lint configuration file * added special linting rules where necessary --- .github/workflows/ci-tests.yml | 2 +- backend/project/endpoints/index.py | 16 ++++++---- backend/project/models/course_relations.py | 3 -- backend/project/models/courses.py | 3 +- backend/project/models/projects.py | 3 +- backend/project/models/submissions.py | 3 +- backend/project/models/users.py | 2 +- backend/pylintrc | 10 +++++++ backend/tests/conftest.py | 4 +-- backend/tests/models/__index__.py | 0 backend/tests/models/conftest.py | 29 +++++++++++++------ backend/tests/models/course_test.py | 8 +++-- .../models/projects_and_submissions_test.py | 17 +++++++---- backend/tests/models/users_test.py | 8 ++++- 14 files changed, 71 insertions(+), 37 deletions(-) create mode 100644 backend/pylintrc create mode 100644 backend/tests/models/__index__.py diff --git a/.github/workflows/ci-tests.yml b/.github/workflows/ci-tests.yml index aa79f382..10a23a0f 100644 --- a/.github/workflows/ci-tests.yml +++ b/.github/workflows/ci-tests.yml @@ -57,6 +57,6 @@ jobs: - name: Run linting working-directory: ./backend - run: pylint ./*/*.py + run: find . -type f -name "*.py" | xargs pylint diff --git a/backend/project/endpoints/index.py b/backend/project/endpoints/index.py index e5b68473..384cefd9 100644 --- a/backend/project/endpoints/index.py +++ b/backend/project/endpoints/index.py @@ -1,4 +1,7 @@ -"""Index api point""" +""" +This is the index endpoint file. It contains the index endpoint of the API as specified by OpenAPI. +""" + from flask import Blueprint from flask_restful import Resource @@ -6,12 +9,15 @@ class Index(Resource): - """Api endpoint for the / route""" + """ + Subclass of restfull Resource, used to define the index endpoint of the API. + """ def get(self): - """Example of an api endpoint function that will respond to get requests made to / - return a json data structure with key Message and value Hello World!""" - return {"Message": "Hello World!"} + """ + Implementation of the GET method for the index endpoint. Returns the OpenAPI object. + """ + return {"Message": "Hello World!"} index_bp.add_url_rule("/", view_func=Index.as_view("index")) diff --git a/backend/project/models/course_relations.py b/backend/project/models/course_relations.py index 0677ef54..c53807b6 100644 --- a/backend/project/models/course_relations.py +++ b/backend/project/models/course_relations.py @@ -1,10 +1,7 @@ """Models for relation between users and courses""" -# pylint: disable=too-few-public-methods from sqlalchemy import Integer, Column, ForeignKey, PrimaryKeyConstraint, String from project import db -from project.models.users import Users -from project.models.courses import Courses class BaseCourseRelation(db.Model): """Base class for course relation models, diff --git a/backend/project/models/courses.py b/backend/project/models/courses.py index 0881ca56..2b208b4c 100644 --- a/backend/project/models/courses.py +++ b/backend/project/models/courses.py @@ -1,8 +1,7 @@ """The Courses model""" -# pylint: disable=too-few-public-methods + from sqlalchemy import Integer, Column, ForeignKey, String from project import db -from project.models.users import Users class Courses(db.Model): """This class described the courses table, diff --git a/backend/project/models/projects.py b/backend/project/models/projects.py index a64f6082..0dd37911 100644 --- a/backend/project/models/projects.py +++ b/backend/project/models/projects.py @@ -1,8 +1,7 @@ """Model for projects""" -# pylint: disable=too-few-public-methods + from sqlalchemy import ARRAY, Boolean, Column, DateTime, ForeignKey, Integer, String, Text from project import db -from project.models.courses import Courses class Projects(db.Model): """This class describes the projects table, diff --git a/backend/project/models/submissions.py b/backend/project/models/submissions.py index f9de28b4..97e8762c 100644 --- a/backend/project/models/submissions.py +++ b/backend/project/models/submissions.py @@ -1,8 +1,7 @@ """Model for submissions""" -# pylint: disable=too-few-public-methods + from sqlalchemy import Column,String,ForeignKey,Integer,CheckConstraint,DateTime,Boolean from project import db -from project.models.users import Users class Submissions(db.Model): """This class describes the submissions table, diff --git a/backend/project/models/users.py b/backend/project/models/users.py index c5af5287..c3ea45c0 100644 --- a/backend/project/models/users.py +++ b/backend/project/models/users.py @@ -1,5 +1,5 @@ """Model for users""" -# pylint: disable=too-few-public-methods + from sqlalchemy import Boolean, Column, String from project import db diff --git a/backend/pylintrc b/backend/pylintrc new file mode 100644 index 00000000..83eff274 --- /dev/null +++ b/backend/pylintrc @@ -0,0 +1,10 @@ +[MASTER] +init-hook='import sys; sys.path.append(".")' + +[test-files:*_test.py] +disable= + W0621, # Redefining name %r from outer scope (line %s) + +[modules:project/modules/*] +disable= + R0903 # Too few public methods (modules don't require us to have public methods) diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index 582991ed..010ef293 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -8,11 +8,11 @@ def app(): Returns: Flask -- A Flask application instance """ - app = create_app() # pylint: disable=redefined-outer-name ; fixture testing requires the same name to be used + app = create_app() yield app @pytest.fixture -def client(app): # pylint: disable=redefined-outer-name ; fixture testing requires the same name to be used +def client(app): """A fixture that creates a test client for the app. Arguments: app {Flask} -- A Flask application instance diff --git a/backend/tests/models/__index__.py b/backend/tests/models/__index__.py new file mode 100644 index 00000000..e69de29b diff --git a/backend/tests/models/conftest.py b/backend/tests/models/conftest.py index 64e4461c..150d433e 100644 --- a/backend/tests/models/conftest.py +++ b/backend/tests/models/conftest.py @@ -1,19 +1,19 @@ """ - +Configuration for the models tests. Contains all the fixtures needed for multiple models tests. """ + import os +from datetime import datetime from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker -from datetime import datetime +from sqlalchemy.engine.url import URL +from dotenv import load_dotenv +import pytest from project import db from project.models.courses import Courses from project.models.course_relations import CourseAdmins, CourseStudents from project.models.projects import Projects -from project.models.submissions import Submissions from project.models.users import Users -from sqlalchemy.engine.url import URL -from dotenv import load_dotenv -import pytest load_dotenv() @@ -35,6 +35,8 @@ @pytest.fixture def db_session(): + """Create a new database session for a test. + After the test, all changes are rolled back and the session is closed.""" db.metadata.create_all(engine) session = Session() yield session @@ -47,26 +49,31 @@ def db_session(): @pytest.fixture def valid_user(): + """A valid user for testing""" user = Users(uid="student", is_teacher=False, is_admin=False) - return user + return user @pytest.fixture def teachers(): + """A list of 10 teachers for testing""" users = [Users(uid=str(i), is_teacher=True, is_admin=False) for i in range(10)] return users @pytest.fixture def course_teacher(): + """A user that's a teacher for for testing""" sel2_teacher = Users(uid="Bart", is_teacher=True, is_admin=False) return sel2_teacher - + @pytest.fixture def course(course_teacher): + """A course for testing, with the course teacher as the teacher.""" sel2 = Courses(name="Sel2", teacher=course_teacher.uid) return sel2 @pytest.fixture def course_students(): + """A list of 5 students for testing.""" students = [ Users(uid="student_sel2_" + str(i), is_teacher=False, is_admin=False) for i in range(5) @@ -75,6 +82,7 @@ def course_students(): @pytest.fixture def course_students_relation(course,course_students): + """A list of 5 course relations for testing.""" course_relations = [ CourseStudents(course_id=course.course_id, uid=course_students[i].uid) for i in range(5) @@ -83,16 +91,19 @@ def course_students_relation(course,course_students): @pytest.fixture def assistent(): + """An assistent for testing.""" assist = Users(uid="assistent_sel2") return assist @pytest.fixture() def course_admin(course,assistent): + """A course admin for testing.""" admin_relation = CourseAdmins(uid=assistent.uid, course_id=course.course_id) return admin_relation @pytest.fixture() -def valid_project(course): +def valid_project(): + """A valid project for testing.""" deadline = datetime(2024, 2, 25, 12, 0, 0) # February 25, 2024, 12:00 PM project = Projects( title="Project", diff --git a/backend/tests/models/course_test.py b/backend/tests/models/course_test.py index d8b92e1a..20898db8 100644 --- a/backend/tests/models/course_test.py +++ b/backend/tests/models/course_test.py @@ -1,6 +1,6 @@ +"""Test module for the Courses model""" import pytest from sqlalchemy.exc import IntegrityError -from psycopg2.errors import ForeignKeyViolation from project.models.courses import Courses from project.models.users import Users from project.models.course_relations import CourseAdmins, CourseStudents @@ -47,7 +47,7 @@ def test_foreignkey_coursestudents_uid( db_session.add_all(course_students_relation) db_session.commit() - def test_correct_courserelations( + def test_correct_courserelations( # pylint: disable=too-many-arguments ; all arguments are needed for the test self, db_session, course, @@ -57,7 +57,9 @@ def test_correct_courserelations( assistent, course_admin, ): - """Tests if we get the expected results for correct usage of CourseStudents and CourseAdmins""" + """Tests if we get the expected results for + correct usage of CourseStudents and CourseAdmins""" + db_session.add(course_teacher) db_session.commit() diff --git a/backend/tests/models/projects_and_submissions_test.py b/backend/tests/models/projects_and_submissions_test.py index e79eaf93..5f20aa1c 100644 --- a/backend/tests/models/projects_and_submissions_test.py +++ b/backend/tests/models/projects_and_submissions_test.py @@ -1,14 +1,19 @@ +"""This module tests the Projects and Submissions model""" from datetime import datetime import pytest from sqlalchemy.exc import IntegrityError -from project.models.courses import Courses -from project.models.course_relations import CourseAdmins, CourseStudents from project.models.projects import Projects from project.models.submissions import Submissions -from project.models.users import Users -class TestProjectsAndSubmissionsModel: - def test_deadline(self,db_session,course,course_teacher,valid_project,valid_user): +class TestProjectsAndSubmissionsModel: # pylint: disable=too-few-public-methods + """Test class for the database models of projects and submissions""" + def test_deadline(self,db_session, # pylint: disable=too-many-arguments ; all arguments are needed for the test + course, + course_teacher, + valid_project, + valid_user): + """Tests if the deadline is correctly set + and if the submission is correctly connected to the project""" db_session.add(course_teacher) db_session.commit() db_session.add(course) @@ -55,4 +60,4 @@ def test_deadline(self,db_session,course,course_teacher,valid_project,valid_user ) assert submission_check.grading == 15 assert submission.grading == 15 - # Interesting! all the model objects are connected \ No newline at end of file + # Interesting! all the model objects are connected diff --git a/backend/tests/models/users_test.py b/backend/tests/models/users_test.py index e9e1acaf..efc7f579 100644 --- a/backend/tests/models/users_test.py +++ b/backend/tests/models/users_test.py @@ -1,3 +1,6 @@ +""" +This file contains the tests for the Users model. +""" from project.models.users import Users @@ -5,15 +8,18 @@ class TestUserModel: """Test class for the database models""" def test_valid_user(self, db_session, valid_user): + """Tests if a valid user can be added to the database.""" db_session.add(valid_user) db_session.commit() assert valid_user in db_session.query(Users).all() def test_is_teacher(self, db_session, teachers): + """Tests if the is_teacher field is correctly set to True + for the teachers when added to the database.""" db_session.add_all(teachers) db_session.commit() teacher_count = 0 for usr in db_session.query(Users).filter_by(is_teacher=True): teacher_count += 1 assert usr.is_teacher - assert teacher_count == 10 \ No newline at end of file + assert teacher_count == 10