-->

網頁

顯示具有 Laravel 標籤的文章。 顯示所有文章
顯示具有 Laravel 標籤的文章。 顯示所有文章

2019/10/07

Laravel UrlGenerator 判斷 HTTP or HTTPS 的因素

第一個要求 Laravel 要使用 HTTP or HTTPS (以下簡稱 protocol ... 因為字太多了 .._Drz) 的方法,其實就是在「.env」做設定,例如:
APP_URL=http://zeroplex.tw

再來網路上應該會找到,要開發者在 AppServiceProvider 中加入設定:
\URL::forceScheme('https');

這邊的 URL facade,可以從 config/app.php 中追蹤到,是 \Illuminate\Routing\UrlGenerator::class 的 alias,設定了 forceSheme() 以後,未來透過 UrlGenerator 建立的 link 都會是設定好的 protocol。

BUT .... 就是這個 BUT,若是遇到另一個其他的 method 來產生 URL (例如 Illuminate\Routing\Redirector::route() ...),這樣就可能吃到開發者設定的 protocol ,則由 Laravel 會自動抓進來的 request 來判斷該用什麼 protocol,若 application 剛好是靠 Nginx 在 handle HTTP SSL 的話,request 到 Laravel 這端時 HTTPS 就已經轉成 HTTP,導致 Laravel 以為 application 沒有上 HTTPS。

若要讓 reverse proxy 後面的 Laravel application 都固定用 HTTPS 的話,可以再到 app/Http/Middleware/TrustedProxy.php 去修改設定,讓 Laravel 識別 proxy 做出對應的動作 (給正確的 protocol)。



Ref: Laravel 5 force HTTPS issue with login routing to HTTP

2019/07/18

使用 Eloquent migration 刪除有 key constrain 的 table / index

建立 table 時可能會同時建立 foreign key:
$table->foreign('good_id')
    ->references('id')
    ->on('goods')
    ->onDelete('cascade');

$table->index('value');

這個情況下要直接 dropIndex() 是會出現錯誤的,要先把 key constraint 解掉再來刪除 index。

而 constraint key name 用 show index from TABLE 是看不到的,但是可以使用下面的語法看到 create table 時做的事情:
show create table NAME

看到 contrain key name 以後先用 dropForeign() 刪除,再 dropIndex() 即可。

ps. 記得事情處理完以後,要把 constraint 加回去喔

2019/06/28

注意 PHPUnit 的 fixture 行為

理論上,各個 test case 不應該互相影響,所以 PHPUnit 設計的 fixtures 像是 setUp() 和 tearDown() 都會在各個 test case 前後執行。

簡單做個測試:
<?php

use PHPUnit\Framework\TestCase;

class LibTest extends TestCase
{
    public function setUp(): void
    {
        $this->data = null;
    }

    public function tearDown(): void
    {
        $this->data = null;
    }

    public function testOne()
    {
        $this->data = 123;
        $this->assertEquals(123, $this->data);

        return $this->data;
    }

    /**
     * @depends testOne
     */
    public function testTwo($data)
    {
        $this->assertEquals(123, $this->data);
    }
}

// -----

PHPUnit 8.2.3 by Sebastian Bergmann and contributors.

.F

即使在 test case 加上 @depends 標記,fixture 也會運作,所以若是要讓下一個 test case 繼續使用的測試值,都必須用 return 的方式傳值。

----

另外,Laravel 提供的 testing tools 也有相同的行為。例如:「RefreshDatabase」,在 test case 執行結束以後就會把資料清空,因此如果要對 DB 做多像檢查,就必須在同一個 test case 中建立多個 assertions (個人不喜歡這樣做),不然即使加上 @depends,DB 中的資料也會被 refresh 掉。

2019/06/27

在 Laravel unit test 手動建立 HTTP request

現在有個 controller 收到 HTTP POST data 以後才會動作,且這個 controller 為 AJAX controller,沒有 view 沒辦法用 Selenium 測試:
class TargetController extends Controller
{
    public function doSomething(Request $req)
    {
        // do something ....
    }
}

要測試的話,其實可以透過一些工具手動測試,像是 PostMan 等類似的工具。但這種測試會遇到一些問題:Middle 有檢查使用者身份、需要拿到 access token 才能進 controller 等等。這樣會讓測試多了不少不確定因素 (變因),導致測試結果不準確。

要進行測試較好的方法,就是建立一個 HTTP request 來模擬實際情況:
$req = new \lluminate\Http\Request();

$ctrl = new TargetController()
$result = $ctrl->doSomething($req);

不過可惜的是 Request 這個類別,設計原始的用意是從 $_GET、$_POST、$_FILE 等全域變數整理成物件方便 access,所以若要在 request 中加入參數,目前只能透過 replace() 來增加。例如需要新增 key/value pair,必須這樣撰寫:
$request->replace([
    'key' => 'value',
]);

至於模擬檔案上傳 .... 我還在找方法,確定了以後再來寫筆記。



Ref:

2017/03/05

Laravel 5.3 的 API routing

弄了很久才搞清楚 5.3 版的 routing 是怎麼搞的,覺得作者把事情弄的更複雜了,也少了一些彈性。

Laravel 5.3 中,routes 已經不是放在 App/Http 底下了,將設定獨立出來放在根目錄:
johnroyer@box:~/devel/laravel53$ tree routes
routes
├── api.php
├── console.php
└── web.php

有個 API 專用 routing 看了當然開心,只是怎麼樣都是不出來 api.php 這邊的設定要怎樣才能起作用。

後來找了很久才發現 Route 功能,已經在 provider 階段把 web / api 的 routing rule 寫死,所以 API 的 routing 有固定的 prefix,在網址是上必須是「http://laravel.root/api」開頭,才會吃到 api.php 的設定。該項 rule 被寫在 RouteServiceProvider 中:
    protected function mapApiRoutes()
    {
        Route::group([
            'middleware' => 'api',
            'namespace' => $this->namespace,
            'prefix' => 'api',
        ], function ($router) {
            require base_path('routes/api.php');
        });
    }


Reference: