This commit is contained in:
parent
faf881fa0c
commit
a8bc400371
3 changed files with 128 additions and 7 deletions
|
|
@ -181,5 +181,63 @@ int main(int argc, char** argv) {
|
|||
Check(personOk, "about Person schema parses and names the founder");
|
||||
}
|
||||
|
||||
// ── the post's video ──────────────────────────────────────────────
|
||||
// Google carouselled these recordings off the bare <video> element; the
|
||||
// VideoObject is what makes that deliberate rather than lucky.
|
||||
//
|
||||
// PostVideoLd only marks up our OWN mirrored copies, so this can only be
|
||||
// asserted when the fixture was actually mirrored — an unmirrored checkout
|
||||
// still carries the instance's absolute URLs, and skipping is the correct
|
||||
// behaviour there, not a failure. Same reasoning (and same note) as the
|
||||
// format-ladder checks in ShouldServePostPages.
|
||||
{
|
||||
constexpr std::string_view kVideoPost =
|
||||
"/posts/fairphone-6-postmarketos-working-main-camera";
|
||||
const std::string postBody = srv.Body(std::string(kVideoPost));
|
||||
if (postBody.find("poster=\"/media/") == std::string::npos) {
|
||||
std::println("note: no locally-mirrored poster on {} — the "
|
||||
"VideoObject checks did not run", kVideoPost);
|
||||
} else {
|
||||
bool found = false;
|
||||
bool complete = false;
|
||||
bool ownMirror = false;
|
||||
for (const Json::Value& doc : ExtractLd(srv, std::string(kVideoPost))) {
|
||||
if (doc.Str("@type") != "BlogPosting") continue;
|
||||
const Json::Value* v = doc.Find("video");
|
||||
if (!v) continue;
|
||||
if (v->IsArray() && v->array.empty()) continue;
|
||||
// One video: the object itself, not a single-element array.
|
||||
const Json::Value& vid = v->IsArray() ? v->array.front() : *v;
|
||||
found = true;
|
||||
const std::string_view thumb = vid.Str("thumbnailUrl");
|
||||
const std::string_view content = vid.Str("contentUrl");
|
||||
complete = vid.Str("@type") == "VideoObject"
|
||||
&& !vid.Str("name").empty()
|
||||
&& !vid.Str("uploadDate").empty()
|
||||
&& !thumb.empty() && !content.empty();
|
||||
ownMirror = thumb.starts_with("https://catcrafts.net/media/")
|
||||
&& content.starts_with("https://catcrafts.net/media/");
|
||||
}
|
||||
Check(found, "a video post's BlogPosting carries a video node");
|
||||
Check(complete, "VideoObject has the fields the rich result requires");
|
||||
Check(ownMirror, "video thumbnail and content URLs point at our own mirror");
|
||||
}
|
||||
}
|
||||
|
||||
// A post that leads with no video must not grow an empty video property:
|
||||
// an Article claiming a video it does not have is a structured-data error,
|
||||
// not a harmless extra key.
|
||||
{
|
||||
bool sawPosting = false;
|
||||
bool bare = true;
|
||||
for (const Json::Value& doc :
|
||||
ExtractLd(srv, "/posts/the-linux-phone-travel-experience")) {
|
||||
if (doc.Str("@type") != "BlogPosting") continue;
|
||||
sawPosting = true;
|
||||
if (doc.Find("video")) bare = false;
|
||||
}
|
||||
Check(sawPosting && bare, "a post with no video carries no video node");
|
||||
}
|
||||
|
||||
return Finish();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue