releaf-i18n_database 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +24 -0
- data/app/assets/javascripts/releaf/controllers/releaf/i18n_database/translations.js +22 -0
- data/app/assets/stylesheets/releaf/controllers/releaf/i18n_database/translations.scss +95 -0
- data/app/builders/releaf/i18n_database/translations/builders_common.rb +13 -0
- data/app/builders/releaf/i18n_database/translations/edit_builder.rb +41 -0
- data/app/builders/releaf/i18n_database/translations/index_builder.rb +44 -0
- data/app/builders/releaf/i18n_database/translations/table_builder.rb +31 -0
- data/app/controllers/releaf/i18n_database/translations_controller.rb +171 -0
- data/app/lib/releaf/i18n_database/translations_importer.rb +72 -0
- data/app/lib/releaf/i18n_database/translations_utilities.rb +66 -0
- data/app/models/releaf/i18n_database/translation.rb +17 -0
- data/app/models/releaf/i18n_database/translation_data.rb +11 -0
- data/app/views/releaf/i18n_database/translations/_form_fields.haml +40 -0
- data/app/views/releaf/i18n_database/translations/export.xlsx.axlsx +24 -0
- data/lib/releaf-i18n_database.rb +5 -0
- data/lib/releaf/i18n_database/backend.rb +169 -0
- data/lib/releaf/i18n_database/builders_autoload.rb +10 -0
- data/lib/releaf/i18n_database/engine.rb +36 -0
- data/lib/releaf/i18n_database/humanize_missing_translations.rb +15 -0
- data/releaf-i18n_database.gemspec +21 -0
- data/spec/builders/translations/builder_common_spec.rb +39 -0
- data/spec/builders/translations/edit_builder_spec.rb +93 -0
- data/spec/builders/translations/index_builder_spec.rb +96 -0
- data/spec/builders/translations/table_builder_spec.rb +68 -0
- data/spec/controllers/i18n_backend/translations_controller_spec.rb +157 -0
- data/spec/features/translations_spec.rb +162 -0
- data/spec/fixtures/all_translations_exported.xlsx +0 -0
- data/spec/fixtures/time.formats.xlsx +0 -0
- data/spec/fixtures/translations_import.xlsx +0 -0
- data/spec/fixtures/unsupported_import_file.png +0 -0
- data/spec/lib/i18n_database/backend_spec.rb +337 -0
- data/spec/lib/i18n_database/humanize_missing_translations_spec.rb +18 -0
- data/spec/lib/i18n_database/translations_importer_spec.rb +17 -0
- data/spec/lib/i18n_database/translations_utilities_spec.rb +175 -0
- data/spec/models/i18n_database/translation_data_spec.rb +13 -0
- data/spec/models/i18n_database/translation_spec.rb +49 -0
- metadata +151 -0
@@ -0,0 +1,162 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
feature "Translations" do
|
3
|
+
background do
|
4
|
+
auth_as_user
|
5
|
+
|
6
|
+
t1 = create(:translation, key: 'test.key1')
|
7
|
+
t2 = create(:translation, key: 'great.stuff')
|
8
|
+
t3 = create(:translation, key: 'geek.stuff')
|
9
|
+
create(:translation_data, lang: 'en', localization: 'testa atslēga', translation_id: t1.id)
|
10
|
+
create(:translation_data, lang: 'en', localization: 'awesome stuff', translation_id: t2.id)
|
11
|
+
create(:translation_data, lang: 'lv', localization: 'lieliska manta', translation_id: t2.id)
|
12
|
+
create(:translation_data, lang: 'en', localization: 'geek stuff', translation_id: t3.id)
|
13
|
+
create(:translation_data, lang: 'lv', localization: 'nūģu lieta', translation_id: t3.id)
|
14
|
+
end
|
15
|
+
|
16
|
+
scenario "blank only filtering", js: true do
|
17
|
+
visit releaf_i18n_database_translations_path
|
18
|
+
expect(page).to have_number_of_resources(3)
|
19
|
+
|
20
|
+
check "Only blank"
|
21
|
+
expect(page).to have_number_of_resources(1)
|
22
|
+
|
23
|
+
click_link "Edit"
|
24
|
+
expect(page).to have_css(".table tbody.list tr", count: 1)
|
25
|
+
|
26
|
+
within ".table tr.item:first-child" do
|
27
|
+
fill_in "translations[][localizations][lv]", with: "lv tulkojums"
|
28
|
+
fill_in "translations[][localizations][en]", with: "en translation"
|
29
|
+
end
|
30
|
+
click_button "Save"
|
31
|
+
expect(page).to have_notification("Update succeeded")
|
32
|
+
|
33
|
+
# TODO: fix when phantomjs will have file download implemented
|
34
|
+
#click_link "Export"
|
35
|
+
#filename = page.response_headers["Content-Disposition"].split("=")[1].gsub("\"","")
|
36
|
+
#tmp_file = Dir.tmpdir + '/' + filename
|
37
|
+
#File.open(tmp_file, "wb") { |f| f.write(page.body) }
|
38
|
+
#fixture_path = File.expand_path('../fixtures/blank_translations_exported.xlsx', __dir__)
|
39
|
+
#expect(tmp_file).to match_excel(fixture_path)
|
40
|
+
#File.delete(tmp_file)
|
41
|
+
|
42
|
+
click_link "Back to list"
|
43
|
+
expect(page).to have_number_of_resources(0)
|
44
|
+
|
45
|
+
uncheck "Only blank"
|
46
|
+
expect(page).to have_number_of_resources(3)
|
47
|
+
end
|
48
|
+
|
49
|
+
scenario "index" do
|
50
|
+
visit releaf_i18n_database_translations_path
|
51
|
+
expect( page ).to have_content 'test.key1'
|
52
|
+
expect( page ).to have_content 'great.stuff'
|
53
|
+
expect( page ).to have_content 'geek.stuff'
|
54
|
+
|
55
|
+
expect( page ).to have_content 'testa atslēga'
|
56
|
+
expect( page ).to have_content 'awesome stuff'
|
57
|
+
expect( page ).to have_content 'lieliska manta'
|
58
|
+
expect( page ).to have_content 'geek stuff'
|
59
|
+
expect( page ).to have_content 'nūģu lieta'
|
60
|
+
end
|
61
|
+
|
62
|
+
scenario "Editing", js: true do
|
63
|
+
visit releaf_i18n_database_translations_path
|
64
|
+
|
65
|
+
fill_in 'search', with: "stuff"
|
66
|
+
expect(page).to have_number_of_resources(2)
|
67
|
+
click_link "Edit"
|
68
|
+
|
69
|
+
within ".table tr.item:first-child" do
|
70
|
+
expect(find_field("translations[][key]").value).to eq("geek.stuff")
|
71
|
+
fill_in "translations[][key]", with: ""
|
72
|
+
fill_in "translations[][localizations][lv]", with: "lv tulkojums"
|
73
|
+
fill_in "translations[][localizations][en]", with: "en translation"
|
74
|
+
end
|
75
|
+
|
76
|
+
click_button "Save"
|
77
|
+
expect(page).to have_notification("Update failed", :error)
|
78
|
+
|
79
|
+
within ".table tr.item:last-child" do
|
80
|
+
click_button "Remove item"
|
81
|
+
end
|
82
|
+
expect(page).to have_css(".table tr.item", count: 1) # wait for fade out to complete
|
83
|
+
|
84
|
+
within ".table tr.item:first-child" do
|
85
|
+
fill_in "translations[][key]", with: "great.stuff"
|
86
|
+
end
|
87
|
+
|
88
|
+
click_button "Save"
|
89
|
+
expect(page).to have_notification("Update succeeded")
|
90
|
+
|
91
|
+
# rename key
|
92
|
+
within ".table tr.item:first-child" do
|
93
|
+
fill_in "translations[][key]", with: "another.great.stuff"
|
94
|
+
end
|
95
|
+
click_button "Save"
|
96
|
+
expect(page).to have_notification("Update succeeded")
|
97
|
+
|
98
|
+
click_link "Back to list"
|
99
|
+
expect(page).to have_number_of_resources(1)
|
100
|
+
expect(page).to have_content 'lv tulkojums'
|
101
|
+
expect(page).to have_content 'en translation'
|
102
|
+
end
|
103
|
+
|
104
|
+
scenario "Import excel file with translations", js: true do
|
105
|
+
visit releaf_i18n_database_translations_path
|
106
|
+
expect(page).to have_no_css(".table td span", text: "Eksports")
|
107
|
+
expect(page).to have_no_css(".table td span", text: "Export")
|
108
|
+
expect(page).to have_no_css(".table td span", text: "jauns")
|
109
|
+
|
110
|
+
script = "$('form.import').css({display: 'block'});"
|
111
|
+
page.execute_script(script)
|
112
|
+
|
113
|
+
fixture_path = File.expand_path('../fixtures/translations_import.xlsx', __dir__)
|
114
|
+
|
115
|
+
within('form.import') do
|
116
|
+
attach_file(:import_file, fixture_path)
|
117
|
+
end
|
118
|
+
|
119
|
+
expect(page).to have_css(".breadcrumbs li:last-child", text: "Import")
|
120
|
+
find(:css, 'input[name="translations[][localizations][lv]"][value="Eksports"]')
|
121
|
+
find(:css, 'input[name="translations[][localizations][en]"][value="Export"]')
|
122
|
+
|
123
|
+
click_button "Import"
|
124
|
+
expect(page).to have_notification("successfuly imported 4 translations")
|
125
|
+
|
126
|
+
visit releaf_i18n_database_translations_path
|
127
|
+
expect(page).to have_css(".table td span", text: "Eksports")
|
128
|
+
expect(page).to have_css(".table td span", text: "Export")
|
129
|
+
expect(page).to have_css(".table td span", text: "jauns")
|
130
|
+
end
|
131
|
+
|
132
|
+
scenario "Import unsupported file", js: true do
|
133
|
+
visit releaf_i18n_database_translations_path
|
134
|
+
|
135
|
+
script = "$('form.import').css({display: 'block'});"
|
136
|
+
page.execute_script(script)
|
137
|
+
|
138
|
+
fixture_path = File.expand_path('../fixtures/unsupported_import_file.png', __dir__)
|
139
|
+
|
140
|
+
within('form.import') do
|
141
|
+
attach_file(:import_file, fixture_path)
|
142
|
+
end
|
143
|
+
|
144
|
+
expect(page).to have_notification("Unsupported file format", "error")
|
145
|
+
end
|
146
|
+
|
147
|
+
scenario "Export translations" do
|
148
|
+
visit releaf_i18n_database_translations_path
|
149
|
+
click_link "Export"
|
150
|
+
|
151
|
+
expect(page.response_headers["Content-Type"]).to eq('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; charset=utf-8')
|
152
|
+
|
153
|
+
filename = page.response_headers["Content-Disposition"].split("=")[1].gsub("\"","")
|
154
|
+
tmp_file = Dir.tmpdir + '/' + filename
|
155
|
+
File.open(tmp_file, "wb") { |f| f.write(page.body) }
|
156
|
+
|
157
|
+
fixture_path = File.expand_path('../fixtures/all_translations_exported.xlsx', __dir__)
|
158
|
+
expect(tmp_file).to match_excel(fixture_path)
|
159
|
+
|
160
|
+
File.delete(tmp_file)
|
161
|
+
end
|
162
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,337 @@
|
|
1
|
+
require "rails_helper"
|
2
|
+
|
3
|
+
describe Releaf::I18nDatabase::Backend do
|
4
|
+
|
5
|
+
before do
|
6
|
+
allow( Releaf::I18nDatabase ).to receive(:create_missing_translations).and_return(true)
|
7
|
+
allow( I18n.backend ).to receive(:reload_cache?).and_return(true)
|
8
|
+
I18n.backend.reload_cache
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "#store_translations" do
|
12
|
+
it "merges given translations to cache" do
|
13
|
+
translation = FactoryGirl.create(:translation, key: "admin.content.save")
|
14
|
+
FactoryGirl.create(:translation_data, translation: translation, localization: "save", lang: "en")
|
15
|
+
FactoryGirl.create(:translation_data, translation: translation, localization: "saglabāt", lang: "lv")
|
16
|
+
I18n.backend.reload_cache
|
17
|
+
allow( I18n.backend ).to receive(:reload_cache?).and_return(false)
|
18
|
+
|
19
|
+
expect{ I18n.backend.store_translations(:en, {admin: {profile: "profils"}}) }.to change{ I18n.t("admin.profile") }.
|
20
|
+
from("Profile").to("profils")
|
21
|
+
|
22
|
+
expect(I18n.t("admin.content.save", locale: "lv")).to eq("saglabāt")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#default" do
|
27
|
+
context "when `create_default: false` option exists" do
|
28
|
+
it "adds `create_default: true` option and remove `create_default` option" do
|
29
|
+
expect(subject).to receive(:resolve).with("en", "aa", "bb", count: 1, fallback: true, create_missing: false)
|
30
|
+
subject.send(:default, "en", "aa", "bb", count:1, default: "xxx", fallback: true, create_default: false, create_missing: false)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "does not change given options" do
|
34
|
+
options = {count:1, default: "xxx", fallback: true, create_default: false}
|
35
|
+
expect{ subject.send(:default, "en", "aa", "bb", options) }.to_not change{ options }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context "when `create_default: false` option does not exists" do
|
40
|
+
it "does not modify options" do
|
41
|
+
expect(subject).to receive(:resolve).with("en", "aa", "bb", count: 1, fallback: true)
|
42
|
+
subject.send(:default, "en", "aa", "bb", count:1, default: "xxx", fallback: true)
|
43
|
+
|
44
|
+
expect(subject).to receive(:resolve).with("en", "aa", "bb", count: 1, fallback: true, create_default: true)
|
45
|
+
subject.send(:default, "en", "aa", "bb", count:1, default: "xxx", fallback: true, create_default: true)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "#create_missing_translation?" do
|
51
|
+
before do
|
52
|
+
Releaf::I18nDatabase.create_missing_translations = true
|
53
|
+
end
|
54
|
+
|
55
|
+
context "when missing translation creation is enabled globally by i18n config and not disabled by `create_missing` option" do
|
56
|
+
it "returns true" do
|
57
|
+
expect(subject.send(:create_missing_translation?, {})).to be true
|
58
|
+
expect(subject.send(:create_missing_translation?, create_missing: true)).to be true
|
59
|
+
expect(subject.send(:create_missing_translation?, create_missing: nil)).to be true
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context "when missing translation creation is disabled globally by i18n config" do
|
64
|
+
it "returns false" do
|
65
|
+
allow( Releaf::I18nDatabase ).to receive(:create_missing_translations).and_return(false)
|
66
|
+
expect(subject.send(:create_missing_translation?, {})).to be false
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context "when missing translation creation is disabled by `create_missing` option" do
|
71
|
+
it "returns false" do
|
72
|
+
expect(subject.send(:create_missing_translation?, create_missing: false)).to be false
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe ".translations_updated_at" do
|
78
|
+
it "returns translations updated_at from cached settings" do
|
79
|
+
allow(Releaf::Settings).to receive(:[]).with(described_class::UPDATED_AT_KEY).and_return("x")
|
80
|
+
expect(described_class.translations_updated_at).to eq("x")
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe ".translations_updated_at=" do
|
85
|
+
it "stores translations updated_at to cached settings" do
|
86
|
+
expect(Releaf::Settings).to receive(:[]=).with(described_class::UPDATED_AT_KEY, "xx")
|
87
|
+
described_class.translations_updated_at = "xx"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe "#reload_cache?" do
|
92
|
+
context "when last translation update differs from last cache load" do
|
93
|
+
it "returns true" do
|
94
|
+
allow(described_class).to receive(:translations_updated_at).and_return(1)
|
95
|
+
described_class::CACHE[:updated_at] = 2
|
96
|
+
expect(subject.reload_cache?).to be true
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context "when last translation update differs from last cache load" do
|
101
|
+
it "returns false" do
|
102
|
+
allow(described_class).to receive(:translations_updated_at).and_return(1)
|
103
|
+
described_class::CACHE[:updated_at] = 1
|
104
|
+
expect(subject.reload_cache?).to be false
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe "#reload_cache" do
|
110
|
+
it "resets missing array" do
|
111
|
+
I18n.t("something")
|
112
|
+
expect{ I18n.backend.reload_cache }.to change{ described_class::CACHE[:missing].blank? }.from(false).to(true)
|
113
|
+
end
|
114
|
+
|
115
|
+
it "writes last translations update timestamp to cache" do
|
116
|
+
allow(described_class).to receive(:translations_updated_at).and_return("x")
|
117
|
+
expect{ I18n.backend.reload_cache }.to change{ described_class::CACHE[:updated_at] }.to("x")
|
118
|
+
end
|
119
|
+
|
120
|
+
it "loads all translated data to cache as hash" do
|
121
|
+
translation = FactoryGirl.create(:translation, key: "admin.xx.save")
|
122
|
+
FactoryGirl.create(:translation_data, translation: translation, localization: "saglabāt", lang: "lv")
|
123
|
+
FactoryGirl.create(:translation_data, translation: translation, localization: "save", lang: "en")
|
124
|
+
|
125
|
+
expect{ I18n.backend.reload_cache }.to change{ described_class::CACHE[:translations].blank? }.from(true).to(false)
|
126
|
+
|
127
|
+
expect(described_class::CACHE[:translations][:lv][:admin][:xx][:save]).to eq("saglabāt")
|
128
|
+
expect(described_class::CACHE[:translations][:en][:admin][:xx][:save]).to eq("save")
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
describe "#lookup" do
|
133
|
+
describe "cache reload" do
|
134
|
+
let(:timestamp){ Time.now }
|
135
|
+
|
136
|
+
context "when cache timestamp differs from translations update timestamp" do
|
137
|
+
it "reloads cache" do
|
138
|
+
described_class::CACHE[:updated_at] = timestamp
|
139
|
+
allow(described_class).to receive(:translations_updated_at).and_return(timestamp + 1.day)
|
140
|
+
expect(I18n.backend).to receive(:reload_cache)
|
141
|
+
I18n.t("cancel")
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
context "when cache timestamp is same as translations update timestamp" do
|
146
|
+
it "does not reload cache" do
|
147
|
+
allow( I18n.backend ).to receive(:reload_cache?).and_call_original
|
148
|
+
described_class::CACHE[:updated_at] = timestamp
|
149
|
+
allow(described_class).to receive(:translations_updated_at).and_return(timestamp)
|
150
|
+
|
151
|
+
expect(I18n.backend).to_not receive(:reload_cache)
|
152
|
+
I18n.t("cancel")
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
context "when translation exists within higher level key (instead of being scope)" do
|
158
|
+
it "returns nil (Humanize key)" do
|
159
|
+
translation = FactoryGirl.create(:translation, key: "some.food")
|
160
|
+
FactoryGirl.create(:translation_data, translation: translation, lang: "lv", localization: "suņi")
|
161
|
+
expect(I18n.t("some.food", locale: "lv")).to eq("suņi")
|
162
|
+
expect(I18n.t("some.food.asd", locale: "lv")).to eq("Asd")
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
context "when pluralized translation requested" do
|
167
|
+
context "when valid pluralized data matched" do
|
168
|
+
it "returns pluralized translation" do
|
169
|
+
translation = FactoryGirl.create(:translation, key: "dog.other")
|
170
|
+
FactoryGirl.create(:translation_data, translation: translation, lang: "lv", localization: "suņi")
|
171
|
+
expect(I18n.t("dog", locale: "lv", count: 2)).to eq("suņi")
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
context "when invalid pluralized data matched" do
|
176
|
+
it "returns nil (Humanize key)" do
|
177
|
+
translation = FactoryGirl.create(:translation, key: "dog.food")
|
178
|
+
FactoryGirl.create(:translation_data, translation: translation, lang: "lv", localization: "suņi")
|
179
|
+
expect(I18n.t("dog", locale: "lv", count: 2)).to eq("Dog")
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
context "existing translation" do
|
185
|
+
context "when translation exists with different case" do
|
186
|
+
it "returns existing translation" do
|
187
|
+
translation = FactoryGirl.create(:translation, key: "Save")
|
188
|
+
FactoryGirl.create(:translation_data, translation: translation, lang: "lv", localization: "Saglabāt")
|
189
|
+
I18n.backend.reload_cache
|
190
|
+
|
191
|
+
expect(I18n.t("save", locale: "lv")).to eq("Saglabāt")
|
192
|
+
expect(I18n.t("Save", locale: "lv")).to eq("Saglabāt")
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
context "when translations hash exists in parent scope" do
|
197
|
+
before do
|
198
|
+
translation = FactoryGirl.create(:translation, key: "dog.other")
|
199
|
+
FactoryGirl.create(:translation_data, translation: translation, lang: "en", localization: "dogs")
|
200
|
+
end
|
201
|
+
|
202
|
+
context "when pluralized translation requested" do
|
203
|
+
it "returns pluralized translation" do
|
204
|
+
expect(I18n.t("admin.controller.dog", count: 2)).to eq("dogs")
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
context "when non pluralized translation requested" do
|
209
|
+
it "returns nil" do
|
210
|
+
expect(I18n.t("admin.controller.dog")).to eq("Dog")
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
context "when translation has default" do
|
216
|
+
context "when default creation is disabled" do
|
217
|
+
it "creates base translation" do
|
218
|
+
expect{ I18n.t("xxx.test.mest", default: :"xxx.mest", create_default: false) }.to change{ Releaf::I18nDatabase::Translation.pluck(:key) }
|
219
|
+
.to(["xxx.test.mest"])
|
220
|
+
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
context "when default creation is not disabled" do
|
225
|
+
it "creates base and default translations" do
|
226
|
+
expect{ I18n.t("xxx.test.mest", default: :"xxx.mest") }.to change{ Releaf::I18nDatabase::Translation.pluck(:key) }
|
227
|
+
.to(match_array(["xxx.mest", "xxx.test.mest"]))
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
context "in parent scope" do
|
233
|
+
context "nonexistent translation in given scope" do
|
234
|
+
it "uses parent scope" do
|
235
|
+
translation = FactoryGirl.create(:translation, key: "validation.admin.blank")
|
236
|
+
FactoryGirl.create(:translation_data, translation: translation, lang: "lv", localization: "Tukšs")
|
237
|
+
expect(I18n.t("blank", scope: "validation.admin.roles", locale: "lv")).to eq("Tukšs")
|
238
|
+
end
|
239
|
+
|
240
|
+
context "when `inherit_scopes` option is `false`" do
|
241
|
+
it "does not lookup upon higher level scopes" do
|
242
|
+
translation = FactoryGirl.create(:translation, key: "validation.admin.blank")
|
243
|
+
FactoryGirl.create(:translation_data, translation: translation, lang: "lv", localization: "Tukšs")
|
244
|
+
expect(I18n.t("blank", scope: "validation.admin.roles", locale: "lv", inherit_scopes: false)).to eq("Blank")
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
context "and empty translation value in given scope" do
|
250
|
+
it "uses parent scope" do
|
251
|
+
parent_translation = FactoryGirl.create(:translation, key: "validation.admin.blank")
|
252
|
+
FactoryGirl.create(:translation_data, translation: parent_translation, lang: "lv", localization: "Tukšs")
|
253
|
+
|
254
|
+
translation = FactoryGirl.create(:translation, key: "validation.admin.roles.blank")
|
255
|
+
FactoryGirl.create(:translation_data, translation: translation, lang: "lv", localization: "")
|
256
|
+
|
257
|
+
expect(I18n.t("blank", scope: "validation.admin.roles", locale: "lv")).to eq("Tukšs")
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
context "and existing translation value in given scope" do
|
262
|
+
it "uses given scope" do
|
263
|
+
parent_translation = FactoryGirl.create(:translation, key: "validation.admin.blank")
|
264
|
+
FactoryGirl.create(:translation_data, translation: parent_translation, lang: "lv", localization: "Tukšs")
|
265
|
+
|
266
|
+
translation = FactoryGirl.create(:translation, key: "validation.admin.roles.blank")
|
267
|
+
FactoryGirl.create(:translation_data, translation: translation, lang: "lv", localization: "Tukša vērtība")
|
268
|
+
|
269
|
+
expect(I18n.t("blank", scope: "validation.admin.roles", locale: "lv")).to eq("Tukša vērtība")
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
context "when scope defined" do
|
275
|
+
it "uses given scope" do
|
276
|
+
translation = FactoryGirl.create(:translation, key: "admin.content.cancel")
|
277
|
+
FactoryGirl.create(:translation_data, translation: translation, lang: "lv", localization: "Atlikt")
|
278
|
+
expect(I18n.t("cancel", scope: "admin.content", locale: "lv")).to eq("Atlikt")
|
279
|
+
end
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
context "nonexistent translation" do
|
284
|
+
context "loading multiple times" do
|
285
|
+
it "queries db only for the first time" do
|
286
|
+
I18n.t("save", scope: "admin.xx")
|
287
|
+
expect(Releaf::I18nDatabase::Translation).not_to receive(:where)
|
288
|
+
I18n.t("save", scope: "admin.xx")
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
context "with nonexistent translation" do
|
293
|
+
before do
|
294
|
+
allow(Releaf.application.config).to receive(:all_locales).and_return(["ru", "lv"])
|
295
|
+
end
|
296
|
+
|
297
|
+
it "creates empty translation" do
|
298
|
+
expect { I18n.t("save") }.to change { Releaf::I18nDatabase::Translation.where(key: "save").count }.by(1)
|
299
|
+
end
|
300
|
+
|
301
|
+
context "when count option passed" do
|
302
|
+
context "when create_plurals option not passed" do
|
303
|
+
it "creates empty translation" do
|
304
|
+
expect { I18n.t("animals.horse", count: 1) }.to change { Releaf::I18nDatabase::Translation.where(key: "animals.horse").count }.by(1)
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
context "when negative create_plurals option passed" do
|
309
|
+
it "creates empty translation" do
|
310
|
+
expect { I18n.t("animals.horse", create_plurals: false, count: 1) }.to change { Releaf::I18nDatabase::Translation.where(key: "animals.horse").count }.by(1)
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
context "when positive create_plurals option passed" do
|
315
|
+
it "creates pluralized translations for all Releaf locales" do
|
316
|
+
result = ["animals.horse.few", "animals.horse.many", "animals.horse.one", "animals.horse.other", "animals.horse.zero"]
|
317
|
+
expect{ I18n.t("animals.horse", count: 1, create_plurals: true) }.to change{ Releaf::I18nDatabase::Translation.pluck(:key).sort }.
|
318
|
+
from([]).to(result.sort)
|
319
|
+
end
|
320
|
+
end
|
321
|
+
end
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
context "when scope requested" do
|
326
|
+
it "returns all scope translations" do
|
327
|
+
translation1 = FactoryGirl.create(:translation, key: "admin.content.cancel")
|
328
|
+
FactoryGirl.create(:translation_data, translation: translation1, lang: "lv", localization: "Atlikt")
|
329
|
+
translation2 = FactoryGirl.create(:translation, key: "admin.content.save")
|
330
|
+
FactoryGirl.create(:translation_data, translation: translation2, lang: "lv", localization: "Saglabāt")
|
331
|
+
|
332
|
+
expect(I18n.t("admin.content", locale: "lv")).to eq({cancel: "Atlikt", save: "Saglabāt"})
|
333
|
+
expect(I18n.t("admin.content", locale: "en")).to eq({cancel: nil, save: nil})
|
334
|
+
end
|
335
|
+
end
|
336
|
+
end
|
337
|
+
end
|