mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
commit
3b253cf38d
10
README.md
10
README.md
@ -7,15 +7,7 @@
|
||||
|
||||
[](https://www.codacy.com/app/turbo124/invoiceninja?utm_source=github.com&utm_medium=referral&utm_content=invoiceninja/invoiceninja&utm_campaign=Badge_Grade)
|
||||
|
||||
# Invoice Ninja version 5.1 RC2!
|
||||
|
||||
Invoice Ninja version 5.1 has now reached Release Candidate 2!
|
||||
|
||||
What does this mean exactly? We consider this version _almost_ stable. There may be some remaining small issues which we would love to get feedback on. We would really appreciate the community booting up this version and attempting the migration from their Invoice Ninja V4 application and inspect the migrated data.
|
||||
|
||||
We'd also like feedback on any issues that you can see, and help us nail down the few remaining issues before Version 5 graduates to Stable Gold Release.
|
||||
|
||||
Please note we do not consider this version ready for production use, please stick with your V4 installation for your production clients!
|
||||
# Invoice Ninja version 5!
|
||||
|
||||
## Quick Start
|
||||
|
||||
|
@ -171,7 +171,7 @@ class LoginController extends BaseController
|
||||
|
||||
//if user has 2fa enabled - lets check this now:
|
||||
|
||||
if($user->google_2fa_secret && $request->has('one_time_password'))
|
||||
if($user->google_2fa_secret && $request->has('one_time_password') && strlen($request->input('one_time_password')) >= 1)
|
||||
{
|
||||
$google2fa = new Google2FA();
|
||||
|
||||
@ -194,6 +194,7 @@ class LoginController extends BaseController
|
||||
|
||||
$user->setCompany($user->account->default_company);
|
||||
$timeout = auth()->user()->company()->default_password_timeout;
|
||||
|
||||
Cache::put(auth()->user()->hashed_id.'_logged_in', Str::random(64), $timeout);
|
||||
|
||||
$cu = CompanyUser::query()
|
||||
@ -322,33 +323,34 @@ class LoginController extends BaseController
|
||||
|
||||
if ($user) {
|
||||
|
||||
$client = new Google_Client();
|
||||
$client->setClientId(config('ninja.auth.google.client_id'));
|
||||
$client->setClientSecret(config('ninja.auth.google.client_secret'));
|
||||
$client->setRedirectUri(config('ninja.app_url'));
|
||||
// we are no longer accessing the permissions for gmail - email permissions here
|
||||
|
||||
$token = false;
|
||||
// $client = new Google_Client();
|
||||
// $client->setClientId(config('ninja.auth.google.client_id'));
|
||||
// $client->setClientSecret(config('ninja.auth.google.client_secret'));
|
||||
// $client->setRedirectUri(config('ninja.app_url'));
|
||||
|
||||
try{
|
||||
$token = $client->authenticate(request()->input('server_auth_code'));
|
||||
}
|
||||
catch(\Exception $e) {
|
||||
// $token = false;
|
||||
|
||||
return response()
|
||||
->json(['message' => ctrans('texts.invalid_credentials')], 401)
|
||||
->header('X-App-Version', config('ninja.app_version'))
|
||||
->header('X-Api-Version', config('ninja.minimum_client_version'));
|
||||
// try{
|
||||
// $token = $client->authenticate(request()->input('server_auth_code'));
|
||||
// }
|
||||
// catch(\Exception $e) {
|
||||
|
||||
}
|
||||
// return response()
|
||||
// ->json(['message' => ctrans('texts.invalid_credentials')], 401)
|
||||
// ->header('X-App-Version', config('ninja.app_version'))
|
||||
// ->header('X-Api-Version', config('ninja.minimum_client_version'));
|
||||
|
||||
$refresh_token = '';
|
||||
// }
|
||||
|
||||
if (array_key_exists('refresh_token', $token)) {
|
||||
$refresh_token = $token['refresh_token'];
|
||||
}
|
||||
// $refresh_token = '';
|
||||
|
||||
//$access_token = $token['access_token'];
|
||||
// if (array_key_exists('refresh_token', $token)) {
|
||||
// $refresh_token = $token['refresh_token'];
|
||||
// }
|
||||
|
||||
|
||||
$name = OAuth::splitName($google->harvestName($user));
|
||||
|
||||
$new_account = [
|
||||
|
@ -54,7 +54,7 @@ class QueryLogging
|
||||
nlog($request->method().' - '.$request->url().": $count queries - ".$time);
|
||||
|
||||
// if($count > 50)
|
||||
// Log::nlog($queries);
|
||||
//nlog($queries);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@ use App\Models\Client;
|
||||
use App\Models\GroupSetting;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class StoreClientRequest extends Request
|
||||
{
|
||||
@ -48,7 +49,6 @@ class StoreClientRequest extends Request
|
||||
|
||||
/* Ensure we have a client name, and that all emails are unique*/
|
||||
//$rules['name'] = 'required|min:1';
|
||||
$rules['id_number'] = 'unique:clients,id_number,'.$this->id.',id,company_id,'.$this->company_id;
|
||||
$rules['settings'] = new ValidClientGroupSettingsRule();
|
||||
$rules['contacts.*.email'] = 'bail|nullable|distinct|sometimes|email';
|
||||
$rules['contacts.*.password'] = [
|
||||
@ -66,6 +66,10 @@ class StoreClientRequest extends Request
|
||||
$rules['hosted_clients'] = new CanStoreClientsRule($this->company_id);
|
||||
}
|
||||
|
||||
$rules['number'] = ['nullable',Rule::unique('clients')->where('company_id', auth()->user()->company()->id)];
|
||||
$rules['id_number'] = ['nullable',Rule::unique('clients')->where('company_id', auth()->user()->company()->id)];
|
||||
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
@ -122,7 +126,7 @@ class StoreClientRequest extends Request
|
||||
public function messages()
|
||||
{
|
||||
return [
|
||||
'unique' => ctrans('validation.unique', ['attribute' => 'email']),
|
||||
// 'unique' => ctrans('validation.unique', ['attribute' => ['email','number']),
|
||||
//'required' => trans('validation.required', ['attribute' => 'email']),
|
||||
'contacts.*.email.required' => ctrans('validation.email', ['attribute' => 'email']),
|
||||
];
|
||||
|
@ -16,6 +16,7 @@ use App\Http\Requests\Request;
|
||||
use App\Http\ValidationRules\ValidClientGroupSettingsRule;
|
||||
use App\Utils\Traits\ChecksEntityStatus;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class UpdateClientRequest extends Request
|
||||
{
|
||||
@ -52,7 +53,14 @@ class UpdateClientRequest extends Request
|
||||
$rules['country_id'] = 'integer|nullable';
|
||||
$rules['shipping_country_id'] = 'integer|nullable';
|
||||
//$rules['id_number'] = 'unique:clients,id_number,,id,company_id,' . auth()->user()->company()->id;
|
||||
$rules['id_number'] = 'unique:clients,id_number,'.$this->id.',id,company_id,'.$this->company_id;
|
||||
//$rules['id_number'] = 'unique:clients,id_number,'.$this->id.',id,company_id,'.$this->company_id;
|
||||
|
||||
if($this->id_number)
|
||||
$rules['id_number'] = Rule::unique('clients')->where('company_id', auth()->user()->company()->id)->ignore($this->client->id);
|
||||
|
||||
if($this->number)
|
||||
$rules['number'] = Rule::unique('clients')->where('company_id', auth()->user()->company()->id)->ignore($this->client->id);
|
||||
|
||||
$rules['settings'] = new ValidClientGroupSettingsRule();
|
||||
$rules['contacts.*.email'] = 'bail|nullable|distinct|sometimes|email';
|
||||
$rules['contacts.*.password'] = [
|
||||
@ -72,7 +80,6 @@ class UpdateClientRequest extends Request
|
||||
public function messages()
|
||||
{
|
||||
return [
|
||||
'unique' => ctrans('validation.unique', ['attribute' => 'email']),
|
||||
'email' => ctrans('validation.email', ['attribute' => 'email']),
|
||||
'name.required' => ctrans('validation.required', ['attribute' => 'name']),
|
||||
'required' => ctrans('validation.required', ['attribute' => 'email']),
|
||||
|
@ -16,6 +16,7 @@ use App\Http\Requests\Request;
|
||||
use App\Utils\Traits\ChecksEntityStatus;
|
||||
use App\Utils\Traits\CleanLineItems;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class UpdateCreditRequest extends Request
|
||||
{
|
||||
@ -52,9 +53,8 @@ class UpdateCreditRequest extends Request
|
||||
$rules['documents'] = 'file|mimes:png,ai,svg,jpeg,tiff,pdf,gif,psd,txt,doc,xls,ppt,xlsx,docx,pptx|max:20000';
|
||||
}
|
||||
|
||||
if ($this->input('number')) {
|
||||
$rules['number'] = 'unique:credits,number,'.$this->id.',id,company_id,'.$this->credit->company_id;
|
||||
}
|
||||
if($this->number)
|
||||
$rules['number'] = Rule::unique('credits')->where('company_id', auth()->user()->company()->id)->ignore($this->credit->id);
|
||||
|
||||
$rules['line_items'] = 'array';
|
||||
|
||||
|
@ -35,10 +35,9 @@ class StoreExpenseRequest extends Request
|
||||
{
|
||||
$rules = [];
|
||||
|
||||
if (isset($this->number)) {
|
||||
if ($this->number)
|
||||
$rules['number'] = Rule::unique('expenses')->where('company_id', auth()->user()->company()->id);
|
||||
}
|
||||
|
||||
|
||||
if(!empty($this->client_id))
|
||||
$rules['client_id'] = 'bail|sometimes|exists:clients,id,company_id,'.auth()->user()->company()->id;
|
||||
|
||||
|
@ -16,6 +16,7 @@ use App\Http\ValidationRules\Invoice\LockedInvoiceRule;
|
||||
use App\Utils\Traits\ChecksEntityStatus;
|
||||
use App\Utils\Traits\CleanLineItems;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class UpdateInvoiceRequest extends Request
|
||||
{
|
||||
@ -49,10 +50,8 @@ class UpdateInvoiceRequest extends Request
|
||||
|
||||
$rules['id'] = new LockedInvoiceRule($this->invoice);
|
||||
|
||||
// if ($this->input('number') && strlen($this->input('number')) >= 1) {
|
||||
if ($this->input('number')) {
|
||||
$rules['number'] = 'unique:invoices,number,'.$this->id.',id,company_id,'.$this->invoice->company_id;
|
||||
}
|
||||
if($this->number)
|
||||
$rules['number'] = Rule::unique('invoices')->where('company_id', auth()->user()->company()->id)->ignore($this->invoice->id);
|
||||
|
||||
$rules['line_items'] = 'array';
|
||||
|
||||
|
@ -16,6 +16,7 @@ use App\Http\ValidationRules\PaymentAppliedValidAmount;
|
||||
use App\Http\ValidationRules\ValidCreditsPresentRule;
|
||||
use App\Utils\Traits\ChecksEntityStatus;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class UpdatePaymentRequest extends Request
|
||||
{
|
||||
@ -35,12 +36,14 @@ class UpdatePaymentRequest extends Request
|
||||
public function rules()
|
||||
{
|
||||
$rules = [
|
||||
'number' => 'nullable|unique:payments,number,'.$this->id.',id,company_id,'.$this->payment->company_id,
|
||||
'invoices' => ['array', new PaymentAppliedValidAmount, new ValidCreditsPresentRule],
|
||||
'invoices.*.invoice_id' => 'distinct',
|
||||
'documents' => 'mimes:png,ai,svg,jpeg,tiff,pdf,gif,psd,txt,doc,xls,ppt,xlsx,docx,pptx',
|
||||
];
|
||||
|
||||
if($this->number)
|
||||
$rules['number'] = Rule::unique('payments')->where('company_id', auth()->user()->company()->id)->ignore($this->payment->id);
|
||||
|
||||
if ($this->input('documents') && is_array($this->input('documents'))) {
|
||||
$documents = count($this->input('documents'));
|
||||
|
||||
|
@ -15,6 +15,7 @@ use App\Http\Requests\Request;
|
||||
use App\Utils\Traits\ChecksEntityStatus;
|
||||
use App\Utils\Traits\CleanLineItems;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class UpdateQuoteRequest extends Request
|
||||
{
|
||||
@ -46,9 +47,8 @@ class UpdateQuoteRequest extends Request
|
||||
$rules['documents'] = 'file|mimes:png,ai,svg,jpeg,tiff,pdf,gif,psd,txt,doc,xls,ppt,xlsx,docx,pptx|max:20000';
|
||||
}
|
||||
|
||||
if ($this->input('number')) {
|
||||
$rules['number'] = 'unique:quotes,number,'.$this->id.',id,company_id,'.$this->quote->company_id;
|
||||
}
|
||||
if($this->number)
|
||||
$rules['number'] = Rule::unique('quotes')->where('company_id', auth()->user()->company()->id)->ignore($this->quote->id);
|
||||
|
||||
$rules['line_items'] = 'array';
|
||||
|
||||
|
@ -16,6 +16,7 @@ use App\Utils\Traits\ChecksEntityStatus;
|
||||
use App\Utils\Traits\CleanLineItems;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class UpdateRecurringInvoiceRequest extends Request
|
||||
{
|
||||
@ -47,9 +48,9 @@ class UpdateRecurringInvoiceRequest extends Request
|
||||
$rules['documents'] = 'file|mimes:png,ai,svg,jpeg,tiff,pdf,gif,psd,txt,doc,xls,ppt,xlsx,docx,pptx|max:20000';
|
||||
}
|
||||
|
||||
if ($this->input('number')) {
|
||||
$rules['number'] = 'unique:recurring_invoices,number,'.$this->recurring_invoice->id.',id,company_id,'.$this->recurring_invoice->company_id;
|
||||
}
|
||||
if($this->number)
|
||||
$rules['number'] = Rule::unique('recurring_invoices')->where('company_id', auth()->user()->company()->id)->ignore($this->recurring_invoice->id);
|
||||
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ namespace App\Http\Requests\RecurringQuote;
|
||||
use App\Http\Requests\Request;
|
||||
use App\Utils\Traits\ChecksEntityStatus;
|
||||
use App\Utils\Traits\CleanLineItems;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class UpdateRecurringQuoteRequest extends Request
|
||||
{
|
||||
@ -47,6 +48,9 @@ class UpdateRecurringQuoteRequest extends Request
|
||||
|
||||
$input['line_items'] = isset($input['line_items']) ? $this->cleanItems($input['line_items']) : [];
|
||||
|
||||
if($this->number)
|
||||
$rules['number'] = Rule::unique('recurring_quotes')->where('company_id', auth()->user()->company()->id)->ignore($this->recurring_quote->id);
|
||||
|
||||
$this->replace($input);
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
namespace App\Http\Requests\TaxRate;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class UpdateTaxRateRequest extends Request
|
||||
{
|
||||
@ -27,10 +28,14 @@ class UpdateTaxRateRequest extends Request
|
||||
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
// 'name' => 'unique:tax_rates,name,'.$this->tax_rate->name.',id,company_id,'.auth()->user()->companyId(),
|
||||
'name' => 'unique:tax_rates,name,'.$this->id.',id,company_id,'.$this->company_id,
|
||||
'rate' => 'numeric',
|
||||
];
|
||||
$rules = [];
|
||||
|
||||
$rules['rate'] = 'numeric';
|
||||
|
||||
if($this->number)
|
||||
$rules['number'] = Rule::unique('tax_rates')->where('company_id', auth()->user()->company()->id)->ignore($this->tax_rate->id);
|
||||
|
||||
return $rules;
|
||||
|
||||
}
|
||||
}
|
||||
|
19
app/Http/Requests/Vendor/UpdateVendorRequest.php
vendored
19
app/Http/Requests/Vendor/UpdateVendorRequest.php
vendored
@ -14,6 +14,7 @@ namespace App\Http\Requests\Vendor;
|
||||
use App\Http\Requests\Request;
|
||||
use App\Utils\Traits\ChecksEntityStatus;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class UpdateVendorRequest extends Request
|
||||
{
|
||||
@ -35,18 +36,15 @@ class UpdateVendorRequest extends Request
|
||||
/* Ensure we have a client name, and that all emails are unique*/
|
||||
|
||||
$rules['country_id'] = 'integer|nullable';
|
||||
//$rules['id_number'] = 'unique:clients,id_number,,id,company_id,' . auth()->user()->company()->id;
|
||||
$rules['id_number'] = 'unique:clients,id_number,'.$this->id.',id,company_id,'.$this->company_id;
|
||||
|
||||
if($this->number)
|
||||
$rules['number'] = Rule::unique('vendors')->where('company_id', auth()->user()->company()->id)->ignore($this->vendor->id);
|
||||
|
||||
if($this->id_number)
|
||||
$rules['id_number'] = Rule::unique('vendors')->where('company_id', auth()->user()->company()->id)->ignore($this->vendor->id);
|
||||
|
||||
$rules['contacts.*.email'] = 'nullable|distinct';
|
||||
|
||||
$contacts = request('contacts');
|
||||
|
||||
if (is_array($contacts)) {
|
||||
// for ($i = 0; $i < count($contacts); $i++) {
|
||||
// // $rules['contacts.' . $i . '.email'] = 'nullable|email|unique:client_contacts,email,' . isset($contacts[$i]['id'].',company_id,'.$this->company_id);
|
||||
// //$rules['contacts.' . $i . '.email'] = 'nullable|email';
|
||||
// }
|
||||
}
|
||||
|
||||
return $rules;
|
||||
}
|
||||
@ -54,7 +52,6 @@ class UpdateVendorRequest extends Request
|
||||
public function messages()
|
||||
{
|
||||
return [
|
||||
'unique' => ctrans('validation.unique', ['attribute' => 'email']),
|
||||
'email' => ctrans('validation.email', ['attribute' => 'email']),
|
||||
'name.required' => ctrans('validation.required', ['attribute' => 'name']),
|
||||
'required' => ctrans('validation.required', ['attribute' => 'email']),
|
||||
|
@ -37,6 +37,7 @@ class Project extends BaseModel
|
||||
'custom_value4',
|
||||
'assigned_user_id',
|
||||
'color',
|
||||
'number',
|
||||
];
|
||||
|
||||
public function getEntityType()
|
||||
|
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddUniqueConstraintsOnAllEntities extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('expenses', function (Blueprint $table) {
|
||||
$table->unique(['company_id', 'number']);
|
||||
});
|
||||
|
||||
Schema::table('tasks', function (Blueprint $table) {
|
||||
$table->unique(['company_id', 'number']);
|
||||
});
|
||||
|
||||
Schema::table('vendors', function (Blueprint $table) {
|
||||
$table->unique(['company_id', 'number']);
|
||||
});
|
||||
|
||||
Schema::table('payments', function (Blueprint $table) {
|
||||
$table->unique(['company_id', 'number']);
|
||||
});
|
||||
|
||||
Schema::table('projects', function (Blueprint $table) {
|
||||
$table->unique(['company_id', 'number']);
|
||||
});
|
||||
|
||||
Schema::table('clients', function (Blueprint $table) {
|
||||
$table->unique(['company_id', 'number']);
|
||||
});
|
||||
|
||||
Schema::table('payment_hashes', function (Blueprint $table) {
|
||||
$table->unique(['hash']);
|
||||
});
|
||||
|
||||
Schema::table('recurring_invoices', function (Blueprint $table) {
|
||||
$table->string('number')->change();
|
||||
$table->unique(['company_id', 'number']);
|
||||
});
|
||||
|
||||
Schema::table('recurring_invoice_invitations', function (Blueprint $table) {
|
||||
$table->unique(['client_contact_id', 'recurring_invoice_id'],'recur_invoice_client_unique');
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
@ -54,6 +54,28 @@ class ClientApiTest extends TestCase
|
||||
$response->assertStatus(200);
|
||||
}
|
||||
|
||||
public function testDuplicateNumberCatch()
|
||||
{
|
||||
$data = [
|
||||
'name' => $this->faker->firstName,
|
||||
'number' => 'iamaduplicate',
|
||||
];
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->post('/api/v1/clients', $data);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->post('/api/v1/clients', $data);
|
||||
|
||||
$response->assertStatus(302);
|
||||
}
|
||||
|
||||
public function testClientPut()
|
||||
{
|
||||
$data = [
|
||||
@ -67,6 +89,20 @@ class ClientApiTest extends TestCase
|
||||
])->put('/api/v1/clients/'.$this->encodePrimaryKey($this->client->id), $data);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->put('/api/v1/clients/'.$this->encodePrimaryKey($this->client->id), $data);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->post('/api/v1/clients/', $data);
|
||||
|
||||
$response->assertStatus(302);
|
||||
}
|
||||
|
||||
public function testClientGet()
|
||||
|
@ -131,4 +131,80 @@ class CreditTest extends TestCase
|
||||
|
||||
$response->assertStatus(200);
|
||||
}
|
||||
|
||||
public function testDuplicateNumberCatch()
|
||||
{
|
||||
$data = [
|
||||
'status_id' => 1,
|
||||
'number' => 'dfdfd',
|
||||
'discount' => 0,
|
||||
'is_amount_discount' => 1,
|
||||
'number' => '3434343',
|
||||
'public_notes' => 'notes',
|
||||
'is_deleted' => 0,
|
||||
'custom_value1' => 0,
|
||||
'custom_value2' => 0,
|
||||
'custom_value3' => 0,
|
||||
'custom_value4' => 0,
|
||||
'status' => 1,
|
||||
'client_id' => $this->encodePrimaryKey($this->client->id),
|
||||
];
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->post('/api/v1/credits', $data);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->post('/api/v1/credits', $data);
|
||||
|
||||
$response->assertStatus(302);
|
||||
}
|
||||
|
||||
public function testCreditPut()
|
||||
{
|
||||
$data = [
|
||||
'status_id' => 1,
|
||||
'number' => 'dfdfd',
|
||||
'discount' => 0,
|
||||
'is_amount_discount' => 1,
|
||||
'number' => '3434343',
|
||||
'public_notes' => 'notes',
|
||||
'is_deleted' => 0,
|
||||
'custom_value1' => 0,
|
||||
'custom_value2' => 0,
|
||||
'custom_value3' => 0,
|
||||
'custom_value4' => 0,
|
||||
'status' => 1,
|
||||
'client_id' => $this->encodePrimaryKey($this->client->id),
|
||||
];
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->put('/api/v1/credits/'.$this->encodePrimaryKey($this->credit->id), $data);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->put('/api/v1/credits/'.$this->encodePrimaryKey($this->credit->id), $data);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->post('/api/v1/credits/', $data);
|
||||
|
||||
$response->assertStatus(302);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -57,11 +57,34 @@ class ExpenseApiTest extends TestCase
|
||||
$this->assertNotEmpty($arr['data']['number']);
|
||||
}
|
||||
|
||||
public function testDuplicateNumberCatch()
|
||||
{
|
||||
$data = [
|
||||
'public_notes' => $this->faker->firstName,
|
||||
'number' => 'iamaduplicate',
|
||||
];
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->post('/api/v1/expenses', $data);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->post('/api/v1/expenses', $data);
|
||||
|
||||
$response->assertStatus(302);
|
||||
}
|
||||
|
||||
|
||||
public function testExpensePut()
|
||||
{
|
||||
$data = [
|
||||
'public_notes' => $this->faker->firstName,
|
||||
'id_number' => 'Coolio',
|
||||
'number' => 'Coolio',
|
||||
];
|
||||
|
||||
$response = $this->withHeaders([
|
||||
@ -70,6 +93,22 @@ class ExpenseApiTest extends TestCase
|
||||
])->put('/api/v1/expenses/'.$this->encodePrimaryKey($this->expense->id), $data);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->put('/api/v1/expenses/'.$this->encodePrimaryKey($this->expense->id), $data);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->post('/api/v1/expenses/', $data);
|
||||
|
||||
$response->assertStatus(302);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function testExpenseGet()
|
||||
|
@ -125,8 +125,15 @@ class InvoiceTest extends TestCase
|
||||
])->post('/api/v1/invoices/', $invoice)
|
||||
->assertStatus(200);
|
||||
|
||||
//test that the same request should produce a validation error due
|
||||
//to duplicate number being used.
|
||||
|
||||
$arr = $response->json();
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->put('/api/v1/invoices/'.$arr['data']['id'], $invoice)
|
||||
->assertStatus(200);
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
|
@ -104,6 +104,15 @@ class PaymentTest extends TestCase
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->put('/api/v1/payments/'.$this->encodePrimaryKey($Payment->id), $Payment->toArray());
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
|
@ -16,6 +16,7 @@ use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Tests\MockAccountData;
|
||||
use Tests\TestCase;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
/**
|
||||
* @test
|
||||
@ -56,6 +57,7 @@ class ProjectApiTest extends TestCase
|
||||
$data = [
|
||||
'name' => $this->faker->firstName,
|
||||
'client_id' => $this->client->hashed_id,
|
||||
'number' => 'duplicate',
|
||||
];
|
||||
|
||||
$response = $this->withHeaders([
|
||||
@ -64,6 +66,26 @@ class ProjectApiTest extends TestCase
|
||||
])->post('/api/v1/projects', $data);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$arr = $response->json();
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->put('/api/v1/projects/'.$arr['data']['id'], $data)->assertStatus(200);
|
||||
|
||||
try{
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->post('/api/v1/projects', $data);
|
||||
}
|
||||
catch(ValidationException $e){
|
||||
$response->assertStatus(302);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function testProjectPut()
|
||||
|
@ -86,7 +86,8 @@ class QuoteTest extends TestCase
|
||||
|
||||
$quote_update = [
|
||||
'status_id' => Quote::STATUS_APPROVED,
|
||||
// 'client_id' => $this->encodePrimaryKey($quote->client_id),
|
||||
'client_id' => $this->encodePrimaryKey($this->quote->client_id),
|
||||
'number' => 'Rando',
|
||||
];
|
||||
|
||||
$this->assertNotNull($this->quote);
|
||||
@ -98,6 +99,22 @@ class QuoteTest extends TestCase
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->put('/api/v1/quotes/'.$this->encodePrimaryKey($this->quote->id), $quote_update);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->post('/api/v1/quotes/', $quote_update);
|
||||
|
||||
$response->assertStatus(302);
|
||||
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
|
@ -117,6 +117,7 @@ class RecurringInvoiceTest extends TestCase
|
||||
$RecurringInvoice_update = [
|
||||
'status_id' => RecurringInvoice::STATUS_DRAFT,
|
||||
'client_id' => $this->encodePrimaryKey($RecurringInvoice->client_id),
|
||||
'number' => 'customnumber'
|
||||
];
|
||||
|
||||
$this->assertNotNull($RecurringInvoice);
|
||||
@ -127,6 +128,26 @@ class RecurringInvoiceTest extends TestCase
|
||||
])->put('/api/v1/recurring_invoices/'.$this->encodePrimaryKey($RecurringInvoice->id), $RecurringInvoice_update)
|
||||
->assertStatus(200);
|
||||
|
||||
$arr = $response->json();
|
||||
|
||||
$this->assertEquals('customnumber', $arr['data']['number']);
|
||||
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->put('/api/v1/recurring_invoices/'.$this->encodePrimaryKey($RecurringInvoice->id), $RecurringInvoice_update)
|
||||
->assertStatus(200);
|
||||
|
||||
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->post('/api/v1/recurring_invoices/', $RecurringInvoice_update)
|
||||
->assertStatus(302);
|
||||
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
|
@ -14,6 +14,7 @@ use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Tests\MockAccountData;
|
||||
use Tests\TestCase;
|
||||
|
||||
@ -44,6 +45,7 @@ class TaskApiTest extends TestCase
|
||||
{
|
||||
$data = [
|
||||
'description' => $this->faker->firstName,
|
||||
'number' => 'taskynumber'
|
||||
];
|
||||
|
||||
$response = $this->withHeaders([
|
||||
@ -54,6 +56,27 @@ class TaskApiTest extends TestCase
|
||||
$arr = $response->json();
|
||||
$response->assertStatus(200);
|
||||
|
||||
$this->assertEquals('taskynumber', $arr['data']['number']);
|
||||
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->put('/api/v1/tasks/'.$arr['data']['id'], $data);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
try{
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->post('/api/v1/tasks', $data);
|
||||
|
||||
$arr = $response->json();
|
||||
}catch(ValidationException $e){
|
||||
$response->assertStatus(302);
|
||||
}
|
||||
|
||||
$this->assertNotEmpty($arr['data']['number']);
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@ use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Tests\MockAccountData;
|
||||
use Tests\TestCase;
|
||||
|
||||
@ -59,6 +60,7 @@ class VendorApiTest extends TestCase
|
||||
$data = [
|
||||
'name' => $this->faker->firstName,
|
||||
'id_number' => 'Coolio',
|
||||
'number' => 'wiggles'
|
||||
];
|
||||
|
||||
$response = $this->withHeaders([
|
||||
@ -67,6 +69,33 @@ class VendorApiTest extends TestCase
|
||||
])->put('/api/v1/vendors/'.$this->encodePrimaryKey($this->vendor->id), $data);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$arr = $response->json();
|
||||
|
||||
$this->assertEquals('Coolio', $arr['data']['id_number']);
|
||||
$this->assertEquals('wiggles', $arr['data']['number']);
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->put('/api/v1/vendors/'.$this->encodePrimaryKey($this->vendor->id), $data);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
|
||||
try{
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->post('/api/v1/vendors/', $data);
|
||||
|
||||
|
||||
}catch(ValidationException $e){
|
||||
|
||||
$response->assertStatus(302);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function testVendorGet()
|
||||
|
Loading…
x
Reference in New Issue
Block a user