11import csv
22from datetime import datetime
3+ from pathlib import Path
4+ from typing import List
35
46from behave import given , when , then
57from behave .runner import Context
@@ -11,7 +13,7 @@ def step_impl_csv_file_is_encoded_utf8(context: Context):
1113 # context.csv_file.encoding = 'utf-8'
1214 # context.csv_file.separator = ','
1315 with open ("tests/features/data/well-inventory-valid.csv" , "r" ) as f :
14- context .csv_file_content = f .read ()
16+ context .file_content = f .read ()
1517
1618
1719@given ("valid lexicon values exist for:" )
@@ -22,7 +24,11 @@ def step_impl_valid_lexicon_values(context: Context):
2224@given ("my CSV file contains multiple rows of well inventory data" )
2325def step_impl_csv_file_contains_multiple_rows (context : Context ):
2426 """Sets up the CSV file with multiple rows of well inventory data."""
25- context .rows = csv .DictReader (context .csv_file_content .splitlines ())
27+ context .rows = _get_rows (context )
28+
29+
30+ def _get_rows (context : Context ) -> List [str ]:
31+ return list (csv .DictReader (context .file_content .splitlines ()))
2632
2733
2834@given ("the CSV includes required fields:" )
@@ -62,10 +68,10 @@ def step_impl(context: Context):
6268 print (f"Optional fields: { optional_fields } " )
6369
6470
65- @when ("I upload the CSV file to the bulk upload endpoint" )
71+ @when ("I upload the file to the bulk upload endpoint" )
6672def step_impl (context : Context ):
6773 context .response = context .client .post (
68- "/well-inventory-csv" , data = {"file" : context .csv_file_content }
74+ "/well-inventory-csv" , data = {"file" : context .file_content }
6975 )
7076
7177
@@ -87,15 +93,13 @@ def step_impl(context: Context):
8793 response_json = context .response .json ()
8894 wells = response_json .get ("wells" , [])
8995 assert len (wells ) == len (
90- context .rows
96+ context .row_count
9197 ), "Expected the same number of wells as rows in the CSV"
9298
9399
94100@given ('my CSV file contains rows missing a required field "well_name_point_id"' )
95101def step_impl (context : Context ):
96- with open ("tests/features/data/well-inventory-invalid.csv" , "r" ) as f :
97- context .csv_file_content = f .read ()
98- context .rows = csv .DictReader (context .csv_file_content .splitlines ())
102+ _set_file_content (context , "well-inventory-missing-required.csv" )
99103
100104
101105@then ("the response includes validation errors for all rows missing required fields" )
@@ -127,9 +131,7 @@ def step_impl(context: Context):
127131
128132@given ('my CSV file contains one or more duplicate "well_name_point_id" values' )
129133def step_impl (context : Context ):
130- with open ("tests/features/data/well-inventory-duplicate.csv" , "r" ) as f :
131- context .csv_file_content = f .read ()
132- context .rows = csv .DictReader (context .csv_file_content .splitlines ())
134+ _set_file_content (context , "well-inventory-duplicate.csv" )
133135
134136
135137@then ("the response includes validation errors indicating duplicated values" )
@@ -163,43 +165,76 @@ def step_impl(context: Context):
163165 assert "error" in error , "Expected validation error to include error message"
164166
165167
168+ def _set_file_content (context : Context , name ):
169+ path = Path ("tests" ) / "features" / "data" / name
170+ with open (path , "r" ) as f :
171+ context .file_content = f .read ()
172+ if name .endswith (".csv" ):
173+ context .rows = _get_rows (context )
174+
175+
166176@given (
167177 'my CSV file contains invalid lexicon values for "contact_role" or other lexicon fields'
168178)
169179def step_impl (context : Context ):
170- with open ("tests/features/data/well-inventory-invalid-lexicon.csv" , "r" ) as f :
171- context .csv_file_content = f .read ()
172- context .rows = csv .DictReader (context .csv_file_content .splitlines ())
180+ _set_file_content (context , "well-inventory-invalid-lexicon.csv" )
173181
174182
175183@given ('my CSV file contains invalid ISO 8601 date values in the "date_time" field' )
176184def step_impl (context : Context ):
177- with open ("tests/features/data/well-inventory-invalid-date.csv" , "r" ) as f :
178- context .csv_file_content = f .read ()
179- context .rows = csv .DictReader (context .csv_file_content .splitlines ())
185+ _set_file_content (context , "well-inventory-invalid-date.csv" )
180186
181187
182188@given (
183189 'my CSV file contains values that cannot be parsed as numeric in numeric-required fields such as "utm_easting"'
184190)
185191def step_impl (context : Context ):
186- with open ("tests/features/data/well-inventory-invalid-numeric.csv" , "r" ) as f :
187- context .csv_file_content = f .read ()
192+ _set_file_content (context , "well-inventory-invalid-numeric.csv" )
188193
189194
190195@given ("my CSV file contains column headers but no data rows" )
191196def step_impl (context : Context ):
192- with open ("tests/features/data/well-inventory-no-data.csv" , "r" ) as f :
193- context .csv_file_content = f .read ()
194- context .rows = csv .DictReader (context .csv_file_content .splitlines ())
197+ _set_file_content (context , "well-inventory-no-data-headers.csv" )
195198
196199
197200@given ("my CSV file is empty" )
198201def step_impl (context : Context ):
199- context .csv_file_content = ""
202+ context .file_content = ""
200203 context .rows = []
201204
202205
206+ @given ("I have a non-CSV file" )
207+ def step_impl (context : Context ):
208+ _set_file_content (context , "well-inventory-invalid-filetype.txt" )
209+
210+
211+ @then ("the response includes an error message indicating unsupported file type" )
212+ def step_impl (context : Context ):
213+ response_json = context .response .json ()
214+ assert "error" in response_json , "Expected response to include an error message"
215+ assert (
216+ "Unsupported file type" in response_json ["error" ]
217+ ), "Expected error message to indicate unsupported file type"
218+
219+
220+ @then ("the response includes an error message indicating an empty file" )
221+ def step_impl (context : Context ):
222+ response_json = context .response .json ()
223+ assert "error" in response_json , "Expected response to include an error message"
224+ assert (
225+ "Empty file" in response_json ["error" ]
226+ ), "Expected error message to indicate an empty file"
227+
228+
229+ @then ("the response includes an error indicating that no data rows were found" )
230+ def step_impl (context : Context ):
231+ response_json = context .response .json ()
232+ assert "error" in response_json , "Expected response to include an error message"
233+ assert (
234+ "No data rows found" in response_json ["error" ]
235+ ), "Expected error message to indicate no data rows were found"
236+
237+
203238# @given(
204239# "the system has valid lexicon values for contact_role, contact_type, phone_type, email_type, address_type, elevation_method, well_pump_type, well_purpose, well_hole_status, and monitoring_frequency"
205240# )
@@ -220,7 +255,7 @@ def step_impl(context: Context):
220255# nrow = ",".join([row[k] for k in keys])
221256# nrows.append(nrow)
222257#
223- # context.csv_file_content = "\n".join(nrows)
258+ # context.file_content = "\n".join(nrows)
224259#
225260#
226261# @when("I upload the CSV file to the bulk upload endpoint")
@@ -229,7 +264,7 @@ def step_impl(context: Context):
229264# # Simulate uploading the CSV file to the bulk upload endpoint
230265# context.response = context.client.post(
231266# "/bulk-upload/well-inventory",
232- # files={"file": ("well_inventory.csv", context.csv_file_content , "text/csv")},
267+ # files={"file": ("well_inventory.csv", context.file_content , "text/csv")},
233268# )
234269#
235270#
0 commit comments