Coverage for src/csv_schema_validator/tests/test_validate_csv.py: 0%
66 statements
« prev ^ index » next coverage.py v7.10.6, created at 2025-09-20 12:34 +0200
« prev ^ index » next coverage.py v7.10.6, created at 2025-09-20 12:34 +0200
1import pytest
2import tempfile
3import os
5from csv_schema_validator.validate_csv import validate_csv
8class TestValidateCSV:
9 """Test suite for the validate_csv function"""
11 @pytest.fixture
12 def temp_dir(self):
13 """Create a temporary directory for test files"""
14 with tempfile.TemporaryDirectory() as tmpdir:
15 yield tmpdir
17 @pytest.fixture
18 def basic_schema(self):
19 """Create a basic schema file for testing"""
20 return {
21 "name": "Test Schema",
22 "description": "Basic test schema",
23 "fields": [
24 {
25 "name": "id",
26 "type": "integer",
27 "required": True,
28 "description": "Unique identifier",
29 },
30 {
31 "name": "name",
32 "type": "string",
33 "required": True,
34 "description": "Name field",
35 },
36 {
37 "name": "email",
38 "type": "string",
39 "required": True,
40 "pattern": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
41 "description": "Email address",
42 },
43 {
44 "name": "department",
45 "type": "string",
46 "required": True,
47 "enum": ["Engineering", "Marketing", "Sales"],
48 "description": "Department",
49 },
50 {
51 "name": "salary",
52 "type": "number",
53 "required": True,
54 "min": 30000,
55 "max": 200000,
56 "description": "Salary",
57 },
58 {
59 "name": "is_active",
60 "type": "boolean",
61 "required": True,
62 "description": "Active status",
63 },
64 ],
65 }
67 @pytest.fixture
68 def invalid_schema(self):
69 """Create an invalid schema file for testing"""
70 return {
71 "name": "Invalid Schema",
72 "description": "Invalid schema",
73 "fields": [
74 {
75 "name": "id",
76 "required": True,
77 },
78 ],
79 "invalid_field": "invalid_field",
80 }
82 @pytest.fixture
83 def non_json_non_text_schema(self):
84 """Create a non JSON non text schema file for testing"""
85 return 123
87 @pytest.fixture
88 def non_json_text_schema(self):
89 """Create a non JSON schema file for testing"""
90 return "invalid schema"
92 @pytest.fixture
93 def valid_csv(self, temp_dir):
94 """Create a valid CSV file for testing"""
95 csv_content = """id,name,email,department,salary,is_active
961,John Doe,john.doe@company.com,Engineering,75000,true
972,Jane Smith,jane.smith@company.com,Marketing,65000,false"""
99 csv_file = os.path.join(temp_dir, "valid.csv")
100 with open(csv_file, "w") as f:
101 f.write(csv_content)
102 return csv_file
104 @pytest.fixture
105 def invalid_csv(self, temp_dir):
106 """Create an invalid CSV file for testing"""
107 csv_content = """id,name,email,department,salary,is_active
1081,John Doe,invalid-email,Engineering,75000,true
1092,Jane Smith,jane.smith@company.com,InvalidDept,65000,false
1103,invalid-id,Bob Johnson,bob@company.com,Sales,25000,maybe
1114,Alice Williams,alice@company.com,Marketing,300000,true"""
112 csv_file = os.path.join(temp_dir, "invalid.csv")
113 with open(csv_file, "w") as f:
114 f.write(csv_content)
115 return csv_file
117 @pytest.fixture
118 def non_matching_csv(self, temp_dir):
119 """Create a non matching CSV file for testing"""
120 csv_content = """id,namee,email,department,salary,is_active
1211,John Doe,john.doe@company,Engineerin,75000,yes
122two,Jane Smith,jane.smith@company.com,Marketing,65000,false"""
123 csv_file = os.path.join(temp_dir, "non_matching.csv")
124 with open(csv_file, "w") as f:
125 f.write(csv_content)
126 return csv_file
128 def test_validate_csv_empty_file(self, temp_dir, basic_schema):
129 """Test validation of empty CSV file"""
130 empty_csv = os.path.join(temp_dir, "empty.csv")
131 with open(empty_csv, "w") as f:
132 f.write("")
134 result = validate_csv(empty_csv, basic_schema)
135 assert result == {
136 "is_valid": False,
137 "errors": [
138 {
139 "error_type": "empty_csv_file",
140 "value": empty_csv,
141 "row": -1,
142 "column": -1,
143 "details": {},
144 }
145 ],
146 }
148 def test_validate_invalid_schema(self, valid_csv, invalid_schema):
149 result = validate_csv(valid_csv, invalid_schema)
150 assert result == {
151 "is_valid": False,
152 "errors": [
153 {
154 "field": "fields.0.type",
155 "message": "Field required",
156 "type": "missing",
157 "input": {"name": "id", "required": True},
158 }
159 ],
160 "validated_schema": None,
161 }
163 def test_non_json_text_schema(self, valid_csv, non_json_text_schema):
164 result = validate_csv(valid_csv, non_json_text_schema)
165 assert result == {
166 "is_valid": False,
167 "errors": [
168 {
169 "error_type": "invalid_schema",
170 "error_message": "csv_schema_validator.schema_models.CSVSchema() argument after ** must be a mapping, not str",
171 }
172 ],
173 "schema_value": "invalid schema",
174 }
176 def test_non_json_non_text_schema(self, valid_csv, non_json_non_text_schema):
177 result = validate_csv(valid_csv, non_json_non_text_schema)
178 assert result == {
179 "is_valid": False,
180 "errors": [
181 {
182 "error_type": "invalid_schema",
183 "error_message": "csv_schema_validator.schema_models.CSVSchema() argument after ** must be a mapping, not int",
184 }
185 ],
186 "schema_value": 123,
187 }
189 def test_validate_valid_csv(self, valid_csv, basic_schema):
190 result = validate_csv(valid_csv, basic_schema)
191 assert result == {
192 "is_valid": True,
193 "errors": [],
194 }
196 def test_validate_non_matching_csv(self, non_matching_csv, basic_schema):
197 result = validate_csv(non_matching_csv, basic_schema)
198 print("Actual result")
199 print(result)
200 assert result == {
201 "is_valid": False,
202 "errors": [
203 {
204 "error_type": "missing_fields",
205 "value": [
206 "id",
207 "namee",
208 "email",
209 "department",
210 "salary",
211 "is_active",
212 ],
213 "row": -1,
214 "column": -1,
215 "details": {
216 "required_fields": [
217 "id",
218 "name",
219 "email",
220 "department",
221 "salary",
222 "is_active",
223 ],
224 "missing_fields": ["name"],
225 },
226 },
227 {
228 "error_type": "pattern_not_matched",
229 "value": "john.doe@company",
230 "column": "email",
231 "row": 0,
232 "details": {
233 "expected_pattern": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
234 },
235 },
236 {
237 "error_type": "not_in_enum",
238 "value": "Engineerin",
239 "column": "department",
240 "row": 0,
241 "details": {"expected_enum": ["Engineering", "Marketing", "Sales"]},
242 },
243 {
244 "error_type": "invalid_boolean",
245 "value": "yes",
246 "column": "is_active",
247 "row": 0,
248 "details": {"supported_values": ["true", "false"]},
249 },
250 {
251 "error_type": "invalid_integer",
252 "value": "two",
253 "column": "id",
254 "row": 1,
255 "details": {},
256 },
257 ],
258 }
260 """
261 Test case to handle, both cli and library:
262 - Invalid CSV file - not matching schema
263 """