mirror of
https://github.com/usetrmnl/trmnl-api.git
synced 2026-04-29 13:35:13 -07:00
Added recipe endpoint
Necessary to perform API requests and acquire models for further processing. This also wires up the client and exposes the endpoint for immediate use. Milestone: minor
This commit is contained in:
@@ -17,6 +17,7 @@ module TRMNL
|
||||
endpoint_log: :log,
|
||||
endpoint_models: :models,
|
||||
endpoint_palettes: :palettes,
|
||||
endpoint_recipes: :recipes,
|
||||
endpoint_setup: :setup
|
||||
]
|
||||
|
||||
@@ -29,6 +30,7 @@ module TRMNL
|
||||
endpoint_log: :type,
|
||||
endpoint_models: :type,
|
||||
endpoint_palettes: :type,
|
||||
endpoint_recipes: :type,
|
||||
endpoint_setup: :type
|
||||
]
|
||||
|
||||
@@ -53,6 +55,8 @@ module TRMNL
|
||||
|
||||
def palettes = endpoint_palettes.call
|
||||
|
||||
def recipes(**) = endpoint_recipes.call(**)
|
||||
|
||||
def setup(**) = endpoint_setup.call(**)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -17,6 +17,7 @@ module TRMNL
|
||||
register(:log) { Log.new }
|
||||
register(:models) { Model.new }
|
||||
register(:palettes) { Palette.new }
|
||||
register(:recipes) { Recipe.new }
|
||||
register(:setup) { Setup.new }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "inspectable"
|
||||
require "pipeable"
|
||||
|
||||
module TRMNL
|
||||
module API
|
||||
module Endpoints
|
||||
# Handles API request/response.
|
||||
class Recipe
|
||||
include TRMNL::API::Dependencies[
|
||||
:requester,
|
||||
contract: "contracts.recipe",
|
||||
model: "models.recipe"
|
||||
]
|
||||
|
||||
include Inspectable[contract: :type]
|
||||
include Pipeable
|
||||
|
||||
def call(**)
|
||||
pipe(
|
||||
requester.get("recipes.json", **),
|
||||
try(:parse, catch: JSON::ParserError),
|
||||
validate(contract, as: :to_h),
|
||||
to(model, :for)
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -103,6 +103,15 @@ RSpec.describe TRMNL::API::Client do
|
||||
end
|
||||
end
|
||||
|
||||
describe "#recipe" do
|
||||
let(:endpoint) { instance_spy TRMNL::API::Endpoints::Recipe }
|
||||
|
||||
it "messages endpoint" do
|
||||
client = described_class.new endpoint_recipes: endpoint
|
||||
expect(client.recipes).to have_received(:call).with(no_args)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#setup" do
|
||||
let(:endpoint) { instance_spy TRMNL::API::Endpoints::Setup }
|
||||
|
||||
@@ -122,6 +131,7 @@ RSpec.describe TRMNL::API::Client do
|
||||
endpoint_log: "TRMNL::API::Endpoints::Log",
|
||||
endpoint_models: "TRMNL::API::Endpoints::Model",
|
||||
endpoint_palettes: "TRMNL::API::Endpoints::Palette",
|
||||
endpoint_recipes: "TRMNL::API::Endpoints::Recipe",
|
||||
endpoint_setup: "TRMNL::API::Endpoints::Setup"
|
||||
)
|
||||
end
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "spec_helper"
|
||||
|
||||
RSpec.describe TRMNL::API::Endpoints::Recipe do
|
||||
subject(:endpoint) { described_class.new requester: }
|
||||
|
||||
include_context "with application dependencies"
|
||||
|
||||
let :requester do
|
||||
TRMNL::API::Requester.new http: do |settings|
|
||||
settings.uri = "https://usetrmnl.com"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#call" do
|
||||
context "with success" do
|
||||
let :http do
|
||||
HTTP::Fake::Client.new do
|
||||
get "/recipes.json" do
|
||||
headers["Content-Type"] = "application/json"
|
||||
status 200
|
||||
|
||||
<<~JSON
|
||||
{
|
||||
"data": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "test",
|
||||
"screenshot_url": "https://screens.trmnl.io/test.png",
|
||||
"published_at": "2026-01-02T03:04:05.000Z",
|
||||
"custom_fields": [],
|
||||
"author_bio": {
|
||||
"keyname": "test",
|
||||
"name": "Test",
|
||||
"field_type": "author_bio"
|
||||
},
|
||||
"stats": {
|
||||
"installs": 1,
|
||||
"forks": 2
|
||||
}
|
||||
}
|
||||
],
|
||||
"total": 2,
|
||||
"from": 1,
|
||||
"to": 2,
|
||||
"per_page": 25,
|
||||
"current_page": 1,
|
||||
"prev_page_url": null,
|
||||
"next_page_url": "/recipes.json?page=2"
|
||||
}
|
||||
JSON
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "answers record" do
|
||||
expect(endpoint.call.success).to match(
|
||||
TRMNL::API::Models::Recipe[
|
||||
data: [
|
||||
TRMNL::API::Models::Recipes::Entry[
|
||||
id: 1,
|
||||
name: "test",
|
||||
published_at: Time.parse("2026-01-02T03:04:05.000Z"),
|
||||
screenshot_url: "https://screens.trmnl.io/test.png",
|
||||
author: TRMNL::API::Models::Recipes::Author[
|
||||
keyname: "test",
|
||||
name: "Test",
|
||||
field_type: "author_bio",
|
||||
description_locales: {}
|
||||
],
|
||||
custom_fields: [],
|
||||
statistics: TRMNL::API::Models::Recipes::Statistics[installs: 1, forks: 2]
|
||||
]
|
||||
],
|
||||
total: 2,
|
||||
from: 1,
|
||||
to: 2,
|
||||
per_page: 25,
|
||||
current_page: 1,
|
||||
prev_page_url: nil,
|
||||
next_page_url: "/recipes.json?page=2"
|
||||
]
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context "with failure" do
|
||||
let :http do
|
||||
HTTP::Fake::Client.new do
|
||||
get "/recipes.json" 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 "has inspected attributes" do
|
||||
expect(described_class.new.inspect).to match_inspection(contract: "Dry::Schema::JSON")
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user