Coverage for mindsdb / integrations / handlers / shopify_handler / tests / test_shopify_handler.py: 0%
444 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-21 00:36 +0000
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-21 00:36 +0000
1import unittest
2from unittest.mock import MagicMock, patch
3import sys
5from mindsdb.integrations.libs.response import HandlerStatusResponse as StatusResponse
6from mindsdb.integrations.libs.api_handler_exceptions import (
7 MissingConnectionParams,
8 ConnectionFailed,
9 InvalidNativeQuery,
10)
12# Mock shopify and requests modules before importing the handler
13if "shopify" not in sys.modules:
14 sys.modules["shopify"] = MagicMock()
15 sys.modules["shopify.ShopifyResource"] = MagicMock()
16 sys.modules["shopify.Session"] = MagicMock()
17 sys.modules["shopify.Shop"] = MagicMock()
19if "requests" not in sys.modules:
20 sys.modules["requests"] = MagicMock()
22from mindsdb.integrations.handlers.shopify_handler.shopify_handler import ShopifyHandler
25class BaseShopifyHandlerTest(unittest.TestCase):
26 """Base test class with common setup and helper methods."""
28 # Test constants
29 TEST_SHOP_URL = "test-shop.myshopify.com"
30 TEST_CLIENT_ID = "test_client_id"
31 TEST_CLIENT_SECRET = "test_client_secret"
32 TEST_HANDLER_NAME = "test_shopify_handler"
34 def setUp(self):
35 """Set up test fixtures."""
36 self.connection_data = {
37 "shop_url": self.TEST_SHOP_URL,
38 "client_id": self.TEST_CLIENT_ID,
39 "client_secret": self.TEST_CLIENT_SECRET,
40 }
42 def tearDown(self):
43 """Clean up after tests."""
44 pass
47class TestShopifyHandlerInitialization(BaseShopifyHandlerTest):
48 """Test suite for Shopify Handler initialization."""
50 def test_handler_initialization_success(self):
51 """Test successful handler initialization with all required parameters."""
52 handler = ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=self.connection_data)
54 self.assertEqual(handler.name, self.TEST_HANDLER_NAME)
55 self.assertEqual(handler.connection_data, self.connection_data)
56 self.assertFalse(handler.is_connected)
57 self.assertIsNone(handler.connection)
59 def test_handler_initialization_without_connection_data(self):
60 """Test handler initialization fails when connection_data is missing."""
61 with self.assertRaises(MissingConnectionParams) as context:
62 ShopifyHandler(self.TEST_HANDLER_NAME)
64 self.assertIn("Incomplete parameters", str(context.exception))
66 def test_handler_initialization_missing_shop_url(self):
67 """Test handler initialization fails when shop_url is missing."""
68 incomplete_data = {
69 "client_id": self.TEST_CLIENT_ID,
70 "client_secret": self.TEST_CLIENT_SECRET,
71 }
73 with self.assertRaises(MissingConnectionParams) as context:
74 ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=incomplete_data)
76 self.assertIn("shop_url", str(context.exception))
78 def test_handler_initialization_missing_client_id(self):
79 """Test handler initialization fails when client_id is missing."""
80 incomplete_data = {
81 "shop_url": self.TEST_SHOP_URL,
82 "client_secret": self.TEST_CLIENT_SECRET,
83 }
85 with self.assertRaises(MissingConnectionParams) as context:
86 ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=incomplete_data)
88 self.assertIn("client_id", str(context.exception))
90 def test_handler_initialization_missing_client_secret(self):
91 """Test handler initialization fails when client_secret is missing."""
92 incomplete_data = {
93 "shop_url": self.TEST_SHOP_URL,
94 "client_id": self.TEST_CLIENT_ID,
95 }
97 with self.assertRaises(MissingConnectionParams) as context:
98 ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=incomplete_data)
100 self.assertIn("client_secret", str(context.exception))
102 def test_handler_tables_registered(self):
103 """Test that all required tables are registered during initialization."""
104 handler = ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=self.connection_data)
106 expected_tables = [
107 "products",
108 "customers",
109 "orders",
110 "product_variants",
111 "marketing_events",
112 "inventory_items",
113 "staff_members",
114 "gift_cards",
115 ]
117 for table_name in expected_tables:
118 self.assertIn(table_name, handler._tables)
121class TestShopifyHandlerConnection(BaseShopifyHandlerTest):
122 """Test suite for Shopify Handler connection management."""
124 @patch("mindsdb.integrations.handlers.shopify_handler.shopify_handler.requests")
125 @patch("mindsdb.integrations.handlers.shopify_handler.shopify_handler.shopify")
126 def test_connect_success(self, mock_shopify, mock_requests):
127 """Test successful connection to Shopify API."""
128 # Mock the OAuth response
129 mock_response = MagicMock()
130 mock_response.json.return_value = {"access_token": "test_access_token"}
131 mock_requests.post.return_value = mock_response
133 # Mock the Session
134 mock_session = MagicMock()
135 mock_shopify.Session.return_value = mock_session
137 handler = ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=self.connection_data)
138 result = handler.connect()
140 # Verify OAuth request was made
141 mock_requests.post.assert_called_once()
142 call_args = mock_requests.post.call_args
143 self.assertIn(self.TEST_SHOP_URL, call_args[0][0])
144 self.assertEqual(call_args[1]["data"]["client_id"], self.TEST_CLIENT_ID)
145 self.assertEqual(call_args[1]["data"]["client_secret"], self.TEST_CLIENT_SECRET)
147 # Verify session was created
148 mock_shopify.Session.assert_called_once_with(self.TEST_SHOP_URL, "2025-10", "test_access_token")
150 self.assertTrue(handler.is_connected)
151 self.assertEqual(result, mock_session)
153 @patch("mindsdb.integrations.handlers.shopify_handler.shopify_handler.requests")
154 @patch("mindsdb.integrations.handlers.shopify_handler.shopify_handler.shopify")
155 def test_connect_when_already_connected(self, mock_shopify, mock_requests):
156 """Test that connect returns existing connection when already connected."""
157 mock_session = MagicMock()
159 handler = ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=self.connection_data)
160 handler.connection = mock_session
161 handler.is_connected = True
163 result = handler.connect()
165 # Should not make new OAuth request
166 mock_requests.post.assert_not_called()
167 mock_shopify.Session.assert_not_called()
169 self.assertEqual(result, mock_session)
171 @patch("mindsdb.integrations.handlers.shopify_handler.shopify_handler.requests")
172 def test_connect_oauth_failure(self, mock_requests):
173 """Test connection failure when OAuth request fails."""
174 error_msg = "Invalid credentials"
175 mock_requests.post.side_effect = Exception(error_msg)
177 handler = ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=self.connection_data)
179 with self.assertRaises(Exception) as context:
180 handler.connect()
182 self.assertIn(error_msg, str(context.exception))
183 self.assertFalse(handler.is_connected)
185 @patch("mindsdb.integrations.handlers.shopify_handler.shopify_handler.requests")
186 def test_connect_missing_access_token(self, mock_requests):
187 """Test connection failure when access token is missing from response."""
188 mock_response = MagicMock()
189 mock_response.json.return_value = {} # No access_token
190 mock_requests.post.return_value = mock_response
192 handler = ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=self.connection_data)
194 with self.assertRaises(ConnectionFailed) as context:
195 handler.connect()
197 self.assertIn("Unable to get an access token", str(context.exception))
198 self.assertFalse(handler.is_connected)
200 @patch("mindsdb.integrations.handlers.shopify_handler.shopify_handler.requests")
201 @patch("mindsdb.integrations.handlers.shopify_handler.shopify_handler.shopify")
202 def test_check_connection_success(self, mock_shopify, mock_requests):
203 """Test successful connection check."""
204 # Mock OAuth response
205 mock_response = MagicMock()
206 mock_response.json.return_value = {"access_token": "test_access_token"}
207 mock_requests.post.return_value = mock_response
209 # Mock session and shop
210 mock_session = MagicMock()
211 mock_shopify.Session.return_value = mock_session
212 mock_shopify.ShopifyResource.activate_session = MagicMock()
213 mock_shopify.Shop.current.return_value = MagicMock()
215 handler = ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=self.connection_data)
216 result = handler.check_connection()
218 self.assertIsInstance(result, StatusResponse)
219 self.assertTrue(result.success)
220 self.assertTrue(handler.is_connected)
222 # Verify session was activated and Shop.current was called
223 mock_shopify.ShopifyResource.activate_session.assert_called_once_with(mock_session)
224 mock_shopify.Shop.current.assert_called_once()
226 @patch("mindsdb.integrations.handlers.shopify_handler.shopify_handler.requests")
227 @patch("mindsdb.integrations.handlers.shopify_handler.shopify_handler.shopify")
228 def test_check_connection_failure(self, mock_shopify, mock_requests):
229 """Test connection check failure."""
230 # Mock OAuth response
231 mock_response = MagicMock()
232 mock_response.json.return_value = {"access_token": "test_access_token"}
233 mock_requests.post.return_value = mock_response
235 # Mock session
236 mock_session = MagicMock()
237 mock_shopify.Session.return_value = mock_session
238 mock_shopify.ShopifyResource.activate_session = MagicMock()
240 # Make Shop.current fail
241 error_message = "Invalid shop"
242 mock_shopify.Shop.current.side_effect = Exception(error_message)
244 handler = ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=self.connection_data)
246 with self.assertRaises(ConnectionFailed):
247 handler.check_connection()
249 @patch("mindsdb.integrations.handlers.shopify_handler.shopify_handler.requests")
250 def test_check_connection_oauth_failure(self, mock_requests):
251 """Test connection check failure during OAuth."""
252 error_message = "OAuth failed"
253 mock_requests.post.side_effect = Exception(error_message)
255 handler = ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=self.connection_data)
257 with self.assertRaises(ConnectionFailed):
258 handler.check_connection()
261class TestShopifyHandlerQueries(BaseShopifyHandlerTest):
262 """Test suite for Shopify Handler query execution."""
264 @patch("mindsdb.integrations.handlers.shopify_handler.shopify_handler.requests")
265 @patch("mindsdb.integrations.handlers.shopify_handler.shopify_handler.shopify")
266 @patch("mindsdb.integrations.handlers.shopify_handler.shopify_handler.parse_sql")
267 def test_native_query_success(self, mock_parse_sql, mock_shopify, mock_requests):
268 """Test successful native query execution."""
269 # Mock OAuth response
270 mock_response = MagicMock()
271 mock_response.json.return_value = {"access_token": "test_access_token"}
272 mock_requests.post.return_value = mock_response
274 # Mock session
275 mock_session = MagicMock()
276 mock_shopify.Session.return_value = mock_session
278 # Mock parse_sql
279 mock_ast = MagicMock()
280 mock_parse_sql.return_value = mock_ast
282 handler = ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=self.connection_data)
284 # Mock the query method to return a success response
285 handler.query = MagicMock()
286 mock_query_response = MagicMock()
287 handler.query.return_value = mock_query_response
289 query = "SELECT * FROM products"
290 result = handler.native_query(query)
292 mock_parse_sql.assert_called_once_with(query)
293 handler.query.assert_called_once_with(mock_ast)
294 self.assertEqual(result, mock_query_response)
296 @patch("mindsdb.integrations.handlers.shopify_handler.shopify_handler.parse_sql")
297 def test_native_query_invalid_sql(self, mock_parse_sql):
298 """Test native query with invalid SQL."""
299 mock_parse_sql.side_effect = Exception("Invalid SQL")
301 handler = ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=self.connection_data)
303 query = "INVALID SQL QUERY"
304 with self.assertRaises(InvalidNativeQuery) as context:
305 handler.native_query(query)
307 self.assertIn("invalid", str(context.exception).lower())
310class TestShopifyHandlerConnectionArgs(BaseShopifyHandlerTest):
311 """Test suite for Shopify Handler connection arguments validation."""
313 def test_connection_args_structure(self):
314 """Test that connection_args has the correct structure."""
315 from mindsdb.integrations.handlers.shopify_handler.connection_args import connection_args
317 required_fields = ["type", "description", "required", "label"]
319 # Check shop_url
320 self.assertIn("shop_url", connection_args)
321 for field in required_fields:
322 self.assertIn(field, connection_args["shop_url"])
323 self.assertTrue(connection_args["shop_url"]["required"])
325 # Check client_id
326 self.assertIn("client_id", connection_args)
327 for field in required_fields:
328 self.assertIn(field, connection_args["client_id"])
329 self.assertTrue(connection_args["client_id"]["required"])
331 # Check client_secret
332 self.assertIn("client_secret", connection_args)
333 for field in required_fields:
334 self.assertIn(field, connection_args["client_secret"])
335 self.assertTrue(connection_args["client_secret"]["required"])
336 self.assertTrue(connection_args["client_secret"].get("secret", False))
338 def test_connection_args_example_structure(self):
339 """Test that connection_args_example has the correct structure."""
340 from mindsdb.integrations.handlers.shopify_handler.connection_args import (
341 connection_args_example,
342 )
344 self.assertIn("shop_url", connection_args_example)
345 self.assertIn("client_id", connection_args_example)
346 self.assertIn("client_secret", connection_args_example)
348 self.assertIsInstance(connection_args_example["shop_url"], str)
349 self.assertIsInstance(connection_args_example["client_id"], str)
350 self.assertIsInstance(connection_args_example["client_secret"], str)
353class TestShopifyHandlerEdgeCases(BaseShopifyHandlerTest):
354 """Test suite for Shopify Handler edge cases."""
356 def test_handler_name_attribute(self):
357 """Test that handler has correct name attribute."""
358 handler = ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=self.connection_data)
359 self.assertEqual(handler.name, self.TEST_HANDLER_NAME)
361 @patch("mindsdb.integrations.handlers.shopify_handler.shopify_handler.requests")
362 @patch("mindsdb.integrations.handlers.shopify_handler.shopify_handler.shopify")
363 def test_multiple_connections(self, mock_shopify, mock_requests):
364 """Test multiple connection attempts."""
365 # Mock OAuth response
366 mock_response = MagicMock()
367 mock_response.json.return_value = {"access_token": "test_access_token"}
368 mock_requests.post.return_value = mock_response
370 # Mock session
371 mock_session = MagicMock()
372 mock_shopify.Session.return_value = mock_session
374 handler = ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=self.connection_data)
376 # First connection
377 result1 = handler.connect()
378 self.assertTrue(handler.is_connected)
380 # Second connection (should return existing)
381 result2 = handler.connect()
382 self.assertEqual(result1, result2)
384 # Should only call OAuth once
385 self.assertEqual(mock_requests.post.call_count, 1)
387 def test_connection_data_preserved(self):
388 """Test that connection data is preserved after initialization."""
389 handler = ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=self.connection_data)
391 self.assertEqual(handler.connection_data["shop_url"], self.TEST_SHOP_URL)
392 self.assertEqual(handler.connection_data["client_id"], self.TEST_CLIENT_ID)
393 self.assertEqual(handler.connection_data["client_secret"], self.TEST_CLIENT_SECRET)
395 def test_empty_connection_data(self):
396 """Test handler initialization with empty connection_data."""
397 with self.assertRaises(MissingConnectionParams):
398 ShopifyHandler(self.TEST_HANDLER_NAME, connection_data={})
400 def test_partial_connection_data(self):
401 """Test handler initialization with partial connection_data."""
402 partial_data = {"shop_url": self.TEST_SHOP_URL}
404 with self.assertRaises(MissingConnectionParams) as context:
405 ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=partial_data)
407 # Should mention the missing parameters
408 error_message = str(context.exception)
409 self.assertTrue("client_id" in error_message or "client_secret" in error_message)
412class TestShopifyHandlerIntegration(BaseShopifyHandlerTest):
413 """Test suite for Shopify Handler integration scenarios."""
415 @patch("mindsdb.integrations.handlers.shopify_handler.shopify_handler.requests")
416 @patch("mindsdb.integrations.handlers.shopify_handler.shopify_handler.shopify")
417 def test_connection_and_check(self, mock_shopify, mock_requests):
418 """Test connection followed by check_connection."""
419 # Mock OAuth response
420 mock_response = MagicMock()
421 mock_response.json.return_value = {"access_token": "test_access_token"}
422 mock_requests.post.return_value = mock_response
424 # Mock session
425 mock_session = MagicMock()
426 mock_shopify.Session.return_value = mock_session
427 mock_shopify.ShopifyResource.activate_session = MagicMock()
428 mock_shopify.Shop.current.return_value = MagicMock()
430 handler = ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=self.connection_data)
432 # First connect
433 handler.connect()
434 self.assertTrue(handler.is_connected)
436 # Then check connection
437 result = handler.check_connection()
438 self.assertTrue(result.success)
440 def test_handler_with_extra_kwargs(self):
441 """Test handler initialization with extra keyword arguments."""
442 extra_kwargs = {
443 "connection_data": self.connection_data,
444 "extra_param": "extra_value",
445 }
447 handler = ShopifyHandler(self.TEST_HANDLER_NAME, **extra_kwargs)
448 self.assertEqual(handler.name, self.TEST_HANDLER_NAME)
449 self.assertTrue(handler.is_connected is False)
452class TestShopifyHandlerTableMetadata(BaseShopifyHandlerTest):
453 """Test suite for Shopify Handler table metadata methods."""
455 @patch("mindsdb.integrations.handlers.shopify_handler.shopify_tables.query_graphql")
456 def test_products_table_meta_get_tables(self, mock_query_graphql):
457 """Test meta_get_tables method for products table."""
458 mock_query_graphql.return_value = {"productsCount": {"count": 100}}
460 handler = ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=self.connection_data)
461 products_table = handler._tables["products"]
463 result = products_table.meta_get_tables()
465 self.assertIsInstance(result, dict)
466 self.assertEqual(result["table_name"], "products")
467 self.assertEqual(result["table_type"], "BASE TABLE")
468 self.assertIn("table_description", result)
469 self.assertEqual(result["row_count"], 100)
471 def test_products_table_meta_get_primary_keys(self):
472 """Test meta_get_primary_keys method for products table."""
473 handler = ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=self.connection_data)
474 products_table = handler._tables["products"]
476 result = products_table.meta_get_primary_keys("products")
478 self.assertIsInstance(result, list)
479 self.assertEqual(len(result), 1)
480 self.assertEqual(result[0]["table_name"], "products")
481 self.assertEqual(result[0]["column_name"], "id")
483 def test_products_table_meta_get_foreign_keys(self):
484 """Test meta_get_foreign_keys method for products table."""
485 handler = ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=self.connection_data)
486 products_table = handler._tables["products"]
488 result = products_table.meta_get_foreign_keys("products", ["products", "orders"])
490 self.assertIsInstance(result, list)
491 # Products table should have no foreign keys
492 self.assertEqual(len(result), 0)
494 def test_products_table_get_columns(self):
495 """Test get_columns method for products table."""
496 handler = ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=self.connection_data)
497 products_table = handler._tables["products"]
499 result = products_table.get_columns()
501 self.assertIsInstance(result, list)
502 self.assertGreater(len(result), 0)
503 # Check that some expected columns are present
504 self.assertIn("id", result)
505 self.assertIn("title", result)
506 # All items should be strings
507 for column_name in result:
508 self.assertIsInstance(column_name, str)
510 def test_products_table_meta_get_columns(self):
511 """Test meta_get_columns method for products table."""
512 handler = ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=self.connection_data)
513 products_table = handler._tables["products"]
515 result = products_table.meta_get_columns()
517 self.assertIsInstance(result, list)
518 self.assertGreater(len(result), 0)
519 # Each column should be a dictionary with metadata
520 for column in result:
521 self.assertIsInstance(column, dict)
522 self.assertIn("COLUMN_NAME", column)
524 @patch("mindsdb.integrations.handlers.shopify_handler.shopify_tables.query_graphql")
525 def test_product_variants_table_meta_get_tables(self, mock_query_graphql):
526 """Test meta_get_tables method for product_variants table."""
527 mock_query_graphql.return_value = {"productVariantsCount": {"count": 250}}
529 handler = ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=self.connection_data)
530 variants_table = handler._tables["product_variants"]
532 result = variants_table.meta_get_tables()
534 self.assertIsInstance(result, dict)
535 self.assertEqual(result["table_name"], "product_variants")
536 self.assertEqual(result["table_type"], "BASE TABLE")
537 self.assertIn("table_description", result)
538 self.assertEqual(result["row_count"], 250)
540 def test_product_variants_table_meta_get_primary_keys(self):
541 """Test meta_get_primary_keys method for product_variants table."""
542 handler = ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=self.connection_data)
543 variants_table = handler._tables["product_variants"]
545 result = variants_table.meta_get_primary_keys("product_variants")
547 self.assertIsInstance(result, list)
548 self.assertEqual(len(result), 1)
549 self.assertEqual(result[0]["table_name"], "product_variants")
550 self.assertEqual(result[0]["column_name"], "id")
552 def test_product_variants_table_meta_get_foreign_keys(self):
553 """Test meta_get_foreign_keys method for product_variants table."""
554 handler = ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=self.connection_data)
555 variants_table = handler._tables["product_variants"]
557 result = variants_table.meta_get_foreign_keys("product_variants", ["products", "product_variants"])
559 self.assertIsInstance(result, list)
560 # Product variants should have a foreign key to products
561 self.assertGreater(len(result), 0)
562 self.assertEqual(result[0]["PARENT_TABLE_NAME"], "product_variants")
563 self.assertEqual(result[0]["PARENT_COLUMN_NAME"], "productId")
564 self.assertEqual(result[0]["CHILD_TABLE_NAME"], "products")
565 self.assertEqual(result[0]["CHILD_COLUMN_NAME"], "id")
567 def test_product_variants_table_get_columns(self):
568 """Test get_columns method for product_variants table."""
569 handler = ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=self.connection_data)
570 variants_table = handler._tables["product_variants"]
572 result = variants_table.get_columns()
574 self.assertIsInstance(result, list)
575 self.assertGreater(len(result), 0)
576 # Check that some expected columns are present
577 self.assertIn("id", result)
578 self.assertIn("productId", result)
580 def test_product_variants_table_meta_get_columns(self):
581 """Test meta_get_columns method for product_variants table."""
582 handler = ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=self.connection_data)
583 variants_table = handler._tables["product_variants"]
585 result = variants_table.meta_get_columns()
587 self.assertIsInstance(result, list)
588 self.assertGreater(len(result), 0)
589 for column in result:
590 self.assertIsInstance(column, dict)
591 self.assertIn("COLUMN_NAME", column)
593 @patch("mindsdb.integrations.handlers.shopify_handler.shopify_tables.query_graphql")
594 def test_customers_table_meta_get_tables(self, mock_query_graphql):
595 """Test meta_get_tables method for customers table."""
596 mock_query_graphql.return_value = {"customersCount": {"count": 500}}
598 handler = ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=self.connection_data)
599 customers_table = handler._tables["customers"]
601 result = customers_table.meta_get_tables()
603 self.assertIsInstance(result, dict)
604 self.assertEqual(result["table_name"], "customers")
605 self.assertEqual(result["table_type"], "BASE TABLE")
606 self.assertIn("table_description", result)
607 self.assertEqual(result["row_count"], 500)
609 def test_customers_table_meta_get_primary_keys(self):
610 """Test meta_get_primary_keys method for customers table."""
611 handler = ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=self.connection_data)
612 customers_table = handler._tables["customers"]
614 result = customers_table.meta_get_primary_keys("customers")
616 self.assertIsInstance(result, list)
617 self.assertEqual(len(result), 1)
618 self.assertEqual(result[0]["table_name"], "customers")
619 self.assertEqual(result[0]["column_name"], "id")
621 def test_customers_table_meta_get_foreign_keys(self):
622 """Test meta_get_foreign_keys method for customers table."""
623 handler = ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=self.connection_data)
624 customers_table = handler._tables["customers"]
626 result = customers_table.meta_get_foreign_keys("customers", ["customers", "orders"])
628 self.assertIsInstance(result, list)
629 # Customers table should have no foreign keys
630 self.assertEqual(len(result), 0)
632 def test_customers_table_get_columns(self):
633 """Test get_columns method for customers table."""
634 handler = ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=self.connection_data)
635 customers_table = handler._tables["customers"]
637 result = customers_table.get_columns()
639 self.assertIsInstance(result, list)
640 self.assertGreater(len(result), 0)
641 # Check that some expected columns are present
642 self.assertIn("id", result)
643 self.assertIn("emailAddress", result)
645 def test_customers_table_meta_get_columns(self):
646 """Test meta_get_columns method for customers table."""
647 handler = ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=self.connection_data)
648 customers_table = handler._tables["customers"]
650 result = customers_table.meta_get_columns()
652 self.assertIsInstance(result, list)
653 self.assertGreater(len(result), 0)
654 for column in result:
655 self.assertIsInstance(column, dict)
656 self.assertIn("COLUMN_NAME", column)
658 @patch("mindsdb.integrations.handlers.shopify_handler.shopify_tables.query_graphql")
659 def test_orders_table_meta_get_tables(self, mock_query_graphql):
660 """Test meta_get_tables method for orders table."""
661 mock_query_graphql.return_value = {"ordersCount": {"count": 1000}}
663 handler = ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=self.connection_data)
664 orders_table = handler._tables["orders"]
666 result = orders_table.meta_get_tables()
668 self.assertIsInstance(result, dict)
669 self.assertEqual(result["table_name"], "orders")
670 self.assertEqual(result["table_type"], "BASE TABLE")
671 self.assertIn("table_description", result)
672 self.assertEqual(result["row_count"], 1000)
674 def test_orders_table_meta_get_primary_keys(self):
675 """Test meta_get_primary_keys method for orders table."""
676 handler = ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=self.connection_data)
677 orders_table = handler._tables["orders"]
679 result = orders_table.meta_get_primary_keys("orders")
681 self.assertIsInstance(result, list)
682 self.assertEqual(len(result), 1)
683 self.assertEqual(result[0]["table_name"], "orders")
684 self.assertEqual(result[0]["column_name"], "id")
686 def test_orders_table_meta_get_foreign_keys(self):
687 """Test meta_get_foreign_keys method for orders table."""
688 handler = ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=self.connection_data)
689 orders_table = handler._tables["orders"]
691 # Test with customers in the table list
692 result = orders_table.meta_get_foreign_keys("orders", ["customers", "orders"])
694 self.assertIsInstance(result, list)
695 # Orders table should have a foreign key to customers
696 self.assertGreater(len(result), 0)
697 self.assertEqual(result[0]["PARENT_TABLE_NAME"], "orders")
698 self.assertEqual(result[0]["PARENT_COLUMN_NAME"], "customerId")
699 self.assertEqual(result[0]["CHILD_TABLE_NAME"], "customers")
700 self.assertEqual(result[0]["CHILD_COLUMN_NAME"], "id")
702 def test_orders_table_get_columns(self):
703 """Test get_columns method for orders table."""
704 handler = ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=self.connection_data)
705 orders_table = handler._tables["orders"]
707 result = orders_table.get_columns()
709 self.assertIsInstance(result, list)
710 self.assertGreater(len(result), 0)
711 # Check that some expected columns are present
712 self.assertIn("id", result)
713 self.assertIn("customerId", result)
715 def test_orders_table_meta_get_columns(self):
716 """Test meta_get_columns method for orders table."""
717 handler = ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=self.connection_data)
718 orders_table = handler._tables["orders"]
720 result = orders_table.meta_get_columns()
722 self.assertIsInstance(result, list)
723 self.assertGreater(len(result), 0)
724 for column in result:
725 self.assertIsInstance(column, dict)
726 self.assertIn("COLUMN_NAME", column)
728 def test_all_tables_have_metadata_methods(self):
729 """Test that all registered tables have required metadata methods."""
730 handler = ShopifyHandler(self.TEST_HANDLER_NAME, connection_data=self.connection_data)
732 expected_tables = [
733 "products",
734 "customers",
735 "orders",
736 "product_variants",
737 "marketing_events",
738 "inventory_items",
739 "staff_members",
740 "gift_cards",
741 ]
743 for table_name in expected_tables:
744 with self.subTest(table=table_name):
745 table = handler._tables[table_name]
747 # Check that all required methods exist
748 self.assertTrue(hasattr(table, "meta_get_tables"))
749 self.assertTrue(hasattr(table, "meta_get_primary_keys"))
750 self.assertTrue(hasattr(table, "meta_get_foreign_keys"))
751 self.assertTrue(hasattr(table, "get_columns"))
752 self.assertTrue(hasattr(table, "meta_get_columns"))
754 # Check that methods are callable
755 self.assertTrue(callable(table.meta_get_tables))
756 self.assertTrue(callable(table.meta_get_primary_keys))
757 self.assertTrue(callable(table.meta_get_foreign_keys))
758 self.assertTrue(callable(table.get_columns))
759 self.assertTrue(callable(table.meta_get_columns))
762if __name__ == "__main__":
763 unittest.main()