Added IP addresses endpoint

Necessary to request IP address data.

As addressed in the previous contract and model commits, RuboCop is updated to ignore the IP addresses in the specs since this can't be avoided.

Milestone: minor
This commit is contained in:
Brooke Kuhlmann
2025-12-11 14:53:55 -07:00
parent f54458f18f
commit eca4ae4f54
6 changed files with 112 additions and 0 deletions
+1
View File
@@ -13,3 +13,4 @@ Style/IpAddresses:
Exclude:
- spec/lib/trmnl/api/types_spec.rb
- spec/lib/trmnl/api/models/ip_address_spec.rb
- spec/lib/trmnl/api/endpoints/ip_address_spec.rb
+4
View File
@@ -13,6 +13,7 @@ module TRMNL
endpoint_current_screen: :current_screen,
endpoint_display: :display,
endpoint_firmware: :firmware,
endpoint_ip_addresses: :ip_addresses,
endpoint_log: :log,
endpoint_models: :models,
endpoint_setup: :setup
@@ -23,6 +24,7 @@ module TRMNL
endpoint_current_screen: :class,
endpoint_display: :class,
endpoint_firmware: :class,
endpoint_ip_addresses: :class,
endpoint_log: :class,
endpoint_models: :class,
endpoint_setup: :class
@@ -41,6 +43,8 @@ module TRMNL
def firmware = endpoint_firmware.call
def ip_addresses = endpoint_ip_addresses.call
def log(**) = endpoint_log.call(**)
def models(**) = endpoint_models.call(**)
+1
View File
@@ -13,6 +13,7 @@ module TRMNL
register(:current_screen) { CurrentScreen.new }
register(:display) { Display.new }
register(:firmware) { Firmware.new }
register(:ip_addresses) { IPAddress.new }
register(:log) { Log.new }
register(:models) { Model.new }
register(:setup) { Setup.new }
+30
View File
@@ -0,0 +1,30 @@
# frozen_string_literal: true
require "inspectable"
require "pipeable"
module TRMNL
module API
module Endpoints
# Handles API request/response.
class IPAddress
include TRMNL::API::Dependencies[
:requester,
contract: "contracts.ip_address",
model: "models.ip_address"
]
include Inspectable[contract: :class]
include Pipeable
def call
pipe requester.get("ips"),
try(:parse, catch: JSON::ParserError),
validate(contract, as: :to_h),
as(:fetch, :data),
to(model, :for)
end
end
end
end
end
+10
View File
@@ -67,6 +67,15 @@ RSpec.describe TRMNL::API::Client do
end
end
describe "#ip_addresses" do
let(:endpoint) { instance_spy TRMNL::API::Endpoints::IPAddress }
it "messages endpoint" do
client = described_class.new endpoint_ip_addresses: endpoint
expect(client.ip_addresses).to have_received(:call)
end
end
describe "#log" do
let(:endpoint) { instance_spy TRMNL::API::Endpoints::Log }
@@ -100,6 +109,7 @@ RSpec.describe TRMNL::API::Client do
"@endpoint_current_screen=TRMNL::API::Endpoints::CurrentScreen, " \
"@endpoint_display=TRMNL::API::Endpoints::Display, " \
"@endpoint_firmware=TRMNL::API::Endpoints::Firmware, " \
"@endpoint_ip_addresses=TRMNL::API::Endpoints::IPAddress, " \
"@endpoint_log=TRMNL::API::Endpoints::Log, " \
"@endpoint_models=TRMNL::API::Endpoints::Model, " \
"@endpoint_setup=TRMNL::API::Endpoints::Setup, "
@@ -0,0 +1,66 @@
# frozen_string_literal: true
require "spec_helper"
RSpec.describe TRMNL::API::Endpoints::IPAddress do
subject(:endpoint) { described_class.new requester: }
include_context "with application dependencies"
let(:requester) { TRMNL::API::Requester.new http: }
describe "#call" do
let :http do
HTTP::Fake::Client.new do
get "/api/ips" do
headers["Content-Type"] = "application/json"
status 200
<<~JSON
{
"data": {
"ipv4": ["192.168.1.10"],
"ipv6": ["1a00:100:100:1000::1"]
}
}
JSON
end
end
end
it "answers success" do
result = endpoint.call
expect(result).to be_success(
TRMNL::API::Models::IPAddress[
version_4: ["192.168.1.10"],
version_6: ["1a00:100:100:1000::1"]
]
)
end
context "with failure" do
let :http do
HTTP::Fake::Client.new do
get "/api/ips" do
headers["Content-Type"] = "application/json"
status 404
<<~JSON
{"error": "Danger!"}
JSON
end
end
end
it "answers failure" do
result = described_class.new(requester:).call
expect(result).to match(Failure(be_a(HTTP::Response)))
end
end
end
describe "#inspect" do
it_behaves_like "an inspectable endpoint", described_class.new
end
end