require File.join(__dir__, '../../rack_helper.rb')

describe Jpmobile::ParamsFilter do
  include Rack::Test::Methods
  include Jpmobile::RackHelper
  include Jpmobile::Util

  context '漢字コード変換' do
    before(:each) do
      @query_params = {
        'hoge' => 'ほげ',
        'パラメータ' => 'テストです〜■',
      }
      @form_params = {
        'bar' => '万葉集',
        'アジャイル' => '僕の〜♪',
      }
    end

    context 'Shift_JIS 変換の ' do
      before(:each) do
        @query_string = @query_params.map {|k, v|
          '%s=%s' % [Rack::Utils.escape(utf8_to_sjis(k)), Rack::Utils.escape(utf8_to_sjis(v))]
        }.join('&')
        @form_string = @form_params.map {|k, v|
          '%s=%s' % [utf8_to_sjis(k), utf8_to_sjis(v)]
        }.join('&')
      end

      context 'docomo のとき' do
        it 'Shift_JIS が UTF-8 に変換されること' do
          res = Rack::MockRequest.env_for(
            "/?#{@query_string}",
            'REQUEST_METHOD' => 'POST',
            'CONTENT_TYPE' => 'application/x-www-form-urlencoded',
            'HTTP_USER_AGENT' => 'DoCoMo/2.0 SH906i(c100;TB;W24H16)',
            :input => @form_string,
          )

          res = Jpmobile::MobileCarrier.new(Jpmobile::ParamsFilter.new(UnitApplication.new)).call(res)
          req = Rack::Request.new(res[1])
          expect(req.params.size).to eq(4)

          expect(req.params[@query_params.keys.first.dup]).to eq(@query_params[@query_params.keys.first])
          expect(req.params[@query_params.keys.last.dup]).to  eq(@query_params[@query_params.keys.last])

          expect(req.params[@form_params.keys.first.dup]).to eq(@form_params[@form_params.keys.first])
          expect(req.params[@form_params.keys.last.dup]).to  eq(@form_params[@form_params.keys.last])
        end
      end

      context 'au のとき' do
        it 'Shift_JIS が UTF-8 に変換されること' do
          res = Rack::MockRequest.env_for(
            "/?#{@query_string}",
            'REQUEST_METHOD' => 'POST',
            'CONTENT_TYPE' => 'application/x-www-form-urlencoded',
            'HTTP_USER_AGENT' => 'KDDI-CA32 UP.Browser/6.2.0.7.3.129 (GUI) MMP/2.0',
            :input => @form_string,
          )

          res = Jpmobile::MobileCarrier.new(Jpmobile::ParamsFilter.new(UnitApplication.new)).call(res)
          req = Rack::Request.new(res[1])
          expect(req.params.size).to eq(4)

          expect(req.params[@query_params.keys.first.dup]).to eq(@query_params[@query_params.keys.first])
          expect(req.params[@query_params.keys.last.dup]).to  eq(@query_params[@query_params.keys.last])

          expect(req.params[@form_params.keys.first.dup]).to eq(@form_params[@form_params.keys.first])
          expect(req.params[@form_params.keys.last.dup]).to  eq(@form_params[@form_params.keys.last])
        end
      end
    end

    context 'UTF-8 の' do
      before(:each) do
        @query_string = @query_params.map {|k, v|
          '%s=%s' % [Rack::Utils.escape(k), Rack::Utils.escape(v)]
        }.join('&')
        @form_string = @form_params.map {|k, v|
          '%s=%s' % [k, v]
        }.join('&')
      end

      context 'softbank のとき' do
        it '変換されないこと' do
          res = Rack::MockRequest.env_for(
            "/?#{@query_string}",
            'REQUEST_METHOD' => 'POST',
            'CONTENT_TYPE' => 'application/x-www-form-urlencoded',
            'HTTP_USER_AGENT' => 'SoftBank/1.0/910T/TJ001/SN000000000000000 Browser/NetFront/3.3 Profile/MIDP-2.0 Configuration/CLDC-1.1',
            :input => @form_string,
          )

          res = Jpmobile::MobileCarrier.new(Jpmobile::ParamsFilter.new(UnitApplication.new)).call(res)
          req = Rack::Request.new(res[1])
          expect(req.params.size).to eq(4)

          expect(req.params[@query_params.keys.first.dup]).to eq(@query_params[@query_params.keys.first])
          expect(req.params[@query_params.keys.last.dup]).to  eq(@query_params[@query_params.keys.last])

          expect(req.params[@form_params.keys.first.dup]).to eq(@form_params[@form_params.keys.first])
          expect(req.params[@form_params.keys.last.dup]).to  eq(@form_params[@form_params.keys.last])
        end
      end
    end
  end

  context '絵文字変換' do
    context 'docomo の場合' do
      it 'Shift_JIS 絵文字がUTF-8に変換されること' do
        query_string = 'hoge=' + Rack::Utils.escape(sjis("\xf8\x9f"))
        form_string  = 'foo='  + sjis("\xf8\xa1")

        res = Rack::MockRequest.env_for(
          "/?#{query_string}",
          'REQUEST_METHOD' => 'POST',
          'CONTENT_TYPE' => 'application/x-www-form-urlencoded',
          'HTTP_USER_AGENT' => 'DoCoMo/2.0 SH906i(c100;TB;W24H16)',
          :input => form_string,
        )

        res = Jpmobile::MobileCarrier.new(Jpmobile::ParamsFilter.new(UnitApplication.new)).call(res)
        req = Rack::Request.new(res[1])
        expect(req.params.size).to eq(2)

        expect(req.params['hoge']).to eq("\356\230\276")
        expect(req.params['foo']).to  eq("\356\231\200")
      end
    end

    context 'au の場合' do
      it 'Shift_JIS 絵文字がUTF-8に変換されること' do
        query_string = 'hoge=' + Rack::Utils.escape(sjis("\xf6\x59"))
        form_string  = 'foo='  + sjis("\xf6\xfb")

        res = Rack::MockRequest.env_for(
          "/?#{query_string}",
          'REQUEST_METHOD' => 'POST',
          'CONTENT_TYPE' => 'application/x-www-form-urlencoded',
          'HTTP_USER_AGENT' => 'KDDI-CA32 UP.Browser/6.2.0.7.3.129 (GUI) MMP/2.0',
          :input => form_string,
        )

        res = Jpmobile::MobileCarrier.new(Jpmobile::ParamsFilter.new(UnitApplication.new)).call(res)
        req = Rack::Request.new(res[1])
        expect(req.params.size).to eq(2)

        expect(req.params['hoge']).to eq("\356\222\201")
        expect(req.params['foo']).to  eq("\356\224\242")
      end
    end

    context 'Softbank の場合' do
      it 'UTF-8 絵文字がUTF-8に変換されること' do
        query_string = ascii_8bit('hoge=' + Rack::Utils.escape([0xe001].pack('U')))
        form_string  = ascii_8bit('foo='  + [0xe21c].pack('U'))

        res = Rack::MockRequest.env_for(
          "/?#{query_string}",
          'REQUEST_METHOD' => 'POST',
          'CONTENT_TYPE' => 'application/x-www-form-urlencoded',
          'HTTP_USER_AGENT' => 'SoftBank/1.0/910T/TJ001/SN000000000000000 Browser/NetFront/3.3 Profile/MIDP-2.0 Configuration/CLDC-1.1',
          :input => form_string,
        )

        res = Jpmobile::MobileCarrier.new(Jpmobile::ParamsFilter.new(UnitApplication.new)).call(res)
        req = Rack::Request.new(res[1])
        expect(req.params.size).to eq(2)

        expect(req.params['hoge']).to eq("\xef\x80\x81")
        expect(req.params['foo']).to  eq("\xef\x88\x9c")
      end
    end
  end

  context 'パラメータの変換で' do
    context '値として' do
      it '+ が入ってるものが正確に取得できること(token)' do
        token = 'lm/3Pu6RrY+kp8hsnEWp2xygYLInZIxwsB3UWeksaHQ='
        form_string = ascii_8bit("foo=#{Rack::Utils.escape(token)}")

        res = Rack::MockRequest.env_for(
          '/',
          'REQUEST_METHOD' => 'POST',
          'CONTENT_TYPE' => 'application/x-www-form-urlencoded',
          'HTTP_USER_AGENT' => 'SoftBank/1.0/910T/TJ001/SN000000000000000 Browser/NetFront/3.3 Profile/MIDP-2.0 Configuration/CLDC-1.1',
          :input => form_string,
        )

        res = Jpmobile::MobileCarrier.new(Jpmobile::ParamsFilter.new(UnitApplication.new)).call(res)
        req = Rack::Request.new(res[1])
        expect(req.params.size).to eq(1)

        expect(req.params['foo']).to eq(ascii_8bit(token))
      end
    end
  end

  context 'CONTENT_TYPEに' do
    context 'application/jsonが含まれる場合' do
      it 'inputが変換されないこと' do
        form_string = '{"index":"1"}'

        res = Rack::MockRequest.env_for(
          '/',
          'REQUEST_METHOD' => 'POST',
          'CONTENT_TYPE' => 'application/json',
          'HTTP_USER_AGENT' => 'KDDI-CA32 UP.Browser/6.2.0.7.3.129 (GUI) MMP/2.0',
          :input => form_string,
        )

        res = Jpmobile::MobileCarrier.new(Jpmobile::ParamsFilter.new(UnitApplication.new)).call(res)
        req = Rack::Request.new(res[1])
        expect(req.params.size).to eq(0)

        expect(req.body.read).to eq(form_string)
      end
    end
  end

  context 'CONTENT_TYPEに' do
    context 'application/xmlが含まれる場合' do
      it 'inputが変換されないこと' do
        form_string = '<?xml version="1.0"?><value><string>hoge</string></value>'

        res = Rack::MockRequest.env_for(
          '/',
          'REQUEST_METHOD' => 'POST',
          'CONTENT_TYPE' => 'application/xml',
          'HTTP_USER_AGENT' => 'KDDI-CA32 UP.Browser/6.2.0.7.3.129 (GUI) MMP/2.0',
          :input => form_string,
        )

        res = Jpmobile::MobileCarrier.new(Jpmobile::ParamsFilter.new(UnitApplication.new)).call(res)
        req = Rack::Request.new(res[1])
        expect(req.params.size).to eq(0)

        expect(req.body.read).to eq(form_string)
      end
    end
  end
end
