Merge pull request #418 from berkaygure/feature/add-tests

Added Customers and Items tests.
This commit is contained in:
Cüneyt Şentürk 2018-07-26 11:28:38 +03:00 committed by GitHub
commit 1538507e24
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 1756 additions and 171 deletions

24
.env.testing Normal file
View File

@ -0,0 +1,24 @@
APP_NAME=Akaunting
APP_ENV=testing
APP_LOCALE=en-GB
APP_INSTALLED=false
APP_KEY=base64:xBC+BxlC7sXhYAtpTZv8TYAHqoPgsJaXL0S5Id6BbBc=
APP_DEBUG=true
APP_LOG_LEVEL=debug
APP_URL=http://akaunting.test
DB_CONNECTION=sqlite
DB_DATABASE=:memory:
DB_PREFIX=
BROADCAST_DRIVER=log
CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_DRIVER=database
MAIL_DRIVER=mail
MAIL_HOST=localhost
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null

View File

@ -36,7 +36,7 @@ class Info
{
return phpversion();
}
public static function mysqlVersion()
{
if(env('DB_CONNECTION') === 'mysql')

View File

@ -38,7 +38,8 @@
"tucker-eric/eloquentfilter": "1.1.*"
},
"require-dev": {
"fzaninotto/faker": "1.6.*"
"fzaninotto/faker": "1.6.*",
"phpunit/phpunit": "^7.0"
},
"autoload": {
"classmap": [

1490
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,28 @@
<?php
use Faker\Generator;
use App\Models\Auth\User;
use App\Models\Common\Item;
use App\Models\Common\Company;
use Illuminate\Database\Eloquent\Factory;
/** @var Factory $factory */
$factory->define(Item::class, function (Generator $faker) {
/** @var User $user */
$user = User::first();
/** @var Company $company */
$company = $user->companies()->first();
return [
'name' => $faker->title,
'sku' => $faker->languageCode,
'company_id' => $company->id,
'description' => $faker->text(100),
'purchase_price' => $faker->randomFloat(2,10,20),
'sale_price' => $faker->randomFloat(2,10,20),
'quantity' => $faker->randomNumber(2),
'category_id' => $company->categories()->first()->id,
'tax_id' => $company->taxes()->first()->id,
'enabled' => $this->faker->boolean ? 1 : 0
];
});

View File

@ -12,7 +12,7 @@
*/
/** @var \Illuminate\Database\Eloquent\Factory $factory */
$factory->define(App\User::class, function (Faker\Generator $faker) {
$factory->define(\App\Models\Auth\User::class, function (Faker\Generator $faker) {
static $password;
return [

View File

@ -20,19 +20,19 @@ class AddCategoryColumnInvoicesBills extends Migration
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('invoices', function ($table) {
$table->dropColumn('category_id');
});
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('invoices', function ($table) {
$table->dropColumn('category_id');
});
Schema::table('bills', function ($table) {
$table->dropColumn('category_id');
});
}
Schema::table('bills', function ($table) {
$table->dropColumn('category_id');
});
}
}

View File

@ -2,6 +2,7 @@
namespace Database\Seeds;
use App\Models\Common\Company;
use App\Models\Model;
use App\Models\Banking\Account;
use Setting;

View File

@ -2,6 +2,7 @@
namespace Database\Seeds;
use App\Models\Common\Company;
use App\Models\Model;
use App\Models\Expense\BillStatus;
@ -25,7 +26,7 @@ class BillStatuses extends Seeder
private function create()
{
$company_id = $this->command->argument('company');
$company_id = $this->command->argument('company');
$rows = [
[

View File

@ -2,6 +2,7 @@
namespace Database\Seeds;
use App\Models\Common\Company;
use App\Models\Model;
use App\Models\Setting\Category;
@ -25,7 +26,7 @@ class Categories extends Seeder
private function create()
{
$company_id = $this->command->argument('company');
$company_id = $this->command->argument('company');
$rows = [
[

View File

@ -2,6 +2,7 @@
namespace Database\Seeds;
use App\Models\Common\Company;
use App\Models\Model;
use App\Models\Setting\Currency;
@ -25,7 +26,7 @@ class Currencies extends Seeder
private function create()
{
$company_id = $this->command->argument('company');
$company_id = $this->command->argument('company');
$rows = [
[

View File

@ -11,6 +11,6 @@ class DatabaseSeeder extends Seeder
*/
public function run()
{
//
}
}

View File

@ -2,6 +2,7 @@
namespace Database\Seeds;
use App\Models\Common\Company;
use App\Models\Model;
use App\Models\Income\InvoiceStatus;
@ -25,7 +26,7 @@ class InvoiceStatuses extends Seeder
private function create()
{
$company_id = $this->command->argument('company');
$company_id = $this->command->argument('company');
$rows = [
[

View File

@ -2,6 +2,7 @@
namespace Database\Seeds;
use App\Models\Common\Company;
use App\Models\Model;
use Artisan;
@ -25,7 +26,7 @@ class Modules extends Seeder
private function create()
{
$company_id = $this->command->argument('company');
$company_id = $this->command->argument('company');
Artisan::call('module:install', ['alias' => 'offlinepayment', 'company_id' => $company_id]);
Artisan::call('module:install', ['alias' => 'paypalstandard', 'company_id' => $company_id]);

View File

@ -10,7 +10,7 @@ use Illuminate\Database\Seeder;
class Roles extends Seeder
{
/**
/**
* Run the database seeds.
*
* @return void

View File

@ -2,6 +2,7 @@
namespace Database\Seeds;
use App\Models\Common\Company;
use App\Models\Model;
use Illuminate\Database\Seeder;
use Setting;
@ -24,7 +25,7 @@ class Settings extends Seeder
private function create()
{
$company_id = $this->command->argument('company');
$company_id = $this->command->argument('company');
Setting::set([
'general.date_format' => 'd M Y',

View File

@ -2,6 +2,7 @@
namespace Database\Seeds;
use App\Models\Common\Company;
use App\Models\Model;
use App\Models\Setting\Tax;
@ -25,7 +26,7 @@ class Taxes extends Seeder
private function create()
{
$company_id = $this->command->argument('company');
$company_id = $this->command->argument('company');
$rows = [
[

32
phpunit.xml Normal file
View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false">
<testsuites>
<testsuite name="Feature">
<directory suffix="Test.php">./tests/Feature</directory>
</testsuite>
<testsuite name="Unit">
<directory suffix="Test.php">./tests/Unit</directory>
</testsuite>
</testsuites>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">./app</directory>
</whitelist>
</filter>
<php>
<env name="APP_ENV" value="testing"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="QUEUE_DRIVER" value="sync"/>
<env name="MAIL_DRIVER" value="array"/>
</php>
</phpunit>

View File

@ -0,0 +1,77 @@
<?php
namespace Tests\Feature\Common;
use App\Models\Common\Item;
use Illuminate\Http\UploadedFile;
use Tests\Feature\FeatureTestCase;
class ItemsTest extends FeatureTestCase
{
public function testItShouldBeShowTheItemsPage()
{
$this
->loginAs()
->get(route('items.index'))
->assertStatus(200)
->assertSee('Items');
}
public function testItShouldBeShowCreateItemPage()
{
$this
->loginAs()
->get(route('items.create'))
->assertStatus(200)
->assertSee('New Item');
}
public function testItShouldStoreAnItem()
{
$picture = UploadedFile::fake()->create('image.jpg');
$item = [
'name' => $this->faker->title,
'sku' => $this->faker->languageCode,
'picture' => $picture,
'description' => $this->faker->text(100),
'purchase_price' => $this->faker->randomFloat(2,10,20),
'sale_price' => $this->faker->randomFloat(2,10,20),
'quantity' => $this->faker->randomNumber(2),
'category_id' => $this->company->categories()->first()->id,
'tax_id' => $this->company->taxes()->first()->id,
'enabled' => $this->faker->boolean ? 1 : 0
];
$this
->loginAs()
->post(route('items.store'), $item)
->assertStatus(302)
->assertRedirect(route('items.index'));
$this->assertFlashLevel('success');
}
public function testItShouldEditItem()
{
$item = factory(Item::class)->create();
$this
->loginAs()
->get(route('items.edit', ['item' => $item]))
->assertStatus(200)
->assertSee($item->name);
}
public function testItShouldDeleteItem()
{
$item = factory(Item::class)->create();
$this
->loginAs()
->delete(route('items.destroy', ['item' => $item]))
->assertStatus(302)
->assertRedirect(route('items.index'));
$this->assertFlashLevel('success');
}
}

View File

@ -2,21 +2,21 @@
namespace Tests\Feature;
use App\Models\Auth\User;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class ExampleTest extends TestCase
{
/**
/**
* A basic test example.
*
* @return void
*/
public function testBasicTest()
{
$response = $this->get('/');
$response = $this
->actingAs(User::first())
->get('/');
$response->assertStatus(200);
}

View File

@ -0,0 +1,64 @@
<?php
/**
* Created by PhpStorm.
* User: bgure
* Date: 13.07.2018
* Time: 19:44
*/
namespace Tests\Feature;
use App\Models\Auth\User;
use App\Models\Common\Company;
use Faker\Factory;
use Tests\TestCase;
abstract class FeatureTestCase extends TestCase
{
/**
* @var \Faker\Generator
*/
protected $faker;
/** @var User */
protected $user;
/** @var Company */
protected $company;
protected function setUp()
{
parent::setUp();
$this->faker = Factory::create();
$this->user = User::first();
$this->company = $this->user->first()->companies()->first();
}
/**
* Empty for default user.
*
* @param User|null $user
* @param Company|null $company
* @return FeatureTestCase
*/
public function loginAs(User $user = null, Company $company = null)
{
if(!$user) $user = $this->user;
if(!$company) $company = $user->companies()->first();
$this->startSession();
return $this->actingAs($user)
->withSession(['company_id' => $company->id]);
}
public function assertFlashLevel($excepted)
{
$flash["level"] = null;
if($flashMessage = session('flash_notification'))
{
$flash = $flashMessage->first();
}
$this->assertEquals($excepted, $flash['level']);
}
}

View File

@ -0,0 +1,127 @@
<?php
namespace Tests\Feature\Incomes;
use App\Models\Auth\User;
use App\Models\Income\Customer;
use Tests\Feature\FeatureTestCase;
class CustomersTest extends FeatureTestCase
{
public function testItShouldCreateOnlyCustomerWithoutUser()
{
$customer = $this->getCustomerData();
$this->loginAs()
->post(route("customers.store"), $customer)
->assertStatus(302)
->assertRedirect(route("customers.index"));
$this->assertFlashLevel("success");
}
public function testItShouldCreateCustomerWithUser()
{
$customerWithUser = $this->getCustomerDataWithUser();
$this->loginAs()
->post(route("customers.store"), $customerWithUser)
->assertStatus(302)
->assertRedirect(route("customers.index"));
$this->assertFlashLevel("success");
$user = User::where("email", $customerWithUser["email"])->first();
$this->assertNotNull($user);
$this->assertEquals($customerWithUser["email"], $user->email);
}
public function testItShouldNotCreateCustomerWithExistsUser()
{
$customerWithUser = $this->getCustomerDataWithUser();
User::create($customerWithUser);
$this->loginAs()
->post(route('customers.store'), $customerWithUser)
->assertSessionHasErrors(['email']);
}
public function testItShouldBeSeeTheCustomersPage()
{
$customer = Customer::create($this->getCustomerData());
$this
->loginAs()
->get(route('customers.index'))
->assertStatus(200)
->assertSee($customer->email);
}
public function testItShouldBeSeeTheEditCustomersPage()
{
$customer = Customer::create($this->getCustomerData());
$this
->loginAs()
->get(route('customers.edit', ['customer' => $customer->id]))
->assertStatus(200)
->assertSee($customer->email)
->assertSee($customer->name);
}
public function testItShouldUpdateTheCustomer()
{
$customerData = $this->getCustomerData();
$customer = Customer::create($customerData);
$customerData["name"] = $this->faker->name;
$this
->loginAs()
->patch(route('customers.update', $customer->id), $customerData)
->assertStatus(302)
->assertRedirect(route('customers.index'));
$this->assertFlashLevel('success');
}
public function testItShouldDeleteTheCustomer()
{
$customer = Customer::create($this->getCustomerData());
$this->loginAs()
->delete(route('customers.destroy', $customer->id))
->assertStatus(302)
->assertRedirect(route('customers.index'));
$this->assertFlashLevel('success');
}
public function testItShouldNotDeleteIfItHaveRelations()
{
$this->assertTrue(true);
//TODO : This will write after done invoice and revenues tests.
}
// Helpers
private function getCustomerData()
{
return [
'company_id' => $this->company->id,
'name' => $this->faker->name,
'email' => $this->faker->email,
'tax_number' => $this->faker->buildingNumber,
'phone' => $this->faker->phoneNumber,
'address' => $this->faker->streetAddress,
'website' => 'www.akaunting.com',
'currency_code' => $this->company->currencies()->first()->code,
'enabled' => $this->faker->boolean ? 1 : 0
];
}
private function getCustomerDataWithUser()
{
$password = $this->faker->password;
return $this->getCustomerData() + [
'create_user' => 1,
'locale' => 'en-GB',
'password' => $password,
'password_confirmation' => $password
];
}
}

View File

@ -2,9 +2,19 @@
namespace Tests;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
use Illuminate\Support\Facades\Artisan;
abstract class TestCase extends BaseTestCase
{
use CreatesApplication;
use CreatesApplication, DatabaseMigrations;
protected function setUp()
{
parent::setUp();
Artisan::call('db:seed', ['--class' => '\Database\Seeds\TestCompany', '--force' => true]);
Artisan::call('company:seed',['company' => 1]);
}
}

View File

@ -8,7 +8,7 @@ use Illuminate\Foundation\Testing\DatabaseTransactions;
class ExampleTest extends TestCase
{
/**
/**
* A basic test example.
*
* @return void