Web hook messages should only be pushed once, not once for each hook
[gitorious:mainline.git] / test / unit / lib / push_event_logger_test.rb
1 # encoding: utf-8
2 #--
3 #   Copyright (C) 2011 Gitorious AS
4 #
5 #   This program is free software: you can redistribute it and/or modify
6 #   it under the terms of the GNU Affero General Public License as published by
7 #   the Free Software Foundation, either version 3 of the License, or
8 #   (at your option) any later version.
9 #
10 #   This program is distributed in the hope that it will be useful,
11 #   but WITHOUT ANY WARRANTY; without even the implied warranty of
12 #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 #   GNU Affero General Public License for more details.
14 #
15 #   You should have received a copy of the GNU Affero General Public License
16 #   along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 #++
18 require "test_helper"
19
20 class PushEventLoggerTest < ActiveSupport::TestCase
21   
22   context "deciding what events to create" do
23     context "for tags" do
24       should "create meta event when creating" do
25         spec = PushSpecParser.new(NULL_SHA, SHA, "refs/tags/1.0")
26         logger = PushEventLogger.new(Repository.new, spec, User.new)
27
28         assert logger.create_meta_event?
29       end
30
31       should "not create push event when creating" do
32         spec = PushSpecParser.new(NULL_SHA, SHA, "refs/tags/1.0")
33         logger = PushEventLogger.new(Repository.new, spec, User.new)
34
35         assert !logger.create_push_event?
36       end
37
38       should "not create meta event when updating" do
39         spec = PushSpecParser.new(SHA, OTHER_SHA, "refs/tags/1.0")
40         logger = PushEventLogger.new(Repository.new, spec, User.new)
41
42         assert !logger.create_meta_event?
43       end
44
45       should "not create push event when updating" do
46         spec = PushSpecParser.new(SHA, OTHER_SHA, "refs/tags/1.0")
47         logger = PushEventLogger.new(Repository.new, spec, User.new)
48
49         assert !logger.create_push_event?
50       end
51
52       should "create meta event when deleting" do
53         spec = PushSpecParser.new(SHA, NULL_SHA, "refs/tags/1.0")
54         logger = PushEventLogger.new(Repository.new, spec, User.new)
55
56         assert logger.create_meta_event?
57       end
58
59       should "not create push event when deleting" do
60         spec = PushSpecParser.new(SHA, NULL_SHA, "refs/tags/1.0")
61         logger = PushEventLogger.new(Repository.new, spec, User.new)
62
63         assert !logger.create_push_event?
64       end
65     end
66
67     context "for heads" do
68       should "create meta event when creating" do
69         spec = PushSpecParser.new(NULL_SHA, SHA, "refs/heads/master")
70         logger = PushEventLogger.new(Repository.new, spec, User.new)
71
72         assert logger.create_meta_event?
73       end
74
75       should "not create push event when creating" do
76         spec = PushSpecParser.new(NULL_SHA, SHA, "refs/heads/master")
77         logger = PushEventLogger.new(Repository.new, spec, User.new)
78
79         assert !logger.create_push_event?
80       end
81
82       should "not create meta event when updating" do
83         spec = PushSpecParser.new(SHA, OTHER_SHA, "refs/heads/master")
84         logger = PushEventLogger.new(Repository.new, spec, User.new)
85
86         assert !logger.create_meta_event?
87       end
88
89       should "create push event when updating" do
90         spec = PushSpecParser.new(SHA, OTHER_SHA, "refs/heads/master")
91         logger = PushEventLogger.new(Repository.new, spec, User.new)
92
93         assert logger.create_push_event?
94       end
95
96       should "create meta event when deleting" do
97         spec = PushSpecParser.new(SHA, NULL_SHA, "refs/heads/master")
98         logger = PushEventLogger.new(Repository.new, spec, User.new)
99
100         assert logger.create_meta_event?
101       end
102
103       should "not create push event when deleting" do
104         spec = PushSpecParser.new(SHA, NULL_SHA, "refs/heads/master")
105         logger = PushEventLogger.new(Repository.new, spec, User.new)
106
107         assert !logger.create_push_event?
108       end
109     end
110
111     context "for merge requests" do
112       should "not create meta event when updating" do
113         spec = PushSpecParser.new(SHA, OTHER_SHA, "refs/merge-requests/134")
114         logger = PushEventLogger.new(Repository.new, spec, User.new)
115
116         assert !logger.create_meta_event?, "Merge request meta events should be created in the model"
117       end
118     end
119
120     should "not create a push event when updating" do
121         spec = PushSpecParser.new(SHA, OTHER_SHA, "refs/merge-requests/134")
122         logger = PushEventLogger.new(Repository.new, spec, User.new)
123
124         assert !logger.create_push_event?      
125     end
126   end
127
128   context "deciding the action for the meta event" do
129     context "for tags" do
130       should "be Action::CREATE_TAG when creating a tag" do
131         spec = PushSpecParser.new(NULL_SHA, SHA, "refs/tags/feature")
132         logger = PushEventLogger.new(Repository.new, spec, User.new)
133
134         event = logger.build_meta_event
135         assert_equal Action::CREATE_TAG, event.action
136       end
137
138       should "be Action::DELETE_TAG when deleting a tag" do
139         spec = PushSpecParser.new(SHA, NULL_SHA, "refs/tags/feature")
140         logger = PushEventLogger.new(Repository.new, spec, User.new)
141
142         event = logger.build_meta_event
143         assert_equal Action::DELETE_TAG, event.action
144       end
145     end
146
147     context "for heads" do
148       should "be Action::CREATE_BRANCH when creating a head" do
149         spec = PushSpecParser.new(NULL_SHA, SHA, "refs/heads/master")
150         logger = PushEventLogger.new(Repository.new, spec, User.new)
151
152         event = logger.build_meta_event
153         assert_equal Action::CREATE_BRANCH, event.action
154       end
155
156       should "be Action::DELETE_BRANCH when deleting a head" do
157         spec = PushSpecParser.new(SHA, NULL_SHA, "refs/heads/master")
158         logger = PushEventLogger.new(Repository.new, spec, User.new)
159
160         event = logger.build_meta_event
161         assert_equal Action::DELETE_BRANCH, event.action
162       end
163     end
164   end
165
166   context "meta events" do
167     setup do
168       @repository = repositories(:johans)
169       @project = @repository.project
170       @user = @repository.user
171       @create_spec = PushSpecParser.new(SHA, NULL_SHA, "refs/heads/master")
172       @logger = PushEventLogger.new(@repository, @create_spec, @user)
173     end
174
175     should "be new records" do
176       event = @logger.build_meta_event
177
178       assert event.new_record?
179     end
180
181     should "belong to repository's project" do
182       event = @logger.build_meta_event
183
184       assert_equal @project, event.project
185     end
186
187     should "belong to the user pushing" do
188       event = @logger.build_meta_event
189
190       assert_equal @user, event.user
191     end
192
193     should "target repository" do
194       event = @logger.build_meta_event
195
196       assert_equal @repository, event.target
197     end
198
199     should "identify name of the head that changed" do
200       event = @logger.build_meta_event
201
202       assert_equal @create_spec.ref_name, event.data
203     end
204
205     should "build and save meta event" do
206       event = @logger.create_meta_event
207
208       assert !event.new_record?
209     end
210   end
211
212   context "Meta event message" do
213     should "describe new branches" do
214       new_branch_spec = PushSpecParser.new(NULL_SHA, SHA, "refs/heads/master")
215       logger = PushEventLogger.new(Repository.new, new_branch_spec, User.new)
216       event = logger.build_meta_event
217
218       assert_equal("Created branch master", event.body)
219     end
220
221     should "describe new tags" do
222       new_tag_spec = PushSpecParser.new(NULL_SHA, SHA, "refs/tags/release")
223       logger = PushEventLogger.new(Repository.new, new_tag_spec, User.new)
224       event = logger.build_meta_event
225
226
227       assert_equal "Created tag release", event.body
228     end
229
230     should "describe deleted tags" do
231       deleted_tag_spec = PushSpecParser.new(SHA, NULL_SHA, "refs/tags/release")
232       logger = PushEventLogger.new(Repository.new, deleted_tag_spec, User.new)
233       event = logger.build_meta_event
234
235
236       assert_equal "Deleted tag release", event.body      
237     end
238
239     should "describe deleted branches" do
240       deleted_branch_spec = PushSpecParser.new(SHA, NULL_SHA, "refs/heads/topic")
241       logger = PushEventLogger.new(Repository.new, deleted_branch_spec, User.new)
242       event = logger.build_meta_event
243
244       assert_equal "Deleted branch topic", event.body
245     end
246   end
247
248   context "Push event" do
249     setup do
250       @repository = repositories(:johans)
251       @user = users(:johan)
252       @spec = PushSpecParser.new(SHA, OTHER_SHA, "refs/heads/master")
253       @logger = PushEventLogger.new(@repository, @spec, @user)
254       @event = @logger.build_push_event
255     end
256     
257     should "have a user" do
258       assert_equal @user, @event.user
259     end
260
261     should "have a project" do
262       assert_equal @repository.project, @event.project
263     end
264
265     should "have a target" do
266       assert_equal @repository, @event.target
267     end
268
269     should "have an action" do
270       assert_equal Action::PUSH_SUMMARY, @event.action
271     end
272
273     should "know how many commits were pushed" do
274       git = mock
275       log =<<GIT_LOG
276 58226ba392520deb36cf89a7c1e85c047e9d1b2b Make sure meta events create usable meta and data attributes
277 c8db6a4907fc3cd7762e862ea2e1f1683ba00e5f Merge request update events are created from the model
278 bea57a4ac3a6590d1c66f3fadd986943d9830dde Start building event objects in PushEventLogger
279 04a7d04b72c5e9da75b775f0ff0b9b424465313a Start implementation of push event logger/factory
280 e0a6a4f6604efa4a6ab9f83e9bbc92c3a27bd625 Add documentation
281 GIT_LOG
282       git.expects(:log).with({:pretty => "oneline"}, [SHA,OTHER_SHA].join("..")).returns(log)
283       grit = mock(:git => git)
284       @repository.expects(:git).returns(grit)
285
286       assert_equal(5, @logger.calculate_commit_count)
287     end
288
289     should "create a push event with the appropriate data" do
290       @logger.expects(:calculate_commit_count).returns(10)
291       event = @logger.create_push_event
292             
293       assert_equal([SHA, OTHER_SHA, "master", "10"].join(PushEventLogger::PUSH_EVENT_DATA_SEPARATOR), event.data)
294     end
295   end
296
297   context "Parsing the event body" do
298     setup do
299       body = [SHA, OTHER_SHA, "master", "10"].join(PushEventLogger::PUSH_EVENT_DATA_SEPARATOR)
300       @result = PushEventLogger.parse_event_data(body)
301     end
302     
303     should "contain the start sha" do
304       assert_equal SHA, @result[:start_sha]
305     end
306
307     should "contain the end sha" do
308       assert_equal OTHER_SHA, @result[:end_sha]
309     end
310
311     should "contain the branch name" do
312       assert_equal "master", @result[:branch]
313     end
314
315     should "contain the commit count" do
316       assert_equal "10", @result[:commit_count]
317     end
318
319     should "contain a shortened start sha" do
320       assert_equal SHA[0,7], @result[:start_sha_short]
321     end
322
323     should "contain a shortened end sha" do
324       assert_equal OTHER_SHA[0,7], @result[:end_sha_short]
325     end
326   end
327 end