@@ -416,6 +416,100 @@ def test_save_updates_cache(self):
416416 # This should now contain the bridge update
417417 self .assertEqual (updates , {"bridge" : 1 })
418418
419+ def test_serialize_includes_new_field_set_to_none (self ):
420+ """Regression test for issue #708: serialize() should include fields set after init."""
421+ test_obj = Record ({"id" : 123 , "name" : "test" }, None , None )
422+ test_obj .new_field = None
423+
424+ current = test_obj .serialize ()
425+ self .assertIn ("new_field" , current )
426+ self .assertIsNone (current ["new_field" ])
427+
428+ init = test_obj .serialize (init = True )
429+ self .assertNotIn ("new_field" , init )
430+
431+ def test_serialize_includes_new_field_set_to_value (self ):
432+ """Regression test for issue #708: serialize() should include all new fields."""
433+ test_obj = Record ({"id" : 123 , "name" : "test" }, None , None )
434+ test_obj .new_string = "value"
435+ test_obj .new_int = 42
436+ test_obj .new_none = None
437+
438+ current = test_obj .serialize ()
439+ self .assertEqual (current ["new_string" ], "value" )
440+ self .assertEqual (current ["new_int" ], 42 )
441+ self .assertIsNone (current ["new_none" ])
442+
443+ init = test_obj .serialize (init = True )
444+ self .assertNotIn ("new_string" , init )
445+ self .assertNotIn ("new_int" , init )
446+ self .assertNotIn ("new_none" , init )
447+
448+ def test_diff_detects_new_field_set_to_none (self ):
449+ """Regression test for issue #708: _diff() should detect new fields."""
450+ test_obj = Record ({"id" : 123 , "name" : "test" }, None , None )
451+ test_obj .primary_mac_address = None
452+
453+ diff = test_obj ._diff ()
454+ self .assertIn ("primary_mac_address" , diff )
455+
456+ def test_updates_includes_new_field_set_to_none (self ):
457+ """Regression test for issue #708: updates() should include new fields set to None."""
458+ test_obj = Record ({"id" : 123 , "name" : "test" }, None , None )
459+ test_obj .primary_mac_address = None
460+
461+ updates = test_obj .updates ()
462+ self .assertIn ("primary_mac_address" , updates )
463+ self .assertIsNone (updates ["primary_mac_address" ])
464+
465+ def test_updates_includes_new_field_set_to_value (self ):
466+ """Regression test for issue #708: updates() should include all new fields."""
467+ test_obj = Record ({"id" : 123 , "name" : "test" }, None , None )
468+ test_obj .new_field = "new_value"
469+ test_obj .another_field = 42
470+
471+ updates = test_obj .updates ()
472+ self .assertEqual (updates ["new_field" ], "new_value" )
473+ self .assertEqual (updates ["another_field" ], 42 )
474+
475+ def test_nested_object_field_update_issue_708 (self ):
476+ """Regression test for issue #708: nested objects with limited fields."""
477+ api = Mock ()
478+ api .base_url = "http://localhost:8000/api"
479+ interface = Record (
480+ {
481+ "id" : 1 ,
482+ "name" : "eth0" ,
483+ "url" : "http://localhost:8000/api/dcim/interfaces/1/" ,
484+ },
485+ api ,
486+ None ,
487+ )
488+ interface .primary_mac_address = None
489+
490+ updates = interface .updates ()
491+ self .assertIn ("primary_mac_address" , updates )
492+ self .assertIsNone (updates ["primary_mac_address" ])
493+
494+ diff = interface ._diff ()
495+ self .assertIn ("primary_mac_address" , diff )
496+
497+ def test_serialize_excludes_internal_attributes (self ):
498+ """Ensure serialize() filters out internal Record metadata."""
499+ test_obj = Record ({"id" : 123 , "name" : "test" }, None , None )
500+
501+ serialized = test_obj .serialize ()
502+ for attr in [
503+ "api" ,
504+ "endpoint" ,
505+ "url" ,
506+ "has_details" ,
507+ "default_ret" ,
508+ "_init_cache" ,
509+ "_full_cache" ,
510+ ]:
511+ self .assertNotIn (attr , serialized )
512+
419513
420514class RecordSetTestCase (unittest .TestCase ):
421515 ids = [1 , 3 , 5 ]
0 commit comments