summaryrefslogtreecommitdiffstats
path: root/spec/unit/network/http/api/v1_spec.rb
blob: d16ff122a608048db93bd0b4a21e9fb3be3efafe (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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
#!/usr/bin/env ruby

require 'spec_helper'

require 'puppet/network/http/api/v1'

class V1RestApiTester
  include Puppet::Network::HTTP::API::V1
end

describe Puppet::Network::HTTP::API::V1 do
  before do
    @tester = V1RestApiTester.new
  end

  it "should be able to convert a URI into a request" do
    @tester.should respond_to(:uri2indirection)
  end

  it "should be able to convert a request into a URI" do
    @tester.should respond_to(:indirection2uri)
  end

  describe "when converting a URI into a request" do
    before do
      @tester.stubs(:handler).returns "foo"
    end

    it "should require the http method, the URI, and the query parameters" do
      # Not a terribly useful test, but an important statement for the spec
      lambda { @tester.uri2indirection("/foo") }.should raise_error(ArgumentError)
    end

    it "should use the first field of the URI as the environment" do
      @tester.uri2indirection("GET", "/env/foo/bar", {})[3][:environment].should == "env"
    end

    it "should fail if the environment is not alphanumeric" do
      lambda { @tester.uri2indirection("GET", "/env ness/foo/bar", {}) }.should raise_error(ArgumentError)
    end

    it "should use the environment from the URI even if one is specified in the parameters" do
      @tester.uri2indirection("GET", "/env/foo/bar", {:environment => "otherenv"})[3][:environment].should == "env"
    end

    it "should use the second field of the URI as the indirection name" do
      @tester.uri2indirection("GET", "/env/foo/bar", {})[0].should == "foo"
    end

    it "should fail if the indirection name is not alphanumeric" do
      lambda { @tester.uri2indirection("GET", "/env/foo ness/bar", {}) }.should raise_error(ArgumentError)
    end

    it "should use the remainder of the URI as the indirection key" do
      @tester.uri2indirection("GET", "/env/foo/bar", {})[2].should == "bar"
    end

    it "should support the indirection key being a /-separated file path" do
      @tester.uri2indirection("GET", "/env/foo/bee/baz/bomb", {})[2].should == "bee/baz/bomb"
    end

    it "should fail if no indirection key is specified" do
      lambda { @tester.uri2indirection("GET", "/env/foo/", {}) }.should raise_error(ArgumentError)
      lambda { @tester.uri2indirection("GET", "/env/foo", {}) }.should raise_error(ArgumentError)
    end

    it "should choose 'find' as the indirection method if the http method is a GET and the indirection name is singular" do
      @tester.uri2indirection("GET", "/env/foo/bar", {})[1].should == :find
    end

    it "should choose 'find' as the indirection method if the http method is a POST and the indirection name is singular" do
      @tester.uri2indirection("POST", "/env/foo/bar", {})[1].should == :find
    end

    it "should choose 'head' as the indirection method if the http method is a HEAD and the indirection name is singular" do
      @tester.uri2indirection("HEAD", "/env/foo/bar", {})[1].should == :head
    end

    it "should choose 'search' as the indirection method if the http method is a GET and the indirection name is plural" do
      @tester.uri2indirection("GET", "/env/foos/bar", {})[1].should == :search
    end

    it "should choose 'find' as the indirection method if the http method is a GET and the indirection name is facts" do
      @tester.uri2indirection("GET", "/env/facts/bar", {})[1].should == :find
    end

    it "should choose 'save' as the indirection method if the http method is a PUT and the indirection name is facts" do
      @tester.uri2indirection("PUT", "/env/facts/bar", {})[1].should == :save
    end

    it "should choose 'search' as the indirection method if the http method is a GET and the indirection name is inventory" do
      @tester.uri2indirection("GET", "/env/inventory/search", {})[1].should == :search
    end

    it "should choose 'find' as the indirection method if the http method is a GET and the indirection name is facts" do
      @tester.uri2indirection("GET", "/env/facts/bar", {})[1].should == :find
    end

    it "should choose 'save' as the indirection method if the http method is a PUT and the indirection name is facts" do
      @tester.uri2indirection("PUT", "/env/facts/bar", {})[1].should == :save
    end

    it "should choose 'search' as the indirection method if the http method is a GET and the indirection name is inventory" do
      @tester.uri2indirection("GET", "/env/inventory/search", {})[1].should == :search
    end

    it "should choose 'search' as the indirection method if the http method is a GET and the indirection name is facts_search" do
      @tester.uri2indirection("GET", "/env/facts_search/bar", {})[1].should == :search
    end

    it "should change indirection name to 'facts' if the http method is a GET and the indirection name is facts_search" do
      @tester.uri2indirection("GET", "/env/facts_search/bar", {})[0].should == 'facts'
    end

    it "should not change indirection name from 'facts' if the http method is a GET and the indirection name is facts" do
      @tester.uri2indirection("GET", "/env/facts/bar", {})[0].should == 'facts'
    end

    it "should change indirection name to 'status' if the http method is a GET and the indirection name is statuses" do
      @tester.uri2indirection("GET", "/env/statuses/bar", {})[0].should == 'status'
    end

    it "should choose 'delete' as the indirection method if the http method is a DELETE and the indirection name is singular" do
      @tester.uri2indirection("DELETE", "/env/foo/bar", {})[1].should == :destroy
    end

    it "should choose 'save' as the indirection method if the http method is a PUT and the indirection name is singular" do
      @tester.uri2indirection("PUT", "/env/foo/bar", {})[1].should == :save
    end

    it "should fail if an indirection method cannot be picked" do
      lambda { @tester.uri2indirection("UPDATE", "/env/foo/bar", {}) }.should raise_error(ArgumentError)
    end

    it "should URI unescape the indirection key" do
      escaped = URI.escape("foo bar")
      indirection_name, method, key, params = @tester.uri2indirection("GET", "/env/foo/#{escaped}", {})
      key.should == "foo bar"
    end
  end

  describe "when converting a request into a URI" do
    before do
      @request = Puppet::Indirector::Request.new(:foo, :find, "with spaces", :foo => :bar, :environment => "myenv")
    end

    it "should use the environment as the first field of the URI" do
      @tester.indirection2uri(@request).split("/")[1].should == "myenv"
    end

    it "should use the indirection as the second field of the URI" do
      @tester.indirection2uri(@request).split("/")[2].should == "foo"
    end

    it "should pluralize the indirection name if the method is 'search'" do
      @request.stubs(:method).returns :search
      @tester.indirection2uri(@request).split("/")[2].should == "foos"
    end

    it "should use the escaped key as the remainder of the URI" do
      escaped = URI.escape("with spaces")
      @tester.indirection2uri(@request).split("/")[3].sub(/\?.+/, '').should == escaped
    end

    it "should add the query string to the URI" do
      @request.expects(:query_string).returns "?query"
      @tester.indirection2uri(@request).should =~ /\?query$/
    end
  end

  describe "when converting a request into a URI with body" do
    before :each do
      @request = Puppet::Indirector::Request.new(:foo, :find, "with spaces", :foo => :bar, :environment => "myenv")
    end

    it "should use the environment as the first field of the URI" do
      @tester.request_to_uri_and_body(@request).first.split("/")[1].should == "myenv"
    end

    it "should use the indirection as the second field of the URI" do
      @tester.request_to_uri_and_body(@request).first.split("/")[2].should == "foo"
    end

    it "should use the escaped key as the remainder of the URI" do
      escaped = URI.escape("with spaces")
      @tester.request_to_uri_and_body(@request).first.split("/")[3].sub(/\?.+/, '').should == escaped
    end

    it "should return the URI and body separately" do
      @tester.request_to_uri_and_body(@request).should == ["/myenv/foo/with%20spaces", "foo=bar"]
    end
  end
end