- XML escaping and namespaces, no priority, the image cap and file names - News window and cap, sources and languages, the publication name - IndexNow batches of 10 000, answer outcomes, keys and the host filter - HTML sitemap group order, tree order and paging - default slugs, the effective type setting, lastmod config, slot edges
113 lines
4.1 KiB
Go
113 lines
4.1 KiB
Go
package classes
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"regexp"
|
|
"strings"
|
|
"testing"
|
|
|
|
"git.golem15.com/golem15/sm-sitemap-plugin/models"
|
|
)
|
|
|
|
// TestIndexNowBatches pins the requests of at most 10 000 addresses, in
|
|
// order, with nothing for no addresses.
|
|
func TestIndexNowBatches(t *testing.T) {
|
|
if MaxIndexNowURLs != 10000 {
|
|
t.Fatalf("MaxIndexNowURLs = %d", MaxIndexNowURLs)
|
|
}
|
|
urls := func(n int) []string {
|
|
out := make([]string, n)
|
|
for i := range out {
|
|
out[i] = fmt.Sprintf("https://example.test/%d", i)
|
|
}
|
|
return out
|
|
}
|
|
for _, tc := range []struct {
|
|
n int
|
|
want []int
|
|
}{{0, nil}, {1, []int{1}}, {10000, []int{10000}}, {10001, []int{10000, 1}}, {25000, []int{10000, 10000, 5000}}} {
|
|
got := indexNowBatches(urls(tc.n))
|
|
var sizes []int
|
|
next := 0
|
|
for _, b := range got {
|
|
sizes = append(sizes, len(b))
|
|
if len(b) > 0 && b[0] != fmt.Sprintf("https://example.test/%d", next) {
|
|
t.Fatalf("%d addresses: a batch starts at %s, want %d", tc.n, b[0], next)
|
|
}
|
|
next += len(b)
|
|
}
|
|
if fmt.Sprint(sizes) != fmt.Sprint(tc.want) {
|
|
t.Errorf("%d addresses: batches %v, want %v", tc.n, sizes, tc.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
// TestIndexNowOutcome pins the answer mapping: 200 and 202 sent, 429 and
|
|
// 5xx retried, 400, 403 and 422 (and any other status) refused.
|
|
func TestIndexNowOutcome(t *testing.T) {
|
|
for status, want := range map[int]int{
|
|
http.StatusOK: indexNowSent, http.StatusAccepted: indexNowSent,
|
|
http.StatusTooManyRequests: indexNowRetry, 500: indexNowRetry, 502: indexNowRetry, 503: indexNowRetry,
|
|
http.StatusBadRequest: indexNowRefused, http.StatusForbidden: indexNowRefused, http.StatusUnprocessableEntity: indexNowRefused,
|
|
http.StatusNoContent: indexNowRefused, http.StatusNotFound: indexNowRefused,
|
|
} {
|
|
if got := indexNowOutcome(status); got != want {
|
|
t.Errorf("status %d: outcome %d, want %d", status, got, want)
|
|
}
|
|
}
|
|
}
|
|
|
|
// TestIndexNowKeys pins the key format (8 to 128 letters, digits and
|
|
// hyphens), the generated key (32 lowercase hex characters, a new one each
|
|
// time), the key file name and the active key only while IndexNow is on.
|
|
func TestIndexNowKeys(t *testing.T) {
|
|
for k, want := range map[string]bool{
|
|
"abcd1234": true, "ABCD-1234-efgh": true, strings.Repeat("a", 128): true,
|
|
"abc1234": false, strings.Repeat("a", 129): false, "abcd_1234": false, "abcd 1234": false, "../abcd1234": false, "": false,
|
|
} {
|
|
if ValidKey(k) != want {
|
|
t.Errorf("ValidKey(%q) = %v, want %v", k, !want, want)
|
|
}
|
|
}
|
|
a, err := GenerateKey()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
b, _ := GenerateKey()
|
|
if !regexp.MustCompile(`^[0-9a-f]{32}$`).MatchString(a) || a == b || !ValidKey(a) {
|
|
t.Fatalf("GenerateKey = %q, %q", a, b)
|
|
}
|
|
if KeyFileName(a) != a+".txt" || KeyFileName("short") != "" || KeyFileName("x/../y12345") != "" {
|
|
t.Fatal("KeyFileName is wrong")
|
|
}
|
|
key := " " + a + " "
|
|
bad := "bad key"
|
|
if ActiveKey(models.Settings{IndexNowEnabled: true, IndexNowKey: &key}) != a ||
|
|
ActiveKey(models.Settings{IndexNowEnabled: false, IndexNowKey: &key}) != "" ||
|
|
ActiveKey(models.Settings{IndexNowEnabled: true, IndexNowKey: &bad}) != "" ||
|
|
ActiveKey(models.Settings{IndexNowEnabled: true}) != "" {
|
|
t.Fatal("ActiveKey is wrong")
|
|
}
|
|
}
|
|
|
|
// TestSiteURLs pins the host filter: only http(s) addresses on the site's
|
|
// host (case-insensitive, any port or scheme), each once, in order;
|
|
// nothing without a site address.
|
|
func TestSiteURLs(t *testing.T) {
|
|
got := SiteURLs("https://Example.test", []string{
|
|
"https://example.test/a", "https://EXAMPLE.test/b", "http://example.test/c", "https://example.test:8443/d",
|
|
"https://example.test/a", "https://www.example.test/e", "https://other.test/f", "/g", "ftp://example.test/h", "",
|
|
})
|
|
want := "https://example.test/a https://EXAMPLE.test/b http://example.test/c https://example.test:8443/d"
|
|
if strings.Join(got, " ") != want {
|
|
t.Fatalf("SiteURLs = %v, want %s", got, want)
|
|
}
|
|
if SiteURLs("", []string{"https://example.test/a"}) != nil || SiteURLs("/relative", []string{"/a"}) != nil {
|
|
t.Fatal("without a site address nothing is kept")
|
|
}
|
|
if got := SiteURLs("https://example.test", nil); got == nil || len(got) != 0 {
|
|
t.Fatalf("no addresses: %v, want an empty list", got)
|
|
}
|
|
}
|