Monday, 20 November 2017

Automated Testing packages in laravel5

1. Laravel.io portal

Recently re-launched Laravel.io has its source published on Github. And Dries Vints has done quite a good job on writing tests there.
Laravel.io is using both Feature testing and Component (more like Unit) testing. What’s interesting is that the same or similar behavior is tested in both cases.
Example 1 – tests/Feature/ReplyTest.php
 public function users_can_add_a_reply_to_a_thread()
    {
        factory(Thread::class)->create(['subject' => 'The first thread', 'slug' => 'the-first-thread']);
        $this->login();
        $this->visit('/forum/the-first-thread')
            ->type('The first reply', 'body')
            ->press('Reply')
            ->see('The first thread')
            ->see('The first reply')

            ->see('Reply successfully added!');
Example 2 – tests/Components/Jobs/CreateReplyTest.php

 public function we_can_create_a_reply()
    {
        $job = new CreateReply('Foo', '', $this->createUser(), factory(Thread::class)->create());
        $this->assertInstanceOf(Reply::class, $job->handle());

    }
This is actually quite a good thing: it tests both Jobs layer and actually clicking things and using it in the browser.
Also what I’ve noticed is that main Laravel.io has been upgraded to Laravel 5.4, but test suite remained in 5.3-style, with BrowserKitTestCase implementation. Nothing wrong with that, just a notice.
Finally, this project also uses continuous integration with Travis, and later I’ve noticed that most projects use it too.
Have you tried our tool to generate Laravel adminpanel without a line of code?
Go to QuickAdminPanel.com

2. Cachet – an open source status page system

Led by James Brooks and Graham Campbell, this project has a massive test suite. It’s even hard to understand by looking at the surface.
So, where do I start here… Actually, I won’t even dig deeper into the testing logic of this project, cause it is really deep. Here’s an example – tests/Models/ComponentTest.php:
use AltThree\TestBench\ValidationTrait;
use CachetHQ\Cachet\Models\Component;
use CachetHQ\Tests\Cachet\AbstractTestCase;
class ComponentTest extends AbstractTestCase
{
    use ValidationTrait;
    public function testValidation()
    {
        $this->checkRules(new Component());
    }
}
Ok, so there’s ValidationTrait being used, then some AbstractTestCase. And this logic is all over tests – some abstracted “magic” which is doing all the work.
And I’m not saying it is a bad thing – pretty sure it works damn well under the hood. It’s just not easy to learn and follow from this test suite. But if someone wants to dig deeper – good luck!

3. October CMS

No.1 Laravel-based CMS on the market, and it has pretty good testing suite.
First thing – tests folder has a really informative readme.md file, specifically for testing process.
All testing in October CMS consists of:
  • Unit testing
  • Functional testing
  • Plugin testing
And each of these “zones” has its own base class to extend – there’s TestCase, UiTestCaseand PluginTestCase.
The logic is also quite complicated and abstracted – here’s an example tests/unit/backend/models/ExportModelTest.php:
class ExportModelTest extends TestCase
{
    //
    // Helpers
    //
    protected static function callProtectedMethod($object, $name, $params = [])
    {
        $className = get_class($object);
        $class = new ReflectionClass($className);
        $method = $class->getMethod($name);
        $method->setAccessible(true);
        return $method->invokeArgs($object, $params);
    }
    //
    // Tests
    //
    public function testEncodeArrayValue()
    {
        $model = new ExampleExportModel;
        $data = ['foo', 'bar'];
        $result = self::callProtectedMethod($model, 'encodeArrayValue', [$data]);
        $this->assertEquals('foo|bar', $result);
        $data = ['dps | heals | tank', 'paladin', 'berserker', 'gunner'];
        $result = self::callProtectedMethod($model, 'encodeArrayValue', [$data]);
        $this->assertEquals('dps \| heals \| tank|paladin|berserker|gunner', $result);
        $data = ['art direction', 'roman empire', 'sci-fi'];
        $result = self::callProtectedMethod($model, 'encodeArrayValue', [$data, '-']);
        $this->assertEquals('art direction-roman empire-sci\-fi', $result);
    }
}
As you can see, there’s a static helper method (which is, by the way, repeating in other classes, too), then getting class/method and calling it. I’m sure that the creators understand this logic immediately, but it’s hard for outsiders.
What’s also interesting, OctoberCMS uses Selenium for some features: setup documentation is mentioned in tests/readme.md file.

4. Orgmanager – Invite System for GitHub Organizations

This is quite a simple project by Miguel Piedrafita, Orgmanager’s tests are also pretty simple and understandable. Also divided into Unit, Feature and API tests.
What I’ve seen here is an interesting case – calling Artisan commands from tests, like unit/JoinTest.php:
public function testJoinCommand()
    {
        $user = factory(User::class)->create();
        $org = factory(Org::class)->create([
          'userid' => $user->id,
        ]);
        Github::shouldReceive('authenticate')
                  ->once()
                  ->with($org->user->token, null, 'http_token')
                  ->andReturn();
        Artisan::call('orgmanager:joinorg', [
          'org'      => $org->id,
          'username' => $user->github_username,
        ]);
        $this->assertEquals($user->github_username.' was invited to '.$org->name."\n", Artisan::output());
    }
Calling artisan command and asserting its output – pretty interesting. I’m sure it works, but really non-standard way.

5. PHPMap

Created and maintained by Florian Wartner.
PHPMap has a tests suite which reminds of the standards shown by Laracasts or Test-Driven Laravel course. Here’s an example of Feature/FavoritesTest.php:

public function guests_can_not_favorite_anything()
    {
        $this->withExceptionHandling()
            ->post('forum/replies/1/favorites')
            ->assertRedirect('/login');
    }
    public function an_authenticated_user_can_favorite_any_reply()
    {
        $this->signIn();
        $reply = create('App\Models\Forum\Reply');
        $this->post('forum/replies/'.$reply->id.'/forum/favorites');
        $this->assertCount(1, $reply->favorites);
    }

PHPMap’s tests are divided into Unit, Feature and… wait for it… Laravel Dusk! Finally I’ve found the project which actually uses Dusk in production. Here’s how it looks – tests/Browser/MapTest.php:

public function testMap()
    {
        $this->browse(function ($browser) {
            $browser->visit('/map')
                    ->assertSee('PHPMap');
        });
    }
6. Timegrid – Free, open-source, online appointments platform
The biggest contributor to Timegrid is Ariel Vallese, and he’s done the pretty awesome job with tests here.
There are just a lot of tests here: Unit, Acceptance and Integration, and every folder have a few sub-folders deeper. Here’s an example – acceptance/scenarios/consulting/ConsultingScenarioTest.php:

public function it_fits_for_consulting_scenario()
    {
        $this->arrangeScenario();
        $this->the_business_publishes_a_consulting_service();
        $this->the_business_publishes_vacancies();
        $this->a_user_subscribes_to_business();
        $this->the_user_queries_vacancies();
        $this->it_provides_available_times_for_requested_service_date();
        $this->the_user_takes_a_reservation();
        $this->the_user_sees_the_reservation_ticket();
    }
    public function the_business_publishes_a_consulting_service()
    {
        $this->service = $this->makeService([
            'name'     => 'OnSite 4hs Support',
            'duration' => 60 * 4,
            ]);
        $this->actingAs($this->owner);
        $this->call('POST', route('manager.business.service.store', $this->business), $this->service->toArray());
        $this->assertCount(1, $this->business->fresh()->services);
    }

One all-in-one method and then some more test cases one by one.
The official stats in the repository look pretty good: 89% Tests Coverage.
Finally, what is interesting, an author is also testing migrations, here’s tests/unit/migration/MigrationTest.php:

 public function it_refreshes_rollbacks_and_seeds_the_database()
    {
        $database = env('DB_CONNECTION');
        $this->assertNotNull($database);
        $exitCode = Artisan::call('migrate:refresh', ['--database' => $database]);
        $this->assertEquals(0, $exitCode);
        $exitCode = Artisan::call('migrate:rollback', ['--database' => $database]);
        $this->assertEquals(0, $exitCode);
        $exitCode = Artisan::call('migrate', ['--database' => $database]);
        $this->assertEquals(0, $exitCode);
        $exitCode = Artisan::call('db:seed', ['--database' => $database]);
        $this->assertEquals(0, $exitCode);
    }
Using Artisan commands in tests might not be the greatest design pattern, but it simply tests one of the most important functions of any web app.

Thursday, 16 November 2017

How Can we get email ID from Twitter oauth API? Solution

How to get email id of the user who accepted my Twitter application?
I have gone through a lot of forums. But they have mentioned, it is not possible. Also, those posts are older than a year. May I know whether it is possible to get the user email id through twitter API using PHP?
Answer:
Now you can fetch user email address from Twitter API and it's a lot much easier. Just follow these steps...
  1. Click on 'Create New App'
  2. Fill all required credentials and click on 'Create your Twitter application'
  3. Now click on 'Permissions' tab -> check 'Request email addresses from users' field and click on 'Update Settings'. (check given picture)
  4. Now in your PHP code, set all app details and add this code!
    $params = array('include_email' => 'true', 'include_entities' => 'false', 'skip_status' => 'true');
    $data = $connection->get('account/verify_credentials', $params); // get the data
    // getting twitter user profile details $twt_id = $data->id; //twitter user id $twt_email = $data->email; //twitter user email
All Done. Hope it helps you, good luck.

Monday, 13 November 2017

Optimize images in your Laravel 5 application

This package is the Laravel 5.4 and up specific integration of spatie/image-optimizer. It can optimize PNGs, JPGs, SVGs and GIFs by running them through a chain of various image optimization tools. The package will automatically detect which optimization binaries are installed on your system and use them.
Here's how you can use it:
use ImageOptimizer;

// the image will be replaced with an optimized version which should be smaller
ImageOptimizer::optimize($pathToImage);

// if you use a second parameter the package will not modify the original
ImageOptimizer::optimize($pathToImage, $pathToOptimizedImage);
You don't like facades you say? No problem! Just resolve a configured instance of Spatie\ImageOptimizer\OptimizerChain out of the container:
app(Spatie\ImageOptimizer\OptimizerChain::class)->optimize($pathToImage);
The package also contains a middleware to automatically optimize all images in an request.
Don't use Laravel you say? No problem! Just use the underlying spatie/image-optimizer directly.

Installation

You can install the package via composer:
composer require spatie/laravel-image-optimizer
The package will automatically register itself.
The package uses a bunch of binaries to optimize images. To learn which ones on how to install them, head over to the optimization tools section in the readme of the underlying image-optimizer package. That readme also contains info on what these tools will do to your images.
The package comes with some sane defaults to optimize images. You can modify that configuration by publishing the config file.
php artisan vendor:publish --provider="Spatie\LaravelImageOptimizer\ImageOptimizerServiceProvider"
This is the contents of the config/image-optimizer file that will be published:
use Spatie\ImageOptimizer\Optimizers\Svgo;
use Spatie\ImageOptimizer\Optimizers\Optipng;
use Spatie\ImageOptimizer\Optimizers\Gifsicle;
use Spatie\ImageOptimizer\Optimizers\Pngquant;
use Spatie\ImageOptimizer\Optimizers\Jpegoptim;

return [
    /**
     * When calling `optimize` the package will automatically determine which optimizers
     * should run for the given image.
     */
    'optimizers' => [

        Jpegoptim::class => [
            '--strip-all',  // this strips out all text information such as comments and EXIF data
            '--all-progressive'  // this will make sure the resulting image is a progressive one
        ],

        Pngquant::class => [
            '--force' // required parameter for this package
        ],

        Optipng::class => [
            '-i0', // this will result in a non-interlaced, progressive scanned image
            '-o2',  // this set the optimization level to two (multiple IDAT compression trials)
            '-quiet' // required parameter for this package
        ],

        Svgo::class => [
            '--disable=cleanupIDs' // disabling because it is know to cause troubles
        ],

        Gifsicle::class => [
            '-b', // required parameter for this package
            '-O3' // this produces the slowest but best results
        ],
    ],

    /**
     * The maximum time in seconds each optimizer is allowed to run separately.
     */
    'timeout' => 60,

    /**
     * If set to `true` all output of the optimizer binaries will be appended to the default log.
     * You can also set this to a class that implements `Psr\Log\LoggerInterface`.
     */
    'log_optimizer_activity' => false,
];
If you want to automatically optimize images that get uploaded to your application add the \Spatie\LaravelImageOptimizer\Middlewares\OptimizeImages::class in the http kernel.
// app/Http/Kernel.php
protected $routeMiddleware = [
   ...
   'optimizeImages' => \Spatie\LaravelImageOptimizer\Middlewares\OptimizeImages::class,
];

Usage

You can resolve a configured instance of Spatie\ImageOptimizer\OptimizerChain out of the container:
// the image will be replaced with an optimized version which should be smaller
app(Spatie\ImageOptimizer\OptimizerChain::class)->optimize($pathToImage);

// if you use a second parameter the package will not modify the original
app(Spatie\ImageOptimizer\OptimizerChain::class)->optimize($pathToImage, $pathToOptimizedImage);

Using the facade

use ImageOptimizer;

// the image will be replaced with an optimized version which should be smaller
ImageOptimizer::optimize($pathToImage);

// if you use a second parameter the package will not modify the original
ImageOptimizer::optimize($pathToImage, $pathToOptimizedImage);
You don't like facades you say? No problem! Just resolve a configured instance of Spatie\ImageOptimizer\OptimizerChain out of the container:
app(Spatie\ImageOptimizer\OptimizerChain::class)->optimize($pathToImage);

Using the middleware

All images that in requests to routes that use the optimizeImages-middleware will be optimized automatically.
Route::middleware('optimizeImages')->group(function () {
    // all images will be optimized automatically
    Route::post('upload-images', 'UploadController@index');
});

Adding your own optimizers

To learn how to create your own optimizer read the "Writing custom optimizers" section in the readme of the underlying spatie/image-optimizer package.
You can add the fully qualified classname of your optimizer as a key in the optimizers array in the config file.

Example conversions


Here are some example conversions that were made by the optimizer.

Source: https://github.com/spatie/laravel-image-optimizer

cURL error 60: SSL certificate problem: unable to get local issuer certificate (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) in Laravel

  WampServer: Download this file:  http://curl.haxx.se/ca/cacert.pem Place this file in the  C:\wamp64\bin\php\php7.1.9  folder Open  php.in...

Popular Articles