예제 #1
0
class BotTest(unittest.TestCase):

    # initialise our test with a service that we can use during testing and a testing database
    def setUp(self):
        self.database = 'test.sqlite'
        if os.path.exists(self.database):
            os.unlink(self.database)

        self.service = CardstoriesService({
            'db': self.database,
            'plugins-confdir': '../fixture',
            'plugins-libdir': 'LIBDIR',
            'static': 'STATIC'
        })
        self.service.auth = Mock()
        self.service.startService()

    def tearDown(self):
        # kill the service we started before the test
        return self.service.stopService()

    @defer.inlineCallbacks
    def game_create(self):
        """Creates the game, sets the card, and sets the sentence in one step."""
        self.winner_card = winner_card = 5
        sentence = 'SENTENCE'
        self.owner_id = 15
        result = yield self.service.create({'owner_id': [self.owner_id]})
        game_id = result['game_id']
        yield self.service.set_card({
            'action': ['set_card'],
            'card': [winner_card],
            'player_id': [self.owner_id],
            'game_id': [game_id]
        })
        yield self.service.set_sentence({
            'action': ['set_sentence'],
            'sentence': [sentence],
            'player_id': [self.owner_id],
            'game_id': [game_id]
        })

        defer.returnValue(result)

    @defer.inlineCallbacks
    def game_to_vote(self, game_id):
        yield self.service.voting({
            'action': ['voting'],
            'game_id': [game_id],
            'owner_id': [self.owner_id]
        })
        self.assertTrue(self.service.games.has_key(game_id))
        defer.returnValue(True)

    @defer.inlineCallbacks
    def game_to_complete(self, game_id):
        yield self.service.complete({
            'action': ['complete'],
            'game_id': [game_id],
            'owner_id': [self.owner_id]
        })
        self.assertFalse(self.service.games.has_key(game_id))
        defer.returnValue(True)

    @defer.inlineCallbacks
    def test01_play_game(self):
        mock_reactor = bot.reactor = Mock()  # Don't delay calls

        bot_plugin = bot.Plugin(self.service, [])
        self.assertEquals(bot_plugin.name(), 'bot')
        bots = [bot_plugin.bots[0], bot_plugin.bots[1], bot_plugin.bots[2]]
        self.assertEqual(bots[0].player_id, 2)
        self.assertEqual(bots[1].player_id, 3)
        self.assertEqual(bots[2].player_id, 4)

        # New game
        game = yield self.game_create()
        game_id = game['game_id']
        mock_reactor.callLater.assert_called_once_with(
            1, bot_plugin.check_need_player, game_id)
        mock_reactor.reset_mock()

        # Only the author in the game
        game, players_ids = yield bots[0].get_game_by_id(game_id)
        self.assertEqual(len(game['players']), 1)

        # Bots don't join by default
        yield bot_plugin.check_need_player(game_id)
        self.assertEqual(len(mock_reactor.callLater.call_args_list), 0)

        # Enable joining
        request = Request(action=['bot'],
                          enable_join=['true'],
                          game_id=[str(game_id)])
        result = yield bot_plugin.preprocess(True, request)
        self.assertFalse(request.args.has_key('action'))
        self.assertTrue(bot_plugin.enable_join[game_id])
        mock_reactor.reset_mock()

        # Bots join after enabling it
        for i in xrange(2):
            yield bot_plugin.check_need_player(game_id)
            self.assertEqual(len(mock_reactor.callLater.call_args_list), 2)
            mock_reactor.reset_mock()

            game, player_ids = yield bots[i].get_game_by_id(game_id)
            self.assertEqual(game['players'][i + 1]['id'], bots[i].player_id)
            self.assertEqual(game['players'][i + 1]['picked'], None)

        # Bots pick a card
        for i in xrange(2):
            yield bots[i].pick(game_id)
            self.assertFalse(mock_reactor.called)

            game, player_ids = yield bots[i].get_game_by_id(
                game_id, player_id=bots[i].player_id)
            self.assertIsInstance(game['players'][i + 1]['picked'], int)
            self.assertEqual(game['players'][i + 1]['vote'], None)

        # Go to vote phase
        yield self.game_to_vote(game_id)
        self.assertEqual(mock_reactor.callLater.call_args_list,
                         [((3, bots[0].vote, game_id), {}),
                          ((3, bots[1].vote, game_id), {})])
        mock_reactor.reset_mock()

        # A bot should never join or pick at this stage
        joined = yield bots[2].join(game_id)
        self.assertFalse(joined)
        picked = yield bots[2].pick(game_id)
        self.assertFalse(picked)

        # Bots vote
        for i in xrange(2):
            yield bots[i].vote(game_id)
            self.assertFalse(mock_reactor.called)

            game, player_ids = yield bots[i].get_game_by_id(
                game_id, player_id=bots[i].player_id)
            self.assertIsInstance(game['players'][i + 1]['picked'], int)
            self.assertEqual(game['players'][i + 1]['vote'], '')

        # A bot should never vote at this stage
        joined = yield bots[2].vote(game_id)
        self.assertFalse(joined)

    def test02_brain_not_implemented(self):
        brain = bot.Brain(None)
        self.assertRaises(NotImplementedError,
                          brain.get_all_cards_scores_for_sentence, "Test")

    def test03_brain_weighted_card_choice(self):
        brain = bot.Brain(None)
        ranked_cards = [(1, 1), (2, 10000), (3, 0), (4, 0), (5, 0), (6, 0),
                        (7, 0), (8, 0), (9, 0)]
        chosen_card = brain.weighted_card_choice(ranked_cards)
        self.assertTrue(chosen_card == 1 or chosen_card == 2)

    @defer.inlineCallbacks
    def test04_nlwordmatcherbrain(self):
        bot_plugin = bot.Plugin(self.service, [])
        brain = bot.NLWordMatcherBrain(bot_plugin)

        # Make sure we can record scores for cards that are earned (card # > NCARDS)
        max_cards = 42
        assert CardstoriesGame.NCARDS < max_cards <= CardstoriesGame.NCARDS_EARNED

        ranked_cards = yield brain.sort_cards_by_ranking_for_sentence(
            "word", [1, 2, 3, 42])
        self.assertEquals(ranked_cards, [(3, 4), (2, 3), (1, 2),
                                         (max_cards, 1)])
