262 lines
7.7 KiB
Ruby
262 lines
7.7 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
describe Pod, type: :model do
|
|
describe ".find_or_create_by" do
|
|
it "takes a url, and makes one by host" do
|
|
pod = Pod.find_or_create_by(url: "https://example.org/u/maxwell")
|
|
expect(pod.host).to eq("example.org")
|
|
end
|
|
|
|
it "saves the port" do
|
|
pod = Pod.find_or_create_by(url: "https://example.org:3000/")
|
|
expect(pod.host).to eq("example.org")
|
|
expect(pod.port).to eq(3000)
|
|
end
|
|
|
|
it "ignores default ports" do
|
|
pod = Pod.find_or_create_by(url: "https://example.org:443/")
|
|
expect(pod.host).to eq("example.org")
|
|
expect(pod.port).to eq(Pod::DEFAULT_PORT)
|
|
end
|
|
|
|
it "sets ssl boolean" do
|
|
pod = Pod.find_or_create_by(url: "https://example.org/")
|
|
expect(pod.ssl).to be true
|
|
expect(pod.port).to eq(Pod::DEFAULT_PORT)
|
|
end
|
|
|
|
it "updates ssl boolean if upgraded to https" do
|
|
pod = Pod.find_or_create_by(url: "http://example.org/")
|
|
expect(pod.ssl).to be false
|
|
expect(pod.port).to eq(Pod::DEFAULT_PORT)
|
|
pod = Pod.find_or_create_by(url: "https://example.org/")
|
|
expect(pod.ssl).to be true
|
|
expect(pod.port).to eq(Pod::DEFAULT_PORT)
|
|
end
|
|
|
|
it "does not update ssl boolean if downgraded to http" do
|
|
pod = Pod.find_or_create_by(url: "https://example.org/")
|
|
expect(pod.ssl).to be true
|
|
expect(pod.port).to eq(Pod::DEFAULT_PORT)
|
|
pod = Pod.find_or_create_by(url: "http://example.org/")
|
|
expect(pod.ssl).to be true
|
|
expect(pod.port).to eq(Pod::DEFAULT_PORT)
|
|
end
|
|
|
|
it "normalizes hostname to lowercase" do
|
|
pod = Pod.find_or_create_by(url: "https://eXaMpLe.oRg/")
|
|
expect(pod.host).to eq("example.org")
|
|
end
|
|
|
|
context "validation" do
|
|
it "is valid" do
|
|
pod = Pod.find_or_create_by(url: "https://example.org/")
|
|
expect(pod).to be_valid
|
|
end
|
|
|
|
it "doesn't allow own pod" do
|
|
pod = Pod.find_or_create_by(url: AppConfig.url_to("/"))
|
|
expect(pod).not_to be_valid
|
|
end
|
|
|
|
it "doesn't allow own pod with default port" do
|
|
uri = URI.parse("https://example.org/")
|
|
allow(AppConfig).to receive(:pod_uri).and_return(uri)
|
|
|
|
pod = Pod.find_or_create_by(url: AppConfig.url_to("/"))
|
|
expect(pod).not_to be_valid
|
|
end
|
|
|
|
it "doesn't allow own pod with other scheme" do
|
|
uri = URI.parse("https://example.org/")
|
|
allow(AppConfig).to receive(:pod_uri).and_return(uri)
|
|
|
|
pod = Pod.find_or_create_by(url: "http://example.org/")
|
|
expect(pod).not_to be_valid
|
|
end
|
|
end
|
|
end
|
|
|
|
describe ".check_all!" do
|
|
before do
|
|
@pods = (0..4).map do
|
|
double("pod").tap do |pod|
|
|
expect(pod).to receive(:test_connection!)
|
|
end
|
|
end
|
|
allow(Pod).to receive(:find_in_batches).and_yield(@pods)
|
|
end
|
|
|
|
it "calls #test_connection! on every pod" do
|
|
Pod.check_all!
|
|
end
|
|
end
|
|
|
|
describe ".check_scheduled!" do
|
|
it "calls #test_connection! on all scheduled pods" do
|
|
(0..4).map { FactoryBot.create(:pod) }
|
|
FactoryBot.create(:pod, scheduled_check: true)
|
|
|
|
expect_any_instance_of(Pod).to receive(:test_connection!)
|
|
Pod.check_scheduled!
|
|
end
|
|
end
|
|
|
|
describe "#active?" do
|
|
it "returns true for an unchecked pod" do
|
|
pod = FactoryBot.create(:pod)
|
|
expect(pod.active?).to be_truthy
|
|
end
|
|
|
|
it "returns true for an online pod" do
|
|
pod = FactoryBot.create(:pod, status: :no_errors)
|
|
expect(pod.reload.active?).to be_truthy
|
|
end
|
|
|
|
it "returns true for a pod that is offline for less than 14 days" do
|
|
pod = FactoryBot.create(:pod, status: :net_failed, offline_since: DateTime.now.utc - 13.days)
|
|
expect(pod.active?).to be_truthy
|
|
end
|
|
|
|
it "returns false for a pod that is offline for less than 14 days" do
|
|
pod = FactoryBot.create(:pod, status: :net_failed, offline_since: DateTime.now.utc - 15.days)
|
|
expect(pod.active?).to be_falsey
|
|
end
|
|
end
|
|
|
|
describe "#schedule_check_if_needed" do
|
|
it "schedules the pod for the next check if it is offline" do
|
|
pod = FactoryBot.create(:pod, status: :net_failed)
|
|
pod.schedule_check_if_needed
|
|
expect(pod.scheduled_check).to be_truthy
|
|
end
|
|
|
|
it "does nothing if the pod unchecked" do
|
|
pod = FactoryBot.create(:pod)
|
|
pod.schedule_check_if_needed
|
|
expect(pod.scheduled_check).to be_falsey
|
|
end
|
|
|
|
it "does nothing if the pod is online" do
|
|
pod = FactoryBot.create(:pod, status: :no_errors)
|
|
pod.schedule_check_if_needed
|
|
expect(pod.scheduled_check).to be_falsey
|
|
end
|
|
|
|
it "does nothing if the pod is scheduled for the next check" do
|
|
pod = FactoryBot.create(:pod, status: :no_errors, scheduled_check: true)
|
|
expect(pod).not_to receive(:update_column)
|
|
pod.schedule_check_if_needed
|
|
end
|
|
end
|
|
|
|
describe "#test_connection!" do
|
|
before do
|
|
@pod = FactoryBot.create(:pod)
|
|
@now = Time.zone.now
|
|
|
|
@result = ConnectionTester::Result.new
|
|
@result.rt = 123
|
|
@result.software_version = "diaspora a.b.c.d"
|
|
@result.error = ConnectionTester::NetFailure.new("hello error!")
|
|
|
|
expect(ConnectionTester).to receive(:check).at_least(:once).and_return(@result)
|
|
end
|
|
|
|
it "updates the connectivity values" do
|
|
@result.error = nil
|
|
@pod.test_connection!
|
|
|
|
expect(@pod.status).to eq("no_errors")
|
|
expect(@pod.offline?).to be_falsey
|
|
expect(@pod.response_time).to eq(123)
|
|
expect(@pod.checked_at).to be_within(1.second).of @now
|
|
end
|
|
|
|
it "resets the scheduled_check flag" do
|
|
@pod.update(scheduled_check: true)
|
|
|
|
@pod.test_connection!
|
|
|
|
expect(@pod.scheduled_check).to be_falsey
|
|
end
|
|
|
|
it "handles a failed check" do
|
|
@pod.test_connection!
|
|
|
|
expect(@pod.offline?).to be_truthy
|
|
expect(@pod.offline_since).to be_within(1.second).of @now
|
|
end
|
|
|
|
it "removes the error message when there was no error" do
|
|
@pod.update(error: "old error message")
|
|
|
|
@result.error = nil
|
|
@pod.test_connection!
|
|
|
|
expect(@pod.error).to be_nil
|
|
end
|
|
|
|
it "preserves the original offline timestamp" do
|
|
@pod.test_connection!
|
|
|
|
expect(@pod.offline_since).to be_within(1.second).of @now
|
|
|
|
Timecop.travel(Time.zone.today + 30.days) do
|
|
@pod.test_connection!
|
|
expect(@pod.offline_since).to be_within(1.second).of @now
|
|
expect(Time.zone.now).to be_within(1.day).of(@now + 30.days)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "#url_to" do
|
|
it "appends the path to the pod-url" do
|
|
pod = FactoryBot.create(:pod)
|
|
expect(pod.url_to("/receive/public")).to eq("https://#{pod.host}/receive/public")
|
|
end
|
|
|
|
it "includes non-default port in pod url" do
|
|
pod = FactoryBot.create(:pod, port: 3000)
|
|
expect(pod.url_to("/receive/public")).to eq("https://#{pod.host}:#{pod.port}/receive/public")
|
|
end
|
|
end
|
|
|
|
describe "#update_offline_since" do
|
|
let(:pod) { FactoryBot.create(:pod) }
|
|
|
|
it "handles a successful status" do
|
|
pod.status = :no_errors
|
|
pod.update_offline_since
|
|
|
|
expect(pod.offline?).to be_falsey
|
|
expect(pod.offline_since).to be_nil
|
|
end
|
|
|
|
it "handles a failed status" do
|
|
now = Time.zone.now
|
|
|
|
pod.status = :unknown_error
|
|
pod.update_offline_since
|
|
|
|
expect(pod.offline?).to be_truthy
|
|
expect(pod.offline_since).to be_within(1.second).of now
|
|
end
|
|
|
|
it "preserves the original offline timestamp" do
|
|
now = Time.zone.now
|
|
|
|
pod.status = :unknown_error
|
|
pod.update_offline_since
|
|
pod.save
|
|
|
|
expect(pod.offline_since).to be_within(1.second).of now
|
|
|
|
Timecop.travel(Time.zone.today + 30.days) do
|
|
pod.update_offline_since
|
|
expect(pod.offline_since).to be_within(1.second).of now
|
|
expect(Time.zone.now).to be_within(1.day).of(now + 30.days)
|
|
end
|
|
end
|
|
end
|
|
end
|