aboutsummaryrefslogtreecommitdiffstats
path: root/actionwebservice/test/invocation_test.rb
blob: 3ef22fafebb612023a9abb45b21c9ffae4863e8a (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
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
require File.dirname(__FILE__) + '/abstract_unit'

module InvocationTest
  class API < ActionWebService::API::Base
    api_method :add,             :expects => [:int, :int], :returns => [:int]
    api_method :transmogrify,    :expects_and_returns => [:string]
    api_method :fail_with_reason
    api_method :fail_generic
    api_method :no_before
    api_method :no_after
    api_method :only_one
    api_method :only_two
  end

  class Interceptor
    attr :args

    def initialize
      @args = nil
    end

    def intercept(*args)
      @args = args
    end
  end

  InterceptorClass = Interceptor.new 

  class Service < ActionController::Base
    web_service_api API

    before_invocation :intercept_before, :except => [:no_before]
    after_invocation :intercept_after, :except => [:no_after]
    prepend_after_invocation :intercept_after_first, :except => [:no_after]
    prepend_before_invocation :intercept_only, :only => [:only_one, :only_two]
    after_invocation(:only => [:only_one]) do |*args| 
      args[0].instance_variable_set('@block_invoked', args[1])
    end
    after_invocation InterceptorClass, :only => [:only_one]

    attr_accessor :before_invoked
    attr_accessor :after_invoked
    attr_accessor :after_first_invoked
    attr_accessor :only_invoked
    attr_accessor :block_invoked
    attr_accessor :invocation_result
  
    def initialize
      @before_invoked = nil
      @after_invoked = nil
      @after_first_invoked = nil
      @only_invoked = nil
      @invocation_result = nil
      @block_invoked = nil
    end
  
    def add(a, b)
      a + b
    end
  
    def transmogrify(str)
      str.upcase
    end
    
    def fail_with_reason
    end
  
    def fail_generic
    end
  
    def no_before
      5
    end
  
    def no_after
    end
  
    def only_one
    end
  
    def only_two
    end
  
    protected
      def intercept_before(name, args)
        @before_invoked = name
        return [false, "permission denied"] if name == :fail_with_reason
        return false if name == :fail_generic
      end
  
      def intercept_after(name, args, result)
        @after_invoked = name
        @invocation_result = result
      end

      def intercept_after_first(name, args, result)
        @after_first_invoked = name
      end
  
      def intercept_only(name, args)
        raise "Interception error" unless name == :only_one || name == :only_two
        @only_invoked = name
      end
  end
end

class TC_Invocation < Test::Unit::TestCase
  include ActionWebService::Invocation

  def setup
    @service = InvocationTest::Service.new
  end

  def test_invocation
    assert(perform_invocation(:add, 5, 10) == 15)
    assert(perform_invocation(:transmogrify, "hello") == "HELLO")
    assert_raises(NoMethodError) do
      perform_invocation(:nonexistent_method_xyzzy)
    end
  end

  def test_interceptor_registration
    assert(InvocationTest::Service.before_invocation_interceptors.length == 2)
    assert(InvocationTest::Service.after_invocation_interceptors.length == 4)
    assert_equal(:intercept_only, InvocationTest::Service.before_invocation_interceptors[0])
    assert_equal(:intercept_after_first, InvocationTest::Service.after_invocation_interceptors[0])
  end

  def test_interception
    assert(@service.before_invoked.nil?)
    assert(@service.after_invoked.nil?)
    assert(@service.only_invoked.nil?)
    assert(@service.block_invoked.nil?)
    assert(@service.invocation_result.nil?)
    perform_invocation(:add, 20, 50)
    assert(@service.before_invoked == :add)
    assert(@service.after_invoked == :add)
    assert(@service.invocation_result == 70)
  end

  def test_interception_canceling
    reason = nil
    perform_invocation(:fail_with_reason){|r| reason = r}
    assert(@service.before_invoked == :fail_with_reason)
    assert(@service.after_invoked.nil?)
    assert(@service.invocation_result.nil?)
    assert(reason == "permission denied")
    reason = true
    @service.before_invoked = @service.after_invoked = @service.invocation_result = nil
    perform_invocation(:fail_generic){|r| reason = r}
    assert(@service.before_invoked == :fail_generic)
    assert(@service.after_invoked.nil?)
    assert(@service.invocation_result.nil?)
    assert(reason == true)
  end

  def test_interception_except_conditions
    perform_invocation(:no_before)
    assert(@service.before_invoked.nil?)
    assert(@service.after_first_invoked == :no_before)
    assert(@service.after_invoked == :no_before)
    assert(@service.invocation_result == 5)
    @service.before_invoked = @service.after_invoked = @service.invocation_result = nil
    perform_invocation(:no_after)
    assert(@service.before_invoked == :no_after)
    assert(@service.after_invoked.nil?)
    assert(@service.invocation_result.nil?)
  end

  def test_interception_only_conditions
    assert(@service.only_invoked.nil?)
    perform_invocation(:only_one)
    assert(@service.only_invoked == :only_one)
    assert(@service.block_invoked == :only_one)
    assert(InvocationTest::InterceptorClass.args[1] == :only_one)
    @service.only_invoked = nil
    perform_invocation(:only_two)
    assert(@service.only_invoked == :only_two)
  end

  private
    def perform_invocation(method_name, *args, &block)
      @service.perform_invocation(method_name, args, &block)
    end
end