예제 #2
0
class ChatTest(unittest.TestCase):

    # initialise our test with a service that we can use during testing and a testing database
    def setUp(self):
        self.database = 'test.sqlite'
        if os.path.exists(self.database):
            os.unlink(self.database)

        # Empty 'chat/' subdir
        self.test_logdir = 'test_logdir.tmp'
        if os.path.exists(self.test_logdir):
            shutil.rmtree(self.test_logdir)

        self.service = CardstoriesService({
            'db': self.database,
            'plugins-confdir': 'CONFDIR',
            'plugins-libdir': 'LIBDIR',
            'plugins-logdir': self.test_logdir,
            'static': 'STATIC'
        })
        self.service.startService()

    def tearDown(self):
        # kill the service we started before the test
        return self.service.stopService()

    @defer.inlineCallbacks
    def complete_game(self):
        self.winner_card = winner_card = 5
        sentence = 'SENTENCE'
        owner_id = 15
        result = yield self.service.create({
            'card': [winner_card],
            'sentence': [sentence],
            'owner_id': [owner_id]
        })
        game_id = result['game_id']

        yield self.service.set_card({
            'action': ['set_card'],
            'card': [winner_card],
            'player_id': [owner_id],
            'game_id': [game_id]
        })

        yield self.service.set_sentence({
            'action': ['set_sentence'],
            'sentence': [sentence],
            'player_id': [owner_id],
            'game_id': [game_id]
        })

        self.player1 = 16
        for player_id in (self.player1, 17):
            yield self.service.participate({
                'action': ['participate'],
                'player_id': [player_id],
                'game_id': [game_id]
            })
            player = yield self.service.player2game({
                'action': ['player2game'],
                'player_id': [player_id],
                'game_id': [game_id]
            })
            card = player['cards'][0]
            yield self.service.pick({
                'action': ['pick'],
                'player_id': [player_id],
                'game_id': [game_id],
                'card': [card]
            })

        yield self.service.voting({
            'action': ['voting'],
            'game_id': [game_id],
            'owner_id': [owner_id]
        })
        winner_id = self.player1
        yield self.service.vote({
            'action': ['vote'],
            'game_id': [game_id],
            'player_id': [winner_id],
            'card': [winner_card]
        })
        loser_id = 17
        yield self.service.vote({
            'action': ['vote'],
            'game_id': [game_id],
            'player_id': [loser_id],
            'card': [120]
        })
        self.assertTrue(self.service.games.has_key(game_id))
        yield self.service.complete({
            'action': ['complete'],
            'game_id': [game_id],
            'owner_id': [owner_id]
        })
        self.assertFalse(self.service.games.has_key(game_id))
        defer.returnValue(True)

    def test00_create_logdir(self):
        chat_instance = Plugin(self.service, [])
        logdir = os.path.join(self.test_logdir, 'chat')
        self.assertTrue(os.path.exists(logdir))

    @defer.inlineCallbacks
    def test00_preprocess_noop(self):
        # create a new instance of the plugin and make sure it's the right type
        chat_instance = Plugin(self.service, [])
        self.assertEquals(chat_instance.name(), 'chat')
        # run a game to get into a realistic situation
        yield self.complete_game()
        # run the preprocess method and make sure it does not affect anything during a normal 'game' event
        result_in = 'RESULT'
        result_out = yield chat_instance.preprocess(result_in,
                                                    Request(action=['game']))
        self.assertEquals(result_in, result_out)

    @defer.inlineCallbacks
    def test01_add_message(self):
        # new instance of the chat plugin to test
        chat_instance = Plugin(self.service, [])
        # create a message event request
        player_id = 200
        sentence = "This is my sentence!"
        now = int(runtime.seconds() * 1000)
        request = Request(action=['message'],
                          player_id=[player_id],
                          sentence=[sentence])
        # verify we have no messages yet
        self.assertEquals(len(chat_instance.messages), 0)
        # run the request
        result = yield chat_instance.preprocess(True, request)
        # verify we now have one message
        self.assertEquals(len(chat_instance.messages), 1)
        # verify the event has been removed from the pipeline
        self.assertFalse(request.args.has_key('action'))
        # verify the message we added is in the list
        self.assertEquals(chat_instance.messages[0]["player_id"], player_id)
        self.assertEquals(chat_instance.messages[0]["sentence"], sentence)
        # check that the message has been recorded in log file
        with open(
                os.path.join(self.test_logdir, 'chat',
                             '%s.log' % strftime('%Y-%m-%d'))) as f:
            lines = f.readlines()
            self.assertEquals(len(lines), 1)
            self.assertIn(sentence, lines[0])
            self.assertIn('player_%d' % player_id, lines[0])

    @defer.inlineCallbacks
    def test02_check_added_message_after_now(self):
        # new instance of the chat plugin to test
        chat_instance = Plugin(self.service, [])
        # create a message event request
        player_id = 200
        sentence = "This is my sentence!"
        now = int(runtime.seconds() * 1000)
        request = Request(action=['message'],
                          player_id=[player_id],
                          sentence=[sentence])
        # run the request
        result = yield chat_instance.preprocess(True, request)
        # check to make sure no message is returned if we ask for now or later
        state, players_id_list = yield chat_instance.state(
            {"modified": [now + 1]})
        self.assertTrue(state.has_key('messages'))
        self.assertEquals(len(state['messages']), 0)
        self.assertEquals(players_id_list, [])

    @defer.inlineCallbacks
    def test03_check_added_message_before_now(self):
        # new instance of the chat plugin to test
        chat_instance = Plugin(self.service, [])
        # create a message event request
        player_id = 200
        sentence = "This is my sentence!"
        now = int(runtime.seconds() * 1000)
        request = Request(action=['message'],
                          player_id=[player_id],
                          sentence=[sentence])
        # run the request
        result = yield chat_instance.preprocess(True, request)
        # check to make sure no message is returned if we ask for now or later
        state, players_id_list = yield chat_instance.state(
            {"modified": [now - 1]})
        self.assertEquals(len(state['messages']), 1)
        self.assertEquals(state['messages'][0]['player_id'], player_id)
        self.assertEquals(state['messages'][0]['sentence'], sentence)
        self.assertEquals(players_id_list, [player_id])

    @defer.inlineCallbacks
    def test04_check_multiple_messages(self):
        # new instance of the chat plugin to test
        chat_instance = Plugin(self.service, [])
        # create a message event request
        player_ids = [200, 220, 999]
        sentences = [
            "This is my sentence!", "Yeah another test hello.",
            "Ping ping poing pong."
        ]
        when = []
        for i in range(3):
            when.append(int(runtime.seconds() * 1000))
            request = Request(action=['message'],
                              player_id=[player_ids[i]],
                              sentence=[sentences[i]])
            # run the request
            result = yield chat_instance.preprocess(True, request)
        # check to make sure no message is returned if we ask for now or later
        # we check right back to one second ago to make sure all recently added messages are caught
        state, players_id_list = yield chat_instance.state(
            {"modified": [when[-1] - 1000]})
        self.assertEquals(len(state['messages']), 3)
        for i in range(3):
            self.assertEquals(state['messages'][i]['player_id'], player_ids[i])
            self.assertEquals(state['messages'][i]['sentence'], sentences[i])
        self.assertEquals(players_id_list, player_ids)

    @defer.inlineCallbacks
    def test05_check_half_of_multiple_messages(self):
        # new instance of the chat plugin to test
        chat_instance = Plugin(self.service, [])
        # create a message event request
        player_ids = [200, 220, 999]
        sentences = [
            "This is my sentence!", "Yeah another test hello.",
            "Ping ping poing pong."
        ]
        when = []
        for i in range(3):
            sleep(0.1)
            when.append(int(runtime.seconds() * 1000))
            request = Request(action=['message'],
                              player_id=[player_ids[i]],
                              sentence=[sentences[i]])
            # run the request
            result = yield chat_instance.preprocess(True, request)
        # check to make sure no message is returned if we ask for now or later
        # we check right back to one second ago to make sure all recently added messages are caught
        state, players_id_list = yield chat_instance.state(
            {"modified": [when[-1] - 150]})
        # this time because of the 100ms delay between messages, and only checking to 150ms ago
        # we should only get the last two messages
        self.assertEquals(len(state['messages']), 2)
        for i in range(2):
            self.assertEquals(state['messages'][i]['player_id'],
                              player_ids[i + 1])
            self.assertEquals(state['messages'][i]['sentence'],
                              sentences[i + 1])
        self.assertEquals(players_id_list, player_ids[-2:])

    @defer.inlineCallbacks
    def test06_touch_state(self):
        player_id = 200
        sentence = "This is my sentence!"
        # new instance of chat plugin to run the test against
        chat_instance = Plugin(self.service, [])
        # put the chat instance into the service's pollable_plugins
        self.service.pollable_plugins.append(chat_instance)
        # flag to signify whether the callback has run
        self.called = False
        # service to poll instance waiting for chat
        d = self.service.poll({
            'action': ['poll'],
            'player_id': [player_id],
            'type': ['chat'],
            'modified': [chat_instance.get_modified()]
        })

        # callback which runs once the chat plugin calls touch()
        def check(event):
            self.called = True

        d.addCallback(check)
        # make sure our flag is false before we run
        self.assertFalse(self.called)
        # run the test request
        request = Request(action=['message'],
                          player_id=[player_id],
                          sentence=[sentence])
        result = yield chat_instance.preprocess(True, request)
        yield d
        # make sure the flag is now set after we've run the test
        self.assertTrue(self.called)

    @defer.inlineCallbacks
    def test07_notification_messages(self):
        # new instance of chat plugin to run the test against
        chat_instance = Plugin(self.service, [])

        self.count = 0

        def build_message(self, message):
            """
            message == {'type': 'notification',
                        'game_id': GAME_ID,
                        'player_id': 'OWNER_ID',
                        'sentence': 'SENTENCE'}

            """
            self.count += 1
            self.assertEquals(self.count, 1)
            self.assertEquals(message['type'], 'notification')
            self.assertEquals(message['player_id'], '15')
            self.assertEquals(message['sentence'], 'SENTENCE')

        # build_message should only be called once, upon game creation.
        chat_instance.build_message = build_message
        # run a game to get into a realistic situation
        yield self.complete_game()

    @defer.inlineCallbacks
    def test08_nonascii_characters_message(self):
        # new instance of the chat plugin to test
        chat_instance = Plugin(self.service, [])
        # create a message event request
        player_id = 200
        # The sentence is a 'str' object. Create it by encoding a unicode string.
        unicode_sentence = u"你好 Matjaž Gregorič"
        sentence_bytes = unicode_sentence.encode('utf-8')
        request = Request(action=['message'],
                          player_id=[player_id],
                          sentence=[sentence_bytes])
        # run the request
        result = yield chat_instance.preprocess(True, request)
        # check that the message has been recorded in log file
        with open(
                os.path.join(self.test_logdir, 'chat',
                             '%s.log' % strftime('%Y-%m-%d'))) as f:
            lines = f.readlines()
            self.assertIn(unicode_sentence, lines[0].decode('utf-8'))

    @defer.inlineCallbacks
    def test09_nonascii_characters_notification(self):
        # new instance of the chat plugin to test
        chat_instance = Plugin(self.service, [])

        # create a message event request
        class FakeGame:
            id = 102
            owner_id = 303

        unicode_sentence = u"我不明白 šal čez želodec"
        changes = {
            'type': 'change',
            'details': {
                'type': 'load',
                'sentence': unicode_sentence
            },
            'game': FakeGame()
        }
        result = yield chat_instance.self_notify(changes)
        with open(
                os.path.join(self.test_logdir, 'chat',
                             '%s.log' % strftime('%Y-%m-%d'))) as f:
            lines = f.readlines()
            self.assertIn(unicode_sentence, lines[0].decode('utf-8'))

    @defer.inlineCallbacks
    def test10_escape_html(self):
        # new instance of the chat plugin to test
        chat_instance = Plugin(self.service, [])
        # create a message event request
        player_id = 201
        naughty_sentence = '<script>alert("haha!")</script>'
        now = int(runtime.seconds() * 1000)
        request = Request(action=['message'],
                          player_id=[player_id],
                          sentence=[naughty_sentence])
        # run the request
        result = yield chat_instance.preprocess(True, request)
        # check to make sure our naughty message is returned properly escaped
        state, players_id_list = yield chat_instance.state(
            {"modified": [now - 1]})
        self.assertEquals(state['messages'][0]['player_id'], player_id)
        self.assertEquals(state['messages'][0]['sentence'],
                          '&lt;script&gt;alert("haha!")&lt;/script&gt;')

    @defer.inlineCallbacks
    def test11_link_url(self):
        # new instance of the chat plugin to test
        chat_instance = Plugin(self.service, [])
        # create a message event request
        player_id = 201
        url_sentence = 'For searching the web I use google.com, it\'s great!'
        now = int(runtime.seconds() * 1000)
        request = Request(action=['message'],
                          player_id=[player_id],
                          sentence=[url_sentence])
        # run the request
        result = yield chat_instance.preprocess(True, request)
        # check to make sure our message is returned with a link for the url
        state, players_id_list = yield chat_instance.state(
            {"modified": [now - 1]})
        self.assertEquals(state['messages'][0]['player_id'], player_id)
        self.assertEquals(
            state['messages'][0]['sentence'],
            'For searching the web I use <a target="_blank" href="http://google.com">google.com</a>, it\'s great!'
        )
