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): 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): self.locale, _ = Locale.objects.get_or_create(code='fr') self.repository = RepositoryFactory() self.db_project = ProjectFactory.create( repositories=[self.repository], ) checkout_path_patch = patch.object( Repository, 'checkout_path', new_callable=PropertyMock, return_value=PROJECT_CONFIG_CHECKOUT_PATH ) self.mock_checkout_path = checkout_path_patch.start() self.addCleanup(checkout_path_patch.stop) self.resource_strings = ResourceFactory.create( project=self.db_project, path='values/strings.properties', ) self.resource_strings_reality = ResourceFactory.create( project=self.db_project, path='values/strings_reality.properties', ) # Make sure VCSConfiguration instance is initialized self.db_project.configuration_file = 'l10n.toml' self.vcs_project = VCSProject(self.db_project) self.vcs_project.configuration.configuration_path = os.path.join( PROJECT_CONFIG_CHECKOUT_PATH, self.db_project.configuration_file, )
def test_project_top_contributors(self): """ Tests if view returns top contributors specific for given project. """ first_project = ProjectFactory.create() ResourceFactory.create(project=first_project) first_project_contributor = TranslationFactory.create( entity__resource__project=first_project).user second_project = ProjectFactory.create() ResourceFactory.create(project=second_project) second_project_contributor = TranslationFactory.create( entity__resource__project=second_project).user with patch.object(views.ProjectContributorsView, 'render_to_response', return_value=HttpResponse('')) as mock_render: self.client.get('/projects/{}/contributors/'.format( first_project.slug)) assert_equal(mock_render.call_args[0][0]['project'], first_project) assert_equal(list(mock_render.call_args[0][0]['contributors']), [first_project_contributor]) self.client.get('/projects/{}/contributors/'.format( second_project.slug)) assert_equal(mock_render.call_args[0][0]['project'], second_project) assert_equal(list(mock_render.call_args[0][0]['contributors']), [second_project_contributor])
def test_project_top_contributors(client): """ Tests if view returns top contributors specific for given project. """ first_project = ProjectFactory.create(visibility="public") ResourceFactory.create(project=first_project) first_project_contributor = TranslationFactory.create( entity__resource__project=first_project).user second_project = ProjectFactory.create(visibility="public") ResourceFactory.create(project=second_project) second_project_contributor = TranslationFactory.create( entity__resource__project=second_project).user with patch( "pontoon.projects.views.ProjectContributorsView.render_to_response", return_value=HttpResponse(""), ) as mock_render: client.get( "/projects/{}/ajax/contributors/".format(first_project.slug), HTTP_X_REQUESTED_WITH="XMLHttpRequest", ) assert mock_render.call_args[0][0]["project"] == first_project assert list(mock_render.call_args[0][0]["contributors"]) == [ first_project_contributor ] client.get( "/projects/{}/ajax/contributors/".format(second_project.slug), HTTP_X_REQUESTED_WITH="XMLHttpRequest", ) assert mock_render.call_args[0][0]["project"] == second_project assert list(mock_render.call_args[0][0]["contributors"]) == [ second_project_contributor ]
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 setUp(self): """ We don't call project synchronization during the tests, so we have to create dummy resource project to avoid recurse redirect at /. """ ResourceFactory.create(project=Project.objects.get(pk=1)) self.factory = RequestFactory()
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 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.db_project = ProjectFactory.create( name='db-project', locales=[self.translated_locale], repository_type='git', repository_url='https://example.com/git' ) 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. for resource in self.vcs_project.resources.values(): save_patch = patch.object(resource, 'save') save_patch.start() self.addCleanup(save_patch.stop) self.changeset = sync_projects.ChangeSet(self.db_project, self.vcs_project)
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_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_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(client): """ Checks if project page is returned properly. """ project = ProjectFactory.create(visibility="public") ResourceFactory.create(project=project) with patch("pontoon.projects.views.render", wraps=render) as mock_render: client.get("/projects/{}/".format(project.slug)) assert mock_render.call_args[0][2]["project"] == project
def test_locale_view(self): """ Checks if locale page is returned properly. """ locale = LocaleFactory.create() # Locale requires valid project with resources ResourceFactory.create(project__locales=[locale]) with patch('pontoon.base.views.render', wraps=render) as mock_render: self.client.get('/{}/'.format(locale.code)) assert_equal(mock_render.call_args[0][2]['locale'], locale)
def test_not_authed_public_project(self): """ If the user is not authenticated and we're translating project ID 1, return a 200. """ # Clear out existing project with ID=1 if necessary. Project.objects.filter(id=1).delete() locale = LocaleFactory.create(code='fakelocale') project = ProjectFactory.create(id=1, slug='valid-project', locales=[locale]) ResourceFactory.create(project=project) response = self.client.get('/fakelocale/valid-project/') assert_equal(response.status_code, 200)
def test_not_authed_nonpublic_project(self): """ If the user is not authenticated and we're not translating project ID 1, redirect home. """ # Clear out existing project with ID=1 if necessary. Project.objects.filter(id=2).delete() locale = LocaleFactory.create(code='fakelocale') project = ProjectFactory.create(id=2, slug='valid-project', locales=[locale]) ResourceFactory.create(project=project) response = self.client.get('/fakelocale/valid-project/') assert_redirects(response, reverse('pontoon.home')) assert_equal(self.client.session['translate_error'], {'redirect': '/fakelocale/valid-project/'})
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 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) StatsFactory.create(resource=resource, locale=locale, latest_translation=translation) with patch.object(Project, 'locales_parts_stats') as mock_locales_parts_stats, \ patch('pontoon.base.views.render') as mock_render: mock_locales_parts_stats.return_value = [{ 'resource__path': 'has/stats.po' }, { 'resource__path': 'no/stats.po' }] views.locale_project(self.factory.get('/'), locale='test', slug='test-project') ctx = mock_render.call_args[0][2] assert_equal(ctx['parts'], [{ 'resource__path': 'has/stats.po', 'latest_activity': translation }, { 'resource__path': 'no/stats.po', 'latest_activity': None }])
def test_locales_parts_stats_pages_tied_to_resources(self): """ Return subpage name and stats for locales resources are available for. """ resource_other = ResourceFactory.create( project=self.project, path='/other/path.po' ) EntityFactory.create(resource=resource_other) StatsFactory.create(resource=resource_other, locale=self.locale) StatsFactory.create(resource=resource_other, locale=self.locale_other) SubpageFactory.create( project=self.project, name='Subpage', resources=[self.resource] ) SubpageFactory.create( project=self.project, name='Other Subpage', resources=[resource_other] ) project_details = self._fetch_locales_parts_stats() details = project_details.get(self.locale.code) details_other = project_details.get(self.locale_other.code) assert_equal(details[0]['resource__path'], 'Other Subpage') assert_equal(details[0]['translated_count'], 0) assert_equal(details[1]['resource__path'], 'Subpage') assert_equal(details[1]['translated_count'], 0) assert_equal(details_other[0]['resource__path'], 'Other Subpage') assert_equal(details_other[0]['translated_count'], 0)
def test_parts_stats_pages_tied_to_resources(self): """ Return subpage name and stats for locales resources are available for. """ resource_other = ResourceFactory.create( project=self.project, path='/other/path.po' ) EntityFactory.create(resource=resource_other) TranslatedResourceFactory.create(resource=resource_other, locale=self.locale) TranslatedResourceFactory.create(resource=resource_other, locale=self.locale_other) SubpageFactory.create( project=self.project, name='Subpage', resources=[self.resource] ) SubpageFactory.create( project=self.project, name='Other Subpage', resources=[resource_other] ) details = self.locale.parts_stats(self.project) details_other = self.locale_other.parts_stats(self.project) assert_equal(details[0]['title'], 'Other Subpage') assert_equal(details[0]['translated_strings'], 0) assert_equal(details[1]['title'], 'Subpage') assert_equal(details[1]['translated_strings'], 0) assert_equal(details_other[0]['title'], 'Other Subpage') assert_equal(details_other[0]['translated_strings'], 0)
def test_locales_parts_stats_pages_tied_to_resources(self): """ Return subpage name and stats for locales resources are available for. """ resource_other = ResourceFactory.create(project=self.project, path='/other/path.po') EntityFactory.create(resource=resource_other) StatsFactory.create(resource=resource_other, locale=self.locale) StatsFactory.create(resource=resource_other, locale=self.locale_other) SubpageFactory.create(project=self.project, name='Subpage', resources=[self.resource]) SubpageFactory.create(project=self.project, name='Other Subpage', resources=[resource_other]) project_details = self._fetch_locales_parts_stats() details = project_details.get(self.locale.code) details_other = project_details.get(self.locale_other.code) assert_equal(details[0]['resource__path'], 'Other Subpage') assert_equal(details[0]['translated_count'], 0) assert_equal(details[1]['resource__path'], 'Subpage') assert_equal(details[1]['translated_count'], 0) assert_equal(details_other[0]['resource__path'], 'Other Subpage') assert_equal(details_other[0]['translated_count'], 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.
def setUp(self): self.resource = ResourceFactory.create() self.locale = LocaleFactory.create() ProjectLocale.objects.create(project=self.resource.project, locale=self.locale) TranslatedResource.objects.create(resource=self.resource, locale=self.locale) self.entities = EntityFactory.create_batch(3, resource=self.resource) self.entities_pks = [e.pk for e in self.entities]
def test_parts_stats_pages_tied_to_resources(self): """ Return subpage name and stats for locales resources are available for. """ resource_other = ResourceFactory.create(project=self.project, path='/other/path.po') EntityFactory.create(resource=resource_other) TranslatedResourceFactory.create(resource=resource_other, locale=self.locale) TranslatedResourceFactory.create(resource=resource_other, locale=self.locale_other) SubpageFactory.create(project=self.project, name='Subpage', resources=[self.resource]) SubpageFactory.create(project=self.project, name='Other Subpage', resources=[resource_other]) details = self.locale.parts_stats(self.project) details_other = self.locale_other.parts_stats(self.project) assert_equal(details[0]['title'], 'Other Subpage') assert_equal(details[0]['translated_strings'], 0) assert_equal(details[1]['title'], 'Subpage') assert_equal(details[1]['translated_strings'], 0) assert_equal(details_other[0]['title'], 'Other Subpage') assert_equal(details_other[0]['translated_strings'], 0)
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 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 test_no_subpage_no_stats_in_current_locale(self): """ If there are stats for a resource available in other locales but not in the current one, and no subpages, do not set ctx['part']. """ locale, locale_no_stats = LocaleFactory.create_batch(2) project = ProjectFactory.create(locales=[locale, locale_no_stats]) resource = ResourceFactory.create(project=project, path='foo.lang', entity_count=1) ResourceFactory.create(project=project, entity_count=1) StatsFactory.create(resource=resource, locale=locale) self.client_login() url = '/{}/'.format('/'.join([locale_no_stats.code, project.slug, resource.path])) with patch('pontoon.base.views.render', wraps=render) as mock_render: self.client.get(url) assert_true('part' not in mock_render.call_args[0][2])
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 test_no_subpage_one_stats_in_current_locale(self): """ If there is just one stats for a resource available in the current locale, and no subpages, do not set ctx['part']. """ locale = LocaleFactory.create() project = ProjectFactory.create(locales=[locale]) # Need two resources to trigger setting the part value. resource = ResourceFactory.create(project=project, path='foo.lang', entity_count=1) ResourceFactory.create(project=project, entity_count=1) StatsFactory.create(resource=resource, locale=locale) self.client_login() url = '/{locale.code}/{project.slug}/'.format(locale=locale, project=project) with patch('pontoon.base.views.render', wraps=render) as mock_render: self.client.get(url) assert_true('part' not in mock_render.call_args[0][2])
def test_no_subpage_multiple_stats_in_current_locale(self): """ If there are multiple stats for a resource available in the current locale, and no subpages, set the part to the resource path. """ locale = LocaleFactory.create() project = ProjectFactory.create(locales=[locale]) resource1 = ResourceFactory.create(project=project, path='foo1.lang', entity_count=1) resource2 = ResourceFactory.create(project=project, path='foo2.lang', entity_count=1) StatsFactory.create(resource=resource1, locale=locale) StatsFactory.create(resource=resource2, locale=locale) self.client_login() url = '/' + '/'.join([locale.code, project.slug, resource1.path]) + '/' with patch('pontoon.base.views.render', wraps=render) as mock_render: self.client.get(url) assert_equal(mock_render.call_args[0][2]['part'], 'foo1.lang')
def test_no_subpage_multiple_stats_in_current_locale(self): """ If there are multiple stats for a resource available in the current locale, and no subpages, set the part to the resource path. """ locale = LocaleFactory.create() project = ProjectFactory.create(locales=[locale]) # Need at least two resources and stats to trigger setting the part value. resource1 = ResourceFactory.create(project=project, path="foo1.lang", entity_count=1) resource2 = ResourceFactory.create(project=project, path="foo2.lang", entity_count=1) StatsFactory.create(resource=resource1, locale=locale) StatsFactory.create(resource=resource2, locale=locale) self.client_login() url = "/{locale.code}/{project.slug}/".format(locale=locale, project=project) with patch("pontoon.base.views.render", wraps=render) as mock_render: self.client.get(url) assert_equal(mock_render.call_args[0][2]["part"], "foo1.lang")
def setUp(self): self.locale, _ = Locale.objects.get_or_create(code='fr') self.repository = RepositoryFactory() self.db_project = ProjectFactory.create(repositories=[self.repository ], ) self.resource_strings = ResourceFactory.create( project=self.db_project, path='strings.properties', ) self.resource_strings_reality = ResourceFactory.create( project=self.db_project, path='strings_reality.properties', ) # Make sure VCSConfiguration instance is initialized self.db_project.configuration_file = 'l10n.toml' self.vcs_project = VCSProject(self.db_project)
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 test_project_top_contributors(self): """ Tests if view returns top contributors specific for given project. """ first_project = ProjectFactory.create() ResourceFactory.create(project=first_project) first_project_contributor = TranslationFactory.create(entity__resource__project=first_project).user second_project = ProjectFactory.create() ResourceFactory.create(project=second_project) second_project_contributor = TranslationFactory.create(entity__resource__project=second_project).user with patch.object(views.ProjectContributorsView, 'render_to_response', return_value=HttpResponse('')) as mock_render: self.client.get('/projects/{}/contributors/'.format(first_project.slug)) assert_equal(mock_render.call_args[0][0]['project'], first_project) assert_equal(list(mock_render.call_args[0][0]['contributors']), [first_project_contributor]) self.client.get('/projects/{}/contributors/'.format(second_project.slug)) assert_equal(mock_render.call_args[0][0]['project'], second_project) assert_equal(list(mock_render.call_args[0][0]['contributors']), [second_project_contributor])
def test_no_subpage_no_stats_in_current_locale(self): """ If there are stats for a resource available in other locales but not in the current one, and no subpages, do not set ctx['part']. """ locale, locale_no_stats = LocaleFactory.create_batch(2) project = ProjectFactory.create(locales=[locale, locale_no_stats]) # Need two resources to trigger setting the part value. resource = ResourceFactory.create(project=project, path='foo.lang', entity_count=1) ResourceFactory.create(project=project, entity_count=1) StatsFactory.create(resource=resource, locale=locale) self.client_login() url = '/{locale.code}/{project.slug}/'.format(locale=locale_no_stats, project=project) with patch('pontoon.base.views.render', wraps=render) as mock_render: self.client.get(url) assert_true('part' not in mock_render.call_args[0][2])
def test_project_top_contributors(self): """ Tests if view returns top contributors specific for given project. """ first_project = ProjectFactory.create() ResourceFactory.create(project=first_project) first_project_contributor = TranslationFactory.create( entity__resource__project=first_project).user second_project = ProjectFactory.create() ResourceFactory.create(project=second_project) second_project_contributor = TranslationFactory.create( entity__resource__project=second_project).user with patch.object( views.ProjectContributorsView, "render_to_response", return_value=HttpResponse(""), ) as mock_render: self.client.get( "/projects/{}/ajax/contributors/".format(first_project.slug), HTTP_X_REQUESTED_WITH="XMLHttpRequest", ) assert_equal(mock_render.call_args[0][0]["project"], first_project) assert_equal( list(mock_render.call_args[0][0]["contributors"]), [first_project_contributor], ) self.client.get( "/projects/{}/ajax/contributors/".format(second_project.slug), HTTP_X_REQUESTED_WITH="XMLHttpRequest", ) assert_equal(mock_render.call_args[0][0]["project"], second_project) assert_equal( list(mock_render.call_args[0][0]["contributors"]), [second_project_contributor], )
def setUp(self): super(TranslationUpdateTestCase, self).setUp() locale = LocaleFactory.create() project = ProjectFactory.create() ProjectLocale.objects.create( project=project, locale=locale, ) resource = ResourceFactory.create(project=project) entity = EntityFactory.create(resource=resource) self.translation = TranslationFactory.create(entity=entity, locale=locale) self.translation.locale.translators_group.user_set.add(self.user)
def test_no_subpage_multiple_stats_in_current_locale(self): """ If there are multiple stats for a resource available in the current locale, and no subpages, set the part to the resource path. """ locale = LocaleFactory.create() project = ProjectFactory.create(locales=[locale]) # Need at least two resources and stats to trigger setting the part value. resource1 = ResourceFactory.create(project=project, path='foo1.lang', entity_count=1) resource2 = ResourceFactory.create(project=project, path='foo2.lang', entity_count=1) StatsFactory.create(resource=resource1, locale=locale) StatsFactory.create(resource=resource2, locale=locale) self.client_login() url = '/{locale.code}/{project.slug}/'.format(locale=locale, project=project) with patch('pontoon.base.views.render', wraps=render) as mock_render: self.client.get(url) assert_equal(mock_render.call_args[0][2]['part'], 'foo1.lang')
def test_parts_stats_no_page_multiple_resources(self): """ Return resource paths and stats for locales resources are available for. """ resource_other = ResourceFactory.create(project=self.project, path="/other/path.po") EntityFactory.create(resource=resource_other) StatsFactory.create(resource=resource_other, locale=self.locale) StatsFactory.create(resource=resource_other, locale=self.locale_other) details = self.locale.parts_stats(self.project) details_other = self.locale_other.parts_stats(self.project) assert_equal(details[0]["resource__path"], "/main/path.po") assert_equal(details[0]["translated_count"], 0) assert_equal(details[1]["resource__path"], "/other/path.po") assert_equal(details[1]["translated_count"], 0) assert_equal(len(details_other), 1) assert_equal(details_other[0]["resource__path"], "/other/path.po") assert_equal(details_other[0]["translated_count"], 0)
def test_save_latest_translation_missing_project_locale(self): """ If a translation is saved for a locale that isn't active on the project, do not fail due to a missing ProjectLocale. """ locale = LocaleFactory.create(latest_translation=None) project = ProjectFactory.create(latest_translation=None) resource = ResourceFactory.create(project=project) stats = StatsFactory.create(locale=locale, resource=resource, latest_translation=None) # This calls .save, this should fail if we're not properly # handling the missing ProjectLocale. 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)
def test_parts_stats_pages_tied_to_resources(self): """ Return subpage name and stats for locales resources are available for. """ resource_other = ResourceFactory.create(project=self.project, path="/other/path.po") EntityFactory.create(resource=resource_other) StatsFactory.create(resource=resource_other, locale=self.locale) StatsFactory.create(resource=resource_other, locale=self.locale_other) SubpageFactory.create(project=self.project, name="Subpage", resources=[self.resource]) SubpageFactory.create(project=self.project, name="Other Subpage", resources=[resource_other]) details = self.locale.parts_stats(self.project) details_other = self.locale_other.parts_stats(self.project) assert_equal(details[0]["resource__path"], "Other Subpage") assert_equal(details[0]["translated_count"], 0) assert_equal(details[1]["resource__path"], "Subpage") assert_equal(details[1]["translated_count"], 0) assert_equal(details_other[0]["resource__path"], "Other Subpage") assert_equal(details_other[0]["translated_count"], 0)
def test_parts_stats_no_page_multiple_resources(self): """ Return resource paths and stats for locales resources are available for. """ resource_other = ResourceFactory.create(project=self.project, path='/other/path.po') EntityFactory.create(resource=resource_other) StatsFactory.create(resource=resource_other, locale=self.locale) StatsFactory.create(resource=resource_other, locale=self.locale_other) details = self.locale.parts_stats(self.project) details_other = self.locale_other.parts_stats(self.project) assert_equal(details[0]['resource__path'], '/main/path.po') assert_equal(details[0]['translated_count'], 0) assert_equal(details[1]['resource__path'], '/other/path.po') assert_equal(details[1]['translated_count'], 0) assert_equal(len(details_other), 1) assert_equal(details_other[0]['resource__path'], '/other/path.po') assert_equal(details_other[0]['translated_count'], 0)
def test_save_latest_translation_missing_project_locale(self): """ If a translation is saved for a locale that isn't active on the project, do not fail due to a missing ProjectLocale. """ locale = LocaleFactory.create(latest_translation=None) project = ProjectFactory.create(latest_translation=None) resource = ResourceFactory.create(project=project) translatedresource = TranslatedResourceFactory.create( locale=locale, resource=resource, latest_translation=None) # This calls .save, this should fail if we're not properly # handling the missing ProjectLocale. 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(translatedresource, translation)
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) StatsFactory.create(resource=resource, locale=locale, latest_translation=translation) with patch.object(Project, 'locales_parts_stats') as mock_locales_parts_stats, \ patch('pontoon.base.views.render') as mock_render: mock_locales_parts_stats.return_value = [ {'resource__path': 'has/stats.po'}, {'resource__path': 'no/stats.po'} ] views.locale_project(self.factory.get('/'), locale='test', slug='test-project') ctx = mock_render.call_args[0][2] assert_equal(ctx['parts'], [ {'resource__path': 'has/stats.po', 'latest_activity': translation}, {'resource__path': 'no/stats.po', 'latest_activity': None} ])
def test_parts_stats_no_page_multiple_resources(self): """ Return resource paths and stats for locales resources are available for. """ resource_other = ResourceFactory.create( project=self.project, path='/other/path.po' ) EntityFactory.create(resource=resource_other) TranslatedResourceFactory.create(resource=resource_other, locale=self.locale) TranslatedResourceFactory.create(resource=resource_other, locale=self.locale_other) details = self.locale.parts_stats(self.project) details_other = self.locale_other.parts_stats(self.project) assert_equal(details[0]['title'], '/main/path.po') assert_equal(details[0]['translated_strings'], 0) assert_equal(details[1]['title'], '/other/path.po') assert_equal(details[1]['translated_strings'], 0) assert_equal(len(details_other), 1) assert_equal(details_other[0]['title'], '/other/path.po') assert_equal(details_other[0]['translated_strings'], 0)
def test_locales_parts_stats_no_page_multiple_resources(self): """ Return resource paths and stats for locales resources are available for. """ resource_other = ResourceFactory.create( project=self.project, path='/other/path.po' ) EntityFactory.create(resource=resource_other) StatsFactory.create(resource=resource_other, locale=self.locale) StatsFactory.create(resource=resource_other, locale=self.locale_other) project_details = self._fetch_locales_parts_stats() details = project_details.get(self.locale.code) details_other = project_details.get(self.locale_other.code) assert_equal(details[0]['resource__path'], '/main/path.po') assert_equal(details[0]['translated_count'], 0) assert_equal(details[1]['resource__path'], '/other/path.po') assert_equal(details[1]['translated_count'], 0) assert_equal(len(details_other), 1) assert_equal(details_other[0]['resource__path'], '/other/path.po') assert_equal(details_other[0]['translated_count'], 0)
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_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, '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_latest_activity(mock_parts_stats, mock_render, client, project_a, locale_a): """Ensure that the latest_activity field is added to parts.""" resource = ResourceFactory.create(project=project_a, path='has/stats.po') resource2 = ResourceFactory.create(project=project_a, path='has/stats2.po') translation = TranslationFactory.create(entity__resource=resource, locale=locale_a) TranslatedResourceFactory.create( resource=resource2, locale=locale_a, latest_translation=translation ) mock_parts_stats.return_value = [ { 'title': 'has/stats.po', 'resource__path': 'has/stats.po', 'resource__total_strings': 1, 'approved_strings': 0, 'unreviewed_strings': 1, 'fuzzy_strings': 0, 'strings_with_warnings': 0, 'strings_with_errors': 0, 'resource__deadline': None, 'resource__priority': None, }, { 'title': 'no/stats.po', 'resource__path': 'no/stats.po', 'resource__total_strings': 1, 'approved_strings': 0, 'unreviewed_strings': 0, 'fuzzy_strings': 0, 'strings_with_warnings': 0, 'strings_with_errors': 0, 'resource__deadline': None, 'resource__priority': None, } ] client.get( reverse( 'pontoon.localizations.ajax.resources', args=[ locale_a.code, project_a.slug ], ), HTTP_X_REQUESTED_WITH='XMLHttpRequest' ) ctx = mock_render.call_args[0][2] assert ctx['resources'] == [ { 'latest_activity': translation.latest_activity, 'title': 'has/stats.po', 'resource__path': 'has/stats.po', 'resource__deadline': None, 'resource__priority': None, 'resource__total_strings': 1, 'approved_strings': 0, 'unreviewed_strings': 1, 'fuzzy_strings': 0, 'strings_with_errors': 0, 'strings_with_warnings': 0, 'chart': { 'fuzzy_strings': 0, 'total_strings': 1, 'approved_strings': 0, 'unreviewed_strings': 1, 'strings_with_errors': 0, 'strings_with_warnings': 0, 'approved_share': 0.0, 'unreviewed_share': 100.0, 'fuzzy_share': 0.0, 'warnings_share': 0.0, 'errors_share': 0.0, 'completion_percent': 0, } }, { 'latest_activity': None, 'title': 'no/stats.po', 'resource__path': 'no/stats.po', 'resource__deadline': None, 'resource__priority': None, 'resource__total_strings': 1, 'approved_strings': 0, 'unreviewed_strings': 0, 'fuzzy_strings': 0, 'strings_with_errors': 0, 'strings_with_warnings': 0, 'chart': { 'fuzzy_strings': 0, 'total_strings': 1, 'approved_strings': 0, 'unreviewed_strings': 0, 'strings_with_errors': 0, 'strings_with_warnings': 0, 'approved_share': 0.0, 'unreviewed_share': 0.0, 'fuzzy_share': 0.0, 'warnings_share': 0.0, 'errors_share': 0.0, 'completion_percent': 0, } } ]
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) 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))
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, )