rack-ketai 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/MIT-LICENSE +21 -0
- data/README.rdoc +122 -0
- data/VERSION +1 -0
- data/lib/rack/ketai/carrier/abstract.rb +263 -0
- data/lib/rack/ketai/carrier/au.rb +153 -0
- data/lib/rack/ketai/carrier/cidrs/au.rb +32 -0
- data/lib/rack/ketai/carrier/cidrs/docomo.rb +14 -0
- data/lib/rack/ketai/carrier/cidrs/softbank.rb +10 -0
- data/lib/rack/ketai/carrier/docomo.rb +157 -0
- data/lib/rack/ketai/carrier/emoji/ausjisstrtoemojiid.rb +1391 -0
- data/lib/rack/ketai/carrier/emoji/docomosjisstrtoemojiid.rb +759 -0
- data/lib/rack/ketai/carrier/emoji/emojidata.rb +836 -0
- data/lib/rack/ketai/carrier/emoji/emojiidtotypecast.rb +432 -0
- data/lib/rack/ketai/carrier/emoji/softbankutf8strtoemojiid.rb +1119 -0
- data/lib/rack/ketai/carrier/emoji/softbankwebcodetoutf8str.rb +499 -0
- data/lib/rack/ketai/carrier/general.rb +75 -0
- data/lib/rack/ketai/carrier/iphone.rb +16 -0
- data/lib/rack/ketai/carrier/softbank.rb +144 -0
- data/lib/rack/ketai/carrier/specs/au.rb +1 -0
- data/lib/rack/ketai/carrier/specs/docomo.rb +1 -0
- data/lib/rack/ketai/carrier/specs/softbank.rb +1 -0
- data/lib/rack/ketai/carrier.rb +18 -0
- data/lib/rack/ketai/display.rb +16 -0
- data/lib/rack/ketai/middleware.rb +36 -0
- data/lib/rack/ketai.rb +12 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/unit/au_filter_spec.rb +96 -0
- data/spec/unit/au_spec.rb +240 -0
- data/spec/unit/carrier_spec.rb +30 -0
- data/spec/unit/display_spec.rb +25 -0
- data/spec/unit/docomo_filter_spec.rb +106 -0
- data/spec/unit/docomo_spec.rb +344 -0
- data/spec/unit/emoticon_filter_spec.rb +91 -0
- data/spec/unit/filter_spec.rb +38 -0
- data/spec/unit/iphone_spec.rb +16 -0
- data/spec/unit/middleware_spec.rb +38 -0
- data/spec/unit/softbank_filter_spec.rb +133 -0
- data/spec/unit/softbank_spec.rb +200 -0
- data/spec/unit/valid_addr_spec.rb +86 -0
- data/test/spec_runner.rb +29 -0
- data/tools/generate_emoji_dic.rb +434 -0
- data/tools/update_speclist.rb +87 -0
- metadata +138 -0
@@ -0,0 +1,344 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'rack/ketai/carrier/docomo'
|
3
|
+
describe "Rack::Ketai::Carrier::Docomo" do
|
4
|
+
|
5
|
+
# UAの意味
|
6
|
+
# http://www.nttdocomo.co.jp/service/imode/make/content/browser/html/useragent/
|
7
|
+
|
8
|
+
before(:each) do
|
9
|
+
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "FOMA端末で" do
|
13
|
+
|
14
|
+
# http://www.nttdocomo.co.jp/service/imode/make/content/browser/html/tag/utn.html
|
15
|
+
# FOMA端末製造番号のみ、もしくはFOMAカード製造番号のみの送信はできません。
|
16
|
+
|
17
|
+
describe "iモードIDを取得できたとき" do
|
18
|
+
before(:each) do
|
19
|
+
@env = Rack::MockRequest.env_for('http://hoge.com/dummy?guid=ON',
|
20
|
+
'HTTP_USER_AGENT' => 'DoCoMo/2.0 P903i(c10;serXXXXXXXXXXXXXXX; iccxxxxxxxxxxxxxxxxxxxx)',
|
21
|
+
'HTTP_X_DCMGUID' => '0123abC')
|
22
|
+
@mobile = Rack::Ketai::Carrier::Docomo.new(@env)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "#subscriberid でiモードIDを取得できること" do
|
26
|
+
@mobile.subscriberid.should == '0123abC'
|
27
|
+
end
|
28
|
+
|
29
|
+
it "#deviceid でFOMA端末個体識別子を取得できること" do
|
30
|
+
@mobile.deviceid.should == "XXXXXXXXXXXXXXX"
|
31
|
+
end
|
32
|
+
|
33
|
+
it "#ident でiモードIDを取得できること" do
|
34
|
+
@mobile.ident.should == @mobile.subscriberid
|
35
|
+
@mobile.ident.should == '0123abC'
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "iモードIDが取得できず、FOMAカード個体識別子、FOMA端末個体識別子双方を取得できたとき" do
|
41
|
+
|
42
|
+
before(:each) do
|
43
|
+
@env = Rack::MockRequest.env_for('http://hoge.com/dummy',
|
44
|
+
'HTTP_USER_AGENT' => 'DoCoMo/2.0 P903i(c10;serXXXXXXXXXXXXXXX; iccxxxxxxxxxxxxxxxxxxxx)')
|
45
|
+
@mobile = Rack::Ketai::Carrier::Docomo.new(@env)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "#subscriberid でFOMAカード個体識別子を取得できること" do
|
49
|
+
@mobile.subscriberid.should == "xxxxxxxxxxxxxxxxxxxx"
|
50
|
+
end
|
51
|
+
|
52
|
+
it "#deviceid でFOMA端末個体識別子を取得できること" do
|
53
|
+
@mobile.deviceid.should == "XXXXXXXXXXXXXXX"
|
54
|
+
end
|
55
|
+
|
56
|
+
it "#ident でFOMAカード個体識別子を取得できること" do
|
57
|
+
@mobile.ident.should == @mobile.subscriberid
|
58
|
+
@mobile.ident.should == "xxxxxxxxxxxxxxxxxxxx"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "iモードID、FOMAカード個体識別子およびFOMA端末個体識別子が取得できないとき" do
|
63
|
+
|
64
|
+
before(:each) do
|
65
|
+
@env = Rack::MockRequest.env_for('http://hoge.com/dummy',
|
66
|
+
'HTTP_USER_AGENT' => 'DoCoMo/2.0 SO903i')
|
67
|
+
@mobile = Rack::Ketai::Carrier::Docomo.new(@env)
|
68
|
+
end
|
69
|
+
|
70
|
+
it "#subscriberid は nil を返すこと" do
|
71
|
+
@mobile.subscriberid.should be_nil
|
72
|
+
end
|
73
|
+
|
74
|
+
it "#deviceid は nil を返すこと" do
|
75
|
+
@mobile.deviceid.should be_nil
|
76
|
+
end
|
77
|
+
|
78
|
+
it "#ident は nil を返すこと" do
|
79
|
+
@mobile.ident.should be_nil
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "iモードIDが取得でき、FOMAカード個体識別子およびFOMA端末個体識別子が取得できないとき" do
|
84
|
+
|
85
|
+
before(:each) do
|
86
|
+
@env = Rack::MockRequest.env_for('http://hoge.com/dummy',
|
87
|
+
'HTTP_USER_AGENT' => 'DoCoMo/2.0 SO903i',
|
88
|
+
'HTTP_X_DCMGUID' => '0123abC')
|
89
|
+
@mobile = Rack::Ketai::Carrier::Docomo.new(@env)
|
90
|
+
end
|
91
|
+
|
92
|
+
it "#subscriberid はiモードIDを返すこと" do
|
93
|
+
@mobile.subscriberid.should == '0123abC'
|
94
|
+
end
|
95
|
+
|
96
|
+
it "#deviceid は nil を返すこと" do
|
97
|
+
@mobile.deviceid.should be_nil
|
98
|
+
end
|
99
|
+
|
100
|
+
it "#ident はiモードIDを返すこと" do
|
101
|
+
@mobile.ident.should == '0123abC'
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
it "#name で機種名を取得できること" do
|
106
|
+
env = Rack::MockRequest.env_for('http://hoge.com/dummy',
|
107
|
+
'HTTP_USER_AGENT' => "DoCoMo/2.0 SH02A")
|
108
|
+
mobile = Rack::Ketai::Carrier::Docomo.new(env)
|
109
|
+
mobile.name.should == 'SH02A'
|
110
|
+
end
|
111
|
+
|
112
|
+
it "#cache_size でキャッシュサイズが取得できること" do
|
113
|
+
{
|
114
|
+
'DoCoMo/2.0 P903i' => 5 * 1000,
|
115
|
+
'DoCoMo/2.0 F900i(c100;TJ)' => 100 * 1000,
|
116
|
+
'DoCoMo/2.0 F900i(c100;TC;W22H12)' => 100 * 1000,
|
117
|
+
'DoCoMo/2.0 P903i(c100;serXXXXXXXXXXXXXXX; iccxxxxxxxxxxxxxxxxxxxx)' => 100 * 1000,
|
118
|
+
'DoCoMo/2.0 N06A3(c500;TB;W24H16)' => 500 * 1000,
|
119
|
+
'DoCoMo/2.0 XXXX(c500;TB;W24H16)' => 500 * 1000 # 未知の端末でも
|
120
|
+
}.each do |ua, cache_size|
|
121
|
+
env = Rack::MockRequest.env_for('http://hoge.com/dummy',
|
122
|
+
'HTTP_USER_AGENT' => ua)
|
123
|
+
mobile = Rack::Ketai::Carrier::Docomo.new(env)
|
124
|
+
mobile.cache_size.should == cache_size
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe "ディスプレイ情報を取得できること" do
|
129
|
+
|
130
|
+
it "既知の端末のとき" do
|
131
|
+
@env = Rack::MockRequest.env_for('http://hoge.com/dummy',
|
132
|
+
'HTTP_USER_AGENT' => "DoCoMo/2.0 SH02A(c100;TB;W30H20)")
|
133
|
+
@mobile = Rack::Ketai::Carrier::Docomo.new(@env)
|
134
|
+
display = @mobile.display
|
135
|
+
display.should_not be_nil
|
136
|
+
display.colors.should == 16777216
|
137
|
+
display.width.should == 240
|
138
|
+
display.height.should == 320
|
139
|
+
end
|
140
|
+
|
141
|
+
it "未知の端末のとき" do
|
142
|
+
@env = Rack::MockRequest.env_for('http://hoge.com/dummy',
|
143
|
+
'HTTP_USER_AGENT' => 'DoCoMo/2.0 XX01(c100;TB;W30H20)')
|
144
|
+
@mobile = Rack::Ketai::Carrier::Docomo.new(@env)
|
145
|
+
display = @mobile.display
|
146
|
+
display.should_not be_nil
|
147
|
+
display.colors.should be_nil
|
148
|
+
display.width.should be_nil
|
149
|
+
display.height.should be_nil
|
150
|
+
end
|
151
|
+
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
155
|
+
|
156
|
+
describe "mova端末で" do
|
157
|
+
|
158
|
+
# http://www.nttdocomo.co.jp/service/imode/make/content/browser/html/tag/utn.html
|
159
|
+
|
160
|
+
describe "iモードIDと端末個体識別子を取得できたとき" do
|
161
|
+
before(:each) do
|
162
|
+
@env = Rack::MockRequest.env_for('http://hoge.com/dummy?guid=ON',
|
163
|
+
'HTTP_USER_AGENT' => 'DoCoMo/1.0/SO503i/c10/TB/serXXXXXXXXXXX',
|
164
|
+
'HTTP_X_DCMGUID' => '0123abC')
|
165
|
+
@mobile = Rack::Ketai::Carrier::Docomo.new(@env)
|
166
|
+
end
|
167
|
+
|
168
|
+
it "#subscriberid でiモードIDを取得できること" do
|
169
|
+
@mobile.subscriberid.should == '0123abC'
|
170
|
+
end
|
171
|
+
|
172
|
+
it "#deviceid で端末個体識別子を取得できること" do
|
173
|
+
@mobile.deviceid.should == "XXXXXXXXXXX"
|
174
|
+
end
|
175
|
+
|
176
|
+
it "#ident でiモードIDを取得できること" do
|
177
|
+
@mobile.ident.should == '0123abC'
|
178
|
+
end
|
179
|
+
|
180
|
+
end
|
181
|
+
|
182
|
+
describe "端末個体識別子のみ取得できたとき" do
|
183
|
+
|
184
|
+
before(:each) do
|
185
|
+
@env = Rack::MockRequest.env_for('http://hoge.com/dummy',
|
186
|
+
'HTTP_USER_AGENT' => 'DoCoMo/1.0/SO503i/c10/TB/serXXXXXXXXXXX')
|
187
|
+
@mobile = Rack::Ketai::Carrier::Docomo.new(@env)
|
188
|
+
end
|
189
|
+
|
190
|
+
it "#subscriberid は nil を返すこと" do
|
191
|
+
@mobile.subscriberid.should be_nil
|
192
|
+
end
|
193
|
+
|
194
|
+
it "#deviceid で端末個体識別子を取得できること" do
|
195
|
+
@mobile.deviceid.should == "XXXXXXXXXXX"
|
196
|
+
end
|
197
|
+
|
198
|
+
it "#ident で端末個体識別子を取得できること" do
|
199
|
+
@mobile.ident.should == @mobile.deviceid
|
200
|
+
@mobile.ident.should == "XXXXXXXXXXX"
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
describe "iモードIDも端末個体識別子も取得できないとき" do
|
205
|
+
|
206
|
+
before(:each) do
|
207
|
+
@env = Rack::MockRequest.env_for('http://hoge.com/dummy',
|
208
|
+
'HTTP_USER_AGENT' => 'DoCoMo/1.0/N505i/c20/TB/W24H12')
|
209
|
+
@mobile = Rack::Ketai::Carrier::Docomo.new(@env)
|
210
|
+
end
|
211
|
+
|
212
|
+
it "#subscriberid は nil を返すこと" do
|
213
|
+
@mobile.subscriberid.should be_nil
|
214
|
+
end
|
215
|
+
|
216
|
+
it "#deviceid は nil を返すこと" do
|
217
|
+
@mobile.deviceid.should be_nil
|
218
|
+
end
|
219
|
+
|
220
|
+
it "#ident は nil を返すこと" do
|
221
|
+
@mobile.ident.should be_nil
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
describe "iモードIDのみ取得できたとき" do
|
226
|
+
|
227
|
+
before(:each) do
|
228
|
+
@env = Rack::MockRequest.env_for('http://hoge.com/dummy',
|
229
|
+
'HTTP_USER_AGENT' => 'DoCoMo/1.0/N505i/c20/TB/W24H12',
|
230
|
+
'HTTP_X_DCMGUID' => '0123abC')
|
231
|
+
@mobile = Rack::Ketai::Carrier::Docomo.new(@env)
|
232
|
+
end
|
233
|
+
|
234
|
+
it "#subscriberid はiモードIDを返すこと" do
|
235
|
+
@mobile.subscriberid.should == '0123abC'
|
236
|
+
end
|
237
|
+
|
238
|
+
it "#deviceid は nil を返すこと" do
|
239
|
+
@mobile.deviceid.should be_nil
|
240
|
+
end
|
241
|
+
|
242
|
+
it "#ident はiモードIDを返すこと" do
|
243
|
+
@mobile.ident.should == '0123abC'
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
it "#name で機種名を取得できること" do
|
248
|
+
env = Rack::MockRequest.env_for('http://hoge.com/dummy',
|
249
|
+
'HTTP_USER_AGENT' => "DoCoMo/1.0/SO502i")
|
250
|
+
mobile = Rack::Ketai::Carrier::Docomo.new(env)
|
251
|
+
mobile.name.should == 'SO502i'
|
252
|
+
end
|
253
|
+
|
254
|
+
it "#cache_size でキャッシュサイズが取得できること" do
|
255
|
+
{
|
256
|
+
'DoCoMo/1.0/F502i' => 5 * 1000,
|
257
|
+
'DoCoMo/1.0/D503i/c10' => 10 * 1000,
|
258
|
+
'DoCoMo/1.0/N504i/c10/TB' => 10 * 1000,
|
259
|
+
'DoCoMo/1.0/SO506iS/c20/TB/W20H10' => 20 * 1000,
|
260
|
+
}.each do |ua, cache_size|
|
261
|
+
env = Rack::MockRequest.env_for('http://hoge.com/dummy',
|
262
|
+
'HTTP_USER_AGENT' => ua)
|
263
|
+
mobile = Rack::Ketai::Carrier::Docomo.new(env)
|
264
|
+
mobile.cache_size.should == cache_size
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
describe "ディスプレイ情報を取得できること" do
|
269
|
+
|
270
|
+
it "既知の端末のとき" do
|
271
|
+
@env = Rack::MockRequest.env_for('http://hoge.com/dummy',
|
272
|
+
'HTTP_USER_AGENT' => "DoCoMo/1.0/SO502i")
|
273
|
+
@mobile = Rack::Ketai::Carrier::Docomo.new(@env)
|
274
|
+
display = @mobile.display
|
275
|
+
display.should_not be_nil
|
276
|
+
display.colors.should == 4
|
277
|
+
display.width.should == 120
|
278
|
+
display.height.should == 120
|
279
|
+
end
|
280
|
+
|
281
|
+
it "未知の端末のとき" do
|
282
|
+
@env = Rack::MockRequest.env_for('http://hoge.com/dummy',
|
283
|
+
'HTTP_USER_AGENT' => 'DoCoMo/1.0/X000i')
|
284
|
+
@mobile = Rack::Ketai::Carrier::Docomo.new(@env)
|
285
|
+
display = @mobile.display
|
286
|
+
display.should_not be_nil
|
287
|
+
display.colors.should be_nil
|
288
|
+
display.width.should be_nil
|
289
|
+
display.height.should be_nil
|
290
|
+
end
|
291
|
+
|
292
|
+
end
|
293
|
+
|
294
|
+
end
|
295
|
+
|
296
|
+
describe "#supports_cookie? を使うとき" do
|
297
|
+
|
298
|
+
# iモードブラウザ 2.0から対応
|
299
|
+
# といっても、iモードブラウザ 2.0かどうか判断するには
|
300
|
+
# キャッシュサイズで調べるしかない(c500)
|
301
|
+
# キャッシュが不明な場合は端末データベースから判断
|
302
|
+
# (ただし信頼性が低いので最後の手段)
|
303
|
+
|
304
|
+
it "Cookie対応機種なら true を返すこと" do
|
305
|
+
env = Rack::MockRequest.env_for('http://hoge.com/dummy',
|
306
|
+
'HTTP_USER_AGENT' => 'DoCoMo/2.0 F02B')
|
307
|
+
mobile = Rack::Ketai::Carrier::Docomo.new(env)
|
308
|
+
mobile.should be_respond_to(:supports_cookie?)
|
309
|
+
mobile.should be_supports_cookie
|
310
|
+
end
|
311
|
+
|
312
|
+
it "Cookie未対応機種なら false を返すこと" do
|
313
|
+
env = Rack::MockRequest.env_for('http://hoge.com/dummy',
|
314
|
+
'HTTP_USER_AGENT' => 'DoCoMo/2.0 L06A')
|
315
|
+
mobile = Rack::Ketai::Carrier::Docomo.new(env)
|
316
|
+
mobile.should be_respond_to(:supports_cookie?)
|
317
|
+
mobile.should_not be_supports_cookie
|
318
|
+
end
|
319
|
+
|
320
|
+
it "不明な機種でもキャッシュサイズがわかればそれを基に判断すること" do
|
321
|
+
env = Rack::MockRequest.env_for('http://hoge.com/dummy',
|
322
|
+
'HTTP_USER_AGENT' => 'DoCoMo/2.0 X00HOGE3(c500;TB;W24H15)')
|
323
|
+
mobile = Rack::Ketai::Carrier::Docomo.new(env)
|
324
|
+
mobile.should be_respond_to(:supports_cookie?)
|
325
|
+
mobile.should be_supports_cookie
|
326
|
+
|
327
|
+
env = Rack::MockRequest.env_for('http://hoge.com/dummy',
|
328
|
+
'HTTP_USER_AGENT' => 'DoCoMo/2.0 X00HOGE3(c100;TB;W24H15)')
|
329
|
+
mobile = Rack::Ketai::Carrier::Docomo.new(env)
|
330
|
+
mobile.should be_respond_to(:supports_cookie?)
|
331
|
+
mobile.should_not be_supports_cookie
|
332
|
+
end
|
333
|
+
|
334
|
+
it "不明な機種でキャッシュサイズもわからないなら false を返すこと" do
|
335
|
+
env = Rack::MockRequest.env_for('http://hoge.com/dummy',
|
336
|
+
'HTTP_USER_AGENT' => 'DoCoMo/2.0 X00HOGE')
|
337
|
+
mobile = Rack::Ketai::Carrier::Docomo.new(env)
|
338
|
+
mobile.should be_respond_to(:supports_cookie?)
|
339
|
+
mobile.should_not be_supports_cookie
|
340
|
+
end
|
341
|
+
|
342
|
+
end
|
343
|
+
|
344
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'kconv'
|
3
|
+
require 'rack/ketai/carrier/general'
|
4
|
+
|
5
|
+
describe Rack::Ketai::Carrier::General::EmoticonFilter, "外部フィルタを適用する時" do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
@filter = Rack::Ketai::Carrier::General::EmoticonFilter.new(:emoticons_path => '/images/emoticons')
|
9
|
+
end
|
10
|
+
|
11
|
+
it "emoticons_path が与えられないときはなにもしないこと" do
|
12
|
+
filter = Rack::Ketai::Carrier::General::EmoticonFilter.new
|
13
|
+
Rack::Ketai::Carrier::General::EmoticonFilter::EMOJIID_TO_TYPECAST_EMOTICONS.each do |emojiid, filenames|
|
14
|
+
str = '今日はいい[e:'+format("%03X", emojiid)+']ですね。'
|
15
|
+
resdata = str
|
16
|
+
|
17
|
+
status, headers, body = filter.outbound(200, { "Content-Type" => "text/html"}, [str])
|
18
|
+
|
19
|
+
body[0].should == resdata
|
20
|
+
end
|
21
|
+
filter = Rack::Ketai::Carrier::General::EmoticonFilter.new(:emoticons_path => '')
|
22
|
+
Rack::Ketai::Carrier::General::EmoticonFilter::EMOJIID_TO_TYPECAST_EMOTICONS.each do |emojiid, filenames|
|
23
|
+
str = '今日はいい[e:'+format("%03X", emojiid)+']ですね。'
|
24
|
+
resdata = str
|
25
|
+
|
26
|
+
status, headers, body = filter.outbound(200, { "Content-Type" => "text/html"}, [str])
|
27
|
+
|
28
|
+
body[0].should == resdata
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
it "データ中の絵文字IDをimgタグに変換すること" do
|
33
|
+
Rack::Ketai::Carrier::General::EmoticonFilter::EMOJIID_TO_TYPECAST_EMOTICONS.each do |emojiid, filenames|
|
34
|
+
tag = filenames.collect{ |filename| "<img src=\"/images/emoticons/#{filename}.gif\" />" }.join('')
|
35
|
+
resdata = "今日はいい#{tag}ですね。"
|
36
|
+
|
37
|
+
status, headers, body = @filter.outbound(200, { "Content-Type" => "text/html"}, ['今日はいい[e:'+format("%03X", emojiid)+']ですね。'])
|
38
|
+
|
39
|
+
body[0].should == resdata
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
it "データ中に絵文字ID=絵文字IDだが絵文字≠絵文字IDのIDが含まれているとき、正しく逆変換できること" do
|
44
|
+
resdata = "たとえば<img src=\"/images/emoticons/happy01.gif\" />「e-330 HAPPY FACE WITH OPEN MOUTH」とか。"
|
45
|
+
|
46
|
+
status, headers, body = @filter.outbound(200, { "Content-Type" => "text/html"}, ["たとえば[e:330]「e-330 HAPPY FACE WITH OPEN MOUTH」とか。"])
|
47
|
+
|
48
|
+
body[0].should == resdata
|
49
|
+
end
|
50
|
+
|
51
|
+
it "データ中にTypepad絵文字にはない絵文字IDが存在するとき、代替文字を表示すること" do
|
52
|
+
resdata = "黒い矢印[#{[0x2190].pack('U')}]です" # 左黒矢印
|
53
|
+
|
54
|
+
status, headers, body = @filter.outbound(200, { "Content-Type" => "text/html"}, ['黒い矢印[e:AFB]です'])
|
55
|
+
|
56
|
+
body[0].should == resdata
|
57
|
+
end
|
58
|
+
|
59
|
+
it "Content-typeがhtmlでないときには変換しないこと(未設定の場合除く)" do
|
60
|
+
emojiid = 0x00F
|
61
|
+
filenames = ["sun","cloud"]
|
62
|
+
str = '今日はいい[e:'+format("%03X", emojiid)+']ですね。'
|
63
|
+
tag = filenames.collect{ |filename| "<img src=\"/images/emoticons/#{filename}.gif\" />" }.join('')
|
64
|
+
|
65
|
+
%w(text/plain text/xml text/json application/json text/javascript application/rss+xml image/jpeg).each do |contenttype|
|
66
|
+
resdata = str
|
67
|
+
|
68
|
+
status, headers, body = @filter.outbound(200, { "Content-Type" => contenttype}, ['今日はいい[e:'+format("%03X", emojiid)+']ですね。'])
|
69
|
+
|
70
|
+
body[0].should == resdata
|
71
|
+
end
|
72
|
+
|
73
|
+
%w(text/html application/xhtml+xml).each do |contenttype|
|
74
|
+
resdata = '今日はいい'+tag+'ですね。'
|
75
|
+
|
76
|
+
status, headers, body = @filter.outbound(200, { "Content-Type" => contenttype}, ['今日はいい[e:'+format("%03X", emojiid)+']ですね。'])
|
77
|
+
|
78
|
+
body[0].should == resdata
|
79
|
+
end
|
80
|
+
|
81
|
+
resdata = '今日はいい'+tag+'ですね。'
|
82
|
+
status, headers, body = @filter.outbound(200, { "Content-Type" => ''}, ['今日はいい[e:'+format("%03X", emojiid)+']ですね。'])
|
83
|
+
body[0].should == resdata
|
84
|
+
|
85
|
+
resdata = '今日はいい'+tag+'ですね。'
|
86
|
+
status, headers, body = @filter.outbound(200, {}, ['今日はいい[e:'+format("%03X", emojiid)+']ですね。'])
|
87
|
+
body[0].should == resdata
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'rack/ketai/carrier/general'
|
3
|
+
describe Rack::Ketai::Carrier::General do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@env = Rack::MockRequest.env_for('http://hoge.com/dummy')
|
7
|
+
@carrier = Rack::Ketai::Carrier::General.new(@env)
|
8
|
+
end
|
9
|
+
|
10
|
+
it ":disable_filter オプションを指定しないか false を渡すとフィルタが実行されること" do
|
11
|
+
options = { }
|
12
|
+
response = [200, { }, ['']]
|
13
|
+
mock_filter = mock(Rack::Ketai::Carrier::General::EmoticonFilter)
|
14
|
+
mock_filter.should_receive(:inbound).once.with(@env).and_return(@env)
|
15
|
+
mock_filter.should_receive(:outbound).once.with(*response).and_return(response)
|
16
|
+
Rack::Ketai::Carrier::General::EmoticonFilter.should_receive(:new).at_least(1).with(options).and_return(mock_filter)
|
17
|
+
@carrier.filtering(@env, options){ |env| response }
|
18
|
+
|
19
|
+
options = { :disable_filter => false }
|
20
|
+
response = [200, { }, ['']]
|
21
|
+
mock_filter = mock(Rack::Ketai::Carrier::General::EmoticonFilter)
|
22
|
+
mock_filter.should_receive(:inbound).once.with(@env).and_return(@env)
|
23
|
+
mock_filter.should_receive(:outbound).once.with(*response).and_return(response)
|
24
|
+
Rack::Ketai::Carrier::General::EmoticonFilter.should_receive(:new).at_least(1).with(options).and_return(mock_filter)
|
25
|
+
@carrier.filtering(@env, options){ |env| response }.should == response
|
26
|
+
end
|
27
|
+
|
28
|
+
it ":disable_filter オプションに true を渡すと、フィルタが実行されないこと" do
|
29
|
+
options = { :disable_filter => true }
|
30
|
+
response = [200, { }, ['']]
|
31
|
+
mock_filter = mock(Rack::Ketai::Carrier::General::EmoticonFilter)
|
32
|
+
mock_filter.should_receive(:inbound).exactly(0)
|
33
|
+
mock_filter.should_receive(:outbound).exactly(0)
|
34
|
+
Rack::Ketai::Carrier::General::EmoticonFilter.should_receive(:new).any_number_of_times.with(options).and_return(mock_filter)
|
35
|
+
@carrier.filtering(@env, options){ |env| response }.should == response
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'rack/ketai/carrier/iphone'
|
3
|
+
describe "Rack::Ketai::Carrier::IPhone" do
|
4
|
+
|
5
|
+
describe "#supports_cookie? を使うとき" do
|
6
|
+
# iPhone はCookie対応
|
7
|
+
it "#supports_cookie? は true を返す" do
|
8
|
+
env = Rack::MockRequest.env_for('http://hoge.com/dummy',
|
9
|
+
'HTTP_USER_AGENT' => 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_0 like Mac OS X; ja-jp) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8A293 Safari/6531.22.7')
|
10
|
+
mobile = Rack::Ketai::Carrier::IPhone.new(env)
|
11
|
+
mobile.should be_respond_to(:supports_cookie?)
|
12
|
+
mobile.should be_supports_cookie
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
describe Rack::Ketai::Middleware, "#call を実行するとき" do
|
4
|
+
|
5
|
+
it "適切な env['rack.ketai'] を設定できること" do
|
6
|
+
{
|
7
|
+
'DoCoMo/1.0/N505i' => Rack::Ketai::Carrier::Docomo, # Mova
|
8
|
+
'DoCoMo/2.0 P903i' => Rack::Ketai::Carrier::Docomo, # FOMA
|
9
|
+
'KDDI-CA39 UP.Browser/6.2.0.13.1.5 (GUI) MMP/2.0' => Rack::Ketai::Carrier::Au, # WAP2.0 MMP2.0
|
10
|
+
'KDDI-TS21 UP.Browser/6.0.2.273 (GUI) MMP/1.1' => Rack::Ketai::Carrier::Au, # WAP2.0 MMP1.1
|
11
|
+
'SoftBank/1.0/930SH/SHJ001[/Serial] Browser/NetFront/3.4 Profile/MIDP-2.0 Configuration/CLDC-1.1' => Rack::Ketai::Carrier::Softbank, # SoftBank 3GC
|
12
|
+
'Mozilla/5.0 (iPhone; U; CPU iPhone OS 2_0_1 like Mac OS X; ja-jp) AppleWebKit/525.18.1 (KHTML, like Gecko) Version/3.1.1 Mobile/5B108 Safari/525.20' => Rack::Ketai::Carrier::IPhone,
|
13
|
+
'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; Q312461; .NET CLR 1.0.3705; .NET CLR 1.1.4322; .NET CLR 2.0.50727)' => nil, # IE8
|
14
|
+
'Mozilla/5.0 (Windows; U; Windows NT 5.1; ja; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1' => nil,
|
15
|
+
'Opera/9.21 (Windows NT 5.1; U; ja)' => nil,
|
16
|
+
'Mozilla/5.0 (Windows; U; Windows NT 5.1; ja-JP) AppleWebKit/525.19 (KHTML, like Gecko) Version/3.1.2 Safari/525.21' => nil,
|
17
|
+
'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.29 Safari/525.13' => nil,
|
18
|
+
}.each do |ua, carrier|
|
19
|
+
mock_env = Rack::MockRequest.env_for('http://hoge.com/dummy','HTTP_USER_AGENT' => ua)
|
20
|
+
|
21
|
+
mock_app = mock('App')
|
22
|
+
mock_app.should_receive(:call) do |env|
|
23
|
+
if carrier
|
24
|
+
env['rack.ketai'].should_not be_nil
|
25
|
+
env['rack.ketai'].mobile?.should be_true
|
26
|
+
else
|
27
|
+
env['rack.ketai'].should be_nil
|
28
|
+
env['rack.ketai'].mobile?.should be_false
|
29
|
+
end
|
30
|
+
[200, { "Content-Type" => "text/plain"}, ["OK"]]
|
31
|
+
end
|
32
|
+
|
33
|
+
middleware = Rack::Ketai::Middleware.new(mock_app, { })
|
34
|
+
middleware.call(mock_env)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'kconv'
|
3
|
+
require 'rack/ketai/carrier/softbank'
|
4
|
+
describe Rack::Ketai::Carrier::Softbank::Filter, "内部フィルタを適用する時" do
|
5
|
+
|
6
|
+
before(:each) do
|
7
|
+
@filter = Rack::Ketai::Carrier::Softbank::Filter.new
|
8
|
+
end
|
9
|
+
|
10
|
+
it "POSTデータ中のUTF-8バイナリの絵文字を絵文字IDに変換すること" do
|
11
|
+
Rack::Ketai::Carrier::Softbank::Filter::EMOJI_TO_EMOJIID.should_not be_empty
|
12
|
+
Rack::Ketai::Carrier::Softbank::Filter::EMOJI_TO_EMOJIID.each do |emoji, emojiid|
|
13
|
+
postdata = CGI.escape("message=今日はいい" + emoji + "ですね。")
|
14
|
+
postdata.force_encoding('UTF-8') if postdata.respond_to?(:force_encoding)
|
15
|
+
|
16
|
+
env = Rack::MockRequest.env_for('http://hoge.com/dummy',
|
17
|
+
'HTTP_USER_AGENT' => 'Softbank/2.0 P903i',
|
18
|
+
:method => 'POST',
|
19
|
+
:input => postdata)
|
20
|
+
env = @filter.inbound(env)
|
21
|
+
request = Rack::Request.new(env)
|
22
|
+
request.params['message'].should == '今日はいい[e:'+format("%03X", emojiid)+']ですね。'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
it "POSTデータ中のウェブコードの絵文字を絵文字IDに変換すること" do
|
27
|
+
Rack::Ketai::Carrier::Softbank::Filter::WEBCODE_TO_EMOJI.should_not be_empty
|
28
|
+
Rack::Ketai::Carrier::Softbank::Filter::EMOJI_TO_EMOJIID.should_not be_empty
|
29
|
+
Rack::Ketai::Carrier::Softbank::Filter::WEBCODE_TO_EMOJI.each do |webcode, emoji|
|
30
|
+
emojiid = Rack::Ketai::Carrier::Softbank::Filter::EMOJI_TO_EMOJIID[emoji]
|
31
|
+
postdata = CGI.escape("message=今日はいい\x1B$" + webcode + "\x0Fですね。")
|
32
|
+
postdata.force_encoding('UTF-8') if postdata.respond_to?(:force_encoding)
|
33
|
+
|
34
|
+
env = Rack::MockRequest.env_for('http://hoge.com/dummy',
|
35
|
+
'HTTP_USER_AGENT' => 'Softbank/2.0 P903i',
|
36
|
+
:method => 'POST',
|
37
|
+
:input => postdata)
|
38
|
+
env = @filter.inbound(env)
|
39
|
+
request = Rack::Request.new(env)
|
40
|
+
request.params['message'].should == '今日はいい[e:'+format("%03X", emojiid)+']ですね。'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
it "POSTデータ中の連続するウェブコードの絵文字を絵文字IDに変換すること" do
|
45
|
+
postdata = CGI.escape("message=今日の天気は\x1B$Gji\x0Fです\x1B$ON\x0F")
|
46
|
+
postdata.force_encoding('UTF-8') if postdata.respond_to?(:force_encoding)
|
47
|
+
|
48
|
+
env = Rack::MockRequest.env_for('http://hoge.com/dummy',
|
49
|
+
'HTTP_USER_AGENT' => 'Softbank/2.0 P903i',
|
50
|
+
:method => 'POST',
|
51
|
+
:input => postdata)
|
52
|
+
env = @filter.inbound(env)
|
53
|
+
request = Rack::Request.new(env)
|
54
|
+
request.params['message'].should == '今日の天気は[e:00F]です[e:B60]'
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
describe Rack::Ketai::Carrier::Softbank::Filter, "外部フィルタを適用する時" do
|
60
|
+
|
61
|
+
before(:each) do
|
62
|
+
@filter = Rack::Ketai::Carrier::Softbank::Filter.new
|
63
|
+
end
|
64
|
+
|
65
|
+
it "データ中の絵文字IDをウェブコードに変換すること" do
|
66
|
+
Rack::Ketai::Carrier::Softbank::Filter::WEBCODE_TO_EMOJI.should_not be_empty
|
67
|
+
Rack::Ketai::Carrier::Softbank::Filter::EMOJI_TO_EMOJIID.should_not be_empty
|
68
|
+
Rack::Ketai::Carrier::Softbank::Filter::WEBCODE_TO_EMOJI.each do |webcode, emoji|
|
69
|
+
emojiid = Rack::Ketai::Carrier::Softbank::Filter::EMOJI_TO_EMOJIID[emoji]
|
70
|
+
resdata = "今日はいい\x1B$#{webcode}\x0Fですね。"
|
71
|
+
|
72
|
+
status, headers, body = @filter.outbound(200, { "Content-Type" => "text/html"}, ['今日はいい[e:'+format("%03X", emojiid)+']ですね。'])
|
73
|
+
|
74
|
+
body[0].should == resdata
|
75
|
+
end
|
76
|
+
|
77
|
+
resdata = "今日の天気は\x1B$Gj\x0F\x1B$Gi\x0Fです\x1B$ON\x0F"
|
78
|
+
status, headers, body = @filter.outbound(200, { "Content-Type" => "text/html"}, ['今日の天気は[e:00F]です[e:B60]'])
|
79
|
+
body[0].should == resdata
|
80
|
+
end
|
81
|
+
|
82
|
+
it "Content-typeが指定なし,text/html, application/xhtml+xml 以外の時はフィルタを適用しないこと" do
|
83
|
+
Rack::Ketai::Carrier::Softbank::Filter::WEBCODE_TO_EMOJI.should_not be_empty
|
84
|
+
Rack::Ketai::Carrier::Softbank::Filter::EMOJI_TO_EMOJIID.should_not be_empty
|
85
|
+
Rack::Ketai::Carrier::Softbank::Filter::WEBCODE_TO_EMOJI.each do |webcode, emoji|
|
86
|
+
emojiid = Rack::Ketai::Carrier::Softbank::Filter::EMOJI_TO_EMOJIID[emoji]
|
87
|
+
internaldata = '今日はいい[e:'+format("%03X", emojiid)+']ですね。'
|
88
|
+
%w(text/plain text/xml text/json application/json text/javascript application/rss+xml image/jpeg).each do |contenttype|
|
89
|
+
status, headers, body = @filter.outbound(200, { "Content-Type" => contenttype }, [internaldata])
|
90
|
+
body[0].should == internaldata
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
it "データ中に絵文字ID=絵文字IDだが絵文字≠絵文字IDのIDが含まれているとき、正しく逆変換できること" do
|
96
|
+
emoji = [0xF649].pack('n')
|
97
|
+
resdata = "たとえば\x1B$P*\x0F「e-33E RELIEVED FACE」とか。"
|
98
|
+
|
99
|
+
status, headers, body = @filter.outbound(200, { "Content-Type" => "text/html"}, ["たとえば[e:33E]「e-33E RELIEVED FACE」とか。"])
|
100
|
+
|
101
|
+
body[0].should == resdata
|
102
|
+
end
|
103
|
+
|
104
|
+
it "データ中にSoftBankにはない絵文字IDが存在するとき、代替文字を表示すること" do
|
105
|
+
resdata = "Soon[SOON]です" # soon
|
106
|
+
|
107
|
+
status, headers, body = @filter.outbound(200, { "Content-Type" => "text/html"}, ['Soon[e:018]です'])
|
108
|
+
|
109
|
+
body[0].should == resdata
|
110
|
+
end
|
111
|
+
|
112
|
+
it "Content-typeを適切に書き換えられること" do
|
113
|
+
[
|
114
|
+
[nil, nil],
|
115
|
+
['text/html', 'text/html; charset=utf-8'],
|
116
|
+
['text/html; charset=utf-8', 'text/html; charset=utf-8'],
|
117
|
+
['text/html;charset=utf-8', 'text/html;charset=utf-8'],
|
118
|
+
['application/xhtml+xml', 'application/xhtml+xml; charset=utf-8'],
|
119
|
+
['application/xhtml+xml; charset=utf-8', 'application/xhtml+xml; charset=utf-8'],
|
120
|
+
['application/xhtml+xml;charset=utf-8', 'application/xhtml+xml;charset=utf-8'],
|
121
|
+
['text/javascript', 'text/javascript'],
|
122
|
+
['text/json', 'text/json'],
|
123
|
+
['application/json', 'application/json'],
|
124
|
+
['text/javascript+json', 'text/javascript+json'],
|
125
|
+
['image/jpeg', 'image/jpeg'],
|
126
|
+
['application/octet-stream', 'application/octet-stream'],
|
127
|
+
].each do |content_type, valid_content_type|
|
128
|
+
status, headers, body = @filter.outbound(200, { "Content-Type" => content_type}, ['適当な本文'])
|
129
|
+
headers['Content-Type'].should == valid_content_type
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|