聚會時間公告: 因應COSCUP 2011, Kalug 8月份休會一次

八月 11, 2015

小惡魔AppleBOY
AppleBOY
is about »

tag cloud

» Facebook React Jest 搭配 Webpack 測試

logo_og

Facebook React 就是要搭配 Webpack,Webpack 已經是前端開發的必備工具,要測試 React Component 就是要用 Facebook 開發的 Jest 框架,使用 Webpack 也許會搭配 Less or Sass Loader 讓每個 component 都可以獨立有 CSS 檔案。要在 JS 內直接引入 CSS 檔案寫法如下

import '!style!css!less!./Schedule.less';
import React, { Component } from 'react';

透過 webpack 就可以把這些 header 檔案 build 成單一檔案,但是遇到的問題是,如果搭配 Jest 測試,我們使用了 babel-jest 來做 script preprocessor 如下

{
  "devDependencies": {
    "babel-jest": "*",
    "jest-cli": "*"
  },
  "scripts": {
    "test": "jest"
  },
  "jest": {
    "scriptPreprocessor": "<rootDir>/node_modules/babel-jest",
    "testFileExtensions": ["es6", "js"],
    "moduleFileExtensions": ["js", "json", "es6"]
  }
}

接著執行 npm test,可以看到會噴出 !style!css!less!./Schedule.less not found,原因就是 babel 看不懂 !style!css!less!,這是 webpack loader 特有的寫法,要解決這問題有兩種方式

  • 所有 Less 檔案全部寫在 Top 目錄內的 app.js
  • 改寫 script preprocessor

第一種方法就是把 less 檔案都獨立寫到最外層的 app.js 檔案,因為通常 app.js 幾乎不用寫測試,裡面只是單純的 initial component 而已,這是一種方法,但是我覺得不是很好,第二種做法是直接將 babel-jest 轉出來的程式碼將 less 部分抽掉,再跑測試。首先在主目錄建立 jest-script-preprocessor.js 內容如下,透過 Regular expression 將 .less 模組去掉。

var babelJest = require('babel-jest');

