Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UOE-11757/UOE-11758: Changes for /geo endpoint with updated response #992

Open
wants to merge 6 commits into
base: ci
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions modules/pubmatic/openwrap/cache/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type Cache interface {
GetProfileTypePlatforms() (map[string]int, error)
GetAppIntegrationPaths() (map[string]int, error)
GetAppSubIntegrationPaths() (map[string]int, error)
GetGDPRCountryCodes() (map[string]struct{}, error)

Set(key string, value interface{})
Get(key string) (interface{}, bool)
Expand Down
21 changes: 21 additions & 0 deletions modules/pubmatic/openwrap/cache/gocache/compliance.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package gocache

import (
"fmt"

"github.com/golang/glog"
"github.com/prebid/prebid-server/v2/modules/pubmatic/openwrap/models"
)

var errorGDPRCountryUpdate = "[ErrorGDPRCountryUpdate]:%w"

// We are not saving data in cache here
func (c *cache) GetGDPRCountryCodes() (map[string]struct{}, error) {
gdprCountryCodes, err := c.db.GetGDPRCountryCodes()
if err != nil {
c.metricEngine.RecordDBQueryFailure(models.GDPRCountryCodesQuery, "", "")
glog.Errorf(models.ErrDBQueryFailed, models.GDPRCountryCodesQuery, "", "", err)
return gdprCountryCodes, fmt.Errorf(errorGDPRCountryUpdate, err)
}
return gdprCountryCodes, nil
}
95 changes: 95 additions & 0 deletions modules/pubmatic/openwrap/cache/gocache/compliance_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package gocache

import (
"errors"
"testing"

"github.com/golang/mock/gomock"
gocache "github.com/patrickmn/go-cache"

"github.com/prebid/prebid-server/v2/modules/pubmatic/openwrap/config"
"github.com/prebid/prebid-server/v2/modules/pubmatic/openwrap/database"
mock_database "github.com/prebid/prebid-server/v2/modules/pubmatic/openwrap/database/mock"
"github.com/prebid/prebid-server/v2/modules/pubmatic/openwrap/metrics"
mock_metrics "github.com/prebid/prebid-server/v2/modules/pubmatic/openwrap/metrics/mock"
"github.com/prebid/prebid-server/v2/modules/pubmatic/openwrap/models"
"github.com/stretchr/testify/assert"
)

func TestCache_GetGDPRCountryCodes(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockDatabase := mock_database.NewMockDatabase(ctrl)
mockEngine := mock_metrics.NewMockMetricsEngine(ctrl)
type fields struct {
cache *gocache.Cache
cfg config.Cache
db database.Database
metricEngine metrics.MetricsEngine
}
tests := []struct {
name string
fields fields
want map[string]struct{}
setup func()
wantErr bool
}{
{
name: "Valid Data present in DB, return same",
want: map[string]struct{}{
"US": {},
"LV": {},
"DE": {},
},
setup: func() {
mockDatabase.EXPECT().GetGDPRCountryCodes().Return(map[string]struct{}{
"US": {},
"LV": {},
"DE": {},
}, nil)
},
fields: fields{
cache: gocache.New(100, 100),
db: mockDatabase,
cfg: config.Cache{
CacheDefaultExpiry: 1000,
},
},
wantErr: false,
},
{
name: "Error In DB, Set Empty",
want: nil,
setup: func() {
mockDatabase.EXPECT().GetGDPRCountryCodes().Return(nil, errors.New("QUERY FAILD"))
mockEngine.EXPECT().RecordDBQueryFailure(models.GDPRCountryCodesQuery, "", "").Return()
},
fields: fields{
cache: gocache.New(100, 100),
db: mockDatabase,
cfg: config.Cache{
CacheDefaultExpiry: 1000,
},
metricEngine: mockEngine,
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.setup()
c := &cache{
cache: tt.fields.cache,
cfg: tt.fields.cfg,
db: tt.fields.db,
metricEngine: tt.fields.metricEngine,
}
got, err := c.GetGDPRCountryCodes()
if (err != nil) != tt.wantErr {
t.Errorf("cache.GetGDPRCountryCodes() error = %v, wantErr %v", err, tt.wantErr)
return
}
assert.Equal(t, tt.want, got, tt.name)
})
}
}
15 changes: 15 additions & 0 deletions modules/pubmatic/openwrap/cache/mock/mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions modules/pubmatic/openwrap/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ type Queries struct {
GetProfileTypePlatformMapQuery string
GetAppIntegrationPathMapQuery string
GetAppSubIntegrationPathMapQuery string
GetGDPRCountryCodes string
}

type Cache struct {
Expand Down
1 change: 1 addition & 0 deletions modules/pubmatic/openwrap/database/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ type Database interface {
GetProfileTypePlatforms() (map[string]int, error)
GetAppIntegrationPaths() (map[string]int, error)
GetAppSubIntegrationPaths() (map[string]int, error)
GetGDPRCountryCodes() (map[string]struct{}, error)
}
15 changes: 15 additions & 0 deletions modules/pubmatic/openwrap/database/mock/mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 36 additions & 0 deletions modules/pubmatic/openwrap/database/mysql/compliance.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package mysql

import (
"context"
"time"

"github.com/golang/glog"
)

func (db *mySqlDB) GetGDPRCountryCodes() (map[string]struct{}, error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Millisecond*time.Duration(db.cfg.MaxDbContextTimeout)))
defer cancel()

rows, err := db.conn.QueryContext(ctx, db.cfg.Queries.GetGDPRCountryCodes)
if err != nil {
return nil, err
}
defer rows.Close()

// map to store the country codes
countryCodes := make(map[string]struct{})
for rows.Next() {
var countryCode string
if err := rows.Scan(&countryCode); err != nil {
glog.Error("ErrRowScanFailed GetGDPRCountryCodes Err: ", err.Error())
continue
}
//TO-DO keeping case-sensitive?
countryCodes[countryCode] = struct{}{}
Copy link
Collaborator Author

@pm-saurabh-narkhede pm-saurabh-narkhede Jan 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check with AdServer team about adding entry in table
Discussion to keeping this as only lower or upper case.
Also check whenever gdpr country table is updated we should get notified

}

if err = rows.Err(); err != nil {
return nil, err
}
return countryCodes, nil
}
156 changes: 156 additions & 0 deletions modules/pubmatic/openwrap/database/mysql/compliance_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
package mysql

