require 'rails_helper' RSpec.describe NostrManager::FetchLatestEvent, type: :model do let(:filter) { Nostr::Filter.new(authors: ["pubkey"], kinds: [0], limit: 1) } let(:event_v1) { { "id" => "aaa", "created_at" => 1000, "content" => "v1" } } let(:event_v2) { { "id" => "bbb", "created_at" => 2000, "content" => "v2" } } describe "with no events found" do it "returns nil" do allow(NostrManager::FetchEvent).to receive(:call).and_return(nil) result = described_class.call(relays: ["wss://a", "wss://b"], filter: filter) expect(result).to be_nil end end describe "with event on 1 relay only" do it "returns the event" do allow(NostrManager::FetchEvent).to receive(:call) do |args| case args[:relay_url] when "wss://a" then event_v1 else nil end end result = described_class.call( relays: ["wss://a", "wss://b", "wss://c"], filter: filter ) expect(result).to eq(event_v1) end end describe "with events on 2 relays, different versions" do it "returns the latest event (max created_at)" do allow(NostrManager::FetchEvent).to receive(:call) do |args| case args[:relay_url] when "wss://a" then event_v1 when "wss://b" then event_v2 end end result = described_class.call(relays: ["wss://a", "wss://b"], filter: filter) expect(result).to eq(event_v2) end end describe "with duplicate events (same ID) on 2 relays" do it "returns the single event without double-counting" do allow(NostrManager::FetchEvent).to receive(:call).and_return(event_v1) result = described_class.call(relays: ["wss://a", "wss://b"], filter: filter) expect(result).to eq(event_v1) end end describe "with timeout after finding 1 event" do it "still returns the found event" do allow(NostrManager::FetchEvent).to receive(:call) do |args| case args[:relay_url] when "wss://a" then event_v1 when "wss://b" then raise Timeout::Error end end result = described_class.call(relays: ["wss://a", "wss://b"], filter: filter) expect(result).to eq(event_v1) end end describe "with max_events reached" do it "stops querying further relays" do call_count = 0 allow(NostrManager::FetchEvent).to receive(:call) do |args| call_count += 1 raise "should not query wss://c" if args[:relay_url] == "wss://c" case args[:relay_url] when "wss://a" then event_v1 when "wss://b" then event_v2 end end described_class.call( relays: ["wss://a", "wss://b", "wss://c"], filter: filter ) expect(call_count).to eq(2) end end end