From ef400115e2a9f74c7483f8ef422270fa0726ca1f Mon Sep 17 00:00:00 2001 From: Brooke Kuhlmann Date: Wed, 10 Dec 2025 16:31:20 -0700 Subject: [PATCH] Added categories endpoint Necessary to provide access to category data. Milestone: minor --- lib/trmnl/api/client.rb | 4 ++ lib/trmnl/api/endpoints/category.rb | 27 ++++++++ lib/trmnl/api/endpoints/container.rb | 1 + spec/lib/trmnl/api/client_spec.rb | 9 +++ spec/lib/trmnl/api/endpoints/category_spec.rb | 63 +++++++++++++++++++ 5 files changed, 104 insertions(+) create mode 100644 lib/trmnl/api/endpoints/category.rb create mode 100644 spec/lib/trmnl/api/endpoints/category_spec.rb diff --git a/lib/trmnl/api/client.rb b/lib/trmnl/api/client.rb index 30b5293..45228ed 100644 --- a/lib/trmnl/api/client.rb +++ b/lib/trmnl/api/client.rb @@ -9,6 +9,7 @@ module TRMNL include Dependencies[:settings] include Endpoints::Dependencies[ + endpoint_categories: :categories, endpoint_current_screen: :current_screen, endpoint_display: :display, endpoint_firmware: :firmware, @@ -18,6 +19,7 @@ module TRMNL ] include Inspectable[ + endpoint_categories: :class, endpoint_current_screen: :class, endpoint_display: :class, endpoint_firmware: :class, @@ -31,6 +33,8 @@ module TRMNL yield settings if block_given? end + def categories = endpoint_categories.call + def current_screen(**) = endpoint_current_screen.call(**) def display(**) = endpoint_display.call(**) diff --git a/lib/trmnl/api/endpoints/category.rb b/lib/trmnl/api/endpoints/category.rb new file mode 100644 index 0000000..bc0b966 --- /dev/null +++ b/lib/trmnl/api/endpoints/category.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require "inspectable" +require "pipeable" + +module TRMNL + module API + module Endpoints + # Handles API request/response. + class Category + include TRMNL::API::Dependencies[:requester, contract: "contracts.category"] + + include Inspectable[contract: :class] + include Pipeable + + def call + pipe( + requester.get("categories"), + try(:parse, catch: JSON::ParserError), + validate(contract, as: :to_h), + as(:fetch, :data) + ) + end + end + end + end +end diff --git a/lib/trmnl/api/endpoints/container.rb b/lib/trmnl/api/endpoints/container.rb index 4f1b6b0..4886896 100644 --- a/lib/trmnl/api/endpoints/container.rb +++ b/lib/trmnl/api/endpoints/container.rb @@ -9,6 +9,7 @@ module TRMNL module Container extend Containable + register(:categories) { Category.new } register(:current_screen) { CurrentScreen.new } register(:display) { Display.new } register(:firmware) { Firmware.new } diff --git a/spec/lib/trmnl/api/client_spec.rb b/spec/lib/trmnl/api/client_spec.rb index 51329b3..1bceef7 100644 --- a/spec/lib/trmnl/api/client_spec.rb +++ b/spec/lib/trmnl/api/client_spec.rb @@ -31,6 +31,15 @@ RSpec.describe TRMNL::API::Client do end end + describe "#categories" do + let(:endpoint) { instance_spy TRMNL::API::Endpoints::Category } + + it "messages endpoint" do + client = described_class.new endpoint_categories: endpoint + expect(client.categories).to have_received(:call) + end + end + describe "#current_screen" do let(:endpoint) { instance_spy TRMNL::API::Endpoints::CurrentScreen } diff --git a/spec/lib/trmnl/api/endpoints/category_spec.rb b/spec/lib/trmnl/api/endpoints/category_spec.rb new file mode 100644 index 0000000..da62928 --- /dev/null +++ b/spec/lib/trmnl/api/endpoints/category_spec.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe TRMNL::API::Endpoints::Category do + subject(:endpoint) { described_class.new requester: } + + include_context "with application dependencies" + + let(:requester) { TRMNL::API::Requester.new http: } + + describe "#call" do + context "with success" do + let :http do + HTTP::Fake::Client.new do + get "/api/categories" do + headers["Content-Type"] = "application/json" + status 200 + + <<~JSON + { + "data": [ + "analytics", + "art", + "calendar" + ] + } + JSON + end + end + end + + it "answers response" do + result = endpoint.call + expect(result).to be_success(%w[analytics art calendar]) + end + end + + context "with failure" do + let :http do + HTTP::Fake::Client.new do + get "/api/categories" do + headers["Content-Type"] = "application/json" + status 404 + + <<~JSON + {"error": "Danger!"} + JSON + end + end + end + + it "answers failure response" 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