Skip to content
quarry Artifact [cf171d824b]
Login

Artifact [cf171d824b]

Artifact cf171d824ba84e89ec7047e40352db8ff859ff489a5be7180a0e0a5a543d5378:


package obs

import "testing"

func TestClassify(t *testing.T) {
	for _, tc := range []struct {
		name    string
		f       Facts
		kind    string
		crawler string
	}{
		{"a named crawler", Facts{UA: "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"}, KindCrawler, "Googlebot"},
		{"an AI crawler", Facts{UA: "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2"}, KindCrawler, "GPTBot"},
		{"a crawler that signed in is still a crawler", Facts{UA: "ClaudeBot/1.0", Account: "x"}, KindCrawler, "ClaudeBot"},
		{"a verified account", Facts{UA: "curl/8.4.0", Account: "dmestas"}, KindPerson, ""},
		{"an anonymous sync", Facts{UA: "zit/0.6.6", Door: DoorSync, Client: "zit"}, KindUnsure, ""},
		{"no user agent", Facts{}, KindAutomated, ""},
		{"a library", Facts{UA: "python-requests/2.31"}, KindAutomated, ""},
		{"an unnamed bot", Facts{UA: "Mozilla/5.0 (compatible; SomeCrawler/1.0)"}, KindAutomated, ""},
		{"a browser", Facts{UA: "Mozilla/5.0 (X11; Linux x86_64; rv:131.0) Gecko/20100101 Firefox/131.0"}, KindPerson, ""},
		{"something else", Facts{UA: "Lynx/2.9"}, KindUnsure, ""},
	} {
		got := Classify(tc.f)
		if got.Kind != tc.kind || got.Crawler != tc.crawler {
			t.Errorf("FAIL: %s: %+v, want kind %s crawler %q", tc.name, got, tc.kind, tc.crawler)
		}
	}
}

// The client is named the way a reader would name it, and a sync round
// that already named its client is believed over its user agent.
func TestTheClientIsNamed(t *testing.T) {
	for ua, want := range map[string]string{
		"zit/0.6.6":   "zit",
		"zig/0.15":    "zit",
		"Fossil/2.26": "fossil",
		"curl/8.4.0":  "curl",
		"Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 Chrome/130.0 Safari/537.36 Edg/130.0": "Edge",
		"Mozilla/5.0 (Macintosh) AppleWebKit/605.1.15 Version/18.0 Safari/605.1.15":             "Safari",
	} {
		if got := Classify(Facts{UA: ua}).Client; got != want {
			t.Errorf("FAIL: %q named %q, want %q", ua, got, want)
		}
	}
	if got := Classify(Facts{UA: "Mozilla/5.0", Door: DoorSync, Client: "fossil"}).Client; got != "fossil" {
		t.Errorf("FAIL: the sync round's own client was overridden: %q", got)
	}
}