mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-05-24 02:14:21 -04:00
Test for Gmail (#3706)
* Fixes for null values in custom values * Refactor mailing * Working on send emails from GMail API * Fixes for tests * Test for GMail
This commit is contained in:
parent
a01d7a59aa
commit
d05bd7d2c1
@ -312,7 +312,7 @@ class LoginController extends BaseController
|
||||
if(array_key_exists('refresh_token', $token))
|
||||
$refresh_token = $token['refresh_token'];
|
||||
|
||||
$access_token = $token['access_token'];
|
||||
$access_token = $token['access_token'];
|
||||
|
||||
$name = OAuth::splitName($google->harvestName($user));
|
||||
|
||||
|
60
app/Jobs/Mail/BaseMailerJob.php
Normal file
60
app/Jobs/Mail/BaseMailerJob.php
Normal file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs\Mail;
|
||||
|
||||
use App\Libraries\Google\Google;
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\User;
|
||||
use App\Providers\MailServiceProvider;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\Config;
|
||||
|
||||
class BaseMailerJob implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
|
||||
private function setMailDriver(string $driver)
|
||||
{
|
||||
switch ($driver) {
|
||||
case 'default':
|
||||
break;
|
||||
case 'gmail':
|
||||
$this->setGmailMailer();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function setGmailMailer()
|
||||
{
|
||||
$sending_user = $this->entity->client->getSetting('gmail_sending_user_id');
|
||||
|
||||
$user = User::find($sending_user);
|
||||
|
||||
$google = (new Google())->init();
|
||||
$google->getClient->setAccessToken($user->oauth_user_token);
|
||||
|
||||
if ($google->getClient->isAccessTokenExpired()) {
|
||||
$google->refreshToken($user);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now that our token is refresh and valid we can boot the
|
||||
* mail driver at runtime and also set the token which will persist
|
||||
* just for this request.
|
||||
*/
|
||||
|
||||
Config::set('mail.driver', 'gmail');
|
||||
Config::set('services.gmail.token', $user->oauth_user_token);
|
||||
(new MailServiceProvider(app()))->register();
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -2,14 +2,23 @@
|
||||
|
||||
namespace App\Jobs\Mail;
|
||||
|
||||
use App\Jobs\Util\SystemLogger;
|
||||
use App\Libraries\Google\Google;
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Mail\Admin\EntitySent;
|
||||
use App\Mail\Admin\EntitySentObject;
|
||||
use App\Models\SystemLog;
|
||||
use App\Models\User;
|
||||
use App\Providers\MailServiceProvider;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\Config;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
class EntitySentEmail implements ShouldQueue
|
||||
class EntitySentEmail extends BaseMailerJob implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
@ -45,32 +54,37 @@ class EntitySentEmail implements ShouldQueue
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
//set DB
|
||||
MultiDB::setDb($this->company->db);
|
||||
|
||||
//if we need to set an email driver do it now
|
||||
$this->setMailDriver($this->entity->client->getSetting('email_sending_method'));
|
||||
|
||||
}
|
||||
$mail_obj = (new EntitySentObject($this->invitation, $this->entity_type))->build();
|
||||
$mail_obj->from = $this->entity->user->present()->name();
|
||||
|
||||
private function setMailDriver(string $driver)
|
||||
{
|
||||
switch ($driver) {
|
||||
case 'default':
|
||||
break;
|
||||
case 'gmail':
|
||||
$this->setGmailMailer();
|
||||
break;
|
||||
default:
|
||||
|
||||
break;
|
||||
//send email
|
||||
// Mail::to($this->user->email)
|
||||
Mail::to('turbo124@gmail.com') //@todo
|
||||
->send(new EntitySent($mail_obj));
|
||||
|
||||
//catch errors
|
||||
if (count(Mail::failures()) > 0) {
|
||||
$this->logMailError(Mail::failures());
|
||||
}
|
||||
if($driver == 'default')
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
private function setGmailMailer()
|
||||
private function logMailError($errors)
|
||||
{
|
||||
$sending_user = $this->entity->client->getSetting('gmail_sending_user_id');
|
||||
|
||||
SystemLogger::dispatch(
|
||||
$errors,
|
||||
SystemLog::CATEGORY_MAIL,
|
||||
SystemLog::EVENT_MAIL_SEND,
|
||||
SystemLog::TYPE_FAILURE,
|
||||
$this->invoice->client
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
65
app/Libraries/Google/Google.php
Normal file
65
app/Libraries/Google/Google.php
Normal file
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com)
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Libraries\Google;
|
||||
|
||||
/**
|
||||
* Class Google
|
||||
* @package App\Libraries\Google
|
||||
*/
|
||||
class Google
|
||||
{
|
||||
public $client;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->client = new \Google_Client();
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
$this->client->setClientId(config('ninja.auth.google.client_id'));
|
||||
$this->client->setClientSecret(config('ninja.auth.google.client_secret'));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getClient()
|
||||
{
|
||||
return $this->client;
|
||||
}
|
||||
|
||||
public function checkAccessToken()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function refreshToken($user)
|
||||
{
|
||||
if($this->client->isAccessTokenExpired()) {
|
||||
$this->client->fetchAccessTokenWithRefreshToken($user->oauth_user_refresh_token);
|
||||
|
||||
$access_token = $this->client->getAccessToken();
|
||||
|
||||
if(is_string($access_token))
|
||||
$user->oauth_user_token = $access_token;
|
||||
elseif(isset($access_token['access_token']))
|
||||
$user->oauth_user_token = $access_token['access_token']);
|
||||
|
||||
$user->save();
|
||||
|
||||
$this->client->setAccessToken($access_token);
|
||||
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
45
app/Mail/Admin/EntitySent.php
Normal file
45
app/Mail/Admin/EntitySent.php
Normal file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com)
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Mail\Admin;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Mail\Mailable;
|
||||
|
||||
class EntitySent extends Mailable
|
||||
{
|
||||
|
||||
public $mail_obj;
|
||||
/**
|
||||
* Create a new message instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($mail_obj)
|
||||
{
|
||||
$this->mail_obj = $mail_obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the message.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
return $this->from($this->mail_obj->from) //todo
|
||||
->subject($this->mail_obj->subject)
|
||||
->markdown($this->mail_obj->markdown, ['data' => $this->mail_obj->data])
|
||||
->withSwiftMessage(function ($message) {
|
||||
$message->getHeaders()->addTextHeader('Tag', $this->mail_obj->tag);
|
||||
});
|
||||
}
|
||||
}
|
90
app/Mail/Admin/EntitySentObject.php
Normal file
90
app/Mail/Admin/EntitySentObject.php
Normal file
@ -0,0 +1,90 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com)
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Mail\Admin;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Utils\Number;
|
||||
|
||||
class EntitySentObject
|
||||
{
|
||||
public $invitation;
|
||||
|
||||
public $entity_type;
|
||||
|
||||
public $entity;
|
||||
|
||||
public $contact;
|
||||
|
||||
public $company;
|
||||
|
||||
public $settings;
|
||||
|
||||
public function __construct($invitation, $entity_type)
|
||||
{
|
||||
$this->invitation = $invitation;
|
||||
$this->entity_type = $entity_type;
|
||||
$this->entity = $invitation->{$entity_type};
|
||||
$this->contact = $invitation->contact;
|
||||
$this->company = $invitation->company;
|
||||
$this->settings = $this->entity->client->getMergedSettings();
|
||||
}
|
||||
|
||||
public function build()
|
||||
{
|
||||
$mail_obj = new \stdClass;
|
||||
$mail_obj->amount = $this->getAmount();
|
||||
$mail_obj->subject = $this->getSubject();
|
||||
$mail_obj->data = $this->getData();
|
||||
$mail_obj->markdown = 'email.admin.generic';
|
||||
$mail_obj->tag = $this->company->company_key;
|
||||
|
||||
return $mail_obj;
|
||||
}
|
||||
|
||||
private function getAmount()
|
||||
{
|
||||
return Number::formatMoney($this->entity->amount, $this->entity->client);
|
||||
}
|
||||
|
||||
private function getSubject()
|
||||
{
|
||||
return
|
||||
ctrans(
|
||||
"texts.notification_{$this->entity_type}_sent_subject",
|
||||
[
|
||||
'client' => $this->contact->present()->name(),
|
||||
'invoice' => $this->entity->number,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
private function getData()
|
||||
{
|
||||
$data = [
|
||||
'title' => $this->getSubject,
|
||||
'message' => ctrans(
|
||||
"texts.notification_{$this->entity_type}_sent",
|
||||
[
|
||||
'amount' => $amount,
|
||||
'client' => $this->contact->present()->name(),
|
||||
'invoice' => $this->entity->number,
|
||||
]
|
||||
),
|
||||
'url' => $this->invitation->getAdminLink(),
|
||||
'button' => ctrans("texts.view_{$this->entity_type}"),
|
||||
'signature' => $this->settings->email_signature,
|
||||
'logo' => $this->company->present()->logo(),
|
||||
];
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
@ -34,7 +34,7 @@ class CreditTest extends TestCase
|
||||
public function testCreditsList()
|
||||
{
|
||||
|
||||
factory(Client::class, 1)->create(['user_id' => $user->id, 'company_id' => $company->id])->each(function ($c) {
|
||||
factory(Client::class, 1)->create(['user_id' => $this->user->id, 'company_id' => $this->company->id])->each(function ($c) {
|
||||
factory(\App\Models\ClientContact::class, 1)->create([
|
||||
'user_id' => $this->user->id,
|
||||
'client_id' => $c->id,
|
||||
|
@ -44,64 +44,30 @@ class InvoiceTest extends TestCase
|
||||
|
||||
public function testInvoiceList()
|
||||
{
|
||||
Account::all()->each(function($account) {
|
||||
$account->delete();
|
||||
});
|
||||
|
||||
$data = [
|
||||
'first_name' => $this->faker->firstName,
|
||||
'last_name' => $this->faker->lastName,
|
||||
'name' => $this->faker->company,
|
||||
'email' => $this->faker->unique()->safeEmail,
|
||||
'password' => 'ALongAndBrilliantPassword123',
|
||||
'_token' => csrf_token(),
|
||||
'privacy_policy' => 1,
|
||||
'terms_of_service' => 1
|
||||
];
|
||||
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
])->post('/api/v1/signup?include=account', $data);
|
||||
|
||||
$acc = $response->json();
|
||||
|
||||
$account = Account::find($this->decodePrimaryKey($acc['data'][0]['account']['id']));
|
||||
|
||||
$company_token = $account->default_company->tokens()->first();
|
||||
$token = $company_token->token;
|
||||
$company = $company_token->company;
|
||||
|
||||
$user = $company_token->user;
|
||||
|
||||
$this->assertNotNull($company_token);
|
||||
$this->assertNotNull($token);
|
||||
$this->assertNotNull($user);
|
||||
$this->assertNotNull($company);
|
||||
//$this->assertNotNull($user->token->company);
|
||||
|
||||
factory(\App\Models\Client::class, 1)->create(['user_id' => $user->id, 'company_id' => $company->id])->each(function ($c) use ($user, $company) {
|
||||
factory(\App\Models\Client::class, 1)->create(['user_id' => $this->user->id, 'company_id' => $this->company->id])->each(function ($c){
|
||||
factory(\App\Models\ClientContact::class, 1)->create([
|
||||
'user_id' => $user->id,
|
||||
'user_id' => $this->user->id,
|
||||
'client_id' => $c->id,
|
||||
'company_id' => $company->id,
|
||||
'company_id' => $this->company->id,
|
||||
'is_primary' => 1
|
||||
]);
|
||||
|
||||
factory(\App\Models\ClientContact::class, 1)->create([
|
||||
'user_id' => $user->id,
|
||||
'user_id' => $this->user->id,
|
||||
'client_id' => $c->id,
|
||||
'company_id' => $company->id
|
||||
'company_id' => $this->company->id
|
||||
]);
|
||||
});
|
||||
|
||||
$client = Client::all()->first();
|
||||
|
||||
factory(\App\Models\Invoice::class, 1)->create(['user_id' => $user->id, 'company_id' => $company->id, 'client_id' => $client->id]);
|
||||
factory(\App\Models\Invoice::class, 1)->create(['user_id' => $this->user->id, 'company_id' => $this->company->id, 'client_id' => $this->client->id]);
|
||||
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $token,
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->get('/api/v1/invoices');
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
Loading…
x
Reference in New Issue
Block a user