feat(downloads): WiFi-only network-type-aware download gating
Add a metered/cellular network detector so downloads honour a "WiFi only" preference. Android reports network type via NetworkTypeMonitor; Rust exposes it through download/network.rs and holds the queue pump when on a metered connection, emitting a queue-wide waitingForNetwork event. The frontend surfaces this via the networkType service and a waitingForNetwork store flag. TRACES: UR-053 | DR-074
This commit is contained in:
@@ -309,6 +309,35 @@ describe("downloads store", () => {
|
||||
expect(state.stats.queuedCount).toBe(1); // 1 pending
|
||||
});
|
||||
|
||||
// The Transfers view shows only in-flight rows; a completed transfer must
|
||||
// NOT appear there (it lives in Downloaded). Mirrors the /downloads page's
|
||||
// `transfers` derivation: active + pending + failed.
|
||||
// TRACES: UR-055 | DR-084 | UT-052
|
||||
it("transfers set excludes completed downloads", async () => {
|
||||
const { downloads, activeDownloads, pendingDownloads, failedDownloads } = await import(
|
||||
"./downloads"
|
||||
);
|
||||
|
||||
mockInvoke.mockResolvedValueOnce({
|
||||
downloads: [
|
||||
{ id: 1, itemId: "a", userId: "u", filePath: "/a", status: "downloading", progress: 0.5, bytesDownloaded: 5, queuedAt: "t", retryCount: 0, priority: 0, mediaType: "audio", downloadSource: "user" },
|
||||
{ id: 2, itemId: "b", userId: "u", filePath: "/b", status: "pending", progress: 0, bytesDownloaded: 0, queuedAt: "t", retryCount: 0, priority: 0, mediaType: "audio", downloadSource: "user" },
|
||||
{ id: 3, itemId: "c", userId: "u", filePath: "/c", status: "completed", progress: 1, bytesDownloaded: 9, queuedAt: "t", retryCount: 0, priority: 0, mediaType: "audio", downloadSource: "user" },
|
||||
{ id: 4, itemId: "d", userId: "u", filePath: "/d", status: "failed", progress: 0, bytesDownloaded: 0, queuedAt: "t", retryCount: 1, priority: 0, mediaType: "audio", downloadSource: "user" },
|
||||
],
|
||||
stats: { total: 4, activeCount: 1, queuedCount: 1, completedCount: 1, failedCount: 1, pausedCount: 0 },
|
||||
});
|
||||
|
||||
await downloads.refresh("u");
|
||||
|
||||
const transfers = get(activeDownloads)
|
||||
.concat(get(pendingDownloads))
|
||||
.concat(get(failedDownloads));
|
||||
const ids = transfers.map((d) => d.id).sort();
|
||||
expect(ids).toEqual([1, 2, 4]);
|
||||
expect(transfers.some((d) => d.status === "completed")).toBe(false);
|
||||
});
|
||||
|
||||
it("should support status filter", async () => {
|
||||
const { downloads } = await import("./downloads");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user