Example #1
0
class TestBot(unittest.TestCase):
    def setUp(self):
        self.bot = Bot("test_config.json", "test")

    def test_get_comic(self):
        self.assertIsNone(self.bot.get_comic(-1))
        self.assertEqual(
            self.bot.get_comic(327), {
                "month": "10",
                "num": 327,
                "link": "",
                "year": "2007",
                "news": "",
                "safe_title": "Exploits of a Mom",
                "transcript":
                "[[A woman is talking on the phone, holding a cup]]\nPhone: Hi, this is your son's school. We're having some computer trouble.\nMom: Oh dear\u00e2\u0080\u0094did he break something?\nPhone: In a way\u00e2\u0080\u0094\nPhone: Did you really name your son \"Robert'); DROP TABLE Students;--\" ?\nMom: Oh, yes. Little Bobby Tables, we call him.\nPhone: Well, we've lost this year's student records. I hope you're happy.\nMom: And I hope you've learned to sanitize your database inputs.\n{{title-text: Her daughter is named Help I'm trapped in a driver's license factory.}}",
                "alt":
                "Her daughter is named Help I'm trapped in a driver's license factory.",
                "img": "https://imgs.xkcd.com/comics/exploits_of_a_mom.png",
                "title": "Exploits of a Mom",
                "day": "10"
            })

    def test_match_numbers_strict(self):
        self.assertEqual(self.bot.match_numbers("Test", True), [])
        self.assertEqual(self.bot.match_numbers("!123 !123", True), ["123"])
        self.assertEqual(self.bot.match_numbers("7? !080. !99", True),
                         ["80", "99"])
        self.assertEqual(self.bot.match_numbers("!900 10000", True), ["900"])
        self.assertEqual(
            self.bot.match_numbers("!Test !001234 5678 !-1", True), ["1234"])
        self.assertEqual(len(self.bot.match_numbers("!random random", True)),
                         1)

    def test_find_numbers_non_strict(self):
        self.assertEqual(self.bot.match_numbers("Test", False), [])
        self.assertEqual(self.bot.match_numbers("!123.", False), ["123"])
        self.assertEqual(
            self.bot.match_numbers("07/ !080. !00099 99 0099", False),
            ["7", "80", "99"])
        self.assertEqual(self.bot.match_numbers("!900 010000", False),
                         ["900", "10000"])
        self.assertEqual(self.bot.match_numbers("!Test !1234 5678 !-1", False),
                         ["1234", "5678", "1"])
        self.assertEqual(len(self.bot.match_numbers("!random random", False)),
                         2)

    def test_response_size_limited(self):
        comment = CommentMock()
        too_big_response = ''.join(
            ['1' for _ in range(RESPONSE_CHAR_LIMIT + 1)])
        self.bot.reply(comment=comment, response=too_big_response)
        self.assertEqual(
            comment.reply_called, 0,
            f'Expected no reply() call, saw {comment.reply_called}')
        self.assertEqual(comment.save_called, 1,
                         f'Expected 1 save() call, saw {comment.save_called}')

    def test_combine_responses_truncates_response(self):
        # There may be a less fragile way of constructing this test, but this will test the
        # functionality.
        too_many_responses = [f'1' for _ in range(RESPONSE_COUNT_LIMIT + 1)]
        expected_combined_response_length = \
            len('\n'.join(too_many_responses[:RESPONSE_COUNT_LIMIT])) + \
            len(self.bot._closer()) + len('\n')
        actual_combined_response = self.bot.combine_responses(
            responses=too_many_responses)
        self.assertEqual(
            len(actual_combined_response), expected_combined_response_length,
            f'Expected response of length {expected_combined_response_length}, found {len(actual_combined_response)}'
        )
