diff --git a/atdb/atdb/settings/dev.py b/atdb/atdb/settings/dev.py
index 58b33911e885963e72c5478ba2eac0ca910567c3..687f2d334ce7a1fef476829280e69efef9fedf6a 100644
--- a/atdb/atdb/settings/dev.py
+++ b/atdb/atdb/settings/dev.py
@@ -13,7 +13,8 @@ DATABASES = {
          'ENGINE': 'django.db.backends.postgresql_psycopg2',
          'USER': 'atdb_admin',
          'PASSWORD': 'atdb123',
-         'NAME': 'atdb_ldv_astronauth_6feb2023',
+         #'NAME': 'atdb_ldv_astronauth_6feb2023',
+          'NAME': 'atdb_ldv_27jun2023',
          'HOST': 'localhost',
          'PORT': '5432',
     },
diff --git a/atdb/taskdatabase/models.py b/atdb/taskdatabase/models.py
index fbfad8676fbb073deb7c22466221d76bf7f92c64..2504c27646e7727ea3ba9892200179c70416c8ed 100644
--- a/atdb/taskdatabase/models.py
+++ b/atdb/taskdatabase/models.py
@@ -133,12 +133,6 @@ class Task(models.Model):
             tasks_for_this_sasid = Task.objects.filter(sas_id=self.sas_id)
             self.calculated_qualities = qualities.calculate_qualities(self, tasks_for_this_sasid, quality_thresholds)
 
-            try:
-                self.remarks['calculated_qualities'] = self.calculated_qualities
-            except:
-                self.remarks = {}
-                self.remarks['calculated_qualities'] = self.calculated_qualities
-
         super(Task, self).save(*args, **kwargs)
 
 
diff --git a/atdb/taskdatabase/services/algorithms.py b/atdb/taskdatabase/services/algorithms.py
index 75d1f4ca37db36ae9c68a8b4b50aebb01ed4bf68..81cfcf36b6af69fc038babfe127f249c551f7648 100644
--- a/atdb/taskdatabase/services/algorithms.py
+++ b/atdb/taskdatabase/services/algorithms.py
@@ -801,7 +801,7 @@ def construct_summary(task):
     results = ""
     total_size_input = 0
     total_size_output = 0
-    qualities = {'poor': 0, 'moderate': 0, 'good': 0}
+    quality_values = {'poor': 0, 'moderate': 0, 'good': 0}
 
     sas_id = task.sas_id
     title = "<h4>Summary File for SAS_ID " + task.sas_id + "</h4> "
@@ -885,9 +885,9 @@ def construct_summary(task):
 
                 try:
                     key = task.calculated_qualities['per_task']
-                    qualities[key] = qualities[key] + 1
+                    quality_values[key] = quality_values[key] + 1
                 except:
-                    # ignore the tasks that have no calculated quality (they are probably not 'stored').
+                    # ignore the tasks that have no calculated quality.
                     pass
 
                 results += line
@@ -908,7 +908,7 @@ def construct_summary(task):
                 totals += '<tr><td colspan="2"><b>Calculated Quality</b></td>'
                 totals += '<td class="' + sasid_quality + '">' + str(sasid_quality) + '</td></tr>'
 
-                totals += '<tr><td colspan="2"><b>Quality Statistics</b></td><td>' + str(qualities) + '</td></tr>'
+                totals += '<tr><td colspan="2"><b>Quality Statistics</b></td><td>' + str(quality_values) + '</td></tr>'
 
                 try:
                     quality_thresholds = json.loads(Configuration.objects.get(key='quality_thresholds').value)
diff --git a/atdb/taskdatabase/services/calculated_qualities.py b/atdb/taskdatabase/services/calculated_qualities.py
index c6c2a87b0bf3d23b2173131ae4f2616b4bb9cde0..31ac82cef83be01e37506fe2377c8f8e1a52ca5d 100644
--- a/atdb/taskdatabase/services/calculated_qualities.py
+++ b/atdb/taskdatabase/services/calculated_qualities.py
@@ -1,6 +1,5 @@
 import logging
 logger = logging.getLogger(__name__)
