Skip to content

Commit 7c89e0a

Browse files
authored
Merge pull request #1998 from bcgov/fix/alex-draft-schedule-filter-1931
Feat: Draft Schedule Records Exclusions - 1931
2 parents a554365 + 7d52214 commit 7c89e0a

File tree

11 files changed

+394
-141
lines changed

11 files changed

+394
-141
lines changed

backend/lcfs/tests/fuel_export/test_fuel_exports_services.py

+35-19
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
from lcfs.web.api.fuel_export.repo import FuelExportRepository
1616
from lcfs.db.models.compliance.FuelExport import FuelExport
1717
from lcfs.db.base import ActionTypeEnum, UserTypeEnum
18+
from lcfs.db.models.user.Role import RoleEnum
19+
from types import SimpleNamespace
1820

1921
# Mock common data for reuse
2022
mock_fuel_type = FuelTypeSchema(
@@ -32,10 +34,16 @@
3234
category="Diesel",
3335
)
3436

35-
3637
# FuelExportServices Tests
38+
39+
3740
@pytest.mark.anyio
3841
async def test_get_fuel_export_options_success(fuel_export_service, mock_repo):
42+
dummy_user = SimpleNamespace(id=1, role_names=[RoleEnum.GOVERNMENT])
43+
dummy_request = MagicMock()
44+
dummy_request.user = dummy_user
45+
fuel_export_service.request = dummy_request
46+
3947
mock_repo.get_fuel_export_table_options.return_value = []
4048
result = await fuel_export_service.get_fuel_export_options("2024")
4149
assert isinstance(result, FuelTypeOptionsResponse)
@@ -44,6 +52,12 @@ async def test_get_fuel_export_options_success(fuel_export_service, mock_repo):
4452

