Просмотр исходного кода

Moved to webmock for telegram integration tests.

Martin Edenhofer 8 лет назад
Родитель
Сommit
85abb738d8
6 измененных файлов с 123 добавлено и 64 удалено
  1. 12 0
      .gitlab-ci.yml
  2. 3 0
      Gemfile
  3. 9 0
      Gemfile.lock
  4. 5 4
      app/controllers/application_controller.rb
  5. 5 33
      lib/telegram.rb
  6. 89 27
      test/integration/telegram_controller_test.rb

+ 12 - 0
.gitlab-ci.yml

@@ -255,6 +255,18 @@ test:integration:sipgate:
     - ruby -I test test/integration/sipgate_controller_test.rb
     - ruby -I test test/integration/sipgate_controller_test.rb
     - rake db:drop
     - rake db:drop
 
 
+test:integration:telegram:
+  stage: test
+  tags:
+    - core
+  script:
+    - export RAILS_ENV=test
+    - rake db:create
+    - rake db:migrate
+    - rake db:seed
+    - ruby -I test test/integration/telegram_controller_test.rb
+    - rake db:drop
+
 test:integration:es_mysql:
 test:integration:es_mysql:
   stage: test
   stage: test
   tags:
   tags:

+ 3 - 0
Gemfile

@@ -122,6 +122,9 @@ group :development, :test do
 
 
   # Use Factory Girl for generating random test data
   # Use Factory Girl for generating random test data
   gem 'factory_girl_rails'
   gem 'factory_girl_rails'
+
+  # mock http calls
+  gem 'webmock'
 end
 end
 
 
 gem 'puma', group: :puma
 gem 'puma', group: :puma

+ 9 - 0
Gemfile.lock

@@ -82,6 +82,8 @@ GEM
       term-ansicolor (~> 1.3.0)
       term-ansicolor (~> 1.3.0)
       thor (~> 0.19.1)
       thor (~> 0.19.1)
       tins (>= 1.6.0, < 2)
       tins (>= 1.6.0, < 2)
+    crack (0.4.3)
+      safe_yaml (~> 1.0.0)
     daemons (1.2.4)
     daemons (1.2.4)
     delayed_job (4.1.2)
     delayed_job (4.1.2)
       activesupport (>= 3.0, < 5.1)
       activesupport (>= 3.0, < 5.1)
@@ -151,6 +153,7 @@ GEM
       guard (~> 2.8)
       guard (~> 2.8)
       guard-compat (~> 1.0)
       guard-compat (~> 1.0)
       multi_json (~> 1.8)
       multi_json (~> 1.8)
+    hashdiff (0.3.2)
     hashie (3.4.4)
     hashie (3.4.4)
     htmlentities (4.3.4)
     htmlentities (4.3.4)
     http (1.0.4)
     http (1.0.4)
@@ -325,6 +328,7 @@ GEM
     ruby-progressbar (1.8.1)
     ruby-progressbar (1.8.1)
     ruby_dep (1.4.0)
     ruby_dep (1.4.0)
     rubyzip (1.2.0)
     rubyzip (1.2.0)
+    safe_yaml (1.0.4)
     sass (3.4.22)
     sass (3.4.22)
     sass-rails (5.0.6)
     sass-rails (5.0.6)
       railties (>= 4.0.0, < 6)
       railties (>= 4.0.0, < 6)
@@ -398,6 +402,10 @@ GEM
     unicorn (5.2.0)
     unicorn (5.2.0)
       kgio (~> 2.6)
       kgio (~> 2.6)
       raindrops (~> 0.7)
       raindrops (~> 0.7)
+    webmock (2.3.2)
+      addressable (>= 2.3.6)
+      crack (>= 0.3.2)
+      hashdiff
     websocket (1.2.3)
     websocket (1.2.3)
     writeexcel (1.0.5)
     writeexcel (1.0.5)
     zendesk_api (1.14.0)
     zendesk_api (1.14.0)
@@ -480,6 +488,7 @@ DEPENDENCIES
   twitter
   twitter
   uglifier
   uglifier
   unicorn
   unicorn
+  webmock
   writeexcel
   writeexcel
   zendesk_api
   zendesk_api
 
 

+ 5 - 4
app/controllers/application_controller.rb

