diff --git a/Demo/ParselyDemo/FirstViewController.swift b/Demo/ParselyDemo/FirstViewController.swift index ef520bc..55f6178 100644 --- a/Demo/ParselyDemo/FirstViewController.swift +++ b/Demo/ParselyDemo/FirstViewController.swift @@ -7,7 +7,7 @@ class FirstViewController: UIViewController { @IBAction func didTouchButton(_ sender: Any) { os_log("didTouchButton", log: OSLog.default, type: .debug) - let demoMetas = ParselyMetadata(authors: ["Yogi Berr"]) + let demoMetas = ParselyMetadata(authors: ["Yogi Berr"], page_type: "post") delegate.parsely.trackPageView(url: "http://parsely.com/path/cool-blog-post/1?qsarg=nawp&anotherone=yup", metadata: demoMetas, extraData: ["product-id": "12345"], siteId: "subdomain.parsely-test.com") } diff --git a/Sources/Metadata.swift b/Sources/Metadata.swift index bc906ba..305269f 100644 --- a/Sources/Metadata.swift +++ b/Sources/Metadata.swift @@ -3,12 +3,33 @@ import Foundation public class ParselyMetadata { var canonical_url: String? var pub_date: Date? + var save_date: Date? var title: String? var authors: Array? var image_url: String? var section: String? var tags: Array? var duration: TimeInterval? + var page_type: String? + var urls: String? + var post_id: String? + var pub_date_tmsp: Date? + var custom_metadata: String? + var save_date_tmsp: Date? + var thumb_url: String? + var full_content_word_count: Int? + var share_urls: Array? + var data_source: String? + var canonical_hash: String? + var canonical_hash64: String? + var video_platform: String? + var language: String? + var full_content: String? + var full_content_sha512: String? + var network_id_str: String? + var network_canonical: String? + var content_enrichments: Dictionary? + /** A class to manage and re-use metadata. Metadata contained in an instance of this @@ -16,29 +37,89 @@ public class ParselyMetadata { - Parameter canonical_url: A post's canonical url. For videos, it is overridden with the vId and thus can be omitted. - Parameter pub_date: Date this piece of content was published. + - Parameter save_date: Date this piece of content was saved. - Parameter title: Title of the content. - Parameter authors: Up to 10 authors are accepted. - Parameter image_url: Where the main image for this post is hosted. - Parameter section: Same as section for website integration. - Parameter tags: Up to 20 tags on an event are allowed. - Parameter duration: Durations passed explicitly to trackVideoStart take precedence over any in metadata. + - Parameter page_type: The type of page being tracked + - Parameter urls: A list of urls associated with this post. + - Parameter post_id: A unique identifier for this post. + - Parameter pub_date_tmsp: Date this piece of content was published. + - Parameter custom_metadata: A string of custom metadata. + - Parameter save_date_tmsp: Date this piece of content was saved. + - Parameter thumb_url: Where the thumbnail image for this post is hosted. + - Parameter full_content_word_count: The number of words in the full content. + - Parameter share_urls: A list of urls associated with this post. + - Parameter data_source: The data source for this post. + - Parameter canonical_hash: The canonical hash for this post. + - Parameter canonical_hash64: The canonical hash for this post. + - Parameter video_platform: The video platform for this post. + - Parameter language: The language for this post. + - Parameter full_content: The full content for this post. + - Parameter full_content_sha512: The full content sha512 for this post. + - Parameter network_id_str: The network id for this post. + - Parameter network_canonical: The network canonical for this post. + - Parameter content_enrichments: The content enrichments for this post. */ public init(canonical_url: String? = nil, pub_date: Date? = nil, + save_date: Date? = nil, title: String? = nil, authors: Array? = nil, image_url: String? = nil, section: String? = nil, tags: Array? = nil, - duration: TimeInterval? = nil) { + duration: TimeInterval? = nil, + page_type: String? = nil, + urls: String? = nil, + post_id: String? = nil, + pub_date_tmsp: Date? = nil, + custom_metadata: String? = nil, + save_date_tmsp: Date? = nil, + thumb_url: String? = nil, + full_content_word_count: Int? = nil, + share_urls: Array? = nil, + data_source: String? = nil, + canonical_hash: String? = nil, + canonical_hash64: String? = nil, + video_platform: String? = nil, + language: String? = nil, + full_content: String? = nil, + full_content_sha512: String? = nil, + network_id_str: String? = nil, + network_canonical: String? = nil, + content_enrichments: Dictionary? = nil) { self.canonical_url = canonical_url self.pub_date = pub_date + self.save_date = save_date self.title = title self.authors = authors self.image_url = image_url self.section = section self.tags = tags self.duration = duration + self.page_type = page_type + self.urls = urls + self.post_id = post_id + self.pub_date_tmsp = pub_date_tmsp + self.custom_metadata = custom_metadata + self.save_date_tmsp = save_date_tmsp + self.thumb_url = thumb_url + self.full_content_word_count = full_content_word_count + self.share_urls = share_urls + self.data_source = data_source + self.canonical_hash = canonical_hash + self.canonical_hash64 = canonical_hash64 + self.video_platform = video_platform + self.language = language + self.full_content = full_content + self.full_content_sha512 = full_content_sha512 + self.network_id_str = network_id_str + self.network_canonical = network_canonical + self.content_enrichments = content_enrichments } func toDict() -> Dictionary { @@ -50,6 +131,9 @@ public class ParselyMetadata { if let pub_date { metas["pub_date"] = String(format:"%i", pub_date.millisecondsSince1970) } + if let save_date { + metas["save_date"] = String(format:"%i", save_date.millisecondsSince1970) + } if let title { metas["title"] = title } @@ -68,7 +152,63 @@ public class ParselyMetadata { if let duration { metas["duration"] = duration } - + if let page_type { + metas["page_type"] = page_type + } + if let urls { + metas["urls"] = urls + } + if let post_id { + metas["post_id"] = post_id + } + if let pub_date_tmsp { + metas["pub_date_tmsp"] = String(format:"%i", pub_date_tmsp.millisecondsSince1970) + } + if let custom_metadata { + metas["custom_metadata"] = custom_metadata + } + if let save_date_tmsp { + metas["save_date_tmsp"] = String(format:"%i", save_date_tmsp.millisecondsSince1970) + } + if let thumb_url { + metas["thumb_url"] = thumb_url + } + if let full_content_word_count { + metas["full_content_word_count"] = full_content_word_count + } + if let share_urls { + metas["share_urls"] = share_urls + } + if let data_source { + metas["data_source"] = data_source + } + if let canonical_hash { + metas["canonical_hash"] = canonical_hash + } + if let canonical_hash64 { + metas["canonical_hash64"] = canonical_hash64 + } + if let video_platform { + metas["video_platform"] = video_platform + } + if let language { + metas["language"] = language + } + if let full_content { + metas["full_content"] = full_content + } + if let full_content_sha512 { + metas["full_content_sha512"] = full_content_sha512 + } + if let network_id_str { + metas["network_id_str"] = network_id_str + } + if let network_canonical { + metas["network_canonical"] = network_canonical + } + if let content_enrichments { + metas["content_enrichments"] = content_enrichments + } return metas } } diff --git a/Tests/MetadataTests.swift b/Tests/MetadataTests.swift index e3dd6f5..21b373b 100644 --- a/Tests/MetadataTests.swift +++ b/Tests/MetadataTests.swift @@ -6,12 +6,32 @@ class MetadataTests: XCTestCase { let expected: Dictionary = [ "canonical_url": "http://parsely-test.com", "pub_date": Date(), + "save_date": Date(), "title": "a title.", "authors": ["Yogi Berra"], "image_url": "http://parsely-test.com/image2", "section": "Things my mother says", "tags": ["tag1", "tag2"], - "duration": TimeInterval(100) + "duration": TimeInterval(100), + "page_type": "post", + "urls": "http://parsely-test.com", + "post_id": "1", + "pub_date_tmsp": Date(), + "custom_metadata": "hedgehogs", + "save_date_tmsp": Date(), + "thumb_url": "http://parsely-test.com/image2", + "full_content_word_count": 100, + "share_urls": ["http://parsely-test.com"], + "data_source": "the moon", + "canonical_hash": "hash_browns", + "canonical_hash64": "hash_browns64", + "video_platform": "youtube", + "language": "en", + "full_content": "the full content of the article", + "full_content_sha512": "what is this?", + "network_id_str": "abc", + "network_canonical": "network canonical" + ] func testToDictEmpty() { @@ -32,15 +52,37 @@ class MetadataTests: XCTestCase { let metasUnderTest = ParselyMetadata( canonical_url: expected["canonical_url"] as? String, pub_date: expected["pub_date"] as? Date, + save_date: expected["save_date"] as? Date, title: expected["title"] as? String, authors: expected["authors"] as? Array, image_url: expected["image_url"] as? String, section: expected["section"] as? String, tags: expected["tags"] as? Array, - duration: expected["duration"] as? TimeInterval + duration: expected["duration"] as? TimeInterval, + page_type: expected["page_type"] as? String, + urls: expected["urls"] as? String, + post_id: expected["post_id"] as? String, + pub_date_tmsp: expected["pub_date_tmsp"] as? Date, + custom_metadata: expected["custom_metadata"] as? String, + save_date_tmsp: expected["save_date_tmsp"] as? Date, + thumb_url: expected["thumb_url"] as? String, + full_content_word_count: expected["full_content_word_count"] as? Int, + share_urls: expected["share_urls"] as? Array, + data_source: expected["data_source"] as? String, + canonical_hash: expected["canonical_hash"] as? String, + canonical_hash64: expected["canonical_hash64"] as? String, + video_platform: expected["video_platform"] as? String, + language: expected["language"] as? String, + full_content: expected["full_content"] as? String, + full_content_sha512: expected["full_content_sha512"] as? String, + network_id_str: expected["network_id_str"] as? String, + network_canonical: expected["network_canonical"] as? String ) let actual: Dictionary = metasUnderTest.toDict() let pubDateUnix: String = String(format:"%i", (expected["pub_date"]! as! Date).millisecondsSince1970) + let saveDateUnix: String = String(format:"%i", (expected["save_date"]! as! Date).millisecondsSince1970) + let pubDateTmspUnix: String = String(format:"%i", (expected["pub_date_tmsp"]! as! Date).millisecondsSince1970) + let saveDateTmspUnix: String = String(format:"%i", (expected["save_date_tmsp"]! as! Date).millisecondsSince1970) XCTAssertFalse(actual.isEmpty, "Creating a ParselyMetadataobject with many parameters results in a " + "non-empty object") XCTAssertEqual(actual["link"]! as! String, expected["canonical_url"]! as! String, @@ -49,6 +91,9 @@ class MetadataTests: XCTestCase { XCTAssertEqual(actual["pub_date"]! as! String, pubDateUnix, "The pub_date field in the result of ParselyMetadata.toDict should match the pub_date argument " + "used at initialization") + XCTAssertEqual(actual["save_date"]! as! String, pubDateUnix, + "The save_date field in the result of ParselyMetadata.toDict should match the save_date argument " + + "used at initialization") XCTAssertEqual(actual["title"]! as! String, expected["title"]! as! String, "The title field in the result of ParselyMetadata.toDict should match the title argument " + "used at initialization") @@ -67,6 +112,60 @@ class MetadataTests: XCTestCase { XCTAssertEqual(actual["duration"]! as! TimeInterval, expected["duration"]! as! TimeInterval, "The duration field in the result of ParselyMetadata.toDict should match the duration argument " + "used at initialization") + XCTAssertEqual(actual["page_type"]! as! String, expected["page_type"]! as! String, + "The page_type field in the result of ParselyMetadata.toDict should match the page_type argument " + + "used at initialization") + XCTAssertEqual(actual["urls"]! as! String, expected["urls"]! as! String, + "The urls field in the result of ParselyMetadata.toDict should match the urls argument " + + "used at initialization") + XCTAssertEqual(actual["post_id"]! as! String, expected["post_id"]! as! String, + "The post_id field in the result of ParselyMetadata.toDict should match the post_id argument " + + "used at initialization") + XCTAssertEqual(actual["pub_date_tmsp"]! as! String, pubDateTmspUnix, + "The pub_date_tmsp field in the result of ParselyMetadata.toDict should match the pub_date_tmsp argument " + + "used at initialization") + XCTAssertEqual(actual["custom_metadata"]! as! String, expected["custom_metadata"]! as! String, + "The custom_metadata field in the result of ParselyMetadata.toDict should match the custom_metadata argument " + + "used at initialization") + XCTAssertEqual(actual["save_date_tmsp"]! as! String, saveDateTmspUnix, + "The save_date_tmsp field in the result of ParselyMetadata.toDict should match the save_date_tmsp argument " + + "used at initialization") + XCTAssertEqual(actual["thumb_url"]! as! String, expected["thumb_url"]! as! String, + "The thumb_url field in the result of ParselyMetadata.toDict should match the thumb_url argument " + + "used at initialization") + XCTAssertEqual(actual["full_content_word_count"]! as! Int, expected["full_content_word_count"]! as! Int, + "The full_content_word_count field in the result of ParselyMetadata.toDict should match the full_content_word_count argument " + + "used at initialization") + XCTAssertEqual(actual["share_urls"]! as! Array, expected["share_urls"]! as! Array, + "The share_urls field in the result of ParselyMetadata.toDict should match the share_urls argument " + + "used at initialization") + XCTAssertEqual(actual["data_source"]! as! String, expected["data_source"]! as! String, + "The data_source field in the result of ParselyMetadata.toDict should match the data_source argument " + + "used at initialization") + XCTAssertEqual(actual["canonical_hash"]! as! String, expected["canonical_hash"]! as! String, + "The canonical_hash field in the result of ParselyMetadata.toDict should match the canonical_hash argument " + + "used at initialization") + XCTAssertEqual(actual["canonical_hash64"]! as! String, expected["canonical_hash64"]! as! String, + "The canonical_hash64 field in the result of ParselyMetadata.toDict should match the canonical_hash64 argument " + + "used at initialization") + XCTAssertEqual(actual["video_platform"]! as! String, expected["video_platform"]! as! String, + "The video_platform field in the result of ParselyMetadata.toDict should match the video_platform argument " + + "used at initialization") + XCTAssertEqual(actual["language"]! as! String, expected["language"]! as! String, + "The language field in the result of ParselyMetadata.toDict should match the language argument " + + "used at initialization") + XCTAssertEqual(actual["full_content"]! as! String, expected["full_content"]! as! String, + "The full_content field in the result of ParselyMetadata.toDict should match the full_content argument " + + "used at initialization") + XCTAssertEqual(actual["full_content_sha512"]! as! String, expected["full_content_sha512"]! as! String, + "The full_content_sha512 field in the result of ParselyMetadata.toDict should match the full_content_sha512 argument " + + "used at initialization") + XCTAssertEqual(actual["network_id_str"]! as! String, expected["network_id_str"]! as! String, + "The network_id_str field in the result of ParselyMetadata.toDict should match the network_id_str argument " + + "used at initialization") + XCTAssertEqual(actual["network_canonical"]! as! String, expected["network_canonical"]! as! String, + "The network_canonical field in the result of ParselyMetadata.toDict should match the network_canonical argument " + + "used at initialization") } func testMetadata() { @@ -78,7 +177,8 @@ class MetadataTests: XCTestCase { image_url: expected["image_url"] as? String, section: expected["section"] as? String, tags: expected["tags"] as? Array, - duration: expected["duration"] as? TimeInterval + duration: expected["duration"] as? TimeInterval, + page_type: expected["page_type"] as? String ) XCTAssertEqual(metasUnderTest.canonical_url, expected["canonical_url"]! as? String, "The canonical_url field on ParselyMetadata should match the canonical_url argument " + @@ -104,5 +204,8 @@ class MetadataTests: XCTestCase { XCTAssertEqual(metasUnderTest.duration, expected["duration"]! as? TimeInterval, "The duration field on ParselyMetadata should match the duration argument " + "used at initialization") + XCTAssertEqual(metasUnderTest.page_type, expected["page_type"]! as? String, + "The page_type field on ParselyMetadata should match the page_type argument " + + "used at initialization") } } diff --git a/Tests/RequestBuilderTests.swift b/Tests/RequestBuilderTests.swift index 4c0301f..77d2fc7 100644 --- a/Tests/RequestBuilderTests.swift +++ b/Tests/RequestBuilderTests.swift @@ -8,12 +8,32 @@ class RequestBuilderTests: XCTestCase { let exampleMetadata: ParselyMetadata = ParselyMetadata( canonical_url:"http://parsely-test.com", pub_date: Date(timeIntervalSince1970: 3), + save_date: Date(timeIntervalSince1970: 4), title: "a title.", authors: ["Yogi Berra"], image_url: "http://parsely-test.com/image2", section: "Things my mother says", tags: ["tag1", "tag2"], - duration: TimeInterval(100) + duration: TimeInterval(100), + page_type: "post", + urls: "http://parsely-test.com/1", + post_id: "1", + pub_date_tmsp: Date(timeIntervalSince1970: 5), + custom_metadata: "custom", + save_date_tmsp: Date(timeIntervalSince1970: 6), + thumb_url: "http://parsely-test.com/thumb", + full_content_word_count: 1000, + share_urls: ["http://parsely-test.com/share1", "http://parsely-test.com/share2"], + data_source: "test", + canonical_hash: "hash", + canonical_hash64: "hash64", + video_platform: "youtube", + language: "en", + full_content: "full content", + full_content_sha512: "full content sha512", + network_id_str: "network id", + network_canonical: "http://parsely-test.com/network_canonical", + content_enrichments: ["enrichment1": "value1", "enrichment2": "value2"] ) return [Event( "pageview", diff --git a/Tests/VideoTests.swift b/Tests/VideoTests.swift index 5fc44aa..fd03bea 100644 --- a/Tests/VideoTests.swift +++ b/Tests/VideoTests.swift @@ -73,12 +73,32 @@ class VideoTests: ParselyTestCase { let firstTestMetadata = ParselyMetadata( canonical_url: testUrl, pub_date: Date(), + save_date: Date(), title: "test", authors: nil, image_url: nil, section: testSectionFirst, tags: nil, - duration: nil + duration: nil, + page_type: "post", + urls: nil, + post_id: nil, + pub_date_tmsp: nil, + custom_metadata: nil, + save_date_tmsp: nil, + thumb_url: nil, + full_content_word_count: nil, + share_urls: nil, + data_source: nil, + canonical_hash: nil, + canonical_hash64: nil, + video_platform: nil, + language: nil, + full_content: nil, + full_content_sha512: nil, + network_id_str: nil, + network_canonical: nil, + content_enrichments: nil ) videoManager.trackPlay( @@ -99,12 +119,32 @@ class VideoTests: ParselyTestCase { let secondTestMetadata = ParselyMetadata( canonical_url: testUrl, pub_date: Date(), + save_date: Date(), title: "test", authors: nil, image_url: nil, section: testSectionSecond, tags: nil, - duration: nil + duration: nil, + page_type: "post", + urls: nil, + post_id: nil, + pub_date_tmsp: nil, + custom_metadata: nil, + save_date_tmsp: nil, + thumb_url: nil, + full_content_word_count: nil, + share_urls: nil, + data_source: nil, + canonical_hash: nil, + canonical_hash64: nil, + video_platform: nil, + language: nil, + full_content: nil, + full_content_sha512: nil, + network_id_str: nil, + network_canonical: nil, + content_enrichments: nil ) videoManager.trackPlay(