1- """Unit tests for updater.components """
1+ """Unit tests for updater.components"""
2+
23import logging
3- import pytest
4+ from os . path import commonpath
45from pathlib import Path
56from unittest .mock import patch , mock_open
67
7- from updater .components import (
8- ComponentConfig , ComponentStatus , load_components
9- )
8+ from updater .components import load_components
109
1110BUNDLE_YAML = """
12- pool_internal_minutes: 30
11+ poll_interval_minutes: 1440
1312components:
1413 - name: klipper
15- - type: git
16- - path: ~/klipper
17- - service: klipper.service
18- - reset_mode: hard
19- - order: 1
20- - name: BlocksScreen
21- - type: git
22- - path: ~/BlocksScreen
23- - service: BlocksScreen.service
24- - reset_mode: hard
25- - order: 99
14+ type: git
15+ path: ~/klipper
16+ service: klipper.service
17+ reset_mode: hard
18+ order: 1
19+ - name: blockscreen
20+ type: git
21+ path: ~/BlocksScreen
22+ service: BlocksScreen.service
23+ reset_mode: hard
24+ order: 99
2625"""
2726
2827OVERRIDE_YAML = """
3736 order: 5
3837"""
3938
39+
4040def _mock_load (bundled : str , override : str | None = None ):
4141 import updater .components as mod
42+
4243 bundled_path = Path (mod .__file__ ).parent / "components.yaml"
4344
4445 def fake_open (path , * a , ** kw ):
4546 if Path (path ) == bundled_path :
4647 return mock_open (read_data = bundled )()
4748 if override is not None :
4849 return mock_open (read_data = override )()
49- raise FileNotFoundError (Path )
50+ raise FileNotFoundError (path )
51+
5052 return fake_open
5153
5254
5355class TestLoadComponents :
5456 def test_load_return_sorted_by_order (self ):
55- with patch ("builtins.open" , _mock_load (BUNDLE_YAML )), patch ("pathlib.Path.exists" , return_value = False ), patch ("pathlib.Path.is_dir" , return_value = True ):
56- components = load_components ()
57+ with (
58+ patch ("builtins.open" , _mock_load (BUNDLE_YAML )),
59+ patch ("pathlib.Path.exists" , return_value = False ),
60+ patch ("pathlib.Path.is_dir" , return_value = True ),
61+ ):
62+ components = load_components ()
5763 names = [c .name for c in components ]
58- assert names .index ("klipper" ) < names .index ("BlocksScreen " )
59-
64+ assert names .index ("klipper" ) < names .index ("blockscreen " )
65+
6066 def test_missing_override_file_silently_ignored (self ):
61- with patch ("builtins.open" , _mock_load (BUNDLE_YAML )), patch ("pathlib.Path.exists" , return_value = False ), patch ("pathlib.Path.is_dir" , return_value = True ):
67+ with (
68+ patch ("builtins.open" , _mock_load (BUNDLE_YAML )),
69+ patch ("pathlib.Path.exists" , return_value = False ),
70+ patch ("pathlib.Path.is_dir" , return_value = True ),
71+ ):
6272 components = load_components ()
6373 assert len (components ) >= 2
6474
75+
6576class TestYamlMerge :
66- def test_ovvrides_path_by_name (self ):
67- with patch ("builtins.open" , _mock_load (BUNDLE_YAML )), patch ("pathlib.Path.exists" , return_value = True ), patch ("pathlib.Path.is_dir" , return_value = True ):
77+ def test_overrides_path_by_name (self ):
78+ with (
79+ patch ("builtins.open" , _mock_load (BUNDLE_YAML , OVERRIDE_YAML )),
80+ patch ("pathlib.Path.exists" , return_value = True ),
81+ patch ("pathlib.Path.is_dir" , return_value = True ),
82+ ):
6883 components = load_components ()
6984 klipper = next (c for c in components if c .name == "klipper" )
7085 assert str (klipper .path ).endswith ("costum_klipper" )
7186 assert klipper .service == "klipper.service"
7287
73- def test_appends_new_componentself (self ):
74- with patch ("builtins.open" , _mock_load (BUNDLE_YAML , OVERRIDE_YAML )), patch ("pathlib.Path.exists" , return_value = True ), patch ("pathlib.Path.is_dir" , return_value = True ):
88+ def test_appends_new_component (self ):
89+ with (
90+ patch ("builtins.open" , _mock_load (BUNDLE_YAML , OVERRIDE_YAML )),
91+ patch ("pathlib.Path.exists" , return_value = True ),
92+ patch ("pathlib.Path.is_dir" , return_value = True ),
93+ ):
7594 components = load_components ()
7695 assert any (c .name == "my-plugin" for c in components )
96+
7797 def test_keeps_bundled_fields_not_in_override (self ):
78- with patch ("builtins.open" , _mock_load (BUNDLE_YAML , OVERRIDE_YAML )), patch ("pathlib.Path.exists" , return_value = True ), patch ("pathlib.Path.is_dir" , return_value = True ):
98+ with (
99+ patch ("builtins.open" , _mock_load (BUNDLE_YAML , OVERRIDE_YAML )),
100+ patch ("pathlib.Path.exists" , return_value = True ),
101+ patch ("pathlib.Path.is_dir" , return_value = True ),
102+ ):
79103 components = load_components ()
80104 klipper = next (c for c in components if c .name == "klipper" )
81- assert klipper .type == "git"
105+ assert klipper .kind == "git"
82106 assert klipper .reset_mode == "hard"
83107
84108 def test_syntax_error_falls_back_to_bundled (self , caplog ):
85- with patch ("builtins.open" , _mock_load (BUNDLE_YAML , OVERRIDE_YAML )), patch ("pathlib.Path.exists" , return_value = True ), patch ("pathlib.Path.is_dir" , return_value = True ), \
86- caplog .at_level (logging .ERROR , logger = "updater.components" ):
109+ invalid_yaml = "key: [unclosed"
110+ with (
111+ patch ("builtins.open" , _mock_load (BUNDLE_YAML , invalid_yaml )),
112+ patch ("pathlib.Path.exists" , return_value = True ),
113+ patch ("pathlib.Path.is_dir" , return_value = True ),
114+ caplog .at_level (logging .ERROR , logger = "updater.components" ),
115+ ):
87116 components = load_components ()
88117 names = [c .name for c in components ]
89118 assert "klipper" in names
@@ -100,9 +129,11 @@ def test_invalid_component_skipped_with_warning(self, caplog):
100129 service: bad.service
101130 order: 10
102131"""
103- with patch ("builtins.open" , _mock_load (bad_yaml )), \
104- patch ("pathlib.Path.exists" , return_value = True ), \
105- caplog .at_level (logging .WARNING , logger = "updater.components" ):
132+ with (
133+ patch ("builtins.open" , _mock_load (bad_yaml )),
134+ patch ("pathlib.Path.exists" , return_value = True ),
135+ caplog .at_level (logging .WARNING , logger = "updater.components" ),
136+ ):
106137 components = load_components ()
107138 assert not any (c .name == "bad" for c in components )
108139 assert any ("bad" in r .message for r in caplog .records )
@@ -116,8 +147,10 @@ def test_path_outside_home_rejected(self):
116147 service: outside.service
117148 order: 10
118149"""
119- with patch ("builtins.open" , _mock_load (outside_yaml )), \
120- patch ("pathlib.Path.exists" , return_value = False ):
150+ with (
151+ patch ("builtins.open" , _mock_load (outside_yaml )),
152+ patch ("pathlib.Path.exists" , return_value = False ),
153+ ):
121154 components = load_components ()
122155 assert not any (c .name == "outside" for c in components )
123156
@@ -130,25 +163,31 @@ def test_service_name_with_slash_rejected(self):
130163 service: ../bad.service
131164 order: 10
132165"""
133- with patch ("builtins.open" , _mock_load (bad_yaml )), \
134- patch ("pathlib.Path.exists" , return_value = False ):
166+ with (
167+ patch ("builtins.open" , _mock_load (bad_yaml )),
168+ patch ("pathlib.Path.exists" , return_value = False ),
169+ ):
135170 components = load_components ()
136- assert not any (c .name == "evil " for c in components )
171+ assert not any (c .name == "bad " for c in components )
137172
138173 def test_service_name_with_shell_metachar_rejected (self ):
139174 for metachar in [";" , "&" , "|" , "$" , "`" ]:
140175 bad_yaml = f"""
141176components:
142- - name: bad
143- type: git
144- path: ~/bad
145- service: bad{ metachar } cmd.service
146- order: 10
177+ - name: bad
178+ type: git
179+ path: ~/bad
180+ service: bad{ metachar } cmd.service
181+ order: 10
147182"""
148- with patch ("builtins.open" , _mock_load (bad_yaml )), \
149- patch ("pathlib.Path.exists" , return_value = False ):
183+ with (
184+ patch ("builtins.open" , _mock_load (bad_yaml )),
185+ patch ("pathlib.Path.exists" , return_value = False ),
186+ ):
150187 components = load_components ()
151- assert not any (c .name == "bad" for c in components ), f"metachar { metachar !r} not rejected"
188+ assert not any (c .name == "bad" for c in components ), (
189+ f"metachar { metachar !r} not rejected"
190+ )
152191
153192 def test_service_name_valid_pattern_accepted (self ):
154193 good_yaml = """
@@ -159,9 +198,10 @@ def test_service_name_valid_pattern_accepted(self):
159198 service: my-plugin.service
160199 order: 5
161200"""
162- with patch ("builtins.open" , _mock_load (good_yaml )), \
163- patch ("pathlib.Path.exists" , return_value = False ), \
164- patch ("pathlib.Path.is_dir" , return_value = True ):
201+ with (
202+ patch ("builtins.open" , _mock_load (good_yaml )),
203+ patch ("pathlib.Path.exists" , return_value = False ),
204+ patch ("pathlib.Path.is_dir" , return_value = True ),
205+ ):
165206 components = load_components ()
166207 assert any (c .name == "my-plugin" for c in components )
167-
0 commit comments