@@ -79,4 +79,197 @@ defmodule Tesla.Middleware.BaseUrlTest do
7979 assert { :ok , env } = @ middleware . call ( % Env { url: "HTTPS://other.foo" } , [ ] , "http://example.com" )
8080 assert env . url == "HTTPS://other.foo"
8181 end
82+
83+ test "strict policy: prepend base url even with http scheme" do
84+ assert { :ok , env } =
85+ @ middleware . call (
86+ % Env { url: "http://other.foo" } ,
87+ [ ] ,
88+ base_url: "http://example.com" ,
89+ policy: :strict
90+ )
91+
92+ assert env . url == "http://example.com/http://other.foo"
93+ end
94+
95+ test "strict policy: prepend base url even with https scheme" do
96+ assert { :ok , env } =
97+ @ middleware . call (
98+ % Env { url: "https://other.foo" } ,
99+ [ ] ,
100+ base_url: "http://example.com" ,
101+ policy: :strict
102+ )
103+
104+ assert env . url == "http://example.com/https://other.foo"
105+ end
106+
107+ test "strict policy: still works with relative paths" do
108+ assert { :ok , env } =
109+ @ middleware . call ( % Env { url: "/path" } , [ ] ,
110+ base_url: "http://example.com" ,
111+ policy: :strict
112+ )
113+
114+ assert env . url == "http://example.com/path"
115+ end
116+
117+ test "strict policy: case insensitive scheme detection" do
118+ assert { :ok , env } =
119+ @ middleware . call (
120+ % Env { url: "HTTP://other.foo" } ,
121+ [ ] ,
122+ base_url: "http://example.com" ,
123+ policy: :strict
124+ )
125+
126+ assert env . url == "http://example.com/HTTP://other.foo"
127+
128+ assert { :ok , env } =
129+ @ middleware . call (
130+ % Env { url: "HTTPS://other.foo" } ,
131+ [ ] ,
132+ base_url: "http://example.com" ,
133+ policy: :strict
134+ )
135+
136+ assert env . url == "http://example.com/HTTPS://other.foo"
137+ end
138+
139+ test "default policy (no policy): respects permissive behavior" do
140+ assert { :ok , env } =
141+ @ middleware . call ( % Env { url: "http://other.foo" } , [ ] , base_url: "http://example.com" )
142+
143+ assert env . url == "http://other.foo"
144+ end
145+
146+ test "backward compatibility: string base url works with new implementation" do
147+ assert { :ok , env } = @ middleware . call ( % Env { url: "http://other.foo" } , [ ] , "http://example.com" )
148+ assert env . url == "http://other.foo"
149+
150+ assert { :ok , env } = @ middleware . call ( % Env { url: "/path" } , [ ] , "http://example.com" )
151+ assert env . url == "http://example.com/path"
152+ end
153+
154+ test "policy validation: accepts valid policy values" do
155+ assert { :ok , env } =
156+ @ middleware . call (
157+ % Env { url: "http://other.foo" } ,
158+ [ ] ,
159+ base_url: "http://example.com" ,
160+ policy: :strict
161+ )
162+
163+ assert env . url == "http://example.com/http://other.foo"
164+
165+ assert { :ok , env } =
166+ @ middleware . call (
167+ % Env { url: "http://other.foo" } ,
168+ [ ] ,
169+ base_url: "http://example.com" ,
170+ policy: :insecure
171+ )
172+
173+ assert env . url == "http://other.foo"
174+ end
175+
176+ test "policy validation: raises error for invalid policy values" do
177+ assert_raise ArgumentError , "invalid policy :strikt, expected :strict or :insecure" , fn ->
178+ @ middleware . call (
179+ % Env { url: "http://other.foo" } ,
180+ [ ] ,
181+ base_url: "http://example.com" ,
182+ policy: :strikt
183+ )
184+ end
185+
186+ assert_raise ArgumentError , "invalid policy :secure, expected :strict or :insecure" , fn ->
187+ @ middleware . call (
188+ % Env { url: "http://other.foo" } ,
189+ [ ] ,
190+ base_url: "http://example.com" ,
191+ policy: :secure
192+ )
193+ end
194+
195+ assert_raise ArgumentError , "invalid policy \" strict\" , expected :strict or :insecure" , fn ->
196+ @ middleware . call (
197+ % Env { url: "http://other.foo" } ,
198+ [ ] ,
199+ base_url: "http://example.com" ,
200+ policy: "strict"
201+ )
202+ end
203+
204+ assert_raise ArgumentError , "invalid policy 123, expected :strict or :insecure" , fn ->
205+ @ middleware . call (
206+ % Env { url: "http://other.foo" } ,
207+ [ ] ,
208+ base_url: "http://example.com" ,
209+ policy: 123
210+ )
211+ end
212+ end
213+
214+ test "edge case: empty string base_url" do
215+ assert { :ok , env } = @ middleware . call ( % Env { url: "/path" } , [ ] , "" )
216+ assert env . url == "/path"
217+
218+ assert { :ok , env } = @ middleware . call ( % Env { url: "path" } , [ ] , "" )
219+ assert env . url == "path"
220+
221+ assert { :ok , env } = @ middleware . call ( % Env { url: "" } , [ ] , "" )
222+ assert env . url == ""
223+
224+ assert { :ok , env } = @ middleware . call ( % Env { url: "http://example.com" } , [ ] , "" )
225+ assert env . url == "http://example.com"
226+
227+ assert { :ok , env } = @ middleware . call ( % Env { url: "/path" } , [ ] , base_url: "" )
228+ assert env . url == "/path"
229+ end
230+
231+ test "edge case: empty string base_url with strict policy" do
232+ assert { :ok , env } =
233+ @ middleware . call (
234+ % Env { url: "http://example.com" } ,
235+ [ ] ,
236+ base_url: "" ,
237+ policy: :strict
238+ )
239+
240+ assert env . url == "http://example.com"
241+
242+ assert { :ok , env } =
243+ @ middleware . call (
244+ % Env { url: "/path" } ,
245+ [ ] ,
246+ base_url: "" ,
247+ policy: :strict
248+ )
249+
250+ assert env . url == "/path"
251+ end
252+
253+ test "error handling: invalid base_url types" do
254+ assert_raise ArgumentError , "base_url must be a string but got nil" , fn ->
255+ @ middleware . call ( % Env { url: "/path" } , [ ] , base_url: nil )
256+ end
257+
258+ assert_raise ArgumentError , "base_url must be a string but got :invalid" , fn ->
259+ @ middleware . call ( % Env { url: "/path" } , [ ] , base_url: :invalid )
260+ end
261+
262+ assert_raise ArgumentError , "base_url must be a string but got 123" , fn ->
263+ @ middleware . call ( % Env { url: "/path" } , [ ] , base_url: 123 )
264+ end
265+
266+ # Missing :base_url key (same error as nil)
267+ assert_raise ArgumentError , "base_url must be a string but got nil" , fn ->
268+ @ middleware . call ( % Env { url: "/path" } , [ ] , policy: :strict )
269+ end
270+
271+ assert_raise ArgumentError , "base_url must be a string but got nil" , fn ->
272+ @ middleware . call ( % Env { url: "/path" } , [ ] , [ ] )
273+ end
274+ end
82275end
0 commit comments