177 lines
5.7 KiB
Go
177 lines
5.7 KiB
Go
package web
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
"videoweb/app/service/configser"
|
|
"videoweb/app/service/playletser"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
func TestAttachPageSEOUsesPageTypeInsteadOfRequestDomain(t *testing.T) {
|
|
gin.SetMode(gin.TestMode)
|
|
|
|
tests := []struct {
|
|
name string
|
|
requestURL string
|
|
foreverURL string
|
|
status int
|
|
data gin.H
|
|
wantRobots string
|
|
wantRobotsHeader string
|
|
wantCanonical string
|
|
wantJSONLD bool
|
|
}{
|
|
{
|
|
name: "public page on alternate domain remains indexable",
|
|
requestURL: "https://alternate.example/",
|
|
foreverURL: "https://primary.example",
|
|
status: http.StatusOK,
|
|
data: gin.H{},
|
|
wantRobots: "index,follow,max-image-preview:large,max-snippet:-1,max-video-preview:-1",
|
|
wantCanonical: "https://primary.example/",
|
|
wantJSONLD: true,
|
|
},
|
|
{
|
|
name: "public page without permanent address remains indexable",
|
|
requestURL: "https://alternate.example/about",
|
|
status: http.StatusOK,
|
|
data: gin.H{},
|
|
wantRobots: "index,follow,max-image-preview:large,max-snippet:-1,max-video-preview:-1",
|
|
wantCanonical: "https://alternate.example/about",
|
|
wantJSONLD: true,
|
|
},
|
|
{
|
|
name: "search page is not indexable",
|
|
requestURL: "https://alternate.example/search/short-drama",
|
|
foreverURL: "https://primary.example",
|
|
status: http.StatusOK,
|
|
data: gin.H{},
|
|
wantRobots: "noindex,follow",
|
|
wantRobotsHeader: "noindex, follow",
|
|
},
|
|
{
|
|
name: "private page is neither indexed nor followed",
|
|
requestURL: "https://alternate.example/profile",
|
|
foreverURL: "https://primary.example",
|
|
status: http.StatusOK,
|
|
data: gin.H{},
|
|
wantRobots: "noindex,nofollow",
|
|
wantRobotsHeader: "noindex, nofollow",
|
|
},
|
|
{
|
|
name: "navigation page is not indexable",
|
|
requestURL: "https://alternate.example/",
|
|
foreverURL: "https://primary.example",
|
|
status: http.StatusOK,
|
|
data: gin.H{"isNavPage": true},
|
|
wantRobots: "noindex,follow",
|
|
wantRobotsHeader: "noindex, follow",
|
|
},
|
|
{
|
|
name: "missing public entity is not indexable",
|
|
requestURL: "https://alternate.example/tags/missing",
|
|
foreverURL: "https://primary.example",
|
|
status: http.StatusOK,
|
|
data: gin.H{"seoEntityValid": false},
|
|
wantRobots: "noindex,follow",
|
|
wantRobotsHeader: "noindex, follow",
|
|
},
|
|
{
|
|
name: "error page is not indexable",
|
|
requestURL: "https://alternate.example/about",
|
|
foreverURL: "https://primary.example",
|
|
status: http.StatusNotFound,
|
|
data: gin.H{},
|
|
wantRobots: "noindex,follow",
|
|
wantRobotsHeader: "noindex, follow",
|
|
},
|
|
{
|
|
name: "canonical play page stays indexable",
|
|
requestURL: "https://alternate.example/play/zhuazou",
|
|
foreverURL: "https://primary.example",
|
|
status: http.StatusOK,
|
|
data: gin.H{},
|
|
wantRobots: "index,follow,max-image-preview:large,max-snippet:-1,max-video-preview:-1",
|
|
wantCanonical: "https://primary.example/play/zhuazou",
|
|
wantJSONLD: true,
|
|
},
|
|
{
|
|
name: "play page with chapter still canonicalizes to two-segment path",
|
|
requestURL: "https://alternate.example/play/zhuazou",
|
|
foreverURL: "https://primary.example",
|
|
status: http.StatusOK,
|
|
data: gin.H{
|
|
"playlet": playletser.PlayletInfoResp{ID: 12, Slug: "zhuazou"},
|
|
"chapter": playletser.PlayletChapterInfoResp{ID: 901, PlayletID: 12},
|
|
},
|
|
wantRobots: "index,follow,max-image-preview:large,max-snippet:-1,max-video-preview:-1",
|
|
wantCanonical: "https://primary.example/play/zhuazou",
|
|
wantJSONLD: true,
|
|
},
|
|
{
|
|
name: "episode play page is not indexable",
|
|
requestURL: "https://alternate.example/play/zhuazou/12",
|
|
foreverURL: "https://primary.example",
|
|
status: http.StatusOK,
|
|
data: gin.H{},
|
|
wantRobots: "noindex,follow",
|
|
wantRobotsHeader: "noindex, follow",
|
|
},
|
|
{
|
|
name: "unwatchable series play page is not indexable",
|
|
requestURL: "https://alternate.example/series-play/film-1",
|
|
foreverURL: "https://primary.example",
|
|
status: http.StatusOK,
|
|
data: gin.H{"canWatch": false},
|
|
wantRobots: "noindex,follow",
|
|
wantRobotsHeader: "noindex, follow",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
response := httptest.NewRecorder()
|
|
ctx, _ := gin.CreateTestContext(response)
|
|
ctx.Request = httptest.NewRequest(http.MethodGet, tt.requestURL, nil)
|
|
|
|
data := gin.H{
|
|
"appConfig": configser.AppConfigVM{
|
|
ForeverURLAddr: tt.foreverURL,
|
|
},
|
|
}
|
|
for key, value := range tt.data {
|
|
data[key] = value
|
|
}
|
|
|
|
attachPageSEO(ctx, tt.status, data)
|
|
|
|
if got := data["robots"]; got != tt.wantRobots {
|
|
t.Fatalf("robots = %q, want %q", got, tt.wantRobots)
|
|
}
|
|
if got := response.Header().Get("X-Robots-Tag"); got != tt.wantRobotsHeader {
|
|
t.Fatalf("X-Robots-Tag = %q, want %q", got, tt.wantRobotsHeader)
|
|
}
|
|
|
|
canonicalValue, hasCanonical := data["canonicalURL"]
|
|
if tt.wantCanonical == "" {
|
|
if hasCanonical {
|
|
t.Fatalf("canonicalURL must be absent, got %#v", canonicalValue)
|
|
}
|
|
} else {
|
|
canonical, ok := canonicalValue.(string)
|
|
if !hasCanonical || !ok || canonical != tt.wantCanonical {
|
|
t.Fatalf("canonicalURL = %#v, want %q", canonicalValue, tt.wantCanonical)
|
|
}
|
|
}
|
|
|
|
jsonLD, hasJSONLD := data["jsonLD"]
|
|
if hasJSONLD != tt.wantJSONLD {
|
|
t.Fatalf("jsonLD presence = %v, want %v (value %#v)", hasJSONLD, tt.wantJSONLD, jsonLD)
|
|
}
|
|
})
|
|
}
|
|
}
|