def test_disabled_projects(self): """Only sync projects that aren't disabled.""" ProjectFactory.create(disabled=True) active_project = ProjectFactory.create(disabled=False) self.execute_command() self.mock_sync_project.delay.assert_called_with(active_project.pk, no_pull=False, no_commit=False)
def test_handle_disabled_projects(self): """Only sync projects that aren't disabled.""" disabled_project = ProjectFactory.create(disabled=True) active_project = ProjectFactory.create(disabled=False) self.command.handle_project = Mock() self.execute_command() self.command.handle_project.assert_any_call(active_project) assert_not_in(call(disabled_project), self.command.handle_project.mock_calls)
def test_needs_sync(self): """ Project.needs_sync should be True if ChangedEntityLocale objects exist for its entities or if Project.has_changed is True. """ assert_true(ProjectFactory.create(has_changed=True).needs_sync) project = ProjectFactory.create(has_changed=False) ChangedEntityLocaleFactory.create(entity__resource__project=project) assert_true(project.needs_sync)
def test_locale_not_available(self): """ If the requested locale is not available for this project, redirect home. """ LocaleFactory.create(code='fakelocale') ProjectFactory.create(slug='valid-project') response = self.client.get('/fakelocale/valid-project/path/') assert_equal(response.status_code, 404)
def test_locale_not_available(self): """ If the requested locale is not available for this project, redirect home. """ LocaleFactory.create(code='fakelocale') ProjectFactory.create(slug='valid-project') response = self.client.get('/fakelocale/valid-project/') assert_redirects(response, reverse('pontoon.home')) assert_equal(self.client.session['translate_error'], {'none': None})
def test_locale_not_available(self): """ If the requested locale is not available for this project, redirect home. """ LocaleFactory.create(code="fakelocale") ProjectFactory.create(slug="valid-project") response = self.client.get("/fakelocale/valid-project/") assert_redirects(response, reverse("pontoon.home")) assert_equal(self.client.session["translate_error"], {"none": None})
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_non_repository_projects(self): """Only sync projects with data_source=repository.""" ProjectFactory.create(data_source='database') repo_project = ProjectFactory.create(data_source='repository') self.execute_command() self.mock_sync_project.delay.assert_called_with( repo_project.pk, ANY, locale=None, no_pull=False, no_commit=False, force=False )
def test_repository_for_path_none(self): """ If the project has no matching repositories, raise a ValueError. """ project = ProjectFactory.create(repositories=[]) with assert_raises(ValueError): project.repository_for_path("doesnt/exist")
def test_get_latest_activity_without_latest(self): """ If the project doesn't have a latest_translation and no locale is given, return None. """ project = ProjectFactory.create(latest_translation=None) assert_is_none(project.get_latest_activity())
def setUp(self): self.locale = LocaleFactory.create(cldr_plurals="0,1") self.project = ProjectFactory.create(locales=[self.locale]) self.main_resource = ResourceFactory.create(project=self.project, path="main.lang") self.other_resource = ResourceFactory.create(project=self.project, path="other.lang") self.main_entity = EntityFactory.create( resource=self.main_resource, string="Source String", string_plural="Plural Source String", key="Source String", ) self.other_entity = EntityFactory.create( resource=self.other_resource, string="Other Source String", key="Key" + KEY_SEPARATOR + "Other Source String", ) self.main_translation = TranslationFactory.create( entity=self.main_entity, locale=self.locale, plural_form=0, string="Translated String" ) self.main_translation_plural = TranslationFactory.create( entity=self.main_entity, locale=self.locale, plural_form=1, string="Translated Plural String" ) self.other_translation = TranslationFactory.create( entity=self.other_entity, locale=self.locale, string="Other Translated String" ) self.subpage = SubpageFactory.create(project=self.project, name="Subpage", resources=[self.main_resource])
def setUp(self): """ We setup a sample contributor with random set of translations. """ super(ContributorTimelineViewTests, self).setUp() self.project = ProjectFactory.create() self.translations = OrderedDict() for i in range(26): date = make_aware(datetime(2016, 12, 1) - timedelta(days=i)) translations_count = randint(1, 3) self.translations.setdefault((date, translations_count), []).append( sorted( TranslationFactory.create_batch( translations_count, date=date, user=self.user, entity__resource__project=self.project, ), key=lambda t: t.pk, reverse=True, ) ) mock_render = patch('pontoon.contributors.views.render', return_value=HttpResponse('')) self.mock_render = mock_render.start() self.addCleanup(mock_render.stop)
def test_save_latest_translation_update(self): """ When a translation is saved, update the latest_translation attribute on the related project, locale, stats, and project_locale objects. """ locale = LocaleFactory.create(latest_translation=None) project = ProjectFactory.create(locales=[locale], latest_translation=None) resource = ResourceFactory.create(project=project) stats = StatsFactory.create(locale=locale, resource=resource, latest_translation=None) project_locale = ProjectLocale.objects.get(locale=locale, project=project) assert_is_none(locale.latest_translation) assert_is_none(project.latest_translation) assert_is_none(stats.latest_translation) assert_is_none(project_locale.latest_translation) translation = TranslationFactory.create( locale=locale, entity__resource=resource, date=aware_datetime(1970, 1, 1) ) self.assert_latest_translation(locale, translation) self.assert_latest_translation(project, translation) self.assert_latest_translation(stats, translation) self.assert_latest_translation(project_locale, translation) # Ensure translation is replaced for newer translations newer_translation = TranslationFactory.create( locale=locale, entity__resource=resource, date=aware_datetime(1970, 2, 1) ) self.assert_latest_translation(locale, newer_translation) self.assert_latest_translation(project, newer_translation) self.assert_latest_translation(stats, newer_translation) self.assert_latest_translation(project_locale, newer_translation) # Ensure translation isn't replaced for older translations. TranslationFactory.create( locale=locale, entity__resource=resource, date=aware_datetime(1970, 1, 5) ) self.assert_latest_translation(locale, newer_translation) self.assert_latest_translation(project, newer_translation) self.assert_latest_translation(stats, newer_translation) self.assert_latest_translation(project_locale, newer_translation) # Ensure approved_date is taken into consideration as well. newer_approved_translation = TranslationFactory.create( locale=locale, entity__resource=resource, approved_date=aware_datetime(1970, 3, 1) ) self.assert_latest_translation(locale, newer_approved_translation) self.assert_latest_translation(project, newer_approved_translation) self.assert_latest_translation(stats, newer_approved_translation) self.assert_latest_translation(project_locale, newer_approved_translation)
def setUp(self): timezone_patch = patch.object(sync_projects, 'timezone') self.mock_timezone = timezone_patch.start() self.addCleanup(timezone_patch.stop) self.mock_timezone.now.return_value = aware_datetime(1970, 1, 1) self.translated_locale = LocaleFactory.create(code='translated-locale') self.inactive_locale = LocaleFactory.create(code='inactive-locale') self.repository = RepositoryFactory() self.db_project = ProjectFactory.create( name='db-project', locales=[self.translated_locale], repositories=[self.repository] ) self.main_db_resource = ResourceFactory.create( project=self.db_project, path='main.lang', format='lang' ) self.other_db_resource = ResourceFactory.create( project=self.db_project, path='other.lang', format='lang' ) self.missing_db_resource = ResourceFactory.create( project=self.db_project, path='missing.lang', format='lang' ) # Load paths from the fake locale directory. checkout_path_patch = patch.object( Project, 'checkout_path', new_callable=PropertyMock, return_value=FAKE_CHECKOUT_PATH ) checkout_path_patch.start() self.addCleanup(checkout_path_patch.stop) self.vcs_project = VCSProject(self.db_project) self.main_vcs_resource = self.vcs_project.resources[self.main_db_resource.path] self.other_vcs_resource = self.vcs_project.resources[self.other_db_resource.path] self.missing_vcs_resource = self.vcs_project.resources[self.missing_db_resource.path] self.main_vcs_entity = self.main_vcs_resource.entities['Source String'] self.main_vcs_translation = self.main_vcs_entity.translations['translated-locale'] # Mock VCSResource.save() for each resource to avoid altering # the filesystem. resource_save_patch = patch.object(VCSResource, 'save') resource_save_patch.start() self.addCleanup(resource_save_patch.stop) self.changeset = sync_projects.ChangeSet( self.db_project, self.vcs_project, aware_datetime(1970, 1, 1) )
def test_can_commit_true(self): """ can_commit should be True if there is a repo that can be committed to. """ repo = RepositoryFactory.build(type=Repository.GIT) project = ProjectFactory.create(repositories=[repo]) assert_true(project.can_commit)
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_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_repository_type_first(self): """ If a project has repos, return the type of the repo created first. """ project = ProjectFactory.create(repositories=[]) RepositoryFactory.create(project=project, type=Repository.GIT) RepositoryFactory.create(project=project, type=Repository.HG) assert_equal(project.repository_type, Repository.GIT)
def test_repository_for_path(self): """ Return the first repo found with a checkout path that contains the given path. """ repo1, repo2, repo3 = RepositoryFactory.build_batch(3) project = ProjectFactory.create(repositories=[repo1, repo2, repo3]) path = os.path.join(repo2.checkout_path, "foo", "bar") assert_equal(project.repository_for_path(path), repo2)
def test_invalid_locale_valid_project(self): """ If the project is valid but the locale isn't, redirect home. """ project = ProjectFactory.create(slug='valid-project') ResourceFactory.create(project=project) response = self.client.get('/invalid-locale/valid-project/path/') assert_equal(response.status_code, 404)
def test_project_slugs(self): """ If project slugs are passed to Command.handle, only sync projects matching those slugs. """ ignore_project, handle_project = ProjectFactory.create_batch(2) self.execute_command(handle_project.slug) self.mock_sync_project.delay.assert_called_with(handle_project.pk, no_pull=False, no_commit=False)
def test_invalid_locale_valid_project(self): """ If the project is valid but the locale isn't, redirect home. """ project = ProjectFactory.create(slug="valid-project") ResourceFactory.create(project=project) response = self.client.get("/invalid-locale/valid-project/") assert_redirects(response, reverse("pontoon.home")) assert_equal(self.client.session["translate_error"], {"none": None})
def test_options(self): project = ProjectFactory.create() self.execute_command(no_pull=True, no_commit=True) self.mock_sync_project.delay.assert_called_with( project.pk, ANY, no_pull=True, no_commit=True, force=False )
def test_invalid_locale_valid_project(self): """ If the project is valid but the locale isn't, redirect home. """ project = ProjectFactory.create(slug='valid-project') ResourceFactory.create(project=project) response = self.client.get('/invalid-locale/valid-project/') assert_redirects(response, reverse('pontoon.home')) assert_equal(self.client.session['translate_error'], {'none': None})
def test_project_view(self): """ Checks if project page is returned properly. """ project = ProjectFactory.create() ResourceFactory.create(project=project) with patch('pontoon.base.views.render', wraps=render) as mock_render: self.client.get('/projects/{}/'.format(project.slug)) assert_equal(mock_render.call_args[0][2]['project'], project)
def test_handle_project_slugs(self): """ If project slugs are passed to Command.handle, only sync projects matching those slugs. """ ignore_project, handle_project = ProjectFactory.create_batch(2) self.command.handle_project = Mock() self.execute_command(handle_project.slug) self.command.handle_project.assert_called_with(handle_project) assert_not_in(call(ignore_project), self.command.handle_project.mock_calls)
def test_get_latest_activity_with_latest(self): """ If the project has a latest_translation and no locale is given, return it. """ project = ProjectFactory.create() translation = TranslationFactory.create(entity__resource__project=project) project.latest_translation = translation project.save() assert_equal(project.get_latest_activity(), translation.latest_activity)
def setUp(self): self.locale, self.locale_other = LocaleFactory.create_batch(2) self.project = ProjectFactory.create( locales=[self.locale, self.locale_other] ) self.resource = ResourceFactory.create( project=self.project, path='/main/path.po' ) EntityFactory.create(resource=self.resource) StatsFactory.create(resource=self.resource, locale=self.locale)
def setUp(self): super(SyncProjectTests, self).setUp() self.db_project = ProjectFactory.create() self.sync_log = SyncLogFactory.create() self.mock_pull_changes = self.patch( 'pontoon.sync.tasks.pull_changes', return_value=True) self.mock_project_needs_sync = self.patch_object( Project, 'needs_sync', new_callable=PropertyMock, return_value=True) self.mock_sync_project_repo = self.patch('pontoon.sync.tasks.sync_project_repo') self.mock_perform_sync_project = self.patch('pontoon.sync.tasks.perform_sync_project', return_value=[[], []])
def test_get_latest_activity_with_locale(self): """ If a locale is given, defer to ProjectLocale.get_latest_activity. """ locale = LocaleFactory.create() project = ProjectFactory.create(locales=[locale]) with patch.object(ProjectLocale, "get_latest_activity") as mock_get_latest_activity: mock_get_latest_activity.return_value = "latest" assert_equal(locale.get_latest_activity(project=project), "latest") mock_get_latest_activity.assert_called_with(project, locale)
def test_latest_activity(self): """Ensure that the latest_activity field is added to parts.""" locale = LocaleFactory.create(code='test') project = ProjectFactory.create(locales=[locale], slug='test-project') resource = ResourceFactory.create(project=project, path='has/stats.po') translation = TranslationFactory.create(entity__resource=resource, locale=locale) TranslatedResourceFactory.create(resource=resource, locale=locale, latest_translation=translation) with patch.object(Locale, 'parts_stats') as mock_parts_stats, \ patch('pontoon.base.views.render') as mock_render: mock_parts_stats.return_value = [{ 'title': 'has/stats.po', 'resource__path': 'has/stats.po', 'resource__total_strings': 1, 'approved_strings': 0, 'translated_strings': 1, 'fuzzy_strings': 0, }, { 'title': 'no/stats.po', 'resource__path': 'no/stats.po', 'resource__total_strings': 1, 'approved_strings': 0, 'translated_strings': 0, 'fuzzy_strings': 0, }] views.locale_project(self.factory.get('/'), locale='test', slug='test-project') ctx = mock_render.call_args[0][2] assert_equal(ctx['parts'], [{ 'latest_activity': translation.latest_activity, 'title': 'has/stats.po', 'resource__path': 'has/stats.po', 'resource__total_strings': 1, 'approved_strings': 0, 'translated_strings': 1, 'fuzzy_strings': 0, 'chart': { 'fuzzy_strings': 0, 'total_strings': 1, 'approved_strings': 0, 'translated_strings': 1, 'approved_share': 0.0, 'translated_share': 100.0, 'fuzzy_share': 0.0, 'approved_percent': 0 } }, { 'latest_activity': None, 'title': 'no/stats.po', 'resource__path': 'no/stats.po', 'resource__total_strings': 1, 'approved_strings': 0, 'translated_strings': 0, 'fuzzy_strings': 0, 'chart': { 'fuzzy_strings': 0, 'total_strings': 1, 'approved_strings': 0, 'translated_strings': 0, 'approved_share': 0.0, 'translated_share': 0.0, 'fuzzy_share': 0.0, 'approved_percent': 0 } }])
def test_manage_project_strings_list(self): project = ProjectFactory.create(data_source='database', repositories=[]) resource = ResourceFactory.create(project=project) nb_entities = 2 entities = EntityFactory.create_batch(nb_entities, resource=resource) url = reverse('pontoon.admin.project.strings', args=(project.slug, )) response = self.client.get(url) assert_code(response, 200) for i in range(nb_entities): assert_contains(response, 'string %s' % i) # Test editing strings and comments. form_data = { 'form-TOTAL_FORMS': nb_entities, 'form-INITIAL_FORMS': nb_entities, 'form-MIN_NUM_FORMS': 0, 'form-MAX_NUM_FORMS': 1000, 'form-0-id': entities[0].id, 'form-0-string': 'changed 0', 'form-0-comment': 'Wubba lubba dub dub', 'form-1-id': entities[1].id, 'form-1-string': 'string 1', 'form-1-obsolete': 'on', # Remove this one. } response = self.client.post(url, form_data) assert_code(response, 200) assert_contains(response, 'changed 0') assert_contains(response, 'Wubba lubba dub dub') assert_not_contains(response, 'string 0') assert_not_contains(response, 'string 1') # It's been removed. total = Entity.objects.filter( resource=resource, obsolete=False, ).count() assert_equal(total, nb_entities - 1) # Test adding a new string. form_data = { 'form-TOTAL_FORMS': nb_entities, 'form-INITIAL_FORMS': nb_entities - 1, 'form-MIN_NUM_FORMS': 0, 'form-MAX_NUM_FORMS': 1000, 'form-0-id': entities[0].id, 'form-0-string': 'changed 0', 'form-0-comment': 'Wubba lubba dub dub', 'form-1-id': '', 'form-1-string': 'new string', 'form-1-comment': 'adding this entity now', } response = self.client.post(url, form_data) assert_code(response, 200) assert_contains(response, 'changed 0') assert_contains(response, 'new string') assert_contains(response, 'adding this entity now') total = Entity.objects.filter( resource=resource, obsolete=False, ).count() assert_equal(total, nb_entities)
def test_manage_project_strings_download_csv(self): locale_kl = LocaleFactory.create(code='kl', name='Klingon') locale_gs = LocaleFactory.create(code='gs', name='Geonosian') project = ProjectFactory.create(data_source='database', locales=[locale_kl, locale_gs], repositories=[]) url = reverse('pontoon.admin.project.strings', args=(project.slug, )) new_strings = """ And on the pedestal these words appear: 'My name is Ozymandias, king of kings: Look on my works, ye Mighty, and despair!' """ response = self.client.post(url, {'new_strings': new_strings}) assert_code(response, 200) # Test downloading the data. response = self.client.get(url, {'format': 'csv'}) assert_code(response, 200) assert_equal(response._headers['content-type'], ('Content-Type', 'text/csv')) # Verify the original content is here. assert_contains(response, 'pedestal') assert_contains(response, 'Ozymandias') assert_contains(response, 'Mighty') # Verify we have the locale columns. assert_contains(response, 'kl') assert_contains(response, 'gs') # Now add some translations. entity = Entity.objects.filter( string='And on the pedestal these words appear:')[0] TranslationFactory.create( string='Et sur le piédestal il y a ces mots :', entity=entity, locale=locale_kl, approved=True, ) TranslationFactory.create( string='Und auf dem Sockel steht die Schrift: ‚Mein Name', entity=entity, locale=locale_gs, approved=True, ) entity = Entity.objects.filter( string='\'My name is Ozymandias, king of kings:')[0] TranslationFactory.create( string='"Mon nom est Ozymandias, Roi des Rois.', entity=entity, locale=locale_kl, approved=True, ) TranslationFactory.create( string='Ist Osymandias, aller Kön’ge König: –', entity=entity, locale=locale_gs, approved=True, ) entity = Entity.objects.filter( string='Look on my works, ye Mighty, and despair!\'')[0] TranslationFactory.create( string='Voyez mon œuvre, vous puissants, et désespérez !"', entity=entity, locale=locale_kl, approved=True, ) TranslationFactory.create( string='Seht meine Werke, Mächt’ge, und erbebt!‘', entity=entity, locale=locale_gs, approved=True, ) response = self.client.get(url, {'format': 'csv'}) # Verify the translated content is here. assert_contains(response, 'pedestal') assert_contains(response, 'piédestal') assert_contains(response, 'Sockel') assert_contains(response, 'Mighty') assert_contains(response, 'puissants') assert_contains(response, 'Mächt’ge')
def test_can_commit_no_repos(self): """can_commit should be False if there are no repos.""" project = ProjectFactory.create(repositories=[]) assert_false(project.can_commit)
def setUp(self): self.now = aware_datetime(1970, 1, 1) timezone_patch = patch("pontoon.sync.tasks.timezone") self.mock_timezone = timezone_patch.start() self.addCleanup(timezone_patch.stop) self.mock_timezone.now.return_value = self.now self.translated_locale = LocaleFactory.create(code="translated-locale") self.inactive_locale = LocaleFactory.create(code="inactive-locale") self.repository = RepositoryFactory() self.db_project = ProjectFactory.create( name="db-project", locales=[self.translated_locale], repositories=[self.repository], ) self.main_db_resource = ResourceFactory.create(project=self.db_project, path="main.lang", format="lang") self.other_db_resource = ResourceFactory.create( project=self.db_project, path="other.lang", format="lang") self.missing_db_resource = ResourceFactory.create( project=self.db_project, path="missing.lang", format="lang") self.main_db_entity = EntityFactory.create( resource=self.main_db_resource, string="Source String", key="Source String", obsolete=False, ) self.other_db_entity = EntityFactory.create( resource=self.other_db_resource, string="Other Source String", key="Other Source String", obsolete=False, ) self.main_db_translation = TranslationFactory.create( entity=self.main_db_entity, plural_form=None, locale=self.translated_locale, string="Translated String", date=aware_datetime(1970, 1, 1), approved=True, extra={"tags": []}, ) # Load paths from the fake locale directory. checkout_path_patch = patch.object( Project, "checkout_path", new_callable=PropertyMock, return_value=FAKE_CHECKOUT_PATH, ) checkout_path_patch.start() self.addCleanup(checkout_path_patch.stop) vcs_changed_files = { self.main_db_resource.path: [self.translated_locale], self.other_db_resource.path: [self.translated_locale], self.missing_db_resource.path: [self.translated_locale], } changed_files_patch = patch.object( VCSProject, "changed_files", new_callable=PropertyMock, return_value=vcs_changed_files, ) changed_files_patch.start() self.addCleanup(changed_files_patch.stop) source_repository = patch.object( Project, "source_repository", new_callable=PropertyMock, return_value=self.db_project.repositories.all()[0], ) source_repository.start() self.addCleanup(source_repository.stop) self.vcs_project = VCSProject(self.db_project) self.main_vcs_resource = self.vcs_project.resources[ self.main_db_resource.path] self.other_vcs_resource = self.vcs_project.resources[ self.other_db_resource.path] self.missing_vcs_resource = self.vcs_project.resources[ self.missing_db_resource.path] self.main_vcs_entity = self.main_vcs_resource.entities["Source String"] self.main_vcs_translation = self.main_vcs_entity.translations[ "translated-locale"] # Mock VCSResource.save() for each resource to avoid altering # the filesystem. resource_save_patch = patch.object(VCSResource, "save") resource_save_patch.start() self.addCleanup(resource_save_patch.stop) self.changeset = ChangeSet( self.db_project, self.vcs_project, aware_datetime(1970, 1, 1), self.translated_locale, )