module.exports = {
  process: function(src, filename) {
    return babelJest.process(src, filename)
      .replace(/require\(\'[^\']+\.less\'\);/gm, '');
  }
};

然後修改 scriptPreprocessor

"jest": {
  "scriptPreprocessor": "<rootDir>/jest-script-preprocessor",
  "unmockedModulePathPatterns": [
    "<rootDir>/node_modules/react",
    "<rootDir>/node_modules/react-tools"
  ],
  "testFileExtensions": [
    "js",
    "jsx"
  ],
  "moduleFileExtensions": [
    "js",
    "json",
    "jsx"
  ]
}

最後建立 __tests__ 目錄,寫下第一個測試檔案

jest.dontMock('../index');

import React from 'react/addons';
let TestUtils = React.addons.TestUtils;
let About;

describe('About Test', () => {

  beforeEach(function() {
    About = require('../index');
  });

  it('should exists', function() {
    // Render into document
    let about = TestUtils.renderIntoDocument(<About />);
    expect(TestUtils.isCompositeComponent(about)).toBeTruthy();
  });
});

現在 Jest 也內建產生 coverage report 只要加上 --coverage 參數即可

Using Jest CLI v0.4.18
 PASS  src/components/About/__tests__/About.js (2.109s)
1 test passed (1 total)
Run time: 2.381s
------------|----------|----------|----------|----------|----------------|
File        |  % Stmts | % Branch |  % Funcs |  % Lines |Uncovered Lines |
------------|----------|----------|----------|----------|----------------|
 About/     |      100 |      100 |      100 |      100 |                |
  index.jsx |      100 |      100 |      100 |      100 |                |
------------|----------|----------|----------|----------|----------------|
All files   |      100 |      100 |      100 |      100 |                |
------------|----------|----------|----------|----------|----------------|

All reports generated

詳細資訊可以參考 Jest Issue 有網友發了 How to test with Jest when I’m using webpack 問題,有興趣的朋友們可以參考看看。

七月 24, 2014

小惡魔AppleBOY
AppleBOY
is about »

tag cloud

» 升級 PHP Facebook SDK 到 4.0.x 版本

CodeIgniter

最近幫公司建立 Staging 環境,申請了新的 FB App 來,用原本 Facebook v3.2.3 SDK 發現已經不能 work 了,去翻了 Facebook Platform Changelog,看到今年 4 月 30 號以後申請的 App 會強制走 v2.0 Auth 機制,所以原本用 php sdk 3.2.3 版本的話,完全無法呼叫 Auth 2.0 API,導致整個網站爛掉,當然線上的網站是不會隨意換 App ID 及 secret,免得怎麼爆掉的都不知道。這次來教學在 CodeIgniter 轉換 PHP Facebook SDK,可以直接參考官方 4.0.0 的教學,原本 3.2.3 版本直接下載程式碼,放到 library 目錄,直接 include 就可以取得 Facebook 個人資料,4.0.0 版本以後,請先確認系統是否升級為 PHP 5.4 版本以上,並且支援 Composer 安裝,當然如果不用 Composer 也可以,只是要 include 很多檔案,真的比較麻煩。

先在根目錄建立 composer.json 內容填入

{
  "require" : {
    "facebook/php-sdk-v4" : "4.0.*"
  }
}

接著執行 composer install,系統會自動建立 vendor 目錄。在 application/libraries 建立 lib_login.php 檔案,並且寫入底下程式碼

<?php  if (! defined('BASEPATH')) exit('No direct script access allowed');

/**
* Name: Facebook Login Library
*
* Author: appleboy
*
*/

require 'vendor/autoload.php';

use Facebook\FacebookSession;
use Facebook\FacebookRequest;
use Facebook\GraphUser;
use Facebook\FacebookRequestException;
use Facebook\FacebookRedirectLoginHelper;

class Lib_login
{
    /**
     * CodeIgniter global
     *
     * @var string
     **/
    protected $ci;

    /**
     * __construct
     *
     * @return void
     * @author Ben
     **/
    public function __construct()
    {
        $this->ci =& get_instance();
        $this->ci->load->library('session');
        $this->ci->config->load('facebook');

        if (! isset($_SESSION)) {
            session_start();
        }
    }

    public function facebook()
    {
        $facebook_default_scope = explode(',', $this->ci->config->item("facebook_default_scope"));
        $facebook_app_id = $this->ci->config->item("facebook_app_id");
        $facebook_api_secret = $this->ci->config->item("facebook_api_secret");

        // init app with app id and secret
        FacebookSession::setDefaultApplication($facebook_app_id, $facebook_api_secret);

        // login helper with redirect_uri
        $helper = new FacebookRedirectLoginHelper(site_url('login/facebook'));
        // see if a existing session exists
        if (isset($_SESSION) && isset($_SESSION['fb_token'])) {
            // create new session from saved access_token
            $session = new FacebookSession($_SESSION['fb_token']);

            // validate the access_token to make sure it's still valid
            try {
                if (!$session->validate()) {
                    $session = null;
                }
            } catch (Exception $e) {
                // catch any exceptions
                $session = null;
            }
        }

        if (!isset($session) || $session === null) {
            // no session exists

            try {
                $session = $helper->getSessionFromRedirect();
            } catch(FacebookRequestException $ex) {
                // When Facebook returns an error
                // handle this better in production code
                print_r($ex);
            } catch(Exception $ex) {
                // When validation fails or other local issues
                // handle this better in production code
                print_r($ex);
            }
        }

        // see if we have a session
        if (isset($session)) {
            // save the session
            $_SESSION['fb_token'] = $session->getToken();
            // create a session using saved token or the new one we generated at login
            $session = new FacebookSession($session->getToken());

            // graph api request for user data
            $request = new FacebookRequest($session, 'GET', '/me');
            $response = $request->execute();
            // get response
            $graphObject = $response->getGraphObject()->asArray();
            $fb_data = array(
                'me' => $graphObject,
                'loginUrl' => $helper->getLoginUrl($facebook_default_scope)
           );
            $this->ci->session->set_userdata('fb_data', $fb_data);

        } else {
            $fb_data = array(
                'me' => null,
                'loginUrl' => $helper->getLoginUrl($facebook_default_scope)
           );
            $this->ci->session->set_userdata('fb_data', $fb_data);
        }

        return $fb_data;
    }
}

最後寫簡單 controller

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Login extends CI_Controller
{
    public function __construct()
    {
        parent::__construct();
        $this->load->library(array('session', 'lib_login'));
    }

    /**
     * facebook login
     *
     * @return void
     * @author appleboy
     **/
    public function facebook()
    {
        $fb_data = $this->lib_login->facebook();

        // check login data
        if (isset($fb_data['me'])) {
            var_dump($fb_data);
        } else {
            echo '<a href="' . $fb_data['loginUrl'] . '">Login</a>';
        }
    }
}

/* End of file login.php */
/* Location: ./application/controllers/login.php */

打開瀏覽器,直接執行 http://xxxx/login/facebook 就可以看到 Facebook 登入連結。所以程式碼都放在 Githubcodeigniter-facebook-php-sdk-v4,歡迎取用。

五月 14, 2010
» COSCUP@Facebook 名片貼

凍仁去年都在 play 國軍Online,只能利用短短的假期到 COSCUP 2009 的攤位打雜,今年則是正式加入籌備團隊,主要以網路行銷、宣傳為主,而吉祥物的設計沿用 2009 年甄選第一名「熱情的啄木鳥」修改,以下是 COSCUP@Facebook 名片貼語法。

<a href="http://www.facebook.com/coscup" title="COSCUP@Facebook" target="_blank"><img src="http://badge.facebook.com/badge/286365882248.4184.634914735.png" width="120" height="156" style="border: 0px;" /></a>



相關連結:
COSCUP@Plurk
COSCUP@Facebook
COSCUP@Facebook

二月 21, 2010
» Facebook Chat on Empathy

自從使用 Facebook 後凍仁就很少開 MSN,掛著又不見得有人敲,加上有在活動的伙伴不是都在 Plurk 上面噗就是用 HTC 掛 Google Talk。

Facebook 原本就有個聊天室可以線上聊天,現在更可以透過 Empathy, Pidgin, Adium, iChat 即時通訊軟體使用,此篇以 Ubuntu 9.10 預設的 Empathy 為主題。

安裝 Empathy,使用 Ubuntu 9.10 以外的發行版本才需另外安裝

jonny@ubuntu:~$ sudo apt-get install empathy

開啟 Empathy:位於 Ubuntu 應用程式 → 網際網路 → Empathy IM 客戶端程式 (還是比較喜歡 Client)

新增 Facebook 帳號:於 編輯 選單找到 帳號 選項。

輸入 Facebook Chat相關資料,並開啟進階選項。
 
  •  登入 ID:xxxx@chat.facebook.com (可登入 Facebook 線上開講 查詢)
  • 密碼:登入 Facebook 的密碼。
  • 要求加密[TLS/SSL]:取消選取
  • 伺服器:chat.facebook.com
開始用 Empathy 跟 Facebook 的朋友們聊天唄。

資料來源:
Facebook 線上開講 - 無所不在,無限暢談 | Facebook

support:

biggo.com.tw

biggo.sg

A Django site.