2 # This file is part of SMR.
4 # SMR is free software: you can redistribute it and/or modify it under the
5 # terms of the GNU General Public License as published by the Free Software
6 # Foundation, either version 3 of the License, or (at your option) any later
9 # SMR is distributed in the hope that it will be useful, but WITHOUT ANY
10 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License along with
14 # SMR. If not, see <http://www.gnu.org/licenses/>.
21 # typical user session involving interaction with multiple controllers by doing
24 # HINT: regarding path methods, see
25 # http://stackoverflow.com/questions/5345757/in-rails-how-to-see-all-the-path-and-url-methods-added-by-railss-routing#5346350
26 class Demo1UserSessionTest < ActionDispatch::IntegrationTest
31 # try to login as demo1 user
32 test "login as demo1" do
33 # see if it takes us to the login page
35 assert_response :redirect, 'accessing / should redirect to /login'
37 assert_response :success
38 assert_equal login_path, path
40 smr_login(LOGIN, PASSWORD)
44 # try to list documents, upload one, download it again, delete it
45 test "work with documents" do
46 smr_login(LOGIN, PASSWORD)
49 assert_response :success
50 assert_not_nil assigns(:portfolios)
51 assert_not_nil assigns(:document)
52 assert_not_nil docs = assigns(:documents)
53 assert docs.is_a?(UploadedFiles)
56 upload_file = fixture_file_upload('quote.yml', 'text/plain')
57 upload_sha1 = Digest::SHA1.hexdigest(upload_file.read)
61 {:action=>'create', :document=>{:comment=>'IntegrationTest', :content=>upload_file}, :id_portfolio=>'' },
62 {:html=>{:multipart=>true}, :referer=>documents_path }
63 assert_response :redirect
65 assert_not_nil docs = assigns(:documents), 'no document shown after upload'
66 assert docs.is_a?(UploadedFiles)
67 assert_not docs.empty?
68 assert d = docs.each.first
69 assert d.is_a?(UploadedFile)
72 get download_path, {}, {'HTTP_REFERER'=>documents_path}
73 assert_redirected_to documents_path
75 # download what we uploaded
76 get download_path, {:id=>d.id}, {'HTTP_REFERER'=>documents_path}
77 assert_equal @response.content_type, 'text/plain'
78 assert_equal Digest::SHA1.hexdigest(@response.body), upload_sha1
80 # delete what we uploaded
81 get delete_document_path, {:id=>d.id}, {'HTTP_REFERER'=>documents_path}
82 assert_redirected_to documents_path
86 # view a open position
87 test "view open position" do
88 smr_login(LOGIN, PASSWORD)
90 # take second position from asset listing
91 assert_not_nil asset_position_entry = assigns(:open_positions).second
92 assert asset_position_entry.is_a?(AssetPosition)
93 get position_path(:id=>asset_position_entry.id)
94 assert_response :success
95 assert_equal position_path, path
96 assert_not_nil p = assigns(:position)
97 assert p.is_a?(AssetPosition)
99 # position should be open since we took it from open_positions
100 assert_not p.is_closed?
102 assert p.invested.is_a?(Float)
103 assert (p.market_value.is_a?(Float) and p.market_value>0.0)
104 assert p.profit_loss.is_a?(Float)
105 assert p.dividend.received
106 assert (p.charges.is_a?(Float) and p.charges >= 0.0)
107 assert p.gain.is_a?(Float)
109 # it must have at least one revision since its open but not new
110 assert_not_nil first_revision = p.revisions.first
111 assert first_revision.is_a?(PositionRevision)
112 assert first_revision.Order.is_a?(Order)
113 assert_not_equal first_revision.shares, 0.0
116 get position_path(:id=>30)
117 assert_redirected_to root_path, 'no redirect when using position_controller with cash position'
121 # issue and cancel orders on existing position
123 test "issue orders on existing position" do
124 smr_login(LOGIN, PASSWORD)
126 get new_position_path
129 # the form should offer option 3: new order in portfolio OR new order
130 # on existing position
131 assert_not assigns(:position)
132 assert_not assigns(:portfolio)
133 assert open_positions = assigns(:open_positions)
134 assert stocks = assigns(:stocks)
135 assert portfolios = assigns(:portfolios)
137 # issue new order on existing open position
138 marker_order1=Digest::SHA1.hexdigest(Time.now.to_s)
139 post position_index_path(:id_position=>open_positions.first.id),
141 :order_issued=>Time.now, :order_expire=>Time.now+2.days,
142 :order=>{ :shares=>100, :limit=>6.66, :provision=>1.11,
143 :expense=>2.22, :courtage=>0.0,
144 :comment=>marker_order1}
146 {:html=>{:multipart=>true}, :referer=>position_path(:id=>open_positions.first.id) }
149 get position_path(:id=>open_positions.first.id)
151 assert p = assigns(:position)
152 assigns p.is_a?(AssetPosition)
153 assert p.has_pending_orders?
154 neworder1 = p.pending_orders.where(:comment=>marker_order1).first
155 assert neworder1.is_a?(Order), 'issued order not found in pending state, got: %s' % neworder1.inspect
157 # issue and execute new order in one step
158 marker_order2=Digest::SHA1.hexdigest(Time.now.to_s)
159 post position_index_path(:id_position=>open_positions.first.id),
161 :execute_now=>1, :execute_quote=>7.76, :execute_time=>Time.now+2.hours,
162 :order_issued=>Time.now, :order_expire=>Time.now+2.days,
163 :order=>{ :shares=>200, :limit=>7.77, :provision=>0.00,
164 :expense=>0.001, :courtage=>3.33,
165 :comment=>marker_order2}
167 {:html=>{:multipart=>true}, :referer=>position_path }
170 get position_path(:id=>open_positions.first.id)
172 assert p_after_execute = assigns(:position)
173 assigns p_after_execute.is_a?(AssetPosition)
175 assert p_after_execute.revisions.any? {|r| r.Order.comment == marker_order2},
176 'executed new order did not create new revision'
178 # check whether executing changed number of shares, invested, etc... in
179 # position ... and.... well... it should be correctly calculated
180 assert_equal p.shares + 200, p_after_execute.shares,
181 'wrong number of shares in position after order execute'
182 assert_equal p.invested + 200*7.76, p_after_execute.invested,
183 'wrong invested amount in position after order execute'
184 assert_equal p.charges + 0.001 + 3.33, p_after_execute.charges,
185 'wrong charges in position after order execute'
187 # cancel issued neworder1
188 post cancel_order_path,
189 { :action=>'cancel_order', :id_order=>neworder1.id},
190 {:html=>{:multipart=>true}, :referer=>position_path(:id=>p.id) }
191 assert_redirected_to position_path(:id=>p.id)
193 assert p_after_cancel = assigns(:position)
194 assigns p_after_cancel.is_a?(AssetPosition)
195 assert_nil p_after_cancel.pending_orders.where(:comment=>marker_order1).first,
196 'failed to cancel pending order'
200 # utilize a cash position: view, make booking
201 test "work with cash position" do
202 smr_login(LOGIN, PASSWORD)
204 get cashposition_path(:id=>15)
205 assert_redirected_to root_path, 'no redirect when using cashposition_controller with regular position'
207 get cashposition_path(:id=>30)
208 assert_response :success
209 assert_equal cashposition_path(:id=>30), path
211 assert_not_nil cp = assigns(:position)
212 assert cp.is_a?(Smr::AssetPosition)
213 assert cp.is_cash_position?
214 assert_equal -4656, cp.invested, 'wrong balance of cash account'
216 # make booking: one deposit, one withdrawal, re-test balance
217 booking_data = { :id_cashposition=>30, :amount=>100, :date=>'2015-03-25', :comment=>'booking deposit test' }
218 post(cashposition_index_path(:id=>30),
219 {:action=>'create', :booking=>booking_data},
220 {:referer=>cashposition_path(:id=>30) }
223 assert_equal cashposition_path(:id=>30), path
224 assert_not_nil cp = assigns(:position)
225 assert_equal -4556, cp.invested, 'wrong balance after booking deposit'
227 booking_data = { :id_cashposition=>30, :amount=>-1000, :date=>'2015-03-26', :comment=>'booking withdrawal test' }
228 post(cashposition_index_path(:id=>30),
229 {:action=>'create', :booking=>booking_data},
230 {:referer=>cashposition_path(:id=>30) }
233 assert_equal cashposition_path(:id=>30), path
234 assert_not_nil cp = assigns(:position)
235 assert_equal -5556, cp.invested, 'wrong balance after booking withdrawal'
239 # view cashflows from dividends and orders
240 test "view cashflow" do
241 smr_login(LOGIN, PASSWORD)
243 get cashflow_index_path
244 assert_response :success
245 assert_equal cashflow_index_path, path
246 assert_not_nil cflog = assigns(:log)
247 assert cflog.is_a?(CashflowLog)
250 assert i.is_a?(CashflowLogItem)
255 # view and add FigureData
256 test "work with figure data" do
257 smr_login(LOGIN, PASSWORD)
260 assert_response :success
261 assert_equal figures_path, path
262 assert assigns(:securities).is_a?(Array)
263 assert assigns(:selected_security).is_a?(Stock)
264 assert assigns(:have_data).is_a?(FalseClass)
266 # select a security that has figure data
267 get figures_path, {:id_stock=>25, :show=>'this'}
268 assert_response :success
269 assert assigns(:have_data).is_a?(TrueClass)
270 assert assigns(:datatable).render # Raises if no data
273 # - no fixtures on BASF AG, therefore nothing should be shown at first
274 # and then only FigureData we added from here
277 :id_stock=>15, # BASF AG
278 :id_figure_var=>4, # Demo1Var1
279 :period=>'year', :time=>1.days.ago.strftime('%Y-%m-%d'),
280 :analyst=>'integration test', :value=>1.23, :is_expected=>1,
281 :is_audited=>1, :comment=>'made by demo1 integration test'
284 get new_figure_path, :id_stock=>figure_data[:id_stock], :show=>'this'
285 assert_response :success
286 assert assigns(:figuredata).is_a?(FigureData)
287 assert assigns(:have_data).is_a?(FalseClass)
289 {:action=>'create', :figure_data=>figure_data},
290 {:referer=>figures_path}
293 assert_equal figures_path, path
294 assert assigns(:selected_security).is_a?(Stock)
295 assert_equal assigns(:selected_security).id, figure_data[:id_stock]
296 assert assigns(:have_data).is_a?(TrueClass)
298 # try again, but store FigureData on a FigureVar that belongs to
300 # note: thats something the Gui does not allow to do
301 figure_data[:id_figure_var] = 1 # FirstVar, belongs :id_user=1 (admin)
302 figure_data[:id_stock] = 6 # CocaCola Inc.
303 get new_figure_path, :id_stock=>figure_data[:id_stock], :show=>'this'
304 assert_response :success
305 assert assigns(:have_data).is_a?(FalseClass)
307 {:action=>'create', :figure_data=>figure_data},
308 {:referer=>figures_path}
311 assert assigns(:have_data).is_a?(FalseClass)
315 # use the personal blog
316 test "read and blog articles" do
317 smr_login(LOGIN, PASSWORD)
320 assert_response :success
321 assert_equal blog_path, path
322 assert_not_nil blog = assigns(:blogroll)
323 assert blog.is_a?(Blog)
328 assert_response :success
329 assert_equal new_blog_path, path
330 assert_not_nil article = assigns(:article)
331 assert article.is_a?(Comment)
333 {:action=>'create', :comment=>{:title=>'IntegrationTest Title', :comment=>'IntegrationTest Text'} },
334 {:referer=>blog_path }
336 assert_equal blog_path, path
337 assert_not_nil blog = assigns(:blogroll)
338 assert blog.is_a?(Blog)
339 assert_not blog.empty?
340 item = blog.each.first
341 assert item.is_a?(BlogItem)
342 assert_equal 'Comment', item.type
343 assert_equal 'IntegrationTest Title', item.title
344 assert_equal 'IntegrationTest Text', item.body
349 test "work with quoterecords" do
350 smr_login(LOGIN, PASSWORD)
352 get quoterecords_path
353 assert_response :success
355 # get quoterecords on E.On AG (there should not be any) for 2007-08-07
356 post set_session_params_path,
357 {:smr_browse_date=>{:day=>7, :month=>8, :year=>2007}},
358 {:referer=>quoterecords_path}
360 get quoterecords_path, { :id_stock=>25, :show=>'this' }
361 assert_response :success
362 assert assigns(:selected_security).is_a?(Stock)
363 assert_equal 25, assigns(:selected_security).id
365 assert_not_nil quote = assigns(:intraday_quotes).first
366 assert quote.is_a?(Quote)
368 # post a new quoterecord from :intraday_quotes observations
369 marker_qr=Digest::SHA1.hexdigest(Time.now.to_s)
370 post quoterecords_path,
373 :id=>'', :id_stock=>quote.id_stock, :id_quote=>quote.id,
374 :column=>'upward', :comment=>marker_qr,
375 :is_pivotal_point=>0, :is_uphit=>0, :is_downhit=>0, :is_signal=>0
377 :commit=>'record this one'
379 {:referer=>quoterecords_path}
380 assert_response :success
381 assert_equal quoterecords_path, path
383 # now we should see that one listed in previous records
384 assert_not_nil qrs = assigns(:quoterecords)
385 assert qrs.is_a?(Smr::Quoterecords)
387 assert_equal qr.comment, marker_qr
388 assert_equal qr.column, 'upward'
391 get quoterecord_path(:id=>qr.id)
392 assert_response :success
393 assert_not_nil qr_edit = assigns(:quoterecord)
394 assert_equal qr_edit.comment, qr.comment
395 marker_qr_edit=Digest::SHA1.hexdigest(marker_qr + Time.now.to_s)
396 post quoterecords_path,
399 :id=>qr_edit.id, :column=>'downward', :comment=>marker_qr_edit,
400 :is_pivotal_point=>0, :is_uphit=>0, :is_downhit=>0, :is_signal=>0
402 :commit=>'record this one'
404 {:referer=>quoterecords_path}
405 assert_response :success
406 assert_not_nil qrs_edited = assigns(:quoterecords)
407 assert_equal qrs_edited.first.comment, marker_qr_edit
411 # record rules on quoterecords
412 test "work with quoterecord rules" do
413 smr_login(LOGIN, PASSWORD)
415 get quoterecord_rules_path
416 assert_response :success
417 assert assigns(:rules).empty?
420 marker_rule1=Digest::SHA1.hexdigest('obey!' + Time.now.to_s)
421 get new_quoterecord_rule_path
422 assert_response :success
423 post quoterecord_rules_path,
425 :quoterecord_rule=>{:id=>'', :order=>1, :name=>'rule1', :rule=>marker_rule1},
426 :related_columns=>['secondary_rally', 'downward'],
429 {:referer=>new_quoterecord_rule_path}
431 assert_response :success
432 rules = assigns(:rules)
433 assert_not rules.empty?, 'we should have a rule by now'
434 assert_equal rules.first.name, 'rule1'
435 assert_equal rules.first.rule, marker_rule1
436 assert rules.first.get_related_columns.include?('downward'), 'column not related to new rule'
439 marker_edited=Digest::SHA1.hexdigest('I said obey!' + Time.now.to_s)
440 get new_quoterecord_rule_path, :id=>rules.first.id
441 assert_not_nil edit_rule = assigns(:rule)
442 assert_equal edit_rule.rule, marker_rule1
443 post quoterecord_rules_path,
445 :quoterecord_rule=>{:id=>edit_rule.id, :order=>1, :name=>edit_rule.name, :rule=>marker_edited},
446 :related_columns=>['secondary_reaction', 'upward'],
449 {:referer=>new_quoterecord_rule_path}
451 assert_response :success
452 assert_not_nil edited_rule = assigns(:rules).first
453 assert_equal edited_rule.name, 'rule1'
454 assert_equal edited_rule.rule, marker_edited
455 assert edited_rule.get_related_columns.include?('upward'), 'edited column relation not present'