test_customfilters.py 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. import os
  2. from pathlib import Path
  3. from typing import Optional
  4. from urllib.parse import unquote
  5. import pytest
  6. from pytest import CaptureFixture
  7. from gemini_antenna.cgi import customFilters
  8. from gemini_antenna.db import AntennaDB
  9. from gemini_antenna.multiFeedParsing import parsegemsub
  10. script_name = "/~antenna/cgi-bin/filter"
  11. filter_ask_input = "10 Type 'y' if you want to create a filter, otherwise go back.\r\n"
  12. filter_ask_rule_add = "10 Rule to add:\r\n"
  13. filter_ask_rule_remove = "10 Rule to remove:\r\n"
  14. def add_rule(filter_name: str, url: str) -> None:
  15. os.environ['PATH_INFO'] = f"/{filter_name}/add"
  16. os.environ['QUERY_STRING'] = url
  17. customFilters.main()
  18. def remove_rule(filter_name: str, url: str) -> None:
  19. os.environ['PATH_INFO'] = f"/{filter_name}/remove"
  20. os.environ['QUERY_STRING'] = url
  21. customFilters.main()
  22. def read_rules(filter_name: str) -> None:
  23. os.environ['PATH_INFO'] = f"/{filter_name}/read"
  24. customFilters.main()
  25. @pytest.mark.parametrize("path_info, query",
  26. [(None, None), ("/", ""), ("/foo", "n")])
  27. def test_create_ask_input(path_info: Optional[str], query: Optional[str],
  28. capfd: CaptureFixture[str]):
  29. os.environ['SCRIPT_NAME'] = pytest.filter_script_name
  30. if query is not None:
  31. os.environ['QUERY_STRING'] = query
  32. elif 'QUERY_STRING' in os.environ:
  33. del os.environ['QUERY_STRING']
  34. if path_info is not None:
  35. os.environ['PATH_INFO'] = path_info
  36. elif 'PATH_INFO' in os.environ:
  37. del os.environ['PATH_INFO']
  38. customFilters.main()
  39. assert capfd.readouterr().out == filter_ask_input
  40. @pytest.mark.parametrize("query", ["ye", "yes"])
  41. def test_create_success(db: AntennaDB, query: str, capfd: CaptureFixture[str]):
  42. os.environ['SCRIPT_NAME'] = pytest.filter_script_name
  43. os.environ['QUERY_STRING'] = query
  44. customFilters.main()
  45. out: str = capfd.readouterr().out
  46. match = pytest.filter_redirect.match(out)
  47. assert match
  48. filter_name = match.group(1)
  49. assert Path(db.dbPath.parent / "customfilters" / filter_name).exists()
  50. @pytest.mark.parametrize("query", [None, ""])
  51. def test_add_ask_input(db: AntennaDB, filter_name: str, query: str,
  52. capfd: CaptureFixture[str]):
  53. with open(Path("tests") / "feed.gmi") as file:
  54. entries = parsegemsub(file.read(),
  55. "gemini://gemini.jrandom.net/gemlog/")
  56. db.insertFeedEntries(entries)
  57. # test reading rules before anything is filtered
  58. read_rules(filter_name)
  59. out: str = capfd.readouterr().out
  60. assert out.startswith("20 text/gemini\r")
  61. assert out.endswith(
  62. f"""
  63. => add?gemini://gemini.jrandom.net/gemlog/ Click to block 'gemini://gemini.jrandom.net/gemlog/'
  64. => add Click to add custom rule
  65. """)
  66. if query is not None:
  67. os.environ['QUERY_STRING'] = query
  68. elif 'QUERY_STRING' in os.environ:
  69. del os.environ['QUERY_STRING']
  70. os.environ['PATH_INFO'] = f"/{filter_name}/add"
  71. customFilters.main()
  72. assert capfd.readouterr().out == filter_ask_rule_add
  73. @pytest.mark.parametrize("url", [
  74. "gemini://example.com/badfeed",
  75. "gemini%3A%2F%2Fexample.com%2Fbadfeed",
  76. ])
  77. def test_add_success(filter_name: str, url: str, capfd: CaptureFixture[str]):
  78. add_rule(filter_name, url)
  79. out: str = capfd.readouterr().out
  80. assert pytest.filter_redirect.match(out)
  81. url = unquote(url)
  82. read_rules(filter_name)
  83. out: str = capfd.readouterr().out
  84. assert (out ==
  85. f"""20 text/gemini\r
  86. # Your Filter Rules
  87. => remove?{url} {url} (Click to remove)
  88. => add Click to add custom rule
  89. """)
  90. @pytest.mark.parametrize("query", [None, ""])
  91. def test_remove_ask_input(filter_name: str, query: str,
  92. capfd: CaptureFixture[str]):
  93. os.environ['PATH_INFO'] = f"/{filter_name}/remove"
  94. if query is not None:
  95. os.environ['QUERY_STRING'] = query
  96. elif 'QUERY_STRING' in os.environ:
  97. del os.environ['QUERY_STRING']
  98. customFilters.main()
  99. assert capfd.readouterr().out == filter_ask_rule_remove
  100. def test_remove_success(filter_name: str, capfd: CaptureFixture[str]):
  101. urls = [
  102. "gemini://example.com/goodfeed",
  103. "gemini%3A%2F%2Fexample.com%2Fgoodfeed",
  104. ]
  105. for url in urls:
  106. add_rule(filter_name, url)
  107. out: str = capfd.readouterr().out
  108. assert pytest.filter_redirect.match(out)
  109. url = unquote(url)
  110. read_rules(filter_name)
  111. out: str = capfd.readouterr().out
  112. assert f"=> remove?{url} {url} (Click to remove)" in out
  113. for url in urls:
  114. remove_rule(filter_name, url)
  115. out: str = capfd.readouterr().out
  116. assert pytest.filter_redirect.match(out)
  117. url = unquote(url)
  118. read_rules(filter_name)
  119. out: str = capfd.readouterr().out
  120. assert f"=> remove?{url} {url} (Click to remove)" not in out
  121. remove_rule(filter_name, "gemini://example.org/feed")
  122. out: str = capfd.readouterr().out
  123. assert pytest.filter_redirect.match(out)
  124. def test_filtered_feed(db: AntennaDB, filter_name: str,
  125. capfd: CaptureFixture[str]):
  126. with open(Path("tests") / "feed.gmi") as file:
  127. entries = parsegemsub(file.read(),
  128. "gemini://gemini.jrandom.net/gemlog/")
  129. db.insertFeedEntries(entries)
  130. os.environ['PATH_INFO'] = f"/{filter_name}"
  131. customFilters.main()
  132. out: str = capfd.readouterr().out
  133. assert out.startswith(
  134. f"""20 text/gemini\r
  135. => {pytest.filter_script_name}/{filter_name}/read Configure your filter.
  136. # Your Filtered Feed
  137. => gemini://gemini.jrandom.net/gemlog/bokashi.gmi 2020-11-20 J. Random Geminaut's gemlog: - Early Bokashi composting experiments
  138. => gemini://gemini.jrandom.net/gemlog/finite-simple-groups.gmi 2020-11-13 J. Random Geminaut's gemlog: - Trying to get to grips with finite simple groups...
  139. => gemini://gemini.jrandom.net/gemlog/balcony.gmi 2020-11-06 J. Random Geminaut's gemlog: - I started a balcony garden!
  140. > """)
  141. add_rule(filter_name, "gemini://gemini.jrandom.net/gemlog/")
  142. capfd.readouterr()
  143. os.environ['PATH_INFO'] = f"/{filter_name}"
  144. customFilters.main()
  145. out: str = capfd.readouterr().out
  146. assert out.startswith(
  147. f"""20 text/gemini\r
  148. => {pytest.filter_script_name}/{filter_name}/read Configure your filter.
  149. # Your Filtered Feed
  150. >""")