<commit_before>//
//  ┌────┬─┐         ┌─────┐
//  │  ──┤ └─┬───┬───┤  ┌──┼─┬─┬───┐
//  ├──  │ ╷ │ · │ · │  ╵  │ ╵ │ ╷ │
//  └────┴─┴─┴───┤ ┌─┴─────┴───┴─┴─┘
//               └─┘
//
//  Copyright (c) 2018 ShopGun. All rights reserved.

import XCTest
@testable import ShopGunSDK

class SDKEventsTests: XCTestCase {
    // https://gist.github.com/tbug/88c169d2ac5f5bebbf59211eb35ff23a
    var tokenizer: UniqueViewTokenizer!
    fileprivate let dataStore = MockSaltDataStore()
    
    override func setUp() {
        super.setUp()
        
        self.tokenizer = UniqueViewTokenizer(salt: "salty")!
        
        dataStore.salt = "myhash"
        guard let settings = try? Settings.EventsTracker(appId: "appId_123") else { return }
        EventsTracker.configure(settings,
                                dataStore: self.dataStore)
    }
    
    func testDummy() {
        let testDate = Date(eventTimestamp: 12345)
        
        let event = Event.dummy(timestamp: testDate)
        
        XCTAssertFalse(event.id.rawValue.isEmpty)
        XCTAssertEqual(event.type, 0)
        XCTAssertEqual(event.timestamp.eventTimestamp, 12345)
        XCTAssertEqual(event.version, 2)
        XCTAssertEqual(event.payload, [:])
        
        let nowTimestamp = Date().eventTimestamp
        XCTAssert(abs(Event.dummy().timestamp.eventTimestamp - nowTimestamp) <= 2)
    }
    
    func testPagePublicationOpened() {
        let testDate = Date(eventTimestamp: 12345)
        let event = Event.pagedPublicationOpened("pub1", timestamp: testDate, tokenizer: self.tokenizer.tokenize)
        
        XCTAssertFalse(event.id.rawValue.isEmpty)
        XCTAssertEqual(event.type, 1)
        XCTAssertEqual(event.timestamp.eventTimestamp, 12345)
        XCTAssertEqual(event.version, 2)
        XCTAssertEqual(event.payload,
                       ["pp.id": .string("pub1"),
                        "vt": .string("HUdC076YIL8=")])
        
        let nowTimestamp = Date().eventTimestamp
        let defaultEvent = Event.pagedPublicationOpened("😁")
        XCTAssert(abs(defaultEvent.timestamp.eventTimestamp - nowTimestamp) <= 2)
        XCTAssertEqual(defaultEvent.payload,
                       ["pp.id": .string("😁"),
                        "vt": .string("POcLWv7/N4Q=")])
    }
    
    func testPagedPublicationPageOpened() {
        let testDate = Date(eventTimestamp: 12345)
        let event = Event.pagedPublicationPageOpened("pub1", pageNumber: 1, timestamp: testDate, tokenizer: self.tokenizer.tokenize)

        XCTAssertFalse(event.id.rawValue.isEmpty)
        XCTAssertEqual(event.type, 2)
        XCTAssertEqual(event.timestamp.eventTimestamp, 12345)
        XCTAssertEqual(event.version, 2)
        XCTAssertEqual(event.payload,
                       ["pp.id": .string("pub1"),
                        "ppp.n": .int(1),
                        "vt": .string("xX+BAiu1Nmo=")])

        let nowTimestamp = Date().eventTimestamp
        let defaultEvent = Event.pagedPublicationPageOpened("ølØl5Banana", pageNumber: 9999)
        XCTAssert(abs(defaultEvent.timestamp.eventTimestamp - nowTimestamp) <= 2)
        XCTAssertEqual(defaultEvent.payload,
                       ["pp.id": .string("ølØl5Banana"),
                        "ppp.n": .int(9999),
                        "vt": .string("JR8kZFk7M+Y=")])
        
        XCTAssertEqual(Event.pagedPublicationPageOpened("pub1", pageNumber: 1).payload,
                       ["pp.id": .string("pub1"),
                        "ppp.n": .int(1),
                        "vt": .string("GKtJxfAxRZI=")])
        
        XCTAssertEqual(Event.pagedPublicationPageOpened("pub1", pageNumber: 9999).payload,
                       ["pp.id": .string("pub1"),
                        "ppp.n": .int(9999),
                        "vt": .string("VwMOrDD8zMk=")])
    }
    
