11from typing import Dict
2- from pydantic import ValidationError
32
43import pytest
4+ from pydantic import ValidationError
5+
56from suzieq .poller .controller .credential_loader .static import (StaticLoader ,
67 StaticModel )
78from tests .unit .poller .shared .utils import read_yaml_file
@@ -84,30 +85,38 @@ def test_variables_init(monkeypatch):
8485 """
8586 ask_password = 'ask_password'
8687 env_password = 'env_password'
88+ ask_username = 'ask_username'
89+ env_username = 'env_username'
8790 plain_passphrase = 'my-pass'
8891
8992 # 'env' and 'plain' values
9093 init_data = {
9194 'name' : 'n' ,
95+ 'username' : 'env:SUZIEQ_ENV_USERNAME' ,
9296 'key-passphrase' : f'plain:{ plain_passphrase } ' ,
9397 'password' : 'env:SUZIEQ_ENV_PASSWORD'
9498 }
9599 monkeypatch .setenv ('SUZIEQ_ENV_PASSWORD' , env_password )
100+ monkeypatch .setenv ('SUZIEQ_ENV_USERNAME' , env_username )
96101 sl = StaticModel (** init_data )
97102
98103 assert sl .key_passphrase == plain_passphrase
99104 assert sl .password == env_password
105+ assert sl .username == env_username
100106
101107 # 'ask' values
102108 init_data = {
103109 'name' : 'n' ,
110+ 'username' : 'ask' ,
104111 'password' : 'ask'
105112 }
106113 valid_data = StaticModel (** init_data ).dict (by_alias = True )
107- monkeypatch .setattr ('getpass.getpass' , lambda x : ask_password )
114+ mock_get_pass = MockGetPass ([ask_username , ask_password ])
115+ monkeypatch .setattr ('getpass.getpass' , mock_get_pass )
108116 sl = StaticLoader (valid_data )
109117
110118 assert sl ._data .password == ask_password
119+ assert sl ._data .username == ask_username
111120
112121 # unknown parameter
113122 init_data = {
@@ -117,3 +126,40 @@ def test_variables_init(monkeypatch):
117126 }
118127 with pytest .raises (ValidationError ):
119128 StaticModel (** init_data )
129+
130+
131+ class MockGetPass :
132+ """
133+ Mocks `getpass.getpass` for testing, cycling through a list of predefined
134+ responses.
135+
136+ Attributes:
137+ responses (list): A list of responses to simulate sequential user inputs.
138+ call_count (int): Tracks calls to provide the next response in the list.
139+ """
140+
141+ def __init__ (self , responses : list ):
142+ """
143+ Initializes the mock with responses and resets call count.
144+
145+ Args:
146+ responses: Simulated user inputs.
147+ """
148+ self .responses = responses
149+ self .call_count = 0
150+
151+ def __call__ (self , prompt = '' ):
152+ """
153+ Returns the next response from the list, mimicking user input.
154+
155+ Args:
156+ prompt: Unused, present for compatibility.
157+
158+ Returns:
159+ The next simulated user input.
160+ """
161+ response = self .responses [self .call_count ]
162+ self .call_count += 1
163+ if self .call_count >= len (self .responses ):
164+ self .call_count = 0
165+ return response
0 commit comments