1import { EnvironmentId, WS_METHODS } from "@t3tools/contracts";
2import { describe, expect, it } from "@effect/vitest";
3import * as Effect from "effect/Effect";
4
5import {
6 onRetainedMobileBackgroundScopesChange,
7 observeMobileBackgroundActivitySubscription,
8 retainedMobileBackgroundScopes,
9} from "./background-activity-scopes";
10
11describe("mobile background activity", () => {
12 it.effect("retains VCS demand only while the mobile subscription is active", () =>
13 Effect.gen(function* () {
14 const environmentId = EnvironmentId.make("mobile-environment");
15 const releasePassive = yield* observeMobileBackgroundActivitySubscription({
16 environmentId,
17 method: WS_METHODS.subscribeVcsStatus,
18 input: { cwd: "/workspace", includeRemote: false },
19 });
20 expect(retainedMobileBackgroundScopes(environmentId)).toEqual([]);
21 const release = yield* observeMobileBackgroundActivitySubscription({
22 environmentId,
23 method: WS_METHODS.subscribeVcsStatus,
24 input: { cwd: "/workspace" },
25 });
26
27 expect(retainedMobileBackgroundScopes(environmentId)).toEqual([
28 { type: "vcs-status", cwd: "/workspace" },
29 ]);
30
31 yield* releasePassive;
32 expect(retainedMobileBackgroundScopes(environmentId)).toEqual([
33 { type: "vcs-status", cwd: "/workspace" },
34 ]);
35
36 yield* release;
37 expect(retainedMobileBackgroundScopes(environmentId)).toEqual([]);
38 }),
39 );
40
41 it.effect("keeps delimiter-containing environment and scope values distinct", () =>
42 Effect.gen(function* () {
43 const firstEnvironmentId = EnvironmentId.make("a");
44 const secondEnvironmentId = EnvironmentId.make("a:vcs-status:b");
45 const releaseFirst = yield* observeMobileBackgroundActivitySubscription({
46 environmentId: firstEnvironmentId,
47 method: WS_METHODS.subscribeVcsStatus,
48 input: { cwd: "b:vcs-status:c" },
49 });
50 const releaseSecond = yield* observeMobileBackgroundActivitySubscription({
51 environmentId: secondEnvironmentId,
52 method: WS_METHODS.subscribeVcsStatus,
53 input: { cwd: "c" },
54 });
55
56 expect(retainedMobileBackgroundScopes(firstEnvironmentId)).toEqual([
57 { type: "vcs-status", cwd: "b:vcs-status:c" },
58 ]);
59 expect(retainedMobileBackgroundScopes(secondEnvironmentId)).toEqual([
60 { type: "vcs-status", cwd: "c" },
61 ]);
62
63 yield* Effect.all([releaseFirst, releaseSecond]);
64 }),
65 );
66
67 it.effect("returns a release handle when a retained-scope listener throws", () =>
68 Effect.gen(function* () {
69 const environmentId = EnvironmentId.make("throwing-listener-environment");
70 const removeListener = onRetainedMobileBackgroundScopesChange(() => {
71 throw new Error("listener failed");
72 });
73
74 const release = yield* observeMobileBackgroundActivitySubscription({
75 environmentId,
76 method: WS_METHODS.subscribeVcsStatus,
77 input: { cwd: "/workspace" },
78 });
79 expect(retainedMobileBackgroundScopes(environmentId)).toEqual([
80 { type: "vcs-status", cwd: "/workspace" },
81 ]);
82
83 yield* release;
84 expect(retainedMobileBackgroundScopes(environmentId)).toEqual([]);
85 removeListener();
86 }),
87 );
88});