How to mock a response from a package? - laravel

I am trying to mock a response while using php-oppwa
I created this wrapper around that package:
use Bryangruneberg\OPPWA\Factory;
use Bryangruneberg\OPPWA\OPPWAResponse;
use Illuminate\Support\Facades\Config;
class OppwaService
{
public function client()
{
$client = Factory::createClient(
Config::get('gateways.oopwa_user_id'),
Config::get('gateways.oopwa_password'),
Config::get('gateways.oopwa_entity_id'),
Config::get('gateways.oopwa_url'),
);
$api = Factory::createAPI($client);
return $api;
}
public function setupCheckout(int $amount, string $currency, string $paymentType, array $options = [])
{
return $this->client()->prepareCheckout($amount, $currency, $paymentType, $options);
}
public function checkoutSetupWasSuccessful(OPPWAResponse $response)
{
return $this->client()->isPrepareCheckoutSuccess($response);
}
}
And I have this in my controller:
public function __construct(OppwaService $service)
{
$this->service = $service;
}
public function show()
{
$checkout = $this->service->setupCheckout(23, 'USD', OPPWA::PAYMENT_TYPE_DEBIT);
if ($this->service->checkoutSetupWasSuccessful($checkout)) {
$checkoutId = $checkout->getId(); // I am trying to mock this response
}
return view('index',['checkoutId' => $checkoutId ?? null);
}
I am trying to mock getId in my test,
/** #test */
public function checkout_id_exists()
{
$this->mock(OPPWAResponse::class, function ($mock) {
$mock->shouldReceive('getId')->once()->andReturn('555555555-555555555');
});
$this->get(route('checkout.show'))->assertSee('555555555-555555555');
}
But, that doesn't work.. Is it because that OPPWAResponse is in the vendor directory?
How can I mock the response?

Related

Problem for working with DTO - Laravel, PHP

For example I have code like this:
$this->users = $data['data'];
$this->month = $data['month'];
$this->year = $data['year'];
But I need to use DTO. For example I used this function in DTO class:
public function getUsers(): string
{
return $this->users;
}
And as I understand I need to add it to the first code. But I don't understand how to use DTO for my the first code. Can you explain me please?
upd
Now I have:
public function __construct($data, $jobWatcherId)
{
$this->jobWatcherId = $jobWatcherId;
$jobsDTO = new JobsDTO($data['data'], $data['month'], $data['year'],
$data['working_days'], $data['holiday_hours'],
$data['advance_payroll_date'], $data['main_payroll_date']);
}
public function handle()
{
$jobWatcher = JobWatcher::find($this->jobWatcherId);
try {
$startedAt = now();
$jobWatcher->update([
'status_id' => JobWatcherStatusEnum::PROCESSING,
'started_at' => $startedAt,
]);
$redmineService = new RedmineAPIService();
foreach ($jobsDTO->getUsers() as $user) {
}
And for line foreach ($jobsDTO->getUsers() as $user) I have Undefined variable '$jobsDTO'
Your question is a bit unclear, but as I understand it, you want to instantiate a DTO with the above data?
You could have a class like:
class UsersDTO
{
public array $users;
public int $month;
public int $year;
public function __construct(array $users, int $month, int $year)
{
$this->users = $users;
$this->month = $month;
$this->year = $year;
}
public function getUsers(): array
{
return $this->users;
}
public function getMonth(): int
{
return $this->month;
}
public function getYear(): int
{
return $this->year;
}
}
and then somewhere else call:
$usersDTO = new UsersDTO($data['data'], $data['month'], $data['year']);
// Do something with $usersDTO->getUsers();

Can't do pagination in laravel

I need to do a pagination of the data I retrieve from the DB but I get this error:
Call to undefined method App\Models\DataFromRasp::table()
I followed the Laravel documentation but I still getting this error
My controller is this:
class DeviceController extends Controller
{
public function index()
{
$data=Device::all();
return view('backend.auth.user.device', compact("data"));
}
public function create()
{
}
public function store(Request $request)
{
}
public function show(Device $deviceID)
{
$device = Device::firstWhere('id', $deviceID);
return view('backend.auth.user.singleDevice', compact("device"));
}
public function edit(Device $device)
{
//
}
public function update(Request $request, Device $device)
{
//
}
public function destroy(Device $device)
{
//
}
public function visualizeData()
{
$data=DataFromRasp::table('data_from_rasp')->simplePaginate(10);
return view('backend.auth.user.dictionary', compact("data"));
}
public function getData(Request $request)
{
$m_data = $request->get('m_data');
$r_data = $request->get('r_data');
DataFromRasp::create(['MAC' => $m_data, 'RSSI' => $r_data]);
if(($m_data == 'C4:A5:DF:24:05:7E' or $m_data == '70:1C:E7:E4:71:DA') and Device::where('MAC_ADDR', $request->m_data)->doesntExist()){
Device::create(['MAC_ADDR' => $m_data]);
}
}
public function scan()
{
$process = new Process(['python2','C:\Simone\Università\Smart IoT Devices\Lab_Raspy\Bluetooth\prova.py']);
$process->run();
if (!$process->isSuccessful()) { throw new ProcessFailedException($process); }
return redirect()->route('dict');
}
}
The route is:
Route::get('dict', [DeviceController::class, 'visualizeData'])->name('dict');
Can someone help me?
try $data = DataFromRasp::paginate(10)

Laravel: ID as ValueObject is null after save

I'm using ValueObject casting as an ID of my model. Everything works fine when I get a record from database, however when it coming to saving, the ID is null. If I comment "casts" out, ID is correct.
Example:
$game = new Game($data);
$game->created_by = $userId; // Id ValueObject
$game->save();
dd($game);
// attributes:
// "id" => null,
// "created_by" => Id{#value: 10},
Id ValueObject:
class Id
{
public function get($model, $key, $value, $attributes)
{
$this->value = $value;
return $this;
}
public function set($model, $key, $value, $attributes)
{
$this->value = $value;
}
public function value(): int
{
return $this->value;
}
public function __toString()
{
return (string) $this->value;
}
}
Model:
class Game extends Model
{
protected $casts = [
'id' => Id::class
];
}
What can I do with it?
Thanks in advance
Okey, I think that there should be a ValueObject and a CastingObject, I ended up with something similar to this:
class Game extends Model
{
protected $casts = [
'id' => IdCast::class
];
}
class IdCast implements CastsAttributes
{
public function get($model, $key, $value, $attributes)
{
return new Id(
$attributes['id']
);
}
public function set($model, $key, $value, $attributes)
{
return [
'id' => $value
];
}
}
class Id
{
private $value;
public function __construct($id)
{
$this->value = $id;
}
public function value(): int
{
return $this->value;
}
public function __toString()
{
return (string) $this->value;
}
}

Laravel - Prevent from create empty key in database

I have a table where I keep all the settings that will be used on the website, they are saved in the cache, I'm trying to upload the favicon, however when uploading the image the favicon row is updated and an empty key value with the temp path is created at the same time, how can I solve this?
You can see the empty field in the image...
Route
Route::put('/', ['as' => 'setting.update', 'uses' => 'Admin\AdminConfiguracoesController#update']);
Model
class Setting extends Model
{
protected $table = 'settings';
public $timestamps = false;
protected $fillable = ['value'];
}
Controller
class AdminConfiguracoesController extends AdminBaseController
{
private $repository;
public function __construct(SettingRepository $repository){
parent::__construct();
$this->repository = $repository;
}
public function update(Request $request, Factory $cache)
{
$settings = $request->except('_method', '_token');
$this->repository->update($settings);
$cache->forget('settings');
return redirect()->back();
}
}
Repository
class SettingRepository{
private $settings;
public function __construct(Setting $settings)
{
$this->settings = $settings;
}
public function update($key, $value = null)
{
if (is_array($key))
{
foreach ($key as $name => $value)
{
if( $name == "website_favicon" ){
$imageName = $key['website_favicon']->getClientOriginalName();
$this->update($name, asset('public/images/website/'.$imageName));
$key['website_favicon']->move(
base_path() . '/public/images/website/', $imageName
);
} else{
$this->update($name, $value);
}
}
}
$setting = $this->settings->firstOrCreate(['name' => $key]);
$setting->value = $value;
$setting->save();
}
public function lists()
{
return $this->settings->lists('value', 'name')->all();
}
}
The problem is a missing return statement after the foreach loop in your repository. The code after the loop will be executed. $key is an array and $value is the temp value of the uploaded file, which will be set inside the loop.
As I mentioned in my comment, you shouldn't use the repository to upload files. Do it in your controller instead:
AdminConfiguracoesController.php
class AdminConfiguracoesController extends AdminBaseController
{
private $repository;
public function __construct(SettingRepository $repository)
{
parent::__construct();
$this->repository = $repository;
}
public function update(Request $request, Factory $cache)
{
$settings = $request->except('_method', '_token', 'website_favicon');
if ($request->hasFile('website_favicon'))
{
$this->uploadImage($request->file('website_favicon'), 'website_favicon');
$cache->forget('website_favicon');
}
$this->repository->update($settings);
$cache->forget('settings');
return redirect()->back();
}
private function uploadImage(UploadedFile $image, $key)
{
$image->move(public_path('images/website'), $image->getClientOriginalName());
$this->repository->update($key, $image->getClientOriginalName());
}
}
SettingRepository.php
class SettingRepository
{
private $settings;
public function __construct(Setting $settings)
{
$this->settings = $settings;
}
public function update($key, $value = null)
{
if (is_array($key))
{
foreach ($key as $name => $value)
{
$this->update($name, $value);
}
return; // This was missing!
}
$setting = $this->settings->firstOrCreate(['name' => $key]);
$setting->value = $value;
$setting->save();
}
public function lists()
{
return $this->settings->lists('value', 'name')->all();
}
}
You can refactor this even further to use a Job that uploads the image, but this would be overkill for now.

Laravel 4: Passing data from make to the service provider

The code below says it all...
// routes.php
App::make('SimpleGeo',array('test')); <- passing array('test')
// SimpleGeoServiceProvider.php
public function register()
{
$this->app['SimpleGeo'] = $this->app->share(function($app)
{
return new SimpleGeo($what_goes_here);
});
}
// SimpleGeo.php
class SimpleGeo
{
protected $_test;
public function __construct($test) <- need array('test')
{
$this->_test = $test;
}
public function getTest()
{
return $this->_test;
}
}
You can try to bind the class with the parameters directly into your app container, like
<?php // This is your SimpleGeoServiceProvider.php
use Illuminate\Support\ServiceProvider;
Class SimpleGeoServiceProvider extends ServiceProvider {
public function register()
{
$this->app->bind('SimpleGeo', function($app, $parameters)
{
return new SimpleGeo($parameters);
});
}
}
leaving untouched your SimpleGeo.php. You can test it in your routes.php
$test = App::make('SimpleGeo', array('test'));
var_dump ($test);
You need to pass your test array to the class inside of the service provider
// NOT in routes.php but when u need it like the controller
App::make('SimpleGeo'); // <- and don't pass array('test')
public function register()
{
$this->app['SimpleGeo'] = $this->app->share(function($app)
{
return new SimpleGeo(array('test'));
});
}
YourController.php
Public Class YourController
{
public function __construct()
{
$this->simpleGeo = App::make('SimpleGeo');
}
}

Resources