aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/test/controller/webservice_test.rb
blob: b26f037c3679f6fb874bbdf7d675238ad9033b59 (plain) (blame)
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
require 'abstract_unit'
require 'active_support/json/decoding'

class WebServiceTest < ActionDispatch::IntegrationTest
  class TestController < ActionController::Base
    def assign_parameters
      if params[:full]
        render plain: dump_params_keys
      else
        render plain: (params.keys - ['controller', 'action']).sort.join(", ")
      end
    end

    def dump_params_keys(hash = params)
      hash.keys.sort.inject("") do |s, k|
        value = hash[k]

        if value.is_a?(Hash) || value.is_a?(ActionController::Parameters)
          value = "(#{dump_params_keys(value)})"
        else
          value = ""
        end

        s << ", " unless s.empty?
        s << "#{k}#{value}"
      end
    end
  end

  def setup
    @controller = TestController.new
    @integration_session = nil
  end

  def test_check_parameters
    with_test_route_set do
      get "/"
      assert_equal '', @controller.response.body
    end
  end

  def test_post_json
    with_test_route_set do
      post "/",
        params: '{"entry":{"summary":"content..."}}',
        headers: { 'CONTENT_TYPE' => 'application/json' }

      assert_equal 'entry', @controller.response.body
      assert @controller.params.has_key?(:entry)
      assert_equal 'content...', @controller.params["entry"]['summary']
    end
  end

  def test_put_json
    with_test_route_set do
      put "/",
        params: '{"entry":{"summary":"content..."}}',
        headers: { 'CONTENT_TYPE' => 'application/json' }

      assert_equal 'entry', @controller.response.body
      assert @controller.params.has_key?(:entry)
      assert_equal 'content...', @controller.params["entry"]['summary']
    end
  end

  def test_register_and_use_json_simple
    with_test_route_set do
      with_params_parsers Mime::JSON => Proc.new { |data| ActiveSupport::JSON.decode(data)['request'].with_indifferent_access } do
        post "/",
          params: '{"request":{"summary":"content...","title":"JSON"}}',
          headers: { 'CONTENT_TYPE' => 'application/json' }

        assert_equal 'summary, title', @controller.response.body
        assert @controller.params.has_key?(:summary)
        assert @controller.params.has_key?(:title)
        assert_equal 'content...', @controller.params["summary"]
        assert_equal 'JSON', @controller.params["title"]
      end
    end
  end

  def test_use_json_with_empty_request
    with_test_route_set do
      assert_nothing_raised { post "/", headers: { 'CONTENT_TYPE' => 'application/json' } }
      assert_equal '', @controller.response.body
    end
  end

  def test_dasherized_keys_as_json
    with_test_route_set do
      post "/?full=1",
        params: '{"first-key":{"sub-key":"..."}}',
        headers: { 'CONTENT_TYPE' => 'application/json' }
      assert_equal 'action, controller, first-key(sub-key), full', @controller.response.body
      assert_equal "...", @controller.params['first-key']['sub-key']
    end
  end

  def test_parsing_json_doesnot_rescue_exception
    with_test_route_set do
      with_params_parsers Mime::JSON => Proc.new { |data| raise Interrupt } do
        assert_raises(Interrupt) do
          post "/",
            params: '{"title":"JSON"}}',
            headers: { 'CONTENT_TYPE' => 'application/json' }
        end
      end
    end
  end

  private
    def with_params_parsers(parsers = {})
      old_session = @integration_session
      @app = ActionDispatch::ParamsParser.new(app.routes, parsers)
      reset!
      yield
    ensure
      @integration_session = old_session
    end

    def with_test_route_set
      with_routing do |set|
        set.draw do
          match '/', :to => 'web_service_test/test#assign_parameters', :via => :all
        end
        yield
      end
    end
end