def test_missed_behavior(self):
        wwg = WordwallsGame()
        table_id, user = self.round_1()
        wgm = wwg.get_wgm(table_id)
        word_list = wgm.word_list
        self.assert_wl(word_list, {
            'numAlphagrams': 11, 'numCurAlphagrams': 11,
            'numFirstMissed': 6, 'numMissed': 6, 'goneThruOnce': True,
            'questionIndex': 15, 'is_temporary': True
        })
        qs = json.loads(word_list.origQuestions)
        self.assertEqual(len(qs), 11)
        # Now start the quiz again. Should get missed words.
        self.round_2(table_id, user)
        wgm = wwg.get_wgm(table_id)
        word_list = wgm.word_list
        self.assert_wl(word_list, {
            'numAlphagrams': 11, 'numCurAlphagrams': 6,
            'numFirstMissed': 6, 'numMissed': 2, 'goneThruOnce': True,
            'questionIndex': 10, 'is_temporary': True
        })

        qs = json.loads(word_list.origQuestions)
        self.assertEqual(len(qs), 11)

        # Finally, let's solve the final two alphagrams.
        self.round_3(table_id, user)
        wgm = wwg.get_wgm(table_id)
        word_list = wgm.word_list
        self.assert_wl(word_list, {
            'numAlphagrams': 11, 'numCurAlphagrams': 2,
            'numFirstMissed': 6, 'numMissed': 0, 'goneThruOnce': True,
            'questionIndex': 5, 'is_temporary': True
        })

        # And try to start the quiz again.
        params = wwg.start_quiz(table_id, user)
        self.assertTrue('quiz is done' in params['error'])
        wgm = wwg.get_wgm(table_id)
        word_list = wgm.word_list
        self.assert_wl(word_list, {
            'numAlphagrams': 11, 'numCurAlphagrams': 0,
            'numFirstMissed': 6, 'numMissed': 0, 'goneThruOnce': True,
            'questionIndex': 0, 'is_temporary': True
        })

        # Try saving the word list.
        LIST_NAME = 'my cool lišt'
        resp = wwg.save(user, table_id, LIST_NAME)
        self.assertTrue(resp['success'])
        self.assertEqual(resp['listname'], LIST_NAME)
        wgm = wwg.get_wgm(table_id)
        word_list = wgm.word_list
        self.assert_wl(word_list, {
            'numAlphagrams': 11, 'numCurAlphagrams': 0,
            'numFirstMissed': 6, 'numMissed': 0, 'goneThruOnce': True,
            'questionIndex': 0, 'is_temporary': False, 'name': LIST_NAME
        })
Beispiel #2
0
    def test_missed_behavior(self):
        wwg = WordwallsGame()
        table_id, user = self.round_1()
        wgm = wwg.get_wgm(table_id)
        word_list = wgm.word_list
        self.assert_wl(word_list, {
            'numAlphagrams': 11, 'numCurAlphagrams': 11,
            'numFirstMissed': 6, 'numMissed': 6, 'goneThruOnce': True,
            'questionIndex': 15, 'is_temporary': True
        })
        qs = json.loads(word_list.origQuestions)
        self.assertEqual(len(qs), 11)
        # Now start the quiz again. Should get missed words.
        self.round_2(table_id, user)
        wgm = wwg.get_wgm(table_id)
        word_list = wgm.word_list
        self.assert_wl(word_list, {
            'numAlphagrams': 11, 'numCurAlphagrams': 6,
            'numFirstMissed': 6, 'numMissed': 2, 'goneThruOnce': True,
            'questionIndex': 10, 'is_temporary': True
        })

        qs = json.loads(word_list.origQuestions)
        self.assertEqual(len(qs), 11)

        # Finally, let's solve the final two alphagrams.
        self.round_3(table_id, user)
        wgm = wwg.get_wgm(table_id)
        word_list = wgm.word_list
        self.assert_wl(word_list, {
            'numAlphagrams': 11, 'numCurAlphagrams': 2,
            'numFirstMissed': 6, 'numMissed': 0, 'goneThruOnce': True,
            'questionIndex': 5, 'is_temporary': True
        })

        # And try to start the quiz again.
        params = wwg.start_quiz(table_id, user)
        self.assertTrue('quiz is done' in params['error'])
        wgm = wwg.get_wgm(table_id)
        word_list = wgm.word_list
        self.assert_wl(word_list, {
            'numAlphagrams': 11, 'numCurAlphagrams': 0,
            'numFirstMissed': 6, 'numMissed': 0, 'goneThruOnce': True,
            'questionIndex': 0, 'is_temporary': True
        })

        # Try saving the word list.
        LIST_NAME = u'my cool lišt'
        resp = wwg.save(user, table_id, LIST_NAME)
        self.assertTrue(resp['success'])
        self.assertEqual(resp['listname'], LIST_NAME)
        wgm = wwg.get_wgm(table_id)
        word_list = wgm.word_list
        self.assert_wl(word_list, {
            'numAlphagrams': 11, 'numCurAlphagrams': 0,
            'numFirstMissed': 6, 'numMissed': 0, 'goneThruOnce': True,
            'questionIndex': 0, 'is_temporary': False, 'name': LIST_NAME
        })
Beispiel #3
0
def table(request, tableid=None):
    if request.method == 'POST':
        return handle_table_post(request, tableid)
    # Otherwise, it's a GET
    wwg = WordwallsGame()
    if tableid:
        # Check if the user is allowed to enter this table.
        permitted = wwg.allow_access(request.user, tableid)
        if gargoyle.is_active('disable_games', request):
            permitted = False
        if not permitted:
            return render(request, 'wordwalls/notPermitted.html',
                          {'tablenum': tableid})
    params = wwg.get_add_params(tableid)
    # Add styling params from user's profile (for styling table
    # tiles, backgrounds, etc)
    profile = request.user.aerolithprofile
    style = profile.customWordwallsStyle
    if style != "":
        params['style'] = style

    meta_info = get_create_meta_info()
    usermeta = get_user_meta_info(request.user)
    wgm = None
    if tableid:
        wgm = wwg.get_wgm(tableid, False)

    return render(
        request,
        'wordwalls/table.html',
        {
            'tablenum':
            tableid if tableid else 0,
            'current_host':
            wgm.host.username if wgm else '',
            'multiplayer': (json.dumps(wgm.playerType == WordwallsGameModel.
                                       MULTIPLAYER_GAME if wgm else False)),
            'user':
            json.dumps(usermeta),
            'addParams':
            json.dumps(params),
            'avatarUrl':
            profile.avatarUrl,
            'lexicon':
            wgm.lexicon.lexiconName if wgm else None,
            'default_lexicon':
            profile.defaultLexicon.pk,
            'challenge_info':
            json.dumps(meta_info['challenge_info']),
            'available_lexica':
            json.dumps(meta_info['lexica']),
            'intercom_app_id':
            settings.INTERCOM_APP_ID,
            # Use the webpack server if DEBUG is on. XXX This might not actually
            # be a good test; consider using an IS_PRODUCTION flag.
            'STATIC_SRV':
            (settings.WEBPACK_DEV_SERVER_URL if
             (settings.USE_WEBPACK_DEV_SERVER and settings.DEBUG) else '')
        })
