From 80e2f9fa183291bde06bca39d9ecde9d1ff30533 Mon Sep 17 00:00:00 2001 From: Ramirisu Date: Wed, 27 Mar 2024 22:51:49 +0800 Subject: [PATCH] Show the `ApiWarningPage` when the minor number of `api_version` is not the same. --- package-lock.json | 66 ++++++++++++++++++++++++++++-- package.json | 1 + src/locales/en/translation.json | 5 ++- src/locales/zh-CN/translation.json | 5 ++- src/locales/zh-TW/translation.json | 5 ++- src/pages/Result.jsx | 39 ++++++++++++++++-- src/themes/dark.js | 5 +++ src/themes/light.js | 5 +++ src/utils/apiVersion.js | 25 ++++++++++- src/utils/apiVersion.test.js | 24 +++++++++++ 10 files changed, 168 insertions(+), 12 deletions(-) create mode 100644 src/utils/apiVersion.test.js diff --git a/package-lock.json b/package-lock.json index c8efb85..b1617c2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "react-dom": "^18.2.0", "react-i18next": "^13.0.2", "react-router-dom": "^6.14.1", + "semver": "^7.6.0", "zustand": "^4.5.1" }, "devDependencies": { @@ -172,6 +173,15 @@ "url": "https://opencollective.com/babel" } }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/@babel/generator": { "version": "7.23.6", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", @@ -203,6 +213,15 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/@babel/helper-environment-visitor": { "version": "7.22.20", "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", @@ -2588,6 +2607,15 @@ "node": ">=0.10.0" } }, + "node_modules/eslint-plugin-react/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/eslint-scope": { "version": "7.2.2", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", @@ -3948,6 +3976,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -5442,14 +5479,35 @@ } }, "node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dependencies": { + "lru-cache": "^6.0.0" + }, "bin": { "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" } }, + "node_modules/semver/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, "node_modules/set-function-length": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz", diff --git a/package.json b/package.json index df4c45a..ce2633d 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "react-dom": "^18.2.0", "react-i18next": "^13.0.2", "react-router-dom": "^6.14.1", + "semver": "^7.6.0", "zustand": "^4.5.1" }, "scripts": { diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json index 0f5e6f5..76c7d6e 100644 --- a/src/locales/en/translation.json +++ b/src/locales/en/translation.json @@ -223,9 +223,12 @@ }, "result": { "api_error": { - "description": "Sorry, your result is incompatible with current version. Please do the quiz again.", + "description": "Sorry, the result is incompatible with current version. Please do the quiz again.", "index": "Go to index page" }, + "api_warning": { + "description": "The data being showed is from the old question list. Consider doing the quiz again to obtain latest result." + }, "diff_card": { "compare_with": "Compare with {{name}}", "user": "User", diff --git a/src/locales/zh-CN/translation.json b/src/locales/zh-CN/translation.json index 4fac822..7f840ee 100644 --- a/src/locales/zh-CN/translation.json +++ b/src/locales/zh-CN/translation.json @@ -223,9 +223,12 @@ }, "result": { "api_error": { - "description": "抱歉,您的测试结果无法兼容于目前新版号,请重新进行测试。", + "description": "抱歉,您的结果无法兼容于目前新版号,请重新进行测验。", "index": "回到主页" }, + "api_warning": { + "description": "目前显示的资料是来自旧的问题集,请重新进行测验以获得最新结果。" + }, "diff_card": { "compare_with": "与 {{name}} 的比较", "user": "使用者", diff --git a/src/locales/zh-TW/translation.json b/src/locales/zh-TW/translation.json index da8352f..49538af 100644 --- a/src/locales/zh-TW/translation.json +++ b/src/locales/zh-TW/translation.json @@ -223,9 +223,12 @@ }, "result": { "api_error": { - "description": "抱歉,您的測試結果無法相容於目前新版本,請重新進行測試。", + "description": "抱歉,您的結果無法相容於目前新版本,請重新進行測試。", "index": "回到首頁" }, + "api_warning": { + "description": "目前顯示的資料是來自舊的問題集,請重新進行測試以獲得最新結果。" + }, "diff_card": { "compare_with": "與 {{name}} 的比較", "user": "使用者", diff --git a/src/pages/Result.jsx b/src/pages/Result.jsx index 0e77586..2d2bb69 100644 --- a/src/pages/Result.jsx +++ b/src/pages/Result.jsx @@ -1,6 +1,7 @@ import React, { useState } from 'react' import { useNavigate, useSearchParams } from 'react-router-dom' import { Card, Flex, Switch, message } from 'antd' +import { WarningOutlined } from '@ant-design/icons' import { useTranslation } from 'react-i18next' import { useThemeStore } from '../store/store' import MatchCard from '../components/MatchCard' @@ -9,7 +10,7 @@ import { useBreakpoint, getContentMaxWidth } from '../utils/useBreakpoint' import { getIdeologyTags } from '../data/ideology_tag' import { getIdeologyMatchScores, getPoliticalPartyMatchScores } from '../utils/match' import { getValueConstant } from '../utils/getValueConstant' -import { API_VERSION_KEY, API_VERSION_VALUE } from '../utils/apiVersion' +import { API_VERSION_KEY, isApiVersionCompatible, isApiVersionEqual } from '../utils/apiVersion' import * as stylex from '@stylexjs/stylex' const apiErrorButtonStyles = stylex.create({ @@ -126,7 +127,7 @@ const Result = () => { const [messageApi, contextHolder] = message.useMessage() const [expandTags, setExpandTags] = useState(false, []) - const isApiVersionOK = searchParams.get(API_VERSION_KEY) == API_VERSION_VALUE + const apiVersion = searchParams.get(API_VERSION_KEY) || '' const weights = { economic: searchParams.get('economic'), @@ -196,6 +197,7 @@ const Result = () => { const ApiErrorPage = () => ( { borderStyle: 'solid', borderWidth: '4px', borderRadius: '20px', + padding: '20px', }} >

@@ -225,6 +228,33 @@ const Result = () => { ) + const ApiWarningPage = () => ( + + +

+ {t(`quiz.result.api_warning.description`)} +

+
+ ) + return ( { padding: '5px', }} > - {!isApiVersionOK ? ( + {!isApiVersionCompatible(apiVersion) ? ( ) : ( <> + {!isApiVersionEqual(apiVersion) && } { + const version = fixApiVersion1(apiVersion) + if (!semver.valid(version)) { + return false + } + + return semver.major(version) == semver.major(API_VERSION_VALUE) +} + +export const isApiVersionEqual = (apiVersion) => { + const version = fixApiVersion1(apiVersion) + if (!semver.valid(version)) { + return false + } + + return semver.eq(version, API_VERSION_VALUE) +} + +// For the legacy `api_version=1` not being made as correct semver format. +const fixApiVersion1 = (apiVersion) => (apiVersion == '1' ? '1.0.0' : apiVersion) diff --git a/src/utils/apiVersion.test.js b/src/utils/apiVersion.test.js new file mode 100644 index 0000000..858e15b --- /dev/null +++ b/src/utils/apiVersion.test.js @@ -0,0 +1,24 @@ +import { expect, test } from 'vitest' +import { isApiVersionCompatible, isApiVersionEqual, API_VERSION_VALUE } from './apiVersion' + +test('identical apiVersion', () => { + expect(isApiVersionCompatible(API_VERSION_VALUE)).toBe(true) + expect(isApiVersionEqual(API_VERSION_VALUE)).toBe(true) +}) + +test('incompatible apiVersion', () => { + expect(isApiVersionCompatible('0')).toBe(false) + expect(isApiVersionEqual('0')).toBe(false) + expect(isApiVersionCompatible('0.0.0')).toBe(false) + expect(isApiVersionEqual('0.0.0')).toBe(false) +}) + +test('legacy apiVersion=1', () => { + expect(isApiVersionCompatible('1')).toBe(true) + expect(isApiVersionEqual('1')).toBe(true) +}) + +test('apiVersion with identical major number only', () => { + expect(isApiVersionCompatible('1.1000.0')).toBe(true) + expect(isApiVersionEqual('1.1000.0')).toBe(false) +})