Skip to content

Commit

Permalink
Allow loading an external JSON in addition to load vendor list from U…
Browse files Browse the repository at this point in the history
…RL. (#4)
  • Loading branch information
gguridi authored May 3, 2024
1 parent ee967b1 commit 6ad5e64
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 9 deletions.
17 changes: 17 additions & 0 deletions cmp/cmp_test.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"lastUpdated": "2024-05-03T00:00:00Z",
"cmps": {
"1": {
"id": 1,
"name": "CMP #1",
"isCommercial": true,
"environments": ["Web"]
},
"2": {
"id": 2,
"name": "CMP #2",
"isCommercial": false,
"environments": ["Smartphone"]
}
}
}
41 changes: 33 additions & 8 deletions cmp/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cmp

import (
"encoding/json"
"io"
"net/http"

"golang.org/x/exp/maps"
Expand All @@ -20,7 +21,8 @@ type Option func(loader *Loader)

// Loader is the type that contains the logic to load and parse a CMP JSON list.
type Loader struct {
URL string
URL string
JSON string
}

// CMP contains the structure of the CMP info that comes inside the JSON
Expand All @@ -38,6 +40,14 @@ func WithURL(url string) Option {
}
}

// WithJSON allows to pass a JSON string loaded externally so our loader
// will parse the cmp-list JSON format for you.
func WithJSON(json string) Option {
return func(cmp *Loader) {
cmp.JSON = json
}
}

// NewLoader returns a CMP vendor list loader instance.
func NewLoader(options ...Option) *Loader {
loader := &Loader{
Expand All @@ -50,26 +60,41 @@ func NewLoader(options ...Option) *Loader {
}

// Unmarshal parses the JSON vendor list into a struct so we can use them.
func (loader *Loader) Unmarshal(response *http.Response) ([]CMP, error) {
func (loader *Loader) Unmarshal(data []byte) ([]CMP, error) {
type Response struct {
CMPS map[string]CMP `json:"cmps"`
}
data := Response{}
if err := json.NewDecoder(response.Body).Decode(&data); err != nil {
response := Response{}
if err := json.Unmarshal(data, &response); err != nil {
return []CMP{}, err
}
return maps.Values(data.CMPS), nil
return maps.Values(response.CMPS), nil
}

// Load is used to load the vendor list into a list of CMP information.
func (loader *Loader) Load() ([]CMP, error) {
// LoadHTTP is used to load the vendor list from a HTTP url.
func (loader *Loader) LoadHTTP() ([]CMP, error) {
response, err := http.Get(loader.URL)
if err == nil {
return loader.Unmarshal(response)
if data, err := io.ReadAll(response.Body); err == nil {
return loader.Unmarshal(data)
}
}
return []CMP{}, err
}

// LoadJSON is used to load the vendor list from a received JSON string.
func (loader *Loader) LoadJSON() ([]CMP, error) {
return loader.Unmarshal([]byte(loader.JSON))
}

// Load decides which CMP list we are going to load.
func (loader *Loader) Load() ([]CMP, error) {
if loader.JSON != "" {
return loader.LoadJSON()
}
return loader.LoadHTTP()
}

// LoadIDs loads the list of vendor CMP ids globally so we can reuse it
// with subsequent calls.
func (loader *Loader) LoadIDs() error {
Expand Down
28 changes: 27 additions & 1 deletion cmp/loader_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package cmp_test

import (
"os"

"github.com/hybridtheory/iab-tcf/cmp"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
Expand All @@ -27,13 +29,37 @@ var _ = Describe("Loader", func() {

BeforeEach(func() {
loader = cmp.NewLoader(cmp.WithURL(testURL))
err = loader.LoadIDs()
})

It("triggers an error because the url is not found", func() {
Expect(err).To(HaveOccurred())
})

It("is used to retrieve the JSON", func() {
_, err = loader.Load()
Expect(err).Should(MatchError(MatchRegexp("lookup unknown-url")))
})
})

Context("with json", func() {
const (
testJSONFile = "cmp_test.json"
)

BeforeEach(func() {
contents, _ := os.ReadFile(testJSONFile)
loader = cmp.NewLoader(cmp.WithJSON(string(contents)))
err = loader.LoadIDs()
})

It("does not trigger an error", func() {
Expect(err).ToNot(HaveOccurred())
})

It("is used to parse the JSON", func() {
Expect(cmp.ValidCMPs).Should(Equal([]int{1, 2}))
})
})
})

Describe("load", func() {
Expand Down

0 comments on commit 6ad5e64

Please sign in to comment.