mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-05-24 02:14:21 -04:00
Tests, Multi-DB support for incoming URLs (#2466)
* Tests for authentication * Add db field to company table (required if we are doing jobs without an auth()->user() ) * Add Laravel Dusk for browser testing, add ability to set DB by incoming URL Hash
This commit is contained in:
parent
64041fb3cb
commit
dac1aa88d5
12
.travis.yml
12
.travis.yml
@ -44,13 +44,13 @@ before_script:
|
||||
- php artisan key:generate --no-interaction
|
||||
- sed -i '$a NINJA_DEV=true' .env
|
||||
# create the database and user
|
||||
- mysql -u root -e "create database IF NOT EXISTS ninja1;"
|
||||
- mysql -u root -e "create database IF NOT EXISTS ninja2;"
|
||||
- mysql -u root -e "GRANT ALL PRIVILEGES ON ninja1.* To 'ninja'@'localhost' IDENTIFIED BY 'ninja'; FLUSH PRIVILEGES;"
|
||||
- mysql -u root -e "GRANT ALL PRIVILEGES ON ninja2.* To 'ninja'@'localhost' IDENTIFIED BY 'ninja'; FLUSH PRIVILEGES;"
|
||||
- mysql -u root -e "create database IF NOT EXISTS ninja01;"
|
||||
- mysql -u root -e "create database IF NOT EXISTS ninja02;"
|
||||
- mysql -u root -e "GRANT ALL PRIVILEGES ON ninja01.* To 'ninja'@'localhost' IDENTIFIED BY 'ninja'; FLUSH PRIVILEGES;"
|
||||
- mysql -u root -e "GRANT ALL PRIVILEGES ON ninja02.* To 'ninja'@'localhost' IDENTIFIED BY 'ninja'; FLUSH PRIVILEGES;"
|
||||
# migrate and seed the database
|
||||
- php artisan migrate --database=db-ninja-1 --seed --no-interaction
|
||||
- php artisan migrate --database=db-ninja-2 --seed --no-interaction
|
||||
- php artisan migrate --database=db-ninja-01 --seed --no-interaction
|
||||
- php artisan migrate --database=db-ninja-02 --seed --no-interaction
|
||||
- php artisan optimize
|
||||
|
||||
# migrate and seed the database
|
||||
|
@ -4,6 +4,7 @@ namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\Account\CreateAccountRequest;
|
||||
use App\Jobs\Account\CreateAccount;
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class AccountController extends Controller
|
||||
|
27
app/Http/Controllers/Traits/VerifiesUserEmail.php
Normal file
27
app/Http/Controllers/Traits/VerifiesUserEmail.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Traits;
|
||||
|
||||
use App\Models\User;
|
||||
|
||||
trait VerifiesUserEmail
|
||||
{
|
||||
|
||||
public function confirm($code)
|
||||
{
|
||||
$user = User::where('confirmation_code', $code)->first();
|
||||
|
||||
if ($user) {
|
||||
|
||||
$user->email_verified_at = now();
|
||||
$user->confirmation_code = null;
|
||||
$user->save();
|
||||
|
||||
redirect()->route('user.dashboard')->with('message', trans('texts.security_confirmation'));
|
||||
|
||||
}
|
||||
|
||||
redirect()->route('login')->with('message', trans('texts.wrong_confirmation'));
|
||||
|
||||
}
|
||||
}
|
@ -2,29 +2,12 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Http\Controllers\Traits\VerifiesUserEmail;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class UserController extends Controller
|
||||
{
|
||||
use VerifiesUserEmail;
|
||||
|
||||
|
||||
|
||||
public function confirm($code)
|
||||
{
|
||||
$user = User::where('confirmation_code', '=', $code)->get()->first();
|
||||
|
||||
if ($user) {
|
||||
|
||||
$user->email_verified_at = now();
|
||||
$user->confirmation_code = null;
|
||||
$user->save();
|
||||
|
||||
redirect('user.dashboard')->with('message', trans('texts.security_confirmation'));
|
||||
|
||||
} else {
|
||||
|
||||
return Redirect::to('/login')->with('error', trans('texts.wrong_confirmation'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -44,6 +44,9 @@ class Kernel extends HttpKernel
|
||||
'db' => [
|
||||
\App\Http\Middleware\SetDb::class,
|
||||
],
|
||||
'url-db' => [
|
||||
\App\Http\Middleware\UrlSetDb::class,
|
||||
]
|
||||
];
|
||||
|
||||
/**
|
||||
|
36
app/Http/Middleware/UrlSetDb.php
Normal file
36
app/Http/Middleware/UrlSetDb.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Libraries\MultiDB;
|
||||
use Closure;
|
||||
use Hashids\Hashids;
|
||||
|
||||
class UrlSetDb
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
|
||||
public function handle($request, Closure $next, $hash)
|
||||
{
|
||||
|
||||
if (config('ninja.db.multi_db_enabled'))
|
||||
{
|
||||
$hashids = new Hashids(); //decoded output is _always_ an array.
|
||||
|
||||
//parse URL hash and set DB
|
||||
$segments = explode("-", $hash);
|
||||
|
||||
$hashed_db = $hashids->decode($segments[0]);
|
||||
|
||||
MultiDB::setDB(MultiDB::DB_PREFIX . $hashed_db[0]);
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
@ -18,9 +18,7 @@ class SetDb
|
||||
{
|
||||
if (config('ninja.db.multi_db_enabled'))
|
||||
{
|
||||
|
||||
MultiDB::setDB(auth()->user()->db);
|
||||
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
|
@ -41,23 +41,13 @@ class CreateAccount
|
||||
|
||||
$account = Account::create($this->request->toArray());
|
||||
|
||||
$user = CreateUser::dispatchNow($this->request, $account);
|
||||
|
||||
$company = CreateCompany::dispatchNow($this->request, $account);
|
||||
|
||||
UserCompany::create([
|
||||
'user_id' => $user->id,
|
||||
'account_id' => $account->id,
|
||||
'company_id' => $company->id,
|
||||
'is_admin' => true,
|
||||
'is_owner' => true,
|
||||
'permissions' => '',
|
||||
|
||||
]);
|
||||
$user = CreateUser::dispatchNow($this->request, $account, $company);
|
||||
|
||||
Auth::loginUsingId($user->id, true);
|
||||
|
||||
event(new AccountCreated());
|
||||
event(new AccountCreated($user));
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
namespace App\Jobs\User;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Models\UserCompany;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\Account;
|
||||
@ -15,16 +17,20 @@ class CreateUser
|
||||
protected $request;
|
||||
|
||||
protected $account;
|
||||
|
||||
protected $company;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
public function __construct(Request $request, $account)
|
||||
public function __construct(Request $request, $account, $company)
|
||||
{
|
||||
$this->request = $request;
|
||||
$this->account = $account;
|
||||
$this->company = $company;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -37,7 +43,7 @@ class CreateUser
|
||||
|
||||
$user = new User();
|
||||
$user->account_id = $this->account->id;
|
||||
$user->password = Hash::make($this->request->input('password'));
|
||||
$user->password = bcrypt($this->request->input('password'));
|
||||
$user->accepted_terms_version = config('ninja.terms_version');
|
||||
$user->confirmation_code = strtolower(str_random(RANDOM_KEY_LENGTH));
|
||||
$user->db = config('database.default');
|
||||
@ -45,6 +51,16 @@ class CreateUser
|
||||
$user->save();
|
||||
|
||||
|
||||
UserCompany::create([
|
||||
'user_id' => $user->id,
|
||||
'account_id' => $this->account->id,
|
||||
'company_id' => $this->company->id,
|
||||
'is_admin' => true,
|
||||
'is_owner' => true,
|
||||
'permissions' => '',
|
||||
|
||||
]);
|
||||
|
||||
return $user;
|
||||
}
|
||||
}
|
||||
|
@ -10,11 +10,9 @@ use App\Models\User;
|
||||
*/
|
||||
class MultiDB
|
||||
{
|
||||
const DB_PREFIX = 'db-ninja-';
|
||||
|
||||
const DB_NINJA_1 = 1;
|
||||
const DB_NINJA_2 = 2;
|
||||
|
||||
public static $dbs = ['db-ninja-1', 'db-ninja-2'];
|
||||
public static $dbs = ['db-ninja-01', 'db-ninja-02'];
|
||||
|
||||
/**
|
||||
* @param $email
|
||||
|
@ -7,7 +7,7 @@ use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
|
||||
|
||||
class Contact extends Authenticatable
|
||||
class ClientContact extends Authenticatable
|
||||
{
|
||||
use Notifiable;
|
||||
|
0
bootstrap/cache/.gitignore
vendored
Normal file → Executable file
0
bootstrap/cache/.gitignore
vendored
Normal file → Executable file
@ -22,6 +22,7 @@
|
||||
"asgrim/ofxparser": "^1.2",
|
||||
"davejamesmiller/laravel-breadcrumbs": "5.x",
|
||||
"fideloper/proxy": "^4.0",
|
||||
"hashids/hashids": "^3.0",
|
||||
"laracasts/presenter": "^0.2.1",
|
||||
"laravel/framework": "5.7.*",
|
||||
"laravel/socialite": "^3.1",
|
||||
@ -37,6 +38,7 @@
|
||||
"beyondcode/laravel-dump-server": "^1.0",
|
||||
"filp/whoops": "^2.0",
|
||||
"fzaninotto/faker": "^1.4",
|
||||
"laravel/dusk": "^4.0",
|
||||
"mockery/mockery": "^1.0",
|
||||
"nunomaduro/collision": "^2.0",
|
||||
"phpunit/phpunit": "^7.0"
|
||||
|
189
composer.lock
generated
189
composer.lock
generated
@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "3cec8c5c70a52bc9011baabe117ac56c",
|
||||
"content-hash": "8f50fadc77133971d60134045427a805",
|
||||
"packages": [
|
||||
{
|
||||
"name": "asgrim/ofxparser",
|
||||
@ -662,6 +662,72 @@
|
||||
],
|
||||
"time": "2017-03-20T17:10:46+00:00"
|
||||
},
|
||||
{
|
||||
"name": "hashids/hashids",
|
||||
"version": "3.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ivanakimov/hashids.php.git",
|
||||
"reference": "b6c61142bfe36d43740a5419d11c351dddac0458"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/ivanakimov/hashids.php/zipball/b6c61142bfe36d43740a5419d11c351dddac0458",
|
||||
"reference": "b6c61142bfe36d43740a5419d11c351dddac0458",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.1.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^7.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-bcmath": "Required to use BC Math arbitrary precision mathematics (*).",
|
||||
"ext-gmp": "Required to use GNU multiple precision mathematics (*)."
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Hashids\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ivan Akimov",
|
||||
"email": "ivan@barreleye.com",
|
||||
"homepage": "https://twitter.com/IvanAkimov"
|
||||
},
|
||||
{
|
||||
"name": "Vincent Klaiber",
|
||||
"email": "hello@vinkla.com",
|
||||
"homepage": "https://vinkla.com"
|
||||
}
|
||||
],
|
||||
"description": "Generate short, unique, non-sequential ids (like YouTube and Bitly) from numbers",
|
||||
"homepage": "http://hashids.org/php",
|
||||
"keywords": [
|
||||
"bitly",
|
||||
"decode",
|
||||
"encode",
|
||||
"hash",
|
||||
"hashid",
|
||||
"hashids",
|
||||
"ids",
|
||||
"obfuscate",
|
||||
"youtube"
|
||||
],
|
||||
"time": "2018-03-12T16:30:09+00:00"
|
||||
},
|
||||
{
|
||||
"name": "jakub-onderka/php-console-color",
|
||||
"version": "v0.2",
|
||||
@ -3376,6 +3442,66 @@
|
||||
],
|
||||
"time": "2017-07-22T11:58:36+00:00"
|
||||
},
|
||||
{
|
||||
"name": "facebook/webdriver",
|
||||
"version": "1.6.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/facebook/php-webdriver.git",
|
||||
"reference": "bd8c740097eb9f2fc3735250fc1912bc811a954e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/facebook/php-webdriver/zipball/bd8c740097eb9f2fc3735250fc1912bc811a954e",
|
||||
"reference": "bd8c740097eb9f2fc3735250fc1912bc811a954e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-curl": "*",
|
||||
"ext-json": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ext-zip": "*",
|
||||
"php": "^5.6 || ~7.0",
|
||||
"symfony/process": "^2.8 || ^3.1 || ^4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^2.0",
|
||||
"jakub-onderka/php-parallel-lint": "^0.9.2",
|
||||
"php-coveralls/php-coveralls": "^2.0",
|
||||
"php-mock/php-mock-phpunit": "^1.1",
|
||||
"phpunit/phpunit": "^5.7",
|
||||
"sebastian/environment": "^1.3.4 || ^2.0 || ^3.0",
|
||||
"squizlabs/php_codesniffer": "^2.6",
|
||||
"symfony/var-dumper": "^3.3 || ^4.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-SimpleXML": "For Firefox profile creation"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-community": "1.5-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Facebook\\WebDriver\\": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"Apache-2.0"
|
||||
],
|
||||
"description": "A PHP client for Selenium WebDriver",
|
||||
"homepage": "https://github.com/facebook/php-webdriver",
|
||||
"keywords": [
|
||||
"facebook",
|
||||
"php",
|
||||
"selenium",
|
||||
"webdriver"
|
||||
],
|
||||
"time": "2018-05-16T17:37:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "filp/whoops",
|
||||
"version": "2.3.1",
|
||||
@ -3535,6 +3661,67 @@
|
||||
],
|
||||
"time": "2016-01-20T08:20:44+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/dusk",
|
||||
"version": "v4.0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/dusk.git",
|
||||
"reference": "9810f8609c8b53d9a3bac7d38c56530e0d77a6bb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/dusk/zipball/9810f8609c8b53d9a3bac7d38c56530e0d77a6bb",
|
||||
"reference": "9810f8609c8b53d9a3bac7d38c56530e0d77a6bb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"facebook/webdriver": "~1.3",
|
||||
"illuminate/console": "~5.6",
|
||||
"illuminate/support": "~5.6",
|
||||
"nesbot/carbon": "~1.20",
|
||||
"php": ">=7.1.0",
|
||||
"symfony/console": "~4.0",
|
||||
"symfony/process": "~4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery": "~1.0",
|
||||
"phpunit/phpunit": "~7.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "4.0-dev"
|
||||
},
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Laravel\\Dusk\\DuskServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Laravel\\Dusk\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Taylor Otwell",
|
||||
"email": "taylor@laravel.com"
|
||||
}
|
||||
],
|
||||
"description": "Laravel Dusk provides simple end-to-end testing and browser automation.",
|
||||
"keywords": [
|
||||
"laravel",
|
||||
"testing",
|
||||
"webdriver"
|
||||
],
|
||||
"time": "2018-10-03T15:37:05+00:00"
|
||||
},
|
||||
{
|
||||
"name": "mockery/mockery",
|
||||
"version": "1.2.0",
|
||||
|
@ -15,7 +15,7 @@ return [
|
||||
|
|
||||
*/
|
||||
|
||||
'default' => env('CACHE_DRIVER', 'file'),
|
||||
'default' => env('CACHE_DRIVER', 'redis'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
@ -81,7 +81,7 @@ return [
|
||||
'prefix_indexes' => true,
|
||||
],
|
||||
|
||||
'db-ninja-1' => [
|
||||
'db-ninja-01' => [
|
||||
'driver' => 'mysql',
|
||||
'host' => env('DB_HOST1', env('DB_HOST', 'localhost')),
|
||||
'database' => env('DB_DATABASE1', env('DB_DATABASE', 'forge')),
|
||||
@ -96,7 +96,7 @@ return [
|
||||
'engine' => 'InnoDB',
|
||||
],
|
||||
|
||||
'db-ninja-2' => [
|
||||
'db-ninja-02' => [
|
||||
'driver' => 'mysql',
|
||||
'host' => env('DB_HOST2', env('DB_HOST', 'localhost')),
|
||||
'database' => env('DB_DATABASE2', env('DB_DATABASE', 'forge')),
|
||||
|
@ -39,7 +39,7 @@ return [
|
||||
|
|
||||
*/
|
||||
|
||||
'limit' => env('TELESCOPE_LIMIT', 100),
|
||||
'limit' => env('TELESCOPE_LIMIT', null),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
@ -6,6 +6,7 @@ $factory->define(App\Models\Company::class, function (Faker $faker) {
|
||||
return [
|
||||
'name' => $faker->name,
|
||||
'company_key' => strtolower(str_random(RANDOM_KEY_LENGTH)),
|
||||
'ip' => $faker->ipv4
|
||||
'ip' => $faker->ipv4,
|
||||
'db' => config('database.default'),
|
||||
];
|
||||
});
|
||||
|
@ -18,9 +18,9 @@ $factory->define(App\Models\User::class, function (Faker $faker) {
|
||||
'first_name' => $faker->name,
|
||||
'last_name' => $faker->name,
|
||||
'phone' => $faker->phoneNumber,
|
||||
'email' => $faker->unique()->safeEmail,
|
||||
'email' => config('ninja.testvars.username'),
|
||||
'email_verified_at' => now(),
|
||||
'password' => '$2y$10$TKh8H1.PfQx37YgCzwiKb.KjNyWgaHb9cbcoQgdIVFlYg7B77UdFm', // secret
|
||||
'password' => bcrypt(config('ninja.testvars.password')), // secret
|
||||
'remember_token' => str_random(10),
|
||||
'db' => config('database.default')
|
||||
];
|
||||
|
@ -138,6 +138,7 @@ class CreateUsersTable extends Migration
|
||||
$table->unsignedInteger('industry_id')->nullable();
|
||||
$table->unsignedInteger('size_id')->nullable();
|
||||
$table->string('subdomain')->nullable();
|
||||
$table->string('db')->nullable();
|
||||
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
use App\Models\Account;
|
||||
use App\Models\Client;
|
||||
use App\Models\Contact;
|
||||
use App\Models\ClientContact;
|
||||
use App\Models\User;
|
||||
use App\Models\UserAccount;
|
||||
use Illuminate\Database\Seeder;
|
||||
@ -25,41 +25,45 @@ class UsersTableSeeder extends Seeder
|
||||
|
||||
$faker = Faker\Factory::create();
|
||||
|
||||
$account = Account::create([
|
||||
'name' => $faker->name(),
|
||||
'account_key' => strtolower(str_random(RANDOM_KEY_LENGTH)),
|
||||
$account = factory(\App\Models\Account::class)->create();
|
||||
$company = factory(\App\Models\Company::class)->create([
|
||||
'account_id' => $account->id,
|
||||
]);
|
||||
|
||||
$account->default_company_id = $company->id;
|
||||
$account->save();
|
||||
|
||||
$user = User::create([
|
||||
'account_id' => $account->id,
|
||||
'first_name' => $faker->firstName,
|
||||
'last_name' => $faker->lastName,
|
||||
'email' => TEST_USERNAME,
|
||||
'password' => Hash::make(TEST_PASSWORD),
|
||||
'email' => config('ninja.testvars.username'),
|
||||
'password' => Hash::make(config('ninja.testvars.password')),
|
||||
'email_verified_at' => now(),
|
||||
]);
|
||||
|
||||
$client = Client::create([
|
||||
'name' => $faker->name,
|
||||
'account_id' => $account->id,
|
||||
'company_id' => $company->id,
|
||||
]);
|
||||
|
||||
Contact::create([
|
||||
ClientContact::create([
|
||||
'first_name' => $faker->firstName,
|
||||
'last_name' => $faker->lastName,
|
||||
'email' => TEST_CLIENTNAME,
|
||||
'account_id' => $account->id,
|
||||
'password' => Hash::make(TEST_PASSWORD),
|
||||
'email' => config('ninja.testvars.clientname'),
|
||||
'company_id' => $company->id,
|
||||
'password' => Hash::make(config('ninja.testvars.password')),
|
||||
'email_verified_at' => now(),
|
||||
'client_id' =>$client->id,
|
||||
]);
|
||||
|
||||
UserAccount::create([
|
||||
\App\Models\UserCompany::create([
|
||||
'account_id' => $account->id,
|
||||
'company_id' => $company->id,
|
||||
'user_id' => $user->id,
|
||||
'is_owner' => 1,
|
||||
'is_admin' => 1,
|
||||
'is_locked' => 0,
|
||||
'is_default' => 1,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,10 @@
|
||||
<testsuite name="Integration">
|
||||
<directory suffix="Test.php">./tests/Integration</directory>
|
||||
</testsuite>
|
||||
|
||||
<testsuite name="Feature">
|
||||
<directory suffix="Test.php">./tests/Feature</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<filter>
|
||||
<whitelist processUncoveredFilesFromWhitelist="true">
|
||||
|
@ -38,9 +38,6 @@ Route::get('auth/{provider}/callback', 'Auth\LoginController@handleProviderCallb
|
||||
* Authenticated User Routes
|
||||
*/
|
||||
|
||||
Auth::routes(['verify' => true]);
|
||||
|
||||
|
||||
Route::group(['middleware' => ['auth:user', 'db']], function () {
|
||||
|
||||
Route::get('dashboard', 'HomeController@user')->name('user.dashboard');
|
||||
@ -53,8 +50,11 @@ Route::group(['middleware' => ['auth:user', 'db']], function () {
|
||||
/*
|
||||
* Inbound routes requiring DB Lookup
|
||||
*/
|
||||
Route::get('/user/confirm/{confirmation_code}', 'UserController@confirm');
|
||||
Route::group(['middleware' => ['auth:user', 'db']], function () {
|
||||
|
||||
Route::get('/user/confirm/{confirmation_code}', 'UserController@confirm');
|
||||
|
||||
});
|
||||
/*
|
||||
Authenticated Contact Routes
|
||||
*/
|
||||
|
56
tests/Browser/CreateAccountTest.php
Normal file
56
tests/Browser/CreateAccountTest.php
Normal file
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Browser;
|
||||
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Tests\DuskTestCase;
|
||||
use Illuminate\Foundation\Testing\WithFaker;
|
||||
use Illuminate\Foundation\Testing\WithoutMiddleware;
|
||||
|
||||
|
||||
class CreateAccountTest extends DuskTestCase
|
||||
{
|
||||
|
||||
use WithFaker;
|
||||
use DatabaseTransactions;
|
||||
|
||||
|
||||
public function testSignupFormDisplayed()
|
||||
{
|
||||
$response = $this->get('/signup');
|
||||
$response->assertStatus(200);
|
||||
}
|
||||
/**
|
||||
* A valid user can be logged in.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCreateAValidUser()
|
||||
{
|
||||
/*
|
||||
$response = $this->post('/signup', [
|
||||
'first_name' => $this->faker->firstName(),
|
||||
'last_name' => $this->faker->lastName(),
|
||||
'terms_of_service' => 1,
|
||||
'privacy_policy' => 1,
|
||||
'email' => config('ninja.testvars.username'),
|
||||
'password' => config('ninja.testvars.password')
|
||||
]);
|
||||
|
||||
|
||||
$response->assertSuccessful();
|
||||
*/
|
||||
|
||||
$this->visit('/signup')
|
||||
->type($this->faker->firstName(), 'first_name')
|
||||
->type($this->faker->lastName(), 'last_name')
|
||||
->type($this->faker->email(), 'email')
|
||||
->type($this->faker->password(7), 'password')
|
||||
->check('terms_of_service')
|
||||
->check('terms_of_service')
|
||||
->press(trans('texts.create_account'))
|
||||
->seePageIs('/dashboard');
|
||||
|
||||
}
|
||||
|
||||
}
|
23
tests/Browser/ExampleTest.php
Normal file
23
tests/Browser/ExampleTest.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Browser;
|
||||
|
||||
use Tests\DuskTestCase;
|
||||
use Laravel\Dusk\Browser;
|
||||
use Illuminate\Foundation\Testing\DatabaseMigrations;
|
||||
|
||||
class ExampleTest extends DuskTestCase
|
||||
{
|
||||
/**
|
||||
* A basic browser test example.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testBasicExample()
|
||||
{
|
||||
$this->browse(function (Browser $browser) {
|
||||
$browser->visit('/')
|
||||
->assertSee('Laravel');
|
||||
});
|
||||
}
|
||||
}
|
41
tests/Browser/Pages/HomePage.php
Normal file
41
tests/Browser/Pages/HomePage.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Browser\Pages;
|
||||
|
||||
use Laravel\Dusk\Browser;
|
||||
|
||||
class HomePage extends Page
|
||||
{
|
||||
/**
|
||||
* Get the URL for the page.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function url()
|
||||
{
|
||||
return '/';
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the browser is on the page.
|
||||
*
|
||||
* @param Browser $browser
|
||||
* @return void
|
||||
*/
|
||||
public function assert(Browser $browser)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the element shortcuts for the page.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function elements()
|
||||
{
|
||||
return [
|
||||
'@element' => '#selector',
|
||||
];
|
||||
}
|
||||
}
|
20
tests/Browser/Pages/Page.php
Normal file
20
tests/Browser/Pages/Page.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Browser\Pages;
|
||||
|
||||
use Laravel\Dusk\Page as BasePage;
|
||||
|
||||
abstract class Page extends BasePage
|
||||
{
|
||||
/**
|
||||
* Get the global element shortcuts for the site.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function siteElements()
|
||||
{
|
||||
return [
|
||||
'@element' => '#selector',
|
||||
];
|
||||
}
|
||||
}
|
2
tests/Browser/console/.gitignore
vendored
Normal file
2
tests/Browser/console/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
2
tests/Browser/screenshots/.gitignore
vendored
Normal file
2
tests/Browser/screenshots/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
43
tests/DuskTestCase.php
Normal file
43
tests/DuskTestCase.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace Tests;
|
||||
|
||||
use Laravel\Dusk\TestCase as BaseTestCase;
|
||||
use Facebook\WebDriver\Chrome\ChromeOptions;
|
||||
use Facebook\WebDriver\Remote\RemoteWebDriver;
|
||||
use Facebook\WebDriver\Remote\DesiredCapabilities;
|
||||
|
||||
abstract class DuskTestCase extends BaseTestCase
|
||||
{
|
||||
use CreatesApplication;
|
||||
|
||||
/**
|
||||
* Prepare for Dusk test execution.
|
||||
*
|
||||
* @beforeClass
|
||||
* @return void
|
||||
*/
|
||||
public static function prepare()
|
||||
{
|
||||
static::startChromeDriver();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the RemoteWebDriver instance.
|
||||
*
|
||||
* @return \Facebook\WebDriver\Remote\RemoteWebDriver
|
||||
*/
|
||||
protected function driver()
|
||||
{
|
||||
$options = (new ChromeOptions)->addArguments([
|
||||
'--disable-gpu',
|
||||
'--headless'
|
||||
]);
|
||||
|
||||
return RemoteWebDriver::create(
|
||||
'http://localhost:9515', DesiredCapabilities::chrome()->setCapability(
|
||||
ChromeOptions::CAPABILITY, $options
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
79
tests/Feature/LoginTest.php
Normal file
79
tests/Feature/LoginTest.php
Normal file
@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Models\Account;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Tests\TestCase;
|
||||
use Illuminate\Foundation\Testing\WithFaker;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
|
||||
class LoginTest extends TestCase
|
||||
{
|
||||
|
||||
use DatabaseTransactions;
|
||||
|
||||
public function testLoginFormDisplayed()
|
||||
{
|
||||
$response = $this->get('/login');
|
||||
$response->assertStatus(200);
|
||||
}
|
||||
/**
|
||||
* A valid user can be logged in.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testLoginAValidUser()
|
||||
{
|
||||
$account = factory(Account::class)->create();
|
||||
$user = factory(User::class)->create([
|
||||
'account_id' => $account->id,
|
||||
]);
|
||||
|
||||
$response = $this->post('/login', [
|
||||
'email' => config('ninja.testvars.username'),
|
||||
'password' => config('ninja.testvars.password')
|
||||
]);
|
||||
|
||||
$response->assertStatus(302);
|
||||
$this->assertAuthenticatedAs($user);
|
||||
}
|
||||
|
||||
/**
|
||||
* An invalid user cannot be logged in.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testDoesNotLoginAnInvalidUser()
|
||||
{
|
||||
$account = factory(Account::class)->create();
|
||||
$user = factory(User::class)->create([
|
||||
'account_id' => $account->id,
|
||||
]);
|
||||
|
||||
$response = $this->post('/login', [
|
||||
'email' => config('ninja.testvars.username'),
|
||||
'password' => 'invalid'
|
||||
]);
|
||||
|
||||
$response->assertSessionHasErrors();
|
||||
$this->assertGuest();
|
||||
}
|
||||
/**
|
||||
* A logged in user can be logged out.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testLogoutAnAuthenticatedUser()
|
||||
{
|
||||
$account = factory(Account::class)->create();
|
||||
$user = factory(User::class)->create([
|
||||
'account_id' => $account->id,
|
||||
]);
|
||||
|
||||
$response = $this->actingAs($user)->post('/logout');
|
||||
$response->assertStatus(302);
|
||||
$this->assertGuest();
|
||||
}
|
||||
}
|
@ -35,8 +35,8 @@ class MultiDBUserTest extends TestCase
|
||||
|
||||
$ac = factory(\App\Models\Account::class)->make();
|
||||
|
||||
$account = Account::on('db-ninja-1')->create($ac->toArray());
|
||||
$account2 = Account::on('db-ninja-2')->create($ac->toArray());
|
||||
$account = Account::on('db-ninja-01')->create($ac->toArray());
|
||||
$account2 = Account::on('db-ninja-02')->create($ac->toArray());
|
||||
|
||||
$company = factory(\App\Models\Company::class)->make([
|
||||
'account_id' => $account->id,
|
||||
@ -46,8 +46,8 @@ class MultiDBUserTest extends TestCase
|
||||
'account_id' => $account2->id,
|
||||
]);
|
||||
|
||||
Company::on('db-ninja-1')->create($company->toArray());
|
||||
Company::on('db-ninja-2')->create($company2->toArray());
|
||||
Company::on('db-ninja-01')->create($company->toArray());
|
||||
Company::on('db-ninja-02')->create($company2->toArray());
|
||||
|
||||
$user = [
|
||||
'first_name' => 'user_db_1',
|
||||
@ -77,8 +77,8 @@ class MultiDBUserTest extends TestCase
|
||||
|
||||
];
|
||||
|
||||
User::on('db-ninja-1')->create($user);
|
||||
User::on('db-ninja-2')->create($user2);
|
||||
User::on('db-ninja-01')->create($user);
|
||||
User::on('db-ninja-02')->create($user2);
|
||||
}
|
||||
|
||||
public function test_oauth_user_db2_exists()
|
||||
@ -113,12 +113,12 @@ class MultiDBUserTest extends TestCase
|
||||
|
||||
public function test_set_db_invokes()
|
||||
{
|
||||
$this->expectNotToPerformAssertions(MultiDB::setDB('db-ninja-1'));
|
||||
$this->expectNotToPerformAssertions(MultiDB::setDB('db-ninja-01'));
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
DB::connection('db-ninja-1')->table('users')->delete();
|
||||
DB::connection('db-ninja-2')->table('users')->delete();
|
||||
DB::connection('db-ninja-01')->table('users')->delete();
|
||||
DB::connection('db-ninja-02')->table('users')->delete();
|
||||
}
|
||||
}
|
||||
|
@ -29,15 +29,15 @@ class UniqueEmailTest extends TestCase
|
||||
if (! config('ninja.db.multi_db_enabled'))
|
||||
$this->markTestSkipped('Multi DB not enabled - skipping');
|
||||
|
||||
DB::connection('db-ninja-1')->table('users')->delete();
|
||||
DB::connection('db-ninja-2')->table('users')->delete();
|
||||
DB::connection('db-ninja-01')->table('users')->delete();
|
||||
DB::connection('db-ninja-02')->table('users')->delete();
|
||||
|
||||
$this->rule = new UniqueUserRule();
|
||||
|
||||
$ac = factory(\App\Models\Account::class)->make();
|
||||
|
||||
$account = Account::on('db-ninja-1')->create($ac->toArray());
|
||||
$account2 = Account::on('db-ninja-2')->create($ac->toArray());
|
||||
$account = Account::on('db-ninja-01')->create($ac->toArray());
|
||||
$account2 = Account::on('db-ninja-02')->create($ac->toArray());
|
||||
|
||||
$company = factory(\App\Models\Company::class)->make([
|
||||
'account_id' => $account->id,
|
||||
@ -47,8 +47,8 @@ class UniqueEmailTest extends TestCase
|
||||
'account_id' => $account2->id,
|
||||
]);
|
||||
|
||||
Company::on('db-ninja-1')->create($company->toArray());
|
||||
Company::on('db-ninja-2')->create($company2->toArray());
|
||||
Company::on('db-ninja-01')->create($company->toArray());
|
||||
Company::on('db-ninja-02')->create($company2->toArray());
|
||||
|
||||
|
||||
$user = [
|
||||
@ -67,8 +67,8 @@ class UniqueEmailTest extends TestCase
|
||||
'account_id' => $account2->id,
|
||||
];
|
||||
|
||||
User::on('db-ninja-1')->create($user);
|
||||
User::on('db-ninja-2')->create($user2);
|
||||
User::on('db-ninja-01')->create($user);
|
||||
User::on('db-ninja-02')->create($user2);
|
||||
|
||||
}
|
||||
|
||||
@ -88,8 +88,8 @@ class UniqueEmailTest extends TestCase
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
DB::connection('db-ninja-1')->table('users')->delete();
|
||||
DB::connection('db-ninja-2')->table('users')->delete();
|
||||
DB::connection('db-ninja-01')->table('users')->delete();
|
||||
DB::connection('db-ninja-02')->table('users')->delete();
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user