예제 #3
0
class MailTest(unittest.TestCase):
    def setUp(self):
        self.database = 'test.sqlite'
        if os.path.exists(self.database):
            os.unlink(self.database)
        self.service = CardstoriesService({
            'db': self.database,
            'plugins-libdir': '../fixture',
            'plugins-confdir': '../fixture',
            'plugins-dir': '../fixture'
        })
        self.service.startService()

    def tearDown(self):
        return self.service.stopService()

    @defer.inlineCallbacks
    def complete_game(self):
        self.owner_id = 1
        self.player1 = 2
        self.player2 = 3
        self.owner_email = '*****@*****.**'
        self.player1_email = '*****@*****.**'
        self.player2_email = '*****@*****.**'
        self.winner_card = winner_card = 5
        sentence = 'SENTENCE'
        game = yield self.service.create({'owner_id': [self.owner_id]})
        self.game_id = game['game_id']
        yield self.service.set_card({
            'action': ['set_card'],
            'card': [winner_card],
            'game_id': [self.game_id],
            'player_id': [self.owner_id]
        })
        yield self.service.set_sentence({
            'action': ['set_sentence'],
            'sentence': [sentence],
            'game_id': [self.game_id],
            'player_id': [self.owner_id]
        })
        yield self.service.invite({
            'action': ['invite'],
            'game_id': [self.game_id],
            'invited_email': [self.player1_email],
            'owner_id': [self.owner_id]
        })
        for player_id in (self.player1, self.player2):
            yield self.service.participate({
                'action': ['participate'],
                'player_id': [player_id],
                'game_id': [self.game_id]
            })
            player = yield self.service.player2game({
                'action': ['player2game'],
                'player_id': [player_id],
                'game_id': [self.game_id]
            })
            card = player['cards'][0]
            yield self.service.pick({
                'action': ['pick'],
                'player_id': [player_id],
                'game_id': [self.game_id],
                'card': [card]
            })

        yield self.service.voting({
            'action': ['voting'],
            'game_id': [self.game_id],
            'owner_id': [self.owner_id]
        })
        winner_id = self.player1
        yield self.service.vote({
            'action': ['vote'],
            'game_id': [self.game_id],
            'player_id': [winner_id],
            'card': [winner_card]
        })
        loser_id = self.player2
        yield self.service.vote({
            'action': ['vote'],
            'game_id': [self.game_id],
            'player_id': [loser_id],
            'card': [120]
        })
        self.assertTrue(self.service.games.has_key(self.game_id))
        yield self.service.complete({
            'action': ['complete'],
            'game_id': [self.game_id],
            'owner_id': [self.owner_id]
        })
        self.assertFalse(self.service.games.has_key(self.game_id))
        defer.returnValue(True)

    def test00_init(self):
        plugin = mail.Plugin(self.service, [])
        self.assertEquals(plugin.name(), 'mail')
        self.assertEquals(plugin.host, 'localhost')
        for allowed in mail.Plugin.ALLOWED:
            self.assertTrue(plugin.templates.has_key(allowed))

    @defer.inlineCallbacks
    def test01_invite(self):
        plugin = mail.Plugin(self.service, [])

        def get_player_email(player_id):
            if player_id == self.player1:
                email = self.player1_email
            elif player_id == self.player2:
                email = self.player2_email
            elif player_id == self.owner_id:
                email = self.owner_email
            return defer.succeed(email)

        self.service.auth.get_player_email = get_player_email

        def get_player_id(email, create=False):
            return defer.succeed(self.player1)

        self.service.auth.get_player_id = get_player_id

        self.count = 0

        def sendmail(host, sender, recipients, email):
            self.count += 1
            self.assertSubstring('game_id=%d' % self.game_id, email)
            self.assertSubstring('url=URL', email)
            self.assertSubstring('static_url=STATIC_URL', email)
            if self.count == 1:
                self.assertSubstring('_INVITE_', email)
                self.assertSubstring('owner_email=%s' % self.owner_name, email)
            elif self.count in (2, 3):
                self.assertSubstring('_PICK_', email)
                if self.count == 2:
                    self.assertSubstring('player_email=%s' % self.player1_name,
                                         email)
                elif self.count == 3:
                    self.assertSubstring('player_email=%s' % self.player2_name,
                                         email)
            elif self.count in (4, 5):
                self.assertSubstring('_VOTE_', email)
                if self.count == 4:
                    self.assertSubstring('player_email=%s' % self.player1_name,
                                         email)
                elif self.count == 5:
                    self.assertSubstring('player_email=%s' % self.player2_name,
                                         email)
            elif self.count == 6:
                self.assertSubstring('_VOTING_', email)
            elif self.count == 7:
                self.assertSubstring('_COMPLETE_', email)
                self.assertSubstring('owner_email=%s' % self.owner_name, email)
            return defer.succeed(True)

        plugin.sendmail = sendmail

        yield self.complete_game()
        self.assertEqual(self.count, 7)

    @defer.inlineCallbacks
    def test02_send_nothing(self):
        self.service.auth.get_players_emails = Mock(
            return_value=['not_an_email'])
        plugin = mail.Plugin(self.service, [])
        d = plugin.send('SUBJECT', [1], 'TEMPLATE', {})

        def check(result):
            self.assertFalse(result)

        d.addCallback(check)
        yield d
예제 #4
0
class ChatTest(unittest.TestCase):

    # initialise our test with a service that we can use during testing and a testing database
    def setUp(self):
        self.database = 'test.sqlite'
        if os.path.exists(self.database):
            os.unlink(self.database)

        # Empty 'chat/' subdir
        self.test_logdir = 'test_logdir.tmp'
        if os.path.exists(self.test_logdir):
            shutil.rmtree(self.test_logdir)

        self.service = CardstoriesService({'db': self.database,
                                           'plugins-confdir': 'CONFDIR',
                                           'plugins-libdir': 'LIBDIR',
                                           'plugins-logdir': self.test_logdir,
                                           'static': 'STATIC'
                                           })
        self.service.startService()

    def tearDown(self):
        # kill the service we started before the test
        return self.service.stopService()

    @defer.inlineCallbacks
    def complete_game(self):
        self.winner_card = winner_card = 5
        sentence = 'SENTENCE'
        owner_id = 15
        result = yield self.service.create({'card': [winner_card],
                                            'sentence': [sentence],
                                            'owner_id': [owner_id]})
        game_id = result['game_id']

        yield self.service.set_card({'action': ['set_card'],
                                     'card': [winner_card],
                                     'player_id': [owner_id],
                                     'game_id': [game_id]})

        yield self.service.set_sentence({'action': ['set_sentence'],
                                         'sentence': [sentence],
                                         'player_id': [owner_id],
                                         'game_id': [game_id]})

        self.player1 = 16
        for player_id in (self.player1, 17):
            yield self.service.participate({ 'action': ['participate'],
                                             'player_id': [player_id],
                                             'game_id': [game_id] })
            player = yield self.service.player2game({ 'action': ['player2game'],
                                                      'player_id': [player_id],
                                                      'game_id': [game_id] })
            card = player['cards'][0]
            yield self.service.pick({ 'action': ['pick'],
                                      'player_id': [player_id],
                                      'game_id': [game_id],
                                      'card': [card] })

        yield self.service.voting({ 'action': ['voting'],
                                    'game_id': [game_id],
                                    'owner_id': [owner_id] })
        winner_id = self.player1
        yield self.service.vote({ 'action': ['vote'],
                                  'game_id': [game_id],
                                  'player_id': [winner_id],
                                  'card': [winner_card] })
        loser_id = 17
        yield self.service.vote({ 'action': ['vote'],
                                  'game_id': [game_id],
                                  'player_id': [loser_id],
                                  'card': [120] })
        self.assertTrue(self.service.games.has_key(game_id))
        yield self.service.complete({ 'action': ['complete'],
                                      'game_id': [game_id],
                                      'owner_id': [owner_id] })
        self.assertFalse(self.service.games.has_key(game_id))
        defer.returnValue(True)

    def test00_create_logdir(self):
        chat_instance = Plugin(self.service, [])
        logdir = os.path.join(self.test_logdir, 'chat')
        self.assertTrue(os.path.exists(logdir))

    @defer.inlineCallbacks
    def test00_preprocess_noop(self):
        # create a new instance of the plugin and make sure it's the right type
        chat_instance = Plugin(self.service, [])
        self.assertEquals(chat_instance.name(), 'chat')
        # run a game to get into a realistic situation
        yield self.complete_game()
        # run the preprocess method and make sure it does not affect anything during a normal 'game' event
        result_in = 'RESULT'
        result_out = yield chat_instance.preprocess(result_in, Request(action=['game']))
        self.assertEquals(result_in, result_out)

    @defer.inlineCallbacks
    def test01_add_message(self):
        # new instance of the chat plugin to test
        chat_instance = Plugin(self.service, [])
        # create a message event request
        player_id = 200
        sentence = "This is my sentence!"
        now = int(runtime.seconds() * 1000)
        request = Request(action=['message'], player_id=[player_id], sentence=[sentence])
        # verify we have no messages yet
        self.assertEquals(len(chat_instance.messages), 0)
        # run the request
        result = yield chat_instance.preprocess(True, request)
        # verify we now have one message
        self.assertEquals(len(chat_instance.messages), 1)
        # verify the event has been removed from the pipeline
        self.assertFalse(request.args.has_key('action'))
        # verify the message we added is in the list
        self.assertEquals(chat_instance.messages[0]["player_id"], player_id)
        self.assertEquals(chat_instance.messages[0]["sentence"], sentence)
        # check that the message has been recorded in log file
        with open(os.path.join(self.test_logdir, 'chat', '%s.log' % strftime('%Y-%m-%d'))) as f:
            lines = f.readlines()
            self.assertEquals(len(lines), 1)
            self.assertIn(sentence, lines[0])
            self.assertIn('player_%d' % player_id, lines[0])


    @defer.inlineCallbacks
    def test02_check_added_message_after_now(self):
        # new instance of the chat plugin to test
        chat_instance = Plugin(self.service, [])
        # create a message event request
        player_id = 200
        sentence = "This is my sentence!"
        now = int(runtime.seconds() * 1000)
        request = Request(action=['message'], player_id=[player_id], sentence=[sentence])
        # run the request
        result = yield chat_instance.preprocess(True, request)
        # check to make sure no message is returned if we ask for now or later
        state, players_id_list = yield chat_instance.state({"modified": [now + 1]})
        self.assertTrue(state.has_key('messages'))
        self.assertEquals(len(state['messages']), 0)
        self.assertEquals(players_id_list, [])

    @defer.inlineCallbacks
    def test03_check_added_message_before_now(self):
        # new instance of the chat plugin to test
        chat_instance = Plugin(self.service, [])
        # create a message event request
        player_id = 200
        sentence = "This is my sentence!"
        now = int(runtime.seconds() * 1000)
        request = Request(action=['message'], player_id=[player_id], sentence=[sentence])
        # run the request
        result = yield chat_instance.preprocess(True, request)
        # check to make sure no message is returned if we ask for now or later
        state, players_id_list = yield chat_instance.state({"modified": [now - 1]})
        self.assertEquals(len(state['messages']), 1)
        self.assertEquals(state['messages'][0]['player_id'], player_id)
        self.assertEquals(state['messages'][0]['sentence'], sentence)
        self.assertEquals(players_id_list, [player_id])

    @defer.inlineCallbacks
    def test04_check_multiple_messages(self):
        # new instance of the chat plugin to test
        chat_instance = Plugin(self.service, [])
        # create a message event request
        player_ids = [200, 220, 999]
        sentences = ["This is my sentence!", "Yeah another test hello.", "Ping ping poing pong."]
        when = []
        for i in range(3):
            when.append(int(runtime.seconds() * 1000))
            request = Request(action=['message'], player_id=[player_ids[i]], sentence=[sentences[i]])
            # run the request
            result = yield chat_instance.preprocess(True, request)
        # check to make sure no message is returned if we ask for now or later
        # we check right back to one second ago to make sure all recently added messages are caught
        state, players_id_list = yield chat_instance.state({"modified": [when[-1] - 1000]})
        self.assertEquals(len(state['messages']), 3)
        for i in range(3):
            self.assertEquals(state['messages'][i]['player_id'], player_ids[i])
            self.assertEquals(state['messages'][i]['sentence'], sentences[i])
        self.assertEquals(players_id_list, player_ids)

    @defer.inlineCallbacks
    def test05_check_half_of_multiple_messages(self):
        # new instance of the chat plugin to test
        chat_instance = Plugin(self.service, [])
        # create a message event request
        player_ids = [200, 220, 999]
        sentences = ["This is my sentence!", "Yeah another test hello.", "Ping ping poing pong."]
        when = []
        for i in range(3):
            sleep(0.1)
            when.append(int(runtime.seconds() * 1000))
            request = Request(action=['message'], player_id=[player_ids[i]], sentence=[sentences[i]])
            # run the request
            result = yield chat_instance.preprocess(True, request)
        # check to make sure no message is returned if we ask for now or later
        # we check right back to one second ago to make sure all recently added messages are caught
        state, players_id_list = yield chat_instance.state({"modified": [when[-1] - 150]})
        # this time because of the 100ms delay between messages, and only checking to 150ms ago
        # we should only get the last two messages
        self.assertEquals(len(state['messages']), 2)
        for i in range(2):
            self.assertEquals(state['messages'][i]['player_id'], player_ids[i + 1])
            self.assertEquals(state['messages'][i]['sentence'], sentences[i + 1])
        self.assertEquals(players_id_list, player_ids[-2:])

    @defer.inlineCallbacks
    def test06_touch_state(self):
        player_id = 200
        sentence = "This is my sentence!"
        # new instance of chat plugin to run the test against
        chat_instance = Plugin(self.service, [])
        # put the chat instance into the service's pollable_plugins
        self.service.pollable_plugins.append(chat_instance)
        # flag to signify whether the callback has run
        self.called = False
        # service to poll instance waiting for chat
        d = self.service.poll({'action': ['poll'],
                               'player_id': [player_id],
                               'type': ['chat'],
                               'modified': [chat_instance.get_modified()]})
        # callback which runs once the chat plugin calls touch()
        def check(event):
            self.called = True
        d.addCallback(check)
        # make sure our flag is false before we run
        self.assertFalse(self.called)
        # run the test request
        request = Request(action=['message'], player_id=[player_id], sentence=[sentence])
        result = yield chat_instance.preprocess(True, request)
        yield d
        # make sure the flag is now set after we've run the test
        self.assertTrue(self.called)

    @defer.inlineCallbacks
    def test07_notification_messages(self):
        # new instance of chat plugin to run the test against
        chat_instance = Plugin(self.service, [])

        self.count = 0
        def build_message(self, message):
            """
            message == {'type': 'notification',
                        'game_id': GAME_ID,
                        'player_id': 'OWNER_ID',
                        'sentence': 'SENTENCE'}

            """
            self.count += 1
            self.assertEquals(self.count, 1)
            self.assertEquals(message['type'], 'notification')
            self.assertEquals(message['player_id'], '15')
            self.assertEquals(message['sentence'], 'SENTENCE')

        # build_message should only be called once, upon game creation.
        chat_instance.build_message = build_message
        # run a game to get into a realistic situation
        yield self.complete_game()

    @defer.inlineCallbacks
    def test08_nonascii_characters_message(self):
        # new instance of the chat plugin to test
        chat_instance = Plugin(self.service, [])
        # create a message event request
        player_id = 200
        # The sentence is a 'str' object. Create it by encoding a unicode string.
        unicode_sentence = u"你好 Matjaž Gregorič"
        sentence_bytes = unicode_sentence.encode('utf-8')
        request = Request(action=['message'], player_id=[player_id], sentence=[sentence_bytes])
        # run the request
        result = yield chat_instance.preprocess(True, request)
        # check that the message has been recorded in log file
        with open(os.path.join(self.test_logdir, 'chat', '%s.log' % strftime('%Y-%m-%d'))) as f:
            lines = f.readlines()
            self.assertIn(unicode_sentence, lines[0].decode('utf-8'))

    @defer.inlineCallbacks
    def test09_nonascii_characters_notification(self):
        # new instance of the chat plugin to test
        chat_instance = Plugin(self.service, [])
        # create a message event request
        class FakeGame:
            id = 102
            owner_id = 303
        unicode_sentence = u"我不明白 šal čez želodec"
        changes = {'type': 'change',
                   'details': {'type': 'load',
                               'sentence': unicode_sentence},
                   'game': FakeGame()}
        result = yield chat_instance.self_notify(changes)
        with open(os.path.join(self.test_logdir, 'chat', '%s.log' % strftime('%Y-%m-%d'))) as f:
            lines = f.readlines()
            self.assertIn(unicode_sentence, lines[0].decode('utf-8'))

    @defer.inlineCallbacks
    def test10_escape_html(self):
        # new instance of the chat plugin to test
        chat_instance = Plugin(self.service, [])
        # create a message event request
        player_id = 201
        naughty_sentence = '<script>alert("haha!")</script>'
        now = int(runtime.seconds() * 1000)
        request = Request(action=['message'], player_id=[player_id], sentence=[naughty_sentence])
        # run the request
        result = yield chat_instance.preprocess(True, request)
        # check to make sure our naughty message is returned properly escaped
        state, players_id_list = yield chat_instance.state({"modified": [now - 1]})
        self.assertEquals(state['messages'][0]['player_id'], player_id)
        self.assertEquals(state['messages'][0]['sentence'], '&lt;script&gt;alert("haha!")&lt;/script&gt;')

    @defer.inlineCallbacks
    def test11_link_url(self):
        # new instance of the chat plugin to test
        chat_instance = Plugin(self.service, [])
        # create a message event request
        player_id = 201
        url_sentence = 'For searching the web I use google.com, it\'s great!'
        now = int(runtime.seconds() * 1000)
        request = Request(action=['message'], player_id=[player_id], sentence=[url_sentence])
        # run the request
        result = yield chat_instance.preprocess(True, request)
        # check to make sure our message is returned with a link for the url
        state, players_id_list = yield chat_instance.state({"modified": [now - 1]})
        self.assertEquals(state['messages'][0]['player_id'], player_id)
        self.assertEquals(state['messages'][0]['sentence'], 'For searching the web I use <a target="_blank" href="http://google.com">google.com</a>, it\'s great!')