Beispiel #4
0
    def test_replace_challenge(self):
        result = self.client.post('/wordwalls/api/new_challenge/',
                                  data=json.dumps({
                                      'lexicon': 9,
                                      'challenge': 14,
                                      'date': '2013-11-29',
                                      'tablenum': 0
                                  }),
                                  content_type='application/json')
        self.assertEqual(result.status_code, 200)
        content = json.loads(result.content)
        response = self.client.get('/wordwalls/table/{0}/'.format(
            content['tablenum']))
        addl_params = json.loads(response.context['addParams'])
        tablenum = int(response.context['tablenum'])
        self.assertEqual(addl_params['tempListName'],
                         'NWL18 Today\'s 15s - 2013-11-29')

        game = WordwallsGame()
        old_word_list = game.get_wgm(tablenum, lock=False).word_list
        self.assertTrue(old_word_list.is_temporary)
        self.assertTrue(old_word_list.pk > 0)
        old_pk = old_word_list.pk

        result = self.client.post('/wordwalls/api/new_challenge/',
                                  data=json.dumps({
                                      'tablenum': tablenum,
                                      'lexicon': 12,
                                      'challenge': 7,
                                      'date': '2016-10-12'
                                  }),
                                  content_type='application/json')
        result_obj = json.loads(result.content)
        self.assertEqual(result_obj['tablenum'], tablenum)
        expected_list_name = 'CSW19 Today\'s 8s - 2016-10-12'
        self.assertEqual(result_obj['list_name'], expected_list_name)
        self.assertFalse(result_obj['autosave'])
        game = WordwallsGame()
        wl = game.get_wgm(tablenum, lock=False).word_list
        orig_questions = json.loads(wl.origQuestions)
        self.assertEqual(len(orig_questions), 50)
        self.assertEqual(len(orig_questions[28]['q']), 8)
        # Check that old word list got deleted.
        with self.assertRaises(WordwallsGameModel.DoesNotExist):
            WordwallsGameModel.objects.get(pk=old_pk)
Beispiel #5
0
 def test_quiz_ends_after_time(self, timer_ran_out):
     # Mock timer running out by the time the guess comes in.
     timer_ran_out.return_value = True
     table_id, user = self.setup_quiz()
     wwg = WordwallsGame()
     wwg.start_quiz(table_id, user)
     guess_state = wwg.guess('CATS', table_id, user)
     self.assertFalse(guess_state['going'])
     self.assertEqual(guess_state['alphagram'], '')
     wgm = wwg.get_wgm(table_id)
     state = json.loads(wgm.currentGameState)
     self.assertFalse(state['quizGoing'])
 def test_quiz_ends_after_time(self, timer_ran_out):
     # Mock timer running out by the time the guess comes in.
     timer_ran_out.return_value = True
     table_id, user = self.setup_quiz()
     wwg = WordwallsGame()
     wwg.start_quiz(table_id, user)
     guess_state = wwg.guess('CATS', table_id, user)
     self.assertFalse(guess_state['going'])
     self.assertEqual(guess_state['alphagram'], '')
     wgm = wwg.get_wgm(table_id)
     state = json.loads(wgm.currentGameState)
     self.assertFalse(state['quizGoing'])
Beispiel #7
0
 def test_word_list_created(self):
     table_id, user = self.setup_quiz()
     wwg = WordwallsGame()
     wgm = wwg.get_wgm(table_id)
     word_list = wgm.word_list
     self.assert_wl(word_list, {
         'version': 2,
         'lexicon': Lexicon.objects.get(lexiconName='America'),
         'user': user, 'numAlphagrams': 81, 'numCurAlphagrams': 81,
         'numFirstMissed': 0, 'numMissed': 0, 'goneThruOnce': False,
         'questionIndex': 0, 'is_temporary': True
     })
     # The name should be a random uuid.
     self.assertEqual(len(word_list.name), 32)
     qs = json.loads(word_list.origQuestions)
     self.assertEqual(len(qs), 81)
     # Search for one in particular
     self.assertTrue({'q': 'AEEINRSU', 'a': ['UNEASIER']} in qs)
 def test_word_list_created(self):
     logger.debug('In test_word_list_created')
     table_id, user = self.setup_quiz()
     wwg = WordwallsGame()
     wgm = wwg.get_wgm(table_id)
     word_list = wgm.word_list
     self.assert_wl(word_list, {
         'version': 2,
         'lexicon': Lexicon.objects.get(lexiconName='NWL18'),
         'user': user, 'numAlphagrams': 81, 'numCurAlphagrams': 81,
         'numFirstMissed': 0, 'numMissed': 0, 'goneThruOnce': False,
         'questionIndex': 0, 'is_temporary': True
     })
     # The name should be a random uuid.
     self.assertEqual(len(word_list.name), 32)
     qs = json.loads(word_list.origQuestions)
     self.assertEqual(len(qs), 81)
     # Search for one in particular
     self.assertTrue({'q': 'AEEINRSU', 'a': ['UNEASIER']} in qs)
Beispiel #9
0
def log(request):
    body = json.loads(request.body)
    if body['type'] == 'nothost':
        tablenum = body['tablenum']
        current_host = body['currentHost']
        username = body['username']
        multiplayer = body['tableIsMultiplayer']
        wgm = None
        if tablenum:
            wwg = WordwallsGame()
            wgm = wwg.get_wgm(tablenum, False)
            actual_host = wgm.host.username if wgm.host else None
            players_in = ', '.join([u.username for u in wgm.inTable.all()])
            logger.info(
                '[event=nothost] tablenum=%s current_host=%s username=%s '
                'multiplayer=%s actual_host=%s players_in="%s"', tablenum,
                current_host, username, multiplayer, actual_host, players_in)

    return response('OK')
