]> git.openstreetmap.org Git - rails.git/blob - test/models/trace_test.rb
Use unique test directories for each trace test
[rails.git] / test / models / trace_test.rb
1 require "test_helper"
2 require "gpx"
3 require "minitest/mock"
4
5 class TraceTest < ActiveSupport::TestCase
6   # Use temporary directories with unique names for each test
7   # This allows the tests to be run in parallel.
8   def setup
9     @gpx_trace_dir_orig = Settings.gpx_trace_dir
10     @gpx_image_dir_orig = Settings.gpx_image_dir
11     Settings.gpx_trace_dir = Dir.mktmpdir("trace", Rails.root.join("test/gpx"))
12     Settings.gpx_image_dir = Dir.mktmpdir("image", Rails.root.join("test/gpx"))
13   end
14
15   def teardown
16     FileUtils.remove_dir(Settings.gpx_trace_dir)
17     FileUtils.remove_dir(Settings.gpx_image_dir)
18     Settings.gpx_trace_dir = @gpx_trace_dir_orig
19     Settings.gpx_image_dir = @gpx_image_dir_orig
20   end
21
22   def test_visible
23     public_trace_file = create(:trace)
24     create(:trace, :deleted)
25     check_query(Trace.visible, [public_trace_file])
26   end
27
28   def test_visible_to
29     first_user = create(:user)
30     second_user = create(:user)
31     third_user = create(:user)
32     fourth_user = create(:user)
33     public_trace_file = create(:trace, :visibility => "public", :user => first_user)
34     anon_trace_file = create(:trace, :visibility => "private", :user => second_user)
35     identifiable_trace_file = create(:trace, :visibility => "identifiable", :user => first_user)
36     pending_trace_file = create(:trace, :visibility => "public", :user => second_user, :inserted => false)
37     trackable_trace_file = create(:trace, :visibility => "trackable", :user => second_user)
38     _other_trace_file = create(:trace, :visibility => "private", :user => third_user)
39
40     check_query(Trace.visible_to(first_user), [
41                   public_trace_file, identifiable_trace_file, pending_trace_file
42                 ])
43     check_query(Trace.visible_to(second_user), [
44                   public_trace_file, anon_trace_file, trackable_trace_file,
45                   identifiable_trace_file, pending_trace_file
46                 ])
47     check_query(Trace.visible_to(fourth_user), [
48                   public_trace_file, identifiable_trace_file, pending_trace_file
49                 ])
50   end
51
52   def test_visible_to_all
53     public_trace_file = create(:trace, :visibility => "public")
54     _private_trace_file = create(:trace, :visibility => "private")
55     identifiable_trace_file = create(:trace, :visibility => "identifiable")
56     _trackable_trace_file = create(:trace, :visibility => "trackable")
57     deleted_trace_file = create(:trace, :deleted, :visibility => "public")
58     pending_trace_file = create(:trace, :visibility => "public", :inserted => false)
59
60     check_query(Trace.visible_to_all, [
61                   public_trace_file, identifiable_trace_file,
62                   deleted_trace_file, pending_trace_file
63                 ])
64   end
65
66   def test_tagged
67     london_trace_file = create(:trace) do |trace|
68       create(:tracetag, :trace => trace, :tag => "London")
69     end
70     birmingham_trace_file = create(:trace) do |trace|
71       create(:tracetag, :trace => trace, :tag => "Birmingham")
72     end
73     check_query(Trace.tagged("London"), [london_trace_file])
74     check_query(Trace.tagged("Birmingham"), [birmingham_trace_file])
75     check_query(Trace.tagged("Unknown"), [])
76   end
77
78   def test_validations
79     trace_valid({})
80     trace_valid({ :user_id => nil }, false)
81     trace_valid(:name => "a" * 255)
82     trace_valid({ :name => "a" * 256 }, false)
83     trace_valid({ :description => nil }, false)
84     trace_valid(:description => "a" * 255)
85     trace_valid({ :description => "a" * 256 }, false)
86     trace_valid(:visibility => "private")
87     trace_valid(:visibility => "public")
88     trace_valid(:visibility => "trackable")
89     trace_valid(:visibility => "identifiable")
90     trace_valid({ :visibility => "foo" }, false)
91   end
92
93   def test_tagstring
94     trace = build(:trace)
95     trace.tagstring = "foo bar baz"
96     assert trace.valid?
97     assert_equal 3, trace.tags.length
98     assert_equal "foo", trace.tags[0].tag
99     assert_equal "bar", trace.tags[1].tag
100     assert_equal "baz", trace.tags[2].tag
101     assert_equal "foo, bar, baz", trace.tagstring
102     trace.tagstring = "foo, bar baz ,qux"
103     assert trace.valid?
104     assert_equal 3, trace.tags.length
105     assert_equal "foo", trace.tags[0].tag
106     assert_equal "bar baz", trace.tags[1].tag
107     assert_equal "qux", trace.tags[2].tag
108     assert_equal "foo, bar baz, qux", trace.tagstring
109   end
110
111   def test_public?
112     assert_equal true, build(:trace, :visibility => "public").public?
113     assert_equal false, build(:trace, :visibility => "private").public?
114     assert_equal false, build(:trace, :visibility => "trackable").public?
115     assert_equal true, build(:trace, :visibility => "identifiable").public?
116     assert_equal true, build(:trace, :deleted, :visibility => "public").public?
117   end
118
119   def test_trackable?
120     assert_equal false, build(:trace, :visibility => "public").trackable?
121     assert_equal false, build(:trace, :visibility => "private").trackable?
122     assert_equal true, build(:trace, :visibility => "trackable").trackable?
123     assert_equal true, build(:trace, :visibility => "identifiable").trackable?
124     assert_equal false, build(:trace, :deleted, :visibility => "public").trackable?
125   end
126
127   def test_identifiable?
128     assert_equal false, build(:trace, :visibility => "public").identifiable?
129     assert_equal false, build(:trace, :visibility => "private").identifiable?
130     assert_equal false, build(:trace, :visibility => "trackable").identifiable?
131     assert_equal true, build(:trace, :visibility => "identifiable").identifiable?
132     assert_equal false, build(:trace, :deleted, :visibility => "public").identifiable?
133   end
134
135   def test_mime_type
136     # The ids refer to the .gpx fixtures in test/traces
137     check_mime_type("a", "application/gpx+xml")
138     check_mime_type("b", "application/gpx+xml")
139     check_mime_type("c", "application/x-bzip2")
140     check_mime_type("d", "application/x-gzip")
141     check_mime_type("f", "application/x-zip")
142     check_mime_type("g", "application/x-tar")
143     check_mime_type("h", "application/x-gzip")
144     check_mime_type("i", "application/x-bzip2")
145   end
146
147   def test_extension_name
148     # The ids refer to the .gpx fixtures in test/traces
149     check_extension_name("a", ".gpx")
150     check_extension_name("b", ".gpx")
151     check_extension_name("c", ".gpx.bz2")
152     check_extension_name("d", ".gpx.gz")
153     check_extension_name("f", ".zip")
154     check_extension_name("g", ".tar")
155     check_extension_name("h", ".tar.gz")
156     check_extension_name("i", ".tar.bz2")
157   end
158
159   def test_xml_file
160     check_xml_file("a", "848caa72f2f456d1bd6a0fdf228aa1b9")
161     check_xml_file("b", "db4cb5ed2d7d2b627b3b504296c4f701")
162     check_xml_file("c", "848caa72f2f456d1bd6a0fdf228aa1b9")
163     check_xml_file("d", "abd6675fdf3024a84fc0a1deac147c0d")
164     check_xml_file("f", "a7c05d676c77dc14369c21be216a3713")
165     check_xml_file("g", "a7c05d676c77dc14369c21be216a3713")
166     check_xml_file("h", "a7c05d676c77dc14369c21be216a3713")
167     check_xml_file("i", "a7c05d676c77dc14369c21be216a3713")
168   end
169
170   def test_large_picture
171     picture = File.read(Rails.root.join("test/gpx/fixtures/a.gif"), :mode => "rb")
172
173     trace = Trace.create
174     trace.large_picture = picture
175     assert_equal "7c841749e084ee4a5d13f12cd3bef456", md5sum(File.new(trace.large_picture_name))
176     assert_equal picture, trace.large_picture
177
178     trace.destroy
179   end
180
181   def test_icon_picture
182     picture = File.read(Rails.root.join("test/gpx/fixtures/a_icon.gif"), :mode => "rb")
183
184     trace = Trace.create
185     trace.icon_picture = picture
186     assert_equal "b47baf22ed0e85d77e808694fad0ee27", md5sum(File.new(trace.icon_picture_name))
187     assert_equal picture, trace.icon_picture
188
189     trace.destroy
190   end
191
192   # When testing the trace.import method, care needs to be taken regarding the icon
193   # fixture files, since the fixtures could be overwritten by newly generated files.
194   # We use FakeFS to temporarily protect the real fixture files from being overwritten.
195
196   def test_import_removes_previous_tracepoints
197     FakeFS do
198       FakeFS::FileSystem.clone(Rails.root.join("test/gpx"))
199       trace = create(:trace, :fixture => "a")
200       # Tracepoints don't have a primary key, so we use a specific latitude to
201       # check for successful deletion
202       create(:tracepoint, :latitude => 54321, :trace => trace)
203       assert_equal 1, Tracepoint.where(:latitude => 54321).count
204
205       trace.import
206
207       assert_equal 0, Tracepoint.where(:latitude => 54321).count
208     end
209   end
210
211   def test_import_creates_tracepoints
212     FakeFS do
213       FakeFS::FileSystem.clone(Rails.root.join("test/gpx"))
214       trace = create(:trace, :fixture => "a")
215       assert_equal 0, Tracepoint.where(:gpx_id => trace.id).count
216
217       trace.import
218
219       trace.reload
220       assert_equal 1, Tracepoint.where(:gpx_id => trace.id).count
221
222       # Check that the tile has been set prior to the bulk import
223       # i.e. that the callbacks have been run correctly
224       assert_equal 3221331576, Tracepoint.where(:gpx_id => trace.id).first.tile
225     end
226   end
227
228   def test_import_creates_icon
229     FakeFS do
230       FakeFS::FileSystem.clone(Rails.root.join("test/gpx"))
231       trace = create(:trace, :fixture => "a")
232       icon_path = File.join(Settings.gpx_image_dir, "#{trace.id}_icon.gif")
233       FileUtils.rm(icon_path)
234       assert_equal false, File.exist?(icon_path)
235
236       trace.import
237
238       assert_equal true, File.exist?(icon_path)
239     end
240   end
241
242   def test_import_creates_large_picture
243     FakeFS do
244       FakeFS::FileSystem.clone(Rails.root.join("test/gpx"))
245       trace = create(:trace, :fixture => "a")
246       large_picture_path = File.join(Settings.gpx_image_dir, "#{trace.id}.gif")
247       FileUtils.rm(large_picture_path)
248       assert_equal false, File.exist?(large_picture_path)
249
250       trace.import
251
252       assert_equal true, File.exist?(large_picture_path)
253     end
254   end
255
256   def test_import_handles_bz2
257     FakeFS do
258       FakeFS::FileSystem.clone(Rails.root.join("test/gpx"))
259       trace = create(:trace, :fixture => "c")
260
261       trace.import
262
263       assert_equal 1, trace.size
264     end
265   end
266
267   def test_import_handles_plain
268     FakeFS do
269       FakeFS::FileSystem.clone(Rails.root.join("test/gpx"))
270       trace = create(:trace, :fixture => "a")
271
272       trace.import
273
274       assert_equal 1, trace.size
275     end
276   end
277
278   def test_import_handles_plain_with_bom
279     FakeFS do
280       FakeFS::FileSystem.clone(Rails.root.join("test/gpx"))
281       trace = create(:trace, :fixture => "b")
282
283       trace.import
284
285       assert_equal 1, trace.size
286     end
287   end
288
289   def test_import_handles_gz
290     trace = create(:trace, :fixture => "d")
291
292     FakeFS do
293       FakeFS::FileSystem.clone(Rails.root.join("test/gpx"))
294       trace.import
295
296       assert_equal 1, trace.size
297     ensure
298       trace.destroy
299     end
300   end
301
302   def test_import_handles_zip
303     trace = create(:trace, :fixture => "f")
304
305     FakeFS do
306       FakeFS::FileSystem.clone(Rails.root.join("test/gpx"))
307       trace.import
308
309       assert_equal 2, trace.size
310     ensure
311       trace.destroy
312     end
313   end
314
315   def test_import_handles_tar
316     trace = create(:trace, :fixture => "g")
317
318     FakeFS do
319       FakeFS::FileSystem.clone(Rails.root.join("test/gpx"))
320       trace.import
321
322       assert_equal 2, trace.size
323     ensure
324       trace.destroy
325     end
326   end
327
328   def test_import_handles_tar_gz
329     trace = create(:trace, :fixture => "h")
330
331     FakeFS do
332       FakeFS::FileSystem.clone(Rails.root.join("test/gpx"))
333       trace.import
334
335       assert_equal 2, trace.size
336     ensure
337       trace.destroy
338     end
339   end
340
341   def test_import_handles_tar_bz2
342     trace = create(:trace, :fixture => "i")
343
344     FakeFS do
345       FakeFS::FileSystem.clone(Rails.root.join("test/gpx"))
346       trace.import
347
348       assert_equal 2, trace.size
349     ensure
350       trace.destroy
351     end
352   end
353
354   private
355
356   def check_query(query, traces)
357     traces = traces.map(&:id).sort
358     assert_equal traces, query.order(:id).ids
359   end
360
361   def check_mime_type(id, mime_type)
362     assert_equal mime_type, create(:trace, :fixture => id).mime_type
363   end
364
365   def check_extension_name(id, extension_name)
366     assert_equal extension_name, create(:trace, :fixture => id).extension_name
367   end
368
369   def check_xml_file(id, md5sum)
370     assert_equal md5sum, md5sum(create(:trace, :fixture => id).xml_file)
371   end
372
373   def trace_valid(attrs, result = true)
374     entry = build(:trace, attrs)
375     assert_equal result, entry.valid?, "Expected #{attrs.inspect} to be #{result}"
376   end
377
378   def md5sum(io)
379     io.each_with_object(Digest::MD5.new) { |l, d| d.update(l) }.hexdigest
380   end
381 end