Example #2
0
class TestBot(unittest.TestCase):
    def setUp(self):
        self.bot = Bot("./cfg/test_config.json", "test", ":memory:")

    def test_get_comic(self):
        self.assertIsNone(self.bot.get_comic(-1))
        self.assertEqual(
            self.bot.get_comic(327), {
                "month": "10",
                "num": 327,
                "link": "",
                "year": "2007",
                "news": "",
                "safe_title": "Exploits of a Mom",
                "transcript":
                "[[A woman is talking on the phone, holding a cup]]\nPhone: Hi, this is your son's school. We're having some computer trouble.\nMom: Oh dear\u00e2\u0080\u0094did he break something?\nPhone: In a way\u00e2\u0080\u0094\nPhone: Did you really name your son \"Robert'); DROP TABLE Students;--\" ?\nMom: Oh, yes. Little Bobby Tables, we call him.\nPhone: Well, we've lost this year's student records. I hope you're happy.\nMom: And I hope you've learned to sanitize your database inputs.\n{{title-text: Her daughter is named Help I'm trapped in a driver's license factory.}}",
                "alt":
                "Her daughter is named Help I'm trapped in a driver's license factory.",
                "img": "https://imgs.xkcd.com/comics/exploits_of_a_mom.png",
                "title": "Exploits of a Mom",
                "day": "10"
            })

    def test_match_numbers_strict(self):
        self.assertEqual(self.bot.match_numbers("Test", True), [])
        self.assertEqual(self.bot.match_numbers("!123 !123", True), ["123"])
        self.assertEqual(self.bot.match_numbers("7? !080. !99", True),
                         ["80", "99"])
        self.assertEqual(self.bot.match_numbers("!900 10000", True), ["900"])
        self.assertEqual(
            self.bot.match_numbers("!Test !001234 5678 !-1", True), ["1234"])
        self.assertEqual(len(self.bot.match_numbers("!random random", True)),
                         1)
        self.assertEqual(
            self.bot.match_numbers("!3 relevant xkcd: 6, !relevant xkcd: 5 1",
                                   True), ["3", "6", "5"])
        self.assertEqual(self.bot.match_numbers("!9 !23...25 #9...7", True),
                         ["9", "23", "24", "25", "7", "8"])
        self.assertEqual(
            self.bot.match_numbers(
                "https://www.google.com/maps/dir/Okay,+Oklahoma,+USA/Whynot,+North+Carolina+27341,+USA/@35.283469,-92.0617932,6z/data=!3m1!4b1!4m14!4m13!1m5!1m1!1s0x87b60bd75e51d2d3:0x120194060a920373!2m2!1d-95.3182985!2d35.8506548!1m5!1m1!1s0x8853609903e1db5b:0x15b011f26e28c49e!2m2!1d-79.7480465!2d35.5402827!3e0",
                True), [])
        self.assertEqual(self.bot.match_numbers("number is mid!1string", True),
                         [])
        self.assertEqual(
            self.bot.match_numbers("!12 hello https://www.google.com/!1",
                                   True), ["12"])
        self.assertEqual(self.bot.match_numbers("#1mid#6number", True), ["1"])

    def test_find_numbers_non_strict(self):
        self.assertEqual(self.bot.match_numbers("Test", False), [])
        self.assertEqual(self.bot.match_numbers("!123.", False), ["123"])
        self.assertEqual(
            self.bot.match_numbers("07/ !080. !00099 99 0099", False),
            ["7", "80", "99"])
        self.assertEqual(self.bot.match_numbers("!900 010000", False),
                         ["900", "10000"])
        self.assertEqual(self.bot.match_numbers("!Test !1234 5678 !-1", False),
                         ["1234", "5678", "1"])
        self.assertEqual(len(self.bot.match_numbers("!random random", False)),
                         2)
        self.assertEqual(
            self.bot.match_numbers("!3 relevant xkcd: 6, !relevant xkcd: 5 1",
                                   False), ["3", "6", "5", "1"])
        self.assertEqual(self.bot.match_numbers("9 23...25 9...7", False),
                         ["9", "23", "25", "7", "24", "8"])

    def test_response_size_limited(self):
        comment = CommentMock()
        too_big_response = ''.join(
            ['1' for _ in range(RESPONSE_CHAR_LIMIT + 1)])
        self.bot.reply(comment=comment, response=too_big_response)
        self.assertEqual(
            comment.reply_called, 0,
            f'Expected no reply() call, saw {comment.reply_called}')
        self.assertEqual(comment.save_called, 1,
                         f'Expected 1 save() call, saw {comment.save_called}')

    def test_combine_responses_truncates_response(self):
        # There may be a less fragile way of constructing this test, but this will test the functionality.
        too_many_responses = [f'1' for _ in range(RESPONSE_COUNT_LIMIT + 1)]
        expected_combined_response_length = \
            len('\n'.join(too_many_responses[:RESPONSE_COUNT_LIMIT])) + \
            len(self.bot._closer()) + len('\n')
        actual_combined_response = self.bot.combine_responses(
            responses=too_many_responses)
        self.assertEqual(
            len(actual_combined_response), expected_combined_response_length,
            f'Expected response of length {expected_combined_response_length}, found {len(actual_combined_response)}'
        )

    def test_urlescape(self):
        expected = textwrap.dedent("""
        **[859:](http://xkcd.com/859)** (  
        **Alt-text:** >!Brains aside, I wonder how many poorly-written xkcd.com-parsing scripts will break on this title (or ;;"\'\'{<<[\' this mouseover text."!<  
        [Image](https://imgs.xkcd.com/comics/%28.png)  
        [Mobile](http://m.xkcd.com/859)  
        [Explanation](http://www.explainxkcd.com/wiki/index.php/859)  
        """)
        self.assertEqual(self.bot.format_response(self.bot.get_comic(859)),
                         expected)

    def test_match_titles(self):
        self.assertEqual(
            self.bot.match_titles("!6 #irony #36blownApart !1000comics"),
            ["6", "irony", "36blownApart", "1000comics"])
        self.assertEqual(self.bot.match_titles("#dummy!Title"),
                         ["dummy!Title"])

    def test_get_comic_by_title(self):
        self.bot.database.add_comic_title("irony", 6)
        self.assertEqual(
            self.bot.get_comic_by_title("IrOnY"), {
                "month": "1",
                "num": 6,
                "link": "",
                "year": "2006",
                "news": "",
                "safe_title": "Irony",
                "transcript":
                "Narrator: When self-reference, irony, and meta-humor go too far\nNarrator: A CAUTIONARY TALE\nMan 1: This statement wouldn't be funny if not for irony!\nMan 1: ha ha\nMan 2: ha ha, I guess.\nNarrator: 20,000 years later...\n[[desolate badlands landscape with an imposing sun in the sky]]\n{{It's commonly known that too much perspective can be a downer.}}",
                "alt":
                "It's commonly known that too much perspective can be a downer.",
                "img": "https://imgs.xkcd.com/comics/irony_color.jpg",
                "title": "Irony",
                "day": "1"
            })
        self.assertIsNone(self.bot.get_comic_by_title("dummy"))