@@ -113,14 +113,15 @@ class ApplicationController < ActionController::Base
     session[:ping] = Time.zone.now.iso8601
     session[:ping] = Time.zone.now.iso8601
 
 
     # check if remote ip need to be updated
     # check if remote ip need to be updated
-    if !session[:remote_ip] || session[:remote_ip] != request.remote_ip
-      session[:remote_ip]  = request.remote_ip
-      session[:geo]        = Service::GeoIp.location(request.remote_ip)
+    if session[:user_id]
+      if !session[:remote_ip] || session[:remote_ip] != request.remote_ip
+        session[:remote_ip] = request.remote_ip
+        session[:geo]       = Service::GeoIp.location(request.remote_ip)
+      end
     end
     end
 
 
     # fill user agent
     # fill user agent
     return if session[:user_agent]
     return if session[:user_agent]
-
     session[:user_agent] = request.env['HTTP_USER_AGENT']
     session[:user_agent] = request.env['HTTP_USER_AGENT']
   end
   end
 
 

+ 5 - 33
lib/telegram.rb

@@ -79,7 +79,11 @@ returns
     end
     end
 
 
     # generate randam callback token
     # generate randam callback token
-    callback_token = SecureRandom.urlsafe_base64(10)
+    callback_token = if Rails.env.test?
+                       'callback_token'
+                     else
+                       SecureRandom.urlsafe_base64(10)
+                     end
 
 
     # set webhook / callback url for this bot @ telegram
     # set webhook / callback url for this bot @ telegram
     callback_url = "#{Setting.get('http_type')}://#{Setting.get('fqdn')}/api/v1/channels_telegram_webhook/#{callback_token}?bid=#{bot['id']}"
     callback_url = "#{Setting.get('http_type')}://#{Setting.get('fqdn')}/api/v1/channels_telegram_webhook/#{callback_token}?bid=#{bot['id']}"
@@ -599,16 +603,6 @@ returns
   end
   end
 
 
   def download_file(file_id)
   def download_file(file_id)
-    if Rails.env.test?
-      result = Result.new(
-        success: true,
-        body: 'ok',
-        data: 'ok',
-        code: 200,
-        content_type: 'application/stream',
-      )
-      return result
-    end
     document = @api.getFile(file_id)
     document = @api.getFile(file_id)
     url = "https://api.telegram.org/file/bot#{@token}/#{document['file_path']}"
     url = "https://api.telegram.org/file/bot#{@token}/#{document['file_path']}"
     UserAgent.get(
     UserAgent.get(
@@ -621,26 +615,4 @@ returns
     )
     )
   end
   end
 
 
-  class Result
-
-    attr_reader :error
-    attr_reader :body
-    attr_reader :data
-    attr_reader :code
-    attr_reader :content_type
-
-    def initialize(options)
-      @success      = options[:success]
-      @body         = options[:body]
-      @data         = options[:data]
-      @code         = options[:code]
-      @content_type = options[:content_type]
-      @error        = options[:error]
-    end
-
-    def success?
-      return true if @success
-      false
-    end
-  end
 end
 end

+ 89 - 27
test/integration/telegram_controller_test.rb

@@ -1,40 +1,75 @@
 # encoding: utf-8
 # encoding: utf-8
 require 'test_helper'
 require 'test_helper'
 require 'rexml/document'
 require 'rexml/document'
+require 'webmock/minitest'
 
 
 class TelegramControllerTest < ActionDispatch::IntegrationTest
 class TelegramControllerTest < ActionDispatch::IntegrationTest
   setup do
   setup do
     @headers = { 'ACCEPT' => 'application/json', 'CONTENT_TYPE' => 'application/json' }
     @headers = { 'ACCEPT' => 'application/json', 'CONTENT_TYPE' => 'application/json' }
+  end
+
+  test 'basic call' do
+    Ticket.destroy_all
 
 
     # configure telegram channel
     # configure telegram channel
-    token = ENV['TELEGRAM_TOKEN']
+    token = 'valid_token'
+    bot_id = 123_456_789
     group_id = Group.find_by(name: 'Users').id
     group_id = Group.find_by(name: 'Users').id
