package files import ( "fmt" "os" "strings" "testing" "time" "codeberg.org/danjones000/my-log/config" "codeberg.org/danjones000/my-log/models" "github.com/nalgeon/be" ) func TestAppend(tt *testing.T) { tt.Run("success", func(t *testing.T) { t.Run("single", appendTestSingle) t.Run("two", appendTestTwoEntries) t.Run("new_line", appendTestAddNewLine) t.Run("no-new-line", appendTestDontAddNewLine) t.Run("dot-folder", appendTestDotFolder) t.Run("no-dot-folder", appendTestDotFolderNo) t.Run("no-ext", appendTestNoExt) }) tt.Run("failure", func(t *testing.T) { t.Run("badEntry", appendTestBadEntry) t.Run("load-err", appendTestConfLoadErr) t.Run("mkdir-err", appendTestMkdirErr) t.Run("append-log-err", appendTestOpenErr) }) } func setupAppendTest(t *testing.T) string { t.Helper() dir := t.ArtifactDir() config.Overrides["input.path"] = dir config.Overrides["input.ext"] = "log" t.Cleanup(func() { delete(config.Overrides, "input.path") delete(config.Overrides, "input.ext") }) return dir } func appendTestSingle(t *testing.T) { dir := setupAppendTest(t) when := time.Now().Local() e := models.Entry{ Title: "Jimmy", Date: when, Fields: []models.Meta{ {Key: "foo", Value: 42}, {Key: "bar", Value: true}, }, } l := models.Log{ Name: "test", Entries: []models.Entry{e}, } err := Append(l) be.Err(t, err, nil) by, err := os.ReadFile(dir + "/test.log") be.Err(t, err, nil) st := string(by) be.True(t, strings.Contains(st, "Jimmy\n")) be.True(t, strings.Contains(st, "\n@foo 42")) be.True(t, strings.Contains(st, "\n@bar true")) } func appendTestTwoEntries(t *testing.T) { dir := setupAppendTest(t) when := time.Now().Local() whens := when.Format(models.DateFormat) e := []models.Entry{ {Title: "one", Date: when}, {Title: "two", Date: when}, } l := models.Log{ Name: "test", Entries: e, } err := Append(l) be.Err(t, err, nil) by, _ := os.ReadFile(dir + "/test.log") st := string(by) be.True(t, strings.Contains(st, fmt.Sprintf("@begin %s - one", whens))) be.True(t, strings.Contains(st, fmt.Sprintf("@begin %s - two", whens))) } func appendTestAddNewLine(t *testing.T) { dir := setupAppendTest(t) os.WriteFile(dir+"/test.log", []byte("foo"), 0644) when := time.Now().Local() whens := when.Format(models.DateFormat) e := []models.Entry{ {Title: "one", Date: when, Fields: models.Metas{{Key: "id", Value: "jimmy"}}}, } l := models.Log{ Name: "test", Entries: e, } err := Append(l) be.Err(t, err, nil) by, _ := os.ReadFile(dir + "/test.log") exp := fmt.Sprintf("foo\n@begin %s - one\n@id jimmy @end\n", whens) be.Equal(t, string(by), exp) } func appendTestDontAddNewLine(t *testing.T) { dir := setupAppendTest(t) os.WriteFile(dir+"/test.log", []byte("foo\n"), 0644) when := time.Now().Local() whens := when.Format(models.DateFormat) e := []models.Entry{ {Title: "one", Date: when, Fields: models.Metas{{Key: "id", Value: "jimmy"}}}, } l := models.Log{ Name: "test", Entries: e, } err := Append(l) be.Err(t, err, nil) by, _ := os.ReadFile(dir + "/test.log") exp := fmt.Sprintf("foo\n@begin %s - one\n@id jimmy @end\n", whens) be.Equal(t, string(by), exp) } func appendTestBadEntry(t *testing.T) { dir := setupAppendTest(t) e := models.Entry{ Title: "Jimmy", } l := models.Log{ Name: "test", Entries: []models.Entry{e}, } err := Append(l) be.Err(t, err, nil) by, _ := os.ReadFile(dir + "/test.log") be.Equal(t, by, []byte{}) } func appendTestDotFolder(t *testing.T) { config.Overrides["input.dotFolder"] = "true" t.Cleanup(func() { delete(config.Overrides, "input.dotFolder") }) dir := setupAppendTest(t) e := models.Entry{ Title: "something", Date: time.Now(), } l := models.Log{ Name: "sub.test", Entries: []models.Entry{e}, } err := Append(l) be.Err(t, err, nil) by, err := os.ReadFile(dir + "/sub/test.log") be.Err(t, err, nil) st := string(by) be.True(t, strings.Contains(st, fmt.Sprintf("@begin %s - %s", e.Date.Format(models.DateFormat), e.Title))) } func appendTestDotFolderNo(t *testing.T) { config.Overrides["input.dotFolder"] = "false" t.Cleanup(func() { delete(config.Overrides, "input.dotFolder") }) dir := setupAppendTest(t) e := models.Entry{ Title: "another", Date: time.Now(), } l := models.Log{ Name: "sub.test", Entries: []models.Entry{e}, } err := Append(l) be.Err(t, err, nil) by, err := os.ReadFile(dir + "/sub.test.log") be.Err(t, err, nil) st := string(by) be.True(t, strings.Contains(st, fmt.Sprintf("@begin %s - %s", e.Date.Format(models.DateFormat), e.Title))) } func appendTestNoExt(t *testing.T) { dir := setupAppendTest(t) config.Overrides["input.ext"] = "" t.Cleanup(func() { config.Overrides["input.ext"] = "log" }) e := models.Entry{ Title: "baz", Date: time.Now(), } l := models.Log{ Name: "foobar", Entries: []models.Entry{e}, } err := Append(l) be.Err(t, err, nil) by, err := os.ReadFile(dir + "/foobar") be.Err(t, err, nil) st := string(by) be.True(t, strings.Contains(st, fmt.Sprintf("@begin %s - %s", e.Date.Format(models.DateFormat), e.Title))) } func appendTestConfLoadErr(t *testing.T) { dir := t.ArtifactDir() currConf := config.ConfigPath tmp, _ := os.CreateTemp(dir, "app-conf-*.toml") fname := tmp.Name() t.Cleanup(func() { tmp.Close() }) t.Cleanup(func() { os.Remove(fname) }) fmt.Fprintln(tmp, `{"not":"toml"}`) config.ConfigPath = fname t.Cleanup(func() { config.ConfigPath = currConf }) err := Append(models.Log{}) be.Err(t, err, "toml") } func appendTestMkdirErr(t *testing.T) { // Don't run this test as root config.Overrides["input.path"] = "/var/my-logs-test" t.Cleanup(func() { delete(config.Overrides, "input.path") }) err := Append(models.Log{}) be.Err(t, err, "permission denied") } func appendTestOpenErr(t *testing.T) { dir := setupAppendTest(t) l := models.Log{ Name: "test-open-err", } fname := dir + "/test-open-err.log" os.MkdirAll(dir, 0750) f, _ := os.Create(fname) f.Close() os.Chmod(fname, 0400) err := Append(l) be.Err(t, err, "permission denied") }