Skip to content

Commit

Permalink
Implement face lifecycle tests and added mock database functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
Devasy23 committed Mar 7, 2024
1 parent 2e7782f commit f240fe5
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 22 deletions.
23 changes: 23 additions & 0 deletions API/database.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from pymongo import MongoClient
from datetime import datetime


class Database:
def __init__(self, uri="mongodb://localhost:27017/", db_name="ImageDB"):
self.client = MongoClient(uri)
self.db = self.client[db_name]

def find(self, collection, query=None):
return self.db[collection].find(query)

def insert_one(self, collection, document):
return self.db[collection].insert_one(document)

def find_one(self, collection,filter, projection=None):
return self.db[collection].find_one(filter=filter ,projection=projection)

def find_one_and_delete(self, collection, query):
return self.db[collection].find_one_and_delete(query)

def update_one(self, collection, query, update):
return self.db[collection].update_one(query, update)
32 changes: 18 additions & 14 deletions API/route.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from PIL import Image
from pydantic import BaseModel
from pymongo import MongoClient
from API.database import Database

# Create a logger object
logger = logging.getLogger(__name__)
Expand All @@ -25,12 +26,14 @@
router = APIRouter()

# To create connection with Mongodb
mongodb_uri = "mongodb://localhost:27017/"
port = 8000
client = MongoClient(mongodb_uri, port)
# mongodb_uri = "mongodb://localhost:27017/"
# port = 8000
# client = MongoClient(mongodb_uri, port)

db = client["ImageDB"]
faceEntries = db["faceEntries"]
# db = client["ImageDB"]
client = Database()

collection="faceEntries"


# Models for the data to be sent and received by the server
Expand Down Expand Up @@ -76,24 +79,25 @@ async def create_new_faceEntry(Employee: Employee):
)
os.remove(image_filename)
# Store the data in the database
db.faceEntries.insert_one(
{
client.insert_one(collection, {
"EmployeeCode": EmployeeCode,
"Name": Name,
"gender": gender,
"Department": Department,
"time": time,
"embeddings": embeddings,
"Image": encoded_image,
}
)
})
# db.faceEntries.insert_one(

# )
return {"message": "Face entry created successfully"}