-    #bot = Telegram.check_token(token)
-    #Setting.set('http_type', 'http')
-    Setting.set('http_type', 'https')
-    Setting.set('fqdn', 'me.zammad.com')
-    Channel.where(area: 'Telegram::Bot').destroy_all
+
     UserInfo.current_user_id = 1
     UserInfo.current_user_id = 1
-    @channel = Telegram.create_or_update_channel(token, { group_id: group_id, welcome: 'hi!' })
-
-    groups = Group.where(name: 'Users')
-    roles  = Role.where(name: %w(Agent))
-    agent  = User.create_or_update(
-      login: 'telegram-agent@example.com',
-      firstname: 'E',
-      lastname: 'S',
-      email: 'telegram-agent@example.com',
-      password: 'agentpw',
-      active: true,
-      roles: roles,
-      groups: groups,
-    )
-    UserInfo.current_user_id = nil
+    Channel.where(area: 'Telegram::Bot').destroy_all
 
 
-  end
+    # try with invalid token
+    stub_request(:get, 'https://api.telegram.org/botnot_existing/getMe')
+      .to_return(status: 404, body: '{"ok":false,"error_code":404,"description":"Not Found"}', headers: {})
 
 
-  test 'basic call' do
-    Ticket.destroy_all
+    assert_raises(RuntimeError) {
+      Telegram.check_token('not_existing')
+    }
+
+    # try valid token
+    stub_request(:get, "https://api.telegram.org/bot#{token}/getMe")
+      .to_return(status: 200, body: "{\"ok\":true,\"result\":{\"id\":#{bot_id},\"first_name\":\"Chrispresso Customer Service\",\"username\":\"ChrispressoBot\"}}", headers: {})
+
+    bot = Telegram.check_token(token)
+    assert_equal(bot_id, bot['id'])
+
+    stub_request(:get, "https://api.telegram.org/bot#{token}/getMe")
+      .to_return(status: 200, body: "{\"ok\":true,\"result\":{\"id\":#{bot_id},\"first_name\":\"Chrispresso Customer Service\",\"username\":\"ChrispressoBot\"}}", headers: {})
+
+    Setting.set('http_type', 'http')
+    assert_raises(RuntimeError) {
+      Telegram.create_or_update_channel(token, { group_id: group_id, welcome: 'hi!' })
+    }
+
+    # try invalid port
+    stub_request(:get, "https://api.telegram.org:443/bot#{token}/getMe")
+      .to_return(status: 200, body: "{\"ok\":true,\"result\":{\"id\":#{bot_id},\"first_name\":\"Chrispresso Customer Service\",\"username\":\"ChrispressoBot\"}}", headers: {})
+    stub_request(:get, "https://api.telegram.org:443/bot#{token}/setWebhook?url=https://somehost.example.com:12345/api/v1/channels_telegram_webhook/callback_token?bid=#{bot_id}")
+      .to_return(status: 400, body: '{"ok":false,"error_code":400,"description":"Bad Request: bad webhook: Webhook can be set up only on ports 80, 88, 443 or 8443"}', headers: {})
+
+    Setting.set('http_type', 'https')
+    Setting.set('fqdn', 'somehost.example.com:12345')
+    assert_raises(RuntimeError) {
+      Telegram.create_or_update_channel(token, { group_id: group_id, welcome: 'hi!' })
+    }
+
+    # try invalid host
+    stub_request(:get, "https://api.telegram.org:443/bot#{token}/setWebhook?url=https://somehost.example.com/api/v1/channels_telegram_webhook/callback_token?bid=#{bot_id}")
+      .to_return(status: 400, body: '{"ok":false,"error_code":400,"description":"Bad Request: bad webhook: getaddrinfo: Name or service not known"}', headers: {})
+
+    Setting.set('fqdn', 'somehost.example.com')
+    assert_raises(RuntimeError) {
+      Telegram.create_or_update_channel(token, { group_id: group_id, welcome: 'hi!' })
+    }
+
+    # valid token, host and port
+    stub_request(:get, "https://api.telegram.org:443/bot#{token}/setWebhook?url=https://example.com/api/v1/channels_telegram_webhook/callback_token?bid=#{bot_id}")
+      .to_return(status: 200, body: '{"ok":true,"result":true,"description":"Webhook was set"}', headers: {})
+
+    Setting.set('fqdn', 'example.com')
+    channel = Telegram.create_or_update_channel(token, { group_id: group_id, welcome: 'hi!' })
+    UserInfo.current_user_id = nil
 
 
     # start communication #1
     # start communication #1
     post '/api/v1/channels/telegram_webhook', read_messaage('personal1_message_start'), @headers
     post '/api/v1/channels/telegram_webhook', read_messaage('personal1_message_start'), @headers
