def test_change_sound_owner(self, delete_sound_solr): # Prepare some content userA, packsA, soundsA = create_user_and_sounds(num_sounds=4, num_packs=1, tags="tag1 tag2 tag3 tag4 tag5") userB, _, _ = create_user_and_sounds(num_sounds=0, num_packs=0, user=User.objects.create_user("testuser2", password="******")) fake_original_path_template = '/test/path/{sound_id}_{user_id}.wav' for sound in soundsA: sound.change_processing_state("OK") sound.change_moderation_state("OK") sound.original_path = fake_original_path_template.format(sound_id=sound.id, user_id=userA.id) sound.save() # Check initial number of sounds is ok self.assertEqual(userA.profile.num_sounds, 4) self.assertEqual(userB.profile.num_sounds, 0) # Select change to change ownership and change index dirty for later checks target_sound = soundsA[0] target_sound.is_index_dirty = False target_sound.save() target_sound_id = target_sound.id target_sound_pack = target_sound.pack target_sound_tags = [ti.id for ti in target_sound.tags.all()] remaining_sound_ids = [s.id for s in soundsA[1:]] # Other sounds that the user owns # Change ownership of sound target_sound.change_owner(userB) # Perform checks sound = Sound.objects.get(id=target_sound_id) self.assertEqual(userA.profile.num_sounds, 3) self.assertEqual(userB.profile.num_sounds, 1) self.assertEqual(sound.user, userB) self.assertEqual(sound.is_index_dirty, True) self.assertEqual(sound.pack.name, target_sound_pack.name) self.assertEqual(sound.pack.num_sounds, 1) self.assertEqual(target_sound_pack.num_sounds, 3) self.assertEqual(sound.pack.user, userB) self.assertEqual(sound.original_path, fake_original_path_template.format(sound_id=sound.id, user_id=userB.id)) # Delete original user and perform further checks userA.delete() # Completely delete form db (instead of user.profile.delete_user()) sound = Sound.objects.get(id=target_sound_id) self.assertItemsEqual([ti.id for ti in sound.tags.all()], target_sound_tags) calls = [mock.call(i) for i in remaining_sound_ids] delete_sound_solr.assert_has_calls(calls) # All other sounds by the user were deleted
def setUp(self): cache.clear() user, packs, sounds = create_user_and_sounds(num_sounds=1) self.sound = sounds[0] self.sound.change_processing_state("OK") self.sound.change_moderation_state("OK") self.user = user
def test_cors_header(self): # Create App to login using token user, packs, sounds = create_user_and_sounds(num_sounds=5, num_packs=1) c = ApiV2Client(user=user, status='OK', redirect_uri="https://freesound.com", url="https://freesound.com", name="test") c.save() sound = sounds[0] sound.change_processing_state("OK") sound.change_moderation_state("OK") headers = { 'HTTP_AUTHORIZATION': 'Token %s' % c.key, 'HTTP_ORIGIN': 'https://www.google.com' } resp = self.client.options(reverse('apiv2-sound-instance', kwargs={'pk': sound.id}), secure=True, **headers) self.assertEqual(resp.status_code, 200) # Check if header is present self.assertEqual(resp['ACCESS-CONTROL-ALLOW-ORIGIN'], '*')
def test_pack_views_response_ok(self): user, packs, sounds = create_user_and_sounds(num_sounds=5, num_packs=1) for sound in sounds: sound.change_processing_state("OK") sound.change_moderation_state("OK") # Login so api returns session login based responses self.client.login(username=user.username, password='******') # 200 response on pack instance resp = self.client.get( reverse('apiv2-pack-instance', kwargs={'pk': packs[0].id})) self.assertEqual(resp.status_code, 200) # 200 response on pack instance sounds list resp = self.client.get( reverse('apiv2-pack-sound-list', kwargs={'pk': packs[0].id})) self.assertEqual(resp.status_code, 200) # 200 response on pack instance download # This test uses a https connection. resp = self.client.get(reverse('apiv2-pack-download', kwargs={'pk': packs[0].id}), secure=True) self.assertEqual(resp.status_code, 200)
def test_get_analysis(self): _, _, sounds = create_user_and_sounds(num_sounds=1) sound = sounds[0] analysis_data = {'descriptor1': 0.56, 'descirptor2': 1.45, 'descriptor3': 'label'} # Create one analysis object that stores the data in the model. Check that get_analysis returns correct data. sa = SoundAnalysis.objects.create(sound=sound, extractor="TestExtractor1", analysis_data=analysis_data) self.assertEqual(sound.analyses.all().count(), 1) self.assertEqual(sa.get_analysis().keys(), analysis_data.keys()) self.assertEqual(sa.get_analysis()['descriptor1'], 0.56) # Now create an analysis object which stores output in a JSON file. Again check that get_analysis works. analysis_filename = '%i_testextractor_out.json' sound_analysis_folder = os.path.join(settings.ANALYSIS_PATH, str(sound.id / 1000)) create_directories(sound_analysis_folder) json.dump(analysis_data, open(os.path.join(sound_analysis_folder, analysis_filename), 'w')) sa2 = SoundAnalysis.objects.create(sound=sound, extractor="TestExtractor2", analysis_filename=analysis_filename) self.assertEqual(sound.analyses.all().count(), 2) self.assertEqual(sa2.get_analysis().keys(), analysis_data.keys()) self.assertEqual(sa2.get_analysis()['descriptor1'], 0.56) # Create an analysis object which references a non-existing file. Check that get_analysis returns None. sa3 = SoundAnalysis.objects.create(sound=sound, extractor="TestExtractor3", analysis_filename='non_existing_file.json') self.assertEqual(sound.analyses.all().count(), 3) self.assertEqual(sa3.get_analysis(), None)
def test_oauth2_response_ok(self): user, packs, sounds = create_user_and_sounds(num_sounds=5, num_packs=1) client = ApiV2Client.objects.create( user=user, description='', name='', url='', redirect_uri='https://freesound.org') # Login so api returns session login based responses self.client.login(username=user.username, password='******') # 200 response on Oauth2 authorize resp = self.client.post(reverse('oauth2_provider:authorize'), { 'client_id': client.id, 'response_type': 'code' }, secure=True) self.assertEqual(resp.status_code, 200) # 302 response on Oauth2 logout and authorize resp = self.client.post( reverse('oauth2_provider:logout_and_authorize'), {'client_id': client.id}, secure=True) self.assertEqual(resp.status_code, 302)
def test_delete_sound_view(self, delete_sound_solr): user, packs, sounds = create_user_and_sounds(num_sounds=1, num_packs=1) sound = sounds[0] sound_id = sound.id sound.change_processing_state("OK") sound.change_moderation_state("OK") self.client.login(username=user.username, password='******') # Try delete with incorrect encrypted sound id link (should not delete sound) encrypted_link = encrypt(u"%d\t%f" % (1234, time.time())) resp = self.client.post(reverse('sound-delete', args=[sound.user.username, sound.id]), {"encrypted_link": encrypted_link}) self.assertEqual(resp.status_code, 403) self.assertEqual(Sound.objects.filter(id=sound_id).count(), 1) # Try delete with expired encrypted link (should not delete sound) encrypted_link = encrypt(u"%d\t%f" % (sound.id, time.time() - 15)) resp = self.client.post(reverse('sound-delete', args=[sound.user.username, sound.id]), {"encrypted_link": encrypted_link}) self.assertEqual(resp.status_code, 200) self.assertEqual(Sound.objects.filter(id=sound_id).count(), 1) # Try delete with valid link (should delete sound) encrypted_link = encrypt(u"%d\t%f" % (sound.id, time.time())) resp = self.client.post(reverse('sound-delete', args=[sound.user.username, sound.id]), {"encrypted_link": encrypted_link}) self.assertEqual(Sound.objects.filter(id=sound_id).count(), 0) self.assertRedirects(resp, reverse('accounts-home')) delete_sound_solr.assert_called_once_with(sound.id)
def setUp(self): user, packs, sounds = create_user_and_sounds(num_sounds=3, num_packs=1, tags="tag1 tag2 tag3") self.sound_ids = [s.id for s in sounds] self.user = user self.pack = packs[0]
def setUp(self): user, packs, sounds = create_user_and_sounds(num_sounds=1, num_packs=1) self.sound = sounds[0] self.sound.moderation_state = "OK" self.sound.processing_state = "OK" self.sound.save() self.pack = packs[0] self.user = user self.factory = RequestFactory()
def test_embed_iframe(self): user, packs, sounds = create_user_and_sounds(num_sounds=1, num_packs=1) sound = sounds[0] sound.moderation_state = 'OK' sound.processing_state = 'OK' sound.save() resp = self.client.get(reverse('embed-simple-sound-iframe', kwargs={"sound_id": sound.id, 'player_size': 'medium'})) self.assertEqual(resp.status_code, 200)
def test_pack_delete(self): user, packs, sounds = create_user_and_sounds(num_sounds=5, num_packs=1) for sound in sounds: sound.change_processing_state("OK") sound.change_moderation_state("OK") self.assertEqual(user.profile.num_sounds, 5) pack = packs[0] pack.delete_pack(remove_sounds=False) self.assertEqual(User.objects.get(id=user.id).profile.num_sounds, 5) # Should be 5 as sounds are not deleted self.assertEqual(pack.is_deleted, True)
def setUp(self): user, _, sounds = create_user_and_sounds() self.user = user self.sound = sounds[0] self.sound.moderation_state = "OK" self.sound.processing_state = "OK" self.sound.analysis_state = "OK" self.sound.similarity_state = "OK" self.sound.save() SoundOfTheDay.objects.create(sound=self.sound, date_display=datetime.date.today())
def test_edit_pack(self): user, packs, sounds = create_user_and_sounds(num_sounds=4, num_packs=2) for sound in sounds: sound.change_processing_state("OK") sound.change_moderation_state("OK") pack1 = packs[0] pack2 = packs[1] self.assertEqual(Pack.objects.get(id=pack1.id).num_sounds, 2) self.assertEqual(Pack.objects.get(id=pack2.id).num_sounds, 2) # Move one sound from one pack to the other sound_ids_pack1 = [s.id for s in pack1.sounds.all()] sound_ids_pack2 = [s.id for s in pack2.sounds.all()] sound_ids_pack2.append(sound_ids_pack1.pop()) self.client.login(username=user.username, password='******') resp = self.client.post(reverse('pack-edit', args=[pack2.user.username, pack2.id]), { 'submit': [u'submit'], 'pack_sounds': u','.join([str(sid) for sid in sound_ids_pack2]), 'name': [u'Test pack 1 (edited)'], 'description': [u'A new description'] }) self.assertRedirects(resp, reverse('pack', args=[pack2.user.username, pack2.id])) self.assertEqual(Pack.objects.get(id=pack1.id).num_sounds, 1) self.assertEqual(Pack.objects.get(id=pack2.id).num_sounds, 3) # Move one sound that had no pack user, packs, sounds = create_user_and_sounds(num_sounds=1, num_packs=0, user=user, count_offset=5) sound = sounds[0] sound.change_processing_state("OK") sound.change_moderation_state("OK") resp = self.client.post(reverse('pack-edit', args=[pack2.user.username, pack2.id]), { 'submit': [u'submit'], 'pack_sounds': u','.join([str(snd.id) for snd in Pack.objects.get(id=pack2.id).sounds.all()] + [str(sound.id)]), 'name': [u'Test pack 1 (edited again)'], 'description': [u'A new description'] }) self.assertRedirects(resp, reverse('pack', args=[pack2.user.username, pack2.id])) self.assertEqual(Pack.objects.get(id=pack1.id).num_sounds, 1) self.assertEqual(Pack.objects.get(id=pack2.id).num_sounds, 4) self.assertEqual(Sound.objects.get(id=sound.id).pack.id, pack2.id)
def test_sound_delete(self, delete_sound_solr): user, packs, sounds = create_user_and_sounds() sound = sounds[0] sound_id = sound.id sound.change_processing_state("OK") sound.change_moderation_state("OK") sound.add_comment(user, "some comment") self.assertEqual(user.profile.num_sounds, 1) self.assertEqual(Comment.objects.count(), 1) sound.delete() self.assertEqual(user.profile.num_sounds, 0) self.assertEqual(Comment.objects.count(), 0) delete_sound_solr.assert_called_once_with(sound_id)
def setUp(self): user, packs, sounds = create_user_and_sounds(num_sounds=1) self.SOUND_DESCRIPTION = 'Simple Sound Description' self.USER_SOUND_SIGNATURE = 'Sound Signature.' self.USER_VISITOR_SOUND_SIGNATURE = 'Sound Visitor Signature.' self.sound = sounds[0] self.sound.description = self.SOUND_DESCRIPTION self.sound.moderation_state = "OK" self.sound.processing_state = "OK" self.sound.save() self.user = user self.user_visitor = User.objects.create_user( username='******', password='******')
def test_random_sound_view(self, random_sound): """ Get a sound from solr and redirect to it. """ users, packs, sounds = create_user_and_sounds(num_sounds=1) sound = sounds[0] # We only use the ID field from solr random_sound.return_value = {'id': sound.id} response = self.client.get(reverse('sounds-random')) self.assertEqual(response.status_code, 302) self.assertEqual( response.url, '/people/testuser/sounds/{}/?random_browsing=true'.format( sound.id))
def test_oembed_sound(self): # Get iframe of a sound using oembed user, packs, sounds = create_user_and_sounds(num_sounds=1, num_packs=1) sound = sounds[0] sound_id = sound.id sound.change_processing_state("OK") sound.change_moderation_state("OK") self.client.login(username=user.username, password='******') # Get url of the sound url = reverse('sound', args=[sound.user.username, sound_id]) resp = self.client.get(reverse('oembed-sound')+'?url='+url) self.assertEqual(resp.status_code, 200) self.assertTrue(resp.content != '')
def test_create_and_delete_sounds(self, delete_sound_solr): N_SOUNDS = 5 user, packs, sounds = create_user_and_sounds(num_sounds=N_SOUNDS, num_packs=1) pack = packs[0] self.assertEqual(pack.num_sounds, 0) for count, sound in enumerate(pack.sounds.all()): sound.change_processing_state("OK") sound.change_moderation_state("OK") self.assertEqual(Pack.objects.get(id=pack.id).num_sounds, count + 1) # Check pack has all sounds sound_to_delete = sounds[0] sound_to_delete_id = sound_to_delete.id sound_to_delete.delete() delete_sound_solr.assert_called_once_with(sound_to_delete_id) self.assertEqual(Pack.objects.get(id=pack.id).num_sounds, N_SOUNDS - 1) # Check num_sounds on delete sound
def test_basic_user_response_ok(self): user, packs, sounds = create_user_and_sounds(num_sounds=5, num_packs=1) # 200 response on login page resp = self.client.get(reverse('api-login'), secure=True) self.assertEqual(resp.status_code, 200) self.client.login(username=user.username, password='******') # 200 response on keys page resp = self.client.get(reverse('apiv2-apply'), secure=True) self.assertEqual(resp.status_code, 200) # 302 response on logout page resp = self.client.get(reverse('api-logout'), secure=True) self.assertEqual(resp.status_code, 302)
def _create_test_sound(self): """Create a sound which is suitable for being chosen as a random sound""" try: user = User.objects.get(username="******") except User.DoesNotExist: user = None user, packs, sounds = create_user_and_sounds(num_sounds=1, user=user) sound = sounds[0] sound.is_explicit = False sound.moderation_state = 'OK' sound.processing_state = 'OK' sound.avg_rating = 8 sound.num_ratings = 5 sound.save() return sound
def test_edit_sound(self): N_SOUNDS = 1 user, packs, sounds = create_user_and_sounds(num_sounds=N_SOUNDS, num_packs=1) pack = packs[0] sound = sounds[0] self.assertEqual(pack.num_sounds, 0) sound.change_processing_state("OK") sound.change_moderation_state("OK") self.assertEqual(Pack.objects.get(id=pack.id).num_sounds, 1) # Check pack has all sounds self.client.login(username=user.username, password='******') resp = self.client.post(reverse('sound-edit', args=[sound.user.username, sound.id]), { 'submit': [u'submit'], 'pack-new_pack': [u'new pack name'], 'pack-pack': [u''], }) self.assertRedirects(resp, reverse('sound', args=[sound.user.username, sound.id])) self.assertEqual(Pack.objects.get(id=pack.id).num_sounds, 0) # Sound changed from pack
def setUp(self): user, packs, sounds = create_user_and_sounds(num_packs=1) self.user = user self.sound = sounds[0] self.pack = packs[0] self.sound.moderation_state = "OK" self.sound.processing_state = "OK" self.sound.analysis_state = "OK" self.sound.similarity_state = "OK" self.sound.save() SoundOfTheDay.objects.create(sound=self.sound, date_display=datetime.date.today()) Download.objects.create(user=self.user, sound=self.sound, license=self.sound.license, created=self.sound.created) PackDownload.objects.create(user=self.user, pack=self.pack, created=self.pack.created)
def test_create_enough_new_sounds(self): """ If we have some random sounds selected for the future, make sure that we always have at least settings.NUMBER_OF_RANDOM_SOUNDS_IN_ADVANCE sounds waiting in the future.""" sound_ids = [] user, packs, sounds = create_user_and_sounds(num_sounds=10) for s in sounds: sound_ids.append(s.id) sound = Sound.objects.get(id=19) SoundOfTheDay.objects.create(sound=sound, date_display=datetime.date(2017, 06, 20)) SoundOfTheDay.objects.create(sound=sound, date_display=datetime.date(2017, 06, 21)) call_command("create_random_sound") sound_of_days = SoundOfTheDay.objects.count() self.assertEqual(sound_of_days, 6)
def test_moderation_and_processing_state_changes(self, delete_sound_solr): user, packs, sounds = create_user_and_sounds() sound = sounds[0] self.assertEqual(user.profile.num_sounds, 0) # Sound not yet moderated or processed sound.change_moderation_state("OK") self.assertEqual(user.profile.num_sounds, 0) # Sound not yet processed sound.change_processing_state("OK") self.assertEqual(user.profile.num_sounds, 1) # Sound now processed and moderated sound.change_processing_state("OK") self.assertEqual(user.profile.num_sounds, 1) # Sound reprocessed and again set as ok sound.change_processing_state("OK") self.assertEqual(user.profile.num_sounds, 1) # Sound reprocessed second time and again set as ok sound.change_processing_state("FA") self.assertEqual(user.profile.num_sounds, 0) # Sound failed processing delete_sound_solr.assert_called_once_with(sound.id) sound.change_processing_state("OK") self.assertEqual(user.profile.num_sounds, 1) # Sound processed again as ok sound.change_moderation_state("DE") self.assertEqual(user.profile.num_sounds, 0) # Sound unmoderated self.assertEqual(delete_sound_solr.call_count, 2) # Sound deleted once when going to FA, once when DE
def test_random_sound_view_no_solr(self, random_sound): """ If solr is down, get a random sound from the database and redirect to it. """ users, packs, sounds = create_user_and_sounds(num_sounds=1) sound = sounds[0] # Update sound attributes to be selected by Sound.objects.random sound.moderation_state = sound.processing_state = 'OK' sound.is_explicit = False sound.avg_rating = 8 sound.num_ratings = 5 sound.save() # Returned if there is an issue accessing solr random_sound.return_value = {} # we find the sound due to Sound.objects.random response = self.client.get(reverse('sounds-random')) self.assertEqual(response.status_code, 302) self.assertEqual( response.url, '/people/testuser/sounds/{}/?random_browsing=true'.format( sound.id))
def test_oldusername_sound_redirect(self): user, packs, sounds = create_user_and_sounds(num_sounds=1, num_packs=1) sound = sounds[0] sound.change_processing_state("OK") sound.change_moderation_state("OK") # Add new OldUsername to the user accounts.models.OldUsername.objects.create(user=sound.user, username='******') # get url of the sound with oldusername url = reverse('sound', args=['oldusername', sound.id]) resp = self.client.get(url) url = reverse('sound', args=[sound.user.username, sound.id]) # Check redirect to new username self.assertRedirects(resp, url, status_code=301) # Check using wrong username url = reverse('sound', args=['wrongusername', sound.id]) resp = self.client.get(url) self.assertEqual(resp.status_code, 404)
def test_deletedsound_creation(self, delete_sound_solr): user, packs, sounds = create_user_and_sounds() sound = sounds[0] sound.change_processing_state("OK") sound.change_moderation_state("OK") sound_id = sound.id sound.delete() delete_sound_solr.assert_called_once_with(sound_id) self.assertEqual(DeletedSound.objects.filter(sound_id=sound_id).exists(), True) ds = DeletedSound.objects.get(sound_id=sound_id) # Check this elements are in the json saved on DeletedSound keys = ['num_ratings', 'duration', 'id', 'geotag_id', 'comments', 'base_filename_slug', 'num_downloads', 'md5', 'description', 'original_path', 'pack_id', 'license', 'created', 'original_filename', 'geotag'] json_data = ds.data.keys() for k in keys: self.assertTrue(k in json_data)
def test_random_sound_view_bad_solr(self, random_sound): """ Solr may send us a sound id which no longer exists (index hasn't been updated). In this case, use the database access """ users, packs, sounds = create_user_and_sounds(num_sounds=1) sound = sounds[0] # Update sound attributes to be selected by Sound.objects.random sound.moderation_state = sound.processing_state = 'OK' sound.is_explicit = False sound.avg_rating = 8 sound.num_ratings = 5 sound.save() # We only use the ID field from solr random_sound.return_value = {'id': sound.id + 100} # Even though solr returns sound.id+100, we find we are redirected to the db sound, because # we call Sound.objects.random response = self.client.get(reverse('sounds-random')) self.assertEqual(response.status_code, 302) self.assertEqual( response.url, '/people/testuser/sounds/{}/?random_browsing=true'.format( sound.id))
def _test_add_remove_remixes(self, cache_keys, check_present): _, _, sounds = create_user_and_sounds(num_sounds=1, user=self.user) another_sound = sounds[0] self._assertCacheAbsent(cache_keys) self.client.login(username='******', password='******') self.assertEqual(self.sound.remix_group.count(), 0) self.assertFalse(check_present()) self._assertCachePresent(cache_keys) # Indicate another sound as source resp = self.client.post(self._get_sound_url('sound-edit-sources'), { 'sources': str(another_sound.id) }) self.assertEqual(resp.status_code, 200) call_command('create_remix_groups') self._assertCacheAbsent(cache_keys) # Check remix icon self.sound.refresh_from_db() self.assertEqual(self.sound.remix_group.count(), 1) self.assertTrue(check_present()) self._assertCachePresent(cache_keys) # Remove remix from the sound resp = self.client.post(self._get_sound_url('sound-edit-sources'), { 'sources': '' }) self.assertEqual(resp.status_code, 200) call_command('create_remix_groups') self._assertCacheAbsent(cache_keys) # Check remix icon being absent self.sound.refresh_from_db() self.assertEqual(self.sound.remix_group.count(), 0) self.assertFalse(check_present())
def test_encoding(self): # Create App to login using token user, packs, sounds = create_user_and_sounds(num_sounds=5, num_packs=1) c = ApiV2Client(user=user, status='OK', redirect_uri="https://freesound.com", url="https://freesound.com", name="test") c.save() sound = sounds[0] sound.change_processing_state("OK") sound.change_moderation_state("OK") headers = { 'HTTP_AUTHORIZATION': 'Token %s' % c.key, } # make query that can't be decoded resp = self.client.options( "/apiv2/search/text/?query=ambient&filter=tag:(rain%20OR%CAfe)", secure=True, **headers) self.assertEqual(resp.status_code, 200)
def setUp(self): user, _, sounds = create_user_and_sounds(num_sounds=1, type="mp3") # Use mp3 so it needs converstion to PCM self.sound = sounds[0] self.user = user
def test_report_count_statuses(self): # Create some initial data user, pp, ss = create_user_and_sounds(num_sounds=1, num_packs=1) pack = pp[0] sound = ss[0] sound.change_processing_state("OK") sound.change_moderation_state("OK") SoundRating.objects.create(sound=sound, user=user, rating=4) sound.refresh_from_db() # Refresh from db after methods that use F-expressions sound.add_comment(user=user, comment="testComment") sound.refresh_from_db() # Refresh from db after methods that use F-expressions forum = Forum.objects.create(name="testForum", name_slug="test_forum", description="test") thread = Thread.objects.create(forum=forum, title="testThread", author=user) Post.objects.create(author=user, body="testBody", thread=thread) Post.objects.create(author=user, body="testBody unnmoderated", thread=thread, moderation_state="NM") user.profile.refresh_from_db() # Refresh from db after methods that use F-expressions # Assert initial counts are ok self.assertEquals(user.profile.num_sounds, 1) self.assertEquals(user.profile.num_posts, 1) # Note that count is 1 because one of the posts is not moderated self.assertEquals(pack.num_sounds, 1) self.assertEquals(pack.num_downloads, 0) self.assertEquals(sound.num_ratings, 1) self.assertEquals(sound.avg_rating, 4) self.assertEquals(sound.num_comments, 1) self.assertEquals(sound.num_downloads, 0) # Run command and assert counts are still ok call_command('report_count_statuses') self.assertEquals(user.profile.num_sounds, 1) self.assertEquals(user.profile.num_posts, 1) self.assertEquals(pack.num_sounds, 1) self.assertEquals(pack.num_downloads, 0) self.assertEquals(sound.num_ratings, 1) self.assertEquals(sound.avg_rating, 4) self.assertEquals(sound.num_comments, 1) self.assertEquals(sound.num_downloads, 0) # Manually set the counts to something wrong user.profile.num_sounds = 21 user.profile.num_posts = 21 user.profile.save() pack.num_sounds = 21 pack.num_downloads = 21 pack.save() sound.num_ratings = 21 sound.avg_rating = 21 sound.num_comments = 21 sound.num_downloads = 21 sound.save() # Re-run command with -n and assert counts are still wrong call_command('report_count_statuses', '--no-changes') user.profile.refresh_from_db() sound.refresh_from_db() pack.refresh_from_db() self.assertNotEquals(user.profile.num_sounds, 1) self.assertNotEquals(user.profile.num_posts, 1) self.assertNotEquals(pack.num_sounds, 1) self.assertNotEquals(pack.num_downloads, 0) self.assertNotEquals(sound.num_ratings, 1) self.assertNotEquals(sound.avg_rating, 4) self.assertNotEquals(sound.num_comments, 1) self.assertNotEquals(sound.num_downloads, 0) # Re-run command with -d and assert that all counts are ok except for download counts call_command('report_count_statuses', '--skip-downloads') user.profile.refresh_from_db() sound.refresh_from_db() pack.refresh_from_db() self.assertEquals(user.profile.num_sounds, 1) self.assertEquals(user.profile.num_posts, 1) # Note this is still 1 as unmoderated posts do not count self.assertEquals(pack.num_sounds, 1) self.assertNotEquals(pack.num_downloads, 0) self.assertEquals(sound.num_ratings, 1) self.assertEquals(sound.avg_rating, 4) self.assertEquals(sound.num_comments, 1) self.assertNotEquals(sound.num_downloads, 0) # Re-run command with no options set and check that all counts are ok now call_command('report_count_statuses') user.profile.refresh_from_db() sound.refresh_from_db() pack.refresh_from_db() self.assertEquals(user.profile.num_sounds, 1) self.assertEquals(user.profile.num_posts, 1) self.assertEquals(pack.num_sounds, 1) self.assertEquals(pack.num_downloads, 0) self.assertEquals(sound.num_ratings, 1) self.assertEquals(sound.avg_rating, 4) self.assertEquals(sound.num_comments, 1) self.assertEquals(sound.num_downloads, 0)