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/>.
20 # typical user session involving interaction with multiple controllers by doing
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
30 # try to login as demo1 user
31 test "login as demo1" do
32 # see if it takes us to the login page
34 assert_response :redirect, 'accessing / should redirect to /login'
36 assert_response :success
37 assert_equal login_path, path
39 smr_login(LOGIN, PASSWORD)
43 # try to list documents, upload one, download it again, delete it
44 test "work with documents" do
45 smr_login(LOGIN, PASSWORD)
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)
55 upload_file = fixture_file_upload('quote.yml', 'text/plain')
56 upload_sha1 = Digest::SHA1.hexdigest(upload_file.read)
60 {:action=>'create', :document=>{:comment=>'IntegrationTest', :content=>upload_file}, :id_portfolio=>'' },
61 {:html=>{:multipart=>true}, :referer=>documents_path }
62 assert_response :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)
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
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?
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
116 # issue and cancel orders on existing position
118 test "issue orders on existing position" do
119 smr_login(LOGIN, PASSWORD)
121 get new_position_path
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)
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}
141 {:html=>{:multipart=>true}, :referer=>positions_path }
144 get '%s/%i' % [positions_path, open_positions.first.id]
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'
152 # issue and execute new order in one step
153 marker_order2=Digest::SHA1.hexdigest(Time.now.to_s)
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}
162 {:html=>{:multipart=>true}, :referer=>positions_path }
165 get '%s/%i' % [positions_path, open_positions.first.id]
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]
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'
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)
206 assert i.is_a?(SmrCashflowLogItem)
211 # view and add FigureData
212 test "work with figure data" do
213 smr_login(LOGIN, PASSWORD)
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
236 # use the personal blog
237 test "read and blog articles" do
238 smr_login(LOGIN, PASSWORD)
241 assert_response :success
242 assert_equal blog_path, path
243 assert_not_nil blog = assigns(:blogroll)
244 assert blog.is_a?(SmrBlog)
249 assert_response :success
250 assert_equal new_blog_path, path
251 assert_not_nil article = assigns(:article)
252 assert article.is_a?(Comment)
254 {:action=>'create', :comment=>{:title=>'IntegrationTest Title', :comment=>'IntegrationTest Text'} },
255 {:referer=>blog_path }
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