File size: 7,371 Bytes
595350e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
import unittest
from fastapi.testclient import TestClient
import sys
import os
import argparse

# Add the project root to sys.path to allow importing main and other modules
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))

# Global storage for CLI arguments
CLI_ARGS = None

try:
    from main import app
except ImportError as e:
    print(f"Error importing app from main: {e}")
    # Fallback or exit if necessary
    sys.exit(1)

class TestSanatanAIAPI(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.client = TestClient(app)

    def test_get_languages(self):
        """Test GET /api/languages"""
        response = self.client.get("/api/languages")
        self.assertEqual(response.status_code, 200)
        data = response.json()
        self.assertIsInstance(data, list)
        self.assertTrue(len(data) > 0)
        # Check for English
        self.assertTrue(any(lang['code'] == 'en' for lang in data))

    def test_get_languages_v2(self):
        """Test GET /api/languages_v2"""
        response = self.client.get("/api/languages_v2")
        self.assertEqual(response.status_code, 200)
        data = response.json()
        self.assertIsInstance(data, list)

    def test_post_greet(self):
        """Test POST /api/greet"""
        payload = {
            "language": "English",
            "text": "Hello",
            "session_id": "test-session"
        }
        response = self.client.post("/api/greet", json=payload)
        self.assertEqual(response.status_code, 200)
        data = response.json()
        self.assertIn("reply", data)
        self.assertIn("session_id", data)
        self.assertEqual(data["session_id"], "test-session")

    def test_get_scriptures(self):
        """Test GET /api/scriptures"""
        response = self.client.get("/api/scriptures")
        self.assertEqual(response.status_code, 200)
        data = response.json()
        self.assertIsInstance(data, dict)
        self.assertTrue(len(data) > 0)

    def test_get_scripture_configs(self):
        """Test GET /api/scripture_configs"""
        response = self.client.get("/api/scripture_configs")
        self.assertEqual(response.status_code, 200)
        data = response.json()
        self.assertIn("scriptures", data)
        self.assertIsInstance(data["scriptures"], list)

    def test_get_scripture_categories(self):
        """Test GET /api/scripture_categories"""
        response = self.client.get("/api/scripture_categories")
        self.assertEqual(response.status_code, 200)
        data = response.json()
        self.assertIn("categories", data)
        self.assertIsInstance(data["categories"], list)

    def test_get_donation_products(self):
        """Test GET /api/donation/products"""
        response = self.client.get("/api/donation/products")
        self.assertEqual(response.status_code, 200)
        data = response.json()
        self.assertIsInstance(data, list)
        self.assertTrue(any(p['id'] == 'donation_unit_0100' for p in data))

    def test_get_translations(self):
        """Test GET /api/translations"""
        response = self.client.get("/api/translations")
        # This might return 404 if data/translations.json is missing
        if response.status_code == 200:
            data = response.json()
            self.assertIsInstance(data, dict)
        else:
            self.assertEqual(response.status_code, 404)

    def test_quiz_generate_basic(self):
        """Test POST /api/quiz/generate with minimal payload"""
        payload = {
            "language": "English"
        }
        response = self.client.post("/api/quiz/generate", json=payload)
        # This might take time as it calls generate_question
        self.assertEqual(response.status_code, 200)
        data = response.json()
        self.assertIn("question", data)
        self.assertIn("choices", data)


    def test_chat_basic(self):
        """Test POST /api/chat basic interaction with optional CLI query"""
        query = CLI_ARGS.query if CLI_ARGS else "What is the Bhagavad Gita?"
        payload = {
            "language": "English",
            "text": query,
            "session_id": "test-chat-session"
        }
        print(f"\n[Chat Test] Sending query: '{query}'")
        response = self.client.post("/api/chat", json=payload)
        self.assertEqual(response.status_code, 200)
        data = response.json()
        self.assertIn("reply", data)
        self.assertIn("session_id", data)
        print(f"  -> Received reply (length: {len(data['reply'])})")
        print(f"  -> Received reply : \n{data['reply']}")

    def test_search_scripture(self):
        """Test POST /api/scripture/{scripture_name}/search with optional CLI params"""
        # Use CLI args if provided, else fall back to defaults
        scripture_name = CLI_ARGS.scripture if CLI_ARGS else "bhagavat_gita"
        field = CLI_ARGS.field if CLI_ARGS else "verse"
        raw_value = CLI_ARGS.value if CLI_ARGS else "1"
        
        # Simple casting: try int, then float, then stay string
        try:
            value = int(raw_value)
        except ValueError:
            try:
                value = float(raw_value)
            except ValueError:
                value = raw_value

        payload = {
            "filter_obj": {
                "filters": [
                    {
                        "metadata_field": field,
                        "metadata_search_operator": "$eq",
                        "metadata_value": value
                    }
                ]
            }
        }
        
        print(f"\n[Search Test] Testing {scripture_name} where {field} = {value}")
        response = self.client.post(f"/api/scripture/{scripture_name}/search", json=payload)
        self.assertEqual(response.status_code, 200)
        data = response.json()
        self.assertIn("results", data)
        self.assertIsInstance(data["results"], list)
        
        # Mark as failed if results are empty
        self.assertTrue(len(data["results"]) > 0, f"No results found for {scripture_name} where {field} = {value}")
        print(f"  -> Found {len(data['results'])} matches. First match: {data['results'][0].get('text')[:50]}...")

    def test_get_scripture_toc(self):
        """Test GET /api/scripture/{scripture_name}/toc"""
        scripture_name = CLI_ARGS.scripture if CLI_ARGS else "bhagavat_gita"
        response = self.client.get(f"/api/scripture/{scripture_name}/toc")
        self.assertEqual(response.status_code, 200)
        data = response.json()
        self.assertIn("toc", data)
        self.assertIsInstance(data["toc"], list)

if __name__ == "__main__":
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument('--scripture', default='bhagavat_gita', help='Scripture name to search')
    parser.add_argument('--field', default='verse', help='Metadata field to filter by')
    parser.add_argument('--value', default='1', help='Metadata value to search for')
    parser.add_argument('--query', default=None, help='Custom chat query for test_chat_basic')
    
    # Parse our specific args and leave the rest for unittest (like -v or test names)
    CLI_ARGS, remaining_argv = parser.parse_known_args()
    
    # Re-inject the script name to keep unittest happy
    unittest.main(argv=[sys.argv[0]] + remaining_argv)