Skip to content

Commit beee6fc

Browse files
authored
Merge pull request #64 from eman/fix/remove-strict-token-check-in-init
fix: Remove stale token check from NavienMqttClient.__init__()
2 parents 47eaa19 + ba5f648 commit beee6fc

2 files changed

Lines changed: 49 additions & 44 deletions

File tree

src/nwp500/mqtt/client.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -150,20 +150,21 @@ def __init__(
150150
- None: Auto-detect from device (default)
151151
152152
Raises:
153-
MqttCredentialsError: If auth client is not authenticated, tokens
154-
are stale/expired, or AWS credentials are not available
153+
MqttCredentialsError: If auth client is not authenticated or AWS
154+
credentials are not available
155155
"""
156156
if not auth_client.is_authenticated:
157157
raise MqttCredentialsError(
158158
"Authentication client must be authenticated before "
159159
"creating MQTT client. Call auth_client.sign_in() first."
160160
)
161161

162-
if not auth_client.has_valid_tokens:
163-
raise MqttCredentialsError(
164-
"Tokens are stale/expired. "
165-
"Call ensure_valid_token() or re_authenticate() first."
166-
)
162+
# Token validity is checked in connect() which also refreshes stale
163+
# tokens automatically. This allows creating MQTT clients with
164+
# restored tokens that may have expired between sessions. Token
165+
# validation and refresh are deferred until connect() is called; if
166+
# connect() is never called, tokens are not revalidated/refreshed
167+
# and no MQTT connection is established.
167168

168169
if not auth_client.current_tokens:
169170
raise MqttCredentialsError("No tokens available from auth client")

tests/test_mqtt_client_init.py

Lines changed: 41 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -108,44 +108,40 @@ def test_mqtt_client_init_rejects_not_authenticated(
108108

109109
assert "must be authenticated" in str(exc_info.value).lower()
110110

111-
def test_mqtt_client_init_rejects_expired_jwt(
111+
def test_mqtt_client_init_accepts_expired_jwt(
112112
self, auth_client_with_expired_jwt
113113
):
114-
"""Test MQTT client rejects auth client with expired JWT tokens."""
115-
with pytest.raises(MqttCredentialsError) as exc_info:
116-
NavienMqttClient(auth_client_with_expired_jwt)
114+
"""Test MQTT client can be created with expired JWT tokens.
117115
118-
error_msg = str(exc_info.value).lower()
119-
assert "stale/expired" in error_msg
120-
assert (
121-
"ensure_valid_token" in error_msg or "re_authenticate" in error_msg
122-
)
116+
Token refresh happens in connect(), not in __init__().
117+
"""
118+
# Should not raise - token refresh happens during connect()
119+
mqtt_client = NavienMqttClient(auth_client_with_expired_jwt)
120+
assert mqtt_client is not None
121+
assert not mqtt_client.is_connected
123122

124-
def test_mqtt_client_init_rejects_expired_aws_credentials(
123+
def test_mqtt_client_init_accepts_expired_aws_credentials(
125124
self, auth_client_with_expired_aws_credentials
126125
):
127-
"""Test MQTT client rejects auth client with expired AWS credentials."""
128-
with pytest.raises(MqttCredentialsError) as exc_info:
129-
NavienMqttClient(auth_client_with_expired_aws_credentials)
126+
"""Test MQTT client can be created with expired AWS credentials.
130127
131-
error_msg = str(exc_info.value).lower()
132-
assert "stale/expired" in error_msg
133-
assert (
134-
"ensure_valid_token" in error_msg or "re_authenticate" in error_msg
135-
)
128+
Token refresh happens in connect(), not in __init__().
129+
"""
130+
# Should not raise - token refresh happens during connect()
131+
mqtt_client = NavienMqttClient(auth_client_with_expired_aws_credentials)
132+
assert mqtt_client is not None
133+
assert not mqtt_client.is_connected
136134

137-
def test_mqtt_client_init_error_message_guidance(
135+
def test_mqtt_client_init_accepts_expired_tokens_without_error(
138136
self, auth_client_with_expired_jwt
139137
):
140-
"""Test MQTT client init error provides clear guidance on recovery."""
141-
with pytest.raises(MqttCredentialsError) as exc_info:
142-
NavienMqttClient(auth_client_with_expired_jwt)
138+
"""Test MQTT client accepts expired tokens without error.
143139
144-
error_msg = str(exc_info.value)
145-
# Should mention recovery methods
146-
assert (
147-
"ensure_valid_token" in error_msg or "re_authenticate" in error_msg
148-
), f"Error message should mention recovery methods: {error_msg}"
140+
Token validation moved to connect() which handles refresh automatically.
141+
"""
142+
# Should not raise any error about stale/expired tokens
143+
mqtt_client = NavienMqttClient(auth_client_with_expired_jwt)
144+
assert mqtt_client is not None
149145

150146

151147
class TestHasValidTokensProperty:
@@ -195,12 +191,16 @@ def test_has_valid_tokens_true_with_no_aws_expiration(self):
195191
# Should be True: JWT valid and AWS credentials have no expiration
196192
assert auth_client.has_valid_tokens is True
197193

198-
def test_has_valid_tokens_integration_with_mqtt_init(
194+
def test_mqtt_client_creation_succeeds_with_valid_tokens(
199195
self, auth_client_with_valid_tokens
200196
):
201-
"""Test that has_valid_tokens integrates correctly with MQTT init."""
202-
# When has_valid_tokens is True, MQTT init should succeed
203-
assert auth_client_with_valid_tokens.has_valid_tokens is True
197+
"""Test that MQTT client creation succeeds with valid tokens.
198+
199+
Verifies MQTT client can be created successfully when auth_client has
200+
valid tokens. Token validation is deferred to connect().
201+
"""
202+
# MQTT init should succeed regardless of token validity
203+
# Token validation is deferred to connect()
204204
mqtt_client = NavienMqttClient(auth_client_with_valid_tokens)
205205
assert mqtt_client is not None
206206

@@ -475,7 +475,11 @@ class TestTokenValidationEdgeCases:
475475
"""Test edge cases in token validation."""
476476

477477
def test_expired_jwt_near_expiry_buffer(self):
478-
"""Test token considered expired within 5-minute buffer."""
478+
"""Test token considered expired within 5-minute buffer.
479+
480+
MQTT init no longer rejects expired tokens since validation
481+
happens in connect().
482+
"""
479483
auth_client = NavienAuthClient("test@example.com", "password")
480484
# Token expires in 3 minutes - should be considered expired
481485
near_expiry = datetime.now() - timedelta(seconds=3420)
@@ -497,11 +501,11 @@ def test_expired_jwt_near_expiry_buffer(self):
497501
assert tokens.is_expired is True
498502
assert auth_client.has_valid_tokens is False
499503

500-
# MQTT init should reject it
501-
with pytest.raises(MqttCredentialsError) as exc_info:
502-
NavienMqttClient(auth_client)
503-
504-
assert "stale/expired" in str(exc_info.value).lower()
504+
# MQTT init should NOT reject it - token validation moved to
505+
# connect()
506+
mqtt_client = NavienMqttClient(auth_client)
507+
assert mqtt_client is not None
508+
assert not mqtt_client.is_connected
505509

506510
def test_multiple_validation_checks_mqtt_init(
507511
self, auth_client_with_valid_tokens

0 commit comments

Comments
 (0)