Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
d9cca8e
[gh-25] Added tests for redcap components
Girik1105 Feb 13, 2025
453e87e
[gh-25] Made new dir tests in track, used testcase for testing core r…
Girik1105 Feb 14, 2025
b95af7d
[gh-25] Added tests for order func incomplete record and order success
Girik1105 Feb 14, 2025
b6eaead
[gh-25] added test for order failure (gbf)
Girik1105 Feb 14, 2025
956572c
[gh-25] Complete order tests with logs
Girik1105 Feb 14, 2025
30e7e3b
[gh-25] Added logs, comments for redcap, fixed file scrture
Girik1105 Feb 14, 2025
58b5317
[story/gh-25] refactored gbf to break down large methods into helpers…
jophals Feb 15, 2025
524145c
Merge branch 'story/gh-25' of https://github.com/diging/edrop-connect…
jophals Feb 15, 2025
62465d2
[story/gh-25] implemented gbf unit tests, refactored some GBF methods…
jophals Feb 17, 2025
6e7c062
Merge branch 'develop' into story/gh-25
jophals Feb 17, 2025
635ba69
[story/GH-25] added logging to test_gbf, cleaned up import statements
jophals Feb 18, 2025
6efb13b
Merge branch 'story/gh-25' of https://github.com/diging/edrop-connect…
jophals Feb 18, 2025
dccb1f0
[gh-25] Fixed tests - error arises in 2 tests in test_gbf
Girik1105 Feb 20, 2025
94910b3
[gh-25] Fixed redcap tests
Girik1105 Feb 21, 2025
002f434
[gh-25] Fixed extra spcaes, added removed comment back
Girik1105 Feb 21, 2025
b8ac044
Merge branch 'develop' into story/gh-25
jdamerow Feb 25, 2025
7c93ca4
Trying to get tests to run
jdamerow Feb 25, 2025
aeb42a0
[gh-25] make db host configurable, to be able to run tests in an action
jdamerow Feb 25, 2025
eff5422
Merge branch 'story/gh-25' of https://github.com/diging/edrop-connect…
jdamerow Feb 25, 2025
224f9a7
Let's try this again
jdamerow Feb 25, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .github/workflows/django_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,26 @@ jobs:
build:

runs-on: ubuntu-latest
env:
POSTGRES_USER: dbuser
POSTGRES_PASSWORD: dbpassword
POSTGRES_NAME: dbname
POSTGRES_PORT: 5432
POSTGRES_HOST: localhost
services:
db:
image: postgres:16
env:
POSTGRES_USER: ${{ env.POSTGRES_USER }}
POSTGRES_PASSWORD: ${{ env.POSTGRES_PASSWORD }}
POSTGRES_DB: ${{ env.POSTGRES_NAME }}
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
strategy:
max-parallel: 4
matrix:
Expand Down
2 changes: 1 addition & 1 deletion edrop/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@
'NAME': os.environ.get('POSTGRES_NAME'),
'USER': os.environ.get('POSTGRES_USER'),
'PASSWORD': os.environ.get('POSTGRES_PASSWORD'),
'HOST': 'db',
'HOST': os.environ.get('POSTGRES_HOST', 'db'),
'PORT': os.environ.get('POSTGRES_PORT'),
}
}
Expand Down
15 changes: 12 additions & 3 deletions track/gbf.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ def create_order(order, adress_data):
logger.info(message)

# make order with GBF
return _place_order_with_GBF(order_json, order_number)
order_response = _place_order_with_GBF(order_json, order_number)

return _check_order_response(order_response, order_number)

