Skip to content
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

App: improve title translation, add caching, enable debug toolbar #469

Merged
merged 13 commits into from
Jul 15, 2024
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ build/

# Unit test / coverage reports
.coverage*
htmlcov

# Django development
*/settings/local.py
Expand Down
10 changes: 5 additions & 5 deletions cc_legal_tools/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,13 +116,13 @@
},
]

# template_fragments
# For our use case, caching doesn't appear to offer any benefits and only adds
# complexity. This was determined by testing both publishing speed and page
# speed.
# The caching API is used, but there are no caching MIDDLEWARE, above, as we
# are not using site caching (which adds overhead without benefit for our uses)
CACHES = {
"default": {
"BACKEND": "django.core.cache.backends.dummy.DummyCache",
"BACKEND": "django.core.cache.backends.locmem.LocMemCache",
"TIMEOUT": 600,
"OPTIONS": {"CULL_FREQUENCY": 0, "MAX_ENTRIES": 3000},
},
}

Expand Down
5 changes: 3 additions & 2 deletions cc_legal_tools/settings/dev.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,10 @@
# can set DEBUG_TOOLBAR_CONFIG['IS_RUNNING_TESTS'] = False to bypass
# this check.
DEBUG = True
DEBUG_TOOLBAR_CONFIG = {"SHOW_TOOLBAR_CALLBACK": lambda request: DEBUG}
INSTALLED_APPS += [ # noqa: F405
"debug_toolbar",
]
MIDDLEWARE += ( # noqa: F405
MIDDLEWARE += [ # noqa: F405
"debug_toolbar.middleware.DebugToolbarMiddleware",
)
]
2 changes: 1 addition & 1 deletion cc_legal_tools/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,5 @@ def custom_page_not_found(request):
import debug_toolbar

urlpatterns += [
re_path(r"^__debug__/", include(debug_toolbar.urls)),
path("__debug__/", include(debug_toolbar.urls)),
]
61 changes: 45 additions & 16 deletions dev/coverage.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,67 @@
#
# Run coverage tests and report
#
set -o errtrace
set -o nounset

# This script passes all arguments to Coverage Tests. For example, it can be
# called from the cc-legal-tools-app directory like so:
#
# ./dev/coverage.sh --failfast

