From f7e5cfd79d2f15e56605097c5169c226470105a2 Mon Sep 17 00:00:00 2001 From: 86LAK <121588258+86LAK@users.noreply.github.com> Date: Sun, 5 May 2024 20:45:01 +1000 Subject: [PATCH 1/6] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 41fc998..fa8bfbc 100644 --- a/README.md +++ b/README.md @@ -25,12 +25,14 @@ This project is brought to you by the Evan Hughes FanClub. Our team consists of: - [Shanon Lakshan Chandrasekara](https://github.com/86LAK) - [Jackson Trenarry](https://github.com/JTrenarry) - [Olivia Ronda](https://github.com/vilnor) -- [Ibrahim Cassim](https://github.com/IbrahimCassim) ### DevOps - [Shanon Lakshan Chandrasekara](https://github.com/86LAK) +### QUT Guy Who Has Vanished? +- [Ibrahim Cassim](https://github.com/IbrahimCassim) + ## Deployment Deployment of UniBasement is managed via the GitHub Actions. This is the recommended and easiest way to deploy the application and automatically preserve the state files. The GitHub actions utilise and manage its state files in AWS via an S3 bucket. From b306855c98b28daa182ab92f24ee38744016c33d Mon Sep 17 00:00:00 2001 From: JTrenerry Date: Sun, 5 May 2024 22:50:44 +1000 Subject: [PATCH 2/6] Adds star tests --- integration_tests/test_courses.py | 146 ++++++++++++++++++++++++++- integration_tests/test_full_suite.py | 4 +- 2 files changed, 144 insertions(+), 6 deletions(-) diff --git a/integration_tests/test_courses.py b/integration_tests/test_courses.py index 469fe6b..795926a 100644 --- a/integration_tests/test_courses.py +++ b/integration_tests/test_courses.py @@ -95,7 +95,9 @@ def test_course_get_course(self): "courseCode": "ENGG1001", "courseName": "Programming for Engineers", "courseDescription": "An introductory course covering basic concepts of software engineering.", - "university": "UQ" + "university": "UQ", + "stars": 0, + "votes": 0 } response = requests.get(self.host() + '/courses/' + courseCode) @@ -120,9 +122,9 @@ def test_course_get_all(self): Checks for the correct response message """ expectedCourses = [ - {"courseCode": "ENGG1001", "courseName": "Programming for Engineers", "courseDescription": "An introductory course covering basic concepts of software engineering.", "university": "UQ"}, - {"courseCode": "ENGG1100", "courseName": "Professional Engineering", "courseDescription": "An introductory course covering fundamental concepts in engineering principles.", "university": "UQ"}, - {"courseCode": "MATH1051", "courseName": "Calculus & Linear Algebra", "courseDescription": "A foundational course in calculus covering limits, derivatives, and integrals.", "university": "UQ"} + {"courseCode": "ENGG1001", "courseName": "Programming for Engineers", "courseDescription": "An introductory course covering basic concepts of software engineering.", "university": "UQ", "stars": 0, "votes": 0}, + {"courseCode": "ENGG1100", "courseName": "Professional Engineering", "courseDescription": "An introductory course covering fundamental concepts in engineering principles.", "university": "UQ", "stars": 0, "votes": 0}, + {"courseCode": "MATH1051", "courseName": "Calculus & Linear Algebra", "courseDescription": "A foundational course in calculus covering limits, derivatives, and integrals.", "university": "UQ", "stars": 0, "votes": 0}, ] response = requests.get(self.host() + '/courses') @@ -133,8 +135,142 @@ def test_course_get_all(self): self.assertIn(expectedCourse, response.json()) + def test_course_patch_star(self): + """ + Checks for a 200 response from the /courses/:courseCode/star endpoint + Checks for the correct response message + """ + course_data = { + "courseCode": "STAR1001", + "courseName": "Stargazing", + "courseDescription": "An introductory course covering basic concepts of astronomy.", + "university": "UQ" + } + + # Make a new course + response = requests.post(self.host() + '/courses', json=course_data, headers={'Accept': 'application/json'}) + self.assertEqual(201, response.status_code) + + user = { + "userId": "stars", + } + + # Make a new user + response = requests.post(self.host() + '/users', json=user) + self.assertEqual(201, response.status_code) + + stars = { + "starRating": 5, + "userId": "stars", + } + + + response = requests.patch(self.host() + '/courses/' + 'STAR1001' + '/star', json=stars) + self.assertEqual(200, response.status_code) + self.assertEqual('Course starred', response.json()) + + response = requests.get(self.host() + '/courses/' + 'STAR1001') + self.assertEqual(200, response.status_code) + self.assertEqual(5, response.json()['stars']) + + stars = { + "starRating": 3, + "userId": "stars", + } + + response = requests.patch(self.host() + '/courses/' + 'STAR1001' + '/star', json=stars) + self.assertEqual(200, response.status_code) + self.assertEqual('Course starred', response.json()) + + response = requests.get(self.host() + '/courses/' + 'STAR1001') + self.assertEqual(200, response.status_code) + self.assertEqual(3, response.json()['stars']) + + def test_course_patch_star_miss(self): + """ + Checks for a 400 response from the /courses/:courseCode/star endpoint + Checks for the correct response message + """ + stars = { + "starRating": 5, + } + + response = requests.patch(self.host() + '/courses/' + 'STAR2001' + '/star', json=stars) + self.assertEqual(400, response.status_code) + self.assertEqual('Missing starRating or userId', response.json()) + + stars = { + "userId": "stars", + } + + response = requests.patch(self.host() + '/courses/' + 'STAR2001' + '/star', json=stars) + self.assertEqual(400, response.status_code) + self.assertEqual('Missing starRating or userId', response.json()) + + + def test_course_patch_bad_star(self): + """ + Checks for a 400 response from the /courses/:courseCode/star endpoint + Checks for the correct response message + """ + + stars = { + "starRating": 6, + "userId": "stars", + } + + + response = requests.patch(self.host() + '/courses/' + 'STAR1001' + '/star', json=stars) + self.assertEqual(400, response.status_code) + self.assertEqual('Star rating must be between 0 and 5', response.json()) + + stars = { + "starRating": -1, + "userId": "stars", + } + + response = requests.patch(self.host() + '/courses/' + 'STAR1001' + '/star', json=stars) + self.assertEqual(400, response.status_code) + self.assertEqual('Star rating must be between 0 and 5', response.json()) + + + def test_course_patch_star_user(self): + """ + Checks for a 404 response from the /courses/:courseCode/star endpoint + Checks for the correct response message + """ + stars = { + "starRating": 5, + "userId": "stari", + } + + + response = requests.patch(self.host() + '/courses/' + 'STAR1001' + '/star', json=stars) + self.assertEqual(404, response.status_code) + self.assertEqual('User not found', response.json()) + + def test_course_patch_star_course(self): + """ + Checks for a 404 response from the /courses/:courseCode/star endpoint + Checks for the correct response message + """ + user = { + "userId": "stary", + } + + # Make a new user + response = requests.post(self.host() + '/users', json=user) + self.assertEqual(201, response.status_code) + stars = { + "starRating": 5, + "userId": "stary", + } + + response = requests.patch(self.host() + '/courses/' + 'STAR2401' + '/star', json=stars) + self.assertEqual(404, response.status_code) + self.assertEqual('Course not found', response.json()) if __name__ == '__main__': - unittest.main() \ No newline at end of file + unittest.main() diff --git a/integration_tests/test_full_suite.py b/integration_tests/test_full_suite.py index 76f5ad4..27d6875 100644 --- a/integration_tests/test_full_suite.py +++ b/integration_tests/test_full_suite.py @@ -44,6 +44,8 @@ def test_full_1(self): "courseName": "The History of Toyota 86", "courseDescription": "A course on the history of the Toyota 86 and its impact on the automotive industry.", "university": "The University of Queensland", + "stars": 0, + "votes": 0 } # Create a course @@ -355,4 +357,4 @@ def test_full_1(self): if __name__ == '__main__': - unittest.main() \ No newline at end of file + unittest.main() From d347ad83bd3fa25e08562476689431c5a4284804 Mon Sep 17 00:00:00 2001 From: JTrenerry Date: Sun, 5 May 2024 23:19:46 +1000 Subject: [PATCH 3/6] finish user tests --- integration_tests/test_users.py | 56 +++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 integration_tests/test_users.py diff --git a/integration_tests/test_users.py b/integration_tests/test_users.py new file mode 100644 index 0000000..c19422d --- /dev/null +++ b/integration_tests/test_users.py @@ -0,0 +1,56 @@ +import unittest +import requests + +from .base import BaseCase + + +class TestUser(BaseCase): + + def test_user_post(self): + """ + Checks for a 201 response from the /courses endpoint + Checks for the correct response message + """ + user_data = { + "userId": "EVAN", + } + + response = requests.post(self.host() + '/users', json=user_data, headers={'Accept': 'application/json'}) + + self.assertEqual(201, response.status_code) + self.assertEqual("User Added", response.json()) + + + def test_user_post_missing(self): + """ + Checks for a 201 response from the /courses endpoint + Checks for the correct response message + """ + user_data = { + "filler": "meow", + } + + response = requests.post(self.host() + '/users', json=user_data, headers={'Accept': 'application/json'}) + + self.assertEqual(400, response.status_code) + self.assertEqual("Missing userId", response.json()) + + + def test_user_post_double(self): + """ + Checks for a 201 response from the /courses endpoint + Checks for the correct response message + """ + user_data = { + "userId": "DoughBell", + } + + response = requests.post(self.host() + '/users', json=user_data, headers={'Accept': 'application/json'}) + + self.assertEqual(201, response.status_code) + self.assertEqual("User Added", response.json()) + + response = requests.post(self.host() + '/users', json=user_data, headers={'Accept': 'application/json'}) + + self.assertEqual(409, response.status_code) + self.assertEqual("User already exists", response.json()) From 518b98d42735d9a8ec7b9d0e0aeeeaa5fc6d5f00 Mon Sep 17 00:00:00 2001 From: JTrenerry Date: Sun, 5 May 2024 23:24:34 +1000 Subject: [PATCH 4/6] adds last line in --- integration_tests/test_users.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/integration_tests/test_users.py b/integration_tests/test_users.py index c19422d..f44e868 100644 --- a/integration_tests/test_users.py +++ b/integration_tests/test_users.py @@ -54,3 +54,6 @@ def test_user_post_double(self): self.assertEqual(409, response.status_code) self.assertEqual("User already exists", response.json()) + +if __name__ == '__main__': + unittest.main() From ad561bbc4add69083a8bae1ed0c4a87436ac1d51 Mon Sep 17 00:00:00 2001 From: JTrenerry Date: Sun, 5 May 2024 23:28:22 +1000 Subject: [PATCH 5/6] ahsa --- integration_tests/test_users.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration_tests/test_users.py b/integration_tests/test_users.py index f44e868..2d68439 100644 --- a/integration_tests/test_users.py +++ b/integration_tests/test_users.py @@ -12,7 +12,7 @@ def test_user_post(self): Checks for the correct response message """ user_data = { - "userId": "EVAN", + "userId": "EVANs", } response = requests.post(self.host() + '/users', json=user_data, headers={'Accept': 'application/json'}) From fd3bbb50cb52eda1504203aa30eadfc75497dec0 Mon Sep 17 00:00:00 2001 From: JTrenerry Date: Sun, 5 May 2024 23:32:55 +1000 Subject: [PATCH 6/6] fix --- backend/src/routes/routes.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/backend/src/routes/routes.ts b/backend/src/routes/routes.ts index 94ab94c..087d98d 100644 --- a/backend/src/routes/routes.ts +++ b/backend/src/routes/routes.ts @@ -125,14 +125,14 @@ router.patch('/courses/:courseCode/star', async (req: Request const { courseCode } = req.params; const { starRating, userId } = req.body; - if (!starRating || !userId) { + if (starRating === undefined || !userId) { res.status(400).json('Missing starRating or userId'); return; } // Checks to see star rating is between 1 and 5 - if (starRating < 1 || starRating > 5) { - res.status(400).json('Star rating must be between 1 and 5'); + if (starRating < 0 || starRating > 5) { + res.status(400).json('Star rating must be between 0 and 5'); return; } @@ -367,6 +367,7 @@ router.post('/users', async (req: Request, res: Response) => const { rowCount } = await db.query(` INSERT INTO users ("userId") VALUES ($1) + ON CONFLICT DO NOTHING `, [userId]); if (rowCount === 0) { @@ -643,7 +644,7 @@ router.get('/courses/:courseCode', async (req: Request, res: const { courseCode } = req.params; const { rows } = await db.query(` - SELECT "courseCode", "courseName", "courseDescription", "university" + SELECT "courseCode", "courseName", "courseDescription", "university", "stars", "votes" FROM courses WHERE courses."courseCode" = $1 `, [courseCode]); @@ -662,7 +663,7 @@ router.get('/courses', async (req: Request, re const limit = req.query.limit ?? 100; const { rows } = await db.query(` - SELECT "courseCode", "courseName", "courseDescription", "university" + SELECT "courseCode", "courseName", "courseDescription", "university", "stars", "votes" FROM courses LIMIT $1 OFFSET $2