Beispiel #10
0
def table_response(tablenum):
    game = WordwallsGame()
    addl_params = game.get_add_params(tablenum)
    wgm = game.get_wgm(tablenum, lock=False)

    # Sometimes, 'tempListName' will not be in addl_params, when this
    # is loading an already existing saved list. Instead, get from saveName.
    if addl_params.get("saveName"):
        autosave = True
        list_name = addl_params["saveName"]
    else:
        autosave = False
        list_name = addl_params["tempListName"]
    return response(
        {
            "tablenum": tablenum,
            "list_name": list_name,
            "lexicon": wgm.lexicon.lexiconName,
            "autosave": autosave,
            "multiplayer": addl_params.get("multiplayer", False),
        }
    )
Beispiel #11
0
 def test_continue_list_multiplayer(self):
     # Fist load a new challenge, to create a table.
     result = self.client.post('/wordwalls/api/new_challenge/',
                               data=json.dumps({
                                   'lexicon': 7,
                                   'challenge': 14,
                                   'tablenum': 0,
                                   'date': '2013-11-29'
                               }),
                               content_type='application/json')
     self.assertEqual(result.status_code, 200)
     content = json.loads(result.content)
     tablenum = content['tablenum']
     # Now try to continue a saved list in multiplayer mode.
     result = self.client.post('/wordwalls/api/load_saved_list/',
                               data=json.dumps({
                                   'lexicon': 7,
                                   'desiredTime': 5,
                                   'questionsPerRound': 50,
                                   'selectedList': 2,
                                   'tablenum': tablenum,
                                   'listOption': 'continue',
                                   'multiplayer': True
                               }),
                               content_type='application/json')
     logger.debug(result.content)
     self.assertEqual(result.status_code, 200)
     # We should make a new copy of the word list, instead of use
     # the existing one.
     game = WordwallsGame()
     new_word_list = game.get_wgm(tablenum, lock=False).word_list
     old_word_list = WordList.objects.get(pk=2)
     self.assertEqual(new_word_list.origQuestions,
                      old_word_list.origQuestions)
     self.assertTrue(new_word_list.is_temporary)
     self.assertFalse(old_word_list.is_temporary)
Beispiel #12
0
def table(request, id):
    if request.method == 'POST':
        action = request.POST['action']
        logger.debug(u'user=%s, action=%s, table=%s', request.user, action, id)
        if action == "start":
            return start_game(request, id)
        elif action == "guess":
            logger.debug(u'guess=%s', request.POST['guess'])
            wwg = WordwallsGame()
            state = wwg.guess(request.POST['guess'].strip(), id, request.user)
            if state is None:
                return response(_('Quiz is already over.'),
                                status=StatusCode.BAD_REQUEST)
            logger.debug(u'table=%s Returning %s', id, state)
            return response({'g': state['going'], 'C': state['alphagram'],
                             'w': state['word'],
                             'a': state['already_solved']})
        elif action == "gameEnded":
            wwg = WordwallsGame()
            ret = wwg.check_game_ended(id)
            # 'going' is the opposite of 'game ended'
            return response({'g': not ret})
        elif action == "giveUp":
            wwg = WordwallsGame()
            ret = wwg.give_up(request.user, id)
            return response({'g': not ret})
        elif action == "save":
            wwg = WordwallsGame()
            ret = wwg.save(request.user, id, request.POST['listname'])
            return response(ret)
        elif action == "giveUpAndSave":
            wwg = WordwallsGame()
            ret = wwg.give_up_and_save(request.user, id,
                                       request.POST['listname'])
            # this shouldn't return a response, because it's not going to be
            # caught by the javascript
            logger.debug("Give up and saving returned: %s" % ret)
            return response(ret)
        elif action == "savePrefs":
            profile = request.user.aerolithprofile
            profile.customWordwallsStyle = request.POST['prefs']
            profile.save()
            return response({'success': True})
        elif action == "getDcData":
            wwg = WordwallsGame()
            dcId = wwg.get_dc_id(id)
            if dcId > 0:
                leaderboardData = getLeaderboardDataDcInstance(
                    DailyChallenge.objects.get(pk=dcId))
                return response(leaderboardData)
        else:
            return response({'success': False},
                            status=StatusCode.BAD_REQUEST)

    else:   # it's a GET
        wwg = WordwallsGame()
        permitted = wwg.permit(request.user, id)
        if gargoyle.is_active('disable_games', request):
            permitted = False
        if not permitted:
            return render(request, 'wordwalls/notPermitted.html',
                          {'tablenum': id})
        params = wwg.get_add_params(id)
        # Add styling params from user's profile (for styling table
        # tiles, backgrounds, etc)
        profile = request.user.aerolithprofile
        style = profile.customWordwallsStyle
        if style != "":
            params['style'] = style

        return render(request, 'wordwalls/table.html',
                      {'tablenum': id,
                       'username': request.user.username,
                       'addParams': json.dumps(params),
                       'avatarUrl': profile.avatarUrl,
                       'CURRENT_VERSION': CURRENT_VERSION,
                       'lexicon': wwg.get_wgm(id).lexicon
                       })