4553
@pytest.mark.anyio
4654
async def test_get_fuel_export_list_success(fuel_export_service, mock_repo):
55+
# Set up a dummy request with a valid user
56+
dummy_user = SimpleNamespace(id=1, role_names=[RoleEnum.GOVERNMENT])
57+
dummy_request = MagicMock()
58+
dummy_request.user = dummy_user
59+
fuel_export_service.request = dummy_request
60+
4761
# Create a mock FuelExport with all required fields
4862
mock_export = FuelExport(
4963
fuel_export_id=1,
@@ -57,10 +71,7 @@ async def test_get_fuel_export_list_success(fuel_export_service, mock_repo):
5771
export_date=date.today(),
5872
group_uuid="test-uuid",
5973
provision_of_the_act_id=1,
60-
provision_of_the_act={
61-
"provision_of_the_act_id": 1,
62-
"name": "Test Provision"
63-
},
74+
provision_of_the_act={"provision_of_the_act_id": 1, "name": "Test Provision"},
6475
version=0,
6576
user_type=UserTypeEnum.SUPPLIER,
6677
action_type=ActionTypeEnum.CREATE,
@@ -70,11 +81,20 @@ async def test_get_fuel_export_list_success(fuel_export_service, mock_repo):
7081
result = await fuel_export_service.get_fuel_export_list(1)
7182

7283
assert isinstance(result, FuelExportsSchema)
73-
mock_repo.get_fuel_export_list.assert_called_once_with(1)
84+
# Expect the repo call to include exclude_draft_reports=True based on the user
85+
mock_repo.get_fuel_export_list.assert_called_once_with(
86+
1, exclude_draft_reports=True
87+
)
7488

7589

7690
@pytest.mark.anyio
7791
async def test_get_fuel_exports_paginated_success(fuel_export_service, mock_repo):
92+
# Set up a dummy request with a valid user
93+
dummy_user = SimpleNamespace(id=1, role_names=[RoleEnum.GOVERNMENT])
94+
dummy_request = MagicMock()
95+
dummy_request.user = dummy_user
96+
fuel_export_service.request = dummy_request
97+
7898
mock_export = FuelExport(
7999
fuel_export_id=1,
80100
compliance_report_id=1,
@@ -86,10 +106,7 @@ async def test_get_fuel_exports_paginated_success(fuel_export_service, mock_repo
86106
units="L",
87107
export_date=date.today(),
88108
provision_of_the_act_id=1,
89-
provision_of_the_act={
90-
"provision_of_the_act_id": 1,
91-
"name": "Test Provision"
92-
},
109+
provision_of_the_act={"provision_of_the_act_id": 1, "name": "Test Provision"},
93110
)
94111
mock_repo.get_fuel_exports_paginated.return_value = ([mock_export], 1)
95112

@@ -103,10 +120,15 @@ async def test_get_fuel_exports_paginated_success(fuel_export_service, mock_repo
103120
assert result.pagination.total == 1
104121
assert result.pagination.page == 1
105122
assert result.pagination.size == 10
106-
mock_repo.get_fuel_exports_paginated.assert_called_once_with(pagination_mock, 1)
123+
# Expect the extra parameter to be passed
124+
mock_repo.get_fuel_exports_paginated.assert_called_once_with(
125+
pagination_mock, 1, exclude_draft_reports=True
126+
)
107127

108128

109129
# FuelExportActionService Tests
130+
131+
110132
@pytest.mark.anyio
111133
async def test_action_create_fuel_export_success(fuel_export_action_service, mock_repo):
112134
input_data = FuelExportCreateUpdateSchema(
@@ -131,10 +153,7 @@ async def test_action_create_fuel_export_success(fuel_export_action_service, moc
131153
user_type=UserTypeEnum.SUPPLIER,
132154
action_type=ActionTypeEnum.CREATE,
133155
provision_of_the_act_id=1,
134-
provision_of_the_act={
135-
"provision_of_the_act_id": 1,
136-
"name": "Act Provision"
137-
},
156+
provision_of_the_act={"provision_of_the_act_id": 1, "name": "Act Provision"},
138157
fuel_type_id=1,
139158
fuel_category_id=1,
140159
quantity=100,
@@ -181,10 +200,7 @@ async def test_action_update_fuel_export_success(fuel_export_action_service, moc
181200
fuel_type_id=1,
182201
fuel_category_id=1,
183202
provision_of_the_act_id=1,
184-
provision_of_the_act={
185-
"provision_of_the_act_id": 1,
186-
"name": "Act Provision"
187-
},
203+
provision_of_the_act={"provision_of_the_act_id": 1, "name": "Act Provision"},
188204
quantity=100,
189205
units="L",
190206
export_date=date.today(),

backend/lcfs/tests/fuel_supply/test_fuel_supplies_repo.py

+100-16
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,25 @@
1+
import math
12
import pytest
23
from unittest.mock import MagicMock, AsyncMock
34
from sqlalchemy.ext.asyncio import AsyncSession
45

56
from lcfs.db.models.compliance import FuelSupply
67
from lcfs.web.api.fuel_supply.repo import FuelSupplyRepository
78
from lcfs.web.api.fuel_supply.schema import FuelSupplyCreateUpdateSchema
9+
from lcfs.web.api.fuel_supply.schema import (
10+
FuelSuppliesSchema,
11+
PaginationResponseSchema,
12+
FuelSupplyResponseSchema,
13+
)
14+
from lcfs.web.api.base import PaginationRequestSchema
815

916

1017
@pytest.fixture
1118
def mock_db_session():
1219
session = AsyncMock(spec=AsyncSession)
1320

14-
# Create a mock that properly mimics SQLAlchemy's async result chain
1521
async def mock_execute(*args, **kwargs):
16-
mock_result = (
17-
MagicMock()
18-
) # Changed to MagicMock since the chained methods are sync
22+
mock_result = MagicMock()
1923
mock_result.scalars = MagicMock(return_value=mock_result)
2024
mock_result.unique = MagicMock(return_value=mock_result)
2125
mock_result.all = MagicMock(return_value=[MagicMock(spec=FuelSupply)])
@@ -36,24 +40,34 @@ def fuel_supply_repo(mock_db_session):
3640

3741

3842
@pytest.mark.anyio
39-
async def test_get_fuel_supply_list(fuel_supply_repo, mock_db_session):
43+
async def test_get_fuel_supply_list_exclude_draft_reports(
44+
fuel_supply_repo, mock_db_session
45+
):
4046
compliance_report_id = 1
41-
mock_result = [MagicMock(spec=FuelSupply)]
47+
expected_fuel_supplies = [MagicMock(spec=FuelSupply)]
4248

43-
# Set up the mock to return our desired result
49+
# Set up the mock result chain with proper method chaining.
4450
mock_result_chain = MagicMock()
4551
mock_result_chain.scalars = MagicMock(return_value=mock_result_chain)
4652
mock_result_chain.unique = MagicMock(return_value=mock_result_chain)
47-
mock_result_chain.all = MagicMock(return_value=mock_result)
53+
mock_result_chain.all = MagicMock(return_value=expected_fuel_supplies)
4854

49-
async def mock_execute(*args, **kwargs):
55+
async def mock_execute(query, *args, **kwargs):
5056
return mock_result_chain
5157

5258
mock_db_session.execute = mock_execute
5359

54-
result = await fuel_supply_repo.get_fuel_supply_list(compliance_report_id)
60+
# Test when drafts should be excluded (e.g. government user).
61+
result_gov = await fuel_supply_repo.get_fuel_supply_list(
62+
compliance_report_id, exclude_draft_reports=True
63+
)
64+
assert result_gov == expected_fuel_supplies
5565

56-
assert result == mock_result
66+
# Test when drafts are not excluded.
67+
result_non_gov = await fuel_supply_repo.get_fuel_supply_list(
68+
compliance_report_id, exclude_draft_reports=False
69+
)
70+
assert result_non_gov == expected_fuel_supplies
5771

5872

5973
@pytest.mark.anyio
@@ -80,19 +94,89 @@ async def test_check_duplicate(fuel_supply_repo, mock_db_session):
8094
units="L",
8195
)
8296

83-
# Set up the mock chain using regular MagicMock since the chained methods are sync
97+
# Set up the mock chain using MagicMock for synchronous chained methods.
8498
mock_result_chain = MagicMock()
8599
mock_result_chain.scalars = MagicMock(return_value=mock_result_chain)
86-
mock_result_chain.first = MagicMock(
87-
return_value=MagicMock(spec=FuelSupply))
100+
mock_result_chain.first = MagicMock(return_value=MagicMock(spec=FuelSupply))
88101

89-
# Define an async execute function that returns our mock chain
90102
async def mock_execute(*args, **kwargs):
91103
return mock_result_chain
92104

93-
# Replace the session's execute with our new mock
94105
mock_db_session.execute = mock_execute
95106

96107
result = await fuel_supply_repo.check_duplicate(fuel_supply_data)
97108

98109
assert result is not None
110+
111+
112+
@pytest.mark.anyio
113+
async def test_get_fuel_supplies_paginated_exclude_draft_reports(fuel_supply_repo):
114+
# Define a sample pagination request.
115+
pagination = PaginationRequestSchema(page=1, size=10)
116+
compliance_report_id = 1
117+
total_count = 20
118+
119+
# Build a valid fuel supply record that passes validation.
120+
valid_fuel_supply = {
121+
"fuel_supply_id": 1,
122+
"complianceReportId": 1,
123+
"version": 0,
124+
"fuelTypeId": 1,
125+
"quantity": 100,
126+
"groupUuid": "some-uuid",
127+
"userType": "SUPPLIER",
128+
"actionType": "CREATE",
129+
"fuelType": {"fuel_type_id": 1, "fuelType": "Diesel", "units": "L"},
130+
"fuelCategory": {"fuel_category_id": 1, "category": "Diesel"},
131+
"endUseType": {"endUseTypeId": 1, "type": "Transport", "subType": "Personal"},
132+
"provisionOfTheAct": {"provisionOfTheActId": 1, "name": "Act Provision"},
133+
"compliancePeriod": "2024",
134+
"units": "L",
135+
"fuelCode": {
136+
"fuelStatus": {"status": "Approved"},
137+
"fuelCode": "FUEL123",
138+
"carbonIntensity": 15.0,
139+
},
140+
"fuelTypeOther": "Optional",
141+
}
142+
expected_fuel_supplies = [valid_fuel_supply]
143+
144+
async def mock_get_fuel_supplies_paginated(
145+
pagination, compliance_report_id, exclude_draft_reports
146+
):
147+
total_pages = math.ceil(total_count / pagination.size) if total_count > 0 else 0
148+
pagination_response = PaginationResponseSchema(
149+
page=pagination.page,
150+
size=pagination.size,
151+
total=total_count,
152+
total_pages=total_pages,
153+
)
154+
processed = [
155+
FuelSupplyResponseSchema.model_validate(fs) for fs in expected_fuel_supplies
156+
]
157+
return FuelSuppliesSchema(
158+
pagination=pagination_response, fuel_supplies=processed
159+
)
160+
161+
fuel_supply_repo.get_fuel_supplies_paginated = AsyncMock(
162+
side_effect=mock_get_fuel_supplies_paginated
163+
)
164+
165+
result = await fuel_supply_repo.get_fuel_supplies_paginated(
166+
pagination, compliance_report_id, exclude_draft_reports=True
167+
)
168+
169+
# Validate pagination values.
170+
assert result.pagination.page == pagination.page
171+
assert result.pagination.size == pagination.size
172+
assert result.pagination.total == total_count
173+
expected_total_pages = (
174+
math.ceil(total_count / pagination.size) if total_count > 0 else 0
175+
)
176+
assert result.pagination.total_pages == expected_total_pages
177+
178+
# Validate that the fuel supplies list is correctly transformed.
179+
expected_processed = [
180+
FuelSupplyResponseSchema.model_validate(fs) for fs in expected_fuel_supplies
181+
]
182+
assert result.fuel_supplies == expected_processed

0 commit comments

Comments
 (0)