def _generate_order_number(order):
"""
Expand Down Expand Up @@ -100,6 +102,9 @@ def _place_order_with_GBF(order_json, order_number):
log_manager.append_to_gbf_log(LogManager.LEVEL_INFO, response, order_number)
logger.info(response)

return response

def _check_order_response(response, order_number):
response_body = response.json()
log_manager.append_to_gbf_log(LogManager.LEVEL_DEBUG, response_body, order_number)
logger.debug(response_body)
Expand Down Expand Up @@ -142,7 +147,7 @@ def get_order_confirmations(order_numbers):

GBF sends json like this:
{
"success": true,
"success": True,
"dataArray": [
{
"format": "json",
Expand Down Expand Up @@ -184,7 +189,7 @@ def get_order_confirmations(order_numbers):
message = err
log_manager.append_to_gbf_log(LogManager.LEVEL_ERROR, message)
logger.error(message)
return None
return None

response_body = response.json()
# if for some reason GBF does not return a success response
Expand Down Expand Up @@ -218,6 +223,10 @@ def get_order_confirmations(order_numbers):
return None

confirmations = json.loads(data_object["data"])

return _extract_tracking_info(confirmations)

def _extract_tracking_info(confirmations):
tracking_info = {}
if "ShippingConfirmations" in confirmations:
for shipping_confirmation in confirmations['ShippingConfirmations']:
Expand Down
3 changes: 2 additions & 1 deletion track/redcap.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ def set_order_number(record_id, order_number):
if r.status_code != HTTPStatus.OK:
logger.error(f'HTTP Status: {r.status_code}')
logger.error(r.json())
raise REDCapError(f"REDCap returned {r.status_code}.")
else:
logger.debug("Succesfully send order number to REDCap.")

Expand Down Expand Up @@ -156,7 +157,6 @@ def set_tracking_info(order_objects):
return

for order in order_objects:

# in case an order has not been shipped yet, we don't update REDcap
if not order.ship_date:
continue
Expand Down Expand Up @@ -196,6 +196,7 @@ def set_tracking_info(order_objects):
message = r.json()
log_manager.append_to_redcap_log(LogManager.LEVEL_ERROR, message)
logger.error(message)
raise REDCapError(f"REDCap returned {r.status_code}.")
else:
message = f"Succesfully sent tracking information to REDCap for the following records: {[order.record_id for order in order_objects]}."
log_manager.append_to_redcap_log(LogManager.LEVEL_INFO, message)
Expand Down
Empty file added track/tests/__init__.py
Empty file.
195 changes: 195 additions & 0 deletions track/tests/test_gbf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
import logging
from unittest.mock import patch, MagicMock
from django.test import TestCase, override_settings
import json

import track.gbf as gbf
from track.models import *

logger = logging.getLogger(__name__)

order_json = {
"test": "true",
"orders": [
{
"orderNumber": "EDROP-00014",
"shippingInfo": {
"address": {
"company": "John Doe",
"addressLine1": "1234 Main Street",
"addressLine2": "PO Box 5",
"city": "Phoenix",
"state": "AZ",
"zipCode": "00000",
"country": "United States",
"phone": "1111111111",
"residential": True
},
"shipMethod": "FedEx Ground",
},
"lineItems": [
{
"itemNumber": "111",
"itemQuantity": 1.0,
}
]
}
]
}

address_data = {
"first_name": "John",
"last_name": "Doe",
"street1": "1234 Main Street",
"street2": "PO Box 5",
"city": "Phoenix",
"state": "AZ",
"zip": "00000",
"phone": "1111111111",
}

class OrderResponse:
def __init__(self, status_code, json_data=None):
self.status_code = status_code
self.json_data = json_data

def json(self):
return self.json_data

confirmation_response_json = {
"success": True,
"dataArray": [
{
"format": "json",
"data": "{\r\n \"ShippingConfirmations\": [\r\n {\r\n \"OrderNumber\": \"EDROP-00014\",\r\n \"Shipper\": \"\",\r\n \"ShipVia\": \"FedEx Ground\",\r\n \"ShipDate\": \"2025-01-23\",\r\n \"ClientID\": \"\",\r\n \"Tracking\": [\r\n \"270000004830\"\r\n ],\r\n \"Items\": [\r\n {\r\n \"ItemNumber\": \"K-BAN-001\",\r\n \"SerialNumber\": \"EV-05FCSG\",\r\n \"ShippedQty\": 1,\r\n \"ReturnTracking\": [\r\n \"XXXXXXXXXXXX\"\r\n ],\r\n \"TubeSerial\": [\r\n \"SIHIRJT5786\"\r\n ]\r\n }\r\n ]\r\n }\r\n ]\r\n}"
}
]
}

tracking_info = {
'EDROP-00014': {
'date_kit_shipped': '2025-01-23',
'kit_tracking_n': ['270000004830'],
'return_tracking_n': ['XXXXXXXXXXXX'],
'tube_serial_n': ['SIHIRJT5786']
}
}

@override_settings(GBF_URL="http://host.docker.internal:3000/")
class TestGBF(TestCase):
def setUp(self):
self.mock_order_number = "EDROP-00014"
self.mock_order_json = order_json
self.mock_order_response = OrderResponse(200, {'success': True, 'message': 'EXM-0000XX_RDQYD_20250115_154237.xml'})
self.order_object = Order.objects.create(pk=14, project_id=1, order_number=None)
self.address_data = address_data
self.order_response_json = {'success': True, 'message': 'EXM-0000XX_RDQYD_20250115_154237.xml'}
self.order_numbers = ["EDROP-00014", "EDROP-00015"]
self.confirmation_response_json = confirmation_response_json
self.tracking_info = tracking_info

@patch("track.gbf._place_order_with_GBF")
@patch("track.gbf._generate_order_json")
@patch("track.gbf._generate_order_number")
def test_create_order(self, mock_generate_order_number, mock_generate_order_json, mock_place_order_with_GBF):
mock_generate_order_number.return_value = self.mock_order_number
mock_generate_order_json.return_value = self.mock_order_json
mock_place_order_with_GBF.side_effect = lambda json, order_number: self.mock_order_response

result = gbf.create_order(self.order_object, self.address_data)

updated_order_object = Order.objects.filter(pk=self.order_object.id).first()

self.assertEqual(updated_order_object.order_number, "EDROP-00014")
self.assertEqual(result, True)

logger.debug(f'Order {updated_order_object.order_number} was successfully created.')

def test_generate_order_number(self):
result = gbf._generate_order_number(self.order_object)
self.assertEqual(result, "EDROP-00014")

def test_generate_order_json(self):
self.order_object.order_number = "EDROP-00014"

result = gbf._generate_order_json(self.order_object, self.address_data)
result_data = json.loads(result)

self.assertIn("test", result_data)
self.assertIn("orders", result_data)
self.assertIn("orderNumber", result_data['orders'][0])
self.assertIn("shippingInfo", result_data['orders'][0])
self.assertIn("lineItems", result_data['orders'][0])
self.assertIn("address", result_data['orders'][0]['shippingInfo'])
self.assertIn("shipMethod", result_data['orders'][0]['shippingInfo'])
self.assertEqual(result_data['orders'][0]['orderNumber'], "EDROP-00014")
self.assertEqual(result_data['orders'][0]['shippingInfo']['address']['company'], "John Doe")
self.assertEqual(result_data['orders'][0]['shippingInfo']['address']['zipCode'], "00000")

@patch("track.gbf.requests.post")
def test_place_order_with_GBF_success(self, mock_request):
mock_response = MagicMock()
mock_response.status_code = 200
mock_response.json.return_value = self.order_response_json
mock_request.return_value = mock_response

result = gbf._place_order_with_GBF(self.mock_order_json, self.mock_order_number)
result_body = result.json()

mock_request.assert_called_once()
self.assertEqual(result.status_code, 200)
self.assertIn("success", result_body)
self.assertIn("message", result_body)
self.assertEqual(result_body["success"], True)

logger.debug(f'Order {self.mock_order_json['orders'][0]['orderNumber']} was successfully placed.')

@patch("track.gbf.requests.post")
def test_place_order_with_GBF_failure(self, mock_request):
mock_response = MagicMock()
mock_response.status_code = 400
mock_response.json.return_value = {"success": False, "error": "Bad Request"}
mock_request.return_value = mock_response

result = gbf._place_order_with_GBF(self.mock_order_json, self.mock_order_number)

mock_request.assert_called_once()
self.assertEqual(result.status_code, 400)

logger.error('The order was unable to be placed due to a bad request.')

@patch("track.gbf._extract_tracking_info")
@patch("track.gbf.requests.post")
def test_get_order_confirmations_success(self, mock_request, mock_extract_tracking_info):
mock_response = MagicMock()
mock_response.status_code = 200
mock_response.raise_for_status.return_value = None
mock_response.json.return_value = self.confirmation_response_json
mock_request.return_value = mock_response
mock_extract_tracking_info.return_value = self.tracking_info

result = gbf.get_order_confirmations(self.order_numbers)

mock_request.assert_called_once()
mock_extract_tracking_info.assert_called_once()
self.assertIn("EDROP-00014", result)
self.assertIn("2025-01-23", result['EDROP-00014']['date_kit_shipped'])
self.assertIn("270000004830", result['EDROP-00014']['kit_tracking_n'])
self.assertIn('XXXXXXXXXXXX', result['EDROP-00014']['return_tracking_n'])
self.assertIn('SIHIRJT5786', result['EDROP-00014']['tube_serial_n'])

logger.debug(f'The following order numbers were successfully checked for order confirmation: {self.order_numbers}')

@patch("track.gbf.requests.post")
def test_get_order_confirmations_failure(self, mock_request):
mock_response = MagicMock()
mock_response.status_code = 400
mock_response.json.return_value = {"success": False, "error": "Bad Request"}
mock_request.return_value = mock_response

result = gbf.get_order_confirmations(self.order_numbers)

mock_request.assert_called_once()
self.assertEqual(result, None)

logger.error('The order confirmation failed due to a bad request.')
Loading