- golem15_seo_autolinks (migration 202610280007) and the settings column autolink_max (Links tab, 0 to 20, default 3) - classes/autolinks.go: checked save and delete with history, ForPage - ok resolve answers carry autolinks for the page's locale without disabled phrases and links to the page itself, and autolink_max
100 lines
3.8 KiB
Go
100 lines
3.8 KiB
Go
package seo_test
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"net/http"
|
|
"testing"
|
|
|
|
"git.golem15.com/golem15/sm-seo-plugin/classes"
|
|
"git.golem15.com/golem15/sm-seo-plugin/models"
|
|
"git.golem15.com/golem15/summercms/modules/lagoon"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// autolinksOf reads the resolve answer's autolinks as phrase → url, and
|
|
// its autolink_max (-1 when absent).
|
|
func autolinksOf(t *testing.T, got map[string]any) (map[string]string, int) {
|
|
t.Helper()
|
|
out := map[string]string{}
|
|
if list, ok := got["autolinks"].([]any); ok {
|
|
for _, item := range list {
|
|
m, _ := item.(map[string]any)
|
|
phrase, _ := m["phrase"].(string)
|
|
url, _ := m["url"].(string)
|
|
out[phrase] = url
|
|
}
|
|
}
|
|
most := -1
|
|
if n, ok := got["autolink_max"].(float64); ok {
|
|
most = int(n)
|
|
}
|
|
return out, most
|
|
}
|
|
|
|
// saveAutolink writes an auto-link through the service, as the screen and
|
|
// the API do.
|
|
func (e *testEnv) saveAutolink(t *testing.T, a models.Autolink) models.Autolink {
|
|
t.Helper()
|
|
svc := e.seoPlugin(t).Service()
|
|
err := lagoon.Transaction(t.Context(), e.db, func(ctx context.Context, tx *gorm.DB) error {
|
|
return svc.SaveAutolink(classes.WithTx(ctx, tx), tx, &a)
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("save auto-link %q: %v", a.Phrase, err)
|
|
}
|
|
return a
|
|
}
|
|
|
|
// TestAutolinksTracer is the tracer of D-82's auto-links: an editor adds
|
|
// the phrase "lwia grzywa" for every locale, and the next page that
|
|
// resolves carries it with autolink_max; the page it links to does not,
|
|
// nor does a disabled phrase or a phrase of another locale; autolink_max 0
|
|
// answers none.
|
|
func TestAutolinksTracer(t *testing.T) {
|
|
env := bootEnv(t)
|
|
token := env.admin(t, true)
|
|
env.expect(t, http.StatusCreated, http.MethodPost, "/_seo/api/v1/pages", token, map[string]any{"url": "/grzyby/lwia-grzywa", "title": "Lwia grzywa"})
|
|
env.createPage(t, token, map[string]any{"title": "Other", "slug": "other", "published": true})
|
|
|
|
env.saveAutolink(t, models.Autolink{Phrase: " lwia grzywa ", URL: "/grzyby/lwia-grzywa", Enabled: true})
|
|
env.saveAutolink(t, models.Autolink{Phrase: "boczniak", URL: "/grzyby/boczniak", Enabled: false})
|
|
env.saveAutolink(t, models.Autolink{Phrase: "lion's mane", URL: "/lions-mane", Locale: "en", Enabled: true})
|
|
|
|
links, most := autolinksOf(t, env.resolve(t, "/pl/pages/other"))
|
|
if most != 3 || len(links) != 1 || links["lwia grzywa"] != "/grzyby/lwia-grzywa" {
|
|
t.Fatalf("pl page autolinks = %v, autolink_max %d; want only lwia grzywa and 3", links, most)
|
|
}
|
|
links, _ = autolinksOf(t, env.resolve(t, "/pages/other"))
|
|
if len(links) != 2 || links["lion's mane"] != "/lions-mane" || links["lwia grzywa"] == "" {
|
|
t.Fatalf("en page autolinks = %v, want lwia grzywa and the en phrase", links)
|
|
}
|
|
got := env.resolve(t, "/grzyby/lwia-grzywa")
|
|
if got["action"] != "ok" {
|
|
t.Fatalf("registry page resolves %v", got)
|
|
}
|
|
if links, _ = autolinksOf(t, got); links["lwia grzywa"] != "" {
|
|
t.Fatalf("the target page carries its own phrase: %v", links)
|
|
}
|
|
if got := env.resolve(t, "/pages/missing"); got["autolinks"] != nil || got["autolink_max"] != nil {
|
|
t.Fatalf("a not_found answer carries auto-links: %v", got)
|
|
}
|
|
|
|
var revisions int64
|
|
env.db.Raw(`SELECT COUNT(*) FROM golem15_seo_revisions WHERE subject_kind = 'autolink'`).Scan(&revisions)
|
|
if revisions != 3 {
|
|
t.Fatalf("auto-link history rows = %d, want 3", revisions)
|
|
}
|
|
|
|
env.expect(t, http.StatusOK, http.MethodPut, "/_seo/api/v1/settings", token, map[string]any{"autolink_max": 0})
|
|
got = env.resolve(t, "/pl/pages/other")
|
|
if links, most = autolinksOf(t, got); most != 0 || len(links) != 0 {
|
|
raw, _ := json.Marshal(got)
|
|
t.Fatalf("autolink_max 0 answers %s", raw)
|
|
}
|
|
rec := env.call(t, http.MethodPut, "/_seo/api/v1/settings", token, map[string]any{"autolink_max": 21})
|
|
if rec.Code != http.StatusUnprocessableEntity {
|
|
t.Fatalf("autolink_max 21 = %d %s, want 422", rec.Code, rec.Body.String())
|
|
}
|
|
}
|