Beispiel #13
0
 def test_replace_with_wordlist(self):
     # First, load a challenge.
     result = self.client.post('/wordwalls/api/new_challenge/',
                               data=json.dumps({
                                   'lexicon': 7,
                                   'challenge': 14,
                                   'tablenum': 0,
                                   'date': '2013-11-29'
                               }),
                               content_type='application/json')
     self.assertEqual(result.status_code, 200)
     content = json.loads(result.content)
     response = self.client.get('/wordwalls/table/{0}/'.format(
         content['tablenum']))
     addl_params = json.loads(response.context['addParams'])
     tablenum = int(response.context['tablenum'])
     self.assertEqual(addl_params['tempListName'],
                      'America Today\'s 15s - 2013-11-29')
     game = WordwallsGame()
     old_word_list = game.get_wgm(tablenum, lock=False).word_list
     self.assertTrue(old_word_list.is_temporary)
     self.assertTrue(old_word_list.pk > 0)
     old_pk = old_word_list.pk
     # Now load a new search
     result = self.client.post(
         '/wordwalls/api/new_search/',
         data=json.dumps({
             'tablenum':
             tablenum,
             'lexicon':
             12,
             'desiredTime':
             4.5,
             'questionsPerRound':
             75,
             'searchCriteria': [
                 {
                     'searchType': 1,  # see protobuf file for defs
                     'minValue': 9,
                     'maxValue': 9,
                 },
                 {
                     'searchType': 2,  # see protobuf file for defs
                     'minValue': 84,
                     'maxValue': 223,
                 }
             ]
         }),
         content_type='application/json')
     self.assertEqual(result.status_code, 200)
     result_obj = json.loads(result.content)
     self.assertEqual(result_obj['tablenum'], tablenum)
     expected_list_name = 'CSW19 9s (84 - 223)'
     self.assertEqual(result_obj['list_name'], expected_list_name)
     self.assertFalse(result_obj['autosave'])
     game = WordwallsGame()
     wl = game.get_wgm(tablenum, lock=False).word_list
     orig_questions = json.loads(wl.origQuestions)
     self.assertEqual(len(orig_questions), 140)
     self.assertEqual(len(orig_questions[18]['q']), 9)
     # Check that old word list got deleted.
     with self.assertRaises(WordwallsGameModel.DoesNotExist):
         WordwallsGameModel.objects.get(pk=old_pk)
class WordwallsNamedListTest(TestCase, WordListAssertMixin):
    """ "Named" lists. """
    fixtures = ['test/lexica.yaml',
                'test/users.json',
                'test/profiles.json',
                'test/word_lists.json',
                'test/named_lists.json']

    def setUp(self):
        self.user = User.objects.get(username='******')
        self.lex = Lexicon.objects.get(lexiconName='America')
        self.wwg = WordwallsGame()

    def test_range_list_short(self):
        table_id = self.wwg.initialize_by_named_list(
            self.lex, self.user, NamedList.objects.get(pk=3143), 240)
        self.assertNotEqual(table_id, 0)
        wgm = self.wwg.get_wgm(table_id)
        word_list = wgm.word_list
        self.assert_wl(word_list, {
            'numAlphagrams': 1000, 'numCurAlphagrams': 1000,
            'numFirstMissed': 0, 'numMissed': 0, 'goneThruOnce': False,
            'questionIndex': 0, 'is_temporary': True
        })
        orig_questions = set(json.dumps(q)
                             for q in json.loads(word_list.origQuestions))
        self.assertEqual(len(orig_questions), 1000)
        # Start the quiz.
        wwg = WordwallsGame()
        params = wwg.start_quiz(table_id, self.user)
        self.assertEqual(len(params['questions']), 50)

    def test_range_list_long(self):
        table_id = self.wwg.initialize_by_named_list(
            self.lex, self.user, NamedList.objects.get(pk=3099), 240)
        self.assertNotEqual(table_id, 0)
        wgm = self.wwg.get_wgm(table_id)
        word_list = wgm.word_list
        self.assert_wl(word_list, {
            'numAlphagrams': 21063, 'numCurAlphagrams': 21063,
            'numFirstMissed': 0, 'numMissed': 0, 'goneThruOnce': False,
            'questionIndex': 0, 'is_temporary': True
        })
        orig_questions = set(json.dumps(q)
                             for q in json.loads(word_list.origQuestions))
        self.assertEqual(len(orig_questions), 21063)
        # Start the quiz.
        wwg = WordwallsGame()
        params = wwg.start_quiz(table_id, self.user)
        self.assertEqual(len(params['questions']), 50)

    def test_individual_alphas(self):
        table_id = self.wwg.initialize_by_named_list(
            self.lex, self.user, NamedList.objects.get(pk=3092), 240)
        self.assertNotEqual(table_id, 0)
        wgm = self.wwg.get_wgm(table_id)
        word_list = wgm.word_list
        self.assert_wl(word_list, {
            'numAlphagrams': 691, 'numCurAlphagrams': 691,
            'numFirstMissed': 0, 'numMissed': 0, 'goneThruOnce': False,
            'questionIndex': 0, 'is_temporary': True
        })
        orig_questions = set(json.dumps(q)
                             for q in json.loads(word_list.origQuestions))
        self.assertEqual(len(orig_questions), 691)
        # Start the quiz.
        wwg = WordwallsGame()
        params = wwg.start_quiz(table_id, self.user)
        self.assertEqual(len(params['questions']), 50)
        logger.debug(params['questions'])
        self.assertNotEqual(re.search(r'[JQXZ]', params['questions'][0]['a']),
                            None)
