diff --git a/.github/workflows/full-test.yml b/.github/workflows/full-test.yml new file mode 100644 index 0000000..eb58382 --- /dev/null +++ b/.github/workflows/full-test.yml @@ -0,0 +1,27 @@ +name: run full test + +on: + +jobs: + run_smoke_test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: 3.8 + - name: Install pipenv + run: | + python -m pip install --upgrade pip + python -m pip install --upgrade setuptools wheel + python -m pip install -r tests/misc/requirements.txt + - name: Install test dependencies + run: | + pip install -e ./ + pip install -r tests/misc/requirements.txt + - name: Run smoke test + run: python pytest + working-directory: example + env: + API_BASE_PATH: "https://faceapi.regulaforensics.com/" diff --git a/tests/Tests_detect.py b/tests/Tests_detect.py new file mode 100644 index 0000000..248503e --- /dev/null +++ b/tests/Tests_detect.py @@ -0,0 +1,108 @@ +from regula.facesdk.webclient.gen.model.detect_request_attributes import DetectRequestAttributes +from regula.facesdk.webclient.gen.model.output_image_params import OutputImageParams +from regula.facesdk.webclient.gen.model.quality_request import QualityRequest +from regula.facesdk.webclient.gen.model.detect_request import DetectRequest +from regula.facesdk.webclient.gen.model.process_param import ProcessParam +from regula.facesdk.webclient.gen.model.crop import Crop +from misc.paths_and_urls import * +import pytest +import base64 + + +@pytest.fixture +def detect_setup(): + face1 = read_image_bytes(FACE_1_PATH) + face1_b64 = base64.b64encode(face1).decode('utf-8') + sev_faces = read_image_bytes(SEVERAL_FACES_IMAGE_PATH) + sev_faces_b64 = base64.b64encode(sev_faces).decode('utf-8') + yield [face1_b64, sev_faces_b64] + + +def basic_assertions(response): + # We use this function to avoid repeating code in every test + assert response['code'] == 0 + assert 'results' in response, "'results' field not found in response" + assert 'detections' in response['results'], "'detections' field not found in 'results'" + assert response['results']['detections'], "No detections found" + + +def test_detect_api(facesdk, detect_setup): + request = DetectRequest(image=detect_setup[0]) + response = create_dictionary(facesdk.matching_api.detect(request)) + basic_assertions(response) + + +def test_scenario(facesdk, detect_setup): + scenario = 'QUALITY_FULL' + params = ProcessParam(scenario=scenario) + request = DetectRequest(image=detect_setup[0], process_param=params) + response = create_dictionary(facesdk.matching_api.detect(request)) + basic_assertions(response) + scenario = 'QUALITY_FULL' + assert response['results'][ + 'scenario'] == scenario, f"Expected "+scenario+" but got "+response['results']['scenario'] + + +def test_cropAllFaces_scenario(facesdk, detect_setup): + params = ProcessParam(scenario='cropAllFaces', only_central_face=False) + request = DetectRequest(image=detect_setup[1], process_param=params) + response = create_dictionary(facesdk.matching_api.detect(request)) + basic_assertions(response) + detections = response['results']['detections'] + assert len(detections) == 5, f"Expected 5 detections, but got {len(detections)} detections" + + +def test_only_central_face(facesdk, detect_setup): + params = ProcessParam(only_central_face=True) + request = DetectRequest(image=detect_setup[1], process_param=params) + response = create_dictionary(facesdk.matching_api.detect(request)) + basic_assertions(response) + detections = response['results']['detections'] + assert len(detections) == 1, f"Expected 1 detection, but got {len(detections)} detections" + + +def test_outputImageParams(facesdk, detect_setup): + background_color = [128, 128, 128] + crop_params = Crop(type=0, pad_color=[0, 0, 0], size=[300, 400], ) + oi_params = OutputImageParams(background_color=background_color, crop=crop_params) + params = ProcessParam(output_image_params=oi_params) + request = DetectRequest(image=detect_setup[1], process_param=params) + response = create_dictionary(facesdk.matching_api.detect(request)) + basic_assertions(response) + detections = response['results']['detections'] + assert len(detections) > 0, "No detections found in response" + assert detections[0]['crop'] != '', "'crop' field is empty" + + +def test_quality(facesdk, detect_setup): + attributes = DetectRequestAttributes(config=[{'name': 'Age', 'range': [5, 45]}]) + quality_request = QualityRequest( + background_match_color=[128, 128, 128], + config=[{"name": "Roll", "range": [-5, 5]}] + ) + params = ProcessParam(quality=quality_request) + request = DetectRequest(image=detect_setup[1], process_param=params, attributes=attributes) + response = create_dictionary(facesdk.matching_api.detect(request)) + basic_assertions(response) + detection = response['results']['detections'][0] + assert len(detection) > 0, "No detections found in response" + assert detection['quality']['details'][0]['name'] == 'Roll' + assert detection['quality']['details'][0]['range'] == [-5.0, 5.0] + + +def test_attributes(facesdk, detect_setup): + attributes = DetectRequestAttributes(config=[{'name': 'Age', 'range': [5, 45]}]) + request = DetectRequest(image=detect_setup[1], process_param=ProcessParam(attributes=attributes)) + response = create_dictionary(facesdk.matching_api.detect(request)) + basic_assertions(response) + detection = response['results']['detections'][0] + assert len(detection) > 0, "No detections found in response" + attribute_details = detection['attributes']['details'] + assert attribute_details[0]['name'] == 'Age' + assert 5 <= attribute_details[0]['value'][0] <= 45 + assert 5 <= attribute_details[0]['value'][1] <= 45 + + +def test_without_attributes(facesdk, detect_setup): + request = DetectRequest(image=detect_setup[0]) + facesdk.matching_api.detect(request) diff --git a/tests/Tests_group.py b/tests/Tests_group.py new file mode 100644 index 0000000..c273c89 --- /dev/null +++ b/tests/Tests_group.py @@ -0,0 +1,147 @@ +from regula.facesdk.webclient.gen.model.group_to_create import GroupToCreate +from regula.facesdk.webclient.gen.model.person_fields import PersonFields +from regula.facesdk.webclient.gen.model.update_group import UpdateGroup +from misc.paths_and_urls import * +import pytest + +test_group_name = "test" +name_a = "Person A" +base_metadata = {'description': 'This is a test group'} + + +@pytest.fixture +def groups_setup(facesdk): + # This fixture creates a group before test, passes created group_id to the test and removes this group_id after test + created_group_response = ( + create_dictionary(facesdk.group_api.create_group(group_name=test_group_name, metadata=base_metadata))) + group_id = created_group_response['id'] + yield group_id, created_group_response + delete_response = facesdk.group_api.delete_group(group_id) + assert delete_response is None, f"Unexpected response: {delete_response}" + + +def test_create_and_delete_group(groups_setup): + # We don't need to create group because it's already created via fixture. + # We just need to check creation response, deletion response will be checked in groups_setup + group_id, response_dict = groups_setup + assert response_dict is not None, "No response received" + assert response_dict['name'] == test_group_name, "Name of the group is incorrect" + assert response_dict['metadata']['description'] == base_metadata['description'], ("Metadata of the group is " + "incorrect") + + +def test_get_all_groups(facesdk): + # Step 1: Make a list to store the ids of the created groups + created_group_ids = [] + # Step 2: Creation of groups + for i in range(4): + # Create a group and get its id from response + create_response = create_dictionary(facesdk.group_api.create_group(f"{test_group_name}_{i}")) + group_id = create_response['id'] + # Store the group_id for later deletion + created_group_ids.append(group_id) + + # Step 3: Get all groups + response_dict = create_dictionary(facesdk.group_api.get_all_groups(page=2, size=2)) + + # Step 4: Deletion of groups + for group_id in created_group_ids: + # Remove the group using its id + delete_response = facesdk.group_api.delete_group(group_id) + assert delete_response is None, f"Unexpected response: {delete_response}" + + # Step 5: check that page 2 with 2 items exist + assert response_dict is not None, "No response received" + assert len(response_dict['items']) == 2, f"Expected 2 items on page, but got {len(response_dict['items'])} items" + assert response_dict['page'] == 2, f"Expected page to be 2, but got {response_dict['page']}" + + +def test_get_all_persons_by_group_id(facesdk, groups_setup): + # Step 1: Getting created group_id from fixture + group_id = groups_setup[0] + # Step 2: Adding person to a created group + person_fields = PersonFields(name=name_a, groups=[group_id], metadata=base_metadata) + facesdk.person_api.create_person(person_fields) + # Step 3: Get persons from created group_id + persons_response = facesdk.group_api.get_all_persons_by_group_id(page=1, size=1, group_id=group_id) + persons_response_dict = create_dictionary(persons_response) + + facesdk.person_api.delete_person(persons_response_dict['items'][0]['id']) + assert persons_response_dict is not None, "No response received" + assert persons_response_dict['items'][0]['name'] == name_a, "Name of Person is incorrect" + assert persons_response_dict['items'][0]['metadata']['description'] == base_metadata['description'], \ + "Metadata of the group is incorrect" + assert persons_response_dict['items'][0]['groups'][0] == group_id, "group_id is incorrect" + + +def test_get_group(facesdk, groups_setup): + # Step 1: Get all groups and take the first group_id that appears + groups_response_dict = create_dictionary(facesdk.group_api.get_all_groups(page=1, size=1)) + assert len(groups_response_dict['items']) > 0, "No groups found" + group_id = groups_response_dict['items'][0]['id'] + + # Step 2: Using obtained id to get chosen group + group_response_dict = create_dictionary(facesdk.group_api.get_group(group_id)) + assert group_response_dict is not None, "No response received" + assert group_response_dict['id'] == group_id, "group_id is incorrect" + + +def test_group_update(facesdk, groups_setup): + # Step 1: Getting group_id from the fixture + group_id = groups_setup[0] + # Step 2: Updating group with new name + new_name = 'updated_test_group' + updated_metadata = {'description': 'updated meta'} + facesdk.group_api.update_group(group_id=group_id, + group_to_create=GroupToCreate(name=new_name, metadata=updated_metadata)) + updated_group_response_dict = create_dictionary(facesdk.group_api.get_group(group_id)) + + # Step 3: Checking that name is updated + assert updated_group_response_dict[ + 'name'] == new_name, f"Group name not updated: {updated_group_response_dict['name']}" + assert updated_group_response_dict['metadata']['description'] == updated_metadata[ + 'description'], "Updated group meta is wrong" + + +def test_update_persons_in_group(facesdk, groups_setup): + # Step 1: Getting group_id from the fixture + group_id = groups_setup[0] + + # Step 2: Creating some persons and adding them to the group + person_fields = PersonFields(name=name_a, groups=[group_id], metadata=base_metadata) + facesdk.person_api.create_person(person_fields) + + # Step 3: Getting the group's persons + initial_persons_response = facesdk.group_api.get_all_persons_by_group_id(page=1, size=10, group_id=group_id) + initial_persons_response_dict = create_dictionary(initial_persons_response) + initial_person_ids = [person['id'] for person in initial_persons_response_dict['items']] + + # Step 4: Removing them + update_group_remove = UpdateGroup(remove_items=initial_person_ids) + facesdk.group_api.update_persons_in_group(group_id=group_id, update_group=update_group_remove) + + # Step 5: Creating new persons and adding them to the group + new_person_names = ["New Person A", "New Person B"] + new_person_ids = [] + for name in new_person_names: + person_fields = PersonFields(name=name, groups=[group_id], metadata=base_metadata) + created_person_response_dict = create_dictionary(facesdk.person_api.create_person(person_fields)) + new_person_ids.append(created_person_response_dict['id']) + + # Step 6: Testing that they're here + updated_persons_response_dict = create_dictionary( + facesdk.group_api.get_all_persons_by_group_id(page=1, size=10, group_id=group_id)) + updated_person_ids = [person['id'] for person in updated_persons_response_dict['items']] + assert set(updated_person_ids) == set( + new_person_ids), f"Updated person ids don't match: {updated_person_ids} != {new_person_ids}" + updated_person_names = [person['name'] for person in updated_persons_response_dict['items']] + assert set(updated_person_names) == set( + new_person_names), f"Updated person ids don't match: {updated_person_names} != {new_person_names}" + assert len(updated_persons_response_dict['items']) == 2, 'Expected 2 persons in updated list' + + +def test_create_group_without_metadata(facesdk): + created_group_response_dict = ( + create_dictionary(facesdk.group_api.create_group(group_name=test_group_name))) + group_id = created_group_response_dict['id'] + facesdk.group_api.delete_group(group_id) diff --git a/tests/Tests_matching.py b/tests/Tests_matching.py new file mode 100644 index 0000000..c836c03 --- /dev/null +++ b/tests/Tests_matching.py @@ -0,0 +1,63 @@ +from regula.facesdk.webclient.gen.model.image_source import ImageSource +from regula.facesdk.webclient import MatchImage, MatchRequest +from misc.paths_and_urls import * + + +def validate_response(response, expected_detections_count, expected_first, expected_second=None): + assert response['code'] == 0, f"Unexpected response code: {response['code']}" + assert isinstance(response.get('detections', []), list), "'detections' field should be an array" + assert len(response.get('detections', [])) == expected_detections_count, \ + f"'detections' array should have {expected_detections_count} entries" + assert 'results' in response, "'results' field not found in response" + assert isinstance(response['results'], list), "'results' should be an array" + assert response['results'][0]['first'] == expected_first, f"Expected 'first' to be {expected_first}" + if expected_second is not None: + assert response['results'][0].get('second', + None) == expected_second, f"Expected 'second' to be {expected_second}" + + +def create_match_request(type1, path1, type2=None, path2=None): + images = [MatchImage(index=1, data=read_image_bytes(path1), type=type1)] + if type2 and path2: + images.append(MatchImage(index=2, data=read_image_bytes(path2), type=type2)) + return MatchRequest(images=images) + + +def test_matching_api(facesdk): + match_request = create_match_request(ImageSource.LIVE, FACE_1_PATH, ImageSource.DOCUMENT_RFID, FACE_1_PATH) + response_dict = create_dictionary(facesdk.matching_api.match(match_request)) + validate_response(response_dict, expected_detections_count=2, expected_first=3, expected_second=2) + + +def test_liveAndPrintedDoc_type(facesdk): + match_request = create_match_request(ImageSource.DOCUMENT_PRINTED, PRINTED_DOCUMENT_PATH, ImageSource.LIVE, + LIVE_PHOTO_PATH) + response_dict = create_dictionary(facesdk.matching_api.match(match_request)) + validate_response(response_dict, expected_detections_count=2, expected_first=1, expected_second=3) + + +def test_docWithLive_type(facesdk): + match_request = create_match_request(ImageSource.DOCUMENT_WITH_LIVE, DOCUMENT_WITH_LIVE_PATH) + response_dict = create_dictionary(facesdk.matching_api.match(match_request)) + validate_response(response_dict, expected_detections_count=1, expected_first=4) + + +def test_external_type(facesdk): + match_request = create_match_request(ImageSource.DOCUMENT_PRINTED, PRINTED_DOCUMENT_PATH, ImageSource.EXTERNAL, + LIVE_PHOTO_PATH) + response_dict = create_dictionary(facesdk.matching_api.match(match_request)) + validate_response(response_dict, expected_detections_count=2, expected_first=1, expected_second=5) + + +def test_documentRFID_type(facesdk): + match_request = create_match_request(ImageSource.DOCUMENT_PRINTED, PRINTED_DOCUMENT_PATH, ImageSource.DOCUMENT_RFID, + LIVE_PHOTO_PATH) + response_dict = create_dictionary(facesdk.matching_api.match(match_request)) + validate_response(response_dict, expected_detections_count=2, expected_first=1, expected_second=2) + + +def test_ghost_type(facesdk): + match_request = create_match_request(ImageSource.DOCUMENT_PRINTED, PRINTED_DOCUMENT_PATH, ImageSource.GHOST, + LIVE_PHOTO_PATH) + response_dict = create_dictionary(facesdk.matching_api.match(match_request)) + validate_response(response_dict, expected_detections_count=2, expected_first=1, expected_second=6) diff --git a/tests/Tests_person.py b/tests/Tests_person.py new file mode 100644 index 0000000..be03746 --- /dev/null +++ b/tests/Tests_person.py @@ -0,0 +1,127 @@ +from regula.facesdk.webclient.gen.model.image_fields_image import ImageFieldsImage +from regula.facesdk.webclient.gen.model.search_request import SearchRequest +from regula.facesdk.webclient.gen.model.person_fields import PersonFields +import regula + +from misc.paths_and_urls import * +import pytest + +test_name = "test" +name_a = "Person A" +base_metadata = {'description': 'This is a test group'} + + +@pytest.fixture +def group_and_person_setup(facesdk): + # This fixture creates a group and person before test, passes created group_id to the test and removes this + # group after test + created_group_response_dict = ( + create_dictionary(facesdk.group_api.create_group(group_name=test_name, metadata=base_metadata))) + group_id = created_group_response_dict['id'] + person_fields = PersonFields(name=name_a, groups=[group_id], metadata=base_metadata) + created_person_response_dict = create_dictionary(facesdk.person_api.create_person(person_fields)) + yield facesdk, created_person_response_dict, group_id + facesdk.group_api.delete_group(group_id) + try: + facesdk.person_api.delete_person(created_person_response_dict['id']) + except regula.facesdk.webclient.gen.exceptions.NotFoundException: + pass # Ignore the not found exception and proceed + + +def test_create_person(group_and_person_setup): + # We don't need to create person, cause its created in our fixture. We just need to check the response here + facesdk, person_response_dict, group_id = group_and_person_setup + assert person_response_dict['name'] == "Person A", "The name of the person is incorrect" + assert group_id in person_response_dict['groups'], "The group ID is not present in the person's group list" + assert person_response_dict['metadata']['description'] == base_metadata['description'], \ + "The description of person is incorrect" + + +def test_get_person(group_and_person_setup): + facesdk, person_response_dict, group_id = group_and_person_setup + person_id = person_response_dict['id'] + response = facesdk.person_api.get_person(person_id=person_id) + response_dict = create_dictionary(response) + assert response_dict is not None, "No response received" + assert response_dict['id'] == person_id, f"Expected person_id to be {person_id}, but got {response_dict['id']}" + + +def test_update_person(group_and_person_setup): + facesdk, person_response_dict, group_id = group_and_person_setup + person_id = person_response_dict['id'] + name_b = 'Person B' + description = 'upd' + person_fields = PersonFields(name=name_b, metadata={'description': description}) + facesdk.person_api.update_person(person_id=person_id, person_fields=person_fields) + response = facesdk.person_api.get_person(person_id=person_id) + response_dict = create_dictionary(response) + assert response_dict is not None, "No response received" + assert response_dict['name'] == name_b, f"Expected name to be " + name_b + ", but got {response_dict['name']}" + assert response_dict['metadata']['description'] == description, f"Expected description to be " + description + + +def test_delete_person(group_and_person_setup): + facesdk, person_response_dict, group_id = group_and_person_setup + person_id = person_response_dict['id'] + facesdk.person_api.delete_person(person_id=person_id) + response = facesdk.group_api.get_all_persons_by_group_id(page=1, size=1, group_id=group_id) + response_dict = create_dictionary(response) + assert response_dict['items'] == [], f"Expected 'items' to be empty, but got {response_dict['items']}" + + +def test_get_person_images(group_and_person_setup): + facesdk, person_response_dict, group_id = group_and_person_setup + person_id = person_response_dict['id'] + face1 = read_image_bytes(FACE_1_PATH) + facesdk.person_api.add_image_to_person(person_id=person_id, content=face1) + person_id = person_response_dict['id'] + response = facesdk.person_api.get_all_images_by_person_id(page=1, size=1, person_id=person_id) + response_dict = create_dictionary(response) + assert 'items' in response_dict, "'items' key not found in the response dictionary" + assert "id" in response_dict["items"], 'id of photo not found' + assert "path" in response_dict["items"], 'path of photo not found' + + +def test_person_groups(group_and_person_setup): + facesdk, person_response_dict, group_id = group_and_person_setup + test_name_2 = 'Second_test' + created_group_response_dict = ( + create_dictionary(facesdk.group_api.create_group(group_name=test_name_2, metadata=base_metadata))) + group_id_2 = created_group_response_dict['id'] + person_fields = PersonFields(name=name_a, groups=[group_id, group_id_2], metadata=base_metadata) + person_id_2 = create_dictionary(facesdk.person_api.create_person(person_fields))['id'] + response_dict = create_dictionary( + facesdk.person_api.get_all_groups_by_person_id(page=1, size=2, person_id=person_id_2)) + # Asserting on the number of items in the response + assert len(response_dict['items']) == 2, f"Expected 2 items, but got {len(response_dict['items'])}" + # Collecting the names of the groups from the response + group_names = [group['name'] for group in response_dict['items']] + # Asserting on the names of the groups + assert test_name in group_names, test_name + " not found in group names" + assert test_name_2 in group_names, test_name_2 + " not found in group names" + facesdk.person_api.delete_person(person_id_2) + facesdk.group_api.delete_group(group_id_2) + + +def test_add_image_to_person(group_and_person_setup): + facesdk, person_response_dict, group_id = group_and_person_setup + person_id = person_response_dict['id'] + face1 = read_image_bytes(FACE_1_PATH) + facesdk.person_api.add_image_to_person(person_id=person_id, content=face1) + request = SearchRequest(group_ids=[group_id], + image=ImageFieldsImage(content_type="", content=face1), + limit=10, + threshold=0.8) + response = create_dictionary(facesdk.search_api.search(request)) + person_ids = [person['id'] for person in response['persons']] + assert person_id in person_ids, f"person_id {person_id} is not in the search results" + person = next((p for p in response['persons'] if p['id'] == person_id), None) + assert person is not None, f"person_id {person_id} not found in the persons list" + assert person['images'][0]['path'] != "", f"The image path for person_id {person_id} is empty" + + +def test_create_person_without_metadata(group_and_person_setup): + facesdk, person_response_dict, group_id = group_and_person_setup + person_fields = PersonFields(name=name_a, groups=[group_id]) + created_person_response_dict = create_dictionary(facesdk.person_api.create_person(person_fields)) + facesdk.person_api.delete_person(created_person_response_dict['id']) diff --git a/tests/Tests_search.py b/tests/Tests_search.py new file mode 100644 index 0000000..7f150c9 --- /dev/null +++ b/tests/Tests_search.py @@ -0,0 +1,104 @@ +from regula.facesdk.webclient.gen.model.output_image_params import OutputImageParams +from regula.facesdk.webclient.gen.model.image_fields_image import ImageFieldsImage +from regula.facesdk.webclient.gen.model.resize_options import ResizeOptions +from regula.facesdk.webclient.gen.model.search_request import SearchRequest +from regula.facesdk.webclient.gen.model.person_fields import PersonFields +from regula.facesdk.webclient.gen.model.crop import Crop +from misc.paths_and_urls import * +import pytest + +base_metadata = {'description': 'This is a test group'} +test_group_name = "test" +name_a = "Person A" + + +def standard_assertions(response, person_id): + # We need this function because every test should check this first, and we don't want to repeat + # these assertions for every test + person = next((p for p in response['persons'] if p['id'] == person_id), None) + assert person is not None, f"person_id {person_id} not found in the persons list" + assert person['images'][0]['path'] != "", f"The image path for person_id {person_id} is empty" + + +@pytest.fixture(scope="function") +def facesdk_setup(facesdk): + # Remember to choose API_BASE_PATH in paths_and_urls.py + # We need to set up a group and person with image, so we'll have where to search + group_id = create_dictionary(facesdk.group_api.create_group(test_group_name))['id'] + person_fields = PersonFields(name=name_a, groups=[group_id], metadata=base_metadata) + person_id = create_dictionary(facesdk.person_api.create_person(person_fields))['id'] + face = read_image_bytes(FACE_1_PATH) + facesdk.person_api.add_image_to_person(person_id=person_id, content=face) + # Yield passes variables right to the tests + yield facesdk, group_id, person_id, face + # Everything written after yield will be done after every test + facesdk.group_api.delete_group(group_id) + facesdk.person_api.delete_person(person_id) + + +def test_search_limit_and_threshold(facesdk_setup): + # Getting all the info from set-up function + facesdk, group_id, person_id, face = facesdk_setup + response = create_dictionary(facesdk.search_api.search( + SearchRequest( + group_ids=[group_id], + image=ImageFieldsImage( + content_type="image/jpeg", + content=face + ), + limit=10, + threshold=0.8 + ), + )) + standard_assertions(response, person_id) + + +def test_search_background_and_crop(facesdk_setup): + # Getting all the info from set-up function + facesdk, group_id, person_id, face = facesdk_setup + background_color = [128, 128, 128] + crop_params = Crop(type=0, pad_color=[0, 0, 0], size=[300, 400], ) + oi_params = OutputImageParams(background_color=background_color, crop=crop_params) + response = create_dictionary(facesdk.search_api.search( + SearchRequest( + group_ids=[group_id], + image=ImageFieldsImage( + content_type="image/jpeg", + content=face + ), + output_image_params=oi_params, + ), + )) + standard_assertions(response, person_id) + person = next((p for p in response['persons'] if p['id'] == person_id), None) + assert 'crop' in person['detection'], "Crop data not found in person's detection" + assert person['detection']['crop'] != "", "Crop data is empty" + + +def test_search_resize(facesdk_setup): + # Getting all the info from set-up function + facesdk, group_id, person_id, face = facesdk_setup + res_opt = ResizeOptions(height=867, width=1300, quality=99) + response = create_dictionary(facesdk.search_api.search( + SearchRequest( + group_ids=[group_id], + image=ImageFieldsImage( + content_type="image/jpeg", + content=face, + resize_options=res_opt + ), + ), + )) + standard_assertions(response, person_id) + + +def test_search_url(facesdk_setup): + # Getting all the info from set-up function + facesdk, group_id, person_id, face = facesdk_setup + response = create_dictionary(facesdk.search_api.search( + SearchRequest( + group_ids=[group_id], + image=ImageFieldsImage(image_url='https://i.imgur.com/u9gEjx7.jpeg'), + ), + )) + standard_assertions(response, person_id) diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/misc/__init__.py b/tests/misc/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/misc/files/face1.jpg b/tests/misc/files/face1.jpg new file mode 100644 index 0000000..2bcdffa Binary files /dev/null and b/tests/misc/files/face1.jpg differ diff --git a/tests/misc/files/face2.jpg b/tests/misc/files/face2.jpg new file mode 100644 index 0000000..5f2c45a Binary files /dev/null and b/tests/misc/files/face2.jpg differ diff --git a/tests/misc/files/me.png b/tests/misc/files/me.png new file mode 100644 index 0000000..480f883 Binary files /dev/null and b/tests/misc/files/me.png differ diff --git a/tests/misc/files/me_and_id.png b/tests/misc/files/me_and_id.png new file mode 100644 index 0000000..cd7e053 Binary files /dev/null and b/tests/misc/files/me_and_id.png differ diff --git a/tests/misc/files/printedDoc.png b/tests/misc/files/printedDoc.png new file mode 100644 index 0000000..783faf9 Binary files /dev/null and b/tests/misc/files/printedDoc.png differ diff --git a/tests/misc/files/severalFaces.jpg b/tests/misc/files/severalFaces.jpg new file mode 100644 index 0000000..0ce51b6 Binary files /dev/null and b/tests/misc/files/severalFaces.jpg differ diff --git a/tests/misc/paths_and_urls.py b/tests/misc/paths_and_urls.py new file mode 100644 index 0000000..6d00215 --- /dev/null +++ b/tests/misc/paths_and_urls.py @@ -0,0 +1,34 @@ +import os +import pytest +from regula.facesdk.webclient.ext import FaceSdk + +API_BASE_PATH = "http://localhost:41101/" +# API_BASE_PATH = "http://172.20.40.141:41101" +# API_BASE_PATH = "https://faceapi.regulaforensics.com/" +# API_BASE_PATH = "https://test-faceapi.regulaforensics.com/" + +project_dir = os.path.dirname(os.path.abspath(__file__)) +files_path = os.path.join(project_dir, 'files') + +FACE_1_PATH = os.path.join(files_path, "face1.jpg") +FACE_2_PATH = os.path.join(files_path, "face2.jpg") +LIVE_PHOTO_PATH = os.path.join(files_path, "me.png") +PRINTED_DOCUMENT_PATH = os.path.join(files_path, "printedDoc.png") +DOCUMENT_WITH_LIVE_PATH = os.path.join(files_path, "me_and_id.png") +SEVERAL_FACES_IMAGE_PATH = os.path.join(files_path, "severalFaces.jpg") + + +def read_image_bytes(image_path): + with open(image_path, "rb") as f: + return f.read() + + +def create_dictionary(response): + # We need this function because a response object is not subscriptable + response_dict = response.to_dict() if hasattr(response, 'to_dict') else response + return response_dict + + +@pytest.fixture +def facesdk(): + return FaceSdk(host=API_BASE_PATH) \ No newline at end of file diff --git a/tests/misc/pytest.ini b/tests/misc/pytest.ini new file mode 100644 index 0000000..53404e4 --- /dev/null +++ b/tests/misc/pytest.ini @@ -0,0 +1,7 @@ +[pytest] +python_files = Tests_*.py +rp_api_key = regula_1V27anKyT7WRWT8W9ujDk3yPgZE7B2F1cRcSBzpmEAeK3bDtZG143UWaGjUt1qW6 +rp_endpoint = http://172.20.40.141:8080 +rp_project = web-client-faces +rp_launch = Python-client +rp_launch_attributes = 'PyTest' diff --git a/tests/misc/requirements.txt b/tests/misc/requirements.txt new file mode 100644 index 0000000..a87656a --- /dev/null +++ b/tests/misc/requirements.txt @@ -0,0 +1,5 @@ +pytest +requests +allure-pytest +regula.facesdk.webclient +pytest-reportportal \ No newline at end of file