
RedirectTest.pudu
Pudu33 lines3.4 KB
1/** @Test.Domain.Redirect.Suite — which redirects are followed, and how the request changes */2module PuduLangHttpClient.Domain.RedirectTest34import Std.Http as Http5import Std.Io as Io6import Std.Test as Test7import PuduLangHttpClient.Domain.Redirect as Redirect8910fn main() -> Int {11 let from = "https://a.test/x/y?q#f"12 let checks = Test.suite("Domain.Redirect", &[13 Test.equals("every redirect status is one and no other", &[200, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309].filter(|code: Int| Redirect.isRedirect(code)), &[300, 301, 302, 303, 307, 308]),14 Test.equals("a relative location resolves against the request and drops its fragment", &Redirect.next(&Http.Get, 302, from, "z#frag"), &Some(Redirect.Hop{method: Http.Get, uri: "https://a.test/x/z", keepsBody: true, keepsCredentials: true})),15 Test.equals("a see-other turns a put into a get without a body", &Redirect.next(&Http.Put, 303, from, "/done"), &Some(Redirect.Hop{method: Http.Get, uri: "https://a.test/done", keepsBody: false, keepsCredentials: true})),16 Test.equals("a see-other keeps a head", &Redirect.next(&Http.Head, 303, from, "/done"), &Some(Redirect.Hop{method: Http.Head, uri: "https://a.test/done", keepsBody: true, keepsCredentials: true})),17 Test.equals("a moved, found, or multiple-choices turns a post into a get", &[300, 301, 302].map(|code: Int| Redirect.next(&Http.Post, code, from, "/n")), &[300, 301, 302].map(|_c: Int| Some(Redirect.Hop{method: Http.Get, uri: "https://a.test/n", keepsBody: false, keepsCredentials: true}))),18 Test.equals("a moved or found keeps a put", &Redirect.next(&Http.Put, 301, from, "/n"), &Some(Redirect.Hop{method: Http.Put, uri: "https://a.test/n", keepsBody: true, keepsCredentials: true})),19 Test.equals("a temporary or permanent redirect keeps a post and its body", &[307, 308].map(|code: Int| Redirect.next(&Http.Post, code, from, "/n")), &[307, 308].map(|_c: Int| Some(Redirect.Hop{method: Http.Post, uri: "https://a.test/n", keepsBody: true, keepsCredentials: true}))),20 Test.equals("another origin loses the credentials", &Redirect.next(&Http.Get, 302, from, "https://b.test/"), &Some(Redirect.Hop{method: Http.Get, uri: "https://b.test/", keepsBody: true, keepsCredentials: false})),21 Test.equals("another port is another origin", &Redirect.next(&Http.Get, 302, "http://a.test/", "http://a.test:81/"), &Some(Redirect.Hop{method: Http.Get, uri: "http://a.test:81/", keepsBody: true, keepsCredentials: false})),22 Test.equals("plain to secured is followed", &Redirect.next(&Http.Get, 301, "http://a.test/", "https://a.test/"), &Some(Redirect.Hop{method: Http.Get, uri: "https://a.test/", keepsBody: true, keepsCredentials: false})),23 Test.equals("secured to plain is not followed", &Redirect.next(&Http.Get, 301, from, "http://a.test/"), &None),24 Test.equals("a location with spaces is escaped", &Redirect.next(&Http.Get, 302, from, " /a b "), &Some(Redirect.Hop{method: Http.Get, uri: "https://a.test/a%20b", keepsBody: true, keepsCredentials: true})),25 Test.equals("an empty location, another scheme, or a status that does not redirect is not followed", &[Redirect.next(&Http.Get, 302, from, " "), Redirect.next(&Http.Get, 302, from, "ftp://a/"), Redirect.next(&Http.Get, 304, from, "/x"), Redirect.next(&Http.Get, 302, "/relative", "/x")], &[None, None, None, None])26 ])27 let ran = Test.run(&checks)28 for failure in Test.failuresOf(&ran) {29 let _reported = Io.writeErrorLine(failure)30 }31 Test.report(&ran)32}33