Merge branch 'master' into refactor-change-password

This commit is contained in:
Moriz Wahl 2021-07-01 13:23:13 +02:00
commit 5a3138875a
13 changed files with 228 additions and 98 deletions

View File

@ -206,7 +206,7 @@ jobs:
report_name: Coverage Frontend
type: lcov
result_path: ./coverage/lcov.info
min_coverage: 33
min_coverage: 35
token: ${{ github.token }}
##############################################################################

View File

@ -333,16 +333,27 @@ class AppRequestsController extends AppController
$this->addAdminError('StateBalancesController', 'overview', $gdtEntries, $user['id'] ? $user['id'] : 0);
}
$limit = $count;
$offset = 0;
if($page == 1) {
$limit--;
} else {
$offset = (( $page - 1 ) * $count) - 1;
}
$stateUserTransactionsQuery = $stateUserTransactionsTable
->find()
->where(['state_user_id' => $user['id']])
->order(['balance_date' => $orderDirection])
->contain([])
->limit($count)
->page($page)
->limit($limit)
//->page($page)
->offset($offset)
;
$decay = true;
if($page > 1) {
$decay = false;
}
$transactions = [];
$transactions_from_db = $stateUserTransactionsQuery->toArray();

View File

@ -98,7 +98,12 @@ class StateBalancesTable extends AppTable
// if start date for decay is after enddate, we also just return input
if($decayStartDate === null || $decayStartDate >= $endDate) {
if($withInterval) {
return ['balance' => $startBalance, 'interval' => new \DateInterval('PT0S')];
return [
'balance' => $startBalance,
'interval' => new \DateInterval('PT0S'),
'start_date' => $startDate->getTimestamp(),
'end_date' => $startDate->getTimestamp()
];
} else {
return $startBalance;
}
@ -118,7 +123,12 @@ class StateBalancesTable extends AppTable
}
$decay = $state_balance->partDecay($endDate);
if($withInterval) {
return ['balance' => $decay, 'interval' => $interval];
return [
'balance' => $decay,
'interval' => $interval,
'start_date' => $state_balance->record_date->getTimestamp(),
'end_date' => $endDate->getTimestamp()
];
} else {
return $decay;
}

View File

