From 1cc2aeadc2bac0304c7876a898212aa0b25bc95b Mon Sep 17 00:00:00 2001 From: Brooke Kuhlmann Date: Thu, 11 Dec 2025 14:03:43 -0700 Subject: [PATCH] Added palette endpoint Necessary to request and process Palettes API response. Milestone: minor --- lib/trmnl/api/client.rb | 4 ++ lib/trmnl/api/endpoints/container.rb | 1 + lib/trmnl/api/endpoints/palette.rb | 32 +++++++++ spec/lib/trmnl/api/client_spec.rb | 10 +++ spec/lib/trmnl/api/endpoints/palette_spec.rb | 76 ++++++++++++++++++++ 5 files changed, 123 insertions(+) create mode 100644 lib/trmnl/api/endpoints/palette.rb create mode 100644 spec/lib/trmnl/api/endpoints/palette_spec.rb diff --git a/lib/trmnl/api/client.rb b/lib/trmnl/api/client.rb index b41d97a..8bb00b7 100644 --- a/lib/trmnl/api/client.rb +++ b/lib/trmnl/api/client.rb @@ -16,6 +16,7 @@ module TRMNL endpoint_ip_addresses: :ip_addresses, endpoint_log: :log, endpoint_models: :models, + endpoint_palettes: :palettes, endpoint_setup: :setup ] @@ -27,6 +28,7 @@ module TRMNL endpoint_ip_addresses: :class, endpoint_log: :class, endpoint_models: :class, + endpoint_palettes: :class, endpoint_setup: :class ] @@ -49,6 +51,8 @@ module TRMNL def models(**) = endpoint_models.call(**) + def palettes = endpoint_palettes.call + def setup(**) = endpoint_setup.call(**) end end diff --git a/lib/trmnl/api/endpoints/container.rb b/lib/trmnl/api/endpoints/container.rb index 3ab1294..cb97788 100644 --- a/lib/trmnl/api/endpoints/container.rb +++ b/lib/trmnl/api/endpoints/container.rb @@ -16,6 +16,7 @@ module TRMNL register(:ip_addresses) { IPAddress.new } register(:log) { Log.new } register(:models) { Model.new } + register(:palettes) { Palette.new } register(:setup) { Setup.new } end end diff --git a/lib/trmnl/api/endpoints/palette.rb b/lib/trmnl/api/endpoints/palette.rb new file mode 100644 index 0000000..2ce9564 --- /dev/null +++ b/lib/trmnl/api/endpoints/palette.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +require "inspectable" +require "pipeable" + +module TRMNL + module API + module Endpoints + # Handles API request/response. + class Palette + include TRMNL::API::Dependencies[ + :requester, + contract: "contracts.palette", + model: "models.palette" + ] + + include Inspectable[contract: :class] + include Pipeable + + def call + pipe( + requester.get("palettes"), + try(:parse, catch: JSON::ParserError), + validate(contract, as: :to_h), + as(:fetch, :data), + map { |data| model.for(**data) } + ) + end + end + end + end +end diff --git a/spec/lib/trmnl/api/client_spec.rb b/spec/lib/trmnl/api/client_spec.rb index ee34433..92d501c 100644 --- a/spec/lib/trmnl/api/client_spec.rb +++ b/spec/lib/trmnl/api/client_spec.rb @@ -94,6 +94,15 @@ RSpec.describe TRMNL::API::Client do end end + describe "#palette" do + let(:endpoint) { instance_spy TRMNL::API::Endpoints::Palette } + + it "messages endpoint" do + client = described_class.new endpoint_palettes: endpoint + expect(client.palettes).to have_received(:call).with(no_args) + end + end + describe "#setup" do let(:endpoint) { instance_spy TRMNL::API::Endpoints::Setup } @@ -112,6 +121,7 @@ RSpec.describe TRMNL::API::Client do "@endpoint_ip_addresses=TRMNL::API::Endpoints::IPAddress, " \ "@endpoint_log=TRMNL::API::Endpoints::Log, " \ "@endpoint_models=TRMNL::API::Endpoints::Model, " \ + "@endpoint_palettes=TRMNL::API::Endpoints::Palette, " \ "@endpoint_setup=TRMNL::API::Endpoints::Setup, " ) end diff --git a/spec/lib/trmnl/api/endpoints/palette_spec.rb b/spec/lib/trmnl/api/endpoints/palette_spec.rb new file mode 100644 index 0000000..896ef06 --- /dev/null +++ b/spec/lib/trmnl/api/endpoints/palette_spec.rb @@ -0,0 +1,76 @@ +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe TRMNL::API::Endpoints::Palette 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/palettes" do + headers["Content-Type"] = "application/json" + status 200 + + <<~JSON + { + "data": [ + { + "id": "test", + "name": "Test", + "grays": 2, + "colors": ["#000000", "#FFFFFF"], + "framework_class": "screen--1bit" + } + ] + } + JSON + end + end + end + + it "answers success" do + result = endpoint.call + + expect(result).to be_success( + [ + TRMNL::API::Models::Palette[ + id: "test", + name: "Test", + grays: 2, + colors: %w[#000000 #FFFFFF], + framework_class: "screen--1bit" + ] + ] + ) + end + + context "with failure" do + let :http do + HTTP::Fake::Client.new do + get "/api/palettes" 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