Skip to content

Commit

Permalink
Merge bb53ec0 into bd6d97e
Browse files Browse the repository at this point in the history
  • Loading branch information
phlax authored Apr 5, 2018
2 parents bd6d97e + bb53ec0 commit 777b103
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 97 deletions.
3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
dist: trusty
sudo: false
language: python
addons:
hosts:
- redis
env:
- TOXENV=py27-django110-sqlite PYTHONPATH=$HOME/virtualenv/python2.7.14/lib/python2.7/site-packages TOX_TESTENV_PASSENV="PYTHONPATH"
- TOXENV=py27-django110-mysql PYTHONPATH=$HOME/virtualenv/python2.7.14/lib/python2.7/site-packages TOX_TESTENV_PASSENV="PYTHONPATH"
Expand Down
9 changes: 6 additions & 3 deletions pootle/apps/pootle_fs/files.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,17 @@ def __init__(self, store_fs):
"""
:param store_fs: ``StoreFS`` object
"""
self.store_fs = self._validate_store_fs(store_fs)
self.pootle_path = store_fs.pootle_path
self.path = store_fs.path

def _validate_store_fs(self, store_fs):
from .models import StoreFS

if not isinstance(store_fs, StoreFS):
raise TypeError(
"pootle_fs.FSFile expects a StoreFS")
self.store_fs = store_fs
self.pootle_path = store_fs.pootle_path
self.path = store_fs.path
return store_fs

