Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions spec/lib/tiny_admin/configure_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# frozen_string_literal: true

require "dummy_rails_app"
require "rails_helper"

RSpec.describe "TinyAdmin.configure" do # rubocop:disable RSpec/DescribeClass
let(:settings) { TinyAdmin::Settings.instance }

around do |example|
saved = settings.instance_variable_get(:@options)&.deep_dup
saved_store = settings.instance_variable_get(:@store)
saved_loaded = settings.instance_variable_get(:@loaded)
example.run
ensure
settings.instance_variable_set(:@options, saved)
settings.instance_variable_set(:@store, saved_store)
settings.instance_variable_set(:@loaded, saved_loaded)
end

it "yields settings to the block" do
yielded = nil
TinyAdmin.configure { |s| yielded = s }
expect(yielded).to eq(settings)
end

it "allows setting options via the block" do
TinyAdmin.configure { |s| s.root_path = "/custom" }
expect(settings.root_path).to eq("/custom")
end

it "returns settings when no block is given" do
result = TinyAdmin.configure
expect(result).to eq(settings)
end
end
65 changes: 65 additions & 0 deletions spec/lib/tiny_admin/utils_prepare_page_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# frozen_string_literal: true

require "dummy_rails_app"
require "rails_helper"

RSpec.describe TinyAdmin::Utils, "#prepare_page" do
let(:utils_instance) { Class.new { include TinyAdmin::Utils }.new }
let(:settings) { TinyAdmin::Settings.instance }

around do |example|
saved = settings.instance_variable_get(:@options)&.deep_dup
saved_store = settings.instance_variable_get(:@store)
saved_loaded = settings.instance_variable_get(:@loaded)
settings.load_settings
example.run
ensure
settings.instance_variable_set(:@options, saved)
settings.instance_variable_set(:@store, saved_store)
settings.instance_variable_set(:@loaded, saved_loaded)
end

it "returns an instance of the given page class" do
page = utils_instance.prepare_page(TinyAdmin::Views::Pages::Root)
expect(page).to be_a(TinyAdmin::Views::Pages::Root)
end

it "assigns head, flash, and navbar components", :aggregate_failures do
page = utils_instance.prepare_page(TinyAdmin::Views::Pages::Root)
expect(page.head_component).to be_a(TinyAdmin::Views::Components::Head)
expect(page.flash_component).to be_a(TinyAdmin::Views::Components::Flash)
expect(page.navbar_component).to be_a(TinyAdmin::Views::Components::Navbar)
end

it "sets the page title from attributes" do
page = utils_instance.prepare_page(TinyAdmin::Views::Pages::Root, attributes: { title: "My Title" })
expect(page.title).to eq("My Title")
end

it "sets params on the page" do
page = utils_instance.prepare_page(TinyAdmin::Views::Pages::Root, params: { "page" => "2" })
expect(page.params).to eq({ "page" => "2" })
end

it "passes no_menu option to hide navbar items" do
page = utils_instance.prepare_page(TinyAdmin::Views::Pages::Root, options: [:no_menu])
expect(page.navbar_component.items).to eq([])
end

it "yields the page to the block when given" do
yielded = nil
utils_instance.prepare_page(TinyAdmin::Views::Pages::Root) { |p| yielded = p }
expect(yielded).to be_a(TinyAdmin::Views::Pages::Root)
end

it "resolves widget class names from strings" do
widget_class = Class.new(Phlex::HTML) do
def view_template
plain "test"
end
end
stub_const("TestWidget", widget_class)
page = utils_instance.prepare_page(TinyAdmin::Views::Pages::Root, attributes: { widgets: ["TestWidget"] })
expect(page.widgets).to eq([TestWidget])
end
end
43 changes: 43 additions & 0 deletions spec/lib/tiny_admin/views/components/field_value_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# frozen_string_literal: true

require "dummy_rails_app"
require "rails_helper"

RSpec.describe TinyAdmin::Views::Components::FieldValue do
let(:settings) { TinyAdmin::Settings.instance }

before { settings.load_settings }

describe "with a basic field" do
let(:field) { TinyAdmin::Field.new(name: "title", type: :string, title: "Title", options: {}) }
let(:record) { double("record", id: 1) } # rubocop:disable RSpec/VerifiedDoubles

it "renders the translated value in a span", :aggregate_failures do
html = described_class.new(field, "Hello", record: record).call
expect(html).to include("Hello")
expect(html).to include("<span")
end
end

describe "with link_to option" do
let(:field) { TinyAdmin::Field.new(name: "author_id", type: :integer, title: "Author", options: { link_to: "authors" }) }
let(:record) { double("record", id: 1) } # rubocop:disable RSpec/VerifiedDoubles

