def test_setting_reviews_to_order_by_level_works(self): self.client.force_login(self.user) level_4_review = create_review(create_vocab("level4"), self.user) level_4_review.vocabulary.readings.create(level=4, character="level4", kana="level4") level_5_review = create_review(create_vocab("level5"), self.user) level_5_review.vocabulary.readings.create(level=5, character="level5", kana="level5") level_3_review = create_review(create_vocab("level3"), self.user) level_3_review.vocabulary.readings.create(level=3, character="level3", kana="level3") response = self.client.get(reverse("api:review-current")) reviews = response.data["results"] actual_review_order = [review["vocabulary"]["readings"][0]["level"] for review in reviews] assert len(reviews) == 4 assert [3, 4, 5, 5] != actual_review_order self.user.profile.order_reviews_by_level = True self.user.profile.save() response = self.client.get(reverse("api:review-current")) reviews = response.data["results"] actual_review_order = [review["vocabulary"]["readings"][0]["level"] for review in reviews] assert len(reviews) == 4 assert [3, 4, 5, 5] == actual_review_order
def test_get_vocab_by_kanji_correctly_fails_on_duplicate_kanji(self): v = create_vocab("my vocab") create_reading(v, "kana_1", "kanji", 5) v2 = create_vocab("my vocab") create_reading(v2, "kana_2", "kanji", 5) self.assertRaises(Vocabulary.MultipleObjectsReturned, get_vocab_by_kanji, "kanji")
def test_get_vocab_by_kanji_correctly_fails_on_duplicate_kanji(self): v = create_vocab("my vocab") create_reading(v, "kana_1", "kanji", 5) v2 = create_vocab("my vocab") create_reading(v2, "kana_2", "kanji", 5) self.assertRaises( Vocabulary.MultipleObjectsReturned, get_vocab_by_kanji, "kanji" )
def test_associate_vocab_to_user_successfully_creates_review(self): new_vocab = create_vocab("dishwasher") review, created = associate_vocab_to_user(new_vocab, self.user) self.assertTrue(review.needs_review is True) self.assertTrue(created)
def test_user_returns_from_vacation_correctly_increments_review_timestamps(self): now = timezone.now() two_hours_ago = now - timezone.timedelta(hours=2) two_hours_from_now = now + timezone.timedelta(hours=2) four_hours_from_now = now + timezone.timedelta(hours=4) self.user.profile.on_vacation = True # Create review that should be reviewed never again, but got reviewed 2 hours ago. review = create_review(create_vocab("wazoop"), self.user) review.burned = True review.next_review_date = None review.last_studied = two_hours_ago review.save() self.user.profile.vacation_date = two_hours_ago self.user.profile.save() self.review.last_studied = two_hours_ago self.review.next_review_date = two_hours_from_now self.review.save() previously_studied = self.review.last_studied user_returns_from_vacation(self.user) self.review.refresh_from_db() self.assertNotEqual(self.review.last_studied, previously_studied) self.assertAlmostEqual(self.review.next_review_date, four_hours_from_now, delta=timezone.timedelta(minutes=15)) self.assertAlmostEqual(self.review.last_studied, now, delta=timezone.timedelta(minutes=15)) self.assertAlmostEqual(review.last_studied, two_hours_ago, delta=timezone.timedelta(minutes=15)) self.assertAlmostEqual(review.next_review_date, None)
def setUp(self): self.user = create_user("Tadgh") create_profile(self.user, "any_key", 5) self.vocabulary = create_vocab("radioactive bat") self.reading = create_reading(self.vocabulary, "ねこ", "猫", 2) self.review = create_review(self.vocabulary, self.user) self._vocab_api_regex = re.compile("https://www\.wanikani\.com/api/user/.*")
def setUp(self): self.user = create_user("Tadgh") self.user.set_password("password") create_profile(self.user, "any key", 1) self.user.save() self.vocabulary = create_vocab("cat") self.review = create_review(self.vocabulary, self.user) self.review.meaning_synonyms.get_or_create(text="minou")
def test_meaning_contains_checks_for_word_boundaries(self): self.client.force_login(self.user) create_vocab("frog") create_vocab("puppy") create_vocab("up, upwards") create_vocab("not down, up") response = self.client.get( reverse("api:vocabulary-list") + "?meaning_contains=up") data = response.data assert len(data["results"]) == 2
def test_reviews_endpoint_omits_lessons(self): self.client.force_login(user=self.user) # Create a lesson new_review = create_review(create_vocab("sample"), self.user) new_review.streak = 0 new_review.save() response = self.client.get(reverse("api:review-current")) self.assertEqual(response.data["count"], 1)
def test_lesson_route_returns_srs_0_reviews(self): self.client.force_login(user=self.user) # Create a lesson new_review = create_review(create_vocab("sample"), self.user) new_review.streak = 0 new_review.save() response = self.client.get(reverse("api:review-lesson")) self.assertEqual(response.data["count"], 1)
def test_meaning_contains_checks_for_word_boundaries(self): self.client.force_login(self.user) create_vocab("frog") create_vocab("puppy") create_vocab("up, upwards") create_vocab("not down, up") response = self.client.get( reverse("api:vocabulary-list") + "?meaning_contains=up" ) data = response.data assert len(data["results"]) == 2
def test_tag_search_works(self): vocab = create_vocab("spicy meatball") vocab2 = create_vocab("spicy pizza") reading = create_reading(vocab, "SOME_READING", "SOME_CHARACTER", 5) reading2 = create_reading(vocab2, "SOME_OTHER_READING", "SOME_OTHER_CHARACTER", 5) spicy_tag = Tag.objects.create(name='spicy') reading.tags.add(spicy_tag) reading2.tags.add(spicy_tag) reading.save() reading2.save() spicy_tag.refresh_from_db() spicy_vocab = spicy_tag.get_all_vocabulary() self.assertTrue(spicy_vocab.count() == 2)
def setUp(self): self.user = create_user("user1") self.user.set_password("password") self.user.save() create_profile(self.user, "some_key", 5) # create a piece of vocab with one reading. self.vocabulary = create_vocab("cat") self.cat_reading = create_reading(self.vocabulary, "kana", "kanji", 5) self.review = create_userspecific(self.vocabulary, self.user) self.factory = RequestFactory()
def test_review_page_shows_all_items_when_burnt_setting_is_disabled(self): word = create_vocab("phlange") self.user.profile.only_review_burned = False self.user.profile.save() another_review = create_userspecific(word, self.user) another_review.wanikani_burned = True another_review.save() response = self.client.get(reverse("kw:review")) self.assertContains(response, "radioactive bat") self.assertContains(response, "phlange")
def test_tag_search_works(self): vocab = create_vocab("spicy meatball") vocab2 = create_vocab("spicy pizza") reading = create_reading(vocab, "SOME_READING", "SOME_CHARACTER", 5) reading2 = create_reading( vocab2, "SOME_OTHER_READING", "SOME_OTHER_CHARACTER", 5 ) spicy_tag = Tag.objects.create(name="spicy") reading.tags.add(spicy_tag) reading2.tags.add(spicy_tag) reading.save() reading2.save() spicy_tag.refresh_from_db() spicy_vocab = spicy_tag.get_all_vocabulary() self.assertTrue(spicy_vocab.count() == 2)
def test_returning_review_count_that_is_time_delimited_functions_correctly(self): new_review = create_review(create_vocab("arbitrary word"), self.user) new_review.needs_review = False more_than_24_hours_from_now = timezone.now() + timezone.timedelta(hours=25) new_review.next_review_date = more_than_24_hours_from_now new_review.save() self.review.next_review_date = timezone.now() self.review.needs_review = False self.review.save() future_reviews = get_users_future_reviews(self.user, time_limit=timezone.timedelta(hours=24)) self.assertEqual(future_reviews.count(), 1)
def test_review_page_shows_all_items_when_burnt_setting_is_disabled(self): self.client.force_login(user=self.user) word = create_vocab("phlange") self.user.profile.minimum_wk_srs_level_to_review = WkSrsLevel.APPRENTICE.name self.user.profile.save() another_review = create_review(word, self.user) another_review.wanikani_srs_numeric = 5 another_review.save() response = self.client.get(reverse("api:review-current")) self.assertContains(response, "radioactive bat") self.assertContains(response, "phlange")
def test_setting_reviews_to_order_by_level_works(self): self.client.force_login(self.user) level_4_review = create_review(create_vocab("level4"), self.user) level_4_review.vocabulary.readings.create( level=4, character="level4", kana="level4" ) level_5_review = create_review(create_vocab("level5"), self.user) level_5_review.vocabulary.readings.create( level=5, character="level5", kana="level5" ) level_3_review = create_review(create_vocab("level3"), self.user) level_3_review.vocabulary.readings.create( level=3, character="level3", kana="level3" ) response = self.client.get(reverse("api:review-current")) reviews = response.data["results"] actual_review_order = [ review["vocabulary"]["readings"][0]["level"] for review in reviews ] assert len(reviews) == 4 assert [3, 4, 5, 5] != actual_review_order self.user.profile.order_reviews_by_level = True self.user.profile.save() response = self.client.get(reverse("api:review-current")) reviews = response.data["results"] actual_review_order = [ review["vocabulary"]["readings"][0]["level"] for review in reviews ] assert len(reviews) == 4 assert [3, 4, 5, 5] == actual_review_order
def setUp(self): self.user = create_user("user1") self.user.set_password("password") self.user.save() create_profile(self.user, "some_key", 5) # create a piece of vocab with one reading. self.vocabulary = create_vocab("radioactive bat") self.cat_reading = create_reading(self.vocabulary, "ねこ", "猫", 5) # setup a review with two synonyms self.review = create_review(self.vocabulary, self.user) self.client = Client() self.client.login(username="******", password="******")
def test_filtering_on_wk_srs_levels_works(self): self.client.force_login(user=self.user) word = create_vocab("phlange") self.user.profile.minimum_wk_srs_level_to_review = WkSrsLevel.BURNED.name self.user.profile.save() another_review = create_review(word, self.user) another_review.wanikani_srs_numeric = WANIKANI_SRS_LEVELS[ WkSrsLevel.BURNED.name][0] another_review.save() response = self.client.get(reverse("api:review-current")) self.assertNotContains(response, "radioactive bat") self.assertContains(response, "phlange")
def test_review_counts_endpoint_returns_correct_information(self): self.client.force_login(self.user) # Our initial review should be ready to review. response = self.client.get(reverse("api:review-counts")) self.assertEqual(response.data["reviews_count"], 1) self.assertEqual(response.data["lessons_count"], 0) create_lesson(create_vocab("new_lesson"), self.user) # Now we should have 1 lesson and 1 review. response = self.client.get(reverse("api:review-counts")) self.assertEqual(response.data["reviews_count"], 1) self.assertEqual(response.data["lessons_count"], 1)
def test_searching_based_on_reading_returns_distinct_responses(self): reading_to_search = "eyylmao" v = create_vocab("vocabulary with 2 readings.") create_reading(v, reading_to_search, "character_1", 5) create_reading(v, reading_to_search, "character_2", 5) create_review(v, self.user) self.client.force_login(self.user) response = self.client.get( reverse("api:vocabulary-list") + "?reading_contains={}".format(reading_to_search)) self.assertEqual(response.status_code, 200) data = response.data self.assertEqual(len(data["results"]), 1)
def test_returning_review_count_that_is_time_delimited_functions_correctly(self): new_review = create_review(create_vocab("arbitrary word"), self.user) new_review.needs_review = False more_than_24_hours_from_now = timezone.now() + timezone.timedelta(hours=25) new_review.next_review_date = more_than_24_hours_from_now new_review.save() self.review.next_review_date = timezone.now() self.review.needs_review = False self.review.save() future_reviews = get_users_future_reviews( self.user, time_limit=timezone.timedelta(hours=24) ) self.assertEqual(future_reviews.count(), 1)
def test_filtering_on_wk_srs_levels_works(self): self.client.force_login(user=self.user) word = create_vocab("phlange") self.user.profile.minimum_wk_srs_level_to_review = WkSrsLevel.BURNED.name self.user.profile.save() another_review = create_review(word, self.user) another_review.wanikani_srs_numeric = WANIKANI_SRS_LEVELS[ WkSrsLevel.BURNED.name ][0] another_review.save() response = self.client.get(reverse("api:review-current")) self.assertNotContains(response, "radioactive bat") self.assertContains(response, "phlange")
def test_once_user_answers_lesson_once_it_becomes_review(self): self.client.force_login(user=self.user) # Create a lesson new_review = create_review(create_vocab("sample"), self.user) new_review.streak = 0 new_review.save() response = self.client.get(reverse("api:review-lesson")) self.assertEqual(response.data["count"], 1) self.client.post(reverse("api:review-correct", args=(new_review.id,))) self.review.refresh_from_db() response = self.client.get(reverse("api:review-lesson")) self.assertEqual(response.data["count"], 0)
def test_burnt_items_arent_included_when_getting_next_review_date(self): current_time = timezone.now() self.review.next_review_date = current_time self.review.needs_review = False self.review.save() older_burnt_review = create_userspecific(create_vocab("test"), self.user) older_burnt_review.burned = True older_burnt_review.needs_review = False an_hour_ago = current_time - timedelta(hours=1) older_burnt_review.next_review_date = an_hour_ago older_burnt_review.save() response = self.client.get("/kw/") self.assertEqual(response.context['next_review_date'], current_time)
def test_searching_based_on_reading_returns_distinct_responses(self): reading_to_search = "eyylmao" v = create_vocab("vocabulary with 2 readings.") create_reading(v, reading_to_search, "character_1", 5) create_reading(v, reading_to_search, "character_2", 5) review = create_review(v, self.user) self.client.force_login(self.user) response = self.client.get( reverse("api:review-list") + "?reading_contains={}".format(reading_to_search) ) self.assertEqual(response.status_code, 200) data = response.data self.assertEqual(len(data["results"]), 1)
def test_when_user_resets_their_account_we_remove_all_reviews_and_then_unlock_their_current_level(self): self.user.profile.unlocked_levels.get_or_create(level=1) new_review = create_review(create_vocab("arbitrary word"), self.user) new_review.needs_review = True new_review.save() self.assertEqual(get_users_current_reviews(self.user).count(), 2) mock_vocab_list_response_with_single_vocabulary(self.user) mock_user_info_response(self.user.profile.api_key) reset_user(self.user, 1) self.user.refresh_from_db() self.user.profile.refresh_from_db() self.assertEqual(get_users_lessons(self.user).count(), 0) self.assertEqual(self.user.profile.level, 5)
def test_wrong_answer_records_failure(self): vocab = create_vocab("dog") us = create_userspecific(vocab, self.user) self.client.post( reverse("kw:record_answer"), { 'user_correct': "false", 'user_specific_id': us.id, 'wrong_before': 'false' }) us.refresh_from_db() recorded_properly = (us.incorrect == 1 and us.streak == 0 and us.needs_review is True) self.assertTrue(recorded_properly)
def test_when_user_resets_their_account_we_remove_all_reviews_and_then_unlock_their_current_level( self): return self.user.profile.unlocked_levels.get_or_create(level=1) new_review = create_review(create_vocab("arbitrary word"), self.user) new_review.needs_review = True new_review.save() self.assertEqual(get_users_current_reviews(self.user).count(), 2) # TODO Fill with V2 mocks. reset_user(self.user, 1) self.user.refresh_from_db() self.user.profile.refresh_from_db() self.assertEqual(get_users_lessons(self.user).count(), 0) self.assertEqual(self.user.profile.level, 5)
def test_adding_a_level_to_reset_command_only_resets_levels_above_or_equal_togiven( self): self.client.force_login(user=self.user) v = create_vocab("test") create_reading(v, "test", "test", 3) create_review(v, self.user) mock_user_info_response(self.user.profile.api_key) self.user.profile.unlocked_levels.get_or_create(level=2) response = self.client.get((reverse("api:review-current"))) self.assertEqual(response.data['count'], 2) self.assertListEqual(self.user.profile.unlocked_levels_list(), [5, 2]) self.client.post(reverse("api:user-reset"), data={'level': 3}) response = self.client.get((reverse("api:review-current"))) self.assertEqual(response.data['count'], 0) self.assertListEqual(self.user.profile.unlocked_levels_list(), [2])
def test_fetching_vocabulary_shows_is_reviable_field_on_associated_vocabulary(self): self.client.force_login(self.user) self.review.wanikani_srs_numeric = 1 self.review.save() wk_burned_review = create_review(create_vocab("test"), self.user) wk_burned_review.wanikani_srs_numeric = 9 wk_burned_review.save() self.user.profile.minimum_wk_srs_level_to_review = WkSrsLevel.BURNED.name self.user.profile.save() response = self.client.get(reverse("api:vocabulary-list")) data = response.data assert data["results"][0]["is_reviewable"] is False assert data["results"][1]["is_reviewable"] is True
def setUp(self): self.user = create_user("user1") self.user.set_password("password") self.user.save() create_profile(self.user, "some_key", 5) # create a piece of vocab with one reading. self.vocabulary = create_vocab("radioactive bat") self.cat_reading = create_reading(self.vocabulary, "kana", "kanji", 5) # setup a review with two synonyms self.review = create_userspecific(self.vocabulary, self.user) self.client = Client() self.client.login(username="******", password="******") self._vocab_api_regex = re.compile( "https://www\.wanikani\.com/api/user/.*")
def test_burnt_items_arent_included_when_getting_next_review_date(self): self.client.force_login(user=self.user) current_time = timezone.now() self.review.next_review_date = current_time self.review.needs_review = False self.review.save() older_burnt_review = create_review(create_vocab("test"), self.user) older_burnt_review.burned = True older_burnt_review.needs_review = False an_hour_ago = current_time - timedelta(hours=1) older_burnt_review.next_review_date = an_hour_ago older_burnt_review.save() response = self.client.get(reverse("api:user-me")) self.assertEqual(response.data["profile"]["next_review_date"], current_time)
def test_fetching_vocabulary_shows_is_reviable_field_on_associated_vocabulary( self): self.client.force_login(self.user) self.review.wanikani_srs_numeric = 1 self.review.save() wk_burned_review = create_review(create_vocab("test"), self.user) wk_burned_review.wanikani_srs_numeric = 9 wk_burned_review.save() self.user.profile.minimum_wk_srs_level_to_review = WkSrsLevel.BURNED.name self.user.profile.save() response = self.client.get(reverse("api:vocabulary-list")) data = response.data assert (data['results'][0]['is_reviewable'] is False) assert (data['results'][1]['is_reviewable'] is True)
def test_handle_wanikani_level_down_correctly_deletes_invalid_reviews( self): self.user.profile.level = 5 self.user.profile.save() self.user.profile.unlocked_levels.get_or_create(level=5) #Create a review at current levelwait, vocab = create_vocab("ANY WORD") create_reading(vocab, "some reading", "some char", self.user.profile.level) create_userspecific(vocab, self.user) self.user.profile.handle_wanikani_level_change( self.user.profile.level - 1) reviews = UserSpecific.objects.filter(user=self.user) self.assertTrue(reviews.count() == 1)
def test_when_user_resets_their_account_we_remove_all_reviews_and_then_unlock_their_current_level( self ): self.user.profile.unlocked_levels.get_or_create(level=1) new_review = create_review(create_vocab("arbitrary word"), self.user) new_review.needs_review = True new_review.save() self.assertEqual(get_users_current_reviews(self.user).count(), 2) mock_vocab_list_response_with_single_vocabulary(self.user, self.user.profile.level) mock_user_info_response(self.user.profile.api_key) reset_user(self.user, 1) self.user.refresh_from_db() self.user.profile.refresh_from_db() self.assertEqual(get_users_lessons(self.user).count(), 0) self.assertEqual(self.user.profile.level, 5)
def test_review_filtering_by_maximum_wk_srs_level(self): self.client.force_login(self.user) self.user.profile.maximum_wk_srs_level_to_review = WkSrsLevel.APPRENTICE.name self.user.profile.save() self.review.wanikani_srs_numeric = 5 self.review.wanikani_srs = WkSrsLevel.GURU.name self.review.needs_review = True self.review.save() # Prepare an apprentice review. apprentice_review = create_review(create_vocab("new_vocab"), self.user) apprentice_review.wanikani_srs_numeric = 1 apprentice_review.needs_review = True apprentice_review.save() response = self.client.get(reverse("api:review-current")) data = response.data self.assertEqual(data["count"], 1)
def test_vocabulary_that_has_multiple_readings_with_same_tag_appears_only_once( self): vocab = create_vocab("spicy meatball") reading = create_reading(vocab, "SOME_READING", "SOME_CHARACTER", 5) reading2 = create_reading(vocab, "SOME_OTHER_READING", "SOME_OTHER_CHARACTER", 5) spicy_tag = Tag.objects.create(name='spicy') reading.tags.add(spicy_tag) reading2.tags.add(spicy_tag) reading.save() reading2.save() spicy_tag.refresh_from_db() spicy_vocab = spicy_tag.get_all_vocabulary() self.assertEqual(spicy_vocab.count(), 1)
def test_user_returns_from_vacation_correctly_increments_review_timestamps(self): now = timezone.now() two_hours_ago = now - timezone.timedelta(hours=2) two_hours_from_now = now + timezone.timedelta(hours=2) four_hours_from_now = now + timezone.timedelta(hours=4) self.user.profile.on_vacation = True # Create review that should be reviewed never again, but got reviewed 2 hours ago. review = create_review(create_vocab("wazoop"), self.user) review.burned = True review.next_review_date = None review.last_studied = two_hours_ago review.save() self.user.profile.vacation_date = two_hours_ago self.user.profile.save() self.review.last_studied = two_hours_ago self.review.next_review_date = two_hours_from_now self.review.save() previously_studied = self.review.last_studied user_returns_from_vacation(self.user) self.review.refresh_from_db() self.assertNotEqual(self.review.last_studied, previously_studied) self.assertAlmostEqual( self.review.next_review_date, four_hours_from_now, delta=timezone.timedelta(minutes=15), ) self.assertAlmostEqual( self.review.last_studied, now, delta=timezone.timedelta(minutes=15) ) self.assertAlmostEqual( review.last_studied, two_hours_ago, delta=timezone.timedelta(minutes=15) ) self.assertAlmostEqual(review.next_review_date, None)
def test_review_filtering_by_maximum_wk_srs_level(self): self.client.force_login(self.user) self.user.profile.maximum_wk_srs_level_to_review = ( WkSrsLevel.APPRENTICE.name ) self.user.profile.save() self.review.wanikani_srs_numeric = 5 self.review.wanikani_srs = WkSrsLevel.GURU.name self.review.needs_review = True self.review.save() # Prepare an apprentice review. apprentice_review = create_review(create_vocab("new_vocab"), self.user) apprentice_review.wanikani_srs_numeric = 1 apprentice_review.needs_review = True apprentice_review.save() response = self.client.get(reverse("api:review-current")) data = response.data self.assertEqual(data["count"], 1)
def test_vocabulary_that_has_multiple_readings_with_same_tag_appears_only_once( self ): vocab = create_vocab("spicy meatball") reading = create_reading(vocab, "SOME_READING", "SOME_CHARACTER", 5) reading2 = create_reading( vocab, "SOME_OTHER_READING", "SOME_OTHER_CHARACTER", 5 ) spicy_tag = Tag.objects.create(name="spicy") reading.tags.add(spicy_tag) reading2.tags.add(spicy_tag) reading.save() reading2.save() spicy_tag.refresh_from_db() spicy_vocab = spicy_tag.get_all_vocabulary() self.assertEqual(spicy_vocab.count(), 1)
def test_one_time_script_for_vocabulary_merging_works(self): # Merger should: # 1) Pull entire Wanikani vocabulary set. # 2) For each vocabulary, check kanji. # Option A: # 3) If multiple vocab that have a reading with that kanji are returned, Create *one* new vocab for that kanji, # with current info from API. # 3.5) Make sure to copy over the various metadata on the reading we have previously pulled (sentences etc) # 4) Find all Reviews that point to any of the previous vocabulary objects. # 5) Find maximum of all the reviews when grouped by user. Which has highest SRS, etc. This will be the user's # original vocab. Probably best to confirm by checking creation date. # 6) Point the review's Vocabulary to the newly created vocabulary object from step 3. # 7) Delete all other Vocabulary that are now out of date. This should cascade deletion # down to the other reviews. # Option B: 3) If only one vocab is found for a particular kanji, we have successfully *not* created # duplicates, meaning the WK vocab has never changed meaning. 4) We do not have to do anything here. Woohoo! # Create two vocab, identical kanji, different meanings. v1 = create_vocab("dog") # < -- vestigial vocab. v2 = create_vocab("dog, woofer, pupper") # < -- real, current vocab. create_reading(v1, "doggo1", "犬", 5) create_reading(v2, "doggo2", "犬", 5) # Make it so that review 1 has overall better SRS score for the user. review_1 = create_review(v1, self.user) review_1.streak = 4 review_1.correct = 4 review_1.incorrect = 2 review_1.save() review_2 = create_review(v2, self.user) review_2.streak = 2 review_2.correct = 4 review_2.incorrect = 3 review_2.save() MeaningSynonym.objects.create(review=review_1, text="flimflammer") MeaningSynonym.objects.create(review=review_2, text="shazwopper") AnswerSynonym.objects.create(review=review_1, character="CHS1", kana="KS1") AnswerSynonym.objects.create(review=review_2, character="CHS2", kana="KS2") # Assign another user an old version of the vocab. user2 = create_user("asdf") review_3 = create_review(v1, user2) review_3.streak = 5 review_3.correct = 5 review_3.incorrect = 0 review_3.save() # User now has two different vocab, each with their own meaning, however kanji are identical. # Pull fake "current" vocab. this response, wherein we fetch the data from WK, and it turns out we already # have a local vocabulary with an identical meaning (i.e., we have already stored the correct and # currently active vocabulary. responses.add( responses.GET, "https://www.wanikani.com/api/user/{}/vocabulary/{}".format( constants.API_KEY, self.user.profile.level ), json=sample_api_responses.single_vocab_existing_meaning_and_should_now_merge, status=200, content_type="application/json", ) old_vocab = Vocabulary.objects.filter(readings__character="犬") self.assertEqual(old_vocab.count(), 2) generate_user_stats(self.user) one_time_merge_level(self.user.profile.level) generate_user_stats(self.user) new_vocab = Vocabulary.objects.filter(readings__character="犬") self.assertEqual(new_vocab.count(), 1) new_review = UserSpecific.objects.filter( user=self.user, vocabulary__readings__character="犬" ) self.assertEqual(new_review.count(), 1) new_review = new_review[0] self.assertEqual(new_review.streak, review_1.streak) self.assertEqual(new_review.correct, review_1.correct) self.assertEqual(new_review.incorrect, review_1.incorrect) self.assertEqual(new_review.next_review_date, review_1.next_review_date) self.assertEqual(new_review.last_studied, review_1.last_studied) # Should have smashed together all the synonyms too. self.assertEqual(len(new_review.synonyms_list()), 2) self.assertEqual(len(new_review.reading_synonyms.all()), 2) second_users_reviews = UserSpecific.objects.filter(user=user2) self.assertEqual(second_users_reviews.count(), 1) user_two_review = second_users_reviews[0] self.assertEqual(user_two_review.streak, 5) self.assertTrue(user_two_review.vocabulary.meaning == "dog, woofer, pupper")
def test_get_vocab_by_kanji_works_in_case_of_multiple_reading_vocab(self): v = create_vocab("my vocab") create_reading(v, "kana_1", "kanji", 5) create_reading(v, "kana_2", "kanji", 5) get_vocab_by_kanji("kanji")
def setUp(self): self.user = create_user("Tadgh") create_profile(self.user, "any_key", 5) self.vocabulary = create_vocab("radioactive bat") self.reading = create_reading(self.vocabulary, "ねこ", "猫", 5) self.review = create_review(self.vocabulary, self.user)
def test_report_counts_endpoint(self): # Report a vocab. self.client.force_login(user=self.user) # This should only ever create ONE report, as we continually update the same one. We do not allow users to # multi-report a single vocab. self.client.post( reverse("api:report-list"), data={"reading": self.reading.id, "reason": "This still makes no sense!!!"}, ) self.client.post( reverse("api:report-list"), data={"reading": self.reading.id, "reason": "ahhh!!!"}, ) self.client.post( reverse("api:report-list"), data={"reading": self.reading.id, "reason": "Help!"}, ) self.client.post( reverse("api:report-list"), data={"reading": self.reading.id, "reason": "asdf!!!"}, ) self.client.post( reverse("api:report-list"), data={"reading": self.reading.id, "reason": "fdsa!!!"}, ) self.client.post( reverse("api:report-list"), data={"reading": self.reading.id, "reason": "Final report!!!!"}, ) # Have another user report it user = create_user("test2") create_profile(user, "test", 5) self.client.force_login(user=user) self.client.post( reverse("api:report-list"), data={"reading": self.reading.id, "reason": "This still makes no sense!!!"}, ) # Report another vocab, but only once new_vocab = create_vocab("some other vocab") reading = create_reading(new_vocab, "reading", "reading_char", 1) self.client.post( reverse("api:report-list"), data={"reading": reading.id, "reason": "This still makes no sense!!!"}, ) # Login with admin self.client.force_login(self.admin) resp = self.client.get(reverse("api:report-counts")) assert resp.data[0]["report_count"] > resp.data[1]["report_count"] assert resp.data[0]["report_count"] == 2 assert resp.data[0]["reading"] == self.reading.id assert resp.data[1]["report_count"] == 1 assert resp.data[1]["reading"] == reading.id resp = self.client.get(reverse("api:report-list")) assert resp.data["count"] == 3
def test_reading_clean_fails_with_invalid_levels_too_low(self): v = create_vocab("cat") r = create_reading(v, "ねこ", "ねこ", 0) self.assertRaises(ValidationError, r.clean_fields)
def test_newly_created_user_specific_has_null_last_studied_date(self): review = create_review(create_vocab("test"), self.user) self.assertIsNone(review.last_studied)
def test_default_review_times_are_not_rounded(self): rounded_time = self.review.next_review_date new_vocab = create_review(create_vocab("fresh"), self.user) self.assertNotEqual(rounded_time, new_vocab.next_review_date)
def test_available_readings_returns_only_readings_youve_unlocked(self): v = create_vocab("cat") r = create_reading(v, "ねこ", "ねこ", 5) r = create_reading(v, "ねこな", "猫", 1) self.assertTrue(len(v.available_readings(2)) == 1)