@@ -13,9 +13,11 @@ import { describe, expect, it, vi } from "vitest";
1313import type { AppSettings , WorkspaceInfo } from "@/types" ;
1414import {
1515 connectWorkspace ,
16+ getAppBuildType ,
1617 getAgentsSettings ,
1718 getConfigModel ,
1819 getExperimentalFeatureList ,
20+ isMobileRuntime ,
1921 getModelList ,
2022 listWorkspaces ,
2123} from "@services/tauri" ;
@@ -34,22 +36,28 @@ vi.mock("@services/tauri", async () => {
3436 return {
3537 ...actual ,
3638 connectWorkspace : vi . fn ( ) ,
39+ getAppBuildType : vi . fn ( ) ,
3740 getModelList : vi . fn ( ) ,
3841 getConfigModel : vi . fn ( ) ,
3942 getExperimentalFeatureList : vi . fn ( ) ,
4043 getAgentsSettings : vi . fn ( ) ,
44+ isMobileRuntime : vi . fn ( ) ,
4145 listWorkspaces : vi . fn ( ) ,
4246 } ;
4347} ) ;
4448
4549const connectWorkspaceMock = vi . mocked ( connectWorkspace ) ;
50+ const getAppBuildTypeMock = vi . mocked ( getAppBuildType ) ;
4651const getConfigModelMock = vi . mocked ( getConfigModel ) ;
4752const getModelListMock = vi . mocked ( getModelList ) ;
4853const getExperimentalFeatureListMock = vi . mocked ( getExperimentalFeatureList ) ;
4954const getAgentsSettingsMock = vi . mocked ( getAgentsSettings ) ;
55+ const isMobileRuntimeMock = vi . mocked ( isMobileRuntime ) ;
5056const listWorkspacesMock = vi . mocked ( listWorkspaces ) ;
5157connectWorkspaceMock . mockResolvedValue ( undefined ) ;
58+ getAppBuildTypeMock . mockResolvedValue ( "release" ) ;
5259getConfigModelMock . mockResolvedValue ( null ) ;
60+ isMobileRuntimeMock . mockResolvedValue ( false ) ;
5361listWorkspacesMock . mockResolvedValue ( [ ] ) ;
5462getAgentsSettingsMock . mockResolvedValue ( {
5563 configPath : "/Users/me/.codex/config.toml" ,
@@ -105,6 +113,7 @@ const baseSettings: AppSettings = {
105113 showMessageFilePath : true ,
106114 chatHistoryScrollbackItems : 200 ,
107115 threadTitleAutogenerationEnabled : false ,
116+ automaticAppUpdateChecksEnabled : true ,
108117 uiFontFamily :
109118 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif' ,
110119 codeFontFamily :
@@ -267,6 +276,56 @@ const renderComposerSection = (
267276 return { onUpdateAppSettings } ;
268277} ;
269278
279+ const renderAboutSection = (
280+ options : {
281+ appSettings ?: Partial < AppSettings > ;
282+ onUpdateAppSettings ?: ComponentProps < typeof SettingsView > [ "onUpdateAppSettings" ] ;
283+ onToggleAutomaticAppUpdateChecks ?: ComponentProps <
284+ typeof SettingsView
285+ > [ "onToggleAutomaticAppUpdateChecks" ] ;
286+ } = { } ,
287+ ) => {
288+ cleanup ( ) ;
289+ const onUpdateAppSettings =
290+ options . onUpdateAppSettings ?? vi . fn ( ) . mockResolvedValue ( undefined ) ;
291+ const onToggleAutomaticAppUpdateChecks =
292+ options . onToggleAutomaticAppUpdateChecks ?? vi . fn ( ) ;
293+ const props : ComponentProps < typeof SettingsView > = {
294+ reduceTransparency : false ,
295+ onToggleTransparency : vi . fn ( ) ,
296+ appSettings : { ...baseSettings , ...options . appSettings } ,
297+ openAppIconById : { } ,
298+ onUpdateAppSettings,
299+ onToggleAutomaticAppUpdateChecks,
300+ workspaceGroups : [ ] ,
301+ groupedWorkspaces : [ ] ,
302+ ungroupedLabel : "Ungrouped" ,
303+ onClose : vi . fn ( ) ,
304+ onMoveWorkspace : vi . fn ( ) ,
305+ onDeleteWorkspace : vi . fn ( ) ,
306+ onCreateWorkspaceGroup : vi . fn ( ) . mockResolvedValue ( null ) ,
307+ onRenameWorkspaceGroup : vi . fn ( ) . mockResolvedValue ( null ) ,
308+ onMoveWorkspaceGroup : vi . fn ( ) . mockResolvedValue ( null ) ,
309+ onDeleteWorkspaceGroup : vi . fn ( ) . mockResolvedValue ( null ) ,
310+ onAssignWorkspaceGroup : vi . fn ( ) . mockResolvedValue ( null ) ,
311+ onRunDoctor : vi . fn ( ) . mockResolvedValue ( createDoctorResult ( ) ) ,
312+ onUpdateWorkspaceSettings : vi . fn ( ) . mockResolvedValue ( undefined ) ,
313+ scaleShortcutTitle : "Scale shortcut" ,
314+ scaleShortcutText : "Use Command +/-" ,
315+ onTestNotificationSound : vi . fn ( ) ,
316+ onTestSystemNotification : vi . fn ( ) ,
317+ dictationModelStatus : null ,
318+ onDownloadDictationModel : vi . fn ( ) ,
319+ onCancelDictationDownload : vi . fn ( ) ,
320+ onRemoveDictationModel : vi . fn ( ) ,
321+ } ;
322+
323+ render ( < SettingsView { ...props } /> ) ;
324+ fireEvent . click ( screen . getByRole ( "button" , { name : "About" } ) ) ;
325+
326+ return { onUpdateAppSettings, onToggleAutomaticAppUpdateChecks } ;
327+ } ;
328+
270329const renderFeaturesSection = (
271330 options : {
272331 appSettings ?: Partial < AppSettings > ;
@@ -673,6 +732,28 @@ describe("SettingsView Display", () => {
673732 } ) ;
674733} ) ;
675734
735+ describe ( "SettingsView About" , ( ) => {
736+ it ( "toggles automatic app update checks" , async ( ) => {
737+ const onToggleAutomaticAppUpdateChecks = vi . fn ( ) ;
738+ renderAboutSection ( {
739+ onToggleAutomaticAppUpdateChecks,
740+ appSettings : { automaticAppUpdateChecksEnabled : false } ,
741+ } ) ;
742+
743+ const row = screen
744+ . getByText ( "Automatically check for app updates" )
745+ . closest ( ".settings-toggle-row" ) as HTMLElement | null ;
746+ if ( ! row ) {
747+ throw new Error ( "Expected automatic app update checks row" ) ;
748+ }
749+ fireEvent . click ( within ( row ) . getByRole ( "button" ) ) ;
750+
751+ await waitFor ( ( ) => {
752+ expect ( onToggleAutomaticAppUpdateChecks ) . toHaveBeenCalledTimes ( 1 ) ;
753+ } ) ;
754+ } ) ;
755+ } ) ;
756+
676757describe ( "SettingsView Environments" , ( ) => {
677758 it ( "saves the setup script for the selected project" , async ( ) => {
678759 const onUpdateWorkspaceSettings = vi . fn ( ) . mockResolvedValue ( undefined ) ;
0 commit comments