it "wraps the value in a link", :aggregate_failures do
html = described_class.new(field, "42", record: record).call
expect(html).to include("<a")
expect(html).to include("authors")
expect(html).to include("42")
end
end

describe "with value_class option" do
let(:field) { TinyAdmin::Field.new(name: "status", type: :string, title: "Status", options: { options: ["value_class"] }) }
let(:record) { double("record", id: 1) } # rubocop:disable RSpec/VerifiedDoubles

it "adds value-based CSS class to the span" do
html = described_class.new(field, "active", record: record).call
expect(html).to include("value-active")
end
end
end
90 changes: 90 additions & 0 deletions spec/lib/tiny_admin/views/components/filters_form_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# frozen_string_literal: true

require "dummy_rails_app"
require "rails_helper"

RSpec.describe TinyAdmin::Views::Components::FiltersForm do
let(:component) { described_class.new }

before do
TinyAdmin::Settings.instance.load_settings
component.update_attributes(section_path: "/admin/posts", filters: filters)
end

describe "with a boolean filter" do
let(:field) { TinyAdmin::Field.new(name: "published", type: :boolean, title: "Published", options: {}) }
let(:filters) { { field => { filter: { type: :boolean }, value: "1" } } }

it "renders a select with true/false options", :aggregate_failures do
html = component.call
expect(html).to include("form-select")
expect(html).to include("true")
expect(html).to include("false")
end
end

describe "with a date filter" do
let(:field) { TinyAdmin::Field.new(name: "created_at", type: :date, title: "Created At", options: {}) }
let(:filters) { { field => { filter: { type: :date }, value: "2024-01-01" } } }

it "renders a date input", :aggregate_failures do
html = component.call
expect(html).to include('type="date"')
expect(html).to include("2024-01-01")
end
end

describe "with a datetime filter" do
let(:field) { TinyAdmin::Field.new(name: "updated_at", type: :datetime, title: "Updated At", options: {}) }
let(:filters) { { field => { filter: { type: :datetime }, value: "2024-01-01T12:00" } } }

it "renders a datetime-local input" do
html = component.call
expect(html).to include('type="datetime-local"')
end
end

describe "with an integer filter" do
let(:field) { TinyAdmin::Field.new(name: "age", type: :integer, title: "Age", options: {}) }
let(:filters) { { field => { filter: { type: :integer }, value: "25" } } }

it "renders a number input" do
html = component.call
expect(html).to include('type="number"')
end
end

describe "with a select filter" do
let(:field) { TinyAdmin::Field.new(name: "state", type: :select, title: "State", options: {}) }
let(:filters) { { field => { filter: { type: :select, values: %w[available unavailable] }, value: "available" } } }

it "renders a select with the provided values", :aggregate_failures do
html = component.call
expect(html).to include("form-select")
expect(html).to include("available")
expect(html).to include("unavailable")
end
end

describe "with a text filter (default)" do
let(:field) { TinyAdmin::Field.new(name: "title", type: :string, title: "Title", options: {}) }
let(:filters) { { field => { filter: {}, value: "hello" } } }

it "renders a text input", :aggregate_failures do
html = component.call
expect(html).to include('type="text"')
expect(html).to include("hello")
end
end

describe "action buttons" do
let(:field) { TinyAdmin::Field.new(name: "title", type: :string, title: "Title", options: {}) }
let(:filters) { { field => { filter: {}, value: "" } } }

it "renders Clear and Filter buttons", :aggregate_failures do
html = component.call
expect(html).to include("Clear")
expect(html).to include("Filter")
end
end
end
43 changes: 43 additions & 0 deletions spec/lib/tiny_admin/views/components/widgets_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# frozen_string_literal: true

require "dummy_rails_app"
require "rails_helper"

RSpec.describe TinyAdmin::Views::Components::Widgets do
describe "with nil widgets" do
it "renders nothing" do
html = described_class.new(nil).call
expect(html).to eq("")
end
end

describe "with empty widgets" do
it "renders nothing" do
html = described_class.new([]).call
expect(html).to eq("")
end
end

describe "with valid widget classes" do
let(:widget_class) do
Class.new(Phlex::HTML) do
def view_template
plain "Widget content"
end
end
end

it "renders each widget in a card", :aggregate_failures do
html = described_class.new([widget_class]).call
expect(html).to include("Widget content")
expect(html).to include("card-body")
end
end

describe "with non-Phlex widget" do
it "skips non-Phlex classes" do
html = described_class.new([String]).call
expect(html).not_to include("card-body")
end
end
end
Loading