diff --git a/fertiscan/db/metadata/inspection/__init__.py b/fertiscan/db/metadata/inspection/__init__.py index 0e9c07db..7aa97c14 100644 --- a/fertiscan/db/metadata/inspection/__init__.py +++ b/fertiscan/db/metadata/inspection/__init__.py @@ -112,8 +112,8 @@ class Specifications(ValidatedModel): fr: List[Specification] -# Awkwardly named so to avoid name conflict this represents the inspection object in the database -# and not the inspection object used as a form on the application +# Awkwardly named so to avoid name conflict this represents the inspection object in the database +# and not the inspection object used as a form on the application class DBInspection(ValidatedModel): id: UUID4 verified: bool = False @@ -188,7 +188,7 @@ def build_inspection_import(analysis_form: dict,user_id) -> str: website=org.get("website"), phone_number=org.get("phone_number"), edited=False, - is_main_contact = False + is_main_contact=False, ) ) @@ -225,7 +225,6 @@ def build_inspection_import(analysis_form: dict,user_id) -> str: record_keeping=None, ) - cautions = SubLabel( en=analysis_form.get("cautions_en", []), fr=analysis_form.get("cautions_fr", []), @@ -360,12 +359,22 @@ def build_inspection_export(cursor, inspection_id) -> str: metrics.density = metrics.density or Metric() product_info.metrics = metrics + # Retrieve the registration numbers + reg_numbers = registration_number.get_registration_numbers_json( + cursor, label_info_id + ) + reg_number_model_list = [] + for reg_number in reg_numbers["registration_numbers"]: + + reg_number_model_list.append(RegistrationNumber.model_validate(reg_number)) + product_info.registration_numbers = reg_number_model_list + # get the organizations information (Company and Manufacturer) orgs = organization.get_organizations_info_json(cursor, label_info_id) org_list = [] - if len(orgs["organizations"])>0: + if len(orgs["organizations"]) > 0: for org in orgs["organizations"]: - org_list.append(OrganizationInformation.model_validate(org)) + org_list.append(OrganizationInformation.model_validate(org)) # Get all the sub labels sub_labels = sub_label.get_sub_label_json(cursor, label_info_id) diff --git a/fertiscan/db/queries/inspection/__init__.py b/fertiscan/db/queries/inspection/__init__.py index 76a75881..6716ef32 100644 --- a/fertiscan/db/queries/inspection/__init__.py +++ b/fertiscan/db/queries/inspection/__init__.py @@ -131,6 +131,7 @@ def is_inspection_verified(cursor: Cursor, inspection_id): "Failed to check inspection verification status. No data returned." ) + VERIFIED = 0 UPLOAD_DATE = 1 UPDATED_AT = 2 diff --git a/fertiscan/db/queries/label/__init__.py b/fertiscan/db/queries/label/__init__.py index c534df66..9929a08f 100644 --- a/fertiscan/db/queries/label/__init__.py +++ b/fertiscan/db/queries/label/__init__.py @@ -27,7 +27,7 @@ def new_label_information( title_en: str, title_fr: str, is_minimal: bool, - record_keeping:bool, + record_keeping: bool, ): """ This function create a new label_information in the database. @@ -183,7 +183,8 @@ def get_label_dimension(cursor, label_id): ) return data -def delete_label_info(cursor:Cursor, label_id:str): + +def delete_label_info(cursor: Cursor, label_id: str): """ This function deletes a label information from the database. diff --git a/fertiscan/db/queries/organization/__init__.py b/fertiscan/db/queries/organization/__init__.py index 8b4c57f5..ac3200cc 100644 --- a/fertiscan/db/queries/organization/__init__.py +++ b/fertiscan/db/queries/organization/__init__.py @@ -63,7 +63,14 @@ def new_organization(cursor: Cursor, name, website, phone_number, address): @handle_query_errors(OrganizationInformationCreationError) def new_organization_information( - cursor: Cursor, address: str, name: str, website: str, phone_number: str, label_id: UUID, edited: bool = False, is_main_contact: bool = False + cursor: Cursor, + address: str, + name: str, + website: str, + phone_number: str, + label_id: UUID, + edited: bool = False, + is_main_contact: bool = False, ): """ This function create a new organization information in the database using function. @@ -81,7 +88,9 @@ def new_organization_information( - str: The UUID of the organization information """ if label_id is None: - raise OrganizationInformationCreationError("Label ID is required for organization information creation.") + raise OrganizationInformationCreationError( + "Label ID is required for organization information creation." + ) query = """ SELECT new_organization_information(%s, %s, %s, %s, %s, %s, %s); """ @@ -101,6 +110,7 @@ def new_organization_information( return result[0] raise OrganizationCreationError("Failed to create Organization. No data returned.") + @handle_query_errors(OrganizationInformationRetrievalError) def get_organization_info(cursor: Cursor, information_id): """ @@ -134,6 +144,7 @@ def get_organization_info(cursor: Cursor, information_id): "Organization information not found with information_id: " + information_id ) + def get_organizations_info_label(cursor: Cursor, label_id: UUID): """ This function get a organization information from the database. @@ -188,7 +199,8 @@ def get_organizations_info_json(cursor: Cursor, label_id: UUID) -> dict: raise OrganizationInformationRetrievalError( "Failed to get Registration Numbers with the given label_id. No data returned." ) - + + def get_organization_json(cursor: Cursor, fertilizer_id: UUID) -> dict: """ This function get a organization information from the database. @@ -217,9 +229,10 @@ def get_organization_json(cursor: Cursor, fertilizer_id: UUID) -> dict: else: return {} + @handle_query_errors(OrganizationInformationUpdateError) def update_organization_info( - cursor: Cursor, information_id:UUID, name, website, phone_number + cursor: Cursor, information_id: UUID, name, website, phone_number ): """ This function update a organization information in the database. @@ -255,6 +268,7 @@ def update_organization_info( ) return information_id + def upsert_organization_info(cursor: Cursor, organization_info, label_id: UUID): """ This function upserts an organization information in the database. @@ -269,9 +283,16 @@ def upsert_organization_info(cursor: Cursor, organization_info, label_id: UUID): query = """ SELECT upsert_organization_info(%s, %s); """ - cursor.execute(query, (organization_info, str(label_id),)) + cursor.execute( + query, + ( + organization_info, + str(label_id), + ), + ) return cursor.fetchone()[0] + def upsert_organization(cursor: Cursor, organization_info_id: UUID): """ This function upserts an organization information in the database. @@ -286,12 +307,12 @@ def upsert_organization(cursor: Cursor, organization_info_id: UUID): query = """ SELECT upsert_organization(%s); """ - cursor.execute(query, ( str(organization_info_id),)) + cursor.execute(query, (str(organization_info_id),)) return cursor.fetchone()[0] @handle_query_errors(OrganizationRetrievalError) -def get_organization(cursor: Cursor, organization_id:UUID): +def get_organization(cursor: Cursor, organization_id: UUID): """ This function get a organization from the database. diff --git a/tests/fertiscan/db/delete_inspection/test_delete_inspection.py b/tests/fertiscan/db/delete_inspection/test_delete_inspection.py index 35df6c3a..95c97349 100644 --- a/tests/fertiscan/db/delete_inspection/test_delete_inspection.py +++ b/tests/fertiscan/db/delete_inspection/test_delete_inspection.py @@ -53,8 +53,8 @@ def setUp(self): self.inspection_id = inspection_data["inspection_id"] self.label_info_id = inspection_data["product"]["label_id"] - #self.company_info_id = inspection_data["company"]["id"] - #self.manufacturer_info_id = inspection_data["manufacturer"]["id"] + # self.company_info_id = inspection_data["company"]["id"] + # self.manufacturer_info_id = inspection_data["manufacturer"]["id"] # Update the inspection to verified true inspection_data["verified"] = True diff --git a/tests/fertiscan/db/test_organization.py b/tests/fertiscan/db/test_organization.py index f02ae0a8..e113999e 100644 --- a/tests/fertiscan/db/test_organization.py +++ b/tests/fertiscan/db/test_organization.py @@ -105,7 +105,13 @@ def setUp(self): self.cursor = self.con.cursor() db.create_search_path(self.con, self.cursor, DB_SCHEMA) - self.owner_id = organization.new_organization(cursor=self.cursor, name="test-owner", website="www.test.com", phone_number="123456789", address="test-address") + self.owner_id = organization.new_organization( + cursor=self.cursor, + name="test-owner", + website="www.test.com", + phone_number="123456789", + address="test-address", + ) self.province_name = "test-province" self.region_name = "test-region" @@ -122,13 +128,13 @@ def tearDown(self): def test_new_location(self): location_id = organization.new_location( - self.cursor, self.name, self.address, self.region_id,self.owner_id + self.cursor, self.name, self.address, self.region_id, self.owner_id ) self.assertTrue(validator.is_valid_uuid(location_id)) def test_get_location(self): location_id = organization.new_location( - self.cursor, self.name, self.address, self.region_id,self.owner_id + self.cursor, self.name, self.address, self.region_id, self.owner_id ) location_data = organization.get_location(self.cursor, location_id) @@ -203,32 +209,50 @@ def setUp(self): self.record_keeping, ) - def tearDown(self): self.con.rollback() db.end_query(self.con, self.cursor) def test_new_organization_information_with_address(self): id = organization.new_organization_information( - self.cursor, self.address, self.name, self.website, self.phone, self.label_information_id, False, True + self.cursor, + self.address, + self.name, + self.website, + self.phone, + self.label_information_id, + False, + True, ) self.assertTrue(validator.is_valid_uuid(id)) def test_new_organization_info_no_address(self): id = organization.new_organization_information( - cursor=self.cursor, address=None, name=self.name, website=self.website, phone_number=self.phone, label_id=self.label_information_id, edited=False,is_main_contact=True + cursor=self.cursor, + address=None, + name=self.name, + website=self.website, + phone_number=self.phone, + label_id=self.label_information_id, + edited=False, + is_main_contact=True, ) self.assertTrue(validator.is_valid_uuid(id)) def test_new_organization_empty(self): with self.assertRaises(organization.OrganizationInformationCreationError): - organization.new_organization( - self.cursor, None, None, None, None - ) + organization.new_organization(self.cursor, None, None, None, None) def test_get_organization_info(self): id = organization.new_organization_information( - self.cursor, self.address, self.name, self.website, self.phone, self.label_information_id, False, True + self.cursor, + self.address, + self.name, + self.website, + self.phone, + self.label_information_id, + False, + True, ) data = organization.get_organization_info(self.cursor, id) self.assertEqual(data[0], self.name) @@ -239,16 +263,24 @@ def test_get_organization_info(self): self.assertEqual(data[5], False) self.assertEqual(data[6], True) - def test_get_organization_info_not_found(self): with self.assertRaises(organization.OrganizationInformationNotFoundError): organization.get_organization_info(self.cursor, str(uuid.uuid4())) def test_get_organization_info_label(self): organization.new_organization_information( - self.cursor, self.address, self.name, self.website, self.phone, self.label_information_id, False, True + self.cursor, + self.address, + self.name, + self.website, + self.phone, + self.label_information_id, + False, + True, + ) + data = organization.get_organizations_info_label( + self.cursor, self.label_information_id ) - data = organization.get_organizations_info_label(self.cursor, self.label_information_id) self.assertEqual(data[0][0], self.name) self.assertEqual(data[0][1], self.website) self.assertEqual(data[0][2], self.phone) @@ -259,7 +291,14 @@ def test_update_organization_info(self): new_website = "www.new.com" new_phone = "987654321" id = organization.new_organization_information( - self.cursor, self.address, self.name, self.website, self.phone, self.label_information_id, False, True + self.cursor, + self.address, + self.name, + self.website, + self.phone, + self.label_information_id, + False, + True, ) old_data = organization.get_organization_info(self.cursor, id) self.assertEqual(old_data[0], self.name) @@ -281,7 +320,7 @@ def test_new_organization_information(self): name=self.name, website=self.website, phone_number=self.phone, - label_id=self.label_information_id + label_id=self.label_information_id, ) self.assertTrue(validator.is_valid_uuid(id)) @@ -292,7 +331,7 @@ def test_get_organizations_info_json(self): name=self.name, website=self.website, phone_number=self.phone, - label_id=self.label_information_id + label_id=self.label_information_id, ) manufacturer_id = organization.new_organization_information( self.cursor, @@ -300,15 +339,19 @@ def test_get_organizations_info_json(self): name=self.name, website=self.website, phone_number=self.phone, - label_id=self.label_information_id + label_id=self.label_information_id, + ) + data = organization.get_organizations_info_json( + self.cursor, self.label_information_id ) - data = organization.get_organizations_info_json(self.cursor, self.label_information_id) self.assertEqual(len(data["organizations"]), 2) self.assertEqual(data["organizations"][0]["id"], str(company_id)) self.assertEqual(data["organizations"][1]["id"], str(manufacturer_id)) def test_get_organizations_info_json_not_found(self): - data = organization.get_organizations_info_json(self.cursor, self.label_information_id) + data = organization.get_organizations_info_json( + self.cursor, self.label_information_id + ) self.assertDictEqual(data, {"organizations": []}) def test_upsert_organizations_info(self): @@ -323,17 +366,39 @@ def test_upsert_organizations_info(self): phone_number=self.phone, address=self.address, edited=False, - is_main_contact=True + is_main_contact=True, ).model_dump_json() old_org = json.dumps([old_org]) - organizations_dict = {"organizations": [{"name": self.name, "website": self.website, "phone_number": self.phone, "address": self.address,"edited": True,"is_main_contact": True}]} + organizations_dict = { + "organizations": [ + { + "name": self.name, + "website": self.website, + "phone_number": self.phone, + "address": self.address, + "edited": True, + "is_main_contact": True, + } + ] + } # Test inserting a new organization information - self.assertRaises(organization.OrganizationInformationNotFoundError, organization.get_organizations_info_label, self.cursor, self.label_information_id) - received_data = organization.upsert_organization_info(self.cursor, json.dumps(organizations_dict["organizations"]), self.label_information_id) - upserted_data = organization.get_organizations_info_label(self.cursor, self.label_information_id) + self.assertRaises( + organization.OrganizationInformationNotFoundError, + organization.get_organizations_info_label, + self.cursor, + self.label_information_id, + ) + received_data = organization.upsert_organization_info( + self.cursor, + json.dumps(organizations_dict["organizations"]), + self.label_information_id, + ) + upserted_data = organization.get_organizations_info_label( + self.cursor, self.label_information_id + ) self.assertIsNotNone(upserted_data) self.assertIsNotNone(received_data[0]["name"]) self.assertIsNotNone(received_data[0]["id"]) @@ -346,24 +411,37 @@ def test_upsert_organizations_info(self): received_data[0]["phone_number"] = new_phone received_data[0]["address"] = new_address - organization.upsert_organization_info(self.cursor, json.dumps(received_data), self.label_information_id) - new_data = organization.get_organizations_info_label(self.cursor, self.label_information_id) + organization.upsert_organization_info( + self.cursor, json.dumps(received_data), self.label_information_id + ) + new_data = organization.get_organizations_info_label( + self.cursor, self.label_information_id + ) self.assertIsNotNone(new_data) self.assertEqual(len(new_data), 1) self.assertEqual(new_data[0][0], new_name) self.assertEqual(new_data[0][1], new_website) self.assertEqual(new_data[0][2], new_phone) - self.assertNotEqual(new_data[0][3], upserted_data[0][3]) # Address should be updated therefore the id must have changed + self.assertNotEqual( + new_data[0][3], upserted_data[0][3] + ) # Address should be updated therefore the id must have changed def test_delete_label_with_linked_organization_information(self): # create a organization information organization_id = organization.new_organization_information( - self.cursor,self.address, self.name, self.website, self.phone, self.label_information_id,False,True + self.cursor, + self.address, + self.name, + self.website, + self.phone, + self.label_information_id, + False, + True, ) # label_info = label.get_label_information_json(self.cursor, self.label_information_id) # Attempt to delete the inspection, which should raise a notice but not fail deleted_rows = label.delete_label_info(self.cursor, self.label_information_id) - self.assertGreaterEqual(deleted_rows,1) + self.assertGreaterEqual(deleted_rows, 1) self.cursor.execute( "SELECT COUNT(*) FROM organization_information WHERE id = %s;", @@ -373,8 +451,8 @@ def test_delete_label_with_linked_organization_information(self): self.assertEqual( org_count, 0, - "Organization information should have been deleted when the label was deleted",) - + "Organization information should have been deleted when the label was deleted", + ) class test_organization(unittest.TestCase): @@ -390,7 +468,7 @@ def setUp(self): self.phone = "123456789" self.location_name = "test-location" self.address = "test-address" - + self.lot_number = "lot_number" self.product_name = "product_name" self.npk = "npk" @@ -422,7 +500,14 @@ def setUp(self): ) self.org_info_id = organization.new_organization_information( - self.cursor, self.address, self.name, self.website, self.phone, self.label_information_id, False, True + self.cursor, + self.address, + self.name, + self.website, + self.phone, + self.label_information_id, + False, + True, ) def tearDown(self): @@ -438,7 +523,7 @@ def test_new_organization(self): def test_new_organization_no_location(self): organization_id = organization.new_organization( self.cursor, self.name, self.website, self.phone, None - ) + ) self.assertTrue(validator.is_valid_uuid(organization_id)) def test_upsert_organization(self): @@ -446,11 +531,11 @@ def test_upsert_organization(self): organization_id = organization.new_organization( self.cursor, self.name, "wrong-website", "wrong-phone", "wrong-address" ) - update_id = organization.upsert_organization( - self.cursor, str(self.org_info_id) - ) + update_id = organization.upsert_organization(self.cursor, str(self.org_info_id)) self.assertEqual(organization_id, update_id) - organization_data = organization.get_organization(self.cursor, str(organization_id)) + organization_data = organization.get_organization( + self.cursor, str(organization_id) + ) self.assertEqual(organization_data[0], self.name) self.assertEqual(organization_data[1], self.website) self.assertEqual(organization_data[2], self.phone) diff --git a/tests/fertiscan/db/update_inspection/test_update_guaranteed.py b/tests/fertiscan/db/update_inspection/test_update_guaranteed.py index 664ef9c8..4ff1fdc7 100644 --- a/tests/fertiscan/db/update_inspection/test_update_guaranteed.py +++ b/tests/fertiscan/db/update_inspection/test_update_guaranteed.py @@ -29,7 +29,7 @@ def setUp(self): db.create_search_path(self.conn, self.cursor, DB_SCHEMA) self.label_id = label.new_label_information( - cursor=self.cursor, + cursor=self.cursor, name="test-label", lot_number=None, npk=None, @@ -39,7 +39,8 @@ def setUp(self): title_en=None, title_fr=None, is_minimal=False, - record_keeping=False,) + record_keeping=False, + ) # Set up test data for guaranteed analysis with open("tests/fertiscan/inspection_export.json") as f: diff --git a/tests/fertiscan/db/update_inspection/test_update_ingredients.py b/tests/fertiscan/db/update_inspection/test_update_ingredients.py index 97c40483..5575f4d9 100644 --- a/tests/fertiscan/db/update_inspection/test_update_ingredients.py +++ b/tests/fertiscan/db/update_inspection/test_update_ingredients.py @@ -21,13 +21,13 @@ class TestUpdateIngredientsFunction(unittest.TestCase): def setUp(self): - # Connect to the PostgreSQL database with the specified schema + # Connect to the PostgreSQL database with the specified schema self.conn = db.connect_db(DB_CONNECTION_STRING, DB_SCHEMA) self.cursor = db.cursor(self.conn) db.create_search_path(self.conn, self.cursor, DB_SCHEMA) self.label_id = label.new_label_information( - cursor=self.cursor, + cursor=self.cursor, name="test-label", lot_number=None, npk=None, @@ -37,7 +37,8 @@ def setUp(self): title_en=None, title_fr=None, is_minimal=False, - record_keeping=False,) + record_keeping=False, + ) # Set up test data for ingredients self.sample_organic_ingredients = json.dumps( @@ -156,6 +157,5 @@ def test_update_organic_ingredients(self): ) - if __name__ == "__main__": unittest.main() diff --git a/tests/fertiscan/db/update_inspection/test_update_inspection.py b/tests/fertiscan/db/update_inspection/test_update_inspection.py index fdd3f1dc..4b78c844 100644 --- a/tests/fertiscan/db/update_inspection/test_update_inspection.py +++ b/tests/fertiscan/db/update_inspection/test_update_inspection.py @@ -6,7 +6,7 @@ import datastore.db.__init__ as db from datastore.db.metadata import picture_set -from datastore.db.queries import user,picture +from datastore.db.queries import user, picture from fertiscan.db.queries import label from fertiscan.db.metadata.inspection import ( DBInspection, @@ -14,6 +14,7 @@ ) from fertiscan.db.queries.inspection import get_inspection_dict, update_inspection from fertiscan.db.queries import organization + load_dotenv() # Database connection and schema settings @@ -30,11 +31,11 @@ class TestUpdateInspectionFunction(unittest.TestCase): def setUp(self): - # Connect to the PostgreSQL database with the specified schema + # Connect to the PostgreSQL database with the specified schema self.conn = db.connect_db(DB_CONNECTION_STRING, DB_SCHEMA) self.cursor = db.cursor(self.conn) db.create_search_path(self.conn, self.cursor, DB_SCHEMA) - + self.user_email = "test-update-inspection@email" self.inspector_id = user.register_user(self.cursor, self.user_email) self.folder_name = "test-folder" @@ -44,7 +45,7 @@ def setUp(self): ) self.F = label.new_label_information( - cursor=self.cursor, + cursor=self.cursor, name="test-label", lot_number=None, npk=None, @@ -54,7 +55,8 @@ def setUp(self): title_en=None, title_fr=None, is_minimal=False, - record_keeping=False,) + record_keeping=False, + ) self.cursor.execute( "INSERT INTO users (email) VALUES ('other_user@example.com') RETURNING id;" @@ -78,7 +80,9 @@ def setUp(self): print(self.created_data["organizations"]) self.created_inspection = Inspection.model_validate(self.created_data) - foo = organization.get_organizations_info_label(self.cursor,self.created_data["product"]["label_id"]) + foo = organization.get_organizations_info_label( + self.cursor, self.created_data["product"]["label_id"] + ) print("=========") print(foo) print("=========") @@ -272,7 +276,6 @@ def test_update_inspection_with_verified_true(self): organization_id, "An organization record should have been created." ) - def test_update_inspection_unauthorized_user(self): # Update the inspection model for testing the update function altered_inspection = self.created_inspection.model_copy() @@ -332,5 +335,6 @@ def test_update_inspection_without_organizations(self): "No organization record should be created when organizations is empty.", ) + if __name__ == "__main__": unittest.main() diff --git a/tests/fertiscan/db/update_inspection/test_update_inspection_python.py b/tests/fertiscan/db/update_inspection/test_update_inspection_python.py index d2c261ac..2c3817b6 100644 --- a/tests/fertiscan/db/update_inspection/test_update_inspection_python.py +++ b/tests/fertiscan/db/update_inspection/test_update_inspection_python.py @@ -5,7 +5,7 @@ from dotenv import load_dotenv -import datastore.db.__init__ as db +import datastore.db.__init__ as db from fertiscan import get_full_inspection_json from fertiscan.db.metadata.inspection import Inspection from fertiscan.db.queries.inspection import update_inspection diff --git a/tests/fertiscan/db/update_inspection/test_update_metrics.py b/tests/fertiscan/db/update_inspection/test_update_metrics.py index a1abff8d..0b10d5a4 100644 --- a/tests/fertiscan/db/update_inspection/test_update_metrics.py +++ b/tests/fertiscan/db/update_inspection/test_update_metrics.py @@ -20,14 +20,14 @@ class TestUpdateMetricsFunction(unittest.TestCase): - def setUp(self): + def setUp(self): # Connect to the PostgreSQL database with the specified schema self.conn = db.connect_db(DB_CONNECTION_STRING, DB_SCHEMA) self.cursor = db.cursor(self.conn) db.create_search_path(self.conn, self.cursor, DB_SCHEMA) self.label_id = label.new_label_information( - cursor=self.cursor, + cursor=self.cursor, name="test-label", lot_number=None, npk=None, @@ -37,7 +37,8 @@ def setUp(self): title_en=None, title_fr=None, is_minimal=False, - record_keeping=False,) + record_keeping=False, + ) # Set up test data for metrics using Pydantic models self.sample_metrics = Metrics( diff --git a/tests/fertiscan/db/update_inspection/test_update_sub_labels.py b/tests/fertiscan/db/update_inspection/test_update_sub_labels.py index 4000422a..8dc09878 100644 --- a/tests/fertiscan/db/update_inspection/test_update_sub_labels.py +++ b/tests/fertiscan/db/update_inspection/test_update_sub_labels.py @@ -35,7 +35,7 @@ def setUp(self): db.create_search_path(self.conn, self.cursor, DB_SCHEMA) self.label_id = label.new_label_information( - cursor=self.cursor, + cursor=self.cursor, name="test-label", lot_number=None, npk=None, @@ -45,7 +45,8 @@ def setUp(self): title_en=None, title_fr=None, is_minimal=False, - record_keeping=False,) + record_keeping=False, + ) # Load and validate the inspection data from the JSON file using the Inspection model with open(TEST_INPUT_JSON_PATH) as f: @@ -111,7 +112,6 @@ def test_update_sub_labels(self): "SELECT update_sub_labels(%s, %s);", (self.label_id, json.dumps(self.sample_sub_labels)), ) - saved_data = sub_label.get_sub_label_json(self.cursor, self.label_id) nb_sub_labels = len(saved_data["instructions"]["en"]) + len( diff --git a/tests/fertiscan/db/update_inspection/test_upsert_fertilizer.py b/tests/fertiscan/db/update_inspection/test_upsert_fertilizer.py index 93b26941..41ca6678 100644 --- a/tests/fertiscan/db/update_inspection/test_upsert_fertilizer.py +++ b/tests/fertiscan/db/update_inspection/test_upsert_fertilizer.py @@ -6,7 +6,7 @@ import datastore.db.__init__ as db from datastore.db.queries import user, picture from datastore.db.metadata import picture_set -from fertiscan.db.queries import inspection,organization,label +from fertiscan.db.queries import inspection, organization, label load_dotenv() @@ -21,11 +21,11 @@ class TestUpsertFertilizerFunction(unittest.TestCase): - def setUp(self): + def setUp(self): # Connect to the PostgreSQL database with the specified schema self.conn = db.connect_db(DB_CONNECTION_STRING, DB_SCHEMA) self.cursor = db.cursor(self.conn) - db.create_search_path(self.conn, self.cursor, DB_SCHEMA) + db.create_search_path(self.conn, self.cursor, DB_SCHEMA) self.user_email = "test-update-inspection@email" self.inspector_id = user.register_user(self.cursor, self.user_email) @@ -36,7 +36,7 @@ def setUp(self): ) self.label_info_id = label.new_label_information( - cursor=self.cursor, + cursor=self.cursor, name="test-label", lot_number=None, npk=None, @@ -46,7 +46,8 @@ def setUp(self): title_en=None, title_fr=None, is_minimal=False, - record_keeping=False,) + record_keeping=False, + ) # Insert an inspection record self.inspection_id = inspection.new_inspection( @@ -57,8 +58,9 @@ def setUp(self): cursor=self.cursor, name="Test Organization", address="123 Test St.", - website="www.test.com", - phone_number="123-456-7890") + website="www.test.com", + phone_number="123-456-7890", + ) def tearDown(self): # Rollback any changes to leave the database state as it was before the test diff --git a/tests/fertiscan/metadata/test_inspection.py b/tests/fertiscan/metadata/test_inspection.py index bf83aedd..32b1e3be 100644 --- a/tests/fertiscan/metadata/test_inspection.py +++ b/tests/fertiscan/metadata/test_inspection.py @@ -34,7 +34,9 @@ def setUp(self): self.user_id = user.register_user(self.cursor, "test-email@email") - self.formatted_analysis = metadata.build_inspection_import(self.analyse,self.user_id) + self.formatted_analysis = metadata.build_inspection_import( + self.analyse, self.user_id + ) self.picture_set_id = picture.new_picture_set( self.cursor, json.dumps({}), self.user_id @@ -45,7 +47,9 @@ def tearDown(self): db.end_query(self.con, self.cursor) def test_perfect_inspection(self): - formatted_analysis = metadata.build_inspection_import(self.analyse,self.user_id) + formatted_analysis = metadata.build_inspection_import( + self.analyse, self.user_id + ) inspection_dict = inspection.new_inspection_with_label_info( self.cursor, self.user_id, self.picture_set_id, formatted_analysis @@ -56,14 +60,18 @@ def test_perfect_inspection(self): if inspection_id is None: self.fail("Inspection not created") - data = metadata.build_inspection_export( - self.cursor, str(inspection_id) - ) + data = metadata.build_inspection_export(self.cursor, str(inspection_id)) data = json.loads(data) self.assertIsNotNone(data["inspection_id"]) - self.assertEqual(inspection_dict["inspector_id"],data["inspector_id"]) + self.assertEqual(inspection_dict["inspector_id"], data["inspector_id"]) self.assertEqual(inspection_dict["inspection_id"], data["inspection_id"]) self.assertEqual(inspection_dict["verified"], data["verified"]) + print(data["product"]) + + self.assertListEqual( + inspection_dict["product"]["registration_numbers"], + data["product"]["registration_numbers"], + ) self.assertDictEqual(inspection_dict["product"], data["product"]) print("=====\n========\n") print(inspection_dict["organizations"]) @@ -82,7 +90,9 @@ def test_perfect_inspection(self): def test_no_organization(self): self.analyse["organizations"] = [] - formatted_analysis = metadata.build_inspection_import(self.analyse,self.user_id) + formatted_analysis = metadata.build_inspection_import( + self.analyse, self.user_id + ) # print(formatted_analysis) inspection_dict = inspection.new_inspection_with_label_info( @@ -94,19 +104,19 @@ def test_no_organization(self): if inspection_id is None: self.fail("Inspection not created") - data = metadata.build_inspection_export( - self.cursor, str(inspection_id) - ) + data = metadata.build_inspection_export(self.cursor, str(inspection_id)) data = json.loads(data) self.assertIsNotNone(data["inspection_id"]) - self.assertEqual(inspection_dict["inspector_id"],data["inspector_id"]) + self.assertEqual(inspection_dict["inspector_id"], data["inspector_id"]) self.assertEqual(inspection_dict["inspection_id"], data["inspection_id"]) self.assertEqual(inspection_dict["verified"], data["verified"]) self.assertListEqual(inspection_dict["organizations"], data["organizations"]) def test_no_volume(self): self.analyse["volume"] = None - formatted_analysis = metadata.build_inspection_import(self.analyse,self.user_id) + formatted_analysis = metadata.build_inspection_import( + self.analyse, self.user_id + ) # print(formatted_analysis) inspection_dict = inspection.new_inspection_with_label_info( @@ -118,12 +128,10 @@ def test_no_volume(self): if inspection_id is None: self.fail("Inspection not created") - data = metadata.build_inspection_export( - self.cursor, str(inspection_id) - ) + data = metadata.build_inspection_export(self.cursor, str(inspection_id)) data = json.loads(data) self.assertIsNotNone(data["inspection_id"]) - self.assertEqual(inspection_dict["inspector_id"],data["inspector_id"]) + self.assertEqual(inspection_dict["inspector_id"], data["inspector_id"]) self.assertEqual(inspection_dict["inspection_id"], data["inspection_id"]) self.assertEqual(inspection_dict["verified"], data["verified"]) @@ -136,7 +144,9 @@ def test_no_volume(self): def test_no_weight(self): self.analyse["weight"] = [] - formatted_analysis = metadata.build_inspection_import(self.analyse,self.user_id) + formatted_analysis = metadata.build_inspection_import( + self.analyse, self.user_id + ) # print(formatted_analysis) inspection_dict = inspection.new_inspection_with_label_info( @@ -148,12 +158,10 @@ def test_no_weight(self): if inspection_id is None: self.fail("Inspection not created") - data = metadata.build_inspection_export( - self.cursor, str(inspection_id) - ) + data = metadata.build_inspection_export(self.cursor, str(inspection_id)) data = json.loads(data) self.assertIsNotNone(data["inspection_id"]) - self.assertEqual(inspection_dict["inspector_id"],data["inspector_id"]) + self.assertEqual(inspection_dict["inspector_id"], data["inspector_id"]) self.assertEqual(inspection_dict["inspection_id"], data["inspection_id"]) self.assertEqual(inspection_dict["verified"], data["verified"]) @@ -163,7 +171,9 @@ def test_no_weight(self): def test_missing_sub_label(self): self.analyse["instructions_en"] = [] self.analyse["instructions_fr"] = [] - formatted_analysis = metadata.build_inspection_import(self.analyse,self.user_id) + formatted_analysis = metadata.build_inspection_import( + self.analyse, self.user_id + ) # print(formatted_analysis) inspection_dict = inspection.new_inspection_with_label_info( @@ -175,12 +185,10 @@ def test_missing_sub_label(self): if inspection_id is None: self.fail("Inspection not created") - data = metadata.build_inspection_export( - self.cursor, str(inspection_id) - ) + data = metadata.build_inspection_export(self.cursor, str(inspection_id)) data = json.loads(data) self.assertIsNotNone(data["inspection_id"]) - self.assertEqual(inspection_dict["inspector_id"],data["inspector_id"]) + self.assertEqual(inspection_dict["inspector_id"], data["inspector_id"]) self.assertEqual(inspection_dict["inspection_id"], data["inspection_id"]) self.assertEqual(inspection_dict["verified"], data["verified"]) @@ -190,13 +198,39 @@ def test_missing_sub_label(self): self.assertListEqual(data["instructions"]["fr"], []) self.assertListEqual(data["instructions"]["en"], []) + def test_empty_registration_number(self): + self.analyse["registration_number"] = [] + formatted_analysis = metadata.build_inspection_import( + self.analyse, self.user_id + ) + + # print(formatted_analysis) + inspection_dict = inspection.new_inspection_with_label_info( + self.cursor, self.user_id, self.picture_set_id, formatted_analysis + ) + inspection_id = inspection_dict["inspection_id"] + + # label_information_id = inspection_dict["product"]["label_id"] + + if inspection_id is None: + self.fail("Inspection not created") + data = metadata.build_inspection_export(self.cursor, str(inspection_id)) + data = json.loads(data) + self.assertIsNotNone(data["inspection_id"]) + self.assertEqual(inspection_dict["inspector_id"], data["inspector_id"]) + self.assertEqual(inspection_dict["inspection_id"], data["inspection_id"]) + self.assertEqual(inspection_dict["verified"], data["verified"]) + self.assertEqual(data["product"]["registration_numbers"], []) + def test_unequal_sub_label_lengths_and_order(self): expected_instructions_en = ["one", ""] expected_instructions_fr = ["un", "deux"] self.analyse["instructions_en"] = expected_instructions_en self.analyse["instructions_fr"] = expected_instructions_fr - formatted_analysis = metadata.build_inspection_import(self.analyse,self.user_id) + formatted_analysis = metadata.build_inspection_import( + self.analyse, self.user_id + ) inspection_dict = inspection.new_inspection_with_label_info( self.cursor, self.user_id, self.picture_set_id, formatted_analysis @@ -208,9 +242,7 @@ def test_unequal_sub_label_lengths_and_order(self): if inspection_id is None: self.fail("Inspection not created") - data = metadata.build_inspection_export( - self.cursor, str(inspection_id) - ) + data = metadata.build_inspection_export(self.cursor, str(inspection_id)) data = json.loads(data) self.assertIsNotNone(data["instructions"]) @@ -324,7 +356,9 @@ def test_missing_guaranteed_analysis(self): "title": None, "nutrients": [], } - formatted_analysis = metadata.build_inspection_import(self.analyse,self.user_id) + formatted_analysis = metadata.build_inspection_import( + self.analyse, self.user_id + ) # print(formatted_analysis) inspection_dict = inspection.new_inspection_with_label_info( @@ -337,13 +371,11 @@ def test_missing_guaranteed_analysis(self): if inspection_id is None: self.fail("Inspection not created") data = json.loads( - metadata.build_inspection_export( - self.cursor, str(inspection_id) - ) + metadata.build_inspection_export(self.cursor, str(inspection_id)) ) self.assertIsNotNone(data["inspection_id"]) - self.assertEqual(inspection_dict["inspector_id"],data["inspector_id"]) + self.assertEqual(inspection_dict["inspector_id"], data["inspector_id"]) self.assertEqual(inspection_dict["inspection_id"], data["inspection_id"]) self.assertEqual(inspection_dict["verified"], data["verified"]) @@ -398,7 +430,9 @@ def test_missing_guaranteed_analysis(self): # ) def test_null_in_middle_of_sub_label_en(self): - formatted_analysis = metadata.build_inspection_import(self.analyse,self.user_id) + formatted_analysis = metadata.build_inspection_import( + self.analyse, self.user_id + ) # Convert the JSON string to a dictionary formatted_analysis_dict = json.loads(formatted_analysis) @@ -422,9 +456,7 @@ def test_null_in_middle_of_sub_label_en(self): # label_id = inspection_dict["product"]["label_id"] # Get inspection data using the inspection_id and label_id - inspection_data = metadata.build_inspection_export( - self.cursor, inspection_id - ) + inspection_data = metadata.build_inspection_export(self.cursor, inspection_id) inspection_data = json.loads(inspection_data) # Assert that null in cautions_en is replaced by an empty string @@ -443,7 +475,9 @@ def test_null_in_middle_of_sub_label_en(self): ) def test_mismatched_sub_label_lengths_en_longer(self): - formatted_analysis = metadata.build_inspection_import(self.analyse,self.user_id) + formatted_analysis = metadata.build_inspection_import( + self.analyse, self.user_id + ) # Convert the JSON string to a dictionary formatted_analysis_dict = json.loads(formatted_analysis) @@ -467,9 +501,7 @@ def test_mismatched_sub_label_lengths_en_longer(self): # label_id = inspection_dict["product"]["label_id"] # Get inspection data using the inspection_id and label_id - inspection_data = metadata.build_inspection_export( - self.cursor, inspection_id - ) + inspection_data = metadata.build_inspection_export(self.cursor, inspection_id) inspection_data = json.loads(inspection_data) # Assert that both cautions_en and cautions_fr are padded to the same length @@ -484,7 +516,9 @@ def test_mismatched_sub_label_lengths_en_longer(self): ) def test_mismatched_sub_label_lengths_fr_longer(self): - formatted_analysis = metadata.build_inspection_import(self.analyse,self.user_id) + formatted_analysis = metadata.build_inspection_import( + self.analyse, self.user_id + ) # Convert the JSON string to a dictionary formatted_analysis_dict = json.loads(formatted_analysis) @@ -508,9 +542,7 @@ def test_mismatched_sub_label_lengths_fr_longer(self): # label_id = inspection_dict["product"]["label_id"] # Get inspection data using the inspection_id and label_id - inspection_data = metadata.build_inspection_export( - self.cursor, inspection_id - ) + inspection_data = metadata.build_inspection_export(self.cursor, inspection_id) inspection_data = json.loads(inspection_data) # Print the inspection data @@ -528,12 +560,15 @@ def test_mismatched_sub_label_lengths_fr_longer(self): def test_organizations_not_located(self): # Modify analyse data to have empty addresses test_str = "Test string" - orgs = [metadata.OrganizationInformation(name=test_str).model_dump(), - metadata.OrganizationInformation(website=test_str).model_dump() - ] + orgs = [ + metadata.OrganizationInformation(name=test_str).model_dump(), + metadata.OrganizationInformation(website=test_str).model_dump(), + ] self.analyse["organizations"] = orgs - formatted_analysis = metadata.build_inspection_import(self.analyse,self.user_id) + formatted_analysis = metadata.build_inspection_import( + self.analyse, self.user_id + ) # Create inspection and get label information inspection_dict = inspection.new_inspection_with_label_info( @@ -544,9 +579,7 @@ def test_organizations_not_located(self): # label_id = inspection_dict["product"]["label_id"] # Get inspection data using the inspection_id and label_id - inspection_data = metadata.build_inspection_export( - self.cursor, inspection_id - ) + inspection_data = metadata.build_inspection_export(self.cursor, inspection_id) inspection_data = json.loads(inspection_data) # Assert that organization address is empty @@ -605,7 +638,9 @@ def tearDown(self): db.end_query(self.con, self.cursor) def test_perfect_inspection(self): - formatted_analysis = metadata.build_inspection_import(self.analyse,self.user_id) + formatted_analysis = metadata.build_inspection_import( + self.analyse, self.user_id + ) inspection_dict = inspection.new_inspection_with_label_info( self.cursor, self.user_id, self.picture_set_id, formatted_analysis @@ -620,7 +655,9 @@ def test_empty_sub_label(self): self.analyse["cautions_en"] = [] self.analyse["cautions_fr"] = [] - formatted_analysis = metadata.build_inspection_import(self.analyse,self.user_id) + formatted_analysis = metadata.build_inspection_import( + self.analyse, self.user_id + ) # Create inspection and get label information inspection_dict = inspection.new_inspection_with_label_info( @@ -630,9 +667,7 @@ def test_empty_sub_label(self): # label_id = inspection_dict["product"]["label_id"] # Get inspection data using the inspection_id and label_id - inspection_data = metadata.build_inspection_export( - self.cursor, inspection_id - ) + inspection_data = metadata.build_inspection_export(self.cursor, inspection_id) inspection_data = json.loads(inspection_data) # Assert that cautions in both 'en' and 'fr' are empty @@ -647,19 +682,19 @@ def test_missing_keys(self): # intentionally leaving out other required keys } with self.assertRaises(BuildInspectionImportError) as context: - metadata.build_inspection_import(analysis_form,self.user_id) + metadata.build_inspection_import(analysis_form, self.user_id) self.assertIn("The analysis form is missing keys", str(context.exception)) def test_validation_error(self): self.analyse["weight"] = [{"unit": "kg", "value": "invalid_value"}] with self.assertRaises(BuildInspectionImportError) as context: - metadata.build_inspection_import(self.analyse,self.user_id) + metadata.build_inspection_import(self.analyse, self.user_id) self.assertIn("Validation error", str(context.exception)) def test_npk_error(self): self.analyse["npk"] = "invalid_npk" with self.assertRaises(NPKError): - metadata.build_inspection_import(self.analyse,self.user_id) + metadata.build_inspection_import(self.analyse, self.user_id) @patch("fertiscan.db.metadata.inspection.extract_npk") def test_unexpected_error(self, mock_extract_npk): @@ -667,7 +702,7 @@ def test_unexpected_error(self, mock_extract_npk): mock_extract_npk.side_effect = Exception("Simulated unexpected error") with self.assertRaises(BuildInspectionImportError) as context: - metadata.build_inspection_import(self.analyse,self.user_id) + metadata.build_inspection_import(self.analyse, self.user_id) self.assertIn("Unexpected error", str(context.exception)) self.assertIn("Simulated unexpected error", str(context.exception)) diff --git a/tests/fertiscan/test_datastore.py b/tests/fertiscan/test_datastore.py index 6c890b9a..d8e8db2b 100644 --- a/tests/fertiscan/test_datastore.py +++ b/tests/fertiscan/test_datastore.py @@ -17,7 +17,15 @@ import fertiscan import fertiscan.db.metadata.inspection as metadata from datastore.db.queries import picture -from fertiscan.db.queries import inspection, label, metric, nutrients, sub_label,ingredient, organization +from fertiscan.db.queries import ( + inspection, + label, + metric, + nutrients, + sub_label, + ingredient, + organization, +) BLOB_CONNECTION_STRING = os.environ["FERTISCAN_STORAGE_URL"] if BLOB_CONNECTION_STRING is None or BLOB_CONNECTION_STRING == "": @@ -134,7 +142,7 @@ def setUp(self): ) + len(self.analysis_json.get("guaranteed_analysis_fr").get("nutrients")) self.nb_ingredients = len(self.analysis_json.get("ingredients_en")) + len( - self.analysis_json.get("ingredients_fr") + self.analysis_json.get("ingredients_fr") ) # self.nb_micronutrients = len(self.analysis_json.get("micronutrients_en")) + len( @@ -152,7 +160,7 @@ def tearDown(self): print(e) def test_register_analysis(self): - #print(self.user.id) + # print(self.user.id) self.assertTrue(self.container_client.exists()) analysis = asyncio.run( fertiscan.register_analysis( @@ -179,8 +187,10 @@ def test_register_analysis(self): len(metrics), 4 ) # There are 4 metrics in the analysis_json (1 volume, 1 density, 2 weight ) - ingredients = ingredient.get_ingredient_json(self.cursor, str(analysis["product"]["label_id"])) - #print(ingredients) + ingredients = ingredient.get_ingredient_json( + self.cursor, str(analysis["product"]["label_id"]) + ) + # print(ingredients) # specifications = specification.get_all_specifications( # cursor=self.cursor, label_id=str(analysis["product"]["label_id"]) @@ -227,8 +237,12 @@ def test_register_analysis(self): label_dimension = label.get_label_dimension(self.cursor, label_id) - self.assertEqual(str(label_dimension[1][0]), str(analysis["organizations"][0]["id"])) - self.assertEqual(str(label_dimension[1][1]), str(analysis["organizations"][1]["id"])) + self.assertEqual( + str(label_dimension[1][0]), str(analysis["organizations"][0]["id"]) + ) + self.assertEqual( + str(label_dimension[1][1]), str(analysis["organizations"][1]["id"]) + ) self.assertEqual(len(label_dimension[2]), self.nb_instructions) @@ -262,7 +276,9 @@ def test_register_analysis_empty(self): "guaranteed_analysis_fr": {"title": None, "nutrients": []}, } - formatted_analysis = metadata.build_inspection_import(empty_analysis,self.user.id) + formatted_analysis = metadata.build_inspection_import( + empty_analysis, self.user.id + ) picture_set_id = picture.new_picture_set( self.cursor, json.dumps({}), self.user.id ) @@ -280,9 +296,7 @@ def test_register_analysis_empty(self): self.assertIsNone(label_data[1]) # Verify getters - inspection_data = metadata.build_inspection_export( - self.cursor, inspection_id - ) + inspection_data = metadata.build_inspection_export(self.cursor, inspection_id) inspection_data = json.loads(inspection_data) # TODO: investigate if this should pass and why it doesn't # Make sure the inspection data is either a empty array or None @@ -314,7 +328,9 @@ def test_register_analysy_missing_key(self): ) def test_get_full_inspection_json(self): - formatted_analysis = metadata.build_inspection_import(self.analysis_json, self.user.id) + formatted_analysis = metadata.build_inspection_import( + self.analysis_json, self.user.id + ) picture_set_id = picture.new_picture_set( self.cursor, json.dumps({}), self.user.id ) @@ -429,7 +445,7 @@ def test_update_inspection(self): old_name = analysis["guaranteed_analysis"]["fr"][0]["name"] new_name = "Nouveau nom" user_feedback = "This is a feedback" - new_record_keeping= True + new_record_keeping = True # new_specification_en = [ # {"humidity": new_value, "ph": 6.5, "solubility": 100, "edited": True} # ] @@ -551,10 +567,9 @@ def test_update_inspection(self): # Verify organizations are saved orgs = organization.get_organizations_info_label(self.cursor, label_id) - - self.assertEqual(len(orgs), 3) # 2 default + 1 new - self.assertEqual(len(orgs), len(old_organizations)+1) + self.assertEqual(len(orgs), 3) # 2 default + 1 new + self.assertEqual(len(orgs), len(old_organizations) + 1) # VERIFY OLAP new_label_dimension = label.get_label_dimension(self.cursor, label_id)