@@ -46,13 +81,13 @@ class TelegramControllerTest < ActionDispatch::IntegrationTest
     result = JSON.parse(@response.body)
     result = JSON.parse(@response.body)
     assert_equal('bot param missing', result['error'])
     assert_equal('bot param missing', result['error'])
 
 
-    callback_url = "/api/v1/channels_telegram_webhook/not_existing?bid=#{@channel.options[:bot][:id]}"
+    callback_url = "/api/v1/channels_telegram_webhook/not_existing?bid=#{channel.options[:bot][:id]}"
     post callback_url, read_messaage('personal1_message_start'), @headers
     post callback_url, read_messaage('personal1_message_start'), @headers
     assert_response(422)
     assert_response(422)
     result = JSON.parse(@response.body)
     result = JSON.parse(@response.body)
     assert_equal('invalid callback token', result['error'])
     assert_equal('invalid callback token', result['error'])
 
 
-    callback_url = "/api/v1/channels_telegram_webhook/#{@channel.options[:callback_token]}?bid=#{@channel.options[:bot][:id]}"
+    callback_url = "/api/v1/channels_telegram_webhook/#{channel.options[:callback_token]}?bid=#{channel.options[:bot][:id]}"
     post callback_url, read_messaage('personal1_message_start'), @headers
     post callback_url, read_messaage('personal1_message_start'), @headers
     assert_response(200)
     assert_response(200)
 
 
@@ -139,6 +174,11 @@ class TelegramControllerTest < ActionDispatch::IntegrationTest
     assert_equal('text/plain', ticket.articles.last.content_type)
     assert_equal('text/plain', ticket.articles.last.content_type)
 
 
     # send message2
     # send message2
+    stub_request(:get, "https://api.telegram.org/bot#{token}/getFile?file_id=ABC-123VabcOcv123w0ABHywrcPqfrbAYIABC")
+      .to_return(status: 200, body: '{"result":{"file_size":123,"file_id":"ABC-123VabcOcv123w0ABHywrcPqfrbAYIABC","file_path":"abc123"}}', headers: {})
+    stub_request(:get, "https://api.telegram.org/file/bot#{token}/abc123")
+      .to_return(status: 200, body: 'ABC1', headers: {})
+
     post callback_url, read_messaage('personal3_message_content2'), @headers
     post callback_url, read_messaage('personal3_message_content2'), @headers
     assert_response(200)
     assert_response(200)
     assert_equal(3, Ticket.count)
     assert_equal(3, Ticket.count)
@@ -150,6 +190,13 @@ class TelegramControllerTest < ActionDispatch::IntegrationTest
     assert_equal('text/html', ticket.articles.last.content_type)
     assert_equal('text/html', ticket.articles.last.content_type)
 
 
     # send message3
     # send message3
+    stub_request(:get, "https://api.telegram.org/bot#{token}/getFile?file_id=AAQCABO0I4INAATATQAB5HWPq4XgxQACAg")
+      .to_return(status: 200, body: '{"result":{"file_size":123,"file_id":"ABC-123AAQCABO0I4INAATATQAB5HWPq4XgxQACAg","file_path":"abc123"}}', headers: {})
+    stub_request(:get, "https://api.telegram.org/file/bot#{token}/abc123")
+      .to_return(status: 200, body: 'ABC2', headers: {})
+    stub_request(:get, "https://api.telegram.org/bot#{token}/getFile?file_id=BQADAgADDgAD7x6ZSC_-1LMkOEmoAg")
+      .to_return(status: 200, body: '{"result":{"file_size":123,"file_id":"ABC-123BQADAgADDgAD7x6ZSC_-1LMkOEmoAg","file_path":"abc123"}}', headers: {})
+
     post callback_url, read_messaage('personal3_message_content3'), @headers
     post callback_url, read_messaage('personal3_message_content3'), @headers
     assert_response(200)
     assert_response(200)
     assert_equal(3, Ticket.count)
     assert_equal(3, Ticket.count)
