Skip to content
Open
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
2 changes: 1 addition & 1 deletion .github/workflows/generate-matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"lint",
"lmfdb/abvar/fq/test_av.py lmfdb/abvar/fq/test_browse_page.py lmfdb/number_fields/test_numberfield.py lmfdb/bianchi_modular_forms/test_bmf.py",
"lmfdb/galois_groups/test_galoisgroup.py lmfdb/siegel_modular_forms/test_siegel_modular_forms.py",
"lmfdb/tests/test_dynamic_knowls.py lmfdb/tests/test_root.py lmfdb/hecke_algebras/test_hecke_algebras.py lmfdb/tests/test_homepage.py lmfdb/elliptic_curves/test_ell_curves.py lmfdb/elliptic_curves/test_browse_page.py",
"lmfdb/tests/test_dynamic_knowls.py lmfdb/knowledge/test_knowledge.py lmfdb/tests/test_root.py lmfdb/hecke_algebras/test_hecke_algebras.py lmfdb/tests/test_homepage.py lmfdb/elliptic_curves/test_ell_curves.py lmfdb/elliptic_curves/test_browse_page.py",
"lmfdb/sato_tate_groups/test_st.py lmfdb/hilbert_modular_forms/test_hmf.py lmfdb/tests/test_spelling.py lmfdb/tests/test_template_namespace.py lmfdb/tests/test_acknowlegments.py lmfdb/tests/test_tensor_products.py",
"lmfdb/cluster_pictures/test_clusterpicture.py lmfdb/local_fields/test_localfields.py lmfdb/ecnf/test_ecnf.py lmfdb/ecnf/test_isog_class.py lmfdb/api/test_api.py lmfdb/characters/test_characters.py",
"lmfdb/users/test_users.py lmfdb/lattice/test_lattice.py lmfdb/maass_forms/test_maass.py lmfdb/higher_genus_w_automorphisms/test_hgcwa.py lmfdb/belyi/test_belyi.py lmfdb/hypergm/test_hgm.py lmfdb/tests/test_utils.py lmfdb/tests/test_connection_reset.py",
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/matrix_includes.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@
"server": "devmirror"
},
{
"files": "lmfdb/tests/test_dynamic_knowls.py lmfdb/tests/test_root.py lmfdb/tests/test_code_coverage.py lmfdb/hecke_algebras/test_hecke_algebras.py lmfdb/tests/test_homepage.py lmfdb/tests/test_random_redirects.py lmfdb/elliptic_curves/test_ell_curves.py lmfdb/elliptic_curves/test_browse_page.py",
"folders": "elliptic_curves hecke_algebras tests",
"files": "lmfdb/tests/test_dynamic_knowls.py lmfdb/knowledge/test_knowledge.py lmfdb/tests/test_root.py lmfdb/tests/test_code_coverage.py lmfdb/hecke_algebras/test_hecke_algebras.py lmfdb/tests/test_homepage.py lmfdb/tests/test_random_redirects.py lmfdb/elliptic_curves/test_ell_curves.py lmfdb/elliptic_curves/test_browse_page.py",
"folders": "elliptic_curves hecke_algebras knowledge tests",
"server": "proddb"
},
{
"files": "lmfdb/tests/test_dynamic_knowls.py lmfdb/tests/test_root.py lmfdb/tests/test_code_coverage.py lmfdb/hecke_algebras/test_hecke_algebras.py lmfdb/tests/test_homepage.py lmfdb/tests/test_random_redirects.py lmfdb/elliptic_curves/test_ell_curves.py lmfdb/elliptic_curves/test_browse_page.py",
"folders": "elliptic_curves hecke_algebras tests",
"files": "lmfdb/tests/test_dynamic_knowls.py lmfdb/knowledge/test_knowledge.py lmfdb/tests/test_root.py lmfdb/tests/test_code_coverage.py lmfdb/hecke_algebras/test_hecke_algebras.py lmfdb/tests/test_homepage.py lmfdb/tests/test_random_redirects.py lmfdb/elliptic_curves/test_ell_curves.py lmfdb/elliptic_curves/test_browse_page.py",
"folders": "elliptic_curves hecke_algebras knowledge tests",
"server": "devmirror"
},
{
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ jobs:
- name: checking that we didn't miss any test files
shell: bash -l {0}
# If this fails you need to update the file list above and file count
run: test $(find lmfdb -name 'test_*.py' -or -name '*_test.py' | wc -l) -eq 44
run: test $(find lmfdb -name 'test_*.py' -or -name '*_test.py' | wc -l) -eq 45

- name: Config LMFDB to run tests against proddb
if: matrix.files != 'lint' && matrix.server == 'proddb'
Expand Down
9 changes: 9 additions & 0 deletions lmfdb/knowledge/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -860,6 +860,15 @@ def index():
else:
flash_error("Unexpected error %s occurred during knowl search", str(e))
all_knowls = []
# Knowls whose id starts with "ui." (e.g. search-box help bubbles, sort-order
# or statistics-extent explanations) are user-interface helper texts rather
# than context-free definitions. They should not clutter the public knowl
# browse/search index, so we hide them -- and their "ui" category -- from
# visitors who are not logged in. See LMFDB issue #3721.
if not current_user.is_authenticated:
all_knowls = [k for k in all_knowls if not k["id"].startswith("ui.")]
if cur_cat == "ui":
cur_cat = ""
categories = Counter()
if cur_cat:
# Always include the current category
Expand Down
73 changes: 73 additions & 0 deletions lmfdb/knowledge/test_knowledge.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Tests for the knowledge (knowl) blueprint.

from lmfdb.tests import LmfdbTest
from lmfdb.knowledge import main as knowl_main


class KnowlUIVisibilityTest(LmfdbTest):
"""
Issue #3721: knowls whose id starts with ``ui.`` are user-interface helper
texts (search-box help, sort-order and statistics-extent explanations, ...)
rather than context-free definitions. They must be hidden from the public
(logged-out) knowl browse/search index, together with their ``ui`` category.
"""

# Stand-in for a knowldb.search() response: one ui. helper and one ordinary
# (context-free) math-definition knowl.
_fake_knowls = [
{"id": "ui.demo_helper", "title": "Demo UI helper"},
{"id": "ec.q.conductor", "title": "Conductor of an elliptic curve"},
]

def _get_index(self):
"""Render /knowledge/ with knowldb.search patched to return _fake_knowls."""
knowl_main.knowldb.search = lambda *args, **kwargs: [dict(k) for k in self._fake_knowls]
try:
return self.tc.get("/knowledge/", follow_redirects=True).get_data(as_text=True)
finally:
# Remove the instance override, restoring the real bound method.
del knowl_main.knowldb.search

def test_index_page_loads(self):
# Regression: the public knowl index still renders.
page = self.tc.get("/knowledge/", follow_redirects=True).get_data(as_text=True)
assert "Knowledge database" in page

def test_ui_knowl_hidden_when_logged_out(self):
page = self._get_index()
# The ui. helper and its "ui" category are hidden from a logged-out user ...
assert "ui.demo_helper" not in page
assert "ui(1)" not in page
# ... while ordinary knowls and their categories remain visible.
assert "ec.q.conductor" in page
assert "ec(1)" in page

def test_ui_category_query_hidden_when_logged_out(self):
# Explicitly requesting ?category=ui must not surface an empty "ui" category.
knowl_main.knowldb.search = lambda *args, **kwargs: [dict(k) for k in self._fake_knowls]
try:
page = self.tc.get("/knowledge/?category=ui", follow_redirects=True).get_data(as_text=True)
finally:
del knowl_main.knowldb.search
assert "ui.demo_helper" not in page
assert "ui(0)" not in page
assert "ui(1)" not in page

def test_ui_knowl_visible_when_logged_in(self):
# When authenticated, the filter is skipped and ui. knowls are listed.
class _FakeUser:
is_authenticated = True

def is_admin(self):
return False

orig_user = knowl_main.current_user
knowl_main.current_user = _FakeUser()
knowl_main.knowldb.search = lambda *args, **kwargs: [dict(k) for k in self._fake_knowls]
try:
page = self.tc.get("/knowledge/", follow_redirects=True).get_data(as_text=True)
finally:
knowl_main.current_user = orig_user
del knowl_main.knowldb.search
assert "ui.demo_helper" in page
assert "ec.q.conductor" in page
Loading