Skip to content

Commit

Permalink
This fixes two bugs apparent in nesting of translations in subprojects (
Browse files Browse the repository at this point in the history
readthedocs#3909)

* This fixes two bugs apparent in nesting of translations in subprojects

The canonical domain was not searching as deep as we support. We support
translations nested in subprojects, and vice versa, this was previously only
searching for translation or subproject, so no nesting at all.

The path was also a similar problem, but instead of a heavy refactor that reused
the canonical domain lookup, I just altered the logic a little here. The pattern
was required to support both superproject as a translation project and
subproject as a translation project.

* Add resolver tests

Also lints our test file
  • Loading branch information
agjohnson authored Apr 6, 2018
1 parent 2c9e62d commit b3686ca
Show file tree
Hide file tree
Showing 3 changed files with 289 additions and 68 deletions.
2 changes: 1 addition & 1 deletion readthedocs-common
47 changes: 28 additions & 19 deletions readthedocs/core/resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,7 @@ def resolve_path(self, project, filename='', version_slug=None,
language=None, single_version=None, subdomain=None,
cname=None, private=None):
"""Resolve a URL with a subset of fields defined."""
relation = project.superprojects.first()
cname = cname or project.domains.filter(canonical=True).first()
main_language_project = project.main_language_project

version_slug = version_slug or project.get_default_version()
language = language or project.language

Expand All @@ -93,17 +90,27 @@ def resolve_path(self, project, filename='', version_slug=None,

filename = self._fix_filename(project, filename)

if main_language_project:
project_slug = main_language_project.slug
language = project.language
subproject_slug = None
elif relation:
project_slug = relation.parent.slug
subproject_slug = relation.alias
cname = relation.parent.domains.filter(canonical=True).first()
else:
project_slug = project.slug
subproject_slug = None
current_project = project
project_slug = project.slug
subproject_slug = None
# We currently support more than 2 levels of nesting subprojects and
# translations, only loop twice to avoid sticking in the loop
for _ in range(0, 2):
main_language_project = current_project.main_language_project
relation = current_project.superprojects.first()

if main_language_project:
current_project = main_language_project
project_slug = main_language_project.slug
language = project.language
subproject_slug = None
elif relation:
current_project = relation.parent
project_slug = relation.parent.slug
subproject_slug = relation.alias
cname = relation.parent.domains.filter(canonical=True).first()
else:
break

single_version = bool(project.single_version or single_version)

Expand Down Expand Up @@ -146,17 +153,19 @@ def resolve(self, project, protocol='http', filename='', private=None,

def _get_canonical_project(self, project):
"""
Get canonical project in the case of subproject or translations.
Recursively get canonical project for subproject or translations.
We need to recursively search here as a nested translations inside
subprojects, and vice versa, are supported.
:type project: Project
:rtype: Project
"""
main_language_project = project.main_language_project
relation = project.superprojects.first()
if main_language_project:
return main_language_project
if project.main_language_project:
return self._get_canonical_project(project.main_language_project)
elif relation:
return relation.parent
return self._get_canonical_project(relation.parent)
return project

def _get_project_subdomain(self, project):
Expand Down
Loading

0 comments on commit b3686ca

Please sign in to comment.