mirror of https://github.com/zulip/zulip.git
python: Merge concatenated string literals that Black would uglify.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
parent
d8d0e7dfff
commit
5028c081cb
|
@ -46,8 +46,7 @@ def generate_time_series_data(days: int=100, business_hours_base: float=10,
|
||||||
else:
|
else:
|
||||||
raise AssertionError(f"Unknown frequency: {frequency}")
|
raise AssertionError(f"Unknown frequency: {frequency}")
|
||||||
if length < 2:
|
if length < 2:
|
||||||
raise AssertionError("Must be generating at least 2 data points. "
|
raise AssertionError(f"Must be generating at least 2 data points. Currently generating {length}")
|
||||||
f"Currently generating {length}")
|
|
||||||
growth_base = growth ** (1. / (length-1))
|
growth_base = growth ** (1. / (length-1))
|
||||||
values_no_noise = [seasonality[i % len(seasonality)] * (growth_base**i) for i in range(length)]
|
values_no_noise = [seasonality[i % len(seasonality)] * (growth_base**i) for i in range(length)]
|
||||||
|
|
||||||
|
|
|
@ -93,8 +93,7 @@ if replication_info:
|
||||||
|
|
||||||
else:
|
else:
|
||||||
replication_info = run_sql_query(
|
replication_info = run_sql_query(
|
||||||
'client_addr, state, sent_lsn, write_lsn, flush_lsn, replay_lsn'
|
'client_addr, state, sent_lsn, write_lsn, flush_lsn, replay_lsn from pg_stat_replication'
|
||||||
' from pg_stat_replication'
|
|
||||||
)
|
)
|
||||||
if replication_info == 0:
|
if replication_info == 0:
|
||||||
report('CRITICAL', 'No replicas!')
|
report('CRITICAL', 'No replicas!')
|
||||||
|
|
|
@ -17,16 +17,15 @@ def parse_args() -> argparse.Namespace:
|
||||||
"examined and removed.")
|
"examined and removed.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--threshold", dest="threshold_days", type=int, default=14,
|
"--threshold", dest="threshold_days", type=int, default=14,
|
||||||
metavar="<days>", help="Deployments older than "
|
metavar="<days>",
|
||||||
"threshold days will be deleted. (defaults to 14)")
|
help="Deployments older than threshold days will be deleted. (defaults to 14)")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--dry-run", action="store_true",
|
"--dry-run", action="store_true",
|
||||||
help="If specified then script will only print the deployments and "
|
help="If specified then script will only print the deployments and "
|
||||||
"caches that it will delete/keep back. It will not delete anything.")
|
"caches that it will delete/keep back. It will not delete anything.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--verbose", action="store_true",
|
"--verbose", action="store_true",
|
||||||
help="If specified then script will print a detailed report "
|
help="If specified then script will print a detailed report of what is going on.")
|
||||||
"of what is going on.")
|
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
args.verbose |= args.dry_run # Always print a detailed report in case of dry run.
|
args.verbose |= args.dry_run # Always print a detailed report in case of dry run.
|
||||||
|
|
|
@ -22,8 +22,7 @@ if __name__ == '__main__':
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument('--show-ignored',
|
parser.add_argument('--show-ignored',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
help='Show strings that passed the check because they '
|
help='Show strings that passed the check because they contained ignored phrases.')
|
||||||
'contained ignored phrases.')
|
|
||||||
parser.add_argument('--no-generate',
|
parser.add_argument('--no-generate',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
help="Don't run makemessages command.")
|
help="Don't run makemessages command.")
|
||||||
|
|
|
@ -30,8 +30,7 @@ class UnusedImagesLinterSpider(BaseDocumentationSpider):
|
||||||
def closed(self, *args: Any, **kwargs: Any) -> None:
|
def closed(self, *args: Any, **kwargs: Any) -> None:
|
||||||
unused_images = set(os.listdir(self.images_static_dir)) - self.static_images
|
unused_images = set(os.listdir(self.images_static_dir)) - self.static_images
|
||||||
if unused_images:
|
if unused_images:
|
||||||
exception_message = "The following images are not used in documentation " \
|
exception_message = "The following images are not used in documentation and can be removed: {}"
|
||||||
"and can be removed: {}"
|
|
||||||
self._set_error_state()
|
self._set_error_state()
|
||||||
unused_images_relatedpath = [
|
unused_images_relatedpath = [
|
||||||
os.path.join(self.images_path, img) for img in unused_images]
|
os.path.join(self.images_path, img) for img in unused_images]
|
||||||
|
|
|
@ -79,8 +79,7 @@ if platform.architecture()[0] == '64bit':
|
||||||
elif platform.architecture()[0] == '32bit':
|
elif platform.architecture()[0] == '32bit':
|
||||||
arch = "i386"
|
arch = "i386"
|
||||||
else:
|
else:
|
||||||
logging.critical("Only x86 is supported;"
|
logging.critical("Only x86 is supported; ask on chat.zulip.org if you want another architecture.")
|
||||||
" ask on chat.zulip.org if you want another architecture.")
|
|
||||||
# Note: It's probably actually not hard to add additional
|
# Note: It's probably actually not hard to add additional
|
||||||
# architectures.
|
# architectures.
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
|
@ -110,8 +110,7 @@ def setup_bash_profile() -> None:
|
||||||
|
|
||||||
BASH_PROFILE = BASH_PROFILES[0]
|
BASH_PROFILE = BASH_PROFILES[0]
|
||||||
DOT_PROFILE = BASH_PROFILES[2]
|
DOT_PROFILE = BASH_PROFILES[2]
|
||||||
OLD_PROFILE_TEXT = "source /srv/zulip-py3-venv/bin/activate\n" + \
|
OLD_PROFILE_TEXT = "source /srv/zulip-py3-venv/bin/activate\ncd /srv/zulip\n"
|
||||||
"cd /srv/zulip\n"
|
|
||||||
|
|
||||||
if os.path.exists(DOT_PROFILE):
|
if os.path.exists(DOT_PROFILE):
|
||||||
try:
|
try:
|
||||||
|
|
21
tools/lint
21
tools/lint
|
@ -50,25 +50,20 @@ def run() -> None:
|
||||||
|
|
||||||
linter_config.external_linter('css', ['node', 'node_modules/.bin/stylelint'], ['css'],
|
linter_config.external_linter('css', ['node', 'node_modules/.bin/stylelint'], ['css'],
|
||||||
fix_arg='--fix',
|
fix_arg='--fix',
|
||||||
description="Standard CSS style and formatting linter "
|
description="Standard CSS style and formatting linter (config: stylelint.config.js)")
|
||||||
"(config: stylelint.config.js)")
|
|
||||||
linter_config.external_linter('eslint', ['node', 'node_modules/.bin/eslint',
|
linter_config.external_linter('eslint', ['node', 'node_modules/.bin/eslint',
|
||||||
'--max-warnings=0', '--cache', '--ext', '.js,.ts'], ['js', 'ts'],
|
'--max-warnings=0', '--cache', '--ext', '.js,.ts'], ['js', 'ts'],
|
||||||
fix_arg='--fix',
|
fix_arg='--fix',
|
||||||
description="Standard JavaScript style and formatting linter "
|
description="Standard JavaScript style and formatting linter (config: .eslintrc).")
|
||||||
"(config: .eslintrc).")
|
|
||||||
linter_config.external_linter('puppet', ['puppet', 'parser', 'validate'], ['pp'],
|
linter_config.external_linter('puppet', ['puppet', 'parser', 'validate'], ['pp'],
|
||||||
description="Runs the puppet parser validator, "
|
description="Runs the puppet parser validator, checking for syntax errors.")
|
||||||
"checking for syntax errors.")
|
|
||||||
linter_config.external_linter('puppet-lint',
|
linter_config.external_linter('puppet-lint',
|
||||||
['puppet-lint', '--fail-on-warnings', *PUPPET_CHECK_RULES_TO_EXCLUDE],
|
['puppet-lint', '--fail-on-warnings', *PUPPET_CHECK_RULES_TO_EXCLUDE],
|
||||||
['pp'],
|
['pp'],
|
||||||
fix_arg='--fix',
|
fix_arg='--fix',
|
||||||
description="Standard puppet linter "
|
description="Standard puppet linter (config: tools/linter_lib/exclude.py)")
|
||||||
"(config: tools/linter_lib/exclude.py)")
|
|
||||||
linter_config.external_linter('templates', ['tools/check-templates'], ['hbs', 'html'],
|
linter_config.external_linter('templates', ['tools/check-templates'], ['hbs', 'html'],
|
||||||
description="Custom linter checks whitespace formatting "
|
description="Custom linter checks whitespace formatting of HTML templates",
|
||||||
"of HTML templates",
|
|
||||||
fix_arg='--fix')
|
fix_arg='--fix')
|
||||||
linter_config.external_linter('openapi', ['node', 'tools/check-openapi'], ['yaml'],
|
linter_config.external_linter('openapi', ['node', 'tools/check-openapi'], ['yaml'],
|
||||||
description="Validates our OpenAPI/Swagger API documentation "
|
description="Validates our OpenAPI/Swagger API documentation "
|
||||||
|
@ -89,8 +84,7 @@ def run() -> None:
|
||||||
pass_targets=False,
|
pass_targets=False,
|
||||||
description="Shares duplicate packages in yarn.lock")
|
description="Shares duplicate packages in yarn.lock")
|
||||||
linter_config.external_linter('gitlint', ['tools/commit-message-lint'],
|
linter_config.external_linter('gitlint', ['tools/commit-message-lint'],
|
||||||
description="Checks commit messages for common formatting errors "
|
description="Checks commit messages for common formatting errors (config: .gitlint)")
|
||||||
"(config: .gitlint)")
|
|
||||||
linter_config.external_linter('isort', ['isort'], ['py'],
|
linter_config.external_linter('isort', ['isort'], ['py'],
|
||||||
description="Sorts Python import statements",
|
description="Sorts Python import statements",
|
||||||
check_arg=['--check-only', '--diff'])
|
check_arg=['--check-only', '--diff'])
|
||||||
|
@ -112,8 +106,7 @@ def run() -> None:
|
||||||
"--dangerously-allow-arbitrary-code-execution-from-rules"]
|
"--dangerously-allow-arbitrary-code-execution-from-rules"]
|
||||||
linter_config.external_linter('semgrep-py', [*semgrep_command, "--lang=python"], ['py'],
|
linter_config.external_linter('semgrep-py', [*semgrep_command, "--lang=python"], ['py'],
|
||||||
fix_arg='--autofix',
|
fix_arg='--autofix',
|
||||||
description="Syntactic Grep (semgrep) Code Search Tool "
|
description="Syntactic Grep (semgrep) Code Search Tool (config: ./tools/semgrep.yml)")
|
||||||
"(config: ./tools/semgrep.yml)")
|
|
||||||
|
|
||||||
linter_config.external_linter('thirdparty', ['tools/check-thirdparty'],
|
linter_config.external_linter('thirdparty', ['tools/check-thirdparty'],
|
||||||
description="Check docs/THIRDPARTY copyright file syntax")
|
description="Check docs/THIRDPARTY copyright file syntax")
|
||||||
|
|
|
@ -382,8 +382,7 @@ def main() -> None:
|
||||||
TestRunner = get_runner(settings)
|
TestRunner = get_runner(settings)
|
||||||
|
|
||||||
if parallel > 1:
|
if parallel > 1:
|
||||||
print("-- Running tests in parallel mode with {} "
|
print(f"-- Running tests in parallel mode with {parallel} processes.", flush=True)
|
||||||
"processes.".format(parallel), flush=True)
|
|
||||||
else:
|
else:
|
||||||
print("-- Running tests in serial mode.", flush=True)
|
print("-- Running tests in serial mode.", flush=True)
|
||||||
|
|
||||||
|
|
|
@ -7,11 +7,9 @@ from tools.lib.capitalization import check_capitalization, get_safe_text, is_cap
|
||||||
|
|
||||||
class GetSafeTextTestCase(TestCase):
|
class GetSafeTextTestCase(TestCase):
|
||||||
def test_get_safe_text(self) -> None:
|
def test_get_safe_text(self) -> None:
|
||||||
string = ('Messages in __page_params.product_name__ go to a '
|
string = ('Messages in __page_params.product_name__ go to a stream and have a topic.')
|
||||||
'stream and have a topic.')
|
|
||||||
safe_text = get_safe_text(string)
|
safe_text = get_safe_text(string)
|
||||||
self.assertEqual(safe_text, 'Messages in __page_params_product_name__ '
|
self.assertEqual(safe_text, 'Messages in __page_params_product_name__ go to a stream and have a topic.')
|
||||||
'go to a stream and have a topic.')
|
|
||||||
|
|
||||||
string = "Zulip Zulip. Zulip some text!"
|
string = "Zulip Zulip. Zulip some text!"
|
||||||
safe_text = get_safe_text(string)
|
safe_text = get_safe_text(string)
|
||||||
|
|
|
@ -156,9 +156,7 @@ class HomepageForm(forms.Form):
|
||||||
from_multiuse_invite = self.from_multiuse_invite
|
from_multiuse_invite = self.from_multiuse_invite
|
||||||
|
|
||||||
if realm is None:
|
if realm is None:
|
||||||
raise ValidationError(_("The organization you are trying to "
|
raise ValidationError(_("The organization you are trying to join using {email} does not exist.").format(email=email))
|
||||||
"join using {email} does not "
|
|
||||||
"exist.").format(email=email))
|
|
||||||
|
|
||||||
if not from_multiuse_invite and realm.invite_required:
|
if not from_multiuse_invite and realm.invite_required:
|
||||||
raise ValidationError(_("Please request an invite for {email} "
|
raise ValidationError(_("Please request an invite for {email} "
|
||||||
|
|
|
@ -236,8 +236,7 @@ def notify_bot_owner(event: Dict[str, Any],
|
||||||
if status_code:
|
if status_code:
|
||||||
notification_message += f"\nThe webhook got a response with status code *{status_code}*."
|
notification_message += f"\nThe webhook got a response with status code *{status_code}*."
|
||||||
if response_content:
|
if response_content:
|
||||||
notification_message += "\nThe response contains the following payload:\n" \
|
notification_message += f"\nThe response contains the following payload:\n```\n{response_content!r}\n```"
|
||||||
f"```\n{response_content!r}\n```"
|
|
||||||
if exception:
|
if exception:
|
||||||
notification_message += "\nWhen trying to send a request to the webhook service, an exception " \
|
notification_message += "\nWhen trying to send a request to the webhook service, an exception " \
|
||||||
f"of type {type(exception).__name__} occurred:\n```\n{exception}\n```"
|
f"of type {type(exception).__name__} occurred:\n```\n{exception}\n```"
|
||||||
|
|
|
@ -26,13 +26,11 @@ PUSH_COMMITS_MESSAGE_TEMPLATE_WITHOUT_COMMITTERS = PUSH_COMMITS_BASE + """
|
||||||
{commits_data}
|
{commits_data}
|
||||||
"""
|
"""
|
||||||
PUSH_DELETE_BRANCH_MESSAGE_TEMPLATE = "{user_name} [deleted]({compare_url}) the branch {branch_name}."
|
PUSH_DELETE_BRANCH_MESSAGE_TEMPLATE = "{user_name} [deleted]({compare_url}) the branch {branch_name}."
|
||||||
PUSH_LOCAL_BRANCH_WITHOUT_COMMITS_MESSAGE_TEMPLATE = ("{user_name} [pushed]({compare_url}) "
|
PUSH_LOCAL_BRANCH_WITHOUT_COMMITS_MESSAGE_TEMPLATE = "{user_name} [pushed]({compare_url}) the branch {branch_name}."
|
||||||
"the branch {branch_name}.")
|
|
||||||
PUSH_COMMITS_MESSAGE_EXTENSION = "Commits by {}"
|
PUSH_COMMITS_MESSAGE_EXTENSION = "Commits by {}"
|
||||||
PUSH_COMMITTERS_LIMIT_INFO = 3
|
PUSH_COMMITTERS_LIMIT_INFO = 3
|
||||||
|
|
||||||
FORCE_PUSH_COMMITS_MESSAGE_TEMPLATE = ("{user_name} [force pushed]({url}) "
|
FORCE_PUSH_COMMITS_MESSAGE_TEMPLATE = "{user_name} [force pushed]({url}) to branch {branch_name}. Head is now {head}."
|
||||||
"to branch {branch_name}. Head is now {head}.")
|
|
||||||
CREATE_BRANCH_MESSAGE_TEMPLATE = "{user_name} created [{branch_name}]({url}) branch."
|
CREATE_BRANCH_MESSAGE_TEMPLATE = "{user_name} created [{branch_name}]({url}) branch."
|
||||||
CREATE_BRANCH_WITHOUT_URL_MESSAGE_TEMPLATE = "{user_name} created {branch_name} branch."
|
CREATE_BRANCH_WITHOUT_URL_MESSAGE_TEMPLATE = "{user_name} created {branch_name} branch."
|
||||||
REMOVE_BRANCH_MESSAGE_TEMPLATE = "{user_name} deleted branch {branch_name}."
|
REMOVE_BRANCH_MESSAGE_TEMPLATE = "{user_name} deleted branch {branch_name}."
|
||||||
|
|
|
@ -21,12 +21,10 @@ class Command(ZulipBaseCommand):
|
||||||
# first check if the db has been initialized
|
# first check if the db has been initialized
|
||||||
Realm.objects.first()
|
Realm.objects.first()
|
||||||
except ProgrammingError:
|
except ProgrammingError:
|
||||||
raise CommandError("The Zulip database does not appear to exist. "
|
raise CommandError("The Zulip database does not appear to exist. Have you run initialize-database?")
|
||||||
"Have you run initialize-database?")
|
|
||||||
|
|
||||||
url = generate_realm_creation_url(by_admin=True)
|
url = generate_realm_creation_url(by_admin=True)
|
||||||
self.stdout.write(self.style.SUCCESS("Please visit the following "
|
self.stdout.write(self.style.SUCCESS("Please visit the following secure single-use link to register your "))
|
||||||
"secure single-use link to register your "))
|
|
||||||
self.stdout.write(self.style.SUCCESS("new Zulip organization:\033[0m"))
|
self.stdout.write(self.style.SUCCESS("new Zulip organization:\033[0m"))
|
||||||
self.stdout.write("")
|
self.stdout.write("")
|
||||||
self.stdout.write(self.style.SUCCESS(f" \033[1;92m{url}\033[0m"))
|
self.stdout.write(self.style.SUCCESS(f" \033[1;92m{url}\033[0m"))
|
||||||
|
|
|
@ -76,8 +76,7 @@ import a database dump from one or more JSON files."""
|
||||||
if not os.path.exists(path):
|
if not os.path.exists(path):
|
||||||
raise CommandError(f"Directory not found: '{path}'")
|
raise CommandError(f"Directory not found: '{path}'")
|
||||||
if not os.path.isdir(path):
|
if not os.path.isdir(path):
|
||||||
raise CommandError("Export file should be folder; if it's a "
|
raise CommandError("Export file should be folder; if it's a tarball, please unpack it first.")
|
||||||
"tarball, please unpack it first.")
|
|
||||||
paths.append(path)
|
paths.append(path)
|
||||||
|
|
||||||
for path in paths:
|
for path in paths:
|
||||||
|
|
|
@ -47,8 +47,7 @@ class Command(ZulipBaseCommand):
|
||||||
allow_subdomains=options["allow_subdomains"])
|
allow_subdomains=options["allow_subdomains"])
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
except IntegrityError:
|
except IntegrityError:
|
||||||
raise CommandError(f"The domain {domain} is already a part "
|
raise CommandError(f"The domain {domain} is already a part of your organization.")
|
||||||
"of your organization.")
|
|
||||||
elif options["op"] == "remove":
|
elif options["op"] == "remove":
|
||||||
try:
|
try:
|
||||||
RealmDomain.objects.get(realm=realm, domain=domain).delete()
|
RealmDomain.objects.get(realm=realm, domain=domain).delete()
|
||||||
|
|
|
@ -36,12 +36,10 @@ approach shown above.
|
||||||
'into Zulip')
|
'into Zulip')
|
||||||
|
|
||||||
parser.add_argument('-u', '--url',
|
parser.add_argument('-u', '--url',
|
||||||
help='The URL on your Zulip server that you want '
|
help='The URL on your Zulip server that you want to post the fixture to')
|
||||||
'to post the fixture to')
|
|
||||||
|
|
||||||
parser.add_argument('-H', '--custom-headers',
|
parser.add_argument('-H', '--custom-headers',
|
||||||
help='The headers you want to provide along with '
|
help='The headers you want to provide along with your mock request to Zulip.')
|
||||||
'your mock request to Zulip.')
|
|
||||||
|
|
||||||
self.add_realm_args(parser, help="Specify which realm/subdomain to connect to; default is zulip")
|
self.add_realm_args(parser, help="Specify which realm/subdomain to connect to; default is zulip")
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,7 @@ class Command(ZulipBaseCommand):
|
||||||
self.add_realm_args(parser)
|
self.add_realm_args(parser)
|
||||||
|
|
||||||
self.add_user_list_args(parser,
|
self.add_user_list_args(parser,
|
||||||
help='Turn off digests for this comma-separated '
|
help='Turn off digests for this comma-separated list of email addresses.',
|
||||||
'list of email addresses.',
|
|
||||||
all_users_help="Turn off digests for everyone in realm.")
|
all_users_help="Turn off digests for everyone in realm.")
|
||||||
|
|
||||||
def handle(self, **options: str) -> None:
|
def handle(self, **options: str) -> None:
|
||||||
|
|
|
@ -1486,8 +1486,7 @@ class TestAuthenticatedJsonPostViewDecorator(ZulipTestCase):
|
||||||
with self.assertLogs(level="WARNING") as m, \
|
with self.assertLogs(level="WARNING") as m, \
|
||||||
mock.patch('zerver.decorator.get_subdomain', return_value=''):
|
mock.patch('zerver.decorator.get_subdomain', return_value=''):
|
||||||
self.assert_json_error_contains(self._do_test(user),
|
self.assert_json_error_contains(self._do_test(user),
|
||||||
"Account is not associated with this "
|
"Account is not associated with this subdomain")
|
||||||
"subdomain")
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
m.output,
|
m.output,
|
||||||
["WARNING:root:User {} ({}) attempted to access API on wrong subdomain ({})".format(email, 'zulip', ''),
|
["WARNING:root:User {} ({}) attempted to access API on wrong subdomain ({})".format(email, 'zulip', ''),
|
||||||
|
@ -1497,8 +1496,7 @@ class TestAuthenticatedJsonPostViewDecorator(ZulipTestCase):
|
||||||
with self.assertLogs(level="WARNING") as m, \
|
with self.assertLogs(level="WARNING") as m, \
|
||||||
mock.patch('zerver.decorator.get_subdomain', return_value='acme'):
|
mock.patch('zerver.decorator.get_subdomain', return_value='acme'):
|
||||||
self.assert_json_error_contains(self._do_test(user),
|
self.assert_json_error_contains(self._do_test(user),
|
||||||
"Account is not associated with this "
|
"Account is not associated with this subdomain")
|
||||||
"subdomain")
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
m.output,
|
m.output,
|
||||||
["WARNING:root:User {} ({}) attempted to access API on wrong subdomain ({})".format(email, 'zulip', 'acme'),
|
["WARNING:root:User {} ({}) attempted to access API on wrong subdomain ({})".format(email, 'zulip', 'acme'),
|
||||||
|
@ -1545,8 +1543,7 @@ class TestAuthenticatedJsonViewDecorator(ZulipTestCase):
|
||||||
with self.assertLogs(level="WARNING") as m, \
|
with self.assertLogs(level="WARNING") as m, \
|
||||||
mock.patch('zerver.decorator.get_subdomain', return_value=''):
|
mock.patch('zerver.decorator.get_subdomain', return_value=''):
|
||||||
self.assert_json_error_contains(self._do_test(email),
|
self.assert_json_error_contains(self._do_test(email),
|
||||||
"Account is not associated with this "
|
"Account is not associated with this subdomain")
|
||||||
"subdomain")
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
m.output,
|
m.output,
|
||||||
["WARNING:root:User {} ({}) attempted to access API on wrong subdomain ({})".format(email, "zulip", "")]
|
["WARNING:root:User {} ({}) attempted to access API on wrong subdomain ({})".format(email, "zulip", "")]
|
||||||
|
@ -1555,8 +1552,7 @@ class TestAuthenticatedJsonViewDecorator(ZulipTestCase):
|
||||||
with self.assertLogs(level="WARNING") as m, \
|
with self.assertLogs(level="WARNING") as m, \
|
||||||
mock.patch('zerver.decorator.get_subdomain', return_value='acme'):
|
mock.patch('zerver.decorator.get_subdomain', return_value='acme'):
|
||||||
self.assert_json_error_contains(self._do_test(email),
|
self.assert_json_error_contains(self._do_test(email),
|
||||||
"Account is not associated with this "
|
"Account is not associated with this subdomain")
|
||||||
"subdomain")
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
m.output,
|
m.output,
|
||||||
["WARNING:root:User {} ({}) attempted to access API on wrong subdomain ({})".format(email, "zulip", "acme")]
|
["WARNING:root:User {} ({}) attempted to access API on wrong subdomain ({})".format(email, "zulip", "acme")]
|
||||||
|
|
|
@ -490,8 +490,7 @@ class PrivacyTermsTest(ZulipTestCase):
|
||||||
response)
|
response)
|
||||||
|
|
||||||
def test_custom_terms_of_service_template(self) -> None:
|
def test_custom_terms_of_service_template(self) -> None:
|
||||||
not_configured_message = 'This installation of Zulip does not have a configured ' \
|
not_configured_message = 'This installation of Zulip does not have a configured terms of service'
|
||||||
'terms of service'
|
|
||||||
with self.settings(TERMS_OF_SERVICE=None):
|
with self.settings(TERMS_OF_SERVICE=None):
|
||||||
response = self.client_get('/terms/')
|
response = self.client_get('/terms/')
|
||||||
self.assert_in_success_response([not_configured_message], response)
|
self.assert_in_success_response([not_configured_message], response)
|
||||||
|
@ -501,8 +500,7 @@ class PrivacyTermsTest(ZulipTestCase):
|
||||||
self.assert_not_in_success_response([not_configured_message], response)
|
self.assert_not_in_success_response([not_configured_message], response)
|
||||||
|
|
||||||
def test_custom_privacy_policy_template(self) -> None:
|
def test_custom_privacy_policy_template(self) -> None:
|
||||||
not_configured_message = 'This installation of Zulip does not have a configured ' \
|
not_configured_message = 'This installation of Zulip does not have a configured privacy policy'
|
||||||
'privacy policy'
|
|
||||||
with self.settings(PRIVACY_POLICY=None):
|
with self.settings(PRIVACY_POLICY=None):
|
||||||
response = self.client_get('/privacy/')
|
response = self.client_get('/privacy/')
|
||||||
self.assert_in_success_response([not_configured_message], response)
|
self.assert_in_success_response([not_configured_message], response)
|
||||||
|
|
|
@ -1009,8 +1009,7 @@ class MarkdownTest(ZulipTestCase):
|
||||||
realm_filter.save()
|
realm_filter.save()
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
realm_filter.__str__(),
|
realm_filter.__str__(),
|
||||||
'<RealmFilter(zulip): #(?P<id>[0-9]{2,8})'
|
'<RealmFilter(zulip): #(?P<id>[0-9]{2,8}) https://trac.example.com/ticket/%(id)s>')
|
||||||
' https://trac.example.com/ticket/%(id)s>')
|
|
||||||
|
|
||||||
msg = Message(sender=self.example_user('othello'))
|
msg = Message(sender=self.example_user('othello'))
|
||||||
msg.set_topic_name("#444")
|
msg.set_topic_name("#444")
|
||||||
|
@ -1679,8 +1678,7 @@ class MarkdownTest(ZulipTestCase):
|
||||||
realm_filter.save()
|
realm_filter.save()
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
realm_filter.__str__(),
|
realm_filter.__str__(),
|
||||||
'<RealmFilter(zulip): #(?P<id>[0-9]{2,8})'
|
'<RealmFilter(zulip): #(?P<id>[0-9]{2,8}) https://trac.example.com/ticket/%(id)s>')
|
||||||
' https://trac.example.com/ticket/%(id)s>')
|
|
||||||
# Create a user that potentially interferes with the pattern.
|
# Create a user that potentially interferes with the pattern.
|
||||||
test_user = create_user(
|
test_user = create_user(
|
||||||
email='atomic@example.com',
|
email='atomic@example.com',
|
||||||
|
@ -1736,8 +1734,7 @@ class MarkdownTest(ZulipTestCase):
|
||||||
realm_filter.save()
|
realm_filter.save()
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
realm_filter.__str__(),
|
realm_filter.__str__(),
|
||||||
'<RealmFilter(zulip): #(?P<id>[0-9]{2,8})'
|
'<RealmFilter(zulip): #(?P<id>[0-9]{2,8}) https://trac.example.com/ticket/%(id)s>')
|
||||||
' https://trac.example.com/ticket/%(id)s>')
|
|
||||||
# Create a user-group that potentially interferes with the pattern.
|
# Create a user-group that potentially interferes with the pattern.
|
||||||
user_id = user_profile.id
|
user_id = user_profile.id
|
||||||
user_group = self.create_user_group_for_test('support #123')
|
user_group = self.create_user_group_for_test('support #123')
|
||||||
|
@ -1908,8 +1905,7 @@ class MarkdownTest(ZulipTestCase):
|
||||||
realm_filter.save()
|
realm_filter.save()
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
realm_filter.__str__(),
|
realm_filter.__str__(),
|
||||||
'<RealmFilter(zulip): #(?P<id>[0-9]{2,8})'
|
'<RealmFilter(zulip): #(?P<id>[0-9]{2,8}) https://trac.example.com/ticket/%(id)s>')
|
||||||
' https://trac.example.com/ticket/%(id)s>')
|
|
||||||
# Create a topic link that potentially interferes with the pattern.
|
# Create a topic link that potentially interferes with the pattern.
|
||||||
denmark = get_stream('Denmark', realm)
|
denmark = get_stream('Denmark', realm)
|
||||||
msg = Message(sender=sender_user_profile, sending_client=get_client("test"))
|
msg = Message(sender=sender_user_profile, sending_client=get_client("test"))
|
||||||
|
@ -1974,8 +1970,7 @@ class MarkdownTest(ZulipTestCase):
|
||||||
realm_filter.save()
|
realm_filter.save()
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
realm_filter.__str__(),
|
realm_filter.__str__(),
|
||||||
'<RealmFilter(zulip): #(?P<id>[0-9]{2,8})'
|
'<RealmFilter(zulip): #(?P<id>[0-9]{2,8}) https://trac.example.com/ticket/%(id)s>')
|
||||||
' https://trac.example.com/ticket/%(id)s>')
|
|
||||||
# Create a stream that potentially interferes with the pattern.
|
# Create a stream that potentially interferes with the pattern.
|
||||||
stream = Stream.objects.create(name='Stream #1234', realm=realm)
|
stream = Stream.objects.create(name='Stream #1234', realm=realm)
|
||||||
msg = Message(sender=sender_user_profile, sending_client=get_client("test"))
|
msg = Message(sender=sender_user_profile, sending_client=get_client("test"))
|
||||||
|
|
|
@ -256,8 +256,7 @@ class MessageDictTest(ZulipTestCase):
|
||||||
url_format_string=url_format_string)
|
url_format_string=url_format_string)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
realm_filter.__str__(),
|
realm_filter.__str__(),
|
||||||
'<RealmFilter(zulip): #(?P<id>[0-9]{2,8})'
|
'<RealmFilter(zulip): #(?P<id>[0-9]{2,8}) https://trac.example.com/ticket/%(id)s>')
|
||||||
' https://trac.example.com/ticket/%(id)s>')
|
|
||||||
|
|
||||||
def get_message(sender: UserProfile) -> Message:
|
def get_message(sender: UserProfile) -> Message:
|
||||||
msg_id = self.send_stream_message(sender, 'Denmark', 'hello world', topic_name,
|
msg_id = self.send_stream_message(sender, 'Denmark', 'hello world', topic_name,
|
||||||
|
|
|
@ -293,9 +293,7 @@ class EditMessageTest(ZulipTestCase):
|
||||||
self.example_user("hamlet"),
|
self.example_user("hamlet"),
|
||||||
"Scotland",
|
"Scotland",
|
||||||
topic_name="editing",
|
topic_name="editing",
|
||||||
content=('content before edit, line 1\n'
|
content='content before edit, line 1\n\ncontent before edit, line 3')
|
||||||
'\n'
|
|
||||||
'content before edit, line 3'))
|
|
||||||
new_content_2 = ('content before edit, line 1\n'
|
new_content_2 = ('content before edit, line 1\n'
|
||||||
'content after edit, line 2\n'
|
'content after edit, line 2\n'
|
||||||
'content before edit, line 3')
|
'content before edit, line 3')
|
||||||
|
@ -310,8 +308,7 @@ class EditMessageTest(ZulipTestCase):
|
||||||
message_history_2 = json_response_2['message_history']
|
message_history_2 = json_response_2['message_history']
|
||||||
|
|
||||||
self.assertEqual(message_history_2[0]['rendered_content'],
|
self.assertEqual(message_history_2[0]['rendered_content'],
|
||||||
('<p>content before edit, line 1</p>\n'
|
'<p>content before edit, line 1</p>\n<p>content before edit, line 3</p>')
|
||||||
'<p>content before edit, line 3</p>'))
|
|
||||||
self.assertEqual(message_history_2[1]['rendered_content'],
|
self.assertEqual(message_history_2[1]['rendered_content'],
|
||||||
('<p>content before edit, line 1<br>\n'
|
('<p>content before edit, line 1<br>\n'
|
||||||
'content after edit, line 2<br>\n'
|
'content after edit, line 2<br>\n'
|
||||||
|
@ -321,8 +318,7 @@ class EditMessageTest(ZulipTestCase):
|
||||||
'content <span class="highlight_text_inserted">after edit, line 2<br> '
|
'content <span class="highlight_text_inserted">after edit, line 2<br> '
|
||||||
'content</span> before edit, line 3</p>'))
|
'content</span> before edit, line 3</p>'))
|
||||||
self.assertEqual(message_history_2[1]['prev_rendered_content'],
|
self.assertEqual(message_history_2[1]['prev_rendered_content'],
|
||||||
('<p>content before edit, line 1</p>\n'
|
'<p>content before edit, line 1</p>\n<p>content before edit, line 3</p>')
|
||||||
'<p>content before edit, line 3</p>'))
|
|
||||||
|
|
||||||
def test_edit_link(self) -> None:
|
def test_edit_link(self) -> None:
|
||||||
# Link editing
|
# Link editing
|
||||||
|
|
|
@ -3248,9 +3248,9 @@ class MessageHasKeywordsTest(ZulipTestCase):
|
||||||
|
|
||||||
# This message should claim attachments 1 only because attachment 2
|
# This message should claim attachments 1 only because attachment 2
|
||||||
# is not being parsed as a link by Markdown.
|
# is not being parsed as a link by Markdown.
|
||||||
body = ("Some files here ...[zulip.txt]({})" +
|
body = (f"Some files here ...[zulip.txt]({dummy_urls[0]})"
|
||||||
"{}.... Some more...." +
|
f"{dummy_urls[1]}.... Some more...."
|
||||||
"{}").format(dummy_urls[0], dummy_urls[1], dummy_urls[1])
|
f"{dummy_urls[1]}")
|
||||||
self.send_stream_message(user_profile, "Denmark", body, "test")
|
self.send_stream_message(user_profile, "Denmark", body, "test")
|
||||||
assert_attachment_claimed(dummy_path_ids[0], True)
|
assert_attachment_claimed(dummy_path_ids[0], True)
|
||||||
assert_attachment_claimed(dummy_path_ids[1], False)
|
assert_attachment_claimed(dummy_path_ids[1], False)
|
||||||
|
|
|
@ -123,12 +123,9 @@ class TestBrowserAndOsUserAgentStrings(ZulipTestCase):
|
||||||
'Chrome/54.0.2840.59 Safari/537.36', 'Chrome', 'Linux'),
|
'Chrome/54.0.2840.59 Safari/537.36', 'Chrome', 'Linux'),
|
||||||
('mozilla/5.0 (windows nt 6.1; win64; x64) applewebkit/537.36 (khtml, like gecko) ' +
|
('mozilla/5.0 (windows nt 6.1; win64; x64) applewebkit/537.36 (khtml, like gecko) ' +
|
||||||
'chrome/56.0.2924.87 safari/537.36', 'Chrome', 'Windows'),
|
'chrome/56.0.2924.87 safari/537.36', 'Chrome', 'Windows'),
|
||||||
('mozilla/5.0 (windows nt 6.1; wow64; rv:51.0) ' +
|
('mozilla/5.0 (windows nt 6.1; wow64; rv:51.0) gecko/20100101 firefox/51.0', 'Firefox', 'Windows'),
|
||||||
'gecko/20100101 firefox/51.0', 'Firefox', 'Windows'),
|
('mozilla/5.0 (windows nt 6.1; wow64; trident/7.0; rv:11.0) like gecko', 'Internet Explorer', 'Windows'),
|
||||||
('mozilla/5.0 (windows nt 6.1; wow64; trident/7.0; rv:11.0) ' +
|
('Mozilla/5.0 (Android; Mobile; rv:27.0) Gecko/27.0 Firefox/27.0', 'Firefox', 'Android'),
|
||||||
'like gecko', 'Internet Explorer', 'Windows'),
|
|
||||||
('Mozilla/5.0 (Android; Mobile; rv:27.0) ' +
|
|
||||||
'Gecko/27.0 Firefox/27.0', 'Firefox', 'Android'),
|
|
||||||
('Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X) '
|
('Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X) '
|
||||||
'AppleWebKit/602.1.50 (KHTML, like Gecko) '
|
'AppleWebKit/602.1.50 (KHTML, like Gecko) '
|
||||||
'CriOS/56.0.2924.75 Mobile/14E5239e Safari/602.1', 'Chrome', 'iOS'),
|
'CriOS/56.0.2924.75 Mobile/14E5239e Safari/602.1', 'Chrome', 'iOS'),
|
||||||
|
|
|
@ -102,8 +102,7 @@ class OpenAPIToolsTest(ZulipTestCase):
|
||||||
|
|
||||||
def test_validate_against_openapi_schema(self) -> None:
|
def test_validate_against_openapi_schema(self) -> None:
|
||||||
with self.assertRaises(ValidationError,
|
with self.assertRaises(ValidationError,
|
||||||
msg=("Additional properties are not" +
|
msg="Additional properties are not allowed ('foo' was unexpected)"):
|
||||||
" allowed ('foo' was unexpected)")):
|
|
||||||
bad_content: Dict[str, object] = {
|
bad_content: Dict[str, object] = {
|
||||||
'msg': '',
|
'msg': '',
|
||||||
'result': 'success',
|
'result': 'success',
|
||||||
|
|
|
@ -923,8 +923,7 @@ class HandlePushNotificationTest(PushNotificationTest):
|
||||||
return_value={'apns': True}), \
|
return_value={'apns': True}), \
|
||||||
mock.patch('zerver.lib.push_notifications.get_message_payload_gcm',
|
mock.patch('zerver.lib.push_notifications.get_message_payload_gcm',
|
||||||
return_value=({'gcm': True}, {})), \
|
return_value=({'gcm': True}, {})), \
|
||||||
mock.patch('zerver.lib.push_notifications'
|
mock.patch('zerver.lib.push_notifications.send_notifications_to_bouncer') as mock_send:
|
||||||
'.send_notifications_to_bouncer') as mock_send:
|
|
||||||
handle_push_notification(user_profile.id, missed_message)
|
handle_push_notification(user_profile.id, missed_message)
|
||||||
mock_send.assert_called_with(user_profile.id,
|
mock_send.assert_called_with(user_profile.id,
|
||||||
{'apns': True},
|
{'apns': True},
|
||||||
|
@ -957,10 +956,8 @@ class HandlePushNotificationTest(PushNotificationTest):
|
||||||
return_value={'apns': True}), \
|
return_value={'apns': True}), \
|
||||||
mock.patch('zerver.lib.push_notifications.get_message_payload_gcm',
|
mock.patch('zerver.lib.push_notifications.get_message_payload_gcm',
|
||||||
return_value=({'gcm': True}, {})), \
|
return_value=({'gcm': True}, {})), \
|
||||||
mock.patch('zerver.lib.push_notifications'
|
mock.patch('zerver.lib.push_notifications.send_apple_push_notification') as mock_send_apple, \
|
||||||
'.send_apple_push_notification') as mock_send_apple, \
|
mock.patch('zerver.lib.push_notifications.send_android_push_notification') as mock_send_android, \
|
||||||
mock.patch('zerver.lib.push_notifications'
|
|
||||||
'.send_android_push_notification') as mock_send_android, \
|
|
||||||
mock.patch('zerver.lib.push_notifications.push_notifications_enabled', return_value = True) as mock_push_notifications:
|
mock.patch('zerver.lib.push_notifications.push_notifications_enabled', return_value = True) as mock_push_notifications:
|
||||||
|
|
||||||
handle_push_notification(self.user_profile.id, missed_message)
|
handle_push_notification(self.user_profile.id, missed_message)
|
||||||
|
@ -980,8 +977,7 @@ class HandlePushNotificationTest(PushNotificationTest):
|
||||||
)
|
)
|
||||||
|
|
||||||
with self.settings(PUSH_NOTIFICATION_BOUNCER_URL=True), \
|
with self.settings(PUSH_NOTIFICATION_BOUNCER_URL=True), \
|
||||||
mock.patch('zerver.lib.push_notifications'
|
mock.patch('zerver.lib.push_notifications.send_notifications_to_bouncer') as mock_send:
|
||||||
'.send_notifications_to_bouncer') as mock_send:
|
|
||||||
handle_remove_push_notification(user_profile.id, [message.id])
|
handle_remove_push_notification(user_profile.id, [message.id])
|
||||||
mock_send.assert_called_with(
|
mock_send.assert_called_with(
|
||||||
user_profile.id,
|
user_profile.id,
|
||||||
|
@ -1030,10 +1026,8 @@ class HandlePushNotificationTest(PushNotificationTest):
|
||||||
PushDeviceToken.objects.filter(user=self.user_profile,
|
PushDeviceToken.objects.filter(user=self.user_profile,
|
||||||
kind=PushDeviceToken.APNS))
|
kind=PushDeviceToken.APNS))
|
||||||
|
|
||||||
with mock.patch('zerver.lib.push_notifications'
|
with mock.patch('zerver.lib.push_notifications.send_android_push_notification') as mock_send_android, \
|
||||||
'.send_android_push_notification') as mock_send_android, \
|
mock.patch('zerver.lib.push_notifications.send_apple_push_notification') as mock_send_apple:
|
||||||
mock.patch('zerver.lib.push_notifications'
|
|
||||||
'.send_apple_push_notification') as mock_send_apple:
|
|
||||||
handle_remove_push_notification(self.user_profile.id, [message.id])
|
handle_remove_push_notification(self.user_profile.id, [message.id])
|
||||||
mock_send_android.assert_called_with(
|
mock_send_android.assert_called_with(
|
||||||
android_devices,
|
android_devices,
|
||||||
|
@ -1116,10 +1110,8 @@ class HandlePushNotificationTest(PushNotificationTest):
|
||||||
return_value={'apns': True}), \
|
return_value={'apns': True}), \
|
||||||
mock.patch('zerver.lib.push_notifications.get_message_payload_gcm',
|
mock.patch('zerver.lib.push_notifications.get_message_payload_gcm',
|
||||||
return_value=({'gcm': True}, {})), \
|
return_value=({'gcm': True}, {})), \
|
||||||
mock.patch('zerver.lib.push_notifications'
|
mock.patch('zerver.lib.push_notifications.send_apple_push_notification') as mock_send_apple, \
|
||||||
'.send_apple_push_notification') as mock_send_apple, \
|
mock.patch('zerver.lib.push_notifications.send_android_push_notification') as mock_send_android, \
|
||||||
mock.patch('zerver.lib.push_notifications'
|
|
||||||
'.send_android_push_notification') as mock_send_android, \
|
|
||||||
mock.patch('zerver.lib.push_notifications.logger.error') as mock_logger, \
|
mock.patch('zerver.lib.push_notifications.logger.error') as mock_logger, \
|
||||||
mock.patch('zerver.lib.push_notifications.push_notifications_enabled', return_value = True) as mock_push_notifications:
|
mock.patch('zerver.lib.push_notifications.push_notifications_enabled', return_value = True) as mock_push_notifications:
|
||||||
handle_push_notification(self.user_profile.id, missed_message)
|
handle_push_notification(self.user_profile.id, missed_message)
|
||||||
|
@ -1914,9 +1906,7 @@ class GCMSendTest(PushNotificationTest):
|
||||||
|
|
||||||
data = self.get_gcm_data()
|
data = self.get_gcm_data()
|
||||||
send_android_push_notification_to_user(self.user_profile, data, {})
|
send_android_push_notification_to_user(self.user_profile, data, {})
|
||||||
msg = ("GCM: Got canonical ref %s "
|
msg = "GCM: Got canonical ref %s replacing %s but new ID not registered! Updating."
|
||||||
"replacing %s but new ID not "
|
|
||||||
"registered! Updating.")
|
|
||||||
mock_warning.assert_called_once_with(msg, t2, t1)
|
mock_warning.assert_called_once_with(msg, t2, t1)
|
||||||
|
|
||||||
self.assertEqual(get_count('1111'), 0)
|
self.assertEqual(get_count('1111'), 0)
|
||||||
|
|
|
@ -646,9 +646,7 @@ class DefaultEmojiReactionTests(EmojiReactionBase):
|
||||||
|
|
||||||
def test_delete_insufficient_arguments_reaction(self) -> None:
|
def test_delete_insufficient_arguments_reaction(self) -> None:
|
||||||
result = self.delete_reaction({})
|
result = self.delete_reaction({})
|
||||||
self.assert_json_error(result, 'At least one of the following '
|
self.assert_json_error(result, 'At least one of the following arguments must be present: emoji_name, emoji_code')
|
||||||
'arguments must be present: emoji_name, '
|
|
||||||
'emoji_code')
|
|
||||||
|
|
||||||
def test_delete_non_existing_emoji_reaction(self) -> None:
|
def test_delete_non_existing_emoji_reaction(self) -> None:
|
||||||
reaction_info = {
|
reaction_info = {
|
||||||
|
|
|
@ -217,8 +217,7 @@ class TestServiceBotStateHandler(ZulipTestCase):
|
||||||
key = 'capacity-filling entry'
|
key = 'capacity-filling entry'
|
||||||
storage.put(key, 'x' * (settings.USER_STATE_SIZE_LIMIT - len(key)))
|
storage.put(key, 'x' * (settings.USER_STATE_SIZE_LIMIT - len(key)))
|
||||||
|
|
||||||
with self.assertRaisesMessage(StateError, "Request exceeds storage limit by 32 characters. "
|
with self.assertRaisesMessage(StateError, "Request exceeds storage limit by 32 characters. The limit is 100 characters."):
|
||||||
"The limit is 100 characters."):
|
|
||||||
storage.put('too much data', 'a few bits too long')
|
storage.put('too much data', 'a few bits too long')
|
||||||
|
|
||||||
second_storage = StateHandler(self.second_bot_profile)
|
second_storage = StateHandler(self.second_bot_profile)
|
||||||
|
|
|
@ -1603,8 +1603,7 @@ so we didn't send them an invitation. We did send invitations to everyone else!"
|
||||||
email_change_key = email_change_url.split('/')[-1]
|
email_change_key = email_change_url.split('/')[-1]
|
||||||
url = '/accounts/do_confirm/' + email_change_key
|
url = '/accounts/do_confirm/' + email_change_key
|
||||||
result = self.client_get(url)
|
result = self.client_get(url)
|
||||||
self.assert_in_success_response(["Whoops. We couldn't find your "
|
self.assert_in_success_response(["Whoops. We couldn't find your confirmation link in the system."], result)
|
||||||
"confirmation link in the system."], result)
|
|
||||||
|
|
||||||
def test_confirmation_expired(self) -> None:
|
def test_confirmation_expired(self) -> None:
|
||||||
email = self.nonreg_email("alice")
|
email = self.nonreg_email("alice")
|
||||||
|
@ -1621,8 +1620,7 @@ so we didn't send them an invitation. We did send invitations to everyone else!"
|
||||||
|
|
||||||
target_url = '/' + url.split('/', 3)[3]
|
target_url = '/' + url.split('/', 3)[3]
|
||||||
result = self.client_get(target_url)
|
result = self.client_get(target_url)
|
||||||
self.assert_in_success_response(["Whoops. The confirmation link has expired "
|
self.assert_in_success_response(["Whoops. The confirmation link has expired or been deactivated."], result)
|
||||||
"or been deactivated."], result)
|
|
||||||
|
|
||||||
def test_send_more_than_one_invite_to_same_user(self) -> None:
|
def test_send_more_than_one_invite_to_same_user(self) -> None:
|
||||||
self.user_profile = self.example_user('iago')
|
self.user_profile = self.example_user('iago')
|
||||||
|
@ -3281,8 +3279,7 @@ class UserSignUpTest(InviteUserBase):
|
||||||
def test_failed_signup_due_to_nonexistent_realm(self) -> None:
|
def test_failed_signup_due_to_nonexistent_realm(self) -> None:
|
||||||
email = 'user@acme.com'
|
email = 'user@acme.com'
|
||||||
form = HomepageForm({'email': email}, realm=None)
|
form = HomepageForm({'email': email}, realm=None)
|
||||||
self.assertIn("organization you are trying to join using {} does "
|
self.assertIn(f"organization you are trying to join using {email} does not exist", form.errors['email'][0])
|
||||||
"not exist".format(email), form.errors['email'][0])
|
|
||||||
|
|
||||||
def test_access_signup_page_in_root_domain_without_realm(self) -> None:
|
def test_access_signup_page_in_root_domain_without_realm(self) -> None:
|
||||||
result = self.client_get('/register', subdomain="", follow=True)
|
result = self.client_get('/register', subdomain="", follow=True)
|
||||||
|
|
|
@ -26,8 +26,7 @@ def create_realm_domain(request: HttpRequest, user_profile: UserProfile,
|
||||||
except ValidationError as e:
|
except ValidationError as e:
|
||||||
return json_error(_('Invalid domain: {}').format(e.messages[0]))
|
return json_error(_('Invalid domain: {}').format(e.messages[0]))
|
||||||
if RealmDomain.objects.filter(realm=user_profile.realm, domain=domain).exists():
|
if RealmDomain.objects.filter(realm=user_profile.realm, domain=domain).exists():
|
||||||
return json_error(_("The domain {domain} is already"
|
return json_error(_("The domain {domain} is already a part of your organization.").format(domain=domain))
|
||||||
" a part of your organization.").format(domain=domain))
|
|
||||||
realm_domain = do_add_realm_domain(user_profile.realm, domain, allow_subdomains)
|
realm_domain = do_add_realm_domain(user_profile.realm, domain, allow_subdomains)
|
||||||
return json_success({'new_domain': [realm_domain.id, realm_domain.domain]})
|
return json_success({'new_domain': [realm_domain.id, realm_domain.domain]})
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,7 @@ DOCUMENT_TEMPLATE = "{user_name} {verb} the document [{title}]({url})"
|
||||||
QUESTION_TEMPLATE = "{user_name} {verb} the question [{title}]({url})"
|
QUESTION_TEMPLATE = "{user_name} {verb} the question [{title}]({url})"
|
||||||
QUESTIONS_ANSWER_TEMPLATE = ("{user_name} {verb} the [answer]({answer_url}) " +
|
QUESTIONS_ANSWER_TEMPLATE = ("{user_name} {verb} the [answer]({answer_url}) " +
|
||||||
"of the question [{question_title}]({question_url})")
|
"of the question [{question_title}]({question_url})")
|
||||||
COMMENT_TEMPLATE = ("{user_name} {verb} the [comment]({answer_url}) "
|
COMMENT_TEMPLATE = "{user_name} {verb} the [comment]({answer_url}) of the task [{task_title}]({task_url})"
|
||||||
"of the task [{task_title}]({task_url})")
|
|
||||||
MESSAGE_TEMPLATE = "{user_name} {verb} the message [{title}]({url})"
|
MESSAGE_TEMPLATE = "{user_name} {verb} the message [{title}]({url})"
|
||||||
TODO_LIST_TEMPLATE = "{user_name} {verb} the todo list [{title}]({url})"
|
TODO_LIST_TEMPLATE = "{user_name} {verb} the todo list [{title}]({url})"
|
||||||
TODO_TEMPLATE = "{user_name} {verb} the todo task [{title}]({url})"
|
TODO_TEMPLATE = "{user_name} {verb} the todo task [{title}]({url})"
|
||||||
|
|
|
@ -31,10 +31,8 @@ from zerver.models import UserProfile
|
||||||
BITBUCKET_TOPIC_TEMPLATE = '{repository_name}'
|
BITBUCKET_TOPIC_TEMPLATE = '{repository_name}'
|
||||||
|
|
||||||
BITBUCKET_FORK_BODY = "{actor} forked the repository into [{fork_name}]({fork_url})."
|
BITBUCKET_FORK_BODY = "{actor} forked the repository into [{fork_name}]({fork_url})."
|
||||||
BITBUCKET_COMMIT_STATUS_CHANGED_BODY = ('[System {key}]({system_url}) changed status of'
|
BITBUCKET_COMMIT_STATUS_CHANGED_BODY = '[System {key}]({system_url}) changed status of {commit_info} to {status}.'
|
||||||
' {commit_info} to {status}.')
|
BITBUCKET_REPO_UPDATED_CHANGED = '{actor} changed the {change} of the **{repo_name}** repo from **{old}** to **{new}**'
|
||||||
BITBUCKET_REPO_UPDATED_CHANGED = ('{actor} changed the {change} of the **{repo_name}**'
|
|
||||||
' repo from **{old}** to **{new}**')
|
|
||||||
BITBUCKET_REPO_UPDATED_ADDED = '{actor} changed the {change} of the **{repo_name}** repo to **{new}**'
|
BITBUCKET_REPO_UPDATED_ADDED = '{actor} changed the {change} of the **{repo_name}** repo to **{new}**'
|
||||||
|
|
||||||
PULL_REQUEST_SUPPORTED_ACTIONS = [
|
PULL_REQUEST_SUPPORTED_ACTIONS = [
|
||||||
|
|
|
@ -23,23 +23,17 @@ NAME_CHANGED_TEMPLATE = ("The name of the {entity} {name_template} was changed f
|
||||||
ARCHIVED_TEMPLATE = "The {entity} {name_template} was {action}."
|
ARCHIVED_TEMPLATE = "The {entity} {name_template} was {action}."
|
||||||
STORY_TASK_TEMPLATE = "Task **{task_description}** was {action} the story {name_template}."
|
STORY_TASK_TEMPLATE = "Task **{task_description}** was {action} the story {name_template}."
|
||||||
STORY_TASK_COMPLETED_TEMPLATE = "Task **{task_description}** ({name_template}) was completed. :tada:"
|
STORY_TASK_COMPLETED_TEMPLATE = "Task **{task_description}** ({name_template}) was completed. :tada:"
|
||||||
STORY_ADDED_REMOVED_EPIC_TEMPLATE = ("The story {story_name_template} was {action} the"
|
STORY_ADDED_REMOVED_EPIC_TEMPLATE = "The story {story_name_template} was {action} the epic {epic_name_template}."
|
||||||
" epic {epic_name_template}.")
|
STORY_EPIC_CHANGED_TEMPLATE = "The story {story_name_template} was moved from {old_epic_name_template} to {new_epic_name_template}."
|
||||||
STORY_EPIC_CHANGED_TEMPLATE = ("The story {story_name_template} was moved from {old_epic_name_template}"
|
|
||||||
" to {new_epic_name_template}.")
|
|
||||||
STORY_ESTIMATE_TEMPLATE = "The estimate for the story {story_name_template} was set to {estimate}."
|
STORY_ESTIMATE_TEMPLATE = "The estimate for the story {story_name_template} was set to {estimate}."
|
||||||
FILE_ATTACHMENT_TEMPLATE = "A {type} attachment `{file_name}` was added to the story {name_template}."
|
FILE_ATTACHMENT_TEMPLATE = "A {type} attachment `{file_name}` was added to the story {name_template}."
|
||||||
STORY_LABEL_TEMPLATE = "The label **{label_name}** was added to the story {name_template}."
|
STORY_LABEL_TEMPLATE = "The label **{label_name}** was added to the story {name_template}."
|
||||||
STORY_UPDATE_PROJECT_TEMPLATE = ("The story {name_template} was moved from"
|
STORY_UPDATE_PROJECT_TEMPLATE = "The story {name_template} was moved from the **{old}** project to **{new}**."
|
||||||
" the **{old}** project to **{new}**.")
|
STORY_UPDATE_TYPE_TEMPLATE = "The type of the story {name_template} was changed from **{old_type}** to **{new_type}**."
|
||||||
STORY_UPDATE_TYPE_TEMPLATE = ("The type of the story {name_template} was changed"
|
|
||||||
" from **{old_type}** to **{new_type}**.")
|
|
||||||
DELETE_TEMPLATE = "The {entity_type} **{name}** was deleted."
|
DELETE_TEMPLATE = "The {entity_type} **{name}** was deleted."
|
||||||
STORY_UPDATE_OWNER_TEMPLATE = "New owner added to the story {name_template}."
|
STORY_UPDATE_OWNER_TEMPLATE = "New owner added to the story {name_template}."
|
||||||
STORY_GITHUB_PR_TEMPLATE = ("New GitHub PR [#{name}]({url}) opened for story"
|
STORY_GITHUB_PR_TEMPLATE = "New GitHub PR [#{name}]({url}) opened for story {name_template} ({old} -> {new})."
|
||||||
" {name_template} ({old} -> {new}).")
|
STORY_GITHUB_BRANCH_TEMPLATE = "New GitHub branch [{name}]({url}) associated with story {name_template} ({old} -> {new})."
|
||||||
STORY_GITHUB_BRANCH_TEMPLATE = ("New GitHub branch [{name}]({url})"
|
|
||||||
" associated with story {name_template} ({old} -> {new}).")
|
|
||||||
|
|
||||||
|
|
||||||
def get_action_with_primary_id(payload: Dict[str, Any]) -> Dict[str, Any]:
|
def get_action_with_primary_id(payload: Dict[str, Any]) -> Dict[str, Any]:
|
||||||
|
|
|
@ -180,8 +180,7 @@ class FrontHookTests(WebhookTestCase):
|
||||||
|
|
||||||
def test_comment(self) -> None:
|
def test_comment(self) -> None:
|
||||||
expected_topic = 'cnv_keocka'
|
expected_topic = 'cnv_keocka'
|
||||||
expected_message = "**Bender Rodriguez** left a comment:\n" \
|
expected_message = "**Bender Rodriguez** left a comment:\n```quote\nSure.\n```"
|
||||||
"```quote\nSure.\n```"
|
|
||||||
|
|
||||||
self.check_webhook(
|
self.check_webhook(
|
||||||
"comment",
|
"comment",
|
||||||
|
|
|
@ -414,8 +414,7 @@ def get_pull_request_review_requested_body(helper: Helper) -> str:
|
||||||
pr_number = payload['pull_request']['number']
|
pr_number = payload['pull_request']['number']
|
||||||
pr_url = payload['pull_request']['html_url']
|
pr_url = payload['pull_request']['html_url']
|
||||||
message = "**{sender}** requested {reviewers} for a review on [PR #{pr_number}]({pr_url})."
|
message = "**{sender}** requested {reviewers} for a review on [PR #{pr_number}]({pr_url})."
|
||||||
message_with_title = ("**{sender}** requested {reviewers} for a review on "
|
message_with_title = "**{sender}** requested {reviewers} for a review on [PR #{pr_number} {title}]({pr_url})."
|
||||||
"[PR #{pr_number} {title}]({pr_url}).")
|
|
||||||
body = message_with_title if include_title else message
|
body = message_with_title if include_title else message
|
||||||
|
|
||||||
all_reviewers = []
|
all_reviewers = []
|
||||||
|
|
|
@ -11,12 +11,11 @@ from zerver.lib.response import json_success
|
||||||
from zerver.lib.webhooks.common import check_send_webhook_message
|
from zerver.lib.webhooks.common import check_send_webhook_message
|
||||||
from zerver.models import UserProfile
|
from zerver.models import UserProfile
|
||||||
|
|
||||||
MESSAGE_TEMPLATE = (
|
MESSAGE_TEMPLATE = """\
|
||||||
'Author: {}\n'
|
Author: {}
|
||||||
'Build status: {} {}\n'
|
Build status: {} {}
|
||||||
'Details: [build log]({})\n'
|
Details: [build log]({})
|
||||||
'Comment: {}'
|
Comment: {}"""
|
||||||
)
|
|
||||||
|
|
||||||
@webhook_view('Gocd')
|
@webhook_view('Gocd')
|
||||||
@has_request_variables
|
@has_request_variables
|
||||||
|
|
|
@ -130,8 +130,7 @@ class LibratoWebhookHandler(LibratoWebhookParser):
|
||||||
condition: Dict[str, Any]) -> str:
|
condition: Dict[str, Any]) -> str:
|
||||||
summary_function, threshold, condition_type, duration = self.parse_condition(condition)
|
summary_function, threshold, condition_type, duration = self.parse_condition(condition)
|
||||||
metric_name, recorded_at = self.parse_violation(violation)
|
metric_name, recorded_at = self.parse_violation(violation)
|
||||||
metric_condition_template = ("\n * Metric `{metric_name}`, {summary_function} "
|
metric_condition_template = "\n * Metric `{metric_name}`, {summary_function} was {condition_type} {threshold}"
|
||||||
"was {condition_type} {threshold}")
|
|
||||||
content = metric_condition_template.format(
|
content = metric_condition_template.format(
|
||||||
metric_name=metric_name, summary_function=summary_function, condition_type=condition_type,
|
metric_name=metric_name, summary_function=summary_function, condition_type=condition_type,
|
||||||
threshold=threshold)
|
threshold=threshold)
|
||||||
|
|
|
@ -62,8 +62,7 @@ def body(message: Dict[str, Any]) -> str:
|
||||||
|
|
||||||
title = canary_kind(message).title()
|
title = canary_kind(message).title()
|
||||||
name = canary_name(message)
|
name = canary_name(message)
|
||||||
body = (f"**:alert: {title} *{name}* has been triggered!**\n\n"
|
body = f"**:alert: {title} *{name}* has been triggered!**\n\n{message['Intro']}\n\n"
|
||||||
f"{message['Intro']}\n\n")
|
|
||||||
|
|
||||||
if 'IncidentHash' in message:
|
if 'IncidentHash' in message:
|
||||||
body += f"**Incident Id:** `{message['IncidentHash']}`\n"
|
body += f"**Incident Id:** `{message['IncidentHash']}`\n"
|
||||||
|
|
|
@ -14,11 +14,10 @@ GOOD_STATUSES = ['Passed', 'Fixed']
|
||||||
BAD_STATUSES = ['Failed', 'Broken', 'Still Failing', 'Errored', 'Canceled']
|
BAD_STATUSES = ['Failed', 'Broken', 'Still Failing', 'Errored', 'Canceled']
|
||||||
PENDING_STATUSES = ['Pending']
|
PENDING_STATUSES = ['Pending']
|
||||||
|
|
||||||
MESSAGE_TEMPLATE = (
|
MESSAGE_TEMPLATE = """\
|
||||||
'Author: {}\n'
|
Author: {}
|
||||||
'Build status: {} {}\n'
|
Build status: {} {}
|
||||||
'Details: [changes]({}), [build log]({})'
|
Details: [changes]({}), [build log]({})"""
|
||||||
)
|
|
||||||
|
|
||||||
@webhook_view('Travis')
|
@webhook_view('Travis')
|
||||||
@has_request_variables
|
@has_request_variables
|
||||||
|
|
|
@ -635,8 +635,7 @@ class MirrorWorker(QueueProcessingWorker):
|
||||||
try:
|
try:
|
||||||
rate_limit_mirror_by_realm(recipient_realm)
|
rate_limit_mirror_by_realm(recipient_realm)
|
||||||
except RateLimited:
|
except RateLimited:
|
||||||
logger.warning("MirrorWorker: Rejecting an email from: %s "
|
logger.warning("MirrorWorker: Rejecting an email from: %s to realm: %s - rate limited.",
|
||||||
"to realm: %s - rate limited.",
|
|
||||||
msg['From'], recipient_realm.name)
|
msg['From'], recipient_realm.name)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
@ -987,8 +987,7 @@ class ExternalAuthResult:
|
||||||
data_dict = {}
|
data_dict = {}
|
||||||
|
|
||||||
if login_token is not None:
|
if login_token is not None:
|
||||||
assert (not data_dict) and (user_profile is None), ("Passing in data_dict or user_profile " +
|
assert (not data_dict) and (user_profile is None), "Passing in data_dict or user_profile with login_token is disallowed."
|
||||||
"with login_token is disallowed.")
|
|
||||||
self.instantiate_with_token(login_token, delete_stored_data)
|
self.instantiate_with_token(login_token, delete_stored_data)
|
||||||
else:
|
else:
|
||||||
self.data_dict = data_dict.copy()
|
self.data_dict = data_dict.copy()
|
||||||
|
|
Loading…
Reference in New Issue