diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 9cb2867..19634c4 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -1,5 +1,5 @@ # .github/workflows/docker-image.yml -name: Build and Push Docker Image +name: Build, Test, and Push Docker Image on: push: @@ -43,6 +43,19 @@ jobs: echo "tag=prerelease" >> $GITHUB_OUTPUT fi + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.9' + + - name: Install dependencies + run: | + pip install -r requirements.txt + + - name: Run tests + run: | + python -m unittest discover tests + - name: Build and push Docker image uses: docker/build-push-action@v4 with: diff --git a/Dockerfile b/Dockerfile index 8922883..a939711 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,6 +6,9 @@ WORKDIR /app COPY requirements.txt ./ RUN pip install --no-cache-dir -r requirements.txt +# Install testing dependencies +RUN pip install --no-cache-dir pytest + COPY . . CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:5000", "app:app"] diff --git a/app.py b/app.py index 7b069e0..7631e3b 100644 --- a/app.py +++ b/app.py @@ -6,7 +6,12 @@ app = Flask(__name__, static_folder='static', template_folder='templates') # Configure SQLite database -app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///tasks.db' +if app.config.get('TESTING'): + # Use in-memory database for testing + app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:' +else: + app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///tasks.db' + app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False db = SQLAlchemy(app) diff --git a/requirements.txt b/requirements.txt index 13d018d..2d9f159 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,5 @@ Flask==3.0.3 Flask-SQLAlchemy==3.1.1 Werkzeug==3.0.6 -gunicorn==23.0.0 \ No newline at end of file +gunicorn==23.0.0 +pytest==6.2.5 \ No newline at end of file diff --git a/tests/test_app.py b/tests/test_app.py new file mode 100644 index 0000000..78171d6 --- /dev/null +++ b/tests/test_app.py @@ -0,0 +1,70 @@ +import unittest +from app import app, db, Task + +class AppTestCase(unittest.TestCase): + def setUp(self): + # Set up a test client and use an in-memory database + self.app = app.test_client() + app.config['TESTING'] = True + app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:' + with app.app_context(): + db.create_all() + + def tearDown(self): + # Clean up after each test + with app.app_context(): + db.session.remove() + db.drop_all() + + def test_index_page(self): + # Test that the index page loads correctly + response = self.app.get('/') + self.assertEqual(response.status_code, 200) + self.assertIn(b'Daily Tasks', response.data) + + def test_add_task(self): + # Test adding a new task + response = self.app.post('/add', data={'task': 'Test Task'}, follow_redirects=True) + self.assertEqual(response.status_code, 200) + self.assertIn(b'Test Task', response.data) + + def test_toggle_task(self): + # Test toggling a task's completion status + with app.app_context(): + task = Task(name='Test Task') + db.session.add(task) + db.session.commit() + task_id = task.id + response = self.app.post(f'/toggle/{task_id}', follow_redirects=True) + self.assertEqual(response.status_code, 200) + with app.app_context(): + task = Task.query.get(task_id) + self.assertTrue(task.completed) + + def test_update_points(self): + # Test updating a task's points + with app.app_context(): + task = Task(name='Test Task') + db.session.add(task) + db.session.commit() + task_id = task.id + response = self.app.post(f'/update_points/{task_id}', data={'points': '10'}, follow_redirects=True) + self.assertEqual(response.status_code, 200) + with app.app_context(): + task = Task.query.get(task_id) + self.assertEqual(task.points, 10) + + def test_clear_tasks(self): + # Test clearing all tasks + with app.app_context(): + task = Task(name='Test Task') + db.session.add(task) + db.session.commit() + response = self.app.post('/clear', follow_redirects=True) + self.assertEqual(response.status_code, 204) + with app.app_context(): + tasks = Task.query.all() + self.assertEqual(len(tasks), 0) + +if __name__ == '__main__': + unittest.main()