@@ -177,6 +224,9 @@ class TelegramControllerTest < ActionDispatch::IntegrationTest
     assert_equal('text/plain', ticket.articles.first.content_type)
     assert_equal('text/plain', ticket.articles.first.content_type)
 
 
     # send voice5
     # send voice5
+    stub_request(:get, "https://api.telegram.org/bot#{token}/getFile?file_id=AwADAgADVQADCEIYSZwyOmSZK9iZAg")
+      .to_return(status: 200, body: '{"result":{"file_size":123,"file_id":"ABC-123AwADAgADVQADCEIYSZwyOmSZK9iZAg","file_path":"abc123"}}', headers: {})
+
     post callback_url, read_messaage('personal3_message_content5'), @headers
     post callback_url, read_messaage('personal3_message_content5'), @headers
     assert_response(200)
     assert_response(200)
     assert_equal(3, Ticket.count)
     assert_equal(3, Ticket.count)
@@ -188,11 +238,20 @@ class TelegramControllerTest < ActionDispatch::IntegrationTest
     assert_equal(1, ticket.articles.last.attachments.count)
     assert_equal(1, ticket.articles.last.attachments.count)
 
 
     # start communication #4 - with sticker
     # start communication #4 - with sticker
+    stub_request(:get, "https://api.telegram.org/bot#{token}/getFile?file_id=AAQDABO3-e4qAASs6ZOjJUT7tQ4lAAIC")
+      .to_return(status: 200, body: '{"result":{"file_size":123,"file_id":"ABC-123AAQDABO3-e4qAASs6ZOjJUT7tQ4lAAIC","file_path":"abc123"}}', headers: {})
+    stub_request(:get, "https://api.telegram.org/bot#{token}/getFile?file_id=BQADAwAD0QIAAqbJWAAB8OkQqgtDQe0C")
+      .to_return(status: 200, body: '{"result":{"file_size":123,"file_id":"ABC-123BQADAwAD0QIAAqbJWAAB8OkQqgtDQe0C","file_path":"abc123"}}', headers: {})
+
     post callback_url, read_messaage('personal4_message_content1'), @headers
     post callback_url, read_messaage('personal4_message_content1'), @headers
     assert_response(200)
     assert_response(200)
     assert_equal(4, Ticket.count)
     assert_equal(4, Ticket.count)
     ticket = Ticket.last
     ticket = Ticket.last
-    assert_equal('💻', ticket.title)
+    if Rails.application.config.db_4bytes_utf8
+      assert_equal('💻', ticket.title)
+    else
+      assert_equal('', ticket.title)
+    end
     assert_equal('new', ticket.state.name)
     assert_equal('new', ticket.state.name)
     assert_equal(1, ticket.articles.count)
     assert_equal(1, ticket.articles.count)
     assert_match(/<img style="/i, ticket.articles.last.body)
     assert_match(/<img style="/i, ticket.articles.last.body)
@@ -200,6 +259,9 @@ class TelegramControllerTest < ActionDispatch::IntegrationTest
     assert_equal(1, ticket.articles.last.attachments.count)
     assert_equal(1, ticket.articles.last.attachments.count)
 
 
     # start communication #5 - with photo
     # start communication #5 - with photo
+    stub_request(:get, "https://api.telegram.org/bot#{token}/getFile?file_id=AgADAgADwacxGxk5MUmim45lijOwsKk1Sw0ABNQoaI8BwR_z_2MFAAEC")
+      .to_return(status: 200, body: '{"result":{"file_size":123,"file_id":"ABC-123AgADAgADwacxGxk5MUmim45lijOwsKk1Sw0ABNQoaI8BwR_z_2MFAAEC","file_path":"abc123"}}', headers: {})
+
     post callback_url, read_messaage('personal5_message_content1'), @headers
     post callback_url, read_messaage('personal5_message_content1'), @headers
     assert_response(200)
     assert_response(200)
     assert_equal(5, Ticket.count)
     assert_equal(5, Ticket.count)