releaf-i18n_database 0.2.1

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.
Files changed (38) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +24 -0
  3. data/app/assets/javascripts/releaf/controllers/releaf/i18n_database/translations.js +22 -0
  4. data/app/assets/stylesheets/releaf/controllers/releaf/i18n_database/translations.scss +95 -0
  5. data/app/builders/releaf/i18n_database/translations/builders_common.rb +13 -0
  6. data/app/builders/releaf/i18n_database/translations/edit_builder.rb +41 -0
  7. data/app/builders/releaf/i18n_database/translations/index_builder.rb +44 -0
  8. data/app/builders/releaf/i18n_database/translations/table_builder.rb +31 -0
  9. data/app/controllers/releaf/i18n_database/translations_controller.rb +171 -0
  10. data/app/lib/releaf/i18n_database/translations_importer.rb +72 -0
  11. data/app/lib/releaf/i18n_database/translations_utilities.rb +66 -0
  12. data/app/models/releaf/i18n_database/translation.rb +17 -0
  13. data/app/models/releaf/i18n_database/translation_data.rb +11 -0
  14. data/app/views/releaf/i18n_database/translations/_form_fields.haml +40 -0
  15. data/app/views/releaf/i18n_database/translations/export.xlsx.axlsx +24 -0
  16. data/lib/releaf-i18n_database.rb +5 -0
  17. data/lib/releaf/i18n_database/backend.rb +169 -0
  18. data/lib/releaf/i18n_database/builders_autoload.rb +10 -0
  19. data/lib/releaf/i18n_database/engine.rb +36 -0
  20. data/lib/releaf/i18n_database/humanize_missing_translations.rb +15 -0
  21. data/releaf-i18n_database.gemspec +21 -0
  22. data/spec/builders/translations/builder_common_spec.rb +39 -0
  23. data/spec/builders/translations/edit_builder_spec.rb +93 -0
  24. data/spec/builders/translations/index_builder_spec.rb +96 -0
  25. data/spec/builders/translations/table_builder_spec.rb +68 -0
  26. data/spec/controllers/i18n_backend/translations_controller_spec.rb +157 -0
  27. data/spec/features/translations_spec.rb +162 -0
  28. data/spec/fixtures/all_translations_exported.xlsx +0 -0
  29. data/spec/fixtures/time.formats.xlsx +0 -0
  30. data/spec/fixtures/translations_import.xlsx +0 -0
  31. data/spec/fixtures/unsupported_import_file.png +0 -0
  32. data/spec/lib/i18n_database/backend_spec.rb +337 -0
  33. data/spec/lib/i18n_database/humanize_missing_translations_spec.rb +18 -0
  34. data/spec/lib/i18n_database/translations_importer_spec.rb +17 -0
  35. data/spec/lib/i18n_database/translations_utilities_spec.rb +175 -0
  36. data/spec/models/i18n_database/translation_data_spec.rb +13 -0
  37. data/spec/models/i18n_database/translation_spec.rb +49 -0
  38. 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
@@ -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