@@ -298,6 +298,51 @@ def test_apply_updates_existing_licenses(self, db: DatabaseTransactionFixture):
298298 assert new_license .id == old_license .id
299299 assert old_license .status == LicenseStatus .unavailable
300300
301+ def test_apply_updates_existing_license_when_removed_from_feed (
302+ self , db : DatabaseTransactionFixture , caplog
303+ ):
304+ edition , pool = db .edition (with_license_pool = True )
305+
306+ # Start with one license for this pool.
307+ existing_license = db .license (
308+ pool ,
309+ expires = None ,
310+ checkouts_left = 2 ,
311+ checkouts_available = 3 ,
312+ status = LicenseStatus .available ,
313+ )
314+
315+ assert isinstance (existing_license .identifier , str )
316+ assert existing_license .checkouts_left == 2
317+ assert existing_license .checkouts_available == 3
318+ assert existing_license .status == LicenseStatus .available
319+
320+ # The feed does not include the license
321+ circulation_data = CirculationData (
322+ licenses = [], # No licenses in the updated feed
323+ data_source = edition .data_source ,
324+ primary_identifier = edition .primary_identifier ,
325+ )
326+ with caplog .at_level ("WARNING" ):
327+ circulation_data .apply (db .session , pool .collection )
328+ db .session .commit ()
329+
330+ updated_license = pool .licenses [0 ]
331+ assert updated_license .id == existing_license .id
332+ assert (
333+ updated_license .status == LicenseStatus .unavailable
334+ ) # Status should have changed
335+ assert (
336+ updated_license .checkouts_left == 2
337+ ) # Checkouts left should remain unchanged.
338+ assert (
339+ updated_license .checkouts_available == 3
340+ ) # Checkouts available should remain unchanged.
341+ assert (
342+ f"License { existing_license .identifier } has been removed from feed"
343+ in caplog .text
344+ )
345+
301346 def test_apply_with_licenses_overrides_availability (
302347 self , db : DatabaseTransactionFixture
303348 ):
0 commit comments