@ -185,18 +185,20 @@ class TransactionsTable extends Table
if($i > 0 ) {
$prev = $stateUserTransactions[$i-1];
}
if($prev && $decay == true)
if($prev)
{
if($prev->balance > 0) {
$current = $su_transaction;
$calculated_decay = $stateBalancesTable->calculateDecay($prev->balance, $prev->balance_date, $current->balance_date, true);
$balance = floatval($prev->balance - $calculated_decay['balance']);
if($balance > 100)
if($balance)
{
$final_transactions['decay'] = [
$final_transaction['decay'] = [
'balance' => $balance,
'decay_duration' => $calculated_decay['interval']->format('%a days, %H hours, %I minutes, %S seconds')
'decay_duration' => $calculated_decay['interval']->format('%a days, %H hours, %I minutes, %S seconds'),
'decay_start' => $calculated_decay['start_date'],
'decay_end' => $calculated_decay['end_date']
];
}
}
@ -250,21 +252,24 @@ class TransactionsTable extends Table
$final_transactions[] = $final_transaction;
if($i == $stateUserTransactionsCount-1 && $decay == true) {
if($i == $stateUserTransactionsCount-1 && $decay) {
$now = new FrozenTime();
$calculated_decay = $stateBalancesTable->calculateDecay(
$su_transaction->balance,
$su_transaction->balance_date, new FrozenTime(), true);
$su_transaction->balance_date, $now, true);
$decay_start_date = $stateBalancesTable->getDecayStartDateCached();
$duration = $su_transaction->balance_date->timeAgoInWords();
if($decay_start_date > $su_transaction->balance_date) {
$duration = $decay_start_date->timeAgoInWords();
}
$balance = floatval($su_transaction->balance - $calculated_decay['balance']);
if($balance > 100) {
if($balance) {
$final_transactions[] = [
'type' => 'decay',
'balance' => $balance,
'decay_duration' => $duration,
'decay_start' => $calculated_decay['start_date'],
'decay_end' => $calculated_decay['end_date'],
'memo' => ''
];
}

View File

@ -46,12 +46,12 @@ class StateUserTransactionsFixture extends BaseTestFixture
[8, 4, 4, 2, 0, '2021-04-14 00:00:00'],
[23, 1, 5, 2, 0, '2021-04-14 09:01:07'],
[24, 4, 5, 2, 0, '2021-04-14 09:01:07'],
[25, 4, 6, 2, 0, '2021-04-14 09:02:28'],
[26, 1, 6, 2, 0, '2021-04-14 09:02:28'],
[27, 4, 7, 2, 0, '2021-04-14 09:28:46'],
[28, 1, 7, 2, 0, '2021-04-14 09:28:46'],
[29, 4, 8, 2, 0, '2021-04-14 09:31:28'],
[30, 1, 8, 2, 0, '2021-04-14 09:31:28']
[25, 4, 7, 2, 0, '2021-04-14 09:02:28'],
[26, 1, 7, 2, 0, '2021-04-14 09:02:28'],
[27, 4, 8, 2, 0, '2021-04-14 09:28:46'],
[28, 1, 8, 2, 0, '2021-04-14 09:28:46'],
[29, 4, 9, 2, 0, '2021-04-14 09:31:28'],
[30, 1, 9, 2, 0, '2021-04-14 09:31:28']
];
$this->records = $this->sqlEntrysToRecords($sql, $this->fields);
parent::init();

View File

@ -43,9 +43,9 @@ class TransactionSendCoinsFixture extends BaseTestFixture
[2, 3, '0000000000000000000000000000000000000000000000000000000000000000', 1, 'e3369de3623ce8446d0424c4013e7a1d71a2671ae3d7bf1e798ebf0665d145f2', 4, 1000000, 6254699],
[3, 4, '0000000000000000000000000000000000000000000000000000000000000000', 1, 'e3369de3623ce8446d0424c4013e7a1d71a2671ae3d7bf1e798ebf0665d145f2', 4, 100000, 7027197],
[11, 5, '0000000000000000000000000000000000000000000000000000000000000000', 1, 'e3369de3623ce8446d0424c4013e7a1d71a2671ae3d7bf1e798ebf0665d145f2', 4, 100000, 6922113],
[12, 6, '0000000000000000000000000000000000000000000000000000000000000000', 4, 'f7f4a49a4ac10379f8b9ddcb731c4d9ec495e6edd16075f52672cd25e3179f0f', 1, 100000, 9212951],
[13, 7, '0000000000000000000000000000000000000000000000000000000000000000', 4, 'f7f4a49a4ac10379f8b9ddcb731c4d9ec495e6edd16075f52672cd25e3179f0f', 1, 100000, 9112627],
[14, 8, '0000000000000000000000000000000000000000000000000000000000000000', 4, 'f7f4a49a4ac10379f8b9ddcb731c4d9ec495e6edd16075f52672cd25e3179f0f', 1, 100000, 8912594]
[12, 7, '0000000000000000000000000000000000000000000000000000000000000000', 4, 'f7f4a49a4ac10379f8b9ddcb731c4d9ec495e6edd16075f52672cd25e3179f0f', 1, 100000, 9212951],
[13, 8, '0000000000000000000000000000000000000000000000000000000000000000', 4, 'f7f4a49a4ac10379f8b9ddcb731c4d9ec495e6edd16075f52672cd25e3179f0f', 1, 100000, 9112627],
[14, 9, '0000000000000000000000000000000000000000000000000000000000000000', 4, 'f7f4a49a4ac10379f8b9ddcb731c4d9ec495e6edd16075f52672cd25e3179f0f', 1, 100000, 8912594]
];
$this->records = $this->sqlEntrysToRecords($sql, $this->fields);

View File

@ -41,9 +41,9 @@ class TransactionSignaturesFixture extends BaseTestFixture
[3, 3, 'c70f124feaaea02194d22a5f597963ed3e430343122a0952877854766fe37a709f92b39510de2aae494ef11abe743cd59f08f971b1e0e36f4c333990453d8b0d', 'f7f4a49a4ac10379f8b9ddcb731c4d9ec495e6edd16075f52672cd25e3179f0f'],
[4, 4, 'a65b39e51ab6191c51d5629bbcefd30f85f801efbb14e1c635c519e97abe217a248820fa1fc6aef56227c9d888c1919bc92471d5d7ae3522c9c50fba9f0d8402', 'f7f4a49a4ac10379f8b9ddcb731c4d9ec495e6edd16075f52672cd25e3179f0f'],
[5, 5, 'a65b39e51ab6191c51d5629bbcefd30f85f801efbb14e1c635c519e97abe217a248820fa1fc6aef56227c9d888c1919bc92471d5d7ae3522c9c50fba9f0d8402', 'f7f4a49a4ac10379f8b9ddcb731c4d9ec495e6edd16075f52672cd25e3179f0f'],
[6, 6, 'c233726674bff9bfb8ccb98bf358c6bc701825d971ece915d3c3a3de98886d1d13ee2f773cd9fc4ccbe543ac17be0d780ebead23a0dbf4ec814f7bae2efb9c0e', 'e3369de3623ce8446d0424c4013e7a1d71a2671ae3d7bf1e798ebf0665d145f2'],
[7, 7, '83ab780535883ec53ee76d0f68db0e1596418c9e100c806a4d4655d4dedf589d54a6319a2795dabab301e212b52f0dafb2725b7583447f19e47cb417d188a107', 'e3369de3623ce8446d0424c4013e7a1d71a2671ae3d7bf1e798ebf0665d145f2'],
[8, 8, '83ab780535883ec53ee76d0f68db0e1596418c9e100c806a4d4655d4dedf589d54a6319a2795dabab301e212b52f0dafb2725b7583447f19e47cb417d188a107', 'e3369de3623ce8446d0424c4013e7a1d71a2671ae3d7bf1e798ebf0665d145f2']
[6, 7, 'c233726674bff9bfb8ccb98bf358c6bc701825d971ece915d3c3a3de98886d1d13ee2f773cd9fc4ccbe543ac17be0d780ebead23a0dbf4ec814f7bae2efb9c0e', 'e3369de3623ce8446d0424c4013e7a1d71a2671ae3d7bf1e798ebf0665d145f2'],
[7, 8, '83ab780535883ec53ee76d0f68db0e1596418c9e100c806a4d4655d4dedf589d54a6319a2795dabab301e212b52f0dafb2725b7583447f19e47cb417d188a107', 'e3369de3623ce8446d0424c4013e7a1d71a2671ae3d7bf1e798ebf0665d145f2'],
[8, 9, '83ab780535883ec53ee76d0f68db0e1596418c9e100c806a4d4655d4dedf589d54a6319a2795dabab301e212b52f0dafb2725b7583447f19e47cb417d188a107', 'e3369de3623ce8446d0424c4013e7a1d71a2671ae3d7bf1e798ebf0665d145f2']
];
$this->records = $this->sqlEntrysToRecords($sql, $this->fields);
parent::init();

View File

@ -44,9 +44,10 @@ class TransactionsFixture extends BaseTestFixture
[3, NULL, 2, '4e2235f208edaf5cbb285955732022a625cf1e100eb629c56896d2fbfb8b34e800000000000000000000000000000000', 'test', '2021-04-12 00:00:00', 1],
[4, NULL, 2, 'fc6e69696beb7c56ad7c511fc3999f954411427bec810184b70c092911deae1900000000000000000000000000000000', 'test time', '2021-04-14 00:00:00', 1],
[5, NULL, 2, 'a7149ebc0d6cd8c061906dafe05e13689b51642a41100d0ec7bb6cd2dcafdc1800000000000000000000000000000000', 'test time', '2021-04-14 09:01:07', 1],
[6, NULL, 2, '2e3c3ab3e42c06f2ecb12f61c970712467d8ad9ddfa16fa58dd76492e5924b7d00000000000000000000000000000000', 'test time 3', '2021-04-14 09:02:28', 1],
[7, NULL, 2, 'c2c6354d77ff371daeee25fce9c947748b53d3d6b8398a92bd681923cfd2057100000000000000000000000000000000', 'test login crash', '2021-04-14 09:28:46', 1],
[8, NULL, 2, '5a8cbf1aaac06b00b2951ff39983cb2ca9a1e6710d72c8e5067278dc679a823100000000000000000000000000000000', 'test login crash', '2021-04-14 09:31:28', 1]
[6, NULL, 9, '', '', '2021-04-14 09:02:00', 1],
[7, NULL, 2, '2e3c3ab3e42c06f2ecb12f61c970712467d8ad9ddfa16fa58dd76492e5924b7d00000000000000000000000000000000', 'test time 3', '2021-04-14 09:02:28', 1],
[8, NULL, 2, 'c2c6354d77ff371daeee25fce9c947748b53d3d6b8398a92bd681923cfd2057100000000000000000000000000000000', 'test login crash', '2021-04-14 09:28:46', 1],
[9, NULL, 2, '5a8cbf1aaac06b00b2951ff39983cb2ca9a1e6710d72c8e5067278dc679a823100000000000000000000000000000000', 'test login crash', '2021-04-14 09:31:28', 1]
];
$this->records = $this->sqlEntrysToRecords($sql, $this->fields);
parent::init();

