Audio property with type declaration as structured property.
27 | 28 | 29 | -------------------------------------------------------------------------------- /Tests/SwiftyOpenGraphTests/Examples/audio-url.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |Audio defined as structured properties.
23 |Compare to og:audio alias for parser support of og:audio:url vs. og:audio.
24 | 25 | -------------------------------------------------------------------------------- /Tests/SwiftyOpenGraphTests/Examples/image-array.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |Two images declared as an array.
26 | 27 | 28 | -------------------------------------------------------------------------------- /Tests/SwiftyOpenGraphTests/Examples/image-url.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |Example of basic properties with a structured image including og:image:url.
20 |Compare to og:image alias for parser support of og:image:url vs. og:image.
21 | 22 | -------------------------------------------------------------------------------- /Tests/SwiftyOpenGraphTests/Examples/min.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |An example of an HTML document lacking required properties.
12 |Contains optional properties and HTML fallback content.
13 | 14 | -------------------------------------------------------------------------------- /Tests/SwiftyOpenGraphTests/Examples/optional.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |A video.movie object.
41 | 42 | -------------------------------------------------------------------------------- /Tests/SwiftyOpenGraphTests/OpenGraphTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import SchafKit 3 | @testable import SwiftyOpenGraph 4 | 5 | final class OpenGraphTests: XCTestCase { 6 | 7 | func getHtml(for url: String) async -> String { 8 | let result = try! await SKNetworking.request(url: url) 9 | 10 | return .init(data: result.data, encoding: .utf8)! 11 | } 12 | 13 | func test(date: Date?, shortUSString: String) { 14 | XCTAssertNotNil(date) 15 | 16 | let formatter = DateFormatter(dateStyle: .short) 17 | formatter.locale = .init(identifier: "en_US") 18 | XCTAssertEqual(formatter.string(from: date!), shortUSString) 19 | } 20 | 21 | func getGraph(filename: String) -> OpenGraph? { 22 | do { 23 | let thisSourceFile = URL(fileURLWithPath: #file) 24 | let thisDirectory = thisSourceFile.deletingLastPathComponent().absoluteString 25 | let html = try String(contentsOf: URL(string: "\(thisDirectory)Examples/\(filename).html")!) 26 | 27 | return OpenGraph(html: html) 28 | } 29 | catch let err { 30 | XCTFail("File retrieval failed with error: \(err)") 31 | } 32 | return nil 33 | } 34 | 35 | func testRequired() { 36 | guard let graph = getGraph(filename: "required") else { 37 | XCTFail("No graph object found.") 38 | return 39 | } 40 | 41 | XCTAssertEqual(graph.title, "Minimum required properties") 42 | XCTAssertEqual(graph.url, "http://examples.opengraphprotocol.us/required.html") 43 | XCTAssertEqual(graph.image.url, "http://examples.opengraphprotocol.us/media/images/50.png") 44 | XCTAssertNil(graph.image.mimeType) 45 | XCTAssertEqual(graph.determiner, .blank) 46 | 47 | XCTAssertTrue(graph.additionalImages.isEmpty) 48 | } 49 | 50 | func testOptional() { 51 | guard let graph = getGraph(filename: "optional") else { 52 | XCTFail("No graph object found.") 53 | return 54 | } 55 | 56 | XCTAssertEqual(graph.title, "Open Graph protocol examples") 57 | XCTAssertEqual(graph.url, "http://examples.opengraphprotocol.us/") 58 | XCTAssertEqual(graph.determiner, .the) 59 | XCTAssertEqual(graph.locale, "de_DE") 60 | XCTAssertEqual(graph.alternateLocales, ["en_US", "fr_FR"]) 61 | XCTAssertEqual(graph.image.url, "http://examples.opengraphprotocol.us/media/images/logo.png") 62 | XCTAssertEqual(graph.image.width, 300) 63 | XCTAssertEqual(graph.image.height, 300) 64 | XCTAssertEqual(graph.image.mimeType, "image/png") 65 | 66 | XCTAssertTrue(graph.additionalImages.isEmpty) 67 | } 68 | 69 | func testImageArray() { 70 | guard let graph = getGraph(filename: "image-array") else { 71 | XCTFail("No graph object found.") 72 | return 73 | } 74 | 75 | XCTAssertEqual(graph.title, "Two structured image properties") 76 | XCTAssertEqual(graph.siteName, "Open Graph protocol examples") 77 | XCTAssertEqual(graph.url, "http://examples.opengraphprotocol.us/image-array.html") 78 | 79 | XCTAssertEqual(graph.image.url, "http://examples.opengraphprotocol.us/media/images/75.png") 80 | XCTAssertEqual(graph.image.secureUrl, "https://d72cgtgi6hvvl.cloudfront.net/media/images/75.png") 81 | XCTAssertEqual(graph.image.width, 75) 82 | XCTAssertEqual(graph.image.height, 75) 83 | XCTAssertEqual(graph.image.mimeType, "image/png") 84 | XCTAssertEqual(graph.image.alt, "The first image, at 75x75px.") 85 | 86 | XCTAssertEqual(graph.additionalImages.count, 1) 87 | 88 | XCTAssertEqual(graph.additionalImages[0].url, "http://examples.opengraphprotocol.us/media/images/50.png") 89 | XCTAssertEqual(graph.additionalImages[0].secureUrl, "https://d72cgtgi6hvvl.cloudfront.net/media/images/50.png") 90 | XCTAssertEqual(graph.additionalImages[0].width, 50) 91 | XCTAssertEqual(graph.additionalImages[0].height, 50) 92 | XCTAssertEqual(graph.additionalImages[0].mimeType, "image/png") 93 | XCTAssertNil(graph.additionalImages[0].alt) 94 | 95 | switch graph.type { 96 | case .website: 97 | break 98 | default: 99 | XCTFail("Graph type was not album.") 100 | return 101 | } 102 | } 103 | 104 | func testImageURL() { 105 | guard let graph = getGraph(filename: "image-url") else { 106 | XCTFail("No graph object found.") 107 | return 108 | } 109 | 110 | XCTAssertEqual(graph.title, "Full structured image property") 111 | XCTAssertEqual(graph.siteName, "Open Graph protocol examples") 112 | XCTAssertEqual(graph.url, "http://examples.opengraphprotocol.us/image-url.html") 113 | 114 | XCTAssertEqual(graph.image.url, "http://examples.opengraphprotocol.us/media/images/50.png") 115 | XCTAssertEqual(graph.image.secureUrl, "https://d72cgtgi6hvvl.cloudfront.net/media/images/50.png") 116 | XCTAssertEqual(graph.image.width, 50) 117 | XCTAssertEqual(graph.image.height, 50) 118 | XCTAssertEqual(graph.image.mimeType, "image/png") 119 | 120 | XCTAssertTrue(graph.additionalImages.isEmpty) 121 | 122 | switch graph.type { 123 | case .website: 124 | break 125 | default: 126 | XCTFail("Graph type was not album.") 127 | return 128 | } 129 | } 130 | 131 | func testAudioArray() { 132 | guard let graph = getGraph(filename: "audio-array") else { 133 | XCTFail("No graph object found.") 134 | return 135 | } 136 | 137 | XCTAssertEqual(graph.title, "Two structured audio properties") 138 | XCTAssertEqual(graph.siteName, "Open Graph protocol examples") 139 | XCTAssertEqual(graph.url, "http://examples.opengraphprotocol.us/audio-array.html") 140 | 141 | XCTAssertEqual(graph.image.url, "http://examples.opengraphprotocol.us/media/images/50.png") 142 | XCTAssertEqual(graph.image.secureUrl, "https://d72cgtgi6hvvl.cloudfront.net/media/images/50.png") 143 | XCTAssertEqual(graph.image.width, 50) 144 | XCTAssertEqual(graph.image.height, 50) 145 | XCTAssertEqual(graph.image.mimeType, "image/png") 146 | 147 | XCTAssertEqual(graph.audios.count, 2) 148 | 149 | XCTAssertEqual(graph.audios[0].url, "http://examples.opengraphprotocol.us/media/audio/1khz.mp3") 150 | XCTAssertEqual(graph.audios[0].secureUrl, "https://d72cgtgi6hvvl.cloudfront.net/media/audio/1khz.mp3") 151 | XCTAssertEqual(graph.audios[0].mimeType, "audio/mpeg") 152 | XCTAssertNil(graph.audios[0].alt) 153 | 154 | XCTAssertEqual(graph.audios[1].url, "http://examples.opengraphprotocol.us/media/audio/250hz.mp3") 155 | XCTAssertEqual(graph.audios[1].secureUrl, "https://d72cgtgi6hvvl.cloudfront.net/media/audio/250hz.mp3") 156 | XCTAssertEqual(graph.audios[1].mimeType, "audio/mpeg") 157 | XCTAssertEqual(graph.audios[1].alt, "The second audio, at 250hz.") 158 | 159 | switch graph.type { 160 | case .website: 161 | break 162 | default: 163 | XCTFail("Graph type was not album.") 164 | return 165 | } 166 | } 167 | 168 | func testAudioURL() { 169 | guard let graph = getGraph(filename: "audio-url") else { 170 | XCTFail("No graph object found.") 171 | return 172 | } 173 | 174 | XCTAssertEqual(graph.title, "Structured audio property") 175 | XCTAssertEqual(graph.siteName, "Open Graph protocol examples") 176 | XCTAssertEqual(graph.url, "http://examples.opengraphprotocol.us/audio-url.html") 177 | 178 | XCTAssertEqual(graph.image.url, "http://examples.opengraphprotocol.us/media/images/50.png") 179 | XCTAssertEqual(graph.image.secureUrl, "https://d72cgtgi6hvvl.cloudfront.net/media/images/50.png") 180 | XCTAssertEqual(graph.image.width, 50) 181 | XCTAssertEqual(graph.image.height, 50) 182 | XCTAssertEqual(graph.image.mimeType, "image/png") 183 | 184 | XCTAssertEqual(graph.audios.count, 1) 185 | 186 | XCTAssertEqual(graph.audios[0].url, "http://examples.opengraphprotocol.us/media/audio/250hz.mp3") 187 | XCTAssertEqual(graph.audios[0].secureUrl, "https://d72cgtgi6hvvl.cloudfront.net/media/audio/250hz.mp3") 188 | XCTAssertEqual(graph.audios[0].mimeType, "audio/mpeg") 189 | XCTAssertNil(graph.audios[0].alt) 190 | 191 | switch graph.type { 192 | case .website: 193 | break 194 | default: 195 | XCTFail("Graph type was not album.") 196 | return 197 | } 198 | } 199 | 200 | func testVideoMovie() { 201 | guard let graph = getGraph(filename: "video-movie") else { 202 | XCTFail("No graph object found.") 203 | return 204 | } 205 | 206 | XCTAssertEqual(graph.title, "Arrival of a Train at La Ciotat") 207 | XCTAssertEqual(graph.description, "L'arrivée d'un train en gare de La Ciotat is an 1895 French short black-and-white silent documentary film directed and produced by Auguste and Louis Lumière. Its first public showing took place in January 1896.") 208 | XCTAssertEqual(graph.locale, "en_US") 209 | XCTAssertEqual(graph.url, "http://examples.opengraphprotocol.us/video-movie.html") 210 | 211 | XCTAssertEqual(graph.image.url, "http://examples.opengraphprotocol.us/media/images/train.jpg") 212 | XCTAssertEqual(graph.image.secureUrl, "https://d72cgtgi6hvvl.cloudfront.net/media/images/train.jpg") 213 | XCTAssertEqual(graph.image.width, 500) 214 | XCTAssertEqual(graph.image.height, 328) 215 | XCTAssertEqual(graph.image.mimeType, "image/jpeg") 216 | 217 | XCTAssertTrue(graph.audios.isEmpty) 218 | 219 | XCTAssertEqual(graph.videos.count, 3) 220 | 221 | XCTAssertEqual(graph.videos[0].url, "http://fpdownload.adobe.com/strobe/FlashMediaPlayback.swf?src=http%3A%2F%2Fexamples.opengraphprotocol.us%2Fmedia%2Fvideo%2Ftrain.mp4") 222 | XCTAssertEqual(graph.videos[0].secureUrl, "https://fpdownload.adobe.com/strobe/FlashMediaPlayback.swf?src=https%3A%2F%2Fd72cgtgi6hvvl.cloudfront.net%2Fmedia%2Fvideo%2Ftrain.mp4") 223 | XCTAssertEqual(graph.videos[0].mimeType, "application/x-shockwave-flash") 224 | XCTAssertEqual(graph.videos[0].width, 472) 225 | XCTAssertEqual(graph.videos[0].height, 296) 226 | XCTAssertNil(graph.videos[0].alt) 227 | 228 | XCTAssertEqual(graph.videos[1].mimeType, "video/mp4") 229 | XCTAssertEqual(graph.videos[1].width, 472) 230 | XCTAssertEqual(graph.videos[1].height, 296) 231 | XCTAssertNil(graph.videos[1].alt) 232 | 233 | XCTAssertEqual(graph.videos[2].mimeType, "video/webm") 234 | XCTAssertEqual(graph.videos[2].width, 480) 235 | XCTAssertEqual(graph.videos[2].height, 320) 236 | XCTAssertNil(graph.videos[2].alt) 237 | 238 | switch graph.type { 239 | case .video(let attributes): 240 | XCTAssertEqual(attributes.kind, .movie) 241 | let formatter = DateFormatter(dateStyle: .short) 242 | formatter.locale = .init(identifier: "en_US") 243 | XCTAssertEqual(formatter.string(from: attributes.releaseDate!), "12/28/95") 244 | XCTAssertEqual(attributes.directors, ["http://examples.opengraphprotocol.us/profile.html"]) 245 | XCTAssertEqual(attributes.duration, 50) 246 | XCTAssertEqual(attributes.tags, ["La Ciotat", "train"]) 247 | break 248 | default: 249 | XCTFail("Graph type was not album.") 250 | return 251 | } 252 | } 253 | 254 | func testMin() { 255 | XCTAssertNil(getGraph(filename: "min")) 256 | } 257 | 258 | func testMusicAlbum() async throws { 259 | let url = "https://music.apple.com/us/album/fallen-embers-deluxe-version/1591091543" 260 | let html = await getHtml(for: url) 261 | 262 | guard let graph = OpenGraph(html: html) else { 263 | XCTFail("No graph object found.") 264 | return 265 | } 266 | 267 | XCTAssertEqual(graph.title, "Fallen Embers (Deluxe Version) by ILLENIUM on Apple Music") 268 | XCTAssertEqual(graph.url, url) 269 | 270 | XCTAssertEqual(graph.image.url, "https://is1-ssl.mzstatic.com/image/thumb/Music122/v4/94/c2/14/94c21487-8703-4ae5-9386-17335d5e9f5d/093624874690.jpg/1200x1200bf-60.jpg") 271 | XCTAssertEqual(graph.image.secureUrl, "https://is1-ssl.mzstatic.com/image/thumb/Music122/v4/94/c2/14/94c21487-8703-4ae5-9386-17335d5e9f5d/093624874690.jpg/1200x1200bf-60.jpg") 272 | XCTAssertEqual(graph.image.alt, "Fallen Embers (Deluxe Version) by ILLENIUM on Apple Music") 273 | XCTAssertEqual(graph.image.width, 1200) 274 | XCTAssertEqual(graph.image.height, 1200) 275 | XCTAssertEqual(graph.image.mimeType, "image/jpg") 276 | 277 | switch graph.type { 278 | case .album(let album): 279 | XCTAssertEqual(album.songs.count, 19) 280 | XCTAssertEqual(album.songs[0].url, "https://music.apple.com/us/song/wouldnt-change-a-thing/1591091768") 281 | XCTAssertEqual(album.songs[0].disc, 1) 282 | XCTAssertEqual(album.songs[0].track, 1) 283 | XCTAssertEqual(album.songs[0].duration, 187) 284 | 285 | XCTAssertEqual(album.musician, "https://music.apple.com/us/artist/illenium/645420096") 286 | test(date: album.releaseDate, shortUSString: "10/22/21") 287 | 288 | default: 289 | XCTFail("Graph type was not album.") 290 | return 291 | } 292 | } 293 | } 294 | --------------------------------------------------------------------------------