mirror of https://github.com/zulip/zulip.git
python: Remove locally dead code.
These changes are all independent of each other; I just didn’t feel like making dozens of commits for them. Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
parent
9afe6d0829
commit
4206e5f00b
|
@ -352,15 +352,8 @@ def mock_stripe(
|
|||
return _mock_stripe
|
||||
|
||||
|
||||
# A Kandra is a fictional character that can become anything. Used as a
|
||||
# wildcard when testing for equality.
|
||||
class Kandra: # nocoverage: TODO
|
||||
def __eq__(self, other: Any) -> bool:
|
||||
return True
|
||||
|
||||
|
||||
class StripeTestCase(ZulipTestCase):
|
||||
def setUp(self, *mocks: Mock) -> None:
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
realm = get_realm("zulip")
|
||||
|
||||
|
@ -2381,7 +2374,7 @@ class StripeTest(StripeTestCase):
|
|||
invoice_plans_as_needed(self.next_year)
|
||||
mocked.assert_not_called()
|
||||
|
||||
def test_reupgrade_by_billing_admin_after_downgrade(self, *mocks: Mock) -> None:
|
||||
def test_reupgrade_by_billing_admin_after_downgrade(self) -> None:
|
||||
user = self.example_user("hamlet")
|
||||
|
||||
with patch("corporate.lib.stripe.timezone_now", return_value=self.now):
|
||||
|
@ -2557,7 +2550,7 @@ class StripeTest(StripeTestCase):
|
|||
for key, value in line_item_params.items():
|
||||
self.assertEqual(renewal_item.get(key), value)
|
||||
|
||||
def test_update_licenses_of_automatic_plan_from_billing_page(self, *mocks: Mock) -> None:
|
||||
def test_update_licenses_of_automatic_plan_from_billing_page(self) -> None:
|
||||
user = self.example_user("hamlet")
|
||||
self.login_user(user)
|
||||
|
||||
|
|
|
@ -30,7 +30,6 @@ from scripts.lib.zulip_tools import (
|
|||
assert_running_as_root,
|
||||
get_config,
|
||||
get_config_file,
|
||||
get_tornado_ports,
|
||||
parse_os_release,
|
||||
run_psql_as_postgres,
|
||||
su_to_zulip,
|
||||
|
@ -97,7 +96,6 @@ deploy_path = args.deploy_path
|
|||
os.chdir(deploy_path)
|
||||
|
||||
config_file = get_config_file()
|
||||
tornado_processes = len(get_tornado_ports(config_file))
|
||||
|
||||
IS_SERVER_UP = True
|
||||
|
||||
|
|
|
@ -555,17 +555,6 @@ def get_config(
|
|||
return default_value
|
||||
|
||||
|
||||
def set_config(
|
||||
config_file: configparser.RawConfigParser,
|
||||
section: str,
|
||||
key: str,
|
||||
value: str,
|
||||
) -> None:
|
||||
if not config_file.has_section(section):
|
||||
config_file.add_section(section)
|
||||
config_file.set(section, key, value)
|
||||
|
||||
|
||||
def get_config_file() -> configparser.RawConfigParser:
|
||||
config_file = configparser.RawConfigParser()
|
||||
config_file.read("/etc/zulip/zulip.conf")
|
||||
|
|
|
@ -8,7 +8,6 @@ from premailer import Premailer
|
|||
|
||||
ZULIP_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../")
|
||||
EMAIL_TEMPLATES_PATH = os.path.join(ZULIP_PATH, "templates", "zerver", "emails")
|
||||
COMPILED_EMAIL_TEMPLATES_PATH = os.path.join(EMAIL_TEMPLATES_PATH, "compiled")
|
||||
CSS_SOURCE_PATH = os.path.join(EMAIL_TEMPLATES_PATH, "email.css")
|
||||
|
||||
|
||||
|
|
|
@ -320,7 +320,7 @@ class `HelloWorldHookTests`:
|
|||
class HelloWorldHookTests(WebhookTestCase):
|
||||
STREAM_NAME = 'test'
|
||||
URL_TEMPLATE = "/api/v1/external/helloworld?&api_key={api_key}"
|
||||
FIXTURE_DIR_NAME = 'helloworld'
|
||||
WEBHOOK_DIR_NAME = 'helloworld'
|
||||
|
||||
# Note: Include a test function per each distinct message condition your integration supports
|
||||
def test_hello_message(self) -> None:
|
||||
|
@ -333,7 +333,7 @@ class HelloWorldHookTests(WebhookTestCase):
|
|||
|
||||
```
|
||||
|
||||
In the above example, `STREAM_NAME`, `URL_TEMPLATE`, and `FIXTURE_DIR_NAME` refer
|
||||
In the above example, `STREAM_NAME`, `URL_TEMPLATE`, and `WEBHOOK_DIR_NAME` refer
|
||||
to class attributes from the base class, `WebhookTestCase`. These are needed by
|
||||
the helper function `check_webhook` to determine how to execute
|
||||
your test. `STREAM_NAME` should be set to your default stream. If it doesn't exist,
|
||||
|
|
|
@ -34,7 +34,7 @@ EXCLUDED_FILES = [
|
|||
def check_our_files(modified_only: bool, all_dups: bool, fix: bool, targets: List[str]) -> None:
|
||||
by_lang = lister.list_files(
|
||||
targets=targets,
|
||||
modified_only=args.modified,
|
||||
modified_only=modified_only,
|
||||
ftypes=["hbs", "html"],
|
||||
group_by_ftype=True,
|
||||
exclude=EXCLUDED_FILES,
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
import html
|
||||
import os
|
||||
import pprint
|
||||
import sys
|
||||
from collections import defaultdict
|
||||
from typing import Any, Dict, List, Set
|
||||
|
@ -40,25 +39,6 @@ def clean_up_pattern(s: str) -> str:
|
|||
return result
|
||||
|
||||
|
||||
def encode_info(info: Any) -> str:
|
||||
try:
|
||||
result = ""
|
||||
try:
|
||||
info = orjson.loads(info)
|
||||
result = "(stringified)\n"
|
||||
except orjson.JSONDecodeError:
|
||||
pass
|
||||
result += html.escape(pprint.pformat(info, indent=4))
|
||||
return "<pre>" + result + "</pre>"
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
return html.escape(str(info))
|
||||
except Exception:
|
||||
pass
|
||||
return "NOT ENCODABLE"
|
||||
|
||||
|
||||
def fix_test_name(s: str) -> str:
|
||||
return s.replace("zerver.tests.", "")
|
||||
|
||||
|
|
|
@ -5,11 +5,6 @@ from typing import Dict, List, Optional, Sequence, Set
|
|||
from .template_parser import FormattedException, Token, tokenize
|
||||
|
||||
|
||||
class HtmlBranchesException(Exception):
|
||||
# TODO: Have callers pass in line numbers.
|
||||
pass
|
||||
|
||||
|
||||
class HtmlTreeBranch:
|
||||
"""
|
||||
For <p><div id='yo'>bla<span class='bar'></span></div></p>, store a
|
||||
|
|
|
@ -76,18 +76,6 @@ except OSError:
|
|||
)
|
||||
sys.exit(1)
|
||||
|
||||
if platform.architecture()[0] == "64bit":
|
||||
arch = "amd64"
|
||||
elif platform.architecture()[0] == "32bit":
|
||||
arch = "i386"
|
||||
else:
|
||||
logging.critical(
|
||||
"Only x86 is supported; ask on chat.zulip.org if you want another architecture."
|
||||
)
|
||||
# Note: It's probably actually not hard to add additional
|
||||
# architectures.
|
||||
sys.exit(1)
|
||||
|
||||
distro_info = parse_os_release()
|
||||
vendor = distro_info["ID"]
|
||||
os_version = distro_info["VERSION_ID"]
|
||||
|
|
|
@ -90,7 +90,7 @@ else:
|
|||
manage_args = [f"--settings={settings_module}"]
|
||||
os.environ["DJANGO_SETTINGS_MODULE"] = settings_module
|
||||
|
||||
from scripts.lib.zulip_tools import CYAN, ENDC, FAIL
|
||||
from scripts.lib.zulip_tools import CYAN, ENDC
|
||||
|
||||
proxy_port = base_port
|
||||
django_port = base_port + 1
|
||||
|
@ -310,15 +310,6 @@ class TornadoHandler(BaseHandler):
|
|||
target_port = tornado_port
|
||||
|
||||
|
||||
class ErrorHandler(BaseHandler):
|
||||
@web.asynchronous
|
||||
def prepare(self) -> None:
|
||||
print(FAIL + "Unexpected request: " + ENDC, self.request.path)
|
||||
self.set_status(500)
|
||||
self.write("path not supported")
|
||||
self.finish()
|
||||
|
||||
|
||||
class Application(web.Application):
|
||||
def __init__(self, enable_logging: bool = False) -> None:
|
||||
handlers = [
|
||||
|
@ -334,10 +325,6 @@ class Application(web.Application):
|
|||
super().log_request(handler)
|
||||
|
||||
|
||||
def on_shutdown() -> None:
|
||||
IOLoop.instance().stop()
|
||||
|
||||
|
||||
def shutdown_handler(*args: Any, **kwargs: Any) -> None:
|
||||
io_loop = IOLoop.instance()
|
||||
if io_loop._callbacks:
|
||||
|
|
|
@ -265,7 +265,7 @@ def setup_emoji_farms(cache_path: str, emoji_data: List[Dict[str, Any]]) -> None
|
|||
if emoji_dict["has_img_" + alt_name]:
|
||||
ensure_emoji_image(emoji_dict, src_emoji_farm, target_emoji_farm)
|
||||
skin_variations = emoji_dict.get("skin_variations", {})
|
||||
for skin_tone, img_info in skin_variations.items():
|
||||
for img_info in skin_variations.values():
|
||||
if img_info["has_img_" + alt_name]:
|
||||
ensure_emoji_image(img_info, src_emoji_farm, target_emoji_farm)
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@ from emoji_setup_utils import EMOJISETS, emoji_is_universal, get_emoji_code
|
|||
|
||||
TOOLS_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
ZULIP_PATH = os.path.dirname(TOOLS_DIR)
|
||||
EMOJI_MAP_FILE = os.path.join(TOOLS_DIR, "setup", "emoji", "emoji_map.json")
|
||||
UNIFIED_REACTIONS_FILE = os.path.join(
|
||||
ZULIP_PATH, "zerver", "management", "data", "unified_reactions.json"
|
||||
)
|
||||
|
@ -27,8 +26,6 @@ with open(EMOJI_DATA_FILE, "rb") as fp:
|
|||
EMOJI_DATA = orjson.loads(fp.read())
|
||||
with open(UNIFIED_REACTIONS_FILE, "rb") as fp:
|
||||
UNIFIED_REACTIONS_MAP = orjson.loads(fp.read())
|
||||
with open(EMOJI_MAP_FILE, "rb") as fp:
|
||||
EMOJI_MAP = orjson.loads(fp.read())
|
||||
|
||||
EMOJI_IMAGE_TEMPLATE = """
|
||||
<img class="emoji" src="images-{emojiset}-64/{emoji_code}.png" title={emojiset}>
|
||||
|
|
|
@ -82,17 +82,6 @@ with test_server_running(
|
|||
site=site,
|
||||
)
|
||||
|
||||
# Prepare a generic bot client for curl testing
|
||||
email = "default-bot@zulip.com"
|
||||
realm = get_realm("zulip")
|
||||
bot_user = get_user(email, realm)
|
||||
api_key = get_api_key(bot_user)
|
||||
bot_client = Client(
|
||||
email=email,
|
||||
api_key=api_key,
|
||||
site=site,
|
||||
)
|
||||
|
||||
# Prepare the non-admin client
|
||||
email = "guest@zulip.com" # guest is not an admin
|
||||
guest_user = do_create_user(
|
||||
|
|
|
@ -6,7 +6,6 @@ import subprocess
|
|||
from typing import NoReturn
|
||||
|
||||
os.chdir(os.path.join(os.path.dirname(__file__), ".."))
|
||||
STATIC_PATH = "static/"
|
||||
|
||||
|
||||
def build_for_prod_or_puppeteer(quiet: bool) -> NoReturn:
|
||||
|
|
|
@ -192,42 +192,6 @@ def build_subscription(recipient_id: int, user_id: int, subscription_id: int) ->
|
|||
return subscription_dict
|
||||
|
||||
|
||||
def build_public_stream_subscriptions(
|
||||
zerver_userprofile: List[ZerverFieldsT],
|
||||
zerver_recipient: List[ZerverFieldsT],
|
||||
zerver_stream: List[ZerverFieldsT],
|
||||
) -> List[ZerverFieldsT]:
|
||||
"""
|
||||
This function was only used for HipChat, but it may apply to
|
||||
future conversions. We often did't get full subscriber data in
|
||||
the HipChat export, so this function just autosubscribes all
|
||||
users to every public stream. This returns a list of Subscription
|
||||
dicts.
|
||||
"""
|
||||
subscriptions: List[ZerverFieldsT] = []
|
||||
|
||||
public_stream_ids = {stream["id"] for stream in zerver_stream if not stream["invite_only"]}
|
||||
|
||||
public_stream_recipient_ids = {
|
||||
recipient["id"]
|
||||
for recipient in zerver_recipient
|
||||
if recipient["type"] == Recipient.STREAM and recipient["type_id"] in public_stream_ids
|
||||
}
|
||||
|
||||
user_ids = [user["id"] for user in zerver_userprofile]
|
||||
|
||||
for recipient_id in public_stream_recipient_ids:
|
||||
for user_id in user_ids:
|
||||
subscription = build_subscription(
|
||||
recipient_id=recipient_id,
|
||||
user_id=user_id,
|
||||
subscription_id=NEXT_ID("subscription"),
|
||||
)
|
||||
subscriptions.append(subscription)
|
||||
|
||||
return subscriptions
|
||||
|
||||
|
||||
class GetUsers(Protocol):
|
||||
def __call__(self, stream_id: int = ..., huddle_id: int = ...) -> Set[int]:
|
||||
...
|
||||
|
@ -618,37 +582,6 @@ def process_avatars(
|
|||
return avatar_list + avatar_original_list
|
||||
|
||||
|
||||
def write_avatar_png(avatar_folder: str, realm_id: int, user_id: int, bits: bytes) -> ZerverFieldsT:
|
||||
"""
|
||||
Use this function for conversions like HipChat where
|
||||
the bits for the .png file come in something like
|
||||
a users.json file, and where we don't have to
|
||||
fetch avatar images externally.
|
||||
"""
|
||||
avatar_hash = user_avatar_path_from_ids(
|
||||
user_profile_id=user_id,
|
||||
realm_id=realm_id,
|
||||
)
|
||||
|
||||
image_fn = avatar_hash + ".original"
|
||||
image_path = os.path.join(avatar_folder, image_fn)
|
||||
|
||||
with open(image_path, "wb") as image_file:
|
||||
image_file.write(bits)
|
||||
|
||||
# Return metadata that eventually goes in records.json.
|
||||
metadata = dict(
|
||||
path=image_path,
|
||||
s3_path=image_path,
|
||||
realm_id=realm_id,
|
||||
user_profile_id=user_id,
|
||||
# We only write the .original file; ask the importer to do the thumbnailing.
|
||||
importer_should_thumbnail=True,
|
||||
)
|
||||
|
||||
return metadata
|
||||
|
||||
|
||||
ListJobData = TypeVar("ListJobData")
|
||||
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import importlib
|
||||
import json
|
||||
import os
|
||||
from typing import Any, Callable, Dict, Optional
|
||||
|
||||
from django.conf import settings
|
||||
from django.utils.translation import gettext as _
|
||||
from zulip_bots.lib import BotIdentity, RateLimit
|
||||
|
||||
from zerver.lib.actions import (
|
||||
internal_send_huddle_message,
|
||||
|
@ -22,10 +22,6 @@ from zerver.lib.integrations import EMBEDDED_BOTS
|
|||
from zerver.lib.topic import get_topic_from_message_info
|
||||
from zerver.models import UserProfile, get_active_user
|
||||
|
||||
our_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
from zulip_bots.lib import BotIdentity, RateLimit
|
||||
|
||||
|
||||
def get_bot_handler(service_name: str) -> Any:
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ from typing import Any, Callable, Dict, List, Tuple
|
|||
|
||||
from django.conf import settings
|
||||
from django.contrib.sessions.models import Session
|
||||
from django.db.models import Q
|
||||
from django.utils.timezone import now as timezone_now
|
||||
|
||||
# This file needs to be different from cache.py because cache.py
|
||||
|
@ -17,45 +16,20 @@ from zerver.lib.cache import (
|
|||
get_remote_cache_requests,
|
||||
get_remote_cache_time,
|
||||
get_stream_cache_key,
|
||||
to_dict_cache_key_id,
|
||||
user_profile_by_api_key_cache_key,
|
||||
user_profile_cache_key,
|
||||
)
|
||||
from zerver.lib.message import MessageDict
|
||||
from zerver.lib.sessions import session_engine
|
||||
from zerver.lib.users import get_all_api_keys
|
||||
from zerver.models import (
|
||||
Client,
|
||||
Huddle,
|
||||
Message,
|
||||
Stream,
|
||||
UserProfile,
|
||||
get_client_cache_key,
|
||||
huddle_hash_cache_key,
|
||||
)
|
||||
|
||||
MESSAGE_CACHE_SIZE = 75000
|
||||
|
||||
|
||||
def message_fetch_objects() -> List[Any]:
|
||||
try:
|
||||
max_id = Message.objects.only("id").order_by("-id")[0].id
|
||||
except IndexError:
|
||||
return []
|
||||
return Message.objects.select_related().filter(
|
||||
~Q(sender__email="tabbott/extra@mit.edu"), id__gt=max_id - MESSAGE_CACHE_SIZE
|
||||
)
|
||||
|
||||
|
||||
def message_cache_items(items_for_remote_cache: Dict[str, Tuple[bytes]], message: Message) -> None:
|
||||
"""
|
||||
Note: this code is untested, and the caller has been
|
||||
commented out for a while.
|
||||
"""
|
||||
key = to_dict_cache_key_id(message.id)
|
||||
value = MessageDict.to_dict_uncached([message])[message.id]
|
||||
items_for_remote_cache[key] = (value,)
|
||||
|
||||
|
||||
def user_cache_items(
|
||||
items_for_remote_cache: Dict[str, Tuple[UserProfile]], user_profile: UserProfile
|
||||
|
@ -142,10 +116,6 @@ cache_fillers: Dict[
|
|||
10000,
|
||||
),
|
||||
"stream": (get_streams, stream_cache_items, 3600 * 24 * 7, 10000),
|
||||
# Message cache fetching disabled until we can fix the fact that it
|
||||
# does a bunch of inefficient memcached queries as part of filling
|
||||
# the display_recipient cache
|
||||
# 'message': (message_fetch_objects, message_cache_items, 3600 * 24, 1000),
|
||||
"huddle": (
|
||||
lambda: Huddle.objects.select_related().all(),
|
||||
huddle_cache_items,
|
||||
|
|
|
@ -85,14 +85,6 @@ subscription_fields: Sequence[Tuple[str, object]] = [
|
|||
]
|
||||
|
||||
|
||||
equals_add_or_remove = UnionType(
|
||||
[
|
||||
# force vertical
|
||||
Equals("add"),
|
||||
Equals("remove"),
|
||||
]
|
||||
)
|
||||
|
||||
value_type = UnionType(
|
||||
[
|
||||
# force vertical formatting
|
||||
|
|
|
@ -77,13 +77,11 @@ FilterArgs = Dict[str, Any]
|
|||
IdSource = Tuple[TableName, Field]
|
||||
SourceFilter = Callable[[Record], bool]
|
||||
|
||||
# These next two types are callbacks, which mypy does not
|
||||
# This next type is a callback, which mypy does not
|
||||
# support well, because PEP 484 says "using callbacks
|
||||
# with keyword arguments is not perceived as a common use case."
|
||||
# CustomFetch = Callable[[TableData, Config, Context], None]
|
||||
# PostProcessData = Callable[[TableData, Config, Context], None]
|
||||
CustomFetch = Any # TODO: make more specific, see above
|
||||
PostProcessData = Any # TODO: make more specific
|
||||
|
||||
# The keys of our MessageOutput variables are normally
|
||||
# List[Record], but when we write partials, we can get
|
||||
|
|
|
@ -122,13 +122,6 @@ def verbose_compile(pattern: str) -> Pattern[str]:
|
|||
)
|
||||
|
||||
|
||||
def normal_compile(pattern: str) -> Pattern[str]:
|
||||
return re.compile(
|
||||
fr"^(.*?){pattern}(.*)$",
|
||||
re.DOTALL | re.UNICODE,
|
||||
)
|
||||
|
||||
|
||||
STREAM_LINK_REGEX = r"""
|
||||
(?<![^\s'"\(,:<]) # Start after whitespace or specified chars
|
||||
\#\*\* # and after hash sign followed by double asterisks
|
||||
|
|
|
@ -53,8 +53,6 @@ from zerver.models import (
|
|||
query_for_ids,
|
||||
)
|
||||
|
||||
RealmAlertWord = Dict[int, List[str]]
|
||||
|
||||
|
||||
class RawReactionRow(TypedDict):
|
||||
emoji_code: str
|
||||
|
|
|
@ -19,7 +19,6 @@ from zerver.lib.response import json_method_not_allowed
|
|||
from zerver.lib.types import ViewFuncT
|
||||
|
||||
METHODS = ("GET", "HEAD", "POST", "PUT", "DELETE", "PATCH")
|
||||
FLAGS = "override_api_url_scheme"
|
||||
|
||||
|
||||
def default_never_cache_responses(view_func: ViewFuncT) -> ViewFuncT:
|
||||
|
|
|
@ -11,7 +11,6 @@ class ExtraConsoleOutputInTestException(Exception):
|
|||
|
||||
class ExtraConsoleOutputFinder:
|
||||
def __init__(self) -> None:
|
||||
self.latest_test_name = ""
|
||||
valid_line_patterns = [
|
||||
# Example: Running zerver.tests.test_attachments.AttachmentsTests.test_delete_unauthenticated
|
||||
"^Running ",
|
||||
|
|
|
@ -311,7 +311,6 @@ class HostRequestMock(HttpRequest):
|
|||
self.POST[key] = str(post_data[key])
|
||||
self.method = "POST"
|
||||
|
||||
self._log_data: Dict[str, Any] = {}
|
||||
if meta_data is None:
|
||||
self.META = {"PATH_INFO": "test"}
|
||||
else:
|
||||
|
|
|
@ -214,7 +214,7 @@ def generate_topic_history_from_db_rows(rows: List[Tuple[str, int]]) -> List[Dic
|
|||
canonical_topic_names[canonical_name] = (max_message_id, topic_name)
|
||||
|
||||
history = []
|
||||
for canonical_topic, (max_message_id, topic_name) in canonical_topic_names.items():
|
||||
for max_message_id, topic_name in canonical_topic_names.values():
|
||||
history.append(
|
||||
dict(name=topic_name, max_id=max_message_id),
|
||||
)
|
||||
|
|
|
@ -4,8 +4,7 @@ import itertools
|
|||
import re
|
||||
import secrets
|
||||
from itertools import zip_longest
|
||||
from time import sleep
|
||||
from typing import Any, Callable, Iterator, List, Optional, Sequence, Set, Tuple, TypeVar
|
||||
from typing import Any, Callable, Iterator, List, Optional, Set, Tuple, TypeVar
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
|
@ -58,33 +57,6 @@ class StatsDWrapper:
|
|||
|
||||
statsd = StatsDWrapper()
|
||||
|
||||
# Runs the callback with slices of all_list of a given batch_size
|
||||
def run_in_batches(
|
||||
all_list: Sequence[T],
|
||||
batch_size: int,
|
||||
callback: Callable[[Sequence[T]], None],
|
||||
sleep_time: int = 0,
|
||||
logger: Optional[Callable[[str], None]] = None,
|
||||
) -> None:
|
||||
if len(all_list) == 0:
|
||||
return
|
||||
|
||||
limit = (len(all_list) // batch_size) + 1
|
||||
for i in range(limit):
|
||||
start = i * batch_size
|
||||
end = (i + 1) * batch_size
|
||||
if end >= len(all_list):
|
||||
end = len(all_list)
|
||||
batch = all_list[start:end]
|
||||
|
||||
if logger:
|
||||
logger(f"Executing {end-start} in batch {i+1} of {limit}")
|
||||
|
||||
callback(batch)
|
||||
|
||||
if i != limit - 1:
|
||||
sleep(sleep_time)
|
||||
|
||||
|
||||
def make_safe_digest(string: str, hash_func: Callable[[bytes], Any] = hashlib.sha1) -> str:
|
||||
"""
|
||||
|
|
|
@ -1550,9 +1550,6 @@ class UserProfile(AbstractBaseUser, PermissionsMixin, UserBaseSettings):
|
|||
# API rate limits, formatted as a comma-separated list of range:max pairs
|
||||
rate_limits: str = models.CharField(default="", max_length=100)
|
||||
|
||||
# Hours to wait before sending another email to a user
|
||||
EMAIL_REMINDER_WAITPERIOD = 24
|
||||
|
||||
# Default streams for some deprecated/legacy classes of bot users.
|
||||
default_sending_stream: Optional["Stream"] = models.ForeignKey(
|
||||
"zerver.Stream",
|
||||
|
|
|
@ -16,11 +16,10 @@ import json
|
|||
import os
|
||||
import sys
|
||||
from functools import wraps
|
||||
from typing import Any, Callable, Dict, Iterable, List, Optional, Set, TypeVar, cast
|
||||
from typing import Any, Callable, Dict, List, Set, TypeVar, cast
|
||||
|
||||
from zulip import Client
|
||||
|
||||
from zerver.lib import mdiff
|
||||
from zerver.models import get_realm, get_user
|
||||
from zerver.openapi.openapi import validate_against_openapi_schema
|
||||
|
||||
|
@ -1428,58 +1427,6 @@ def test_invalid_stream_error(client: Client) -> None:
|
|||
|
||||
|
||||
# SETUP METHODS FOLLOW
|
||||
def test_against_fixture(
|
||||
result: Dict[str, Any],
|
||||
fixture: Dict[str, Any],
|
||||
check_if_equal: Optional[Iterable[str]] = None,
|
||||
check_if_exists: Optional[Iterable[str]] = None,
|
||||
) -> None:
|
||||
assertLength(result, fixture)
|
||||
|
||||
if check_if_equal is None and check_if_exists is None:
|
||||
for key, value in fixture.items():
|
||||
assertEqual(key, result, fixture)
|
||||
|
||||
if check_if_equal is not None:
|
||||
for key in check_if_equal:
|
||||
assertEqual(key, result, fixture)
|
||||
|
||||
if check_if_exists is not None:
|
||||
for key in check_if_exists:
|
||||
assertIn(key, result)
|
||||
|
||||
|
||||
def assertEqual(key: str, result: Dict[str, Any], fixture: Dict[str, Any]) -> None:
|
||||
if result[key] != fixture[key]:
|
||||
first = f"{key} = {result[key]}"
|
||||
second = f"{key} = {fixture[key]}"
|
||||
raise AssertionError(
|
||||
"Actual and expected outputs do not match; showing diff:\n"
|
||||
+ mdiff.diff_strings(first, second)
|
||||
)
|
||||
else:
|
||||
assert result[key] == fixture[key]
|
||||
|
||||
|
||||
def assertLength(result: Dict[str, Any], fixture: Dict[str, Any]) -> None:
|
||||
if len(result) != len(fixture):
|
||||
result_string = json.dumps(result, indent=4, sort_keys=True)
|
||||
fixture_string = json.dumps(fixture, indent=4, sort_keys=True)
|
||||
raise AssertionError(
|
||||
"The lengths of the actual and expected outputs do not match; showing diff:\n"
|
||||
+ mdiff.diff_strings(result_string, fixture_string)
|
||||
)
|
||||
else:
|
||||
assert len(result) == len(fixture)
|
||||
|
||||
|
||||
def assertIn(key: str, result: Dict[str, Any]) -> None:
|
||||
if key not in result.keys():
|
||||
raise AssertionError(
|
||||
f"The actual output does not contain the the key `{key}`.",
|
||||
)
|
||||
else:
|
||||
assert key in result
|
||||
|
||||
|
||||
def test_messages(client: Client, nonadmin_client: Client) -> None:
|
||||
|
|
|
@ -819,7 +819,6 @@ class SocialAuthBase(DesktopFlowTestingLib, ZulipTestCase):
|
|||
SIGNUP_URL: str
|
||||
AUTHORIZATION_URL: str
|
||||
AUTH_FINISH_URL: str
|
||||
CONFIG_ERROR_URL: str
|
||||
ACCESS_TOKEN_URL: str
|
||||
USER_INFO_URL: str
|
||||
CLIENT_KEY_SETTING: str
|
||||
|
@ -1780,7 +1779,6 @@ class SAMLAuthBackendTest(SocialAuthBase):
|
|||
SIGNUP_URL = "/accounts/register/social/saml/test_idp"
|
||||
AUTHORIZATION_URL = "https://idp.testshib.org/idp/profile/SAML2/Redirect/SSO"
|
||||
AUTH_FINISH_URL = "/complete/saml/"
|
||||
CONFIG_ERROR_URL = "/config-error/saml"
|
||||
|
||||
# We have to define our own social_auth_test as the flow of SAML authentication
|
||||
# is different from the other social backends.
|
||||
|
@ -2651,7 +2649,6 @@ class AppleAuthMixin:
|
|||
AUTHORIZATION_URL = "https://appleid.apple.com/auth/authorize"
|
||||
ACCESS_TOKEN_URL = "https://appleid.apple.com/auth/token"
|
||||
AUTH_FINISH_URL = "/complete/apple/"
|
||||
CONFIG_ERROR_URL = "/config-error/apple"
|
||||
|
||||
def generate_id_token(
|
||||
self, account_data_dict: Dict[str, str], audience: Optional[str] = None
|
||||
|
@ -3033,7 +3030,6 @@ class GenericOpenIdConnectTest(SocialAuthBase):
|
|||
JWKS_URL = f"{BASE_OIDC_URL}/jwks"
|
||||
USER_INFO_URL = f"{BASE_OIDC_URL}/userinfo"
|
||||
AUTH_FINISH_URL = "/complete/oidc/"
|
||||
CONFIG_ERROR_URL = "/config-error/oidc"
|
||||
|
||||
def social_auth_test(
|
||||
self,
|
||||
|
@ -3215,7 +3211,6 @@ class GitHubAuthBackendTest(SocialAuthBase):
|
|||
ACCESS_TOKEN_URL = "https://github.com/login/oauth/access_token"
|
||||
USER_INFO_URL = "https://api.github.com/user"
|
||||
AUTH_FINISH_URL = "/complete/github/"
|
||||
CONFIG_ERROR_URL = "/config-error/github"
|
||||
email_data: List[Dict[str, Any]] = []
|
||||
|
||||
def social_auth_test_finish(
|
||||
|
@ -3737,7 +3732,6 @@ class GitLabAuthBackendTest(SocialAuthBase):
|
|||
ACCESS_TOKEN_URL = "https://gitlab.com/oauth/token"
|
||||
USER_INFO_URL = "https://gitlab.com/api/v4/user"
|
||||
AUTH_FINISH_URL = "/complete/gitlab/"
|
||||
CONFIG_ERROR_URL = "/config-error/gitlab"
|
||||
|
||||
def test_gitlab_auth_enabled(self) -> None:
|
||||
with self.settings(AUTHENTICATION_BACKENDS=("zproject.backends.GitLabAuthBackend",)):
|
||||
|
@ -3759,7 +3753,6 @@ class GoogleAuthBackendTest(SocialAuthBase):
|
|||
ACCESS_TOKEN_URL = "https://accounts.google.com/o/oauth2/token"
|
||||
USER_INFO_URL = "https://www.googleapis.com/oauth2/v3/userinfo"
|
||||
AUTH_FINISH_URL = "/complete/google/"
|
||||
CONFIG_ERROR_URL = "/config-error/google"
|
||||
|
||||
def get_account_data_dict(self, email: str, name: str) -> Dict[str, Any]:
|
||||
return dict(email=email, name=name, email_verified=True)
|
||||
|
|
|
@ -2,7 +2,6 @@ import asyncio
|
|||
import base64
|
||||
import datetime
|
||||
import itertools
|
||||
import os
|
||||
import re
|
||||
import uuid
|
||||
from contextlib import contextmanager
|
||||
|
@ -87,8 +86,6 @@ if settings.ZILENCER_ENABLED:
|
|||
RemoteZulipServer,
|
||||
)
|
||||
|
||||
ZERVER_DIR = os.path.dirname(os.path.dirname(__file__))
|
||||
|
||||
|
||||
@skipUnless(settings.ZILENCER_ENABLED, "requires zilencer")
|
||||
class BouncerTestCase(ZulipTestCase):
|
||||
|
|
|
@ -182,10 +182,6 @@ class ClientDescriptor:
|
|||
ret.last_connection_time = d["last_connection_time"]
|
||||
return ret
|
||||
|
||||
def prepare_for_pickling(self) -> None:
|
||||
self.current_handler_id = None
|
||||
self._timeout_handle = None
|
||||
|
||||
def add_event(self, event: Mapping[str, Any]) -> None:
|
||||
if self.current_handler_id is not None:
|
||||
handler = get_handler_by_id(self.current_handler_id)
|
||||
|
@ -709,11 +705,6 @@ def fetch_events(query: Mapping[str, Any]) -> Dict[str, Any]:
|
|||
return dict(type="async")
|
||||
|
||||
|
||||
# Send email notifications to idle users
|
||||
# after they are idle for 1 hour
|
||||
NOTIFY_AFTER_IDLE_HOURS = 1
|
||||
|
||||
|
||||
def build_offline_notification(user_profile_id: int, message_id: int) -> Dict[str, Any]:
|
||||
return {
|
||||
"user_profile_id": user_profile_id,
|
||||
|
|
|
@ -9,8 +9,6 @@ from zerver.lib.response import json_success
|
|||
from zerver.lib.webhooks.common import check_send_webhook_message
|
||||
from zerver.models import UserProfile
|
||||
|
||||
CHECK_IS_REPLY = "in reply to"
|
||||
|
||||
|
||||
@webhook_view("Flock")
|
||||
@has_request_variables
|
||||
|
|
|
@ -4,7 +4,6 @@ from zerver.lib.test_classes import WebhookTestCase
|
|||
class SonarqubeHookTests(WebhookTestCase):
|
||||
STREAM_NAME = "SonarQube"
|
||||
URL_TEMPLATE = "/api/v1/external/sonarqube?api_key={api_key}&stream={stream}"
|
||||
FIXTURE_DIR_NAME = "sonarqube"
|
||||
WEBHOOK_DIR_NAME = "sonarqube"
|
||||
|
||||
def test_analysis_success(self) -> None:
|
||||
|
|
|
@ -13,10 +13,8 @@ class TransifexHookTests(WebhookTestCase):
|
|||
PROJECT = "project-title"
|
||||
LANGUAGE = "en"
|
||||
RESOURCE = "file"
|
||||
REVIEWED = True
|
||||
|
||||
def test_transifex_reviewed_message(self) -> None:
|
||||
self.REVIEWED = True
|
||||
expected_topic = f"{self.PROJECT} in {self.LANGUAGE}"
|
||||
expected_message = f"Resource {self.RESOURCE} fully reviewed."
|
||||
self.url = self.build_webhook_url(
|
||||
|
@ -28,7 +26,6 @@ class TransifexHookTests(WebhookTestCase):
|
|||
self.check_webhook("", expected_topic, expected_message)
|
||||
|
||||
def test_transifex_translated_message(self) -> None:
|
||||
self.REVIEWED = False
|
||||
expected_topic = f"{self.PROJECT} in {self.LANGUAGE}"
|
||||
expected_message = f"Resource {self.RESOURCE} fully translated."
|
||||
self.url = self.build_webhook_url(
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
from django import forms
|
||||
|
||||
|
||||
class EnterpriseToSForm(forms.Form):
|
||||
full_name = forms.CharField(max_length=100)
|
||||
company = forms.CharField(max_length=100)
|
||||
terms = forms.BooleanField(required=True)
|
Loading…
Reference in New Issue