Best Python code snippet using localstack_python
test_perseus_import.py
Source:test_perseus_import.py  
...13        author = Author()14        author.name = "Flavius Josephus"15        author.save()16        17        book_xml = self.load_test_resource('j.vit_gk_portion.xml')18        book_doc = parseString(book_xml)19        self.importer.import_xml_document(book_doc)20        21        self.assertEqual(self.importer.get_title_slug("josephi-vita"), ("josephi-vita-1" , True))22    23    def test_bibl_struct_import(self):24        25        bibl_struct_xml = """<biblStruct>26                              <monogr>27                                <author>Flavius Josephus</author>28                                <title>Flavii Iosephi opera</title>29                                <editor role="editor">B. Niese</editor>30                                <imprint>31                                  <pubPlace>Berlin</pubPlace>32                                  <publisher>Weidmann</publisher>33                                  <date>1890</date>34                                </imprint>35                              </monogr>36                            </biblStruct>"""37    38        bible_struct_document = parseString(bibl_struct_xml)39        self.importer.make_work("test_bibl_struct_import", try_to_get_existing_work=False)40        41        self.importer.import_info_from_bibl_struct(bible_struct_document)42        43        self.assertEqual(self.importer.work.authors.all()[0].name,"Flavius Josephus")44        self.assertEqual(self.importer.work.title,"Flavii Iosephi opera")45        46    def test_findTagInDivision(self):47        48        xml = r"""<div1 type="Book" n="1">49<note anchored="yes" type="title" place="inline">*prooi/mion peri\ th=s o(/lhs pragmatei/as.50<list type="toc">51<head>*ta/de e)/nestin e)n th=| prw/th| tw=n *)iwsh/pou i(storiw=n52th=s *)ioudai+kh=s a)rxaiologi/as.</head></list></note></div1>"""53        document = parseString(xml)54        55        div_node = document.getElementsByTagName("div1")[0]56        57        head = self.importer.findTagInDivision(div_node, "head")58    59        self.assertEqual(head.tagName, "head")60        61    def test_get_language(self):62        63        language_xml = """<language id="greek">Greek</language>"""64        65        lang_document = parseString(language_xml)66        67        language = self.importer.get_language(lang_document)68        69        self.assertEqual(language, "Greek")70        71    def write_out_test_file(self, content):72        73        fname = 'C:\\Users\\Luke\\Desktop\\output.txt'74        f = open(fname, 'w')75        f.write(content)76        f.close()77        78    def test_get_text(self):79        80        sample_xml = r"<head>*ta/de e)/nestin e)n th=| <num>b</num> tw=n *)iwsh/pou i(storiw=n th=s *)ioudai+kh=s a)rxaiologi/as.</head>"81        82        doc = parseString(sample_xml)83        84        head = doc.getElementsByTagName("head")[0]85        86        expected = r"*ta/de e)/nestin e)n th=|  tw=n *)iwsh/pou i(storiw=n th=s *)ioudai+kh=s a)rxaiologi/as."87        88        self.assertEqual(PerseusTextImporter.getText(head.childNodes, False), expected)89        90    def test_get_text_recursive(self):91        92        sample_xml = r"<head>*ta/de e)/nestin e)n th=| <num>b</num> tw=n *)iwsh/pou i(storiw=n th=s *)ioudai+kh=s a)rxaiologi/as.</head>"93        94        doc = parseString(sample_xml)95        96        head = doc.getElementsByTagName("head")[0]97        98        expected = r"*ta/de e)/nestin e)n th=| b tw=n *)iwsh/pou i(storiw=n th=s *)ioudai+kh=s a)rxaiologi/as."99        100        self.assertEqual(PerseusTextImporter.getText(head.childNodes, True), expected)101        102    def test_get_states(self):103                                    104        states_xml = """ <refsDecl doctype="TEI.2">105                            <state unit="section"/>106                            <state n="chunk" unit="Whiston section"/>107                         </refsDecl>"""108                            109        states_doc = parseString(states_xml)110        111        states = PerseusTextImporter.getStates(states_doc)112        113        self.assertEqual(states[0].name, "section")114        self.assertEqual(states[1].name, "Whiston section")115        self.assertEqual(states[1].section_type, "chunk")116        117    def test_get_chunks(self):118        119        encoding_desc_xml = """ <encodingDesc>120                              <refsDecl doctype="TEI.2">121                            <state unit="section"/>122                              </refsDecl>123                              <refsDecl doctype="TEI.2">124                            <state n="chunk" unit="Whiston section"/>125                              </refsDecl>126                            </encodingDesc>"""127        128        encoding_desc = parseString(encoding_desc_xml)129        130        chunks = PerseusTextImporter.getStateSets(encoding_desc)131        132        self.assertEqual(chunks[0][0].name, "section")133        134        self.assertEqual(chunks[1][0].name, "Whiston section")135        self.assertEqual(chunks[1][0].section_type, "chunk")136    137    def test_get_title(self):138        139        book_xml = self.load_test_resource('plut.078_teubner_gk.xml')140        book_doc = parseString(book_xml)141        142        tei_header_node = book_doc.getElementsByTagName("teiHeader")[0]143        144        title = PerseusTextImporter.get_title_from_tei_header(tei_header_node)145        146        self.assertEqual(title, "Conjugalia Praecepta")147        148    def test_get_title_sub_nodes(self):149        150        book_xml = self.load_test_resource('xen.socratalia_eng.xml')151        book_doc = parseString(book_xml)152        153        tei_header_node = book_doc.getElementsByTagName("teiHeader")[0]154        155        title = PerseusTextImporter.get_title_from_tei_header(tei_header_node)156        157        self.assertEqual(title, "Works on Socrates")158        159    def test_get_title_for_processing(self):160        161        book_xml = self.load_test_resource('xen.anab_gk_header.xml')162        book_doc = parseString(book_xml)163        164        tei_header_node = book_doc.getElementsByTagName("teiHeader")[0]165        166        title = PerseusTextImporter.get_title_from_tei_header(tei_header_node)167        168        self.assertEqual(title, "Anabasis")169        170    def test_get_title_not_sub(self):171        172        book_xml = self.load_test_resource('plut.gal_gk.xml')173        book_doc = parseString(book_xml)174        175        tei_header_node = book_doc.getElementsByTagName("teiHeader")[0]176        177        title = PerseusTextImporter.get_title_from_tei_header(tei_header_node)178        179        self.assertEqual(title, "Galba")180        181    def test_get_author_from_tei_header(self):182        183        book_xml = self.load_test_resource('aristot.vir_gk.xml')184        book_doc = parseString(book_xml)185        186        tei_header_node = book_doc.getElementsByTagName("teiHeader")[0]187        188        author = PerseusTextImporter.get_author_from_tei_header(tei_header_node)189        190        self.assertEqual(author, "Aristotle")191        192    def test_get_editors(self):193        194        book_xml = self.load_test_resource('1_gk.xml')195        book_doc = parseString(book_xml)196        197        editors = PerseusTextImporter.get_editors(book_doc)198        199        self.assertEqual(editors[0], "J. M. Edmonds")200        201    def test_get_editors_multiple(self):202        203        book_xml = self.load_test_resource('nt_gk.xml')204        book_doc = parseString(book_xml)205        206        editors = PerseusTextImporter.get_editors(book_doc)207        208        self.assertEqual(editors[0], "Brooke Foss Westcott")209        self.assertEqual(editors[1], "Fenton John Anthony Hort")210        211    def test_get_editors_multiple_in_single_field(self):212        213        book_xml = self.load_test_resource('plut.127_loeb_eng.xml')214        book_doc = parseString(book_xml)215        216        editors = PerseusTextImporter.get_editors(book_doc)217        218        self.assertEqual(editors[0], "Harold Cherniss")219        self.assertEqual(editors[1], "William C. Helmbold")220    221    def test_get_author_no_title_stmt(self):222        223        book_xml = self.load_test_resource('aristot.vir_gk.xml')224        book_doc = parseString(book_xml)225        self.assertEqual(PerseusTextImporter.get_author(book_doc), "Aristotle")226        227    def test_load_book_descriptorless_milestone(self):228        # See issue #440 (http://lukemurphey.net/issues/440)229        self.importer.state_set = 0230        file_name = self.get_test_resource_file_name('dh.hist04_gk.xml')231        self.importer.import_file(file_name)232        233        verse = Verse.objects.filter(division__work=self.importer.work).order_by("sequence_number")[0]234        235        self.assertEqual(verse.indicator, "1")236        237    def test_load_book_multilevel_divisions(self):238        # See issue #430 (http://lukemurphey.net/issues/430)239        self.importer.state_set = 0240        file_name = self.get_test_resource_file_name('1_gk.xml')241        self.importer.import_file(file_name)242        243        divisions = Division.objects.filter(work=self.importer.work).order_by("sequence_number")244        245        self.assertEqual(divisions[0].title, None)246        self.assertEqual(divisions[0].descriptor, "1")247        self.assertEqual(divisions[1].title, "ÎαλλίνοÏ
")248        249    def test_get_author_no_bibl_struct(self):250        251        book_xml = self.load_test_resource('plut.cat.ma_gk_portion.xml')252        book_doc = parseString(book_xml)253        self.assertEqual(PerseusTextImporter.get_author(book_doc), "Plutarch")254        255    def test_load_bad_chars(self):256        257        book_xml = self.load_test_resource('plut.cat.ma_gk_portion.xml')258        #book_xml = self.load_test_resource('plut.cat.ma_gk.xml')259        self.importer.import_xml_string(book_xml)260        261    def test_load_bad_chars2(self):262        file_name = self.get_test_resource_file_name('plut.cat.ma_gk_portion.xml')263        self.importer.import_file(file_name)264    265    def test_load_book_with_basic_div(self):266        file_name = self.get_test_resource_file_name('52_gk.xml')267        self.importer.import_file(file_name)268        269    def test_load_book_with_milestone_line_numbers(self):270        file_name = self.get_test_resource_file_name('aesch.ag_eng.xml')271        self.importer.state_set = "*"272        self.importer.ignore_division_markers = True273        self.importer.use_line_count_for_divisions = True274        275        self.importer.import_file(file_name)276        277        work = self.importer.work278        279        divisions = Division.objects.filter(work=work)280        281        self.assertEqual(divisions[0].title, "lines 1-39")282        self.assertEqual(divisions[1].title, "lines 40-82")283        self.assertEqual(divisions[2].title, "lines 83-103")284        self.assertEqual(divisions[3].title, "lines 104-1616")285        self.assertEqual(divisions[4].title, "lines 1617-1648")286        self.assertEqual(divisions[5].title, "lines 1649-1672")287    def test_load_book_with_multiple_divisions_with_same_id(self):288        # See https://lukemurphey.net/issues/2537289        # This checks the logic that 290        file_name = self.get_test_resource_file_name('overriding_div.xml')291        self.importer.state_set = "*"292        self.importer.ignore_division_markers = False293        294        self.importer.import_file(file_name)295        296        work = self.importer.work297        298        divisions = Division.objects.filter(work=work)299        300        self.assertEqual(divisions[1].descriptor, "1")301        self.assertEqual(divisions[2].descriptor, "2")302        # self.assertEqual(divisions[3].descriptor, "2a")303        304    def test_get_line_count(self):305        306        verse_xml = r"""307        <verse>308                <milestone ed="p" n="1" unit="line"/>Release from this weary task of mine has been my plea to the gods throughout this long year's watch, in which, lying upon the palace roof of the Atreidae,309                 upon my bent arm, like a dog, I have learned to know well the gathering of the night's stars, those radiant potentates conspicuous in the firmament,310                <milestone ed="p" n="5" unit="line"/>bringers of winter and summer to mankind the constellations, when they rise and set.311                <p>So now I am still watching for the signal-flame, the gleaming fire that is to bring news from <placeName key="perseus,Troy">Troy</placeName> and312                    <milestone ed="p" n="10" unit="line"/>tidings of its capture.  For thus commands my queen, woman in passionate heart and man in strength of purpose.313                      And whenever I make here my bed, restless and dank with dew and unvisited by dreams-for instead of sleep fear stands ever by my side,314                    <milestone ed="p" n="15" unit="line"/>so that I cannot close my eyelids fast in sleep-and whenever I care to sing or hum "and thus apply an antidote of song to ward off drowsiness",315                     then my tears start forth, as I bewail the fortunes of this house of ours, not ordered for the best as in days gone by.316                    <milestone ed="p" n="20" unit="line"/>But tonight may there come a happy release from my weary task!  May the fire with its glad tidings flash through the gloom!317                </p>318                <p>319                    <stage>The signal fire suddenly flashes out</stage>320                    Oh welcome, you blaze in the night, a light as if of day, you harbinger of many a choral dance in <placeName key="tgn,7010720">Argos</placeName> in thanksgiving for this glad event!321                </p>322                <p>323                    <milestone ed="p" n="25" unit="line"/>Hallo! Hallo!324                    To Agamemnon's queen I thus cry aloud the signal to rise from her bed, and as quickly as she can to lift up in her palace halls a shout of joy in welcome of this fire, if the city of <placeName key="tgn,7002329">Ilium</placeName>325                    <milestone ed="p" n="30" unit="line"/>truly is taken, as this beacon unmistakably announces.326                      And I will make an overture with a dance upon my own account; for my lord's lucky roll I shall count to my own score, now that this beacon has thrown me triple six.327                </p>328                <p>Ah well, may the master of the house come home and may329                    <milestone ed="p" n="35" unit="line"/>I clasp his welcome hand in mine!  For the rest I stay silent; a great ox stands upon my tongue330                    <note anchored="yes" n="36" resp="Smyth">A proverbial expression (of uncertain origin) for enforced silence; cf. fr. 176, 'A key stands guard upon my tongue.'</note>-331                    yet the house itself, could it but speak, might tell a plain enough tale; since, for my part, by my own choice I have words for those who know, and to those who do not know, I've lost my memory.332                </p>333        </verse>334        """335        336        verse_doc = parseString(verse_xml)337        338        line_number, _ = self.importer.get_line_count(verse_doc)339        340        self.assertEqual(str(line_number), "35")341        342    def test_get_line_count_trailing_line(self):343        344        verse_xml = r"""345        <verse>346                <milestone ed="p" n="1" unit="line"/>Release from this weary task of mine has been my plea to the gods throughout this long year's watch, in which, lying upon the palace roof of the Atreidae,347                 upon my bent arm, like a dog, I have learned to know well the gathering of the night's stars, those radiant potentates conspicuous in the firmament,348                <milestone ed="p" n="5" unit="line"/>bringers of winter and summer to mankind the constellations, when they rise and set.349                <p>So now I am still watching for the signal-flame, the gleaming fire that is to bring news from <placeName key="perseus,Troy">Troy</placeName> and350                    <milestone ed="p" n="10" unit="line"/>tidings of its capture.  For thus commands my queen, woman in passionate heart and man in strength of purpose.351                      And whenever I make here my bed, restless and dank with dew and unvisited by dreams-for instead of sleep fear stands ever by my side,352                    <milestone ed="p" n="15" unit="line"/>so that I cannot close my eyelids fast in sleep-and whenever I care to sing or hum "and thus apply an antidote of song to ward off drowsiness",353                     then my tears start forth, as I bewail the fortunes of this house of ours, not ordered for the best as in days gone by.354                    <milestone ed="p" n="20" unit="line"/>But tonight may there come a happy release from my weary task!  May the fire with its glad tidings flash through the gloom!355                </p>356                <p>357                    <stage>The signal fire suddenly flashes out</stage>358                    Oh welcome, you blaze in the night, a light as if of day, you harbinger of many a choral dance in <placeName key="tgn,7010720">Argos</placeName> in thanksgiving for this glad event!359                </p>360                <p>361                    <milestone ed="p" n="25" unit="line"/>Hallo! Hallo!362                    To Agamemnon's queen I thus cry aloud the signal to rise from her bed, and as quickly as she can to lift up in her palace halls a shout of joy in welcome of this fire, if the city of <placeName key="tgn,7002329">Ilium</placeName>363                    <milestone ed="p" n="30" unit="line"/>truly is taken, as this beacon unmistakably announces.364                      And I will make an overture with a dance upon my own account; for my lord's lucky roll I shall count to my own score, now that this beacon has thrown me triple six.365                </p>366                <p>Ah well, may the master of the house come home and may367                    <milestone ed="p" n="35" unit="line"/>I clasp his welcome hand in mine!  For the rest I stay silent; a great ox stands upon my tongue368                    <note anchored="yes" n="36" resp="Smyth">A proverbial expression (of uncertain origin) for enforced silence; cf. fr. 176, 'A key stands guard upon my tongue.'</note>-369                    yet the house itself, could it but speak, might tell a plain enough tale; since, for my part, by my own choice I have words for those who know, and to those who do not know, I've lost my memory.370                </p>371                <p>An extra line...</p>372        </verse>373        """374        375        verse_doc = parseString(verse_xml)376        377        line_number, _ = self.importer.get_line_count(verse_doc)378        379        self.assertEqual(str(line_number), "36")380    381    def test_load_book_with_empty_first_milestone(self):382        file_name = self.get_test_resource_file_name('52_gk.xml')383        384        self.importer.ignore_content_before_first_milestone = True385        self.importer.import_file(file_name)386        387        divisions = Division.objects.filter(work=self.importer.work)388        verses = Verse.objects.filter(division__work=self.importer.work)389        390        # This should not be:391        # á¼ÏοκηÏÏ
ÏÎ¸Îµá½·Ï ÏÎ¹Ï á¼°Î±ÏÏικὴν á¼Î¾á½³Î¼Î±Î¸ÎµÎ½. μανένÏα Ïὸν ÏαÏá½³Ïα καὶ á½Ïὸ Ïῶν á¼Î»Î»Ïν ἰαÏÏῶν á¼ÏεγνÏÏμένον ἰαÏá½±Î¼ÎµÎ½Î¿Ï ...        392        expected = r"""<?xml version="1.0" ?><verse> ou) kaina\ me\n tau=ta, w)= a)/ndres dikastai/, ou)de\ para/doca ta\ ^ u(po\ tou= patro\s e)n tw=| paro/nti gigno/mena, ou)de\ nu=n prw=ton ta\ toiau=ta o)rgi/zetai, a)lla\ pro/xeiros ou(=tos o( no/mos au)tw=| kai\ sunh/qws e)pi\ tou=t' a)fiknei=tai to\ dikasth/rion. e)kei=no de\ kaino/teron nu=n dustuxw=, o(/ti e)/gklhma me\n i)/dion393ou)k e)/xw, kinduneu/w de\ timwri/an u(posxei=n u(pe\r th=s te/xnhs ei) mh\ pa/nta du/natai pei/qesqai tou/tw| keleu/onti, ou(= ti/ ge/noit' a)\n a)topw/teron, qerapeu/ein e)k prosta/gmatos, ou)ke/q' w(s h( te/xnh du/natai, a)ll' w(s o( path\r bou/letai ; e)boulo/mhn me\n ou)=n th\n i)atrikh\n kai\ toiou=to/n ti e)/xein394<pb id="v.5.p.478"/> fa/rmakon o(\ mh\ mo/non tou\s memhno/tas a)lla\ kai\ tou\s a)di/kws o)rgizome/nous pau/ein e)du/nato, i(/na kai\ tou=to tou= patro\s to\ no/shma i)asai/mhn. nuni\395de\ ta\ me\n th=s mani/as au)tw=| te/leon pe/pautai,396ta\ de\ th=s o)rgh=s ma=llon e)pitei/netai, kai\ to\ deino/taton, toi=s me\n a)/llois a(/pasin swfronei=, kat' e)mou= de\ tou= qerapeu/santos mo/nou mai/netai. to\n me\n ou)=n misqo\n th=s qerapei/as o(ra=te oi(=on a)polamba/nw, a)pokhrutto/menos u(p' au)tou= pa/lin kai\ tou= ge/nous a)llotriou/menos deu/teron, w(/sper dia\ tou=t' a)nalhfqei\s pro\s o)li/gon i(/n' a)timo/teros ge/nwmai polla/kis. e)kpesw\n th=s oi)ki/as.397</verse>"""398        399        self.assertEqual(verses[0].original_content, expected)400        401        self.assertEqual(divisions[1].descriptor, "1")402        self.assertEqual(divisions[1].level, 1)403    404    def test_load_book_no_bibl_struct(self):405        # See issue #438 (http://lukemurphey.net/issues/438)406        self.importer.state_set = 0407        file_name = self.get_test_resource_file_name('aristot.vir_gk.xml')408        self.importer.import_file(file_name)409    410    def test_load_book_with_line_numbers(self):411        412        book_xml = self.load_test_resource('hom.od.butler_eng.xml')413        book_doc = parseString(book_xml)414        415        #self.importer.state_set = 0416        self.importer.use_line_count_for_divisions = True417        418        self.importer.import_xml_document(book_doc)419        420        work = self.importer.work421        422        divisions = Division.objects.filter(work=work).order_by("sequence_number")423        424        self.assertEqual(divisions.count(), 10)425        426        #self.assertEqual(divisions[1].title, "lines 1-32")427        428        self.assertEqual(divisions[1].title, "lines 1-96")429        self.assertEqual(divisions[1].title_slug, "lines-1-96")430        self.assertEqual(divisions[1].descriptor, "1")431        432        433        self.assertEqual(divisions[8].title, "Scroll 2")434        self.assertEqual(divisions[8].descriptor, "2")435        436        self.assertEqual(divisions[9].title, "lines 1-15")437        self.assertEqual(divisions[9].title_slug, "lines-1-15")438        self.assertEqual(divisions[9].descriptor, "1")439        440    def test_load_book_with_line_numbers_per_division(self):441        442        book_xml = self.load_test_resource('hom.il.butler_eng.xml')443        book_doc = parseString(book_xml)444        445        #self.importer.state_set = 0446        self.importer.use_line_count_for_divisions = True447        448        self.importer.import_xml_document(book_doc)449        450        work = self.importer.work451        452        divisions = Division.objects.filter(work=work).order_by("sequence_number")453        454        self.assertEqual(divisions.count(), 5)455        456        # Make sure that the first division has the title declared in the head node457        self.assertEqual(divisions[0].title, "Scroll 1")458        self.assertEqual(divisions[0].descriptor, "1")459        460        # Check the second division461        self.assertEqual(divisions[1].parent_division.id, divisions[0].id) # Make sure that the second is under the first node462        self.assertEqual(divisions[1].title, "lines 1-39")463        self.assertEqual(divisions[1].title_slug, "lines-1-39")464        self.assertEqual(divisions[1].descriptor, "1")465        466        # Check the third division467        self.assertEqual(divisions[2].parent_division.id, divisions[0].id)468        self.assertEqual(divisions[2].title, "lines 40-45")469        self.assertEqual(divisions[2].title_slug, "lines-40-45")470        self.assertEqual(divisions[2].descriptor, "40")471        472        # Check the fourth division473        self.assertEqual(divisions[3].parent_division, None)474        self.assertEqual(divisions[3].title, "Scroll 2")475        self.assertEqual(divisions[3].descriptor, "2")476        477        # Check the fifth division478        self.assertEqual(divisions[4].parent_division.id, divisions[3].id)479        self.assertEqual(divisions[4].title, "lines 1-15")480        self.assertEqual(divisions[4].title_slug, "lines-1-15")481        self.assertEqual(divisions[4].descriptor, "1")482        483        484        485    def test_load_book_with_line_numbers_and_parent_divisions(self):486        487        book_xml = self.load_test_resource('hom.il_eng.xml')488        book_doc = parseString(book_xml)489        490        self.importer.state_set = 0491        self.importer.use_line_count_for_divisions = True492        493        self.importer.import_xml_document(book_doc)494        495        work = self.importer.work496        497        divisions = Division.objects.filter(work=work).order_by("sequence_number")498        499        self.assertEqual(str(divisions[0]), "Book 1")500        self.assertEqual(str(divisions[1]), "lines 1-32")501    502    def test_load_book(self):503        504        # Pre-make the author in order to see if the importer is smart enough to not create a duplicate505        author = Author()506        author.name = "Flavius Josephus"507        author.save()508        509        book_xml = self.load_test_resource('j.vit_gk_portion.xml')510        book_doc = parseString(book_xml)511        self.importer.import_xml_document(book_doc)512        513        divisions = Division.objects.filter(work=self.importer.work)514        verses = Verse.objects.filter(division=divisions[0])515        516        # Make sure the importer is smart enougn not to make duplicate authors517        self.assertEqual(Author.objects.filter(name="Flavius Josephus").count(), 1)518        self.assertEqual(divisions.count(), 1)519        self.assertEqual(verses.count(), 7)520        self.assertEqual(verses[0].indicator, "1")521        self.assertEqual(verses[1].indicator, "2")522        523        # Make sure we slugified the title accordingly524        self.assertEqual(self.importer.work.title_slug, "josephi-vita")525        526        # Make sure the original content527        expected_content = r"""<?xml version="1.0" ?><verse><p>*)emoi\ de\ ge/nos e)sti\n ou)k a)/shmon, a)ll' e)c i(ere/wn a)/nwqen528katabebhko/s. w(/sper d' h( par' e(ka/stois a)/llh ti/s e)stin eu)genei/as529u(po/qesis, ou(/tws par' h(mi=n h( th=s i(erwsu/nhs metousi/a tekmh/rio/n530e)stin ge/nous lampro/thtos. </p></verse>"""531        532        self.assertEqual(verses[0].original_content, expected_content)533    534    def test_load_book_division_name_from_type_field(self):535        536        # Pre-make the author in order to see if the importer is smart enough to not create a duplicate537        author = Author()538        author.name = "Flavius Josephus"539        author.save()540        541        book_xml = self.load_test_resource('07_gk.xml')542        book_doc = parseString(book_xml)543        self.importer.import_xml_document(book_doc)544        545        divisions = Division.objects.filter(work=self.importer.work)[:1]546        547        # Make sure the division title was set correctly548        self.assertEqual(divisions[0].title, "Introduction")549        self.assertEqual(divisions[0].original_title, "intro")550    551    def test_load_book_multiple_texts(self):552        """553        Make sure works that include multiple text nodes are imported correctly,554        555        See #459, http://lukemurphey.net/issues/459556        """557        558        # This work has multiple text nodes. See if they are imported as separate units559        self.importer.state_set = 0560        book_xml = self.load_test_resource('apollod_gk.xml')561        book_doc = parseString(book_xml)562        self.importer.import_xml_document(book_doc)563        564        divisions = Division.objects.filter(work=self.importer.work)565        verses = Verse.objects.filter(division__work=self.importer.work)566        567        # Make sure no divisions are marked readable if they have no verses568        for division in divisions:569            if division.readable_unit:570                self.assertGreater(Verse.objects.filter(division=division).count(), 0)571        572        self.assertEqual(divisions[0].descriptor, "Library")573        574        # 35: 28 sections + 2 text nodes + 3 chapters + 2 div1575        self.assertEqual(divisions.count(), 35)576        self.assertEqual(verses.count(), 28)577        578    def test_load_book_texts_with_head(self):579        580        # This work has multiple text nodes. See if they are imported as separate units581        self.importer.state_set = 0582        book_xml = self.load_test_resource('appian.fw_gk.xml')583        book_doc = parseString(book_xml)584        self.importer.import_xml_document(book_doc)585        586        divisions = Division.objects.filter(work=self.importer.work)587        verses = Verse.objects.filter(division__work=self.importer.work)588        589        self.assertEqual(divisions[0].descriptor, "Reg.")590        self.assertEqual(divisions[0].original_title, "*e*k *t*h*s *b*a*s*i*l*i*k*h*s.")591        592        # 2: 1 text nodes, 0 chapters, 1 div1593        self.assertEqual(divisions.count(), 2)594        self.assertEqual(verses.count(), 2)595    596    def test_load_book_editors(self):597        598        # Pre-make the author in order to see if the importer is smart enough to not create a duplicate599        author = Author()600        author.name = "Fenton John Anthony Hort"601        author.save()602        603        book_xml = self.load_test_resource('nt_gk.xml')604        book_doc = parseString(book_xml)605        self.importer.import_xml_document(book_doc)606        607        self.assertEqual(Author.objects.filter(name="Fenton John Anthony Hort").count(), 1)608        609        self.assertEqual(self.importer.work.editors.all().count(), 2)610        self.assertEqual(self.importer.work.editors.filter(name="Brooke Foss Westcott").count(), 1)611        self.assertEqual(self.importer.work.editors.filter(name="Fenton John Anthony Hort").count(), 1)612    613    def test_load_book_alternate_state_set(self):614        self.importer.state_set = 1  #Using Whiston sections as opposed to the defaults615        book_xml = self.load_test_resource('j.vit_gk_portion.xml')616        book_doc = parseString(book_xml)617        work = self.importer.import_xml_document(book_doc)618        619        divisions = Division.objects.filter(work=work)620        621        self.assertEqual(divisions.count(), 2)622        self.assertEqual(Verse.objects.filter(division=divisions[0]).count(), 1)623        self.assertEqual(Verse.objects.filter(division=divisions[1]).count(), 1)624        625    def test_load_book_division_descriptors(self):626        self.importer.state_set = 1627        book_xml = self.load_test_resource('j.bj_gk.xml')628        book_doc = parseString(book_xml)629        work = self.importer.import_xml_document(book_doc)630        631        divisions = Division.objects.filter(work=work)632        633        self.assertEqual(divisions.count(), 2)634        self.assertEqual(divisions[0].descriptor, "1")635        636    def test_load_book_line_count_division_titles(self):637        self.importer.state_set = 1638        self.importer.use_line_count_for_divisions = True639        book_xml = self.load_test_resource('aesch.eum_gk.xml')640        book_doc = parseString(book_xml)641        work = self.importer.import_xml_document(book_doc)642        643        divisions = Division.objects.filter(work=work)644        645        #self.assertEqual(divisions.count(), 3)646        #self.assertEqual(Verse.objects.filter(division=divisions[0]).count(), 1)647        self.assertEqual(divisions[1].title, "lines 1-33")648        self.assertEqual(divisions[2].title, "lines 34-38")649        650    def test_load_book_empty_sub_divisions(self):651        self.importer.state_set = 0652        653        book_xml = self.load_test_resource('aesch.lib_gk.xml')654        book_doc = parseString(book_xml)655        656        work = self.importer.import_xml_document(book_doc)657        658        divisions = Division.objects.filter(work=work)659        660        self.assertEqual(divisions.count(), 6) # Was 3 before cards are always treated as chunks661        self.assertEqual(Verse.objects.filter(division=divisions[0]).count(), 0)662        self.assertEqual(Verse.objects.filter(division=divisions[1]).count(), 1)663        self.assertEqual(Verse.objects.filter(division=divisions[2]).count(), 0)664    665    def test_load_book_no_chunks(self):666        # See bug #446, http://lukemurphey.net/issues/446667        self.importer.state_set = 0668        669        book_xml = self.load_test_resource('nt_gk.xml')670        book_doc = parseString(book_xml)671        672        work = self.importer.import_xml_document(book_doc)673        674        divisions = Division.objects.filter(work=work)675        676        self.assertEqual(divisions[0].original_title, "*k*a*t*a *m*a*q*q*a*i*o*n")677        678        self.assertEqual(divisions.count(), 2)679        self.assertEqual(Verse.objects.filter(division=divisions[0]).count(), 0)680        self.assertEqual(Verse.objects.filter(division=divisions[1]).count(), 4)681        682    def test_load_book_xml_processing_instruction(self):683        # See bug #557, http://lukemurphey.net/issues/557684        self.importer.state_set = 0685        686        book_xml = self.load_test_resource('hist_eng.xml')687        book_doc = parseString(book_xml)688        689        work = self.importer.import_xml_document(book_doc)690        691    def test_load_book_no_verses(self):692        # See bug #446, http://lukemurphey.net/issues/446693        self.importer.state_set = "*"694        695        book_xml = self.load_test_resource('char_gk.xml')696        book_doc = parseString(book_xml)697        698        work = self.importer.import_xml_document(book_doc)699        700        divisions = Division.objects.filter(work=work)701        702        self.assertEqual(divisions[0].original_title, "*Prooi/mion")703        704        self.assertEqual(divisions.count(), 2)705        self.assertEqual(Verse.objects.filter(division=divisions[0]).count(), 5)706        self.assertEqual(Verse.objects.filter(division=divisions[1]).count(), 5)707        708    def test_load_book_no_verses2(self):709        # See bug #446, http://lukemurphey.net/issues/446710        self.importer.state_set = 0711        self.importer.ignore_division_markers = False712        713        book_xml = self.load_test_resource('plut.068_teubner_gk.xml')714        book_doc = parseString(book_xml)715        716        work = self.importer.import_xml_document(book_doc)717        718        divisions = Division.objects.filter(work=work)719        720        self.assertEqual(divisions.count(), 2)721        self.assertEqual(Verse.objects.filter(division=divisions[0]).count(), 0)722        self.assertEqual(Verse.objects.filter(division=divisions[1]).count(), 1)723    724    def test_load_book_merged_state_set(self):725        726        self.importer.state_set = None727        book_xml = self.load_test_resource('j.vit_gk_portion.xml')728        book_doc = parseString(book_xml)729        work = self.importer.import_xml_document(book_doc)730        731        divisions = Division.objects.filter(work=work)732        733        self.assertEqual(divisions.count(), 2)734        self.assertEqual(Verse.objects.filter(division=divisions[0]).count(), 6)735        self.assertEqual(Verse.objects.filter(division=divisions[1]).count(), 1)736    737    def test_load_book_ignore_divs_not_in_refsdecl(self):738        739        self.importer.state_set = 0740        self.importer.ignore_undeclared_divs = True741        file_name = self.get_test_resource_file_name('1_gk.xml')742        self.importer.import_file(file_name)743        744        divisions = Division.objects.filter(work=self.importer.work)745        746        # Make sure that the div3 nodes were not treated as chunks747        self.assertEqual(len(divisions), 3) # Would be 5 otherwise748        749    750    def test_load_book_with_sections(self):751        752        self.importer.state_set = 1 #Using Whiston sections as opposed to the defaults753        book_xml = self.load_test_resource('j.aj_gk_portion.xml')754        book_doc = parseString(book_xml)755        work = self.importer.import_xml_document(book_doc)756        757        divisions = Division.objects.filter(work=work).distinct()758        759        self.assertEqual(divisions[1].descriptor, "pr.")760        self.assertEqual(Verse.objects.filter(division__work=work).count(), 5)761        self.assertEqual(Verse.objects.filter(division=divisions[1]).count(), 2)762        763        self.assertEqual(divisions.count(), 5)764        self.assertEqual(divisions[0].type, "Book")765        self.assertEqual(divisions[0].level, 1)766        767        self.assertEqual(divisions[1].type, "Whiston chapter")768        self.assertEqual(divisions[1].level, 2)769        770        self.assertEqual(divisions[0].original_title, r"""*ta/de e)/nestin e)n th=| prw/th| tw=n *)iwsh/pou i(storiw=n771th=s *)ioudai+kh=s a)rxaiologi/as.""")772        self.assertEqual(divisions[2].original_title, r"""*ta/de e)/nestin e)n th=|  b  tw=n *)iwsh/pou i(storiw=n th=s773*)ioudai+kh=s a)rxaiologi/as.""")774        775        # Make sure that the text from the TOC did not get included776        expected_content = r"""<?xml version="1.0" ?><verse><milestone n="1" unit="section"/><p>*meta\ de\ th\n *)isa/kou teleuth\n oi( pai=des au)tou= merisa/menoi 777th\n oi)/khsin pro\s a)llh/lous ou)x h(\n e)/labon tau/thn kate/sxon,778a)ll' *(hsau=s me\n th=s *nebrwni/as po/lews e)kxwrh/sas tw=| a)delfw=| e)n779*saeira=| dihta=to kai\ th=s *)idoumai/as h)=rxen ou(/tw kale/sas th\n xw/ran780a)p' au)tou=: *)/adwmos ga\r e)pwnoma/zeto kata\ toiau/thn ai)ti/an tuxw\n781th=s e)piklh/sews. <milestone n="2" unit="section"/>a)po\ qh/ras pote\ kai\ po/nou tou= peri\ to\ kunh/gion 782limw/ttwn e)panh=ken, e)/ti de\ h)=n pai=s th\n h(liki/an, e)pituxw\n783de\ ta)delfw=| fakh=n e)skeuako/ti pro\s a)/riston au(tw=| canqh\n sfo/dra784th\n xroia\n kai\ dia\ tou=t' e)/ti ma=llon o)rexqei\s h)ci/ou parasxei=n785au)tw=| pro\s trofh/n. <milestone n="3" unit="section"/>o( de\ a)podo/sqai to\ presbei=on au)tw=| tou= fagei=n786sunergw=| xrhsa/menos th=| pei/nh| to\n a)delfo\n h)na/gkaze, ka)kei=nos u(po\787tou= limou= proaxqei\s paraxwrei= tw=n presbei/wn au)tw=| meq' o(/rkwn.788e)/nqen dia\ th\n canqo/thta tou= brw/matos u(po\ tw=n h(likiwtw=n kata\789paidia\n *)/adwmos e)piklhqei/s, a)/dwma ga\r *(ebrai=oi to\ e)ruqro\n kalou=si, 790th\n xw/ran ou(/tws proshgo/reusen: *(/ellhnes ga\r au)th\n e)pi\ to\791semno/teron *)idoumai/an w)no/masan.792</p></verse>"""793        794        self.assertEqual(Verse.objects.filter(division=divisions[3])[0].original_content, expected_content)795        796    def test_load_book_break_sections(self):797        # See #424, http://lukemurphey.net/issues/424798        799        book_xml = self.load_test_resource('aristd.rhet_gk.xml')800        book_doc = parseString(book_xml)801        self.importer.only_last_state_is_non_chunk = True802        self.importer.import_xml_document(book_doc)803        804        divisions = Division.objects.filter(work=self.importer.work)805        806        self.assertEqual(divisions.count(), 5)807        self.assertEqual(divisions[1].parent_division.id, divisions[0].id)808        self.assertEqual(divisions[2].parent_division.id, divisions[1].id)809        810        self.assertEqual(divisions[4].parent_division.id, divisions[3].id)811        812    def test_load_book_ignore_divs_and_use_line_numbers(self):813        # See #468, http://lukemurphey.net/issues/468814        815        book_xml = self.load_test_resource('soph.trach_gk.xml')816        book_doc = parseString(book_xml)817        self.importer.use_line_count_for_divisions = True818        self.importer.ignore_division_markers = True819        self.importer.state_set = 0820        self.importer.import_xml_document(book_doc)821        822        divisions = Division.objects.filter(work=self.importer.work)823        824        self.assertEqual(divisions.count(), 4)825        self.assertEqual(divisions[0].title, "lines 1-48")826        827    def test_load_book_only_bottom_division_readable(self):828        # See #502, http://lukemurphey.net/issues/502829        830        book_xml = self.load_test_resource('01_gk.xml')831        book_doc = parseString(book_xml)832        self.importer.only_leaf_divisions_readable = True833        self.importer.import_xml_document(book_doc)834        835        divisions = Division.objects.filter(work=self.importer.work)836        837        self.assertEqual(divisions.count(), 13)838        self.assertEqual(divisions.filter(readable_unit=True).count(), 11) #is 13 without using only_leaf_divisions_readable = True 839        840    def test_load_book_explicit_division_tags(self):841        # See #503, http://lukemurphey.net/issues/503842        843        book_xml = self.load_test_resource('01_gk.xml')844        book_doc = parseString(book_xml)845        self.importer.only_leaf_divisions_readable = True846        self.importer.division_tags = ["div1", "div2"]847        self.importer.import_xml_document(book_doc)848        849        divisions = Division.objects.filter(work=self.importer.work)850        851        self.assertEqual(divisions.count(), 12) #Should not have made the div3 under chapter 10 a division852        853    def test_xml_use_line_numbers(self):854        855        tei_node_portion_xml = """856        <teiHeader type="text" status="new">857            <encodingDesc>...test_priceline_integration.py
Source:test_priceline_integration.py  
...48            provider_hotel_id=hotel_id,49            simplenight_hotel_id="SN123",50        )51        # Null mandatory fees52        priceline_contract_response = load_test_resource("priceline/priceline-postpaid-contract2.json")53        priceline_hotel_id_response = load_test_resource("priceline/hotel_specific_search_response.json")54        avail_endpoint = transport.endpoint(PricelineTransport.Endpoint.HOTEL_EXPRESS)55        contract_endpoint = transport.endpoint(PricelineTransport.Endpoint.EXPRESS_CONTRACT)56        with requests_mock.Mocker() as mocker:57            mocker.get(avail_endpoint, text=priceline_hotel_id_response)58            mocker.post(contract_endpoint, text=priceline_contract_response)59            results = priceline.search_by_id(search)60        self.assertEqual("priceline", results.provider)61        self.assertEqual("700363264", results.hotel_id)62        self.assertIsNotNone(results.start_date)63        self.assertIsNotNone(results.end_date)64        self.assertEqual(1, results.occupancy.adults)65        self.assertEqual("Best Western Plus Bayside Hotel", results.hotel_details.name)66        self.assertEqual("Best Western International", results.hotel_details.chain_name)67        self.assertEqual("1717 Embarcadero", results.hotel_details.address.address1)68        self.assertEqual("Oakland", results.hotel_details.address.city)69        self.assertEqual("CA", results.hotel_details.address.province)70        self.assertEqual("US", results.hotel_details.address.country)71        self.assertEqual("CA 94606", results.hotel_details.address.postal_code)72        self.assertIn("This bay front Oakland hotel", results.hotel_details.property_description)73        self.assertEqual(10.0, results.hotel_details.review_rating)74        self.assertEqual(3.0, results.hotel_details.star_rating)75        self.assertAlmostEqual(701.70, float(results.room_rates[0].total_base_rate.amount))76        self.assertEqual("USD", results.room_rates[0].total_base_rate.currency)77    @freeze_time("2020-10-01")78    def test_hotel_express_location_search(self):79        transport = PricelineTransport(test_mode=True)80        priceline = PricelineAdapter(transport)81        location = "1"82        checkin = datetime.now().date() + timedelta(days=30)83        checkout = datetime.now().date() + timedelta(days=35)84        search_request = AdapterLocationSearch(85            start_date=checkin, end_date=checkout, occupancy=AdapterOccupancy(), location_id=location86        )87        resource_file = "priceline/priceline-hotel-express-city-cancellable-rates.json"88        priceline_city_search_resource = load_test_resource(resource_file)89        endpoint = transport.endpoint(PricelineTransport.Endpoint.HOTEL_EXPRESS)90        with requests_mock.Mocker() as mocker:91            mocker.get(endpoint, text=priceline_city_search_resource)92            results = priceline.search_by_location(search_request)93        self.assertEqual(10, len(results))94        self.assertEqual("St. Regis San Francisco", results[0].hotel_details.name)95        self.assertEqual("The Mosser Hotel", results[1].hotel_details.name)96        self.assertEqual(CancellationSummary.NON_REFUNDABLE, results[0].rate_plans[0].cancellation_policy.summary)97        self.assertEqual(CancellationSummary.FREE_CANCELLATION, results[1].rate_plans[0].cancellation_policy.summary)98    def test_priceline_booking(self):99        booking_request = test_objects.booking_request()100        priceline_booking_response = load_test_resource("priceline/booking-response.json")101        transport = PricelineTransport(test_mode=True)102        priceline = PricelineAdapter(transport=PricelineTransport(test_mode=True))103        endpoint = transport.endpoint(PricelineTransport.Endpoint.EXPRESS_BOOK)104        with requests_mock.Mocker() as mocker:105            mocker.post(endpoint, text=priceline_booking_response)106            reservation = priceline.book(booking_request)107        self.assertEqual("30796806215", reservation.locator.id)108        self.assertEqual("CONF0", reservation.hotel_locator[0].id)109        self.assertIsNotNone(reservation.checkin)110        self.assertIsNotNone(reservation.checkout)111        self.assertEqual(1, reservation.traveler.occupancy.adults)112        self.assertEqual("John", reservation.traveler.first_name)113        self.assertEqual("Simplenight", reservation.traveler.last_name)114        self.assertEqual(RateType.BOOKABLE, reservation.room_rate.rate_type)115    @freeze_time("2020-10-01")116    def test_priceline_booking_service_cancellation_policies(self):117        checkin = datetime.now().date() + timedelta(days=30)118        checkout = datetime.now().date() + timedelta(days=35)119        search = HotelLocationSearch(120            start_date=checkin,121            end_date=checkout,122            occupancy=RoomOccupancy(adults=1),123            location_id="1",124            provider="priceline",125        )126        resource_file = "priceline/priceline-hotel-express-city-cancellable-rates.json"127        priceline_city_search_resource = load_test_resource(resource_file)128        priceline_booking_response = load_test_resource("priceline/booking-response-cancellable.json")129        priceline_recheck_response = load_test_resource("priceline/recheck-response.json")130        transport = PricelineTransport(test_mode=True)131        avail_endpoint = transport.endpoint(PricelineTransport.Endpoint.HOTEL_EXPRESS)132        book_endpoint = transport.endpoint(PricelineTransport.Endpoint.EXPRESS_BOOK)133        recheck_endpoint = transport.endpoint(PricelineTransport.Endpoint.EXPRESS_CONTRACT)134        with patch("stripe.Token.create") as stripe_token_mock:135            stripe_token_mock.return_value = {"id": "tok_foo"}136            with patch("stripe.Charge.create") as stripe_create_mock:137                stripe_create_mock.return_value = {138                    "currency": "USD",139                    "id": "payment-id",140                    "amount": 100.00,141                    "object": "settled",142                }143                with patch("api.hotel.hotel_mappings.find_simplenight_hotel_id") as mock_find_simplenight_id:144                    mock_find_simplenight_id.return_value = "123"145                    with requests_mock.Mocker() as mocker:146                        mocker.get(avail_endpoint, text=priceline_city_search_resource)147                        mocker.post(recheck_endpoint, text=priceline_recheck_response)148                        mocker.post(book_endpoint, text=priceline_booking_response)149                        availability_response = hotel_service.search_by_location(search)150                        self.assertTrue(len(availability_response) >= 1)151                        self.assertTrue(len(availability_response[0].room_types) >= 1)152                        hotel_to_book = availability_response[0]153                        room_to_book = hotel_to_book.room_types[0]154                        booking_request = test_objects.booking_request(rate_code=room_to_book.code)155                        booking_response = booking_service.book_hotel(booking_request)156        booking = Booking.objects.get(transaction_id=booking_response.transaction_id)157        booking_id = booking.booking_id158        cancellation_policies = HotelCancellationPolicy.objects.filter(hotel_booking__booking__booking_id=booking_id)159        self.assertEqual(3, len(cancellation_policies))160        self.assertEqual("FREE_CANCELLATION", cancellation_policies[0].cancellation_type)161        self.assertEqual("2017-02-03", str(cancellation_policies[0].begin_date))162        self.assertEqual("2020-10-29", str(cancellation_policies[0].end_date))163        self.assertEqual("PARTIAL_REFUND", cancellation_policies[1].cancellation_type)164        self.assertEqual("2020-10-29", str(cancellation_policies[1].begin_date))165        self.assertEqual("2020-10-31", str(cancellation_policies[1].end_date))166        self.assertEqual("NON_REFUNDABLE", cancellation_policies[2].cancellation_type)167        self.assertEqual("2020-10-31", str(cancellation_policies[2].begin_date))168        self.assertEqual("2024-07-27", str(cancellation_policies[2].end_date))169    @freeze_time("2020-10-09")170    def test_priceline_postpaid_fees(self):171        transport = PricelineTransport(test_mode=True)172        priceline = PricelineAdapter(transport)173        hotel_id = "700033110"174        checkin = datetime.now().date() + timedelta(days=30)175        checkout = datetime.now().date() + timedelta(days=35)176        search = AdapterHotelSearch(177            start_date=checkin,178            end_date=checkout,179            occupancy=AdapterOccupancy(),180            provider_hotel_id=hotel_id,181            simplenight_hotel_id="SN123",182        )183        priceline_hotel_id_response = load_test_resource("priceline/priceline-postpaid-hotelavail.json")184        priceline_contract_response = load_test_resource("priceline/priceline-postpaid-contract1.json")185        avail_endpoint = transport.endpoint(PricelineTransport.Endpoint.HOTEL_EXPRESS)186        contract_endpoint = transport.endpoint(PricelineTransport.Endpoint.EXPRESS_CONTRACT)187        with requests_mock.Mocker() as mocker:188            mocker.get(avail_endpoint, text=priceline_hotel_id_response)189            mocker.post(contract_endpoint, text=priceline_contract_response)190            results = priceline.search_by_id(search)191        self.assertEqual(Decimal("233.20"), results.room_rates[0].postpaid_fees.total.amount)192        self.assertEqual("USD", results.room_rates[0].postpaid_fees.total.currency)193        self.assertEqual(1, len(results.room_rates[0].postpaid_fees.fees))194        self.assertEqual("Resort Fee", results.room_rates[0].postpaid_fees.fees[0].description)195    @freeze_time("2020-10-12")196    def test_multi_room(self):197        checkin = datetime.now().date() + timedelta(days=30)198        checkout = datetime.now().date() + timedelta(days=31)199        search = HotelSpecificSearch(200            start_date=checkin,201            end_date=checkout,202            occupancy=RoomOccupancy(adults=2, num_rooms=1),203            hotel_id="700021105",204            provider="priceline",205        )206        transport = PricelineTransport(test_mode=True)207        avail_endpoint = transport.endpoint(PricelineTransport.Endpoint.HOTEL_EXPRESS)208        single_room_response = load_test_resource("priceline/priceline-multiroom-numroom1.json")209        multi_room_response = load_test_resource("priceline/priceline-multiroom-numroom2.json")210        with patch("api.hotel.hotel_mappings.find_simplenight_hotel_id") as mock_find_simplenight_id:211            mock_find_simplenight_id.return_value = "123"212            with patch("api.hotel.hotel_mappings.find_provider_hotel_id") as mock_find_provider:213                mock_find_provider.return_value = "ABC123"214                with requests_mock.Mocker() as mocker:215                    mocker.get(avail_endpoint, text=single_room_response)216                    availability_response = hotel_service.search_by_id(search)217        self.assertEqual(1, availability_response.occupancy.num_rooms)218        self.assertEqual(Decimal("230.88"), availability_response.room_types[0].total.amount)219        self.assertEqual(Decimal("189.28"), availability_response.room_types[0].total_base_rate.amount)220        search.occupancy.num_rooms = 2221        with patch("api.hotel.hotel_mappings.find_simplenight_hotel_id") as mock_find_simplenight_id:222            mock_find_simplenight_id.return_value = "123"223            with patch("api.hotel.hotel_mappings.find_provider_hotel_id") as mock_find_provider:224                mock_find_provider.return_value = "ABC123"225                with requests_mock.Mocker() as mocker:226                    mocker.get(avail_endpoint, text=multi_room_response)227                    availability_response = hotel_service.search_by_id(search)228        self.assertEqual(2, availability_response.occupancy.num_rooms)229        self.assertEqual(Decimal("455.04"), availability_response.room_types[0].total.amount)230        self.assertEqual(Decimal("378.56"), availability_response.room_types[0].total_base_rate.amount)231    def test_priceline_cancel(self):232        transport = PricelineTransport(test_mode=True)233        adapter = PricelineAdapter(transport=transport)234        lookup_resource = load_test_resource("priceline/priceline-lookup-response.json")235        lookup_endpoint = transport.endpoint(PricelineTransport.Endpoint.EXPRESS_LOOKUP)236        cancel_endpoint = transport.endpoint(PricelineTransport.Endpoint.EXPRESS_CANCEL)237        cancel_resource = load_test_resource("priceline/priceline-cancel-response.json")238        with requests_mock.Mocker() as mocker:239            mocker.post(lookup_endpoint, text=lookup_resource)240            mocker.post(cancel_endpoint, text=cancel_resource)241            cancel_response = adapter.cancel(242                AdapterCancelRequest(hotel_id="14479", record_locator="700243838", email_address="foo@bar.baz")243            )244        self.assertTrue(cancel_response.is_cancelled)245    def test_priceline_cancel_failure(self):246        transport = PricelineTransport(test_mode=True)247        adapter = PricelineAdapter(transport=transport)248        lookup_resource = load_test_resource("priceline/priceline-lookup-response.json")249        lookup_endpoint = transport.endpoint(PricelineTransport.Endpoint.EXPRESS_LOOKUP)250        cancel_endpoint = transport.endpoint(PricelineTransport.Endpoint.EXPRESS_CANCEL)251        cancel_resource = load_test_resource("priceline/priceline-cancel-failure-response.json")252        with requests_mock.Mocker() as mocker:253            mocker.post(lookup_endpoint, text=lookup_resource)254            mocker.post(cancel_endpoint, text=cancel_resource)255            with pytest.raises(BookingException) as e:256                adapter.cancel(257                    AdapterCancelRequest(hotel_id="14479", record_locator="700243838", email_address="foo@bar.baz")258                )259        self.assertIn("Could not cancel booking", str(e))260    def test_priceline_booking_error_handled(self):261        transport = PricelineTransport(test_mode=True)262        priceline = PricelineAdapter(transport)263        payment_object = test_objects.payment("4111111111111111")264        booking_request = test_objects.booking_request(payment_object)265        mock_priceline_booking_response = load_test_resource("priceline/priceline-book-error.json")266        booking_endpoint = transport.endpoint(PricelineTransport.Endpoint.EXPRESS_BOOK)267        with requests_mock.Mocker() as mocker:268            mocker.post(booking_endpoint, text=mock_priceline_booking_response)269            with pytest.raises(BookingException) as e:270                priceline.book(booking_request)271        self.assertEqual("Hotel.Express.Book: Invalid name_first", str(e.value))272    def test_priceline_search_by_hotel_id_batch(self):273        transport = PricelineTransport(test_mode=True)274        priceline = PricelineAdapter(transport)275        hotel_ids = ["700363264", "702812247", "700243838"]276        checkin = datetime.now().date() + timedelta(days=30)277        checkout = datetime.now().date() + timedelta(days=35)278        search = AdapterHotelBatchSearch(279            start_date=checkin,280            end_date=checkout,281            occupancy=AdapterOccupancy(),282            provider_hotel_ids=hotel_ids,283            simplenight_hotel_ids=["SN123", "SN456", "SN789"],284        )285        resource = load_test_resource("priceline/hotel-express-batch.json")286        endpoint = transport.endpoint(PricelineTransport.Endpoint.HOTEL_EXPRESS)287        with requests_mock.Mocker() as mocker:288            mocker.get(endpoint, text=resource)289            results = priceline.search_by_id_batch(search)290        self.assertIsNotNone(results)291        self.assertEqual(3, len(results))292        results.sort(key=lambda x: hotel_ids.index(x.hotel_id))293        self.assertEqual("700363264", results[0].hotel_id)294        self.assertEqual("Best Western Plus Bayside Hotel", results[0].hotel_details.name)295        self.assertEqual("702812247", results[1].hotel_id)296        self.assertEqual("Hyatt Place San Francisco/Downtown", results[1].hotel_details.name)297        self.assertEqual("700243838", results[2].hotel_id)298        self.assertEqual("Hyatt Centric Fisherman's Wharf San Francisco", results[2].hotel_details.name)299    @freeze_time("2020-10-01")300    def test_priceline_booking_service_no_billing_address(self):301        checkin = datetime.now().date() + timedelta(days=30)302        checkout = datetime.now().date() + timedelta(days=35)303        search = HotelLocationSearch(304            start_date=checkin,305            end_date=checkout,306            occupancy=RoomOccupancy(adults=1),307            location_id="1",308            provider="priceline",309        )310        resource_file = "priceline/priceline-hotel-express-city-cancellable-rates.json"311        priceline_city_search_resource = load_test_resource(resource_file)312        priceline_booking_response = load_test_resource("priceline/booking-response-cancellable.json")313        priceline_recheck_response = load_test_resource("priceline/recheck-response.json")314        transport = PricelineTransport(test_mode=True)315        avail_endpoint = transport.endpoint(PricelineTransport.Endpoint.HOTEL_EXPRESS)316        book_endpoint = transport.endpoint(PricelineTransport.Endpoint.EXPRESS_BOOK)317        recheck_endpoint = transport.endpoint(PricelineTransport.Endpoint.EXPRESS_CONTRACT)318        with patch("stripe.Token.create") as stripe_token_mock:319            stripe_token_mock.return_value = {"id": "tok_foo"}320            with patch("stripe.Charge.create") as stripe_create_mock:321                stripe_create_mock.return_value = {322                    "currency": "USD",323                    "id": "payment-id",324                    "amount": 100.00,325                    "object": "settled",326                }327                with patch("api.hotel.hotel_mappings.find_simplenight_hotel_id") as mock_find_simplenight_id:328                    mock_find_simplenight_id.return_value = "123"329                    with requests_mock.Mocker() as mocker:330                        mocker.get(avail_endpoint, text=priceline_city_search_resource)331                        mocker.post(recheck_endpoint, text=priceline_recheck_response)332                        mocker.post(book_endpoint, text=priceline_booking_response)333                        availability_response = hotel_service.search_by_location(search)334                        self.assertTrue(len(availability_response) >= 1)335                        self.assertTrue(len(availability_response[0].room_types) >= 1)336                        hotel_to_book = availability_response[0]337                        room_to_book = hotel_to_book.room_types[0]338                        payment = Payment(payment_method=PaymentMethod.PAYMENT_TOKEN, payment_token="tok_mastercard")339                        booking_request = HotelBookingRequest(340                            api_version=1,341                            transaction_id=str(uuid.uuid4())[:8],342                            hotel_id="1",343                            language="en_US",344                            customer=test_objects.customer(),345                            traveler=test_objects.traveler(),346                            room_code=room_to_book.code,347                            payment=payment,348                        )349                        booking_response = booking_service.book_hotel(booking_request)350        print(booking_response)351    def test_priceline_reviews(self):352        transport = PricelineTransport(test_mode=True)353        priceline = PricelineAdapter(transport=transport)354        priceline_reviews_resource = load_test_resource("priceline/priceline-user-reviews.json")355        with requests_mock.Mocker() as mocker:356            mocker.get(transport.endpoint(PricelineTransport.Endpoint.REVIEWS), text=priceline_reviews_resource)357            reviews = priceline.reviews(hotel_id="700363264")358        self.assertEqual(9.4, reviews.average_rating)359        self.assertEqual(5, reviews.review_count)360        self.assertEqual(5, len(reviews.reviews))361        self.assertEqual("Gregory", reviews.reviews[0].reviewer_name)362        self.assertEqual(date(2020, 9, 2), reviews.reviews[0].review_date)363        self.assertEqual(10.0, reviews.reviews[0].review_rating)364        self.assertIn("Big clean room", reviews.reviews[0].good_text)...conftest.py
Source:conftest.py  
...3from core.utils.helpers import load_test_resource4from typing import List, Dict, Union5@pytest.fixture()6def strava_models_summary_activity_list():7    resource = load_test_resource('strava_summary_activity_list')8    return resource9@pytest.fixture()10def strava_models_detailed_activity():11    resource = load_test_resource('strava_detailed_activity')12    return resource13@pytest.fixture()14def strava_models_lap_list():15    resource = load_test_resource('strava_lap_list')16    return resource17@pytest.fixture()18def strava_models_map():19    resource = load_test_resource('strava_map')20    return resource21@pytest.fixture()22def strava_models_segment_effort_list():23    resource = load_test_resource('strava_segment_effort_list')24    return resource25@pytest.fixture()26def strava_models_split_list():27    resource = load_test_resource('strava_split_list')28    return resource29@pytest.fixture()30def strava_models_athlete_stats():31    resource = load_test_resource('strava_athlete_stats')32    return resource33@pytest.fixture()34def strava_models_best_efforts_list():35    resource = load_test_resource('strava_best_efforts_list')36    return resource37@pytest.fixture()38def strava_models_segment():39    resource = load_test_resource('strava_segment')40    return resource41@pytest.fixture()42def strava_models_totals_list():43    resource = load_test_resource('strava_totals_list')44    return resource45@pytest.fixture()46def strava_models_detailed_activity_list():47    resource = load_test_resource('strava_detailed_activity_list')48    return resource49@pytest.fixture()50def daily_timestamps():51    resource = load_test_resource('daily_timestamps')52    return resource53@pytest.fixture()54def quarter_hour_timestamps():55    resource = load_test_resource('quarter_hour_timestamps.json')56    return resource57@pytest.fixture()58def input_dataframe():59    rows = []60    for i in range(0, 10):61        data = {62            'column1': f'a_{i}',63            'column2': f'b_{i}',64            'column3': f'c_{i}',65        }66        rows.append(data)67    return pd.DataFrame(rows)68@pytest.fixture()69def target_dataframe():...Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
