mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Testing adding Stripe credit card
- Added: iframeLoaded method for Cypress - Fixed: saving payment method id for CreditCard.php - Added: chromeWebSecurity: false flag for insecure iframe connections - Formatted: payment_methods/index - Formatted: payment-methods-table.blade.php - Added: Test for adding credit card to Stripe - Fixed: Removing client gateway tokens
This commit is contained in:
parent
107e3faa6e
commit
4918269bf2
@ -48,7 +48,7 @@ class PaymentMethodController extends Controller
|
|||||||
|
|
||||||
return $gateway
|
return $gateway
|
||||||
->driver(auth()->user()->client)
|
->driver(auth()->user()->client)
|
||||||
->setPaymentMethod(GatewayType::BANK_TRANSFER)
|
->setPaymentMethod(GatewayType::CREDIT_CARD)
|
||||||
->authorizeView($data);
|
->authorizeView($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,7 +64,7 @@ class PaymentMethodController extends Controller
|
|||||||
|
|
||||||
return $gateway
|
return $gateway
|
||||||
->driver(auth()->user()->client)
|
->driver(auth()->user()->client)
|
||||||
->setPaymentMethod(GatewayType::BANK_TRANSFER)
|
->setPaymentMethod(GatewayType::CREDIT_CARD)
|
||||||
->authorizeResponse($request);
|
->authorizeResponse($request);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,7 +133,7 @@ class PaymentMethodController extends Controller
|
|||||||
public function destroy(ClientGatewayToken $payment_method)
|
public function destroy(ClientGatewayToken $payment_method)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
event(new MethodDeleted($payment_method));
|
event(new MethodDeleted($payment_method, auth('contact')->user()->company));
|
||||||
$payment_method->delete();
|
$payment_method->delete();
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
Log::error(json_encode($e));
|
Log::error(json_encode($e));
|
||||||
|
@ -45,7 +45,7 @@ class CreditCard
|
|||||||
$server_response = json_decode($request->input('gateway_response'));
|
$server_response = json_decode($request->input('gateway_response'));
|
||||||
|
|
||||||
$gateway_id = $request->input('gateway_id');
|
$gateway_id = $request->input('gateway_id');
|
||||||
$gateway_type_id = $request->input('gateway_type_id');
|
$gateway_type_id = $request->input('payment_method_id');
|
||||||
$is_default = $request->input('is_default');
|
$is_default = $request->input('is_default');
|
||||||
|
|
||||||
$payment_method = $server_response->payment_method;
|
$payment_method = $server_response->payment_method;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
"video": false,
|
"video": false,
|
||||||
"baseUrl": "http://invoiceninja.wip/"
|
"baseUrl": "http://invoiceninja.wip/",
|
||||||
|
"chromeWebSecurity": false
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,35 @@ context('Payment methods', () => {
|
|||||||
.should('contain.text', 'Payment Method');
|
.should('contain.text', 'Payment Method');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should add stripe credit card', () => {
|
||||||
|
cy.visit('/client/payment_methods');
|
||||||
|
|
||||||
|
cy.get('body')
|
||||||
|
.find('#add-payment-method')
|
||||||
|
.first()
|
||||||
|
.should('contain.text', 'Add Payment Method')
|
||||||
|
.click()
|
||||||
|
|
||||||
|
cy.location().should(location => {
|
||||||
|
expect(location.pathname).to.eq('/client/payment_methods/create');
|
||||||
|
});
|
||||||
|
|
||||||
|
cy.wait(3000);
|
||||||
|
|
||||||
|
cy.get('#cardholder-name').type('Invoice Ninja');
|
||||||
|
|
||||||
|
cy.getWithinIframe('[name="cardnumber"]').type('4242424242424242');
|
||||||
|
cy.getWithinIframe('[name="exp-date"]').type('2442');
|
||||||
|
cy.getWithinIframe('[name="cvc"]').type('242');
|
||||||
|
cy.getWithinIframe('[name="postal"]').type('12345');
|
||||||
|
|
||||||
|
cy.get('#card-button').click();
|
||||||
|
|
||||||
|
cy.location().should(location => {
|
||||||
|
expect(location.pathname).to.eq('/client/payment_methods');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should have per page options dropdown', () => {
|
it('should have per page options dropdown', () => {
|
||||||
cy.visit('/client/payment_methods');
|
cy.visit('/client/payment_methods');
|
||||||
|
|
||||||
|
30
cypress/support/commands.js
vendored
30
cypress/support/commands.js
vendored
@ -44,3 +44,33 @@ Cypress.Commands.add('clientLogin', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Cypress.Commands.add(
|
||||||
|
'iframeLoaded',
|
||||||
|
{prevSubject: 'element'},
|
||||||
|
($iframe) => {
|
||||||
|
const contentWindow = $iframe.prop('contentWindow');
|
||||||
|
return new Promise(resolve => {
|
||||||
|
if (
|
||||||
|
contentWindow
|
||||||
|
) {
|
||||||
|
resolve(contentWindow)
|
||||||
|
} else {
|
||||||
|
$iframe.on('load', () => {
|
||||||
|
resolve(contentWindow)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
Cypress.Commands.add(
|
||||||
|
'getInDocument',
|
||||||
|
{prevSubject: 'Permission denied to access property "document" on cross-origin object'},
|
||||||
|
(document, selector) => Cypress.$(selector, document)
|
||||||
|
);
|
||||||
|
|
||||||
|
Cypress.Commands.add(
|
||||||
|
'getWithinIframe',
|
||||||
|
(targetElement) => cy.get('iframe').iframeLoaded().its('document').getInDocument(targetElement)
|
||||||
|
);
|
||||||
|
@ -10,81 +10,85 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
@if($client->getCreditCardGateway())
|
@if($client->getCreditCardGateway())
|
||||||
<a href="{{ route('client.payment_methods.create') }}" class="button button-primary">{{ ctrans('texts.add_payment_method') }}</a>
|
<a href="{{ route('client.payment_methods.create') }}" id="add-payment-method"
|
||||||
|
class="button button-primary">{{ ctrans('texts.add_payment_method') }}</a>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
<div class="-my-2 py-2 overflow-x-auto sm:-mx-6 sm:px-6 lg:-mx-8 lg:px-8">
|
<div class="-my-2 py-2 overflow-x-auto sm:-mx-6 sm:px-6 lg:-mx-8 lg:px-8">
|
||||||
<div class="align-middle inline-block min-w-full overflow-hidden rounded">
|
<div class="align-middle inline-block min-w-full overflow-hidden rounded">
|
||||||
<table class="min-w-full shadow rounded border border-gray-200 mt-4 payment-methods-table">
|
<table class="min-w-full shadow rounded border border-gray-200 mt-4 payment-methods-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||||
<span role="button" wire:click="sortBy('created_at')" class="cursor-pointer">
|
<span role="button" wire:click="sortBy('created_at')" class="cursor-pointer">
|
||||||
{{ ctrans('texts.created_at') }}
|
{{ ctrans('texts.created_at') }}
|
||||||
</span>
|
</span>
|
||||||
</th>
|
</th>
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||||
<span role="button" wire:click="sortBy('type_id')" class="cursor-pointer">
|
<span role="button" wire:click="sortBy('type_id')" class="cursor-pointer">
|
||||||
{{ ctrans('texts.payment_type_id') }}
|
{{ ctrans('texts.payment_type_id') }}
|
||||||
</span>
|
</span>
|
||||||
</th>
|
</th>
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||||
{{ ctrans('texts.type') }}
|
{{ ctrans('texts.type') }}
|
||||||
</th>
|
</th>
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||||
{{ ctrans('texts.expires') }}
|
{{ ctrans('texts.expires') }}
|
||||||
</th>
|
</th>
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||||
{{ ctrans('texts.card_number') }}
|
{{ ctrans('texts.card_number') }}
|
||||||
</th>
|
</th>
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||||
{{ ctrans('texts.default') }}
|
{{ ctrans('texts.default') }}
|
||||||
</th>
|
</th>
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50"></th>
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50"></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@forelse($payment_methods as $payment_method)
|
@forelse($payment_methods as $payment_method)
|
||||||
<tr class="bg-white group hover:bg-gray-100">
|
<tr class="bg-white group hover:bg-gray-100">
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||||
{{ $payment_method->formatDateTimestamp($payment_method->created_at, $client->date_format()) }}
|
{{ $payment_method->formatDateTimestamp($payment_method->created_at, $client->date_format()) }}
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||||
{{ ctrans("texts.{$payment_method->gateway_type->alias}") }}
|
{{ ctrans("texts.{$payment_method->gateway_type->alias}") }}
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||||
{{ ucfirst(optional($payment_method->meta)->brand) }}
|
{{ ucfirst(optional($payment_method->meta)->brand) }}
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||||
@if(isset($payment_method->meta->exp_month) && isset($payment_method->meta->exp_year))
|
@if(isset($payment_method->meta->exp_month) && isset($payment_method->meta->exp_year))
|
||||||
{{ $payment_method->meta->exp_month}} / {{ $payment_method->meta->exp_year }}
|
{{ $payment_method->meta->exp_month}} / {{ $payment_method->meta->exp_year }}
|
||||||
@endif
|
@endif
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||||
@isset($payment_method->meta->last4)
|
@isset($payment_method->meta->last4)
|
||||||
**** {{ $payment_method->meta->last4 }}
|
**** {{ $payment_method->meta->last4 }}
|
||||||
@endisset
|
@endisset
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||||
@if($payment_method->is_default)
|
@if($payment_method->is_default)
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-check">
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none"
|
||||||
<path d="M20 6L9 17l-5-5" />
|
stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
||||||
</svg>
|
stroke-linejoin="round" class="feather feather-check">
|
||||||
@endif
|
<path d="M20 6L9 17l-5-5"/>
|
||||||
</td>
|
</svg>
|
||||||
<td class="px-6 py-4 whitespace-no-wrap flex items-center justify-end text-sm leading-5 font-medium">
|
@endif
|
||||||
<a href="{{ route('client.payment_methods.show', $payment_method->hashed_id) }}" class="text-blue-600 hover:text-indigo-900 focus:outline-none focus:underline">
|
</td>
|
||||||
@lang('texts.view')
|
<td class="px-6 py-4 whitespace-no-wrap flex items-center justify-end text-sm leading-5 font-medium">
|
||||||
</a>
|
<a href="{{ route('client.payment_methods.show', $payment_method->hashed_id) }}"
|
||||||
</td>
|
class="text-blue-600 hover:text-indigo-900 focus:outline-none focus:underline">
|
||||||
</tr>
|
@lang('texts.view')
|
||||||
@empty
|
</a>
|
||||||
<tr class="bg-white group hover:bg-gray-100">
|
</td>
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500" colspan="100%">
|
</tr>
|
||||||
{{ ctrans('texts.no_results') }}
|
@empty
|
||||||
</td>
|
<tr class="bg-white group hover:bg-gray-100">
|
||||||
</tr>
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500" colspan="100%">
|
||||||
@endforelse
|
{{ ctrans('texts.no_results') }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@endforelse
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
@ -95,6 +99,7 @@
|
|||||||
{{ ctrans('texts.showing_x_of', ['first' => $payment_methods->firstItem(), 'last' => $payment_methods->lastItem(), 'total' => $payment_methods->total()]) }}
|
{{ ctrans('texts.showing_x_of', ['first' => $payment_methods->firstItem(), 'last' => $payment_methods->lastItem(), 'total' => $payment_methods->total()]) }}
|
||||||
</span>
|
</span>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
{{ $payment_methods->links() }}
|
{{ $payment_methods->links() }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
@ -1,14 +1,6 @@
|
|||||||
@extends('portal.ninja2020.layout.app')
|
@extends('portal.ninja2020.layout.app')
|
||||||
@section('meta_title', ctrans('texts.payment_methods'))
|
@section('meta_title', ctrans('texts.payment_methods'))
|
||||||
|
|
||||||
@section('header')
|
|
||||||
<div class="mt-5 sm:mt-0 sm:ml-6 sm:flex-shrink-0 sm:flex sm:items-center">
|
|
||||||
<div class="inline-flex rounded-md shadow-sm">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@endsection
|
|
||||||
|
|
||||||
@section('body')
|
@section('body')
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
@livewire('payment-methods-table', ['client' => $client])
|
@livewire('payment-methods-table', ['client' => $client])
|
||||||
|
Loading…
x
Reference in New Issue
Block a user