    func testPotentialLocalBusinessVisit() {
        let testDate = Date(eventTimestamp: 12345)
        let event = Event.potentialLocalBusinessVisit(for: .init(rawValue: "e3dclwL"), dealerId: .init(rawValue: "d7fazg"), horizontalAccuracy: 93, distanceToStore: 85, timeSinceLastInteraction: 3600, timestamp: testDate)
        
        XCTAssertFalse(event.id.rawValue.isEmpty)
        XCTAssertEqual(event.type, 10)
        XCTAssertEqual(event.timestamp.eventTimestamp, 12345)
        XCTAssertEqual(event.version, 2)
        
        XCTAssertEqual(event.payload,
                       ["lb.id": .string("e3dclwL"),
                        "lb.bid": .string("d7fazg"),
                        "l.hac": .int(93),
                        "lb.dis": .int(85),
                        "b.cin": .bool(true),
                        "b.cint": .int(1),
                        "vt": .string("JGwLh2htW9c=")])
    }
    
    func testOfferOpened() {
        let testDate = Date(eventTimestamp: 12345)
        let event = Event.offerOpened("offer_123", timestamp: testDate, tokenizer: self.tokenizer.tokenize)
        
        XCTAssertFalse(event.id.rawValue.isEmpty)
        XCTAssertEqual(event.type, 3)
        XCTAssertEqual(event.timestamp.eventTimestamp, 12345)
        XCTAssertEqual(event.version, 2)
        XCTAssertEqual(event.payload,
                       ["of.id": .string("offer_123"),
                        "vt": .string("YNcV9px8d8U=")])
        
        let nowTimestamp = Date().eventTimestamp
        let defaultEvent = Event.offerOpened("øffer_321")
        XCTAssert(abs(defaultEvent.timestamp.eventTimestamp - nowTimestamp) <= 2)
        XCTAssertEqual(defaultEvent.payload,
                       ["of.id": .string("øffer_321"),
                        "vt": .string("ryYm+eb1bUU=")])
    }
    
    func testClientSessionOpened() {
        let testDate = Date(eventTimestamp: 12345)
        
        let event = Event.clientSessionOpened(timestamp: testDate)
        
        XCTAssertFalse(event.id.rawValue.isEmpty)
        XCTAssertEqual(event.type, 4)
        XCTAssertEqual(event.timestamp.eventTimestamp, 12345)
        XCTAssertEqual(event.version, 2)
        XCTAssertEqual(event.payload, [:])
        
        let nowTimestamp = Date().eventTimestamp
        XCTAssert(abs(Event.clientSessionOpened().timestamp.eventTimestamp - nowTimestamp) <= 2)
    }
    
    func testSearched() {
        let testDate = Date(eventTimestamp: 12345)
        let query = "Søme Very Long Séarch string 🌈"
        let event = Event.searched(for: query, languageCode: "DA", timestamp: testDate, tokenizer: self.tokenizer.tokenize)
        
        XCTAssertFalse(event.id.rawValue.isEmpty)
        XCTAssertEqual(event.type, 5)
        XCTAssertEqual(event.timestamp.eventTimestamp, 12345)
        XCTAssertEqual(event.version, 2)
        XCTAssertEqual(event.payload,
                       ["sea.q": .string(query),
                        "sea.l": .string("DA"),
                        "vt": .string("erHTNwqSrLY=")])
        
        let nowTimestamp = Date().eventTimestamp
        let defaultEvent = Event.searched(for: "", languageCode: nil)
        XCTAssert(abs(defaultEvent.timestamp.eventTimestamp - nowTimestamp) <= 2)
        XCTAssertEqual(defaultEvent.payload,
                       ["sea.q": .string(""),
                        "vt": .string("2oEIMMzybMM=")])
        
        XCTAssertEqual(Event.searched(for: "my search string", languageCode: "a").payload,
                       ["sea.q": .string("my search string"),
                        "sea.l": .string("a"),
                        "vt": .string("bNOIlf+nAAU=")])
        
        XCTAssertEqual(Event.searched(for: "my search string 😁", languageCode: nil).payload,
                       ["sea.q": .string("my search string 😁"),
                        "vt": .string("+OJqwh68nIk=")])
        
        XCTAssertEqual(Event.searched(for: "øl og æg", languageCode: nil).payload,
                       ["sea.q": .string("øl og æg"),
                        "vt": .string("NTgj68OWnbc=")])
    }
    
