@@ -152,3 +152,119 @@ def capturing_put(**kwargs):
152152
153153 item = captured ["Item" ]
154154 assert "expiration" in item , "open item must carry a DynamoDB TTL attribute"
155+
156+
157+ # --------------------------------------------------------------------------- serialization coverage
158+
159+
160+ def test_item_to_record_full_item (persistence ):
161+ """Cover _item_to_record with all fields present (lines 109-122)."""
162+ item = {
163+ "id" : {"S" : "payment" },
164+ "state" : {"S" : "HALF_OPEN" },
165+ "failure_count" : {"N" : "3" },
166+ "opened_at" : {"N" : "1000" },
167+ "half_open_owner" : {"S" : "env-x" },
168+ "probe_lease_expiry" : {"N" : "2000" },
169+ "expiration" : {"N" : "9999" },
170+ }
171+ record = persistence ._item_to_record (item )
172+ assert record .name == "payment"
173+ assert record .state == CircuitState .HALF_OPEN
174+ assert record .failure_count == 3
175+ assert record .opened_at == 1000
176+ assert record .half_open_owner == "env-x"
177+ assert record .probe_lease_expiry == 2000
178+ assert record .expiry_timestamp == 9999
179+
180+
181+ def test_item_to_record_minimal_item (persistence ):
182+ """Cover _item_to_record with optional fields absent."""
183+ item = {
184+ "id" : {"S" : "payment" },
185+ "state" : {"S" : "CLOSED" },
186+ }
187+ record = persistence ._item_to_record (item )
188+ assert record .name == "payment"
189+ assert record .state == CircuitState .CLOSED
190+ assert record .failure_count == 0
191+ assert record .opened_at is None
192+ assert record .half_open_owner is None
193+ assert record .probe_lease_expiry is None
194+
195+
196+ def test_record_to_item_full_record (persistence ):
197+ """Cover _record_to_item with all fields set (lines 124-139)."""
198+ from aws_lambda_powertools .utilities .circuit_breaker_alpha .persistence .record import CircuitStateRecord
199+
200+ record = CircuitStateRecord (
201+ name = "payment" ,
202+ state = CircuitState .HALF_OPEN ,
203+ failure_count = 5 ,
204+ opened_at = 1000 ,
205+ half_open_owner = "env-a" ,
206+ probe_lease_expiry = 2000 ,
207+ expiry_timestamp = 9999 ,
208+ )
209+ item = persistence ._record_to_item (record )
210+ assert item ["id" ] == {"S" : "payment" }
211+ assert item ["state" ] == {"S" : "HALF_OPEN" }
212+ assert item ["failure_count" ] == {"N" : "5" }
213+ assert item ["opened_at" ] == {"N" : "1000" }
214+ assert item ["half_open_owner" ] == {"S" : "env-a" }
215+ assert item ["probe_lease_expiry" ] == {"N" : "2000" }
216+ assert item ["expiration" ] == {"N" : "9999" }
217+
218+
219+ def test_record_to_item_minimal_record (persistence ):
220+ """Cover _record_to_item with optional fields as None (branch misses on lines 131-137)."""
221+ from aws_lambda_powertools .utilities .circuit_breaker_alpha .persistence .record import CircuitStateRecord
222+
223+ record = CircuitStateRecord (name = "payment" , state = CircuitState .CLOSED )
224+ item = persistence ._record_to_item (record )
225+ assert item == {
226+ "id" : {"S" : "payment" },
227+ "state" : {"S" : "CLOSED" },
228+ "failure_count" : {"N" : "0" },
229+ }
230+ assert "opened_at" not in item
231+ assert "half_open_owner" not in item
232+ assert "probe_lease_expiry" not in item
233+ assert "expiration" not in item
234+
235+
236+ def test_get_record_returns_deserialized_item (persistence ):
237+ """Cover _get_record success path (lines 141-153)."""
238+ stubber = Stubber (persistence .client )
239+ stubber .add_response (
240+ "get_item" ,
241+ {
242+ "Item" : {
243+ "id" : {"S" : "payment" },
244+ "state" : {"S" : "OPEN" },
245+ "failure_count" : {"N" : "5" },
246+ "opened_at" : {"N" : "1000" },
247+ },
248+ },
249+ {"TableName" : TABLE_NAME , "Key" : {"id" : {"S" : "payment" }}, "ConsistentRead" : False },
250+ )
251+ with stubber :
252+ record = persistence ._get_record ("payment" )
253+ assert record .state == CircuitState .OPEN
254+ assert record .failure_count == 5
255+ assert record .opened_at == 1000
256+
257+
258+ def test_build_half_open_condition_without_expected_opened_at (persistence ):
259+ """Cover _build_half_open_condition when expected_opened_at is None (line 172 branch)."""
260+ result = persistence ._build_half_open_condition (expected_opened_at = None )
261+ assert ":expected_opened_at" not in result ["ConditionExpression" ]
262+ assert "#opened_at" not in result ["ExpressionAttributeNames" ]
263+
264+
265+ def test_build_half_open_condition_with_expected_opened_at (persistence ):
266+ """Cover _build_half_open_condition when expected_opened_at is set (lines 172-177)."""
267+ result = persistence ._build_half_open_condition (expected_opened_at = 5000 )
268+ assert "#opened_at = :expected_opened_at" in result ["ConditionExpression" ]
269+ assert result ["ExpressionAttributeNames" ]["#opened_at" ] == "opened_at"
270+ assert result ["ExpressionAttributeValues" ][":expected_opened_at" ] == {"N" : "5000" }
0 commit comments