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:
David Bomba 2020-05-16 12:04:24 +10:00 committed by GitHub
parent a01d7a59aa
commit d05bd7d2c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 302 additions and 62 deletions

View File

@ -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));

View 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();
}
}

View File

@ -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
);
}
}

View 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;
}
}

View 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);
});
}
}

View 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;
}
}

View File

@ -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,

View File

@ -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);