Skip to content

Commit

Permalink
introduce SPConsentables as categories and vendors to SPUSNatConsent
Browse files Browse the repository at this point in the history
  • Loading branch information
andresilveirah committed Feb 29, 2024
1 parent 01bd1a3 commit f771d77
Show file tree
Hide file tree
Showing 10 changed files with 147 additions and 111 deletions.
38 changes: 38 additions & 0 deletions ConsentViewController/Classes/Consents/SPConsentable.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//
// SPConsentable.swift
// Pods
//
// Created by Andre Herculano on 29.02.24.
//

import Foundation

protocol Consentable {
var id: String { get }
var consented: Bool { get }
}

@objcMembers public class SPConsentable: NSObject, Consentable, Codable {
enum CodingKeys: String, CodingKey {
case id = "_id"
case consented
}

public let id: String
public let consented: Bool

override open var description: String {
"SPConsentable(id: \(id), consented: \(consented))"
}

init(id: String, consented: Bool) {
self.id = id
self.consented = consented
}

override public func isEqual(_ object: Any?) -> Bool {
guard let other = object as? SPConsentable else { return false }

return other.id == id && other.consented == consented
}
}
41 changes: 26 additions & 15 deletions ConsentViewController/Classes/Consents/SPUSNatConsent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,19 @@
import Foundation

@objcMembers public class SPUSNatConsent: NSObject, Codable, CampaignConsent, NSCopying {
struct UserConsents: Codable, Equatable {
let vendors, categories: [SPConsentable]
}

public struct ConsentString: Codable, Equatable {
public let sectionId: Int
public let sectionName, consentString: String
}

public var vendors: [SPConsentable] { userConsents.vendors }

public var categories: [SPConsentable] { userConsents.categories }

public var uuid: String?

public var applies: Bool
Expand All @@ -22,8 +30,6 @@ import Foundation
/// A dictionary with all GPP related data
public var GPPData: SPJson?

let categories: [String]

var dateCreated, expirationDate: SPDate

/// Required by SP endpoints
Expand All @@ -34,13 +40,16 @@ import Foundation

var consentStatus: ConsentStatus

var userConsents: UserConsents

override open var description: String {
"""
SPUSNatConsent(
- uuid: \(uuid ?? "")
- applies: \(applies)
- consentStrings: \(consentStrings)
- categories: \(categories)
- vendors: \(vendors)
- dateCreated: \(dateCreated)
- expirationDate: \(expirationDate)
)
Expand All @@ -55,7 +64,8 @@ import Foundation
consentStrings: [ConsentString],
webConsentPayload: SPWebConsentPayload? = nil,
lastMessage: LastMessageData? = nil,
categories: [String],
categories: [SPConsentable],
vendors: [SPConsentable],
consentStatus: ConsentStatus,
GPPData: SPJson? = nil
) {
Expand All @@ -66,9 +76,9 @@ import Foundation
self.consentStrings = consentStrings
self.webConsentPayload = webConsentPayload
self.lastMessage = lastMessage
self.categories = []
self.consentStatus = consentStatus
self.GPPData = GPPData
self.userConsents = UserConsents(vendors: vendors, categories: categories)
}

required public init(from decoder: Decoder) throws {
Expand All @@ -80,9 +90,9 @@ import Foundation
consentStrings = try container.decode([ConsentString].self, forKey: .consentStrings)
webConsentPayload = try container.decodeIfPresent(SPWebConsentPayload.self, forKey: .webConsentPayload)
lastMessage = try container.decodeIfPresent(LastMessageData.self, forKey: .lastMessage)
categories = try container.decode([String].self, forKey: .categories)
consentStatus = try container.decode(ConsentStatus.self, forKey: .consentStatus)
GPPData = try container.decodeIfPresent(SPJson.self, forKey: .GPPData)
userConsents = try container.decodeIfPresent(UserConsents.self, forKey: .userConsents) ?? UserConsents(vendors: [], categories: [])
}

public static func empty() -> SPUSNatConsent { SPUSNatConsent(
Expand All @@ -91,20 +101,20 @@ import Foundation
expirationDate: .distantFuture(),
consentStrings: [],
categories: [],
vendors: [],
consentStatus: ConsentStatus()
)}

override public func isEqual(_ object: Any?) -> Bool {
if let other = object as? SPUSNatConsent {
return other.uuid == uuid &&
other.applies == applies &&
other.consentStrings.count == consentStrings.count &&
other.consentStrings.sorted(by: { $0.sectionId > $1.sectionId }) ==
other.consentStrings.sorted(by: { $0.sectionId > $1.sectionId }) &&
other.categories == categories
} else {
return false
}
guard let other = object as? SPUSNatConsent else { return false }

return other.uuid == uuid &&
other.applies == applies &&
other.consentStrings.count == consentStrings.count &&
other.consentStrings.sorted(by: { $0.sectionId > $1.sectionId }) ==
other.consentStrings.sorted(by: { $0.sectionId > $1.sectionId }) &&
other.categories == categories &&
other.vendors == vendors
}

public func copy(with zone: NSZone? = nil) -> Any { SPUSNatConsent(
Expand All @@ -116,6 +126,7 @@ import Foundation
webConsentPayload: webConsentPayload,
lastMessage: lastMessage,
categories: categories,
vendors: vendors,
consentStatus: consentStatus,
GPPData: GPPData
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,6 @@ struct CCPAChoiceResponse: Equatable {
let GPPData: SPJson
}

struct USNatChoiceResponse: Equatable, Decodable {
let uuid: String
let consentStrings: [SPUSNatConsent.ConsentString]
let categories: [String]
let dateCreated, expirationDate: SPDate
let webConsentPayload: SPWebConsentPayload?
let consentStatus: ConsentStatus
let GPPData: SPJson?
}

extension CCPAChoiceResponse: Decodable {
enum CodingKeys: CodingKey {
case uuid, dateCreated, consentedAll, rejectedAll,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ struct ConsentStatusResponse: Decodable, Equatable {
let consentStrings: [SPUSNatConsent.ConsentString]
let dateCreated, expirationDate: SPDate
let consentStatus: ConsentStatus
let categories: [String]
let webConsentPayload: SPWebConsentPayload?
let GPPData: SPJson?
let userConsents: SPUSNatConsent.UserConsents
}

let gdpr: GDPR?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ extension Consent: Codable {
webConsentPayload: consents.webConsentPayload,
lastMessage: LastMessageData(from: messageMetaData),
categories: consents.categories,
vendors: consents.vendors,
consentStatus: consents.consentStatus,
GPPData: consents.GPPData
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ typealias CCPAPrivacyManagerViewHandler = (Result<CCPAPrivacyManagerViewResponse
typealias MessageHandler = (Result<Message, SPError>) -> Void
typealias CCPAConsentHandler = (Result<CCPAChoiceResponse, SPError>) -> Void
typealias GDPRConsentHandler = (Result<GDPRChoiceResponse, SPError>) -> Void
typealias USNatConsentHandler = (Result<USNatChoiceResponse, SPError>) -> Void
typealias USNatConsentHandler = (Result<SPUSNatConsent, SPError>) -> Void
typealias ConsentHandler<T: Decodable & Equatable> = (Result<(SPJson, T), SPError>) -> Void
typealias AddOrDeleteCustomConsentHandler = (Result<AddOrDeleteCustomConsentResponse, SPError>) -> Void
typealias ConsentStatusHandler = (Result<ConsentStatusResponse, SPError>) -> Void
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,8 @@ class SourcepointClientCoordinator: SPClientCoordinator {
expirationDate: usnat.expirationDate,
consentStrings: usnat.consentStrings,
webConsentPayload: usnat.webConsentPayload,
categories: usnat.categories,
categories: usnat.userConsents.categories,
vendors: usnat.userConsents.vendors,
consentStatus: usnat.consentStatus,
GPPData: usnat.GPPData
)
Expand Down Expand Up @@ -839,7 +840,7 @@ class SourcepointClientCoordinator: SPClientCoordinator {

func postChoice(
_ action: SPAction,
handler: @escaping (Result<USNatChoiceResponse, SPError>) -> Void
handler: @escaping (Result<SPUSNatConsent, SPError>) -> Void
) {
spClient.postUSNatAction(
actionType: action.type,
Expand Down Expand Up @@ -932,7 +933,7 @@ class SourcepointClientCoordinator: SPClientCoordinator {

func handleUSNatPostChoice(
_ action: SPAction,
_ postResponse: USNatChoiceResponse
_ postResponse: SPUSNatConsent
) {
state.usnat = SPUSNatConsent(
uuid: postResponse.uuid,
Expand All @@ -942,6 +943,7 @@ class SourcepointClientCoordinator: SPClientCoordinator {
consentStrings: postResponse.consentStrings,
webConsentPayload: postResponse.webConsentPayload,
categories: postResponse.categories,
vendors: postResponse.vendors,
consentStatus: postResponse.consentStatus,
GPPData: postResponse.GPPData
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,16 +173,7 @@ class SourcePointClientMock: SourcePointProtocol {
if let error = error {
handler(.failure(error))
} else {
handler(.success(USNatChoiceResponse(
uuid: "",
consentStrings: [],
categories: [],
dateCreated: .now(),
expirationDate: .distantFuture(),
webConsentPayload: nil,
consentStatus: .init(),
GPPData: nil
)))
handler(.success(SPUSNatConsent.empty()))
}
}

Expand Down
40 changes: 28 additions & 12 deletions Example/ConsentViewController_ExampleTests/SPUSNatConsentSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class SPUSNatConsentsSpec: QuickSpec {
let consents = SPUSNatConsent.empty()
expect(consents.uuid).to(beNil())
expect(consents.applies).to(beFalse())
expect(consents.dateCreated.date.doubleValue).to(beCloseTo(SPDate(date: Date()).date.doubleValue, within: 0.001))
expect(consents.dateCreated.date.doubleValue).to(beCloseTo(SPDate(date: Date()).date.doubleValue, within: 0.01))
}
}

Expand All @@ -33,7 +33,16 @@ class SPUSNatConsentsSpec: QuickSpec {
"sectionName": "abc",
"consentString": "xyz"
}],
"categories": ["foo"],
"userConsents": {
"categories": [{
"_id": "categoryId",
"consented": false
}],
"vendors": [{
"_id": "vendorId",
"consented": false
}]
},
"consentStatus": {
"granularStatus": {},
"hasConsentData": false
Expand All @@ -44,16 +53,23 @@ class SPUSNatConsentsSpec: QuickSpec {
}
""".data(using: .utf8)
}
let consent = try usnatConsents.decoded() as SPUSNatConsent
expect(consent.applies).to(beTrue())
expect(consent.categories).to(equal(["foo"]))
expect(consent.GPPData).to(equal(try? SPJson(["foo": "bar"])))
expect(consent.consentStrings).to(equal([
.init(sectionId: 99, sectionName: "abc", consentString: "xyz")
]))
expect(consent.dateCreated).to(equal(year: 2023, month: 2, day: 6))
expect(consent.expirationDate).to(equal(year: 2024, month: 2, day: 6))
expect(consent.consentStatus).to(equal(ConsentStatus()))
do {
let consent = try usnatConsents.decoded() as SPUSNatConsent
expect(consent.applies).to(beTrue())
expect(consent.categories)
.to(equal([SPConsentable(id: "categoryId", consented: false)]))
expect(consent.vendors)
.to(equal([SPConsentable(id: "vendorId", consented: false)]))
expect(consent.GPPData).to(equal(try? SPJson(["foo": "bar"])))
expect(consent.consentStrings).to(equal([
.init(sectionId: 99, sectionName: "abc", consentString: "xyz")
]))
expect(consent.dateCreated).to(equal(year: 2023, month: 2, day: 6))
expect(consent.expirationDate).to(equal(year: 2024, month: 2, day: 6))
expect(consent.consentStatus).to(equal(ConsentStatus()))
} catch {
fail(String(describing: error))
}
}
}
}
Loading

0 comments on commit f771d77

Please sign in to comment.