Laravel 5.0 phpunit models - php

I have clean install of Laravel 5.0, and I have issues with phpunit tests.
If I create a test for user model, I'm getting error - User class not found.
If I test controllers, works fine, controller classes are detected.
As a temporary workaround, just to test if it is working, I added class User inside UserTest.php.
I tried to add folder models in app folder, placing the class inside, similar as it was in Laravel 4.2, changed composer.json as well, ran composer dump-autoload, but it didn't work.
"autoload": {
"classmap": [
"database",
"app/model"
],
"psr-4": {
"App\\": "app/",
}
},
The simple classes looks like this:
// tests/models/UserTest.php
class UserTest extends TestCase
{
protected $user;
public function setUp()
{
parent::setUp();
}
public function testEmptyNameFailExpected()
{
$user = new User;
$user->name = '';
$result = $user->isValid();
$this->assertFalse($result);
return $user;
}
}
And here is User.php class in app folder (in laravel 5.0 the architecture is different)
// app/User.php
namespace App;
use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use Illuminate\Support\Facades\Validator;
class User extends Model implements AuthenticatableContract, CanResetPasswordContract
{
use Authenticatable, CanResetPassword;
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = ['name', 'email', 'password'];
public static $rules = [ 'name' => 'required|min:3' ];
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = ['password', 'remember_token'];
/**
* validate input
*
* #return bool
*/
public function isValid()
{
$validation = Validator::make($this->attributes, static ::$rules);
if ($validation->passes()) return true;
$this->errors = $validation->messages();
return false;
}
}

I noticed two problems with your code:
You said your test folder is
app/tests/models/UserTest.php
That is incorrect. In a clean install of Laravel 5.0 - the test class is in the base folder - not the app folder - so it should be
tests/models/UserTest.php
Also - your User is namespaced in Laravel 5.0 - so your code will need to be
$user = new \App\User;

Related

Laravel 8 factory not found despite dumping composer autoloader

I'm creating factories in my Laravel 8 project, I've used them before so am quite familiar with their set up.
In my project, I'm having trouble getting Laravel to pick up my factories and cannot figure out why, the error I'm getting is that my factory class can't be found, I've tried composer dump-autoload and also have tried various cache clearing commands with no result.
What am I missing?
My database/factories/BrandFactory is:
<?php
namespace Database\Factories;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use Carbon\Carbon;
class BrandFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* #var string
*/
protected $model = Brand::class;
/**
* Define the model's default state.
*
* #return array
*/
public function definition()
{
$todo = $this->faker->unique()->company();
$slug = Str::slug($brand);
return [
'user_id' => User::all()->random()->id,
'brand' => $brand,
'slug' => $slug,
'url' => $this->faker->domain(),
'created_at' => Carbon::now()->subDays(rand(1, 14))
];
}
}
I have HasFactory on my model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Brand extends Model
{
use HasFactory, SoftDeletes;
/**
* The table associated with the model.
*
* #var string
*/
protected $table = 'brands';
/**
* The attributes that are mass assignable.
*
* #var string[]
*/
protected $fillable = [
'brand',
'url'
];
/**
* The relationships that should always be loaded.
*
* #var array
*/
protected $with = [
'form'
];
/**
* Get the form associated with the user.
*/
public function form()
{
return $this->hasOne(Form::class);
}
/**
* Get the brand that owns the comment.
*/
public function brand()
{
return $this->belongsTo(User::class);
}
}
Which is called from my seeder:
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use App\Models\Brand;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* #return void
*/
public function run()
{
Brand::factory(3)->create();
}
}
Also, since this is a Laravel 8 project, autoloader is configured correctly to:
"autoload": {
"psr-4": {
"App\\": "app/",
"Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/"
}
}
Your code look fine, anyway, you can tell your model to find it's own factory using newFactory method:
In your model:
protected static function newFactory()
{
return Database\Factories\BrandFactory::new();
}

Subscription won't update in database after subscription is updated in Stripe using Laravel Cashier and Jenssegers MongoDB