Example #3
0
class TestBot(unittest.TestCase):
    def setUp(self):
        self.bot = Bot("./cfg/test_config.json", "test", ":memory:")

    def test_get_comic(self):
        self.assertIsNone(self.bot.get_comic(-1))
        self.assertEqual(
            self.bot.get_comic(327), {
                "month": "10",
                "num": 327,
                "link": "",
                "year": "2007",
                "news": "",
                "safe_title": "Exploits of a Mom",
                "transcript":
                "[[A woman is talking on the phone, holding a cup]]\nPhone: Hi, this is your son's school. We're having some computer trouble.\nMom: Oh dear\u00e2\u0080\u0094did he break something?\nPhone: In a way\u00e2\u0080\u0094\nPhone: Did you really name your son \"Robert'); DROP TABLE Students;--\" ?\nMom: Oh, yes. Little Bobby Tables, we call him.\nPhone: Well, we've lost this year's student records. I hope you're happy.\nMom: And I hope you've learned to sanitize your database inputs.\n{{title-text: Her daughter is named Help I'm trapped in a driver's license factory.}}",
                "alt":
                "Her daughter is named Help I'm trapped in a driver's license factory.",
                "img": "https://imgs.xkcd.com/comics/exploits_of_a_mom.png",
                "title": "Exploits of a Mom",
                "day": "10"
            })
        self.assertIsNone(self.bot.get_comic(404))

        self.assertEqual(
            self.bot.get_comic(10000), {
                "title": "Does not exist yet!",
                "alt": "&nbsp;",
                "img":
                "https://www.explainxkcd.com/wiki/images/9/92/not_found.png",
                "num": 404
            })

        self.assertEqual(
            self.bot.get_comic(
                314159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316527120190914564856692346034861045432664821339360726024914127372458700660631558817488152092096282925409171536436789259036001133053054882046652138414695194151160943305727036575959195309218611738193261179310511854807446237996274956735188575272489122793818301194912983367336244065664308602139494639522473719070217986094370277053921717629317675238467481846766940513200056812714526356082778577134275778960917363717872146844090122495343014654958537105079227968925892354201995611212902196086403441815981362977477130996051870721134999999837297804995105973173281609631859502445945534690830264252230825334468503526193118817101000313783875288658753320838142061717766914730359825349042875546873115956286388235378759375195778185778053217122680661300192787661119590921642019893809525720106548586327886593615338182796823030195203530185296899577362259941389124972177528347913151557485724245415069595082953311686172785588907509838175463746493931925506040092770167113900984882401285836160356370766010471018194295559619894676783744944825537977472684710404753464620804668425906949129331367702898915210475216205696602405803815019351125338243003558764024749647326391419927260426992279678235478163600934172164121992458631503028618297455570674983850549458858692699569092721079750930295532116534498720275596023648066549911988183479775356636980742654252786255181841757467289097777279380008164706001614524919217321721477235014144197356854816136115735255213347574184946843852332390739414333454776241686251898356948556209921922218427255025425688767179049460165346680498862723279178608578438382796797668145410095388378636095068006422512520511739298489608412848862694560424196528502221066118630674427862203919494504712371378696095636437191728746776465757396241389086583264599581339047802759009946576407895126946839835259570982582262052248940772671947826848260147699090264013639443745530506820349625245174939965143142980919065925093722169646151570985838741059788595977297549893016175392846813826868386894277415599185592524595395943104997252468084598727364469584865383673622262609912460805124388439045124413654976278079771569143599770012961608944169486855584840635342207222582848864815845602850601684273945226746767889525213852254995466672782398645659611635488623057745649803559363456817432411251507606947945109659609402522887971089314566913686722874894056010150330861792868092087476091782493858900971490967598526136554978189312978482168299894872265880485756401427047755513237964145152374623436454285844479526586782105114135473573952311342716610213596953623144295248493718711014576540359027993440374200731057853906219838744780847848968332144571386875194350643021845319104848100537061468067491927819119793995206141966342875444064374512371819217999839101591956181467514269123974894090718649423196156794520809514655022523160388193014209376213785595663893778708303906979207734672218256259966150142150306803844773454920260541466592520149744285073251866600213243408819071048633173464965145390579626856100550810665879699816357473638405257145910289706414011097120628043903975951567715770042033786993600723055876317635942187312514712053292819182618612586732157919841484882916447060957527069572209175671167229109816909152801735067127485832228718352093539657251210835791513698820914442100675103346711031412671113699086585163983150197016515116851714376576183515565088490998985998238734552833163550764791853589322618548963213293308985706420467525907091548141654985946163718027098199430992448895757128289059232332609729971208443357326548938239119325974636673058360414281388303203824903758985243744170291327656180937734440307074692112019130203303801976211011004492932151608424448596376698389522868478312355265821314495768572624334418930396864262434107732269780280731891544110104468232527162010526522721116603966655730925471105578537634668206531098965269186205647693125705863566201855810072936065987648611791045334885034611365768675324944166803962657978771855608455296541266540853061434443185867697514566140680070023787765913440171274947042056223053899456131407112700040785473326993908145466464588079727082668306343285878569830523580893306575740679545716377525420211495576158140025012622859413021647155097925923099079654737612551765675135751782966645477917450112996148903046399471329621073404375189573596145890193897131117904297828564750320319869151402870808599048010941214722131794764777262241425485454033215718530614228813758504306332175182979866223717215916077166925474873898665494945011465406284336639379003976926567214638530673609657120918076383271664162748888007869256029022847210403172118608204190004229661711963779213375751149595015660496318629472654736425230817703675159067350235072835405670403867435136222247715891504953098444893330963408780769325993978054193414473774418426312986080998886874132604721569516239658645730216315981931951673538129741677294786724229246543668009806769282382806899640048243540370141631496589794092432378969070697794223625082216889573837986230015937764716512289357860158816175578297352334460428151262720373431465319777741603199066554187639792933441952154134189948544473456738316249934191318148092777710386387734317720754565453220777092120190516609628049092636019759882816133231666365286193266863360627356763035447762803504507772355471058595487027908143562401451718062464362679456127531813407833033625423278394497538243720583531147711992606381334677687969597030983391307710987040859133746414428227726346594704745878477872019277152807317679077071572134447306057007334924369311383504931631284042512192565179806941135280131470130478164378851852909285452011658393419656213491434159562586586557055269049652098580338507224264829397285847831630577775606888764462482468579260395352773480304802900587607582510474709164396136267604492562742042083208566119062545433721315359584506877246029016187667952406163425225771954291629919306455377991403734043287526288896399587947572917464263574552540790914513571113694109119393251910760208252026187985318877058429725916778131496990090192116971737278476847268608490033770242429165130050051683233643503895170298939223345172201381280696501178440874519601212285993716231301711444846409038906449544400619869075485160263275052983491874078668088183385102283345085048608250393021332197155184306354550076682829493041377655279397517546139539846833936383047461199665385815384205685338621867252334028308711232827892125077126294632295639898989358211674562701021835646220134967151881909730381198004973407239610368540664319395097901906996395524530054505806855019567302292191393391856803449039820595510022635353619204199474553859381023439554495977837790237421617271117236434354394782218185286240851400666044332588856986705431547069657474585503323233421073015459405165537906866273337995851156257843229882737231989875714159578111963583300594087306812160287649628674460477464915995054973742562690104903778198683593814657412680492564879855614537234786733039046883834363465537949864192705638729317487233208376011230299113679386270894387993620162951541337142489283072201269014754668476535761647737946752004907571555278196536213239264061601363581559074220202031872776052772190055614842555187925303435139844253223415762336106425063904975008656271095359194658975141310348227693062474353632569160781547818115284366795706110861533150445212747392454494542368288606134084148637767009612071512491404302725386076482363414334623518975766452164137679690314950191085759844239198629164219399490723623464684411739403265918404437805133389452574239950829659122850855582157250310712570126683024029295252201187267675622041542051618416348475651699981161410100299607838690929160302884002691041407928862150784245167090870006992821206604183718065355672525325675
            ), {
                "title": "Does not exist yet!",
                "alt": "&nbsp;",
                "img":
                "https://www.explainxkcd.com/wiki/images/9/92/not_found.png",
                "num": 404
            })

    def test_match_numbers_strict(self):
        self.assertEqual(self.bot.match_numbers("Test", True), [])
        self.assertEqual(self.bot.match_numbers("!123 !123", True), ["123"])
        self.assertEqual(self.bot.match_numbers("7? !080. !99", True),
                         ["80", "99"])
        self.assertEqual(self.bot.match_numbers("!900 10000", True), ["900"])
        self.assertEqual(
            self.bot.match_numbers("!Test !001234 5678 !-1", True), ["1234"])
        self.assertEqual(len(self.bot.match_numbers("!random random", True)),
                         1)
        self.assertEqual(
            self.bot.match_numbers("!3 relevant xkcd: 6, !relevant xkcd: 5 1",
                                   True), ["3", "6", "5"])
        self.assertEqual(self.bot.match_numbers("!9 !23...25 #9...7", True),
                         ["9", "23", "24", "25", "7", "8"])
        self.assertEqual(
            self.bot.match_numbers(
                "https://www.google.com/maps/dir/Okay,+Oklahoma,+USA/Whynot,+North+Carolina+27341,+USA/@35.283469,-92.0617932,6z/data=!3m1!4b1!4m14!4m13!1m5!1m1!1s0x87b60bd75e51d2d3:0x120194060a920373!2m2!1d-95.3182985!2d35.8506548!1m5!1m1!1s0x8853609903e1db5b:0x15b011f26e28c49e!2m2!1d-79.7480465!2d35.5402827!3e0",
                True), [])
        self.assertEqual(self.bot.match_numbers("number is mid!1string", True),
                         [])
        self.assertEqual(
            self.bot.match_numbers("!12 hello https://www.google.com/!1",
                                   True), ["12"])
        self.assertEqual(self.bot.match_numbers("#1mid#6number", True), ["1"])

    def test_find_numbers_non_strict(self):
        self.assertEqual(self.bot.match_numbers("Test", False), [])
        self.assertEqual(self.bot.match_numbers("!123.", False), ["123"])
        self.assertEqual(
            self.bot.match_numbers("07/ !080. !00099 99 0099", False),
            ["7", "80", "99"])
        self.assertEqual(self.bot.match_numbers("!900 010000", False),
                         ["900", "10000"])
        self.assertEqual(self.bot.match_numbers("!Test !1234 5678 !-1", False),
                         ["1234", "5678", "1"])
        self.assertEqual(len(self.bot.match_numbers("!random random", False)),
                         2)
        self.assertEqual(
            self.bot.match_numbers("!3 relevant xkcd: 6, !relevant xkcd: 5 1",
                                   False), ["3", "6", "5", "1"])
        self.assertEqual(self.bot.match_numbers("9 23...25 9...7", False),
                         ["9", "23", "25", "7", "24", "8"])

    def test_response_size_limited(self):
        comment = CommentMock()
        too_big_response = ''.join(
            ['1' for _ in range(RESPONSE_CHAR_LIMIT + 1)])
        self.bot.reply(comment=comment, response=too_big_response)
        self.assertEqual(
            comment.reply_called, 0,
            f'Expected no reply() call, saw {comment.reply_called}')
        self.assertEqual(comment.save_called, 1,
                         f'Expected 1 save() call, saw {comment.save_called}')

    def test_combine_responses_truncates_response(self):
        # There may be a less fragile way of constructing this test, but this will test the functionality.
        too_many_responses = [f'1' for _ in range(RESPONSE_COUNT_LIMIT + 1)]
        expected_combined_response_length = \
            len('\n'.join(too_many_responses[:RESPONSE_COUNT_LIMIT])) + \
            len(self.bot._closer()) + len('\n')
        actual_combined_response = self.bot.combine_responses(
            responses=too_many_responses)
        self.assertEqual(
            len(actual_combined_response), expected_combined_response_length,
            f'Expected response of length {expected_combined_response_length}, found {len(actual_combined_response)}'
        )

    def test_urlescape(self):
        expected = textwrap.dedent("""
        **[859:](http://xkcd.com/859)** (  
        **Alt-text:** >!Brains aside, I wonder how many poorly-written xkcd.com-parsing scripts will break on this title (or ;;"\'\'{<<[\' this mouseover text."!<  
        [Image](https://imgs.xkcd.com/comics/%28.png)  
        [Mobile](http://m.xkcd.com/859)  
        [Explanation](http://www.explainxkcd.com/wiki/index.php/859)  
        """)
        self.assertEqual(self.bot.format_response(self.bot.get_comic(859)),
                         expected)

    def test_match_titles(self):
        self.assertEqual(
            self.bot.match_titles("!6 #irony #36blownApart !1000comics"),
            ["6", "irony", "36blownApart", "1000comics"])
        self.assertEqual(self.bot.match_titles("#dummy!Title"),
                         ["dummy!Title"])

    def test_get_comic_by_title(self):
        self.bot.database.add_comic_title("irony", 6)
        self.assertEqual(
            self.bot.get_comic_by_title("IrOnY"), {
                "month": "1",
                "num": 6,
                "link": "",
                "year": "2006",
                "news": "",
                "safe_title": "Irony",
                "transcript":
                "Narrator: When self-reference, irony, and meta-humor go too far\nNarrator: A CAUTIONARY TALE\nMan 1: This statement wouldn't be funny if not for irony!\nMan 1: ha ha\nMan 2: ha ha, I guess.\nNarrator: 20,000 years later...\n[[desolate badlands landscape with an imposing sun in the sky]]\n{{It's commonly known that too much perspective can be a downer.}}",
                "alt":
                "It's commonly known that too much perspective can be a downer.",
                "img": "https://imgs.xkcd.com/comics/irony_color.jpg",
                "title": "Irony",
                "day": "1"
            })
        self.assertIsNone(self.bot.get_comic_by_title("dummy"))