2018-05-21 18:56:45 +02:00
|
|
|
# These are tests for Zulip's database migrations. System documented at:
|
|
|
|
# https://zulip.readthedocs.io/en/latest/subsystems/schema-migrations.html
|
|
|
|
#
|
|
|
|
# You can also read
|
|
|
|
# https://www.caktusgroup.com/blog/2016/02/02/writing-unit-tests-django-migrations/
|
|
|
|
# to get a tutorial on the framework that inspired this feature.
|
2022-03-02 02:19:34 +01:00
|
|
|
|
2020-06-11 00:54:34 +02:00
|
|
|
from django.db.migrations.state import StateApps
|
2018-05-21 18:56:45 +02:00
|
|
|
|
2018-04-09 18:37:07 +02:00
|
|
|
from zerver.lib.test_classes import MigrationsTestCase
|
2019-02-13 10:22:16 +01:00
|
|
|
from zerver.lib.test_helpers import use_db_models
|
2018-04-09 18:37:07 +02:00
|
|
|
|
2019-02-13 10:22:16 +01:00
|
|
|
# Important note: These tests are very expensive, and details of
|
|
|
|
# Django's database transaction model mean it does not super work to
|
|
|
|
# have a lot of migrations tested in this file at once; so we usually
|
|
|
|
# delete the old migration tests when adding a new one, so this file
|
|
|
|
# always has a single migration test in it as an example.
|
|
|
|
#
|
|
|
|
# The error you get with multiple similar tests doing migrations on
|
|
|
|
# the same table is this (table name may vary):
|
|
|
|
#
|
|
|
|
# django.db.utils.OperationalError: cannot ALTER TABLE
|
|
|
|
# "zerver_subscription" because it has pending trigger events
|
2019-05-13 07:04:31 +02:00
|
|
|
#
|
|
|
|
# As a result, we generally mark these tests as skipped once they have
|
|
|
|
# been tested for a migration being merged.
|
2019-05-06 16:34:31 +02:00
|
|
|
|
2021-02-12 08:19:30 +01:00
|
|
|
|
2022-10-05 21:18:45 +02:00
|
|
|
class LinkifierURLFormatString(MigrationsTestCase):
|
|
|
|
migrate_from = "0440_realmfilter_url_template"
|
|
|
|
migrate_to = "0441_backfill_realmfilter_url_template"
|
2022-03-02 02:19:34 +01:00
|
|
|
|
|
|
|
@use_db_models
|
|
|
|
def setUpBeforeMigration(self, apps: StateApps) -> None:
|
2022-10-05 21:18:45 +02:00
|
|
|
RealmFilter = apps.get_model("zerver", "RealmFilter")
|
2019-05-06 16:34:31 +02:00
|
|
|
|
2022-03-02 02:19:34 +01:00
|
|
|
iago = self.example_user("iago")
|
|
|
|
|
2022-10-05 21:18:45 +02:00
|
|
|
urls = [
|
|
|
|
"http://example.com/",
|
|
|
|
"https://example.com/",
|
|
|
|
"https://user:password@example.com/",
|
|
|
|
"https://example.com/@user/thing",
|
|
|
|
"https://example.com/!path",
|
|
|
|
"https://example.com/foo.bar",
|
|
|
|
"https://example.com/foo[bar]",
|
|
|
|
"https://example.com/{foo}",
|
|
|
|
"https://example.com/{foo}{bars}",
|
|
|
|
"https://example.com/{foo}/and/{bar}",
|
|
|
|
"https://example.com/?foo={foo}",
|
|
|
|
"https://example.com/%ab",
|
|
|
|
"https://example.com/%ba",
|
|
|
|
"https://example.com/%21",
|
|
|
|
"https://example.com/words%20with%20spaces",
|
|
|
|
"https://example.com/back%20to%20{back}",
|
|
|
|
"https://example.com/encoded%2fwith%2fletters",
|
|
|
|
"https://example.com/encoded%2Fwith%2Fupper%2Fcase%2Fletters",
|
|
|
|
"https://example.com/%%",
|
|
|
|
"https://example.com/%%(",
|
|
|
|
"https://example.com/%%()",
|
|
|
|
"https://example.com/%%(foo",
|
|
|
|
"https://example.com/%%(foo)",
|
|
|
|
"https://example.com/%%(foo)s",
|
|
|
|
"https://example.com/%(foo)s",
|
|
|
|
"https://example.com/%(foo)s%(bar)s",
|
|
|
|
]
|
|
|
|
self.linkifier_ids = []
|
|
|
|
|
|
|
|
for index, url in enumerate(urls):
|
|
|
|
self.linkifier_ids.append(
|
|
|
|
RealmFilter.objects.create(
|
|
|
|
realm=iago.realm,
|
|
|
|
pattern=f"dummy{index}",
|
|
|
|
url_format_string=url,
|
|
|
|
).id
|
|
|
|
)
|
|
|
|
|
|
|
|
def test_converted_url_templates(self) -> None:
|
|
|
|
RealmFilter = self.apps.get_model("zerver", "RealmFilter")
|
|
|
|
|
|
|
|
expected_urls = [
|
|
|
|
"http://example.com/",
|
|
|
|
"https://example.com/",
|
|
|
|
"https://user:password@example.com/",
|
|
|
|
"https://example.com/@user/thing",
|
|
|
|
"https://example.com/!path",
|
|
|
|
"https://example.com/foo.bar",
|
|
|
|
"https://example.com/foo[bar]",
|
|
|
|
"https://example.com/%7Bfoo%7D",
|
|
|
|
"https://example.com/%7Bfoo%7D%7Bbars%7D",
|
|
|
|
"https://example.com/%7Bfoo%7D/and/%7Bbar%7D",
|
|
|
|
"https://example.com/?foo=%7Bfoo%7D",
|
|
|
|
"https://example.com/%ab",
|
|
|
|
"https://example.com/%ba",
|
|
|
|
"https://example.com/%21",
|
|
|
|
"https://example.com/words%20with%20spaces",
|
|
|
|
"https://example.com/back%20to%20%7Bback%7D",
|
|
|
|
"https://example.com/encoded%2fwith%2fletters",
|
|
|
|
"https://example.com/encoded%2Fwith%2Fupper%2Fcase%2Fletters",
|
|
|
|
"https://example.com/%",
|
|
|
|
"https://example.com/%(",
|
|
|
|
"https://example.com/%()",
|
|
|
|
"https://example.com/%(foo",
|
|
|
|
"https://example.com/%(foo)",
|
|
|
|
"https://example.com/%(foo)s",
|
|
|
|
"https://example.com/{foo}",
|
|
|
|
"https://example.com/{foo}{bar}",
|
|
|
|
]
|
|
|
|
|
|
|
|
for linkifier_id, expected in zip(self.linkifier_ids, expected_urls):
|
|
|
|
linkifier = RealmFilter.objects.filter(id=linkifier_id).first()
|
|
|
|
self.assertIsNotNone(linkifier)
|
|
|
|
self.assertEqual(linkifier.url_template, expected)
|