    func testOfferOpenedAfterSearch() {
        let testDate = Date(eventTimestamp: 12345)
        let query = "Søme Very Long Séarch string 🌈"
        let event = Event.offerOpenedAfterSearch(offerId: "offer_123", query: query, languageCode: "DA", timestamp: testDate)
        
        XCTAssertFalse(event.id.rawValue.isEmpty)
        XCTAssertEqual(event.type, 7)
        XCTAssertEqual(event.timestamp.eventTimestamp, 12345)
        XCTAssertEqual(event.version, 2)
        XCTAssertEqual(event.payload,
                       ["sea.q": .string(query),
                        "sea.l": .string("DA"),
                        "of.id": .string("offer_123")])
        
        let nowTimestamp = Date().eventTimestamp
        let defaultEvent = Event.offerOpenedAfterSearch(offerId: "abc123", query: "", languageCode: nil)
        XCTAssert(abs(defaultEvent.timestamp.eventTimestamp - nowTimestamp) <= 2)
        XCTAssertEqual(defaultEvent.payload,
                       ["sea.q": .string(""),
                        "of.id": .string("abc123")])
    }
    
    func testFirstOfferOpenedAfterSearch() {
        let testDate = Date(eventTimestamp: 12345)
        let query = "Another Very Long Séarch string 🌈"
        let offerIds = ["b", "a", "c"].map(CoreAPI.Offer.Identifier.init(rawValue:))
        let event = Event.firstOfferOpenedAfterSearch(offerId: "offer_123", precedingOfferIds: offerIds, query: query, languageCode: "DA", timestamp: testDate)
        
        XCTAssertFalse(event.id.rawValue.isEmpty)
        XCTAssertEqual(event.type, 6)
        XCTAssertEqual(event.timestamp.eventTimestamp, 12345)
        XCTAssertEqual(event.version, 2)
        XCTAssertEqual(event.payload,
                       ["sea.q": .string(query),
                        "sea.l": .string("DA"),
                        "of.id": .string("offer_123"),
                        "of.ids": .array([.string("b"), .string("a"), .string("c")])
                        ])
        
        let nowTimestamp = Date().eventTimestamp
        let defaultEvent = Event.firstOfferOpenedAfterSearch(offerId: "abc123", precedingOfferIds: [], query: "", languageCode: nil)
        XCTAssert(abs(defaultEvent.timestamp.eventTimestamp - nowTimestamp) <= 2)
        XCTAssertEqual(defaultEvent.payload,
                       ["sea.q": .string(""),
                        "of.id": .string("abc123"),
                        "of.ids": .array([])
                        ])
        
        let manyOfferIds = Array(50..<250).map({ CoreAPI.Offer.Identifier(rawValue: String($0)) })
        
        let clampedOfferIds = manyOfferIds.prefix(100).map({ JSONValue.string($0.rawValue) })
        
        let bigEvent = Event.firstOfferOpenedAfterSearch(offerId: "abc123", precedingOfferIds: manyOfferIds, query: "", languageCode: nil)
        
        
        XCTAssertEqual(bigEvent.payload,
                       ["sea.q": .string(""),
                        "of.id": .string("abc123"),
                        "of.ids": .array(clampedOfferIds)<commit_msg>Little tidying of code<commit_after>//
//  ┌────┬─┐         ┌─────┐
//  │  ──┤ └─┬───┬───┤  ┌──┼─┬─┬───┐
//  ├──  │ ╷ │ · │ · │  ╵  │ ╵ │ ╷ │
//  └────┴─┴─┴───┤ ┌─┴─────┴───┴─┴─┘
//               └─┘
//
//  Copyright (c) 2018 ShopGun. All rights reserved.

import XCTest
@testable import ShopGunSDK

class SDKEventsTests: XCTestCase {
    // https://gist.github.com/tbug/88c169d2ac5f5bebbf59211eb35ff23a
    var tokenizer: UniqueViewTokenizer!
    fileprivate let dataStore = MockSaltDataStore()
    
    override func setUp() {
        super.setUp()
        
        self.tokenizer = UniqueViewTokenizer(salt: "salty")!
        
        dataStore.salt = "myhash"
        guard let settings = try? Settings.EventsTracker(appId: "appId_123") else { return }
        EventsTracker.configure(settings,
                                dataStore: self.dataStore)
    }
    
    func testDummy() {
        let testDate = Date(eventTimestamp: 12345)
        
        let event = Event.dummy(timestamp: testDate)
        
        XCTAssertFalse(event.id.rawValue.isEmpty)
        XCTAssertEqual(event.type, 0)
        XCTAssertEqual(event.timestamp.eventTimestamp, 12345)
        XCTAssertEqual(event.version, 2)
        XCTAssertEqual(event.payload, [:])
        
        let nowTimestamp = Date().eventTimestamp
        XCTAssert(abs(Event.dummy().timestamp.eventTimestamp - nowTimestamp) <= 2)
    }
    
    func testPagePublicationOpened() {
        let testDate = Date(eventTimestamp: 12345)
        let event = Event.pagedPublicationOpened("pub1", timestamp: testDate, tokenizer: self.tokenizer.tokenize)
        
        XCTAssertFalse(event.id.rawValue.isEmpty)
        XCTAssertEqual(event.type, 1)
        XCTAssertEqual(event.timestamp.eventTimestamp, 12345)
        XCTAssertEqual(event.version, 2)
        XCTAssertEqual(event.payload,
                       ["pp.id": .string("pub1"),
                        "vt": .string("HUdC076YIL8=")])
        
        let nowTimestamp = Date().eventTimestamp
        let defaultEvent = Event.pagedPublicationOpened("😁")
        XCTAssert(abs(defaultEvent.timestamp.eventTimestamp - nowTimestamp) <= 2)
        XCTAssertEqual(defaultEvent.payload,
                       ["pp.id": .string("😁"),
                        "vt": .string("POcLWv7/N4Q=")])
    }
    
    func testPagedPublicationPageOpened() {
        let testDate = Date(eventTimestamp: 12345)
        let event = Event.pagedPublicationPageOpened("pub1", pageNumber: 1, timestamp: testDate, tokenizer: self.tokenizer.tokenize)

        XCTAssertFalse(event.id.rawValue.isEmpty)
        XCTAssertEqual(event.type, 2)
        XCTAssertEqual(event.timestamp.eventTimestamp, 12345)
        XCTAssertEqual(event.version, 2)
        XCTAssertEqual(event.payload,
                       ["pp.id": .string("pub1"),
                        "ppp.n": .int(1),
                        "vt": .string("xX+BAiu1Nmo=")])

        let nowTimestamp = Date().eventTimestamp
        let defaultEvent = Event.pagedPublicationPageOpened("ølØl5Banana", pageNumber: 9999)
        XCTAssert(abs(defaultEvent.timestamp.eventTimestamp - nowTimestamp) <= 2)
        XCTAssertEqual(defaultEvent.payload,
                       ["pp.id": .string("ølØl5Banana"),
                        "ppp.n": .int(9999),
                        "vt": .string("JR8kZFk7M+Y=")])
        
        XCTAssertEqual(Event.pagedPublicationPageOpened("pub1", pageNumber: 1).payload,
                       ["pp.id": .string("pub1"),
                        "ppp.n": .int(1),
                        "vt": .string("GKtJxfAxRZI=")])
        
        XCTAssertEqual(Event.pagedPublicationPageOpened("pub1", pageNumber: 9999).payload,
                       ["pp.id": .string("pub1"),
                        "ppp.n": .int(9999),
                        "vt": .string("VwMOrDD8zMk=")])
    }
    
    func testPotentialLocalBusinessVisit() {
        let testDate = Date(eventTimestamp: 12345)
        let event = Event.potentialLocalBusinessVisit(for: .init(rawValue: "e3dclwL"), dealerId: .init(rawValue: "d7fazg"), horizontalAccuracy: 93, distanceToStore: 85, timeSinceLastInteraction: 3600, timestamp: testDate)
        
        XCTAssertFalse(event.id.rawValue.isEmpty)
        XCTAssertEqual(event.type, 10)
        XCTAssertEqual(event.timestamp.eventTimestamp, 12345)
        XCTAssertEqual(event.version, 2)
        
        XCTAssertEqual(event.payload,
                       ["lb.id": .string("e3dclwL"),
                        "lb.bid": .string("d7fazg"),
                        "l.hac": .int(93),
                        "lb.dis": .int(85),
                        "b.cin": .bool(true),
                        "b.cint": .int(1),
                        "vt": .string("JGwLh2htW9c=")])
    }
    
    func testOfferOpened() {
        let testDate = Date(eventTimestamp: 12345)
        let event = Event.offerOpened("offer_123", timestamp: testDate, tokenizer: self.tokenizer.tokenize)
        
        XCTAssertFalse(event.id.rawValue.isEmpty)
        XCTAssertEqual(event.type, 3)
        XCTAssertEqual(event.timestamp.eventTimestamp, 12345)
        XCTAssertEqual(event.version, 2)
        XCTAssertEqual(event.payload,
                       ["of.id": .string("offer_123"),
                        "vt": .string("YNcV9px8d8U=")])
        
        let nowTimestamp = Date().eventTimestamp
        let defaultEvent = Event.offerOpened("øffer_321")
        XCTAssert(abs(defaultEvent.timestamp.eventTimestamp - nowTimestamp) <= 2)
        XCTAssertEqual(defaultEvent.payload,
                       ["of.id": .string("øffer_321"),
                        "vt": .string("ryYm+eb1bUU=")])
    }
    
    func testClientSessionOpened() {
        let testDate = Date(eventTimestamp: 12345)
        
        let event = Event.clientSessionOpened(timestamp: testDate)
        
        XCTAssertFalse(event.id.rawValue.isEmpty)
        XCTAssertEqual(event.type, 4)
        XCTAssertEqual(event.timestamp.eventTimestamp, 12345)
        XCTAssertEqual(event.version, 2)
        XCTAssertEqual(event.payload, [:])
        
        let nowTimestamp = Date().eventTimestamp
        XCTAssert(abs(Event.clientSessionOpened().timestamp.eventTimestamp - nowTimestamp) <= 2)
    }
    
    func testSearched() {
        let testDate = Date(eventTimestamp: 12345)
        let query = "Søme Very Long Séarch string 🌈"
        let event = Event.searched(for: query, languageCode: "DA", timestamp: testDate, tokenizer: self.tokenizer.tokenize)
        
        XCTAssertFalse(event.id.rawValue.isEmpty)
        XCTAssertEqual(event.type, 5)
        XCTAssertEqual(event.timestamp.eventTimestamp, 12345)
        XCTAssertEqual(event.version, 2)
        XCTAssertEqual(event.payload,
                       ["sea.q": .string(query),
                        "sea.l": .string("DA"),
                        "vt": .string("erHTNwqSrLY=")])
        
        let nowTimestamp = Date().eventTimestamp
        let defaultEvent = Event.searched(for: "", languageCode: nil)
        XCTAssert(abs(defaultEvent.timestamp.eventTimestamp - nowTimestamp) <= 2)
        XCTAssertEqual(defaultEvent.payload,
                       ["sea.q": .string(""),
                        "vt": .string("2oEIMMzybMM=")])
        
        XCTAssertEqual(Event.searched(for: "my search string", languageCode: "a").payload,
                       ["sea.q": .string("my search string"),
                        "sea.l": .string("a"),
                        "vt": .string("bNOIlf+nAAU=")])
        
        XCTAssertEqual(Event.searched(for: "my search string 😁", languageCode: nil).payload,
                       ["sea.q": .string("my search string 😁"),
                        "vt": .string("+OJqwh68nIk=")])
        
        XCTAssertEqual(Event.searched(for: "øl og æg", languageCode: nil).payload,
                       ["sea.q": .string("øl og æg"),
                        "vt": .string("NTgj68OWnbc=")])
    }
    
    func testOfferOpenedAfterSearch() {
        let testDate = Date(eventTimestamp: 12345)
        let query = "Søme Very Long Séarch string 🌈"
        let event = Event.offerOpenedAfterSearch(offerId: "offer_123", query: query, languageCode: "DA", timestamp: testDate)
        
        XCTAssertFalse(event.id.rawValue.isEmpty)
        XCTAssertEqual(event.type, 7)
        XCTAssertEqual(event.timestamp.eventTimestamp, 12345)
        XCTAssertEqual(event.version, 2)
        XCTAssertEqual(event.payload,
                       ["sea.q": .string(query),
                        "sea.l": .string("DA"),
                        "of.id": .string("offer_123")])
        
        let nowTimestamp = Date().eventTimestamp
        let defaultEvent = Event.offerOpenedAfterSearch(offerId: "abc123", query: "", languageCode: nil)
        XCTAssert(abs(defaultEvent.timestamp.eventTimestamp - nowTimestamp) <= 2)
        XCTAssertEqual(defaultEvent.payload,
                       ["sea.q": .string(""),
                        "of.id": .string("abc123")])
    }
    
    func testFirstOfferOpenedAfterSearch() {
        let testDate = Date(eventTimestamp: 12345)
        let query = "Another Very Long Séarch string 🌈"
        let offerIds = ["b", "a", "c"].map(CoreAPI.Offer.Identifier.init(rawValue:))
        let event = Event.firstOfferOpenedAfterSearch(offerId: "offer_123", precedingOfferIds: offerIds, query: query, languageCode: "DA", timestamp: testDate)
        
        XCTAssertFalse(event.id.rawValue.isEmpty)
        XCTAssertEqual(event.type, 6)
        XCTAssertEqual(event.timestamp.eventTimestamp, 12345)
        XCTAssertEqual(event.version, 2)
        XCTAssertEqual(event.payload,
                       ["sea.q": .string(query),
                        "sea.l": .string("DA"),
                        "of.id": .string("offer_123"),
                        "of.ids": .array([.string("b"), .string("a"), .string("c")])
                        ])
        
        let nowTimestamp = Date().eventTimestamp
        let defaultEvent = Event.firstOfferOpenedAfterSearch(offerId: "abc123", precedingOfferIds: [], query: "", languageCode: nil)
        XCTAssert(abs(defaultEvent.timestamp.eventTimestamp - nowTimestamp) <= 2)
        XCTAssertEqual(defaultEvent.payload,
                       ["sea.q": .string(""),
                        "of.id": .string("abc123"),
                        "of.ids": .array([])
                        ])
        
        let manyOfferIds = Array(50..<250).map({ CoreAPI.Offer.Identifier(rawValue: String($0)) })
        
        let clampedOfferIds = manyOfferIds.prefix(100).map({ JSONValue.string($0.rawValue) })
        
        let bigEvent = Event.firstOfferOpenedAfterSearch(offerId: "abc123", precedingOfferIds: manyOfferIds, query: "", languageCode: nil)
        
        XCTAssertEqual(bigEvent.payload,
                       ["sea.q": .string(""),
                        "of.id": .string("abc123"),
                        "of.ids": .array(clampedOfferIds)
{'fraction_non_alphanumeric': 0.13338811284579566, 'fraction_numerical': 0.0238290879211175, 'mean_word_length': 2.0354718026880976, 'pattern_counts': {'":': 108, '<': 21, '<?xml version=': 0, '>': 3, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6069446', 'n_tokens_mistral': 7092, 'n_tokens_neox': 6547, 'n_words': 1096}