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

module InvocationTest
  class API < ActionService::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 Service < ActionService::Base
    web_service_api API

    before_invocation :intercept_before, :except => [:no_before]
    after_invocation :intercept_after, :except => [:no_after]
    before_invocation :intercept_only, :only => [:only_one, :only_two]

    attr_accessor :before_invoked
    attr_accessor :after_invoked
    attr_accessor :only_invoked
    attr_accessor :invocation_result
  
    def initialize
      @before_invoked = nil
      @after_invoked = nil
      @only_invoked = nil
      @invocation_result = 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
  
    def not_public
    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_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 ActionService::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(InvocationError) do
      perform_invocation(:not_public)
    end
    assert_raises(InvocationError) 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 == 1)
  end

  def test_interception
    assert(@service.before_invoked.nil? && @service.after_invoked.nil? && @service.only_invoked.nil? && @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_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)
    @service.only_invoked = nil
    perform_invocation(:only_two)
    assert(@service.only_invoked == :only_two)
  end

  private
    def perform_invocation(method_name, *args, &block)
      public_method_name = @service.class.web_service_api.public_api_method_name(method_name)
      args ||= []
      request = InvocationRequest.new(ConcreteInvocation, public_method_name, method_name, args)
      @service.perform_invocation(request, &block)
    end
end