package journal_test import ( "bytes" "context" "encoding/base64" "net/url" "os" "path/filepath" "strconv" "strings" "testing" "git.golem15.com/golem15/sm-journal-plugin/console" "git.golem15.com/golem15/sm-journal-plugin/models" "git.golem15.com/golem15/summercms/modules/backpack" "git.golem15.com/golem15/summercms/modules/bonfire" "git.golem15.com/golem15/summercms/modules/compass" "git.golem15.com/golem15/summercms/modules/lagoon/attach" "gocloud.dev/blob" _ "gocloud.dev/blob/fileblob" ) // TestImageVariantsCommandCLI pins journal:image-variants in the // generated CLI, where no database and no bucket are published: the // command opens database.dsn and storage.uploads.bucket_url itself and // writes the missing variants; without a DSN it names the setting. func TestImageVariantsCommandCLI(t *testing.T) { if testShort() { t.Skip("Postgres") } env := newPostsEnv(t) var name string if err := env.gdb.Raw(`SELECT current_database()`).Scan(&name).Error; err != nil { t.Fatal(err) } u, err := url.Parse(adminDSN) if err != nil { t.Fatal(err) } u.Path = "/" + name post := models.Post{Title: "Cli", Slug: "cli", Content: "

x

", Published: true} if err := env.gdb.Create(&post).Error; err != nil { t.Fatal(err) } dir := t.TempDir() disk := "cli123def456ghi789jkl0.jpg" key := attach.BlobKey(disk) if err := os.MkdirAll(filepath.Join(dir, filepath.Dir(key)), 0o755); err != nil { t.Fatal(err) } if err := os.WriteFile(filepath.Join(dir, key), jpegOf(t, 900, 600), 0o644); err != nil { t.Fatal(err) } file := attach.File{DiskName: disk, FileName: "cli.jpg", ContentType: "image/jpeg", Field: "featured_images", AttachmentType: post.MorphName(), AttachmentID: strconv.FormatUint(uint64(post.ID), 10)} if err := env.gdb.Create(&file).Error; err != nil { t.Fatal(err) } run := func(environ ...string) (int, string) { t.Helper() cfg, err := compass.Open(compass.Options{Dir: t.TempDir(), Environ: append([]string{"SUMMER_ENV=development"}, environ...)}) if err != nil { t.Fatal(err) } app := backpack.New(cfg) var buf strings.Builder root, err := bonfire.NewRootIO("summer", []bonfire.Command{console.ImageVariants(app)}, strings.NewReader(""), &buf, &buf) if err != nil { t.Fatal(err) } return bonfire.Execute(context.Background(), root, []string{"journal:image-variants"}), buf.String() } if code, out := run(); code == 0 || !strings.Contains(out, "database is not configured (set SUMMER_DATABASE__DSN)") { t.Fatalf("without a DSN: %d\n%s", code, out) } code, out := run("SUMMER_DATABASE__DSN="+u.String(), "SUMMER_STORAGE__UPLOADS__BUCKET_URL=file://"+dir, "SUMMER_APP__KEY="+base64.StdEncoding.EncodeToString(bytes.Repeat([]byte("k"), 32))) if code != 0 || !strings.Contains(out, "Checked 1 featured images, wrote 2 variants") { t.Fatalf("journal:image-variants from the CLI: %d\n%s", code, out) } var variants []models.ImageVariant if err := env.gdb.Where("file_id = ?", file.ID).Order("width ASC").Find(&variants).Error; err != nil { t.Fatal(err) } if len(variants) != 2 || variants[0].Width != 480 || variants[1].Width != 800 { t.Fatalf("variants = %+v, want 480 and 800 (1200 is wider than the original)", variants) } bucket, err := blob.OpenBucket(t.Context(), "file://"+dir) if err != nil { t.Fatal(err) } defer bucket.Close() if ok, err := bucket.Exists(t.Context(), variants[1].WebPKey); err != nil || !ok { t.Fatalf("the CLI's WebP %s is not in the bucket: %v", variants[1].WebPKey, err) } } // TestFixHeadingsCommandCLI pins L1 WR-01 (D-50): journal:fix-headings in // the generated CLI, where no database is published: without a DSN it // names the setting, with one it opens database.dsn and prints the dry run. func TestFixHeadingsCommandCLI(t *testing.T) { if testShort() { t.Skip("Postgres") } env := newPostsEnv(t) var name string if err := env.gdb.Raw(`SELECT current_database()`).Scan(&name).Error; err != nil { t.Fatal(err) } u, err := url.Parse(adminDSN) if err != nil { t.Fatal(err) } u.Path = "/" + name post := models.Post{Title: "Cli heading", Slug: "cli-heading", Content: "

A

x

", ContentHTML: "

A

x

"} if err := env.gdb.Create(&post).Error; err != nil { t.Fatal(err) } run := func(environ ...string) (int, string) { t.Helper() cfg, err := compass.Open(compass.Options{Dir: t.TempDir(), Environ: append([]string{"SUMMER_ENV=development"}, environ...)}) if err != nil { t.Fatal(err) } app := backpack.New(cfg) var buf strings.Builder root, err := bonfire.NewRootIO("summer", []bonfire.Command{console.FixHeadings(app)}, strings.NewReader(""), &buf, &buf) if err != nil { t.Fatal(err) } return bonfire.Execute(context.Background(), root, []string{"journal:fix-headings"}), buf.String() } if code, out := run(); code == 0 || !strings.Contains(out, "database is not configured (set SUMMER_DATABASE__DSN)") { t.Fatalf("without a DSN: %d\n%s", code, out) } code, out := run("SUMMER_DATABASE__DSN="+u.String(), "SUMMER_APP__KEY="+base64.StdEncoding.EncodeToString(bytes.Repeat([]byte("k"), 32))) if code != 0 || !strings.Contains(out, "Would convert 1 H1 headings in 1 posts and 0 categories. Run with --apply to save.") { t.Fatalf("journal:fix-headings from the CLI: %d\n%s", code, out) } if p := storedPost(t, env, post.ID); p.Content != "

A

x

" { t.Fatalf("the dry run wrote %q", p.Content) } }