66import pytest
77
88from sift_client .sift_types import Channel
9- from sift_client .sift_types .channel import ChannelDataType , ChannelReference
9+ from sift_client .sift_types .channel import ChannelDataType , ChannelReference , ChannelUpdate
1010
1111
1212@pytest .fixture
@@ -22,6 +22,10 @@ def mock_channel(mock_client):
2222 bit_field_elements = [],
2323 enum_types = {},
2424 asset_id = "test_asset_id" ,
25+ display_description = "display description" ,
26+ display_unit = "m/s" ,
27+ metadata = {},
28+ active = True ,
2529 created_date = datetime .now (timezone .utc ),
2630 modified_date = datetime .now (timezone .utc ),
2731 created_by_user_id = "user1" ,
@@ -215,3 +219,83 @@ def test_data_method_with_minimal_params(self, mock_channel, mock_client):
215219 limit = None ,
216220 )
217221 assert result == mock_data
222+
223+ def test_update_calls_client_and_updates_self (self , mock_channel , mock_client ):
224+ """Test that update() calls client.channels.update and calls _update."""
225+ updated_channel = MagicMock ()
226+ mock_client .channels .update .return_value = updated_channel
227+
228+ with MagicMock () as mock_update :
229+ mock_channel ._update = mock_update
230+
231+ update = ChannelUpdate (display_description = "new description" )
232+ result = mock_channel .update (update )
233+
234+ mock_client .channels .update .assert_called_once_with (channel = mock_channel , update = update )
235+ mock_update .assert_called_once_with (updated_channel )
236+ assert result is mock_channel
237+
238+ def test_archive_sets_active_false_via_update (self , mock_channel , mock_client ):
239+ """archive() delegates to update with active=False and updates in place."""
240+ updated = MagicMock ()
241+ mock_client .channels .update .return_value = updated
242+
243+ with MagicMock () as mock_update :
244+ mock_channel ._update = mock_update
245+ result = mock_channel .archive ()
246+
247+ mock_client .channels .update .assert_called_once_with (
248+ channel = mock_channel , update = {"active" : False }
249+ )
250+ mock_update .assert_called_once_with (updated )
251+ assert result is mock_channel
252+
253+ def test_unarchive_sets_active_true_via_update (self , mock_channel , mock_client ):
254+ """unarchive() delegates to update with active=True and updates in place."""
255+ updated = MagicMock ()
256+ mock_client .channels .update .return_value = updated
257+
258+ with MagicMock () as mock_update :
259+ mock_channel ._update = mock_update
260+ result = mock_channel .unarchive ()
261+
262+ mock_client .channels .update .assert_called_once_with (
263+ channel = mock_channel , update = {"active" : True }
264+ )
265+ mock_update .assert_called_once_with (updated )
266+ assert result is mock_channel
267+
268+
269+ class TestChannelUpdate :
270+ """Channel-specific field wiring for ChannelUpdate.
271+
272+ The generic ModelUpdate behavior (field-mask generation, unset/None exclusion,
273+ resource-id requirement, the metadata converter and MappingHelper path expansion)
274+ is already covered in test_base.py and test_asset.py. These tests only assert the
275+ parts unique to ChannelUpdate: which proto fields its fields map onto.
276+ """
277+
278+ def test_fields_map_to_correct_proto_fields (self ):
279+ """Each ChannelUpdate field targets its matching Channel proto field and mask path."""
280+ update = ChannelUpdate (
281+ display_description = "new description" ,
282+ display_unit = "volts" ,
283+ metadata = {"source" : "pytest" },
284+ active = False ,
285+ )
286+ update .resource_id = "test_channel_id"
287+
288+ proto , mask = update .to_proto_with_mask ()
289+
290+ assert proto .channel_id == "test_channel_id"
291+ assert proto .display_description == "new description"
292+ # display_unit is renamed onto the proto's display_unit_id field.
293+ assert proto .display_unit_id == "volts"
294+ assert {md .key .name : md .string_value for md in proto .metadata } == {"source" : "pytest" }
295+ assert proto .active is False
296+ assert set (mask .paths ) == {
297+ "display_description" ,
298+ "display_unit_id" ,
299+ "metadata" ,
300+ "active" ,
301+ }
0 commit comments