summaryrefslogtreecommitdiff
path: root/test/integration/dispatcher_test.rb
blob: 0fb395a4c579a9b291bb53460e21ea7a0480135b (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
require 'test_helper'
require 'nickserver/dispatcher'

#
# Test integration between the Dispatcher and the RequestHandlers
#
# Starting from a given request we test the interaction between the dispatcher
# and the different RequestHandlers. There's a lot of combinations possible
# and we only test a couple of them to ensure the parts work together well.
#
# This does not test the server. We stub and mock the sources. The nickserver
# integration test covers these as well.
#

class Nickserver::DispatcherTest < Minitest::Test
  def test_empty_query
    handle
    assert_response not_found
  end

  def test_invalid_query
    handle address: ['asdf']
    assert_response error('Not a valid address')
  end

  def test_fingerprint_to_short
    handle fingerprint: ['44F2F455E28']
    assert_response error('Fingerprint invalid: 44F2F455E28')
  end

  def test_fingerprint_is_not_hex
    fingerprint = 'X36E738D69173C13Z709E44F2F455E2824D18DDX'
    handle fingerprint: [fingerprint]
    assert_response error("Fingerprint invalid: #{fingerprint}")
  end

  def test_missing_domain
    handle address: ['valid@email.tld']
    stub_nicknym_not_available
    wkd_source.expect :query, success, [Nickserver::EmailAddress]
    assert_response success
  end

  def test_email_via_wkd
    handle address: ['valid@email.tld'],
           headers: { 'Host' => 'http://nickserver.me' }
    stub_nicknym_not_available
    wkd_source.expect :query, success, [Nickserver::EmailAddress]
    assert_response success
  end

  def test_email_via_wkd_nicknym_unreachable
    handle address: ['valid@email.tld'],
           headers: { 'Host' => 'http://nickserver.me' }
    stub_nicknym_raises
    wkd_source.expect :query, success, [Nickserver::EmailAddress]
    assert_response success
  end

  def test_email_not_found_wkd_nicknym_unreachable
    handle address: ['valid@email.tld'],
           headers: { 'Host' => 'http://nickserver.me' }
    stub_nicknym_raises
    wkd_source.expect :query, nil, [Nickserver::EmailAddress]
    hkp_source.expect :query, nil, [Nickserver::EmailAddress]
    assert_response http_connection_error
  end

  def test_email_via_nicknym
    handle address: ['valid@email.tld'],
           headers: { 'Host' => 'http://nickserver.me' }
    nicknym_source.expect :available_for?, true, [String]
    nicknym_source.expect :query, success, [Nickserver::EmailAddress]
    assert_response success
  end

  def test_get_key_with_fingerprint
    handle fingerprint: ['E36E738D69173C13D709E44F2F455E2824D18DDF']
    stub_nicknym_not_available
    hkp_source.expect :get_key_by_fingerprint, success,
                      ['E36E738D69173C13D709E44F2F455E2824D18DDF']
    assert_response success
  end

  protected

  def handle(params = {})
    @headers = params.delete(:headers) || {}
    @params = Hash[params.map { |k, v| [k.to_s, v] }]
  end

  def assert_response(response)
    Nickserver::Nicknym::Source.stub :new, nicknym_source do
      Nickserver::Wkd::Source.stub :new, wkd_source do
        Nickserver::Hkp::Source.stub :new, hkp_source do
          responder.expect :respond, nil, [response.status, response.content]
          dispatcher.respond_to @params, @headers
          responder.verify
        end
      end
    end
  end

  def wkd_source
    @wkd_source ||= Minitest::Mock.new
  end

  def hkp_source
    @hkp_source ||= Minitest::Mock.new
  end

  def stub_nicknym_not_available
    def nicknym_source.available_for?(*_args)
      false
    end
  end

  def stub_nicknym_raises
    def nicknym_source.available_for?(*_args)
      raise HTTP::ConnectionError
    end
  end

  def nicknym_source
    @nicknym_source ||= Minitest::Mock.new
  end

  def success
    response status: 200, content: 'fake content'
  end

  def not_found
    response status: 404, content: "404 Not Found\n"
  end

  def error(msg)
    response status: 500, content: "500 #{msg}\n"
  end

  def http_connection_error
    response status: 502,
             content: JSON.dump(error: 'HTTP::ConnectionError')
  end

  def response(options)
    Nickserver::Response.new(options[:status], options[:content])
  end

  def dispatcher
    Nickserver::Dispatcher.new responder
  end

  def responder
    @responder ||= Minitest::Mock.new
  end
end