Skip to content

Commit

Permalink
feat: implement unsubscribe by id
Browse files Browse the repository at this point in the history
  • Loading branch information
OrKoN committed Jan 21, 2025
1 parent d1f33fd commit 56a145f
Show file tree
Hide file tree
Showing 9 changed files with 57 additions and 4 deletions.
3 changes: 3 additions & 0 deletions src/bidiMapper/BidiNoOpParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,9 @@ export class BidiNoOpParser implements BidiCommandParameterParser {
parseSubscribeParams(params: unknown): Session.SubscriptionRequest {
return params as Session.SubscriptionRequest;
}
parseUnsubscribeParams(params: unknown): Session.UnsubscribeByAttributesRequest|Session.UnsubscribeByIdRequest {
return params as Session.UnsubscribeByAttributesRequest|Session.UnsubscribeByIdRequest;
}
// keep-sorted end

// Storage module
Expand Down
1 change: 1 addition & 0 deletions src/bidiMapper/BidiParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ export interface BidiCommandParameterParser {
// Session module
// keep-sorted start block=yes
parseSubscribeParams(params: unknown): Session.SubscriptionRequest;
parseUnsubscribeParams(params: unknown): Session.UnsubscribeByAttributesRequest|Session.UnsubscribeByIdRequest;
// keep-sorted end

// Storage module
Expand Down
5 changes: 5 additions & 0 deletions src/bidiMapper/modules/session/EventManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,11 @@ export class EventManager extends EventEmitter<EventManagerEventsMap> {
await this.toggleModulesIfNeeded();
}

async unsubscribeByIds(subscriptionIds: string[]): Promise<void> {
this.#subscriptionManager.unsubscribeById(subscriptionIds);
await this.toggleModulesIfNeeded();
}

async toggleModulesIfNeeded(): Promise<void> {
// TODO(1): Only update changed subscribers
// TODO(2): Enable for Worker Targets
Expand Down
8 changes: 7 additions & 1 deletion src/bidiMapper/modules/session/SessionProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,15 @@ export class SessionProcessor {
}

async unsubscribe(
params: Session.SubscriptionRequest,
params: Session.UnsubscribeByAttributesRequest|Session.UnsubscribeByIdRequest,
channel: BidiPlusChannel = {},
): Promise<EmptyResult> {
if ('subscriptions' in params) {
await this.#eventManager.unsubscribeByIds(
params.subscriptions,
);
return {};
}
await this.#eventManager.unsubscribe(
params.events as ChromiumBidi.EventNames[],
params.contexts ?? [],
Expand Down
15 changes: 13 additions & 2 deletions src/bidiMapper/modules/session/SubscriptionManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ export type Subscription = {

export class SubscriptionManager {
#subscriptions: Subscription[] = [];
#knownSubscriptionIds = new Set<string>();
#browsingContextStorage: BrowsingContextStorage;

constructor(browsingContextStorage: BrowsingContextStorage) {
Expand Down Expand Up @@ -222,6 +223,7 @@ export class SubscriptionManager {
channel,
};
this.#subscriptions.push(subscription);
this.#knownSubscriptionIds.add(subscription.id);
return subscription;
}

Expand Down Expand Up @@ -349,8 +351,17 @@ export class SubscriptionManager {
/**
* Unsubscribes by subscriptionId.
*/
unsubscribeById(_subscription: string) {
// TODO: implement.
unsubscribeById(subscriptionIds: string[]) {
const subscriptionIdsSet = new Set(subscriptionIds);
const unknownIds = difference(subscriptionIdsSet, this.#knownSubscriptionIds);

if (unknownIds.size !== 0) {
throw new InvalidArgumentException('No subscription found');
}
this.#subscriptions = this.#subscriptions.filter(subscription => {
return subscriptionIdsSet.has(subscription.id);
});
this.#knownSubscriptionIds = difference(this.#knownSubscriptionIds, subscriptionIdsSet);
}
}

Expand Down
3 changes: 3 additions & 0 deletions src/bidiTab/BidiParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,9 @@ export class BidiParser implements BidiCommandParameterParser {
parseSubscribeParams(params: unknown): Session.SubscriptionRequest {
return Parser.Session.parseSubscribeParams(params);
}
parseUnsubbscribeParams(params: unknown): Session.UnsubscribeByAttributesRequest|Session.UnsubscribeByIdRequest {
return Parser.Session.parseUnsubscribeParams(params);
}
// keep-sorted end

// Storage module
Expand Down
9 changes: 9 additions & 0 deletions src/protocol-parser/protocol-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,15 @@ export namespace Session {
WebDriverBidi.Session.SubscriptionRequestSchema,
) as Protocol.Session.SubscriptionRequest;
}

export function parseUnsubscribeParams(
params: unknown,
): Protocol.Session.UnsubscribeByAttributesRequest|Protocol.Session.UnsubscribeByIdRequest {
return parseObject(
params,
WebDriverBidi.Session.UnsubscribeByIdRequestSchema,
) as Protocol.Session.UnsubscribeByAttributesRequest|Protocol.Session.UnsubscribeByIdRequest;
}
}

export namespace Input {
Expand Down
15 changes: 15 additions & 0 deletions tests/session/test_subscription.py
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,21 @@ async def test_subscribeWithoutContext_bufferedEventsFromNotClosedContextsAreRet
assert {"type": "success", "id": command_id, 'result': ANY} == resp


@pytest.mark.asyncio
async def test_unsubscribe_by_id(websocket):
res = await subscribe(websocket, ["log.entryAdded"])
await execute_command(
websocket,
{
"method": "session.unsubscribe",
"params": {
"subscriptions": [
res["subscription"]
]
}
})


@pytest.mark.asyncio
@pytest.mark.parametrize("channel_name", ["channel", "goog:channel"])
async def test_unsubscribeIsAtomic(websocket, context_id, iframe_id,
Expand Down
2 changes: 1 addition & 1 deletion tests/test_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ async def subscribe(websocket,
command[channel_name
if channel_name is not None else "goog:channel"] = channel

await execute_command(websocket, command)
return await execute_command(websocket, command)


async def send_JSON_command(websocket, command: dict) -> int:
Expand Down

0 comments on commit 56a145f

Please sign in to comment.