@@ -30,6 +30,12 @@ def setUp(self):
3030 ]
3131 }
3232
33+ self .mock_target_config = {
34+ 'cloud_name' : 'target-cloud' ,
35+ 'api_key' : 'target-key' ,
36+ 'api_secret' : 'target-secret'
37+ }
38+
3339 @patch ('cloudinary.api.metadata_fields' )
3440 def test_list_metadata_items (self , mock_metadata_fields ):
3541 """Test listing metadata fields"""
@@ -44,13 +50,32 @@ def test_list_metadata_items(self, mock_metadata_fields):
4450 ]
4551 }
4652
47- result = clone_module .list_metadata_items ()
53+ result = clone_module .list_metadata_items ("metadata_fields" )
4854
4955 mock_metadata_fields .assert_called_once ()
5056 self .assertEqual (result , mock_metadata_fields .return_value ['metadata_fields' ])
5157
58+ @patch ('cloudinary.api.metadata_rules' )
59+ def test_list_metadata_rules (self , mock_metadata_rules ):
60+ """Test listing metadata fields"""
61+ mock_metadata_rules .return_value = {
62+ 'metadata_rules' : [
63+ {
64+ 'external_id' : 'test_field' ,
65+ 'type' : 'string' ,
66+ 'label' : 'Test Field' ,
67+ 'mandatory' : False
68+ }
69+ ]
70+ }
71+
72+ result = clone_module .list_metadata_items ("metadata_rules" )
73+
74+ mock_metadata_rules .assert_called_once ()
75+ self .assertEqual (result , mock_metadata_rules .return_value ['metadata_rules' ])
76+
5277 @patch ('cloudinary.api.add_metadata_field' )
53- def test_create_metadata_item (self , mock_add_metadata_field ):
78+ def test_create_metadata_item_field (self , mock_add_metadata_field ):
5479 """Test creating a single metadata field"""
5580 metadata_field = {
5681 'external_id' : 'test_field' ,
@@ -59,12 +84,31 @@ def test_create_metadata_item(self, mock_add_metadata_field):
5984 'mandatory' : False
6085 }
6186
62- clone_module .create_metadata_item (metadata_field )
87+ clone_module .create_metadata_item ('add_metadata_field' , metadata_field , self . mock_target_config )
6388
6489 mock_add_metadata_field .assert_called_once_with (metadata_field )
6590
91+ @patch ('cloudinary.api.add_metadata_rule' )
92+ def test_create_metadata_item_rule (self , mock_add_metadata_rule ):
93+ """Test creating a single metadata rule"""
94+ metadata_rule = {
95+ 'external_id' : 'test_rule' ,
96+ 'condition' : 'if' ,
97+ 'metadata_field' : {
98+ 'external_id' : 'test_field'
99+ },
100+ 'results' : [{
101+ 'value' : 'test_value' ,
102+ 'apply_to' : ['metadata_field_external_id' ]
103+ }]
104+ }
105+
106+ clone_module .create_metadata_item ('add_metadata_rule' , metadata_rule , self .mock_target_config )
107+
108+ mock_add_metadata_rule .assert_called_once_with (metadata_rule )
109+
66110 @patch ('cloudinary.api.add_metadata_field' )
67- def test_create_metadata_item_with_error (self , mock_add_metadata_field ):
111+ def test_create_metadata_item_field_with_error (self , mock_add_metadata_field ):
68112 """Test creating metadata field with API error"""
69113 metadata_field = {
70114 'external_id' : 'test_field' ,
@@ -76,7 +120,28 @@ def test_create_metadata_item_with_error(self, mock_add_metadata_field):
76120 mock_add_metadata_field .side_effect = Exception ("API Error" )
77121
78122 with self .assertLogs (logger , level = 'ERROR' ) as log :
79- clone_module .create_metadata_item (metadata_field )
123+ clone_module .create_metadata_item ('add_metadata_field' , metadata_field , self .mock_target_config )
124+ self .assertIn ('Error creating metadata field' , log .output [0 ])
125+
126+ @patch ('cloudinary.api.add_metadata_rule' )
127+ def test_create_metadata_item_rule_with_error (self , mock_add_metadata_rule ):
128+ """Test creating metadata rule with API error"""
129+ metadata_rule = {
130+ 'external_id' : 'test_rule' ,
131+ 'condition' : 'if' ,
132+ 'metadata_field' : {
133+ 'external_id' : 'test_field'
134+ },
135+ 'results' : [{
136+ 'value' : 'test_value' ,
137+ 'apply_to' : ['metadata_field_external_id' ]
138+ }]
139+ }
140+
141+ mock_add_metadata_rule .side_effect = Exception ("API Error" )
142+
143+ with self .assertLogs (logger , level = 'ERROR' ) as log :
144+ clone_module .create_metadata_item ('add_metadata_rule' , metadata_rule , self .mock_target_config )
80145 self .assertIn ('Error creating metadata field' , log .output [0 ])
81146
82147 @patch .object (clone_module , 'create_metadata_item' )
@@ -95,17 +160,50 @@ def test_compare_create_metadata_items_new_fields(self, mock_list, mock_create):
95160 'label' : 'Field 2'
96161 }
97162 ]
163+
164+ destination_fields = []
98165
99- # Simulate destination having no fields
100- mock_list .return_value = []
101-
102- clone_module .compare_create_metadata_items (source_fields )
166+ clone_module .compare_create_metadata_items (source_fields , destination_fields , self .mock_target_config , key = "metadata_fields" )
103167
104168 # Both fields should be created
105169 self .assertEqual (mock_create .call_count , 2 )
106170 mock_create .assert_any_call (source_fields [0 ])
107171 mock_create .assert_any_call (source_fields [1 ])
108172
173+ @patch .object (clone_module , 'create_metadata_item' )
174+ @patch .object (clone_module , 'list_metadata_items' )
175+ def test_compare_create_metadata_items_new_rules (self , mock_list , mock_create ):
176+ """Test comparing and creating new metadata rules"""
177+ source_rules = [
178+ {
179+ 'external_id' : 'rule1' ,
180+ 'condition' : 'if' ,
181+ 'metadata_field' : {'external_id' : 'field1' },
182+ 'results' : [{
183+ 'value' : 'value1' ,
184+ 'apply_to' : ['target_field1' ]
185+ }]
186+ },
187+ {
188+ 'external_id' : 'rule2' ,
189+ 'condition' : 'if' ,
190+ 'metadata_field' : {'external_id' : 'field2' },
191+ 'results' : [{
192+ 'value' : 'value2' ,
193+ 'apply_to' : ['target_field2' ]
194+ }]
195+ }
196+ ]
197+
198+ destination_rules = []
199+
200+ clone_module .compare_create_metadata_items (source_rules , destination_rules , self .mock_target_config , key = "metadata_rules" )
201+
202+ # Both rules should be created
203+ self .assertEqual (mock_create .call_count , 2 )
204+ mock_create .assert_any_call ('add_metadata_rule' , source_rules [0 ])
205+ mock_create .assert_any_call ('add_metadata_rule' , source_rules [1 ])
206+
109207 @patch .object (clone_module , 'create_metadata_item' )
110208 @patch .object (clone_module , 'list_metadata_items' )
111209 def test_compare_create_metadata_items_existing_fields (self , mock_list , mock_create ):
@@ -119,19 +217,53 @@ def test_compare_create_metadata_items_existing_fields(self, mock_list, mock_cre
119217 ]
120218
121219 # Simulate destination already having the field
122- mock_list . return_value = [
220+ destination_fields = [
123221 {
124222 'external_id' : 'field1' ,
125223 'type' : 'string' ,
126224 'label' : 'Field 1'
127225 }
128226 ]
129227
130- clone_module .compare_create_metadata_items (source_fields )
228+ clone_module .compare_create_metadata_items (source_fields , destination_fields , self . mock_target_config , key = "metadata_fields" )
131229
132230 # No fields should be created
133231 mock_create .assert_not_called ()
134232
233+ @patch .object (clone_module , 'create_metadata_item' )
234+ @patch .object (clone_module , 'list_metadata_items' )
235+ def test_compare_create_metadata_items_existing_rules (self , mock_list , mock_create ):
236+ """Test comparing when rules already exist"""
237+ source_rules = [
238+ {
239+ 'external_id' : 'rule1' ,
240+ 'condition' : 'if' ,
241+ 'metadata_field' : {'external_id' : 'field1' },
242+ 'results' : [{
243+ 'value' : 'value1' ,
244+ 'apply_to' : ['target_field1' ]
245+ }]
246+ }
247+ ]
248+
249+ # Simulate destination already having the rule
250+ destination_rules = [
251+ {
252+ 'external_id' : 'rule1' ,
253+ 'condition' : 'if' ,
254+ 'metadata_field' : {'external_id' : 'field1' },
255+ 'results' : [{
256+ 'value' : 'value1' ,
257+ 'apply_to' : ['target_field1' ]
258+ }]
259+ }
260+ ]
261+
262+ clone_module .compare_create_metadata_items (source_rules , destination_rules , self .mock_target_config , key = "metadata_rules" )
263+
264+ # No rules should be created
265+ mock_create .assert_not_called ()
266+
135267 @patch .object (clone_module , 'create_metadata_item' )
136268 @patch .object (clone_module , 'list_metadata_items' )
137269 def test_compare_create_metadata_items_mixed_scenario (self , mock_list , mock_create ):
@@ -150,19 +282,61 @@ def test_compare_create_metadata_items_mixed_scenario(self, mock_list, mock_crea
150282 ]
151283
152284 # Simulate destination having only one field
153- mock_list . return_value = [
285+ destination_fields = [
154286 {
155287 'external_id' : 'existing_field' ,
156288 'type' : 'string' ,
157289 'label' : 'Existing Field'
158290 }
159291 ]
160292
161- clone_module .compare_create_metadata_items (source_fields )
293+ clone_module .compare_create_metadata_items (source_fields , destination_fields , self . mock_target_config , key = "metadata_fields" )
162294
163295 # Only new_field should be created
164296 mock_create .assert_called_once_with (source_fields [1 ])
165297
298+ @patch .object (clone_module , 'create_metadata_item' )
299+ @patch .object (clone_module , 'list_metadata_items' )
300+ def test_compare_create_metadata_items_mixed_rules_scenario (self , mock_list , mock_create ):
301+ """Test comparing with mix of new and existing rules"""
302+ source_rules = [
303+ {
304+ 'external_id' : 'existing_rule' ,
305+ 'condition' : 'if' ,
306+ 'metadata_field' : {'external_id' : 'field1' },
307+ 'results' : [{
308+ 'value' : 'value1' ,
309+ 'apply_to' : ['target_field1' ]
310+ }]
311+ },
312+ {
313+ 'external_id' : 'new_rule' ,
314+ 'condition' : 'if' ,
315+ 'metadata_field' : {'external_id' : 'field2' },
316+ 'results' : [{
317+ 'value' : 'value2' ,
318+ 'apply_to' : ['target_field2' ]
319+ }]
320+ }
321+ ]
322+
323+ # Simulate destination having only one rule
324+ destination_rules = [
325+ {
326+ 'external_id' : 'existing_rule' ,
327+ 'condition' : 'if' ,
328+ 'metadata_field' : {'external_id' : 'field1' },
329+ 'results' : [{
330+ 'value' : 'value1' ,
331+ 'apply_to' : ['target_field1' ]
332+ }]
333+ }
334+ ]
335+
336+ clone_module .compare_create_metadata_items (source_rules , destination_rules , self .mock_target_config , key = "metadata_rules" )
337+
338+ # Only new_rule should be created
339+ mock_create .assert_called_once_with ('add_metadata_rule' , source_rules [1 ])
166340
167341if __name__ == '__main__' :
168342 unittest .main ()
0 commit comments