I am having trouble getting my new subscription to be updated in MongoDB Database. Im using Laravel Cashier, Stripe, and Jenssegers MongoDB.
In the stripe dashboard, users have been successfully added as customers and subscribers.
Here is the ERROR:
[23:24:17] LOG.error: Call to a member function prepare() on null
{"userId":"4ec1b45d36623t2269477d0...
Here is where the ERROR lives:
return true;
}
$statement = $this->getPdo()->prepare($query);
$this->bindValues($statement, $this->prepareBindings($bindings));
Here is my controller:
namespace App\Http\Controllers;
use App\Plan;
use App\User;
use Exception;
use Illuminate\Http\Request;
class CheckoutController extends Controller
{
/**
* The collection name
*
* #var array
*/
public function checkout($plan_id)
{
$plan = Plan::findOrFail($plan_id);
$intent = auth()->user()->createSetupIntent();
return view('billing.checkout', compact('plan', 'intent'));
}
public function process(Request $request)
{
$plan = Plan::findOrFail($request->input('billing_plan_id'));
try {
auth()->user()->newSubscription($plan->name, $plan->stripe_plan_id)-
>create($request->input('payment-method'));
return redirect()->route('billing')->withMessage('Subscribed Successfully');
} catch (Exception $e) {
return redirect()->back()->withError($e->getMessage());
}
}
Here is My User Model:
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Model;
use Jenssegers\Mongodb\Auth\User as Authenticatable;
use Laravel\Cashier\Billable;
use Illuminate\Foundation\Auth;
class User extends Authenticatable
{
use Billable, Notifiable;
protected $connection = 'mongodb';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'username', 'password', 'phone', 'last_login_at',
'last_login_ip',
];
/**
* The collection name
*
* #var array
*/
protected $table = 'users';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $dates = ['deleted_at'];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
}
Here is My Plan Model:
namespace App;
use Jenssegers\Mongodb\Eloquent\Model;
/**
* #method static findOrFail($plan_id)
*/
class Plan extends Model
{
protected $fillable = [
'name',
'price',
'stripe_plan_id'
];
}
Here is my Subscription Migration:
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Migrations\Migration;
use Jenssegers\Mongodb\Schema\Blueprint;
class CreateSubscriptionsTable extends Migration
{
/**
* The name of the database connection to use.
*
* #var string
*/
protected $connection = 'mongodb';
public function up()
{
Schema::create('subscriptions', function (Blueprint $collection) {
$collection->bigIncrements('id');
$collection->unsignedBigInteger('userid');
$collection->string('name');
$collection->string('stripe_id');
$collection->string('stripe_status');
$collection->string('stripe_plan')->nullable()->change();
$collection->integer('quantity')->nullable()->change();
$collection->timestamp('trial_ends_at')->nullable();
$collection->timestamp('ends_at')->nullable();
$collection->timestamps();
$collection->index(['user_id', 'stripe_status']);
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('subscriptions');
}
}
Please help me figure out the source of this issue and how to solve it.
Make sure your model (i'm guessing it's a model but you didn't mention / show it) that is calling $this->getPdo() is extending Jenssegers eloquent model class and not Laravels.
For example:
Replace
class MyModel extends Model
With
class MyModel extends \Jenssegers\Mongodb\Eloquent\Model
Partial Solution:
Although I am getting the same error below
"Call to a member function prepare() on null {"userId":"4ec1b45d36623t2269477d0...".
In order to get the Subscription to update in the database I went into the Subscription.php file in Cashier and I replaced
use Illuminate\Database\Eloquent\Model;
with
use Jenssegers\Mongodb\Eloquent\Model;
This will fix database update issue, but something wierd is still going on in the Connection.php file causing the error.
$statement = $this->getPdo()->prepare($query);

Laravel class not being found in a model

I am trying to get my project to use authorization roles to restrict users to certain featuers and I am following along with a tutorial. When I make a call to a class in my user.php file I am getting an error that the class App\Role can't be found. I am not sure if it is a namespace issue but I can't get to the bottom of it. I believe it is the roles function that is giving me this issue.
<?php
namespace EliteWorker;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'address', 'phone', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function roles() {
return $this->belongsToMany('App\Role');
}
public function hasAnyRoles($roles){
return null !== $this->roles()->whereIn('name', $roles)->first();
}
public function hasAnyRole($role){
return null !== $this->roles()->where('name', $role)->first();
}
}
You changed the namespace to EliteWorker so if the Model class RoleĀ is generated with Artisan, it'll also have that namespace
public function roles()
{
return $this->belongsToMany('EliteWorker\Role');
}
Note that you can also get the model base name by calling the class static property
public function roles()
{
return $this->belongsToMany(Role::class);
}
No need to import it if it's in the same namespace
Also note that the artisan command app:name has been removed in Laravel 6 to encourage developers to use the generic App namespace

Laravel Caffeinated Modules Model Factory - Unable to locate factory with name

I appreciate this question does appear on here many times, however after looking through the answers and attempting to resolve the issue, it unfortunately still persists.
I am using the Caffeinated Modules for Laravel package with Laravel 5.6. I have created a User module which contains the following.
UserTableSeeder App/Modules/User/Database/Seeds/UserTableSeeder.php
<?php
namespace App\Modules\User\Database\Seeds;
use Illuminate\Database\Seeder;
use App\Modules\User\Models\User;
class UserTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
factory(User::class, 3)->create();
}
}
UserFactory App/Modules/User/Database/Factories/UserFactory.php
<?php
use Faker\Generator as Faker;
use App\Modules\User\Models\User;
/*
|--------------------------------------------------------------------------
| Model Factories
|--------------------------------------------------------------------------
|
| This directory should contain each of the model factory definitions for
| your application. Factories provide a convenient way to generate new
| model instances for testing / seeding your application's database.
|
*/
$factory->define(User::class, function (Faker $faker) {
return [
'name' => $faker->name,
'email' => $faker->unique()->safeEmail,
'password' => '$2y$10$TKh8H1.PfQx37YgCzwiKb.KjNyWgaHb9cbcoQgdIVFlYg7B77UdFm', // secret
'remember_token' => str_random(10),
];
});
UserDatabaseSeeder App/Modules/User/Database/Seeds/UserDatabaseSeeder.php
<?php
namespace App\Modules\User\Database\Seeds;
use Illuminate\Database\Seeder;
class UserDatabaseSeeder extends Seeder
{
public function run()
{
$this->call(UserTableSeeder::class);
}
}
User App/Modules/User/Models/User.php
<?php
namespace App\Modules\User\Models;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
}
When I run
php artisan module:seed
the UserDatabaseSeeder calls the UserTableSeeder but produces the following error message:
Seeding: App\Modules\User\Database\Seeds\UserTableSeeder
InvalidArgumentException : Unable to locate factory with name
[default] [App\Modules\User\Models\User].
Any help is much appreciated.
Basically Caffinated Modules doesn't support loading factories from your module out of the box.
I found this issue that includes a fix: https://github.com/caffeinated/modules/issues/337
Add this to your ModuleServiceProvider:
/**
* Register the module services.
*
* #return void
*/
public function register()
{
$this->app->register(RouteServiceProvider::class);
$this->mergeConfigFrom(
__DIR__.'/../config.php',
'user'
);
$this->registerEloquentFactoriesFrom(__DIR__.'/../Database/Factories');
}
/**
* Register factories.
*
* #param string $path
* #return void
*/
protected function registerEloquentFactoriesFrom($path)
{
$this->app->make(Factory::class)->load($path);
}

