Skip to content

Commit

Permalink
Add public VendorList interface method to get GVL specification versi…
Browse files Browse the repository at this point in the history
…on (#37)
  • Loading branch information
bsardo authored Jun 16, 2023
1 parent b1cf544 commit 43b9894
Show file tree
Hide file tree
Showing 9 changed files with 101 additions and 53 deletions.
3 changes: 3 additions & 0 deletions api/vendorlist.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import "github.com/prebid/go-gdpr/consentconstants"
// VendorList is an interface used to fetch information about an IAB Global Vendor list.
// For the latest version, see: https://vendorlist.consensu.org/vendorlist.json
type VendorList interface {
// SpecVersion returns the version of the global vendor list specification the list adheres to
SpecVersion() uint16

// Version returns the version of the vendor list which this is.
//
// If the input was malformed, this will return 0.
Expand Down
11 changes: 9 additions & 2 deletions vendorlist/eager-parsing.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ func ParseEagerly(data []byte) (api.VendorList, error) {
}

parsedList := parsedVendorList{
specVersion: contract.GVLSpecificationVersion,
version: contract.Version,
vendors: make(map[uint16]parsedVendor, len(contract.Vendors)),
}
Expand Down Expand Up @@ -61,8 +62,13 @@ func mapify(input []uint8) map[consentconstants.Purpose]struct{} {
}

type parsedVendorList struct {
version uint16
vendors map[uint16]parsedVendor
specVersion uint16
version uint16
vendors map[uint16]parsedVendor
}

func (l parsedVendorList) SpecVersion() uint16 {
return l.specVersion
}

func (l parsedVendorList) Version() uint16 {
Expand Down Expand Up @@ -117,6 +123,7 @@ func (l parsedVendor) SpecialFeature(featureID consentconstants.SpecialFeature)
}

type vendorListContract struct {
GVLSpecificationVersion uint16 `json:"gvlSpecificationVersion"`
Version uint16 `json:"vendorListVersion"`
Vendors []vendorListVendorContract `json:"vendors"`
}
Expand Down
7 changes: 7 additions & 0 deletions vendorlist/lazy-parsing.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ func ParseLazily(data []byte) api.VendorList {

type lazyVendorList []byte

func (l lazyVendorList) SpecVersion() uint16 {
if val, ok := lazyParseInt(l, "gvlSpecificationVersion"); ok {
return uint16(val)
}
return 0
}

func (l lazyVendorList) Version() uint16 {
if val, ok := lazyParseInt(l, "vendorListVersion"); ok {
return uint16(val)
Expand Down
1 change: 1 addition & 0 deletions vendorlist/shared_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ func vendorListTester(parser func(data []byte) api.VendorList) func(*testing.T)
return func(t *testing.T) {
list := parser([]byte(testData))
assertIntsEqual(t, 5, int(list.Version()))
assertIntsEqual(t, 0, int(list.SpecVersion()))
assertNil(t, list.Vendor(2), true)
assertNil(t, list.Vendor(32), false)
}
Expand Down
23 changes: 15 additions & 8 deletions vendorlist2/eager-parsing.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import (
// The returned object can be shared safely between goroutines.
//
// This is ideal if:
// 1. You plan to call functions on the returned VendorList many times before discarding it.
// 2. You need strong input validation and good error messages.
// 1. You plan to call functions on the returned VendorList many times before discarding it.
// 2. You need strong input validation and good error messages.
//
// Otherwise, you may get better performance with ParseLazily.
func ParseEagerly(data []byte) (api.VendorList, error) {
Expand All @@ -27,8 +27,9 @@ func ParseEagerly(data []byte) (api.VendorList, error) {
}

parsedList := parsedVendorList{
version: contract.Version,
vendors: make(map[uint16]parsedVendor, len(contract.Vendors)),
specVersion: contract.GVLSpecificationVersion,
version: contract.Version,
vendors: make(map[uint16]parsedVendor, len(contract.Vendors)),
}

for _, v := range contract.Vendors {
Expand Down Expand Up @@ -69,8 +70,13 @@ func mapifySpecialFeature(input []uint8) map[consentconstants.SpecialFeature]str
}

type parsedVendorList struct {
version uint16
vendors map[uint16]parsedVendor
specVersion uint16
version uint16
vendors map[uint16]parsedVendor
}

func (l parsedVendorList) SpecVersion() uint16 {
return l.specVersion
}

func (l parsedVendorList) Version() uint16 {
Expand Down Expand Up @@ -138,8 +144,9 @@ func (l parsedVendor) SpecialFeature(featureID consentconstants.SpecialFeature)
}

type vendorListContract struct {
Version uint16 `json:"vendorListVersion"`
Vendors map[string]vendorListVendorContract `json:"vendors"`
GVLSpecificationVersion uint16 `json:"gvlSpecificationVersion"`
Version uint16 `json:"vendorListVersion"`
Vendors map[string]vendorListVendorContract `json:"vendors"`
}

type vendorListVendorContract struct {
Expand Down
48 changes: 28 additions & 20 deletions vendorlist2/eager-parsing_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,31 @@ import (
)

func TestParseEagerlyVendorList(t *testing.T) {
tests := []struct{
name string
vendorList string
vendorListVersion uint16
tests := []struct {
name string
vendorList string
vendorListSpecVersion uint16
vendorListVersion uint16
}{
{
name: "vendor list spec 2",
vendorList: testDataSpecVersion2,
vendorListVersion: 28,
name: "vendor_list_spec_2",
vendorList: testDataSpecVersion2,
vendorListSpecVersion: 2,
vendorListVersion: 28,
},
{
name: "vendor list spec 3",
vendorList: testDataSpecVersion3,
vendorListVersion: 1,
name: "vendor_list_spec_3",
vendorList: testDataSpecVersion3,
vendorListSpecVersion: 3,
vendorListVersion: 1,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
parsedGVL, err := ParseEagerly([]byte(tt.vendorList))
assert.NoError(t, err)
assert.Equal(t, tt.vendorListSpecVersion, parsedGVL.SpecVersion())
assert.Equal(t, tt.vendorListVersion, parsedGVL.Version())
assert.NotNil(t, parsedGVL.Vendor(8))
assert.NotNil(t, parsedGVL.Vendor(80))
Expand All @@ -37,27 +41,31 @@ func TestParseEagerlyVendorList(t *testing.T) {
}

func TestParseEagerlyEmptyVendorList(t *testing.T) {
tests := []struct{
name string
vendorList string
vendorListVersion uint16
tests := []struct {
name string
vendorList string
vendorListSpecVersion uint16
vendorListVersion uint16
}{
{
name: "vendor list spec 2",
vendorList: testDataSpecVersion2Empty,
vendorListVersion: 28,
name: "vendor_list_spec_2",
vendorList: testDataSpecVersion2Empty,
vendorListSpecVersion: 2,
vendorListVersion: 28,
},
{
name: "vendor list spec 3",
vendorList: testDataSpecVersion3Empty,
vendorListVersion: 1,
name: "vendor_list_spec_3",
vendorList: testDataSpecVersion3Empty,
vendorListSpecVersion: 3,
vendorListVersion: 1,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
parsedGVL, err := ParseEagerly([]byte(tt.vendorList))
assert.NoError(t, err)
assert.Equal(t, tt.vendorListSpecVersion, parsedGVL.SpecVersion())
assert.Equal(t, tt.vendorListVersion, parsedGVL.Version())
assert.Nil(t, parsedGVL.Vendor(8))
assert.Nil(t, parsedGVL.Vendor(80))
Expand Down
11 changes: 9 additions & 2 deletions vendorlist2/lazy-parsing.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import (
// The returned object can be shared safely between goroutines.
//
// This is ideal if:
// 1. You only need to look up a few vendors or purpose IDs
// 2. You don't need good errors on malformed input
// 1. You only need to look up a few vendors or purpose IDs
// 2. You don't need good errors on malformed input
//
// Otherwise, you may get better performance with ParseEagerly.
func ParseLazily(data []byte) api.VendorList {
Expand All @@ -22,6 +22,13 @@ func ParseLazily(data []byte) api.VendorList {

type lazyVendorList []byte

func (l lazyVendorList) SpecVersion() uint16 {
if val, ok := lazyParseInt(l, "gvlSpecificationVersion"); ok {
return uint16(val)
}
return 0
}

func (l lazyVendorList) Version() uint16 {
if val, ok := lazyParseInt(l, "vendorListVersion"); ok {
return uint16(val)
Expand Down
48 changes: 28 additions & 20 deletions vendorlist2/lazy-parsing_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,30 @@ import (
)

func TestParseLazilyVendorList(t *testing.T) {
tests := []struct{
name string
vendorList string
vendorListVersion uint16
tests := []struct {
name string
vendorList string
vendorListSpecVersion uint16
vendorListVersion uint16
}{
{
name: "vendor list spec 2",
vendorList: testDataSpecVersion2,
vendorListVersion: 28,
name: "vendor_list_spec_2",
vendorList: testDataSpecVersion2,
vendorListSpecVersion: 2,
vendorListVersion: 28,
},
{
name: "vendor list spec 3",
vendorList: testDataSpecVersion3,
vendorListVersion: 1,
name: "vendor_list_spec_3",
vendorList: testDataSpecVersion3,
vendorListSpecVersion: 3,
vendorListVersion: 1,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
parsedGVL := ParseLazily([]byte(tt.vendorList))
assert.Equal(t, tt.vendorListSpecVersion, parsedGVL.SpecVersion())
assert.Equal(t, tt.vendorListVersion, parsedGVL.Version())
assert.NotNil(t, parsedGVL.Vendor(8))
assert.NotNil(t, parsedGVL.Vendor(80))
Expand All @@ -36,26 +40,30 @@ func TestParseLazilyVendorList(t *testing.T) {
}

func TestParseLazilyEmptyVendorList(t *testing.T) {
tests := []struct{
name string
vendorList string
vendorListVersion uint16
tests := []struct {
name string
vendorList string
vendorListSpecVersion uint16
vendorListVersion uint16
}{
{
name: "vendor list spec 2",
vendorList: testDataSpecVersion2Empty,
vendorListVersion: 28,
name: "vendor_list_spec_2",
vendorList: testDataSpecVersion2Empty,
vendorListSpecVersion: 2,
vendorListVersion: 28,
},
{
name: "vendor list spec 3",
vendorList: testDataSpecVersion3Empty,
vendorListVersion: 1,
name: "vendor_list_spec_3",
vendorList: testDataSpecVersion3Empty,
vendorListSpecVersion: 3,
vendorListVersion: 1,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
parsedGVL := ParseLazily([]byte(tt.vendorList))
assert.Equal(t, tt.vendorListSpecVersion, parsedGVL.SpecVersion())
assert.Equal(t, tt.vendorListVersion, parsedGVL.Version())
assert.Nil(t, parsedGVL.Vendor(8))
assert.Nil(t, parsedGVL.Vendor(80))
Expand Down
2 changes: 1 addition & 1 deletion vendorlist2/shared_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func AssertVendorListCorrectness(t *testing.T, gvl api.VendorList) {
assertBoolsEqual(t, false, v.SpecialPurpose(1))
assertBoolsEqual(t, false, v.SpecialPurpose(2))
assertBoolsEqual(t, false, v.SpecialPurpose(3)) // Does not exist yet

assertBoolsEqual(t, false, v.SpecialFeature(1))
assertBoolsEqual(t, false, v.SpecialFeature(2))
assertBoolsEqual(t, false, v.SpecialFeature(3)) // Does not exist yet
Expand Down

0 comments on commit 43b9894

Please sign in to comment.