From a5a7cd3107d988f9aedfa92cab698c043026b4ab Mon Sep 17 00:00:00 2001
From: Rui Alves <alvesrui951@gmail.com>
Date: Wed, 4 Dec 2024 12:52:08 +0000
Subject: [PATCH] Added more unit tests for the review controller (#15162)

---
 frigate/api/review.py                     |  20 +-
 frigate/test/http_api/base_http_test.py   |  30 +-
 frigate/test/http_api/test_http_review.py | 557 ++++++++++++++++++++--
 3 files changed, 544 insertions(+), 63 deletions(-)

diff --git a/frigate/api/review.py b/frigate/api/review.py
index 21b468640..04e3e6dcd 100644
--- a/frigate/api/review.py
+++ b/frigate/api/review.py
@@ -26,6 +26,7 @@ from frigate.api.defs.review_responses import (
 )
 from frigate.api.defs.tags import Tags
 from frigate.models import Recordings, ReviewSegment
+from frigate.review.maintainer import SeverityEnum
 from frigate.util.builtin import get_tz_modifiers
 
 logger = logging.getLogger(__name__)
@@ -161,7 +162,7 @@ def review_summary(params: ReviewSummaryQueryParams = Depends()):
                     None,
                     [
                         (
-                            (ReviewSegment.severity == "alert"),
+                            (ReviewSegment.severity == SeverityEnum.alert),
                             ReviewSegment.has_been_reviewed,
                         )
                     ],
@@ -173,7 +174,7 @@ def review_summary(params: ReviewSummaryQueryParams = Depends()):
                     None,
                     [
                         (
-                            (ReviewSegment.severity == "detection"),
+                            (ReviewSegment.severity == SeverityEnum.detection),
                             ReviewSegment.has_been_reviewed,
                         )
                     ],
@@ -185,7 +186,7 @@ def review_summary(params: ReviewSummaryQueryParams = Depends()):
                     None,
                     [
                         (
-                            (ReviewSegment.severity == "alert"),
+                            (ReviewSegment.severity == SeverityEnum.alert),
                             1,
                         )
                     ],
@@ -197,7 +198,7 @@ def review_summary(params: ReviewSummaryQueryParams = Depends()):
                     None,
                     [
                         (
-                            (ReviewSegment.severity == "detection"),
+                            (ReviewSegment.severity == SeverityEnum.detection),
                             1,
                         )
                     ],
@@ -230,6 +231,7 @@ def review_summary(params: ReviewSummaryQueryParams = Depends()):
         label_clause = reduce(operator.or_, label_clauses)
         clauses.append((label_clause))
 
+    day_in_seconds = 60 * 60 * 24
     last_month = (
         ReviewSegment.select(
             fn.strftime(
@@ -246,7 +248,7 @@ def review_summary(params: ReviewSummaryQueryParams = Depends()):
                     None,
                     [
                         (
-                            (ReviewSegment.severity == "alert"),
+                            (ReviewSegment.severity == SeverityEnum.alert),
                             ReviewSegment.has_been_reviewed,
                         )
                     ],
@@ -258,7 +260,7 @@ def review_summary(params: ReviewSummaryQueryParams = Depends()):
                     None,
                     [
                         (
-                            (ReviewSegment.severity == "detection"),
+                            (ReviewSegment.severity == SeverityEnum.detection),
                             ReviewSegment.has_been_reviewed,
                         )
                     ],
@@ -270,7 +272,7 @@ def review_summary(params: ReviewSummaryQueryParams = Depends()):
                     None,
                     [
                         (
-                            (ReviewSegment.severity == "alert"),
+                            (ReviewSegment.severity == SeverityEnum.alert),
                             1,
                         )
                     ],
@@ -282,7 +284,7 @@ def review_summary(params: ReviewSummaryQueryParams = Depends()):
                     None,
                     [
                         (
-                            (ReviewSegment.severity == "detection"),
+                            (ReviewSegment.severity == SeverityEnum.detection),
                             1,
                         )
                     ],
@@ -292,7 +294,7 @@ def review_summary(params: ReviewSummaryQueryParams = Depends()):
         )
         .where(reduce(operator.and_, clauses))
         .group_by(
-            (ReviewSegment.start_time + seconds_offset).cast("int") / (3600 * 24),
+            (ReviewSegment.start_time + seconds_offset).cast("int") / day_in_seconds,
         )
         .order_by(ReviewSegment.start_time.desc())
     )
diff --git a/frigate/test/http_api/base_http_test.py b/frigate/test/http_api/base_http_test.py
index 013785692..ad1d449c5 100644
--- a/frigate/test/http_api/base_http_test.py
+++ b/frigate/test/http_api/base_http_test.py
@@ -9,7 +9,7 @@ from playhouse.sqliteq import SqliteQueueDatabase
 
 from frigate.api.fastapi_app import create_fastapi_app
 from frigate.config import FrigateConfig
-from frigate.models import Event, ReviewSegment
+from frigate.models import Event, Recordings, ReviewSegment
 from frigate.review.maintainer import SeverityEnum
 from frigate.test.const import TEST_DB, TEST_DB_CLEANUPS
 
@@ -146,17 +146,35 @@ class BaseTestHttp(unittest.TestCase):
     def insert_mock_review_segment(
         self,
         id: str,
-        start_time: datetime.datetime = datetime.datetime.now().timestamp(),
-        end_time: datetime.datetime = datetime.datetime.now().timestamp() + 20,
+        start_time: float = datetime.datetime.now().timestamp(),
+        end_time: float = datetime.datetime.now().timestamp() + 20,
+        severity: SeverityEnum = SeverityEnum.alert,
+        has_been_reviewed: bool = False,
     ) -> Event:
-        """Inserts a basic event model with a given id."""
+        """Inserts a review segment model with a given id."""
         return ReviewSegment.insert(
             id=id,
             camera="front_door",
             start_time=start_time,
             end_time=end_time,
-            has_been_reviewed=False,
-            severity=SeverityEnum.alert,
+            has_been_reviewed=has_been_reviewed,
+            severity=severity,
             thumb_path=False,
             data={},
         ).execute()
+
+    def insert_mock_recording(
+        self,
+        id: str,
+        start_time: float = datetime.datetime.now().timestamp(),
+        end_time: float = datetime.datetime.now().timestamp() + 20,
+    ) -> Event:
+        """Inserts a recording model with a given id."""
+        return Recordings.insert(
+            id=id,
+            path=id,
+            camera="front_door",
+            start_time=start_time,
+            end_time=end_time,
+            duration=end_time - start_time,
+        ).execute()
diff --git a/frigate/test/http_api/test_http_review.py b/frigate/test/http_api/test_http_review.py
index 19e1f26f8..3bd8779aa 100644
--- a/frigate/test/http_api/test_http_review.py
+++ b/frigate/test/http_api/test_http_review.py
@@ -1,76 +1,89 @@
-import datetime
+from datetime import datetime, timedelta
 
 from fastapi.testclient import TestClient
 
-from frigate.models import Event, ReviewSegment
+from frigate.models import Event, Recordings, ReviewSegment
+from frigate.review.maintainer import SeverityEnum
 from frigate.test.http_api.base_http_test import BaseTestHttp
 
 
 class TestHttpReview(BaseTestHttp):
     def setUp(self):
-        super().setUp([Event, ReviewSegment])
+        super().setUp([Event, Recordings, ReviewSegment])
+        self.app = super().create_app()
+
+    def _get_reviews(self, ids: list[str]):
+        return list(
+            ReviewSegment.select(ReviewSegment.id)
+            .where(ReviewSegment.id.in_(ids))
+            .execute()
+        )
+
+    def _get_recordings(self, ids: list[str]):
+        return list(
+            Recordings.select(Recordings.id).where(Recordings.id.in_(ids)).execute()
+        )
+
+    ####################################################################################################################
+    ###################################  GET /review Endpoint   ########################################################
+    ####################################################################################################################
 
     # Does not return any data point since the end time (before parameter) is not passed and the review segment end_time is 2 seconds from now
     def test_get_review_no_filters_no_matches(self):
-        app = super().create_app()
-        now = datetime.datetime.now().timestamp()
+        now = datetime.now().timestamp()
 
-        with TestClient(app) as client:
+        with TestClient(self.app) as client:
             super().insert_mock_review_segment("123456.random", now, now + 2)
-            reviews_response = client.get("/review")
-            assert reviews_response.status_code == 200
-            reviews_in_response = reviews_response.json()
-            assert len(reviews_in_response) == 0
+            response = client.get("/review")
+            assert response.status_code == 200
+            response_json = response.json()
+            assert len(response_json) == 0
 
     def test_get_review_no_filters(self):
-        app = super().create_app()
-        now = datetime.datetime.now().timestamp()
+        now = datetime.now().timestamp()
 
-        with TestClient(app) as client:
+        with TestClient(self.app) as client:
             super().insert_mock_review_segment("123456.random", now - 2, now - 1)
-            reviews_response = client.get("/review")
-            assert reviews_response.status_code == 200
-            reviews_in_response = reviews_response.json()
-            assert len(reviews_in_response) == 1
+            response = client.get("/review")
+            assert response.status_code == 200
+            response_json = response.json()
+            assert len(response_json) == 1
 
     def test_get_review_with_time_filter_no_matches(self):
-        app = super().create_app()
-        now = datetime.datetime.now().timestamp()
+        now = datetime.now().timestamp()
 
-        with TestClient(app) as client:
+        with TestClient(self.app) as client:
             id = "123456.random"
             super().insert_mock_review_segment(id, now, now + 2)
             params = {
                 "after": now,
                 "before": now + 3,
             }
-            reviews_response = client.get("/review", params=params)
-            assert reviews_response.status_code == 200
-            reviews_in_response = reviews_response.json()
-            assert len(reviews_in_response) == 0
+            response = client.get("/review", params=params)
+            assert response.status_code == 200
+            response_json = response.json()
+            assert len(response_json) == 0
 
     def test_get_review_with_time_filter(self):
-        app = super().create_app()
-        now = datetime.datetime.now().timestamp()
+        now = datetime.now().timestamp()
 
-        with TestClient(app) as client:
+        with TestClient(self.app) as client:
             id = "123456.random"
             super().insert_mock_review_segment(id, now, now + 2)
             params = {
                 "after": now - 1,
                 "before": now + 3,
             }
-            reviews_response = client.get("/review", params=params)
-            assert reviews_response.status_code == 200
-            reviews_in_response = reviews_response.json()
-            assert len(reviews_in_response) == 1
-            assert reviews_in_response[0]["id"] == id
+            response = client.get("/review", params=params)
+            assert response.status_code == 200
+            response_json = response.json()
+            assert len(response_json) == 1
+            assert response_json[0]["id"] == id
 
     def test_get_review_with_limit_filter(self):
-        app = super().create_app()
-        now = datetime.datetime.now().timestamp()
+        now = datetime.now().timestamp()
 
-        with TestClient(app) as client:
+        with TestClient(self.app) as client:
             id = "123456.random"
             id2 = "654321.random"
             super().insert_mock_review_segment(id, now, now + 2)
@@ -80,17 +93,49 @@ class TestHttpReview(BaseTestHttp):
                 "after": now,
                 "before": now + 3,
             }
-            reviews_response = client.get("/review", params=params)
-            assert reviews_response.status_code == 200
-            reviews_in_response = reviews_response.json()
-            assert len(reviews_in_response) == 1
-            assert reviews_in_response[0]["id"] == id2
+            response = client.get("/review", params=params)
+            assert response.status_code == 200
+            response_json = response.json()
+            assert len(response_json) == 1
+            assert response_json[0]["id"] == id2
+
+    def test_get_review_with_severity_filters_no_matches(self):
+        now = datetime.now().timestamp()
+
+        with TestClient(self.app) as client:
+            id = "123456.random"
+            super().insert_mock_review_segment(id, now, now + 2, SeverityEnum.detection)
+            params = {
+                "severity": "detection",
+                "after": now - 1,
+                "before": now + 3,
+            }
+            response = client.get("/review", params=params)
+            assert response.status_code == 200
+            response_json = response.json()
+            assert len(response_json) == 1
+            assert response_json[0]["id"] == id
+
+    def test_get_review_with_severity_filters(self):
+        now = datetime.now().timestamp()
+
+        with TestClient(self.app) as client:
+            id = "123456.random"
+            super().insert_mock_review_segment(id, now, now + 2, SeverityEnum.detection)
+            params = {
+                "severity": "alert",
+                "after": now - 1,
+                "before": now + 3,
+            }
+            response = client.get("/review", params=params)
+            assert response.status_code == 200
+            response_json = response.json()
+            assert len(response_json) == 0
 
     def test_get_review_with_all_filters(self):
-        app = super().create_app()
-        now = datetime.datetime.now().timestamp()
+        now = datetime.now().timestamp()
 
-        with TestClient(app) as client:
+        with TestClient(self.app) as client:
             id = "123456.random"
             super().insert_mock_review_segment(id, now, now + 2)
             params = {
@@ -103,8 +148,424 @@ class TestHttpReview(BaseTestHttp):
                 "after": now - 1,
                 "before": now + 3,
             }
-            reviews_response = client.get("/review", params=params)
-            assert reviews_response.status_code == 200
-            reviews_in_response = reviews_response.json()
-            assert len(reviews_in_response) == 1
-            assert reviews_in_response[0]["id"] == id
+            response = client.get("/review", params=params)
+            assert response.status_code == 200
+            response_json = response.json()
+            assert len(response_json) == 1
+            assert response_json[0]["id"] == id
+
+    ####################################################################################################################
+    ###################################  GET /review/summary Endpoint   #################################################
+    ####################################################################################################################
+    def test_get_review_summary_all_filters(self):
+        with TestClient(self.app) as client:
+            super().insert_mock_review_segment("123456.random")
+            params = {
+                "cameras": "front_door",
+                "labels": "all",
+                "zones": "all",
+                "timezone": "utc",
+            }
+            response = client.get("/review/summary", params=params)
+            assert response.status_code == 200
+            response_json = response.json()
+            # e.g. '2024-11-24'
+            today_formatted = datetime.today().strftime("%Y-%m-%d")
+            expected_response = {
+                "last24Hours": {
+                    "reviewed_alert": 0,
+                    "reviewed_detection": 0,
+                    "total_alert": 1,
+                    "total_detection": 0,
+                },
+                today_formatted: {
+                    "day": today_formatted,
+                    "reviewed_alert": 0,
+                    "reviewed_detection": 0,
+                    "total_alert": 1,
+                    "total_detection": 0,
+                },
+            }
+            self.assertEqual(response_json, expected_response)
+
+    def test_get_review_summary_no_filters(self):
+        with TestClient(self.app) as client:
+            super().insert_mock_review_segment("123456.random")
+            response = client.get("/review/summary")
+            assert response.status_code == 200
+            response_json = response.json()
+            # e.g. '2024-11-24'
+            today_formatted = datetime.today().strftime("%Y-%m-%d")
+            expected_response = {
+                "last24Hours": {
+                    "reviewed_alert": 0,
+                    "reviewed_detection": 0,
+                    "total_alert": 1,
+                    "total_detection": 0,
+                },
+                today_formatted: {
+                    "day": today_formatted,
+                    "reviewed_alert": 0,
+                    "reviewed_detection": 0,
+                    "total_alert": 1,
+                    "total_detection": 0,
+                },
+            }
+            self.assertEqual(response_json, expected_response)
+
+    def test_get_review_summary_multiple_days(self):
+        now = datetime.now()
+        five_days_ago = datetime.today() - timedelta(days=5)
+
+        with TestClient(self.app) as client:
+            super().insert_mock_review_segment(
+                "123456.random", now.timestamp() - 2, now.timestamp() - 1
+            )
+            super().insert_mock_review_segment(
+                "654321.random",
+                five_days_ago.timestamp(),
+                five_days_ago.timestamp() + 1,
+            )
+            response = client.get("/review/summary")
+            assert response.status_code == 200
+            response_json = response.json()
+            # e.g. '2024-11-24'
+            today_formatted = now.strftime("%Y-%m-%d")
+            # e.g. '2024-11-19'
+            five_days_ago_formatted = five_days_ago.strftime("%Y-%m-%d")
+            expected_response = {
+                "last24Hours": {
+                    "reviewed_alert": 0,
+                    "reviewed_detection": 0,
+                    "total_alert": 1,
+                    "total_detection": 0,
+                },
+                today_formatted: {
+                    "day": today_formatted,
+                    "reviewed_alert": 0,
+                    "reviewed_detection": 0,
+                    "total_alert": 1,
+                    "total_detection": 0,
+                },
+                five_days_ago_formatted: {
+                    "day": five_days_ago_formatted,
+                    "reviewed_alert": 0,
+                    "reviewed_detection": 0,
+                    "total_alert": 1,
+                    "total_detection": 0,
+                },
+            }
+            self.assertEqual(response_json, expected_response)
+
+    def test_get_review_summary_multiple_days_edge_cases(self):
+        now = datetime.now()
+        five_days_ago = datetime.today() - timedelta(days=5)
+        twenty_days_ago = datetime.today() - timedelta(days=20)
+        one_month_ago = datetime.today() - timedelta(days=30)
+        one_month_ago_ts = one_month_ago.timestamp()
+
+        with TestClient(self.app) as client:
+            super().insert_mock_review_segment("123456.random", now.timestamp())
+            super().insert_mock_review_segment(
+                "123457.random", five_days_ago.timestamp()
+            )
+            super().insert_mock_review_segment(
+                "123458.random",
+                twenty_days_ago.timestamp(),
+                None,
+                SeverityEnum.detection,
+            )
+            # One month ago plus 5 seconds fits within the condition (review.start_time > month_ago). Assuming that the endpoint does not take more than 5 seconds to be invoked
+            super().insert_mock_review_segment(
+                "123459.random",
+                one_month_ago_ts + 5,
+                None,
+                SeverityEnum.detection,
+            )
+            # This won't appear in the output since it's not within last month start_time clause (review.start_time > month_ago)
+            super().insert_mock_review_segment("123450.random", one_month_ago_ts)
+            response = client.get("/review/summary")
+            assert response.status_code == 200
+            response_json = response.json()
+            # e.g. '2024-11-24'
+            today_formatted = now.strftime("%Y-%m-%d")
+            # e.g. '2024-11-19'
+            five_days_ago_formatted = five_days_ago.strftime("%Y-%m-%d")
+            # e.g. '2024-11-04'
+            twenty_days_ago_formatted = twenty_days_ago.strftime("%Y-%m-%d")
+            # e.g. '2024-10-24'
+            one_month_ago_formatted = one_month_ago.strftime("%Y-%m-%d")
+            expected_response = {
+                "last24Hours": {
+                    "reviewed_alert": 0,
+                    "reviewed_detection": 0,
+                    "total_alert": 1,
+                    "total_detection": 0,
+                },
+                today_formatted: {
+                    "day": today_formatted,
+                    "reviewed_alert": 0,
+                    "reviewed_detection": 0,
+                    "total_alert": 1,
+                    "total_detection": 0,
+                },
+                five_days_ago_formatted: {
+                    "day": five_days_ago_formatted,
+                    "reviewed_alert": 0,
+                    "reviewed_detection": 0,
+                    "total_alert": 1,
+                    "total_detection": 0,
+                },
+                twenty_days_ago_formatted: {
+                    "day": twenty_days_ago_formatted,
+                    "reviewed_alert": 0,
+                    "reviewed_detection": 0,
+                    "total_alert": 0,
+                    "total_detection": 1,
+                },
+                one_month_ago_formatted: {
+                    "day": one_month_ago_formatted,
+                    "reviewed_alert": 0,
+                    "reviewed_detection": 0,
+                    "total_alert": 0,
+                    "total_detection": 1,
+                },
+            }
+            self.assertEqual(response_json, expected_response)
+
+    def test_get_review_summary_multiple_in_same_day(self):
+        now = datetime.now()
+        five_days_ago = datetime.today() - timedelta(days=5)
+
+        with TestClient(self.app) as client:
+            super().insert_mock_review_segment("123456.random", now.timestamp())
+            five_days_ago_ts = five_days_ago.timestamp()
+            for i in range(20):
+                super().insert_mock_review_segment(
+                    f"123456_{i}.random_alert",
+                    five_days_ago_ts,
+                    five_days_ago_ts,
+                    SeverityEnum.alert,
+                )
+            for i in range(15):
+                super().insert_mock_review_segment(
+                    f"123456_{i}.random_detection",
+                    five_days_ago_ts,
+                    five_days_ago_ts,
+                    SeverityEnum.detection,
+                )
+            response = client.get("/review/summary")
+            assert response.status_code == 200
+            response_json = response.json()
+            # e.g. '2024-11-24'
+            today_formatted = now.strftime("%Y-%m-%d")
+            # e.g. '2024-11-19'
+            five_days_ago_formatted = five_days_ago.strftime("%Y-%m-%d")
+            expected_response = {
+                "last24Hours": {
+                    "reviewed_alert": 0,
+                    "reviewed_detection": 0,
+                    "total_alert": 1,
+                    "total_detection": 0,
+                },
+                today_formatted: {
+                    "day": today_formatted,
+                    "reviewed_alert": 0,
+                    "reviewed_detection": 0,
+                    "total_alert": 1,
+                    "total_detection": 0,
+                },
+                five_days_ago_formatted: {
+                    "day": five_days_ago_formatted,
+                    "reviewed_alert": 0,
+                    "reviewed_detection": 0,
+                    "total_alert": 20,
+                    "total_detection": 15,
+                },
+            }
+            self.assertEqual(response_json, expected_response)
+
+    def test_get_review_summary_multiple_in_same_day_with_reviewed(self):
+        five_days_ago = datetime.today() - timedelta(days=5)
+
+        with TestClient(self.app) as client:
+            five_days_ago_ts = five_days_ago.timestamp()
+            for i in range(10):
+                super().insert_mock_review_segment(
+                    f"123456_{i}.random_alert_not_reviewed",
+                    five_days_ago_ts,
+                    five_days_ago_ts,
+                    SeverityEnum.alert,
+                    False,
+                )
+            for i in range(10):
+                super().insert_mock_review_segment(
+                    f"123456_{i}.random_alert_reviewed",
+                    five_days_ago_ts,
+                    five_days_ago_ts,
+                    SeverityEnum.alert,
+                    True,
+                )
+            for i in range(10):
+                super().insert_mock_review_segment(
+                    f"123456_{i}.random_detection_not_reviewed",
+                    five_days_ago_ts,
+                    five_days_ago_ts,
+                    SeverityEnum.detection,
+                    False,
+                )
+            for i in range(5):
+                super().insert_mock_review_segment(
+                    f"123456_{i}.random_detection_reviewed",
+                    five_days_ago_ts,
+                    five_days_ago_ts,
+                    SeverityEnum.detection,
+                    True,
+                )
+            response = client.get("/review/summary")
+            assert response.status_code == 200
+            response_json = response.json()
+            # e.g. '2024-11-19'
+            five_days_ago_formatted = five_days_ago.strftime("%Y-%m-%d")
+            expected_response = {
+                "last24Hours": {
+                    "reviewed_alert": None,
+                    "reviewed_detection": None,
+                    "total_alert": None,
+                    "total_detection": None,
+                },
+                five_days_ago_formatted: {
+                    "day": five_days_ago_formatted,
+                    "reviewed_alert": 10,
+                    "reviewed_detection": 5,
+                    "total_alert": 20,
+                    "total_detection": 15,
+                },
+            }
+            self.assertEqual(response_json, expected_response)
+
+    ####################################################################################################################
+    ###################################  POST reviews/viewed Endpoint   ################################################
+    ####################################################################################################################
+    def test_post_reviews_viewed_no_body(self):
+        with TestClient(self.app) as client:
+            super().insert_mock_review_segment("123456.random")
+            response = client.post("/reviews/viewed")
+            # Missing ids
+            assert response.status_code == 422
+
+    def test_post_reviews_viewed_no_body_ids(self):
+        with TestClient(self.app) as client:
+            super().insert_mock_review_segment("123456.random")
+            body = {"ids": [""]}
+            response = client.post("/reviews/viewed", json=body)
+            # Missing ids
+            assert response.status_code == 422
+
+    def test_post_reviews_viewed_non_existent_id(self):
+        with TestClient(self.app) as client:
+            id = "123456.random"
+            super().insert_mock_review_segment(id)
+            body = {"ids": ["1"]}
+            response = client.post("/reviews/viewed", json=body)
+            assert response.status_code == 200
+            response = response.json()
+            assert response["success"] == True
+            assert response["message"] == "Reviewed multiple items"
+            # Verify that in DB the review segment was not changed
+            review_segment_in_db = (
+                ReviewSegment.select(ReviewSegment.has_been_reviewed)
+                .where(ReviewSegment.id == id)
+                .get()
+            )
+            assert review_segment_in_db.has_been_reviewed == False
+
+    def test_post_reviews_viewed(self):
+        with TestClient(self.app) as client:
+            id = "123456.random"
+            super().insert_mock_review_segment(id)
+            body = {"ids": [id]}
+            response = client.post("/reviews/viewed", json=body)
+            assert response.status_code == 200
+            response = response.json()
+            assert response["success"] == True
+            assert response["message"] == "Reviewed multiple items"
+            # Verify that in DB the review segment was changed
+            review_segment_in_db = (
+                ReviewSegment.select(ReviewSegment.has_been_reviewed)
+                .where(ReviewSegment.id == id)
+                .get()
+            )
+            assert review_segment_in_db.has_been_reviewed == True
+
+    ####################################################################################################################
+    ###################################  POST reviews/delete Endpoint   ################################################
+    ####################################################################################################################
+    def test_post_reviews_delete_no_body(self):
+        with TestClient(self.app) as client:
+            super().insert_mock_review_segment("123456.random")
+            response = client.post("/reviews/delete")
+            # Missing ids
+            assert response.status_code == 422
+
+    def test_post_reviews_delete_no_body_ids(self):
+        with TestClient(self.app) as client:
+            super().insert_mock_review_segment("123456.random")
+            body = {"ids": [""]}
+            response = client.post("/reviews/delete", json=body)
+            # Missing ids
+            assert response.status_code == 422
+
+    def test_post_reviews_delete_non_existent_id(self):
+        with TestClient(self.app) as client:
+            id = "123456.random"
+            super().insert_mock_review_segment(id)
+            body = {"ids": ["1"]}
+            response = client.post("/reviews/delete", json=body)
+            assert response.status_code == 200
+            response_json = response.json()
+            assert response_json["success"] == True
+            assert response_json["message"] == "Delete reviews"
+            # Verify that in DB the review segment was not deleted
+            review_ids_in_db_after = self._get_reviews([id])
+            assert len(review_ids_in_db_after) == 1
+            assert review_ids_in_db_after[0].id == id
+
+    def test_post_reviews_delete(self):
+        with TestClient(self.app) as client:
+            id = "123456.random"
+            super().insert_mock_review_segment(id)
+            body = {"ids": [id]}
+            response = client.post("/reviews/delete", json=body)
+            assert response.status_code == 200
+            response_json = response.json()
+            assert response_json["success"] == True
+            assert response_json["message"] == "Delete reviews"
+            # Verify that in DB the review segment was deleted
+            review_ids_in_db_after = self._get_reviews([id])
+            assert len(review_ids_in_db_after) == 0
+
+    def test_post_reviews_delete_many(self):
+        with TestClient(self.app) as client:
+            ids = ["123456.random", "654321.random"]
+            for id in ids:
+                super().insert_mock_review_segment(id)
+                super().insert_mock_recording(id)
+
+            review_ids_in_db_before = self._get_reviews(ids)
+            recordings_ids_in_db_before = self._get_recordings(ids)
+            assert len(review_ids_in_db_before) == 2
+            assert len(recordings_ids_in_db_before) == 2
+
+            body = {"ids": ids}
+            response = client.post("/reviews/delete", json=body)
+            assert response.status_code == 200
+            response_json = response.json()
+            assert response_json["success"] == True
+            assert response_json["message"] == "Delete reviews"
+
+            # Verify that in DB all review segments and recordings that were passed were deleted
+            review_ids_in_db_after = self._get_reviews(ids)
+            recording_ids_in_db_after = self._get_recordings(ids)
+            assert len(review_ids_in_db_after) == 0
+            assert len(recording_ids_in_db_after) == 0