-import json
 
 def calculate_qualities(task, tasks_for_this_sasid, quality_thresholds):
     """"
@@ -69,6 +68,7 @@ def calculate_qualities(task, tasks_for_this_sasid, quality_thresholds):
 
 
             total = qualities['poor'] + qualities['moderate'] + qualities['good']
+            quality_sasid = None
             if total > 0:
                 percentage_poor = (qualities['poor'] / total) * 100
                 percentage_good = (qualities['good'] / total) * 100
diff --git a/atdb/taskdatabase/tests.py b/atdb/taskdatabase/tests.py
index 7ce503c2dd97ba78597f6ff6e4393132753573f6..14ce21a1f97bfd688a0de36d744cdf348b0672a2 100644
--- a/atdb/taskdatabase/tests.py
+++ b/atdb/taskdatabase/tests.py
@@ -1,3 +1,267 @@
 from django.test import TestCase
-
+import json
+from .services import calculated_qualities as qualities
+from .models import Configuration, Task
 # Create your tests here.
+class TestCalculatedQualities(TestCase):
+
+    @classmethod
+    def setUpTestData(cls):
+        print("setUpTestData: Run once to set up non-modified data for all class methods.")
+        # Set up non-modified objects used by all test methods
+        quality_thresholds = {
+            "moderate": 20,
+            "poor": 50,
+            "overall_poor": 50,
+            "overall_good": 90,
+        }
+        Configuration.objects.create(key="quality_thresholds", value=json.dumps(quality_thresholds))
+
+    def setUp(self):
+        print("setUp: Run once for every test method to setup clean data.")
+
+        outputs0 = {
+            "quality": {
+                "details": {},
+                "observing-conditions": "N/A",
+                "sensitivity": "N/A",
+                "summary": {
+                    "L526107_summaryIS.tar": {
+                        "added": [],
+                        "deleted": [],
+                        "input_name": "L526107_summaryIS.tar",
+                        "input_size": 495749120,
+                        "input_size_str": "472.78 MB",
+                        "output_name": "L526107_summaryIS.tar",
+                        "output_size": 283791360,
+                        "output_size_str": "270.64 MB",
+                        "rfi_percent": 0,
+                        "size_ratio": 0.5724495486749427
+                    }
+                },
+                "uv-coverage": "N/A"
+            },
+        }
+
+        outputs1 = {
+            "quality": {
+                "details": {},
+                "observing-conditions": "N/A",
+                "sensitivity": "N/A",
+                "summary": {
+                    "L526107_SAP002_B073_P000_bf.tar": {
+                        "added": [
+                            "stokes/SAP2/BEAM73/L526105_SAP2_BEAM73_2bit.fits",
+                            "stokes/SAP2/BEAM73/L526105_SAP2_BEAM73_2bit_ldv_psrfits_requantisation.log"
+                        ],
+                        "deleted": [
+                            "stokes/SAP2/BEAM73/L526105_SAP2_BEAM73.fits"
+                        ],
+                        "input_name": "L526107_SAP002_B073_P000_bf.tar",
+                        "input_size": 20353853440,
+                        "input_size_str": "18.96 GB",
+                        "output_name": "L526107_SAP002_B073_P000_bf.tar",
+                        "output_size": 6024990720,
+                        "output_size_str": "5.61 GB",
+                        "rfi_percent": 11.167,
+                        "size_ratio": 0.2960122876860019
+                    }
+                },
+                "uv-coverage": "N/A"
+            },
+        }
+        
+        outputs2 = {
+            "quality": {
+                "details": {},
+                "observing-conditions": "N/A",
+                "sensitivity": "N/A",
+                "summary": {
+                    "L526107_SAP002_B073_P000_bf.tar": {
+                        "added": [
+                            "stokes/SAP2/BEAM73/L526105_SAP2_BEAM73_2bit.fits",
+                            "stokes/SAP2/BEAM73/L526105_SAP2_BEAM73_2bit_ldv_psrfits_requantisation.log"
+                        ],
+                        "deleted": [
+                            "stokes/SAP2/BEAM73/L526105_SAP2_BEAM73.fits"
+                        ],
+                        "input_name": "L526107_SAP002_B073_P000_bf.tar",
+                        "input_size": 20353853440,
+                        "input_size_str": "18.96 GB",
+                        "output_name": "L526107_SAP002_B073_P000_bf.tar",
+                        "output_size": 6024990720,
+                        "output_size_str": "5.61 GB",
+                        "rfi_percent": 22.167,
+                        "size_ratio": 0.2960122876860019
+                    }
+                },
+                "uv-coverage": "N/A"
+            },
+        }
+
+        outputs3 = {
+            "quality": {
+                "details": {},
+                "observing-conditions": "N/A",
+                "sensitivity": "N/A",
+                "summary": {
+                    "L526107_SAP002_B072_P000_bf.tar": {
+                        "added": [
+                            "stokes/SAP2/BEAM72/L526105_SAP2_BEAM72_2bit.fits",
+                            "stokes/SAP2/BEAM72/L526105_SAP2_BEAM72_2bit_ldv_psrfits_requantisation.log"
+                        ],
+                        "deleted": [
+                            "stokes/SAP2/BEAM72/L526105_SAP2_BEAM72.fits"
+                        ],
+                        "input_name": "L526107_SAP002_B072_P000_bf.tar",
+                        "input_size": 20353843200,
+                        "input_size_str": "18.96 GB",
+                        "output_name": "L526107_SAP002_B072_P000_bf.tar",
+                        "output_size": 6024980480,
+                        "output_size_str": "5.61 GB",
+                        "rfi_percent": 31.921,
+                        "size_ratio": 0.2960119335104242
+                    }
+                },
+                "uv-coverage": "N/A"
+            },
+
+        }
+
+        outputs4 = {
+            "quality": {
+                "details": {},
+                "observing-conditions": "N/A",
+                "sensitivity": "N/A",
+                "summary": {
+                    "L526107_SAP002_B070_P000_bf.tar": {
+                        "added": [
+                            "stokes/SAP2/BEAM70/L526105_SAP2_BEAM70_2bit.fits",
+                            "stokes/SAP2/BEAM70/L526105_SAP2_BEAM70_2bit_ldv_psrfits_requantisation.log"
+                        ],
+                        "deleted": [
+                            "stokes/SAP2/BEAM70/L526105_SAP2_BEAM70.fits"
+                        ],
+                        "input_name": "L526107_SAP002_B070_P000_bf.tar",
+                        "input_size": 20353525760,
+                        "input_size_str": "18.96 GB",
+                        "output_name": "L526107_SAP002_B070_P000_bf.tar",
+                        "output_size": 6024755200,
+                        "output_size_str": "5.61 GB",
+                        "rfi_percent": 52.164,
+                        "size_ratio": 0.2960054818531843
+                    }
+                },
+                "uv-coverage": "N/A"
+            },
+        }
+
+        outputs5 = {
+            "quality": {
+                "details": {},
+                "observing-conditions": "N/A",
+                "sensitivity": "N/A",
+                "summary": {
+                    "L526107_SAP002_B072_P000_bf.tar": {
+                        "added": [
+                            "stokes/SAP2/BEAM72/L526105_SAP2_BEAM72_2bit.fits",
+                            "stokes/SAP2/BEAM72/L526105_SAP2_BEAM72_2bit_ldv_psrfits_requantisation.log"
+                        ],
+                        "deleted": [
+                            "stokes/SAP2/BEAM72/L526105_SAP2_BEAM72.fits"
+                        ],
+                        "input_name": "L526107_SAP002_B072_P000_bf.tar",
+                        "input_size": 20353843200,
+                        "input_size_str": "18.96 GB",
+                        "output_name": "L526107_SAP002_B072_P000_bf.tar",
+                        "output_size": 6024980480,
+                        "output_size_str": "5.61 GB",
+                        "size_ratio": 0.2960119335104242
+                    }
+                },
+                "uv-coverage": "N/A"
+            },
+
+        }
+
+        outputs6 = {
+            "quality": {
+                "details": {},
+                "observing-conditions": "N/A",
+                "sensitivity": "N/A",
+                "summary": {
+                    "L526107_SAP002_B070_P000_bf.tar": {
+                        "added": [
+                            "stokes/SAP2/BEAM70/L526105_SAP2_BEAM70_2bit.fits",
+                            "stokes/SAP2/BEAM70/L526105_SAP2_BEAM70_2bit_ldv_psrfits_requantisation.log"
+                        ],
+                        "deleted": [
+                            "stokes/SAP2/BEAM70/L526105_SAP2_BEAM70.fits"
+                        ],
+                        "input_name": "L526107_SAP002_B070_P000_bf.tar",
+                        "input_size": 20353525760,
+                        "input_size_str": "18.96 GB",
+                        "output_name": "L526107_SAP002_B070_P000_bf.tar",
+                        "output_size": 6024755200,
+                        "output_size_str": "5.61 GB",
+                        "size_ratio": 0.2960054818531843
+                    }
+                },
+                "uv-coverage": "N/A"
+            },
+        }
+
+        # create a list of Tasks with various values of rfi_percent to test the quality algorithms
+        # rfi_percent=0, this task should not be included in the calculates
+        Task.objects.get_or_create(sas_id=54321, status='processed', outputs=outputs0)
+
+        # rfi_percent 11,22,31,52
+        Task.objects.get_or_create(sas_id=54321, status='processed', outputs=outputs1)
+        Task.objects.get_or_create(sas_id=54321, status='processed', outputs=outputs2)
+        Task.objects.get_or_create(sas_id=54321, status='processed', outputs=outputs3)
+        Task.objects.get_or_create(sas_id=54321, status='processed', outputs=outputs4)
+        
+        # tasks without rfi_percent (so simulating a different pipeline)
+        Task.objects.get_or_create(sas_id=12345, status='processed', outputs=outputs5)
+        Task.objects.get_or_create(sas_id=12345, status='processed', outputs=outputs6)
+
+    def test_count_tasks(self):
+        actual = Task.objects
+        count = actual.count()
+        self.assertEqual(count,7)
+
+    def test_run_quality_calculation_in_task_model_when_stored(self):
+        for task in Task.objects.all():
+            task.new_status = 'stored'
+            task.save()
+
+        # only 4 tasks should now have calculated_qualities
+        count = 0
+        for task in Task.objects.all():
+            if task.calculated_qualities['per_sasid']:
+                count += 1
+
+        self.assertEqual(count,4)
+
+
+    def test_calculated_qualities_per_task(self):
+
+        # read the quality thresholds from the test database
+        quality_thresholds = json.loads(Configuration.objects.get(key="quality_thresholds").value)
+
+        # get the tasks for sas_id 54321
+        tasks_for_this_sasid = Task.objects.filter(sas_id=54321)
+
+        # run the algorithms and gather the values
+        quality_values = {'poor': 0, 'moderate': 0, 'good': 0}
+
+        for task in tasks_for_this_sasid:
+            q = qualities.calculate_qualities(task, tasks_for_this_sasid, quality_thresholds)
+            try:
+                key = task.calculated_qualities['per_task']
+                quality_values[key] = quality_values[key] + 1
+            except:
+                # ignore the tasks that have no calculated quality.
+                pass
+
+        self.assertEqual(quality_values,{'poor': 1, 'moderate': 2, 'good': 1})
\ No newline at end of file