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_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 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 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 setUp(self): self.user = create_user("Tadgh") create_profile(self.user, "any_key", 5) self.prepLocalVocabulary() self.reading = create_reading(self.v, "ねこ", "猫", 1) self.review = create_review(self.v, self.user) self._vocab_api_regex = re.compile( r"https://www\.wanikani\.com/api/user/.*")
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_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_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_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_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_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 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_reset_command_only_resets_levels_above_requested_level(self): self.client.force_login(user=self.user) v = create_vocab("test") create_reading(v, "test", "test", 2) create_review(v, self.user) # User has unlocked levels 2 and 5 mock_user_response_v2() 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]) # Reset to level 3, should re-lock level 5 self.client.post(reverse("api:user-reset"), data={"level": 3}) response = self.client.get((reverse("api:review-current"))) self.assertEqual(response.data["count"], 1) self.assertListEqual(self.user.profile.unlocked_levels_list(), [2]) # Ensure reset to level 2 keeps reviews at that level self.client.post(reverse("api:user-reset"), data={"level": 2}) response = self.client.get((reverse("api:review-current"))) self.assertEqual(response.data["count"], 1) self.assertListEqual(self.user.profile.unlocked_levels_list(), [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("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_vocab_number_readings_is_correct(self): r = create_reading(self.vocabulary, "ねこ", "ねこ", 2) r = create_reading(self.vocabulary, "ねこな", "猫", 1) self.assertEqual(self.vocabulary.reading_count(), 2)
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 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_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)
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 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_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_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")