Repository: owncloud/ocis
Pull request #9029 (2024-04-30 14:34:39)

test: unit test BindSourcesToStructs
## Description
Just some tests .....

## Related Issue
<!--- This project only accepts pull requests related to open issues -->
<!--- If suggesting a new feature or change, please discuss it in an issue first -->
<!--- If fixing a bug, there should be an issue describing it with steps to reproduce -->
<!--- Please link to the issue here: -->
- Fixes <issue_link>

## Motivation and Context
<!--- Why is this change required? What problem does it solve? -->

## How Has This Been Tested?
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran to -->
<!--- see how your change affects other areas of the code, etc. -->
- test environment:
- test case 1:
- test case 2:
- ...

## Screenshots (if appropriate):

## Types of changes
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
- [ ] Technical debt
- [x] Tests only (no source changes)

## Checklist:
<!-- Tick the checkboxes when done. -->
<!-- Raise documentation ticket in owncloud.github.io/ -->
- [ ] Code changes
- [x] Unit tests added
- [ ] Acceptance tests added
- [ ] Documentation ticket raised: <link> 


update-docs[bot]: Thanks for opening this pull request! The maintainers of this repository would appreciate it if you would create a [changelog](https://github.com/owncloud/ocis/blob/master/changelog/README.md) item based on your changes.

sonarcloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=owncloud_ocis&pullRequest=9029) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 New issues](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=9029&resolved=false&inNewCodePeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=9029&metric=new_accepted_issues&view=list)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=owncloud_ocis&pullRequest=9029&resolved=false&inNewCodePeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [60.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=9029&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=9029&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarCloud](https://sonarcloud.io/dashboard?id=owncloud_ocis&pullRequest=9029)



Patch:
diff --git a/ocis-pkg/config/helpers.go b/ocis-pkg/config/helpers.go
index a7042dccb52..d2f867ef62d 100644
--- a/ocis-pkg/config/helpers.go
+++ b/ocis-pkg/config/helpers.go
@@ -1,16 +1,17 @@
 package config
 
 import (
-	"path"
-
 	gofig "github.com/gookit/config/v2"
 	gooyaml "github.com/gookit/config/v2/yaml"
-
 	"github.com/owncloud/ocis/v2/ocis-pkg/config/defaults"
+	"io/fs"
+	"os"
+	"path"
+	"strings"
 )
 
 var (
-	// decoderConfigTagname sets the tag name to be used from the config structs
+	// decoderConfigTagName sets the tag name to be used from the config structs
 	// currently we only support "yaml" because we only support config loading
 	// from yaml files and the yaml parser has no simple way to set a custom tag name to use
 	decoderConfigTagName = "yaml"
@@ -19,6 +20,12 @@ var (
 // BindSourcesToStructs assigns any config value from a config file / env variable to struct `dst`. Its only purpose
 // is to solely modify `dst`, not dealing with the config structs; and do so in a thread safe manner.
 func BindSourcesToStructs(service string, dst interface{}) (*gofig.Config, error) {
+	fileSystem := os.DirFS("/")
+	filePath := strings.TrimLeft(path.Join(defaults.BaseConfigPath(), service+".yaml"), "/")
+	return bindSourcesToStructs(fileSystem, filePath, service, dst)
+}
+
+func bindSourcesToStructs(fileSystem fs.FS, filePath, service string, dst interface{}) (*gofig.Config, error) {
 	cnf := gofig.NewWithOptions(service)
 	cnf.WithOptions(func(options *gofig.Options) {
 		options.ParseEnv = true
@@ -26,9 +33,17 @@ func BindSourcesToStructs(service string, dst interface{}) (*gofig.Config, error
 	})
 	cnf.AddDriver(gooyaml.Driver)
 
-	_ = cnf.LoadFiles(path.Join(defaults.BaseConfigPath(), service+".yaml"))
+	yamlContent, err := fs.ReadFile(fileSystem, filePath)
+	if err != nil {
+		if os.IsNotExist(err) {
+			return cnf, nil
+		}
+
+		return nil, err
+	}
+	_ = cnf.LoadSources("yaml", yamlContent)
 
-	err := cnf.BindStruct("", &dst)
+	err = cnf.BindStruct("", &dst)
 	if err != nil {
 		return nil, err
 	}


Test patch:
diff --git a/ocis-pkg/config/helpers_test.go b/ocis-pkg/config/helpers_test.go
new file mode 100644
index 00000000000..447cdda4582
--- /dev/null
+++ b/ocis-pkg/config/helpers_test.go
@@ -0,0 +1,188 @@
+package config
+
+import (
+	"gotest.tools/v3/assert"
+	"testing"
+	"testing/fstest"
+)
+
+type TestConfig struct {
+	A string `yaml:"a"`
+	B string `yaml:"b"`
+	C string `yaml:"c"`
+}
+
+func TestBindSourcesToStructs(t *testing.T) {
+	// setup test env
+	yaml := `
+a: "${FOO_VAR|no-foo}"
+b: "${BAR_VAR|no-bar}"
+c: "${CODE_VAR|code}"
+`
+	filePath := "etc/ocis/foo.yaml"
+	fs := fstest.MapFS{
+		filePath: {Data: []byte(yaml)},
+	}
+	// perform test
+	c := TestConfig{}
+	_, err := bindSourcesToStructs(fs, filePath, "foo", &c)
+	if err != nil {
+		t.Error(err)
+	}
+
+	assert.Equal(t, c.A, "no-foo")
+	assert.Equal(t, c.B, "no-bar")
+	assert.Equal(t, c.C, "code")
+}
+
+func TestBindSourcesToStructs_UnknownFile(t *testing.T) {
+	// setup test env
+	filePath := "etc/ocis/foo.yaml"
+	fs := fstest.MapFS{}
+	// perform test
+	c := TestConfig{}
+	_, err := bindSourcesToStructs(fs, filePath, "foo", &c)
+	if err != nil {
+		t.Error(err)
+	}
+
+	assert.Equal(t, c.A, "")
+	assert.Equal(t, c.B, "")
+	assert.Equal(t, c.C, "")
+}
+
+func TestBindSourcesToStructs_NoEnvVar(t *testing.T) {
+	// setup test env
+	yaml := `
+token_manager:
+  jwt_secret: f%LovwC6xnKkHhc.!.Lp4ZYpQDIO7=d@
+machine_auth_api_key: jG&%ZCmCSYqT#Yi$9y28o5u84ZMo2UBf
+system_user_api_key: wqxH7FZHv5gifuLIzxqdyaZOCo2s^yl1
+transfer_secret: $1^2xspR1WHussV16knaJ$x@X*XLPL%y
+system_user_id: 4d0bf32c-83ee-4703-bd43-5e0d6b78215b
+admin_user_id: e2fca2b3-992b-47d5-8ecd-3312418ed3d7
+graph:
+  application:
+    id: 4fdff90c-d13c-47ab-8227-bbd3e6dbee3c
+  events:
+    tls_insecure: true
+  spaces:
+    insecure: true
+  identity:
+    ldap:
+      bind_password: $ZZ8fSJR&YA02jBBPx6IRCzW0kVZ#cBO
+  service_account:
+    service_account_id: c05389b2-d94c-4d01-a9b5-a2f97952cc14
+    service_account_secret: GW5.x1vDM&+NPRi++eV@.P7Tms4vj!=s
+idp:
+  ldap:
+    bind_password: kWJGC6WRY1wQ+e8Bmt--=-3r6gp0CNVS
+idm:
+  service_user_passwords:
+    admin_password: admin
+    idm_password: $ZZ8fSJR&YA02jBBPx6IRCzW0kVZ#cBO
+    reva_password: c68JL=V$c@0GHs!%eSb8r&Ps3rgzKnXJ
+    idp_password: kWJGC6WRY1wQ+e8Bmt--=-3r6gp0CNVS
+proxy:
+  oidc:
+    insecure: true
+  insecure_backends: true
+  service_account:
+    service_account_id: c05389b2-d94c-4d01-a9b5-a2f97952cc14
+    service_account_secret: GW5.x1vDM&+NPRi++eV@.P7Tms4vj!=s
+frontend:
+  app_handler:
+    insecure: true
+  archiver:
+    insecure: true
+  service_account:
+    service_account_id: c05389b2-d94c-4d01-a9b5-a2f97952cc14
+    service_account_secret: GW5.x1vDM&+NPRi++eV@.P7Tms4vj!=s
+auth_basic:
+  auth_providers:
+    ldap:
+      bind_password: c68JL=V$c@0GHs!%eSb8r&Ps3rgzKnXJ
+auth_bearer:
+  auth_providers:
+    oidc:
+      insecure: true
+users:
+  drivers:
+    ldap:
+      bind_password: c68JL=V$c@0GHs!%eSb8r&Ps3rgzKnXJ
+groups:
+  drivers:
+    ldap:
+      bind_password: c68JL=V$c@0GHs!%eSb8r&Ps3rgzKnXJ
+ocdav:
+  insecure: true
+ocm:
+  service_account:
+    service_account_id: c05389b2-d94c-4d01-a9b5-a2f97952cc14
+    service_account_secret: GW5.x1vDM&+NPRi++eV@.P7Tms4vj!=s
+thumbnails:
+  thumbnail:
+    transfer_secret: 0N05@YXB.h3e@lsVfksL4YxwQC9aE5A.
+    webdav_allow_insecure: true
+    cs3_allow_insecure: true
+search:
+  events:
+    tls_insecure: true
+  service_account:
+    service_account_id: c05389b2-d94c-4d01-a9b5-a2f97952cc14
+    service_account_secret: GW5.x1vDM&+NPRi++eV@.P7Tms4vj!=s
+audit:
+  events:
+    tls_insecure: true
+settings:
+  service_account_ids:
+  - c05389b2-d94c-4d01-a9b5-a2f97952cc14
+sharing:
+  events:
+    tls_insecure: true
+storage_users:
+  events:
+    tls_insecure: true
+  mount_id: 64fdfb03-22ff-4788-be4d-d7731a475683
+  service_account:
+    service_account_id: c05389b2-d94c-4d01-a9b5-a2f97952cc14
+    service_account_secret: GW5.x1vDM&+NPRi++eV@.P7Tms4vj!=s
+notifications:
+  notifications:
+    events:
+      tls_insecure: true
+  service_account:
+    service_account_id: c05389b2-d94c-4d01-a9b5-a2f97952cc14
+    service_account_secret: GW5.x1vDM&+NPRi++eV@.P7Tms4vj!=s
+nats:
+  nats:
+    tls_skip_verify_client_cert: true
+gateway:
+  storage_registry:
+    storage_users_mount_id: 64fdfb03-22ff-4788-be4d-d7731a475683
+userlog:
+  service_account:
+    service_account_id: c05389b2-d94c-4d01-a9b5-a2f97952cc14
+    service_account_secret: GW5.x1vDM&+NPRi++eV@.P7Tms4vj!=s
+auth_service:
+  service_account:
+    service_account_id: c05389b2-d94c-4d01-a9b5-a2f97952cc14
+    service_account_secret: GW5.x1vDM&+NPRi++eV@.P7Tms4vj!=s
+clientlog:
+  service_account:
+    service_account_id: c05389b2-d94c-4d01-a9b5-a2f97952cc14
+    service_account_secret: GW5.x1vDM&+NPRi++eV@.P7Tms4vj!=s
+`
+	filePath := "etc/ocis/foo.yaml"
+	fs := fstest.MapFS{
+		filePath: {Data: []byte(yaml)},
+	}
+	// perform test
+	c := Config{}
+	_, err := bindSourcesToStructs(fs, filePath, "foo", &c)
+	if err != nil {
+		t.Error(err)
+	}
+
+	assert.Equal(t, c.Graph.Identity.LDAP.BindPassword, "$ZZ8fSJR&YA02jBBPx6IRCzW0kVZ#cBO")
+}