jpmobile 2.0.2 → 2.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -271,7 +271,10 @@ trans_sid を使用する際には、例えば config/initializers/session_store
271
271
  * au は ISO-2022-JP エンコードで送信
272
272
  * ビューやレイアウトの自動振り分け
273
273
  * docomo であれば app/views/mobile_mailer/registration_mobile_docomo.html.erb など
274
- * 受信に関しては、docomo/SoftBank でテストできないため、実験版とします。
274
+ * 受信に関しては、docomo/SoftBank でテストできていないため、実験版とします。
275
+ * テストして問題あれば随時報告してください。
276
+ * オプションに :decorated => true を追加すると、各キャリアのデコメに適したフォーマットで送信します。
277
+ * ただし docomo/SoftBank でテスト出来ていないため、実験版とします。
275
278
 
276
279
  == テストに必要なgemパッケージ
277
280
  テストを実行するためには以下のgemパッケージが必要です。
data/VERSION.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
2
  :major: 2
3
3
  :minor: 0
4
- :patch: 2
4
+ :patch: 3
5
5
  :build: !!null
@@ -203,5 +203,56 @@ module Jpmobile
203
203
  end
204
204
  end
205
205
  end
206
+
207
+ @@pc_emoticon_image_path = nil
208
+ @@pc_emoticon_yaml = nil
209
+ @@pc_emoticon_hash = nil
210
+
211
+ def self.pc_emoticon_image_path
212
+ @@pc_emoticon_image_path
213
+ end
214
+ def self.pc_emoticon_image_path=(path)
215
+ @@pc_emoticon_image_path=(path)
216
+ end
217
+
218
+ def self.pc_emoticon_yaml=(file)
219
+ @@pc_emoticon_yaml = file
220
+ end
221
+ def self.pc_emoticon_yaml
222
+ @@pc_emoticon_yaml
223
+ end
224
+
225
+ def self.pc_emoticon?
226
+ if @@pc_emoticon_yaml and File.exist?(@@pc_emoticon_yaml) and @@pc_emoticon_image_path
227
+
228
+ unless @@pc_emoticon_hash
229
+ begin
230
+ yaml_hash = YAML.load_file(@@pc_emoticon_yaml)
231
+ @@pc_emoticon_hash = Hash[*(yaml_hash.values.inject([]){ |r, v| r += v.to_a.flatten; r})]
232
+ @@pc_emoticon_image_path.chop if @@pc_emoticon_image_path.match(/\/$/)
233
+
234
+ return true
235
+ rescue => ex
236
+ end
237
+ else
238
+ return true
239
+ end
240
+ end
241
+
242
+ return false
243
+ end
244
+
245
+ def self.emoticons_to_image(str)
246
+ if @@pc_emoticon_hash
247
+ utf8_to_unicodecr(str).gsub(/&#x([0-9a-f]{4});/i) do |match|
248
+ img = @@pc_emoticon_hash[$1.upcase] || (@@pc_emoticon_hash[("%x" % ($1.scanf("%x").first - 0x1000)).upcase] rescue nil)
249
+ if img
250
+ "<img src=\"#{@@pc_emoticon_image_path}/#{img}.gif\" alt=\"#{img}\" />"
251
+ else
252
+ ""
253
+ end
254
+ end
255
+ end
256
+ end
206
257
  end
207
258
  end
data/lib/jpmobile/mail.rb CHANGED
@@ -66,7 +66,8 @@ module Mail
66
66
 
67
67
  self.body.charset = @charset
68
68
  self.body.mobile = @mobile
69
- self.header['Content-Transfer-Encoding'] = '8bit'
69
+ self.header['Content-Transfer-Encoding'] = @mobile.content_transfer_encoding(self.header)
70
+ self.header['Content-ID'] = nil if @mobile.decorated? and !self.content_type.match(/image\//)
70
71
 
71
72
  buffer = header.encoded
72
73
  buffer << "\r\n"
@@ -137,6 +138,93 @@ module Mail
137
138
  alias_method :body_lazy_without_jpmobile, :body_lazy
138
139
  alias_method :body_lazy, :body_lazy_with_jpmobile
139
140
 
141
+ # -- docomo
142
+ # multipart/mixed
143
+ # |- multipart/related
144
+ # | |- multipart/alternative
145
+ # | | |- text/plain
146
+ # | | |- text/html
147
+ # | |- image/xxxx (インライン画像)
148
+ # |- image/xxxx (添付画像)
149
+
150
+ # -- au
151
+ # multipart/mixed
152
+ # |- multipart/alternative
153
+ # | |- text/plain
154
+ # | |- text/html
155
+ # |- image/xxxx (インライン画像)
156
+ # |- image/xxxx (添付画像)
157
+
158
+ # -- normal
159
+ # multipart/mixed
160
+ # |- multipart/alternative
161
+ # | |- text/plain
162
+ # | |- text/html
163
+ # | |- image/xxxx (インライン画像)
164
+ # |- image/xxxx (添付画像)
165
+
166
+ def rearrange!
167
+ if @mobile and @mobile.decoratable?
168
+ @mobile.decorated = true
169
+ text_body_part = find_part_by_content_type("text/plain").first
170
+ html_body_part = find_part_by_content_type("text/html").first
171
+ html_body_part.transport_encoding = 'quoted-printable' if html_body_part
172
+ inline_images = []
173
+ attached_files = []
174
+ attachments.each do |p|
175
+ if p.content_type.match(/^image\//) and p.content_disposition.match(/^inline/)
176
+ p.header['Content-Disposition'] = nil
177
+ inline_images << p
178
+ elsif p.content_disposition
179
+ attached_files << p
180
+ end
181
+ end
182
+
183
+ alternative_part = Mail::Part.new{content_type 'multipart/alternative'}
184
+ alternative_part.add_part(text_body_part) if text_body_part
185
+ alternative_part.add_part(html_body_part) if html_body_part
186
+
187
+ if @mobile.require_related_part?
188
+ related_part = Mail::Part.new{content_type 'multipart/related'}
189
+ related_part.add_part(alternative_part)
190
+ inline_images.each do |inline_image|
191
+ related_part.add_part(inline_image)
192
+ end
193
+ inline_images.clear
194
+ else
195
+ related_part = alternative_part
196
+ end
197
+
198
+ unless self.header['Content-Type'].sub_type == 'mixed'
199
+ self.header['Content-Type'] = self.content_type.gsub(/#{self.header['Content-Type'].sub_type}/, 'mixed')
200
+ end
201
+ self.parts.clear
202
+ self.body = nil
203
+
204
+ self.add_part(related_part)
205
+ inline_images.each do |inline_image|
206
+ self.add_part(inline_image)
207
+ end
208
+ attached_files.each do |attached_file|
209
+ self.add_part(attached_file)
210
+ end
211
+ end
212
+ end
213
+
214
+ def find_part_by_content_type(content_type)
215
+ finded_parts = []
216
+
217
+ self.parts.each do |part|
218
+ if part.multipart?
219
+ finded_parts << part.find_part_by_content_type(content_type)
220
+ elsif part.content_type.match(/^#{content_type}/)
221
+ finded_parts << part
222
+ end
223
+ end
224
+
225
+ finded_parts.flatten
226
+ end
227
+
140
228
  private
141
229
  def convert_encoding_jpmobile
142
230
  # decide mobile carrier
@@ -219,8 +307,17 @@ module Mail
219
307
  if @mobile and !multipart?
220
308
  if @mobile.to_mail_body_encoded?(@raw_source)
221
309
  @raw_source
310
+ elsif Jpmobile::Util.ascii_8bit?(@raw_source)
311
+ enc = Mail::Encodings::get_encoding(get_best_encoding(transfer_encoding))
312
+ Jpmobile::Util.force_encode(enc.encode(@raw_source), nil, @charset)
222
313
  else
223
- @mobile.to_mail_body(Jpmobile::Util.force_encode(@raw_source, @charset, Jpmobile::Util::UTF8))
314
+ if transfer_encoding == 'quoted-printable'
315
+ # [str].pack("M").gsub(/\n/, "\r\n")
316
+ Jpmobile::Util.force_encode([@mobile.to_mail_body(Jpmobile::Util.force_encode(@raw_source, @charset, Jpmobile::Util::UTF8))].pack("M").gsub(/\n/, "\r\n"), Jpmobile::Util::BINARY, @charset)
317
+ # @mobile.to_mail_body(Jpmobile::Util.force_encode(@raw_source, @charset, Jpmobile::Util::UTF8))
318
+ else
319
+ @mobile.to_mail_body(Jpmobile::Util.force_encode(@raw_source, @charset, Jpmobile::Util::UTF8))
320
+ end
224
321
  end
225
322
  else
226
323
  encoded_without_jpmobile(transfer_encoding)
@@ -278,7 +375,7 @@ module Mail
278
375
  if @mobile
279
376
  Jpmobile::Util.encode(crlf_boundary_without_jpmobile, @charset)
280
377
  else
281
- epilogue_without_jpmobile
378
+ crlf_boundary_without_jpmobile
282
379
  end
283
380
  end
284
381
 
@@ -286,7 +383,7 @@ module Mail
286
383
  if @mobile
287
384
  Jpmobile::Util.encode(end_boundary_without_jpmobile, @charset)
288
385
  else
289
- epilogue_without_jpmobile
386
+ end_boundary_without_jpmobile
290
387
  end
291
388
  end
292
389
 
@@ -23,11 +23,16 @@ module Jpmobile
23
23
  end
24
24
  self.lookup_context.mobile = @mobile.variants
25
25
 
26
+ @mobile.decorated = headers.delete(:decorated)
27
+
26
28
  m = super(headers, &block)
27
29
 
28
30
  m.mobile = @mobile
29
31
  m.charset = @mobile.mail_charset
30
32
 
33
+ # for decorated-mail manipulation
34
+ m.rearrange! if @mobile.decorated?
35
+
31
36
  m
32
37
  end
33
38
 
@@ -16,6 +16,8 @@ module Jpmobile::Mobile
16
16
  USER_AGENT_REGEXP = nil
17
17
  # 対応するメールアドレスの正規表現
18
18
  MAIL_ADDRESS_REGEXP = nil
19
+ # テキスト部分の content-transfer-encoding
20
+ MAIL_CONTENT_TRANSFER_ENCODING = '7bit'
19
21
 
20
22
  # 緯度経度があれば Position のインスタンスを返す。
21
23
  def position; return nil; end
@@ -115,6 +117,21 @@ module Jpmobile::Mobile
115
117
  # (charset.nil? or charset == "") ? self.class::MAIL_CHARSET : charset
116
118
  self.class::MAIL_CHARSET
117
119
  end
120
+ def content_transfer_encoding(headers)
121
+ transfer_encoding = headers['Content-Transfer-Encoding']
122
+ case headers['Content-Type'].to_s
123
+ when /text\/plain/
124
+ transfer_encoding.to_s == MAIL_CONTENT_TRANSFER_ENCODING ? transfer_encoding : MAIL_CONTENT_TRANSFER_ENCODING
125
+ when /text\/html/
126
+ if self.decorated?
127
+ 'quoted-printable'
128
+ else
129
+ transfer_encoding.to_s == MAIL_CONTENT_TRANSFER_ENCODING ? transfer_encoding : MAIL_CONTENT_TRANSFER_ENCODING
130
+ end
131
+ else
132
+ transfer_encoding
133
+ end
134
+ end
118
135
  def to_mail_encoding(str)
119
136
  str = Jpmobile::Emoticon.utf8_to_unicodecr(str)
120
137
  str = Jpmobile::Emoticon.unicodecr_to_external(str, Jpmobile::Emoticon::CONVERSION_TABLE_TO_PC_EMAIL, false)
@@ -144,6 +161,18 @@ module Jpmobile::Mobile
144
161
  body = to_mail_internal(body, nil)
145
162
  Jpmobile::Util.force_encode(body, charset, Jpmobile::Util::UTF8)
146
163
  end
164
+ def decoratable?
165
+ false
166
+ end
167
+ def require_related_part?
168
+ false
169
+ end
170
+ def decorated=(boolean)
171
+ @decorated = boolean
172
+ end
173
+ def decorated?
174
+ @decorated
175
+ end
147
176
 
148
177
  # リクエストがこのクラスに属するか調べる
149
178
  # メソッド名に関して非常に不安
@@ -118,6 +118,10 @@ module Jpmobile::Mobile
118
118
  str
119
119
  end
120
120
 
121
+ def decoratable?
122
+ true
123
+ end
124
+
121
125
  private
122
126
  def to_mail_encoding(str)
123
127
  str = Jpmobile::Emoticon.utf8_to_unicodecr(str)
@@ -10,6 +10,8 @@ module Jpmobile::Mobile
10
10
  MAIL_ADDRESS_REGEXP = /.+@docomo\.ne\.jp/
11
11
  # メールのデフォルトのcharset
12
12
  MAIL_CHARSET = "Shift_JIS"
13
+ # テキスト部分の content-transfer-encoding
14
+ MAIL_CONTENT_TRANSFER_ENCODING = '8bit'
13
15
 
14
16
  # オープンiエリアがあればエリアコードを +String+ で返す。無ければ +nil+ を返す。
15
17
  def areacode
@@ -114,6 +116,12 @@ module Jpmobile::Mobile
114
116
  def to_mail_body_encoded?(str)
115
117
  Jpmobile::Util.shift_jis?(str)
116
118
  end
119
+ def decoratable?
120
+ true
121
+ end
122
+ def require_related_part?
123
+ true
124
+ end
117
125
 
118
126
  # i-mode ブラウザのバージョンを返す。
119
127
  # http://labs.unoh.net/2009/07/i_20.html
@@ -11,6 +11,8 @@ module Jpmobile::Mobile
11
11
  MAIL_ADDRESS_REGEXP = /.+@(?:softbank\.ne\.jp|disney\.ne\.jp)/
12
12
  # メールのデフォルトのcharset
13
13
  MAIL_CHARSET = "Shift_JIS"
14
+ # テキスト部分の content-transfer-encoding
15
+ MAIL_CONTENT_TRANSFER_ENCODING = '8bit'
14
16
 
15
17
  # 製造番号を返す。無ければ +nil+ を返す。
16
18
  def serial_number
@@ -80,6 +82,12 @@ module Jpmobile::Mobile
80
82
  def to_mail_body_encoded?(str)
81
83
  Jpmobile::Util.shift_jis?(str)
82
84
  end
85
+ def decoratable?
86
+ true
87
+ end
88
+ def require_related_part?
89
+ true
90
+ end
83
91
 
84
92
  private
85
93
  def to_mail_encoding(str)
@@ -27,17 +27,10 @@ module Jpmobile
27
27
  if type and charset
28
28
  env['Content-Type'] = "#{type}; charset=#{charset}"
29
29
  end
30
- elsif pc_emoticon?
30
+ elsif Jpmobile::Emoticon.pc_emoticon?
31
31
  body = response_to_body(response)
32
32
 
33
- response = body.gsub(/&#x([0-9a-f]{4});/i) do |match|
34
- img = @pc_emoticon_hash[$1.upcase] || (@pc_emoticon_hash[("%x" % ($1.scanf("%x").first - 0x1000)).upcase] rescue nil)
35
- if img
36
- "<img src=\"#{@@pc_emoticon_image_path}/#{img}.gif\" alt=\"#{img}\" />"
37
- else
38
- ""
39
- end
40
- end
33
+ response = Jpmobile::Emoticon.emoticons_to_image(body)
41
34
  end
42
35
 
43
36
  new_response = ::Rack::Response.new(response, status, env)
@@ -45,25 +38,6 @@ module Jpmobile
45
38
  end
46
39
 
47
40
  private
48
- def pc_emoticon?
49
- if @@pc_emoticon_yaml and File.exist?(@@pc_emoticon_yaml) and
50
- @@pc_emoticon_image_path and FileTest.directory?(@@pc_emoticon_image_path)
51
-
52
- unless @pc_emoticon_hash
53
- begin
54
- yaml_hash = YAML.load_file(@@pc_emoticon_yaml)
55
- @pc_emoticon_hash = Hash[*(yaml_hash.values.inject([]){ |r, v| r += v.to_a.flatten; r})]
56
- @@pc_emoticon_image_path.chop if @@pc_emoticon_image_path.match(/\/$/)
57
-
58
- return true
59
- rescue => ex
60
- end
61
- end
62
- end
63
-
64
- return false
65
- end
66
-
67
41
  def response_to_body(response)
68
42
  if response.respond_to?(:to_str)
69
43
  response.to_str
@@ -77,18 +51,6 @@ module Jpmobile
77
51
  body
78
52
  end
79
53
  end
80
-
81
- @@pc_emoticon_image_path = nil
82
- @@pc_emoticon_yaml = nil
83
- class << self
84
- def pc_emoticon_image_path=(path)
85
- @@pc_emoticon_image_path = path
86
- end
87
-
88
- def pc_emoticon_yaml=(file)
89
- @@pc_emoticon_yaml = file
90
- end
91
- end
92
54
  end
93
55
  end
94
56
  end
data/lib/jpmobile/util.rb CHANGED
@@ -102,9 +102,11 @@ module Jpmobile
102
102
  utf8_str = minus_sign_to_fullwidth_hyphen_minus(utf8_str)
103
103
 
104
104
  if utf8_str.respond_to?(:encode)
105
- utf8_str.encode(SJIS, :crlf_newline => true,:undef => :replace,:replace => '?')
105
+ utf8_str.
106
+ gsub(/(\r\n|\r|\n)/, "\r\n").
107
+ encode(SJIS, :undef => :replace, :replace => '?')
106
108
  else
107
- NKF.nkf("-m0 -x -W --oc=cp932 --fb-subchar=63", utf8_str).gsub(/\n/, "\r\n")
109
+ NKF.nkf("-m0 -x -W --oc=cp932 --fb-subchar=63", utf8_str).gsub(/(\r\n|\r|\n)/, "\r\n")
108
110
  end
109
111
  end
110
112
 
@@ -112,7 +114,7 @@ module Jpmobile
112
114
  utf8_str = if sjis_str.respond_to?(:encode)
113
115
  sjis_str.encode("UTF-8", :universal_newline => true)
114
116
  else
115
- NKF.nkf("-m0 -x -w --ic=cp932", sjis_str).gsub(/\r\n/, "\n")
117
+ NKF.nkf("-m0 -x -w --ic=cp932", sjis_str).gsub(/\r\n?/, "\n")
116
118
  end
117
119
 
118
120
  # 波ダッシュ対策
@@ -120,10 +122,15 @@ module Jpmobile
120
122
  end
121
123
 
122
124
  def utf8_to_jis(utf8_str)
125
+ # 波ダッシュ対策
126
+ utf8_str = fullwidth_tilde_to_wavedash(utf8_str)
127
+
123
128
  if utf8_str.respond_to?(:encode)
124
- utf8_str.encode(JIS, :crlf_newline => true)
129
+ utf8_str.
130
+ gsub(/(\r\n|\r|\n)/, "\r\n").
131
+ encode(JIS, :undef => :replace, :replace => '?')
125
132
  else
126
- NKF.nkf("-m0 -x -Wj", utf8_str).gsub(/\n/, "\r\n")
133
+ NKF.nkf("-m0 -x -Wj --fb-subchar=63", utf8_str).gsub(/(\r\n|\r|\n)/, "\r\n")
127
134
  end
128
135
  end
129
136
 
@@ -131,7 +138,7 @@ module Jpmobile
131
138
  if jis_str.respond_to?(:encode)
132
139
  jis_str.encode(UTF8, :universal_newline => true)
133
140
  else
134
- NKF.nkf("-m0 -x -Jw", jis_str).gsub(/\r\n/, "\n")
141
+ NKF.nkf("-m0 -x -Jw", jis_str).gsub(/\r\n?/, "\n")
135
142
  end
136
143
  end
137
144
 
@@ -184,11 +191,17 @@ module Jpmobile
184
191
  end
185
192
 
186
193
  def encode(str, charset)
187
- if Object.const_defined?(:Encoding)
188
- (charset.nil? or charset == "" or str.nil? or str == "") ? str : str.encode(charset)
194
+ if (charset.nil? or charset == "" or str.nil? or str == "")
195
+ str
196
+ elsif utf8?(str) and charset.match(/iso-2022-jp/i)
197
+ utf8_to_jis(str)
198
+ elsif utf8?(str) and charset.match(/shift_jis/i)
199
+ utf8_to_sjis(str)
200
+ elsif utf8?(str) and charset.match(/utf-8/i)
201
+ str
189
202
  else
190
- if str.nil?
191
- str
203
+ if Object.const_defined?(:Encoding)
204
+ str.encode(charset)
192
205
  else
193
206
  case charset
194
207
  when /iso-2022-jp/i
@@ -57,13 +57,17 @@ describe "絵文字が" do
57
57
 
58
58
  @res = Rack::MockRequest.env_for("/", 'Content-Type' => 'text/html; charset=utf-8')
59
59
 
60
- Jpmobile::Rack::Filter.pc_emoticon_yaml = "tmp/emoticon.yaml"
61
- Jpmobile::Rack::Filter.pc_emoticon_image_path = @path = "tmp/emoticons"
60
+ Jpmobile::Emoticon.pc_emoticon_yaml = "tmp/emoticon.yaml"
61
+ Jpmobile::Emoticon.pc_emoticon_image_path = @path = "tmp/emoticons"
62
62
  end
63
63
 
64
64
  after(:each) do
65
- Jpmobile::Rack::Filter.pc_emoticon_yaml = nil
66
- Jpmobile::Rack::Filter.pc_emoticon_image_path = nil
65
+ Jpmobile::Emoticon.pc_emoticon_yaml = nil
66
+ Jpmobile::Emoticon.pc_emoticon_image_path = nil
67
+ end
68
+
69
+ it "Jpmobile::Emoticon.pc_emoticon? がtrueになること" do
70
+ Jpmobile::Emoticon.pc_emoticon?.should be_true
67
71
  end
68
72
 
69
73
  it "docomo 絵文字が画像に変換されること" do
@@ -71,9 +75,9 @@ describe "絵文字が" do
71
75
  response_body(response).should == "<img src=\"#{@path}/sun.gif\" alt=\"sun\" />"
72
76
  end
73
77
 
74
- it "docomo 絵文字コードの埋込みは変換されないこと" do
78
+ it "docomo 絵文字コードが画像に変換されること" do
75
79
  response = Jpmobile::Rack::MobileCarrier.new(Jpmobile::Rack::Filter.new(UnitApplication.new(@docomo_utf8))).call(@res)[2]
76
- response_body(response).should == @docomo_utf8
80
+ response_body(response).should == "<img src=\"#{@path}/sun.gif\" alt=\"sun\" />"
77
81
  end
78
82
 
79
83
  it "au 絵文字が画像に変換されること" do
@@ -81,9 +85,9 @@ describe "絵文字が" do
81
85
  response_body(response).should == "<img src=\"#{@path}/sun.gif\" alt=\"sun\" />"
82
86
  end
83
87
 
84
- it "au 絵文字コードの埋込みは変換されないこと" do
88
+ it "au 絵文字コードが画像に変換されること" do
85
89
  response = Jpmobile::Rack::MobileCarrier.new(Jpmobile::Rack::Filter.new(UnitApplication.new(@au_utf8))).call(@res)[2]
86
- response_body(response).should == @au_utf8
90
+ response_body(response).should == "<img src=\"#{@path}/sun.gif\" alt=\"sun\" />"
87
91
  end
88
92
 
89
93
  it "softbank 絵文字が画像に変換されること" do
@@ -91,9 +95,9 @@ describe "絵文字が" do
91
95
  response_body(response).should == "<img src=\"#{@path}/sun.gif\" alt=\"sun\" />"
92
96
  end
93
97
 
94
- it "softbank 絵文字コードの埋込みは変換されないこと" do
98
+ it "softbank 絵文字コードが画像に変換されること" do
95
99
  response = Jpmobile::Rack::MobileCarrier.new(Jpmobile::Rack::Filter.new(UnitApplication.new(@softbank_utf8))).call(@res)[2]
96
- response_body(response).should == @softbank_utf8
100
+ response_body(response).should == "<img src=\"#{@path}/sun.gif\" alt=\"sun\" />"
97
101
  end
98
102
  end
99
103
 
@@ -70,7 +70,7 @@ describe Jpmobile::Rack::MobileCarrier, "softbank" do
70
70
  res = Rack::MockRequest.env_for(
71
71
  'http://jpmobile-rails.org/',
72
72
  'HTTP_USER_AGENT' => "Vodafone/1.0/V903T/TJ001 Browser/VF-Browser/1.0 Profile/MIDP-2.0 Configuration/CLDC-1.1 Ext-J-Profile/JSCL-1.2.2 Ext-V-Profile/VSCL-2.0.0",
73
- "REMOTE_ADDR"=>"210.175.1.130")
73
+ "REMOTE_ADDR"=>"210.146.7.199")
74
74
  env = Jpmobile::Rack::MobileCarrier.new(UnitApplication.new).call(res)[1]
75
75
 
76
76
  env['rack.jpmobile'].valid_ip?.should be_true
@@ -0,0 +1,76 @@
1
+ # -*- coding: utf-8 -*-
2
+ require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
3
+ require 'mail'
4
+ require 'jpmobile/mail'
5
+
6
+ describe "decorated mails" do
7
+ include Jpmobile::Util
8
+
9
+ before(:each) do
10
+ @mail = Mail.new
11
+ @mail.subject = "万葉"
12
+ @mail.text_part = Mail::Part.new do
13
+ body 'ほげ'
14
+ end
15
+ @mail.from = "ちはやふる <info@jpmobile-rails.org>"
16
+ @mail.to = "むすめふさほせ <info+to@jpmobile-rails.org>"
17
+
18
+ @photo = open(File.join(File.expand_path(File.dirname(__FILE__)), "email-fixtures/photo.jpg")).read
19
+ @mail.attachments.inline['photo.jpg'] = @photo
20
+ @inline_url = @mail.attachments['photo.jpg'].url
21
+ end
22
+
23
+ describe "docomo" do
24
+ before(:each) do
25
+ inline_url = @inline_url
26
+ @mobile = Jpmobile::Mobile::Docomo.new(nil, nil)
27
+ charset = @mobile.mail_charset
28
+ @mail.html_part = Mail::Part.new do
29
+ body '<img src="' + inline_url + '" />'
30
+ content_type "text/html; charset=#{charset}"
31
+ end
32
+ @mail.mobile = @mobile
33
+ end
34
+
35
+ it "top level content-type should be 'multipart/mixed'" do
36
+ @mail.rearrange!
37
+ @mail.content_type.should match('multipart/mixed')
38
+ end
39
+ end
40
+
41
+ describe "au" do
42
+ before(:each) do
43
+ inline_url = @inline_url
44
+ @mobile = Jpmobile::Mobile::Au.new(nil, nil)
45
+ charset = @mobile.mail_charset
46
+ @mail.html_part = Mail::Part.new do
47
+ body '<img src="' + inline_url + '" />'
48
+ content_type "text/html; charset=#{charset}"
49
+ end
50
+ @mail.mobile = @mobile
51
+ end
52
+
53
+ it "top level content-type should be 'multipart/mixed'" do
54
+ @mail.rearrange!
55
+ @mail.content_type.should match('multipart/mixed')
56
+ end
57
+ end
58
+
59
+ describe "softbank" do
60
+ before(:each) do
61
+ inline_url = @inline_url
62
+ @mobile = Jpmobile::Mobile::Softbank.new(nil, nil)
63
+ charset = @mobile.mail_charset
64
+ @mail.html_part = Mail::Part.new do
65
+ body '<img src="' + inline_url + '" />'
66
+ content_type "text/html; charset=#{charset}"
67
+ end
68
+ @mail.mobile = @mobile
69
+ end
70
+
71
+ it "top level content-type should be 'multipart/mixed'" do
72
+ @mail.rearrange!
73
+ @mail.content_type.should match('multipart/mixed')
74
+ end
75
+ end
76
+ end
Binary file
@@ -19,6 +19,31 @@ describe "Jpmobile::Mail" do
19
19
  end
20
20
  end
21
21
 
22
+ describe "Non-mobile" do
23
+ before(:each) do
24
+ @mail = Mail.new do
25
+ subject "万葉"
26
+ from "ちはやふる <info@jpmobile-rails.org>"
27
+ end
28
+ end
29
+ context "has multipart body" do
30
+ before(:each) do
31
+ @mail.parts << Mail::Part.new { body "ほげ" }
32
+ @mail.parts << Mail::Part.new { body "ほげほげ" }
33
+ @mail.parts.each{|p| p.charset = "ISO-2022-JP" }
34
+ end
35
+ context "to_s" do
36
+ subject {
37
+ Mail.new ascii_8bit(@mail.to_s)
38
+ }
39
+ it "should be able to decode bodies" do
40
+ subject.parts[0].body == "ほげ"
41
+ subject.parts[1].body == "ほげほげ"
42
+ end
43
+ end
44
+ end
45
+ end
46
+
22
47
  describe "AbstractMobile" do
23
48
  before(:each) do
24
49
  @mobile = Jpmobile::Mobile::AbstractMobile.new(nil, nil)
@@ -229,4 +254,50 @@ describe "Jpmobile::Mail" do
229
254
  end
230
255
  end
231
256
  end
257
+
258
+ context "with attachments" do
259
+ before(:each) do
260
+ @mobile = Jpmobile::Mobile::AbstractMobile.new(nil, nil)
261
+ @mail.mobile = @mobile
262
+ @mail.to = "むすめふさほせ <info+to@jpmobile-rails.org>"
263
+ @photo = open(File.join(File.expand_path(File.dirname(__FILE__)), "email-fixtures/photo.jpg")).read
264
+ end
265
+
266
+ it "should encodes itself successfully" do
267
+ @mail.attachments['photo.jpg'] = @photo
268
+
269
+ lambda {
270
+ @mail.to_s
271
+ }.should_not raise_error
272
+ end
273
+
274
+ it "should encodes itself successfully with an inline attachment" do
275
+ @mail.attachments.inline['photo.jpg'] = @photo
276
+
277
+ lambda {
278
+ @mail.to_s
279
+ }.should_not raise_error
280
+ end
281
+ end
282
+
283
+ context "encoding conversion" do
284
+ before(:each) do
285
+ @mobile = Jpmobile::Mobile::AbstractMobile.new(nil, nil)
286
+ @mail.mobile = @mobile
287
+ @mail.to = "むすめふさほせ <info+to@jpmobile-rails.org>"
288
+ @photo = open(File.join(File.expand_path(File.dirname(__FILE__)), "email-fixtures/photo.jpg")).read
289
+ end
290
+
291
+ it "wave dash converting correctly" do
292
+ @mail.body = '10:00〜12:00'
293
+
294
+ ascii_8bit(@mail.to_s).should match(Regexp.compile(Regexp.escape(ascii_8bit("\x31\x30\x3a\x30\x30\x1b\x24\x42\x21\x41\x1b\x28\x42\x31\x32\x3a\x30\x30"))))
295
+ end
296
+
297
+ it "full width tilde converting correctly" do
298
+ @mail.body = "10:00#{[0xff5e].pack("U")}12:00"
299
+
300
+ ascii_8bit(@mail.to_s).should match(Regexp.compile(Regexp.escape(ascii_8bit("\x31\x30\x3a\x30\x30\x1b\x24\x42\x21\x41\x1b\x28\x42\x31\x32\x3a\x30\x30"))))
301
+ end
302
+ end
232
303
  end
@@ -18,5 +18,5 @@ RSpec.configure do |c|
18
18
  c.run_all_when_everything_filtered = true
19
19
  c.color_enabled = true
20
20
  c.filter_run_excluding :broken => true
21
- # c.full_backtrace = true
21
+ c.full_backtrace = true
22
22
  end
@@ -3,7 +3,7 @@ require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
3
3
  require 'stringio'
4
4
  require 'nkf'
5
5
 
6
- describe Jpmobile::Util, ".deep_apply" do
6
+ describe Jpmobile::Util do
7
7
  include Jpmobile::Util
8
8
 
9
9
  it 'nilのときはnilを返すこと' do
@@ -34,8 +34,8 @@ describe Jpmobile::Util, ".deep_apply" do
34
34
  utf8_to_sjis("اللغة العربية").should == sjis("????? ???????")
35
35
  end
36
36
 
37
- it "utf8_to_sjis で改行コードが CRLF に変更されること" do
38
- utf8_to_sjis("UTF8\nTEXT\n").should == sjis("UTF8\r\nTEXT\r\n")
37
+ it "utf8_to_sjis ですべての改行コードが CRLF に変更されること" do
38
+ utf8_to_sjis("UTF8\rSAMPLE\nTEXT\r\n").should == sjis("UTF8\r\nSAMPLE\r\nTEXT\r\n")
39
39
  end
40
40
 
41
41
  it "0x8150がU+FFE3に変換されること" do
@@ -63,6 +63,22 @@ describe Jpmobile::Util, ".deep_apply" do
63
63
  jis_to_utf8(jis("\x1b\x24\x42#{$1}\x1b\x28\x42")).should == "しからずんばこじをえず"
64
64
  end
65
65
 
66
+ it "sjis_to_utf8 ですべての改行コードが LF に変更されること" do
67
+ sjis_to_utf8("SJIS\rSAMPLE\nTEXT\r\n").should == utf8("SJIS\nSAMPLE\nTEXT\n")
68
+ end
69
+
70
+ it "utf8_to_sjis で変換できない文字列が含んでいた場合?に変換される" do
71
+ utf8_to_jis("اللغة العربية").should == jis("????? ???????")
72
+ end
73
+
74
+ it "utf8_to_jis ですべての改行コードが CRLF に変更されること" do
75
+ utf8_to_jis("UTF8\rSAMPLE\nTEXT\r\n").should == jis("UTF8\r\nSAMPLE\r\nTEXT\r\n")
76
+ end
77
+
78
+ it "jis_to_utf8 ですべての改行コードが LF に変更されること" do
79
+ jis_to_utf8("JIS\rSAMPLE\nTEXT\r\n").should == utf8("JIS\nSAMPLE\nTEXT\n")
80
+ end
81
+
66
82
  it "fold_textでUTF-8の日本語文字列が指定文字数で折り返された配列で返ること" do
67
83
  fold_text('長い日本語の題名で折り返されるかようにするには事前に分割していないとダメなことがわかりましたよ', 15).should == [
68
84
  '長い日本語の題名で折り返される',
@@ -87,4 +103,9 @@ describe Jpmobile::Util, ".deep_apply" do
87
103
  split_text('', 15).should be_nil
88
104
  split_text(nil, 15).should be_nil
89
105
  end
106
+
107
+ it "全角チルダがjisに適切に変換されること" do
108
+ ascii_8bit(utf8_to_jis("\xef\xbd\x9e")).should == ascii_8bit("\x1b\x24\x42\x21\x41\x1b\x28\x42")
109
+ ascii_8bit(encode("\xef\xbd\x9e", "ISO-2022-JP")).should == ascii_8bit("\x1b\x24\x42\x21\x41\x1b\x28\x42")
110
+ end
90
111
  end
@@ -0,0 +1,11 @@
1
+ # -*- coding: utf-8 -*-
2
+ class DecoratedMailer < Jpmobile::Mailer::Base
3
+ default :from => "info@jp.mobile"
4
+ default :to => "info@jp.mobile"
5
+
6
+ def deco_mail(to_mail)
7
+ attachments.inline['photo.jpg'] = open(File.join(Rails.root, 'spec/fixtures/mobile_mailer/photo.jpg')).read
8
+
9
+ mail(:to => to_mail, :subject => '題名', :decorated => true)
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ <html>
2
+ <body>
3
+ <p>
4
+ HTMLメールの本文
5
+ </p>
6
+ <p>
7
+ <%= image_tag attachments['photo.jpg'].url -%>
8
+ </p>
9
+ </body>
10
+ </html>
@@ -0,0 +1 @@
1
+ テキストメールの本文
@@ -0,0 +1,44 @@
1
+ # -*- coding: utf-8 -*-
2
+ require File.expand_path(File.join(File.dirname(__FILE__), '/../spec_helper'))
3
+
4
+ describe DecoratedMailer do
5
+ include Jpmobile::Util
6
+
7
+ before(:each) do
8
+ ActionMailer::Base.deliveries = []
9
+ end
10
+
11
+ shared_examples_for "content-type" do
12
+ it "sends decorated mail successfully" do
13
+ DecoratedMailer.deco_mail(@to).deliver
14
+
15
+ email = ActionMailer::Base.deliveries.first
16
+ email.header['Content-Type'].main_type.should == 'multipart'
17
+ email.header['Content-Type'].sub_type.should == 'mixed'
18
+ end
19
+ end
20
+
21
+ describe "docomo" do
22
+ before(:each) do
23
+ @to = "docomo@docomo.ne.jp"
24
+ end
25
+
26
+ it_behaves_like "content-type"
27
+ end
28
+
29
+ describe "au" do
30
+ before(:each) do
31
+ @to = "au@ezweb.ne.jp"
32
+ end
33
+
34
+ it_behaves_like "content-type"
35
+ end
36
+
37
+ describe "softbank" do
38
+ before(:each) do
39
+ @to = "softbank@softbank.ne.jp"
40
+ end
41
+
42
+ it_behaves_like "content-type"
43
+ end
44
+ end
@@ -32,7 +32,7 @@ RSpec.configure do |config|
32
32
  config.run_all_when_everything_filtered = true
33
33
  config.color_enabled = true
34
34
  config.filter_run_excluding :broken => true
35
- config.full_backtrace = true
35
+ # config.full_backtrace = true
36
36
  end
37
37
 
38
38
  require 'pp'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jpmobile
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.2
4
+ version: 2.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,11 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2011-09-26 00:00:00.000000000Z
13
+ date: 2011-11-01 00:00:00.000000000Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: jeweler
17
- requirement: &20415560 !ruby/object:Gem::Requirement
17
+ requirement: &21299100 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: '0'
23
23
  type: :development
24
24
  prerelease: false
25
- version_requirements: *20415560
25
+ version_requirements: *21299100
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: rails
28
- requirement: &20415080 !ruby/object:Gem::Requirement
28
+ requirement: &21298540 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ! '>='
@@ -33,10 +33,10 @@ dependencies:
33
33
  version: 3.1.0
34
34
  type: :development
35
35
  prerelease: false
36
- version_requirements: *20415080
36
+ version_requirements: *21298540
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: rspec
39
- requirement: &20393360 !ruby/object:Gem::Requirement
39
+ requirement: &21298040 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ! '>='
@@ -44,10 +44,10 @@ dependencies:
44
44
  version: '0'
45
45
  type: :development
46
46
  prerelease: false
47
- version_requirements: *20393360
47
+ version_requirements: *21298040
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: rspec-rails
50
- requirement: &20392880 !ruby/object:Gem::Requirement
50
+ requirement: &21297560 !ruby/object:Gem::Requirement
51
51
  none: false
52
52
  requirements:
53
53
  - - ! '>='
@@ -55,10 +55,10 @@ dependencies:
55
55
  version: '0'
56
56
  type: :development
57
57
  prerelease: false
58
- version_requirements: *20392880
58
+ version_requirements: *21297560
59
59
  - !ruby/object:Gem::Dependency
60
60
  name: webrat
61
- requirement: &20392400 !ruby/object:Gem::Requirement
61
+ requirement: &21297060 !ruby/object:Gem::Requirement
62
62
  none: false
63
63
  requirements:
64
64
  - - ! '>='
@@ -66,10 +66,10 @@ dependencies:
66
66
  version: '0'
67
67
  type: :development
68
68
  prerelease: false
69
- version_requirements: *20392400
69
+ version_requirements: *21297060
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: geokit
72
- requirement: &20391920 !ruby/object:Gem::Requirement
72
+ requirement: &21296540 !ruby/object:Gem::Requirement
73
73
  none: false
74
74
  requirements:
75
75
  - - ! '>='
@@ -77,10 +77,10 @@ dependencies:
77
77
  version: '0'
78
78
  type: :development
79
79
  prerelease: false
80
- version_requirements: *20391920
80
+ version_requirements: *21296540
81
81
  - !ruby/object:Gem::Dependency
82
82
  name: sqlite3-ruby
83
- requirement: &20391440 !ruby/object:Gem::Requirement
83
+ requirement: &21296000 !ruby/object:Gem::Requirement
84
84
  none: false
85
85
  requirements:
86
86
  - - ! '>='
@@ -88,10 +88,10 @@ dependencies:
88
88
  version: '0'
89
89
  type: :development
90
90
  prerelease: false
91
- version_requirements: *20391440
91
+ version_requirements: *21296000
92
92
  - !ruby/object:Gem::Dependency
93
93
  name: hpricot
94
- requirement: &20390860 !ruby/object:Gem::Requirement
94
+ requirement: &21295480 !ruby/object:Gem::Requirement
95
95
  none: false
96
96
  requirements:
97
97
  - - ! '>='
@@ -99,10 +99,10 @@ dependencies:
99
99
  version: '0'
100
100
  type: :development
101
101
  prerelease: false
102
- version_requirements: *20390860
102
+ version_requirements: *21295480
103
103
  - !ruby/object:Gem::Dependency
104
104
  name: rails
105
- requirement: &20390380 !ruby/object:Gem::Requirement
105
+ requirement: &21294980 !ruby/object:Gem::Requirement
106
106
  none: false
107
107
  requirements:
108
108
  - - ! '>='
@@ -110,10 +110,10 @@ dependencies:
110
110
  version: 3.1.0
111
111
  type: :development
112
112
  prerelease: false
113
- version_requirements: *20390380
113
+ version_requirements: *21294980
114
114
  - !ruby/object:Gem::Dependency
115
115
  name: jeweler
116
- requirement: &20389820 !ruby/object:Gem::Requirement
116
+ requirement: &21294500 !ruby/object:Gem::Requirement
117
117
  none: false
118
118
  requirements:
119
119
  - - ! '>='
@@ -121,10 +121,10 @@ dependencies:
121
121
  version: 1.5.1
122
122
  type: :development
123
123
  prerelease: false
124
- version_requirements: *20389820
124
+ version_requirements: *21294500
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: rspec
127
- requirement: &20389320 !ruby/object:Gem::Requirement
127
+ requirement: &21294020 !ruby/object:Gem::Requirement
128
128
  none: false
129
129
  requirements:
130
130
  - - ! '>='
@@ -132,10 +132,10 @@ dependencies:
132
132
  version: 2.6.0
133
133
  type: :development
134
134
  prerelease: false
135
- version_requirements: *20389320
135
+ version_requirements: *21294020
136
136
  - !ruby/object:Gem::Dependency
137
137
  name: rspec-rails
138
- requirement: &20388840 !ruby/object:Gem::Requirement
138
+ requirement: &21293520 !ruby/object:Gem::Requirement
139
139
  none: false
140
140
  requirements:
141
141
  - - ! '>='
@@ -143,10 +143,10 @@ dependencies:
143
143
  version: 2.6.0
144
144
  type: :development
145
145
  prerelease: false
146
- version_requirements: *20388840
146
+ version_requirements: *21293520
147
147
  - !ruby/object:Gem::Dependency
148
148
  name: webrat
149
- requirement: &20388340 !ruby/object:Gem::Requirement
149
+ requirement: &21293040 !ruby/object:Gem::Requirement
150
150
  none: false
151
151
  requirements:
152
152
  - - ! '>='
@@ -154,10 +154,10 @@ dependencies:
154
154
  version: 0.7.2
155
155
  type: :development
156
156
  prerelease: false
157
- version_requirements: *20388340
157
+ version_requirements: *21293040
158
158
  - !ruby/object:Gem::Dependency
159
159
  name: geokit
160
- requirement: &20387800 !ruby/object:Gem::Requirement
160
+ requirement: &21292560 !ruby/object:Gem::Requirement
161
161
  none: false
162
162
  requirements:
163
163
  - - ! '>='
@@ -165,10 +165,10 @@ dependencies:
165
165
  version: 1.5.0
166
166
  type: :development
167
167
  prerelease: false
168
- version_requirements: *20387800
168
+ version_requirements: *21292560
169
169
  - !ruby/object:Gem::Dependency
170
170
  name: sqlite3-ruby
171
- requirement: &20387280 !ruby/object:Gem::Requirement
171
+ requirement: &21292080 !ruby/object:Gem::Requirement
172
172
  none: false
173
173
  requirements:
174
174
  - - ! '>='
@@ -176,10 +176,10 @@ dependencies:
176
176
  version: 1.3.2
177
177
  type: :development
178
178
  prerelease: false
179
- version_requirements: *20387280
179
+ version_requirements: *21292080
180
180
  - !ruby/object:Gem::Dependency
181
181
  name: hpricot
182
- requirement: &20386760 !ruby/object:Gem::Requirement
182
+ requirement: &21291600 !ruby/object:Gem::Requirement
183
183
  none: false
184
184
  requirements:
185
185
  - - ! '>='
@@ -187,10 +187,10 @@ dependencies:
187
187
  version: 0.8.3
188
188
  type: :development
189
189
  prerelease: false
190
- version_requirements: *20386760
190
+ version_requirements: *21291600
191
191
  - !ruby/object:Gem::Dependency
192
192
  name: git
193
- requirement: &20386260 !ruby/object:Gem::Requirement
193
+ requirement: &21266300 !ruby/object:Gem::Requirement
194
194
  none: false
195
195
  requirements:
196
196
  - - ! '>='
@@ -198,7 +198,7 @@ dependencies:
198
198
  version: 1.2.5
199
199
  type: :development
200
200
  prerelease: false
201
- version_requirements: *20386260
201
+ version_requirements: *21266300
202
202
  description: A Rails plugin for Japanese mobile-phones
203
203
  email: dara@shidara.net
204
204
  executables: []
@@ -276,6 +276,7 @@ files:
276
276
  - spec/rack/jpmobile/windows_phone.rb
277
277
  - spec/rack_helper.rb
278
278
  - spec/spec_helper.rb
279
+ - spec/unit/decorated_mail_spec.rb
279
280
  - spec/unit/email-fixtures/au-attached.eml
280
281
  - spec/unit/email-fixtures/au-decomail.eml
281
282
  - spec/unit/email-fixtures/au-emoji.eml
@@ -286,6 +287,7 @@ files:
286
287
  - spec/unit/email-fixtures/docomo-jis.eml
287
288
  - spec/unit/email-fixtures/pc-mail-multi.eml
288
289
  - spec/unit/email-fixtures/pc-mail-single.eml
290
+ - spec/unit/email-fixtures/photo.jpg
289
291
  - spec/unit/email-fixtures/softbank-blank.eml
290
292
  - spec/unit/email-fixtures/softbank-emoji-utf8.eml
291
293
  - spec/unit/email-fixtures/softbank-emoji.eml
@@ -320,9 +322,12 @@ files:
320
322
  - test/rails/overrides/app/controllers/trans_sid_metal_controller.rb
321
323
  - test/rails/overrides/app/controllers/trans_sid_mobile_controller.rb
322
324
  - test/rails/overrides/app/controllers/trans_sid_none_controller.rb
323
- - test/rails/overrides/app/models/mobile_mailer.rb
324
- - test/rails/overrides/app/models/normal_mailer.rb
325
+ - test/rails/overrides/app/mailers/decorated_mailer.rb
326
+ - test/rails/overrides/app/mailers/mobile_mailer.rb
327
+ - test/rails/overrides/app/mailers/normal_mailer.rb
325
328
  - test/rails/overrides/app/models/user.rb
329
+ - test/rails/overrides/app/views/decorated_mailer/deco_mail.html.erb
330
+ - test/rails/overrides/app/views/decorated_mailer/deco_mail.text.erb
326
331
  - test/rails/overrides/app/views/filter/index.html.erb
327
332
  - test/rails/overrides/app/views/hankaku_filter/index.html.erb
328
333
  - test/rails/overrides/app/views/hankaku_input_filter/index.html.erb
@@ -382,14 +387,16 @@ files:
382
387
  - test/rails/overrides/spec/fixtures/mobile_mailer/docomo-jis.eml
383
388
  - test/rails/overrides/spec/fixtures/mobile_mailer/no-from.eml
384
389
  - test/rails/overrides/spec/fixtures/mobile_mailer/non-jp.eml
390
+ - test/rails/overrides/spec/fixtures/mobile_mailer/photo.jpg
385
391
  - test/rails/overrides/spec/fixtures/mobile_mailer/softbank-blank.eml
386
392
  - test/rails/overrides/spec/fixtures/mobile_mailer/softbank-emoji-utf8.eml
387
393
  - test/rails/overrides/spec/fixtures/mobile_mailer/softbank-emoji.eml
388
394
  - test/rails/overrides/spec/fixtures/mobile_mailer/softbank-gmail-sjis.eml
389
395
  - test/rails/overrides/spec/fixtures/mobile_mailer/softbank-gmail-utf8.eml
390
396
  - test/rails/overrides/spec/helpers/helpers_spec.rb
391
- - test/rails/overrides/spec/models/mobile_mailer_spec.rb
392
- - test/rails/overrides/spec/models/normal_mailer_spec.rb
397
+ - test/rails/overrides/spec/mailers/decorated_mailer_spec.rb
398
+ - test/rails/overrides/spec/mailers/mobile_mailer_spec.rb
399
+ - test/rails/overrides/spec/mailers/normal_mailer_spec.rb
393
400
  - test/rails/overrides/spec/rcov.opts
394
401
  - test/rails/overrides/spec/requests/docomo_guid_spec.rb
395
402
  - test/rails/overrides/spec/requests/docomo_spec.rb