View File

@ -57,8 +57,8 @@ class AppRequestControllerTest extends TestCase
$response = $this->getAndParseWithoutCompare('/api/get-balance/' . $session_id);
$this->assertEquals('success', $response->state);
$this->assertEquals(9100000, $response->balance);
$this->assertLessThan(9100000, $response->decay);
$this->assertEquals(9099652, $response->balance);
$this->assertLessThan(9099652, $response->decay);
}
@ -94,8 +94,8 @@ class AppRequestControllerTest extends TestCase
$response = $this->getAndParseWithoutCompare('/api/get-balance/' . $session_id);
$this->assertEquals('success', $response->state);
$this->assertEquals(10900000, $response->balance);
$this->assertLessThan(10900000, $response->decay);
$this->assertEquals(10899568, $response->balance);
$this->assertLessThan(10899568, $response->decay);
}
public function testGetBalanceInvalidSession()
@ -202,19 +202,15 @@ class AppRequestControllerTest extends TestCase
"email": "test3.yahoo.com"
},
{
"transaction_id": 6,
"transaction_id": 7,
"date": "2021-04-14T09:02:28+00:00",
"memo": "test time 3",
"balance": 100000,
"type": "receive",
"pubkey": "0000000000000000000000000000000000000000000000000000000000000000",
"name": "Samuel Schmied",
"email": "test3.yahoo.com"
},
{
"transaction_id": 7,
"date": "2021-04-14T09:28:46+00:00",
"memo": "test login crash",
"decay": {
"balance": 6,
"decay_duration": "0 days, 00 hours, 00 minutes, 28 seconds",
"decay_start": 1618390920,
"decay_end": 1618390948
},
"balance": 100000,
"type": "receive",
"pubkey": "0000000000000000000000000000000000000000000000000000000000000000",
@ -223,22 +219,52 @@ class AppRequestControllerTest extends TestCase
},
{
"transaction_id": 8,
"date": "2021-04-14T09:31:28+00:00",
"date": "2021-04-14T09:28:46+00:00",
"memo": "test login crash",
"decay": {
"balance": 309,
"decay_duration": "0 days, 00 hours, 26 minutes, 18 seconds",
"decay_start": 1618390948,
"decay_end": 1618392526
},
"balance": 100000,
"type": "receive",
"pubkey": "0000000000000000000000000000000000000000000000000000000000000000",
"name": "Samuel Schmied",
"email": "test3.yahoo.com"
},
{
"transaction_id": 9,
"date": "2021-04-14T09:31:28+00:00",
"memo": "test login crash",
"decay": {
"balance": 33,
"decay_duration": "0 days, 00 hours, 02 minutes, 42 seconds",
"decay_start": 1618392526,
"decay_end": 1618392688
},
"balance": 100000,
"type": "receive",
"pubkey": "0000000000000000000000000000000000000000000000000000000000000000",
"name": "Samuel Schmied",
"email": "test3.yahoo.com"
},
{
"type": "decay",
"balance": 1222493,
"decay_duration": "on 14.04.21",
"decay_start": 1618392688,
"decay_end": 1624956464,
"memo": ""
}
],
"transactionExecutingCount": 0,
"count": 7,
"gdtSum": 180000,
"timeUsed": 0.7237420082092285,
"decay_date": "2021-06-22T08:54:43+00:00",
"balance": 9100000,
"decay": 9100000
"timeUsed": 0.6441609859466553,
"decay_date": "2021-06-29T08:47:44+00:00",
"balance": 9099652,
"decay": 7877159
}';
$this->getAndParse('/api/list-transactions/', json_decode($expectedResult, true));
}
@ -276,6 +302,19 @@ class AppRequestControllerTest extends TestCase
$expected[$field] = $json->$field;
}
}
// decay balance variy always
if(isset($expected['transactions'])) {
$dynamic_transaction_fields = ['decay_duration', 'balance', 'decay_end'];
foreach($expected['transactions'] as $i => $transaction) {
if(isset($transaction['type']) && $transaction['type'] == 'decay') {
foreach($dynamic_transaction_fields as $field) {
if(isset($transaction[$field])) {
$expected['transactions'][$i][$field] = $json->transactions[$i][$field];
}
}
}
}
}
$expected = json_encode($expected);
}

