3030from adsrefpipe .refparsers .handler import verify
3131from adsrefpipe .tests .unittests .stubdata .dbdata import actions_records , parsers_records
3232
33+ import testing .postgresql
34+
35+ def _get_external_identifier (rec ):
36+ """
37+ Works whether rec is a dict (bulk mappings) or an ORM object.
38+ """
39+ if rec is None :
40+ return []
41+ if isinstance (rec , dict ):
42+ return rec .get ("external_identifier" ) or []
43+ return getattr (rec , "external_identifier" , None ) or []
3344
3445class TestDatabase (unittest .TestCase ):
3546
@@ -39,18 +50,13 @@ class TestDatabase(unittest.TestCase):
3950
4051 maxDiff = None
4152
42- postgresql_url_dict = {
43- 'port' : 5432 ,
44- 'host' : '127.0.0.1' ,
45- 'user' : 'postgres' ,
46- 'database' : 'postgres'
47- }
48- postgresql_url = 'postgresql://{user}:{user}@{host}:{port}/{database}' \
49- .format (user = postgresql_url_dict ['user' ],
50- host = postgresql_url_dict ['host' ],
51- port = postgresql_url_dict ['port' ],
52- database = postgresql_url_dict ['database' ]
53- )
53+ _postgresql = testing .postgresql .Postgresql ()
54+ postgresql_url = _postgresql .url ()
55+
56+ @classmethod
57+ def tearDownClass (cls ):
58+ super ().tearDownClass ()
59+ cls ._postgresql .stop ()
5460
5561 def setUp (self ):
5662 self .test_dir = os .path .join (project_home , 'adsrefpipe/tests' )
@@ -88,16 +94,22 @@ def add_stub_data(self):
8894
8995 resolved_reference = [
9096 [
91- ('J.-P. Uzan, Varying constants, gravitation and cosmology, Living Rev. Rel. 14 (2011) 2, [1009.5514]. ' ,'2011LRR....14....2U' ,1.0 ),
92- ('C. J. A. P. Martins, The status of varying constants: A review of the physics, searches and implications, 1709.02923.' ,'2017RPPh...80l6902M' ,1.0 )
97+ ('J.-P. Uzan, Varying constants, gravitation and cosmology, Living Rev. Rel. 14 (2011) 2, [1009.5514]. ' ,
98+ '2011LRR....14....2U' , 1.0 , ['arxiv:1009.5514' ]),
99+ ('C. J. A. P. Martins, The status of varying constants: A review of the physics, searches and implications, 1709.02923.' ,
100+ '2017RPPh...80l6902M' , 1.0 , ['arxiv:1709.02923' ])
93101 ],
94102 [
95- ('Alsubai, K. A., Parley, N. R., Bramich, D. M., et al. 2011, MNRAS, 417, 709.' ,'2011MNRAS.417..709A' ,1.0 ),
96- ('Arcangeli, J., Desert, J.-M., Parmentier, V., et al. 2019, A&A, 625, A136 ' ,'2019A&A...625A.136A' ,1.0 )
103+ ('Alsubai, K. A., Parley, N. R., Bramich, D. M., et al. 2011, MNRAS, 417, 709.' ,
104+ '2011MNRAS.417..709A' , 1.0 , ['doi:10.0000/mnras.417.709' ]),
105+ ('Arcangeli, J., Desert, J.-M., Parmentier, V., et al. 2019, A&A, 625, A136 ' ,
106+ '2019A&A...625A.136A' , 1.0 , ['doi:10.0000/aa.625.A136' ])
97107 ],
98108 [
99- ('Abellan, F. J., Indebetouw, R., Marcaide, J. M., et al. 2017, ApJL, 842, L24' ,'2017ApJ...842L..24A' ,1.0 ),
100- ('Ackermann, M., Albert, A., Atwood, W. B., et al. 2016, A&A, 586, A71 ' ,'2016A&A...586A..71A' ,1.0 )
109+ ('Abellan, F. J., Indebetouw, R., Marcaide, J. M., et al. 2017, ApJL, 842, L24' ,
110+ '2017ApJ...842L..24A' , 1.0 , ['ascl:1701.001' ]),
111+ ('Ackermann, M., Albert, A., Atwood, W. B., et al. 2016, A&A, 586, A71 ' ,
112+ '2016A&A...586A..71A' , 1.0 , ['doi:10.0000/aa.586.A71' ])
101113 ],
102114 ]
103115
@@ -117,8 +129,13 @@ def add_stub_data(self):
117129 ]
118130
119131 with self .app .session_scope () as session :
120- session .bulk_save_objects (actions_records )
121- session .bulk_save_objects (parsers_records )
132+ session .query (Action ).delete ()
133+ session .query (Parser ).delete ()
134+ session .commit ()
135+ if session .query (Action ).count () == 0 :
136+ session .bulk_save_objects (actions_records )
137+ if session .query (Parser ).count () == 0 :
138+ session .bulk_save_objects (parsers_records )
122139 session .commit ()
123140
124141 for i , (a_reference ,a_history ) in enumerate (zip (reference_source ,processed_history )):
@@ -453,9 +470,22 @@ def test_populate_tables_post_resolved_with_classic(self):
453470 """ test populate_tables_post_resolved when resolved_classic is available """
454471
455472 resolved_reference = [
456- {'id' : 'H1I1' , 'refstring' : 'Reference 1' , 'bibcode' : '2023A&A...657A...1X' , 'score' : 1.0 },
457- {'id' : 'H1I2' , 'refstring' : 'Reference 2' , 'bibcode' : '2023A&A...657A...2X' , 'score' : 0.8 }
473+ {
474+ 'id' : 'H1I1' ,
475+ 'refstring' : 'Reference 1' ,
476+ 'bibcode' : '2023A&A...657A...1X' ,
477+ 'score' : 1.0 ,
478+ 'external_identifier' : ['doi:10.1234/abc' , 'arxiv:2301.00001' ],
479+ },
480+ {
481+ 'id' : 'H1I2' ,
482+ 'refstring' : 'Reference 2' ,
483+ 'bibcode' : '2023A&A...657A...2X' ,
484+ 'score' : 0.8 ,
485+ 'external_identifier' : ['ascl:2301.001' , 'doi:10.9999/xyz' ],
486+ }
458487 ]
488+
459489 source_bibcode = "2023A&A...657A...1X"
460490 classic_resolved_filename = "classic_results.txt"
461491 classic_resolved_reference = [
@@ -476,6 +506,12 @@ def test_populate_tables_post_resolved_with_classic(self):
476506 mock_insert .assert_called_once ()
477507 mock_logger .assert_called_with ("Updated 2 resolved reference records successfully." )
478508
509+ # Check whether external_identifier is populated with correct data
510+ _ , resolved_records = mock_update .call_args [0 ]
511+ self .assertEqual (len (resolved_records ), 2 )
512+ self .assertEqual (_get_external_identifier (resolved_records [0 ]), ['doi:10.1234/abc' , 'arxiv:2301.00001' ])
513+ self .assertEqual (_get_external_identifier (resolved_records [1 ]), ['ascl:2301.001' , 'doi:10.9999/xyz' ])
514+
479515 @patch ("adsrefpipe.app.ProcessedHistory" )
480516 @patch ("adsrefpipe.app.ResolvedReference" )
481517 @patch ("adsrefpipe.app.CompareClassic" )
@@ -745,18 +781,13 @@ class TestDatabaseNoStubdata(unittest.TestCase):
745781
746782 maxDiff = None
747783
748- postgresql_url_dict = {
749- 'port' : 5432 ,
750- 'host' : '127.0.0.1' ,
751- 'user' : 'postgres' ,
752- 'database' : 'postgres'
753- }
754- postgresql_url = 'postgresql://{user}:{user}@{host}:{port}/{database}' \
755- .format (user = postgresql_url_dict ['user' ],
756- host = postgresql_url_dict ['host' ],
757- port = postgresql_url_dict ['port' ],
758- database = postgresql_url_dict ['database' ]
759- )
784+ _postgresql = testing .postgresql .Postgresql ()
785+ postgresql_url = _postgresql .url ()
786+
787+ @classmethod
788+ def tearDownClass (cls ):
789+ super ().tearDownClass ()
790+ cls ._postgresql .stop ()
760791
761792 def setUp (self ):
762793 self .test_dir = os .path .join (project_home , 'adsrefpipe/tests' )
@@ -805,26 +836,36 @@ def test_populate_tables(self):
805836 "refraw" : "C. J. A. P. Martins, The status of varying constants: A review of the physics, searches and implications, 1709.02923." ,
806837 "id" : "H1I2" }
807838 ]
839+
840+ # IMPORTANT: use the real column name expected by app/models: external_identifier (list)
808841 resolved_references = [
809842 {
810843 "score" : "1.0" ,
811844 "bibcode" : "2011LRR....14....2U" ,
812845 "refstring" : "J.-P. Uzan, Varying constants, gravitation and cosmology, Living Rev. Rel. 14 (2011) 2, [1009.5514]. " ,
813846 "refraw" : "J.-P. Uzan, Varying constants, gravitation and cosmology, Living Rev. Rel. 14 (2011) 2, [1009.5514]. " ,
814- "id" : "H1I1"
847+ "id" : "H1I1" ,
848+ "external_identifier" : ["arxiv:1009.5514" , "doi:10.1234/abc" ]
815849 },
816850 {
817851 "score" : "1.0" ,
818852 "bibcode" : "2017RPPh...80l6902M" ,
819853 "refstring" : "C. J. A. P. Martins, The status of varying constants: A review of the physics, searches and implications, 1709.02923." ,
820854 "refraw" : "C. J. A. P. Martins, The status of varying constants: A review of the physics, searches and implications, 1709.02923." ,
821855 "id" : "H1I2" ,
856+ "external_identifier" : ["arxiv:1709.02923" , "ascl:2301.001" ]
822857 }
823858 ]
859+
824860 arXiv_stubdata_dir = os .path .join (self .test_dir , 'unittests/stubdata/txt/arXiv/0/' )
825861 with self .app .session_scope () as session :
826- session .bulk_save_objects (actions_records )
827- session .bulk_save_objects (parsers_records )
862+ session .query (Action ).delete ()
863+ session .query (Parser ).delete ()
864+ session .commit ()
865+ if session .query (Action ).count () == 0 :
866+ session .bulk_save_objects (actions_records )
867+ if session .query (Parser ).count () == 0 :
868+ session .bulk_save_objects (parsers_records )
828869 session .commit ()
829870
830871 references = self .app .populate_tables_pre_resolved_initial_status (
@@ -842,6 +883,20 @@ def test_populate_tables(self):
842883 classic_resolved_filename = os .path .join (arXiv_stubdata_dir , '00001.raw.result' ))
843884 self .assertTrue (status == True )
844885
886+ # Verify external_identifier was persisted on ResolvedReference rows
887+ # We know history_id should be 1 for the first inserted ProcessedHistory in an empty DB.
888+ rows = (
889+ session .query (ResolvedReference )
890+ .filter (ResolvedReference .history_id == 1 )
891+ .order_by (ResolvedReference .item_num .asc ())
892+ .all ()
893+ )
894+ self .assertEqual (len (rows ), 2 )
895+ self .assertEqual (rows [0 ].item_num , 1 )
896+ self .assertEqual (rows [1 ].item_num , 2 )
897+ self .assertEqual (rows [0 ].external_identifier , ["arxiv:1009.5514" , "doi:10.1234/abc" ])
898+ self .assertEqual (rows [1 ].external_identifier , ["arxiv:1709.02923" , "ascl:2301.001" ])
899+
845900 def test_get_parser_error (self ):
846901 """ test get_parser when it errors for unrecognized source filename """
847902 with patch .object (self .app .logger , 'error' ) as mock_error :
@@ -851,3 +906,4 @@ def test_get_parser_error(self):
851906
852907if __name__ == '__main__' :
853908 unittest .main ()
909+
0 commit comments