JS不靠譜系列: 寫一個驗證過期時間的函式,包含jest單元測試

CRPER發表於2018-08-01

前言

我們經常用到的token還是cookie,都預設有一個過期時間

我們做鑑權的時候,很依賴這個,所以搗鼓下能不能再嚴謹點

因為之前都是以後臺固定的格式,直接拿到值做一個簡單的判斷;

那,假如後臺傳過來的日期格式變了呢!!

有興趣的瞧瞧,沒興趣的請勿往下走,節省您的時間!


前置基礎

  • jest : 這個測試框架非常不錯,Facebook 出品
  • ES5&&ES6
  • Typescript

我們不講配置,也不講其他瑣碎,只說實現過程


思路分析

重心其實就是圍繞傳參來執行

  • 判斷引數的型別,只考慮兩種情況
  • 數字: 驗證是否為一個正確的時間戳!!!!
  • 字串: 驗證是否是一個datetime格式,亦或者可以轉換成識別的格式(比如 2018/08/01)
  • 型別的轉換及比較
  • 最後返回布林值,來確定該值是否有效

程式碼測試結果

JS不靠譜系列: 寫一個驗證過期時間的函式,包含jest單元測試


程式碼實現

程式碼不多,只涵蓋了這麼幾種情況,具體看測試的文字描述

函式

  • js 版本(isDate.js , 暴露isDate函式,接收一個引數)

function checkDateTime(d) {
  const _date = new Date(d);
  const Now = new Date().getTime();
  const DiffTime = _date.getTime() - Now;

  if (
    _date.getFullYear() === 1970 ||
    _date.getFullYear() < new Date().getFullYear()
  ) {
    // 若是傳入的時間轉換成1970年...那肯定不是我們後臺要傳的時間
    // 小於這個年份的也必然不是,誰的後臺token過期時間超過一年的...
    return false;
  }

  if (DiffTime > 60000) {
    // 過期結束時間必須大於傳入時間
    // 當過期時間還大於一分鐘的時候,
    return true;
  } else {
    // 否則返回false,從外部呼叫這個函式拿到返回值,
    // 做二步處理,續期還是強制退出什麼鬼的
    return false;
  }
}

/**
 * @description 判斷是否為正確的日期
 * @param {*} d
 */
export const isDate = d => {
  // 任何不能給Date識別的引數,子函式呼叫的返回值為NaN
  return isNaN(new Date(d).getTime()) || new Date(d).getTime() === 0
    ? false
    : checkDateTime(d);
};



複製程式碼
  • ts版本(在vscode會有提示錯誤)

DateConstructor: Argument of type 'string | number' is not assignable to parameter of type 'string'.

大體上說日期型別沒法賦值字串型別的值

這個問題似乎等待修復,我在Github上找了,

https://github.com/Microsoft/TypeScript/issues/21758,

有人提交了PR,不知道有沒有合併進去..

https://github.com/Microsoft/TypeScript/commit/7b9ceb85fa4e19ade740faa2af2e00e62e16f7c9


function checkDateTime(d: number | string): boolean {
  const _date: Date = new Date(d);
  const Now: number = new Date().getTime();
  const DiffTime: number = _date.getTime() - Now;

  if (
    _date.getFullYear() === 1970 ||
    _date.getFullYear() < new Date().getFullYear()
  ) {
    // 若是傳入的時間轉換成1970年...那肯定不是我們後臺要傳的時間
    // 小於這個年份的也必然不是,誰的後臺token過期時間超過一年的...
    return false;
  }

  if (DiffTime > 60000) {
    // 當過期時間還大於一分鐘的時候,
    return true;
  } else {
    // 否則返回false,從外部呼叫這個函式拿到返回值,
    // 做二步處理,續期還是強制退出什麼鬼的
    return false;
  }
}

/**
 * @description 判斷是否為正確的日期
 * @param {*} d
 */
export const isDate = (d: string | number) => {
  // 任何不能給Date識別的引數,子函式呼叫的返回值為NaN
  return isNaN(new Date(d).getTime()) || new Date(d).getTime() === 0
    ? false
    : checkDateTime(d);
};


複製程式碼

測試程式碼

import { isDate } from "../../src/utils/isDate";

describe("isDate函式測試集合組", () => {
  test("這種非標準的時間戳只會轉成1970這種,已經過期", () => {
    expect(isDate(21312445)).toBe(false);
  });
  test("已經過期", () => {
    expect(isDate(1533097116565)).toBe(false);
  });
  test("已經過期", () => {
    expect(isDate(1514764800000)).toBe(false);
  });
  test("傳入undefined為false,不傳參就是undefined", () => {
    expect(isDate(undefined)).toBe(false);
  });
  test("傳入null雖然返回0,但也是false", () => {
    expect(isDate(null)).toBe(false);
  });
  test("標準格式的返回true", () => {
    expect(isDate("2018-12-01")).toBe(true);
  });
  test("標準格式的返回true", () => {
    expect(isDate("2018/8/09")).toBe(true);
  });
  test("歷史悠久的也是錯的", () => {
    expect(isDate("1988-10-21")).toBe(false);
  });
  test("非標準格式的返回false", () => {
    expect(isDate("1970-13-51")).toBe(false);
  });
  test("非標準的日期也是false", () => {
    expect(isDate("s2018ww-13-51")).toBe(false);
  });
  test("普通字串會返回fasle", () => {
    expect(isDate("safdaserw")).toBe(false);
  });
});

複製程式碼

總結

純函式測試只要宣告推斷返回值即可, 所以單元測試也非常的直白明瞭..

純函式的好處就是可以低耦合,雖然我們可以在這裡高內聚,比如做續期,請求,路由跳轉什麼的,

那這樣就是一個auth的所有功能了,這不是我想要的,

有不對之處請留言,會及時修正,謝謝閱讀

我的部落格即將搬運同步至騰訊雲+社群,邀請大家一同入駐:https://cloud.tencent.com/developer/support-plan?invite_code=3ohcv8lll3s4c

相關文章