예제 #5
0
class MailTest(unittest.TestCase):

    def setUp(self):
        self.database = 'test.sqlite'
        if os.path.exists(self.database):
            os.unlink(self.database)
        self.service = CardstoriesService({'db': self.database,
                                           'plugins-libdir': '../fixture',
                                           'plugins-confdir': '../fixture',
                                           'plugins-dir': '../fixture'})
        self.service.startService()

    def tearDown(self):
        return self.service.stopService()

    @defer.inlineCallbacks
    def complete_game(self):
        self.owner_id = 1
        self.player1 = 2
        self.player2 = 3
        self.owner_email = '*****@*****.**'
        self.player1_email = '*****@*****.**'
        self.player2_email = '*****@*****.**'
        self.winner_card = winner_card = 5
        sentence = 'SENTENCE'
        game = yield self.service.create({'owner_id': [self.owner_id]})
        self.game_id = game['game_id']
        yield self.service.set_card({ 'action': ['set_card'],
                                      'card': [winner_card],
                                      'game_id': [self.game_id],
                                      'player_id': [self.owner_id] })
        yield self.service.set_sentence({ 'action': ['set_sentence'],
                                          'sentence': [sentence],
                                          'game_id': [self.game_id],
                                          'player_id': [self.owner_id] })
        yield self.service.invite({ 'action': ['invite'],
                                    'game_id': [self.game_id],
                                    'invited_email': [self.player1_email],
                                    'owner_id': [self.owner_id] })
        for player_id in (self.player1, self.player2):
            yield self.service.participate({ 'action': ['participate'],
                                             'player_id': [player_id],
                                             'game_id': [self.game_id] })
            player = yield self.service.player2game({ 'action': ['player2game'],
                                                      'player_id': [player_id],
                                                      'game_id': [self.game_id] })
            card = player['cards'][0]
            yield self.service.pick({ 'action': ['pick'],
                                      'player_id': [player_id],
                                      'game_id': [self.game_id],
                                      'card': [card] })

        yield self.service.voting({ 'action': ['voting'],
                                    'game_id': [self.game_id],
                                    'owner_id': [self.owner_id] })
        winner_id = self.player1
        yield self.service.vote({ 'action': ['vote'],
                                  'game_id': [self.game_id],
                                  'player_id': [winner_id],
                                  'card': [winner_card] })
        loser_id = self.player2
        yield self.service.vote({ 'action': ['vote'],
                                  'game_id': [self.game_id],
                                  'player_id': [loser_id],
                                  'card': [120] })
        self.assertTrue(self.service.games.has_key(self.game_id))
        yield self.service.complete({ 'action': ['complete'],
                                      'game_id': [self.game_id],
                                      'owner_id': [self.owner_id] })
        self.assertFalse(self.service.games.has_key(self.game_id))
        defer.returnValue(True)

    def test00_init(self):
        plugin = mail.Plugin(self.service, [ ])
        self.assertEquals(plugin.name(), 'mail')
        self.assertEquals(plugin.host, 'localhost')
        for allowed in mail.Plugin.ALLOWED:
            self.assertTrue(plugin.templates.has_key(allowed))

    @defer.inlineCallbacks
    def test01_invite(self):
        plugin = mail.Plugin(self.service, [ ])

        def get_player_email(player_id):
            if player_id == self.player1:
                email = self.player1_email
            elif player_id == self.player2:
                email = self.player2_email
            elif player_id == self.owner_id:
                email = self.owner_email
            return defer.succeed(email)
        self.service.auth.get_player_email = get_player_email

        def get_player_id(email, create=False):
            return defer.succeed(self.player1)
        self.service.auth.get_player_id = get_player_id

        self.count = 0

        def sendmail(host, sender, recipients, email):
            self.count += 1
            self.assertSubstring('game_id=%d' % self.game_id, email)
            self.assertSubstring('url=URL', email)
            self.assertSubstring('static_url=STATIC_URL', email)
            if self.count == 1:
                self.assertSubstring('_INVITE_', email)
                self.assertSubstring('owner_email=%s' % self.owner_name, email)
            elif self.count in (2, 3) :
                self.assertSubstring('_PICK_', email)
                if self.count == 2:
                    self.assertSubstring('player_email=%s' % self.player1_name, email)
                elif self.count == 3:
                    self.assertSubstring('player_email=%s' % self.player2_name, email)
            elif self.count in (4, 5) :
                self.assertSubstring('_VOTE_', email)
                if self.count == 4:
                    self.assertSubstring('player_email=%s' % self.player1_name, email)
                elif self.count == 5:
                    self.assertSubstring('player_email=%s' % self.player2_name, email)
            elif self.count == 6:
                self.assertSubstring('_VOTING_', email)
            elif self.count == 7:
                self.assertSubstring('_COMPLETE_', email)
                self.assertSubstring('owner_email=%s' % self.owner_name, email)
            return defer.succeed(True)
        plugin.sendmail = sendmail

        yield self.complete_game()
        self.assertEqual(self.count, 7)

    @defer.inlineCallbacks
    def test02_send_nothing(self):
        self.service.auth.get_players_emails = Mock(return_value=['not_an_email'])
        plugin = mail.Plugin(self.service, [ ])
        d = plugin.send('SUBJECT', [ 1 ], 'TEMPLATE', {})
        def check(result):
            self.assertFalse(result)
        d.addCallback(check)
        yield d
