summaryrefslogtreecommitdiff
path: root/test/elixir/test/attachment_ranges_test.exs
blob: de39836b02f42cf563200e1abc14a914944aec35 (plain)
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
defmodule AttachmentRangesTest do
  use CouchTestCase

  @moduletag :attachments
  @moduletag kind: :single_node

  @moduledoc """
  Test CouchDB attachment range requests
  This is a port of the attachment_ranges.js suite
  """

  @tag :with_db
  test "manages attachment range requests successfully", context do
    db_name = context[:db_name]

    bin_att_doc = %{
      _id: "bin_doc",
      _attachments: %{
        "foo.txt": %{
          content_type: "application/octet-stream",
          data: "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ="
        }
      }
    }

    create_doc(db_name, bin_att_doc)
    # Fetching the whole entity is a 206
    resp =
      Couch.get(
        "/#{db_name}/bin_doc/foo.txt",
        headers: [Range: "bytes=0-28"]
      )

    assert(resp.status_code == 206)
    assert resp.body == "This is a base64 encoded text"
    assert resp.headers["Content-Range"] == "bytes 0-28/29"
    assert resp.headers["Content-Length"] == "29"

    # Fetch the whole entity without an end offset is a 200
    resp =
      Couch.get(
        "/#{db_name}/bin_doc/foo.txt",
        headers: [Range: "bytes=0-"]
      )

    assert(resp.status_code == 200)
    assert resp.body == "This is a base64 encoded text"
    assert resp.headers["Content-Range"] == nil
    assert resp.headers["Content-Length"] == "29"

    # Even if you ask multiple times.
    resp =
      Couch.get(
        "/#{db_name}/bin_doc/foo.txt",
        headers: [Range: "bytes=0-,0-,0-"]
      )

    assert(resp.status_code == 200)

    # Badly formed range header is a 200
    resp =
      Couch.get(
        "/#{db_name}/bin_doc/foo.txt",
        headers: [Range: "bytes:0-"]
      )

    assert(resp.status_code == 200)

    # Fetch the end of an entity without an end offset is a 206
    resp =
      Couch.get(
        "/#{db_name}/bin_doc/foo.txt",
        headers: [Range: "bytes=2-"]
      )

    assert(resp.status_code == 206)
    assert resp.body == "is is a base64 encoded text"
    assert resp.headers["Content-Range"] == "bytes 2-28/29"
    assert resp.headers["Content-Length"] == "27"

    # Fetch first part of entity is a 206
    resp =
      Couch.get(
        "/#{db_name}/bin_doc/foo.txt",
        headers: [Range: "bytes=0-3"]
      )

    assert(resp.status_code == 206)
    assert resp.body == "This"
    assert resp.headers["Content-Range"] == "bytes 0-3/29"
    assert resp.headers["Content-Length"] == "4"

    # Fetch middle of entity is also a 206
    resp =
      Couch.get(
        "/#{db_name}/bin_doc/foo.txt",
        headers: [Range: "bytes=10-15"]
      )

    assert(resp.status_code == 206)
    assert resp.body == "base64"
    assert resp.headers["Content-Range"] == "bytes 10-15/29"
    assert resp.headers["Content-Length"] == "6"

    # Fetch end of entity is also a 206
    resp =
      Couch.get(
        "/#{db_name}/bin_doc/foo.txt",
        headers: [Range: "bytes=-3"]
      )

    assert(resp.status_code == 206)
    assert resp.body == "ext"
    assert resp.headers["Content-Range"] == "bytes 26-28/29"
    assert resp.headers["Content-Length"] == "3"

    # backward range is 416
    resp =
      Couch.get(
        "/#{db_name}/bin_doc/foo.txt",
        headers: [Range: "bytes=5-3"]
      )

    assert(resp.status_code == 416)

    # range completely outside of entity is 416
    resp =
      Couch.get(
        "/#{db_name}/bin_doc/foo.txt",
        headers: [Range: "bytes=300-310"]
      )

    assert(resp.status_code == 416)

    # We ignore a Range header with too many ranges
    resp =
      Couch.get(
        "/#{db_name}/bin_doc/foo.txt",
        headers: [Range: "bytes=0-1,0-1,0-1,0-1,0-1,0-1,0-1,0-1,0-1,0-1"]
      )

    assert(resp.status_code == 200)
  end
end