def test_syncing_vocabulary_pulls_srs_level_successfully(self): mock_user_response_v2() mock_assignments_with_one_assignment() mock_study_materials() Syncer.factory(self.user.profile).sync_with_wk() newly_synced_review = UserSpecific.objects.get( user=self.user, vocabulary__meaning=self.v.meaning) self.assertEqual(newly_synced_review.wanikani_srs_numeric, 4)
def test_syncer_factory(self): # Should return a V2 syncer when the user has a v2 api key added, # otherwise, V1. syncer = Syncer.factory(self.user.profile) assert isinstance(syncer, WanikaniUserSyncerV1) # now for v2 self.user.profile.api_key_v2 = "no longer empty!" self.user.profile.save() syncer = Syncer.factory(self.user.profile) assert isinstance(syncer, WanikaniUserSyncerV2)
def test_sync_with_modified_synonyms_replaces_old_synonyms(self): self.client.force_login(self.user) self.review.meaning_synonyms.get_or_create(text="This will disappear") self.review.meaning_synonyms.get_or_create( text="This will also disappear") self.assertEqual(len(self.review.meaning_synonyms.all()), 2) mock_vocab_list_response_with_single_vocabulary_with_four_synonyms( self.user) Syncer.factory(self.user.profile).sync_recent_unlocked_vocab() self.review.refresh_from_db() self.assertEqual(len(self.review.meaning_synonyms.all()), 4)
def test_syncing_vocabulary_pulls_srs_level_successfully(self): resp_body = sample_api_responses.single_vocab_response responses.add( responses.GET, self._vocab_api_regex, json=resp_body, status=200, content_type="application/json", ) Syncer.factory(self.user.profile).sync_with_wk() newly_synced_review = UserSpecific.objects.get( user=self.user, vocabulary__meaning=self.v.meaning) self.assertEqual(newly_synced_review.wanikani_srs, "apprentice") self.assertEqual(newly_synced_review.wanikani_srs_numeric, 3)
def test_when_reading_level_changes_on_wanikani_we_catch_that_change_and_comply( self): # Mock response so that the level changes on our default vocab. responses.add( responses.GET, self._vocab_api_regex, json=sample_api_responses.single_vocab_response, status=200, content_type="application/json", ) Syncer.factory(self.user.profile).sync_with_wk() vocabulary = Vocabulary.objects.get(meaning="radioactive bat") self.assertEqual(vocabulary.readings.count(), 1)
def test_creating_new_synonyms_on_sync(self): resp_body = deepcopy(sample_api_responses.single_vocab_response) resp_body["requested_information"][0]["user_specific"][ "user_synonyms"] = ["kitten", "large rat"] responses.add( responses.GET, self._vocab_api_regex, json=resp_body, status=200, content_type="application/json", ) Syncer.factory(self.user.profile).sync_with_wk() synonyms_list = self.review.synonyms_list() self.assertIn("large rat", synonyms_list) self.assertIn("kitten", synonyms_list)
def unlock_previous_level(user): user.profile.refresh_from_db() if user.profile.level == constants.LEVEL_MIN: return else: previous_level = user.profile.level - 1 user.profile.unlocked_levels.get_or_create(level=previous_level) syncer = Syncer.factory(user.profile) syncer.unlock_vocab(previous_level)
def reset_user(user, reset_to_level): logger.info( f"{user.username} has requested a reset to level {reset_to_level}") reset_levels(user, reset_to_level) reset_reviews(user, reset_to_level) stop_following_wanikani(user) # Set to current level. level = Syncer.factory(user.profile).get_wanikani_level() user.profile.level = level user.profile.save()
def unlock_all_possible_levels_for_user(user): """ :param user: User to fully unlock. :return: The list of levels unlocked, how many vocab were unlocked, how many vocab remain locked (as they are locked in WK) """ level_list = [level for level in range(1, user.profile.level + 1)] unlocked_now, unlocked_total, locked = Syncer.factory( user.profile).unlock_vocab(level_list) return level_list, unlocked_now, unlocked_total, locked
def test_when_wanikani_changes_meaning_no_duplicate_is_created(self): resp_body = deepcopy(sample_api_responses.single_vocab_response) resp_body["requested_information"][0][ "meaning"] = "NOT radioactive bat" # Mock response so that the level changes on our default vocab. mock_user_info_response(self.user.profile.api_key) responses.add( responses.GET, build_API_sync_string_for_user_for_levels( self.user, [self.user.profile.level]), json=resp_body, status=200, content_type="application/json", ) Syncer.factory(self.user.profile).sync_with_wk() # Will fail if 2 vocab exist with same kanji. get_vocab_by_kanji("猫")
def test_building_api_string_adds_correct_levels(self): self.user.profile.unlocked_levels.get_or_create(level=5) self.user.profile.unlocked_levels.get_or_create(level=3) self.user.profile.unlocked_levels.get_or_create(level=1) self.user.profile.save() api_call = Syncer.factory( self.user.profile).build_API_sync_string_for_levels( self.user.profile.unlocked_levels_list()) correct_string = ( "https://www.wanikani.com/api/user/any_key/vocabulary/5,3,1") self.assertEqual(correct_string, api_call)
def start_following_wanikani(user): try: logger.info(f"User {user.username} is toggling on 'Follow Wanikani'") syncer = Syncer.factory(user.profile) user.profile.level = syncer.get_wanikani_level() user.profile.unlocked_levels.get_or_create(level=user.profile.level) user.profile.save() syncer.sync_user_profile_with_wk syncer.unlock_vocab(user.profile.level) except exceptions.InvalidWaniKaniKey or InvalidWanikaniApiKeyException as e: logger.warning( f"User {user.username} failed to toggle Follow Wanikani as they have an invalid API key" ) user.profile.api_valid = False user.profile.save() raise e
def unlock(self, request, pk=None): user = self.request.user requested_level = pk if int(requested_level) > user.profile.level: return Response(status=status.HTTP_403_FORBIDDEN) unlocked_this_request, total_unlocked, locked = Syncer.factory( user.profile).unlock_vocab(requested_level) user.profile.unlocked_levels.get_or_create(level=requested_level) return Response( dict( unlocked_now=unlocked_this_request, total_unlocked=total_unlocked, locked=locked, ))
def sync_with_wk(user_id, full=False): p = Profile.objects.get(user__id=user_id) syncer = Syncer.factory(p) return syncer.sync_with_wk(full_sync=full)
def test_syncer_factory(self): # now for v2 self.user.profile.api_key_v2 = "no longer empty!" self.user.profile.save() syncer = Syncer.factory(self.user.profile) assert isinstance(syncer, WanikaniUserSyncerV2)