8c95e50554
BEFUND. Die Uebergabe der Teilen-Erweiterung an die App konnte nie
funktionieren: sie legte den Beleg im Gruppen-Container ab, die App suchte ihn
ueber @capacitor/preferences - und dessen iOS-Code liest IMMER
UserDefaults.standard der App, configure({group}) setzt nur ein
Schluessel-Praefix. Falscher Behaelter, falscher Schluessel, und weil ein
fehlender Eintrag der Normalfall ist, meldete nichts einen Fehler.
UMBAU. Die Erweiterung schreibt das PDF als Datei in den Gruppen-Container und
gibt den Pfad im Aufruf mit; die App liest ihn ueber @capacitor/filesystem
(volle file://-Pfade) und loescht ihn danach. Abgeholt ueber getLaunchUrl()
und appUrlOpen - iOS benutzt beide. Nebenbei entfallen die
Base64-Aufblaehung und die 4-MB-Grenze der UserDefaults.
ZWEI WEITERE FEHLER AUF DEMSELBEN WEG. Ein Beleg zu einem bestehenden
Tankvorgang lief in die 20-Sekunden-Frist, obwohl der Server laengst fertig
war. Und beim Duplikat verriet das Backend nicht, welcher Vorgang gemeint ist
- jetzt kommt vorhandener_tank_id mit, und beide Oberflaechen springen
dorthin. Dazu: nach dem Speichern oeffnet sich der neue Vorgang, und waehrend
gelesen wird, steht "Tankbeleg wird verarbeitet ..." mit Zapfsaeule und
Kreisel im Formular.
ZWISCHENABLAGE. navigator.clipboard.read() gibt nur Text, HTML und Bilder
heraus - ein kopiertes PDF ist dort nie zu bekommen. UIPasteboard kennt die
Grenze nicht: ein kleines eigenes Plugin holt es, auch aus Mail (Anhang als
Verweis, ueber pasteboard.urls mit Sicherheitsbereich).
Der native Teil braucht einen Mac-Lauf; ios-teilen-einrichten.mjs spielt beide
Swift-Dateien bei jedem Bau ein.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
120 lines
4.2 KiB
TypeScript
120 lines
4.2 KiB
TypeScript
/**
|
|
* Die Auswertung eines geteilten Belegs — der Teil, der ohne Gerät prüfbar
|
|
* ist. Das Ablegen selbst passiert nativ (ShareViewController.swift) und kann
|
|
* hier nicht nachgestellt werden; geprüft wird, was die App mit dem Aufruf und
|
|
* der abgelegten Datei macht.
|
|
*
|
|
* `@capacitor/core` und `@capacitor/filesystem` werden ersetzt: das eine
|
|
* meldet sonst „kein natives Gerät" und das Lesen steigt sofort aus, das
|
|
* andere greift auf einen Dateibereich zu, den es hier nicht gibt.
|
|
*/
|
|
|
|
import { beforeEach, describe, expect, it, vi } from "vitest"
|
|
|
|
const dateien = new Map<string, string>()
|
|
|
|
vi.mock("@capacitor/core", () => ({
|
|
Capacitor: { isNativePlatform: () => true },
|
|
}))
|
|
|
|
vi.mock("@capacitor/filesystem", () => ({
|
|
Filesystem: {
|
|
readFile: vi.fn(async ({ path }: { path: string }) => {
|
|
const inhalt = dateien.get(path)
|
|
if (inhalt === undefined) throw new Error("nicht gefunden")
|
|
return { data: inhalt }
|
|
}),
|
|
deleteFile: vi.fn(async ({ path }: { path: string }) => {
|
|
dateien.delete(path)
|
|
}),
|
|
},
|
|
}))
|
|
|
|
/** Ein winziges, gültiges PDF als Base64 — der Inhalt ist hier gleichgültig. */
|
|
const PDF_BASE64 = btoa("%PDF-1.4\n%%EOF\n")
|
|
|
|
const PFAD = "file:///var/mobile/Shared/AppGroup/abc/geteilte-belege/1756832400-beleg.pdf"
|
|
const AUFRUF = `datametric360://beleg?pfad=${encodeURIComponent(PFAD)}`
|
|
|
|
describe("Belegpfad aus dem Aufruf", () => {
|
|
it("erkennt den Pfad", async () => {
|
|
const { belegpfadAusUrl } = await import("./geteilterBeleg")
|
|
expect(belegpfadAusUrl(AUFRUF)).toBe(PFAD)
|
|
})
|
|
|
|
it("lässt fremde Aufrufe in Ruhe", async () => {
|
|
const { belegpfadAusUrl } = await import("./geteilterBeleg")
|
|
expect(belegpfadAusUrl("datametric360://einstellungen")).toBeNull()
|
|
expect(belegpfadAusUrl("https://example.org/?pfad=x")).toBeNull()
|
|
expect(belegpfadAusUrl(null)).toBeNull()
|
|
})
|
|
|
|
it("verträgt einen Aufruf ohne Pfad", async () => {
|
|
const { belegpfadAusUrl } = await import("./geteilterBeleg")
|
|
expect(belegpfadAusUrl("datametric360://beleg")).toBeNull()
|
|
expect(belegpfadAusUrl("datametric360://beleg?anderes=1")).toBeNull()
|
|
})
|
|
})
|
|
|
|
describe("geteilten Beleg lesen", () => {
|
|
beforeEach(() => {
|
|
dateien.clear()
|
|
vi.resetModules()
|
|
})
|
|
|
|
it("liefert nichts ohne Aufruf", async () => {
|
|
const { geteiltenBelegLesen } = await import("./geteilterBeleg")
|
|
expect(await geteiltenBelegLesen(null)).toBeNull()
|
|
})
|
|
|
|
it("liest die Datei und gibt sie als PDF zurück", async () => {
|
|
dateien.set(PFAD, PDF_BASE64)
|
|
const { geteiltenBelegLesen } = await import("./geteilterBeleg")
|
|
const datei = await geteiltenBelegLesen(AUFRUF)
|
|
expect(datei).not.toBeNull()
|
|
expect(datei?.type).toBe("application/pdf")
|
|
expect(datei?.name).toBe("1756832400-beleg.pdf")
|
|
expect(datei?.size).toBeGreaterThan(0)
|
|
})
|
|
|
|
/* Der Grund, warum überhaupt gelöscht wird: sonst käme derselbe Beleg bei
|
|
jedem Öffnen erneut, und weil der Upload im Backend einen Vorgang anlegt,
|
|
wären das echte Doppeleinträge. */
|
|
it("räumt die Datei weg, holt sie also genau einmal", async () => {
|
|
dateien.set(PFAD, PDF_BASE64)
|
|
const { geteiltenBelegLesen } = await import("./geteilterBeleg")
|
|
expect(await geteiltenBelegLesen(AUFRUF)).not.toBeNull()
|
|
expect(dateien.has(PFAD)).toBe(false)
|
|
expect(await geteiltenBelegLesen(AUFRUF)).toBeNull()
|
|
})
|
|
|
|
it("verschluckt sich nicht an einer fehlenden Datei", async () => {
|
|
const { geteiltenBelegLesen } = await import("./geteilterBeleg")
|
|
expect(await geteiltenBelegLesen(AUFRUF)).toBeNull()
|
|
})
|
|
})
|
|
|
|
describe("Übergabe an die Tanken-Seite", () => {
|
|
beforeEach(() => vi.resetModules())
|
|
|
|
it("meldet jeden Wechsel an die Horcher", async () => {
|
|
const { geteiltenBelegSetzen, geteiltenBelegStand, geteiltenBelegHorchen } =
|
|
await import("./geteilterBeleg")
|
|
let gerufen = 0
|
|
const abmelden = geteiltenBelegHorchen(() => gerufen++)
|
|
const datei = new File([new Uint8Array([1])], "beleg.pdf", { type: "application/pdf" })
|
|
|
|
geteiltenBelegSetzen(datei)
|
|
expect(geteiltenBelegStand()).toBe(datei)
|
|
expect(gerufen).toBe(1)
|
|
|
|
geteiltenBelegSetzen(null)
|
|
expect(geteiltenBelegStand()).toBeNull()
|
|
expect(gerufen).toBe(2)
|
|
|
|
abmelden()
|
|
geteiltenBelegSetzen(datei)
|
|
expect(gerufen).toBe(2)
|
|
})
|
|
})
|