Files
sm-sitemap-plugin/filter_fixture_test.go
Jakub Zych 2200e46d98 fix: rebuilds collect under one lock and keep moved lastmods
A rebuild takes the transaction-scoped advisory lock
golem15.sitemap.rebuild before it reads the settings and collects, and
applies in the same transaction, so a second rebuild collects only after
the first has committed. apply no longer writes the lastmod of a content
row it did not create, so a lastmod RecordSaved moved meanwhile stays.
2026-11-04 23:04:01 +01:00

78 lines
2.1 KiB
Go

package sitemap_test
import (
"context"
"strings"
"sync"
"git.golem15.com/golem15/sm-sitemap-plugin/contract"
"git.golem15.com/golem15/summercms/modules/backpack"
"git.golem15.com/golem15/summercms/modules/party"
)
// filterPluginID is a fake plugin that publishes a contract.Filter, as the
// SEO plugin does: it imports only the contract package.
const filterPluginID = "acme.filter"
// fakeFilter excludes addresses containing "noindex" (reason noindex) and
// puts addresses containing "promo" into the group offers. It records the
// batches it was asked; hook, when set, runs at the start of every Decide
// (a test blocks a rebuild there).
type fakeFilter struct {
mu sync.Mutex
batches [][]contract.Candidate
hook func()
}
// setHook sets the Decide hook for one test.
func (f *fakeFilter) setHook(t interface{ Cleanup(func()) }, fn func()) {
f.mu.Lock()
f.hook = fn
f.mu.Unlock()
t.Cleanup(func() {
f.mu.Lock()
f.hook = nil
f.mu.Unlock()
})
}
func (f *fakeFilter) Decide(_ context.Context, batch []contract.Candidate) ([]contract.Decision, error) {
f.mu.Lock()
f.batches = append(f.batches, append([]contract.Candidate(nil), batch...))
hook := f.hook
f.mu.Unlock()
if hook != nil {
hook()
}
out := make([]contract.Decision, len(batch))
for i, c := range batch {
switch {
case strings.Contains(c.URL, "noindex"):
out[i] = contract.Decision{Exclude: true, Reason: contract.ReasonNoindex}
case strings.Contains(c.URL, "promo"):
out[i] = contract.Decision{Group: "offers"}
}
}
return out, nil
}
func (f *fakeFilter) Groups(context.Context) ([]contract.Group, error) {
return []contract.Group{{Key: "offers", Titles: map[string]string{"en": "Offers", "pl": "Oferty"}}}, nil
}
var theFilter = &fakeFilter{}
// filterPlugin is acme.filter.
type filterPlugin struct{}
func (filterPlugin) ID() string { return filterPluginID }
func (filterPlugin) Requires() []string { return nil }
func (filterPlugin) Register(app *backpack.App) error {
return app.Publish[contract.Filter](theFilter)
}
func (filterPlugin) Boot(*backpack.App) error { return nil }
func init() {
party.Register(filterPlugin{})
}