Public: anyone can read this; the crew can change it.

"That file is too large to edit here." and "That could not be changed." live in one module each owner reads #5687

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

mason/forge:mason/5625-that-file-is-too-large-to-edit-here-and → main 2 commits fork 1 thread · 1 unresolved

  • Merged. mason/5625-that-file-is-too-large-to-edit-here-and was merged into main as 43243df.

Review

Sign in to review this change.
6 files changed +59 −9
src/web/edit_words.ts added +11
@@ -0,0 +1,11 @@
1 /**
2 * The sentences an edit says when it cannot go ahead, said from one place
3 * so the blob editor, the proposal editor, settings and threads read the
4 * same (#5625).
5 */
6
7 /** A text file past the size the in-browser editor will load. */
8 export const TOO_LARGE_TO_EDIT = "That file is too large to edit here.";
9
10 /** A setting or thread change that was refused for no more specific reason. */
11 export const NOT_CHANGED = "That could not be changed.";
src/web/pages/browse.ts +2 −1
@@ -45,6 +45,7 @@ import { commentCard } from "../comments.ts";
4545 import { renderDiff } from "../diff-view.ts";
4646 import { readForm } from "../form.ts";
4747 import { html, when, type Html } from "../html.ts";
48 import { TOO_LARGE_TO_EDIT } from "../edit_words.ts";
4849 import { flashTo, fragment, page, redirect } from "../layout.ts";
4950 import { codeJs, mirrorJs } from "../client.ts";
5051 import { json, notFound } from "../../http/respond.ts";
@@ -887,7 +888,7 @@ export async function browseEditPage(ctx: Ctx): Promise<Response> {
887888 message:
888889 blob.value.kind === "binary"
889890 ? "That file is binary — propose it with git, not a textarea."
890 : "That file is too large to edit here.",
891 : TOO_LARGE_TO_EDIT,
891892 },
892893 );
893894 return editorPage(
src/web/pages/edit.ts +2 −1
@@ -31,6 +31,7 @@ import { highlightToHtml } from "../highlight-html.ts";
3131 import { loadRepo, notFoundPage, pageHead, signInFirst } from "../chrome.ts";
3232 import { field as formValue, readForm, type Form } from "../form.ts";
3333 import { html, raw, when, type Html } from "../html.ts";
34 import { TOO_LARGE_TO_EDIT } from "../edit_words.ts";
3435 import { flashTo, fragment, page } from "../layout.ts";
3536 import { renderMarkdown } from "../markdown.ts";
3637 import {
@@ -617,7 +618,7 @@ export async function editPage(ctx: Ctx): Promise<Response> {
617618 message:
618619 blob.value.kind === "binary"
619620 ? "That file is binary — edit it with git, not a textarea."
620 : "That file is too large to edit here.",
621 : TOO_LARGE_TO_EDIT,
621622 },
622623 );
623624 }
src/web/pages/settings.ts +5 −4
@@ -96,6 +96,7 @@ import { pageTitle } from "../studio/nouns.ts";
9696 import { appHref } from "./apps.ts";
9797 import { field, readForm, type Form } from "../form.ts";
9898 import { html, when, type Html } from "../html.ts";
99 import { NOT_CHANGED } from "../edit_words.ts";
99100 import { DELETE_REPO, STOP_APP } from "../danger_words.ts";
100101 import { icon } from "../icons.ts";
101102 import { flashTo, page, redirect } from "../layout.ts";
@@ -488,7 +489,7 @@ export async function archiveSubmit(ctx: Ctx): Promise<Response> {
488489 if (asked !== "0" && asked !== "1")
489490 return flashTo(ctx, `${repoBase(repo)}/settings`, {
490491 tone: "danger",
491 message: "That could not be changed.",
492 message: NOT_CHANGED,
492493 });
493494 const archived = asked === "1";
494495 const updated = await updateRepoSettings(ctx.app, ctx.auth.user, repo, {
@@ -500,7 +501,7 @@ export async function archiveSubmit(ctx: Ctx): Promise<Response> {
500501 back,
501502 updated.ok
502503 ? { message: archived ? "Archived." : "Awake again." }
503 : { tone: "danger", message: "That could not be changed." },
504 : { tone: "danger", message: NOT_CHANGED },
504505 );
505506 }
506507
@@ -549,14 +550,14 @@ export async function provenanceSubmit(ctx: Ctx): Promise<Response> {
549550 const asked = field(form, "shown");
550551 const back = `${repoBase(repo)}/settings`;
551552 if (asked !== "0" && asked !== "1")
552 return flashTo(ctx, back, { tone: "danger", message: "That could not be changed." });
553 return flashTo(ctx, back, { tone: "danger", message: NOT_CHANGED });
553554 const set = showProvenance(ctx.app, ctx.auth.user, repo, asked === "1");
554555 return flashTo(
555556 ctx,
556557 back,
557558 set.ok
558559 ? { message: set.value.shown ? "Where this came from is shown." : "Where this came from is hidden." }
559 : { tone: "danger", message: "That could not be changed." },
560 : { tone: "danger", message: NOT_CHANGED },
560561 );
561562 }
562563
src/web/pages/thread.ts +4 −3
@@ -56,6 +56,7 @@ import type { Ctx } from "../../http/context.ts";
5656 import { commentCard } from "../comments.ts";
5757 import { backTo, field, readForm } from "../form.ts";
5858 import { html, raw, when, type Html } from "../html.ts";
59 import { NOT_CHANGED } from "../edit_words.ts";
5960 import { flashOrJson, flashTo } from "../layout.ts";
6061 import {
6162 btn,
@@ -821,7 +822,7 @@ export async function stateSubmit(
821822 ? merged
822823 : changed.error === "forbidden"
823824 ? "Only the author or someone with write access can do that."
824 : "That could not be changed.");
825 : NOT_CHANGED);
825826 return flashOrJson(ctx, dest, { tone: "danger", message });
826827 }
827828 return flashOrJson(ctx, dest, {
@@ -858,7 +859,7 @@ export async function wordsSubmit(
858859 ? `A title is at most ${MAX_TITLE} characters.`
859860 : edited.error === "body_too_long"
860861 ? "That description is too long."
861 : "That could not be changed.");
862 : NOT_CHANGED);
862863 return flashOrJson(ctx, dest, { tone: "danger", message });
863864 }
864865 return flashOrJson(ctx, dest, { message: "Saved." });
@@ -947,7 +948,7 @@ export async function teamsSubmit(ctx: Ctx): Promise<Response> {
947948 const chosen = form.getAll("teams").filter((v): v is string => typeof v === "string");
948949 const set = nameTeams(ctx.app, ctx.auth.user, found.repo, found.issue, chosen);
949950 if (!set.ok)
950 return flashTo(ctx, dest, { tone: "danger", message: ISSUE_TEAMS_SAY[set.error] ?? "That could not be changed." });
951 return flashTo(ctx, dest, { tone: "danger", message: ISSUE_TEAMS_SAY[set.error] ?? NOT_CHANGED });
951952 return flashTo(ctx, dest, {
952953 message: set.value.length === 0 ? "Teams cleared." : `Teams set to ${set.value.join(", ")}.`,
953954 });
test/web-edit-words.test.ts added +35
@@ -0,0 +1,35 @@
1 /**
2 * "That file is too large to edit here." and "That could not be changed."
3 * are said from src/web/edit_words.ts alone (#5625): every page that says
4 * one imports it, and a copy typed back into a page fails here.
5 */
6
7 import { describe, expect, test } from "bun:test";
8 import { readFileSync } from "node:fs";
9 import { join } from "node:path";
10 import { NOT_CHANGED, TOO_LARGE_TO_EDIT } from "../src/web/edit_words.ts";
11
12 const root = join(import.meta.dir, "..");
13 const read = (path: string): string => readFileSync(join(root, path), "utf8");
14
15 const SAYERS: ReadonlyArray<{ path: string; words: string; name: string }> = [
16 { path: "src/web/pages/browse.ts", words: TOO_LARGE_TO_EDIT, name: "TOO_LARGE_TO_EDIT" },
17 { path: "src/web/pages/edit.ts", words: TOO_LARGE_TO_EDIT, name: "TOO_LARGE_TO_EDIT" },
18 { path: "src/web/pages/settings.ts", words: NOT_CHANGED, name: "NOT_CHANGED" },
19 { path: "src/web/pages/thread.ts", words: NOT_CHANGED, name: "NOT_CHANGED" },
20 ];
21
22 describe("edit words live in one module", () => {
23 test("the sentences read as they always have", () => {
24 expect(TOO_LARGE_TO_EDIT).toBe("That file is too large to edit here.");
25 expect(NOT_CHANGED).toBe("That could not be changed.");
26 });
27
28 for (const { path, words, name } of SAYERS) {
29 test(`${path} imports ${name} and types no copy of it`, () => {

The check reads source as text. It is good enough here, but it would miss a copy that differs by a comma. The two exact-text assertions above cover the sentence itself.

30 const text = read(path);
31 expect(text).not.toContain(words);
32 expect(text).toMatch(new RegExp(`import \\{[^}]*\\b${name}\\b[^}]*\\} from "\\.\\./edit_words\\.ts"`));
33 });
34 }
35 });

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs