Files
claude-plugin-runescape/scripts/rsw/internal/prices/integration_test.go
2026-03-05 22:45:55 -06:00

269 lines
6.9 KiB
Go

package prices_test
import (
"strings"
"testing"
"github.com/runescape-wiki/rsw/internal/prices"
)
const osrsPriceBaseURL = "https://prices.runescape.wiki/api/v1/osrs"
func osrsClient() *prices.Client {
return prices.NewClient(osrsPriceBaseURL)
}
// --- OSRS Mapping Tests ---
func TestOSRS_GetMapping_ReturnsItems(t *testing.T) {
items, err := osrsClient().GetMapping()
if err != nil {
t.Fatalf("GetMapping failed: %v", err)
}
if len(items) < 100 {
t.Fatalf("expected at least 100 items, got %d", len(items))
}
}
func TestOSRS_GetMapping_ContainsAbyssalWhip(t *testing.T) {
items, err := osrsClient().GetMapping()
if err != nil {
t.Fatalf("GetMapping failed: %v", err)
}
found := false
for _, item := range items {
if strings.EqualFold(item.Name, "abyssal whip") {
found = true
if item.ID != 4151 {
t.Errorf("expected Abyssal whip ID to be 4151, got %d", item.ID)
}
if !item.Members {
t.Error("expected Abyssal whip to be members-only")
}
break
}
}
if !found {
t.Error("expected to find 'Abyssal whip' in mapping")
}
}
// --- OSRS MappingCache Tests ---
func TestOSRS_MappingCache_LookupByName(t *testing.T) {
mc := prices.NewMappingCache(osrsClient(), "osrs")
if err := mc.Load(); err != nil {
t.Fatalf("Load failed: %v", err)
}
item := mc.LookupByName("Abyssal whip")
if item == nil {
t.Fatal("expected to find Abyssal whip")
}
if item.ID != 4151 {
t.Errorf("expected ID 4151, got %d", item.ID)
}
}
func TestOSRS_MappingCache_LookupByName_CaseInsensitive(t *testing.T) {
mc := prices.NewMappingCache(osrsClient(), "osrs")
if err := mc.Load(); err != nil {
t.Fatalf("Load failed: %v", err)
}
item := mc.LookupByName("ABYSSAL WHIP")
if item == nil {
t.Fatal("expected case-insensitive lookup to find Abyssal whip")
}
}
func TestOSRS_MappingCache_SearchByName(t *testing.T) {
mc := prices.NewMappingCache(osrsClient(), "osrs")
if err := mc.Load(); err != nil {
t.Fatalf("Load failed: %v", err)
}
results := mc.SearchByName("dragon")
if len(results) == 0 {
t.Fatal("expected to find items containing 'dragon'")
}
for _, item := range results {
if !strings.Contains(strings.ToLower(item.Name), "dragon") {
t.Errorf("result %q does not contain 'dragon'", item.Name)
}
}
}
func TestOSRS_MappingCache_LookupByID(t *testing.T) {
mc := prices.NewMappingCache(osrsClient(), "osrs")
if err := mc.Load(); err != nil {
t.Fatalf("Load failed: %v", err)
}
item := mc.LookupByID(4151)
if item == nil {
t.Fatal("expected to find item 4151")
}
if !strings.EqualFold(item.Name, "abyssal whip") {
t.Errorf("expected 'Abyssal whip', got %q", item.Name)
}
}
// --- OSRS Latest Price Tests ---
func TestOSRS_GetLatestForItem_AbyssalWhip(t *testing.T) {
latest, err := osrsClient().GetLatestForItem(4151)
if err != nil {
t.Fatalf("GetLatestForItem failed: %v", err)
}
if latest.High == nil && latest.Low == nil {
t.Error("expected at least one of High or Low to be non-nil")
}
if latest.High != nil && *latest.High <= 0 {
t.Errorf("expected positive high price, got %d", *latest.High)
}
if latest.Low != nil && *latest.Low <= 0 {
t.Errorf("expected positive low price, got %d", *latest.Low)
}
}
func TestOSRS_GetLatestForItem_Nonexistent(t *testing.T) {
_, err := osrsClient().GetLatestForItem(999999999)
if err == nil {
t.Error("expected error for nonexistent item ID")
}
}
// --- OSRS Timeseries Tests ---
func TestOSRS_Get1Hour_AbyssalWhip(t *testing.T) {
entry, err := osrsClient().Get1Hour(4151)
if err != nil {
t.Fatalf("Get1Hour failed: %v", err)
}
if entry.AvgHighPrice == nil {
t.Error("expected AvgHighPrice to be non-nil for Abyssal whip")
} else if *entry.AvgHighPrice <= 0 {
t.Errorf("expected positive AvgHighPrice, got %d", *entry.AvgHighPrice)
}
if entry.AvgLowPrice == nil {
t.Error("expected AvgLowPrice to be non-nil for Abyssal whip")
} else if *entry.AvgLowPrice <= 0 {
t.Errorf("expected positive AvgLowPrice, got %d", *entry.AvgLowPrice)
}
if entry.HighVolume <= 0 {
t.Errorf("expected positive buy volume, got %d", entry.HighVolume)
}
if entry.LowVolume <= 0 {
t.Errorf("expected positive sell volume, got %d", entry.LowVolume)
}
}
func TestOSRS_Get5Min_AbyssalWhip(t *testing.T) {
entry, err := osrsClient().Get5Min(4151)
if err != nil {
t.Fatalf("Get5Min failed: %v", err)
}
if entry.AvgHighPrice == nil {
t.Error("expected AvgHighPrice to be non-nil for Abyssal whip")
} else if *entry.AvgHighPrice <= 0 {
t.Errorf("expected positive AvgHighPrice, got %d", *entry.AvgHighPrice)
}
if entry.AvgLowPrice == nil {
t.Error("expected AvgLowPrice to be non-nil for Abyssal whip")
} else if *entry.AvgLowPrice <= 0 {
t.Errorf("expected positive AvgLowPrice, got %d", *entry.AvgLowPrice)
}
}
// --- RS3 Client Tests ---
func TestRS3_GetDetail_AbyssalWhip(t *testing.T) {
c := prices.NewRS3Client()
detail, err := c.GetDetail(4151)
if err != nil {
t.Fatalf("GetDetail failed: %v", err)
}
if detail.Name != "Abyssal whip" {
t.Errorf("expected name 'Abyssal whip', got %q", detail.Name)
}
if detail.CurrentPrice == "" {
t.Error("expected non-empty current price")
}
if detail.ID != 4151 {
t.Errorf("expected ID 4151, got %d", detail.ID)
}
}
func TestRS3_GetDetail_BluePartyhat(t *testing.T) {
c := prices.NewRS3Client()
detail, err := c.GetDetail(1042)
if err != nil {
t.Fatalf("GetDetail failed: %v", err)
}
if !strings.Contains(strings.ToLower(detail.Name), "partyhat") &&
!strings.Contains(strings.ToLower(detail.Name), "party hat") {
t.Errorf("expected name to contain 'partyhat', got %q", detail.Name)
}
if detail.CurrentPrice == "" {
t.Error("expected non-empty current price")
}
}
func TestRS3_GetDetail_HasTrends(t *testing.T) {
c := prices.NewRS3Client()
detail, err := c.GetDetail(4151)
if err != nil {
t.Fatalf("GetDetail failed: %v", err)
}
if detail.Day30Change == "" {
t.Error("expected non-empty 30-day change")
}
if detail.Day90Change == "" {
t.Error("expected non-empty 90-day change")
}
if detail.Day180Change == "" {
t.Error("expected non-empty 180-day change")
}
validTrends := map[string]bool{"positive": true, "negative": true, "neutral": true}
if !validTrends[detail.Day30Trend] {
t.Errorf("unexpected 30-day trend %q", detail.Day30Trend)
}
if !validTrends[detail.Day90Trend] {
t.Errorf("unexpected 90-day trend %q", detail.Day90Trend)
}
}
func TestRS3_GetDetail_Nonexistent(t *testing.T) {
c := prices.NewRS3Client()
_, err := c.GetDetail(999999999)
if err == nil {
t.Error("expected error for nonexistent RS3 item ID")
}
}
// --- RS3 Exchange Module Tests (via wiki client) ---
// These are in the wiki package test file, but we verify the RS3 price
// client integrates correctly with real item IDs from exchange modules.
func TestRS3_GetDetail_Members_Field(t *testing.T) {
c := prices.NewRS3Client()
detail, err := c.GetDetail(4151)
if err != nil {
t.Fatalf("GetDetail failed: %v", err)
}
if detail.Members != "true" {
t.Errorf("expected Abyssal whip members='true', got %q", detail.Members)
}
}