WIP Add payment methods to place details
This commit is contained in:
@@ -15,6 +15,7 @@ import NostrConnect from './nostr-connect';
|
||||
import Modal from './modal';
|
||||
import PhotoCarousel from './photo-carousel';
|
||||
import PhotoGallery from './photo-gallery';
|
||||
import PlacePaymentMethods from './place-payment-methods';
|
||||
|
||||
import { tracked } from '@glimmer/tracking';
|
||||
import { action } from '@ember/object';
|
||||
@@ -467,6 +468,8 @@ export default class PlaceDetails extends Component {
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
<PlacePaymentMethods @tags={{this.tags}} />
|
||||
|
||||
<div class="meta-info">
|
||||
|
||||
{{#if this.cuisine}}
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
import Component from '@glimmer/component';
|
||||
import Icon from './icon';
|
||||
import { parsePaymentMethods } from '../utils/payment';
|
||||
import { eq } from 'ember-truth-helpers';
|
||||
|
||||
export default class PlacePaymentMethods extends Component {
|
||||
get payment() {
|
||||
return parsePaymentMethods(this.args.tags);
|
||||
}
|
||||
|
||||
get showCash() {
|
||||
return this.payment.cash !== null;
|
||||
}
|
||||
|
||||
get showCards() {
|
||||
return this.payment.cards !== null;
|
||||
}
|
||||
|
||||
get showBitcoin() {
|
||||
return this.payment.bitcoin.status !== null;
|
||||
}
|
||||
|
||||
get cashTitle() {
|
||||
return this.payment.cash === 'accepted' ? 'Cash accepted' : 'No cash';
|
||||
}
|
||||
|
||||
get cardsTitle() {
|
||||
return this.payment.cards === 'accepted' ? 'Cards accepted' : 'No cards';
|
||||
}
|
||||
|
||||
get bitcoinTitle() {
|
||||
if (this.payment.bitcoin.status === 'denied') {
|
||||
return 'No Bitcoin';
|
||||
}
|
||||
if (this.payment.bitcoin.lightning) {
|
||||
return 'Bitcoin (Lightning)';
|
||||
}
|
||||
return 'Bitcoin (On-chain)';
|
||||
}
|
||||
|
||||
<template>
|
||||
{{#if this.payment.hasPaymentInfo}}
|
||||
<div class="place-payment-methods" aria-label="Payment methods">
|
||||
{{#if this.showCash}}
|
||||
<span
|
||||
class="payment-method
|
||||
{{if (eq this.payment.cash 'denied') 'is-denied'}}"
|
||||
data-test-payment-method="cash"
|
||||
title={{this.cashTitle}}
|
||||
aria-label={{this.cashTitle}}
|
||||
>
|
||||
<Icon @name="banknote" @size={{22}} @color="currentColor" />
|
||||
</span>
|
||||
{{/if}}
|
||||
|
||||
{{#if this.showCards}}
|
||||
<span
|
||||
class="payment-method
|
||||
{{if (eq this.payment.cards 'denied') 'is-denied'}}"
|
||||
data-test-payment-method="cards"
|
||||
title={{this.cardsTitle}}
|
||||
aria-label={{this.cardsTitle}}
|
||||
>
|
||||
<Icon @name="payment-card" @size={{22}} @color="currentColor" />
|
||||
</span>
|
||||
{{/if}}
|
||||
|
||||
{{#if this.showBitcoin}}
|
||||
<span
|
||||
class="payment-method
|
||||
{{if (eq this.payment.bitcoin.status 'denied') 'is-denied'}}"
|
||||
data-test-payment-method="bitcoin"
|
||||
title={{this.bitcoinTitle}}
|
||||
aria-label={{this.bitcoinTitle}}
|
||||
>
|
||||
<Icon @name="bitcoin" @size={{22}} @color="currentColor" />
|
||||
{{#if this.payment.bitcoin.lightning}}
|
||||
<span
|
||||
class="payment-method-badge"
|
||||
data-test-payment-badge="lightning"
|
||||
title="Lightning"
|
||||
>
|
||||
<Icon @name="zap" @size={{10}} @color="#f59e0b" />
|
||||
</span>
|
||||
{{/if}}
|
||||
</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</template>
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path d="M23.638 14.904c-1.602 6.43-8.09 10.34-14.52 8.736C2.686 22.04-1.224 15.55.38 9.12 1.984 2.69 8.472-1.22 14.902.384c6.432 1.604 10.34 8.09 8.736 14.52zm-6.273-5.247c.273-1.823-.974-2.805-2.633-3.46l.538-2.158-1.313-.327-.524 2.1c-.345-.086-.7-.168-1.055-.248l.528-2.116-1.313-.328-.538 2.158c-.286-.065-.566-.13-.837-.198l.002-.008-1.812-.452-.35 1.403s.974.223.953.237c.531.133.627.485.611.764l-.612 2.453c.037.01.084.023.136.045l-.14-.035-.856 3.435c-.065.161-.23.403-.601.31.014.02-.953-.238-.953-.238l-.652 1.503 1.71.426c.318.08.63.162.937.24l-.544 2.18 1.312.328.538-2.156c.36.097.708.188 1.05.274l-.535 2.146 1.313.328.544-2.18c2.24.424 3.924.253 4.632-1.773.57-1.63-.028-2.57-1.206-3.18.857-.198 1.503-.762 1.676-1.93zm-3 4.205c-.406 1.63-3.15.75-4.04.528l.721-2.89c.89.222 3.743.662 3.32 2.362zm.407-4.237c-.37 1.484-2.658.73-3.4.545l.654-2.62c.741.185 3.13.53 2.746 2.075z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 964 B |
@@ -1175,6 +1175,57 @@ abbr[title] {
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
|
||||
.place-payment-methods {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
margin-top: 1.2rem;
|
||||
padding-top: 1.2rem;
|
||||
border-top: 1px solid var(--divider-color);
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
|
||||
.payment-method {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
|
||||
.payment-method.is-denied {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.payment-method.is-denied::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: -2px;
|
||||
right: -2px;
|
||||
height: 2px;
|
||||
background-color: var(--danger-color);
|
||||
transform: rotate(-45deg);
|
||||
pointer-events: none;
|
||||
border-radius: 1px;
|
||||
}
|
||||
|
||||
.payment-method-badge {
|
||||
position: absolute;
|
||||
bottom: -3px;
|
||||
right: -5px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: var(--primary-background-color);
|
||||
border-radius: 50%;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
box-shadow: 0 1px 2px rgb(0 0 0 / 15%);
|
||||
}
|
||||
|
||||
.btn {
|
||||
/* TODO: remove this scoped rule in favor of a global box-sizing reset
|
||||
(e.g. `*, *::before, *::after { box-sizing: border-box; }`) at the top
|
||||
|
||||
@@ -113,6 +113,7 @@ import molarTooth from '@waysidemapping/pinhead/dist/icons/molar_tooth.svg?raw';
|
||||
import needleAndSpoolOfThread from '@waysidemapping/pinhead/dist/icons/needle_and_spool_of_thread.svg?raw';
|
||||
import openBook from '@waysidemapping/pinhead/dist/icons/open_book.svg?raw';
|
||||
import palace from '@waysidemapping/pinhead/dist/icons/palace.svg?raw';
|
||||
import paymentCard from '@waysidemapping/pinhead/dist/icons/payment_card.svg?raw';
|
||||
import parkingP from '@waysidemapping/pinhead/dist/icons/p_wide.svg?raw';
|
||||
import personCricketBattingAtCricketBall from '@waysidemapping/pinhead/dist/icons/person_cricket_batting_at_cricket_ball.svg?raw';
|
||||
import personBoardingTramWithDestinationDisplayAndPantographOnTramTrack from '@waysidemapping/pinhead/dist/icons/person_boarding_tram_with_destination_display_and_pantograph_on_tram_track.svg?raw';
|
||||
@@ -148,6 +149,7 @@ import womensAndMensRestroomSymbol from '@waysidemapping/pinhead/dist/icons/wome
|
||||
/*
|
||||
* Custom/local icons
|
||||
*/
|
||||
import bitcoin from '../icons/bitcoin.svg?raw';
|
||||
import loadingRing from '../icons/270-ring.svg?raw';
|
||||
import nostrich from '../icons/nostrich-2.svg?raw';
|
||||
import remotestorage from '../icons/remotestorage.svg?raw';
|
||||
@@ -167,6 +169,7 @@ const ICONS = {
|
||||
'badge-shield-with-fire': badgeShieldWithFire,
|
||||
'beach-umbrella-in-ground': beachUmbrellaInGround,
|
||||
'beer-mug-with-foam': beerMugWithFoam,
|
||||
bitcoin,
|
||||
bookmark,
|
||||
'boxing-glove-up': boxingGloveUp,
|
||||
'burger-and-drink-cup-with-straw': burgerAndDrinkCupWithStraw,
|
||||
@@ -246,6 +249,7 @@ const ICONS = {
|
||||
nostrich,
|
||||
'open-book': openBook,
|
||||
palace,
|
||||
'payment-card': paymentCard,
|
||||
'person-cricket-batting-at-cricket-ball': personCricketBattingAtCricketBall,
|
||||
'person-boarding-tram-with-destination-display-and-pantograph-on-tram-track':
|
||||
personBoardingTramWithDestinationDisplayAndPantographOnTramTrack,
|
||||
@@ -303,7 +307,10 @@ const ICONS = {
|
||||
};
|
||||
|
||||
const FILLED_ICONS = [
|
||||
'banknote',
|
||||
'bitcoin',
|
||||
'fork-and-knife',
|
||||
'payment-card',
|
||||
'wikipedia',
|
||||
'whatsapp',
|
||||
'cup-and-saucer',
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
const CARD_KEYS = [
|
||||
'payment:cards',
|
||||
'payment:credit_cards',
|
||||
'payment:debit_cards',
|
||||
'payment:contactless',
|
||||
'payment:visa',
|
||||
'payment:mastercard',
|
||||
'payment:american_express',
|
||||
'payment:amex',
|
||||
'payment:maestro',
|
||||
'payment:girocard',
|
||||
'payment:discover_card',
|
||||
'payment:diners_club',
|
||||
'payment:jcb',
|
||||
'payment:unionpay',
|
||||
'payment:bancontact',
|
||||
'payment:postfinance_card',
|
||||
'payment:mir',
|
||||
'payment:dankort',
|
||||
'payment:interac',
|
||||
'payment:visa_debit',
|
||||
'payment:mastercard_debit',
|
||||
'payment:apple_pay',
|
||||
'payment:google_pay',
|
||||
];
|
||||
|
||||
function isYes(val) {
|
||||
return val === 'yes' || val === 'only';
|
||||
}
|
||||
|
||||
function isNo(val) {
|
||||
return val === 'no';
|
||||
}
|
||||
|
||||
export function parsePaymentMethods(tags = {}) {
|
||||
const safeTags = tags || {};
|
||||
|
||||
// 1. Cash
|
||||
let cash = null;
|
||||
const cashVal = safeTags['payment:cash'];
|
||||
const coinsVal = safeTags['payment:coins'];
|
||||
const notesVal = safeTags['payment:notes'];
|
||||
|
||||
if (
|
||||
isYes(cashVal) ||
|
||||
(!isNo(cashVal) && (isYes(coinsVal) || isYes(notesVal)))
|
||||
) {
|
||||
cash = 'accepted';
|
||||
} else if (
|
||||
isNo(cashVal) ||
|
||||
(!isYes(cashVal) && isNo(coinsVal) && isNo(notesVal))
|
||||
) {
|
||||
cash = 'denied';
|
||||
}
|
||||
|
||||
// 2. Cards
|
||||
let cards = null;
|
||||
const anyCardAccepted = CARD_KEYS.some((key) => isYes(safeTags[key]));
|
||||
|
||||
if (anyCardAccepted) {
|
||||
cards = 'accepted';
|
||||
} else {
|
||||
const cardsNo = isNo(safeTags['payment:cards']);
|
||||
const creditAndDebitNo =
|
||||
isNo(safeTags['payment:credit_cards']) &&
|
||||
isNo(safeTags['payment:debit_cards']);
|
||||
const cashOnly = safeTags['payment:cash'] === 'only';
|
||||
|
||||
if (cardsNo || creditAndDebitNo || cashOnly) {
|
||||
cards = 'denied';
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Bitcoin
|
||||
const xbtVal = safeTags['currency:XBT'];
|
||||
const lightningVal = safeTags['payment:lightning'];
|
||||
const onchainVal = safeTags['payment:onchain'];
|
||||
const btcVal = safeTags['payment:bitcoin'];
|
||||
const btcCurrencyVal = safeTags['currency:BTC'];
|
||||
|
||||
const isBtcAccepted =
|
||||
isYes(xbtVal) ||
|
||||
isYes(lightningVal) ||
|
||||
isYes(onchainVal) ||
|
||||
isYes(btcVal) ||
|
||||
isYes(btcCurrencyVal);
|
||||
|
||||
const isBtcDenied = !isBtcAccepted && (isNo(xbtVal) || isNo(btcVal));
|
||||
|
||||
const lightning = isYes(lightningVal);
|
||||
const onchain =
|
||||
isYes(onchainVal) ||
|
||||
((isYes(xbtVal) || isYes(btcVal) || isYes(btcCurrencyVal)) &&
|
||||
!isNo(onchainVal));
|
||||
|
||||
const bitcoin = {
|
||||
status: isBtcAccepted ? 'accepted' : isBtcDenied ? 'denied' : null,
|
||||
lightning,
|
||||
onchain: isBtcAccepted ? onchain : false,
|
||||
};
|
||||
|
||||
const hasPaymentInfo =
|
||||
cash !== null || cards !== null || bitcoin.status !== null;
|
||||
|
||||
return {
|
||||
hasPaymentInfo,
|
||||
cash,
|
||||
cards,
|
||||
bitcoin,
|
||||
};
|
||||
}
|
||||
@@ -411,4 +411,41 @@ module('Integration | Component | place-details', function (hooks) {
|
||||
|
||||
assert.dom('button.btn-link').doesNotExist();
|
||||
});
|
||||
|
||||
test('it renders payment methods when payment tags are present on place', async function (assert) {
|
||||
const place = {
|
||||
title: 'Coffee Place',
|
||||
lat: 52.52,
|
||||
lon: 13.4,
|
||||
osmTags: {
|
||||
'payment:cash': 'yes',
|
||||
'payment:cards': 'no',
|
||||
'currency:XBT': 'yes',
|
||||
'payment:lightning': 'yes',
|
||||
},
|
||||
};
|
||||
|
||||
await render(<template><PlaceDetails @place={{place}} /></template>);
|
||||
|
||||
assert.dom('.place-payment-methods').exists();
|
||||
assert.dom('[data-test-payment-method="cash"]').exists();
|
||||
assert.dom('[data-test-payment-method="cards"]').hasClass('is-denied');
|
||||
assert.dom('[data-test-payment-method="bitcoin"]').exists();
|
||||
assert.dom('[data-test-payment-badge="lightning"]').exists();
|
||||
});
|
||||
|
||||
test('it does not render payment methods when no payment tags are present on place', async function (assert) {
|
||||
const place = {
|
||||
title: 'Simple Place',
|
||||
lat: 52.52,
|
||||
lon: 13.4,
|
||||
osmTags: {
|
||||
amenity: 'bench',
|
||||
},
|
||||
};
|
||||
|
||||
await render(<template><PlaceDetails @place={{place}} /></template>);
|
||||
|
||||
assert.dom('.place-payment-methods').doesNotExist();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'marco/tests/helpers';
|
||||
import { render } from '@ember/test-helpers';
|
||||
import PlacePaymentMethods from 'marco/components/place-payment-methods';
|
||||
|
||||
module('Integration | Component | place-payment-methods', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
test('it renders nothing when no payment tags are present', async function (assert) {
|
||||
await render(<template><PlacePaymentMethods @tags={{hash}} /></template>);
|
||||
assert.dom('.place-payment-methods').doesNotExist();
|
||||
|
||||
const otherTags = { amenity: 'restaurant', name: 'Bistro' };
|
||||
await render(
|
||||
<template><PlacePaymentMethods @tags={{otherTags}} /></template>
|
||||
);
|
||||
assert.dom('.place-payment-methods').doesNotExist();
|
||||
});
|
||||
|
||||
test('it renders cash and card icons when accepted', async function (assert) {
|
||||
const tags = {
|
||||
'payment:cash': 'yes',
|
||||
'payment:cards': 'yes',
|
||||
};
|
||||
|
||||
await render(<template><PlacePaymentMethods @tags={{tags}} /></template>);
|
||||
|
||||
assert.dom('.place-payment-methods').exists();
|
||||
assert.dom('[data-test-payment-method="cash"]').exists();
|
||||
assert
|
||||
.dom('[data-test-payment-method="cash"]')
|
||||
.doesNotHaveClass('is-denied');
|
||||
assert.dom('[data-test-payment-method="cards"]').exists();
|
||||
assert
|
||||
.dom('[data-test-payment-method="cards"]')
|
||||
.doesNotHaveClass('is-denied');
|
||||
assert.dom('[data-test-payment-method="bitcoin"]').doesNotExist();
|
||||
});
|
||||
|
||||
test('it shows strike-through when cards are explicitly denied', async function (assert) {
|
||||
const tags = {
|
||||
'payment:cash': 'yes',
|
||||
'payment:cards': 'no',
|
||||
};
|
||||
|
||||
await render(<template><PlacePaymentMethods @tags={{tags}} /></template>);
|
||||
|
||||
assert.dom('[data-test-payment-method="cards"]').exists();
|
||||
assert.dom('[data-test-payment-method="cards"]').hasClass('is-denied');
|
||||
assert
|
||||
.dom('[data-test-payment-method="cash"]')
|
||||
.doesNotHaveClass('is-denied');
|
||||
});
|
||||
|
||||
test('it shows strike-through when cash is explicitly denied', async function (assert) {
|
||||
const tags = {
|
||||
'payment:cash': 'no',
|
||||
'payment:cards': 'yes',
|
||||
};
|
||||
|
||||
await render(<template><PlacePaymentMethods @tags={{tags}} /></template>);
|
||||
|
||||
assert.dom('[data-test-payment-method="cash"]').exists();
|
||||
assert.dom('[data-test-payment-method="cash"]').hasClass('is-denied');
|
||||
assert
|
||||
.dom('[data-test-payment-method="cards"]')
|
||||
.doesNotHaveClass('is-denied');
|
||||
});
|
||||
|
||||
test('it renders on-chain bitcoin without lightning zap badge', async function (assert) {
|
||||
const tags = {
|
||||
'currency:XBT': 'yes',
|
||||
'payment:onchain': 'yes',
|
||||
'payment:lightning': 'no',
|
||||
};
|
||||
|
||||
await render(<template><PlacePaymentMethods @tags={{tags}} /></template>);
|
||||
|
||||
assert.dom('[data-test-payment-method="bitcoin"]').exists();
|
||||
assert
|
||||
.dom('[data-test-payment-method="bitcoin"]')
|
||||
.doesNotHaveClass('is-denied');
|
||||
assert.dom('[data-test-payment-badge="lightning"]').doesNotExist();
|
||||
});
|
||||
|
||||
test('it renders bitcoin with lightning zap badge when lightning is accepted', async function (assert) {
|
||||
const tags = {
|
||||
'currency:XBT': 'yes',
|
||||
'payment:lightning': 'yes',
|
||||
};
|
||||
|
||||
await render(<template><PlacePaymentMethods @tags={{tags}} /></template>);
|
||||
|
||||
assert.dom('[data-test-payment-method="bitcoin"]').exists();
|
||||
assert
|
||||
.dom('[data-test-payment-method="bitcoin"]')
|
||||
.doesNotHaveClass('is-denied');
|
||||
assert.dom('[data-test-payment-badge="lightning"]').exists();
|
||||
});
|
||||
|
||||
test('it renders bitcoin with strike-through when explicitly denied', async function (assert) {
|
||||
const tags = {
|
||||
'currency:XBT': 'no',
|
||||
};
|
||||
|
||||
await render(<template><PlacePaymentMethods @tags={{tags}} /></template>);
|
||||
|
||||
assert.dom('[data-test-payment-method="bitcoin"]').exists();
|
||||
assert.dom('[data-test-payment-method="bitcoin"]').hasClass('is-denied');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,218 @@
|
||||
import { parsePaymentMethods } from 'marco/utils/payment';
|
||||
import { module, test } from 'qunit';
|
||||
|
||||
module('Unit | Utility | payment', function () {
|
||||
test('it returns hasPaymentInfo: false for empty or non-payment tags', function (assert) {
|
||||
assert.deepEqual(parsePaymentMethods(undefined), {
|
||||
hasPaymentInfo: false,
|
||||
cash: null,
|
||||
cards: null,
|
||||
bitcoin: { status: null, lightning: false, onchain: false },
|
||||
});
|
||||
|
||||
assert.deepEqual(parsePaymentMethods({}), {
|
||||
hasPaymentInfo: false,
|
||||
cash: null,
|
||||
cards: null,
|
||||
bitcoin: { status: null, lightning: false, onchain: false },
|
||||
});
|
||||
|
||||
assert.deepEqual(
|
||||
parsePaymentMethods({ amenity: 'cafe', name: 'Coffee Shop' }),
|
||||
{
|
||||
hasPaymentInfo: false,
|
||||
cash: null,
|
||||
cards: null,
|
||||
bitcoin: { status: null, lightning: false, onchain: false },
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
module('cash', function () {
|
||||
test('it identifies cash as accepted', function (assert) {
|
||||
assert.strictEqual(
|
||||
parsePaymentMethods({ 'payment:cash': 'yes' }).cash,
|
||||
'accepted'
|
||||
);
|
||||
assert.strictEqual(
|
||||
parsePaymentMethods({ 'payment:cash': 'only' }).cash,
|
||||
'accepted'
|
||||
);
|
||||
assert.strictEqual(
|
||||
parsePaymentMethods({ 'payment:coins': 'yes' }).cash,
|
||||
'accepted'
|
||||
);
|
||||
assert.strictEqual(
|
||||
parsePaymentMethods({ 'payment:notes': 'yes' }).cash,
|
||||
'accepted'
|
||||
);
|
||||
});
|
||||
|
||||
test('it identifies cash as denied', function (assert) {
|
||||
assert.strictEqual(
|
||||
parsePaymentMethods({ 'payment:cash': 'no' }).cash,
|
||||
'denied'
|
||||
);
|
||||
assert.strictEqual(
|
||||
parsePaymentMethods({ 'payment:coins': 'no', 'payment:notes': 'no' })
|
||||
.cash,
|
||||
'denied'
|
||||
);
|
||||
});
|
||||
|
||||
test('it keeps cash as null when cash tags are absent', function (assert) {
|
||||
assert.strictEqual(
|
||||
parsePaymentMethods({ 'payment:cards': 'yes' }).cash,
|
||||
null
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
module('cards', function () {
|
||||
test('it identifies cards as accepted from generic or card tags', function (assert) {
|
||||
assert.strictEqual(
|
||||
parsePaymentMethods({ 'payment:cards': 'yes' }).cards,
|
||||
'accepted'
|
||||
);
|
||||
assert.strictEqual(
|
||||
parsePaymentMethods({ 'payment:credit_cards': 'yes' }).cards,
|
||||
'accepted'
|
||||
);
|
||||
assert.strictEqual(
|
||||
parsePaymentMethods({ 'payment:debit_cards': 'yes' }).cards,
|
||||
'accepted'
|
||||
);
|
||||
assert.strictEqual(
|
||||
parsePaymentMethods({ 'payment:contactless': 'yes' }).cards,
|
||||
'accepted'
|
||||
);
|
||||
assert.strictEqual(
|
||||
parsePaymentMethods({ 'payment:visa': 'yes' }).cards,
|
||||
'accepted'
|
||||
);
|
||||
assert.strictEqual(
|
||||
parsePaymentMethods({ 'payment:mastercard': 'yes' }).cards,
|
||||
'accepted'
|
||||
);
|
||||
assert.strictEqual(
|
||||
parsePaymentMethods({ 'payment:american_express': 'yes' }).cards,
|
||||
'accepted'
|
||||
);
|
||||
assert.strictEqual(
|
||||
parsePaymentMethods({ 'payment:girocard': 'yes' }).cards,
|
||||
'accepted'
|
||||
);
|
||||
assert.strictEqual(
|
||||
parsePaymentMethods({ 'payment:apple_pay': 'yes' }).cards,
|
||||
'accepted'
|
||||
);
|
||||
assert.strictEqual(
|
||||
parsePaymentMethods({ 'payment:google_pay': 'yes' }).cards,
|
||||
'accepted'
|
||||
);
|
||||
});
|
||||
|
||||
test('it identifies cards as denied when explicitly disabled', function (assert) {
|
||||
assert.strictEqual(
|
||||
parsePaymentMethods({ 'payment:cards': 'no' }).cards,
|
||||
'denied'
|
||||
);
|
||||
assert.strictEqual(
|
||||
parsePaymentMethods({
|
||||
'payment:credit_cards': 'no',
|
||||
'payment:debit_cards': 'no',
|
||||
}).cards,
|
||||
'denied'
|
||||
);
|
||||
assert.strictEqual(
|
||||
parsePaymentMethods({ 'payment:cash': 'only' }).cards,
|
||||
'denied'
|
||||
);
|
||||
});
|
||||
|
||||
test('it accepts cards if debit is accepted even if credit_cards is no', function (assert) {
|
||||
assert.strictEqual(
|
||||
parsePaymentMethods({
|
||||
'payment:credit_cards': 'no',
|
||||
'payment:debit_cards': 'yes',
|
||||
}).cards,
|
||||
'accepted'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
module('bitcoin', function () {
|
||||
test('it identifies on-chain bitcoin acceptance', function (assert) {
|
||||
const result = parsePaymentMethods({ 'currency:XBT': 'yes' });
|
||||
assert.strictEqual(result.bitcoin.status, 'accepted');
|
||||
assert.true(result.bitcoin.onchain);
|
||||
assert.false(result.bitcoin.lightning);
|
||||
});
|
||||
|
||||
test('it identifies bitcoin from payment:onchain tag', function (assert) {
|
||||
const result = parsePaymentMethods({ 'payment:onchain': 'yes' });
|
||||
assert.strictEqual(result.bitcoin.status, 'accepted');
|
||||
assert.true(result.bitcoin.onchain);
|
||||
assert.false(result.bitcoin.lightning);
|
||||
});
|
||||
|
||||
test('it identifies bitcoin with lightning', function (assert) {
|
||||
const result = parsePaymentMethods({
|
||||
'currency:XBT': 'yes',
|
||||
'payment:lightning': 'yes',
|
||||
'payment:onchain': 'no',
|
||||
});
|
||||
assert.strictEqual(result.bitcoin.status, 'accepted');
|
||||
assert.true(result.bitcoin.lightning);
|
||||
assert.false(result.bitcoin.onchain);
|
||||
});
|
||||
|
||||
test('it identifies bitcoin with both lightning and on-chain', function (assert) {
|
||||
const result = parsePaymentMethods({
|
||||
'currency:XBT': 'yes',
|
||||
'payment:lightning': 'yes',
|
||||
'payment:onchain': 'yes',
|
||||
});
|
||||
assert.strictEqual(result.bitcoin.status, 'accepted');
|
||||
assert.true(result.bitcoin.lightning);
|
||||
assert.true(result.bitcoin.onchain);
|
||||
});
|
||||
|
||||
test('it supports fallback bitcoin tags', function (assert) {
|
||||
assert.strictEqual(
|
||||
parsePaymentMethods({ 'payment:bitcoin': 'yes' }).bitcoin.status,
|
||||
'accepted'
|
||||
);
|
||||
assert.strictEqual(
|
||||
parsePaymentMethods({ 'currency:BTC': 'yes' }).bitcoin.status,
|
||||
'accepted'
|
||||
);
|
||||
});
|
||||
|
||||
test('it identifies bitcoin as denied when explicitly no', function (assert) {
|
||||
assert.strictEqual(
|
||||
parsePaymentMethods({ 'currency:XBT': 'no' }).bitcoin.status,
|
||||
'denied'
|
||||
);
|
||||
assert.strictEqual(
|
||||
parsePaymentMethods({ 'payment:bitcoin': 'no' }).bitcoin.status,
|
||||
'denied'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('it handles mixed tags and sets hasPaymentInfo to true', function (assert) {
|
||||
const result = parsePaymentMethods({
|
||||
'payment:cash': 'yes',
|
||||
'payment:cards': 'no',
|
||||
'currency:XBT': 'yes',
|
||||
'payment:lightning': 'yes',
|
||||
});
|
||||
|
||||
assert.true(result.hasPaymentInfo);
|
||||
assert.strictEqual(result.cash, 'accepted');
|
||||
assert.strictEqual(result.cards, 'denied');
|
||||
assert.strictEqual(result.bitcoin.status, 'accepted');
|
||||
assert.true(result.bitcoin.lightning);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user