releaf-i18n_database 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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