added pagination gem, many fixes
[smr.git] / gui / test / integration / demo1_user_session_test.rb
blobda448d7463b750d160cc8e8764ddb96b1bb33064
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
7 # version.
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/>.
16 require 'test_helper'
17 require 'digest/sha1'
20 # typical user session involving interaction with multiple controllers by doing
21 # 'every day work'.
23 # HINT: regarding path methods, see
24 # http://stackoverflow.com/questions/5345757/in-rails-how-to-see-all-the-path-and-url-methods-added-by-railss-routing#5346350
25 class Demo1UserSessionTest < ActionDispatch::IntegrationTest
26     LOGIN = 'demo1'
27     PASSWORD = 'demo'
29     ##
30     # try to login as demo1 user
31     test "login as demo1" do
32         # see if it takes us to the login page
33         get root_path
34         assert_response :redirect, 'accessing / should redirect to /login'
35         follow_redirect!
36         assert_response :success
37         assert_equal login_path, path
38        
39         smr_login(LOGIN, PASSWORD)
40     end
42     ##
43     # try to list documents, upload one, download it again, delete it
44     test "work with documents" do
45         smr_login(LOGIN, PASSWORD)
47         get documents_path
48         assert_response :success
49         assert_not_nil assigns(:portfolios)
50         assert_not_nil assigns(:document)
51         assert_not_nil docs = assigns(:documents)
52         assert docs.is_a?(SmrDocuments) 
53         assert docs.empty?
55         upload_file = fixture_file_upload('quote.yml', 'text/plain')
56         upload_sha1 = Digest::SHA1.hexdigest(upload_file.read)
58         # upload
59         post documents_path,
60             {:action=>'create', :document=>{:comment=>'IntegrationTest', :content=>upload_file}, :id_portfolio=>'' },
61             {:html=>{:multipart=>true}, :referer=>documents_path }
62         assert_response :redirect
63         follow_redirect!
64         assert_not_nil docs = assigns(:documents), 'no document shown after upload'
65         assert docs.is_a?(SmrDocuments) 
66         assert_not docs.empty?
67         assert d = docs.each.first
68         assert d.is_a?(SmrDocument)
70         # download nothing
71         get download_path, {}, {'HTTP_REFERER'=>documents_path}
72         assert_redirected_to documents_path
74         # download what we uploaded
75         get download_path, {:id=>d.id}, {'HTTP_REFERER'=>documents_path}
76         assert_equal @response.content_type, 'text/plain'
77         assert_equal Digest::SHA1.hexdigest(@response.body), upload_sha1
79         # delete what we uploaded
80         get delete_document_path, {:id=>d.id}, {'HTTP_REFERER'=>documents_path}
81         assert_redirected_to documents_path
82     end
84     ##
85     # view a open position
86     test "view open position" do
87         smr_login(LOGIN, PASSWORD)
89         # take second position from asset listing
90         assert_not_nil asset_position_entry = assigns(:open_positions).second
91         assert asset_position_entry.is_a?(SmrPosition)
92         get '%s/%i' % [positions_path, asset_position_entry.id]
93         assert_response :success
94         assert_equal position_path, path
95         assert_not_nil p = assigns(:position)
96         assert p.is_a?(SmrPosition)
98         # position should be open since we took it from open_positions
99         assert_not p.is_closed?
100         assert_not p.is_new?
101         assert p.invested.is_a?(Float)
102         assert (p.market_value.is_a?(Float) and p.market_value>0.0)
103         assert p.profit_loss.is_a?(Float)
104         assert p.dividend.received.is_a?(Float)
105         assert (p.charges.is_a?(Float) and p.charges <=0.0)
106         assert p.gain.is_a?(Float)
108         # it must have at least one revision since its open but not new
109         assert_not_nil first_revision = p.revisions.first
110         assert first_revision.is_a?(PositionRevision)
111         assert first_revision.Order.is_a?(Order)
112         assert_not_equal first_revision.shares, 0.0
113     end
115     ##
116     # issue and cancel orders on existing position
117     #
118     test "issue orders on existing position" do
119         smr_login(LOGIN, PASSWORD)
121         get new_position_path
122         assert :success
124         # the form should offer option 3: new order in portfolio OR new order
125         # on existing position
126         assert_not assigns(:position)
127         assert_not assigns(:portfolio)
128         assert open_positions = assigns(:open_positions)
129         assert stocks = assigns(:stocks)
130         assert portfolios = assigns(:portfolios)
132         # issue new order on existing open position
133         marker_order1=Digest::SHA1.hexdigest(Time.now.to_s)
134         post positions_path, 
135             { :action=>'create', :id_position=>open_positions.first.id,
136               :order_issued=>Time.now, :order_expire=>Time.now+2.days,
137               :order=>{ :shares=>100, :limit=>6.66, :provision=>1.11,
138                         :expense=>2.22, :courtage=>0.0,
139                         :comment=>marker_order1}
140             },
141             {:html=>{:multipart=>true}, :referer=>positions_path }
142         assert :success
144         get '%s/%i' % [positions_path, open_positions.first.id]
145         assert :success
146         assert p = assigns(:position)
147         assigns p.is_a?(SmrPosition)
148         assert p.has_pending_orders?
149         neworder1 = p.pending_orders.where(:comment=>marker_order1).first
150         assert neworder1.is_a?(Order), 'issued order not found in pending state'
151         
152         # issue and execute new order in one step
153         marker_order2=Digest::SHA1.hexdigest(Time.now.to_s)
154         post positions_path, 
155             { :action=>'create', :id_position=>open_positions.first.id,
156               :execute_now=>1, :execute_quote=>7.76,
157               :order_issued=>Time.now, :order_expire=>Time.now+2.days,
158               :order=>{ :shares=>200, :limit=>7.77, :provision=>0.00,
159                         :expense=>0.001, :courtage=>3.33,
160                         :comment=>marker_order2}
161             },
162             {:html=>{:multipart=>true}, :referer=>positions_path }
163         assert :success
165         get '%s/%i' % [positions_path, open_positions.first.id]
166         assert :success
167         assert p_after_execute = assigns(:position)
168         assigns p_after_execute.is_a?(SmrPosition)
170         assert p_after_execute.revisions.any? {|r| r.Order.comment == marker_order2},
171             'executed new order did not create new revision'
173         # check whether executing changed number of shares, invested, etc... in
174         # position ... and.... well... it should be correctly calculated
175         assert_equal p.shares + 200, p_after_execute.shares,
176             'wrong number of shares in position after order execute'
177         assert_equal p.invested + 200*7.76, p_after_execute.invested,
178             'wrong invested amount in position after order execute'
179         assert_equal p.charges - 0.001 - 3.33, p_after_execute.charges,
180             'wrong charges in position after order execute'
182         # cancel issued neworder1
183         post cancel_order_path,
184             { :action=>'cancel_order', :id_order=>neworder1.id},
185             {:html=>{:multipart=>true}, :referer=>'%s/%i' % [positions_path, p.id] }
186         assert_redirected_to '%s/%i' % [positions_path, p.id]
187         follow_redirect!
188         assert p_after_cancel = assigns(:position)
189         assigns p_after_cancel.is_a?(SmrPosition)
190         assert_nil p_after_cancel.pending_orders.where(:comment=>marker_order1).first,
191             'failed to cancel pending order'
192     end 
194     ##
195     # view cashflows from dividends and orders
196     test "view cashflow" do
197         smr_login(LOGIN, PASSWORD)
199         get cashflow_index_path
200         assert_response :success
201         assert_equal cashflow_index_path, path
202         assert_not_nil cflog = assigns(:log)
203         assert cflog.is_a?(SmrCashflowLog)
205         cflog.each do |i|
206             assert i.is_a?(SmrCashflowLogItem)
207         end
208     end
210     ##
211     # view and add FigureData
212     test "work with figure data" do
213         smr_login(LOGIN, PASSWORD)
215         get figures_path
216         assert_response :success
217         assert_equal figures_path, path
218         assert_not_nil sec = assigns(:securities)
219         assert sec.is_a?(ActiveRecord::Relation)
220         assert_not_nil sec_selected = assigns(:selected_security)
221         assert sec_selected.is_a?(Stock)
222         assert_not_nil have_data = assigns(:have_data)
223         assert have_data.is_a?(FalseClass)
225         # select a security that has figure data
226         get figures_path, {:id_stock=>25, :show=>'this'}
227         assert_response :success
228         assert assigns(:have_data).is_a?(TrueClass)
229         assert assigns(:datatable).render  # Raises if no data
231         # add new FigureData
232         # FIXME: tbd
233     end
235     ##
236     # use the personal blog
237     test "read and blog articles" do
238         smr_login(LOGIN, PASSWORD)
240         get blog_path
241         assert_response :success
242         assert_equal blog_path, path
243         assert_not_nil blog = assigns(:blogroll)
244         assert blog.is_a?(SmrBlog)
245         assert blog.empty?
247         # blog new article
248         get new_blog_path
249         assert_response :success
250         assert_equal new_blog_path, path
251         assert_not_nil article = assigns(:article)
252         assert article.is_a?(Comment)
253         post blog_path,
254             {:action=>'create', :comment=>{:title=>'IntegrationTest Title', :comment=>'IntegrationTest Text'} },
255             {:referer=>blog_path }
256         follow_redirect!
257         assert_equal blog_path, path
258         assert_not_nil blog = assigns(:blogroll)
259         assert blog.is_a?(SmrBlog)
260         assert_not blog.empty?
261         item = blog.each.first
262         assert item.is_a?(SmrBlogItem)
263         assert_equal 'Comment', item.type
264         assert_equal 'IntegrationTest Title', item.title
265         assert_equal 'IntegrationTest Text', item.body
266     end