Beispiel #15
0
class WordwallsChallengeBehaviorTest(WordwallsBasicLogicTest):
    """
    Test challenge behavior. Create challenges, quiz on them, leaderboards,
    etc.

    """
    fixtures = ['test/lexica.json',
                'test/users.json',
                'test/profiles.json',
                'dcNames.json',
                'test/daily_challenge.json']

    def setUp(self):
        self.user = User.objects.get(username='******')
        self.lex = Lexicon.objects.get(lexiconName='America')
        self.wwg = WordwallsGame()

    def test_length_challenge(self):
        """ Test a regular challenge by word length (Today's 6s). """
        num_challenges = DailyChallenge.objects.count()
        challenge = DailyChallengeName.objects.get(name="Today's 6s")
        table_id = self.wwg.initialize_daily_challenge(
            self.user, self.lex, challenge, date.today())
        # Assert that it created a challenge.
        self.assertEqual(num_challenges + 1, DailyChallenge.objects.count())
        wgm = self.wwg.get_wgm(table_id)
        state = json.loads(wgm.currentGameState)
        self.assertTrue(state['qualifyForAward'])
        word_list = wgm.word_list
        self.assert_wl(word_list, {
            'numAlphagrams': 50, 'numCurAlphagrams': 50,
            'numFirstMissed': 0, 'numMissed': 0, 'goneThruOnce': False,
            'questionIndex': 0, 'is_temporary': True
        })
        questions = json.loads(word_list.origQuestions)
        for q in questions:
            self.assertEqual(len(q['q']), 6, msg=q)
        self.assertEqual(
            len(set([q['q'] for q in questions])), 50)

    def test_bingo_marathon_challenge(self):
        """ Test bingo marathon challenge. """
        challenge = DailyChallengeName.objects.get(name='Bingo Marathon')
        table_id = self.wwg.initialize_daily_challenge(
            self.user, self.lex, challenge, date.today())
        wgm = self.wwg.get_wgm(table_id)
        state = json.loads(wgm.currentGameState)
        self.assertTrue(state['qualifyForAward'])
        word_list = wgm.word_list
        self.assert_wl(word_list, {
            'numAlphagrams': 100, 'numCurAlphagrams': 100,
            'numFirstMissed': 0, 'numMissed': 0, 'goneThruOnce': False,
            'questionIndex': 0, 'is_temporary': True
        })
        questions = json.loads(word_list.origQuestions)
        # Check there are 50 7s and 50 8s
        num_7s = 0
        num_8s = 0
        for q in questions:
            if len(q['q']) == 7:
                num_7s += 1
            elif len(q['q']) == 8:
                num_8s += 1
        self.assertEqual(num_7s, 50)
        self.assertEqual(num_8s, 50)
        self.assertEqual(
            len(set([q['q'] for q in questions])), 100)
        params = self.wwg.start_quiz(table_id, self.user)
        self.assertEqual(len(params['questions']), 100)
        probability = params['questions'][0]['p']
        self.assertTrue(probability > 0)

    @mock.patch('wordwalls.challenges.gen_blank_challenges',
                side_effect=blank_bingo_generator)
    def test_blank_bingos(self, mock_content):
        """ Test blank bingos. (This comment is unnecessary, right?)"""
        challenge = DailyChallengeName.objects.get(name='Blank Bingos')
        table_id = self.wwg.initialize_daily_challenge(
            self.user, self.lex, challenge, date.today())
        wgm = self.wwg.get_wgm(table_id)
        state = json.loads(wgm.currentGameState)
        self.assertTrue(state['qualifyForAward'])
        word_list = wgm.word_list
        self.assert_wl(word_list, {
            'numAlphagrams': 50, 'numCurAlphagrams': 50,
            'numFirstMissed': 0, 'numMissed': 0, 'goneThruOnce': False,
            'questionIndex': 0, 'is_temporary': True
        })
        questions = json.loads(word_list.origQuestions)
        self.assertEqual(
            len(set([q['q'] for q in questions])), 50)
        params = self.wwg.start_quiz(table_id, self.user)
        self.assertEqual(len(params['questions']), 50)
        # Blank bingos have no probability for their alphagram.
        self.assertTrue(params['questions'][0]['p'] is None)

    def test_play_old_challenge(self):
        """ Play an old challenge instead of creating a new one. """
        num_challenges = DailyChallenge.objects.count()
        challenge = DailyChallengeName.objects.get(name="Bingo Marathon")
        table_id = self.wwg.initialize_daily_challenge(
            self.user, Lexicon.objects.get(lexiconName='CSW15'),
            challenge, date(2015, 12, 8))
        # Assert that it did not create an additional challenge.
        self.assertEqual(num_challenges, DailyChallenge.objects.count())
        wgm = self.wwg.get_wgm(table_id)
        state = json.loads(wgm.currentGameState)
        self.assertFalse(state['qualifyForAward'])
        word_list = wgm.word_list
        self.assert_wl(word_list, {
            'numAlphagrams': 100, 'numCurAlphagrams': 100,
            'numFirstMissed': 0, 'numMissed': 0, 'goneThruOnce': False,
            'questionIndex': 0, 'is_temporary': True
        })
        questions = json.loads(word_list.origQuestions)
        for q in questions:
            self.assertTrue(len(q['q']) in (7, 8), msg=q)
        self.assertEqual(
            len(set([q['q'] for q in questions])), 100)
        params = self.wwg.start_quiz(table_id, self.user)
        self.assertEqual(len(params['questions']), 100)

    def test_play_old_blank_bingos(self):
        """
        Play an old blank bingos challenge instead of creating a new one.

        """
        num_challenges = DailyChallenge.objects.count()
        challenge = DailyChallengeName.objects.get(name="Blank Bingos")
        table_id = self.wwg.initialize_daily_challenge(
            self.user, Lexicon.objects.get(lexiconName='America'),
            challenge, date(2016, 1, 1))
        # Assert that it did not create an additional challenge.
        self.assertEqual(num_challenges, DailyChallenge.objects.count())
        wgm = self.wwg.get_wgm(table_id)
        state = json.loads(wgm.currentGameState)
        self.assertFalse(state['qualifyForAward'])
        word_list = wgm.word_list
        self.assert_wl(word_list, {
            'numAlphagrams': 50, 'numCurAlphagrams': 50,
            'numFirstMissed': 0, 'numMissed': 0, 'goneThruOnce': False,
            'questionIndex': 0, 'is_temporary': True
        })
        questions = json.loads(word_list.origQuestions)
        for q in questions:
            self.assertTrue(len(q['q']) in (7, 8), msg=q)
        self.assertEqual(
            len(set([q['q'] for q in questions])), 50)
        params = self.wwg.start_quiz(table_id, self.user)
        self.assertEqual(len(params['questions']), 50)
