Skip to content

Major Database Refactoring #4958

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 17 commits into from
Nov 10, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions tests/common/db/packaging.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import datetime
import hashlib
import uuid

import factory
import factory.fuzzy
Expand All @@ -36,14 +37,15 @@ class ProjectFactory(WarehouseFactory):
class Meta:
model = Project

id = factory.LazyFunction(uuid.uuid4)
name = factory.fuzzy.FuzzyText(length=12)


class ReleaseFactory(WarehouseFactory):
class Meta:
model = Release

name = factory.LazyAttribute(lambda o: o.project.name)
id = factory.LazyFunction(uuid.uuid4)
project = factory.SubFactory(ProjectFactory)
version = factory.Sequence(lambda n: str(n) + ".0")
canonical_version = factory.LazyAttribute(
Expand All @@ -58,7 +60,6 @@ class FileFactory(WarehouseFactory):
class Meta:
model = File

name = factory.LazyAttribute(lambda o: o.release.name)
release = factory.SubFactory(ReleaseFactory)
python_version = "source"
md5_digest = factory.LazyAttribute(
Expand Down Expand Up @@ -96,8 +97,7 @@ class DependencyFactory(WarehouseFactory):
class Meta:
model = Dependency

name = factory.fuzzy.FuzzyText(length=12)
version = factory.Sequence(lambda n: str(n) + ".0")
release = factory.SubFactory(ReleaseFactory)
kind = factory.fuzzy.FuzzyChoice(int(kind) for kind in DependencyKind)
specifier = factory.fuzzy.FuzzyText(length=12)

Expand Down
4 changes: 1 addition & 3 deletions tests/unit/admin/views/test_blacklist.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,7 @@ def test_adds_blacklist_with_deletes(self, db_request):

project = ProjectFactory.create(name="foo")
release = ReleaseFactory.create(project=project)
FileFactory.create(
name=project.name, version=release.version, filename="who cares"
)
FileFactory.create(release=release, filename="who cares")
RoleFactory.create(project=project, user=db_request.user)

views.add_blacklist(db_request)
Expand Down
3 changes: 2 additions & 1 deletion tests/unit/admin/views/test_projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,8 @@ def test_delete_role(self, db_request):

assert db_request.session.flash.calls == [
pretend.call(
f"Removed '{role.user_name}' as '{role.role_name}' on '{project.name}'",
f"Removed '{role.user.username}' as '{role.role_name}' "
f"on '{project.name}'",
queue="success",
)
]
Expand Down
7 changes: 4 additions & 3 deletions tests/unit/legacy/api/test_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,7 @@ def test_detail_renders(self, pyramid_config, db_request, db_session):
for urlspec in project_urls:
db_session.add(
Dependency(
name=releases[3].project.name,
version="3.0",
release=releases[3],
kind=DependencyKind.project_url.value,
specifier=urlspec,
)
Expand Down Expand Up @@ -460,7 +459,9 @@ def test_normalizing_redirects(self, db_request):
assert isinstance(resp, HTTPMovedPermanently)
assert db_request.route_path.calls == [
pretend.call(
"legacy.api.json.release", name=release.name, version=release.version
"legacy.api.json.release",
name=release.project.name,
version=release.version,
)
]
assert resp.headers["Location"] == "/project/the-redirect"
8 changes: 4 additions & 4 deletions tests/unit/legacy/api/xmlrpc/test_xmlrpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -785,7 +785,7 @@ def test_browse(db_request):
expected_release._classifiers = classifiers

assert set(xmlrpc.browse(db_request, ["Environment :: Other Environment"])) == {
(r.name, r.version) for r in releases
(r.project.name, r.version) for r in releases
}
assert set(
xmlrpc.browse(
Expand All @@ -795,7 +795,7 @@ def test_browse(db_request):
"Development Status :: 5 - Production/Stable",
],
)
) == {(expected_release.name, expected_release.version)}
) == {(expected_release.project.name, expected_release.version)}
assert set(
xmlrpc.browse(
db_request,
Expand All @@ -805,7 +805,7 @@ def test_browse(db_request):
"Programming Language :: Python",
],
)
) == {(expected_release.name, expected_release.version)}
) == {(expected_release.project.name, expected_release.version)}
assert set(
xmlrpc.browse(
db_request,
Expand All @@ -814,7 +814,7 @@ def test_browse(db_request):
"Programming Language :: Python",
],
)
) == {(expected_release.name, expected_release.version)}
) == {(expected_release.project.name, expected_release.version)}


def test_multicall(pyramid_request):
Expand Down
144 changes: 73 additions & 71 deletions tests/unit/manage/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,15 @@

