diff --git a/lib/trmnl/api/contracts/model.rb b/lib/trmnl/api/contracts/model.rb new file mode 100644 index 0000000..b3e9799 --- /dev/null +++ b/lib/trmnl/api/contracts/model.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +require "dry/schema" + +module TRMNL + module API + module Contracts + # Validates API response. + Model = Dry::Schema.JSON do + required(:data).array(:hash) do + required(:name).filled :string + required(:label).filled :string + required(:description).filled :string + required(:colors).filled :integer + required(:bit_depth).filled :integer + required(:scale_factor) { filled? > int? | float? } + required(:rotation).filled :integer + required(:mime_type).filled :string + required(:width).filled :integer + required(:height).filled :integer + required(:offset_x).filled :integer + required(:offset_y).filled :integer + required(:published_at).filled :time + end + end + end + end +end diff --git a/spec/lib/trmnl/api/contracts/model_spec.rb b/spec/lib/trmnl/api/contracts/model_spec.rb new file mode 100644 index 0000000..56dbcd5 --- /dev/null +++ b/spec/lib/trmnl/api/contracts/model_spec.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe TRMNL::API::Contracts::Model do + subject(:contract) { described_class } + + let :payload do + { + name: "test", + label: "Test", + description: "A test.", + colors: 2, + bit_depth: 1, + scale_factor: 1, + rotation: 90, + mime_type: "image/png", + width: 800, + height: 480, + offset_x: 10, + offset_y: 15, + published_at: "2025-07-16T18:18:11+00:00" + } + end + + describe "#call" do + it "validates scale factor is an integer" do + expect(contract.call(data: [payload]).to_monad).to be_success + end + + it "checks scale factor is a float" do + payload[:scale_factor] = 1.5 + expect(contract.call(data: [payload]).to_monad).to be_success + end + + it "answers failure when scale factor is missing" do + payload.delete :scale_factor + + expect(contract.call(data: [payload]).errors.to_h).to eq( + data: { + 0 => { + scale_factor: ["is missing"] + } + } + ) + end + end +end