class WordwallsChallengeBehaviorTest(WordwallsBasicLogicTestBase):
    """
    Test challenge behavior. Create challenges, quiz on them, leaderboards,
    etc.

    """
    fixtures = ['test/lexica.yaml',
                'test/users.json',
                'test/profiles.json',
                'challenge_names.json',
                'test/daily_challenge.json']

    def setUp(self):
        self.user = User.objects.get(username='******')
        self.lex = Lexicon.objects.get(lexiconName='America')
        self.wwg = WordwallsGame()

    def test_length_challenge(self):
        """ Test a regular challenge by word length (Today's 6s). """
        num_challenges = DailyChallenge.objects.count()
        challenge = DailyChallengeName.objects.get(name="Today's 6s")
        table_id = self.wwg.initialize_daily_challenge(
            self.user, self.lex, challenge,
            timezone.localtime(timezone.now()).date())
        # Assert that it created a challenge.
        self.assertEqual(num_challenges + 1, DailyChallenge.objects.count())
        wgm = self.wwg.get_wgm(table_id)
        state = json.loads(wgm.currentGameState)
        self.assertTrue(state['qualifyForAward'])
        word_list = wgm.word_list
        self.assert_wl(word_list, {
            'numAlphagrams': 50, 'numCurAlphagrams': 50,
            'numFirstMissed': 0, 'numMissed': 0, 'goneThruOnce': False,
            'questionIndex': 0, 'is_temporary': True
        })
        questions = json.loads(word_list.origQuestions)
        for q in questions:
            self.assertEqual(len(q['q']), 6, msg=q)
        self.assertEqual(
            len(set([q['q'] for q in questions])), 50)

    def test_bingo_marathon_challenge(self):
        """ Test bingo marathon challenge. """
        challenge = DailyChallengeName.objects.get(name='Bingo Marathon')
        table_id = self.wwg.initialize_daily_challenge(
            self.user, self.lex, challenge,
            timezone.localtime(timezone.now()).date())
        wgm = self.wwg.get_wgm(table_id)
        state = json.loads(wgm.currentGameState)
        self.assertTrue(state['qualifyForAward'])
        word_list = wgm.word_list
        self.assert_wl(word_list, {
            'numAlphagrams': 100, 'numCurAlphagrams': 100,
            'numFirstMissed': 0, 'numMissed': 0, 'goneThruOnce': False,
            'questionIndex': 0, 'is_temporary': True
        })
        questions = json.loads(word_list.origQuestions)
        # Check there are 50 7s and 50 8s
        num_7s = 0
        num_8s = 0
        for q in questions:
            if len(q['q']) == 7:
                num_7s += 1
            elif len(q['q']) == 8:
                num_8s += 1
        self.assertEqual(num_7s, 50)
        self.assertEqual(num_8s, 50)
        self.assertEqual(
            len(set([q['q'] for q in questions])), 100)
        params = self.wwg.start_quiz(table_id, self.user)
        self.assertEqual(len(params['questions']), 100)
        probability = params['questions'][0]['p']
        self.assertTrue(probability > 0)

    @mock.patch('wordwalls.challenges.gen_blank_challenges',
                side_effect=blank_bingo_generator)
    def test_blank_bingos(self, mock_content):
        """ Test blank bingos. (This comment is unnecessary, right?)"""
        challenge = DailyChallengeName.objects.get(name='Blank Bingos')
        table_id = self.wwg.initialize_daily_challenge(
            self.user, self.lex, challenge,
            timezone.localtime(timezone.now()).date())
        wgm = self.wwg.get_wgm(table_id)
        state = json.loads(wgm.currentGameState)
        self.assertTrue(state['qualifyForAward'])
        word_list = wgm.word_list
        self.assert_wl(word_list, {
            'numAlphagrams': 50, 'numCurAlphagrams': 50,
            'numFirstMissed': 0, 'numMissed': 0, 'goneThruOnce': False,
            'questionIndex': 0, 'is_temporary': True
        })
        questions = json.loads(word_list.origQuestions)
        self.assertEqual(
            len(set([q['q'] for q in questions])), 50)
        params = self.wwg.start_quiz(table_id, self.user)
        self.assertEqual(len(params['questions']), 50)
        # Blank bingos have a zero probability for their alphagram.
        self.assertTrue(params['questions'][0]['p'] == 0)

    def test_play_old_challenge(self):
        """ Play an old challenge instead of creating a new one. """
        num_challenges = DailyChallenge.objects.count()
        challenge = DailyChallengeName.objects.get(name="Bingo Marathon")
        table_id = self.wwg.initialize_daily_challenge(
            self.user, Lexicon.objects.get(lexiconName='CSW19'),
            challenge, date(2016, 12, 8))
        # Assert that it did not create an additional challenge.
        self.assertEqual(num_challenges, DailyChallenge.objects.count())
        wgm = self.wwg.get_wgm(table_id)
        state = json.loads(wgm.currentGameState)
        self.assertFalse(state['qualifyForAward'])
        word_list = wgm.word_list
        self.assert_wl(word_list, {
            'numAlphagrams': 100, 'numCurAlphagrams': 100,
            'numFirstMissed': 0, 'numMissed': 0, 'goneThruOnce': False,
            'questionIndex': 0, 'is_temporary': True
        })
        questions = json.loads(word_list.origQuestions)
        for q in questions:
            self.assertTrue(len(q['q']) in (7, 8), msg=q)
        self.assertEqual(
            len(set([q['q'] for q in questions])), 100)
        params = self.wwg.start_quiz(table_id, self.user)
        self.assertEqual(len(params['questions']), 100)

    def test_play_old_blank_bingos(self):
        """
        Play an old blank bingos challenge instead of creating a new one.

        """
        num_challenges = DailyChallenge.objects.count()
        challenge = DailyChallengeName.objects.get(name="Blank Bingos")
        table_id = self.wwg.initialize_daily_challenge(
            self.user, Lexicon.objects.get(lexiconName='America'),
            challenge, date(2016, 1, 1))
        # Assert that it did not create an additional challenge.
        self.assertEqual(num_challenges, DailyChallenge.objects.count())
        wgm = self.wwg.get_wgm(table_id)
        state = json.loads(wgm.currentGameState)
        self.assertFalse(state['qualifyForAward'])
        word_list = wgm.word_list
        self.assert_wl(word_list, {
            'numAlphagrams': 50, 'numCurAlphagrams': 50,
            'numFirstMissed': 0, 'numMissed': 0, 'goneThruOnce': False,
            'questionIndex': 0, 'is_temporary': True
        })
        questions = json.loads(word_list.origQuestions)
        for q in questions:
            self.assertTrue(len(q['q']) in (7, 8), msg=q)
        self.assertEqual(
            len(set([q['q'] for q in questions])), 50)
        params = self.wwg.start_quiz(table_id, self.user)
        self.assertEqual(len(params['questions']), 50)
    def test_solve_all_words(self):
        """
        Test on a word list with more than 50 words. Go to completion,
        ensure quiz on missed, etc.

        """
        table_id, user = self.setup_quiz()
        wwg = WordwallsGame()
        params = wwg.start_quiz(table_id, user)

        def fully_solve_and_assert():
            """Fully solve quiz, asserting various things."""
            valid_words = set()
            for q in params['questions']:
                for w in q['ws']:
                    valid_words.add(w['w'])

            ct = len(valid_words)
            idx = 0
            for w in valid_words:
                idx += 1
                guess_state = wwg.guess(w, table_id, user)
                if idx != ct:
                    self.assertTrue(guess_state['going'])
                else:
                    self.assertFalse(guess_state['going'])      # Quiz ends
                self.assertTrue(guess_state['alphagram'] != '')

        fully_solve_and_assert()   # This solves the first set of 50
        wgm = wwg.get_wgm(table_id)
        word_list = wgm.word_list

        self.assert_wl(word_list, {
            'version': 2,
            'lexicon': Lexicon.objects.get(lexiconName='NWL18'),
            'user': user, 'numAlphagrams': 81, 'numCurAlphagrams': 81,
            'numFirstMissed': 0, 'numMissed': 0, 'goneThruOnce': False,
            'questionIndex': 50, 'is_temporary': True
        })
        # The name should be a random uuid.
        self.assertEqual(len(word_list.name), 32)
        qs = json.loads(word_list.origQuestions)
        self.assertEqual(len(qs), 81)

        # Finish quiz
        params = wwg.start_quiz(table_id, user)
        fully_solve_and_assert()
        wgm = wwg.get_wgm(table_id)
        word_list = wgm.word_list

        self.assert_wl(word_list, {
            'numAlphagrams': 81, 'numCurAlphagrams': 81,
            'numFirstMissed': 0, 'numMissed': 0, 'goneThruOnce': True,
            'questionIndex': 100, 'is_temporary': True
        })

        # Try one more time
        params = wwg.start_quiz(table_id, user)
        self.assertTrue('quiz is done' in params['error'])
        wgm = wwg.get_wgm(table_id)
        word_list = wgm.word_list

        self.assert_wl(word_list, {
            'numAlphagrams': 81, 'numCurAlphagrams': 0,
            'numFirstMissed': 0, 'numMissed': 0, 'goneThruOnce': True,
            'questionIndex': 0, 'is_temporary': True
        })
