33require "rails_helper"
44
55module Alchemy
6- RSpec . describe WildcardUrlMatcher do
6+ RSpec . describe PageFinder do
77 let ( :language ) { create ( :alchemy_language ) }
88 let! ( :language_root ) do
99 create ( :alchemy_page , :language_root , language : language )
@@ -48,70 +48,77 @@ def create_page(name:, layout: "standard", parent: language_root)
4848 let! ( :users_page ) { create_page ( name : "Users" ) }
4949 let! ( :user_profile_page ) { create_page ( name : "User Profile" , layout : "user_profile" , parent : users_page ) }
5050
51+ let ( :params ) { ActionController ::Parameters . new }
52+
5153 it "defaults to Current.language.root_page" do
52- matcher = described_class . new . call ( "products/123" )
53- expect ( matcher . page ) . to eq ( product_detail_page )
54- expect ( matcher . params [ :id ] ) . to eq ( "123" )
54+ page = described_class . new ( params : params ) . call ( "products/123" )
55+ expect ( page ) . to eq ( product_detail_page )
56+ expect ( params [ :id ] ) . to eq ( "123" )
57+ end
58+
59+ it "finds a page by exact urlname" do
60+ page = described_class . new ( params : params ) . call ( "products" )
61+ expect ( page ) . to eq ( products_page )
5562 end
5663
5764 it "returns nil when the parent page is nil" do
58- expect ( described_class . new ( nil ) . call ( "products/123" ) . page ) . to be_nil
65+ expect ( described_class . new ( nil , params : params ) . call ( "products/123" ) ) . to be_nil
5966 end
6067
6168 it "returns nil for a blank path" do
62- expect ( described_class . new ( language_root ) . call ( "" ) . page ) . to be_nil
69+ expect ( described_class . new ( language_root , params : params ) . call ( "" ) ) . to be_nil
6370 end
6471
6572 it "returns nil for a path with no matching prefix" do
66- expect ( described_class . new ( language_root ) . call ( "other/123" ) . page ) . to be_nil
73+ expect ( described_class . new ( language_root , params : params ) . call ( "other/123" ) ) . to be_nil
6774 end
6875
6976 context "single-segment pattern with integer constraint" do
7077 it "matches /products/123" do
71- matcher = described_class . new ( language_root ) . call ( "products/123" )
72- expect ( matcher . page ) . to eq ( product_detail_page )
73- expect ( matcher . params [ :id ] ) . to eq ( "123" )
78+ page = described_class . new ( language_root , params : params ) . call ( "products/123" )
79+ expect ( page ) . to eq ( product_detail_page )
80+ expect ( params [ :id ] ) . to eq ( "123" )
7481 end
7582
7683 it "rejects non-integer and falls through to unconstrained sibling" do
77- matcher = described_class . new ( language_root ) . call ( "products/some-slug" )
78- expect ( matcher . page ) . to eq ( product_by_slug_page )
79- expect ( matcher . params [ :slug ] ) . to eq ( "some-slug" )
84+ page = described_class . new ( language_root , params : params ) . call ( "products/some-slug" )
85+ expect ( page ) . to eq ( product_by_slug_page )
86+ expect ( params [ :slug ] ) . to eq ( "some-slug" )
8087 end
8188 end
8289
8390 context "multi-segment pattern" do
8491 it "matches /blog/2024/my-post and extracts both params" do
85- matcher = described_class . new ( language_root ) . call ( "blog/2024/my-post" )
86- expect ( matcher . page ) . to eq ( blog_post_page )
87- expect ( matcher . params [ :year ] ) . to eq ( "2024" )
88- expect ( matcher . params [ :slug ] ) . to eq ( "my-post" )
92+ page = described_class . new ( language_root , params : params ) . call ( "blog/2024/my-post" )
93+ expect ( page ) . to eq ( blog_post_page )
94+ expect ( params [ :year ] ) . to eq ( "2024" )
95+ expect ( params [ :slug ] ) . to eq ( "my-post" )
8996 end
9097
9198 it "does not match with wrong segment count" do
92- expect ( described_class . new ( language_root ) . call ( "blog/2024" ) . page ) . to be_nil
99+ expect ( described_class . new ( language_root , params : params ) . call ( "blog/2024" ) ) . to be_nil
93100 end
94101 end
95102
96103 context "pattern with static segments" do
97104 let ( :uuid ) { "550e8400-e29b-41d4-a716-446655440000" }
98105
99106 it "matches /users/:uuid/profile" do
100- matcher = described_class . new ( language_root ) . call ( "users/#{ uuid } /profile" )
101- expect ( matcher . page ) . to eq ( user_profile_page )
102- expect ( matcher . params [ :uuid ] ) . to eq ( uuid )
107+ page = described_class . new ( language_root , params : params ) . call ( "users/#{ uuid } /profile" )
108+ expect ( page ) . to eq ( user_profile_page )
109+ expect ( params [ :uuid ] ) . to eq ( uuid )
103110 end
104111
105112 it "does not match without the trailing static segment" do
106- expect ( described_class . new ( language_root ) . call ( "users/#{ uuid } " ) . page ) . to be_nil
113+ expect ( described_class . new ( language_root , params : params ) . call ( "users/#{ uuid } " ) ) . to be_nil
107114 end
108115 end
109116
110117 context "hierarchical patterns (grandchild under pattern page)" do
111118 it "matches /products/42/comments through the pattern parent" do
112- matcher = described_class . new ( language_root ) . call ( "products/42/comments" )
113- expect ( matcher . page ) . to eq ( comments_page )
114- expect ( matcher . params [ :id ] ) . to eq ( "42" )
119+ page = described_class . new ( language_root , params : params ) . call ( "products/42/comments" )
120+ expect ( page ) . to eq ( comments_page )
121+ expect ( params [ :id ] ) . to eq ( "42" )
115122 end
116123 end
117124
@@ -122,10 +129,10 @@ def create_page(name:, layout: "standard", parent: language_root)
122129 let! ( :child_of_single ) { create_page ( name : "My Post" , parent : single_segment_page ) }
123130
124131 it "matches the first pattern sibling even when the other could also match via its child" do
125- matcher = described_class . new ( language_root ) . call ( "shared/2024/my-post" )
126- expect ( matcher . page ) . to eq ( multi_segment_page )
127- expect ( matcher . params [ :year ] ) . to eq ( "2024" )
128- expect ( matcher . params [ :slug ] ) . to eq ( "my-post" )
132+ page = described_class . new ( language_root , params : params ) . call ( "shared/2024/my-post" )
133+ expect ( page ) . to eq ( multi_segment_page )
134+ expect ( params [ :year ] ) . to eq ( "2024" )
135+ expect ( params [ :slug ] ) . to eq ( "my-post" )
129136 end
130137 end
131138
@@ -134,13 +141,13 @@ def create_page(name:, layout: "standard", parent: language_root)
134141 let! ( :sku_page ) { create_page ( name : "SKU Lookup" , layout : "product_by_sku" , parent : warehouse_page ) }
135142
136143 it "matches when the value satisfies the regex" do
137- matcher = described_class . new ( language_root ) . call ( "warehouse/AB-1234" )
138- expect ( matcher . page ) . to eq ( sku_page )
139- expect ( matcher . params [ :sku ] ) . to eq ( "AB-1234" )
144+ page = described_class . new ( language_root , params : params ) . call ( "warehouse/AB-1234" )
145+ expect ( page ) . to eq ( sku_page )
146+ expect ( params [ :sku ] ) . to eq ( "AB-1234" )
140147 end
141148
142149 it "does not match when the value violates the regex" do
143- expect ( described_class . new ( language_root ) . call ( "warehouse/invalid" ) . page ) . to be_nil
150+ expect ( described_class . new ( language_root , params : params ) . call ( "warehouse/invalid" ) ) . to be_nil
144151 end
145152 end
146153 end
0 commit comments