-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from ubuntu/UDENG-5705-Ubuntu-Insights-Consent-…
…Manager feat(internal/consent): UDENG-5705 ubuntu insights consent manager
- Loading branch information
Showing
35 changed files
with
494 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,45 @@ | ||
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= | ||
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= | ||
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= | ||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= | ||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= | ||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= | ||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= | ||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= | ||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= | ||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= | ||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= | ||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= | ||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= | ||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= | ||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= | ||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= | ||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= | ||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= | ||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= | ||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= | ||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= | ||
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= | ||
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= | ||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= | ||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= | ||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= | ||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= | ||
github.com/ubuntu/decorate v0.0.0-20240820145549-b76bb81d1209 h1:paNkjGGwB/Ypory/EPTwVR5uX94TDgrH4PGSaCNAvhE= | ||
github.com/ubuntu/decorate v0.0.0-20240820145549-b76bb81d1209/go.mod h1:PUpwIgUuCQyuCz/gwiq6WYbo7IvtXXd8JqL01ez+jZE= | ||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||
golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= | ||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= | ||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= | ||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= | ||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= | ||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,133 @@ | ||
// Package consent is the implementation of the consent manager component. | ||
// The consent manager is responsible for managing consent files, which are used to store the consent state for a source or the global consent state. | ||
package consent | ||
|
||
import ( | ||
"fmt" | ||
"log/slog" | ||
"os" | ||
"path/filepath" | ||
"strings" | ||
|
||
"github.com/BurntSushi/toml" | ||
"github.com/ubuntu/decorate" | ||
"github.com/ubuntu/ubuntu-insights/internal/constants" | ||
) | ||
|
||
// Manager is a struct that manages consent files. | ||
type Manager struct { | ||
path string | ||
} | ||
|
||
// consentFile is a struct that represents a consent file. | ||
type consentFile struct { | ||
ConsentState bool `toml:"consent_state"` | ||
} | ||
|
||
// New returns a new ConsentManager. | ||
// path is the folder the consents are stored into. | ||
func New(path string) *Manager { | ||
return &Manager{path: path} | ||
} | ||
|
||
// GetConsentState gets the consent state for the given source. | ||
// If the source do not have a consent file, it will be considered as a false state. | ||
// If the source is an empty string, then the global consent state will be returned. | ||
// If the target consent file does not exist, it will not be created. | ||
func (cm Manager) GetConsentState(source string) (bool, error) { | ||
sourceConsent, err := readConsentFile(cm.getConsentFile(source)) | ||
if err != nil { | ||
slog.Error("Error reading source consent file", "source", source, "error", err) | ||
return false, err | ||
} | ||
|
||
return sourceConsent.ConsentState, nil | ||
} | ||
|
||
var consentSourceFilePattern = `%s` + constants.ConsentSourceBaseSeparator + constants.GlobalFileName | ||
|
||
// SetConsentState updates the consent state for the given source. | ||
// If the source is an empty string, then the global consent state will be set. | ||
// If the target consent file does not exist, it will be created. | ||
func (cm Manager) SetConsentState(source string, state bool) (err error) { | ||
defer decorate.OnError(&err, "could not set consent state") | ||
|
||
consent := consentFile{ConsentState: state} | ||
return consent.write(cm.getConsentFile(source)) | ||
} | ||
|
||
// getConsentFile returns the expected path to the consent file for the given source. | ||
// If source is blank, it returns the path to the global consent file. | ||
// It does not check if the file exists, or if it is valid. | ||
func (cm Manager) getConsentFile(source string) string { | ||
p := filepath.Join(cm.path, constants.GlobalFileName) | ||
if source != "" { | ||
p = filepath.Join(cm.path, fmt.Sprintf(consentSourceFilePattern, source)) | ||
} | ||
|
||
return p | ||
} | ||
|
||
// getSourceConsentFiles returns a map of all paths to validly named consent files in the folder, other than the global file. | ||
func (cm Manager) getConsentFiles() (map[string]string, error) { | ||
sourceFiles := make(map[string]string) | ||
|
||
entries, err := os.ReadDir(cm.path) | ||
if err != nil { | ||
return sourceFiles, err | ||
} | ||
|
||
for _, entry := range entries { | ||
if entry.IsDir() { | ||
continue | ||
} | ||
|
||
// Source file | ||
if !strings.HasSuffix(entry.Name(), constants.ConsentSourceBaseSeparator+constants.GlobalFileName) { | ||
continue | ||
} | ||
source := strings.TrimSuffix(entry.Name(), constants.ConsentSourceBaseSeparator+constants.GlobalFileName) | ||
sourceFiles[source] = filepath.Join(cm.path, entry.Name()) | ||
slog.Debug("Found source consent file", "file", sourceFiles[source]) | ||
} | ||
|
||
return sourceFiles, nil | ||
} | ||
|
||
func readConsentFile(path string) (consentFile, error) { | ||
var consent consentFile | ||
_, err := toml.DecodeFile(path, &consent) | ||
slog.Debug("Read consent file", "file", path, "consent", consent.ConsentState) | ||
|
||
return consent, err | ||
} | ||
|
||
// writeConsentFile writes the given consent file to the given path atomically, replacing it if it already exists. | ||
// Not atomic on Windows. | ||
func (cf consentFile) write(path string) (err error) { | ||
tmp, err := os.CreateTemp(filepath.Dir(path), "consent-*.tmp") | ||
if err != nil { | ||
return fmt.Errorf("could not create temporary file: %v", err) | ||
} | ||
defer func() { | ||
_ = tmp.Close() | ||
if err := os.Remove(tmp.Name()); err != nil && !os.IsNotExist(err) { | ||
slog.Warn("Failed to remove temporary file when writing consent file", "file", tmp.Name(), "error", err) | ||
} | ||
}() | ||
|
||
if err := toml.NewEncoder(tmp).Encode(cf); err != nil { | ||
return fmt.Errorf("could not encode consent file: %v", err) | ||
} | ||
|
||
if err := tmp.Close(); err != nil { | ||
return fmt.Errorf("could not close temporary file: %v", err) | ||
} | ||
|
||
if err := os.Rename(tmp.Name(), path); err != nil { | ||
return fmt.Errorf("could not rename temporary file: %v", err) | ||
} | ||
slog.Debug("Wrote consent file", "file", path, "consent", cf.ConsentState) | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
package consent_test | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"path/filepath" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
"github.com/ubuntu/ubuntu-insights/internal/consent" | ||
"github.com/ubuntu/ubuntu-insights/internal/testutils" | ||
) | ||
|
||
func TestGetConsentState(t *testing.T) { | ||
t.Parallel() | ||
|
||
tests := map[string]struct { | ||
source string | ||
globalFile string | ||
|
||
wantErr bool | ||
}{ | ||
"No Global File": {wantErr: true}, | ||
|
||
// Global File Tests | ||
"Valid True Global File": {globalFile: "valid_true-consent.toml"}, | ||
"Valid False Global File": {globalFile: "valid_false-consent.toml"}, | ||
"Invalid Value Global File": {globalFile: "invalid_value-consent.toml", wantErr: true}, | ||
"Invalid File Global File": {globalFile: "invalid_file-consent.toml", wantErr: true}, | ||
|
||
// Source Specific Tests | ||
"Valid True Global File, Valid True Source": {globalFile: "valid_true-consent.toml", source: "valid_true"}, | ||
"Valid True Global File, Valid False Source": {globalFile: "valid_true-consent.toml", source: "valid_false"}, | ||
"Valid True Global File, Invalid Value Source": {globalFile: "valid_true-consent.toml", source: "invalid_value", wantErr: true}, | ||
"Valid True Global File, Invalid File Source": {globalFile: "valid_true-consent.toml", source: "invalid_file", wantErr: true}, | ||
"Valid True Global File, No File Source": {globalFile: "valid_true-consent.toml", source: "not_a_file", wantErr: true}, | ||
|
||
// Invalid Global File, Source Specific Tests | ||
"Invalid Value Global File, Valid True Source": {globalFile: "invalid_value-consent.toml", source: "valid_true"}, | ||
"Invalid Value Global File, Valid False Source": {globalFile: "invalid_value-consent.toml", source: "valid_false"}, | ||
"Invalid Value Global File, Invalid Value Source": {globalFile: "invalid_value-consent.toml", source: "invalid_value", wantErr: true}, | ||
"Invalid Value Global File, Invalid File Source": {globalFile: "invalid_value-consent.toml", source: "invalid_file", wantErr: true}, | ||
"Invalid Value Global File, No File Source": {globalFile: "invalid_value-consent.toml", source: "not_a_file", wantErr: true}, | ||
|
||
// No Global File, Source Specific Tests | ||
"No Global File, Valid True Source": {source: "valid_true"}, | ||
"No Global File, Valid False Source": {source: "valid_false"}, | ||
"No Global File, Invalid Value Source": {source: "invalid_value", wantErr: true}, | ||
"No Global File, Invalid File Source": {source: "invalid_file", wantErr: true}, | ||
"No Global File, No File Source": {source: "not_a_file", wantErr: true}, | ||
} | ||
|
||
for name, tc := range tests { | ||
t.Run(name, func(t *testing.T) { | ||
t.Parallel() | ||
dir, err := setupTmpConsentFiles(t, tc.globalFile) | ||
require.NoError(t, err, "Setup: failed to setup temporary consent files") | ||
defer testutils.CleanupDir(t, dir) | ||
cm := consent.New(dir) | ||
|
||
got, err := cm.GetConsentState(tc.source) | ||
if tc.wantErr { | ||
require.Error(t, err, "expected an error but got none") | ||
return | ||
} | ||
require.NoError(t, err, "got an unexpected error") | ||
|
||
want := testutils.LoadWithUpdateFromGoldenYAML(t, got) | ||
require.Equal(t, want, got, "GetConsentState should return expected consent state") | ||
}) | ||
} | ||
} | ||
|
||
func TestSetConsentStates(t *testing.T) { | ||
t.Parallel() | ||
|
||
tests := map[string]struct { | ||
consentStates map[string]bool | ||
globalFile string | ||
|
||
writeSource string | ||
writeState bool | ||
|
||
wantErr bool | ||
}{ | ||
// New File Tests | ||
"New File, Write Global False": {}, | ||
"New File, Write Global True": {writeState: true}, | ||
"New File, Write Source True": {writeSource: "new_true", writeState: true}, | ||
"New File, Write Source False": {writeSource: "new_false"}, | ||
|
||
// Overwrite File, Different State | ||
"Overwrite File, Write Diff Global False": {globalFile: "valid_true-consent.toml", writeState: false}, | ||
"Overwrite File, Write Diff Global True": {globalFile: "valid_false-consent.toml", writeState: true}, | ||
"Overwrite File, Write Diff Source True": {globalFile: "valid_true-consent.toml", writeSource: "valid_false", writeState: true}, | ||
"Overwrite File, Write Diff Source False": {globalFile: "valid_true-consent.toml", writeSource: "valid_true", writeState: false}, | ||
|
||
// Overwrite File, Same State | ||
"Overwrite File, Write Global True": {globalFile: "valid_true-consent.toml", writeState: true}, | ||
"Overwrite File, Write Global False": {globalFile: "valid_false-consent.toml", writeState: false}, | ||
"Overwrite File, Write Source True": {globalFile: "valid_true-consent.toml", writeSource: "valid_true", writeState: true}, | ||
"Overwrite File, Write Source False": {globalFile: "valid_false-consent.toml", writeSource: "valid_false", writeState: false}, | ||
} | ||
|
||
type goldenFile struct { | ||
States map[string]bool | ||
FileCount int | ||
} | ||
|
||
for name, tc := range tests { | ||
t.Run(name, func(t *testing.T) { | ||
t.Parallel() | ||
dir, err := setupTmpConsentFiles(t, tc.globalFile) | ||
require.NoError(t, err, "Setup: failed to setup temporary consent files") | ||
defer testutils.CleanupDir(t, dir) | ||
cm := consent.New(dir) | ||
|
||
err = cm.SetConsentState(tc.writeSource, tc.writeState) | ||
if tc.wantErr { | ||
require.Error(t, err, "expected an error but got none") | ||
return | ||
} | ||
require.NoError(t, err, "got an unexpected error") | ||
|
||
states, err := cm.GetAllSourceConsentStates(true) | ||
require.NoError(t, err, "got an unexpected error while getting consent states") | ||
|
||
d, err := os.ReadDir(dir) | ||
require.NoError(t, err, "failed to read temporary directory") | ||
got := goldenFile{States: states, FileCount: len(d)} | ||
|
||
want := testutils.LoadWithUpdateFromGoldenYAML(t, got) | ||
require.Equal(t, want, got, "GetConsentStates should return expected consent states") | ||
}) | ||
} | ||
} | ||
|
||
func setupTmpConsentFiles(t *testing.T, globalFile string) (string, error) { | ||
t.Helper() | ||
|
||
// Setup temporary directory | ||
var err error | ||
dir, err := os.MkdirTemp("", "consent-files") | ||
if err != nil { | ||
return dir, fmt.Errorf("failed to create temporary directory: %v", err) | ||
} | ||
|
||
if err = testutils.CopyDir(filepath.Join("testdata", "consent_files"), dir); err != nil { | ||
return dir, fmt.Errorf("failed to copy testdata directory to temporary directory: %v", err) | ||
} | ||
|
||
// Setup globalFile if provided | ||
if globalFile != "" { | ||
if err = testutils.CopyFile(filepath.Join(dir, globalFile), filepath.Join(dir, "consent.toml")); err != nil { | ||
return dir, fmt.Errorf("failed to copy requested global consent file: %v", err) | ||
} | ||
} | ||
|
||
return dir, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package consent | ||
|
||
// GetAllSourceConsentStates gets the consent states for all sources. | ||
// It does not get the global consent state. | ||
// If continueOnErr is true, it will continue to the next source if an error occurs. | ||
func (cm Manager) GetAllSourceConsentStates(continueOnErr bool) (map[string]bool, error) { | ||
p, err := cm.getConsentFiles() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
consentStates := make(map[string]bool) | ||
for source, path := range p { | ||
consent, err := readConsentFile(path) | ||
if err != nil && !continueOnErr { | ||
return nil, err | ||
} | ||
if err != nil { | ||
continue | ||
} | ||
|
||
consentStates[source] = consent.ConsentState | ||
} | ||
|
||
return consentStates, nil | ||
} |
1 change: 1 addition & 0 deletions
1
...consent/testdata/TestGetConsentState/golden/invalid_value_global_file,_valid_false_source
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
false |
1 change: 1 addition & 0 deletions
1
.../consent/testdata/TestGetConsentState/golden/invalid_value_global_file,_valid_true_source
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
true |
1 change: 1 addition & 0 deletions
1
internal/consent/testdata/TestGetConsentState/golden/no_global_file,_valid_false_source
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
false |
1 change: 1 addition & 0 deletions
1
internal/consent/testdata/TestGetConsentState/golden/no_global_file,_valid_true_source
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
true |
Oops, something went wrong.