def get(self): if BIWEEKLYBUDGET_TEST_TIMESTAMP is None: return 'var BIWEEKLYBUDGET_DEFAULT_DATE = new Date();' dt = dtnow() return 'var BIWEEKLYBUDGET_DEFAULT_DATE = new Date(%s, %s, %s);' % ( dt.year, (dt.month - 1), dt.day)
def test_1_modal(self, base_url, selenium): self.baseurl = base_url self.get(selenium, base_url + '/transactions') link = selenium.find_element_by_xpath( '//a[@href="javascript:txnReconcileModal(1)"]') link.click() modal, title, body = self.get_modal_parts(selenium) self.assert_modal_displayed(modal, title, body) assert title.text == 'Transaction Reconcile 1' dl = body.find_element_by_tag_name('dl') assert dl.get_attribute('innerHTML') == '\n' \ '<dt>Date Reconciled</dt><dd>2017-04-10 08:09:11 UTC</dd>\n' \ '<dt>Note</dt><dd>reconcile notes</dd>\n' \ '<dt>Rule</dt><dd>null</dd>\n' trans_tbl = body.find_element_by_id('txnReconcileModal-trans') trans_texts = self.tbody2textlist(trans_tbl) assert trans_texts == [ ['Transaction'], [ 'Date', (dtnow() + timedelta(days=4)).strftime('%Y-%m-%d') ], ['Amount', '$111.13'], ['Budgeted Amount', '$111.11'], ['Description', 'T1foo'], ['Account', 'BankOne (1)'], ['Budget', 'Periodic1 (1)'], ['Notes', 'notesT1'], ['Scheduled?', 'Yes (1)'] ] trans_elems = self.tbody2elemlist(trans_tbl) assert trans_elems[5][1].get_attribute('innerHTML') == '<a href=' \ '"/accounts/1">BankOne (1)</a>' assert trans_elems[6][1].get_attribute('innerHTML') == '<a href=' \ '"/budgets/1">Periodic1 (1)</a>' assert trans_elems[8][1].get_attribute('innerHTML') == '<a href=' \ '"/scheduled/1">Yes (1)</a>' ofx_tbl = body.find_element_by_id('txnReconcileModal-ofx') ofx_texts = self.tbody2textlist(ofx_tbl) assert ofx_texts == [ ['OFX Transaction'], ['Account', 'BankOne (1)'], ['FITID', 'BankOne.0.1'], ['Date Posted', (dtnow() - timedelta(days=6)).strftime('%Y-%m-%d')], ['Amount', '-$20.00'], ['Name', 'Late Fee'], ['Memo', ''], ['Type', 'Debit'], ['Description', ''], ['Notes', ''], ['Checknum', ''], ['MCC', ''], ['SIC', ''], ['OFX Statement'], ['ID', '1'], ['Date', (dtnow() - timedelta(hours=46)).strftime('%Y-%m-%d')], ['Filename', '/stmt/BankOne/0'], [ 'File mtime', (dtnow() - timedelta(hours=46)).strftime('%Y-%m-%d') ], ['Ledger Balance', '$12,345.67'] ] ofx_elems = self.tbody2elemlist(ofx_tbl) assert ofx_elems[1][1].get_attribute('innerHTML') == '<a href=' \ '"/accounts/1">BankOne (1)</a>'
def test_dtnow(self): assert dtnow() == datetime(2016, 5, 13, 11, 21, 32, tzinfo=utc)
def test_dtnow_test(self): assert dtnow() == datetime(2017, 7, 28, 6, 24, 44, tzinfo=utc)
def test_14_fuel_add_with_trans(self, base_url, selenium): self.get(selenium, base_url + '/fuel') link = selenium.find_element_by_id('btn-add-fuel') self.wait_until_clickable(selenium, 'btn-add-fuel') modal, title, body = self.try_click_and_get_modal(selenium, link) self.assert_modal_displayed(modal, title, body) assert title.text == 'Add Fuel Fill' veh_sel = Select(selenium.find_element_by_id('fuel_frm_vehicle')) veh_sel.select_by_value('1') date = selenium.find_element_by_id('fuel_frm_date') date.clear() date.send_keys( (dtnow() - timedelta(days=2)).date().strftime('%Y-%m-%d')) odo = selenium.find_element_by_id('fuel_frm_odo_miles') odo.clear() odo.send_keys('1256') rep_mi = selenium.find_element_by_id('fuel_frm_reported_miles') rep_mi.clear() rep_mi.send_keys('345') lvl_before = Select( selenium.find_element_by_id('fuel_frm_level_before')) lvl_before.select_by_value('10') lvl_after = Select(selenium.find_element_by_id('fuel_frm_level_after')) lvl_after.select_by_value('100') fill_loc = selenium.find_element_by_id('fuel_frm_fill_loc') fill_loc.clear() fill_loc.send_keys('Fill Location2') cpg = selenium.find_element_by_id('fuel_frm_cost_per_gallon') cpg.clear() cpg.send_keys('1.459') cost = selenium.find_element_by_id('fuel_frm_total_cost') cost.clear() cost.send_keys('14.82') gals = selenium.find_element_by_id('fuel_frm_gallons') gals.clear() gals.send_keys('5.678') rep_mpg = selenium.find_element_by_id('fuel_frm_reported_mpg') rep_mpg.clear() rep_mpg.send_keys('28.3') add_trans = selenium.find_element_by_id('fuel_frm_add_trans') assert add_trans.is_selected() acct_sel = Select(body.find_element_by_id('fuel_frm_account')) acct_sel.select_by_value('3') budget_sel = Select(body.find_element_by_id('fuel_frm_budget')) budget_sel.select_by_value('1') notes = selenium.find_element_by_id('fuel_frm_notes') notes.clear() notes.send_keys('My Notes2') # submit the form selenium.find_element_by_id('modalSaveButton').click() self.wait_for_jquery_done(selenium) # check that we got positive confirmation _, _, body = self.get_modal_parts(selenium) x = body.find_elements_by_tag_name('div')[0] assert 'alert-success' in x.get_attribute('class') assert x.text.strip() == 'Successfully saved FuelFill 8 ' \ 'and Transaction 5 in database.' # dismiss the modal selenium.find_element_by_id('modalCloseButton').click() self.wait_for_jquery_done(selenium) # test that datatable was updated table = selenium.find_element_by_id('table-fuel-log') odo_reads = [y[2] for y in self.tbody2textlist(table)] assert odo_reads == [ '1,011', '1,012', '1,013', '1,001', '1,002', '1,003', '1,256', '1,123' ]
def get_page(self, base_url, selenium): self.baseurl = base_url self.dt = dtnow() self.get(selenium, base_url + '/fuel')
def test_pay_period_start_date(self): assert PAY_PERIOD_START_DATE < dtnow().date()
def test_11_fuel_populate_modal(self, base_url, selenium): self.get(selenium, base_url + '/fuel') link = selenium.find_element_by_id('btn-add-fuel') self.wait_until_clickable(selenium, 'btn-add-fuel') link.click() modal, title, body = self.get_modal_parts(selenium) self.assert_modal_displayed(modal, title, body) assert title.text == 'Add Fuel Fill' veh_sel = Select(selenium.find_element_by_id('fuel_frm_vehicle')) opts = [[o.get_attribute('value'), o.text] for o in veh_sel.options] assert opts == [['1', 'Veh1'], ['2', 'Veh2'], ['3', 'Veh3Edited']] assert veh_sel.first_selected_option.get_attribute('value') == '1' date = selenium.find_element_by_id('fuel_frm_date') assert date.get_attribute( 'value') == dtnow().date().strftime('%Y-%m-%d') odo = selenium.find_element_by_id('fuel_frm_odo_miles') assert odo.get_attribute('value') == '' rep_mi = selenium.find_element_by_id('fuel_frm_reported_miles') assert rep_mi.get_attribute('value') == '' lvl_before = Select( selenium.find_element_by_id('fuel_frm_level_before') ) opts = [[o.get_attribute('value'), o.text] for o in lvl_before.options] assert opts == LEVEL_OPTS assert lvl_before.first_selected_option.get_attribute('value') == '0' lvl_after = Select( selenium.find_element_by_id('fuel_frm_level_after') ) opts = [[o.get_attribute('value'), o.text] for o in lvl_after.options] assert opts == LEVEL_OPTS assert lvl_after.first_selected_option.get_attribute('value') == '100' fill_loc = selenium.find_element_by_id('fuel_frm_fill_loc') assert fill_loc.get_attribute('value') == '' cpg = selenium.find_element_by_id('fuel_frm_cost_per_gallon') assert cpg.get_attribute('value') == '' cost = selenium.find_element_by_id('fuel_frm_total_cost') assert cost.get_attribute('value') == '' gals = selenium.find_element_by_id('fuel_frm_gallons') assert gals.get_attribute('value') == '' rep_mpg = selenium.find_element_by_id('fuel_frm_reported_mpg') assert rep_mpg.get_attribute('value') == '' add_trans = selenium.find_element_by_id('fuel_frm_add_trans') assert add_trans.is_selected() acct_sel = Select(body.find_element_by_id('fuel_frm_account')) opts = [[o.get_attribute('value'), o.text] for o in acct_sel.options] assert opts == [ ['None', ''], ['1', 'BankOne'], ['2', 'BankTwoStale'], ['3', 'CreditOne'], ['4', 'CreditTwo'], ['6', 'DisabledBank'], ['5', 'InvestmentOne'] ] assert acct_sel.first_selected_option.get_attribute('value') == '1' budget_sel = Select(body.find_element_by_id('fuel_frm_budget')) opts = [[o.get_attribute('value'), o.text] for o in budget_sel.options] assert opts == [ ['None', ''], ['7', 'Income (income)'], ['1', 'Periodic1'], ['2', 'Periodic2'], ['3', 'Periodic3 Inactive'], ['4', 'Standing1'], ['5', 'Standing2'], ['6', 'Standing3 Inactive'] ] assert budget_sel.first_selected_option.get_attribute('value') == '2' notes = selenium.find_element_by_id('fuel_frm_notes') assert notes.get_attribute('value') == ''
def is_in_past(self): return self.end_date < dtnow().date()
def test_02_transfer_modal(self, base_url, selenium): # Fill in the form self.get(selenium, base_url + '/') # check the table content on the page btable = selenium.find_element_by_id('table-accounts-bank') btexts = self.tbody2textlist(btable) assert btexts == [[ 'BankOne', '$12,789.01 (14 hours ago)', '$0.00', '$12,789.01' ], ['BankTwoStale', '$100.23 (18 days ago)', '-$333.33', '$433.56']] itable = selenium.find_element_by_id('table-accounts-investment') itexts = self.tbody2textlist(itable) assert itexts == [['InvestmentOne', '$10,362.91 (13 days ago)']] # open the modal to do a transfer link = selenium.find_element_by_id('btn_acct_txfr_bank') modal, title, body = self.try_click_and_get_modal(selenium, link) self.assert_modal_displayed(modal, title, body) assert title.text == 'Account Transfer' assert body.find_element_by_id('acct_txfr_frm_date').get_attribute( 'value') == dtnow().strftime('%Y-%m-%d') amt = body.find_element_by_id('acct_txfr_frm_amount') amt.clear() amt.send_keys('123.45') budget_sel = Select(body.find_element_by_id('acct_txfr_frm_budget')) opts = [] for o in budget_sel.options: opts.append([o.get_attribute('value'), o.text]) assert opts == [['None', ''], ['1', 'Periodic1'], ['2', 'Periodic2'], ['4', 'Standing1'], ['5', 'Standing2'], ['7', 'Income (i)']] assert budget_sel.first_selected_option.get_attribute( 'value') == 'None' budget_sel.select_by_value('2') from_acct_sel = Select( body.find_element_by_id('acct_txfr_frm_from_account')) opts = [] for o in from_acct_sel.options: opts.append([o.get_attribute('value'), o.text]) assert opts == [['None', ''], ['1', 'BankOne'], ['2', 'BankTwoStale'], ['3', 'CreditOne'], ['4', 'CreditTwo'], ['6', 'DisabledBank'], ['5', 'InvestmentOne']] assert from_acct_sel.first_selected_option.get_attribute( 'value') == 'None' from_acct_sel.select_by_value('1') to_acct_sel = Select( body.find_element_by_id('acct_txfr_frm_to_account')) opts = [] for o in to_acct_sel.options: opts.append([o.get_attribute('value'), o.text]) assert opts == [['None', ''], ['1', 'BankOne'], ['2', 'BankTwoStale'], ['3', 'CreditOne'], ['4', 'CreditTwo'], ['6', 'DisabledBank'], ['5', 'InvestmentOne']] assert to_acct_sel.first_selected_option.get_attribute( 'value') == 'None' to_acct_sel.select_by_value('2') notes = selenium.find_element_by_id('acct_txfr_frm_notes') notes.clear() notes.send_keys('Account Transfer Notes') # submit the form selenium.find_element_by_id('modalSaveButton').click() self.wait_for_jquery_done(selenium) # check that we got positive confirmation _, _, body = self.get_modal_parts(selenium) x = body.find_elements_by_tag_name('div')[0] assert 'alert-success' in x.get_attribute('class') assert x.text.strip() == 'Successfully saved Transactions 5 and 6' \ ' in database.' # dismiss the modal selenium.find_element_by_id('modalCloseButton').click() self.wait_for_load_complete(selenium) self.wait_for_id(selenium, 'table-accounts-bank') # ensure that the page content updated after refreshing btable = selenium.find_element_by_id('table-accounts-bank') btexts = self.tbody2textlist(btable) assert btexts == [[ 'BankOne', '$12,789.01 (14 hours ago)', '$123.45', '$12,665.56' ], ['BankTwoStale', '$100.23 (18 days ago)', '-$456.78', '$557.01']] itable = selenium.find_element_by_id('table-accounts-investment') itexts = self.tbody2textlist(itable) assert itexts == [['InvestmentOne', '$10,362.91 (13 days ago)']]
def test_2_transfer_modal(self, base_url, selenium, testdb): # Fill in the form self.get(selenium, base_url + '/budgets') # test that updated budget was removed from the page stable = selenium.find_element_by_id('table-standing-budgets') stexts = self.tbody2textlist(stable) assert stexts[1] == ['yes', 'Standing2 (5)', '$9,482.29'] ptable = selenium.find_element_by_id('table-periodic-budgets') ptexts = self.tbody2textlist(ptable) assert ptexts[2] == ['yes', 'Periodic2 (2)', '$234.00'] pp = BiweeklyPayPeriod.period_for_date(dtnow(), testdb) assert float(pp.budget_sums[2]['allocated']) == 222.22 assert float(pp.budget_sums[2]['budget_amount']) == 234.0 assert "%.2f" % float(pp.budget_sums[2]['remaining']) == '11.78' assert float(pp.budget_sums[2]['spent']) == 222.22 assert float(pp.budget_sums[2]['trans_total']) == 222.22 link = selenium.find_element_by_id('btn_budget_txfr') link.click() modal, title, body = self.get_modal_parts(selenium) self.assert_modal_displayed(modal, title, body) assert title.text == 'Budget Transfer' assert body.find_element_by_id('budg_txfr_frm_date').get_attribute( 'value') == dtnow().strftime('%Y-%m-%d') amt = body.find_element_by_id('budg_txfr_frm_amount') amt.clear() amt.send_keys('123.45') acct_sel = Select(body.find_element_by_id('budg_txfr_frm_account')) opts = [] for o in acct_sel.options: opts.append([o.get_attribute('value'), o.text]) assert opts == [['None', ''], ['1', 'BankOne'], ['2', 'BankTwoStale'], ['3', 'CreditOne'], ['4', 'CreditTwo'], ['6', 'DisabledBank'], ['5', 'InvestmentOne']] assert acct_sel.first_selected_option.get_attribute('value') == '1' from_budget_sel = Select( body.find_element_by_id('budg_txfr_frm_from_budget')) opts = [] for o in from_budget_sel.options: opts.append([o.get_attribute('value'), o.text]) assert opts == [['None', ''], ['1', 'Periodic1'], ['2', 'Periodic2'], ['3', 'Periodic3 Inactive'], ['4', 'Standing1'], ['5', 'Standing2'], ['6', 'Standing3 Inactive'], ['7', 'Income (i)']] assert from_budget_sel.first_selected_option.get_attribute( 'value') == 'None' from_budget_sel.select_by_value('5') to_budget_sel = Select( body.find_element_by_id('budg_txfr_frm_to_budget')) opts = [] for o in from_budget_sel.options: opts.append([o.get_attribute('value'), o.text]) assert opts == [['None', ''], ['1', 'Periodic1'], ['2', 'Periodic2'], ['3', 'Periodic3 Inactive'], ['4', 'Standing1'], ['5', 'Standing2'], ['6', 'Standing3 Inactive'], ['7', 'Income (i)']] assert to_budget_sel.first_selected_option.get_attribute( 'value') == 'None' to_budget_sel.select_by_value('2') notes = selenium.find_element_by_id('budg_txfr_frm_notes') notes.clear() notes.send_keys('Budget Transfer Notes') # submit the form selenium.find_element_by_id('modalSaveButton').click() self.wait_for_jquery_done(selenium) # check that we got positive confirmation _, _, body = self.get_modal_parts(selenium) x = body.find_elements_by_tag_name('div')[0] assert 'alert-success' in x.get_attribute('class') assert x.text.strip() == 'Successfully saved Transactions 4 and 5' \ ' in database.' # dismiss the modal selenium.find_element_by_id('modalCloseButton').click() self.wait_for_load_complete(selenium) self.wait_for_id(selenium, 'table-standing-budgets') # test that updated budget was removed from the page stable = selenium.find_element_by_id('table-standing-budgets') stexts = self.tbody2textlist(stable) assert stexts[1] == ['yes', 'Standing2 (5)', '$9,358.84'] ptable = selenium.find_element_by_id('table-periodic-budgets') ptexts = self.tbody2textlist(ptable) assert ptexts[2] == ['yes', 'Periodic2 (2)', '$234.00']
class Transaction(Base, ModelAsDict): __tablename__ = 'transactions' __table_args__ = ({'mysql_engine': 'InnoDB'}) #: Primary Key id = Column(Integer, primary_key=True) #: date of the transaction date = Column(Date, default=dtnow().date()) #: Actual amount of the transaction actual_amount = Column(Numeric(precision=10, scale=4), nullable=False) #: Budgeted amount of the transaction budgeted_amount = Column(Numeric(precision=10, scale=4)) #: description description = Column(String(254), nullable=False, index=True) #: free-form notes notes = Column(String(254)) #: ID of the account this transaction is against account_id = Column(Integer, ForeignKey('accounts.id')) #: Relationship - :py:class:`~.Account` this transaction is against account = relationship("Account", backref="transactions", uselist=False) #: ID of the ScheduledTransaction this Transaction was created from; #: set when a scheduled transaction is converted to a real one scheduled_trans_id = Column(Integer, ForeignKey('scheduled_transactions.id')) #: Relationship - the :py:class:`~.ScheduledTransaction` #: this Transaction was created from; set when a scheduled transaction #: is converted to a real one scheduled_trans = relationship("ScheduledTransaction", backref="transactions", uselist=False) #: ID of the Budget this transaction is against budget_id = Column(Integer, ForeignKey('budgets.id')) #: Relationship - the :py:class:`~.Budget` this transaction is against budget = relationship("Budget", backref="transactions", uselist=False) #: If the transaction is one half of a transfer, the Transaction ID of the #: other half/side of the transfer. transfer_id = Column(Integer, ForeignKey('transactions.id')) #: Relationship - the :py:class:`~.Transaction` that makes up the other #: half/side of a transfer, if this transaction was for a transfer. transfer = relationship("Transaction", remote_side=[id], post_update=True, uselist=False) def __repr__(self): return "<Transaction(id=%s)>" % (self.id) @staticmethod def unreconciled(db): """ Return a query to match all unreconciled Transactions. :param db: active database session to use for queries :type db: sqlalchemy.orm.session.Session :return: query to match all unreconciled Transactions :rtype: sqlalchemy.orm.query.Query """ return db.query(Transaction).filter( Transaction.reconcile.__eq__(null()), Transaction.date.__ge__(RECONCILE_BEGIN_DATE), Transaction.account.has(reconcile_trans=True))
def get_page(self, base_url, selenium): self.baseurl = base_url self.dt = dtnow() self.get(selenium, base_url + '/scheduled')