# To display all records
@router.get("/Data/", response_model=list[Employee])
async def get_employees():
employees_mongo = faceEntries.find()
employees_mongo = client.find(collection)
employees = [
Employee(
EmployeeCode=int(employee.get("EmployeeCode", 0)),
Expand All @@ -112,7 +116,7 @@ async def get_employees():
async def read_employee(EmployeeCode: int):
try:
# logger.info(f"Start {EmployeeCode}")
items = faceEntries.find_one(
items = client.find_one(collection,
filter={"EmployeeCode": EmployeeCode},
projection={
"Name": True,
Expand Down Expand Up @@ -142,7 +146,7 @@ async def read_employee(EmployeeCode: int):
async def update_employees(EmployeeCode: int, Employee: UpdateEmployee):
try:
# logger.warning("Updating Start")
user_id = faceEntries.find_one(
user_id = client.find_one(collection,
{"EmployeeCode": EmployeeCode}, projection={"_id": True}
)
print(user_id)
Expand All @@ -151,7 +155,7 @@ async def update_employees(EmployeeCode: int, Employee: UpdateEmployee):
Employee_data = Employee.model_dump(by_alias=True, exclude_unset=True)
# logger.info(f"Employee data to update: {Employee_data}")
try:
update_result = faceEntries.update_one(
update_result = client.update_one(collection,
filter={"_id": ObjectId(user_id["_id"])},
update={"$set": Employee_data},
)
Expand All @@ -170,6 +174,6 @@ async def update_employees(EmployeeCode: int, Employee: UpdateEmployee):
@router.delete("/delete/{EmployeeCode}")
async def delete_employees(EmployeeCode: int):
print(EmployeeCode)
db.faceEntries.find_one_and_delete({"EmployeeCode": EmployeeCode})
client.find_one_and_delete(collection, {"EmployeeCode": EmployeeCode})

return {"Message": "Successfully Deleted"}
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## [Unreleased]

### Added
- Implemented all test cases in `test_face_cycle`
- Implemented mock test cases for `test_face_cycle` to work on online runners
32 changes: 28 additions & 4 deletions test.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -659,10 +659,34 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": []
"outputs": [
{
"ename": "TypeError",
"evalue": "Database.find_one() missing 1 required positional argument: 'query'",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[0;32mIn[10], line 4\u001b[0m\n\u001b[1;32m 2\u001b[0m EmployeeCode \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m1\u001b[39m\n\u001b[1;32m 3\u001b[0m client \u001b[38;5;241m=\u001b[39m Database()\n\u001b[0;32m----> 4\u001b[0m \u001b[43mclient\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfind_one\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mfaceEntries\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mfilter\u001b[39;49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m{\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mEmployeeCode\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mEmployeeCode\u001b[49m\u001b[43m}\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 5\u001b[0m \u001b[43m \u001b[49m\u001b[43mprojection\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m{\u001b[49m\n\u001b[1;32m 6\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mName\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[1;32m 7\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mgender\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[1;32m 8\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mDepartment\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[1;32m 9\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mImage\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[1;32m 10\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43m_id\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[1;32m 11\u001b[0m \u001b[43m \u001b[49m\u001b[43m}\u001b[49m\u001b[43m)\u001b[49m\n",
"\u001b[0;31mTypeError\u001b[0m: Database.find_one() missing 1 required positional argument: 'query'"
]
}
],
"source": [
"from API.database import Database\n",
"EmployeeCode = 1\n",
"client = Database()\n",
"client.find_one(\"faceEntries\", filter={\"EmployeeCode\": EmployeeCode},\n",
" projection={\n",
" \"Name\": True,\n",
" \"gender\": True,\n",
" \"Department\": True,\n",
" \"Image\": True,\n",
" \"_id\": False,\n",
" })"
]
}
],
"metadata": {
Expand All @@ -681,7 +705,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.16"
"version": "3.10.13"
}
},
"nbformat": 4,
Expand Down
30 changes: 26 additions & 4 deletions testing/test_face_cycle.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,36 @@
import base64

from unittest.mock import MagicMock, patch
from API.database import Database
from fastapi.testclient import TestClient

from API.route import router

client = TestClient(router)


def test_face_lifecycle():

@patch("API.database.Database.find_one_and_delete")
@patch("API.database.Database.update_one")
@patch("API.database.Database.find_one")
@patch("API.database.Database.find")
@patch("API.database.Database.insert_one")
def test_face_lifecycle(mock_insert_one: MagicMock, mock_find: MagicMock, mock_find_one: MagicMock, mock_update_one: MagicMock, mock_find_one_and_delete: MagicMock):
# Register two new faces
mock_doc = {
"_id": "65e6284d01f95cd96ea334a7",
"EmployeeCode": "1",
"Name": "Devansh",
"gender": "Male",
"Department": "IT",
"Image": "encoded_string1",
}

# Configure the mock to return the mock document when find() is called
mock_find.return_value = [mock_doc, mock_doc]
mock_insert_one.return_value = MagicMock(inserted_id="1")
mock_find_one.return_value = mock_doc
mock_update_one.return_value = MagicMock(modified_count=1)
mock_find_one_and_delete.return_value = mock_doc
with open("./test-faces/devansh.jpg", "rb") as image_file:
encoded_string1 = base64.b64encode(image_file.read()).decode("utf-8")
response1 = client.post(
Expand Down Expand Up @@ -42,7 +64,7 @@ def test_face_lifecycle():
# Get all data
response = client.get("/Data/")
assert response.status_code == 200
# assert len(response.json()) == 2
assert len(response.json()) == 2

# Update a face
response = client.put(
Expand All @@ -60,7 +82,7 @@ def test_face_lifecycle():
# Get all data again
response = client.get("/Data/")
assert response.status_code == 200
# assert len(response.json()) == 2
assert len(response.json()) == 2

# Delete a face
response = client.delete("/delete/1")
Expand Down

0 comments on commit f240fe5

Please sign in to comment.