copy_tuner_client 1.4.0 → 1.5.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.
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 238593f77e71df10a71b7710228cf56cf930a320a141a74e573e9ff015b1f730
|
|
4
|
+
data.tar.gz: acd4453041d32c2e43b81207953fca9b68c1bbec5f4cc3dafafc4722fcaada54
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bea767cacf8232f89e3fdd6f1b6b0caee1957b7306cbf018cadfcccee49a7ce22d74640f4319771cb4dda000b61142d45190791cb46aa0b2ee4f4e1f216d7576
|
|
7
|
+
data.tar.gz: 8f4c0d08195e35de0918ca7b1380146770242867f681166a39d8fc206cf16965f316e532bef59baa0525fe26f069b99b876f8ba38de49f6b88d25e2d2a820edc
|
|
@@ -17,6 +17,12 @@ module CopyTunerClient
|
|
|
17
17
|
I18n.t(key.to_s.first == '.' ? scope_key_by_partial(key) : key, **options)
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
+
# NOTE: マーカーは HTML コメントとしてブラウザに無視されつつ Copyray オーバーレイのキー特定に
|
|
21
|
+
# 使われる。HTML 以外の経路(メール本文・render :json・CSV/PDF など)ではコメントが文字列として
|
|
22
|
+
# 出力に混入してしまうため、それらの経路には注入しない。default 引数による初期値登録は維持する
|
|
23
|
+
# 必要があるため、このガードは初期値登録(上の I18n.t 呼び出し)より後に置く。
|
|
24
|
+
return source unless copyray_injectable?
|
|
25
|
+
|
|
20
26
|
if CopyTunerClient.configuration.disable_copyray_comment_injection
|
|
21
27
|
source
|
|
22
28
|
else
|
|
@@ -32,6 +38,24 @@ module CopyTunerClient
|
|
|
32
38
|
CopyTunerClient::Copyray.augment_template(source, scope_key)
|
|
33
39
|
end
|
|
34
40
|
end
|
|
41
|
+
|
|
42
|
+
# NOTE: HTML 以外の経路(メール本文・render :json・CSV/PDF など)ではマーカーが文字列として
|
|
43
|
+
# 出力に混入するため注入しない。判定には controller.request.format を使い、@current_template.format /
|
|
44
|
+
# lookup_context.formats のような ActionView の内部実装には依存させない(Rails バージョン間で壊れうるため)。
|
|
45
|
+
def copyray_injectable?
|
|
46
|
+
current_controller = controller
|
|
47
|
+
return false if current_controller.nil?
|
|
48
|
+
|
|
49
|
+
# NOTE: mailer は request を持たず request.format で判定できない。かつメール本文への
|
|
50
|
+
# マーカー混入は実害が大きいため、controller の型で明示除外する。
|
|
51
|
+
return false if defined?(ActionMailer::Base) && current_controller.is_a?(ActionMailer::Base)
|
|
52
|
+
|
|
53
|
+
# NOTE: request が無い/format が html でない経路には注入しない。&. と || false で
|
|
54
|
+
# request 不在時も安全に false を返す。
|
|
55
|
+
current_controller.request&.format&.html? || false
|
|
56
|
+
end
|
|
57
|
+
private :copyray_injectable?
|
|
58
|
+
|
|
35
59
|
if middleware_enabled
|
|
36
60
|
alias_method :translate_without_copyray_comment, :translate
|
|
37
61
|
alias_method :translate, :translate_with_copyray_comment
|
|
@@ -3,13 +3,39 @@ require 'copy_tuner_client/helper_extension'
|
|
|
3
3
|
require 'copy_tuner_client/copyray'
|
|
4
4
|
|
|
5
5
|
describe CopyTunerClient::HelperExtension do
|
|
6
|
+
# NOTE: helper_extension が参照する CopyTunerClient::Rails は engine への依存があり
|
|
7
|
+
# 単体 spec では require できないため、メソッドをスタブできる最小の入れ物だけ用意する。
|
|
8
|
+
module CopyTunerClient
|
|
9
|
+
module Rails
|
|
10
|
+
def self.controller_of_rails_engine?(_controller)
|
|
11
|
+
false
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# NOTE: request.format で描画フォーマットを判定するため、format を差し替えられる
|
|
17
|
+
# 最小のフェイク request / controller を用意する。mailer 判定は controller の型で行う。
|
|
18
|
+
Format = Struct.new(:type) do
|
|
19
|
+
def html?
|
|
20
|
+
type == :html
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
Request = Struct.new(:format)
|
|
24
|
+
Controller = Struct.new(:request)
|
|
25
|
+
|
|
6
26
|
module KeywordArgumentsHelper
|
|
27
|
+
attr_writer :controller
|
|
28
|
+
|
|
7
29
|
def translate(key, **options)
|
|
8
30
|
"Hello, #{options[:name]}"
|
|
9
31
|
end
|
|
10
32
|
|
|
11
33
|
def controller
|
|
12
|
-
|
|
34
|
+
return @controller if defined?(@controller)
|
|
35
|
+
|
|
36
|
+
# NOTE: 実 HTML 描画では controller が存在し request.format が html になるため、
|
|
37
|
+
# デフォルトはそれを再現した controller。
|
|
38
|
+
@controller = Controller.new(Request.new(Format.new(:html)))
|
|
13
39
|
end
|
|
14
40
|
end
|
|
15
41
|
|
|
@@ -19,14 +45,67 @@ describe CopyTunerClient::HelperExtension do
|
|
|
19
45
|
|
|
20
46
|
CopyTunerClient::HelperExtension.hook_translation_helper(KeywordArgumentsHelper, middleware_enabled: true)
|
|
21
47
|
|
|
48
|
+
let(:view) { KeywordArgumentsView.new }
|
|
49
|
+
|
|
50
|
+
before do
|
|
51
|
+
# NOTE: controller_of_rails_engine? は ::Rails::Engine への依存があり単体 spec では評価できないため、
|
|
52
|
+
# この spec の関心(注入ガード)に絞って常に false を返すようスタブする。
|
|
53
|
+
allow(CopyTunerClient::Rails).to receive(:controller_of_rails_engine?).and_return(false)
|
|
54
|
+
end
|
|
55
|
+
|
|
22
56
|
it 'works with keyword argument method' do
|
|
23
|
-
view = KeywordArgumentsView.new
|
|
24
57
|
expect(view.translate('some.key', name: 'World')).to eq '<!--COPYRAY some.key-->Hello, World'
|
|
25
58
|
end
|
|
26
59
|
|
|
27
60
|
it 'does not inject the overlay marker for a local_first key' do
|
|
28
61
|
CopyTunerClient.configuration.local_first_key_regexp = /\Aviews\./
|
|
29
|
-
view = KeywordArgumentsView.new
|
|
30
62
|
expect(view.translate('views.foo', name: 'World')).to eq 'Hello, World'
|
|
31
63
|
end
|
|
64
|
+
|
|
65
|
+
context 'injection guard by request format' do
|
|
66
|
+
it 'injects the marker when request.format is html' do
|
|
67
|
+
expect(view.translate('some.key', name: 'World')).to eq '<!--COPYRAY some.key-->Hello, World'
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
%i[json text csv pdf].each do |format|
|
|
71
|
+
it "does not inject the marker when request.format is :#{format}" do
|
|
72
|
+
view.controller = Controller.new(Request.new(Format.new(format)))
|
|
73
|
+
expect(view.translate('some.key', name: 'World')).to eq 'Hello, World'
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
context 'injection guard by controller' do
|
|
79
|
+
it 'does not inject the marker when rendered by a mailer' do
|
|
80
|
+
stub_const('ActionMailer::Base', Class.new)
|
|
81
|
+
view.controller = ActionMailer::Base.new
|
|
82
|
+
expect(view.translate('some.key', name: 'World')).to eq 'Hello, World'
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it 'does not inject the marker when controller is nil' do
|
|
86
|
+
view.controller = nil
|
|
87
|
+
expect(view.translate('some.key', name: 'World')).to eq 'Hello, World'
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
it 'does not inject the marker when the controller has no request' do
|
|
91
|
+
view.controller = Controller.new(nil)
|
|
92
|
+
expect(view.translate('some.key', name: 'World')).to eq 'Hello, World'
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
it 'does not raise when ActionMailer is not loaded' do
|
|
96
|
+
hide_const('ActionMailer::Base') if defined?(ActionMailer::Base)
|
|
97
|
+
view.controller = Controller.new(Request.new(Format.new(:html)))
|
|
98
|
+
expect { view.translate('some.key', name: 'World') }.not_to raise_error
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# NOTE: マーカー注入を抑止する非 HTML 経路でも、default 引数による初期値登録(I18n.t 呼び出し)は
|
|
103
|
+
# 維持されなければならない。注入ガードが初期値登録まで巻き添えで止めていないことを保証する。
|
|
104
|
+
context 'default value registration' do
|
|
105
|
+
it 'registers the default value even when the marker is not injected' do
|
|
106
|
+
view.controller = Controller.new(Request.new(Format.new(:json)))
|
|
107
|
+
expect(I18n).to receive(:t).with('some.key', hash_including(default: 'Default'))
|
|
108
|
+
view.translate('some.key', name: 'World', default: 'Default')
|
|
109
|
+
end
|
|
110
|
+
end
|
|
32
111
|
end
|