<commit_before>require 'spec_helper'

include Wechat::Cipher

ENCODING_AES_KEY = Base64.encode64 SecureRandom.hex(16)

class WechatCorpController < ApplicationController
  wechat_responder corpid: 'corpid', corpsecret: 'corpsecret', token: 'token', access_token: '<PASSWORD>',
                   agentid: 1, encoding_aes_key: ENCODING_AES_KEY
end

RSpec.describe WechatCorpController, type: :controller do
  render_views

  let(:message_base) do
    {
      ToUserName: 'toUser',
      FromUserName: 'fromUser',
      CreateTime: '1348831860',
      MsgId: '1234567890123456'
    }
  end

  def signature_params(msg = {})
    xml = message_base.merge(msg).to_xml(root: :xml, skip_instruct: true)

    encrypt = Base64.strict_encode64 encrypt(pack(xml, 'appid'), ENCODING_AES_KEY)
    xml = { Encrypt: encrypt }
    timestamp = '1234567'
    nonce = 'nonce'
    msg_signature = Digest::SHA1.hexdigest(['token', timestamp, nonce, xml[:Encrypt]].sort.join)
    { timestamp: timestamp, nonce: nonce, xml: xml, msg_signature: msg_signature }
  end

  def xml_to_hash(response)
    Hash.from_xml(response.body)['xml'].symbolize_keys
  end

  describe 'Verify signature' do
    it 'on create action faild' do
      post :create, signature_params.merge(msg_signature: 'invalid')
      expect(response.code).to eq '403'
    end

    it 'on create action success' do
      post :create, signature_params(MsgType: 'voice', Voice: { MediaId: 'mediaID' })
      expect(response.code).to eq '200'
      expect(response.body.length).to eq 0
    end
  end

  describe 'corp' do
    controller do
      wechat_responder corpid: 'corpid', corpsecret: 'corpsecret', token: 'token', access_token: 'controller_access_token',
                       agentid: 1, encoding_aes_key: ENCODING_AES_KEY

      on :text do |request, content|
        request.reply.text "echo: #{content}"
      end

      on :event, with: 'my_event' do |request, _key|
        request.reply.text 'echo: my_event'
      end
    end

    specify 'will set controller wechat api and token' do
      access_token = controller.class.wechat.access_token
      expect(access_token.token_file).to eq 'controller_access_token'
      expect(controller.class.token).to eq 'token'
      expect(controller.class.agentid).to eq 1
      expect(controller.class.encrypt_mode).to eq true
      expect(controller.class.encoding_aes_key).to eq ENCODING_AES_KEY
    end

    describe 'response' do
      it 'Verify response signature' do
        post :create, signature_params(MsgType: 'text', Content: 'hello')
        expect(response.code).to eq '200'<commit_msg>Add wechat_responder for enterprise account verify URL rspec.<commit_after>require 'spec_helper'

include Wechat::Cipher

ENCODING_AES_KEY = Base64.encode64 SecureRandom.hex(16)

class WechatCorpController < ApplicationController
  wechat_responder corpid: 'corpid', corpsecret: 'corpsecret', token: 'token', access_token: 'controller_access_token',
                   agentid: 1, encoding_aes_key: ENCODING_AES_KEY
end

RSpec.describe WechatCorpController, type: :controller do
  render_views

  let(:message_base) do
    {
      ToUserName: 'toUser',
      FromUserName: 'fromUser',
      CreateTime: '1348831860',
      MsgId: '1234567890123456'
    }
  end

  def signature_params(msg = {})
    xml = message_base.merge(msg).to_xml(root: :xml, skip_instruct: true)

    encrypt = Base64.strict_encode64 encrypt(pack(xml, 'appid'), ENCODING_AES_KEY)
    xml = { Encrypt: encrypt }
    timestamp = '1234567'
    nonce = 'nonce'
    msg_signature = Digest::SHA1.hexdigest(['token', timestamp, nonce, xml[:Encrypt]].sort.join)
    { timestamp: timestamp, nonce: nonce, xml: xml, msg_signature: msg_signature }
  end

  def signature_echostr(echostr)
    encrypt_echostr = Base64.strict_encode64 encrypt(pack(echostr, 'appid'), ENCODING_AES_KEY)
    timestamp = '1234567'
    nonce = 'nonce'
    msg_signature = Digest::SHA1.hexdigest(['token', timestamp, nonce, encrypt_echostr].sort.join)
    { timestamp: timestamp, nonce: nonce, echostr: encrypt_echostr, msg_signature: msg_signature }
  end

  def xml_to_hash(response)
    Hash.from_xml(response.body)['xml'].symbolize_keys
  end

  describe 'Verify signature' do
    it 'on create action faild' do
      post :create, signature_params.merge(msg_signature: 'invalid')
      expect(response.code).to eq '403'
    end

    it 'on create action success' do
      post :create, signature_params(MsgType: 'voice', Voice: { MediaId: 'mediaID' })
      expect(response.code).to eq '200'
      expect(response.body.length).to eq 0
    end
  end

  specify "echo 'echostr' param when show" do
    get :show, signature_echostr('hello')
    expect(response.body).to eq('hello')
  end

  describe 'corp' do
    controller do
      wechat_responder corpid: 'corpid', corpsecret: 'corpsecret', token: 'token', access_token: 'controller_access_token',
                       agentid: 1, encoding_aes_key: ENCODING_AES_KEY

      on :text do |request, content|
        request.reply.text "echo: #{content}"
      end

      on :event, with: 'my_event' do |request, _key|
        request.reply.text 'echo: my_event'
      end
    end

    specify 'will set controller wechat api and token' do
      access_token = controller.class.wechat.access_token
      expect(access_token.token_file).to eq 'controller_access_token'
      expect(controller.class.token).to eq 'token'
      expect(controller.class.agentid).to eq 1
      expect(controller.class.encrypt_mode).to eq true
      expect(controller.class.encoding_aes_key).to eq ENCODING_AES_KEY
    end

    describe 'response' do
      it 'Verify response signature' do
        post :create, signature_params(MsgType: 'text', Content: 'hello')
        expect(response.code).to eq '200'
{'fraction_non_alphanumeric': 0.10654885654885655, 'fraction_numerical': 0.02182952182952183, 'mean_word_length': 3.636947791164659, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 22}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '960655', 'n_tokens_mistral': 1981, 'n_tokens_neox': 1818, 'n_words': 444}