test: add integration tests for OSRS and RS3 wiki searches and page fetches

This commit is contained in:
2026-03-06 01:37:17 +00:00
parent 794ed0ee13
commit 9cbbbca2e3

View File

@@ -0,0 +1,518 @@
package wiki_test
import (
"fmt"
"strings"
"testing"
"github.com/runescape-wiki/rsw/internal/wiki"
)
const (
osrsAPIURL = "https://oldschool.runescape.wiki/api.php"
rs3APIURL = "https://runescape.wiki/api.php"
)
func osrsClient() *wiki.Client {
return wiki.NewClient(osrsAPIURL)
}
func rs3Client() *wiki.Client {
return wiki.NewClient(rs3APIURL)
}
func containsKeyword(t *testing.T, text, keyword string) {
t.Helper()
if !strings.Contains(strings.ToLower(text), strings.ToLower(keyword)) {
t.Errorf("expected to find keyword %q in text, but it was not found.\nText (first 500 chars): %.500s", keyword, text)
}
}
func containsAnyKeyword(t *testing.T, text string, keywords []string) {
t.Helper()
lower := strings.ToLower(text)
for _, kw := range keywords {
if strings.Contains(lower, strings.ToLower(kw)) {
return
}
}
t.Errorf("expected to find one of %v in text, but none were found.\nText (first 500 chars): %.500s", keywords, text)
}
// --- OSRS Search Tests ---
func TestOSRS_Search_DragonScimitar(t *testing.T) {
results, err := osrsClient().Search("dragon scimitar", 5)
if err != nil {
t.Fatalf("Search failed: %v", err)
}
if len(results) == 0 {
t.Fatal("expected results, got none")
}
found := false
for _, r := range results {
if strings.Contains(strings.ToLower(r.Title), "dragon scimitar") {
found = true
break
}
}
if !found {
t.Errorf("expected to find 'Dragon scimitar' in results, got: %v", titlesOf(results))
}
}
func TestOSRS_Search_AbyssalWhip(t *testing.T) {
results, err := osrsClient().Search("abyssal whip", 5)
if err != nil {
t.Fatalf("Search failed: %v", err)
}
if len(results) == 0 {
t.Fatal("expected results, got none")
}
found := false
for _, r := range results {
if strings.Contains(strings.ToLower(r.Title), "abyssal whip") {
found = true
break
}
}
if !found {
t.Errorf("expected to find 'Abyssal whip' in results, got: %v", titlesOf(results))
}
}
func TestOSRS_Search_MonkeyMadness(t *testing.T) {
results, err := osrsClient().Search("Monkey Madness", 5)
if err != nil {
t.Fatalf("Search failed: %v", err)
}
if len(results) == 0 {
t.Fatal("expected results, got none")
}
found := false
for _, r := range results {
if strings.Contains(strings.ToLower(r.Title), "monkey madness") {
found = true
break
}
}
if !found {
t.Errorf("expected to find 'Monkey Madness' in results, got: %v", titlesOf(results))
}
}
func TestOSRS_Search_MiningTraining(t *testing.T) {
results, err := osrsClient().Search("mining training", 5)
if err != nil {
t.Fatalf("Search failed: %v", err)
}
if len(results) == 0 {
t.Fatal("expected results, got none")
}
found := false
for _, r := range results {
lower := strings.ToLower(r.Title)
if strings.Contains(lower, "mining") {
found = true
break
}
}
if !found {
t.Errorf("expected to find mining-related result, got: %v", titlesOf(results))
}
}
func TestOSRS_Search_Snippet_ContainsKeywords(t *testing.T) {
results, err := osrsClient().Search("dragon scimitar", 5)
if err != nil {
t.Fatalf("Search failed: %v", err)
}
if len(results) == 0 {
t.Fatal("expected results, got none")
}
allText := collectSnippets(results)
containsAnyKeyword(t, allText, []string{"dragon", "scimitar", "weapon", "sword"})
}
// --- RS3 Search Tests ---
func TestRS3_Search_DragonBones(t *testing.T) {
results, err := rs3Client().Search("dragon bones", 5)
if err != nil {
t.Fatalf("Search failed: %v", err)
}
if len(results) == 0 {
t.Fatal("expected results, got none")
}
found := false
for _, r := range results {
if strings.Contains(strings.ToLower(r.Title), "dragon bones") {
found = true
break
}
}
if !found {
t.Errorf("expected to find 'Dragon bones' in results, got: %v", titlesOf(results))
}
}
func TestRS3_Search_PlaguessEnd(t *testing.T) {
results, err := rs3Client().Search("Plague's End", 5)
if err != nil {
t.Fatalf("Search failed: %v", err)
}
if len(results) == 0 {
t.Fatal("expected results, got none")
}
found := false
for _, r := range results {
if strings.Contains(strings.ToLower(r.Title), "plague") {
found = true
break
}
}
if !found {
t.Errorf("expected to find plague-related result, got: %v", titlesOf(results))
}
}
func TestRS3_Search_BluePartyhat(t *testing.T) {
results, err := rs3Client().Search("blue partyhat", 5)
if err != nil {
t.Fatalf("Search failed: %v", err)
}
if len(results) == 0 {
t.Fatal("expected results, got none")
}
found := false
for _, r := range results {
lower := strings.ToLower(r.Title)
if strings.Contains(lower, "partyhat") || strings.Contains(lower, "party hat") {
found = true
break
}
}
if !found {
t.Errorf("expected to find 'Blue partyhat' in results, got: %v", titlesOf(results))
}
}
func TestRS3_Search_PrayerTraining(t *testing.T) {
results, err := rs3Client().Search("prayer training", 5)
if err != nil {
t.Fatalf("Search failed: %v", err)
}
if len(results) == 0 {
t.Fatal("expected results, got none")
}
found := false
for _, r := range results {
lower := strings.ToLower(r.Title)
if strings.Contains(lower, "prayer") {
found = true
break
}
}
if !found {
t.Errorf("expected to find prayer-related result, got: %v", titlesOf(results))
}
}
// --- OSRS Page Tests ---
func TestOSRS_GetPage_DragonScimitar_ContainsKeyInfo(t *testing.T) {
page, err := osrsClient().GetPage("Dragon scimitar")
if err != nil {
t.Fatalf("GetPage failed: %v", err)
}
if page.Wikitext == "" {
t.Fatal("expected non-empty wikitext")
}
containsKeyword(t, page.Wikitext, "scimitar")
containsAnyKeyword(t, page.Wikitext, []string{"members", "Members"})
containsAnyKeyword(t, page.Wikitext, []string{"attack", "Attack", "slash", "Slash"})
}
func TestOSRS_GetPage_AbyssalWhip_ContainsKeyInfo(t *testing.T) {
page, err := osrsClient().GetPage("Abyssal whip")
if err != nil {
t.Fatalf("GetPage failed: %v", err)
}
containsKeyword(t, page.Wikitext, "whip")
containsAnyKeyword(t, page.Wikitext, []string{"slayer", "Slayer"})
containsAnyKeyword(t, page.Wikitext, []string{"abyssal", "Abyssal"})
}
func TestOSRS_GetPage_HasSections(t *testing.T) {
page, err := osrsClient().GetPage("Dragon scimitar")
if err != nil {
t.Fatalf("GetPage failed: %v", err)
}
if len(page.Sections) == 0 {
t.Error("expected page to have sections")
}
}
func TestOSRS_GetPage_MonkeyMadness_Quest(t *testing.T) {
page, err := osrsClient().GetPage("Monkey Madness I")
if err != nil {
t.Fatalf("GetPage failed: %v", err)
}
containsKeyword(t, page.Wikitext, "quest")
containsAnyKeyword(t, page.Wikitext, []string{"gnome", "Gnome", "monkey", "Monkey"})
containsAnyKeyword(t, page.Wikitext, []string{"requirements", "Requirements"})
}
// --- RS3 Page Tests ---
func TestRS3_GetPage_DragonBones_ContainsKeyInfo(t *testing.T) {
page, err := rs3Client().GetPage("Dragon bones")
if err != nil {
t.Fatalf("GetPage failed: %v", err)
}
containsKeyword(t, page.Wikitext, "prayer")
containsAnyKeyword(t, page.Wikitext, []string{"dragon", "Dragon"})
containsAnyKeyword(t, page.Wikitext, []string{"bone", "Bone", "bones", "Bones"})
}
func TestRS3_GetPage_PlaguessEnd_Quest(t *testing.T) {
page, err := rs3Client().GetPage("Plague's End")
if err != nil {
t.Fatalf("GetPage failed: %v", err)
}
containsKeyword(t, page.Wikitext, "quest")
containsAnyKeyword(t, page.Wikitext, []string{"elf", "Elf", "elven", "Elven"})
containsAnyKeyword(t, page.Wikitext, []string{"requirements", "Requirements"})
}
// --- Section Tests ---
func TestOSRS_GetPage_Sections_DragonScimitar(t *testing.T) {
page, err := osrsClient().GetPage("Dragon scimitar")
if err != nil {
t.Fatalf("GetPage failed: %v", err)
}
if len(page.Sections) == 0 {
t.Fatal("expected at least one section")
}
sectionNames := make([]string, len(page.Sections))
for i, s := range page.Sections {
sectionNames[i] = strings.ToLower(s.Line)
}
allSections := strings.Join(sectionNames, " ")
containsAnyKeyword(t, allSections, []string{"combat", "stats", "bonuses", "item", "creation", "drop"})
}
func TestOSRS_GetPageSection_DragonScimitar_FirstSection(t *testing.T) {
page, err := osrsClient().GetPage("Dragon scimitar")
if err != nil {
t.Fatalf("GetPage failed: %v", err)
}
idx := findSectionContaining(page.Sections, []string{"combat", "bonuses", "stats", "creation", "special"})
if idx < 0 {
if len(page.Sections) == 0 {
t.Skip("no sections found")
}
idx = parseFirstSectionIndex(page.Sections)
if idx < 0 {
t.Skip("could not parse any section index")
}
}
section, err := osrsClient().GetPageSection("Dragon scimitar", idx)
if err != nil {
t.Fatalf("GetPageSection failed: %v", err)
}
if section.Wikitext == "" {
t.Error("expected non-empty section wikitext")
}
}
func TestOSRS_GetPage_MiningTraining_Sections(t *testing.T) {
page, err := osrsClient().GetPage("Mining training")
if err != nil {
t.Fatalf("GetPage failed: %v", err)
}
containsKeyword(t, page.Wikitext, "mining")
containsAnyKeyword(t, page.Wikitext, []string{"experience", "xp", "level"})
if len(page.Sections) == 0 {
t.Error("expected mining training page to have sections")
}
}
func TestOSRS_GetPageSection_MiningTraining_FirstSection(t *testing.T) {
page, err := osrsClient().GetPage("Mining training")
if err != nil {
t.Fatalf("GetPage failed: %v", err)
}
idx := parseFirstSectionIndex(page.Sections)
if idx < 0 {
t.Skip("no sections with valid index found")
}
section, err := osrsClient().GetPageSection("Mining training", idx)
if err != nil {
t.Fatalf("GetPageSection failed: %v", err)
}
if section.Wikitext == "" {
t.Error("expected non-empty wikitext for section")
}
containsAnyKeyword(t, section.Wikitext, []string{"mining", "xp", "experience", "level", "ore"})
}
func TestRS3_GetPage_PrayerTraining_Sections(t *testing.T) {
page, err := rs3Client().GetPage("Prayer training")
if err != nil {
t.Fatalf("GetPage failed: %v", err)
}
containsKeyword(t, page.Wikitext, "prayer")
containsAnyKeyword(t, page.Wikitext, []string{"experience", "xp", "level", "bones"})
if len(page.Sections) == 0 {
t.Error("expected prayer training page to have sections")
}
}
func TestRS3_GetPageSection_PrayerTraining_BonesSection(t *testing.T) {
page, err := rs3Client().GetPage("Prayer training")
if err != nil {
t.Fatalf("GetPage failed: %v", err)
}
idx := findSectionContaining(page.Sections, []string{"bones", "altars", "bury", "offering"})
if idx < 0 {
t.Skip("no bones/altars section found")
}
section, err := rs3Client().GetPageSection("Prayer training", idx)
if err != nil {
t.Fatalf("GetPageSection failed: %v", err)
}
containsAnyKeyword(t, section.Wikitext, []string{"prayer", "bone", "xp", "experience"})
}
func TestRS3_GetPage_Slayer_Sections(t *testing.T) {
page, err := rs3Client().GetPage("Slayer")
if err != nil {
t.Fatalf("GetPage failed: %v", err)
}
containsKeyword(t, page.Wikitext, "slayer")
if len(page.Sections) == 0 {
t.Error("expected slayer page to have sections")
}
}
func TestRS3_GetPageSection_Slayer_MastersSection(t *testing.T) {
page, err := rs3Client().GetPage("Slayer")
if err != nil {
t.Fatalf("GetPage failed: %v", err)
}
idx := findSectionContaining(page.Sections, []string{"master", "masters", "tutor"})
if idx < 0 {
t.Skip("no masters section found")
}
section, err := rs3Client().GetPageSection("Slayer", idx)
if err != nil {
t.Fatalf("GetPageSection failed: %v", err)
}
containsAnyKeyword(t, section.Wikitext, []string{"slayer", "master", "task"})
}
// --- FindSectionIndex Tests ---
func TestFindSectionIndex_Found(t *testing.T) {
sections := []wiki.Section{
{Index: "1", Line: "Overview"},
{Index: "2", Line: "Combat styles"},
{Index: "3", Line: "Rewards"},
}
idx := wiki.FindSectionIndex(sections, "Combat styles")
if idx != 2 {
t.Errorf("expected index 2, got %d", idx)
}
}
func TestFindSectionIndex_NotFound(t *testing.T) {
sections := []wiki.Section{
{Index: "1", Line: "Overview"},
}
idx := wiki.FindSectionIndex(sections, "NonExistent")
if idx != -1 {
t.Errorf("expected -1, got %d", idx)
}
}
func TestFindSectionIndex_Empty(t *testing.T) {
idx := wiki.FindSectionIndex(nil, "anything")
if idx != -1 {
t.Errorf("expected -1 for nil sections, got %d", idx)
}
}
// --- Helpers ---
func titlesOf(results []wiki.SearchResult) []string {
titles := make([]string, len(results))
for i, r := range results {
titles[i] = r.Title
}
return titles
}
func collectSnippets(results []wiki.SearchResult) string {
var parts []string
for _, r := range results {
parts = append(parts, r.Snippet)
}
return strings.Join(parts, " ")
}
func findSectionContaining(sections []wiki.Section, keywords []string) int {
for _, s := range sections {
lower := strings.ToLower(s.Line)
for _, kw := range keywords {
if strings.Contains(lower, strings.ToLower(kw)) {
var idx int
if _, err := fmt.Sscanf(s.Index, "%d", &idx); err == nil && idx > 0 {
return idx
}
}
}
}
return -1
}
func parseFirstSectionIndex(sections []wiki.Section) int {
for _, s := range sections {
var idx int
if _, err := fmt.Sscanf(s.Index, "%d", &idx); err == nil && idx > 0 {
return idx
}
}
return -1
}