mirror of
				https://github.com/zulip/zulip.git
				synced 2025-10-30 19:43:47 +00:00 
			
		
		
		
	This is implemented by replacing all matches of "%(var_name)s" in a URL
format string with "{var_name}". Since we do want to ensure that the
templates aren't broken after this migration, a RuntimeError is raised
to let the maintainer know that certain linkifier cannot be converted
automatically if it does not pass the uri_template.validate check.
Also, we need to escape "%%", which is used to represent "%" in the old
format string syntax, as well as "{" and "}", which is a part of the
URL template syntax.
Signed-off-by: Zixuan James Li <p359101898@gmail.com>
		
	
		
			
				
	
	
		
			114 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			114 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| # 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.
 | |
| 
 | |
| from django.db.migrations.state import StateApps
 | |
| 
 | |
| from zerver.lib.test_classes import MigrationsTestCase
 | |
| from zerver.lib.test_helpers import use_db_models
 | |
| 
 | |
| # 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
 | |
| #
 | |
| # As a result, we generally mark these tests as skipped once they have
 | |
| # been tested for a migration being merged.
 | |
| 
 | |
| 
 | |
| class LinkifierURLFormatString(MigrationsTestCase):
 | |
|     migrate_from = "0440_realmfilter_url_template"
 | |
|     migrate_to = "0441_backfill_realmfilter_url_template"
 | |
| 
 | |
|     @use_db_models
 | |
|     def setUpBeforeMigration(self, apps: StateApps) -> None:
 | |
|         RealmFilter = apps.get_model("zerver", "RealmFilter")
 | |
| 
 | |
|         iago = self.example_user("iago")
 | |
| 
 | |
|         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)
 |