File: formdata_spec.cr

package info (click to toggle)
crystal 1.14.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, trixie
  • size: 24,384 kB
  • sloc: javascript: 6,400; sh: 695; makefile: 269; ansic: 121; python: 105; cpp: 77; xml: 32
file content (122 lines) | stat: -rw-r--r-- 3,690 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
require "spec"
require "http/formdata"
require "http/server/response"

describe HTTP::FormData do
  describe ".parse(IO, String)" do
    it "parses formdata" do
      formdata = <<-FORMDATA
        --foo
        Content-Disposition: form-data; name="foo"

        bar
        --foo--
        FORMDATA

      res = nil
      HTTP::FormData.parse(IO::Memory.new(formdata.gsub('\n', "\r\n")), "foo") do |part|
        res = part.body.gets_to_end if part.name == "foo"
      end
      res.should eq("bar")
    end
  end

  describe ".parse(HTTP::Request)" do
    it "parses formdata" do
      formdata = <<-FORMDATA
        --foo
        Content-Disposition: form-data; name="foo"

        bar
        --foo--
        FORMDATA
      headers = HTTP::Headers{"Content-Type" => "multipart/form-data; boundary=foo"}
      request = HTTP::Request.new("GET", "/", headers, formdata.gsub('\n', "\r\n"))

      res = nil
      HTTP::FormData.parse(request) do |part|
        res = part.body.gets_to_end if part.name == "foo"
      end
      res.should eq("bar")
    end

    it "raises on empty body" do
      headers = HTTP::Headers{"Content-Type" => "multipart/form-data; boundary=foo"}
      req = HTTP::Request.new("GET", "/", headers)
      expect_raises(HTTP::FormData::Error, "body is empty") do
        HTTP::FormData.parse(req) { }
      end
    end

    it "raises on no Content-Type" do
      req = HTTP::Request.new("GET", "/", body: "")
      expect_raises(HTTP::FormData::Error, "could not find boundary in Content-Type") do
        HTTP::FormData.parse(req) { }
      end
    end

    it "raises on invalid Content-Type" do
      headers = HTTP::Headers{"Content-Type" => "multipart/form-data; boundary="}
      req = HTTP::Request.new("GET", "/", headers, body: "")
      expect_raises(HTTP::FormData::Error, "could not find boundary in Content-Type") do
        HTTP::FormData.parse(req) { }
      end
    end
  end

  describe ".parse_content_disposition(String)" do
    it "parses all Content-Disposition fields" do
      name, meta = HTTP::FormData.parse_content_disposition %q(form-data; name=foo; filename="foo\"\\bar\ baz\\"; creation-date="Wed, 12 Feb 1997 16:29:51 -0500"; modification-date="12 Feb 1997 16:29:51 -0500"; read-date="Wed, 12 Feb 1997 16:29:51 -0500"; size=432334)

      name.should eq("foo")
      meta.filename.should eq(%q(foo"\bar baz\))
      meta.creation_time.should eq(Time.utc(1997, 2, 12, 21, 29, 51, nanosecond: 0))
      meta.modification_time.should eq(Time.utc(1997, 2, 12, 21, 29, 51, nanosecond: 0))
      meta.read_time.should eq(Time.utc(1997, 2, 12, 21, 29, 51, nanosecond: 0))
      meta.size.should eq(432334)
    end
  end

  describe ".build(IO, String)" do
    it "builds a message" do
      io = IO::Memory.new
      HTTP::FormData.build(io, "boundary") do |g|
        g.field("foo", "bar")
      end

      expected = <<-MULTIPART
        --boundary
        Content-Disposition: form-data; name="foo"

        bar
        --boundary--
        MULTIPART
      io.to_s.should eq(expected.gsub('\n', "\r\n"))
    end
  end

  describe ".build(HTTP::Server::Response, String)" do
    it "builds a message" do
      io = IO::Memory.new
      response = HTTP::Server::Response.new(io)
      HTTP::FormData.build(response, "boundary") do |g|
        g.field("foo", "bar")
      end
      response.close

      expected = <<-MULTIPART
        HTTP/1.1 200 OK
        Content-Type: multipart/form-data; boundary="boundary"
        Content-Length: 75

        --boundary
        Content-Disposition: form-data; name="foo"

        bar
        --boundary--
        MULTIPART

      io.to_s.should eq(expected.gsub('\n', "\r\n"))
    end
  end
end