Beispiel #18
0
class WordwallsNamedListTest(TestCase, WordListAssertMixin):
    """ "Named" lists. """
    fixtures = ['test/lexica.json',
                'test/users.json',
                'test/profiles.json',
                'test/word_lists.json',
                'test/named_lists.json']

    def setUp(self):
        self.user = User.objects.get(username='******')
        self.lex = Lexicon.objects.get(lexiconName='America')
        self.wwg = WordwallsGame()

    def test_range_list_short(self):
        table_id = self.wwg.initialize_by_named_list(
            self.lex, self.user, NamedList.objects.get(pk=3143), 240)
        self.assertNotEqual(table_id, 0)
        wgm = self.wwg.get_wgm(table_id)
        word_list = wgm.word_list
        self.assert_wl(word_list, {
            'numAlphagrams': 1000, 'numCurAlphagrams': 1000,
            'numFirstMissed': 0, 'numMissed': 0, 'goneThruOnce': False,
            'questionIndex': 0, 'is_temporary': True
        })
        orig_questions = set(json.dumps(q)
                             for q in json.loads(word_list.origQuestions))
        self.assertEqual(len(orig_questions), 1000)
        # Start the quiz.
        wwg = WordwallsGame()
        params = wwg.start_quiz(table_id, self.user)
        self.assertEqual(len(params['questions']), 50)

    def test_range_list_long(self):
        table_id = self.wwg.initialize_by_named_list(
            self.lex, self.user, NamedList.objects.get(pk=3099), 240)
        self.assertNotEqual(table_id, 0)
        wgm = self.wwg.get_wgm(table_id)
        word_list = wgm.word_list
        self.assert_wl(word_list, {
            'numAlphagrams': 21063, 'numCurAlphagrams': 21063,
            'numFirstMissed': 0, 'numMissed': 0, 'goneThruOnce': False,
            'questionIndex': 0, 'is_temporary': True
        })
        orig_questions = set(json.dumps(q)
                             for q in json.loads(word_list.origQuestions))
        self.assertEqual(len(orig_questions), 21063)
        # Start the quiz.
        wwg = WordwallsGame()
        params = wwg.start_quiz(table_id, self.user)
        self.assertEqual(len(params['questions']), 50)

    def test_individual_alphas(self):
        table_id = self.wwg.initialize_by_named_list(
            self.lex, self.user, NamedList.objects.get(pk=3092), 240)
        self.assertNotEqual(table_id, 0)
        wgm = self.wwg.get_wgm(table_id)
        word_list = wgm.word_list
        self.assert_wl(word_list, {
            'numAlphagrams': 691, 'numCurAlphagrams': 691,
            'numFirstMissed': 0, 'numMissed': 0, 'goneThruOnce': False,
            'questionIndex': 0, 'is_temporary': True
        })
        orig_questions = set(json.dumps(q)
                             for q in json.loads(word_list.origQuestions))
        self.assertEqual(len(orig_questions), 691)
        # Start the quiz.
        wwg = WordwallsGame()
        params = wwg.start_quiz(table_id, self.user)
        self.assertEqual(len(params['questions']), 50)
        logger.debug(params['questions'])
        self.assertNotEqual(re.search(r'[JQXZ]', params['questions'][0]['a']),
                            None)
