Compare commits

...

21 Commits

Author SHA1 Message Date
raucao 1b78cb4cb4 2.2.1 2024-03-21 12:26:21 +01:00
Râu Cao b32f805cbd Merge pull request #223 from 67P/bugfix/220-reimbursement_sums
Reimbursement form fixes and improvements
2024-03-21 11:38:45 +01:00
raucao 3110fd347e Remove unused variable 2024-03-20 18:31:16 +01:00
raucao 5612ac4e95 Add button type 2024-03-20 18:28:13 +01:00
raucao 69ab4913aa Require connected account for adding reimbursement
Just in the UI, so nothing gets reloaded by accident later
2024-03-20 18:18:10 +01:00
raucao 39e01e4558 Remove commented code 2024-03-20 17:46:26 +01:00
raucao 7afc75dbff Fix wrong BTC sum when adding multiple line items
closes #220
2024-03-20 17:24:37 +01:00
raucao f5f74ae27f Automatically select connected user/contributor as recipient 2024-03-20 17:24:07 +01:00
raucao 55f7baecf6 Update caniuse 2024-03-20 17:21:21 +01:00
raucao bd199fcf26 2.2.0 2024-03-20 15:17:01 +01:00
Râu Cao 0777c213ba Merge pull request #222 from 67P/feature/reimbursement-lists
Improve reimbursement lists
2024-03-20 14:50:33 +01:00
raucao 071922d979 Remove obsolete debug log 2024-03-20 14:35:01 +01:00
raucao fc044df9fd Add correct role to interactive element
Co-authored-by: Garret Alfert <alfert@wevelop.de>
2024-03-20 14:32:37 +01:00
raucao dd2bdd5332 Show dates in collapsed entries of confirmed reimbursements 2024-03-14 19:15:10 +01:00
raucao 0cd05d14bc Don't fail linting for click handlers on arbitrary HTML elements 2024-03-14 17:55:46 +01:00
raucao 3ee140723c Hide line items by default for confirmed reimbursements 2024-03-14 17:49:12 +01:00
raucao 49b3825af4 Show confirmation block for confirmed reimbursements 2024-03-14 17:48:23 +01:00
raucao af309ff682 Hide veto button for confirmed reimbursements 2024-03-14 16:43:57 +01:00
raucao 53f13e4a63 Move reimbursement items to separate component 2024-03-14 16:43:57 +01:00
raucao bcdd033f34 Use prod budget endpoints in dev by default 2024-03-14 16:43:29 +01:00
raucao b9e7737589 Fix typo 2024-03-14 16:43:21 +01:00
22 changed files with 326 additions and 164 deletions
@@ -27,6 +27,10 @@ export default class AddReimbursementComponent extends Component {
this.exchangeRates.fetchRates();
}
get contributorId () {
return this.recipientId || this.kredits.currentUser?.id;
}
get isValidTotal () {
return isValidAmount(this.total);
}
@@ -70,7 +74,7 @@ export default class AddReimbursementComponent extends Component {
}
updateTotalAmountFromFiat() {
let btcAmount = parseFloat(this.total);
let btcAmount = 0;
if (this.exchangeRates.btceur > 0 && this.totalEUR > 0) {
btcAmount += (this.totalEUR / this.exchangeRates.btceur);
@@ -104,7 +108,7 @@ export default class AddReimbursementComponent extends Component {
@action
updateContributor (event) {
this.recipientId = event.target.value;
this.recipientId = parseInt(event.target.value);
}
@action
@@ -136,12 +140,12 @@ export default class AddReimbursementComponent extends Component {
if (!this.kredits.currentUser) { window.alert('You need to connect your RSK account first.'); return false }
if (!this.kredits.currentUserIsCore) { window.alert('Only core contributors can submit reimbursements.'); return false }
const contributor = this.contributors.findBy('id', parseInt(this.recipientId));
const contributor = this.contributors.findBy('id', this.contributorId);
const attributes = {
amount: parseInt(parseFloat(this.total) * 100000000), // convert to sats
token: config.tokens['BTC'],
recipientId: parseInt(this.recipientId),
recipientId: this.contributorId,
title: `Expenses covered by ${contributor.name}`,
description: this.description,
url: this.url,
@@ -2,8 +2,7 @@
<label>
<p class="label">Contributor:</p>
<p>
<select required {{on "change" this.updateContributor}}>
<option value="" selected disabled hidden></option>
<select id="contributor" required {{on "change" this.updateContributor}}>
{{#each this.contributors as |contributor|}}
<option value={{contributor.id}} selected={{eq this.contributorId contributor.id}}>{{contributor.name}}</option>
{{/each}}
@@ -15,6 +14,7 @@
<p class="label">Total amount (BTC):</p>
<p>
<Input @type="text"
@name="total-btc"
@placeholder="0.0015"
@value={{this.total}}
@required={{true}}
@@ -50,7 +50,9 @@
<p class="actions">
<button {{on "click" this.showExpenseForm}}
class="green small" type="button">+ Add another item</button>
id="add-another-item" class="green small" type="button">
+ Add another item
</button>
</p>
{{else}}
<p>No line items yet.</p>
+4 -2
View File
@@ -1,3 +1,5 @@
{{#unless this.isConfirmed}}
{{#if this.isConfirmed}}
Confirmed at block <strong>{{@confirmedAtBlock}}</strong> (~ {{this.confirmedInHumanTime}} ago)
{{else}}
Confirming in <strong>{{this.confirmedInBlocks}}</strong> blocks (~ {{this.confirmedInHumanTime}})
{{/unless}}
{{/if}}
@@ -0,0 +1,68 @@
import Component from '@glimmer/component';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';
import { inject as service } from '@ember/service';
import config from 'kredits-web/config/environment';
import fmtDateLocalized from 'kredits-web/helpers/fmt-date-localized';
export default class ReimbursementItemComponent extends Component {
@service kredits;
@tracked showExpenseDetails = false;
constructor(owner, args) {
super(owner, args);
if (this.isUnconfirmed && !this.isVetoed) {
this.showExpenseDetails = true;
}
}
get ipfsGatewayUrl () {
return config.ipfs.gatewayUrl;
}
get isConfirmed () {
return (this.args.reimbursement.confirmedAt - this.kredits.currentBlock) <= 0;
}
get isUnconfirmed () {
return !this.isConfirmed;
}
get isVetoed () {
return this.args.reimbursement.vetoed;
}
get showVetoButton () {
return this.isUnconfirmed && this.kredits.currentUserIsCore;
}
get showConfirmedIn () {
return !this.isVetoed &&
(this.showExpenseDetails || this.isUnconfirmed);
}
get expenses () {
return this.args.reimbursement.expenses;
}
get expensesDateRange () {
const dates = this.expenses.map(e => e.date).uniq().sort();
let out = fmtDateLocalized.compute(dates.firstObject)
if (dates.length > 1) {
out += ' - ' + fmtDateLocalized.compute(dates.lastObject)
}
return out;
}
@action
toggleExpenseDetails () {
this.showExpenseDetails = !this.showExpenseDetails;
}
@action
veto (id) {
this.kredits.vetoReimbursement(id).then(transaction => {
console.debug('[controllers:budget] Veto submitted to chain: '+transaction.hash);
});
}
}
@@ -0,0 +1,41 @@
<li data-reimbursement-id={{@reimbursement.id}}
class="{{item-status @reimbursement}}"
role="button" {{on "click" this.toggleExpenseDetails}}>
<p class="meta">
<span class="recipient">
<UserAvatar @contributor={{@reimbursement.contributor}} />
</span>
<span class="title">
Expenses covered by {{@reimbursement.contributor.name}}
</span>
</p>
<p class="token-amount">
<span class="amount">
{{sats-to-btc @reimbursement.amount}}</span>&#8239;<span class="symbol">BTC</span>
</p>
{{#if this.showExpenseDetails}}
<ExpenseList @expenses={{@reimbursement.expenses}} />
{{/if}}
<div class="meta">
<p>
{{#if this.showConfirmedIn}}
<ConfirmedIn @confirmedAtBlock={{@reimbursement.confirmedAt}} />
{{else}}
{{#unless this.isVetoed}}{{this.expensesDateRange}}{{/unless}}
{{/if}}
</p>
<p class="actions">
<a href="{{this.ipfsGatewayUrl}}/{{@reimbursement.ipfsHash}}"
class="button small" target="_blank" rel="noopener noreferrer">
Inspect IPFS data
</a>
{{#if this.showVetoButton}}
<button {{on "click" (fn this.veto @reimbursement.id)}}
disabled={{@reimbursement.vetoed}}
class="button small danger" type="button">veto</button>
{{/if}}
</p>
</div>
</li>
@@ -1,23 +1,10 @@
import Component from '@glimmer/component';
import { sort } from '@ember/object/computed';
import { action } from '@ember/object';
import { inject as service } from '@ember/service';
import config from 'kredits-web/config/environment';
export default class ReimbursementListComponent extends Component {
@service kredits;
itemSorting = Object.freeze(['pendingStatus:asc', 'id:desc']);
@sort('args.items', 'itemSorting') itemsSorted;
get ipfsGatewayUrl () {
return config.ipfs.gatewayUrl;
}
@action
veto (id) {
this.kredits.vetoReimbursement(id).then(transaction => {
console.debug('[controllers:budget] Veto submitted to chain: '+transaction.hash);
});
}
}
+3 -36
View File
@@ -1,38 +1,5 @@
<ul class="item-list spaced reimbursement-list {{if @loading 'loading'}}">
{{#each this.itemsSorted as |reimbursement|}}
<li data-reimbursement-id={{reimbursement.id}}
class="{{item-status reimbursement}}">
<p class="meta">
<span class="recipient">
<UserAvatar @contributor={{reimbursement.contributor}} />
</span>
<span class="title">
Expenses covered by {{reimbursement.contributor.name}}
</span>
</p>
<p class="token-amount">
<span class="amount">
{{sats-to-btc reimbursement.amount}}</span>&#8239;<span class="symbol">BTC</span>
</p>
<ExpenseList @expenses={{reimbursement.expenses}} />
<div class="meta">
<p class="confirmation-eta">
<ConfirmedIn @confirmedAtBlock={{reimbursement.confirmedAt}} />
</p>
<p class="actions">
<a href="{{this.ipfsGatewayUrl}}/{{reimbursement.ipfsHash}}"
class="button small" target="_blank" rel="noopener noreferrer">
Inspect IPFS data
</a>
{{#if this.kredits.currentUserIsCore}}
<button {{on "click" (fn this.veto reimbursement.id)}}
disabled={{reimbursement.vetoed}}
class="button small danger" type="button">veto</button>
{{/if}}
</p>
</div>
</li>
<ul class="item-list collapsible spaced reimbursement-list {{if @loading 'loading'}}">
{{#each this.itemsSorted as |item|}}
<ReimbursementItem @reimbursement={{item}} />
{{/each}}
</ul>
+16
View File
@@ -1,10 +1,26 @@
import Controller from '@ember/controller';
import { inject as service } from '@ember/service';
import { alias } from '@ember/object/computed';
import { action } from '@ember/object';
export default class BudgetController extends Controller {
@service kredits;
@service router;
@alias('kredits.reimbursementsUnconfirmed') reimbursementsUnconfirmed;
@alias('kredits.reimbursementsConfirmed') reimbursementsConfirmed;
@alias('kredits.currentUserIsCore') currentUserIsCore;
@action
addReimbursement () {
if (!this.kredits.currentUser) {
window.alert('You need to connect your RSK account first.');
return false;
}
if (!this.kredits.currentUserIsCore) {
window.alert('Only core contributors can submit reimbursements.');
return false;
}
this.router.transitionTo('reimbursements.new');
}
}
+1 -1
View File
@@ -1,7 +1,7 @@
import { helper } from '@ember/component/helper';
import getLocale from 'kredits-web/utils/get-locale';
export default helper(function(dateStr) {
export default helper(function fmtDateLocalized(dateStr) {
const date = new Date(dateStr);
const locale = getLocale();
return new Intl.DateTimeFormat(locale).format(date);
+1 -1
View File
@@ -29,7 +29,7 @@ export default Service.extend({
browserCache: service(),
currentBlock: null,
currentUserAccounts: null, // default to not having an account. this is the wen web3 is loaded.
currentUserAccounts: null, // default to not having an account. this is the when web3 is loaded.
currentUser: null,
contributors: null,
contributions: null,
+10
View File
@@ -16,6 +16,16 @@ ul.item-list {
}
}
&.collapsible {
> li {
border-left: 1px solid transparent;
&:hover {
border-left: 1px solid $blue;
}
}
}
&.loading {
@include loading-border-top;
@@ -43,9 +43,6 @@ ul.reimbursement-list {
flex: 1;
padding: 1.6rem 0 1rem 0;
&.confirmation-eta {
}
&.actions {
text-align: right;
}
+10 -18
View File
@@ -1,22 +1,6 @@
<main id="budget">
<div id="aside">
<!-- <section id="main&#45;nav"> -->
<!-- <header> -->
<!-- <h2>Budget</h2> -->
<!-- </header> -->
<!-- <div class="content"> -->
<!-- <ul> -->
<!-- <li> -->
<!-- <LinkTo @route="budget.expenses">Expenses</LinkTo> -->
<!-- </li> -->
<!-- <li> -->
<!-- <a href="#">Rewards</a> -->
<!-- </li> -->
<!-- </ul> -->
<!-- </div> -->
<!-- </section> -->
<section id="funds">
<header>
<h2>Community funds</h2>
@@ -33,7 +17,11 @@
<header class="with-nav">
<h2>Proposed Reimbursements</h2>
<nav>
<LinkTo @route="reimbursements.new" @title="Submit a reimbursement" class="button small green">add</LinkTo>
<button type="button" class="button small green"
title="Submit a reimbursement"
{{on "click" this.addReimbursement}}>
add
</button>
</nav>
</header>
<div class="content">
@@ -47,7 +35,11 @@
<header class="with-nav">
<h2>Confirmed Reimbursements</h2>
<nav>
<LinkTo @route="reimbursements.new" @title="Submit a reimbursement" class="button small green">add</LinkTo>
<button type="button" class="button small green"
title="Submit a reimbursement"
{{on "click" this.addReimbursement}}>
add
</button>
</nav>
</header>
<div class="content">
+3 -2
View File
@@ -82,8 +82,9 @@ module.exports = function(environment) {
gatewayUrl: 'http://localhost:8080/ipfs'
};
ENV.communityFundsAPI.balances.onchain.url = 'http://localhost:3000/api/btcpay/onchain_btc_balance';
ENV.communityFundsAPI.balances.lightning.url = 'http://localhost:3000/api/btcpay/lightning_btc_balance';
// Uncomment if you want to use local akkounts
// ENV.communityFundsAPI.balances.onchain.url = 'http://localhost:3000/api/btcpay/onchain_btc_balance';
// ENV.communityFundsAPI.balances.lightning.url = 'http://localhost:3000/api/btcpay/lightning_btc_balance';
}
if (environment === 'test') {
+13 -6
View File
@@ -1,12 +1,12 @@
{
"name": "kredits-web",
"version": "2.1.1",
"version": "2.2.1",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "kredits-web",
"version": "2.1.1",
"version": "2.2.1",
"license": "MIT",
"devDependencies": {
"@babel/eslint-parser": "^7.19.1",
@@ -6816,7 +6816,9 @@
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001332",
"version": "1.0.30001599",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001599.tgz",
"integrity": "sha512-LRAQHZ4yT1+f9LemSMeqdMpMxZcc4RMWdj4tiFe3G8tNkWK+E58g+/tzotb5cU6TbcVJLr4fySiAW7XmxQvZQA==",
"dev": true,
"funding": [
{
@@ -6826,9 +6828,12 @@
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/caniuse-lite"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "CC-BY-4.0"
]
},
"node_modules/capture-exit": {
"version": "2.0.0",
@@ -29050,7 +29055,9 @@
}
},
"caniuse-lite": {
"version": "1.0.30001332",
"version": "1.0.30001599",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001599.tgz",
"integrity": "sha512-LRAQHZ4yT1+f9LemSMeqdMpMxZcc4RMWdj4tiFe3G8tNkWK+E58g+/tzotb5cU6TbcVJLr4fySiAW7XmxQvZQA==",
"dev": true
},
"capture-exit": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "kredits-web",
"version": "2.1.1",
"version": "2.2.1",
"private": true,
"description": "Contribution dashboard of the Kosmos project",
"repository": "https://github.com/67P/kredits-web",
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+3 -3
View File
@@ -8,10 +8,10 @@
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<meta name="kredits-web/config/environment" content="%7B%22modulePrefix%22%3A%22kredits-web%22%2C%22environment%22%3A%22production%22%2C%22rootURL%22%3A%22%2F%22%2C%22locationType%22%3A%22auto%22%2C%22EmberENV%22%3A%7B%22FEATURES%22%3A%7B%7D%2C%22EXTEND_PROTOTYPES%22%3A%7B%22Date%22%3Afalse%7D%2C%22_APPLICATION_TEMPLATE_WRAPPER%22%3Afalse%2C%22_DEFAULT_ASYNC_OBSERVERS%22%3Atrue%2C%22_JQUERY_INTEGRATION%22%3Afalse%2C%22_TEMPLATE_ONLY_GLIMMER_COMPONENTS%22%3Atrue%7D%2C%22APP%22%3A%7B%22name%22%3A%22kredits-web%22%2C%22version%22%3A%222.1.1%2B5c9fbf50%22%7D%2C%22web3ProviderUrl%22%3A%22https%3A%2F%2Frsk-testnet.kosmos.org%22%2C%22web3ChainId%22%3A31%2C%22web3NetworkName%22%3A%22RSK%20Testnet%22%2C%22githubConnectUrl%22%3A%22https%3A%2F%2Fhal8000.kosmos.chat%2Fkredits%2Fsignup%2Fconnect%2Fgithub%22%2C%22githubSignupUrl%22%3A%22https%3A%2F%2Fhal8000.kosmos.chat%2Fkredits%2Fsignup%2Fgithub%22%2C%22ipfs%22%3A%7B%22host%22%3A%22ipfs.kosmos.org%22%2C%22port%22%3A%225444%22%2C%22protocol%22%3A%22https%22%2C%22gatewayUrl%22%3A%22https%3A%2F%2Fipfs.kosmos.org%2Fipfs%22%7D%2C%22tokens%22%3A%7B%22BTC%22%3A%220x2260fac5e5542a773aa44fbcfedf7c193bc2c599%22%7D%2C%22communityFundsAPI%22%3A%7B%22balances%22%3A%7B%22onchain%22%3A%7B%22icon%22%3A%22icon-btc.png%22%2C%22symbol%22%3A%22BTC%22%2C%22description%22%3A%22BTC%20on%20chain%22%2C%22url%22%3A%22https%3A%2F%2Fapi.kosmos.org%2Fbtcpay%2Fonchain_btc_balance%22%7D%2C%22lightning%22%3A%7B%22icon%22%3A%22icon-btc-lightning.png%22%2C%22symbol%22%3A%22BTC%22%2C%22description%22%3A%22BTC%20on%20Lightning%20Network%22%2C%22url%22%3A%22https%3A%2F%2Fapi.kosmos.org%2Fbtcpay%2Flightning_btc_balance%22%7D%7D%7D%2C%22corsProxy%22%3A%22https%3A%2F%2Fcors.5apps.com%2F%3Furi%3D%22%2C%22exportApplicationGlobal%22%3Afalse%7D" />
<meta name="kredits-web/config/environment" content="%7B%22modulePrefix%22%3A%22kredits-web%22%2C%22environment%22%3A%22production%22%2C%22rootURL%22%3A%22%2F%22%2C%22locationType%22%3A%22auto%22%2C%22EmberENV%22%3A%7B%22FEATURES%22%3A%7B%7D%2C%22EXTEND_PROTOTYPES%22%3A%7B%22Date%22%3Afalse%7D%2C%22_APPLICATION_TEMPLATE_WRAPPER%22%3Afalse%2C%22_DEFAULT_ASYNC_OBSERVERS%22%3Atrue%2C%22_JQUERY_INTEGRATION%22%3Afalse%2C%22_TEMPLATE_ONLY_GLIMMER_COMPONENTS%22%3Atrue%7D%2C%22APP%22%3A%7B%22name%22%3A%22kredits-web%22%2C%22version%22%3A%222.2.1%2Bb32f805c%22%7D%2C%22web3ProviderUrl%22%3A%22https%3A%2F%2Frsk-testnet.kosmos.org%22%2C%22web3ChainId%22%3A31%2C%22web3NetworkName%22%3A%22RSK%20Testnet%22%2C%22githubConnectUrl%22%3A%22https%3A%2F%2Fhal8000.kosmos.chat%2Fkredits%2Fsignup%2Fconnect%2Fgithub%22%2C%22githubSignupUrl%22%3A%22https%3A%2F%2Fhal8000.kosmos.chat%2Fkredits%2Fsignup%2Fgithub%22%2C%22ipfs%22%3A%7B%22host%22%3A%22ipfs.kosmos.org%22%2C%22port%22%3A%225444%22%2C%22protocol%22%3A%22https%22%2C%22gatewayUrl%22%3A%22https%3A%2F%2Fipfs.kosmos.org%2Fipfs%22%7D%2C%22tokens%22%3A%7B%22BTC%22%3A%220x2260fac5e5542a773aa44fbcfedf7c193bc2c599%22%7D%2C%22communityFundsAPI%22%3A%7B%22balances%22%3A%7B%22onchain%22%3A%7B%22icon%22%3A%22icon-btc.png%22%2C%22symbol%22%3A%22BTC%22%2C%22description%22%3A%22BTC%20on%20chain%22%2C%22url%22%3A%22https%3A%2F%2Fapi.kosmos.org%2Fbtcpay%2Fonchain_btc_balance%22%7D%2C%22lightning%22%3A%7B%22icon%22%3A%22icon-btc-lightning.png%22%2C%22symbol%22%3A%22BTC%22%2C%22description%22%3A%22BTC%20on%20Lightning%20Network%22%2C%22url%22%3A%22https%3A%2F%2Fapi.kosmos.org%2Fbtcpay%2Flightning_btc_balance%22%7D%7D%7D%2C%22corsProxy%22%3A%22https%3A%2F%2Fcors.5apps.com%2F%3Furi%3D%22%2C%22exportApplicationGlobal%22%3Afalse%7D" />
<link integrity="" rel="stylesheet" href="/assets/vendor-ca96b2e19fc9f356e3dbad90c9f3f323.css">
<link integrity="" rel="stylesheet" href="/assets/kredits-web-950f3a97cf1dfead67fdfdc4f5dc1cfb.css">
<link integrity="" rel="stylesheet" href="/assets/kredits-web-1ce689f6aada92a7d79a1947300931cf.css">
@@ -25,7 +25,7 @@
<script src="/assets/vendor-4d87b3e0995c5bb18e46836a089900a4.js" integrity="sha256-5WmWY05Kd+n98Sw0GwuaWodmDVBZ2yVGGtC/2owVfQE= sha512-tiGPA5zvfhnSC9LPTmpvXJmOu30yhsdPqSiZJMPGmE/ez/xJLMaM29vjs4Cs74cDf6fX4uYSGRIu1KfOyGpJYA==" ></script>
<script src="/assets/kredits-web-5b714ebc501e0789ddba130f2a3f10e1.js" integrity="sha256-jb10J7E1WRUc8DztQgvbdsKXYRHqXTqjbap4CVh2AaM= sha512-dx+d1T+WrZs0qG1J4puW0hZEzG2Qh+d5iU3XXnkfkF8ya3lMp/L1xdfzh697Ca5x3/Gw7+j7Mb/LSPUfWuNCEQ==" ></script>
<script src="/assets/kredits-web-71e8e218f4178df50b78058520257c0d.js" integrity="sha256-pQsThEeIoXS7h22Jg3XPg+5l268k7S63rhGhhHC10o8= sha512-CV9qAyQL3jdXW4+DmTdaGFtGYZ9Lz+f4+8aUnQyK+wOeDkLpUultyhhF2P1+wHS6Hm2vj7n213Ef89YblxDgUA==" ></script>
</body>
@@ -1,13 +1,58 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import { click, fillIn, render } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
import contributors from '../../../fixtures/contributors';
module('Integration | Component | add-reimbursement', function(hooks) {
setupRenderingTest(hooks);
test('it works', async function(assert) {
hooks.beforeEach(function() {
let kredits = this.owner.lookup('service:kredits');
kredits.set('contributors', contributors);
kredits.set('currentUser', contributors.findBy('id', 3));
});
test('Contributor select menu', async function(assert) {
await render(hbs`<AddReimbursement />`);
assert.ok(true);
assert.equal(this.element.querySelectorAll('select#contributor option').length, contributors.length,
'contains correct amount of items');
assert.equal(this.element.querySelector('select#contributor option:checked').value, "3",
'preselects the connected contributor account');
});
test('Adding expense items', async function(assert) {
await render(hbs`<AddReimbursement />`);
assert.dom(this.element).includesText('New expense item');
await fillIn('form input[name="expense-amount"]', '49');
await fillIn('form input[name="expense-title"]', 'Domain kosmos.org (yearly fee)');
await click('form#add-expense-item input[type="submit"]');
assert.equal(this.element.querySelector('input[name="total-eur"]').value, '49',
'updates the total EUR amount');
assert.equal(this.element.querySelector('input[name="total-usd"]').value, '0',
'does not update the total USD amount');
assert.equal(this.element.querySelector('input[name="total-btc"]').value, '0.00534493',
'updates the total BTC amount');
assert.dom(this.element).doesNotIncludeText('New expense item');
await click('button#add-another-item');
await fillIn('form input[name="expense-amount"]', '29');
await fillIn('select[name="expense-currency"]', 'USD');
await fillIn('form input[name="expense-title"]', 'Domain kosmos.social (yearly fee)');
await click('form#add-expense-item input[type="submit"]');
assert.equal(this.element.querySelector('input[name="total-usd"]').value, '29',
'updates the total USD amount');
assert.equal(this.element.querySelector('input[name="total-eur"]').value, '49',
'does not update the total EUR amount');
assert.equal(this.element.querySelector('input[name="total-btc"]').value, '0.00804268',
'updates the total BTC amount');
});
});