summaryrefslogtreecommitdiffstats
path: root/spec/unit/indirector.rb
blob: 892e70c1fa08a4e60fdca145d1d8c44defa97349 (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
#!/usr/bin/env ruby

require File.dirname(__FILE__) + '/../spec_helper'

require 'puppet/defaults'
require 'puppet/indirector'

describe Puppet::Indirector, " when available to a model" do
    before do
        @thingie = Class.new do
            extend Puppet::Indirector
        end
    end

    it "should provide a way for the model to register an indirection under a name" do
        @thingie.should respond_to(:indirects)
    end
end

describe Puppet::Indirector, "when registering an indirection" do
    before do
        @thingie = Class.new do
            extend Puppet::Indirector
            attr_reader :name
            def initialize(name)
                @name = name
            end
        end
    end

    it "should require a name when registering a model" do
        Proc.new {@thingie.send(:indirects) }.should raise_error(ArgumentError)
    end

    it "should create an indirection instance to manage each indirecting model" do
        @indirection = @thingie.indirects(:test)
        @indirection.should be_instance_of(Puppet::Indirector::Indirection)
    end
    
    it "should not allow a model to register under multiple names" do
        # Keep track of the indirection instance so we can delete it on cleanup
        @indirection = @thingie.indirects :first
        Proc.new { @thingie.indirects :second }.should raise_error(ArgumentError)
    end

    it "should make the indirection available via an accessor" do
        @indirection = @thingie.indirects :first
        @thingie.indirection.should equal(@indirection)
    end

    it "should pass any provided options to the indirection during initialization" do
        klass = mock 'terminus class'
        Puppet::Indirector::Indirection.expects(:new).with(@thingie, :first, {:some => :options})
        @indirection = @thingie.indirects :first, :some => :options
    end

    after do
        @indirection.delete if @indirection
    end
end

describe "Delegated Indirection Method", :shared => true do
    it "should create an indirection request with the indirection name, the method being delegated, and all of the arguments to the method call" do
        Puppet::Indirector::Request.expects(:new).with(@indirection.name, @method, "me", :one => :two)
        @indirection.stubs(@method)
        @thingie.send(@method, "me", :one => :two)
    end

    it "should delegate to the indirection" do
        @indirection.expects(@method)
        @thingie.send(@method, "me")
    end

    it "should pass the indirection's request instance to the indirection's method" do
        request = mock 'request'
        Puppet::Indirector::Request.expects(:new).returns request
        @indirection.expects(@method).with(request)
        @thingie.send(@method, "me")
    end

    it "should return the results of the delegation as its result" do
        request = mock 'request'
        @indirection.expects(@method).returns "yay"
        @thingie.send(@method, "me").should == "yay"
    end
end

describe Puppet::Indirector, "when redirecting a model" do
    before do
        @thingie = Class.new do
            extend Puppet::Indirector
            attr_reader :name
            def initialize(name)
                @name = name
            end
        end
        @indirection = @thingie.send(:indirects, :test)
    end

    it "should include the Envelope module in the model" do
        @thingie.ancestors.should be_include(Puppet::Indirector::Envelope)
    end

    describe "when finding instances via the model" do
        before { @method = :find }
        it_should_behave_like "Delegated Indirection Method"
    end

    describe "when destroying instances via the model" do
        before { @method = :destroy }
        it_should_behave_like "Delegated Indirection Method"
    end

    describe "when searching for instances via the model" do
        before { @method = :search }
        it_should_behave_like "Delegated Indirection Method"
    end

    # This is an instance method, so it behaves a bit differently.
    describe "when saving instances via the model" do
        before do
            @instance = @thingie.new("me")
        end

        it "should pass the method name, the instance, plus all passed arguments to the indirection's request method" do
            Puppet::Indirector::Request.expects(:new).with(@indirection.name, :save, @instance, :one => :two)
            @indirection.stubs(:save)
            @instance.save(:one => :two)
        end

        it "should delegate to the indirection" do
            @indirection.expects(:save)
            @instance.save
        end

        it "should pass the indirection's request instance to the indirection's method" do
            request = mock 'request'
            Puppet::Indirector::Request.expects(:new).returns request
            @indirection.expects(:save).with(request)
            @instance.save
        end

        it "should return the results of the delegation as its result" do
            request = mock 'request'
            @indirection.expects(:save).returns "yay"
            @instance.save.should == "yay"
        end
    end

    it "should give the model the ability to set the indirection terminus class" do
        @indirection.expects(:terminus_class=).with(:myterm)
        @thingie.terminus_class = :myterm
    end

    it "should give the model the ability to set the indirection cache class" do
        @indirection.expects(:cache_class=).with(:mycache)
        @thingie.cache_class = :mycache
    end

    after do
        @indirection.delete
    end
end