forked from Mike/freno-dev
meta: task ref cleanup
This commit is contained in:
@@ -4,7 +4,7 @@ import SubdomainHeader from "~/components/SubdomainHeader";
|
||||
/**
|
||||
* InputHalo contact page (`inputhalo.freno.me/contact`).
|
||||
*
|
||||
* Thin wrapper over the shared `<ContactForm>` (task 09). Site awareness —
|
||||
* Thin wrapper over the shared `<ContactForm>`. Site awareness —
|
||||
* subject prefix `[InputHalo]`, recipient label, heading, and PageHead
|
||||
* metadata — is derived from `useSite()` inside the component via
|
||||
* `CONTACT_CONTEXT.inputhalo`, so this route needs no explicit props.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Unit tests for the InputHalo landing-page download flow (task 06).
|
||||
* Unit tests for the InputHalo landing-page download flow.
|
||||
*
|
||||
* The helper in `./download.ts` is pure (no solid-js / router / meta imports),
|
||||
* so we exercise the acceptance criterion directly — "the download button
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Integration / visual checks (the rendered landing page, the tRPC client) are
|
||||
* covered by the build gate (`bun run build`) and the manual validation steps
|
||||
* in the task spec; the component is a thin wrapper over this helper.
|
||||
* the component is a thin wrapper over this helper.
|
||||
*/
|
||||
import { describe, it, expect, mock } from "bun:test";
|
||||
import {
|
||||
@@ -49,12 +49,10 @@ describe("InputHalo download constants", () => {
|
||||
|
||||
describe("queryInputHaloDownload", () => {
|
||||
it("calls the query with asset_name 'inputhalo' and returns the signed URL", async () => {
|
||||
const query = mock(
|
||||
(async (input: { asset_name: string }) => {
|
||||
expect(input.asset_name).toBe("inputhalo");
|
||||
return { downloadURL: "https://s3.example.com/InputHalo.dmg?signed=1" };
|
||||
}) as DownloadQueryApi
|
||||
);
|
||||
const query = mock((async (input: { asset_name: string }) => {
|
||||
expect(input.asset_name).toBe("inputhalo");
|
||||
return { downloadURL: "https://s3.example.com/InputHalo.dmg?signed=1" };
|
||||
}) as DownloadQueryApi);
|
||||
|
||||
const url = await queryInputHaloDownload(query);
|
||||
|
||||
@@ -85,9 +83,9 @@ describe("performInputHaloDownload", () => {
|
||||
const SIGNED_URL = "https://s3.example.com/InputHalo-0.1.0.dmg?sig=abc";
|
||||
|
||||
it("redirects to the signed S3 URL returned by the query", async () => {
|
||||
const query = mock(
|
||||
(async () => ({ downloadURL: SIGNED_URL })) as DownloadQueryApi
|
||||
);
|
||||
const query = mock((async () => ({
|
||||
downloadURL: SIGNED_URL
|
||||
})) as DownloadQueryApi);
|
||||
const redirect = mock((url: string) => url);
|
||||
|
||||
const ok = await performInputHaloDownload(query, redirect);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Pure, side-effect-free download orchestration for the InputHalo landing
|
||||
* page (task 06).
|
||||
* page.
|
||||
*
|
||||
* Extracted from the route component so the acceptance criterion —
|
||||
* "download button calls `api.downloads.getDownloadUrl` with `'inputhalo'`
|
||||
@@ -36,9 +36,7 @@ export const INPUTHALO_ICON_DEFAULT =
|
||||
* Keeps the helper decoupled from the full `api` surface and testable with a
|
||||
* stub.
|
||||
*/
|
||||
export interface DownloadQueryApi {
|
||||
(input: { asset_name: string }): Promise<{ downloadURL: string }>;
|
||||
}
|
||||
export type DownloadQueryApi = (input: { asset_name: string }) => Promise<{ downloadURL: string }>
|
||||
|
||||
/**
|
||||
* Resolve the signed S3 download URL for the InputHalo DMG.
|
||||
|
||||
@@ -14,6 +14,7 @@ import { For, createSignal } from "solid-js";
|
||||
import { A } from "@solidjs/router";
|
||||
import { PageHead } from "~/components/PageHead";
|
||||
import SubdomainHeader from "~/components/SubdomainHeader";
|
||||
import { buildMainSiteUrl } from "~/lib/site-context";
|
||||
import Button from "~/components/ui/Button";
|
||||
import DownloadOnAppStoreDark from "~/components/icons/DownloadOnAppStoreDark";
|
||||
import { useDarkMode } from "~/context/darkMode";
|
||||
@@ -274,7 +275,7 @@ export default function InputHaloLanding() {
|
||||
<div class="text-text/60 mx-auto flex max-w-6xl flex-col items-center justify-between gap-4 text-sm sm:flex-row">
|
||||
<span>{site().displayName}</span>
|
||||
<A
|
||||
href="https://freno.me"
|
||||
href={buildMainSiteUrl()}
|
||||
class="hover:text-text underline-offset-4 hover:underline"
|
||||
>
|
||||
freno.me
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
/**
|
||||
* InputHalo privacy policy — `inputhalo.freno.me/privacy` (task 10).
|
||||
* InputHalo privacy policy — `inputhalo.freno.me/privacy`.
|
||||
*
|
||||
* Net-new privacy policy for the InputHalo subdomain. InputHalo is a macOS
|
||||
* menu bar application (`LSUIElement: true`,
|
||||
* `LSApplicationCategoryType: public.app-category.productivity`) — a
|
||||
* productivity utility that lives in the system menu bar. Following the task
|
||||
* notes, Gaze's privacy policy is the template for macOS menu bar apps
|
||||
* productivity utility that lives in the system menu bar. Gaze's privacy policy is the template for macOS menu bar apps
|
||||
* (both are local-only menu bar utilities), so this policy mirrors Gaze's
|
||||
* structure and language while describing InputHalo's own practices.
|
||||
*
|
||||
@@ -16,7 +15,7 @@
|
||||
* - Settings and any cached state are stored locally using standard
|
||||
* macOS mechanisms and are never sent off-device.
|
||||
*
|
||||
* PageHead is site-aware (task 02): only the base title is supplied; the
|
||||
* PageHead is site-aware: only the base title is supplied; the
|
||||
* ` | InputHalo` suffix, `https://inputhalo.freno.me/privacy` canonical, and
|
||||
* OG image are derived automatically. Internal links use public
|
||||
* subdomain-relative paths (`/contact`) consistent with nav-config.ts and
|
||||
|
||||
Reference in New Issue
Block a user