summaryrefslogtreecommitdiff
path: root/test/elixir/test/jsonp_test.exs
blob: 3fdc2ba5fc67fcd94a694a7b8620bd182af879ad (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
defmodule JsonpTest do
  use CouchTestCase

  @moduletag :jsonp

  @tag :with_db
  test "jsonp not configured callbacks", context do
    db_name = context[:db_name]
    {:ok, _} = create_doc(db_name, %{_id: "0", a: 0, b: 0})

    resp = Couch.get("/#{db_name}/0?callback=jsonp_no_chunk")
    assert resp.status_code == 200
    assert resp.headers.hdrs["content-type"] == "application/json"
  end

  @tag :with_db
  test "jsonp unchunked callbacks", context do
    db_name = context[:db_name]

    server_config = [
      %{
        :section => "httpd",
        :key => "allow_jsonp",
        :value => "true"
      }
    ]

    {:ok, create_resp} = create_doc(db_name, %{_id: "0", a: 0, b: 0})

    run_on_modified_server(server_config, fn ->
      resp = Couch.get("/#{db_name}/0?callback=jsonp_no_chunk")

      assert resp.status_code == 200
      assert resp.headers.hdrs["content-type"] == "application/javascript"

      {callback_fun, callback_param} = parse_callback(resp.body)

      assert callback_fun == "jsonp_no_chunk"
      assert create_resp.body["id"] == callback_param["_id"]
      assert create_resp.body["rev"] == callback_param["_rev"]

      resp = Couch.get("/#{db_name}/0?callback=jsonp_no_chunk\"")
      assert resp.status_code == 400
    end)
  end

  @tag :with_db
  test "jsonp chunked callbacks", context do
    db_name = context[:db_name]

    server_config = [
      %{
        :section => "httpd",
        :key => "allow_jsonp",
        :value => "true"
      }
    ]

    design_doc = %{
      _id: "_design/test",
      language: "javascript",
      views: %{
        all_docs: %{map: "function(doc) {if(doc.a) emit(null, doc.a);}"}
      }
    }

    {:ok, _} = create_doc(db_name, design_doc)
    {:ok, _} = create_doc(db_name, %{_id: "0", a: 0, b: 0})
    {:ok, _} = create_doc(db_name, %{_id: "1", a: 1, b: 1})

    run_on_modified_server(server_config, fn ->
      resp = Couch.get("/#{db_name}/_design/test/_view/all_docs?callback=jsonp_chunk")
      assert resp.status_code == 200
      assert resp.headers.hdrs["content-type"] == "application/javascript"

      {callback_fun, callback_param} = parse_callback(resp.body)

      assert callback_fun == "jsonp_chunk"
      assert callback_param["total_rows"] == 1

      resp = Couch.get("/#{db_name}/_design/test/_view/all_docs?callback=jsonp_chunk'")
      assert resp.status_code == 400

      resp = Couch.get("/#{db_name}/_changes?callback=jsonp_chunk")
      assert resp.status_code == 200
      assert resp.headers.hdrs["content-type"] == "application/javascript"

      {callback_fun, callback_param} = parse_callback(resp.body)
      assert callback_fun == "jsonp_chunk"
      assert length(callback_param["results"]) == 3

    end)
  end

  defp parse_callback(msg) do
    captures = Regex.scan(~r/\/\* CouchDB \*\/(\w+)\((.*)\)/s, msg)

    callback_fun =
      captures
      |> Enum.map(fn p -> Enum.at(p, 1) end)
      |> Enum.at(0)

    param =
      captures
      |> Enum.map(fn p -> Enum.at(p, 2) end)
      |> Enum.filter(fn p -> String.trim(p) != "" end)
      |> Enum.map(fn p ->
        p
        |> IO.iodata_to_binary()
        |> :jiffy.decode([:return_maps])
      end)
      |> Enum.at(0)

    {callback_fun, param}
  end
end