# Change directory to cc-legal-tools-app (grandparent directory of this script)
cd ${0%/*}/../
set -o errexit
set -o errtrace
set -o nounset

# shellcheck disable=SC2154
trap '_es=${?};
printf "${0}: line ${LINENO}: \"${BASH_COMMAND}\"";
printf " exited with a status of ${_es}\n";
exit ${_es}' ERR

DIR_REPO="$(cd -P -- "${0%/*}/.." && pwd -P)"
# https://en.wikipedia.org/wiki/ANSI_escape_code
E0="$(printf "\e[0m")" # reset
E30="$(printf "\e[30m")" # black foreground
E31="$(printf "\e[31m")" # red foreground
E107="$(printf "\e[107m")" # bright white background

if ! docker compose exec app true 2>/dev/null; then
echo 'The app container/services is not avaialable.' 1>&2
echo 'First run `docker compose up`.' 1>&2
#### FUNCTIONS ################################################################

error_exit() {
# Echo error message and exit with error
echo -e "${E31}ERROR:${E0} ${*}" 1>&2
exit 1
fi
}

print_header() {
# Print 80 character wide black on white heading with time
printf "${E30}${E107}# %-69s$(date '+%T') ${E0}\n" "${@}"
}

#### MAIN #####################################################################

cd "${DIR_REPO}"

printf "\e[1m\e[7m %-80s\e[0m\n" 'Coverage Erase'
docker compose exec app coverage erase
echo 'done.'
docker compose exec app true 2>/dev/null \
|| error_exit \
'The Docker app container/service is not avaialable. See README.md'

print_header 'Coverage erase'
docker compose exec app coverage erase --debug=dataio
echo

printf "\e[1m\e[7m %-80s\e[0m\n" 'Coverage Tests'
docker compose exec app coverage run \
print_header 'Coverage tests'
docker compose exec app coverage run --debug=pytest \
manage.py test --noinput --parallel 4 ${@:-} \
|| exit
echo

printf "\e[1m\e[7m %-80s\e[0m\n" 'Coverage Combine'
print_header 'Coverage combine'
docker compose exec app coverage combine
echo

printf "\e[1m\e[7m %-80s\e[0m\n" 'Coverage Report'
print_header 'Coverage html'
docker compose exec app coverage html
echo

print_header 'Coverage report'
docker compose exec app coverage report
echo
12 changes: 6 additions & 6 deletions dev/stats.sh
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ error_exit() {
}


header() {
print_header() {
# Print 80 character wide black on white heading with time
printf "${E30}${E107}# %-70s$(date '+%T') ${E0}\n" "${@}"
printf "${E30}${E107}# %-69s$(date '+%T') ${E0}\n" "${@}"
}


Expand All @@ -78,7 +78,7 @@ print_var() {

published_documents() {
local _count _subtotal _ver
header 'Published'
print_header 'Published'
print_var DIR_PUB_LICENSES
print_var DIR_PUB_PUBLICDOMAIN
echo
Expand Down Expand Up @@ -185,7 +185,7 @@ published_documents() {


source_code() {
header 'Source code'
print_header 'Source code'
print_var DIR_REPO
cd "${DIR_REPO}"
scc \
Expand All @@ -197,10 +197,10 @@ source_code() {


todo() {
header 'Deeds & UX translation'
print_header 'Deeds & UX translation'
echo "${E33}TODO${E0}"
echo
header 'Legal Code translation'
print_header 'Legal Code translation'
echo "${E33}TODO${E0}"
echo
}
Expand Down
2 changes: 2 additions & 0 deletions i18n/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,8 @@
"za": gettext_lazy("South Africa"),
}
UNIT_NAMES = {
# 4.0 licenses use "NoDerivatives" instead of "NoDerivs". When appropriate,
# the following values are updated by legal_tools.views.get_tool_title()
"by": gettext_lazy("Attribution"),
"by-nc": gettext_lazy("Attribution-NonCommercial"),
"by-nc-nd": gettext_lazy("Attribution-NonCommercial-NoDerivs"),
Expand Down
176 changes: 101 additions & 75 deletions legal_tools/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@

# Third-party
from django.conf import settings
from django.core.cache import cache
from django.test import TestCase, override_settings
from django.urls import reverse
from django.utils import timezone
from django.utils.translation.trans_real import DjangoTranslation

# First-party/Local
from i18n.utils import get_default_language_for_jurisdiction_deed
from legal_tools.models import UNITS_LICENSES, LegalCode, Tool, build_path
from legal_tools.rdf_utils import (
convert_https_to_http,
Expand All @@ -25,6 +27,7 @@
branch_status_helper,
get_category_and_category_title,
get_deed_rel_path,
get_legal_code_replaced_rel_path,
normalize_path_and_lang,
render_redirect,
)
Expand Down Expand Up @@ -389,6 +392,104 @@ def setUp(self):
super().setUp()


class ViewHelperFunctionsTest(ToolsTestsMixin, TestCase):
def test_get_category_and_category_title_category_tool(self):
category, category_title = get_category_and_category_title(
category=None,
tool=None,
)
self.assertEqual(category, "licenses")
self.assertEqual(category_title, "Licenses")

tool = Tool.objects.get(unit="by", version="4.0")
category, category_title = get_category_and_category_title(
category=None,
tool=tool,
)
self.assertEqual(category, "licenses")
self.assertEqual(category_title, "Licenses")

def test_get_category_and_category_title_category_publicdomain(self):
category, category_title = get_category_and_category_title(
category="publicdomain",
tool=None,
)
self.assertEqual(category, "publicdomain")
self.assertEqual(category_title, "Public Domain")

@override_settings(LANGUAGES_MOSTLY_TRANSLATED=["x1", "x2"])
def test_get_deed_rel_path_mostly_translated_language_code(self):
expected_deed_rel_path = "deed.x1"
deed_rel_path = get_deed_rel_path(
deed_url="/deed.x1",
path_start="/",
language_code="x1",
language_default="x2",
)
self.assertEqual(expected_deed_rel_path, deed_rel_path)

@override_settings(LANGUAGES_MOSTLY_TRANSLATED=["x1", "x2"])
def test_get_deed_rel_path_less_translated_language_code(self):
expected_deed_rel_path = "deed.x2"
deed_rel_path = get_deed_rel_path(
deed_url="/deed.x3",
path_start="/",
language_code="x3",
language_default="x2",
)
self.assertEqual(expected_deed_rel_path, deed_rel_path)

@override_settings(
LANGUAGE_CODE="x1",
LANGUAGES_MOSTLY_TRANSLATED=[],
)
def test_get_deed_rel_path_less_translated_language_default(self):
expected_deed_rel_path = "deed.x1"
deed_rel_path = get_deed_rel_path(
deed_url="/deed.x3",
path_start="/",
language_code="x3",
language_default="x2",
)
self.assertEqual(expected_deed_rel_path, deed_rel_path)

def test_get_legal_code_replaced_rel_path_cache_miss(self):
tool = Tool.objects.get(
unit="by",
version="3.0",
jurisdiction_code="",
)
path_start = "/licenses/by/3.0"
language_code = "en"
language_default = get_default_language_for_jurisdiction_deed(None)

cache.clear()
self.assertFalse(cache.has_key("by-4.0--en-replaced_deed_str"))
self.assertFalse(cache.has_key("by-4.0--en-replaced_legal_code_title"))
_, _, _, _ = get_legal_code_replaced_rel_path(
tool.is_replaced_by, path_start, language_code, language_default
)
self.assertEqual(
cache.get("by-4.0--en-replaced_deed_title"),
"Deed - Attribution 4.0 International",
)
self.assertEqual(
cache.get("by-4.0--en-replaced_legal_code_title"),
"Legal Code - Attribution 4.0 International",
)

def test_normalize_path_and_lang(self):
request_path = "/licenses/by/3.0/de/legalcode"
jurisdiction = "de"
norm_request_path, norm_language_code = normalize_path_and_lang(
request_path,
jurisdiction,
language_code=None,
)
self.assertEqual(norm_request_path, f"{request_path}.de")
self.assertEqual(norm_language_code, "de")


class ViewDevHomeTest(ToolsTestsMixin, TestCase):
def test_view_dev_index_view(self):
url = reverse("dev_index")
Expand Down Expand Up @@ -786,81 +887,6 @@ class ViewLegalCodeTest(TestCase):
# self.assertContains(rsp, 'lang="de"')
# self.assertEqual(lc, context["legal_code"])

def test_get_category_and_category_title_category_tool(self):
category, category_title = get_category_and_category_title(
category=None,
tool=None,
)
self.assertEqual(category, "licenses")
self.assertEqual(category_title, "Licenses")

tool = ToolFactory(
category="licenses",
base_url="https://creativecommons.org/licenses/by/4.0/",
version="4.0",
)
category, category_title = get_category_and_category_title(
category=None,
tool=tool,
)
self.assertEqual(category, "licenses")
self.assertEqual(category_title, "Licenses")

def test_get_category_and_category_title_category_publicdomain(self):
category, category_title = get_category_and_category_title(
category="publicdomain",
tool=None,
)
self.assertEqual(category, "publicdomain")
self.assertEqual(category_title, "Public Domain")

def test_normalize_path_and_lang(self):
request_path = "/licenses/by/3.0/de/legalcode"
jurisdiction = "de"
norm_request_path, norm_language_code = normalize_path_and_lang(
request_path,
jurisdiction,
language_code=None,
)
self.assertEqual(norm_request_path, f"{request_path}.de")
self.assertEqual(norm_language_code, "de")

@override_settings(LANGUAGES_MOSTLY_TRANSLATED=["x1", "x2"])
def test_get_deed_rel_path_mostly_translated_language_code(self):
expected_deed_rel_path = "deed.x1"
deed_rel_path = get_deed_rel_path(
deed_url="/deed.x1",
path_start="/",
language_code="x1",
language_default="x2",
)
self.assertEqual(expected_deed_rel_path, deed_rel_path)

@override_settings(LANGUAGES_MOSTLY_TRANSLATED=["x1", "x2"])
def test_get_deed_rel_path_less_translated_language_code(self):
expected_deed_rel_path = "deed.x2"
deed_rel_path = get_deed_rel_path(
deed_url="/deed.x3",
path_start="/",
language_code="x3",
language_default="x2",
)
self.assertEqual(expected_deed_rel_path, deed_rel_path)

@override_settings(
LANGUAGE_CODE="x1",
LANGUAGES_MOSTLY_TRANSLATED=[],
)
def test_get_deed_rel_path_less_translated_language_default(self):
expected_deed_rel_path = "deed.x1"
deed_rel_path = get_deed_rel_path(
deed_url="/deed.x3",
path_start="/",
language_code="x3",
language_default="x2",
)
self.assertEqual(expected_deed_rel_path, deed_rel_path)

def test_view_legal_code_identifying_jurisdiction_default_language(self):
language_code = "de"
lc = LegalCodeFactory(
Expand Down
Loading