예제 #6
0
class BotTest(unittest.TestCase):

    # initialise our test with a service that we can use during testing and a testing database
    def setUp(self):
        self.database = 'test.sqlite'
        if os.path.exists(self.database):
            os.unlink(self.database)

        self.service = CardstoriesService({'db': self.database,
                                           'plugins-confdir': '../fixture',
                                           'plugins-libdir': 'LIBDIR',
                                           'static': 'STATIC'
                                           })
        self.service.auth = Mock()
        self.service.startService()

    def tearDown(self):
        # kill the service we started before the test
        return self.service.stopService()

    @defer.inlineCallbacks
    def game_create(self):
        """Creates the game, sets the card, and sets the sentence in one step."""
        self.winner_card = winner_card = 5
        sentence = 'SENTENCE'
        self.owner_id = 15
        result = yield self.service.create({'owner_id': [self.owner_id]})
        game_id = result['game_id']
        yield self.service.set_card({'action': ['set_card'],
                                     'card': [winner_card],
                                     'player_id': [self.owner_id],
                                     'game_id': [game_id]})
        yield self.service.set_sentence({'action': ['set_sentence'],
                                         'sentence': [sentence],
                                         'player_id': [self.owner_id],
                                         'game_id': [game_id]})

        defer.returnValue(result)

    @defer.inlineCallbacks
    def game_to_vote(self, game_id):
        yield self.service.voting({ 'action': ['voting'],
                                    'game_id': [game_id],
                                    'owner_id': [self.owner_id] })
        self.assertTrue(self.service.games.has_key(game_id))
        defer.returnValue(True)

    @defer.inlineCallbacks
    def game_to_complete(self, game_id):
        yield self.service.complete({ 'action': ['complete'],
                                      'game_id': [game_id],
                                      'owner_id': [self.owner_id] })
        self.assertFalse(self.service.games.has_key(game_id))
        defer.returnValue(True)

    @defer.inlineCallbacks
    def test01_play_game(self):
        mock_reactor = bot.reactor = Mock() # Don't delay calls

        bot_plugin = bot.Plugin(self.service, [])
        self.assertEquals(bot_plugin.name(), 'bot')
        bots = [bot_plugin.bots[0], bot_plugin.bots[1], bot_plugin.bots[2]]
        self.assertEqual(bots[0].player_id, 2)
        self.assertEqual(bots[1].player_id, 3)
        self.assertEqual(bots[2].player_id, 4)

        # New game
        game = yield self.game_create()
        game_id = game['game_id']
        mock_reactor.callLater.assert_called_once_with(1, bot_plugin.check_need_player, game_id)
        mock_reactor.reset_mock()

        # Only the author in the game
        game, players_ids = yield bots[0].get_game_by_id(game_id)
        self.assertEqual(len(game['players']), 1)

        # Bots don't join by default
        yield bot_plugin.check_need_player(game_id)
        self.assertEqual(len(mock_reactor.callLater.call_args_list), 0)

        # Enable joining
        request = Request(action=['bot'], enable_join=['true'], game_id=[str(game_id)])
        result = yield bot_plugin.preprocess(True, request)
        self.assertFalse(request.args.has_key('action'))
        self.assertTrue(bot_plugin.enable_join[game_id])
        mock_reactor.reset_mock()

        # Bots join after enabling it
        for i in xrange(2):
            yield bot_plugin.check_need_player(game_id)
            self.assertEqual(len(mock_reactor.callLater.call_args_list), 2)
            mock_reactor.reset_mock()

            game, player_ids = yield bots[i].get_game_by_id(game_id)
            self.assertEqual(game['players'][i + 1]['id'], bots[i].player_id)
            self.assertEqual(game['players'][i + 1]['picked'], None)

        # Bots pick a card
        for i in xrange(2):
            yield bots[i].pick(game_id)
            self.assertFalse(mock_reactor.called)

            game, player_ids = yield bots[i].get_game_by_id(game_id, player_id=bots[i].player_id)
            self.assertIsInstance(game['players'][i + 1]['picked'], int)
            self.assertEqual(game['players'][i + 1]['vote'], None)

        # Go to vote phase
        yield self.game_to_vote(game_id)
        self.assertEqual(mock_reactor.callLater.call_args_list,
                         [((3, bots[0].vote, game_id), {}),
                          ((3, bots[1].vote, game_id), {})])
        mock_reactor.reset_mock()

        # A bot should never join or pick at this stage
        joined = yield bots[2].join(game_id)
        self.assertFalse(joined)
        picked = yield bots[2].pick(game_id)
        self.assertFalse(picked)

        # Bots vote
        for i in xrange(2):
            yield bots[i].vote(game_id)
            self.assertFalse(mock_reactor.called)

            game, player_ids = yield bots[i].get_game_by_id(game_id, player_id=bots[i].player_id)
            self.assertIsInstance(game['players'][i + 1]['picked'], int)
            self.assertEqual(game['players'][i + 1]['vote'], '')

        # A bot should never vote at this stage
        joined = yield bots[2].vote(game_id)
        self.assertFalse(joined)

    def test02_brain_not_implemented(self):
        brain = bot.Brain(None)
        self.assertRaises(NotImplementedError, brain.get_all_cards_scores_for_sentence, "Test")

    def test03_brain_weighted_card_choice(self):
        brain = bot.Brain(None)
        ranked_cards = [(1, 1), (2, 10000), (3, 0), (4, 0), (5, 0), (6, 0), (7, 0), (8, 0), (9, 0)]
        chosen_card = brain.weighted_card_choice(ranked_cards)
        self.assertTrue(chosen_card == 1 or chosen_card == 2)

    @defer.inlineCallbacks
    def test04_nlwordmatcherbrain(self):
        bot_plugin = bot.Plugin(self.service, [])
        brain = bot.NLWordMatcherBrain(bot_plugin)

        # Make sure we can record scores for cards that are earned (card # > NCARDS)
        max_cards = 42
        assert CardstoriesGame.NCARDS < max_cards <= CardstoriesGame.NCARDS_EARNED

        ranked_cards = yield brain.sort_cards_by_ranking_for_sentence("word", [1, 2, 3, 42])
        self.assertEquals(ranked_cards, [(3, 4), (2, 3), (1, 2), (max_cards, 1)])