import (
"database/sql"
"errors"
"regexp"
"testing"

"github.com/DATA-DOG/go-sqlmock"
"github.com/prebid/prebid-server/v2/modules/pubmatic/openwrap/config"
"github.com/stretchr/testify/assert"
)

func Test_mySqlDB_GetGDPRCountryCodes(t *testing.T) {
type fields struct {
cfg config.Database
}
tests := []struct {
name string
fields fields
want map[string]struct{}
wantErr error
setup func() *sql.DB
}{
{
name: "empty query in config file",
fields: fields{
cfg: config.Database{
MaxDbContextTimeout: 100,
},
},
want: nil,
wantErr: errors.New("all expectations were already fulfilled, call to Query '' with args [] was not expected"),
setup: func() *sql.DB {
db, _, err := sqlmock.New()
if err != nil {
t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
}
return db
},
},
{
name: "valid rows returned from DB",
fields: fields{
cfg: config.Database{
MaxDbContextTimeout: 100,
Queries: config.Queries{
GetGDPRCountryCodes: "^SELECT (.+) FROM KomliAdServer.geo (.+)",
},
},
},
want: map[string]struct{}{
"DE": {},
"LV": {},
},
wantErr: nil,
setup: func() *sql.DB {
db, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
}
rows := sqlmock.NewRows([]string{"countrycode"}).
AddRow(`DE`).
AddRow(`LV`)
mock.ExpectQuery(regexp.QuoteMeta("^SELECT (.+) FROM KomliAdServer.geo (.+)")).WillReturnRows(rows)
return db
},
},
{
name: "no rows returned from DB",
fields: fields{
cfg: config.Database{
MaxDbContextTimeout: 100,
Queries: config.Queries{
GetGDPRCountryCodes: "^SELECT (.+) FROM KomliAdServer.geo (.+)",
},
},
},
want: map[string]struct{}{},
wantErr: nil,
setup: func() *sql.DB {
db, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
}
rows := sqlmock.NewRows([]string{"countrycode"})
mock.ExpectQuery(regexp.QuoteMeta("^SELECT (.+) FROM KomliAdServer.geo (.+)")).WillReturnRows(rows)
return db
},
},
{
name: "partial row scan error",
fields: fields{
cfg: config.Database{
MaxDbContextTimeout: 1000000,
Queries: config.Queries{
GetGDPRCountryCodes: "^SELECT (.+) FROM KomliAdServer.geo (.+)",
},
},
},
want: map[string]struct{}{},
wantErr: nil,
setup: func() *sql.DB {
db, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
}
rows := sqlmock.NewRows([]string{"countrycode", "extra_column"}).
AddRow(`DE`, `12`)
rows = rows.RowError(1, errors.New("error in row scan"))
mock.ExpectQuery(regexp.QuoteMeta("^SELECT (.+) FROM KomliAdServer.geo (.+)")).WillReturnRows(rows)
return db
},
},
{
name: "error in row scan",
fields: fields{
cfg: config.Database{
MaxDbContextTimeout: 100,
Queries: config.Queries{
GetGDPRCountryCodes: "^SELECT (.+) FROM KomliAdServer.geo (.+)",
},
},
},
want: nil,
wantErr: errors.New("error in row scan"),
setup: func() *sql.DB {
db, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
}
rows := sqlmock.NewRows([]string{"countrycode"}).
AddRow(`DE`).
AddRow(`LV`)
rows = rows.RowError(1, errors.New("error in row scan"))
mock.ExpectQuery(regexp.QuoteMeta("^SELECT (.+) FROM KomliAdServer.geo (.+)")).WillReturnRows(rows)
return db
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
db := &mySqlDB{
conn: tt.setup(),
cfg: tt.fields.cfg,
}
got, err := db.GetGDPRCountryCodes()
if tt.wantErr == nil {
assert.NoError(t, err, tt.name)
} else {
assert.EqualError(t, err, tt.wantErr.Error(), tt.name)
}
assert.Equal(t, tt.want, got)
})
}
}
Loading
Loading