def __str__(self):
return "<%s: %s::%s>" % (
Expand Down
2 changes: 2 additions & 0 deletions requirements/tests.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ pytest==3.2.2
pytest-catchlog==1.2.2
pytest-cov==2.5.1
pytest-django==3.1.2

pytest-mock
6 changes: 2 additions & 4 deletions tests/pootle_fs/display.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,8 @@ def test_fs_response_display_instance(localfs_pootle_untracked):
assert str(display) == "%s\n" % result


@pytest.mark.django_db
def test_fs_response_display_no_change(localfs_pootle_untracked):
plugin = localfs_pootle_untracked
assert str(ResponseDisplay(plugin.sync())) == "No changes made\n"
def test_fs_response_display_no_change():
assert str(ResponseDisplay([])) == "No changes made\n"


@pytest.mark.django_db
Expand Down
153 changes: 78 additions & 75 deletions tests/pootle_fs/files.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,51 +9,62 @@

import os

from mock import PropertyMock, patch

import pytest

from translate.storage.factory import getclass
from translate.storage.po import pofile

from pootle_fs.models import StoreFS
from django.contrib.auth import get_user_model

from pootle_fs.files import FSFile
from pootle_project.models import Project
from pootle_statistics.models import SubmissionTypes
from pootle_store.constants import POOTLE_WINS


@pytest.mark.django_db
class MockProject(object):
local_fs_path = "LOCAL_FS_PATH"
code = 'project0'


class MockStoreFS(object):
pootle_path = "/language0/project0/example.po"
path = "/some/fs/example.po"
project = MockProject()
store = None
last_sync_hash = None
last_sync_revision = None


def test_wrap_store_fs_bad(settings, tmpdir):

with pytest.raises(TypeError):
FSFile("NOT A STORE_FS")


@pytest.mark.django_db
def test_wrap_store_fs(settings, tmpdir):
@patch("pootle_fs.files.FSFile._validate_store_fs")
def test_wrap_store_fs(valid_mock, settings, tmpdir):
"""Add a store_fs for a store that doesnt exist yet"""
settings.POOTLE_FS_WORKING_PATH = os.path.join(str(tmpdir), "fs_file_test")
project = Project.objects.get(code="project0")
pootle_path = "/language0/%s/example.po" % project.code
fs_path = "/some/fs/example.po"
store_fs = StoreFS.objects.create(
pootle_path=pootle_path,
path=fs_path)
valid_mock.side_effect = lambda x: x
store_fs = MockStoreFS()
fs_file = FSFile(store_fs)
assert (
fs_file.file_path
== os.path.join(
settings.POOTLE_FS_WORKING_PATH, project.code,
store_fs.project.local_fs_path,
store_fs.path.strip("/")))
assert fs_file.file_exists is False
assert fs_file.latest_hash is None
assert fs_file.pootle_changed is False
assert fs_file.fs_changed is False

assert fs_file.store is None
assert fs_file.store_exists is False

assert fs_file.deserialize() is None
assert fs_file.serialize() is None
assert str(fs_file) == "<FSFile: %s::%s>" % (pootle_path, fs_path)
assert str(fs_file) == "<FSFile: %s::%s>" % (fs_file.pootle_path, fs_file.path)
assert hash(fs_file) == hash(
"%s::%s::%s::%s"
% (fs_file.path,
Expand All @@ -68,53 +79,47 @@ def test_wrap_store_fs(settings, tmpdir):
assert testdict.values()[0] == "bar"


@pytest.mark.django_db
def test_wrap_store_fs_with_store(settings, tmpdir, tp0_store):
settings.POOTLE_FS_WORKING_PATH = os.path.join(str(tmpdir), "fs_file_test")
fs_path = "/some/fs/example.po"
store_fs = StoreFS.objects.create(
path=fs_path,
store=tp0_store)
project = tp0_store.translation_project.project
@patch("pootle_fs.files.FSFile._validate_store_fs")
def test_wrap_store_fs_with_store(valid_mock):
valid_mock.side_effect = lambda x: x
store_mock = PropertyMock()
store_mock.configure_mock(
**{"data.max_unit_revision": 23,
"serialize.return_value": 73})
store_fs = MockStoreFS()
store_fs.store = store_mock
fs_file = FSFile(store_fs)

assert (
fs_file.file_path
== os.path.join(
settings.POOTLE_FS_WORKING_PATH, project.code,
store_fs.project.local_fs_path,
store_fs.path.strip("/")))
assert fs_file.file_exists is False
assert fs_file.latest_hash is None
assert fs_file.fs_changed is False
assert fs_file.pootle_changed is True
assert fs_file.store == tp0_store
assert fs_file.store is store_mock
assert fs_file.store_exists is True
serialized = fs_file.serialize()
assert serialized
assert serialized == tp0_store.serialize()
assert fs_file.serialize() == 73
assert fs_file.deserialize() is None


@pytest.mark.django_db
def test_wrap_store_fs_with_file(settings, tmpdir, tp0_store, test_fs):
settings.POOTLE_FS_WORKING_PATH = os.path.join(str(tmpdir), "fs_file_test")
project = Project.objects.get(code="project0")
pootle_path = "/language0/%s/example.po" % project.code
fs_path = "/some/fs/example.po"
store_fs = StoreFS.objects.create(
path=fs_path,
pootle_path=pootle_path)
@patch("pootle_fs.files.FSFile._validate_store_fs")
@patch("pootle_fs.files.FSFile.latest_hash")
@patch("pootle_fs.files.os.path.exists")
def test_wrap_store_fs_with_file(path_mock, hash_mock, valid_mock):
valid_mock.side_effect = lambda x: x
path_mock.return_value = True
hash_mock.return_value = 23

store_fs = MockStoreFS()
store_fs.last_sync_hash = 73
fs_file = FSFile(store_fs)
os.makedirs(os.path.dirname(fs_file.file_path))
with test_fs.open("data/po/complex.po") as src:
with open(fs_file.file_path, "w") as target:
data = src.read()
target.write(data)

assert fs_file.pootle_changed is False
assert fs_file.fs_changed is True
assert fs_file.file_exists is True
assert fs_file.latest_hash == str(os.stat(fs_file.file_path).st_mtime)
assert isinstance(fs_file.deserialize(), pofile)
assert str(fs_file.deserialize()) == data


@pytest.mark.django_db
Expand Down Expand Up @@ -346,42 +351,40 @@ def test_wrap_store_fs_pull_submission_type(store_fs_file_store):
== SubmissionTypes.SYSTEM)


@pytest.mark.django_db
def test_fs_file_latest_author(system, member2):

member2.email = "member2@poot.le"
member2.save()
@patch("pootle_fs.files.FSFile.latest_author", new_callable=PropertyMock)
@patch("pootle_fs.files.FSFile.plugin", new_callable=PropertyMock)
@patch("pootle_fs.files.User.objects", new_callable=PropertyMock)
def test_fs_file_latest_author(user_mock, plugin_mock, author_mock):
user_mock.configure_mock(
**{"return_value.get.return_value": 73})
author_mock.return_value = None, None
plugin_mock.configure_mock(
**{"return_value.pootle_user": 23})

class DummyPlugin(object):
pootle_user = system
User = get_user_model()

class DummyFile(FSFile):

_author_name = None
_author_email = None

def __init__(self):
pass

@property
def plugin(self):
return DummyPlugin()
myfile = DummyFile()
assert myfile.latest_user == 23

@property
def latest_author(self):
return self._author_name, self._author_email
author_mock.return_value = 7, None
assert myfile.latest_user == 23
author_mock.return_value = None, 7
assert myfile.latest_user == 23

myfile = DummyFile()
assert myfile.latest_user == system
myfile._author_name = "DOES NOT EXIST"
assert myfile.latest_user == system
myfile._author_email = member2.email
assert myfile.latest_user == member2
myfile._author_name = member2.username
assert myfile.latest_user == member2
myfile._author_email = None
assert myfile.latest_user == system
myfile._author_email = "DOESNT@EXIST.EMAIL"
assert myfile.latest_user == member2
myfile._author_name = "DOES NOT EXIST"
assert myfile.latest_user == system
author_mock.return_value = 7, 17
assert myfile.latest_user == 73
assert (
list(user_mock.return_value.get.call_args)
== [(), {'email': 17}])

user_mock.return_value.get.side_effect = User.DoesNotExist
assert myfile.latest_user == 23
assert (
[list(l) for l in user_mock.return_value.get.call_args_list]
== [[(), {'email': 17}],
[(), {'email': 17}],
[(), {'username': 7}]])
2 changes: 0 additions & 2 deletions tests/pootle_fs/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
from pootle_fs.localfs import LocalFSPlugin, LocalFSUrlValidator


@pytest.mark.django_db
def test_validator_localfs():
validator = fs_url_validator.get(LocalFSPlugin)()
assert isinstance(validator, LocalFSUrlValidator)
Expand All @@ -24,7 +23,6 @@ def test_validator_localfs():
validator.validate("/foo/bar")


@pytest.mark.django_db
def test_validator_translation_mapping():
validator = fs_translation_mapping_validator.get()("asdf")
assert isinstance(validator, TranslationMappingValidator)
23 changes: 13 additions & 10 deletions tests/pootle_language/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
# or later license. See the LICENSE file for a copy of the license and the
# AUTHORS file for copyright and authorship information.

from mock import PropertyMock, patch

import pytest

from django.urls import reverse
Expand Down Expand Up @@ -247,9 +249,13 @@ def test_form_language_suggestions_bad(language0, tp0, admin):


@pytest.mark.django_db
def test_form_language_suggestions_accept_comment(language0, tp0, admin,
member2_with_email,
mailoutbox):
@patch(
'pootle_language.forms.LanguageSuggestionAdminForm.suggestions_review',
new_callable=PropertyMock)
def test_form_language_suggestions_accept_comment(review_mock, language0,
tp0, admin):
review_mock.configure_mock(**{'return_value.accept.return_value': 23})

form = LanguageSuggestionAdminForm(
language=language0,
user=admin,
Expand All @@ -263,13 +269,10 @@ def test_form_language_suggestions_accept_comment(language0, tp0, admin,
== list(
form.language_team.suggestions.filter(
unit__store__translation_project=tp0)))
form.save()
for suggestion in form.suggestions_to_save:
assert suggestion.state.name == "accepted"
assert len(mailoutbox) == 1
for suggestion in form.suggestions_to_save:
assert ("#%s" % suggestion.id) in mailoutbox[0].body
assert "accept" in mailoutbox[0].subject.lower()
assert form.save() == 23
assert (
list(review_mock.return_value.accept.call_args)
== [(), {'comment': u'no thanks'}])


@pytest.mark.django_db
Expand Down
6 changes: 3 additions & 3 deletions tests/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,17 +57,17 @@
# place that will abort everything otherwise
'default': {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': 'redis://127.0.0.1:6379/13',
'LOCATION': 'redis://redis:6379/13',
'TIMEOUT': 604800, # 1 week
},
'redis': {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': 'redis://127.0.0.1:6379/14',
'LOCATION': 'redis://redis:6379/14',
'TIMEOUT': None,
},
'lru': {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': 'redis://127.0.0.1:6379/15',
'LOCATION': 'redis://redis:6379/15',
'TIMEOUT': 604800, # 1 week
},
'exports': {
Expand Down

0 comments on commit 777b103

Please sign in to comment.