from warehouse.manage import views
from warehouse.accounts.interfaces import IUserService, IPasswordBreachedService
from warehouse.packaging.models import JournalEntry, Project, Role, User
from warehouse.packaging.models import JournalEntry, Project, File, Role, User
from warehouse.utils.project import remove_documentation

from ...common.db.accounts import EmailFactory
from ...common.db.packaging import (
JournalEntryFactory,
ProjectFactory,
ReleaseFactory,
FileFactory,
RoleFactory,
UserFactory,
)
Expand Down Expand Up @@ -977,53 +978,51 @@ def test_delete_project_release_bad_confirm(self):
)
]

def test_delete_project_release_file(self, monkeypatch):
release_file = pretend.stub(filename="foo-bar.tar.gz", id=str(uuid.uuid4()))
release = pretend.stub(version="1.2.3", project=pretend.stub(name="foobar"))
request = pretend.stub(
POST={
"confirm_project_name": release.project.name,
"file_id": release_file.id,
},
method="POST",
db=pretend.stub(
delete=pretend.call_recorder(lambda a: None),
add=pretend.call_recorder(lambda a: None),
query=lambda a: pretend.stub(
filter=lambda *a: pretend.stub(one=lambda: release_file)
),
),
route_path=pretend.call_recorder(lambda *a, **kw: "/the-redirect"),
session=pretend.stub(flash=pretend.call_recorder(lambda *a, **kw: None)),
user=pretend.stub(),
remote_addr=pretend.stub(),
def test_delete_project_release_file(self, db_request):
user = UserFactory.create()

project = ProjectFactory.create(name="foobar")
release = ReleaseFactory.create(project=project)
release_file = FileFactory.create(
release=release, filename=f"foobar-{release.version}.tar.gz"
)
journal_obj = pretend.stub()
journal_cls = pretend.call_recorder(lambda **kw: journal_obj)
monkeypatch.setattr(views, "JournalEntry", journal_cls)

view = views.ManageProjectRelease(release, request)
db_request.POST = {
"confirm_project_name": release.project.name,
"file_id": release_file.id,
}
db_request.method = ("POST",)
db_request.route_path = pretend.call_recorder(lambda *a, **kw: "/the-redirect")
db_request.session = pretend.stub(
flash=pretend.call_recorder(lambda *a, **kw: None)
)
db_request.user = user
db_request.remote_addr = "1.2.3.4"

view = views.ManageProjectRelease(release, db_request)

result = view.delete_project_release_file()

assert isinstance(result, HTTPSeeOther)
assert result.headers["Location"] == "/the-redirect"

assert request.session.flash.calls == [
assert db_request.session.flash.calls == [
pretend.call(f"Deleted file {release_file.filename!r}", queue="success")
]
assert request.db.delete.calls == [pretend.call(release_file)]
assert request.db.add.calls == [pretend.call(journal_obj)]
assert journal_cls.calls == [
pretend.call(
name=release.project.name,
action=f"remove file {release_file.filename}",

assert db_request.db.query(File).filter_by(id=release_file.id).first() is None
assert (
db_request.db.query(JournalEntry)
.filter_by(
name=project.name,
version=release.version,
submitted_by=request.user,
submitted_from=request.remote_addr,
action=f"remove file {release_file.filename}",
submitted_by=user,
submitted_from="1.2.3.4",
)
]
assert request.route_path.calls == [
.one()
)
assert db_request.route_path.calls == [
pretend.call(
"manage.project.release",
project_name=release.project.name,
Expand Down Expand Up @@ -1059,74 +1058,77 @@ def test_delete_project_release_file_no_confirm(self):
)
]

def test_delete_project_release_file_not_found(self):
release = pretend.stub(version="1.2.3", project=pretend.stub(name="foobar"))
def test_delete_project_release_file_not_found(self, db_request):
project = ProjectFactory.create(name="foobar")
release = ReleaseFactory.create(project=project)

def no_result_found():
raise NoResultFound

request = pretend.stub(
POST={"confirm_project_name": "whatever"},
method="POST",
db=pretend.stub(
delete=pretend.call_recorder(lambda a: None),
query=lambda a: pretend.stub(
filter=lambda *a: pretend.stub(one=no_result_found)
),
db_request.POST = {"confirm_project_name": "whatever"}
db_request.method = "POST"
db_request.db = pretend.stub(
delete=pretend.call_recorder(lambda a: None),
query=lambda a: pretend.stub(
filter=lambda *a: pretend.stub(one=no_result_found)
),
route_path=pretend.call_recorder(lambda *a, **kw: "/the-redirect"),
session=pretend.stub(flash=pretend.call_recorder(lambda *a, **kw: None)),
)
view = views.ManageProjectRelease(release, request)
db_request.route_path = pretend.call_recorder(lambda *a, **kw: "/the-redirect")
db_request.session = pretend.stub(
flash=pretend.call_recorder(lambda *a, **kw: None)
)

view = views.ManageProjectRelease(release, db_request)

result = view.delete_project_release_file()

assert isinstance(result, HTTPSeeOther)
assert result.headers["Location"] == "/the-redirect"

assert request.db.delete.calls == []
assert request.session.flash.calls == [
assert db_request.db.delete.calls == []
assert db_request.session.flash.calls == [
pretend.call("Could not find file", queue="error")
]
assert request.route_path.calls == [
assert db_request.route_path.calls == [
pretend.call(
"manage.project.release",
project_name=release.project.name,
version=release.version,
)
]

def test_delete_project_release_file_bad_confirm(self):
release_file = pretend.stub(filename="foo-bar.tar.gz", id=str(uuid.uuid4()))
release = pretend.stub(version="1.2.3", project=pretend.stub(name="foobar"))
request = pretend.stub(
POST={"confirm_project_name": "invalid"},
method="POST",
db=pretend.stub(
delete=pretend.call_recorder(lambda a: None),
query=lambda a: pretend.stub(
filter=lambda *a: pretend.stub(one=lambda: release_file)
),
),
route_path=pretend.call_recorder(lambda *a, **kw: "/the-redirect"),
session=pretend.stub(flash=pretend.call_recorder(lambda *a, **kw: None)),
def test_delete_project_release_file_bad_confirm(self, db_request):
project = ProjectFactory.create(name="foobar")
release = ReleaseFactory.create(project=project, version="1.2.3")
release_file = FileFactory.create(
release=release, filename="foobar-1.2.3.tar.gz"
)
view = views.ManageProjectRelease(release, request)

db_request.POST = {
"confirm_project_name": "invalid",
"file_id": str(release_file.id),
}
db_request.method = "POST"
db_request.route_path = pretend.call_recorder(lambda *a, **kw: "/the-redirect")
db_request.session = pretend.stub(
flash=pretend.call_recorder(lambda *a, **kw: None)
)

view = views.ManageProjectRelease(release, db_request)

result = view.delete_project_release_file()

assert isinstance(result, HTTPSeeOther)
assert result.headers["Location"] == "/the-redirect"

assert request.db.delete.calls == []
assert request.session.flash.calls == [
assert db_request.db.query(File).filter_by(id=release_file.id).one()
assert db_request.session.flash.calls == [
pretend.call(
"Could not delete file - "
+ f"'invalid' is not the same as {release.project.name!r}",
queue="error",
)
]
assert request.route_path.calls == [
assert db_request.route_path.calls == [
pretend.call(
"manage.project.release",
project_name=release.project.name,
Expand Down
3 changes: 1 addition & 2 deletions tests/unit/packaging/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,8 +260,7 @@ def test_urls(self, db_session, home_page, download_url, project_urls, expected)
for urlspec in project_urls:
db_session.add(
Dependency(
name=release.project.name,
version=release.version,
release=release,
kind=DependencyKind.project_url.value,
specifier=urlspec,
)
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/search/test_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def test_project_docs(db_session):
"latest_version": first(prs, key=lambda r: not r.is_prerelease).version,
},
}
for p, prs in sorted(releases.items(), key=lambda x: x[0].name.lower())
for p, prs in sorted(releases.items(), key=lambda x: x[0].id)
]


Expand Down
17 changes: 12 additions & 5 deletions tests/unit/utils/test_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,9 @@ def test_remove_project(db_request, flash):
user = UserFactory.create()
project = ProjectFactory.create(name="foo")
release = ReleaseFactory.create(project=project)
FileFactory.create(name=project.name, version=release.version, filename="who cares")
FileFactory.create(release=release, filename="who cares")
RoleFactory.create(user=user, project=project)
DependencyFactory.create(name=project.name, version=release.version)
DependencyFactory.create(release=release)

db_request.user = user
db_request.remote_addr = "192.168.1.1"
Expand All @@ -113,13 +113,20 @@ def test_remove_project(db_request, flash):
assert db_request.session.flash.calls == []

assert not (db_request.db.query(Role).filter(Role.project == project).count())
assert not (db_request.db.query(File).filter(File.name == project.name).count())
assert not (
db_request.db.query(Dependency).filter(Dependency.name == project.name).count()
db_request.db.query(File)
.join(Release)
.join(Project)
.filter(Release.project == project)
.count()
)
assert not (
db_request.db.query(Release).filter(Release.name == project.name).count()
db_request.db.query(Dependency)
.join(Release)
.filter(Release.project == project)
.count()
)
assert not (db_request.db.query(Release).filter(Release.project == project).count())
assert not (
db_request.db.query(Project).filter(Project.name == project.name).count()
)
Expand Down
Loading