Skip to content

Commit 596651c

Browse files
Create bot.py
1 parent 947c91b commit 596651c

File tree

1 file changed

+189
-0
lines changed

1 file changed

+189
-0
lines changed

tests/bot.py

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
import subprocess
2+
import time
3+
from unittest.mock import patch
4+
import sys
5+
import os
6+
import json
7+
import requests
8+
from datetime import datetime
9+
import pytest
10+
from customize_schema import validate_metadata as validator43 # Import validator
11+
12+
class CaltechDataTester:
13+
def __init__(self):
14+
self.test_dir = "caltech_test_data"
15+
self.timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
16+
if not os.path.exists(self.test_dir):
17+
os.makedirs(self.test_dir)
18+
19+
# Create test data directory with timestamp
20+
self.test_run_dir = os.path.join(self.test_dir, f"test_run_{self.timestamp}")
21+
os.makedirs(self.test_run_dir)
22+
23+
# Initialize logging
24+
self.log_file = os.path.join(self.test_run_dir, "test_log.txt")
25+
26+
def log(self, message):
27+
"""Log message to both console and file"""
28+
print(message)
29+
with open(self.log_file, "a") as f:
30+
f.write(f"{datetime.now()}: {message}\n")
31+
32+
def create_test_files(self):
33+
"""Create necessary test files"""
34+
# Create a dummy CSV file
35+
csv_path = os.path.join(self.test_run_dir, "test_data.csv")
36+
with open(csv_path, "w") as f:
37+
f.write("date,temperature,humidity\n")
38+
f.write("2023-01-01,25.5,60\n")
39+
f.write("2023-01-02,26.0,62\n")
40+
f.write("2023-01-03,24.8,65\n")
41+
42+
self.log(f"Created test CSV file: {csv_path}")
43+
return csv_path
44+
45+
def generate_test_responses(self):
46+
"""Generate test responses for CLI prompts"""
47+
return {
48+
"Do you want to create or edit a CaltechDATA record? (create/edit): ": "create",
49+
"Do you want to use metadata from an existing file or create new metadata? (existing/create): ": "create",
50+
"Enter the title of the dataset: ": f"Test Dataset {self.timestamp}",
51+
"Enter the abstract or description of the dataset: ": "This is an automated test dataset containing sample climate data for validation purposes.",
52+
"Enter the number corresponding to the desired license: ": "1",
53+
"Enter your ORCID identifier: ": "0000-0002-1825-0097",
54+
"How many funding entries do you want to provide? ": "1",
55+
"Enter the award number for funding: ": "NSF-1234567",
56+
"Enter the award title for funding: ": "Automated Testing Grant",
57+
"Enter the funder ROR (https://ror.org): ": "021nxhr62",
58+
"Do you want to upload or link data files? (upload/link/n): ": "upload",
59+
"Enter the filename to upload as a supporting file (or 'n' to finish): ": "test_data.csv",
60+
"Do you want to add more files? (y/n): ": "n",
61+
"Do you want to send this record to CaltechDATA? (y/n): ": "y",
62+
}
63+
64+
def extract_record_id(self, output_text):
65+
"""Extract record ID from CLI output"""
66+
try:
67+
for line in output_text.split('\n'):
68+
if 'uploads/' in line:
69+
return line.strip().split('/')[-1]
70+
except Exception as e:
71+
self.log(f"Error extracting record ID: {e}")
72+
return None
73+
74+
def download_and_validate_record(self, record_id):
75+
"""Download and validate the record"""
76+
try:
77+
# Wait for record to be available
78+
time.sleep(5)
79+
80+
# Download metadata
81+
url = f"https://data.caltech.edu/records/{record_id}/export/datacite-json?preview=1"
82+
response = requests.get(url)
83+
response.raise_for_status()
84+
85+
# Save metadata
86+
json_path = os.path.join(self.test_run_dir, f"{record_id}.json")
87+
with open(json_path, 'w') as f:
88+
json.dump(response.json(), f, indent=2)
89+
90+
self.log(f"Downloaded metadata to: {json_path}")
91+
92+
# Validate metadata using the imported validator
93+
validation_errors = validator43(response.json())
94+
95+
if validation_errors:
96+
self.log("❌ Validation errors found:")
97+
for error in validation_errors:
98+
self.log(f" - {error}")
99+
return False
100+
else:
101+
self.log("✅ Validation passed successfully")
102+
return True
103+
104+
except Exception as e:
105+
self.log(f"Error in download and validation: {e}")
106+
return False
107+
108+
def run_test_submission(self):
109+
"""Run the complete test submission process"""
110+
try:
111+
self.log("Starting test submission process...")
112+
113+
# Create test files
114+
test_csv = self.create_test_files()
115+
116+
# Generate responses
117+
responses = self.generate_test_responses()
118+
119+
# Setup output capture
120+
class OutputCapture:
121+
def __init__(self):
122+
self.output = []
123+
def write(self, text):
124+
self.output.append(text)
125+
sys.__stdout__.write(text)
126+
def flush(self):
127+
pass
128+
def get_output(self):
129+
return ''.join(self.output)
130+
131+
output_capture = OutputCapture()
132+
sys.stdout = output_capture
133+
134+
# Mock input and run CLI
135+
def mock_input(prompt):
136+
self.log(f"Prompt: {prompt}")
137+
if prompt in responses:
138+
response = responses[prompt]
139+
self.log(f"Response: {response}")
140+
return response
141+
return ""
142+
143+
with patch('builtins.input', side_effect=mock_input):
144+
try:
145+
import cli
146+
cli.main()
147+
except Exception as e:
148+
self.log(f"Error during CLI execution: {e}")
149+
return False
150+
151+
# Restore stdout
152+
sys.stdout = sys.__stdout__
153+
154+
# Get output and extract record ID
155+
cli_output = output_capture.get_output()
156+
record_id = self.extract_record_id(cli_output)
157+
158+
if not record_id:
159+
self.log("Failed to extract record ID")
160+
return False
161+
162+
self.log(f"Successfully created record with ID: {record_id}")
163+
164+
# Validate the record
165+
return self.download_and_validate_record(record_id)
166+
167+
except Exception as e:
168+
self.log(f"Error in test submission: {e}")
169+
return False
170+
finally:
171+
# Cleanup
172+
if os.path.exists(test_csv):
173+
os.remove(test_csv)
174+
self.log("Test files cleaned up")
175+
176+
def main():
177+
tester = CaltechDataTester()
178+
179+
success = tester.run_test_submission()
180+
181+
if success:
182+
tester.log("\n🎉 Test submission and validation completed successfully!")
183+
else:
184+
tester.log("\n❌ Test submission or validation failed - check logs for details")
185+
186+
tester.log(f"\nTest logs available at: {tester.log_file}")
187+
188+
if __name__ == "__main__":
189+
main()

0 commit comments

Comments
 (0)