def test_handle_project_no_pull(self): """ Don't call repo.pull if command.no_pull is True. """ self.command.no_pull = True self.command.handle_project(self.db_project) assert_false(self.mock_repo_pull.called)
def test_no_project_configuration_basic(self): """ Create/update the TranslatedResource object on all resources available in the current locale. """ update_translated_resources_without_config( self.db_project, self.vcs_project, self.translated_locale, ) assert_true( TranslatedResource.objects.filter( resource=self.main_db_resource, locale=self.translated_locale).exists()) assert_true( TranslatedResource.objects.filter( resource=self.other_db_resource, locale=self.translated_locale).exists()) assert_false( TranslatedResource.objects.filter( resource=self.missing_db_resource, locale=self.translated_locale).exists())
def test_finished(self): log = RepositorySyncLogFactory.create(end_time=None) assert_false(log.finished) log.end_time = aware_datetime(2015, 1, 1) log.save() assert_true(log.finished)
def test_readonly_locales(self): """Don't call commit_changes for locales in read-only mode.""" project_locale = self.translated_locale.project_locale.get( project=self.db_project, ) project_locale.readonly = True project_locale.save() self.mock_pull_changes.return_value = [ True, { self.repository.pk: Locale.objects.filter( pk=self.translated_locale.pk, ), }, ] sync_translations( self.db_project.pk, self.project_sync_log.pk, self.now, no_commit=False, ) assert_false(self.mock_commit_changes.called)
def test_no_project_configuration_extra_locales(self): """ Only create/update the TranslatedResource object for active locales, even if the inactive locale has a resource. """ update_translated_resources_without_config( self.db_project, self.vcs_project, self.translated_locale, ) assert_true(TranslatedResource.objects.filter( resource=self.main_db_resource, locale=self.translated_locale ).exists()) assert_true(TranslatedResource.objects.filter( resource=self.other_db_resource, locale=self.translated_locale ).exists()) assert_false(TranslatedResource.objects.filter( resource=self.main_db_resource, locale=self.inactive_locale ).exists()) assert_false(TranslatedResource.objects.filter( resource=self.other_db_resource, locale=self.inactive_locale ).exists())
def test_project_configuration_basic(self): """ Create/update the TranslatedResource objects based on project configuration. """ with patch.object(self.vcs_project, 'configuration') as configuration: with patch.object(configuration, 'locale_resources') as locale_resources: locale_resources.return_value = [ self.other_db_resource, ] update_translated_resources_with_config( self.db_project, self.vcs_project, self.translated_locale, ) assert_true( TranslatedResource.objects.filter( resource=self.other_db_resource, locale=self.translated_locale, ).exists() ) assert_false( TranslatedResource.objects.filter( resource=self.missing_db_resource, locale=self.translated_locale, ).exists() )
def test_with_or_without_project_config( self, update_translated_resources_with_config_mock, update_translated_resources_without_config_mock, ): """ Pick the right update_translated_resources() method, depending on whether the project configuration file is provided or not. """ # Without project config self.vcs_project.configuration = None update_translated_resources( self.db_project, self.vcs_project, self.translated_locale, ) assert_false(update_translated_resources_with_config_mock.called) assert_true(update_translated_resources_without_config_mock.called) # Reset called value update_translated_resources_with_config_mock.called = False update_translated_resources_without_config_mock.called = False # With project config self.vcs_project.configuration = True update_translated_resources( self.db_project, self.vcs_project, self.translated_locale, ) assert_true(update_translated_resources_with_config_mock.called) assert_false(update_translated_resources_without_config_mock.called)
def test_basic_run(self): """ When the command is run, any scheduled commands that are due to run should be sent to shove. """ command1 = self._mock_command(is_due=False, command='foo') command2 = self._mock_command(is_due=True, command='bar') command3 = self._mock_command(is_due=True, command='baz') path = 'captain.projects.management.commands.process_command_schedule.ScheduledCommand' with patch(path) as MockScheduledCommand: MockScheduledCommand.objects.all.return_value = [command1, command2, command3] cmd = process_command_schedule.Command() cmd.handle() # Commands that aren't due shoudn't have been run. assert_false(command1.project.send_command.called) # Commands that are due should have been run, and should have been saved with an updated # last_run. command2.project.send_command.assert_called_with(None, 'bar') assert_equal(command2.last_run, self.now) command2.save.assert_called_with() command3.project.send_command.assert_called_with(None, 'baz') assert_equal(command3.last_run, self.now) command3.save.assert_called_with()
def test_project_configuration_basic(self): """ Create/update the TranslatedResource objects based on project configuration. """ with patch.object(self.vcs_project, 'configuration') as configuration: with patch.object(configuration, 'locale_resources') as locale_resources: locale_resources.return_value = [ self.other_db_resource, ] update_translated_resources_with_config( self.db_project, self.vcs_project, self.translated_locale, ) assert_true( TranslatedResource.objects.filter( resource=self.other_db_resource, locale=self.translated_locale, ).exists()) assert_false( TranslatedResource.objects.filter( resource=self.missing_db_resource, locale=self.translated_locale, ).exists())
def test_no_project_configuration_extra_locales(self): """ Only create/update the TranslatedResource object for active locales, even if the inactive locale has a resource. """ update_translated_resources_without_config( self.db_project, self.vcs_project, self.translated_locale, ) assert_true( TranslatedResource.objects.filter( resource=self.main_db_resource, locale=self.translated_locale).exists()) assert_true( TranslatedResource.objects.filter( resource=self.other_db_resource, locale=self.translated_locale).exists()) assert_false( TranslatedResource.objects.filter( resource=self.main_db_resource, locale=self.inactive_locale).exists()) assert_false( TranslatedResource.objects.filter( resource=self.other_db_resource, locale=self.inactive_locale).exists())
def test_remove_duplicate_approvals(self): """ Ensure that duplicate approvals are removed. """ # Trigger creation of new approved translation. self.main_vcs_translation.strings[None] = 'New Translated String' self.main_vcs_translation.fuzzy = False # Translation approved after the sync started simulates the race # where duplicate translations occur. duplicate_translation = TranslationFactory.create( entity=self.main_db_entity, locale=self.translated_locale, string='Other New Translated String', approved=True, approved_date=aware_datetime(1970, 1, 3) ) ChangedEntityLocale.objects.filter(entity=self.main_db_entity).delete() with patch('pontoon.sync.tasks.VCSProject', return_value=self.vcs_project): sync_project_repo(self.db_project.pk, self.repository.pk, self.project_sync_log.pk, self.now) # Only one translation should be approved: the duplicate_translation. assert_equal(self.main_db_entity.translation_set.filter(approved=True).count(), 1) new_translation = self.main_db_entity.translation_set.get( string='New Translated String' ) assert_false(new_translation.approved) assert_true(new_translation.approved_date is None) duplicate_translation.refresh_from_db() assert_true(duplicate_translation.approved) assert_equal(duplicate_translation.approved_date, aware_datetime(1970, 1, 3))
def test_finished(self): sync_log = SyncLogFactory.create() # Create repo without existing log so sync is unfinished. repo = RepositoryFactory.create() project_sync_log = ProjectSyncLogFactory.create( sync_log=sync_log, project__repositories=[repo]) # Sync isn't finished until all repos are finished. assert_false(sync_log.finished) repo_log = RepositorySyncLogFactory.create( repository=repo, project_sync_log=project_sync_log, start_time=aware_datetime(2015, 1, 1), end_time=None ) del sync_log.finished assert_false(sync_log.finished) repo_log.end_time = aware_datetime(2015, 1, 2) repo_log.save() del sync_log.finished assert_true(sync_log.finished)
def test_get_latest_activity_doesnt_exist(self): """ If no ProjectLocale exists with the given project/locale, return None. """ assert_false(ProjectLocale.objects.filter(project=self.project, locale=self.locale).exists()) assert_is_none(ProjectLocale.get_latest_activity(self.project, self.locale))
def test_no_pretranslation(self): """ Ensure that pretranslation isn't called if pretranslation not enabled or no new Entity, Locale or TranslatedResource is created. """ self.mock_pull_changes.return_value = [ True, {self.repository.pk: Locale.objects.filter(pk=self.translated_locale.pk)}, ] sync_translations( self.db_project.pk, self.project_sync_log.pk, self.now, [], [], [], ["new_entity"], ) # Pretranslation is not enabled assert_false(self.mock_pretranslate.called) self.db_project.pretranslation_enabled = True self.db_project.save() with self.patch( "pontoon.sync.tasks.update_translated_resources", return_value=False ): sync_translations(self.db_project.pk, self.project_sync_log.pk, self.now) # No new Entity, Locale or TranslatedResource assert_false(self.mock_pretranslate.called)
def test_remove_duplicate_approvals(self): """ Ensure that duplicate approvals are removed. """ # Trigger creation of new approved translation. self.main_vcs_translation.strings[None] = 'New Translated String' self.main_vcs_translation.fuzzy = False # Translation approved after the sync started simulates the race # where duplicate translations occur. duplicate_translation = TranslationFactory.create( entity=self.main_db_entity, locale=self.translated_locale, string='Other New Translated String', approved=True, approved_date=aware_datetime(1970, 1, 3) ) ChangedEntityLocale.objects.filter(entity=self.main_db_entity).delete() with patch('pontoon.sync.tasks.VCSProject', return_value=self.vcs_project): sync_translations(self.db_project.pk, self.repository.pk, self.project_sync_log.pk, self.now, self.mock_changes) # Only one translation should be approved: the duplicate_translation. assert_equal(self.main_db_entity.translation_set.filter(approved=True).count(), 1) new_translation = self.main_db_entity.translation_set.get( string='New Translated String' ) assert_false(new_translation.approved) assert_true(new_translation.approved_date is None) duplicate_translation.refresh_from_db() assert_true(duplicate_translation.approved) assert_equal(duplicate_translation.approved_date, aware_datetime(1970, 1, 3))
def test_handle_cant_commit(self): """If project.can_commit is False, do not sync it.""" with patch.object(Project, 'can_commit', new_callable=PropertyMock) as can_commit: can_commit.return_value = False self.command.handle_project = Mock() self.execute_command(self.db_project.slug) assert_false(self.command.handle_project.called)
def test_no_commit(self): """Don't call commit_changes if command.no_commit is True.""" sync_project_repo(self.db_project.pk, self.repository.pk, self.project_sync_log.pk, self.now, [], no_commit=True) assert_false(self.mock_commit_changes.called)
def test_reset_project_has_changed(self): """After syncing, set db_project.has_changed to False.""" self.db_project.has_changed = True self.db_project.save() sync_project(self.db_project.pk, self.project_sync_log.sync_log.pk) self.db_project.refresh_from_db() assert_false(self.db_project.has_changed)
def test_handle_project_no_pull(self): """ Don't call update_from_repository if command.no_pull is True. """ with patch.object(sync_projects, 'update_from_repository') as update_from_repository: self.command.no_pull = True self.command.handle_project(self.db_project) assert_false(update_from_repository.called)
def test_success_false(self): """ If any shove instance has a nonzero return code return False. """ command = SentCommandFactory.create() CommandLogFactory.create(sent_command=command, return_code=0) CommandLogFactory.create(sent_command=command, return_code=1) assert_false(command.success)
def test_can_commit_false(self): """ can_commit should be False if there are no repo that can be committed to. """ repo = RepositoryFactory.build(type=Repository.FILE) project = ProjectFactory.create(repositories=[repo]) assert_false(project.can_commit)
def test_no_commit(self): """Don't call commit_changes if command.no_commit is True.""" self.mock_pull_changes.return_value = [True, { self.repository.pk: Locale.objects.filter(pk=self.translated_locale.pk) }] sync_translations(self.db_project.pk, self.project_sync_log.pk, self.now, self.mock_changes, no_commit=True) assert_false(self.mock_commit_changes.called)
def test_missing_project(self): """ If a project with the given PK doesn't exist, log it and exit. """ with patch('pontoon.sync.tasks.log') as mock_log, \ patch('pontoon.sync.tasks.perform_sync') as mock_perform_sync: sync_project(99999) mock_log.error.assert_called_with(CONTAINS('99999')) assert_false(mock_perform_sync.called)
def test_no_translation(self): """If no translation exists for a specific locale, skip it.""" self.changeset.update_vcs_entity = Mock() self.changeset.update_db_entity = Mock() self.main_vcs_entity.has_translation_for = Mock(return_value=False) self.call_update_translations([('key', self.main_db_entity, self.main_vcs_entity)]) assert_false(self.changeset.update_vcs_entity.called) assert_false(self.changeset.update_db_entity.called)
def test_missing_project(self): """ If a project with the given PK doesn't exist, log it and exit. """ with patch('pontoon.sync.tasks.log') as mock_log: with assert_raises(Project.DoesNotExist): sync_project(99999, self.sync_log.pk) mock_log.error.assert_called_with(CONTAINS('99999')) assert_false(self.mock_update_originals.called)
def test_cant_commit(self): """If project.can_commit is False, do not sync it.""" project = ProjectFactory.create() with patch.object(Project, "can_commit", new_callable=PropertyMock) as can_commit: can_commit.return_value = False self.execute_command(project.slug) assert_false(self.mock_sync_project.delay.called)
def test_cant_commit(self): """If project.can_commit is False, do not sync it.""" project = ProjectFactory.create() with patch.object(Project, 'can_commit', new_callable=PropertyMock) as can_commit: can_commit.return_value = False self.execute_command(projects=project.slug) assert_false(self.mock_sync_project.delay.called)
def test_no_translation(self): """If no translation exists for a specific locale, skip it.""" self.changeset.update_vcs_entity = Mock() self.changeset.update_db_entity = Mock() self.main_vcs_entity.has_translation_for = Mock(return_value=False) self.call_handle_entity('key', self.main_db_entity, self.main_vcs_entity) assert_false(self.changeset.update_vcs_entity.called) assert_false(self.changeset.update_db_entity.called)
def test_missing_log(self): """ If a log with the given PK doesn't exist, log it and exit. """ with patch('pontoon.sync.tasks.log') as mock_log: with assert_raises(SyncLog.DoesNotExist): sync_project(self.db_project.pk, 99999) mock_log.error.assert_called_with(CONTAINS('99999')) assert_false(self.mock_perform_sync_project.called)
def test_missing_log(self): """ If a log with the given PK doesn't exist, log it and exit. """ with patch('pontoon.sync.tasks.log') as mock_log: with assert_raises(SyncLog.DoesNotExist): sync_project(self.db_project.pk, 99999) mock_log.error.assert_called_with(CONTAINS('99999')) assert_false(self.mock_update_originals.called)
def test_missing_project(self): """ If a project with the given PK doesn't exist, log it and exit. """ with patch('pontoon.sync.tasks.log') as mock_log: with assert_raises(Project.DoesNotExist): sync_project(99999, self.sync_log.pk) mock_log.error.assert_called_with(CONTAINS('99999')) assert_false(self.mock_perform_sync_project.called)
def test_add_locale(self): config = self.vcs_project.configuration.parsed_configuration locale_code = 'new-locale-code' assert_false(locale_code in config.locales) self.vcs_project.configuration.add_locale(locale_code) assert_true(locale_code in config.locales)
def test_missing_project(self): """ If a project with the given PK doesn't exist, log it and exit. """ with patch("pontoon.sync.tasks.log") as mock_log: with assert_raises(Project.DoesNotExist): sync_project(99999, self.sync_log.pk) mock_log.error.assert_called_with(CONTAINS("99999")) assert_false(self.mock_update_originals.called)
def test_unchanged(self): """ If the revisions returned by repo.pull match those from the last sync, consider the VCS unchanged and return False. """ self.mock_repo_pull.return_value = {'single_locale': 'asdf'} self.repository.last_synced_revisions = {'single_locale': 'asdf'} self.repository.save() has_changed, _ = pull_changes(self.db_project, locales=self.db_project.locales.all()) assert_false(has_changed)
def test_is_due_interval_not_passed(self): """ If the interval hasn't passed between the current time and last run time, is_due should return False. """ command = ScheduledCommandFactory(last_run=datetime(2013, 2, 1, 5, 0, 0), interval_minutes=15) with patch('captain.projects.models.timezone') as timezone: timezone.now.return_value = datetime(2013, 2, 1, 5, 14, 0) assert_false(command.is_due)
def test_missing_entities(self): """If either of the entities is missing, skip it.""" self.changeset.update_vcs_entity = Mock() self.changeset.update_db_entity = Mock() self.call_update_translations( [("one", None, self.main_vcs_entity), ("other", self.main_db_entity, None), ("both", None, None)] ) assert_false(self.changeset.update_vcs_entity.called) assert_false(self.changeset.update_db_entity.called)
def test_no_commit(self): """Don't call commit_changes if command.no_commit is True.""" self.mock_pull_changes.return_value = [ True, {self.repository.pk: Locale.objects.filter(pk=self.translated_locale.pk)}, ] sync_translations( self.db_project.pk, self.project_sync_log.pk, self.now, no_commit=True ) assert_false(self.mock_commit_changes.called)
def test_unchanged(self): """ If the revisions returned by repo.pull match those from the last sync, consider the VCS unchanged and return False. """ self.mock_repo_pull.return_value = {'single_locale': 'asdf'} self.repository.last_synced_revisions = {'single_locale': 'asdf'} self.repository.save() assert_false(pull_changes(self.db_project))
def test_get_latest_activity_doesnt_exist(self): """ If no ProjectLocale exists with the given project/locale, return None. """ assert_false( ProjectLocale.objects.filter(project=self.project, locale=self.locale).exists()) assert_is_none( ProjectLocale.get_latest_activity(self.project, self.locale))
def test_create_project_log(self): assert_false(ProjectSyncLog.objects.exists()) repo = RepositoryFactory.create() self.db_project.repositories = [repo] self.db_project.save() sync_project(self.db_project.pk, self.sync_log.pk) log = ProjectSyncLog.objects.get(project=self.db_project) assert_equal(self.mock_sync_translations.delay.call_args[0][1], repo.pk) assert_equal(self.mock_sync_translations.delay.call_args[0][2], log.pk)
def test_sync_log(self): """Create a new sync log when command is run.""" assert_false(SyncLog.objects.exists()) ProjectFactory.create() with patch.object(sync_projects, 'timezone') as mock_timezone: mock_timezone.now.return_value = aware_datetime(2015, 1, 1) self.execute_command() sync_log = SyncLog.objects.all()[0] assert_equal(sync_log.start_time, aware_datetime(2015, 1, 1))
def test_sync_log(self): """Create a new sync log when command is run.""" assert_false(SyncLog.objects.exists()) ProjectFactory.create() with patch.object(sync_projects, "timezone") as mock_timezone: mock_timezone.now.return_value = aware_datetime(2015, 1, 1) self.execute_command() sync_log = SyncLog.objects.all()[0] assert_equal(sync_log.start_time, aware_datetime(2015, 1, 1))
def test_create_project_log(self): assert_false(RepositorySyncLog.objects.exists()) repo = RepositoryFactory.create() self.db_project.repositories = [repo] self.db_project.save() sync_project_repo(self.db_project.pk, self.repository.pk, self.project_sync_log.pk, self.now) log = RepositorySyncLog.objects.get(repository=self.repository) assert_equal(log.repository, self.repository)
def test_get_or_set_project_files_l10n(self): self.vcs_project.configuration.add_locale = Mock() locale_code = self.locale.code assert_equal( self.vcs_project.configuration.get_or_set_project_files( locale_code, ).locale, locale_code, ) assert_false(self.vcs_project.configuration.add_locale.called)
def test_project_locale_added(self): """ When a locale is added to a project, has_changed should be set to True. """ project = ProjectFactory.create(locales=[], has_changed=False) assert_false(project.has_changed) locale = LocaleFactory.create() ProjectLocaleFactory.create(project=project, locale=locale) project.refresh_from_db() assert_true(project.has_changed)
def test_missing_entities(self): """If either of the entities is missing, skip it.""" self.changeset.update_vcs_entity = Mock() self.changeset.update_db_entity = Mock() self.call_update_translations([ ('one', None, self.main_vcs_entity), ('other', self.main_db_entity, None), ('both', None, None), ]) assert_false(self.changeset.update_vcs_entity.called) assert_false(self.changeset.update_db_entity.called)
def test_has_translation_for(self): """ Return True if a translation exists for the given locale, even if the translation is empty/falsey. """ empty_translation = VCSTranslationFactory(strings={}) full_translation = VCSTranslationFactory(strings={None: "TRANSLATED"}) entity = VCSEntityFactory() entity.translations = {"empty": empty_translation, "full": full_translation} assert_false(entity.has_translation_for("missing")) assert_true(entity.has_translation_for("empty")) assert_true(entity.has_translation_for("full"))
def test_save_create_dirs(self): """ If the directories in a resource's path don't exist, create them on save. """ path = self.get_nonexistant_file_path() translated_resource = self.get_nonexistant_file_resource(path) translated_resource.translations[0].strings = {None: "New Translated String"} assert_false(os.path.exists(path)) translated_resource.save(LocaleFactory.create()) assert_true(os.path.exists(path))
def test_has_translation_for(self): """ Return True if a translation exists for the given locale, even if the translation is empty/falsey. """ empty_translation = VCSTranslationFactory(strings={}) full_translation = VCSTranslationFactory(strings={None: 'TRANSLATED'}) entity = VCSEntityFactory() entity.translations = {'empty': empty_translation, 'full': full_translation} assert_false(entity.has_translation_for('missing')) assert_true(entity.has_translation_for('empty')) assert_true(entity.has_translation_for('full'))