github.com/drud/ddev@v1.21.5-alpha1.0.20230226034409-94fcc4b94453/pkg/ddevapp/settings_test.go (about) 1 package ddevapp_test 2 3 import ( 4 "fmt" 5 "os" 6 "path/filepath" 7 "testing" 8 "time" 9 10 . "github.com/drud/ddev/pkg/ddevapp" 11 "github.com/drud/ddev/pkg/fileutil" 12 "github.com/drud/ddev/pkg/nodeps" 13 "github.com/drud/ddev/pkg/testcommon" 14 "github.com/drud/ddev/pkg/util" 15 asrt "github.com/stretchr/testify/assert" 16 ) 17 18 type settingsLocations struct { 19 main string 20 local string 21 } 22 23 var drupalBackdropSettingsLocations = map[string]settingsLocations{ 24 nodeps.AppTypeDrupal6: {main: "sites/default/settings.php", local: "sites/default/settings.ddev.php"}, 25 nodeps.AppTypeDrupal7: {main: "sites/default/settings.php", local: "sites/default/settings.ddev.php"}, 26 nodeps.AppTypeDrupal8: {main: "sites/default/settings.php", local: "sites/default/settings.ddev.php"}, 27 nodeps.AppTypeDrupal9: {main: "sites/default/settings.php", local: "sites/default/settings.ddev.php"}, 28 nodeps.AppTypeBackdrop: {main: "settings.php", local: "settings.ddev.php"}, 29 } 30 31 // TestWriteSettings tests writing app settings (like Drupal 32 // settings.php/settings.ddev.php 33 func TestWriteSettings(t *testing.T) { 34 assert := asrt.New(t) 35 36 expectations := map[string]string{ 37 nodeps.AppTypeBackdrop: "settings.ddev.php", 38 nodeps.AppTypeDrupal6: "sites/default/settings.ddev.php", 39 nodeps.AppTypeDrupal7: "sites/default/settings.ddev.php", 40 nodeps.AppTypeDrupal8: "sites/default/settings.ddev.php", 41 nodeps.AppTypeDrupal9: "sites/default/settings.ddev.php", 42 nodeps.AppTypeWordPress: "wp-config-ddev.php", 43 nodeps.AppTypeTYPO3: "typo3conf/AdditionalConfiguration.php", 44 } 45 testDir := testcommon.CreateTmpDir(t.Name()) 46 47 app, err := NewApp(testDir, true) 48 assert.NoError(err) 49 50 t.Cleanup(func() { 51 err = app.Stop(true, false) 52 assert.NoError(err) 53 _ = os.RemoveAll(testDir) 54 }) 55 56 err = os.MkdirAll(filepath.Join(testDir, app.Docroot, "sites", "default"), 0777) 57 assert.NoError(err) 58 59 // Create expected folders for TYPO3. 60 err = os.MkdirAll(filepath.Join(testDir, app.Docroot, "typo3"), 0777) 61 assert.NoError(err) 62 63 err = os.MkdirAll(filepath.Join(testDir, app.Docroot, "typo3conf"), 0777) 64 assert.NoError(err) 65 66 // TYPO3 wants LocalConfiguration.php to exist in the repo ahead of time. 67 err = os.WriteFile(filepath.Join(testDir, app.Docroot, "typo3conf", "LocalConfiguration.php"), []byte("<?php\n"), 0644) 68 assert.NoError(err) 69 70 for apptype, settingsRelativePath := range expectations { 71 app.Type = apptype 72 73 expectedSettingsFile := filepath.Join(testDir, settingsRelativePath) 74 _, err = os.Stat(expectedSettingsFile) 75 assert.True(os.IsNotExist(err)) 76 createdFile, err := app.CreateSettingsFile() 77 assert.NoError(err) 78 assert.EqualValues(expectedSettingsFile, createdFile) 79 _, err = os.Stat(expectedSettingsFile) 80 assert.NoError(err) 81 signatureFound, err := fileutil.FgrepStringInFile(expectedSettingsFile, nodeps.DdevFileSignature) 82 assert.NoError(err) 83 assert.True(signatureFound, "Failed to find %s in %s", nodeps.DdevFileSignature, expectedSettingsFile) 84 _ = os.Remove(expectedSettingsFile) 85 } 86 87 println("") // Just lets Goland find the PASS when done. 88 } 89 90 // TestWriteDrushConfig test the drush config we write 91 func TestWriteDrushConfig(t *testing.T) { 92 assert := asrt.New(t) 93 app := &DdevApp{} 94 origDir, _ := os.Getwd() 95 96 for _, site := range TestSites { 97 runTime := util.TimeTrack(time.Now(), fmt.Sprintf("%s WriteDrushrc", site.Name)) 98 99 testcommon.ClearDockerEnv() 100 101 if !nodeps.ArrayContainsString([]string{"drupal7", "drupal8", "drupal9", "drupal10", "backdrop"}, site.Type) { 102 continue 103 } 104 err := app.Init(site.Dir) 105 if err != nil { 106 assert.NoError(err, "failed init of %s: %v", site.Name, err) 107 continue 108 } 109 t.Cleanup(func() { 110 err = os.Chdir(origDir) 111 assert.NoError(err) 112 err = app.Stop(true, false) 113 assert.NoError(err) 114 }) 115 116 _, err = app.CreateSettingsFile() 117 assert.NoError(err) 118 119 startErr := app.Start() 120 //nolint: errcheck 121 defer app.Stop(true, false) 122 if startErr != nil { 123 logs, _ := GetErrLogsFromApp(app, startErr) 124 t.Fatalf("app.Start failed, startErr=%v, logs=\n========\n%s\n===========\n", startErr, logs) 125 } 126 127 drushFilePath := filepath.Join(filepath.Dir(app.SiteSettingsPath), "drushrc.php") 128 129 switch app.Type { 130 case nodeps.AppTypeDrupal6, nodeps.AppTypeDrupal7, nodeps.AppTypeBackdrop: 131 if !fileutil.FileExists(drushFilePath) { 132 assert.True(fileutil.FileExists(drushFilePath)) 133 continue 134 } 135 optionFound, err := fileutil.FgrepStringInFile(drushFilePath, "options") 136 assert.NoError(err) 137 assert.True(optionFound) 138 139 default: 140 if fileutil.FileExists(drushFilePath) { 141 assert.False(fileutil.FileExists(drushFilePath), "Drush settings file (%s) should not exist but it does (app.Type=%s)", drushFilePath, app.Type) 142 continue 143 } 144 } 145 146 runTime() 147 } 148 } 149 150 // TestDrupalBackdropIncludeSettingsDdevInNewSettingsFile verifies that when no settings.php file exists, 151 // a settings.php file is created that includes settings.ddev.php. 152 func TestDrupalBackdropIncludeSettingsDdevInNewSettingsFile(t *testing.T) { 153 assert := asrt.New(t) 154 155 dir := testcommon.CreateTmpDir(t.Name()) 156 157 app, err := NewApp(dir, true) 158 assert.NoError(err) 159 160 err = os.MkdirAll(filepath.Join(dir, app.Docroot, "sites", "default"), 0777) 161 assert.NoError(err) 162 163 for appType, relativeSettingsLocations := range drupalBackdropSettingsLocations { 164 app.Type = appType 165 166 relativeSettingsLocation := relativeSettingsLocations.main 167 relativeSettingsDdevLocation := relativeSettingsLocations.local 168 expectedSettingsLocation := filepath.Join(dir, relativeSettingsLocation) 169 expectedSettingsDdevLocation := filepath.Join(dir, relativeSettingsDdevLocation) 170 171 // Ensure that no settings.php exists 172 _ = os.Remove(expectedSettingsLocation) 173 174 // Ensure that no settings.ddev.php file exists 175 _ = os.Remove(expectedSettingsDdevLocation) 176 177 // Invoke the settings file creation process 178 _, err := app.CreateSettingsFile() 179 assert.NoError(err) 180 181 // Ensure that a settings.php was created 182 assert.True(fileutil.FileExists(expectedSettingsLocation)) 183 184 // Ensure that settings.php references settings.ddev.php 185 settingsDdev := filepath.Base(relativeSettingsDdevLocation) 186 newSettingsIncludesSettingsDdev, err := fileutil.FgrepStringInFile(expectedSettingsLocation, settingsDdev) 187 assert.NoError(err) 188 assert.True(newSettingsIncludesSettingsDdev, "Failed to find %s in %s", settingsDdev, expectedSettingsLocation) 189 190 // Ensure that settings.ddev.php exists 191 assert.True(fileutil.FileExists(expectedSettingsDdevLocation)) 192 } 193 } 194 195 // TestDrupalBackdropIncludeSettingsDdevInExistingSettingsFile verifies that when a settings.php file already exists, 196 // it is modified to include settings.ddev.php 197 func TestDrupalBackdropIncludeSettingsDdevInExistingSettingsFile(t *testing.T) { 198 assert := asrt.New(t) 199 200 dir := testcommon.CreateTmpDir(t.Name()) 201 202 app, err := NewApp(dir, true) 203 assert.NoError(err) 204 205 err = os.MkdirAll(filepath.Join(dir, app.Docroot, "sites", "default"), 0777) 206 assert.NoError(err) 207 208 for appType, relativeSettingsLocations := range drupalBackdropSettingsLocations { 209 app.Type = appType 210 211 relativeSettingsLocation := relativeSettingsLocations.main 212 relativeSettingsDdevLocation := relativeSettingsLocations.local 213 expectedSettingsLocation := filepath.Join(dir, relativeSettingsLocation) 214 expectedSettingsDdevLocation := filepath.Join(dir, relativeSettingsDdevLocation) 215 216 // Ensure that no settings.php exists 217 _ = os.Remove(expectedSettingsLocation) 218 219 // Ensure that no settings.ddev.php file exists 220 _ = os.Remove(expectedSettingsDdevLocation) 221 222 // Create a settings.php that does not include settings.ddev.php 223 originalContents := "// this file is not empty\n" 224 err = os.WriteFile(expectedSettingsLocation, []byte(originalContents), 0644) 225 assert.NoError(err) 226 227 // Invoke the settings file creation process 228 _, err = app.CreateSettingsFile() 229 assert.NoError(err) 230 231 // Ensure that settings.php exists 232 assert.True(fileutil.FileExists(expectedSettingsLocation)) 233 234 // Ensure that settings.ddev.php exists 235 assert.True(fileutil.FileExists(expectedSettingsDdevLocation)) 236 237 // Ensure that settings.php references settings.ddev.php 238 settingsDdev := filepath.Base(relativeSettingsDdevLocation) 239 existingSettingsIncludesSettingsDdev, err := fileutil.FgrepStringInFile(expectedSettingsLocation, settingsDdev) 240 assert.NoError(err) 241 assert.True(existingSettingsIncludesSettingsDdev, "Failed to find %s in %s, apptype=%s", settingsDdev, expectedSettingsLocation, appType) 242 243 // Ensure that settings.php includes original contents 244 modifiedSettingsIncludesOriginalContents, err := fileutil.FgrepStringInFile(expectedSettingsLocation, originalContents) 245 assert.NoError(err) 246 assert.True(modifiedSettingsIncludesOriginalContents, "Failed to find %s in %s", originalContents, expectedSettingsLocation) 247 } 248 } 249 250 // TestDrupalBackdropCreateGitIgnoreIfNoneExists verifies that if no .gitignore file exists in the directory 251 // containing settings.php and settings.ddev.php, a .gitignore is created that includes settings.ddev.php. 252 func TestDrupalBackdropCreateGitIgnoreIfNoneExists(t *testing.T) { 253 assert := asrt.New(t) 254 255 dir := testcommon.CreateTmpDir(t.Name()) 256 257 app, err := NewApp(dir, true) 258 assert.NoError(err) 259 260 err = os.MkdirAll(filepath.Join(dir, app.Docroot, "sites", "default"), 0777) 261 assert.NoError(err) 262 263 for appType, relativeSettingsLocations := range drupalBackdropSettingsLocations { 264 app.Type = appType 265 266 relativeSettingsDdevLocation := relativeSettingsLocations.local 267 expectedSettingsDdevLocation := filepath.Join(dir, relativeSettingsDdevLocation) 268 expectedGitIgnoreLocation := filepath.Join(filepath.Dir(expectedSettingsDdevLocation), ".gitignore") 269 fmt.Println(expectedGitIgnoreLocation) 270 271 // Ensure that no .gitignore exists 272 _ = os.Remove(expectedGitIgnoreLocation) 273 274 // Invoke the settings file creation process 275 _, err = app.CreateSettingsFile() 276 assert.NoError(err) 277 278 // Ensure that a .gitignore exists (except for backdrop, which has settings in project root) 279 if app.Type != nodeps.AppTypeBackdrop { 280 assert.True(fileutil.FileExists(expectedGitIgnoreLocation)) 281 282 // Ensure that the new .gitignore includes settings.ddev.php 283 settingsDdev := filepath.Base(relativeSettingsDdevLocation) 284 newGitIgnoreIncludesSettingsDdev, err := fileutil.FgrepStringInFile(expectedGitIgnoreLocation, settingsDdev) 285 assert.NoError(err) 286 assert.True(newGitIgnoreIncludesSettingsDdev, "Failed to find %s in %s", settingsDdev, expectedGitIgnoreLocation) 287 } 288 } 289 } 290 291 // TestDrupalBackdropGitIgnoreAlreadyExists verifies that if a .gitignore already exists in the directory 292 // containing settings.php and settings.ddev.php, it is not modified. 293 func TestDrupalBackdropGitIgnoreAlreadyExists(t *testing.T) { 294 assert := asrt.New(t) 295 296 dir := testcommon.CreateTmpDir(t.Name()) 297 298 app, err := NewApp(dir, true) 299 assert.NoError(err) 300 301 err = os.MkdirAll(filepath.Join(dir, app.Docroot, "sites", "default"), 0777) 302 assert.NoError(err) 303 304 for appType, relativeSettingsLocations := range drupalBackdropSettingsLocations { 305 app.Type = appType 306 307 relativeSettingsDdevLocation := relativeSettingsLocations.local 308 expectedSettingsDdevLocation := filepath.Join(dir, relativeSettingsDdevLocation) 309 expectedGitIgnoreLocation := filepath.Join(filepath.Dir(expectedSettingsDdevLocation), ".gitignore") 310 fmt.Println(expectedGitIgnoreLocation) 311 312 // Ensure that a .gitignore already exists and has some contents 313 originalContents := "not empty" 314 settingsFile, err := os.Create(expectedGitIgnoreLocation) 315 assert.NoError(err) 316 _, err = settingsFile.Write([]byte(originalContents)) 317 assert.NoError(err) 318 319 // Invoke the settings file creation process 320 _, err = app.CreateSettingsFile() 321 assert.NoError(err) 322 323 // Ensure that .gitignore still exists 324 assert.True(fileutil.FileExists(expectedGitIgnoreLocation)) 325 326 // Ensure that the new .gitignore has not been modified to include settings.ddev.php 327 settingsDdev := relativeSettingsDdevLocation 328 existingGitIgnoreIncludesSettingsDdev, err := fileutil.FgrepStringInFile(expectedGitIgnoreLocation, settingsDdev) 329 assert.NoError(err) 330 assert.False(existingGitIgnoreIncludesSettingsDdev, "Found unexpected %s in %s", settingsDdev, expectedGitIgnoreLocation) 331 } 332 } 333 334 // TestDrupalBackdropOverwriteDdevSettings ensures that if a settings.ddev.php file already exists, it is overwritten by the 335 // settings creation process. 336 func TestDrupalBackdropOverwriteDdevSettings(t *testing.T) { 337 assert := asrt.New(t) 338 339 dir := testcommon.CreateTmpDir(t.Name()) 340 341 app, err := NewApp(dir, true) 342 assert.NoError(err) 343 344 err = os.MkdirAll(filepath.Join(dir, app.Docroot, "sites", "default"), 0777) 345 assert.NoError(err) 346 347 for appType, relativeSettingsLocations := range drupalBackdropSettingsLocations { 348 app.Type = appType 349 350 relativeSettingsDdevLocation := relativeSettingsLocations.local 351 expectedSettingsDdevLocation := filepath.Join(dir, relativeSettingsDdevLocation) 352 353 // Ensure that a settings.ddev.php file exists, WITH the #ddev-generated signature 354 originalContents := "not empty " + nodeps.DdevFileSignature 355 settingsFile, err := os.Create(expectedSettingsDdevLocation) 356 assert.NoError(err) 357 _, err = settingsFile.Write([]byte(originalContents)) 358 assert.NoError(err) 359 360 // Invoke the settings file creation process 361 _, err = app.CreateSettingsFile() 362 assert.NoError(err) 363 364 // Ensure settings.ddev.php was overwritten; It had the signature in it 365 // so it was valid to overwrite. The original string should no longer be there. 366 containsOriginalString, err := fileutil.FgrepStringInFile(expectedSettingsDdevLocation, originalContents) 367 assert.NoError(err) 368 assert.False(containsOriginalString, "The file should not have contained the original string %s and it did not.", originalContents) 369 370 // Now do the whole thing again, but this time the settings.ddev.php does *not* have 371 // the #ddev-generated signature, so the file will be respected and not replaced 372 originalContents = "nearly empty " 373 settingsFile, err = os.Create(expectedSettingsDdevLocation) 374 assert.NoError(err) 375 _, err = settingsFile.Write([]byte(originalContents)) 376 assert.NoError(err) 377 378 // Invoke the settings file creation process 379 _, err = app.CreateSettingsFile() 380 assert.NoError(err) 381 382 // Ensure settings.ddev.php was overwritten with new contents 383 containsOriginalString, err = fileutil.FgrepStringInFile(expectedSettingsDdevLocation, originalContents) 384 assert.NoError(err) 385 assert.True(containsOriginalString, "Did not find %s in the settings file; it should have still been there", originalContents) 386 } 387 }