template / files / internal / core / config_test.go
config_test.go
| 1 | package core |
| 2 | |
| 3 | import ( |
| 4 | "errors" |
| 5 | "os" |
| 6 | "path/filepath" |
| 7 | "testing" |
| 8 | |
| 9 | "github.com/stretchr/testify/assert" |
| 10 | ) |
| 11 | |
| 12 | // Compares YAML representation of two objects |
| 13 | func compareObjectYaml(t *testing.T, expected, actual interface{}) { |
| 14 | expectedYaml, err := getYaml(expected) |
| 15 | assert.Nil(t, err, "Error marshalling expected") |
| 16 | actualYaml, err := getYaml(actual) |
| 17 | assert.Nil(t, err, "Error marshalling actual") |
| 18 | assert.Equal(t, len(expectedYaml), len(actualYaml), "Expected YAML and actual YAML are different lengths") |
| 19 | //assert.Equal(t, expectedYaml, actualYaml) |
| 20 | } |
| 21 | |
| 22 | func TestSaveLoadConfig(t *testing.T) { |
| 23 | const configPath string = "./test/test-config.yaml" |
| 24 | configDir := filepath.Dir(configPath) |
| 25 | err := os.Mkdir(configDir, 0755) |
| 26 | if err != nil && !errors.Is(err, os.ErrExist) { |
| 27 | assert.Nil(t, err, "Error creating config directory") |
| 28 | } |
| 29 | defer func() { _ = os.Remove(configDir) }() |
| 30 | |
| 31 | config := defaultConfig() |
| 32 | |
| 33 | // save config |
| 34 | err = saveConfig(configPath, config) |
| 35 | assert.Nil(t, err, "Error saving config") |
| 36 | |
| 37 | // load config |
| 38 | loadedConfig, err := loadConfig(configPath) |
| 39 | assert.Nil(t, err, "Error loading config") |
| 40 | |
| 41 | // test config |
| 42 | compareObjectYaml(t, loadedConfig, config) |
| 43 | |
| 44 | // test load non-existent config |
| 45 | _, err = loadConfig("./test/non-existent-file.yaml") |
| 46 | assert.NotNil(t, err, "Expected to fail to load config, but succeeded") |
| 47 | |
| 48 | // test load invalid yaml |
| 49 | err = os.WriteFile("./invalid-yaml.yaml", []byte("invalid yaml"), 0644) |
| 50 | assert.Nil(t, err, "Error writing invalid yaml file") |
| 51 | _, err = loadConfig("./invalid-yaml.yaml") |
| 52 | assert.NotNil(t, err, "Expected to fail to parse config, but succeeded") |
| 53 | err = os.Remove("./invalid-yaml.yaml") |
| 54 | assert.Nil(t, err, "Error removing invalid yaml file") |
| 55 | |
| 56 | // test saving config to invalid path |
| 57 | err = saveConfig("invalid/path/invalid-config.yaml", config) |
| 58 | assert.NotNil(t, err, "Expected to fail to save config, but succeeded") |
| 59 | |
| 60 | // remove config |
| 61 | err = os.Remove(configPath) |
| 62 | assert.Nil(t, err, "Error removing config file") |
| 63 | |
| 64 | // test default config creation |
| 65 | _, err = os.Stat(configPath) |
| 66 | assert.True(t, errors.Is(err, os.ErrNotExist), "Expected config file to not exist, but it does") |
| 67 | |
| 68 | // fail to get config |
| 69 | _, err = loadConfig(configPath) |
| 70 | assert.NotNil(t, err, "Expected to fail to load config, but succeeded") |
| 71 | |
| 72 | // create default config |
| 73 | err = saveConfig(configPath, defaultConfig()) |
| 74 | assert.Nil(t, err, "Error saving config") |
| 75 | |
| 76 | // test config |
| 77 | compareObjectYaml(t, loadedConfig, config) |
| 78 | |
| 79 | // verify config file exists |
| 80 | stat1, err := os.Stat(configPath) |
| 81 | assert.Nil(t, err, "Expected config file to exist, but it does not") |
| 82 | |
| 83 | // get and create config |
| 84 | loadedConfig, err = loadConfig(configPath) |
| 85 | assert.Nil(t, err, "Error loading config") |
| 86 | |
| 87 | // test config |
| 88 | compareObjectYaml(t, loadedConfig, config) |
| 89 | |
| 90 | // verify config file wasn't updated |
| 91 | stat2, err := os.Stat(configPath) |
| 92 | assert.Nil(t, err, "Expected config file to exist, but it does not") |
| 93 | assert.Equal(t, stat1.ModTime(), stat2.ModTime(), "Expected config file to not be modified, but it was") |
| 94 | } |
| 95 | |
| 96 | func TestValidateDefaultConfig(t *testing.T) { |
| 97 | config := defaultConfig() |
| 98 | err := validateConfig(&config) |
| 99 | if err != nil { |
| 100 | t.Errorf("Expected to validate config, but failed: %v", err) |
| 101 | } |
| 102 | } |
| 103 | |
| 104 | func TestValidateConfig(t *testing.T) { |
| 105 | testFailure := func(config Config, errorText string) { |
| 106 | err := validateConfig(&config) |
| 107 | if err == nil { |
| 108 | t.Errorf("Expected to fail to validate config, but succeeded") |
| 109 | } |
| 110 | assert.Contains(t, err.Error(), errorText) |
| 111 | } |
| 112 | |
| 113 | testFailure(Config{}, "no profiles found") |
| 114 | testFailure(Config{Profiles: []Profile{}}, "no profiles found") |
| 115 | testFailure(Config{Profiles: []Profile{ |
| 116 | { |
| 117 | Name: "daily", |
| 118 | IsDefault: true, |
| 119 | NamePatterns: []ParameterizedText{"daily"}, |
| 120 | FileTemplate: "foo", |
| 121 | }, |
| 122 | }}, "error validating profile") |
| 123 | testFailure(Config{Profiles: []Profile{ |
| 124 | { |
| 125 | Name: "daily", |
| 126 | IsDefault: true, |
| 127 | NamePatterns: []ParameterizedText{"daily"}, |
| 128 | Type: FileType, |
| 129 | TargetDirectory: "foo", |
| 130 | FileTemplate: "foo", |
| 131 | }, |
| 132 | { |
| 133 | Name: "daily2", |
| 134 | IsDefault: true, |
| 135 | NamePatterns: []ParameterizedText{"daily"}, |
| 136 | Type: FileType, |
| 137 | TargetDirectory: "foo", |
| 138 | FileTemplate: "foo", |
| 139 | }, |
| 140 | }}, "multiple default profiles found") |
| 141 | testFailure(Config{Profiles: []Profile{ |
| 142 | { |
| 143 | Name: "daily", |
| 144 | IsDefault: true, |
| 145 | NamePatterns: []ParameterizedText{"daily"}, |
| 146 | Type: FileType, |
| 147 | TargetDirectory: "foo", |
| 148 | FileTemplate: "foo", |
| 149 | }, |
| 150 | { |
| 151 | Name: "daily", |
| 152 | IsDefault: true, |
| 153 | NamePatterns: []ParameterizedText{"daily"}, |
| 154 | Type: FileType, |
| 155 | TargetDirectory: "foo", |
| 156 | FileTemplate: "foo", |
| 157 | }, |
| 158 | }}, "duplicate profile name 'daily'") |
| 159 | } |
| 160 | |
| 161 | func TestLoadConfig(t *testing.T) { |
| 162 | bytes := []byte(` |
| 163 | profiles: |
| 164 | - name: |
| 165 | `) |
| 166 | err := os.WriteFile("./invalid-config.yaml", bytes, 0644) |
| 167 | assert.Nil(t, err, "Error writing invalid config file") |
| 168 | defer func() { _ = os.Remove("./invalid-config.yaml") }() |
| 169 | |
| 170 | // load config |
| 171 | _, err = loadConfig("./invalid-config.yaml") |
| 172 | assert.NotNil(t, err, "Expected to fail to load config, but succeeded") |
| 173 | assert.Contains(t, err.Error(), "error validating profile : profile name is required") |
| 174 | } |
| 175 | |
| 176 | func TestSaveConfig(t *testing.T) { |
| 177 | config := Config{Profiles: []Profile{}} |
| 178 | err := saveConfig("./invalid-config.yaml", config) |
| 179 | assert.NotNil(t, err, "Expected to fail to save config, but succeeded") |
| 180 | assert.Contains(t, err.Error(), "no profiles found") |
| 181 | } |
| 182 | |
| 183 | func TestMergeConfigs(t *testing.T) { |
| 184 | defaultConfig := defaultConfig() |
| 185 | testSuccess := func(config1 Config, config2 Config) Config { |
| 186 | config, err := mergeConfigs(config1, config2) |
| 187 | // compareObjectYaml(t, mergedConfig, expected) |
| 188 | assert.Nil(t, err, "Expected to merge configs, but failed") |
| 189 | return config |
| 190 | } |
| 191 | testFailure := func(config1 Config, config2 Config, errorText string) { |
| 192 | _, err := mergeConfigs(config1, config2) |
| 193 | assert.NotNil(t, err, "Expected to fail to merge configs, but succeeded") |
| 194 | assert.Contains(t, err.Error(), errorText) |
| 195 | } |
| 196 | testFailure(Config{}, Config{}, "no profiles found") |
| 197 | testFailure(Config{Profiles: []Profile{{}}}, Config{}, "error validating config a: error validating profile : profile name is required") |
| 198 | testFailure(Config{Profiles: []Profile{defaultConfig.Profiles[0]}}, Config{}, "error validating config b: no profiles found") |
| 199 | |
| 200 | profile1 := defaultConfig.Profiles[0] |
| 201 | profile2 := defaultConfig.Profiles[1] |
| 202 | testSuccess(Config{Profiles: []Profile{profile1}}, Config{Profiles: []Profile{profile2}}) |
| 203 | |
| 204 | profile1_updated := profile1 |
| 205 | profile1_updated.Description += " This profile has been updated!" |
| 206 | |
| 207 | result := testSuccess(Config{Profiles: []Profile{profile1}}, Config{Profiles: []Profile{profile1_updated}}) |
| 208 | assert.Equal(t, 1, len(result.Profiles)) |
| 209 | assert.Equal(t, profile1_updated.Name, result.Profiles[0].Name) |
| 210 | } |