-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Fix regex for apple-touch-icon #25025
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,235 @@ | ||
| import UIKit | ||
| import Testing | ||
| import AsyncImageKit | ||
|
|
||
| @Suite final class FaviconServiceTests { | ||
| @Test func appleTouchIcon() throws { | ||
| // GIVEN | ||
| let siteURL = try #require(URL(string: "https://example.com")) | ||
|
Check warning on line 8 in Modules/Tests/AsyncImageKitTests/FaviconServiceTests.swift
|
||
| let html = """ | ||
| <html> | ||
| <head> | ||
| <link rel="apple-touch-icon" href="/apple-icon.png"> | ||
| </head> | ||
| </html> | ||
| """ | ||
| let data = Data(html.utf8) | ||
|
|
||
| // WHEN | ||
| let faviconURL = FaviconService.makeFavicon(from: data, siteURL: siteURL) | ||
|
|
||
| // THEN | ||
| #expect(faviconURL.absoluteString == "https://example.com/apple-icon.png") | ||
|
Check warning on line 22 in Modules/Tests/AsyncImageKitTests/FaviconServiceTests.swift
|
||
| } | ||
|
|
||
| @Test func appleTouchIconPrecomposed() throws { | ||
| // GIVEN | ||
| let siteURL = try #require(URL(string: "https://example.com")) | ||
|
Check warning on line 27 in Modules/Tests/AsyncImageKitTests/FaviconServiceTests.swift
|
||
| let html = """ | ||
| <html> | ||
| <head> | ||
| <link rel="apple-touch-icon-precomposed" href="/apple-icon-precomposed.png"> | ||
| </head> | ||
| </html> | ||
| """ | ||
| let data = Data(html.utf8) | ||
|
|
||
| // WHEN | ||
| let faviconURL = FaviconService.makeFavicon(from: data, siteURL: siteURL) | ||
|
|
||
| // THEN | ||
| #expect(faviconURL.absoluteString == "https://example.com/apple-icon-precomposed.png") | ||
|
Check warning on line 41 in Modules/Tests/AsyncImageKitTests/FaviconServiceTests.swift
|
||
| } | ||
|
|
||
| @Test func appleTouchIconWithAbsoluteURL() throws { | ||
| // GIVEN | ||
| let siteURL = try #require(URL(string: "https://example.com")) | ||
|
Check warning on line 46 in Modules/Tests/AsyncImageKitTests/FaviconServiceTests.swift
|
||
| let html = """ | ||
| <html> | ||
| <head> | ||
| <link rel="apple-touch-icon" href="https://cdn.example.com/icon.png"> | ||
| </head> | ||
| </html> | ||
| """ | ||
| let data = Data(html.utf8) | ||
|
|
||
| // WHEN | ||
| let faviconURL = FaviconService.makeFavicon(from: data, siteURL: siteURL) | ||
|
|
||
| // THEN | ||
| #expect(faviconURL.absoluteString == "https://cdn.example.com/icon.png") | ||
|
Check warning on line 60 in Modules/Tests/AsyncImageKitTests/FaviconServiceTests.swift
|
||
| } | ||
|
|
||
| @Test func appleTouchIconWithRelativePath() throws { | ||
| // GIVEN | ||
| let siteURL = try #require(URL(string: "https://example.com")) | ||
|
Check warning on line 65 in Modules/Tests/AsyncImageKitTests/FaviconServiceTests.swift
|
||
| let html = """ | ||
| <html> | ||
| <head> | ||
| <link rel="apple-touch-icon" href="assets/icon.png"> | ||
| </head> | ||
| </html> | ||
| """ | ||
| let data = Data(html.utf8) | ||
|
|
||
| // WHEN | ||
| let faviconURL = FaviconService.makeFavicon(from: data, siteURL: siteURL) | ||
|
|
||
| // THEN | ||
| #expect(faviconURL.absoluteString == "https://example.com/assets/icon.png") | ||
|
Check warning on line 79 in Modules/Tests/AsyncImageKitTests/FaviconServiceTests.swift
|
||
| } | ||
|
|
||
| @Test func appleTouchIconWithAdditionalAttributes() throws { | ||
| // GIVEN | ||
| let siteURL = try #require(URL(string: "https://example.com")) | ||
|
Check warning on line 84 in Modules/Tests/AsyncImageKitTests/FaviconServiceTests.swift
|
||
| let html = """ | ||
| <html> | ||
| <head> | ||
| <link rel="apple-touch-icon" sizes="180x180" href="/apple-icon-180x180.png"> | ||
| </head> | ||
| </html> | ||
| """ | ||
| let data = Data(html.utf8) | ||
|
|
||
| // WHEN | ||
| let faviconURL = FaviconService.makeFavicon(from: data, siteURL: siteURL) | ||
|
|
||
| // THEN | ||
| #expect(faviconURL.absoluteString == "https://example.com/apple-icon-180x180.png") | ||
|
Check warning on line 98 in Modules/Tests/AsyncImageKitTests/FaviconServiceTests.swift
|
||
| } | ||
|
|
||
| @Test func appleTouchIconPrecomposedWithSizes() throws { | ||
| // GIVEN | ||
| let siteURL = try #require(URL(string: "https://example.com")) | ||
|
Check warning on line 103 in Modules/Tests/AsyncImageKitTests/FaviconServiceTests.swift
|
||
| let html = """ | ||
| <html> | ||
| <head> | ||
| <link rel="apple-touch-icon-precomposed" sizes="152x152" href="/apple-icon-precomposed-152.png"> | ||
| </head> | ||
| </html> | ||
| """ | ||
| let data = Data(html.utf8) | ||
|
|
||
| // WHEN | ||
| let faviconURL = FaviconService.makeFavicon(from: data, siteURL: siteURL) | ||
|
|
||
| // THEN | ||
| #expect(faviconURL.absoluteString == "https://example.com/apple-icon-precomposed-152.png") | ||
|
Check warning on line 117 in Modules/Tests/AsyncImageKitTests/FaviconServiceTests.swift
|
||
| } | ||
|
|
||
| @Test func fallbackToFaviconIcon() throws { | ||
| // GIVEN | ||
| let siteURL = try #require(URL(string: "https://example.com")) | ||
|
Check warning on line 122 in Modules/Tests/AsyncImageKitTests/FaviconServiceTests.swift
|
||
| let html = """ | ||
| <html> | ||
| <head> | ||
| <link rel="icon" href="/favicon.ico"> | ||
| </head> | ||
| </html> | ||
| """ | ||
| let data = Data(html.utf8) | ||
|
|
||
| // WHEN | ||
| let faviconURL = FaviconService.makeFavicon(from: data, siteURL: siteURL) | ||
|
|
||
| // THEN | ||
| #expect(faviconURL.absoluteString == "https://example.com/favicon.icon") | ||
|
Check warning on line 136 in Modules/Tests/AsyncImageKitTests/FaviconServiceTests.swift
|
||
| } | ||
|
|
||
| @Test func fallbackWhenNoFaviconFound() throws { | ||
| // GIVEN | ||
| let siteURL = try #require(URL(string: "https://example.com")) | ||
|
Check warning on line 141 in Modules/Tests/AsyncImageKitTests/FaviconServiceTests.swift
|
||
| let html = "<html><head></head></html>" | ||
| let data = Data(html.utf8) | ||
|
|
||
| // WHEN | ||
| let faviconURL = FaviconService.makeFavicon(from: data, siteURL: siteURL) | ||
|
|
||
| // THEN | ||
| #expect(faviconURL.absoluteString == "https://example.com/favicon.icon") | ||
|
Check warning on line 149 in Modules/Tests/AsyncImageKitTests/FaviconServiceTests.swift
|
||
| } | ||
|
|
||
| @Test func appleTouchIconCaseInsensitive() throws { | ||
| // GIVEN | ||
| let siteURL = try #require(URL(string: "https://example.com")) | ||
|
Check warning on line 154 in Modules/Tests/AsyncImageKitTests/FaviconServiceTests.swift
|
||
| let html = """ | ||
| <html> | ||
| <head> | ||
| <link rel="APPLE-TOUCH-ICON" href="/apple-icon.png"> | ||
| </head> | ||
| </html> | ||
| """ | ||
| let data = Data(html.utf8) | ||
|
|
||
| // WHEN | ||
| let faviconURL = FaviconService.makeFavicon(from: data, siteURL: siteURL) | ||
|
|
||
| // THEN | ||
| #expect(faviconURL.absoluteString == "https://example.com/apple-icon.png") | ||
|
Check warning on line 168 in Modules/Tests/AsyncImageKitTests/FaviconServiceTests.swift
|
||
| } | ||
|
|
||
| @Test func multipleAppleTouchIconsUsesFirst() throws { | ||
| // GIVEN | ||
| let siteURL = try #require(URL(string: "https://example.com")) | ||
|
Check warning on line 173 in Modules/Tests/AsyncImageKitTests/FaviconServiceTests.swift
|
||
| let html = """ | ||
| <html> | ||
| <head> | ||
| <link rel="apple-touch-icon" sizes="180x180" href="/apple-icon-180.png"> | ||
| <link rel="apple-touch-icon" sizes="152x152" href="/apple-icon-152.png"> | ||
| <link rel="apple-touch-icon-precomposed" href="/apple-icon-precomposed.png"> | ||
| </head> | ||
| </html> | ||
| """ | ||
| let data = Data(html.utf8) | ||
|
|
||
| // WHEN | ||
| let faviconURL = FaviconService.makeFavicon(from: data, siteURL: siteURL) | ||
|
|
||
| // THEN - Uses the first match | ||
| #expect(faviconURL.absoluteString == "https://example.com/apple-icon-180.png") | ||
|
Check warning on line 189 in Modules/Tests/AsyncImageKitTests/FaviconServiceTests.swift
|
||
| } | ||
|
|
||
| @Test func emptyData() throws { | ||
| // GIVEN | ||
| let siteURL = try #require(URL(string: "https://example.com")) | ||
|
Check warning on line 194 in Modules/Tests/AsyncImageKitTests/FaviconServiceTests.swift
|
||
| let data = Data() | ||
|
|
||
| // WHEN | ||
| let faviconURL = FaviconService.makeFavicon(from: data, siteURL: siteURL) | ||
|
|
||
| // THEN - Falls back to standard favicon path | ||
| #expect(faviconURL.absoluteString == "https://example.com/favicon.icon") | ||
|
Check warning on line 201 in Modules/Tests/AsyncImageKitTests/FaviconServiceTests.swift
|
||
| } | ||
|
|
||
| @Test func siteURLWithPath() throws { | ||
| // GIVEN | ||
| let siteURL = try #require(URL(string: "https://example.com/blog")) | ||
|
Check warning on line 206 in Modules/Tests/AsyncImageKitTests/FaviconServiceTests.swift
|
||
| let html = """ | ||
| <html> | ||
| <head> | ||
| <link rel="apple-touch-icon" href="/apple-icon.png"> | ||
| </head> | ||
| </html> | ||
| """ | ||
| let data = Data(html.utf8) | ||
|
|
||
| // WHEN | ||
| let faviconURL = FaviconService.makeFavicon(from: data, siteURL: siteURL) | ||
|
|
||
| // THEN | ||
| #expect(faviconURL.absoluteString == "https://example.com/apple-icon.png") | ||
|
Check warning on line 220 in Modules/Tests/AsyncImageKitTests/FaviconServiceTests.swift
|
||
| } | ||
|
|
||
| @Test func siteURLWithPathFallback() throws { | ||
| // GIVEN | ||
| let siteURL = try #require(URL(string: "https://example.com/blog")) | ||
|
Check warning on line 225 in Modules/Tests/AsyncImageKitTests/FaviconServiceTests.swift
|
||
| let html = "<html><head></head></html>" | ||
| let data = Data(html.utf8) | ||
|
|
||
| // WHEN | ||
| let faviconURL = FaviconService.makeFavicon(from: data, siteURL: siteURL) | ||
|
|
||
| // THEN | ||
| #expect(faviconURL.absoluteString == "https://example.com/blog/favicon.icon") | ||
|
Check warning on line 233 in Modules/Tests/AsyncImageKitTests/FaviconServiceTests.swift
|
||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't spot any real issue here, but I think the casting between Range and NSRange, String and NSString, and potentially unsafe subscript, could be avoided by using
Swift.Regex.