login with error 'Call to a member function prepare() on null'

Laravel makes me crazy showing the next following error:
The error happens when login controller is triggered.
public function login(Request $request)
{
$this->validateLogin($request);
// If the class is using the ThrottlesLogins trait, we can automatically throttle
// the login attempts for this application. We'll key this by the username and
// the IP address of the client making these requests into this application.
$throttles = $this->isUsingThrottlesLoginsTrait();
if ($throttles && $lockedOut = $this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
$credentials = $this->getCredentials($request);
// $credentials['type']=1;
// return $credentials;die;
if (Auth::guard($this->getGuard())->attempt($credentials, $request->has('remember'))) {
return $this->handleUserWasAuthenticated($request, $throttles);
}
// If the login attempt was unsuccessful we will increment the number of attempts
// to login and redirect the user back to the login form. Of course, when this
// user surpasses their maximum number of attempts they will get locked out.
if ($throttles && ! $lockedOut) {
$this->incrementLoginAttempts($request);
}
return $this->sendFailedLoginResponse($request);
}
Seems like is an error related to the database though the login service is managed by an API that works well. I don't know why this error happens. I'm really newbie to Laravel so if anyone can guide me I will thank.
User Model
namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password','phone','photo','first_name', 'contact_name', 'address', 'phone_number', 'fiscal_number', 'about_us',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function subscription()
{
return $this->hasMany('App\Models\EmployerSubscription','employer_id','_id');
}
public function jobseekers()
{
return $this->hasOne('App\Models\JobSeekers');
}
public function experience()
{
return $this->hasMany('App\Models\Experience')->where('status',true);
}
}
The default User model is extending Illuminate\Database\Eloquent\Model, where it has to extend Jenssegers\Mongodb\Eloquent\Model to work with MongoDB. By changing the User model in app/User.php, this can be resolved. Change your user model to following-
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Auth\Authenticatable;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Foundation\Auth\Access\Authorizable;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
class User extends \Jenssegers\Mongodb\Eloquent\Model implements
AuthenticatableContract,
AuthorizableContract,
CanResetPasswordContract
{
use Authenticatable, Authorizable, CanResetPassword, Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password','phone','photo','first_name', 'contact_name', 'address', 'phone_number', 'fiscal_number', 'about_us',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function subscription()
{
return $this->hasMany('App\Models\EmployerSubscription','employer_id','_id');
}
public function jobseekers()
{
return $this->hasOne('App\Models\JobSeekers');
}
public function experience()
{
return $this->hasMany('App\Models\Experience')->where('status',true);
}
}
As you are saying that login service is managed by API, but as i can see you have used laravel Auth service provider for authentication. Please check database settings in your project .env file. if issue still persist kindly follow below steps.
composer dump-autoload
php artisan cache:clear
php artisan view:clear
php artisan config:clear
and restart your server. Hope that will work.
Go to User model and add the following;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
class User extends Eloquent implements AuthenticatableContract,

Categories