class WordwallsMissedBingosTest(WordwallsBasicLogicTestBase):
    """
    Missed bingos.

    We have one basic case here. It is easiest to test given a good text
    editor; we can search for "board": {some integer} in the leaderboard
    entry json, for example, to quickly find the total number of people
    who did that challenge, etc.

    The answers below are a little bit off from the count, because
    we throw away leaderboard entries where "qualifyForAward" is false.

    For this case, we got Monday, Tuesday, Wednesday, Thursday. We throw
    away the first two (Monday 7s and 8s) since the "missed bingo"
    challenge week starts on Tuesday.

    challenge 40256, leaderboard 40079, answers: 54   Tues  7s
    challenge 40260, leaderboard 40082, answers: 34   Tues  8s
    challenge 40279, leaderboard 40106, answers: 47   Wed   7s
    challenge 40287, leaderboard 40108, answers: 34   Wed   8s
    challenge 40307, leaderboard 40128, answers: 58   Thurs 7s
    challenge 40313, leaderboard 40134, answers: 33   Thurs 8s

    """
    fixtures = ['test/lexica.yaml',
                'test/users.json',
                'test/profiles.json',
                'challenge_names.json',
                'test/daily_challenge.json',
                'test/daily_challenge_leaderboard.json',
                'test/daily_challenge_leaderboard_entry.json',
                'test/daily_challenge_missed_bingos.json']

    expected_missed_bingos = set([
        'ADEEIKKS', 'DEIILMMS', 'ACIORRTT', 'ACELOPRT', 'AFIIMNPR',
        'ALMOOPRS', 'AACEOSST', 'BDEEILNR', 'HIMORSST', 'EHOORSST',
        'AGHNORST', 'ACCILRSY', 'ACCDEILY', 'ACIIRSTT', 'DEHKLNOU',
        'AADGMNOP', 'AEORRRST', 'CIILNOPS', 'AAGIMNOS', 'ADILMOSY',
        'ADEIMSTY', 'DEELLORW', 'EGIILNRS', 'AACEEHRT', 'EEILNOSV',

        'AABLLOR', 'FIOPRST', 'AEHIMSS', 'ACCDHIL', 'ACEHRRX',
        'CEHNOSU', 'ACHHIRS', 'AEGILNR', 'EIMORST', 'EGMORSU',
        'ACCEIST', 'AELMMSY', 'EEINSTV', 'LLOSTUY', 'ACEIRTT',
        'AAAKLMY', 'BIMNOSU', 'AALOPRS', 'CIKNPSY', 'BDNOORU',
        'AEHMPTY', 'ACCILST', 'AEGIKPR', 'ENNORSU', 'ACIRTUY'
    ])

    def setUp(self):
        self.user = User.objects.get(username='******')
        self.lex = Lexicon.objects.get(lexiconName='America')
        self.wwg = WordwallsGame()

    def test_load_missed_bingos(self):
        challenge = DailyChallengeName.objects.get(
            name="Week's Bingo Toughies")
        table_id = self.wwg.initialize_daily_challenge(
            self.user, self.lex, challenge, date(2015, 10, 20))
        wgm = self.wwg.get_wgm(table_id)
        state = json.loads(wgm.currentGameState)
        # This test is run more than a week afterwards, for all time,
        # so it does not qualify for an award anymore. We should maybe
        # mock time to make it clear it's at least a week after 2015/10/19
        self.assertFalse(state['qualifyForAward'])
        word_list = wgm.word_list
        self.assert_wl(word_list, {
            'numAlphagrams': 50, 'numCurAlphagrams': 50,
            'numFirstMissed': 0, 'numMissed': 0, 'goneThruOnce': False,
            'questionIndex': 0, 'is_temporary': True
        })
        questions = json.loads(word_list.origQuestions)
        # logger.debug('Questions: %s', questions)
        self.assertEqual(set([q['q'] for q in questions]),
                         self.expected_missed_bingos)
Beispiel #20
0
class WordwallsMissedBingosTest(WordwallsBasicLogicTest):
    """
    Missed bingos.

    We have one basic case here. It is easiest to test given a good text
    editor; we can search for "board": {some integer} in the leaderboard
    entry json, for example, to quickly find the total number of people
    who did that challenge, etc.

    The answers below are a little bit off from the count, because
    we throw away leaderboard entries where "qualifyForAward" is false.

    For this case, we got Monday, Tuesday, Wednesday, Thursday. We throw
    away the first two (Monday 7s and 8s) since the "missed bingo"
    challenge week starts on Tuesday.

    challenge 40256, leaderboard 40079, answers: 54   Tues  7s
    challenge 40260, leaderboard 40082, answers: 34   Tues  8s
    challenge 40279, leaderboard 40106, answers: 47   Wed   7s
    challenge 40287, leaderboard 40108, answers: 34   Wed   8s
    challenge 40307, leaderboard 40128, answers: 58   Thurs 7s
    challenge 40313, leaderboard 40134, answers: 33   Thurs 8s

    """
    fixtures = ['test/lexica.json',
                # Eventually get rid of these two, because they are
                # replaced by sqlite, but for now we test for backwards
                # compatibility, since we are doing an in-place
                # migration.
                'test/users.json',
                'test/profiles.json',
                'dcNames.json',
                'test/daily_challenge.json',
                'test/daily_challenge_leaderboard.json',
                'test/daily_challenge_leaderboard_entry.json',
                'test/daily_challenge_missed_bingos.json']

    expected_missed_bingos = set([
        'ADEEIKKS', 'DEIILMMS', 'ACIORRTT', 'ACELOPRT', 'AFIIMNPR',
        'ALMOOPRS', 'AACEOSST', 'BDEEILNR', 'HIMORSST', 'EHOORSST',
        'AGHNORST', 'ACCILRSY', 'ACCDEILY', 'ACIIRSTT', 'DEHKLNOU',
        'AADGMNOP', 'AEORRRST', 'CIILNOPS', 'AAGIMNOS', 'ADILMOSY',
        'ADEIMSTY', 'DEELLORW', 'EGIILNRS', 'AACEEHRT', 'EEILNOSV',

        'AABLLOR', 'FIOPRST', 'AEHIMSS', 'ACCDHIL', 'ACEHRRX',
        'CEHNOSU', 'ACHHIRS', 'AEGILNR', 'EIMORST', 'EGMORSU',
        'ACCEIST', 'AELMMSY', 'EEINSTV', 'LLOSTUY', 'ACEIRTT',
        'AAAKLMY', 'BIMNOSU', 'AALOPRS', 'CIKNPSY', 'BDNOORU',
        'AEHMPTY', 'ACCILST', 'AEGIKPR', 'ENNORSU', 'ACIRTUY'
    ])

    def setUp(self):
        self.user = User.objects.get(username='******')
        self.lex = Lexicon.objects.get(lexiconName='America')
        self.wwg = WordwallsGame()

    def test_load_missed_bingos(self):
        challenge = DailyChallengeName.objects.get(
            name="Week's Bingo Toughies")
        table_id = self.wwg.initialize_daily_challenge(
            self.user, self.lex, challenge, date(2015, 10, 20))
        wgm = self.wwg.get_wgm(table_id)
        state = json.loads(wgm.currentGameState)
        # This test is run more than a week afterwards, for all time,
        # so it does not qualify for an award anymore. We should maybe
        # mock time to make it clear it's at least a week after 2015/10/19
        self.assertFalse(state['qualifyForAward'])
        word_list = wgm.word_list
        self.assert_wl(word_list, {
            'numAlphagrams': 50, 'numCurAlphagrams': 50,
            'numFirstMissed': 0, 'numMissed': 0, 'goneThruOnce': False,
            'questionIndex': 0, 'is_temporary': True
        })
        questions = json.loads(word_list.origQuestions)
        # logger.debug('Questions: %s', questions)
        self.assertEqual(set([q['q'] for q in questions]),
                         self.expected_missed_bingos)