Compare commits

..
Author SHA1 Message Date
Graham SteffaniakandCursor 202d9b953a fix(backend): use atomic settings helpers in tests
- media_settings_handler_test: use ApplyMediaSettings/CurrentMediaSettings
  instead of mutating settings.Config.Integrations.Media directly
- settings_redact_test: SwapConfigForTest helper so concurrent tests don't
  race on the global settings.Config
- preview/fill_test: t.Parallel() on the fill subtests

Splits be2b16b0d's backend hunk; base is 493f8f741 (post-merge lockfix).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-11-14 20:31:24 -06:00
7 changed files with 39 additions and 31 deletions

No files matched your search

+1
View File
@@ -93,6 +93,7 @@ func TestFillCenter_MatchesImagingFill(t *testing.T) {
for _, tg := range targets {
for fname, f := range filters {
t.Run(fmt.Sprintf("%s/%dx%d/%s", name, tg[0], tg[1], fname), func(t *testing.T) {
t.Parallel()
want := imaging.Fill(src, tg[0], tg[1], imaging.Center, f)
got := fillCenter(src, tg[0], tg[1], f)
require.Equal(t, fmt.Sprintf("%T", want), fmt.Sprintf("%T", got), "image type")
@@ -13,14 +13,15 @@ import (
func withMediaHandlerSettings(t *testing.T) {
t.Helper()
originalTranscode := settings.Config.Integrations.Media.Transcode
originalMedia := settings.CurrentMediaSettings()
originalFFmpeg := settings.Env.FFmpegAvailable
t.Cleanup(func() {
settings.Config.Integrations.Media.Transcode = originalTranscode
settings.Env.FFmpegAvailable = originalFFmpeg
settings.ApplyMediaSettings(originalMedia)
})
settings.Env.FFmpegAvailable = true
settings.Config.Integrations.Media.Transcode = settings.FullAdminTranscode{
media := originalMedia
media.Transcode = settings.FullAdminTranscode{
UserTranscode: settings.UserTranscode{
Enabled: true,
MaxConcurrentPerUser: 2,
@@ -28,6 +29,7 @@ func withMediaHandlerSettings(t *testing.T) {
MaxConcurrent: 3,
Profiles: settings.DefaultTranscodeProfiles(),
}
settings.ApplyMediaSettings(media)
}
func mediaHandlerContext(admin bool) *Context {
@@ -154,7 +156,9 @@ func TestSettingsMediaHandlerFullPayloadForAdmin(t *testing.T) {
// Disabling transcoding at runtime must be visible to non-admin players.
func TestSettingsMediaHandlerReflectsDisabledTranscode(t *testing.T) {
withMediaHandlerSettings(t)
settings.Config.Integrations.Media.Transcode.Enabled = false
disabled := settings.CurrentMediaSettings()
disabled.Transcode.Enabled = false
settings.ApplyMediaSettings(disabled)
transcode := objectField(t, callMediaGet(t, false), "transcode")
if enabled, ok := transcode["enabled"].(bool); !ok || enabled {
+27 -17
View File
@@ -13,21 +13,31 @@ import (
const settingsRedactSentinel = "SENTINEL-SETTINGS-SECRET"
func swapSettingsConfigForTest(t *testing.T, mutate func(*settings.Settings)) {
t.Helper()
cfg := settings.Config
if mutate != nil {
mutate(&cfg)
}
prev := settings.SwapConfigForTest(cfg)
t.Cleanup(func() { settings.SwapConfigForTest(prev) })
}
// TestSettingsGetHandler_redactsSecrets is the end-to-end regression guard for
// GHSA-892f-9h5p-mfc8: GET /api/settings (and ?property=auth) must not return cleartext secrets.
func TestSettingsGetHandler_redactsSecrets(t *testing.T) {
setupTestEnv(t)
prev := settings.Config
t.Cleanup(func() { settings.Config = prev })
settings.Config.Auth.Key = settingsRedactSentinel
settings.Config.Auth.TotpSecret = settingsRedactSentinel
settings.Config.Auth.Methods.PasswordAuth.AdminPassword = settingsRedactSentinel
settings.Config.Auth.Methods.PasswordAuth.Recaptcha.Secret = settingsRedactSentinel
settings.Config.Auth.Methods.OidcAuth.ClientSecret = settingsRedactSentinel
settings.Config.Auth.Methods.LdapAuth.UserPassword = settingsRedactSentinel
settings.Config.Auth.Methods.JwtAuth.Secret = settingsRedactSentinel
settings.Config.Integrations.OnlyOffice.Secret = settingsRedactSentinel
swapSettingsConfigForTest(t, func(cfg *settings.Settings) {
cfg.Auth.Key = settingsRedactSentinel
cfg.Auth.TotpSecret = settingsRedactSentinel
cfg.Auth.Methods.PasswordAuth.AdminPassword = settingsRedactSentinel
cfg.Auth.Methods.PasswordAuth.Recaptcha.Secret = settingsRedactSentinel
cfg.Auth.Methods.OidcAuth.ClientSecret = settingsRedactSentinel
cfg.Auth.Methods.LdapAuth.UserPassword = settingsRedactSentinel
cfg.Auth.Methods.JwtAuth.Secret = settingsRedactSentinel
cfg.Integrations.OnlyOffice.Secret = settingsRedactSentinel
})
admin := &users.User{
FrontendUser: users.FrontendUser{
@@ -62,9 +72,9 @@ func TestSettingsGetHandler_redactsSecrets(t *testing.T) {
func TestSettingsGetHandler_doesNotMutateLiveConfig(t *testing.T) {
setupTestEnv(t)
prev := settings.Config
t.Cleanup(func() { settings.Config = prev })
settings.Config.Auth.Key = settingsRedactSentinel
swapSettingsConfigForTest(t, func(cfg *settings.Settings) {
cfg.Auth.Key = settingsRedactSentinel
})
admin := &users.User{
FrontendUser: users.FrontendUser{
@@ -92,10 +102,10 @@ func TestSettingsGetHandler_doesNotMutateLiveConfig(t *testing.T) {
func TestSettingsGetHandler_keepsNonSecretAuthFields(t *testing.T) {
setupTestEnv(t)
prev := settings.Config
t.Cleanup(func() { settings.Config = prev })
settings.Config.Auth.Key = settingsRedactSentinel
settings.Config.Auth.TokenExpirationHours = 7
swapSettingsConfigForTest(t, func(cfg *settings.Settings) {
cfg.Auth.Key = settingsRedactSentinel
cfg.Auth.TokenExpirationHours = 7
})
admin := &users.User{
FrontendUser: users.FrontendUser{
-2
View File
@@ -804,7 +804,6 @@ async function downloadChunked(file, shareHash = "") {
* @param {((percent: number) => void) | undefined} [onupload]
* @param {Record<string, string | number>} [headers]
* @param {boolean} [isDir]
* @param {(() => void) | undefined} [onsent]
* @returns {Promise<any> & { xhr?: XMLHttpRequest | null, abort?: () => void }}
*/
export function post(
@@ -1432,7 +1431,6 @@ export function getTextPreviewURLPublic(path, viewToken = state.req?.viewToken)
* @param {((percent: number) => void) | undefined} [onupload]
* @param {Record<string, string | number>} [headers]
* @param {boolean} [isDir]
* @param {(() => void) | undefined} [onsent]
* @returns {Promise<any> & { xhr?: XMLHttpRequest | null, abort?: () => void }}
*/
export function postPublic(
-4
View File
@@ -638,7 +638,6 @@ export const mutations = {
state.user.fileLoading = {
maxConcurrentUpload: 3,
uploadChunkSizeMb: 5,
uploadStallTimeoutSeconds: 10,
downloadChunkSizeMb: 0,
clearAll: false
};
@@ -656,9 +655,6 @@ export const mutations = {
if (state.user.fileLoading.downloadChunkSizeMb === undefined) {
state.user.fileLoading.downloadChunkSizeMb = 0;
}
if (state.user.fileLoading.uploadStallTimeoutSeconds === undefined) {
state.user.fileLoading.uploadStallTimeoutSeconds = 10;
}
}
// Load stored values or use defaults as fallback
-1
View File
@@ -286,7 +286,6 @@ export interface UserObject {
fileLoading?: {
maxConcurrentUpload?: number;
uploadChunkSizeMb?: number;
uploadStallTimeoutSeconds?: number;
clearAll?: boolean;
downloadChunkSizeMb?: number;
maxConcurrent?: number;
+3 -3
View File
@@ -329,9 +329,9 @@ class UploadManager {
try {
const testPath = `${basePath}${dirName}`;
if (getters.isShare()) {
await resourcesApi.postPublic(state.shareInfo?.hash, testPath, new Blob([]), false, undefined, {}, true, undefined);
await resourcesApi.postPublic(state.shareInfo?.hash, testPath, new Blob([]), false, undefined, {}, true);
} else {
await resourcesApi.post(state.req?.source, testPath, new Blob([]), false, undefined, {}, true, undefined);
await resourcesApi.post(state.req?.source, testPath, new Blob([]), false, undefined, {}, true);
}
// No conflict - directory was created successfully
// Mark it so we can skip it later in the queue
@@ -839,7 +839,7 @@ class UploadManager {
}
progressTimeoutMs(): number {
const seconds = state.user?.fileLoading?.uploadStallTimeoutSeconds ?? 0;
const seconds = state.user?.fileLoading?.uploadStallTimeoutSeconds;
return seconds > 0 ? seconds * 1000 : this.PROGRESS_TIMEOUT_MS;
}