View File

@ -63,6 +63,8 @@ Assuming: session is valid
"type": "decay",
"balance": "14.74",
"decay_duration": "4 days, 2 hours ago",
"decay_start": 1618390948,
"decay_end": 1618392526,
"memo": ""
},
{
@ -73,7 +75,13 @@ Assuming: session is valid
"date": "2021-02-19T13:25:36+00:00",
"balance": 192.0,
"memo": "a piece of cake :)",
"pubkey": "038a6f93270dc57b91d76bf110ad3863fcb7d1b08e7692e793fcdb4467e5b6a7"
"pubkey": "038a6f93270dc57b91d76bf110ad3863fcb7d1b08e7692e793fcdb4467e5b6a7",
"decay": {
"balance": 309,
"decay_duration": "0 days, 00 hours, 26 minutes, 18 seconds",
"decay_start": 1618390948,
"decay_end": 1618392526
},
},
{
"name": "Gradido Akademie",

View File

@ -1,6 +1,6 @@
import { mutations, actions } from './store'
const { language, email, sessionId } = mutations
const { language, email, sessionId, username, firstName, lastName, description } = mutations
const { login, logout } = actions
describe('Vuex store', () => {
@ -28,51 +28,102 @@ describe('Vuex store', () => {
expect(state.sessionId).toEqual('1234')
})
})
describe('username', () => {
it('sets the state of username', () => {
const state = { username: null }
username(state, 'user')
expect(state.username).toEqual('user')
})
})
describe('firstName', () => {
it('sets the state of firstName', () => {
const state = { firstName: null }
firstName(state, 'Peter')
expect(state.firstName).toEqual('Peter')
})
})
describe('lastName', () => {
it('sets the state of lastName', () => {
const state = { lastName: null }
lastName(state, 'Lustig')
expect(state.lastName).toEqual('Lustig')
})
})
describe('description', () => {
it('sets the state of description', () => {
const state = { description: null }
description(state, 'Nickelbrille')
expect(state.description).toEqual('Nickelbrille')
})
})
})
describe('actions', () => {
describe('login', () => {
const commit = jest.fn()
const state = {}
const commitedData = {
sessionId: 1234,
user: {
email: 'someone@there.is',
language: 'en',
username: 'user',
first_name: 'Peter',
last_name: 'Lustig',
description: 'Nickelbrille',
},
}
it('calls three commits', () => {
login(
{ commit, state },
{ sessionId: 1234, user: { email: 'someone@there.is', language: 'en' } },
)
it('calls seven commits', () => {
login({ commit, state }, commitedData)
expect(commit).toHaveBeenCalledTimes(7)
})
it('commits sessionId', () => {
login(
{ commit, state },
{ sessionId: 1234, user: { email: 'someone@there.is', language: 'en' } },
)
login({ commit, state }, commitedData)
expect(commit).toHaveBeenNthCalledWith(1, 'sessionId', 1234)
})
it('commits email', () => {
login(
{ commit, state },
{ sessionId: 1234, user: { email: 'someone@there.is', language: 'en' } },
)
login({ commit, state }, commitedData)
expect(commit).toHaveBeenNthCalledWith(2, 'email', 'someone@there.is')
})
it('commits language', () => {
login(
{ commit, state },
{ sessionId: 1234, user: { email: 'someone@there.is', language: 'en' } },
)
login({ commit, state }, commitedData)
expect(commit).toHaveBeenNthCalledWith(3, 'language', 'en')
})
it('commits username', () => {
login({ commit, state }, commitedData)
expect(commit).toHaveBeenNthCalledWith(4, 'username', 'user')
})
it('commits firstName', () => {
login({ commit, state }, commitedData)
expect(commit).toHaveBeenNthCalledWith(5, 'firstName', 'Peter')
})
it('commits lastName', () => {
login({ commit, state }, commitedData)
expect(commit).toHaveBeenNthCalledWith(6, 'lastName', 'Lustig')
})
it('commits description', () => {
login({ commit, state }, commitedData)
expect(commit).toHaveBeenNthCalledWith(7, 'description', 'Nickelbrille')
})
})
describe('logout', () => {
const commit = jest.fn()
const state = {}
it('calls two commits', () => {
it('calls six commits', () => {
logout({ commit, state })
expect(commit).toHaveBeenCalledTimes(6)
})
@ -87,11 +138,36 @@ describe('Vuex store', () => {
expect(commit).toHaveBeenNthCalledWith(2, 'email', null)
})
// how can I get this working?
it.skip('calls sessionStorage.clear()', () => {
it('commits username', () => {
logout({ commit, state })
const spy = jest.spyOn(sessionStorage, 'clear')
expect(spy).toHaveBeenCalledTimes(1)
expect(commit).toHaveBeenNthCalledWith(3, 'username', '')
})
it('commits firstName', () => {
logout({ commit, state })
expect(commit).toHaveBeenNthCalledWith(4, 'firstName', '')
})
it('commits lastName', () => {
logout({ commit, state })
expect(commit).toHaveBeenNthCalledWith(5, 'lastName', '')
})
it('commits description', () => {
logout({ commit, state })
expect(commit).toHaveBeenNthCalledWith(6, 'description', '')
})
// how to get this working?
it.skip('calls sessionStorage.clear()', () => {
const clearStorageMock = jest.fn()
global.sessionStorage = jest.fn(() => {
return {
clear: clearStorageMock,
}
})
logout({ commit, state })
expect(clearStorageMock).toBeCalled()
})
})
})

View File

@ -83,7 +83,7 @@ describe('ForgotPassword', () => {
})
it('displays an error', () => {
expect(form.find('#reset-pwd--live-feedback').text()).toEqual(
expect(form.find('div.invalid-feedback').text()).toEqual(
'The Email field must be a valid email',
)
})
@ -96,8 +96,7 @@ describe('ForgotPassword', () => {
describe('valid Email', () => {
beforeEach(async () => {
await form.find('input').setValue('user@example.org')
form.trigger('submit')
await wrapper.vm.$nextTick()
await form.trigger('submit')
await flushPromises()
})

View File

@ -19,27 +19,7 @@
<b-card-body class="p-4">
<validation-observer ref="observer" v-slot="{ handleSubmit }">
<b-form role="form" @submit.prevent="handleSubmit(onSubmit)">
<validation-provider
name="Email"
:rules="{ required: true, email: true }"
v-slot="validationContext"
>
<b-form-group class="mb-3" label="Email" label-for="input-reset-pwd">
<b-form-input
id="input-reset-pwd"
name="input-reset-pwd"
v-model="form.email"
placeholder="Email"
:state="getValidationState(validationContext)"
aria-describedby="reset-pwd--live-feedback"
></b-form-input>
<b-form-invalid-feedback id="reset-pwd--live-feedback">
{{ validationContext.errors[0] }}
</b-form-invalid-feedback>
</b-form-group>
</validation-provider>
<input-email v-model="form.email"></input-email>
<div class="text-center">
<b-button type="submit" variant="primary">
{{ $t('site.password.reset_now') }}
@ -59,9 +39,13 @@
</template>
<script>
import loginAPI from '../../apis/loginAPI.js'
import InputEmail from '../../components/Inputs/InputEmail'
export default {
name: 'password',
components: {
InputEmail,
},
data() {
return {
disable: 'disabled',
@ -71,9 +55,6 @@ export default {
}
},
methods: {
getValidationState({ dirty, validated, valid = null }) {
return dirty || validated ? valid : null
},
async onSubmit() {
await loginAPI.sendEmail(this.form.email)
// always give success to avoid email spying