diff --git a/src/components/views/dialogs/ChangelogDialog.tsx b/src/components/views/dialogs/ChangelogDialog.tsx index a33b2413ee..ae3c157c78 100644 --- a/src/components/views/dialogs/ChangelogDialog.tsx +++ b/src/components/views/dialogs/ChangelogDialog.tsx @@ -15,8 +15,8 @@ import Spinner from "../elements/Spinner"; import Heading from "../typography/Heading"; interface IProps { - newVersion: string; - version: string; + newVersion: DevelopVersionString; + version: DevelopVersionString; onFinished: (success: boolean) => void; } @@ -32,6 +32,28 @@ interface Commit { const REPOS = ["element-hq/element-web", "matrix-org/matrix-js-sdk"] as const; +export type DevelopVersionString = string & { _developVersionString: never }; + +/* + * Parse a version string is compatible with the Changelog dialog ([element-version]-js-[js-sdk-version]) + */ +export function parseVersion(version: string): Record<(typeof REPOS)[number], string> | null { + const parts = version.split("-"); + if (parts.length === 3 && parts[1] === "js") { + const obj: Record = {}; + for (let i = 0; i < REPOS.length; i++) { + const commit = parts[2 * i]; + obj[REPOS[i]] = commit; + } + return obj; + } + return null; +} + +export function checkVersion(version: string): version is DevelopVersionString { + return parseVersion(version) !== null; +} + export default class ChangelogDialog extends React.Component { public constructor(props: IProps) { super(props); @@ -58,14 +80,11 @@ export default class ChangelogDialog extends React.Component { } public componentDidMount(): void { - const version = this.props.newVersion.split("-"); - const version2 = this.props.version.split("-"); - if (version == null || version2 == null) return; - // parse versions of form: [vectorversion]-react-[react-sdk-version]-js-[js-sdk-version] - for (let i = 0; i < REPOS.length; i++) { - const oldVersion = version2[2 * i]; - const newVersion = version[2 * i]; - this.fetchChanges(REPOS[i], oldVersion, newVersion); + const commits = parseVersion(this.props.version)!; + const newCommits = parseVersion(this.props.newVersion)!; + + for (const repo of REPOS) { + this.fetchChanges(repo, commits[repo], newCommits[repo]); } } diff --git a/src/toasts/UpdateToast.tsx b/src/toasts/UpdateToast.tsx index a0ee6b8089..786b626317 100644 --- a/src/toasts/UpdateToast.tsx +++ b/src/toasts/UpdateToast.tsx @@ -13,21 +13,12 @@ import SdkConfig from "../SdkConfig"; import GenericToast from "../components/views/toasts/GenericToast"; import ToastStore from "../stores/ToastStore"; import QuestionDialog from "../components/views/dialogs/QuestionDialog"; -import ChangelogDialog from "../components/views/dialogs/ChangelogDialog"; +import ChangelogDialog, { checkVersion } from "../components/views/dialogs/ChangelogDialog"; import PlatformPeg from "../PlatformPeg"; import Modal from "../Modal"; const TOAST_KEY = "update"; -/* - * Check a version string is compatible with the Changelog - * dialog ([element-version]-react-[react-sdk-version]-js-[js-sdk-version]) - */ -function checkVersion(ver: string): boolean { - const parts = ver.split("-"); - return parts.length === 5 && parts[1] === "react" && parts[3] === "js"; -} - function installUpdate(): void { PlatformPeg.get()?.installUpdate(); } diff --git a/test/unit-tests/components/views/dialogs/ChangelogDialog-test.tsx b/test/unit-tests/components/views/dialogs/ChangelogDialog-test.tsx index e16abb0e83..547534d207 100644 --- a/test/unit-tests/components/views/dialogs/ChangelogDialog-test.tsx +++ b/test/unit-tests/components/views/dialogs/ChangelogDialog-test.tsx @@ -10,7 +10,10 @@ import React from "react"; import fetchMock from "fetch-mock-jest"; import { render, screen, waitForElementToBeRemoved } from "jest-matrix-react"; -import ChangelogDialog from "../../../../../src/components/views/dialogs/ChangelogDialog"; +import ChangelogDialog, { + DevelopVersionString, + parseVersion, +} from "../../../../../src/components/views/dialogs/ChangelogDialog"; describe("", () => { it("should fetch github proxy url for each repo with old and new version strings", async () => { @@ -64,8 +67,8 @@ describe("", () => { files: [], }); - const newVersion = "newsha1-js-newsha3"; - const oldVersion = "oldsha1-js-oldsha3"; + const newVersion = "newsha1-js-newsha3" as DevelopVersionString; + const oldVersion = "oldsha1-js-oldsha3" as DevelopVersionString; const { asFragment } = render( , ); @@ -78,3 +81,24 @@ describe("", () => { expect(asFragment()).toMatchSnapshot(); }); }); + +describe("parseVersion", () => { + it("should return null for old-style version strings", () => { + expect(parseVersion("aaaabbbb-react-ccccdddd-js-eeeeffff")).toBeNull(); + }); + + it("should return null for invalid version strings", () => { + expect(parseVersion("aaaabbbb-react-ccccdddd")).toBeNull(); + }); + + it("should return null for release version strings", () => { + expect(parseVersion("v1.22.33")).toBeNull(); + }); + + it("should return mapping for develop version string", () => { + expect(parseVersion("aaaabbbb-js-eeeeffff")).toEqual({ + "element-hq/element-web": "aaaabbbb", + "matrix-org/matrix-js-sdk": "eeeeffff", + }); + }); +});