Skip to content
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
26 changes: 26 additions & 0 deletions .github/workflows/python-app.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Application Tests

on:
pull_request:
branches: [ "main" ]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6

- name: Set up Python 3.13
uses: actions/setup-python@v5
with:
python-version: "3.13"

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt

- name: Run tests
Comment on lines +21 to +23
run: |
python -m unittest tests.selenium_tests -v
python -m unittest tests.unit_tests -v
5 changes: 3 additions & 2 deletions app/controllers.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,10 @@ def create_new_group(
return new_group

def check_valid_student(expected_number, student_number, student_id: Optional[str]):
# print(expected_number, student_number, student_id, student_id is not None or student_id != '')
if student_number > expected_number:
if student_id is not None:
raise ValueError(f"Student {student_number} should not be provided for a group of {expected_number} members.")
# if student_id is not None or student_id != '':
# raise ValueError(f"Student {student_number} should not be provided for a group of {expected_number} members.")
return
Comment on lines 49 to 54
Comment on lines 49 to 54

if not student_id:
Expand Down
8 changes: 4 additions & 4 deletions app/templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ <h1 class="class1 h1">Group project sign-up</h1>
{% for group in all_groups %}
<tr>
<td>{{group.group_id}}</td>
<td>{{group.student1}}</td>
<td>{{group.student2}}</td>
<td>{{group.student3}}</td>
<td>{{group.student4}}</td>
<td id="{{group.student1}}">{{group.student1}}</td>
<td id="{{group.student2}}">{{group.student2}}</td>
<td id="{{group.student3}}">{{group.student3}}</td>
<td id="{{group.student4}}">{{group.student4}}</td>
Comment on lines +47 to +50
<td>
<form action="{{ url_for('main.delete_group', group_id=group.group_id) }}" method="POST">
<input type="submit" value="Delete" class="btn btn-danger" />
Expand Down
24 changes: 24 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,31 @@
alembic==1.18.4
attrs==26.1.0
blinker==1.9.0
certifi==2026.4.22
click==8.3.3
Flask==3.1.3
Flask-Migrate==4.1.0
Flask-SQLAlchemy==3.1.1
Flask-WTF==1.3.0
greenlet==3.5.0
h11==0.16.0
idna==3.13
itsdangerous==2.2.0
Jinja2==3.1.6
Mako==1.3.12
MarkupSafe==3.0.3
outcome==1.3.0.post0
PySocks==1.7.1
python-dotenv==1.2.2
selenium==4.43.0
sniffio==1.3.1
sortedcontainers==2.4.0
SQLAlchemy==2.0.49
trio==0.33.0
trio-websocket==0.12.2
typing_extensions==4.15.0
urllib3==2.7.0
websocket-client==1.9.0
Werkzeug==3.1.8
wsproto==1.3.2
WTForms==3.2.2
50 changes: 48 additions & 2 deletions tests/selenium_tests.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@

import multiprocessing
import time
from unittest import TestCase

from flask import url_for
Expand All @@ -8,6 +9,9 @@
from app.config import TestConfig
from app.models import Group, Student, create_test_data
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

localHost = "http://127.0.0.1:5000/"

Expand All @@ -34,5 +38,47 @@ def tearDown(self):
self.app_context.pop()
return super().tearDown()

def test_password_hashing(self):
self.driver.get(localHost)
def test_group_creation(self):
page = CreateGroupPage(self.driver).set_group_members("3").set_student1("12345678").set_student2("87654321")

self.driver.get(localHost)
Comment on lines +41 to +44

self.driver.find_element(By.ID, "student3").send_keys("11223344")

self.driver.find_element(By.ID, "submitBtn").click()

# Wait for the page to reload and the new group to be displayed
WebDriverWait(self.driver, timeout=10).until(
EC.presence_of_element_located((By.ID, "12345678"))
)

student1_element = self.driver.find_element(By.ID, "12345678")
self.assertIsNotNone(student1_element)

# Assert that the student1 element contains the correct text
self.assertEqual(student1_element.text, "12345678", f"Expected student1 element to contain '12345678', but got '{student1_element.text}'")


def test_invalid_group_creation(self):
self.driver.find_element(By.ID, "groupMembers").send_keys("4")
self.driver.find_element(By.ID, "student1").send_keys("12345678")
self.driver.find_element(By.ID, "student2").send_keys("87654321")
self.driver.find_element(By.ID, "student3").send_keys("11223344")

self.driver.find_element(By.ID, "submitBtn").click()

Comment on lines +62 to +69

class CreateGroupPage:
def __init__(self, driver):
self.driver = driver

def set_student1(self, student_id):
self.driver.find_element(By.ID, "student1").send_keys(student_id)
return self

def set_student2(self, student_id):
self.driver.find_element(By.ID, "student2").send_keys(student_id)
return self

def submit_form(self):
self.driver.find_element(By.ID, "submitBtn").click()
Loading