mirror of https://github.com/zulip/zulip.git
python: Convert "".format to Python 3.6 f-strings.
Generated by pyupgrade --py36-plus --keep-percent-format, but with the
NamedTuple changes reverted (see commit
ba7906a3c6
, #15132).
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
parent
8c15081069
commit
8dd83228e7
|
@ -432,7 +432,7 @@ class TestSupportEndpoint(ZulipTestCase):
|
|||
|
||||
def check_preregistration_user_query_result(result: HttpResponse, email: str, invite: Optional[bool]=False) -> None:
|
||||
self.assert_in_success_response(['<span class="label">preregistration user</span>\n',
|
||||
'<b>Email</b>: {}'.format(email),
|
||||
f'<b>Email</b>: {email}',
|
||||
], result)
|
||||
if invite:
|
||||
self.assert_in_success_response(['<span class="label">invite</span>'], result)
|
||||
|
|
|
@ -1103,23 +1103,23 @@ def support(request: HttpRequest) -> HttpResponse:
|
|||
new_discount = Decimal(new_discount)
|
||||
current_discount = get_discount_for_realm(realm)
|
||||
attach_discount_to_realm(realm, new_discount)
|
||||
msg = "Discount of {} changed to {} from {} ".format(realm.name, new_discount, current_discount)
|
||||
msg = f"Discount of {realm.name} changed to {new_discount} from {current_discount} "
|
||||
context["message"] = msg
|
||||
|
||||
status = request.POST.get("status", None)
|
||||
if status is not None:
|
||||
if status == "active":
|
||||
do_send_realm_reactivation_email(realm)
|
||||
context["message"] = "Realm reactivation email sent to admins of {}.".format(realm.name)
|
||||
context["message"] = f"Realm reactivation email sent to admins of {realm.name}."
|
||||
elif status == "deactivated":
|
||||
do_deactivate_realm(realm, request.user)
|
||||
context["message"] = "{} deactivated.".format(realm.name)
|
||||
context["message"] = f"{realm.name} deactivated."
|
||||
|
||||
scrub_realm = request.POST.get("scrub_realm", None)
|
||||
if scrub_realm is not None:
|
||||
if scrub_realm == "scrub_realm":
|
||||
do_scrub_realm(realm)
|
||||
context["message"] = "{} scrubbed.".format(realm.name)
|
||||
context["message"] = f"{realm.name} scrubbed."
|
||||
|
||||
query = request.GET.get("q", None)
|
||||
if query:
|
||||
|
@ -1135,7 +1135,7 @@ def support(request: HttpRequest) -> HttpResponse:
|
|||
hostname = parse_result.hostname
|
||||
assert hostname is not None
|
||||
if parse_result.port:
|
||||
hostname = "{}:{}".format(hostname, parse_result.port)
|
||||
hostname = f"{hostname}:{parse_result.port}"
|
||||
subdomain = get_subdomain_from_hostname(hostname)
|
||||
try:
|
||||
realms.add(get_realm(subdomain))
|
||||
|
@ -1295,13 +1295,13 @@ def realm_activity_link(realm_str: str) -> mark_safe:
|
|||
def realm_stats_link(realm_str: str) -> mark_safe:
|
||||
url_name = 'analytics.views.stats_for_realm'
|
||||
url = reverse(url_name, kwargs=dict(realm_str=realm_str))
|
||||
stats_link = '<a href="{}"><i class="fa fa-pie-chart"></i>{}</a>'.format(url, realm_str)
|
||||
stats_link = f'<a href="{url}"><i class="fa fa-pie-chart"></i>{realm_str}</a>'
|
||||
return mark_safe(stats_link)
|
||||
|
||||
def remote_installation_stats_link(server_id: int, hostname: str) -> mark_safe:
|
||||
url_name = 'analytics.views.stats_for_remote_installation'
|
||||
url = reverse(url_name, kwargs=dict(remote_server_id=server_id))
|
||||
stats_link = '<a href="{}"><i class="fa fa-pie-chart"></i>{}</a>'.format(url, hostname)
|
||||
stats_link = f'<a href="{url}"><i class="fa fa-pie-chart"></i>{hostname}</a>'
|
||||
return mark_safe(stats_link)
|
||||
|
||||
def realm_client_table(user_summaries: Dict[str, Dict[str, Dict[str, Any]]]) -> str:
|
||||
|
|
|
@ -283,7 +283,7 @@ def compute_plan_parameters(
|
|||
price_per_license = 800
|
||||
period_end = add_months(billing_cycle_anchor, 1)
|
||||
else:
|
||||
raise AssertionError('Unknown billing_schedule: {}'.format(billing_schedule))
|
||||
raise AssertionError(f'Unknown billing_schedule: {billing_schedule}')
|
||||
if discount is not None:
|
||||
# There are no fractional cents in Stripe, so round down to nearest integer.
|
||||
price_per_license = int(float(price_per_license * (1 - discount / 100)) + .00001)
|
||||
|
@ -326,12 +326,12 @@ def process_initial_upgrade(user: UserProfile, licenses: int, automanage_license
|
|||
amount=price_per_license * licenses,
|
||||
currency='usd',
|
||||
customer=customer.stripe_customer_id,
|
||||
description="Upgrade to Zulip Standard, ${} x {}".format(price_per_license/100, licenses),
|
||||
description=f"Upgrade to Zulip Standard, ${price_per_license/100} x {licenses}",
|
||||
receipt_email=user.delivery_email,
|
||||
statement_descriptor='Zulip Standard')
|
||||
# Not setting a period start and end, but maybe we should? Unclear what will make things
|
||||
# most similar to the renewal case from an accounting perspective.
|
||||
description = "Payment (Card ending in {})".format(cast(stripe.Card, stripe_charge.source).last4)
|
||||
description = f"Payment (Card ending in {cast(stripe.Card, stripe_charge.source).last4})"
|
||||
stripe.InvoiceItem.create(
|
||||
amount=price_per_license * licenses * -1,
|
||||
currency='usd',
|
||||
|
@ -454,7 +454,7 @@ def invoice_plan(plan: CustomerPlan, event_time: datetime) -> None:
|
|||
plan.invoiced_through = ledger_entry
|
||||
plan.invoicing_status = CustomerPlan.STARTED
|
||||
plan.save(update_fields=['invoicing_status', 'invoiced_through'])
|
||||
idempotency_key: Optional[str] = 'ledger_entry:{}'.format(ledger_entry.id)
|
||||
idempotency_key: Optional[str] = f'ledger_entry:{ledger_entry.id}'
|
||||
if settings.TEST_SUITE:
|
||||
idempotency_key = None
|
||||
stripe.InvoiceItem.create(
|
||||
|
|
|
@ -71,7 +71,7 @@ def fixture_files_for_function(decorated_function: CallableT) -> List[str]: # n
|
|||
decorated_function_name = decorated_function.__name__
|
||||
if decorated_function_name[:5] == 'test_':
|
||||
decorated_function_name = decorated_function_name[5:]
|
||||
return sorted(['{}/{}'.format(STRIPE_FIXTURES_DIR, f) for f in os.listdir(STRIPE_FIXTURES_DIR)
|
||||
return sorted([f'{STRIPE_FIXTURES_DIR}/{f}' for f in os.listdir(STRIPE_FIXTURES_DIR)
|
||||
if f.startswith(decorated_function_name + '--')])
|
||||
|
||||
def generate_and_save_stripe_fixture(decorated_function_name: str, mocked_function_name: str,
|
||||
|
@ -174,7 +174,7 @@ def normalize_fixture_data(decorated_function: CallableT,
|
|||
with open(fixture_file, "w") as f:
|
||||
f.write(file_content)
|
||||
|
||||
MOCKED_STRIPE_FUNCTION_NAMES = ["stripe.{}".format(name) for name in [
|
||||
MOCKED_STRIPE_FUNCTION_NAMES = [f"stripe.{name}" for name in [
|
||||
"Charge.create", "Charge.list",
|
||||
"Coupon.create",
|
||||
"Customer.create", "Customer.retrieve", "Customer.save",
|
||||
|
@ -392,7 +392,7 @@ class StripeTest(StripeTestCase):
|
|||
self.assertEqual(stripe_charges[0].amount, 8000 * self.seat_count)
|
||||
# TODO: fix Decimal
|
||||
self.assertEqual(stripe_charges[0].description,
|
||||
"Upgrade to Zulip Standard, $80.0 x {}".format(self.seat_count))
|
||||
f"Upgrade to Zulip Standard, $80.0 x {self.seat_count}")
|
||||
self.assertEqual(stripe_charges[0].receipt_email, user.email)
|
||||
self.assertEqual(stripe_charges[0].statement_descriptor, "Zulip Standard")
|
||||
# Check Invoices in Stripe
|
||||
|
@ -775,7 +775,7 @@ class StripeTest(StripeTestCase):
|
|||
'Zulip Standard', 'Free Trial', str(self.seat_count),
|
||||
'You are using', '%s of %s licenses' % (self.seat_count, 123),
|
||||
'Your plan will be upgraded to', 'March 2, 2012',
|
||||
'{:,.2f}'.format(80 * 123), 'Billed by invoice'
|
||||
f'{80 * 123:,.2f}', 'Billed by invoice'
|
||||
]:
|
||||
self.assert_in_response(substring, response)
|
||||
|
||||
|
@ -983,13 +983,13 @@ class StripeTest(StripeTestCase):
|
|||
upgrade_params['licenses'] = licenses
|
||||
response = self.upgrade(invoice=invoice, talk_to_stripe=False,
|
||||
del_args=del_args, **upgrade_params)
|
||||
self.assert_json_error_contains(response, "at least {} users".format(min_licenses_in_response))
|
||||
self.assert_json_error_contains(response, f"at least {min_licenses_in_response} users")
|
||||
self.assertEqual(ujson.loads(response.content)['error_description'], 'not enough licenses')
|
||||
|
||||
def check_max_licenses_error(licenses: int) -> None:
|
||||
response = self.upgrade(invoice=True, talk_to_stripe=False,
|
||||
licenses=licenses)
|
||||
self.assert_json_error_contains(response, "with more than {} licenses".format(MAX_INVOICED_LICENSES))
|
||||
self.assert_json_error_contains(response, f"with more than {MAX_INVOICED_LICENSES} licenses")
|
||||
self.assertEqual(ujson.loads(response.content)['error_description'], 'too many licenses')
|
||||
|
||||
def check_success(invoice: bool, licenses: Optional[int], upgrade_params: Dict[str, Any]={}) -> None:
|
||||
|
@ -1108,7 +1108,7 @@ class StripeTest(StripeTestCase):
|
|||
realm = Realm.objects.create(string_id='second', name='second')
|
||||
UserProfile.objects.create(realm=realm, email='member@second.com', pointer=-1)
|
||||
for i in range(5):
|
||||
UserProfile.objects.create(realm=realm, email='guest{}@second.com'.format(i),
|
||||
UserProfile.objects.create(realm=realm, email=f'guest{i}@second.com',
|
||||
pointer=-1, role=UserProfile.ROLE_GUEST)
|
||||
self.assertEqual(get_latest_seat_count(realm), 1)
|
||||
# Test 1 member and 6 guests
|
||||
|
|
|
@ -131,7 +131,7 @@ def initial_upgrade(request: HttpRequest) -> HttpResponse:
|
|||
if customer is not None and get_current_plan_by_customer(customer) is not None:
|
||||
billing_page_url = reverse('corporate.views.billing_home')
|
||||
if request.GET.get("onboarding") is not None:
|
||||
billing_page_url = "{}?onboarding=true".format(billing_page_url)
|
||||
billing_page_url = f"{billing_page_url}?onboarding=true"
|
||||
return HttpResponseRedirect(billing_page_url)
|
||||
|
||||
percent_off = Decimal(0)
|
||||
|
@ -210,7 +210,7 @@ def billing_home(request: HttpRequest) -> HttpResponse:
|
|||
'licenses': licenses,
|
||||
'licenses_used': licenses_used,
|
||||
'renewal_date': renewal_date,
|
||||
'renewal_amount': '{:,.2f}'.format(renewal_cents / 100.),
|
||||
'renewal_amount': f'{renewal_cents / 100.:,.2f}',
|
||||
'payment_method': payment_method,
|
||||
'charge_automatically': charge_automatically,
|
||||
'publishable_key': STRIPE_PUBLISHABLE_KEY,
|
||||
|
|
|
@ -99,7 +99,7 @@ def run_tests(files: Iterable[str], external_host: str) -> None:
|
|||
print('\n\nWe will use loop mode for these tests:\n')
|
||||
for test_file in test_files:
|
||||
print(' ' + os.path.basename(test_file))
|
||||
print('\nnumber of loops: {}\n'.format(loop_cnt))
|
||||
print(f'\nnumber of loops: {loop_cnt}\n')
|
||||
print()
|
||||
else:
|
||||
loop_cnt = None
|
||||
|
@ -130,12 +130,12 @@ def run_tests(files: Iterable[str], external_host: str) -> None:
|
|||
def run_loops(loop_cnt: int) -> None:
|
||||
while True:
|
||||
for trial in range(1, loop_cnt + 1):
|
||||
print('\n\n\nSTARTING TRIAL {} / {}\n'.format(trial, loop_cnt))
|
||||
print(f'\n\n\nSTARTING TRIAL {trial} / {loop_cnt}\n')
|
||||
ret = run_tests()
|
||||
if ret == 0:
|
||||
print('`\n\nSUCCESS! trial #{}\n\n'.format(trial))
|
||||
print(f'`\n\nSUCCESS! trial #{trial}\n\n')
|
||||
else:
|
||||
print('\n\nFAIL! trial #{}\n'.format(trial))
|
||||
print(f'\n\nFAIL! trial #{trial}\n')
|
||||
break
|
||||
|
||||
while True:
|
||||
|
|
|
@ -47,7 +47,7 @@ with open('/etc/zulip/nginx_sharding.conf.tmp', 'w') as nginx_sharding_conf_f, \
|
|||
if '.' in shard:
|
||||
host = shard
|
||||
else:
|
||||
host = "{}.{}".format(shard, external_host)
|
||||
host = f"{shard}.{external_host}"
|
||||
assert host not in shard_map, "host %s duplicated" % (host,)
|
||||
shard_map[host] = int(port)
|
||||
write_realm_nginx_config_line(nginx_sharding_conf_f, host, port)
|
||||
|
|
|
@ -14,7 +14,7 @@ if __name__ == "__main__":
|
|||
dockerfile_settings = yaml.safe_load(f)
|
||||
|
||||
for distro in dockerfile_settings:
|
||||
dockerfile_path = "images/{}/Dockerfile".format(distro)
|
||||
dockerfile_path = f"images/{distro}/Dockerfile"
|
||||
os.makedirs(os.path.dirname(dockerfile_path), exist_ok=True)
|
||||
with open(dockerfile_path, "w") as f:
|
||||
f.write("""\
|
||||
|
|
|
@ -25,7 +25,7 @@ class UnusedImagesLinterSpider(BaseDocumentationSpider):
|
|||
|
||||
def _is_external_url(self, url: str) -> bool:
|
||||
is_external = url.startswith('http') and self.start_urls[0] not in url
|
||||
if self._has_extension(url) and 'localhost:9981/{}'.format(self.images_path) in url:
|
||||
if self._has_extension(url) and f'localhost:9981/{self.images_path}' in url:
|
||||
self.static_images.add(basename(urlparse(url).path))
|
||||
return is_external or self._has_extension(url)
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ append_key = """\
|
|||
"""
|
||||
|
||||
def get_mentor_keys(username: str) -> List[str]:
|
||||
url = 'https://api.github.com/users/{}/keys'.format(username)
|
||||
url = f'https://api.github.com/users/{username}/keys'
|
||||
|
||||
r = requests.get(url)
|
||||
if r.status_code != 200:
|
||||
|
@ -41,7 +41,7 @@ def get_mentor_keys(username: str) -> List[str]:
|
|||
|
||||
keys = r.json()
|
||||
if not keys:
|
||||
print('Mentor "{}" has no public key.'.format(username))
|
||||
print(f'Mentor "{username}" has no public key.')
|
||||
sys.exit(1)
|
||||
|
||||
return [key['key'] for key in keys]
|
||||
|
@ -62,7 +62,7 @@ if __name__ == '__main__':
|
|||
f.write(new_content)
|
||||
f.truncate()
|
||||
|
||||
print('Successfully removed {}\' SSH key!'.format(args.username))
|
||||
print(f'Successfully removed {args.username}\' SSH key!')
|
||||
|
||||
else:
|
||||
keys = get_mentor_keys(args.username)
|
||||
|
@ -70,6 +70,6 @@ if __name__ == '__main__':
|
|||
for key in keys:
|
||||
f.write(append_key.format(username=args.username, key=key))
|
||||
|
||||
print('Successfully added {}\'s SSH key!'.format(args.username))
|
||||
print(f'Successfully added {args.username}\'s SSH key!')
|
||||
print('Can you let your mentor know that they can connect to this machine with:\n')
|
||||
print(' $ ssh zulipdev@{}\n'.format(socket.gethostname()))
|
||||
print(f' $ ssh zulipdev@{socket.gethostname()}\n')
|
||||
|
|
|
@ -39,8 +39,8 @@ def get_config() -> configparser.ConfigParser:
|
|||
return config
|
||||
|
||||
def user_exists(username: str) -> bool:
|
||||
print("Checking to see if GitHub user {} exists...".format(username))
|
||||
user_api_url = "https://api.github.com/users/{}".format(username)
|
||||
print(f"Checking to see if GitHub user {username} exists...")
|
||||
user_api_url = f"https://api.github.com/users/{username}"
|
||||
try:
|
||||
response = urllib.request.urlopen(user_api_url)
|
||||
json.load(response)
|
||||
|
@ -48,28 +48,28 @@ def user_exists(username: str) -> bool:
|
|||
return True
|
||||
except urllib.error.HTTPError as err:
|
||||
print(err)
|
||||
print("Does the github user {} exist?".format(username))
|
||||
print(f"Does the github user {username} exist?")
|
||||
sys.exit(1)
|
||||
|
||||
def get_keys(username: str) -> List[Dict[str, Any]]:
|
||||
print("Checking to see that GitHub user has available public keys...")
|
||||
apiurl_keys = "https://api.github.com/users/{}/keys".format(username)
|
||||
apiurl_keys = f"https://api.github.com/users/{username}/keys"
|
||||
try:
|
||||
response = urllib.request.urlopen(apiurl_keys)
|
||||
userkeys = json.load(response)
|
||||
if not userkeys:
|
||||
print("No keys found. Has user {} added ssh keys to their github account?".format(username))
|
||||
print(f"No keys found. Has user {username} added ssh keys to their github account?")
|
||||
sys.exit(1)
|
||||
print("...public keys found!")
|
||||
return userkeys
|
||||
except urllib.error.HTTPError as err:
|
||||
print(err)
|
||||
print("Has user {} added ssh keys to their github account?".format(username))
|
||||
print(f"Has user {username} added ssh keys to their github account?")
|
||||
sys.exit(1)
|
||||
|
||||
def fork_exists(username: str) -> bool:
|
||||
print("Checking to see GitHub user has forked zulip/zulip...")
|
||||
apiurl_fork = "https://api.github.com/repos/{}/zulip".format(username)
|
||||
apiurl_fork = f"https://api.github.com/repos/{username}/zulip"
|
||||
try:
|
||||
response = urllib.request.urlopen(apiurl_fork)
|
||||
json.load(response)
|
||||
|
@ -77,21 +77,21 @@ def fork_exists(username: str) -> bool:
|
|||
return True
|
||||
except urllib.error.HTTPError as err:
|
||||
print(err)
|
||||
print("Has user {} forked zulip/zulip?".format(username))
|
||||
print(f"Has user {username} forked zulip/zulip?")
|
||||
sys.exit(1)
|
||||
|
||||
def exit_if_droplet_exists(my_token: str, username: str, recreate: bool) -> None:
|
||||
print("Checking to see if droplet for {} already exists...".format(username))
|
||||
print(f"Checking to see if droplet for {username} already exists...")
|
||||
manager = digitalocean.Manager(token=my_token)
|
||||
my_droplets = manager.get_all_droplets()
|
||||
for droplet in my_droplets:
|
||||
if droplet.name.lower() == "{}.zulipdev.org".format(username):
|
||||
if droplet.name.lower() == f"{username}.zulipdev.org":
|
||||
if not recreate:
|
||||
print("Droplet for user {} already exists. Pass --recreate if you "
|
||||
"need to recreate the droplet.".format(username))
|
||||
sys.exit(1)
|
||||
else:
|
||||
print("Deleting existing droplet for {}.".format(username))
|
||||
print(f"Deleting existing droplet for {username}.")
|
||||
droplet.destroy()
|
||||
return
|
||||
print("...No droplet found...proceeding.")
|
||||
|
@ -101,13 +101,13 @@ def set_user_data(username: str, userkey_dicts: List[Dict[str, Any]]) -> str:
|
|||
userkeys = [userkey_dict["key"] for userkey_dict in userkey_dicts]
|
||||
ssh_keys = "\n".join(userkeys)
|
||||
|
||||
setup_root_ssh_keys = "printf '{keys}' > /root/.ssh/authorized_keys".format(keys=ssh_keys)
|
||||
setup_zulipdev_ssh_keys = "printf '{keys}' > /home/zulipdev/.ssh/authorized_keys".format(keys=ssh_keys)
|
||||
setup_root_ssh_keys = f"printf '{ssh_keys}' > /root/.ssh/authorized_keys"
|
||||
setup_zulipdev_ssh_keys = f"printf '{ssh_keys}' > /home/zulipdev/.ssh/authorized_keys"
|
||||
|
||||
# We pass the hostname as username.zulipdev.org to the DigitalOcean API.
|
||||
# But some droplets (eg on 18.04) are created with with hostname set to just username.
|
||||
# So we fix the hostname using cloud-init.
|
||||
hostname_setup = "hostnamectl set-hostname {username}.zulipdev.org".format(username=username)
|
||||
hostname_setup = f"hostnamectl set-hostname {username}.zulipdev.org"
|
||||
|
||||
setup_repo = (
|
||||
"cd /home/zulipdev/{1} && "
|
||||
|
@ -141,7 +141,7 @@ su -c 'git config --global pull.rebase true' zulipdev
|
|||
def create_droplet(my_token: str, template_id: str, username: str, tags: List[str], user_data: str) -> str:
|
||||
droplet = digitalocean.Droplet(
|
||||
token=my_token,
|
||||
name='{}.zulipdev.org'.format(username),
|
||||
name=f'{username}.zulipdev.org',
|
||||
region='nyc3',
|
||||
image=template_id,
|
||||
size_slug='s-1vcpu-2gb',
|
||||
|
@ -157,7 +157,7 @@ def create_droplet(my_token: str, template_id: str, username: str, tags: List[st
|
|||
actions = droplet.get_actions()
|
||||
for action in actions:
|
||||
action.load()
|
||||
print("...[{}]: {}".format(action.type, action.status))
|
||||
print(f"...[{action.type}]: {action.status}")
|
||||
if action.type == 'create' and action.status == 'completed':
|
||||
incomplete = False
|
||||
break
|
||||
|
@ -165,7 +165,7 @@ def create_droplet(my_token: str, template_id: str, username: str, tags: List[st
|
|||
time.sleep(15)
|
||||
print("...droplet created!")
|
||||
droplet.load()
|
||||
print("...ip address for new droplet is: {}.".format(droplet.ip_address))
|
||||
print(f"...ip address for new droplet is: {droplet.ip_address}.")
|
||||
return droplet.ip_address
|
||||
|
||||
def delete_existing_records(records: List[digitalocean.Record], record_name: str) -> None:
|
||||
|
@ -175,7 +175,7 @@ def delete_existing_records(records: List[digitalocean.Record], record_name: str
|
|||
record.destroy()
|
||||
count = count + 1
|
||||
if count:
|
||||
print("Deleted {} existing A records for {}.zulipdev.org.".format(count, record_name))
|
||||
print(f"Deleted {count} existing A records for {record_name}.zulipdev.org.")
|
||||
|
||||
def create_dns_record(my_token: str, username: str, ip_address: str) -> None:
|
||||
domain = digitalocean.Domain(token=my_token, name='zulipdev.org')
|
||||
|
@ -186,9 +186,9 @@ def create_dns_record(my_token: str, username: str, ip_address: str) -> None:
|
|||
wildcard_name = "*." + username
|
||||
delete_existing_records(records, wildcard_name)
|
||||
|
||||
print("Creating new A record for {}.zulipdev.org that points to {}.".format(username, ip_address))
|
||||
print(f"Creating new A record for {username}.zulipdev.org that points to {ip_address}.")
|
||||
domain.create_new_domain_record(type='A', name=username, data=ip_address)
|
||||
print("Creating new A record for *.{}.zulipdev.org that points to {}.".format(username, ip_address))
|
||||
print(f"Creating new A record for *.{username}.zulipdev.org that points to {ip_address}.")
|
||||
domain.create_new_domain_record(type='A', name=wildcard_name, data=ip_address)
|
||||
|
||||
def print_completion(username: str) -> None:
|
||||
|
@ -230,7 +230,7 @@ if __name__ == '__main__':
|
|||
# get command line arguments
|
||||
args = parser.parse_args()
|
||||
username = args.username.lower()
|
||||
print("Creating Zulip developer environment for GitHub user {}...".format(username))
|
||||
print(f"Creating Zulip developer environment for GitHub user {username}...")
|
||||
|
||||
# get config details
|
||||
config = get_config()
|
||||
|
|
|
@ -49,7 +49,7 @@ def fetch_contributors(repo_link: str) -> Optional[List[Dict[str, Dict[str, Any]
|
|||
def write_to_disk(json_data: ContributorsJSON, out_file: str) -> None:
|
||||
with open(out_file, 'w') as f:
|
||||
try:
|
||||
f.write("{}\n".format(json.dumps(json_data, indent=2, sort_keys=True)))
|
||||
f.write(f"{json.dumps(json_data, indent=2, sort_keys=True)}\n")
|
||||
except OSError as e:
|
||||
logger.warning(e)
|
||||
sys.exit(1)
|
||||
|
|
|
@ -47,9 +47,9 @@ from zerver.lib.storage import static_path
|
|||
def create_integration_bot(integration: WebhookIntegration, bot_name: Optional[str]=None) -> UserProfile:
|
||||
realm = get_realm('zulip')
|
||||
owner = get_user_by_delivery_email("iago@zulip.com", realm)
|
||||
bot_email = "{}-bot@example.com".format(integration.name)
|
||||
bot_email = f"{integration.name}-bot@example.com"
|
||||
if bot_name is None:
|
||||
bot_name = "{} Bot".format(integration.name.capitalize())
|
||||
bot_name = f"{integration.name.capitalize()} Bot"
|
||||
try:
|
||||
bot = UserProfile.objects.get(email=bot_email)
|
||||
except UserProfile.DoesNotExist:
|
||||
|
@ -123,13 +123,13 @@ def send_bot_payload_message(bot: UserProfile, integration: WebhookIntegration,
|
|||
if config.custom_headers:
|
||||
headers.update(config.custom_headers)
|
||||
if config.use_basic_auth:
|
||||
credentials = base64.b64encode('{}:{}'.format(bot.email, bot.api_key).encode('utf8')).decode('utf8')
|
||||
auth = 'basic {}'.format(credentials)
|
||||
credentials = base64.b64encode(f'{bot.email}:{bot.api_key}'.encode('utf8')).decode('utf8')
|
||||
auth = f'basic {credentials}'
|
||||
headers.update(dict(Authorization=auth))
|
||||
|
||||
assert isinstance(bot.bot_owner, UserProfile)
|
||||
stream = integration.stream_name or 'devel'
|
||||
url = "{}/{}".format(bot.bot_owner.realm.uri, integration.url)
|
||||
url = f"{bot.bot_owner.realm.uri}/{integration.url}"
|
||||
params = {'api_key': bot.api_key, 'stream': stream}
|
||||
if config.extra_params:
|
||||
params.update(config.extra_params)
|
||||
|
@ -148,7 +148,7 @@ def send_bot_payload_message(bot: UserProfile, integration: WebhookIntegration,
|
|||
else:
|
||||
extra_args = {'json': data}
|
||||
|
||||
url = '{}?{}'.format(url, urlencode(params))
|
||||
url = f'{url}?{urlencode(params)}'
|
||||
|
||||
try:
|
||||
response = requests.post(url=url, headers=headers, **extra_args)
|
||||
|
@ -161,13 +161,13 @@ def send_bot_payload_message(bot: UserProfile, integration: WebhookIntegration,
|
|||
print('Failed to trigger webhook')
|
||||
return False
|
||||
else:
|
||||
print('Triggered {} webhook'.format(integration.name))
|
||||
print(f'Triggered {integration.name} webhook')
|
||||
return True
|
||||
|
||||
def capture_last_message_screenshot(bot: UserProfile, image_path: str) -> None:
|
||||
message = Message.objects.filter(sender=bot).last()
|
||||
if message is None:
|
||||
print('No message found for {}'.format(bot.full_name))
|
||||
print(f'No message found for {bot.full_name}')
|
||||
return
|
||||
message_id = str(message.id)
|
||||
screenshot_script = os.path.join(TOOLS_DIR, 'message-screenshot.js')
|
||||
|
|
|
@ -6,7 +6,7 @@ from subprocess import check_output
|
|||
from typing import Dict, List
|
||||
|
||||
def get_json_filename(locale: str) -> str:
|
||||
return "locale/{}/mobile.json".format(locale)
|
||||
return f"locale/{locale}/mobile.json"
|
||||
|
||||
def get_locales() -> List[str]:
|
||||
output = check_output(['git', 'ls-files', 'locale'])
|
||||
|
|
|
@ -167,7 +167,7 @@ COMPILED_IGNORED_PHRASES = [
|
|||
]
|
||||
|
||||
SPLIT_BOUNDARY = '?.!' # Used to split string into sentences.
|
||||
SPLIT_BOUNDARY_REGEX = re.compile(r'[{}]'.format(SPLIT_BOUNDARY))
|
||||
SPLIT_BOUNDARY_REGEX = re.compile(fr'[{SPLIT_BOUNDARY}]')
|
||||
|
||||
# Regexes which check capitalization in sentences.
|
||||
DISALLOWED_REGEXES = [re.compile(regex) for regex in [
|
||||
|
|
|
@ -98,7 +98,7 @@ def head_binary_search(key: Text, words: List[str]) -> str:
|
|||
while True:
|
||||
if lower > upper:
|
||||
# Should not happen
|
||||
raise Exception("Cannot find imperative mood of {}".format(key))
|
||||
raise Exception(f"Cannot find imperative mood of {key}")
|
||||
|
||||
mid = (lower + upper) // 2
|
||||
imperative_form = words[mid]
|
||||
|
@ -156,7 +156,7 @@ class TitleMatchRegexAllowException(LineRule):
|
|||
regex = self.options['regex'].value
|
||||
pattern = re.compile(regex, re.UNICODE)
|
||||
if not pattern.search(title) and not title.startswith("Revert \""):
|
||||
violation_msg = "Title does not match regex ({})".format(regex)
|
||||
violation_msg = f"Title does not match regex ({regex})"
|
||||
return [RuleViolation(self.id, violation_msg, title)]
|
||||
|
||||
return []
|
||||
|
|
|
@ -11,15 +11,15 @@ from zulint.custom_rules import Rule, RuleList
|
|||
# 'include_only': 'set([<path>, ...])' - includes only those files where <path> is a substring of the filepath.
|
||||
|
||||
PYDELIMS = r'''"'()\[\]{}#\\'''
|
||||
PYREG = r"[^{}]".format(PYDELIMS)
|
||||
PYREG = fr"[^{PYDELIMS}]"
|
||||
PYSQ = r'"(?:[^"\\]|\\.)*"'
|
||||
PYDQ = r"'(?:[^'\\]|\\.)*'"
|
||||
PYLEFT = r"[(\[{]"
|
||||
PYRIGHT = r"[)\]}]"
|
||||
PYCODE = PYREG
|
||||
for depth in range(5):
|
||||
PYGROUP = r"""(?:{}|{}|{}{}*{})""".format(PYSQ, PYDQ, PYLEFT, PYCODE, PYRIGHT)
|
||||
PYCODE = r"""(?:{}|{})""".format(PYREG, PYGROUP)
|
||||
PYGROUP = fr"""(?:{PYSQ}|{PYDQ}|{PYLEFT}{PYCODE}*{PYRIGHT})"""
|
||||
PYCODE = fr"""(?:{PYREG}|{PYGROUP})"""
|
||||
|
||||
FILES_WITH_LEGACY_SUBJECT = {
|
||||
# This basically requires a big DB migration:
|
||||
|
@ -305,7 +305,7 @@ python_rules = RuleList(
|
|||
{'pattern': r'''\WJsonableError\(["'].+\)''',
|
||||
'exclude': {'zerver/tests', 'zerver/views/development/'},
|
||||
'description': 'Argument to JsonableError should be a literal string enclosed by _()'},
|
||||
{'pattern': r"""\b_\((?:\s|{}|{})*[^\s'")]""".format(PYSQ, PYDQ),
|
||||
{'pattern': fr"""\b_\((?:\s|{PYSQ}|{PYDQ})*[^\s'")]""",
|
||||
'description': 'Called _() on a computed string',
|
||||
'exclude_line': {('zerver/lib/i18n.py', 'result = _(string)')},
|
||||
'good_lines': ["return json_error(_('No presence data for %s') % (target.email,))"],
|
||||
|
|
|
@ -91,7 +91,7 @@ def main() -> None:
|
|||
with open(success_stamp, 'w') as f:
|
||||
f.close()
|
||||
|
||||
print("build_emoji: Using cached emojis from {}".format(source_emoji_dump))
|
||||
print(f"build_emoji: Using cached emojis from {source_emoji_dump}")
|
||||
if os.path.lexists(TARGET_EMOJI_DUMP):
|
||||
os.remove(TARGET_EMOJI_DUMP)
|
||||
os.symlink(source_emoji_dump, TARGET_EMOJI_DUMP)
|
||||
|
@ -300,13 +300,13 @@ def setup_old_emoji_farm(cache_path: str,
|
|||
|
||||
for name, codepoint in emoji_map.items():
|
||||
mapped_codepoint = REMAPPED_EMOJIS.get(codepoint, codepoint)
|
||||
image_file_path = os.path.join(google_emoji_cache_path, '{}.png'.format(mapped_codepoint))
|
||||
symlink_path = os.path.join(emoji_cache_path, '{}.png'.format(name))
|
||||
image_file_path = os.path.join(google_emoji_cache_path, f'{mapped_codepoint}.png')
|
||||
symlink_path = os.path.join(emoji_cache_path, f'{name}.png')
|
||||
os.symlink(image_file_path, symlink_path)
|
||||
try:
|
||||
# `emoji_map` contains duplicate entries for the same codepoint with different
|
||||
# names. So creation of symlink for <codepoint>.png may throw `FileExistsError`.
|
||||
unicode_symlink_path = os.path.join(unicode_emoji_cache_path, '{}.png'.format(codepoint))
|
||||
unicode_symlink_path = os.path.join(unicode_emoji_cache_path, f'{codepoint}.png')
|
||||
os.symlink(image_file_path, unicode_symlink_path)
|
||||
except FileExistsError:
|
||||
pass
|
||||
|
|
|
@ -169,7 +169,7 @@ class ZulipInternetBlockedError(Exception):
|
|||
"More details and advice are available here:"
|
||||
"https://zulip.readthedocs.io/en/latest/testing/testing.html#internet-access-inside-test-suites"
|
||||
)
|
||||
msg = "{}\nResponses library error message: {}".format(zulip_msg, original_msg)
|
||||
msg = f"{zulip_msg}\nResponses library error message: {original_msg}"
|
||||
super().__init__(msg)
|
||||
|
||||
def main() -> None:
|
||||
|
@ -405,7 +405,7 @@ def main() -> None:
|
|||
missed_count = len(templates_not_rendered)
|
||||
print("\nError: %s templates have no tests!" % (missed_count,))
|
||||
for template in templates_not_rendered:
|
||||
print(' {}'.format(template))
|
||||
print(f' {template}')
|
||||
print("See zerver/tests/test_templates.py for the exclude list.")
|
||||
failures = True
|
||||
|
||||
|
@ -452,11 +452,11 @@ def main() -> None:
|
|||
prof.disable()
|
||||
with tempfile.NamedTemporaryFile(prefix='profile.data.', delete=False) as stats_file:
|
||||
prof.dump_stats(stats_file.name)
|
||||
print("Profile data saved to {}".format(stats_file.name))
|
||||
print("You can visualize it using e.g. `snakeviz {}`".format(shlex.quote(stats_file.name)))
|
||||
print(f"Profile data saved to {stats_file.name}")
|
||||
print(f"You can visualize it using e.g. `snakeviz {shlex.quote(stats_file.name)}`")
|
||||
print("Note: If you are using vagrant for development environment you will need to do:")
|
||||
print("1.) `vagrant ssh -- -L 8080:127.0.0.1:8080`")
|
||||
print("2.) `snakeviz -s {}`".format(shlex.quote(stats_file.name)))
|
||||
print(f"2.) `snakeviz -s {shlex.quote(stats_file.name)}`")
|
||||
|
||||
if options.report_slow_tests:
|
||||
from zerver.lib.test_runner import report_slow_tests
|
||||
|
|
|
@ -310,7 +310,7 @@ def enforce_proper_coverage(coverage_json: Any) -> bool:
|
|||
line_mapping = coverage_json[path]['statementMap']
|
||||
if check_line_coverage(relative_path, line_coverage, line_mapping, log=False):
|
||||
coverage_not_enforced = True
|
||||
print_error("{} unexpectedly has 100% line coverage.".format(relative_path))
|
||||
print_error(f"{relative_path} unexpectedly has 100% line coverage.")
|
||||
|
||||
if coverage_not_enforced:
|
||||
print()
|
||||
|
@ -332,7 +332,7 @@ if options.coverage and ret == 0:
|
|||
print()
|
||||
if ret == 0:
|
||||
if options.coverage:
|
||||
reports_location = 'http://{}/node-coverage/index.html'.format(get_dev_host())
|
||||
reports_location = f'http://{get_dev_host()}/node-coverage/index.html'
|
||||
print('View coverage reports at ' + CYAN + reports_location + ENDC)
|
||||
|
||||
print(GREEN + "Test(s) passed. SUCCESS!" + ENDC)
|
||||
|
|
|
@ -56,7 +56,7 @@ def check_worker_launch(run_dev: "subprocess.Popen[str]") -> bool:
|
|||
|
||||
if __name__ == '__main__':
|
||||
print('\nStarting Development Server')
|
||||
args = ["{}/run-dev.py".format(TOOLS_DIR)]
|
||||
args = [f"{TOOLS_DIR}/run-dev.py"]
|
||||
run_dev = subprocess.Popen(
|
||||
args,
|
||||
bufsize=1, # line buffered
|
||||
|
|
|
@ -19,7 +19,7 @@ def start_server(logfile_name: str) -> Tuple[bool, str]:
|
|||
with open(logfile_name, 'rb', buffering=0) as logfile:
|
||||
for i in range(200):
|
||||
time.sleep(0.5)
|
||||
print("{}. Polling run-dev...".format(i))
|
||||
print(f"{i}. Polling run-dev...")
|
||||
new_data = logfile.read().decode()
|
||||
if new_data:
|
||||
datalog.append(new_data)
|
||||
|
|
|
@ -23,18 +23,18 @@ class TestRuleList(TestCase):
|
|||
for path in rule.get('exclude', {}):
|
||||
abs_path = os.path.abspath(os.path.join(ROOT_DIR, path))
|
||||
self.assertTrue(os.path.exists(abs_path),
|
||||
"'{}' is neither an existing file, nor a directory. {}".format(path, CHECK_MESSAGE))
|
||||
f"'{path}' is neither an existing file, nor a directory. {CHECK_MESSAGE}")
|
||||
|
||||
for line_tuple in rule.get('exclude_line', {}):
|
||||
path = line_tuple[0]
|
||||
abs_path = os.path.abspath(os.path.join(ROOT_DIR, path))
|
||||
self.assertTrue(os.path.isfile(abs_path),
|
||||
"The file '{}' doesn't exist. {}".format(path, CHECK_MESSAGE))
|
||||
f"The file '{path}' doesn't exist. {CHECK_MESSAGE}")
|
||||
|
||||
for path in rule.get('include_only', {}):
|
||||
if not os.path.splitext(path)[1]:
|
||||
self.assertTrue(path.endswith('/'),
|
||||
"The path '{}' should end with '/'. {}".format(path, CHECK_MESSAGE))
|
||||
f"The path '{path}' should end with '/'. {CHECK_MESSAGE}")
|
||||
|
||||
def test_rule_patterns(self) -> None:
|
||||
"""Verifies that the search regex specified in a custom rule actually matches
|
||||
|
@ -45,7 +45,7 @@ class TestRuleList(TestCase):
|
|||
# create=True is superfluous when mocking built-ins in Python >= 3.5
|
||||
with patch('builtins.open', return_value=StringIO(line + '\n\n'), create=True, autospec=True):
|
||||
self.assertFalse(RuleList([], [rule]).custom_check_file('foo.bar', 'baz', ''),
|
||||
"The pattern '{}' matched the line '{}' while it shouldn't.".format(pattern, line))
|
||||
f"The pattern '{pattern}' matched the line '{line}' while it shouldn't.")
|
||||
|
||||
for line in rule.get('bad_lines', []):
|
||||
# create=True is superfluous when mocking built-ins in Python >= 3.5
|
||||
|
@ -53,4 +53,4 @@ class TestRuleList(TestCase):
|
|||
return_value=StringIO(line + '\n\n'), create=True, autospec=True), patch('builtins.print'):
|
||||
filename = list(rule.get('include_only', {'foo.bar'}))[0]
|
||||
self.assertTrue(RuleList([], [rule]).custom_check_file(filename, 'baz', ''),
|
||||
"The pattern '{}' didn't match the line '{}' while it should.".format(pattern, line))
|
||||
f"The pattern '{pattern}' didn't match the line '{line}' while it should.")
|
||||
|
|
|
@ -72,4 +72,4 @@ for zuliprc_path in zuliprc_paths_list:
|
|||
else:
|
||||
result = 'SUCCESS'
|
||||
reason = 'API key for user %s is already consistent' % (email,)
|
||||
print('{}: {}: {}'.format(zuliprc_path, result, reason))
|
||||
print(f'{zuliprc_path}: {result}: {reason}')
|
||||
|
|
|
@ -119,12 +119,12 @@ def convert_user_data(user_handler: UserHandler,
|
|||
if role == UserProfile.ROLE_GUEST:
|
||||
# Hipchat guest users don't have emails, so
|
||||
# we just fake them.
|
||||
email = 'guest-{id}@example.com'.format(id=id)
|
||||
email = f'guest-{id}@example.com'
|
||||
delivery_email = email
|
||||
else:
|
||||
# Hipchat sometimes doesn't export an email for deactivated users.
|
||||
assert not is_active
|
||||
email = delivery_email = "deactivated-{id}@example.com".format(id=id)
|
||||
email = delivery_email = f"deactivated-{id}@example.com"
|
||||
|
||||
# unmapped fields:
|
||||
# title - Developer, Project Manager, etc.
|
||||
|
|
|
@ -45,7 +45,7 @@ class UserHandler:
|
|||
user_id = self._new_mirror_user_id()
|
||||
short_name = name
|
||||
full_name = name
|
||||
email = 'mirror-{user_id}@example.com'.format(user_id=user_id)
|
||||
email = f'mirror-{user_id}@example.com'
|
||||
delivery_email = email
|
||||
avatar_source = 'G'
|
||||
date_joined = int(timezone_now().timestamp())
|
||||
|
|
|
@ -1112,7 +1112,7 @@ def log_token_warning(token: str) -> None:
|
|||
def get_slack_api_data(slack_api_url: str, get_param: str, **kwargs: Any) -> Any:
|
||||
if not kwargs.get("token"):
|
||||
raise AssertionError("Slack token missing in kwargs")
|
||||
data = requests.get("{}?{}".format(slack_api_url, urlencode(kwargs)))
|
||||
data = requests.get(f"{slack_api_url}?{urlencode(kwargs)}")
|
||||
|
||||
if data.status_code == requests.codes.ok:
|
||||
result = data.json()
|
||||
|
|
|
@ -305,7 +305,7 @@ body:
|
|||
def full_webhook_client_name(raw_client_name: Optional[str]=None) -> Optional[str]:
|
||||
if raw_client_name is None:
|
||||
return None
|
||||
return "Zulip{}Webhook".format(raw_client_name)
|
||||
return f"Zulip{raw_client_name}Webhook"
|
||||
|
||||
# Use this for webhook views that don't get an email passed in.
|
||||
def api_key_only_webhook_view(
|
||||
|
|
|
@ -228,7 +228,7 @@ def generate_password_reset_url(user_profile: UserProfile,
|
|||
uid = urlsafe_base64_encode(force_bytes(user_profile.id))
|
||||
endpoint = reverse('django.contrib.auth.views.password_reset_confirm',
|
||||
kwargs=dict(uidb64=uid, token=token))
|
||||
return "{}{}".format(user_profile.realm.uri, endpoint)
|
||||
return f"{user_profile.realm.uri}{endpoint}"
|
||||
|
||||
class ZulipPasswordResetForm(PasswordResetForm):
|
||||
def save(self,
|
||||
|
@ -319,7 +319,7 @@ class RateLimitedPasswordResetByEmail(RateLimitedObject):
|
|||
super().__init__()
|
||||
|
||||
def key(self) -> str:
|
||||
return "{}:{}".format(type(self).__name__, self.email)
|
||||
return f"{type(self).__name__}:{self.email}"
|
||||
|
||||
def rules(self) -> List[Tuple[int, int]]:
|
||||
return settings.RATE_LIMITING_RULES['password_reset_form_by_email']
|
||||
|
|
|
@ -754,8 +754,8 @@ def do_scrub_realm(realm: Realm) -> None:
|
|||
for user in users:
|
||||
do_delete_messages_by_sender(user)
|
||||
do_delete_avatar_image(user)
|
||||
user.full_name = "Scrubbed {}".format(generate_key()[:15])
|
||||
scrubbed_email = "scrubbed-{}@{}".format(generate_key()[:15], realm.host)
|
||||
user.full_name = f"Scrubbed {generate_key()[:15]}"
|
||||
scrubbed_email = f"scrubbed-{generate_key()[:15]}@{realm.host}"
|
||||
user.email = scrubbed_email
|
||||
user.delivery_email = scrubbed_email
|
||||
user.save(update_fields=["full_name", "email", "delivery_email"])
|
||||
|
|
|
@ -59,10 +59,10 @@ def set_bot_config(bot_profile: UserProfile, key: str, value: str) -> None:
|
|||
obj.save()
|
||||
|
||||
def load_bot_config_template(bot: str) -> Dict[str, str]:
|
||||
bot_module_name = 'zulip_bots.bots.{}'.format(bot)
|
||||
bot_module_name = f'zulip_bots.bots.{bot}'
|
||||
bot_module = importlib.import_module(bot_module_name)
|
||||
bot_module_path = os.path.dirname(bot_module.__file__)
|
||||
config_path = os.path.join(bot_module_path, '{}.conf'.format(bot))
|
||||
config_path = os.path.join(bot_module_path, f'{bot}.conf')
|
||||
if os.path.isfile(config_path):
|
||||
config = configparser.ConfigParser()
|
||||
with open(config_path) as conf:
|
||||
|
|
|
@ -31,9 +31,9 @@ def set_bot_storage(bot_profile: UserProfile, entries: List[Tuple[str, str]]) ->
|
|||
storage_size_difference = 0
|
||||
for key, value in entries:
|
||||
if not isinstance(key, str):
|
||||
raise StateError("Key type is {}, but should be str.".format(type(key)))
|
||||
raise StateError(f"Key type is {type(key)}, but should be str.")
|
||||
if not isinstance(value, str):
|
||||
raise StateError("Value type is {}, but should be str.".format(type(value)))
|
||||
raise StateError(f"Value type is {type(value)}, but should be str.")
|
||||
storage_size_difference += (len(key) + len(value)) - get_bot_storage_size(bot_profile, key)
|
||||
new_storage_size = get_bot_storage_size(bot_profile) + storage_size_difference
|
||||
if new_storage_size > storage_size_limit:
|
||||
|
|
|
@ -769,7 +769,7 @@ class InlineInterestingLinkProcessor(markdown.treeprocessors.Treeprocessor):
|
|||
def youtube_title(self, extracted_data: Dict[str, Any]) -> Optional[str]:
|
||||
title = extracted_data.get("title")
|
||||
if title is not None:
|
||||
return "YouTube - {}".format(title)
|
||||
return f"YouTube - {title}"
|
||||
return None
|
||||
|
||||
def youtube_image(self, url: str) -> Optional[str]:
|
||||
|
@ -796,7 +796,7 @@ class InlineInterestingLinkProcessor(markdown.treeprocessors.Treeprocessor):
|
|||
def vimeo_title(self, extracted_data: Dict[str, Any]) -> Optional[str]:
|
||||
title = extracted_data.get("title")
|
||||
if title is not None:
|
||||
return "Vimeo - {}".format(title)
|
||||
return f"Vimeo - {title}"
|
||||
return None
|
||||
|
||||
def twitter_text(self, text: str,
|
||||
|
@ -1201,7 +1201,7 @@ class Avatar(markdown.inlinepatterns.Pattern):
|
|||
profile_id = user_dict['id']
|
||||
|
||||
img.set('class', 'message_body_gravatar')
|
||||
img.set('src', '/avatar/{}?s=30'.format(profile_id or email))
|
||||
img.set('src', f'/avatar/{profile_id or email}?s=30')
|
||||
img.set('title', email)
|
||||
img.set('alt', email)
|
||||
return img
|
||||
|
@ -1637,7 +1637,7 @@ class UserMentionPattern(markdown.inlinepatterns.Pattern):
|
|||
el.set('class', 'user-mention silent')
|
||||
else:
|
||||
el.set('class', 'user-mention')
|
||||
text = "@{}".format(text)
|
||||
text = f"@{text}"
|
||||
el.text = markdown.util.AtomicString(text)
|
||||
return el
|
||||
return None
|
||||
|
@ -1691,8 +1691,8 @@ class StreamPattern(CompiledPattern):
|
|||
# provide more clarity to API clients.
|
||||
# Also do the same for StreamTopicPattern.
|
||||
stream_url = encode_stream(stream['id'], name)
|
||||
el.set('href', '/#narrow/stream/{stream_url}'.format(stream_url=stream_url))
|
||||
text = '#{stream_name}'.format(stream_name=name)
|
||||
el.set('href', f'/#narrow/stream/{stream_url}')
|
||||
text = f'#{name}'
|
||||
el.text = markdown.util.AtomicString(text)
|
||||
return el
|
||||
return None
|
||||
|
@ -1721,7 +1721,7 @@ class StreamTopicPattern(CompiledPattern):
|
|||
link = '/#narrow/stream/{stream_url}/topic/{topic_url}'.format(stream_url=stream_url,
|
||||
topic_url=topic_url)
|
||||
el.set('href', link)
|
||||
text = '#{stream_name} > {topic_name}'.format(stream_name=stream_name, topic_name=topic_name)
|
||||
text = f'#{stream_name} > {topic_name}'
|
||||
el.text = markdown.util.AtomicString(text)
|
||||
return el
|
||||
return None
|
||||
|
|
|
@ -113,7 +113,7 @@ class APIArgumentsTablePreprocessor(Preprocessor):
|
|||
|
||||
default = argument.get('schema', {}).get('default')
|
||||
if default is not None:
|
||||
description += '\nDefaults to `{}`.'.format(json.dumps(default))
|
||||
description += f'\nDefaults to `{json.dumps(default)}`.'
|
||||
|
||||
# TODO: OpenAPI allows indicating where the argument goes
|
||||
# (path, querystring, form data...). We should document this detail.
|
||||
|
|
|
@ -45,7 +45,7 @@ class IncludeCustomPreprocessor(IncludePreprocessor):
|
|||
with open(filename, encoding=self.encoding) as r:
|
||||
text = r.readlines()
|
||||
except Exception as e:
|
||||
print('Warning: could not find file {}. Error: {}'.format(filename, e))
|
||||
print(f'Warning: could not find file {filename}. Error: {e}')
|
||||
lines[loc] = INC_SYNTAX.sub('', line)
|
||||
raise InvalidMarkdownIncludeStatement(m.group(0).strip())
|
||||
|
||||
|
|
|
@ -124,7 +124,7 @@ class TabbedSectionsPreprocessor(Preprocessor):
|
|||
# Wrapping the content in two newlines is necessary here.
|
||||
# If we don't do this, the inner Markdown does not get
|
||||
# rendered properly.
|
||||
content='\n{}\n'.format(content))
|
||||
content=f'\n{content}\n')
|
||||
tab_content_blocks.append(tab_content_block)
|
||||
return '\n'.join(tab_content_blocks)
|
||||
|
||||
|
|
|
@ -216,7 +216,7 @@ def validate_cache_key(key: str) -> None:
|
|||
if not bool(re.fullmatch(r"([!-~])+", key)):
|
||||
raise InvalidCacheKeyException("Invalid characters in the cache key: " + key)
|
||||
if len(key) > MEMCACHED_MAX_KEY_LENGTH:
|
||||
raise InvalidCacheKeyException("Cache key too long: {} Length: {}".format(key, len(key)))
|
||||
raise InvalidCacheKeyException(f"Cache key too long: {key} Length: {len(key)}")
|
||||
|
||||
def cache_set(key: str, val: Any, cache_name: Optional[str]=None, timeout: Optional[int]=None) -> None:
|
||||
final_key = KEY_PREFIX + key
|
||||
|
|
|
@ -52,7 +52,7 @@ def tracemalloc_dump() -> None:
|
|||
gc.collect()
|
||||
tracemalloc.take_snapshot().dump(path)
|
||||
|
||||
with open('/proc/{}/stat'.format(os.getpid()), 'rb') as f:
|
||||
with open(f'/proc/{os.getpid()}/stat', 'rb') as f:
|
||||
procstat = f.read().split()
|
||||
rss_pages = int(procstat[23])
|
||||
logger.info("tracemalloc dump: tracing %s MiB (%s MiB peak), using %s MiB; rss %s MiB; dumped %s",
|
||||
|
@ -79,7 +79,7 @@ def tracemalloc_listen() -> None:
|
|||
listener_pid = os.getpid()
|
||||
|
||||
sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
|
||||
path = "/tmp/tracemalloc.{}".format(os.getpid())
|
||||
path = f"/tmp/tracemalloc.{os.getpid()}"
|
||||
sock.bind(path)
|
||||
thread = threading.Thread(target=lambda: tracemalloc_listen_sock(sock),
|
||||
daemon=True)
|
||||
|
|
|
@ -43,15 +43,15 @@ def redact_email_address(error_message: str) -> str:
|
|||
# Annotate basic info about the address before scrubbing:
|
||||
if is_missed_message_address(email_address):
|
||||
redacted_message = error_message.replace(email_address,
|
||||
"{} <Missed message address>".format(email_address))
|
||||
f"{email_address} <Missed message address>")
|
||||
else:
|
||||
try:
|
||||
target_stream_id = decode_stream_email_address(email_address)[0].id
|
||||
annotated_address = "{} <Address to stream id: {}>".format(email_address, target_stream_id)
|
||||
annotated_address = f"{email_address} <Address to stream id: {target_stream_id}>"
|
||||
redacted_message = error_message.replace(email_address, annotated_address)
|
||||
except ZulipEmailForwardError:
|
||||
redacted_message = error_message.replace(email_address,
|
||||
"{} <Invalid address>".format(email_address))
|
||||
f"{email_address} <Invalid address>")
|
||||
|
||||
# Scrub the address from the message, to the form XXXXX@example.com:
|
||||
string_to_scrub = address_match.groups()[0]
|
||||
|
@ -429,7 +429,7 @@ def mirror_email_message(data: Dict[str, str]) -> Dict[str, str]:
|
|||
except ZulipEmailForwardError as e:
|
||||
return {
|
||||
"status": "error",
|
||||
"msg": "5.1.1 Bad destination mailbox address: {}".format(e)
|
||||
"msg": f"5.1.1 Bad destination mailbox address: {e}"
|
||||
}
|
||||
|
||||
queue_json_publish(
|
||||
|
@ -449,7 +449,7 @@ class RateLimitedRealmMirror(RateLimitedObject):
|
|||
super().__init__()
|
||||
|
||||
def key(self) -> str:
|
||||
return "{}:{}".format(type(self).__name__, self.realm.string_id)
|
||||
return f"{type(self).__name__}:{self.realm.string_id}"
|
||||
|
||||
def rules(self) -> List[Tuple[int, int]]:
|
||||
return settings.RATE_LIMITING_MIRROR_REALM_RULES
|
||||
|
|
|
@ -141,9 +141,9 @@ def build_message_list(user_profile: UserProfile, messages: List[Message]) -> Li
|
|||
return re.sub(r"\[(\S*)\]\((\S*)\)", r"\2", content)
|
||||
|
||||
def append_sender_to_message(message_plain: str, message_html: str, sender: str) -> Tuple[str, str]:
|
||||
message_plain = "{}: {}".format(sender, message_plain)
|
||||
message_plain = f"{sender}: {message_plain}"
|
||||
message_soup = BeautifulSoup(message_html, "html.parser")
|
||||
sender_name_soup = BeautifulSoup("<b>{}</b>: ".format(sender), "html.parser")
|
||||
sender_name_soup = BeautifulSoup(f"<b>{sender}</b>: ", "html.parser")
|
||||
first_tag = message_soup.find()
|
||||
if first_tag.name == "p":
|
||||
first_tag.insert(0, sender_name_soup)
|
||||
|
|
|
@ -30,9 +30,9 @@ EMOTICON_CONVERSIONS = emoji_codes["emoticon_conversions"]
|
|||
possible_emoticons = EMOTICON_CONVERSIONS.keys()
|
||||
possible_emoticon_regexes = (re.escape(emoticon) for emoticon in possible_emoticons)
|
||||
terminal_symbols = ',.;?!()\\[\\] "\'\\n\\t' # from composebox_typeahead.js
|
||||
emoticon_regex = ('(?<![^{}])(?P<emoticon>('.format(terminal_symbols)
|
||||
emoticon_regex = (f'(?<![^{terminal_symbols}])(?P<emoticon>('
|
||||
+ ')|('.join(possible_emoticon_regexes)
|
||||
+ '))(?![^{}])'.format(terminal_symbols))
|
||||
+ f'))(?![^{terminal_symbols}])')
|
||||
|
||||
# Translates emoticons to their colon syntax, e.g. `:smiley:`.
|
||||
def translate_emoticons(text: str) -> str:
|
||||
|
|
|
@ -92,5 +92,5 @@ def get_language_translation_data(language: str) -> Dict[str, str]:
|
|||
with open(path) as reader:
|
||||
return ujson.load(reader)
|
||||
except FileNotFoundError:
|
||||
print('Translation for {} not found at {}'.format(language, path))
|
||||
print(f'Translation for {language} not found at {path}')
|
||||
return {}
|
||||
|
|
|
@ -333,7 +333,7 @@ def idseq(model_class: Any) -> str:
|
|||
return 'zerver_botuserstatedata_id_seq'
|
||||
elif model_class == BotConfigData:
|
||||
return 'zerver_botuserconfigdata_id_seq'
|
||||
return '{}_id_seq'.format(model_class._meta.db_table)
|
||||
return f'{model_class._meta.db_table}_id_seq'
|
||||
|
||||
def allocate_ids(model_class: Any, count: int) -> List[int]:
|
||||
"""
|
||||
|
|
|
@ -139,9 +139,9 @@ class BotIntegration(Integration):
|
|||
self.logo_url = staticfiles_storage.url(logo)
|
||||
|
||||
if display_name is None:
|
||||
display_name = "{} Bot".format(name.title()) # nocoverage
|
||||
display_name = f"{name.title()} Bot" # nocoverage
|
||||
else:
|
||||
display_name = "{} Bot".format(display_name)
|
||||
display_name = f"{display_name} Bot"
|
||||
self.display_name = display_name
|
||||
|
||||
if doc is None:
|
||||
|
@ -235,7 +235,7 @@ class HubotIntegration(Integration):
|
|||
logo_alt: Optional[str]=None, git_url: Optional[str]=None,
|
||||
legacy: bool=False) -> None:
|
||||
if logo_alt is None:
|
||||
logo_alt = "{} logo".format(name.title())
|
||||
logo_alt = f"{name.title()} logo"
|
||||
self.logo_alt = logo_alt
|
||||
|
||||
if git_url is None:
|
||||
|
|
|
@ -170,7 +170,7 @@ def find_log_origin(record: logging.LogRecord) -> str:
|
|||
# responsible for the request in the logs.
|
||||
from zerver.tornado.ioloop_logging import logging_data
|
||||
shard = logging_data.get('port', 'unknown')
|
||||
logger_name = "{}:{}".format(logger_name, shard)
|
||||
logger_name = f"{logger_name}:{shard}"
|
||||
|
||||
return logger_name
|
||||
|
||||
|
|
|
@ -116,7 +116,7 @@ class RateLimitedUser(RateLimitedObject):
|
|||
super().__init__(backend=backend)
|
||||
|
||||
def key(self) -> str:
|
||||
return "{}:{}:{}".format(type(self).__name__, self.user.id, self.domain)
|
||||
return f"{type(self).__name__}:{self.user.id}:{self.domain}"
|
||||
|
||||
def rules(self) -> List[Tuple[int, int]]:
|
||||
# user.rate_limits are general limits, applicable to the domain 'api_by_user'
|
||||
|
@ -294,7 +294,7 @@ class TornadoInMemoryRateLimiterBackend(RateLimiterBackend):
|
|||
class RedisRateLimiterBackend(RateLimiterBackend):
|
||||
@classmethod
|
||||
def get_keys(cls, entity_key: str) -> List[str]:
|
||||
return ["{}ratelimit:{}:{}".format(KEY_PREFIX, entity_key, keytype)
|
||||
return [f"{KEY_PREFIX}ratelimit:{entity_key}:{keytype}"
|
||||
for keytype in ['list', 'zset', 'block']]
|
||||
|
||||
@classmethod
|
||||
|
|
|
@ -60,7 +60,7 @@ def send_to_push_bouncer(method: str,
|
|||
except (requests.exceptions.Timeout, requests.exceptions.SSLError,
|
||||
requests.exceptions.ConnectionError) as e:
|
||||
raise PushNotificationBouncerRetryLaterError(
|
||||
"{} while trying to connect to push notification bouncer".format(e.__class__.__name__))
|
||||
f"{e.__class__.__name__} while trying to connect to push notification bouncer")
|
||||
|
||||
if res.status_code >= 500:
|
||||
# 500s should be resolved by the people who run the push
|
||||
|
|
|
@ -329,7 +329,7 @@ class ZulipTestCase(TestCase):
|
|||
return None
|
||||
else:
|
||||
self.assert_json_success(result)
|
||||
bot_email = '{}-bot@zulip.testserver'.format(short_name)
|
||||
bot_email = f'{short_name}-bot@zulip.testserver'
|
||||
bot_profile = get_user(bot_email, user_profile.realm)
|
||||
return bot_profile
|
||||
|
||||
|
@ -865,7 +865,7 @@ class ZulipTestCase(TestCase):
|
|||
the attribute only for the specific test function that calls this method,
|
||||
and is isolated from other tests.
|
||||
"""
|
||||
dn = "uid={username},ou=users,dc=zulip,dc=com".format(username=username)
|
||||
dn = f"uid={username},ou=users,dc=zulip,dc=com"
|
||||
if binary:
|
||||
with open(attr_value, "rb") as f:
|
||||
# attr_value should be a path to the file with the binary data
|
||||
|
@ -884,7 +884,7 @@ class ZulipTestCase(TestCase):
|
|||
return self.example_user_ldap_username_map[username]
|
||||
|
||||
def ldap_password(self, uid: str) -> str:
|
||||
return "{}_ldap_password".format(uid)
|
||||
return f"{uid}_ldap_password"
|
||||
|
||||
class WebhookTestCase(ZulipTestCase):
|
||||
"""
|
||||
|
@ -955,15 +955,15 @@ class WebhookTestCase(ZulipTestCase):
|
|||
|
||||
has_arguments = kwargs or args
|
||||
if has_arguments and url.find('?') == -1:
|
||||
url = "{}?".format(url) # nocoverage
|
||||
url = f"{url}?" # nocoverage
|
||||
else:
|
||||
url = "{}&".format(url)
|
||||
url = f"{url}&"
|
||||
|
||||
for key, value in kwargs.items():
|
||||
url = "{}{}={}&".format(url, key, value)
|
||||
url = f"{url}{key}={value}&"
|
||||
|
||||
for arg in args:
|
||||
url = "{}{}&".format(url, arg)
|
||||
url = f"{url}{arg}&"
|
||||
|
||||
return url[:-1] if has_arguments else url
|
||||
|
||||
|
@ -995,7 +995,7 @@ class MigrationsTestCase(ZulipTestCase): # nocoverage
|
|||
|
||||
def setUp(self) -> None:
|
||||
assert self.migrate_from and self.migrate_to, \
|
||||
"TestCase '{}' must define migrate_from and migrate_to properties".format(type(self).__name__)
|
||||
f"TestCase '{type(self).__name__}' must define migrate_from and migrate_to properties"
|
||||
migrate_from: List[Tuple[str, str]] = [(self.app, self.migrate_from)]
|
||||
migrate_to: List[Tuple[str, str]] = [(self.app, self.migrate_to)]
|
||||
executor = MigrationExecutor(connection)
|
||||
|
|
|
@ -345,7 +345,7 @@ def destroy_leaked_test_databases(expiry_time: int = 60 * 60) -> int:
|
|||
if round(time.time()) - os.path.getmtime(file) < expiry_time:
|
||||
with open(file) as f:
|
||||
for line in f:
|
||||
databases_in_use.add('zulip_test_template_{}'.format(line).rstrip())
|
||||
databases_in_use.add(f'zulip_test_template_{line}'.rstrip())
|
||||
else:
|
||||
# Any test-backend run older than expiry_time can be
|
||||
# cleaned up, both the database and the file listing its
|
||||
|
|
|
@ -43,12 +43,12 @@ random_id_range_start = str(random.randint(1, 10000000))
|
|||
|
||||
def get_database_id(worker_id: Optional[int]=None) -> str:
|
||||
if worker_id:
|
||||
return "{}_{}".format(random_id_range_start, worker_id)
|
||||
return f"{random_id_range_start}_{worker_id}"
|
||||
return random_id_range_start
|
||||
|
||||
# The root directory for this run of the test suite.
|
||||
TEST_RUN_DIR = get_or_create_dev_uuid_var_path(
|
||||
os.path.join('test-backend', 'run_{}'.format(get_database_id())))
|
||||
os.path.join('test-backend', f'run_{get_database_id()}'))
|
||||
|
||||
_worker_id = 0 # Used to identify the worker process.
|
||||
|
||||
|
@ -165,7 +165,7 @@ class TextTestResult(runner.TextTestResult):
|
|||
|
||||
def startTest(self, test: TestCase) -> None:
|
||||
TestResult.startTest(self, test)
|
||||
self.stream.writeln("Running {}".format(full_test_name(test))) # type: ignore[attr-defined] # https://github.com/python/typeshed/issues/3139
|
||||
self.stream.writeln(f"Running {full_test_name(test)}") # type: ignore[attr-defined] # https://github.com/python/typeshed/issues/3139
|
||||
self.stream.flush() # type: ignore[attr-defined] # https://github.com/python/typeshed/issues/3139
|
||||
|
||||
def addSuccess(self, *args: Any, **kwargs: Any) -> None:
|
||||
|
@ -382,7 +382,7 @@ def check_import_error(test_name: str) -> None:
|
|||
def initialize_worker_path(worker_id: int) -> None:
|
||||
# Allow each test worker process to write to a unique directory
|
||||
# within `TEST_RUN_DIR`.
|
||||
worker_path = os.path.join(TEST_RUN_DIR, 'worker_{}'.format(_worker_id))
|
||||
worker_path = os.path.join(TEST_RUN_DIR, f'worker_{_worker_id}')
|
||||
os.makedirs(worker_path, exist_ok=True)
|
||||
settings.TEST_WORKER_DIR = worker_path
|
||||
|
||||
|
|
|
@ -247,7 +247,7 @@ def validate_user_custom_profile_field(realm_id: int, field: CustomProfileField,
|
|||
value: Union[int, str, List[int]]) -> Optional[str]:
|
||||
validators = CustomProfileField.FIELD_VALIDATORS
|
||||
field_type = field.field_type
|
||||
var_name = '{}'.format(field.name)
|
||||
var_name = f'{field.name}'
|
||||
if field_type in validators:
|
||||
validator = validators[field_type]
|
||||
result = validator(var_name, value)
|
||||
|
|
|
@ -91,7 +91,7 @@ def get_push_commits_event_message(user_name: str, compare_url: Optional[str],
|
|||
committers_details = "{} ({})".format(*committers_items[0])
|
||||
|
||||
for name, number_of_commits in committers_items[1:-1]:
|
||||
committers_details = "{}, {} ({})".format(committers_details, name, number_of_commits)
|
||||
committers_details = f"{committers_details}, {name} ({number_of_commits})"
|
||||
|
||||
if len(committers_items) > 1:
|
||||
committers_details = "{} and {} ({})".format(committers_details, *committers_items[-1])
|
||||
|
@ -140,7 +140,7 @@ def get_pull_request_event_message(user_name: str, action: str, url: str, number
|
|||
'action': action,
|
||||
'type': type,
|
||||
'url': url,
|
||||
'id': ' #{}'.format(number) if number is not None else '',
|
||||
'id': f' #{number}' if number is not None else '',
|
||||
'title': title,
|
||||
}
|
||||
|
||||
|
@ -162,19 +162,19 @@ def get_pull_request_event_message(user_name: str, action: str, url: str, number
|
|||
|
||||
assignee_info = PULL_REQUEST_OR_ISSUE_ASSIGNEE_INFO_TEMPLATE.format(
|
||||
assignee=assignees_string)
|
||||
main_message = "{} {}".format(main_message, assignee_info)
|
||||
main_message = f"{main_message} {assignee_info}"
|
||||
|
||||
elif assignee:
|
||||
assignee_info = PULL_REQUEST_OR_ISSUE_ASSIGNEE_INFO_TEMPLATE.format(
|
||||
assignee=assignee)
|
||||
main_message = "{} {}".format(main_message, assignee_info)
|
||||
main_message = f"{main_message} {assignee_info}"
|
||||
|
||||
if target_branch and base_branch:
|
||||
branch_info = PULL_REQUEST_BRANCH_INFO_TEMPLATE.format(
|
||||
target=target_branch,
|
||||
base=base_branch
|
||||
)
|
||||
main_message = "{} {}".format(main_message, branch_info)
|
||||
main_message = f"{main_message} {branch_info}"
|
||||
|
||||
punctuation = ':' if message else '.'
|
||||
if (assignees or assignee or (target_branch and base_branch) or (title is None)):
|
||||
|
@ -195,7 +195,7 @@ def get_setup_webhook_message(integration: str, user_name: Optional[str]=None) -
|
|||
content = SETUP_MESSAGE_TEMPLATE.format(integration=integration)
|
||||
if user_name:
|
||||
content += SETUP_MESSAGE_USER_PART.format(user_name=user_name)
|
||||
content = "{}.".format(content)
|
||||
content = f"{content}."
|
||||
return content
|
||||
|
||||
def get_issue_event_message(user_name: str,
|
||||
|
@ -234,7 +234,7 @@ def get_push_tag_event_message(user_name: str,
|
|||
)
|
||||
|
||||
if tag_name[-1] not in string.punctuation:
|
||||
message = '{}.'.format(message)
|
||||
message = f'{message}.'
|
||||
|
||||
return message
|
||||
|
||||
|
@ -250,7 +250,7 @@ def get_commits_comment_action_message(user_name: str,
|
|||
url=commit_url
|
||||
)
|
||||
punctuation = ':' if message else '.'
|
||||
content = '{}{}'.format(content, punctuation)
|
||||
content = f'{content}{punctuation}'
|
||||
if message:
|
||||
content += CONTENT_MESSAGE_TEMPLATE.format(
|
||||
message=message
|
||||
|
|
|
@ -57,7 +57,7 @@ class Command(compilemessages.Command):
|
|||
return po_template.format(locale_path, locale)
|
||||
|
||||
def get_json_filename(self, locale_path: str, locale: str) -> str:
|
||||
return "{}/{}/translations.json".format(locale_path, locale)
|
||||
return f"{locale_path}/{locale}/translations.json"
|
||||
|
||||
def get_name_from_po_file(self, po_filename: str, locale: str) -> str:
|
||||
lang_name_re = re.compile(r'"Language-Team: (.*?) \(')
|
||||
|
@ -67,7 +67,7 @@ class Command(compilemessages.Command):
|
|||
try:
|
||||
return result.group(1)
|
||||
except Exception:
|
||||
print("Problem in parsing {}".format(po_filename))
|
||||
print(f"Problem in parsing {po_filename}")
|
||||
raise
|
||||
else:
|
||||
raise Exception("Unknown language %s" % (locale,))
|
||||
|
@ -85,8 +85,8 @@ class Command(compilemessages.Command):
|
|||
return locales
|
||||
|
||||
def extract_language_options(self) -> None:
|
||||
locale_path = "{}/locale".format(settings.DEPLOY_ROOT)
|
||||
output_path = "{}/language_options.json".format(locale_path)
|
||||
locale_path = f"{settings.DEPLOY_ROOT}/locale"
|
||||
output_path = f"{locale_path}/language_options.json"
|
||||
|
||||
data: Dict[str, List[Dict[str, Any]]] = {'languages': []}
|
||||
|
||||
|
|
|
@ -164,9 +164,9 @@ class Command(ZulipBaseCommand):
|
|||
if reaction.user_profile.realm != realm:
|
||||
raise CommandError("Users from a different realm reacted to message. Aborting...")
|
||||
|
||||
print("\n\033[94mMessage content:\033[0m\n{}\n".format(message.content))
|
||||
print(f"\n\033[94mMessage content:\033[0m\n{message.content}\n")
|
||||
|
||||
print("\033[94mNumber of users that reacted outbox:\033[0m {}\n".format(len(reactions)))
|
||||
print(f"\033[94mNumber of users that reacted outbox:\033[0m {len(reactions)}\n")
|
||||
|
||||
# Allows us to trigger exports separately from command line argument parsing
|
||||
export_realm_wrapper(realm=realm, output_dir=output_dir,
|
||||
|
|
|
@ -71,7 +71,7 @@ class Command(makemessages.Command):
|
|||
|
||||
xgettext_options = makemessages.Command.xgettext_options
|
||||
for func, tag in tags:
|
||||
xgettext_options += ['--keyword={}:1,"{}"'.format(func, tag)]
|
||||
xgettext_options += [f'--keyword={func}:1,"{tag}"']
|
||||
|
||||
def add_arguments(self, parser: ArgumentParser) -> None:
|
||||
super().add_arguments(parser)
|
||||
|
@ -241,7 +241,7 @@ class Command(makemessages.Command):
|
|||
|
||||
def write_translation_strings(self, translation_strings: List[str]) -> None:
|
||||
for locale, output_path in zip(self.get_locales(), self.get_output_paths()):
|
||||
self.stdout.write("[frontend] processing locale {}".format(locale))
|
||||
self.stdout.write(f"[frontend] processing locale {locale}")
|
||||
try:
|
||||
with open(output_path) as reader:
|
||||
old_strings = json.load(reader)
|
||||
|
|
|
@ -89,7 +89,7 @@ Example:
|
|||
|
||||
def _parse_email_fixture(self, fixture_path: str) -> Message:
|
||||
if not self._does_fixture_path_exist(fixture_path):
|
||||
raise CommandError('Fixture {} does not exist'.format(fixture_path))
|
||||
raise CommandError(f'Fixture {fixture_path} does not exist')
|
||||
|
||||
if fixture_path.endswith('.json'):
|
||||
message = self._parse_email_json_fixture(fixture_path)
|
||||
|
|
|
@ -153,7 +153,7 @@ def render_javascript_code_example(function: str, admin_config: Optional[bool]=F
|
|||
for line in snippet:
|
||||
result = re.search('const result.*=(.*);', line)
|
||||
if result:
|
||||
line = " return{};".format(result.group(1))
|
||||
line = f" return{result.group(1)};"
|
||||
# Strip newlines
|
||||
code_example.append(line.rstrip())
|
||||
code_example.append("}).then(console.log).catch(console.err);")
|
||||
|
@ -167,7 +167,7 @@ def curl_method_arguments(endpoint: str, method: str,
|
|||
api_url: str) -> List[str]:
|
||||
# We also include the -sS verbosity arguments here.
|
||||
method = method.upper()
|
||||
url = "{}/v1{}".format(api_url, endpoint)
|
||||
url = f"{api_url}/v1{endpoint}"
|
||||
valid_methods = ["GET", "POST", "DELETE", "PUT", "PATCH", "OPTIONS"]
|
||||
if method == "GET":
|
||||
# Then we need to make sure that each -d option translates to becoming
|
||||
|
@ -206,7 +206,7 @@ cURL example.""".format(endpoint, method, param_name)
|
|||
raise ValueError(msg)
|
||||
ordered_ex_val_str = json.dumps(example_value, sort_keys=True)
|
||||
if curl_argument:
|
||||
return " --data-urlencode {}='{}'".format(param_name, ordered_ex_val_str)
|
||||
return f" --data-urlencode {param_name}='{ordered_ex_val_str}'"
|
||||
return ordered_ex_val_str # nocoverage
|
||||
else:
|
||||
example_value = param.get("example", DEFAULT_EXAMPLE[param_type])
|
||||
|
@ -215,7 +215,7 @@ cURL example.""".format(endpoint, method, param_name)
|
|||
if jsonify:
|
||||
example_value = json.dumps(example_value)
|
||||
if curl_argument:
|
||||
return " -d '{}={}'".format(param_name, example_value)
|
||||
return f" -d '{param_name}={example_value}'"
|
||||
return example_value
|
||||
|
||||
def generate_curl_example(endpoint: str, method: str,
|
||||
|
|
|
@ -185,7 +185,7 @@ def validate_object(content: Dict[str, Any], schema: Dict[str, Any]) -> None:
|
|||
# If the object is not opaque then continue statements
|
||||
# will be executed above and this will be skipped
|
||||
if expected_type is dict:
|
||||
raise SchemaError('Opaque object "{}"'.format(key))
|
||||
raise SchemaError(f'Opaque object "{key}"')
|
||||
# Check that at least all the required keys are present
|
||||
if 'required' in schema:
|
||||
for req_key in schema['required']:
|
||||
|
|
|
@ -97,7 +97,7 @@ def test_authorization_errors_fatal(client: Client, nonadmin_client: Client) ->
|
|||
|
||||
stream_id = client.get_stream_id('private_stream')['stream_id']
|
||||
client.call_endpoint(
|
||||
'streams/{}'.format(stream_id),
|
||||
f'streams/{stream_id}',
|
||||
method='PATCH',
|
||||
request={'is_private': True}
|
||||
)
|
||||
|
@ -945,7 +945,7 @@ def upload_custom_emoji(client: Client) -> None:
|
|||
with open(emoji_path, 'rb') as fp:
|
||||
emoji_name = 'my_custom_emoji'
|
||||
result = client.call_endpoint(
|
||||
'realm/emoji/{}'.format(emoji_name),
|
||||
f'realm/emoji/{emoji_name}',
|
||||
method='POST',
|
||||
files=[fp]
|
||||
)
|
||||
|
@ -1064,8 +1064,8 @@ def test_against_fixture(result: Dict[str, Any], fixture: Dict[str, Any], check_
|
|||
|
||||
def assertEqual(key: str, result: Dict[str, Any], fixture: Dict[str, Any]) -> None:
|
||||
if result[key] != fixture[key]:
|
||||
first = "{key} = {value}".format(key=key, value=result[key])
|
||||
second = "{key} = {value}".format(key=key, value=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:
|
||||
|
@ -1083,7 +1083,7 @@ def assertLength(result: Dict[str, Any], fixture: Dict[str, Any]) -> None:
|
|||
def assertIn(key: str, result: Dict[str, Any]) -> None:
|
||||
if key not in result.keys():
|
||||
raise AssertionError(
|
||||
"The actual output does not contain the the key `{key}`.".format(key=key)
|
||||
f"The actual output does not contain the the key `{key}`."
|
||||
)
|
||||
else:
|
||||
assert key in result
|
||||
|
|
|
@ -11,7 +11,7 @@ from zerver.models import get_realm
|
|||
from zerver.openapi.curl_param_value_generators import REGISTERED_GENERATOR_FUNCTIONS, CALLED_GENERATOR_FUNCTIONS
|
||||
|
||||
def test_generated_curl_examples_for_success(client: Client) -> None:
|
||||
authentication_line = "{}:{}".format(client.email, client.api_key)
|
||||
authentication_line = f"{client.email}:{client.api_key}"
|
||||
# A limited markdown engine that just processes the code example syntax.
|
||||
realm = get_realm("zulip")
|
||||
md_engine = markdown.Markdown(extensions=[markdown_extension.makeExtension(
|
||||
|
|
|
@ -87,7 +87,7 @@ def email_on_new_login(sender: Any, user: UserProfile, request: Any, **kwargs: A
|
|||
hhmm_string = local_time.strftime('%H:%M')
|
||||
else:
|
||||
hhmm_string = local_time.strftime('%I:%M%p')
|
||||
context['login_time'] = local_time.strftime('%A, %B %d, %Y at {} %Z'.format(hhmm_string))
|
||||
context['login_time'] = local_time.strftime(f'%A, %B %d, %Y at {hhmm_string} %Z')
|
||||
context['device_ip'] = request.META.get('REMOTE_ADDR') or _("Unknown IP address")
|
||||
context['device_os'] = get_device_os(user_agent) or _("an unknown operating system")
|
||||
context['device_browser'] = get_device_browser(user_agent) or _("An unknown browser")
|
||||
|
|
|
@ -26,14 +26,14 @@ class AttachmentsTests(ZulipTestCase):
|
|||
user_profile = self.example_user('cordelia')
|
||||
self.login_user(user_profile)
|
||||
with mock.patch('zerver.lib.attachments.delete_message_image', side_effect=Exception()):
|
||||
result = self.client_delete('/json/attachments/{id}'.format(id=self.attachment.id))
|
||||
result = self.client_delete(f'/json/attachments/{self.attachment.id}')
|
||||
self.assert_json_error(result, "An error occurred while deleting the attachment. Please try again later.")
|
||||
|
||||
@mock.patch('zerver.lib.attachments.delete_message_image')
|
||||
def test_remove_attachment(self, ignored: Any) -> None:
|
||||
user_profile = self.example_user('cordelia')
|
||||
self.login_user(user_profile)
|
||||
result = self.client_delete('/json/attachments/{id}'.format(id=self.attachment.id))
|
||||
result = self.client_delete(f'/json/attachments/{self.attachment.id}')
|
||||
self.assert_json_success(result)
|
||||
attachments = user_attachments(user_profile)
|
||||
self.assertEqual(attachments, [])
|
||||
|
@ -48,7 +48,7 @@ class AttachmentsTests(ZulipTestCase):
|
|||
def test_remove_another_user(self) -> None:
|
||||
user_profile = self.example_user('iago')
|
||||
self.login_user(user_profile)
|
||||
result = self.client_delete('/json/attachments/{id}'.format(id=self.attachment.id))
|
||||
result = self.client_delete(f'/json/attachments/{self.attachment.id}')
|
||||
self.assert_json_error(result, 'Invalid attachment')
|
||||
user_profile_to_remove = self.example_user('cordelia')
|
||||
attachments = user_attachments(user_profile_to_remove)
|
||||
|
@ -59,5 +59,5 @@ class AttachmentsTests(ZulipTestCase):
|
|||
self.assert_json_error(result, 'Not logged in: API authentication or user session required', status_code=401)
|
||||
|
||||
def test_delete_unauthenticated(self) -> None:
|
||||
result = self.client_delete('/json/attachments/{id}'.format(id=self.attachment.id))
|
||||
result = self.client_delete(f'/json/attachments/{self.attachment.id}')
|
||||
self.assert_json_error(result, 'Not logged in: API authentication or user session required', status_code=401)
|
||||
|
|
|
@ -491,7 +491,7 @@ class RateLimitAuthenticationTests(ZulipTestCase):
|
|||
salt = generate_random_token(32)
|
||||
|
||||
def _mock_key(self: RateLimitedAuthenticationByUsername) -> str:
|
||||
return "{}:{}".format(salt, original_key_method(self))
|
||||
return f"{salt}:{original_key_method(self)}"
|
||||
|
||||
def attempt_authentication(username: str, password: str) -> Optional[UserProfile]:
|
||||
request = HttpRequest()
|
||||
|
@ -1291,7 +1291,7 @@ class SocialAuthBase(DesktopFlowTestingLib, ZulipTestCase):
|
|||
ldap_user_attr_map = {'full_name': 'cn'}
|
||||
account_data_dict = self.get_account_data_dict(email=email, name=name)
|
||||
|
||||
backend_path = 'zproject.backends.{}'.format(self.BACKEND_CLASS.__name__)
|
||||
backend_path = f'zproject.backends.{self.BACKEND_CLASS.__name__}'
|
||||
with self.settings(
|
||||
POPULATE_PROFILE_VIA_LDAP=True,
|
||||
LDAP_APPEND_DOMAIN='zulip.com',
|
||||
|
@ -1333,7 +1333,7 @@ class SocialAuthBase(DesktopFlowTestingLib, ZulipTestCase):
|
|||
ldap_user_attr_map = {'full_name': 'cn'}
|
||||
account_data_dict = self.get_account_data_dict(email=email, name=name)
|
||||
|
||||
backend_path = 'zproject.backends.{}'.format(self.BACKEND_CLASS.__name__)
|
||||
backend_path = f'zproject.backends.{self.BACKEND_CLASS.__name__}'
|
||||
with self.settings(
|
||||
POPULATE_PROFILE_VIA_LDAP=True,
|
||||
LDAP_EMAIL_ATTR='mail',
|
||||
|
@ -1503,7 +1503,7 @@ class SAMLAuthBackendTest(SocialAuthBase):
|
|||
self.assertTrue(saml_auth_enabled())
|
||||
result = self.client_get("/saml/metadata.xml")
|
||||
self.assert_in_success_response(
|
||||
['entityID="{}"'.format(settings.SOCIAL_AUTH_SAML_SP_ENTITY_ID)], result
|
||||
[f'entityID="{settings.SOCIAL_AUTH_SAML_SP_ENTITY_ID}"'], result
|
||||
)
|
||||
|
||||
def test_social_auth_complete(self) -> None:
|
||||
|
@ -1737,17 +1737,17 @@ class SAMLAuthBackendTest(SocialAuthBase):
|
|||
|
||||
def test_social_auth_saml_login_bad_idp_arg(self) -> None:
|
||||
for action in ['login', 'register']:
|
||||
result = self.client_get('/accounts/{}/social/saml'.format(action))
|
||||
result = self.client_get(f'/accounts/{action}/social/saml')
|
||||
# Missing idp argument.
|
||||
self.assertEqual(result.status_code, 302)
|
||||
self.assertEqual(result.url, '/config-error/saml')
|
||||
|
||||
result = self.client_get('/accounts/{}/social/saml/nonexistent_idp'.format(action))
|
||||
result = self.client_get(f'/accounts/{action}/social/saml/nonexistent_idp')
|
||||
# No such IdP is configured.
|
||||
self.assertEqual(result.status_code, 302)
|
||||
self.assertEqual(result.url, '/config-error/saml')
|
||||
|
||||
result = self.client_get('/accounts/{}/social/saml/'.format(action))
|
||||
result = self.client_get(f'/accounts/{action}/social/saml/')
|
||||
# No matching url pattern.
|
||||
self.assertEqual(result.status_code, 404)
|
||||
|
||||
|
@ -4327,7 +4327,7 @@ class TestMaybeSendToRegistration(ZulipTestCase):
|
|||
|
||||
result = self.client_get(result.url)
|
||||
self.assert_in_response('action="/accounts/register/"', result)
|
||||
self.assert_in_response('value="{}" name="key"'.format(confirmation_key), result)
|
||||
self.assert_in_response(f'value="{confirmation_key}" name="key"', result)
|
||||
|
||||
def test_sso_only_when_preregistration_user_exists(self) -> None:
|
||||
rf = RequestFactory()
|
||||
|
|
|
@ -70,7 +70,7 @@ class BotTest(ZulipTestCase, UploadSerializeMixin):
|
|||
|
||||
def deactivate_bot(self) -> None:
|
||||
email = 'hambot-bot@zulip.testserver'
|
||||
result = self.client_delete("/json/bots/{}".format(self.get_bot_user(email).id))
|
||||
result = self.client_delete(f"/json/bots/{self.get_bot_user(email).id}")
|
||||
self.assert_json_success(result)
|
||||
|
||||
def test_add_bot_with_bad_username(self) -> None:
|
||||
|
@ -541,7 +541,7 @@ class BotTest(ZulipTestCase, UploadSerializeMixin):
|
|||
self.create_bot()
|
||||
self.assert_num_bots_equal(1)
|
||||
invalid_user_id = 1000
|
||||
result = self.client_delete("/json/bots/{}".format(invalid_user_id))
|
||||
result = self.client_delete(f"/json/bots/{invalid_user_id}")
|
||||
self.assert_json_error(result, 'No such bot')
|
||||
self.assert_num_bots_equal(1)
|
||||
|
||||
|
@ -591,7 +591,7 @@ class BotTest(ZulipTestCase, UploadSerializeMixin):
|
|||
bot_email = result.json()['bots'][0]['username']
|
||||
bot = get_user(bot_email, user.realm)
|
||||
self.login('iago')
|
||||
result = self.client_delete("/json/bots/{}".format(bot.id))
|
||||
result = self.client_delete(f"/json/bots/{bot.id}")
|
||||
self.assert_json_error(result, 'No such bot')
|
||||
|
||||
def test_bot_deactivation_attacks(self) -> None:
|
||||
|
@ -610,7 +610,7 @@ class BotTest(ZulipTestCase, UploadSerializeMixin):
|
|||
self.assert_json_error(result, 'No such bot')
|
||||
|
||||
email = 'hambot-bot@zulip.testserver'
|
||||
result = self.client_delete("/json/bots/{}".format(self.get_bot_user(email).id))
|
||||
result = self.client_delete(f"/json/bots/{self.get_bot_user(email).id}")
|
||||
self.assert_json_error(result, 'Insufficient permission')
|
||||
|
||||
# But we don't actually deactivate the other person's bot.
|
||||
|
@ -618,7 +618,7 @@ class BotTest(ZulipTestCase, UploadSerializeMixin):
|
|||
self.assert_num_bots_equal(1)
|
||||
|
||||
# Cannot deactivate a bot as a user
|
||||
result = self.client_delete("/json/users/{}".format(self.get_bot_user(email).id))
|
||||
result = self.client_delete(f"/json/users/{self.get_bot_user(email).id}")
|
||||
self.assert_json_error(result, 'No such user')
|
||||
self.assert_num_bots_equal(1)
|
||||
|
||||
|
@ -632,13 +632,13 @@ class BotTest(ZulipTestCase, UploadSerializeMixin):
|
|||
self.login('othello')
|
||||
email = 'hambot-bot@zulip.testserver'
|
||||
|
||||
result = self.client_post("/json/bots/{}/api_key/regenerate".format(self.get_bot_user(email).id))
|
||||
result = self.client_post(f"/json/bots/{self.get_bot_user(email).id}/api_key/regenerate")
|
||||
self.assert_json_error(result, 'Insufficient permission')
|
||||
|
||||
bot_info = {
|
||||
'full_name': 'Fred',
|
||||
}
|
||||
result = self.client_patch("/json/bots/{}".format(self.get_bot_user(email).id), bot_info)
|
||||
result = self.client_patch(f"/json/bots/{self.get_bot_user(email).id}", bot_info)
|
||||
self.assert_json_error(result, 'Insufficient permission')
|
||||
|
||||
def get_bot(self) -> Dict[str, Any]:
|
||||
|
@ -652,7 +652,7 @@ class BotTest(ZulipTestCase, UploadSerializeMixin):
|
|||
bot = self.get_bot()
|
||||
old_api_key = bot['api_key']
|
||||
email = 'hambot-bot@zulip.testserver'
|
||||
result = self.client_post('/json/bots/{}/api_key/regenerate'.format(self.get_bot_user(email).id))
|
||||
result = self.client_post(f'/json/bots/{self.get_bot_user(email).id}/api_key/regenerate')
|
||||
self.assert_json_success(result)
|
||||
new_api_key = result.json()['api_key']
|
||||
self.assertNotEqual(old_api_key, new_api_key)
|
||||
|
@ -662,7 +662,7 @@ class BotTest(ZulipTestCase, UploadSerializeMixin):
|
|||
def test_update_api_key_for_invalid_user(self) -> None:
|
||||
self.login('hamlet')
|
||||
invalid_user_id = 1000
|
||||
result = self.client_post('/json/bots/{}/api_key/regenerate'.format(invalid_user_id))
|
||||
result = self.client_post(f'/json/bots/{invalid_user_id}/api_key/regenerate')
|
||||
self.assert_json_error(result, 'No such bot')
|
||||
|
||||
def test_add_bot_with_bot_type_default(self) -> None:
|
||||
|
@ -810,7 +810,7 @@ class BotTest(ZulipTestCase, UploadSerializeMixin):
|
|||
'full_name': 'Fred',
|
||||
}
|
||||
email = 'hambot-bot@zulip.testserver'
|
||||
result = self.client_patch("/json/bots/{}".format(self.get_bot_user(email).id), bot_info)
|
||||
result = self.client_patch(f"/json/bots/{self.get_bot_user(email).id}", bot_info)
|
||||
self.assert_json_success(result)
|
||||
|
||||
self.assertEqual('Fred', result.json()['full_name'])
|
||||
|
@ -832,7 +832,7 @@ class BotTest(ZulipTestCase, UploadSerializeMixin):
|
|||
|
||||
bot_email = 'hambot-bot@zulip.testserver'
|
||||
bot = self.get_bot_user(bot_email)
|
||||
url = "/json/bots/{}".format(bot.id)
|
||||
url = f"/json/bots/{bot.id}"
|
||||
|
||||
# It doesn't matter whether a name is taken by a human
|
||||
# or a bot, we can't use it.
|
||||
|
@ -890,7 +890,7 @@ class BotTest(ZulipTestCase, UploadSerializeMixin):
|
|||
'bot_owner_id': othello.id,
|
||||
}
|
||||
email = 'hambot-bot@zulip.testserver'
|
||||
result = self.client_patch("/json/bots/{}".format(self.get_bot_user(email).id), bot_info)
|
||||
result = self.client_patch(f"/json/bots/{self.get_bot_user(email).id}", bot_info)
|
||||
self.assert_json_success(result)
|
||||
|
||||
# Test bot's owner has been changed successfully.
|
||||
|
@ -912,7 +912,7 @@ class BotTest(ZulipTestCase, UploadSerializeMixin):
|
|||
bot_info = {
|
||||
'bot_owner_id': bad_bot_owner_id,
|
||||
}
|
||||
result = self.client_patch("/json/bots/{}".format(self.get_bot_user(email).id), bot_info)
|
||||
result = self.client_patch(f"/json/bots/{self.get_bot_user(email).id}", bot_info)
|
||||
self.assert_json_error(result, "Failed to change owner, no such user")
|
||||
profile = get_user('hambot-bot@zulip.testserver', get_realm('zulip'))
|
||||
self.assertEqual(profile.bot_owner, self.example_user("hamlet"))
|
||||
|
@ -931,7 +931,7 @@ class BotTest(ZulipTestCase, UploadSerializeMixin):
|
|||
}
|
||||
|
||||
email = 'hambot-bot@zulip.testserver'
|
||||
result = self.client_patch("/json/bots/{}".format(self.get_bot_user(email).id), bot_info)
|
||||
result = self.client_patch(f"/json/bots/{self.get_bot_user(email).id}", bot_info)
|
||||
self.assert_json_error(result, "Failed to change owner, user is deactivated")
|
||||
profile = self.get_bot_user(email)
|
||||
self.assertEqual(profile.bot_owner, self.example_user("hamlet"))
|
||||
|
@ -946,7 +946,7 @@ class BotTest(ZulipTestCase, UploadSerializeMixin):
|
|||
}
|
||||
|
||||
email = 'hambot-bot@zulip.testserver'
|
||||
result = self.client_patch("/json/bots/{}".format(self.get_bot_user(email).id), bot_info)
|
||||
result = self.client_patch(f"/json/bots/{self.get_bot_user(email).id}", bot_info)
|
||||
self.assert_json_error(result, "Failed to change owner, no such user")
|
||||
profile = self.get_bot_user(email)
|
||||
self.assertEqual(profile.bot_owner, self.example_user("hamlet"))
|
||||
|
@ -961,7 +961,7 @@ class BotTest(ZulipTestCase, UploadSerializeMixin):
|
|||
}
|
||||
|
||||
email = 'hambot-bot@zulip.testserver'
|
||||
result = self.client_patch("/json/bots/{}".format(self.get_bot_user(email).id), bot_info)
|
||||
result = self.client_patch(f"/json/bots/{self.get_bot_user(email).id}", bot_info)
|
||||
|
||||
# Check that we're still the owner
|
||||
self.assert_json_success(result)
|
||||
|
@ -984,7 +984,7 @@ class BotTest(ZulipTestCase, UploadSerializeMixin):
|
|||
'bot_owner_id': self.get_bot_user('hamelbot-bot@zulip.testserver').id,
|
||||
}
|
||||
email = 'hambot-bot@zulip.testserver'
|
||||
result = self.client_patch("/json/bots/{}".format(self.get_bot_user(email).id), bot_info)
|
||||
result = self.client_patch(f"/json/bots/{self.get_bot_user(email).id}", bot_info)
|
||||
self.assert_json_error(result, "Failed to change owner, bots can't own other bots")
|
||||
profile = get_user(email, get_realm('zulip'))
|
||||
self.assertEqual(profile.bot_owner, self.example_user("hamlet"))
|
||||
|
@ -1008,7 +1008,7 @@ class BotTest(ZulipTestCase, UploadSerializeMixin):
|
|||
with get_test_image_file('img.png') as fp1, \
|
||||
get_test_image_file('img.gif') as fp2:
|
||||
result = self.client_patch_multipart(
|
||||
'/json/bots/{}'.format(self.get_bot_user(email).id),
|
||||
f'/json/bots/{self.get_bot_user(email).id}',
|
||||
dict(file1=fp1, file2=fp2))
|
||||
self.assert_json_error(result, 'You may only upload one file at a time')
|
||||
|
||||
|
@ -1018,7 +1018,7 @@ class BotTest(ZulipTestCase, UploadSerializeMixin):
|
|||
# HAPPY PATH
|
||||
with get_test_image_file('img.png') as fp:
|
||||
result = self.client_patch_multipart(
|
||||
'/json/bots/{}'.format(self.get_bot_user(email).id),
|
||||
f'/json/bots/{self.get_bot_user(email).id}',
|
||||
dict(file=fp))
|
||||
profile = get_user(bot_email, bot_realm)
|
||||
self.assertEqual(profile.avatar_version, 2)
|
||||
|
@ -1043,7 +1043,7 @@ class BotTest(ZulipTestCase, UploadSerializeMixin):
|
|||
'default_sending_stream': 'Denmark',
|
||||
}
|
||||
email = 'hambot-bot@zulip.testserver'
|
||||
result = self.client_patch("/json/bots/{}".format(self.get_bot_user(email).id), bot_info)
|
||||
result = self.client_patch(f"/json/bots/{self.get_bot_user(email).id}", bot_info)
|
||||
self.assert_json_success(result)
|
||||
|
||||
self.assertEqual('Denmark', result.json()['default_sending_stream'])
|
||||
|
@ -1063,7 +1063,7 @@ class BotTest(ZulipTestCase, UploadSerializeMixin):
|
|||
'default_sending_stream': 'Rome',
|
||||
}
|
||||
email = 'hambot-bot@zulip.testserver'
|
||||
result = self.client_patch("/json/bots/{}".format(self.get_bot_user(email).id), bot_info)
|
||||
result = self.client_patch(f"/json/bots/{self.get_bot_user(email).id}", bot_info)
|
||||
self.assert_json_success(result)
|
||||
|
||||
self.assertEqual('Rome', result.json()['default_sending_stream'])
|
||||
|
@ -1083,7 +1083,7 @@ class BotTest(ZulipTestCase, UploadSerializeMixin):
|
|||
'default_sending_stream': '',
|
||||
}
|
||||
email = 'hambot-bot@zulip.testserver'
|
||||
result = self.client_patch("/json/bots/{}".format(self.get_bot_user(email).id), bot_info)
|
||||
result = self.client_patch(f"/json/bots/{self.get_bot_user(email).id}", bot_info)
|
||||
self.assert_json_success(result)
|
||||
|
||||
bot_email = "hambot-bot@zulip.testserver"
|
||||
|
@ -1111,7 +1111,7 @@ class BotTest(ZulipTestCase, UploadSerializeMixin):
|
|||
'default_sending_stream': 'Denmark',
|
||||
}
|
||||
email = 'hambot-bot@zulip.testserver'
|
||||
result = self.client_patch("/json/bots/{}".format(self.get_bot_user(email).id), bot_info)
|
||||
result = self.client_patch(f"/json/bots/{self.get_bot_user(email).id}", bot_info)
|
||||
self.assert_json_success(result)
|
||||
|
||||
self.assertEqual('Denmark', result.json()['default_sending_stream'])
|
||||
|
@ -1137,7 +1137,7 @@ class BotTest(ZulipTestCase, UploadSerializeMixin):
|
|||
'default_sending_stream': 'Denmark',
|
||||
}
|
||||
email = 'hambot-bot@zulip.testserver'
|
||||
result = self.client_patch("/json/bots/{}".format(self.get_bot_user(email).id), bot_info)
|
||||
result = self.client_patch(f"/json/bots/{self.get_bot_user(email).id}", bot_info)
|
||||
self.assert_json_error(result, "Invalid stream name 'Denmark'")
|
||||
|
||||
def test_patch_bot_to_stream_not_found(self) -> None:
|
||||
|
@ -1152,7 +1152,7 @@ class BotTest(ZulipTestCase, UploadSerializeMixin):
|
|||
'default_sending_stream': 'missing',
|
||||
}
|
||||
email = 'hambot-bot@zulip.testserver'
|
||||
result = self.client_patch("/json/bots/{}".format(self.get_bot_user(email).id), bot_info)
|
||||
result = self.client_patch(f"/json/bots/{self.get_bot_user(email).id}", bot_info)
|
||||
self.assert_json_error(result, "Invalid stream name 'missing'")
|
||||
|
||||
def test_patch_bot_events_register_stream(self) -> None:
|
||||
|
@ -1167,7 +1167,7 @@ class BotTest(ZulipTestCase, UploadSerializeMixin):
|
|||
|
||||
email = 'hambot-bot@zulip.testserver'
|
||||
bot_user = self.get_bot_user(email)
|
||||
url = "/json/bots/{}".format(bot_user.id)
|
||||
url = f"/json/bots/{bot_user.id}"
|
||||
|
||||
# Successfully give the bot a default stream.
|
||||
stream_name = 'Denmark'
|
||||
|
@ -1197,7 +1197,7 @@ class BotTest(ZulipTestCase, UploadSerializeMixin):
|
|||
self.assert_json_success(result)
|
||||
|
||||
# Make sure the bot cannot create their own default stream.
|
||||
url = "/api/v1/bots/{}".format(bot_user.id)
|
||||
url = f"/api/v1/bots/{bot_user.id}"
|
||||
result = self.api_patch(bot_user, url, bot_info)
|
||||
self.assert_json_error_contains(result, 'endpoint does not accept')
|
||||
|
||||
|
@ -1217,7 +1217,7 @@ class BotTest(ZulipTestCase, UploadSerializeMixin):
|
|||
'default_events_register_stream': 'Denmark',
|
||||
}
|
||||
email = 'hambot-bot@zulip.testserver'
|
||||
result = self.client_patch("/json/bots/{}".format(self.get_bot_user(email).id), bot_info)
|
||||
result = self.client_patch(f"/json/bots/{self.get_bot_user(email).id}", bot_info)
|
||||
self.assert_json_success(result)
|
||||
|
||||
self.assertEqual('Denmark', result.json()['default_events_register_stream'])
|
||||
|
@ -1242,7 +1242,7 @@ class BotTest(ZulipTestCase, UploadSerializeMixin):
|
|||
'default_events_register_stream': 'Denmark',
|
||||
}
|
||||
email = 'hambot-bot@zulip.testserver'
|
||||
result = self.client_patch("/json/bots/{}".format(self.get_bot_user(email).id), bot_info)
|
||||
result = self.client_patch(f"/json/bots/{self.get_bot_user(email).id}", bot_info)
|
||||
self.assert_json_error(result, "Invalid stream name 'Denmark'")
|
||||
|
||||
def test_patch_bot_events_register_stream_none(self) -> None:
|
||||
|
@ -1257,7 +1257,7 @@ class BotTest(ZulipTestCase, UploadSerializeMixin):
|
|||
'default_events_register_stream': '',
|
||||
}
|
||||
email = 'hambot-bot@zulip.testserver'
|
||||
result = self.client_patch("/json/bots/{}".format(self.get_bot_user(email).id), bot_info)
|
||||
result = self.client_patch(f"/json/bots/{self.get_bot_user(email).id}", bot_info)
|
||||
self.assert_json_success(result)
|
||||
|
||||
bot_email = "hambot-bot@zulip.testserver"
|
||||
|
@ -1280,7 +1280,7 @@ class BotTest(ZulipTestCase, UploadSerializeMixin):
|
|||
'default_events_register_stream': 'missing',
|
||||
}
|
||||
email = 'hambot-bot@zulip.testserver'
|
||||
result = self.client_patch("/json/bots/{}".format(self.get_bot_user(email).id), bot_info)
|
||||
result = self.client_patch(f"/json/bots/{self.get_bot_user(email).id}", bot_info)
|
||||
self.assert_json_error(result, "Invalid stream name 'missing'")
|
||||
|
||||
def test_patch_bot_default_all_public_streams_true(self) -> None:
|
||||
|
@ -1295,7 +1295,7 @@ class BotTest(ZulipTestCase, UploadSerializeMixin):
|
|||
'default_all_public_streams': ujson.dumps(True),
|
||||
}
|
||||
email = 'hambot-bot@zulip.testserver'
|
||||
result = self.client_patch("/json/bots/{}".format(self.get_bot_user(email).id), bot_info)
|
||||
result = self.client_patch(f"/json/bots/{self.get_bot_user(email).id}", bot_info)
|
||||
self.assert_json_success(result)
|
||||
|
||||
self.assertEqual(result.json()['default_all_public_streams'], True)
|
||||
|
@ -1315,7 +1315,7 @@ class BotTest(ZulipTestCase, UploadSerializeMixin):
|
|||
'default_all_public_streams': ujson.dumps(False),
|
||||
}
|
||||
email = 'hambot-bot@zulip.testserver'
|
||||
result = self.client_patch("/json/bots/{}".format(self.get_bot_user(email).id), bot_info)
|
||||
result = self.client_patch(f"/json/bots/{self.get_bot_user(email).id}", bot_info)
|
||||
self.assert_json_success(result)
|
||||
|
||||
self.assertEqual(result.json()['default_all_public_streams'], False)
|
||||
|
@ -1337,7 +1337,7 @@ class BotTest(ZulipTestCase, UploadSerializeMixin):
|
|||
}
|
||||
email = 'hambot-bot@zulip.testserver'
|
||||
# Important: We intentionally use the wrong method, post, here.
|
||||
result = self.client_post("/json/bots/{}".format(self.get_bot_user(email).id),
|
||||
result = self.client_post(f"/json/bots/{self.get_bot_user(email).id}",
|
||||
bot_info)
|
||||
self.assert_json_success(result)
|
||||
|
||||
|
@ -1354,7 +1354,7 @@ class BotTest(ZulipTestCase, UploadSerializeMixin):
|
|||
'full_name': 'Fred',
|
||||
}
|
||||
invalid_user_id = 1000
|
||||
result = self.client_patch("/json/bots/{}".format(invalid_user_id), bot_info)
|
||||
result = self.client_patch(f"/json/bots/{invalid_user_id}", bot_info)
|
||||
self.assert_json_error(result, 'No such bot')
|
||||
self.assert_num_bots_equal(1)
|
||||
|
||||
|
@ -1374,7 +1374,7 @@ class BotTest(ZulipTestCase, UploadSerializeMixin):
|
|||
'service_interface': Service.SLACK,
|
||||
}
|
||||
email = 'hambot-bot@zulip.testserver'
|
||||
result = self.client_patch("/json/bots/{}".format(self.get_bot_user(email).id), bot_info)
|
||||
result = self.client_patch(f"/json/bots/{self.get_bot_user(email).id}", bot_info)
|
||||
self.assert_json_success(result)
|
||||
|
||||
service_interface = ujson.loads(result.content)['service_interface']
|
||||
|
@ -1392,7 +1392,7 @@ class BotTest(ZulipTestCase, UploadSerializeMixin):
|
|||
config_data=ujson.dumps({'key': '12345678'}))
|
||||
bot_info = {'config_data': ujson.dumps({'key': '87654321'})}
|
||||
email = 'test-bot@zulip.testserver'
|
||||
result = self.client_patch("/json/bots/{}".format(self.get_bot_user(email).id), bot_info)
|
||||
result = self.client_patch(f"/json/bots/{self.get_bot_user(email).id}", bot_info)
|
||||
self.assert_json_success(result)
|
||||
config_data = ujson.loads(result.content)['config_data']
|
||||
self.assertEqual(config_data, ujson.loads(bot_info['config_data']))
|
||||
|
|
|
@ -1580,7 +1580,7 @@ class BugdownTest(ZulipTestCase):
|
|||
cordelia = self.example_user('cordelia')
|
||||
msg = Message(sender=sender_user_profile, sending_client=get_client("test"))
|
||||
|
||||
content = "@**Mark Twin|{}**, @**Mark Twin|{}** and @**Cordelia Lear**, hi.".format(twin1.id, twin2.id)
|
||||
content = f"@**Mark Twin|{twin1.id}**, @**Mark Twin|{twin2.id}** and @**Cordelia Lear**, hi."
|
||||
|
||||
self.assertEqual(render_markdown(msg, content),
|
||||
'<p>'
|
||||
|
@ -1918,7 +1918,7 @@ class BugdownTest(ZulipTestCase):
|
|||
stream = Stream.objects.create(name='Stream #1234', realm=realm)
|
||||
msg = Message(sender=sender_user_profile, sending_client=get_client("test"))
|
||||
content = "#**Stream #1234**"
|
||||
href = '/#narrow/stream/{stream_id}-Stream-.231234'.format(stream_id=stream.id)
|
||||
href = f'/#narrow/stream/{stream.id}-Stream-.231234'
|
||||
self.assertEqual(
|
||||
render_markdown(msg, content),
|
||||
'<p><a class="stream" data-stream-id="{s.id}" href="{href}">#{s.name}</a></p>'.format(
|
||||
|
@ -2159,7 +2159,7 @@ class BugdownAvatarTestCase(ZulipTestCase):
|
|||
message = Message(sender=sender_user_profile, sending_client=get_client("test"))
|
||||
|
||||
user_profile = self.example_user('hamlet')
|
||||
msg = '!avatar({})'.format(user_profile.email)
|
||||
msg = f'!avatar({user_profile.email})'
|
||||
converted = bugdown.convert(msg, message=message)
|
||||
values = {'email': user_profile.email, 'id': user_profile.id}
|
||||
self.assertEqual(
|
||||
|
@ -2171,7 +2171,7 @@ class BugdownAvatarTestCase(ZulipTestCase):
|
|||
message = Message(sender=sender_user_profile, sending_client=get_client("test"))
|
||||
|
||||
email = 'fakeuser@example.com'
|
||||
msg = '!avatar({})'.format(email)
|
||||
msg = f'!avatar({email})'
|
||||
converted = bugdown.convert(msg, message=message)
|
||||
self.assertEqual(
|
||||
converted,
|
||||
|
|
|
@ -62,7 +62,7 @@ class CacheKeyValidationTest(ZulipTestCase):
|
|||
class CacheWithKeyDecoratorTest(ZulipTestCase):
|
||||
def test_cache_with_key_invalid_character(self) -> None:
|
||||
def invalid_characters_cache_key_function(user_id: int) -> str:
|
||||
return 'CacheWithKeyDecoratorTest:invalid_character:ą:{}'.format(user_id)
|
||||
return f'CacheWithKeyDecoratorTest:invalid_character:ą:{user_id}'
|
||||
|
||||
@cache_with_key(invalid_characters_cache_key_function, timeout=1000)
|
||||
def get_user_function_with_bad_cache_keys(user_id: int) -> UserProfile:
|
||||
|
@ -101,7 +101,7 @@ class CacheWithKeyDecoratorTest(ZulipTestCase):
|
|||
|
||||
def test_cache_with_key_good_key(self) -> None:
|
||||
def good_cache_key_function(user_id: int) -> str:
|
||||
return 'CacheWithKeyDecoratorTest:good_cache_key:{}'.format(user_id)
|
||||
return f'CacheWithKeyDecoratorTest:good_cache_key:{user_id}'
|
||||
|
||||
@cache_with_key(good_cache_key_function, timeout=1000)
|
||||
def get_user_function_with_good_cache_keys(user_id: int) -> UserProfile:
|
||||
|
@ -125,7 +125,7 @@ class CacheWithKeyDecoratorTest(ZulipTestCase):
|
|||
|
||||
def test_cache_with_key_none_values(self) -> None:
|
||||
def cache_key_function(user_id: int) -> str:
|
||||
return 'CacheWithKeyDecoratorTest:test_cache_with_key_none_values:{}'.format(user_id)
|
||||
return f'CacheWithKeyDecoratorTest:test_cache_with_key_none_values:{user_id}'
|
||||
|
||||
@cache_with_key(cache_key_function, timeout=1000)
|
||||
def get_user_function_can_return_none(user_id: int) -> Optional[UserProfile]:
|
||||
|
@ -155,7 +155,7 @@ class GetCacheWithKeyDecoratorTest(ZulipTestCase):
|
|||
# we got the result from calling the function (None)
|
||||
|
||||
def good_cache_key_function(user_id: int) -> str:
|
||||
return 'CacheWithKeyDecoratorTest:good_cache_key:{}'.format(user_id)
|
||||
return f'CacheWithKeyDecoratorTest:good_cache_key:{user_id}'
|
||||
|
||||
@get_cache_with_key(good_cache_key_function)
|
||||
def get_user_function_with_good_cache_keys(user_id: int) -> Any: # nocoverage
|
||||
|
@ -173,7 +173,7 @@ class GetCacheWithKeyDecoratorTest(ZulipTestCase):
|
|||
|
||||
def test_get_cache_with_bad_key(self) -> None:
|
||||
def bad_cache_key_function(user_id: int) -> str:
|
||||
return 'CacheWithKeyDecoratorTest:invalid_character:ą:{}'.format(user_id)
|
||||
return f'CacheWithKeyDecoratorTest:invalid_character:ą:{user_id}'
|
||||
|
||||
@get_cache_with_key(bad_cache_key_function)
|
||||
def get_user_function_with_bad_cache_keys(user_id: int) -> Any: # nocoverage
|
||||
|
|
|
@ -29,7 +29,7 @@ class VersionTest(ZulipTestCase):
|
|||
|
||||
def test_version_lt(self) -> None:
|
||||
for ver1, cmp, ver2 in self.data:
|
||||
msg = 'expected {} {} {}'.format(ver1, cmp, ver2)
|
||||
msg = f'expected {ver1} {cmp} {ver2}'
|
||||
if cmp == '<':
|
||||
self.assertTrue(version_lt(ver1, ver2), msg=msg)
|
||||
self.assertFalse(version_lt(ver2, ver1), msg=msg)
|
||||
|
|
|
@ -150,7 +150,7 @@ class CreateCustomProfileFieldTest(CustomProfileFieldTestCase):
|
|||
self.assertEqual(field.name, DEFAULT_EXTERNAL_ACCOUNTS['twitter']['name'])
|
||||
self.assertEqual(field.hint, DEFAULT_EXTERNAL_ACCOUNTS['twitter']['hint'])
|
||||
|
||||
result = self.client_delete("/json/realm/profile_fields/{}".format(field.id))
|
||||
result = self.client_delete(f"/json/realm/profile_fields/{field.id}")
|
||||
self.assert_json_success(result)
|
||||
|
||||
# Should also work without name or hint and only external field type and subtype data
|
||||
|
@ -161,13 +161,13 @@ class CreateCustomProfileFieldTest(CustomProfileFieldTestCase):
|
|||
# Default external account field data cannot be updated
|
||||
field = CustomProfileField.objects.get(name="Twitter", realm=realm)
|
||||
result = self.client_patch(
|
||||
"/json/realm/profile_fields/{}".format(field.id),
|
||||
f"/json/realm/profile_fields/{field.id}",
|
||||
info={'name': 'Twitter username',
|
||||
'field_type': CustomProfileField.EXTERNAL_ACCOUNT}
|
||||
)
|
||||
self.assert_json_error(result, 'Default custom field cannot be updated.')
|
||||
|
||||
result = self.client_delete("/json/realm/profile_fields/{}".format(field.id))
|
||||
result = self.client_delete(f"/json/realm/profile_fields/{field.id}")
|
||||
self.assert_json_success(result)
|
||||
|
||||
def test_create_external_account_field(self) -> None:
|
||||
|
@ -292,7 +292,7 @@ class DeleteCustomProfileFieldTest(CustomProfileFieldTestCase):
|
|||
|
||||
self.assertTrue(self.custom_field_exists_in_realm(field.id))
|
||||
result = self.client_delete(
|
||||
"/json/realm/profile_fields/{}".format(field.id))
|
||||
f"/json/realm/profile_fields/{field.id}")
|
||||
self.assert_json_success(result)
|
||||
self.assertFalse(self.custom_field_exists_in_realm(field.id))
|
||||
|
||||
|
@ -359,7 +359,7 @@ class UpdateCustomProfileFieldTest(CustomProfileFieldTestCase):
|
|||
|
||||
field = CustomProfileField.objects.get(name="Phone number", realm=realm)
|
||||
result = self.client_patch(
|
||||
"/json/realm/profile_fields/{}".format(field.id),
|
||||
f"/json/realm/profile_fields/{field.id}",
|
||||
info={'name': '',
|
||||
'field_type': CustomProfileField.SHORT_TEXT}
|
||||
)
|
||||
|
@ -367,7 +367,7 @@ class UpdateCustomProfileFieldTest(CustomProfileFieldTestCase):
|
|||
|
||||
self.assertEqual(CustomProfileField.objects.count(), self.original_count)
|
||||
result = self.client_patch(
|
||||
"/json/realm/profile_fields/{}".format(field.id),
|
||||
f"/json/realm/profile_fields/{field.id}",
|
||||
info={'name': 'New phone number',
|
||||
'field_type': CustomProfileField.SHORT_TEXT})
|
||||
self.assert_json_success(result)
|
||||
|
@ -378,14 +378,14 @@ class UpdateCustomProfileFieldTest(CustomProfileFieldTestCase):
|
|||
self.assertEqual(field.field_type, CustomProfileField.SHORT_TEXT)
|
||||
|
||||
result = self.client_patch(
|
||||
"/json/realm/profile_fields/{}".format(field.id),
|
||||
f"/json/realm/profile_fields/{field.id}",
|
||||
info={'name': '*' * 41,
|
||||
'field_type': CustomProfileField.SHORT_TEXT})
|
||||
msg = "name is too long (limit: 40 characters)"
|
||||
self.assert_json_error(result, msg)
|
||||
|
||||
result = self.client_patch(
|
||||
"/json/realm/profile_fields/{}".format(field.id),
|
||||
f"/json/realm/profile_fields/{field.id}",
|
||||
info={'name': 'New phone number',
|
||||
'hint': '*' * 81,
|
||||
'field_type': CustomProfileField.SHORT_TEXT})
|
||||
|
@ -393,7 +393,7 @@ class UpdateCustomProfileFieldTest(CustomProfileFieldTestCase):
|
|||
self.assert_json_error(result, msg)
|
||||
|
||||
result = self.client_patch(
|
||||
"/json/realm/profile_fields/{}".format(field.id),
|
||||
f"/json/realm/profile_fields/{field.id}",
|
||||
info={'name': 'New phone number',
|
||||
'hint': 'New contact number',
|
||||
'field_type': CustomProfileField.SHORT_TEXT})
|
||||
|
@ -407,7 +407,7 @@ class UpdateCustomProfileFieldTest(CustomProfileFieldTestCase):
|
|||
|
||||
field = CustomProfileField.objects.get(name="Favorite editor", realm=realm)
|
||||
result = self.client_patch(
|
||||
"/json/realm/profile_fields/{}".format(field.id),
|
||||
f"/json/realm/profile_fields/{field.id}",
|
||||
info={'name': 'Favorite editor',
|
||||
'field_data': 'invalid'})
|
||||
self.assert_json_error(result, "Bad value for 'field_data': invalid")
|
||||
|
@ -417,7 +417,7 @@ class UpdateCustomProfileFieldTest(CustomProfileFieldTestCase):
|
|||
'emacs': {'order': '2', 'text': 'Emacs'},
|
||||
})
|
||||
result = self.client_patch(
|
||||
"/json/realm/profile_fields/{}".format(field.id),
|
||||
f"/json/realm/profile_fields/{field.id}",
|
||||
info={'name': 'Favorite editor',
|
||||
'field_data': field_data})
|
||||
self.assert_json_error(result, "field_data is not a dict")
|
||||
|
@ -428,7 +428,7 @@ class UpdateCustomProfileFieldTest(CustomProfileFieldTestCase):
|
|||
'notepad': {'order': '3', 'text': 'Notepad'},
|
||||
})
|
||||
result = self.client_patch(
|
||||
"/json/realm/profile_fields/{}".format(field.id),
|
||||
f"/json/realm/profile_fields/{field.id}",
|
||||
info={'name': 'Favorite editor',
|
||||
'field_data': field_data})
|
||||
self.assert_json_success(result)
|
||||
|
@ -445,7 +445,7 @@ class UpdateCustomProfileFieldTest(CustomProfileFieldTestCase):
|
|||
self.assertTrue(self.custom_field_exists_in_realm(field_1.id))
|
||||
self.assertTrue(self.custom_field_exists_in_realm(field_2.id))
|
||||
result = self.client_patch(
|
||||
"/json/realm/profile_fields/{}".format(field_2.id),
|
||||
f"/json/realm/profile_fields/{field_2.id}",
|
||||
info={'name': 'Phone', 'field_type': CustomProfileField.SHORT_TEXT})
|
||||
self.assert_json_error(
|
||||
result, 'A field with that label already exists.')
|
||||
|
@ -472,19 +472,19 @@ class UpdateCustomProfileFieldTest(CustomProfileFieldTestCase):
|
|||
def test_update_invalid_short_text(self) -> None:
|
||||
field_name = "Phone number"
|
||||
self.assert_error_update_invalid_value(field_name, 't' * 201,
|
||||
"{} is too long (limit: 50 characters)".format(field_name))
|
||||
f"{field_name} is too long (limit: 50 characters)")
|
||||
|
||||
def test_update_invalid_date(self) -> None:
|
||||
field_name = "Birthday"
|
||||
self.assert_error_update_invalid_value(field_name, "a-b-c",
|
||||
"{} is not a date".format(field_name))
|
||||
f"{field_name} is not a date")
|
||||
self.assert_error_update_invalid_value(field_name, 123,
|
||||
"{} is not a string".format(field_name))
|
||||
f"{field_name} is not a string")
|
||||
|
||||
def test_update_invalid_url(self) -> None:
|
||||
field_name = "Favorite website"
|
||||
self.assert_error_update_invalid_value(field_name, "not URL",
|
||||
"{} is not a URL".format(field_name))
|
||||
f"{field_name} is not a URL")
|
||||
|
||||
def test_update_invalid_user_field(self) -> None:
|
||||
field_name = "Mentor"
|
||||
|
@ -554,7 +554,7 @@ class UpdateCustomProfileFieldTest(CustomProfileFieldTestCase):
|
|||
def test_update_invalid_choice_field(self) -> None:
|
||||
field_name = "Favorite editor"
|
||||
self.assert_error_update_invalid_value(field_name, "foobar",
|
||||
"'foobar' is not a valid choice for '{}'.".format(field_name))
|
||||
f"'foobar' is not a valid choice for '{field_name}'.")
|
||||
|
||||
def test_update_choice_field_successfully(self) -> None:
|
||||
self.login('iago')
|
||||
|
|
|
@ -262,7 +262,7 @@ class TestDigestEmailMessages(ZulipTestCase):
|
|||
cordelia = self.example_user('cordelia')
|
||||
stream_id = create_stream_if_needed(cordelia.realm, 'New stream')[0].id
|
||||
new_stream = gather_new_streams(cordelia, cutoff)[1]
|
||||
expected_html = "<a href='http://zulip.testserver/#narrow/stream/{stream_id}-New-stream'>New stream</a>".format(stream_id=stream_id)
|
||||
expected_html = f"<a href='http://zulip.testserver/#narrow/stream/{stream_id}-New-stream'>New stream</a>"
|
||||
self.assertIn(expected_html, new_stream['html'])
|
||||
|
||||
def simulate_stream_conversation(self, stream: str, senders: List[str]) -> List[int]:
|
||||
|
@ -271,7 +271,7 @@ class TestDigestEmailMessages(ZulipTestCase):
|
|||
message_ids = [] # List[int]
|
||||
for sender_name in senders:
|
||||
sender = self.example_user(sender_name)
|
||||
content = 'some content for {} from {}'.format(stream, sender_name)
|
||||
content = f'some content for {stream} from {sender_name}'
|
||||
message_id = self.send_stream_message(sender, stream, content)
|
||||
message_ids.append(message_id)
|
||||
Message.objects.filter(id__in=message_ids).update(sending_client=sending_client)
|
||||
|
|
|
@ -103,7 +103,7 @@ class DocPageTest(ZulipTestCase):
|
|||
files = list(filter(_filter_func, files))
|
||||
|
||||
for f in files:
|
||||
endpoint = '/api/{}'.format(os.path.splitext(f)[0])
|
||||
endpoint = f'/api/{os.path.splitext(f)[0]}'
|
||||
self._test(endpoint, '', doc_html_str=True)
|
||||
|
||||
@slow("Tests dozens of endpoints, including generating lots of emails")
|
||||
|
@ -181,7 +181,7 @@ class DocPageTest(ZulipTestCase):
|
|||
])
|
||||
|
||||
for integration in INTEGRATIONS.keys():
|
||||
url = '/integrations/doc-html/{}'.format(integration)
|
||||
url = f'/integrations/doc-html/{integration}'
|
||||
self._test(url, '', doc_html_str=True)
|
||||
|
||||
def test_integration_pages_open_graph_metadata(self) -> None:
|
||||
|
@ -209,13 +209,13 @@ class DocPageTest(ZulipTestCase):
|
|||
# We don't need to test all the pages for 404
|
||||
for integration in list(INTEGRATIONS.keys())[5]:
|
||||
with self.settings(ROOT_DOMAIN_LANDING_PAGE=True):
|
||||
url = '/en/integrations/doc-html/{}'.format(integration)
|
||||
url = f'/en/integrations/doc-html/{integration}'
|
||||
result = self.client_get(url, subdomain="", follow=True)
|
||||
self.assertEqual(result.status_code, 404)
|
||||
result = self.client_get(url, subdomain="zephyr", follow=True)
|
||||
self.assertEqual(result.status_code, 404)
|
||||
|
||||
url = '/en/integrations/doc-html/{}'.format(integration)
|
||||
url = f'/en/integrations/doc-html/{integration}'
|
||||
result = self.client_get(url, subdomain="", follow=True)
|
||||
self.assertEqual(result.status_code, 404)
|
||||
result = self.client_get(url, subdomain="zephyr", follow=True)
|
||||
|
|
|
@ -211,7 +211,7 @@ class EmailChangeTestCase(ZulipTestCase):
|
|||
response)
|
||||
user_profile = get_user_profile_by_id(user_profile.id)
|
||||
self.assertEqual(user_profile.delivery_email, new_email)
|
||||
self.assertEqual(user_profile.email, "user{}@zulip.testserver".format(user_profile.id))
|
||||
self.assertEqual(user_profile.email, f"user{user_profile.id}@zulip.testserver")
|
||||
obj.refresh_from_db()
|
||||
self.assertEqual(obj.status, 1)
|
||||
with self.assertRaises(UserProfile.DoesNotExist):
|
||||
|
|
|
@ -73,11 +73,11 @@ class TestEncodeDecode(ZulipTestCase):
|
|||
stream_name = 'dev. help'
|
||||
stream = ensure_stream(realm, stream_name)
|
||||
email_address = encode_email_address(stream)
|
||||
self.assertEqual(email_address, "dev-help.{}@testserver".format(stream.email_token))
|
||||
self.assertEqual(email_address, f"dev-help.{stream.email_token}@testserver")
|
||||
|
||||
# The default form of the email address (with an option - "include-footer"):
|
||||
token, options = decode_email_address(
|
||||
"dev-help.{}.include-footer@testserver".format(stream.email_token)
|
||||
f"dev-help.{stream.email_token}.include-footer@testserver"
|
||||
)
|
||||
self._assert_options(options, include_footer=True)
|
||||
self.assertEqual(token, stream.email_token)
|
||||
|
@ -85,7 +85,7 @@ class TestEncodeDecode(ZulipTestCase):
|
|||
# Using + instead of . as the separator is also supported for backwards compatibility,
|
||||
# since that was the original form of addresses that we used:
|
||||
token, options = decode_email_address(
|
||||
"dev-help+{}+include-footer@testserver".format(stream.email_token)
|
||||
f"dev-help+{stream.email_token}+include-footer@testserver"
|
||||
)
|
||||
self._assert_options(options, include_footer=True)
|
||||
self.assertEqual(token, stream.email_token)
|
||||
|
@ -164,8 +164,8 @@ class TestEncodeDecode(ZulipTestCase):
|
|||
|
||||
def test_decode_prefer_text_options(self) -> None:
|
||||
stream = get_stream("Denmark", get_realm("zulip"))
|
||||
address_prefer_text = "Denmark.{}.prefer-text@testserver".format(stream.email_token)
|
||||
address_prefer_html = "Denmark.{}.prefer-html@testserver".format(stream.email_token)
|
||||
address_prefer_text = f"Denmark.{stream.email_token}.prefer-text@testserver"
|
||||
address_prefer_html = f"Denmark.{stream.email_token}.prefer-html@testserver"
|
||||
|
||||
token, options = decode_email_address(address_prefer_text)
|
||||
self._assert_options(options, prefer_text=True)
|
||||
|
@ -301,7 +301,7 @@ class TestStreamEmailMessagesSuccess(ZulipTestCase):
|
|||
|
||||
# stream address is angle-addr within multiple addresses
|
||||
stream_to_addresses = ["A.N. Other <another@example.org>",
|
||||
"Denmark <{}>".format(encode_email_address(stream))]
|
||||
f"Denmark <{encode_email_address(stream)}>"]
|
||||
|
||||
incoming_valid_message = MIMEText('TestStreamEmailMessages Body')
|
||||
|
||||
|
@ -566,8 +566,8 @@ class TestEmailMirrorMessagesWithAttachments(ZulipTestCase):
|
|||
self.login_user(user_profile)
|
||||
self.subscribe(user_profile, "Denmark")
|
||||
stream = get_stream("Denmark", user_profile.realm)
|
||||
stream_address = "Denmark.{}@testserver".format(stream.email_token)
|
||||
stream_address_prefer_html = "Denmark.{}.prefer-html@testserver".format(stream.email_token)
|
||||
stream_address = f"Denmark.{stream.email_token}@testserver"
|
||||
stream_address_prefer_html = f"Denmark.{stream.email_token}.prefer-html@testserver"
|
||||
|
||||
text = "Test message"
|
||||
html = "<html><body><b>Test html message</b></body></html>"
|
||||
|
@ -601,7 +601,7 @@ class TestEmailMirrorMessagesWithAttachments(ZulipTestCase):
|
|||
self.login_user(user_profile)
|
||||
self.subscribe(user_profile, "Denmark")
|
||||
stream = get_stream("Denmark", user_profile.realm)
|
||||
stream_address_prefer_html = "Denmark.{}.prefer-html@testserver".format(stream.email_token)
|
||||
stream_address_prefer_html = f"Denmark.{stream.email_token}.prefer-html@testserver"
|
||||
|
||||
text = "Test message"
|
||||
# This should be correctly identified as empty html body:
|
||||
|
|
|
@ -700,8 +700,8 @@ class TestMissedMessages(ZulipTestCase):
|
|||
self.example_user('othello'), self.example_user('hamlet'),
|
||||
'Come and join us in #**Verona**.')
|
||||
stream_id = get_stream('Verona', get_realm('zulip')).id
|
||||
href = "http://zulip.testserver/#narrow/stream/{stream_id}-Verona".format(stream_id=stream_id)
|
||||
verify_body_include = ['<a class="stream" data-stream-id="5" href="{href}">#Verona</a'.format(href=href)]
|
||||
href = f"http://zulip.testserver/#narrow/stream/{stream_id}-Verona"
|
||||
verify_body_include = [f'<a class="stream" data-stream-id="5" href="{href}">#Verona</a']
|
||||
email_subject = 'PMs with Othello, the Moor of Venice'
|
||||
self._test_cases(msg_id, verify_body_include, email_subject, send_as_user=False, verify_html_body=True)
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ class TestEmbeddedBotMessaging(ZulipTestCase):
|
|||
def test_stream_message_to_embedded_bot(self) -> None:
|
||||
assert self.bot_profile is not None
|
||||
self.send_stream_message(self.user_profile, "Denmark",
|
||||
content="@**{}** foo".format(self.bot_profile.full_name),
|
||||
content=f"@**{self.bot_profile.full_name}** foo",
|
||||
topic_name="bar")
|
||||
last_message = self.get_last_message()
|
||||
self.assertEqual(last_message.content, "beep boop")
|
||||
|
@ -56,7 +56,7 @@ class TestEmbeddedBotMessaging(ZulipTestCase):
|
|||
with patch('zulip_bots.bots.helloworld.helloworld.HelloWorldHandler.initialize',
|
||||
create=True) as mock_initialize:
|
||||
self.send_stream_message(self.user_profile, "Denmark",
|
||||
content="@**{}** foo".format(self.bot_profile.full_name),
|
||||
content=f"@**{self.bot_profile.full_name}** foo",
|
||||
topic_name="bar")
|
||||
mock_initialize.assert_called_once()
|
||||
|
||||
|
@ -66,7 +66,7 @@ class TestEmbeddedBotMessaging(ZulipTestCase):
|
|||
side_effect=EmbeddedBotQuitException("I'm quitting!")):
|
||||
with patch('logging.warning') as mock_logging:
|
||||
self.send_stream_message(self.user_profile, "Denmark",
|
||||
content="@**{}** foo".format(self.bot_profile.full_name),
|
||||
content=f"@**{self.bot_profile.full_name}** foo",
|
||||
topic_name="bar")
|
||||
mock_logging.assert_called_once_with("I'm quitting!")
|
||||
|
||||
|
@ -83,7 +83,7 @@ class TestEmbeddedBotFailures(ZulipTestCase):
|
|||
service_profile.save()
|
||||
with patch('logging.error') as logging_error_mock:
|
||||
self.send_stream_message(user_profile, "Denmark",
|
||||
content="@**{}** foo".format(bot_profile.full_name),
|
||||
content=f"@**{bot_profile.full_name}** foo",
|
||||
topic_name="bar")
|
||||
logging_error_mock.assert_called_once_with(
|
||||
"Error: User %s has bot with invalid embedded bot service %s",
|
||||
|
|
|
@ -2803,7 +2803,7 @@ class EventsRegisterTest(ZulipTestCase):
|
|||
|
||||
hamlet = self.example_user("hamlet")
|
||||
self.subscribe(hamlet, "Denmark")
|
||||
body = "First message ...[zulip.txt](http://{}".format(hamlet.realm.host) + data['uri'] + ")"
|
||||
body = f"First message ...[zulip.txt](http://{hamlet.realm.host}" + data['uri'] + ")"
|
||||
events = self.do_test(
|
||||
lambda: self.send_stream_message(self.example_user("hamlet"), "Denmark", body, "test"),
|
||||
num_events=2)
|
||||
|
@ -2888,7 +2888,7 @@ class EventsRegisterTest(ZulipTestCase):
|
|||
audit_log_entry = RealmAuditLog.objects.filter(
|
||||
event_type=RealmAuditLog.REALM_EXPORTED).first()
|
||||
events = self.do_test(
|
||||
lambda: self.client_delete('/json/export/realm/{id}'.format(id=audit_log_entry.id)),
|
||||
lambda: self.client_delete(f'/json/export/realm/{audit_log_entry.id}'),
|
||||
state_change_expected=False, num_events=1)
|
||||
error = deletion_schema_checker('events[0]', events[0])
|
||||
self.assert_on_error(error)
|
||||
|
|
|
@ -105,7 +105,7 @@ class TranslationTestCase(ZulipTestCase):
|
|||
]
|
||||
|
||||
for lang, word in languages:
|
||||
response = self.fetch('get', '/{}/integrations/'.format(lang), 200)
|
||||
response = self.fetch('get', f'/{lang}/integrations/', 200)
|
||||
self.assert_in_response(word, response)
|
||||
|
||||
|
||||
|
|
|
@ -946,7 +946,7 @@ class ImportExportTest(ZulipTestCase):
|
|||
|
||||
def get_user_mention(r: Realm) -> Set[Any]:
|
||||
mentioned_user = UserProfile.objects.get(delivery_email=self.example_email("hamlet"), realm=r)
|
||||
data_user_id = 'data-user-id="{}"'.format(mentioned_user.id)
|
||||
data_user_id = f'data-user-id="{mentioned_user.id}"'
|
||||
mention_message = get_stream_messages(r).get(rendered_content__contains=data_user_id)
|
||||
return mention_message.content
|
||||
|
||||
|
@ -954,7 +954,7 @@ class ImportExportTest(ZulipTestCase):
|
|||
|
||||
def get_stream_mention(r: Realm) -> Set[Any]:
|
||||
mentioned_stream = get_stream('Denmark', r)
|
||||
data_stream_id = 'data-stream-id="{}"'.format(mentioned_stream.id)
|
||||
data_stream_id = f'data-stream-id="{mentioned_stream.id}"'
|
||||
mention_message = get_stream_messages(r).get(rendered_content__contains=data_stream_id)
|
||||
return mention_message.content
|
||||
|
||||
|
@ -962,7 +962,7 @@ class ImportExportTest(ZulipTestCase):
|
|||
|
||||
def get_user_group_mention(r: Realm) -> Set[Any]:
|
||||
user_group = UserGroup.objects.get(realm=r, name='hamletcharacters')
|
||||
data_usergroup_id = 'data-user-group-id="{}"'.format(user_group.id)
|
||||
data_usergroup_id = f'data-user-group-id="{user_group.id}"'
|
||||
mention_message = get_stream_messages(r).get(rendered_content__contains=data_usergroup_id)
|
||||
return mention_message.content
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ class TestIntegrationsDevPanel(ZulipTestCase):
|
|||
|
||||
def test_check_send_webhook_fixture_message_for_error(self) -> None:
|
||||
bot = get_user('webhook-bot@zulip.com', self.zulip_realm)
|
||||
url = "/api/v1/external/airbrake?api_key={key}".format(key=bot.api_key)
|
||||
url = f"/api/v1/external/airbrake?api_key={bot.api_key}"
|
||||
target_url = "/devtools/integrations/check_send_webhook_fixture_message"
|
||||
body = "{}" # This empty body should generate a KeyError on the webhook code side.
|
||||
|
||||
|
@ -28,7 +28,7 @@ class TestIntegrationsDevPanel(ZulipTestCase):
|
|||
|
||||
def test_check_send_webhook_fixture_message_for_success_without_headers(self) -> None:
|
||||
bot = get_user('webhook-bot@zulip.com', self.zulip_realm)
|
||||
url = "/api/v1/external/airbrake?api_key={key}&stream=Denmark&topic=Airbrake Notifications".format(key=bot.api_key)
|
||||
url = f"/api/v1/external/airbrake?api_key={bot.api_key}&stream=Denmark&topic=Airbrake Notifications"
|
||||
target_url = "/devtools/integrations/check_send_webhook_fixture_message"
|
||||
with open("zerver/webhooks/airbrake/fixtures/error_message.json") as f:
|
||||
body = f.read()
|
||||
|
@ -55,7 +55,7 @@ class TestIntegrationsDevPanel(ZulipTestCase):
|
|||
|
||||
def test_check_send_webhook_fixture_message_for_success_with_headers(self) -> None:
|
||||
bot = get_user('webhook-bot@zulip.com', self.zulip_realm)
|
||||
url = "/api/v1/external/github?api_key={key}&stream=Denmark&topic=GitHub Notifications".format(key=bot.api_key)
|
||||
url = f"/api/v1/external/github?api_key={bot.api_key}&stream=Denmark&topic=GitHub Notifications"
|
||||
target_url = "/devtools/integrations/check_send_webhook_fixture_message"
|
||||
with open("zerver/webhooks/github/fixtures/ping__organization.json") as f:
|
||||
body = f.read()
|
||||
|
@ -78,7 +78,7 @@ class TestIntegrationsDevPanel(ZulipTestCase):
|
|||
|
||||
def test_check_send_webhook_fixture_message_for_success_with_headers_and_non_json_fixtures(self) -> None:
|
||||
bot = get_user('webhook-bot@zulip.com', self.zulip_realm)
|
||||
url = "/api/v1/external/wordpress?api_key={key}&stream=Denmark&topic=Wordpress Notifications".format(key=bot.api_key)
|
||||
url = f"/api/v1/external/wordpress?api_key={bot.api_key}&stream=Denmark&topic=Wordpress Notifications"
|
||||
target_url = "/devtools/integrations/check_send_webhook_fixture_message"
|
||||
with open("zerver/webhooks/wordpress/fixtures/publish_post_no_data_provided.txt") as f:
|
||||
body = f.read()
|
||||
|
@ -129,7 +129,7 @@ class TestIntegrationsDevPanel(ZulipTestCase):
|
|||
|
||||
def test_send_all_webhook_fixture_messages_for_success(self) -> None:
|
||||
bot = get_user('webhook-bot@zulip.com', self.zulip_realm)
|
||||
url = "/api/v1/external/appfollow?api_key={key}&stream=Denmark&topic=Appfollow Bulk Notifications".format(key=bot.api_key)
|
||||
url = f"/api/v1/external/appfollow?api_key={bot.api_key}&stream=Denmark&topic=Appfollow Bulk Notifications"
|
||||
target_url = "/devtools/integrations/send_all_webhook_fixture_messages"
|
||||
|
||||
data = {
|
||||
|
@ -173,7 +173,7 @@ class TestIntegrationsDevPanel(ZulipTestCase):
|
|||
|
||||
def test_send_all_webhook_fixture_messages_for_success_with_non_json_fixtures(self) -> None:
|
||||
bot = get_user('webhook-bot@zulip.com', self.zulip_realm)
|
||||
url = "/api/v1/external/wordpress?api_key={key}&stream=Denmark&topic=Wordpress Bulk Notifications".format(key=bot.api_key)
|
||||
url = f"/api/v1/external/wordpress?api_key={bot.api_key}&stream=Denmark&topic=Wordpress Bulk Notifications"
|
||||
target_url = "/devtools/integrations/send_all_webhook_fixture_messages"
|
||||
|
||||
data = {
|
||||
|
@ -243,7 +243,7 @@ class TestIntegrationsDevPanel(ZulipTestCase):
|
|||
def test_send_all_webhook_fixture_messages_for_missing_fixtures(self, os_path_exists_mock: MagicMock) -> None:
|
||||
os_path_exists_mock.return_value = False
|
||||
bot = get_user('webhook-bot@zulip.com', self.zulip_realm)
|
||||
url = "/api/v1/external/appfollow?api_key={key}&stream=Denmark&topic=Appfollow Bulk Notifications".format(key=bot.api_key)
|
||||
url = f"/api/v1/external/appfollow?api_key={bot.api_key}&stream=Denmark&topic=Appfollow Bulk Notifications"
|
||||
data = {
|
||||
"url": url,
|
||||
"custom_headers": "{}",
|
||||
|
|
|
@ -131,7 +131,7 @@ class OembedTestCase(ZulipTestCase):
|
|||
|
||||
def test_autodiscovered_oembed_xml_format_html(self) -> None:
|
||||
iframe_content = '<iframe src="https://w.soundcloud.com/player"></iframe>'
|
||||
html = '<![CDATA[{}]]>'.format(iframe_content)
|
||||
html = f'<![CDATA[{iframe_content}]]>'
|
||||
stripped_html = strip_cdata(html)
|
||||
self.assertEqual(iframe_content, stripped_html)
|
||||
|
||||
|
@ -299,7 +299,7 @@ class PreviewTestCase(ZulipTestCase):
|
|||
with mock.patch('requests.get', mocked_response):
|
||||
FetchLinksEmbedData().consume(event)
|
||||
|
||||
embedded_link = '<a href="{}" title="The Rock">The Rock</a>'.format(url)
|
||||
embedded_link = f'<a href="{url}" title="The Rock">The Rock</a>'
|
||||
msg = Message.objects.select_related("sender").get(id=msg_id)
|
||||
self.assertIn(embedded_link, msg.rendered_content)
|
||||
|
||||
|
@ -327,7 +327,7 @@ class PreviewTestCase(ZulipTestCase):
|
|||
# Verify the initial message doesn't have the embedded links rendered
|
||||
msg = Message.objects.select_related("sender").get(id=msg_id)
|
||||
self.assertNotIn(
|
||||
'<a href="{}" title="The Rock">The Rock</a>'.format(url),
|
||||
f'<a href="{url}" title="The Rock">The Rock</a>',
|
||||
msg.rendered_content)
|
||||
|
||||
# Mock the network request result so the test can be fast without Internet
|
||||
|
@ -367,7 +367,7 @@ class PreviewTestCase(ZulipTestCase):
|
|||
msg = Message.objects.select_related("sender").get(id=msg_id)
|
||||
# The content of the message has changed since the event for original_url has been created,
|
||||
# it should not be rendered. Another, up-to-date event will have been sent (edited_url).
|
||||
self.assertNotIn('<a href="{}" title="The Rock">The Rock</a>'.format(original_url),
|
||||
self.assertNotIn(f'<a href="{original_url}" title="The Rock">The Rock</a>',
|
||||
msg.rendered_content)
|
||||
mocked_response_edited.assert_not_called()
|
||||
|
||||
|
@ -377,7 +377,7 @@ class PreviewTestCase(ZulipTestCase):
|
|||
# up-to-date event for edited_url.
|
||||
queue_json_publish(*args, **kwargs)
|
||||
msg = Message.objects.select_related("sender").get(id=msg_id)
|
||||
self.assertIn('<a href="{}" title="The Rock">The Rock</a>'.format(edited_url),
|
||||
self.assertIn(f'<a href="{edited_url}" title="The Rock">The Rock</a>',
|
||||
msg.rendered_content)
|
||||
|
||||
with mock.patch('zerver.views.messages.queue_json_publish', wraps=wrapped_queue_json_publish) as patched:
|
||||
|
@ -388,7 +388,7 @@ class PreviewTestCase(ZulipTestCase):
|
|||
|
||||
def test_get_link_embed_data(self) -> None:
|
||||
url = 'http://test.org/'
|
||||
embedded_link = '<a href="{}" title="The Rock">The Rock</a>'.format(url)
|
||||
embedded_link = f'<a href="{url}" title="The Rock">The Rock</a>'
|
||||
|
||||
# When humans send, we should get embedded content.
|
||||
msg = self._send_message_with_test_org_url(sender=self.example_user('hamlet'))
|
||||
|
@ -659,8 +659,8 @@ class PreviewTestCase(ZulipTestCase):
|
|||
'message_realm_id': msg.sender.realm_id,
|
||||
'message_content': url}
|
||||
|
||||
mocked_data = {'html': '<iframe src="{}"></iframe>'.format(url),
|
||||
'oembed': True, 'type': 'video', 'image': '{}/image.png'.format(url)}
|
||||
mocked_data = {'html': f'<iframe src="{url}"></iframe>',
|
||||
'oembed': True, 'type': 'video', 'image': f'{url}/image.png'}
|
||||
mocked_response = mock.Mock(side_effect=self.create_mock_response(url))
|
||||
with self.settings(TEST_SUITE=False, CACHES=TEST_CACHES):
|
||||
with mock.patch('requests.get', mocked_response):
|
||||
|
|
|
@ -283,7 +283,7 @@ class TestGenerateRealmCreationLink(ZulipTestCase):
|
|||
|
||||
result = self.client_post(generated_link, {'email': email})
|
||||
self.assertEqual(result.status_code, 302)
|
||||
self.assertTrue(re.search('/accounts/new/send_confirm/{}$'.format(email),
|
||||
self.assertTrue(re.search(f'/accounts/new/send_confirm/{email}$',
|
||||
result["Location"]))
|
||||
result = self.client_get(result["Location"])
|
||||
self.assert_in_response("Check your email so we can get started", result)
|
||||
|
@ -354,7 +354,7 @@ class TestSendToEmailMirror(ZulipTestCase):
|
|||
self.login_user(user_profile)
|
||||
self.subscribe(user_profile, "Denmark")
|
||||
|
||||
call_command(self.COMMAND_NAME, "--fixture={}".format(fixture_path))
|
||||
call_command(self.COMMAND_NAME, f"--fixture={fixture_path}")
|
||||
message = most_recent_message(user_profile)
|
||||
|
||||
# last message should be equal to the body of the email in 1.txt
|
||||
|
@ -366,7 +366,7 @@ class TestSendToEmailMirror(ZulipTestCase):
|
|||
self.login_user(user_profile)
|
||||
self.subscribe(user_profile, "Denmark")
|
||||
|
||||
call_command(self.COMMAND_NAME, "--fixture={}".format(fixture_path))
|
||||
call_command(self.COMMAND_NAME, f"--fixture={fixture_path}")
|
||||
message = most_recent_message(user_profile)
|
||||
|
||||
# last message should be equal to the body of the email in 1.json
|
||||
|
@ -378,7 +378,7 @@ class TestSendToEmailMirror(ZulipTestCase):
|
|||
self.login_user(user_profile)
|
||||
self.subscribe(user_profile, "Denmark2")
|
||||
|
||||
call_command(self.COMMAND_NAME, "--fixture={}".format(fixture_path), "--stream=Denmark2")
|
||||
call_command(self.COMMAND_NAME, f"--fixture={fixture_path}", "--stream=Denmark2")
|
||||
message = most_recent_message(user_profile)
|
||||
|
||||
# last message should be equal to the body of the email in 1.txt
|
||||
|
@ -395,7 +395,7 @@ class TestConvertMattermostData(ZulipTestCase):
|
|||
with patch('zerver.management.commands.convert_mattermost_data.do_convert_data') as m:
|
||||
mm_fixtures = self.fixture_file_name("", "mattermost_fixtures")
|
||||
output_dir = self.make_import_output_dir("mattermost")
|
||||
call_command(self.COMMAND_NAME, mm_fixtures, "--output={}".format(output_dir))
|
||||
call_command(self.COMMAND_NAME, mm_fixtures, f"--output={output_dir}")
|
||||
|
||||
m.assert_called_with(
|
||||
masking_content=False,
|
||||
|
@ -425,7 +425,7 @@ class TestExport(ZulipTestCase):
|
|||
do_add_reaction(self.example_user("hamlet"), message, "outbox", "1f4e4", Reaction.UNICODE_EMOJI)
|
||||
|
||||
with patch("zerver.management.commands.export.export_realm_wrapper") as m:
|
||||
call_command(self.COMMAND_NAME, "-r=zulip", "--consent-message-id={}".format(message.id))
|
||||
call_command(self.COMMAND_NAME, "-r=zulip", f"--consent-message-id={message.id}")
|
||||
m.assert_called_once_with(realm=realm, public_only=False, consent_message_id=message.id,
|
||||
delete_after_upload=False, threads=mock.ANY, output_dir=mock.ANY,
|
||||
upload=False)
|
||||
|
@ -436,10 +436,10 @@ class TestExport(ZulipTestCase):
|
|||
message.last_edit_time = timezone_now()
|
||||
message.save()
|
||||
with self.assertRaisesRegex(CommandError, "Message was edited. Aborting..."):
|
||||
call_command(self.COMMAND_NAME, "-r=zulip", "--consent-message-id={}".format(message.id))
|
||||
call_command(self.COMMAND_NAME, "-r=zulip", f"--consent-message-id={message.id}")
|
||||
|
||||
message.last_edit_time = None
|
||||
message.save()
|
||||
do_add_reaction(self.mit_user("sipbtest"), message, "outbox", "1f4e4", Reaction.UNICODE_EMOJI)
|
||||
with self.assertRaisesRegex(CommandError, "Users from a different realm reacted to message. Aborting..."):
|
||||
call_command(self.COMMAND_NAME, "-r=zulip", "--consent-message-id={}".format(message.id))
|
||||
call_command(self.COMMAND_NAME, "-r=zulip", f"--consent-message-id={message.id}")
|
||||
|
|
|
@ -796,7 +796,7 @@ class PersonalMessagesTest(ZulipTestCase):
|
|||
user_message = most_recent_usermessage(user_profile)
|
||||
self.assertEqual(
|
||||
str(user_message),
|
||||
'<UserMessage: recip / {} ([])>'.format(user_profile.email)
|
||||
f'<UserMessage: recip / {user_profile.email} ([])>'
|
||||
)
|
||||
|
||||
@slow("checks several profiles")
|
||||
|
@ -1409,7 +1409,7 @@ class MessageDictTest(ZulipTestCase):
|
|||
# extract messages. Note that we increased this from 1ms to
|
||||
# 1.5ms to handle tests running in parallel being a bit
|
||||
# slower.
|
||||
error_msg = "Number of ids: {}. Time delay: {}".format(num_ids, delay)
|
||||
error_msg = f"Number of ids: {num_ids}. Time delay: {delay}"
|
||||
self.assertTrue(delay < 0.0015 * num_ids, error_msg)
|
||||
self.assert_length(queries, 7)
|
||||
self.assertEqual(len(rows), num_ids)
|
||||
|
@ -1959,14 +1959,14 @@ class MessagePOSTTest(ZulipTestCase):
|
|||
"content": "Test message",
|
||||
"client": "test suite",
|
||||
"to": ujson.dumps([othello.id])})
|
||||
self.assert_json_error(result, "'{}' is no longer using Zulip.".format(othello.email))
|
||||
self.assert_json_error(result, f"'{othello.email}' is no longer using Zulip.")
|
||||
|
||||
result = self.client_post("/json/messages", {
|
||||
"type": "private",
|
||||
"content": "Test message",
|
||||
"client": "test suite",
|
||||
"to": ujson.dumps([othello.id, cordelia.id])})
|
||||
self.assert_json_error(result, "'{}' is no longer using Zulip.".format(othello.email))
|
||||
self.assert_json_error(result, f"'{othello.email}' is no longer using Zulip.")
|
||||
|
||||
def test_invalid_type(self) -> None:
|
||||
"""
|
||||
|
@ -2960,7 +2960,7 @@ class EditMessageTest(ZulipTestCase):
|
|||
topic_name='editing',
|
||||
content='This message has not been edited.')
|
||||
|
||||
result = self.client_get('/json/messages/{}/history'.format(msg_id))
|
||||
result = self.client_get(f'/json/messages/{msg_id}/history')
|
||||
|
||||
self.assert_json_success(result)
|
||||
|
||||
|
@ -4158,7 +4158,7 @@ class MessageHasKeywordsTest(ZulipTestCase):
|
|||
def test_claim_attachment(self) -> None:
|
||||
user_profile = self.example_user('hamlet')
|
||||
dummy_path_ids = self.setup_dummy_attachments(user_profile)
|
||||
dummy_urls = ["http://zulip.testserver/user_uploads/{}".format(x) for x in dummy_path_ids]
|
||||
dummy_urls = [f"http://zulip.testserver/user_uploads/{x}" for x in dummy_path_ids]
|
||||
|
||||
# Send message referring the attachment
|
||||
self.subscribe(user_profile, "Denmark")
|
||||
|
@ -4178,17 +4178,17 @@ class MessageHasKeywordsTest(ZulipTestCase):
|
|||
|
||||
# This message tries to claim the third attachment but fails because
|
||||
# Bugdown would not set has_attachments = True here.
|
||||
body = "Link in code: `{}`".format(dummy_urls[2])
|
||||
body = f"Link in code: `{dummy_urls[2]}`"
|
||||
self.send_stream_message(user_profile, "Denmark", body, "test")
|
||||
assert_attachment_claimed(dummy_path_ids[2], False)
|
||||
|
||||
# Another scenario where we wouldn't parse the link.
|
||||
body = "Link to not parse: .{}.`".format(dummy_urls[2])
|
||||
body = f"Link to not parse: .{dummy_urls[2]}.`"
|
||||
self.send_stream_message(user_profile, "Denmark", body, "test")
|
||||
assert_attachment_claimed(dummy_path_ids[2], False)
|
||||
|
||||
# Finally, claim attachment 3.
|
||||
body = "Link: {}".format(dummy_urls[2])
|
||||
body = f"Link: {dummy_urls[2]}"
|
||||
self.send_stream_message(user_profile, "Denmark", body, "test")
|
||||
assert_attachment_claimed(dummy_path_ids[2], True)
|
||||
assert_attachment_claimed(dummy_path_ids[1], False)
|
||||
|
@ -4255,7 +4255,7 @@ class MessageHasKeywordsTest(ZulipTestCase):
|
|||
def test_has_attachment(self) -> None:
|
||||
hamlet = self.example_user('hamlet')
|
||||
dummy_path_ids = self.setup_dummy_attachments(hamlet)
|
||||
dummy_urls = ["http://zulip.testserver/user_uploads/{}".format(x) for x in dummy_path_ids]
|
||||
dummy_urls = [f"http://zulip.testserver/user_uploads/{x}" for x in dummy_path_ids]
|
||||
self.subscribe(hamlet, "Denmark")
|
||||
|
||||
body = ("Files ...[zulip.txt]({}) {} {}").format(dummy_urls[0], dummy_urls[1], dummy_urls[2])
|
||||
|
@ -4267,24 +4267,24 @@ class MessageHasKeywordsTest(ZulipTestCase):
|
|||
self.assertFalse(msg.has_attachment)
|
||||
self.update_message(msg, body)
|
||||
self.assertTrue(msg.has_attachment)
|
||||
self.update_message(msg, 'Link in code: `{}`'.format(dummy_urls[1]))
|
||||
self.update_message(msg, f'Link in code: `{dummy_urls[1]}`')
|
||||
self.assertFalse(msg.has_attachment)
|
||||
# Test blockquotes
|
||||
self.update_message(msg, '> {}'.format(dummy_urls[1]))
|
||||
self.update_message(msg, f'> {dummy_urls[1]}')
|
||||
self.assertTrue(msg.has_attachment)
|
||||
|
||||
# Additional test to check has_attachment is being set is due to the correct attachment.
|
||||
self.update_message(msg, 'Outside: {}. In code: `{}`.'.format(dummy_urls[0], dummy_urls[1]))
|
||||
self.update_message(msg, f'Outside: {dummy_urls[0]}. In code: `{dummy_urls[1]}`.')
|
||||
self.assertTrue(msg.has_attachment)
|
||||
self.assertTrue(msg.attachment_set.filter(path_id=dummy_path_ids[0]))
|
||||
self.assertEqual(msg.attachment_set.count(), 1)
|
||||
|
||||
self.update_message(msg, 'Outside: {}. In code: `{}`.'.format(dummy_urls[1], dummy_urls[0]))
|
||||
self.update_message(msg, f'Outside: {dummy_urls[1]}. In code: `{dummy_urls[0]}`.')
|
||||
self.assertTrue(msg.has_attachment)
|
||||
self.assertTrue(msg.attachment_set.filter(path_id=dummy_path_ids[1]))
|
||||
self.assertEqual(msg.attachment_set.count(), 1)
|
||||
|
||||
self.update_message(msg, 'Both in code: `{} {}`.'.format(dummy_urls[1], dummy_urls[0]))
|
||||
self.update_message(msg, f'Both in code: `{dummy_urls[1]} {dummy_urls[0]}`.')
|
||||
self.assertFalse(msg.has_attachment)
|
||||
self.assertEqual(msg.attachment_set.count(), 0)
|
||||
|
||||
|
@ -4304,16 +4304,16 @@ class MessageHasKeywordsTest(ZulipTestCase):
|
|||
self.assertTrue(m.called)
|
||||
m.reset_mock()
|
||||
|
||||
self.update_message(msg, '[link](/user_uploads/{})'.format(dummy_path_ids[1]))
|
||||
self.update_message(msg, f'[link](/user_uploads/{dummy_path_ids[1]})')
|
||||
self.assertTrue(m.called)
|
||||
m.reset_mock()
|
||||
|
||||
self.update_message(msg, '[new text link](/user_uploads/{})'.format(dummy_path_ids[1]))
|
||||
self.update_message(msg, f'[new text link](/user_uploads/{dummy_path_ids[1]})')
|
||||
self.assertFalse(m.called)
|
||||
m.reset_mock()
|
||||
|
||||
# It's not clear this is correct behavior
|
||||
self.update_message(msg, '[link](user_uploads/{})'.format(dummy_path_ids[2]))
|
||||
self.update_message(msg, f'[link](user_uploads/{dummy_path_ids[2]})')
|
||||
self.assertFalse(m.called)
|
||||
m.reset_mock()
|
||||
|
||||
|
@ -4486,10 +4486,10 @@ class DeleteMessageTest(ZulipTestCase):
|
|||
self.login('iago')
|
||||
hamlet = self.example_user('hamlet')
|
||||
msg_id = self.send_stream_message(hamlet, "Scotland")
|
||||
result = self.client_delete('/json/messages/{msg_id}'.format(msg_id=msg_id + 1),
|
||||
result = self.client_delete(f'/json/messages/{msg_id + 1}',
|
||||
{'message_id': msg_id})
|
||||
self.assert_json_error(result, "Invalid message(s)")
|
||||
result = self.client_delete('/json/messages/{msg_id}'.format(msg_id=msg_id))
|
||||
result = self.client_delete(f'/json/messages/{msg_id}')
|
||||
self.assert_json_success(result)
|
||||
|
||||
def test_delete_message_by_user(self) -> None:
|
||||
|
@ -4504,17 +4504,17 @@ class DeleteMessageTest(ZulipTestCase):
|
|||
|
||||
def test_delete_message_by_admin(msg_id: int) -> HttpResponse:
|
||||
self.login('iago')
|
||||
result = self.client_delete('/json/messages/{msg_id}'.format(msg_id=msg_id))
|
||||
result = self.client_delete(f'/json/messages/{msg_id}')
|
||||
return result
|
||||
|
||||
def test_delete_message_by_owner(msg_id: int) -> HttpResponse:
|
||||
self.login('hamlet')
|
||||
result = self.client_delete('/json/messages/{msg_id}'.format(msg_id=msg_id))
|
||||
result = self.client_delete(f'/json/messages/{msg_id}')
|
||||
return result
|
||||
|
||||
def test_delete_message_by_other_user(msg_id: int) -> HttpResponse:
|
||||
self.login('cordelia')
|
||||
result = self.client_delete('/json/messages/{msg_id}'.format(msg_id=msg_id))
|
||||
result = self.client_delete(f'/json/messages/{msg_id}')
|
||||
return result
|
||||
|
||||
# Test if message deleting is not allowed(default).
|
||||
|
|
|
@ -1143,7 +1143,7 @@ class GetOldMessagesTest(ZulipTestCase):
|
|||
'emoji_name': reaction_name
|
||||
}
|
||||
|
||||
url = '/json/messages/{}/reactions'.format(message_id)
|
||||
url = f'/json/messages/{message_id}/reactions'
|
||||
payload = self.client_post(url, reaction_info)
|
||||
self.assert_json_success(payload)
|
||||
|
||||
|
@ -2667,7 +2667,7 @@ class GetOldMessagesTest(ZulipTestCase):
|
|||
|
||||
stream = get_stream('Scotland', realm)
|
||||
recipient_id = stream.recipient.id
|
||||
cond = "AND NOT (recipient_id = {scotland} AND upper(subject) = upper('golf'))".format(scotland=recipient_id)
|
||||
cond = f"AND NOT (recipient_id = {recipient_id} AND upper(subject) = upper('golf'))"
|
||||
self.assertIn(cond, queries[0]['sql'])
|
||||
|
||||
# Next, verify the use_first_unread_anchor setting invokes
|
||||
|
|
|
@ -332,7 +332,7 @@ so maybe we shouldn't mark it as intentionally undocumented in the urls.
|
|||
except AssertionError: # nocoverage
|
||||
msg = "The following endpoints have been documented but can't be found in urls.py:"
|
||||
for undocumented_path in undocumented_paths:
|
||||
msg += "\n + {}".format(undocumented_path)
|
||||
msg += f"\n + {undocumented_path}"
|
||||
raise AssertionError(msg)
|
||||
|
||||
def get_type_by_priority(self, types: Sequence[Union[type, Tuple[type, object]]]) -> Union[type, Tuple[type, object]]:
|
||||
|
@ -417,7 +417,7 @@ do not match the types declared in the implementation of {}.\n""".format(functio
|
|||
if element[0] == vname:
|
||||
fdvtype = element[1]
|
||||
break
|
||||
msg += "{:<10s}{:^30s}{:>10s}\n".format(vname, str(opvtype), str(fdvtype))
|
||||
msg += f"{vname:<10s}{str(opvtype):^30s}{str(fdvtype):>10s}\n"
|
||||
raise AssertionError(msg)
|
||||
|
||||
def check_argument_types(self, function: Callable[..., HttpResponse],
|
||||
|
|
|
@ -241,7 +241,7 @@ class TestOutgoingWebhookMessaging(ZulipTestCase):
|
|||
bot = self.create_outgoing_bot(bot_owner)
|
||||
|
||||
self.send_stream_message(bot_owner, "Denmark",
|
||||
content="@**{}** foo".format(bot.full_name),
|
||||
content=f"@**{bot.full_name}** foo",
|
||||
topic_name="bar")
|
||||
last_message = self.get_last_message()
|
||||
self.assertEqual(last_message.content, "Hidley ho, I'm a webhook responding!")
|
||||
|
|
|
@ -498,7 +498,7 @@ class UserPresenceAggregationTests(ZulipTestCase):
|
|||
}
|
||||
)
|
||||
|
||||
result = self.client_get("/json/users/{}/presence".format(user.email))
|
||||
result = self.client_get(f"/json/users/{user.email}/presence")
|
||||
return result.json()
|
||||
|
||||
def test_aggregated_info(self) -> None:
|
||||
|
|
|
@ -559,8 +559,8 @@ class AnalyticsBouncerTest(BouncerTestCase):
|
|||
check_for_unwanted_data.first_call = False # type: ignore[attr-defined]
|
||||
else:
|
||||
# Test that we're respecting SYNCED_BILLING_EVENTS
|
||||
self.assertIn('"event_type":{}'.format(RealmAuditLog.USER_REACTIVATED), str(args))
|
||||
self.assertNotIn('"event_type":{}'.format(RealmAuditLog.REALM_LOGO_CHANGED), str(args))
|
||||
self.assertIn(f'"event_type":{RealmAuditLog.USER_REACTIVATED}', str(args))
|
||||
self.assertNotIn(f'"event_type":{RealmAuditLog.REALM_LOGO_CHANGED}', str(args))
|
||||
# Test that we're respecting REALMAUDITLOG_PUSHED_FIELDS
|
||||
self.assertIn('backfilled', str(args))
|
||||
self.assertNotIn('modified_user', str(args))
|
||||
|
@ -1774,7 +1774,7 @@ class TestClearOnRead(ZulipTestCase):
|
|||
|
||||
message_ids = [self.send_stream_message(self.example_user("iago"),
|
||||
stream.name,
|
||||
"yo {}".format(i))
|
||||
f"yo {i}")
|
||||
for i in range(n_msgs)]
|
||||
UserMessage.objects.filter(
|
||||
user_profile_id=hamlet.id,
|
||||
|
|
|
@ -78,7 +78,7 @@ class RealmExportTest(ZulipTestCase):
|
|||
event_type=RealmAuditLog.REALM_EXPORTED).count())
|
||||
|
||||
# Finally, delete the file.
|
||||
result = self.client_delete('/json/export/realm/{id}'.format(id=audit_log_entry.id))
|
||||
result = self.client_delete(f'/json/export/realm/{audit_log_entry.id}')
|
||||
self.assert_json_success(result)
|
||||
with self.assertRaises(botocore.exceptions.ClientError):
|
||||
bucket.Object(path_id).load()
|
||||
|
@ -87,7 +87,7 @@ class RealmExportTest(ZulipTestCase):
|
|||
audit_log_entry.refresh_from_db()
|
||||
export_data = ujson.loads(audit_log_entry.extra_data)
|
||||
self.assertIn('deleted_timestamp', export_data)
|
||||
result = self.client_delete('/json/export/realm/{id}'.format(id=audit_log_entry.id))
|
||||
result = self.client_delete(f'/json/export/realm/{audit_log_entry.id}')
|
||||
self.assert_json_error(result, "Export already deleted")
|
||||
|
||||
# Now try to delete a non-existent export.
|
||||
|
@ -137,7 +137,7 @@ class RealmExportTest(ZulipTestCase):
|
|||
event_type=RealmAuditLog.REALM_EXPORTED).count())
|
||||
|
||||
# Finally, delete the file.
|
||||
result = self.client_delete('/json/export/realm/{id}'.format(id=audit_log_entry.id))
|
||||
result = self.client_delete(f'/json/export/realm/{audit_log_entry.id}')
|
||||
self.assert_json_success(result)
|
||||
response = self.client_get(path_id)
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
@ -146,7 +146,7 @@ class RealmExportTest(ZulipTestCase):
|
|||
audit_log_entry.refresh_from_db()
|
||||
export_data = ujson.loads(audit_log_entry.extra_data)
|
||||
self.assertIn('deleted_timestamp', export_data)
|
||||
result = self.client_delete('/json/export/realm/{id}'.format(id=audit_log_entry.id))
|
||||
result = self.client_delete(f'/json/export/realm/{audit_log_entry.id}')
|
||||
self.assert_json_error(result, "Export already deleted")
|
||||
|
||||
# Now try to delete a non-existent export.
|
||||
|
|
|
@ -107,9 +107,9 @@ class RealmFilterTest(ZulipTestCase):
|
|||
"#(?P<id>[123])",
|
||||
"https://realm.com/my_realm_filter/%(id)s")
|
||||
filters_count = RealmFilter.objects.count()
|
||||
result = self.client_delete("/json/realm/filters/{}".format(filter_id + 1))
|
||||
result = self.client_delete(f"/json/realm/filters/{filter_id + 1}")
|
||||
self.assert_json_error(result, 'Filter not found')
|
||||
|
||||
result = self.client_delete("/json/realm/filters/{}".format(filter_id))
|
||||
result = self.client_delete(f"/json/realm/filters/{filter_id}")
|
||||
self.assert_json_success(result)
|
||||
self.assertEqual(RealmFilter.objects.count(), filters_count - 1)
|
||||
|
|
|
@ -257,7 +257,7 @@ class PasswordResetTest(ZulipTestCase):
|
|||
email, url_pattern=settings.EXTERNAL_HOST + r"(\S\S+)")
|
||||
result = self.client_get(password_reset_url)
|
||||
self.assertEqual(result.status_code, 302)
|
||||
self.assertTrue(result.url.endswith('/{}/'.format(INTERNAL_RESET_URL_TOKEN)))
|
||||
self.assertTrue(result.url.endswith(f'/{INTERNAL_RESET_URL_TOKEN}/'))
|
||||
|
||||
final_reset_url = result.url
|
||||
result = self.client_get(final_reset_url)
|
||||
|
@ -593,7 +593,7 @@ class LoginTest(ZulipTestCase):
|
|||
reset_emails_in_zulip_realm()
|
||||
|
||||
realm = get_realm("zulip")
|
||||
stream_names = ["stream_{}".format(i) for i in range(40)]
|
||||
stream_names = [f"stream_{i}" for i in range(40)]
|
||||
for stream_name in stream_names:
|
||||
stream = self.make_stream(stream_name, realm=realm)
|
||||
DefaultStream.objects.create(stream=stream, realm=realm)
|
||||
|
@ -1007,7 +1007,7 @@ class InviteUserTest(InviteUserBase):
|
|||
"""
|
||||
self.login('hamlet')
|
||||
email = "alice-test@zulip.com"
|
||||
invitee = "Alice Test <{}>".format(email)
|
||||
invitee = f"Alice Test <{email}>"
|
||||
self.assert_json_success(self.invite(invitee, ["Denmark"]))
|
||||
self.assertTrue(find_key_by_email(email))
|
||||
self.check_sent_emails([email], custom_from_name="Hamlet")
|
||||
|
@ -1020,7 +1020,7 @@ class InviteUserTest(InviteUserBase):
|
|||
self.login('hamlet')
|
||||
email = "alice-test@zulip.com"
|
||||
email2 = "bob-test@zulip.com"
|
||||
invitee = "Alice Test <{}>, {}".format(email, email2)
|
||||
invitee = f"Alice Test <{email}>, {email2}"
|
||||
self.assert_json_success(self.invite(invitee, ["Denmark"]))
|
||||
self.assertTrue(find_key_by_email(email))
|
||||
self.assertTrue(find_key_by_email(email2))
|
||||
|
@ -1037,7 +1037,7 @@ class InviteUserTest(InviteUserBase):
|
|||
self.login('hamlet')
|
||||
email = "alice-test@zulip.com"
|
||||
email2 = "bob-test@zulip.com"
|
||||
invitee = "Alice Test <{}>, {}".format(email, email2)
|
||||
invitee = f"Alice Test <{email}>, {email2}"
|
||||
self.assert_json_error(self.invite(invitee, ["Denmark"]),
|
||||
"Must be an organization administrator")
|
||||
|
||||
|
@ -1090,7 +1090,7 @@ class InviteUserTest(InviteUserBase):
|
|||
second_msg = last_3_messages[1]
|
||||
self.assertEqual(second_msg.sender.email, "notification-bot@zulip.com")
|
||||
self.assertTrue(second_msg.content.startswith(
|
||||
"alice_zulip.com <`{}`> accepted your".format(invitee_profile.email)
|
||||
f"alice_zulip.com <`{invitee_profile.email}`> accepted your"
|
||||
))
|
||||
|
||||
# The second, from welcome-bot to the user who was invited.
|
||||
|
@ -1175,7 +1175,7 @@ earl-test@zulip.com""", ["Denmark"]))
|
|||
"""
|
||||
self.login('hamlet')
|
||||
self.assert_json_error(self.invite("iago-test@zulip.com", ["NotARealStream"]),
|
||||
"Stream does not exist with id: {}. No invites were sent.".format(self.INVALID_STREAM_ID))
|
||||
f"Stream does not exist with id: {self.INVALID_STREAM_ID}. No invites were sent.")
|
||||
self.check_sent_emails([])
|
||||
|
||||
def test_invite_existing_user(self) -> None:
|
||||
|
@ -1878,22 +1878,22 @@ class InviteeEmailsParserTests(TestCase):
|
|||
self.email3 = "email3@zulip.com"
|
||||
|
||||
def test_if_emails_separated_by_commas_are_parsed_and_striped_correctly(self) -> None:
|
||||
emails_raw = "{} ,{}, {}".format(self.email1, self.email2, self.email3)
|
||||
emails_raw = f"{self.email1} ,{self.email2}, {self.email3}"
|
||||
expected_set = {self.email1, self.email2, self.email3}
|
||||
self.assertEqual(get_invitee_emails_set(emails_raw), expected_set)
|
||||
|
||||
def test_if_emails_separated_by_newlines_are_parsed_and_striped_correctly(self) -> None:
|
||||
emails_raw = "{}\n {}\n {} ".format(self.email1, self.email2, self.email3)
|
||||
emails_raw = f"{self.email1}\n {self.email2}\n {self.email3} "
|
||||
expected_set = {self.email1, self.email2, self.email3}
|
||||
self.assertEqual(get_invitee_emails_set(emails_raw), expected_set)
|
||||
|
||||
def test_if_emails_from_email_client_separated_by_newlines_are_parsed_correctly(self) -> None:
|
||||
emails_raw = "Email One <{}>\nEmailTwo<{}>\nEmail Three<{}>".format(self.email1, self.email2, self.email3)
|
||||
emails_raw = f"Email One <{self.email1}>\nEmailTwo<{self.email2}>\nEmail Three<{self.email3}>"
|
||||
expected_set = {self.email1, self.email2, self.email3}
|
||||
self.assertEqual(get_invitee_emails_set(emails_raw), expected_set)
|
||||
|
||||
def test_if_emails_in_mixed_style_are_parsed_correctly(self) -> None:
|
||||
emails_raw = "Email One <{}>,EmailTwo<{}>\n{}".format(self.email1, self.email2, self.email3)
|
||||
emails_raw = f"Email One <{self.email1}>,EmailTwo<{self.email2}>\n{self.email3}"
|
||||
expected_set = {self.email1, self.email2, self.email3}
|
||||
self.assertEqual(get_invitee_emails_set(emails_raw), expected_set)
|
||||
|
||||
|
@ -3018,7 +3018,7 @@ class UserSignUpTest(InviteUserBase):
|
|||
request.session = {} # type: ignore[attr-defined]
|
||||
email = 'user@acme.com'
|
||||
form = HomepageForm({'email': email}, realm=realm)
|
||||
self.assertIn("Your email address, {}, is not in one of the domains".format(email),
|
||||
self.assertIn(f"Your email address, {email}, is not in one of the domains",
|
||||
form.errors['email'][0])
|
||||
|
||||
def test_failed_signup_due_to_disposable_email(self) -> None:
|
||||
|
@ -3052,7 +3052,7 @@ class UserSignUpTest(InviteUserBase):
|
|||
request.session = {} # type: ignore[attr-defined]
|
||||
email = 'user@zulip.com'
|
||||
form = HomepageForm({'email': email}, realm=realm)
|
||||
self.assertIn("Please request an invite for {} from".format(email),
|
||||
self.assertIn(f"Please request an invite for {email} from",
|
||||
form.errors['email'][0])
|
||||
|
||||
def test_failed_signup_due_to_nonexistent_realm(self) -> None:
|
||||
|
@ -3856,10 +3856,10 @@ class UserSignUpTest(InviteUserBase):
|
|||
result = self.client_post('/devtools/register_realm/')
|
||||
self.assertEqual(result.status_code, 302)
|
||||
self.assertTrue(result["Location"].startswith(
|
||||
'http://{}.testserver/accounts/login/subdomain'.format(string_id)))
|
||||
f'http://{string_id}.testserver/accounts/login/subdomain'))
|
||||
result = self.client_get(result["Location"], subdomain=string_id)
|
||||
self.assertEqual(result.status_code, 302)
|
||||
self.assertEqual(result["Location"], 'http://{}.testserver'.format(string_id))
|
||||
self.assertEqual(result["Location"], f'http://{string_id}.testserver')
|
||||
|
||||
user_profile = UserProfile.objects.all().order_by("id").last()
|
||||
self.assert_logged_in_user_id(user_profile.id)
|
||||
|
@ -4041,7 +4041,7 @@ class TestFindMyTeam(ZulipTestCase):
|
|||
self.assertEqual(len(outbox), 0)
|
||||
|
||||
def test_find_team_more_than_ten_emails(self) -> None:
|
||||
data = {'emails': ','.join(['hamlet-{}@zulip.com'.format(i) for i in range(11)])}
|
||||
data = {'emails': ','.join([f'hamlet-{i}@zulip.com' for i in range(11)])}
|
||||
result = self.client_post('/accounts/find/', data)
|
||||
self.assertEqual(result.status_code, 200)
|
||||
self.assertIn("Please enter at most 10", result.content.decode('utf8'))
|
||||
|
|
|
@ -831,7 +831,7 @@ class SlackImporter(ZulipTestCase):
|
|||
|
||||
image_path = zerver_attachment[0]['path_id']
|
||||
self.assertIn('/SlackImportAttachment/', image_path)
|
||||
expected_content = '[Apple](/user_uploads/{image_path})\n[banana](example.com/banana.zip)'.format(image_path=image_path)
|
||||
expected_content = f'[Apple](/user_uploads/{image_path})\n[banana](example.com/banana.zip)'
|
||||
self.assertEqual(info['content'], expected_content)
|
||||
|
||||
self.assertTrue(info['has_link'])
|
||||
|
|
|
@ -702,7 +702,7 @@ class StreamAdminTest(ZulipTestCase):
|
|||
# Inspect the notification message sent
|
||||
message = self.get_last_message()
|
||||
actual_stream = Stream.objects.get(id=message.recipient.type_id)
|
||||
message_content = '@_**King Hamlet|{}** renamed stream **stream_name1** to **stream_name2**.'.format(user_profile.id)
|
||||
message_content = f'@_**King Hamlet|{user_profile.id}** renamed stream **stream_name1** to **stream_name2**.'
|
||||
self.assertEqual(actual_stream.name, 'stream_name2')
|
||||
self.assertEqual(actual_stream.realm_id, user_profile.realm_id)
|
||||
self.assertEqual(message.recipient.type, Recipient.STREAM)
|
||||
|
@ -1458,11 +1458,11 @@ class DefaultStreamGroupTest(ZulipTestCase):
|
|||
new_streams.append(new_stream)
|
||||
streams.append(new_stream)
|
||||
|
||||
result = self.client_patch("/json/default_stream_groups/{}/streams".format(group_id),
|
||||
result = self.client_patch(f"/json/default_stream_groups/{group_id}/streams",
|
||||
{"stream_names": ujson.dumps(new_stream_names)})
|
||||
self.assert_json_error(result, "Missing 'op' argument")
|
||||
|
||||
result = self.client_patch("/json/default_stream_groups/{}/streams".format(group_id),
|
||||
result = self.client_patch(f"/json/default_stream_groups/{group_id}/streams",
|
||||
{"op": "invalid", "stream_names": ujson.dumps(new_stream_names)})
|
||||
self.assert_json_error(result, 'Invalid value for "op". Specify one of "add" or "remove".')
|
||||
|
||||
|
@ -1470,16 +1470,16 @@ class DefaultStreamGroupTest(ZulipTestCase):
|
|||
{"op": "add", "stream_names": ujson.dumps(new_stream_names)})
|
||||
self.assert_json_error(result, "Default stream group with id '12345' does not exist.")
|
||||
|
||||
result = self.client_patch("/json/default_stream_groups/{}/streams".format(group_id), {"op": "add"})
|
||||
result = self.client_patch(f"/json/default_stream_groups/{group_id}/streams", {"op": "add"})
|
||||
self.assert_json_error(result, "Missing 'stream_names' argument")
|
||||
|
||||
do_add_default_stream(new_streams[0])
|
||||
result = self.client_patch("/json/default_stream_groups/{}/streams".format(group_id),
|
||||
result = self.client_patch(f"/json/default_stream_groups/{group_id}/streams",
|
||||
{"op": "add", "stream_names": ujson.dumps(new_stream_names)})
|
||||
self.assert_json_error(result, "'stream4' is a default stream and cannot be added to 'group1'")
|
||||
|
||||
do_remove_default_stream(new_streams[0])
|
||||
result = self.client_patch("/json/default_stream_groups/{}/streams".format(group_id),
|
||||
result = self.client_patch(f"/json/default_stream_groups/{group_id}/streams",
|
||||
{"op": "add", "stream_names": ujson.dumps(new_stream_names)})
|
||||
self.assert_json_success(result)
|
||||
default_stream_groups = get_default_stream_groups(realm)
|
||||
|
@ -1487,7 +1487,7 @@ class DefaultStreamGroupTest(ZulipTestCase):
|
|||
self.assertEqual(default_stream_groups[0].name, group_name)
|
||||
self.assertEqual(list(default_stream_groups[0].streams.all().order_by('name')), streams)
|
||||
|
||||
result = self.client_patch("/json/default_stream_groups/{}/streams".format(group_id),
|
||||
result = self.client_patch(f"/json/default_stream_groups/{group_id}/streams",
|
||||
{"op": "add", "stream_names": ujson.dumps(new_stream_names)})
|
||||
self.assert_json_error(result,
|
||||
"Stream 'stream4' is already present in default stream group 'group1'")
|
||||
|
@ -1497,12 +1497,12 @@ class DefaultStreamGroupTest(ZulipTestCase):
|
|||
{"op": "remove", "stream_names": ujson.dumps(new_stream_names)})
|
||||
self.assert_json_error(result, "Default stream group with id '12345' does not exist.")
|
||||
|
||||
result = self.client_patch("/json/default_stream_groups/{}/streams".format(group_id),
|
||||
result = self.client_patch(f"/json/default_stream_groups/{group_id}/streams",
|
||||
{"op": "remove", "stream_names": ujson.dumps(["random stream name"])})
|
||||
self.assert_json_error(result, "Invalid stream name 'random stream name'")
|
||||
|
||||
streams.remove(new_streams[0])
|
||||
result = self.client_patch("/json/default_stream_groups/{}/streams".format(group_id),
|
||||
result = self.client_patch(f"/json/default_stream_groups/{group_id}/streams",
|
||||
{"op": "remove", "stream_names": ujson.dumps([new_stream_names[0]])})
|
||||
self.assert_json_success(result)
|
||||
default_stream_groups = get_default_stream_groups(realm)
|
||||
|
@ -1510,14 +1510,14 @@ class DefaultStreamGroupTest(ZulipTestCase):
|
|||
self.assertEqual(default_stream_groups[0].name, group_name)
|
||||
self.assertEqual(list(default_stream_groups[0].streams.all().order_by('name')), streams)
|
||||
|
||||
result = self.client_patch("/json/default_stream_groups/{}/streams".format(group_id),
|
||||
result = self.client_patch(f"/json/default_stream_groups/{group_id}/streams",
|
||||
{"op": "remove", "stream_names": ujson.dumps(new_stream_names)})
|
||||
self.assert_json_error(result, "Stream 'stream4' is not present in default stream group 'group1'")
|
||||
|
||||
# Test changing description of default stream group
|
||||
new_description = "new group1 description"
|
||||
|
||||
result = self.client_patch("/json/default_stream_groups/{}".format(group_id),
|
||||
result = self.client_patch(f"/json/default_stream_groups/{group_id}",
|
||||
{"group_name": group_name, "op": "change"})
|
||||
self.assert_json_error(result, 'You must pass "new_description" or "new_group_name".')
|
||||
|
||||
|
@ -1525,7 +1525,7 @@ class DefaultStreamGroupTest(ZulipTestCase):
|
|||
{"op": "change", "new_description": ujson.dumps(new_description)})
|
||||
self.assert_json_error(result, "Default stream group with id '12345' does not exist.")
|
||||
|
||||
result = self.client_patch("/json/default_stream_groups/{}".format(group_id),
|
||||
result = self.client_patch(f"/json/default_stream_groups/{group_id}",
|
||||
{"group_name": group_name,
|
||||
"op": "change",
|
||||
"new_description": ujson.dumps(new_description)})
|
||||
|
@ -1538,17 +1538,17 @@ class DefaultStreamGroupTest(ZulipTestCase):
|
|||
# Test changing name of default stream group
|
||||
new_group_name = "new group1"
|
||||
do_create_default_stream_group(realm, "group2", "", [])
|
||||
result = self.client_patch("/json/default_stream_groups/{}".format(group_id),
|
||||
result = self.client_patch(f"/json/default_stream_groups/{group_id}",
|
||||
{"op": "change", "new_group_name": ujson.dumps("group2")})
|
||||
self.assert_json_error(result, "Default stream group 'group2' already exists")
|
||||
new_group = lookup_default_stream_groups(["group2"], realm)[0]
|
||||
do_remove_default_stream_group(realm, new_group)
|
||||
|
||||
result = self.client_patch("/json/default_stream_groups/{}".format(group_id),
|
||||
result = self.client_patch(f"/json/default_stream_groups/{group_id}",
|
||||
{"op": "change", "new_group_name": ujson.dumps(group_name)})
|
||||
self.assert_json_error(result, "This default stream group is already named 'group1'")
|
||||
|
||||
result = self.client_patch("/json/default_stream_groups/{}".format(group_id),
|
||||
result = self.client_patch(f"/json/default_stream_groups/{group_id}",
|
||||
{"op": "change", "new_group_name": ujson.dumps(new_group_name)})
|
||||
self.assert_json_success(result)
|
||||
default_stream_groups = get_default_stream_groups(realm)
|
||||
|
@ -1557,13 +1557,13 @@ class DefaultStreamGroupTest(ZulipTestCase):
|
|||
self.assertEqual(default_stream_groups[0].description, new_description)
|
||||
|
||||
# Test deleting a default stream group
|
||||
result = self.client_delete('/json/default_stream_groups/{}'.format(group_id))
|
||||
result = self.client_delete(f'/json/default_stream_groups/{group_id}')
|
||||
self.assert_json_success(result)
|
||||
default_stream_groups = get_default_stream_groups(realm)
|
||||
self.assert_length(default_stream_groups, 0)
|
||||
|
||||
result = self.client_delete('/json/default_stream_groups/{}'.format(group_id))
|
||||
self.assert_json_error(result, "Default stream group with id '{}' does not exist.".format(group_id))
|
||||
result = self.client_delete(f'/json/default_stream_groups/{group_id}')
|
||||
self.assert_json_error(result, f"Default stream group with id '{group_id}' does not exist.")
|
||||
|
||||
def test_invalid_default_stream_group_name(self) -> None:
|
||||
self.login('iago')
|
||||
|
@ -2900,7 +2900,7 @@ class SubscriptionAPITest(ZulipTestCase):
|
|||
result = self.common_subscribe_to_streams(self.test_user, "Denmark", post_data)
|
||||
self.assert_json_error(
|
||||
result,
|
||||
"User not authorized to execute queries on behalf of '{}'".format(target_profile.id),
|
||||
f"User not authorized to execute queries on behalf of '{target_profile.id}'",
|
||||
status_code=403)
|
||||
|
||||
def test_subscriptions_add_for_principal_invite_only(self) -> None:
|
||||
|
|
|
@ -66,7 +66,7 @@ class TornadoWebTestCase(AsyncHTTPTestCase, ZulipTestCase):
|
|||
session_cookie = settings.SESSION_COOKIE_NAME
|
||||
session_key = self.client.session.session_key
|
||||
self.session_cookie = {
|
||||
"Cookie": "{}={}".format(session_cookie, session_key)
|
||||
"Cookie": f"{session_cookie}={session_key}"
|
||||
}
|
||||
|
||||
def get_session_cookie(self) -> Dict[str, str]:
|
||||
|
@ -102,7 +102,7 @@ class EventsTestCase(TornadoWebTestCase):
|
|||
'last_event_id': -1,
|
||||
}
|
||||
|
||||
path = '/json/events?{}'.format(urllib.parse.urlencode(data))
|
||||
path = f'/json/events?{urllib.parse.urlencode(data)}'
|
||||
self.client_get_async(path)
|
||||
|
||||
def process_events() -> None:
|
||||
|
|
|
@ -353,9 +353,9 @@ class FileUploadTest(UploadSerializeMixin, ZulipTestCase):
|
|||
|
||||
self.subscribe(self.example_user("hamlet"), "Denmark")
|
||||
host = self.example_user('hamlet').realm.host
|
||||
body = "First message ...[zulip.txt](http://{}/user_uploads/".format(host) + d1_path_id + ")"
|
||||
body = f"First message ...[zulip.txt](http://{host}/user_uploads/" + d1_path_id + ")"
|
||||
self.send_stream_message(self.example_user("hamlet"), "Denmark", body, "test")
|
||||
body = "Second message ...[zulip.txt](http://{}/user_uploads/".format(host) + d1_path_id + ")"
|
||||
body = f"Second message ...[zulip.txt](http://{host}/user_uploads/" + d1_path_id + ")"
|
||||
self.send_stream_message(self.example_user("hamlet"), "Denmark", body, "test")
|
||||
|
||||
self.assertEqual(Attachment.objects.get(path_id=d1_path_id).messages.count(), 2)
|
||||
|
@ -374,25 +374,25 @@ class FileUploadTest(UploadSerializeMixin, ZulipTestCase):
|
|||
self.subscribe(self.example_user("hamlet"), "private_stream")
|
||||
|
||||
# First, send the message to the new private stream.
|
||||
body = "First message ...[zulip.txt](http://{}/user_uploads/".format(host) + d1_path_id + ")"
|
||||
body = f"First message ...[zulip.txt](http://{host}/user_uploads/" + d1_path_id + ")"
|
||||
self.send_stream_message(self.example_user("hamlet"), "private_stream", body, "test")
|
||||
self.assertFalse(Attachment.objects.get(path_id=d1_path_id).is_realm_public)
|
||||
self.assertEqual(Attachment.objects.get(path_id=d1_path_id).messages.count(), 1)
|
||||
|
||||
# Then, try having a user who didn't receive the message try to publish it, and fail
|
||||
body = "Illegal message ...[zulip.txt](http://{}/user_uploads/".format(host) + d1_path_id + ")"
|
||||
body = f"Illegal message ...[zulip.txt](http://{host}/user_uploads/" + d1_path_id + ")"
|
||||
self.send_stream_message(self.example_user("cordelia"), "Denmark", body, "test")
|
||||
self.assertEqual(Attachment.objects.get(path_id=d1_path_id).messages.count(), 1)
|
||||
self.assertFalse(Attachment.objects.get(path_id=d1_path_id).is_realm_public)
|
||||
|
||||
# Then, have the owner PM it to another user, giving that other user access.
|
||||
body = "Second message ...[zulip.txt](http://{}/user_uploads/".format(host) + d1_path_id + ")"
|
||||
body = f"Second message ...[zulip.txt](http://{host}/user_uploads/" + d1_path_id + ")"
|
||||
self.send_personal_message(self.example_user("hamlet"), self.example_user("othello"), body)
|
||||
self.assertEqual(Attachment.objects.get(path_id=d1_path_id).messages.count(), 2)
|
||||
self.assertFalse(Attachment.objects.get(path_id=d1_path_id).is_realm_public)
|
||||
|
||||
# Then, have that new recipient user publish it.
|
||||
body = "Third message ...[zulip.txt](http://{}/user_uploads/".format(host) + d1_path_id + ")"
|
||||
body = f"Third message ...[zulip.txt](http://{host}/user_uploads/" + d1_path_id + ")"
|
||||
self.send_stream_message(self.example_user("othello"), "Denmark", body, "test")
|
||||
self.assertEqual(Attachment.objects.get(path_id=d1_path_id).messages.count(), 3)
|
||||
self.assertTrue(Attachment.objects.get(path_id=d1_path_id).is_realm_public)
|
||||
|
@ -415,14 +415,14 @@ class FileUploadTest(UploadSerializeMixin, ZulipTestCase):
|
|||
f2_path_id = re.sub('/user_uploads/', '', result.json()['uri'])
|
||||
|
||||
self.subscribe(hamlet, "test")
|
||||
body = ("[f1.txt](http://{}/user_uploads/".format(host) + f1_path_id + ") "
|
||||
body = (f"[f1.txt](http://{host}/user_uploads/" + f1_path_id + ") "
|
||||
"[f2.txt](http://{}/user_uploads/".format(host) + f2_path_id + ")")
|
||||
msg_id = self.send_stream_message(hamlet, "test", body, "test")
|
||||
|
||||
result = self.client_post("/json/user_uploads", {'file': f3})
|
||||
f3_path_id = re.sub('/user_uploads/', '', result.json()['uri'])
|
||||
|
||||
new_body = ("[f3.txt](http://{}/user_uploads/".format(host) + f3_path_id + ") "
|
||||
new_body = (f"[f3.txt](http://{host}/user_uploads/" + f3_path_id + ") "
|
||||
"[f2.txt](http://{}/user_uploads/".format(host) + f2_path_id + ")")
|
||||
result = self.client_patch("/json/messages/" + str(msg_id), {
|
||||
'message_id': msg_id,
|
||||
|
@ -535,7 +535,7 @@ class FileUploadTest(UploadSerializeMixin, ZulipTestCase):
|
|||
result = self.client_post("/json/user_uploads", {'file': fp})
|
||||
uri = result.json()['uri']
|
||||
fp_path_id = re.sub('/user_uploads/', '', uri)
|
||||
body = "First message ...[zulip.txt](http://{}/user_uploads/".format(host) + fp_path_id + ")"
|
||||
body = f"First message ...[zulip.txt](http://{host}/user_uploads/" + fp_path_id + ")"
|
||||
with self.settings(CROSS_REALM_BOT_EMAILS = {user_2.email, user_3.email}):
|
||||
internal_send_private_message(
|
||||
realm=r1,
|
||||
|
@ -575,7 +575,7 @@ class FileUploadTest(UploadSerializeMixin, ZulipTestCase):
|
|||
result = self.client_post("/json/user_uploads", {'file': fp})
|
||||
uri = result.json()['uri']
|
||||
fp_path_id = re.sub('/user_uploads/', '', uri)
|
||||
body = "First message ...[zulip.txt](http://{}/user_uploads/".format(realm.host) + fp_path_id + ")"
|
||||
body = f"First message ...[zulip.txt](http://{realm.host}/user_uploads/" + fp_path_id + ")"
|
||||
self.send_stream_message(hamlet, stream_name, body, "test")
|
||||
self.logout()
|
||||
|
||||
|
@ -629,7 +629,7 @@ class FileUploadTest(UploadSerializeMixin, ZulipTestCase):
|
|||
result = self.client_post("/json/user_uploads", {'file': fp})
|
||||
uri = result.json()['uri']
|
||||
fp_path_id = re.sub('/user_uploads/', '', uri)
|
||||
body = "First message ...[zulip.txt](http://{}/user_uploads/".format(user.realm.host) + fp_path_id + ")"
|
||||
body = f"First message ...[zulip.txt](http://{user.realm.host}/user_uploads/" + fp_path_id + ")"
|
||||
self.send_stream_message(user, stream_name, body, "test")
|
||||
self.logout()
|
||||
|
||||
|
@ -697,7 +697,7 @@ class FileUploadTest(UploadSerializeMixin, ZulipTestCase):
|
|||
uri = result.json()['uri']
|
||||
fp_path_id = re.sub('/user_uploads/', '', uri)
|
||||
for i in range(20):
|
||||
body = "First message ...[zulip.txt](http://{}/user_uploads/".format(hamlet.realm.host) + fp_path_id + ")"
|
||||
body = f"First message ...[zulip.txt](http://{hamlet.realm.host}/user_uploads/" + fp_path_id + ")"
|
||||
self.send_stream_message(self.example_user("hamlet"), "test-subscribe %s" % (i % 5,), body, "test")
|
||||
self.logout()
|
||||
|
||||
|
@ -739,7 +739,7 @@ class FileUploadTest(UploadSerializeMixin, ZulipTestCase):
|
|||
result = self.client_post("/json/user_uploads", {'file': fp})
|
||||
uri = result.json()['uri']
|
||||
fp_path_id = re.sub('/user_uploads/', '', uri)
|
||||
body = "First message ...[zulip.txt](http://{}/user_uploads/".format(realm.host) + fp_path_id + ")"
|
||||
body = f"First message ...[zulip.txt](http://{realm.host}/user_uploads/" + fp_path_id + ")"
|
||||
self.send_stream_message(self.example_user("hamlet"), "test-subscribe", body, "test")
|
||||
self.logout()
|
||||
|
||||
|
@ -1530,7 +1530,7 @@ class LocalStorageTest(UploadSerializeMixin, ZulipTestCase):
|
|||
realm_id=user_profile.realm_id,
|
||||
emoji_file_name=file_name,
|
||||
)
|
||||
expected_url = "/user_avatars/{emoji_path}".format(emoji_path=emoji_path)
|
||||
expected_url = f"/user_avatars/{emoji_path}"
|
||||
self.assertEqual(expected_url, url)
|
||||
|
||||
def test_tarball_upload_and_deletion_local(self) -> None:
|
||||
|
@ -1843,7 +1843,7 @@ class S3Test(ZulipTestCase):
|
|||
|
||||
url = zerver.lib.upload.upload_backend.get_emoji_url('emoji.png', realm_id)
|
||||
|
||||
expected_url = "https://{bucket}.s3.amazonaws.com/{path}".format(bucket=bucket, path=path)
|
||||
expected_url = f"https://{bucket}.s3.amazonaws.com/{path}"
|
||||
self.assertEqual(expected_url, url)
|
||||
|
||||
@use_s3_backend
|
||||
|
|
|
@ -150,11 +150,11 @@ class UserGroupAPITestCase(ZulipTestCase):
|
|||
'name': 'help',
|
||||
'description': 'Troubleshooting team',
|
||||
}
|
||||
result = self.client_patch('/json/user_groups/{}'.format(user_group.id), info=params)
|
||||
result = self.client_patch(f'/json/user_groups/{user_group.id}', info=params)
|
||||
self.assert_json_success(result)
|
||||
|
||||
# Test when new data is not supplied.
|
||||
result = self.client_patch('/json/user_groups/{}'.format(user_group.id), info={})
|
||||
result = self.client_patch(f'/json/user_groups/{user_group.id}', info={})
|
||||
self.assert_json_error(result, "No new data supplied")
|
||||
|
||||
# Test when invalid user group is supplied
|
||||
|
@ -170,7 +170,7 @@ class UserGroupAPITestCase(ZulipTestCase):
|
|||
'name': 'help',
|
||||
'description': 'Troubleshooting',
|
||||
}
|
||||
result = self.client_patch('/json/user_groups/{}'.format(user_group.id), info=params)
|
||||
result = self.client_patch(f'/json/user_groups/{user_group.id}', info=params)
|
||||
self.assert_json_error(result, "Only group members and organization administrators can administer this group.")
|
||||
|
||||
self.logout()
|
||||
|
@ -181,7 +181,7 @@ class UserGroupAPITestCase(ZulipTestCase):
|
|||
'name': 'help',
|
||||
'description': 'Troubleshooting',
|
||||
}
|
||||
result = self.client_patch('/json/user_groups/{}'.format(user_group.id), info=params)
|
||||
result = self.client_patch(f'/json/user_groups/{user_group.id}', info=params)
|
||||
self.assert_json_success(result)
|
||||
|
||||
def test_user_group_update_by_guest_user(self) -> None:
|
||||
|
@ -203,7 +203,7 @@ class UserGroupAPITestCase(ZulipTestCase):
|
|||
'name': 'help',
|
||||
'description': 'Troubleshooting team',
|
||||
}
|
||||
result = self.client_patch('/json/user_groups/{}'.format(user_group.id), info=params)
|
||||
result = self.client_patch(f'/json/user_groups/{user_group.id}', info=params)
|
||||
self.assert_json_error(result, "Not allowed for guest users")
|
||||
|
||||
def test_user_group_update_to_already_existing_name(self) -> None:
|
||||
|
@ -216,9 +216,9 @@ class UserGroupAPITestCase(ZulipTestCase):
|
|||
params = {
|
||||
'name': marketing_user_group.name,
|
||||
}
|
||||
result = self.client_patch('/json/user_groups/{}'.format(support_user_group.id), info=params)
|
||||
result = self.client_patch(f'/json/user_groups/{support_user_group.id}', info=params)
|
||||
self.assert_json_error(
|
||||
result, "User group '{}' already exists.".format(marketing_user_group.name))
|
||||
result, f"User group '{marketing_user_group.name}' already exists.")
|
||||
|
||||
def test_user_group_delete(self) -> None:
|
||||
hamlet = self.example_user('hamlet')
|
||||
|
@ -233,7 +233,7 @@ class UserGroupAPITestCase(ZulipTestCase):
|
|||
# Test success
|
||||
self.assertEqual(UserGroup.objects.count(), 2)
|
||||
self.assertEqual(UserGroupMembership.objects.count(), 3)
|
||||
result = self.client_delete('/json/user_groups/{}'.format(user_group.id))
|
||||
result = self.client_delete(f'/json/user_groups/{user_group.id}')
|
||||
self.assert_json_success(result)
|
||||
self.assertEqual(UserGroup.objects.count(), 1)
|
||||
self.assertEqual(UserGroupMembership.objects.count(), 2)
|
||||
|
@ -255,7 +255,7 @@ class UserGroupAPITestCase(ZulipTestCase):
|
|||
cordelia = self.example_user('cordelia')
|
||||
self.login_user(cordelia)
|
||||
|
||||
result = self.client_delete('/json/user_groups/{}'.format(user_group.id))
|
||||
result = self.client_delete(f'/json/user_groups/{user_group.id}')
|
||||
self.assert_json_error(result, "Only group members and organization administrators can administer this group.")
|
||||
self.assertEqual(UserGroup.objects.count(), 2)
|
||||
|
||||
|
@ -264,7 +264,7 @@ class UserGroupAPITestCase(ZulipTestCase):
|
|||
iago = self.example_user('iago')
|
||||
self.login_user(iago)
|
||||
|
||||
result = self.client_delete('/json/user_groups/{}'.format(user_group.id))
|
||||
result = self.client_delete(f'/json/user_groups/{user_group.id}')
|
||||
self.assert_json_success(result)
|
||||
self.assertEqual(UserGroup.objects.count(), 1)
|
||||
self.assertEqual(UserGroupMembership.objects.count(), 2)
|
||||
|
@ -284,7 +284,7 @@ class UserGroupAPITestCase(ZulipTestCase):
|
|||
|
||||
# Guest users can't delete any user group(not even those of which they are a member)
|
||||
self.login_user(guest_user)
|
||||
result = self.client_delete('/json/user_groups/{}'.format(user_group.id))
|
||||
result = self.client_delete(f'/json/user_groups/{user_group.id}')
|
||||
self.assert_json_error(result, "Not allowed for guest users")
|
||||
|
||||
def test_update_members_of_user_group(self) -> None:
|
||||
|
@ -303,7 +303,7 @@ class UserGroupAPITestCase(ZulipTestCase):
|
|||
othello = self.example_user('othello')
|
||||
add = [othello.id]
|
||||
params = {'add': ujson.dumps(add)}
|
||||
result = self.client_post('/json/user_groups/{}/members'.format(user_group.id),
|
||||
result = self.client_post(f'/json/user_groups/{user_group.id}/members',
|
||||
info=params)
|
||||
self.assert_json_success(result)
|
||||
self.assertEqual(UserGroupMembership.objects.count(), 4)
|
||||
|
@ -311,9 +311,9 @@ class UserGroupAPITestCase(ZulipTestCase):
|
|||
self.assertEqual(len(members), 2)
|
||||
|
||||
# Test adding a member already there.
|
||||
result = self.client_post('/json/user_groups/{}/members'.format(user_group.id),
|
||||
result = self.client_post(f'/json/user_groups/{user_group.id}/members',
|
||||
info=params)
|
||||
self.assert_json_error(result, "User {} is already a member of this group".format(othello.id))
|
||||
self.assert_json_error(result, f"User {othello.id} is already a member of this group")
|
||||
self.assertEqual(UserGroupMembership.objects.count(), 4)
|
||||
members = get_memberships_of_users(user_group, [hamlet, othello])
|
||||
self.assertEqual(len(members), 2)
|
||||
|
@ -324,7 +324,7 @@ class UserGroupAPITestCase(ZulipTestCase):
|
|||
self.login_user(cordelia)
|
||||
add = [cordelia.id]
|
||||
params = {'add': ujson.dumps(add)}
|
||||
result = self.client_post('/json/user_groups/{}/members'.format(user_group.id),
|
||||
result = self.client_post(f'/json/user_groups/{user_group.id}/members',
|
||||
info=params)
|
||||
self.assert_json_error(result, "Only group members and organization administrators can administer this group.")
|
||||
self.assertEqual(UserGroupMembership.objects.count(), 4)
|
||||
|
@ -336,7 +336,7 @@ class UserGroupAPITestCase(ZulipTestCase):
|
|||
aaron = self.example_user('aaron')
|
||||
add = [aaron.id]
|
||||
params = {'add': ujson.dumps(add)}
|
||||
result = self.client_post('/json/user_groups/{}/members'.format(user_group.id),
|
||||
result = self.client_post(f'/json/user_groups/{user_group.id}/members',
|
||||
info=params)
|
||||
self.assert_json_success(result)
|
||||
self.assertEqual(UserGroupMembership.objects.count(), 5)
|
||||
|
@ -348,7 +348,7 @@ class UserGroupAPITestCase(ZulipTestCase):
|
|||
self.login_user(hamlet)
|
||||
# Test remove members
|
||||
params = {'delete': ujson.dumps([othello.id])}
|
||||
result = self.client_post('/json/user_groups/{}/members'.format(user_group.id),
|
||||
result = self.client_post(f'/json/user_groups/{user_group.id}/members',
|
||||
info=params)
|
||||
self.assert_json_success(result)
|
||||
self.assertEqual(UserGroupMembership.objects.count(), 4)
|
||||
|
@ -357,15 +357,15 @@ class UserGroupAPITestCase(ZulipTestCase):
|
|||
|
||||
# Test remove a member that's already removed
|
||||
params = {'delete': ujson.dumps([othello.id])}
|
||||
result = self.client_post('/json/user_groups/{}/members'.format(user_group.id),
|
||||
result = self.client_post(f'/json/user_groups/{user_group.id}/members',
|
||||
info=params)
|
||||
self.assert_json_error(result, "There is no member '{}' in this user group".format(othello.id))
|
||||
self.assert_json_error(result, f"There is no member '{othello.id}' in this user group")
|
||||
self.assertEqual(UserGroupMembership.objects.count(), 4)
|
||||
members = get_memberships_of_users(user_group, [hamlet, othello, aaron])
|
||||
self.assertEqual(len(members), 2)
|
||||
|
||||
# Test when nothing is provided
|
||||
result = self.client_post('/json/user_groups/{}/members'.format(user_group.id),
|
||||
result = self.client_post(f'/json/user_groups/{user_group.id}/members',
|
||||
info={})
|
||||
msg = 'Nothing to do. Specify at least one of "add" or "delete".'
|
||||
self.assert_json_error(result, msg)
|
||||
|
@ -374,7 +374,7 @@ class UserGroupAPITestCase(ZulipTestCase):
|
|||
self.logout()
|
||||
self.login_user(cordelia)
|
||||
params = {'delete': ujson.dumps([hamlet.id])}
|
||||
result = self.client_post('/json/user_groups/{}/members'.format(user_group.id),
|
||||
result = self.client_post(f'/json/user_groups/{user_group.id}/members',
|
||||
info=params)
|
||||
self.assert_json_error(result, "Only group members and organization administrators can administer this group.")
|
||||
self.assertEqual(UserGroupMembership.objects.count(), 4)
|
||||
|
@ -383,7 +383,7 @@ class UserGroupAPITestCase(ZulipTestCase):
|
|||
# Test when organization admin tries to remove members from group
|
||||
iago = self.example_user('iago')
|
||||
self.login_user(iago)
|
||||
result = self.client_post('/json/user_groups/{}/members'.format(user_group.id),
|
||||
result = self.client_post(f'/json/user_groups/{user_group.id}/members',
|
||||
info=params)
|
||||
self.assert_json_success(result)
|
||||
self.assertEqual(UserGroupMembership.objects.count(), 3)
|
||||
|
@ -460,13 +460,13 @@ class UserGroupAPITestCase(ZulipTestCase):
|
|||
|
||||
# Test add member
|
||||
params = {'add': ujson.dumps([cordelia.id])}
|
||||
result = self.client_post('/json/user_groups/{}/members'.format(user_group.id),
|
||||
result = self.client_post(f'/json/user_groups/{user_group.id}/members',
|
||||
info=params)
|
||||
self.assert_json_success(result)
|
||||
|
||||
# Test remove member
|
||||
params = {'delete': ujson.dumps([cordelia.id])}
|
||||
result = self.client_post('/json/user_groups/{}/members'.format(user_group.id),
|
||||
result = self.client_post(f'/json/user_groups/{user_group.id}/members',
|
||||
info=params)
|
||||
self.assert_json_success(result)
|
||||
|
||||
|
@ -475,11 +475,11 @@ class UserGroupAPITestCase(ZulipTestCase):
|
|||
'name': 'help',
|
||||
'description': 'Troubleshooting',
|
||||
}
|
||||
result = self.client_patch('/json/user_groups/{}'.format(user_group.id), info=params)
|
||||
result = self.client_patch(f'/json/user_groups/{user_group.id}', info=params)
|
||||
self.assert_json_success(result)
|
||||
|
||||
# Test delete a group
|
||||
result = self.client_delete('/json/user_groups/{}'.format(user_group.id))
|
||||
result = self.client_delete(f'/json/user_groups/{user_group.id}')
|
||||
self.assert_json_success(result)
|
||||
|
||||
user_group = create_user_group(name='support',
|
||||
|
@ -502,12 +502,12 @@ class UserGroupAPITestCase(ZulipTestCase):
|
|||
|
||||
# Test add member
|
||||
params = {'add': ujson.dumps([cordelia.id])}
|
||||
result = self.client_post('/json/user_groups/{}/members'.format(user_group.id),
|
||||
result = self.client_post(f'/json/user_groups/{user_group.id}/members',
|
||||
info=params)
|
||||
self.assert_json_error(result, "Must be an organization administrator")
|
||||
|
||||
# Test delete a group
|
||||
result = self.client_delete('/json/user_groups/{}'.format(user_group.id))
|
||||
result = self.client_delete(f'/json/user_groups/{user_group.id}')
|
||||
self.assert_json_error(result, "Must be an organization administrator")
|
||||
|
||||
# Test changing groups name
|
||||
|
@ -515,5 +515,5 @@ class UserGroupAPITestCase(ZulipTestCase):
|
|||
'name': 'help',
|
||||
'description': 'Troubleshooting',
|
||||
}
|
||||
result = self.client_patch('/json/user_groups/{}'.format(user_group.id), info=params)
|
||||
result = self.client_patch(f'/json/user_groups/{user_group.id}', info=params)
|
||||
self.assert_json_error(result, "Must be an organization administrator")
|
||||
|
|
|
@ -116,7 +116,7 @@ class PermissionTest(ZulipTestCase):
|
|||
do_change_user_role(admin, UserProfile.ROLE_REALM_ADMINISTRATOR)
|
||||
|
||||
invalid_user_id = 1000
|
||||
result = self.client_patch('/json/users/{}'.format(invalid_user_id), {})
|
||||
result = self.client_patch(f'/json/users/{invalid_user_id}', {})
|
||||
self.assert_json_error(result, 'No such user')
|
||||
|
||||
def test_admin_api(self) -> None:
|
||||
|
@ -142,7 +142,7 @@ class PermissionTest(ZulipTestCase):
|
|||
|
||||
events: List[Mapping[str, Any]] = []
|
||||
with tornado_redirected_to_list(events):
|
||||
result = self.client_patch('/json/users/{}'.format(othello.id), req)
|
||||
result = self.client_patch(f'/json/users/{othello.id}', req)
|
||||
self.assert_json_success(result)
|
||||
admin_users = realm.get_human_admin_users()
|
||||
self.assertTrue(othello in admin_users)
|
||||
|
@ -154,7 +154,7 @@ class PermissionTest(ZulipTestCase):
|
|||
req = dict(role=ujson.dumps(UserProfile.ROLE_MEMBER))
|
||||
events = []
|
||||
with tornado_redirected_to_list(events):
|
||||
result = self.client_patch('/json/users/{}'.format(othello.id), req)
|
||||
result = self.client_patch(f'/json/users/{othello.id}', req)
|
||||
self.assert_json_success(result)
|
||||
admin_users = realm.get_human_admin_users()
|
||||
self.assertFalse(othello in admin_users)
|
||||
|
@ -167,7 +167,7 @@ class PermissionTest(ZulipTestCase):
|
|||
req = dict(role=ujson.dumps(UserProfile.ROLE_MEMBER))
|
||||
events = []
|
||||
with tornado_redirected_to_list(events):
|
||||
result = self.client_patch('/json/users/{}'.format(desdemona.id), req)
|
||||
result = self.client_patch(f'/json/users/{desdemona.id}', req)
|
||||
self.assert_json_success(result)
|
||||
admin_users = realm.get_human_admin_users()
|
||||
self.assertFalse(desdemona in admin_users)
|
||||
|
@ -175,12 +175,12 @@ class PermissionTest(ZulipTestCase):
|
|||
self.assertEqual(person['user_id'], desdemona.id)
|
||||
self.assertEqual(person['role'], UserProfile.ROLE_MEMBER)
|
||||
with tornado_redirected_to_list([]):
|
||||
result = self.client_patch('/json/users/{}'.format(iago.id), req)
|
||||
result = self.client_patch(f'/json/users/{iago.id}', req)
|
||||
self.assert_json_error(result, 'Cannot remove the only organization administrator')
|
||||
|
||||
# Make sure only admins can patch other user's info.
|
||||
self.login('othello')
|
||||
result = self.client_patch('/json/users/{}'.format(hamlet.id), req)
|
||||
result = self.client_patch(f'/json/users/{hamlet.id}', req)
|
||||
self.assert_json_error(result, 'Insufficient permission')
|
||||
|
||||
def test_admin_api_hide_emails(self) -> None:
|
||||
|
@ -261,7 +261,7 @@ class PermissionTest(ZulipTestCase):
|
|||
self.login('iago')
|
||||
hamlet = self.example_user('hamlet')
|
||||
req = dict(full_name=ujson.dumps(new_name))
|
||||
result = self.client_patch('/json/users/{}'.format(hamlet.id), req)
|
||||
result = self.client_patch(f'/json/users/{hamlet.id}', req)
|
||||
self.assert_json_success(result)
|
||||
hamlet = self.example_user('hamlet')
|
||||
self.assertEqual(hamlet.full_name, new_name)
|
||||
|
@ -355,7 +355,7 @@ class PermissionTest(ZulipTestCase):
|
|||
req = dict(role=ujson.dumps(UserProfile.ROLE_GUEST))
|
||||
events: List[Mapping[str, Any]] = []
|
||||
with tornado_redirected_to_list(events):
|
||||
result = self.client_patch('/json/users/{}'.format(hamlet.id), req)
|
||||
result = self.client_patch(f'/json/users/{hamlet.id}', req)
|
||||
self.assert_json_success(result)
|
||||
|
||||
hamlet = self.example_user("hamlet")
|
||||
|
@ -374,7 +374,7 @@ class PermissionTest(ZulipTestCase):
|
|||
req = dict(role=ujson.dumps(UserProfile.ROLE_MEMBER))
|
||||
events: List[Mapping[str, Any]] = []
|
||||
with tornado_redirected_to_list(events):
|
||||
result = self.client_patch('/json/users/{}'.format(polonius.id), req)
|
||||
result = self.client_patch(f'/json/users/{polonius.id}', req)
|
||||
self.assert_json_success(result)
|
||||
|
||||
polonius = self.example_user("polonius")
|
||||
|
@ -397,7 +397,7 @@ class PermissionTest(ZulipTestCase):
|
|||
req = dict(role=ujson.dumps(UserProfile.ROLE_GUEST))
|
||||
events: List[Mapping[str, Any]] = []
|
||||
with tornado_redirected_to_list(events):
|
||||
result = self.client_patch('/json/users/{}'.format(hamlet.id), req)
|
||||
result = self.client_patch(f'/json/users/{hamlet.id}', req)
|
||||
self.assert_json_success(result)
|
||||
|
||||
hamlet = self.example_user("hamlet")
|
||||
|
@ -421,7 +421,7 @@ class PermissionTest(ZulipTestCase):
|
|||
req = dict(role=ujson.dumps(UserProfile.ROLE_REALM_ADMINISTRATOR))
|
||||
events: List[Mapping[str, Any]] = []
|
||||
with tornado_redirected_to_list(events):
|
||||
result = self.client_patch('/json/users/{}'.format(polonius.id), req)
|
||||
result = self.client_patch(f'/json/users/{polonius.id}', req)
|
||||
self.assert_json_success(result)
|
||||
|
||||
polonius = self.example_user("polonius")
|
||||
|
@ -457,7 +457,7 @@ class PermissionTest(ZulipTestCase):
|
|||
'value': fields[field_name],
|
||||
})
|
||||
|
||||
result = self.client_patch('/json/users/{}'.format(cordelia.id),
|
||||
result = self.client_patch(f'/json/users/{cordelia.id}',
|
||||
{'profile_data': ujson.dumps(new_profile_data)})
|
||||
self.assert_json_success(result)
|
||||
|
||||
|
@ -482,7 +482,7 @@ class PermissionTest(ZulipTestCase):
|
|||
'value': field_value,
|
||||
})
|
||||
|
||||
result = self.client_patch('/json/users/{}'.format(cordelia.id),
|
||||
result = self.client_patch(f'/json/users/{cordelia.id}',
|
||||
{'profile_data': ujson.dumps(new_profile_data)})
|
||||
self.assert_json_error(result, error_msg)
|
||||
|
||||
|
@ -491,7 +491,7 @@ class PermissionTest(ZulipTestCase):
|
|||
'id': 9001,
|
||||
'value': ''
|
||||
}]
|
||||
result = self.client_patch('/json/users/{}'.format(cordelia.id),
|
||||
result = self.client_patch(f'/json/users/{cordelia.id}',
|
||||
{'profile_data': ujson.dumps(invalid_profile_data)})
|
||||
self.assert_json_error(result, 'Field id 9001 not found.')
|
||||
|
||||
|
@ -500,7 +500,7 @@ class PermissionTest(ZulipTestCase):
|
|||
'id': 9001,
|
||||
'value': 'some data'
|
||||
}]
|
||||
result = self.client_patch('/json/users/{}'.format(cordelia.id),
|
||||
result = self.client_patch(f'/json/users/{cordelia.id}',
|
||||
{'profile_data': ujson.dumps(invalid_profile_data)})
|
||||
self.assert_json_error(result, 'Field id 9001 not found.')
|
||||
|
||||
|
@ -515,7 +515,7 @@ class PermissionTest(ZulipTestCase):
|
|||
'id': field.id,
|
||||
'value': value,
|
||||
})
|
||||
result = self.client_patch('/json/users/{}'.format(cordelia.id),
|
||||
result = self.client_patch(f'/json/users/{cordelia.id}',
|
||||
{'profile_data': ujson.dumps(empty_profile_data)})
|
||||
self.assert_json_success(result)
|
||||
for field_dict in cordelia.profile_data:
|
||||
|
@ -544,7 +544,7 @@ class PermissionTest(ZulipTestCase):
|
|||
'id': field.id,
|
||||
'value': value,
|
||||
})
|
||||
result = self.client_patch('/json/users/{}'.format(cordelia.id),
|
||||
result = self.client_patch(f'/json/users/{cordelia.id}',
|
||||
{'profile_data': ujson.dumps(new_profile_data)})
|
||||
self.assert_json_success(result)
|
||||
for field_dict in cordelia.profile_data:
|
||||
|
@ -562,7 +562,7 @@ class PermissionTest(ZulipTestCase):
|
|||
'id': field.id,
|
||||
'value': "New hamlet Biography",
|
||||
})
|
||||
result = self.client_patch('/json/users/{}'.format(hamlet.id),
|
||||
result = self.client_patch(f'/json/users/{hamlet.id}',
|
||||
{'profile_data': ujson.dumps(new_profile_data)})
|
||||
self.assert_json_error(result, 'Insufficient permission')
|
||||
|
||||
|
@ -586,7 +586,7 @@ class BulkCreateUserTest(ZulipTestCase):
|
|||
fred = get_user_by_delivery_email('fred@zulip.com', realm)
|
||||
self.assertEqual(
|
||||
fred.email,
|
||||
'user{}@zulip.testserver'.format(fred.id)
|
||||
f'user{fred.id}@zulip.testserver'
|
||||
)
|
||||
|
||||
lisa = get_user_by_delivery_email('lisa@zulip.com', realm)
|
||||
|
@ -970,12 +970,12 @@ class ActivateTest(ZulipTestCase):
|
|||
user = self.example_user('hamlet')
|
||||
self.assertTrue(user.is_active)
|
||||
|
||||
result = self.client_delete('/json/users/{}'.format(user.id))
|
||||
result = self.client_delete(f'/json/users/{user.id}')
|
||||
self.assert_json_success(result)
|
||||
user = self.example_user('hamlet')
|
||||
self.assertFalse(user.is_active)
|
||||
|
||||
result = self.client_post('/json/users/{}/reactivate'.format(user.id))
|
||||
result = self.client_post(f'/json/users/{user.id}/reactivate')
|
||||
self.assert_json_success(result)
|
||||
user = self.example_user('hamlet')
|
||||
self.assertTrue(user.is_active)
|
||||
|
@ -990,7 +990,7 @@ class ActivateTest(ZulipTestCase):
|
|||
|
||||
# Cannot deactivate a nonexistent user.
|
||||
invalid_user_id = 1000
|
||||
result = self.client_delete('/json/users/{}'.format(invalid_user_id))
|
||||
result = self.client_delete(f'/json/users/{invalid_user_id}')
|
||||
self.assert_json_error(result, 'No such user')
|
||||
|
||||
result = self.client_delete('/json/users/{}'.format(self.example_user("webhook_bot").id))
|
||||
|
@ -999,12 +999,12 @@ class ActivateTest(ZulipTestCase):
|
|||
result = self.client_delete('/json/users/{}'.format(self.example_user("iago").id))
|
||||
self.assert_json_success(result)
|
||||
|
||||
result = self.client_delete('/json/users/{}'.format(admin.id))
|
||||
result = self.client_delete(f'/json/users/{admin.id}')
|
||||
self.assert_json_error(result, 'Cannot deactivate the only organization administrator')
|
||||
|
||||
# Cannot reactivate a nonexistent user.
|
||||
invalid_user_id = 1000
|
||||
result = self.client_post('/json/users/{}/reactivate'.format(invalid_user_id))
|
||||
result = self.client_post(f'/json/users/{invalid_user_id}/reactivate')
|
||||
self.assert_json_error(result, 'No such user')
|
||||
|
||||
def test_api_with_insufficient_permissions(self) -> None:
|
||||
|
@ -1398,7 +1398,7 @@ class GetProfileTest(ZulipTestCase):
|
|||
|
||||
# Tests the GET ../users/{id} api endpoint.
|
||||
user = self.example_user('hamlet')
|
||||
result = ujson.loads(self.client_get('/json/users/{}'.format(user.id)).content)
|
||||
result = ujson.loads(self.client_get(f'/json/users/{user.id}').content)
|
||||
self.assertEqual(result['user']['email'], user.email)
|
||||
self.assertEqual(result['user']['full_name'], user.full_name)
|
||||
self.assertIn("user_id", result['user'])
|
||||
|
@ -1407,14 +1407,14 @@ class GetProfileTest(ZulipTestCase):
|
|||
self.assertFalse(result['user']['is_admin'])
|
||||
self.assertFalse(result['user']['is_owner'])
|
||||
|
||||
result = ujson.loads(self.client_get('/json/users/{}?include_custom_profile_fields=true'.format(user.id)).content)
|
||||
result = ujson.loads(self.client_get(f'/json/users/{user.id}?include_custom_profile_fields=true').content)
|
||||
|
||||
self.assertIn('profile_data', result['user'])
|
||||
result = self.client_get('/json/users/{}?'.format(30))
|
||||
result = self.client_get(f'/json/users/{30}?')
|
||||
self.assert_json_error(result, "No such user")
|
||||
|
||||
bot = self.example_user("default_bot")
|
||||
result = ujson.loads(self.client_get('/json/users/{}'.format(bot.id)).content)
|
||||
result = ujson.loads(self.client_get(f'/json/users/{bot.id}').content)
|
||||
self.assertEqual(result['user']['email'], bot.email)
|
||||
self.assertTrue(result['user']['is_bot'])
|
||||
|
||||
|
|
|
@ -96,7 +96,7 @@ def check_send_webhook_fixture_message(request: HttpRequest,
|
|||
try:
|
||||
custom_headers_dict = ujson.loads(custom_headers)
|
||||
except ValueError as ve:
|
||||
return json_error("Custom HTTP headers are not in a valid JSON format. {}".format(ve)) # nolint
|
||||
return json_error(f"Custom HTTP headers are not in a valid JSON format. {ve}") # nolint
|
||||
|
||||
response = send_webhook_fixture_message(url, body, is_json,
|
||||
custom_headers_dict)
|
||||
|
|
|
@ -153,12 +153,12 @@ def add_integrations_open_graph_context(context: Dict[str, Any], request: HttpRe
|
|||
|
||||
if path_name in INTEGRATIONS:
|
||||
integration = INTEGRATIONS[path_name]
|
||||
context['OPEN_GRAPH_TITLE'] = 'Connect {name} to Zulip'.format(name=integration.display_name)
|
||||
context['OPEN_GRAPH_TITLE'] = f'Connect {integration.display_name} to Zulip'
|
||||
context['OPEN_GRAPH_DESCRIPTION'] = description
|
||||
|
||||
elif path_name in CATEGORIES:
|
||||
category = CATEGORIES[path_name]
|
||||
context['OPEN_GRAPH_TITLE'] = 'Connect your {category} tools to Zulip'.format(category=category)
|
||||
context['OPEN_GRAPH_TITLE'] = f'Connect your {category} tools to Zulip'
|
||||
context['OPEN_GRAPH_DESCRIPTION'] = description
|
||||
|
||||
elif path_name == 'integrations':
|
||||
|
|
|
@ -223,7 +223,7 @@ class NarrowBuilder:
|
|||
if ord(c) >= 128:
|
||||
# convert the character to hex postgres regex will take
|
||||
# \uXXXX
|
||||
s[i] = '\\u{:0>4x}'.format(ord(c))
|
||||
s[i] = f'\\u{ord(c):0>4x}'
|
||||
else:
|
||||
s[i] = '\\' + c
|
||||
return ''.join(s)
|
||||
|
|
|
@ -24,11 +24,11 @@ def api_alertmanager_webhook(request: HttpRequest, user_profile: UserProfile,
|
|||
name = labels.get(
|
||||
name_field, annotations.get(name_field, "(unknown)"))
|
||||
desc = labels.get(
|
||||
desc_field, annotations.get(desc_field, "<missing field: {}>".format(desc_field)))
|
||||
desc_field, annotations.get(desc_field, f"<missing field: {desc_field}>"))
|
||||
|
||||
url = alert.get("generatorURL").replace("tab=1", "tab=0")
|
||||
|
||||
body = "{description} ([graph]({url}))".format(description=desc, url=url)
|
||||
body = f"{desc} ([graph]({url}))"
|
||||
if name not in topics:
|
||||
topics[name] = {"firing": [], "resolved": []}
|
||||
topics[name][alert["status"]].append(body)
|
||||
|
@ -51,7 +51,7 @@ def api_alertmanager_webhook(request: HttpRequest, user_profile: UserProfile,
|
|||
title=title,
|
||||
message=messages[0])
|
||||
else:
|
||||
message_list = "\n".join(["* {}".format(m) for m in messages])
|
||||
message_list = "\n".join([f"* {m}" for m in messages])
|
||||
body = "{icon} **{title}**\n{messages}".format(
|
||||
icon=icon,
|
||||
title=title,
|
||||
|
|
|
@ -80,7 +80,7 @@ def get_verb(event: str, prefix: str) -> str:
|
|||
|
||||
def add_punctuation_if_necessary(body: str, title: str) -> str:
|
||||
if title[-1] not in string.punctuation:
|
||||
body = '{}.'.format(body)
|
||||
body = f'{body}.'
|
||||
return body
|
||||
|
||||
def get_document_body(event: str, payload: Dict[str, Any]) -> str:
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue