First, let's get into the application's context:
We are on CustomerController, which is a Resource Controller sending a post request to the Store method.
This is my store method:
$customerDTO = new \repositories\dtos\CreateCustomerDTO();
$customerDTO->hydrate( Input::All() );
/** #var Customer $customer */
$customer = $this->customers->create( $customerDTO );
if ( $customer != null ){
header('Location: '.url('/customers/'.$customer->clacli));
return Redirect::action('CustomerController#show', array($customer->id) );
}
$userMessage = array(
'messageType' => 'error',
'messageContent' => 'Error creating a new Customer'
);
return Redirect::action('CustomerController#index')
->with(array('userMessage' => $userMessage));
I had to put a "header" because the Redirect call is not working.
When i put this line:
$customer = $this->customers->create( $customerDTO );
All the redirects stops to work.
And what is inside $this->customers? It's just a repository to abstract the database from the controller, i'm going to need to change the database on the near future.
Well, the code inside $this->customers->create is:
return Customer::create( $dto->toArray() );
And it's working, also all the test of my customersRepository are working. It's just a call to the Eloquent Model create method with an array of data.
So i can't figure out why the Redirect is not working. Any tip?
I tried with return 'test'; just after the call to $this->customers->create( $customerDTO); and didn't work either.
It was a strange problem with the sessions. We get it fixed, not sure why...
Related
Today I face a strange problem (as I face this first time so it is a strange problem for me). After saving the content of a model I just write the following line of code return route('organization'); so that it will redirect to the naming route organization after saving the content.
Once the content of the organization model saves it just print the URL of the page http//xyz.laravel/organization rather than printing the content of the page itself!
When I manually type and hit the dashboard URL it surprisingly prints the dashboard URL rather than loading the dashboard content! like the below image:
Everything was working fine before I tried to store the content of that model. Once the content is stored the application starts strange behavior. Here is the code of that model:
public function store(Request $request)
{
$validated = $request->validate([
'organization_name' => 'required|unique:organizations|max:255',
'abn_number' => 'required',
'address_one' => 'required|max:100',
'state' => 'required',
'post_code' => 'required'
]);
// check organization exist or not
$org = Organization::where('organization_name', $request->organization_name)->get();
if( count( $org ) > 0 ) {
//
} else {
$organization = new Organization();
$organization->organization_name = $request->organization_name;
$organization->abn_number = $request->abn_number;
$organization->address_one = $request->address_one;
$organization->address_two = $request->address_two;
$organization->state = $request->state;
$organization->post_code = $request->post_code;
$organization->created_by = Auth::user()->id;
$organization->created_at = Carbon::now();
$organization->save();
return route('organization');
}
}
Can anyone tell me what's actually happen and how can I fix this issue?
return route('organization'); will generate the URL link to the route and print it
You can use
return redirect()->route('organization);
You can get more info from https://laravel.com/docs/8.x/redirects
This is because you are not redirecting to that route but you are returning route url as a string, to redirect a user to a named route you can use global redirect() helper as below
return redirect()->route('organization'); instead of return route('organization');
for more see
documentation
Symfony project PHPunit coverage test
UserController
public function userEdit($id, Request $request)
{
$user = $this->userRepository->findOneByCode($id);
if (!$user) {
throw new Exception("User not found!");
}
$userForm = $this->createForm(UserForm::class, $user);
$userForm->handleRequest($request);
if ($userForm->isSubmitted() && $userForm->isValid()) {
$this->userService->save($user);
return $this->redirectToRoute('user_list');
}
return $this->render(
'user/user.html.twig', [
'form' => $userForm->createView(),
]
);
}
TestUserController
public function testUserEdit()
{
$client = static::createClient();
$crawler = $client->request('GET', '/user/test/edit');
$formData = array(
'username' => 'test',
'email' => 'test#test.nl',
'roles' => 'ROLE_ADMIN'
);
$this->assertEquals(
200,
$client->getResponse()->getStatusCode()
);
$form = $this->factory->create(UserForm::class);
$object = User::fromArray($formData);
$form->submit($formData);
$this->assertTrue($form->isSynchronized());
$this->assertEquals($object, $form->getData());
$view = $form->createView();
$children = $view->children;
foreach (array_keys($formData) as $key) {
$this->assertArrayHasKey($key, $children);
}
}
In the userEdit method we have a if loop. But When we run PHPunit coverage test the if loop is not executed. The other if loop for submit is also not covered.
What goes wrong and what can I do in order to cover the test ? Also is this the best solution for Symfony form test since I am new to PHPunit.
I noticed a few things in your code that seem wrong:
The userEdit method name should be userEditAction.
Select the form like this:
$form = $crawler->selectButton('submit')->form();
That 'submit' text is the label on the submit button (e.g. Save).
And then, after filling the fields:
$crawler = $client->submit($form);
You check if the submit was successful by asserting that the resulting HTML page contains expected element (e.g.):
$this->assertGreaterThan(0, $crawler->filter('h1')->count());
Btw. put: $client->followRedirects(true); after instantiating the Client.
Examples are from the official docs.
Regarding the some lines that were not covered by test: whenever you have if clause, you need to test for both conditions. In your case, first you probably have a valid user, instance of User and the other case should be that you pass there an invalid user (null or whatever else). That is usually accomplished by using #dataProvider annotation and method. The data provider method supplies sets of data to the test method. There can be more than one set, so another set contains invalid data to cover the other outcome of the if() clause.
This blog has great examples.
To cover the content of the if-conditions you have to fulfill the conditions new tests. To enter the first if for example you have to write a test where you mock the userRepository and make findOneByCode return null. Then the following if-condition will be executed and throw an exception. Finally you test for a thrown exception in the test.
For the other if-condition you proceed in a similar manner. Write a new test which is designed to fulfill the condition and test the code inside it.
I have a problem with one of my controllers either in Laravel or Ember. I can get the record to save after filling out the form but the record will not persist to the database. Again the form saves the record but doesn't push the record to the database. I tried following Embers guides on pushing data to the server but no juice. Also thanks for all the help from this site, you have got me this far, hopefully I can get this worked out with your help. Here are the controllers,
Laravel Controller
$statusCode = 200;
$libraries = $request->all();
$library = Library::create($libraries);
$criteria = $library->toArray();
return Response::json([
'libraries' => $criteria],
$statusCode);
Ember Route
model() {
return this.store.createRecord('library');
},
actions: {
saveLibrary(item) {
item.save().then(() => this.transitionTo('libraries'));
},
willTransition() {
//rollbackAttributes() removes the record from the store
// if model is 'isNew'
this.controller.set('model').rollbackAttributes();
}
}
In controller, you should use transitionToRoute. and implement POST request for /libraries for save method call.
actions: {
saveLibrary() {
//You dont need to pass. you need to update model properties. and then call save method.
this.get('model').save().then(() => this.transitionToRoute('libraries'));
}
}
I would like use a method of controller from another bundle, in my controller.
The method this->forward need a Response object, and i don't know how to use it.
public function indexAction($name)
{
$response = $this->forward('AcmeHelloBundle:Hello:fancy', array(
'name' => $name,
'color' => 'green',
));
// ... further modify the response or return it directly
return $response;
}
And i saw that i can use service but i want to know if its the best solution or they are another.
$this->forward takes arguments in this order:
Logical Name of controller action in string format i.e. 'AcmeHelloBundle:Hello:fancy'
Parameters to be passed as request variables in array format i.e. array(
'name' => $name,
'color' => 'green',
)
These parameters can be accessed in the controller using request access functions.
Sometimes you want to bypass security completely and run a command in another controller despite a user's permissions level. Luckily you can do that fairly easily.
First, run a use Command for your controller at the top of the controller you want to use the data from:
use AppBundle\Controller\MySourceDataController;
Then call that function from within your destination controller:
$response = MySourceDataController::getTheData( $option1, $option2 );
If you need to pass a Request object, you can do it this way:
$response = MySourceDataController::getTheData( new Request( array(
'server' => 'USAServer1',
) ), $option2 );
This returns a Request with the set parameter of server. I also defined a $option2, this would be a variable often defined in the URL such as:
* #Route("/mydata/{server}/", name="api-source-data")
* #param Request $request
* #param $server
Lastly, if you're passing JSON in that controller and want to convert it back to an object, you can run this bit of code on the $response:
if ( 0 === strpos( $response->headers->get( 'Content-Type' ), 'application/json' ) ) {
$response = json_decode( $response->getContent(), true );
}
Voila. Access any controller form any other controller and bypass security notation for the source controller. :)
Using Laravel 4 to create a "Read-it-Later" application just for testing purposes.
I'm able to successfully store a URL and Description into my application using the following curl command:
curl -d 'url=http://testsite.com&description=For Testing' readitlater.local/api/v1/url
I'm interested in using GET to accomplish the same thing but by passing my variables in a URL (e.g. readitlater.local/api/v1/url?url=testsite.com?description=For%20Testing)
Here is my UrlController segment:
/**
* Store a newly created resource in storage.
*
* #return Response
*/
public function store()
{
$url = new Url;
$url->url = Request::get('url');
$url->description = Request::get('description');
$url->save();
return Response::json(array(
'error' => false,
'urls' => $urls->toArray()),
200
);
}
Here is my Url model:
<?php
class Url extends Eloquent {
protected $table = 'urls';
}
I read through the Laravel docs on input types but I'm not certain how to apply that to my current controller: http://laravel.com/docs/requests#basic-input
Any tips?
You didn't apply what you correctly linked to...Use Input::get() to fetch anything from GET or POST, and the Request class to get info on the current request. Are you looking for something like this?
public function store()
{
$url = new Url; // I guess this is your Model
$url->url = Request::url();
$url->description = Input::get('description');
$url->save();
return Response::json(array(
'error' => false,
'urls' => Url::find($url->id)->toArray(),
/* Not sure about this. You want info for the current url?
(you already have them...no need to query the DB) or you want ALL the urls?
In this case, use Url::all()->toArray()
*/
200
);
}