# frozen_string_literal: true require "spec_helpers" describe Wayfarer::Middleware::Fetch do let(:task) { build(:task) } let(:page) { Object.new } let(:agent) { Object.new } let(:result) { Wayfarer::Networking::Result::Success.new(page) } let(:context) do double(instance: agent).tap do |context| allow(context).to receive(:fetch).with(task.url).and_return(result) end end subject { described_class.new } describe "#call" do let(:controller) do Struct.new(:task).include(Wayfarer::Middleware::Stage::API).new(task) end before do allow(controller).to receive(:run_callbacks).with(:fetch).and_yield spy.tap do |pool| allow(pool).to receive(:with).and_yield(context) allow(subject).to receive(:pool).and_return(pool) end task.metadata.staged_urls = SortedSet.new task.metadata.controller = controller end context "with page assigned" do before { task.metadata.page = page } it "does not alter the page" do expect { subject.call(task) }.not_to(change { task.metadata.page }) end it "yields" do expect { |spy| subject.call(task, &spy) }.to yield_control end end it "runs callbacks" do expect(controller).to receive(:run_callbacks).with(:fetch) subject.call(task) end it "fetches the URL" do expect(context).to receive(:fetch).with(task.url) subject.call(task) end context "with Redirect" do let(:redirect_url) { test_app_path("/foobar") } let(:result) { Wayfarer::Networking::Result::Redirect.new(page) } it "stages the redirect URL" do expect { subject.call(task) }.to change { task.metadata.staged_urls.count }.by(1) end it "does not yield" do expect { |spy| subject.call(task, &spy) }.not_to yield_control end end context "with Success" do it "assigns the context" do expect { subject.call(task) }.to change { task.metadata.context }.to(context) end it "assigns the page" do expect { subject.call(task) }.to change { task.metadata.page }.to(result.page) end it "yields" do expect { |spy| subject.call(task, &spy) }.to yield_control end end end describe described_class::API do subject(:controller) do Struct.new(:task).include(described_class).new(task) end describe "#agent" do before { task.metadata.context = context } it "returns the agent" do expect(controller.agent).to be(context.instance) end end describe "#context" do before { task.metadata.context = context } it "returns the context" do expect(controller.context).to be(task.metadata.context) end end describe "#page" do before { task.metadata.page = page } it "returns the page" do expect(controller.page).to be(task.metadata.page) end context "with live keyword" do before { task.metadata.context = context } context "with stateful agent" do before do result.page = Object.new allow(context).to receive(:live).and_return(result) end it "replaces the page" do expect { controller.page(live: true) }.to change { task.metadata.page }.to(result.page) end end context "with stateless agent" do before { allow(context).to receive(:live).and_return(nil) } it "does not alter the page" do expect { controller.page(live: true) }.not_to(change { task.metadata.page }) end end end end describe "#http" do it "returns a redirect-following HTTP agent" do expect(controller.http).to be_a(Wayfarer::Networking::Follow) end end end end