diff --git a/.config/rubocop/config.yml b/.config/rubocop/config.yml index d19cf14..089e133 100644 --- a/.config/rubocop/config.yml +++ b/.config/rubocop/config.yml @@ -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 diff --git a/lib/trmnl/api/client.rb b/lib/trmnl/api/client.rb index 45228ed..b41d97a 100644 --- a/lib/trmnl/api/client.rb +++ b/lib/trmnl/api/client.rb @@ -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(**) diff --git a/lib/trmnl/api/endpoints/container.rb b/lib/trmnl/api/endpoints/container.rb index 4886896..3ab1294 100644 --- a/lib/trmnl/api/endpoints/container.rb +++ b/lib/trmnl/api/endpoints/container.rb @@ -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 } diff --git a/lib/trmnl/api/endpoints/ip_address.rb b/lib/trmnl/api/endpoints/ip_address.rb new file mode 100644 index 0000000..5fe652e --- /dev/null +++ b/lib/trmnl/api/endpoints/ip_address.rb @@ -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 diff --git a/spec/lib/trmnl/api/client_spec.rb b/spec/lib/trmnl/api/client_spec.rb index 1bceef7..ee34433 100644 --- a/spec/lib/trmnl/api/client_spec.rb +++ b/spec/lib/trmnl/api/client_spec.rb @@ -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, " diff --git a/spec/lib/trmnl/api/endpoints/ip_address_spec.rb b/spec/lib/trmnl/api/endpoints/ip_address_spec.rb new file mode 100644 index 0000000..4ca56cd --- /dev/null +++ b/spec/lib/trmnl/api/endpoints/ip_address_spec.rb @@ -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