Repository: electron/electron
Pull request: test: improve cookie changed event coverage

#### Description of Change

Add coverage for some uncovered cookie 'changed' events:

- `overwrite` + `inserted` events when a cookie is overwritten with a new value
- `overwrite` + `inserted-no-value-change-overwrite` when a cookie is overwritten with the same value
- `expired-overwrite` when a cookie is overwritten with an expired cookie

#### Checklist

- [x] PR description included
- [x] I have built and tested this PR
- [x] `npm test` passes
- [x] tests are [changed or added](https://github.com/electron/electron/blob/main/docs/development/testing.md)
- [x] [PR release notes](https://github.com/electron/clerk/blob/main/README.md) describe the change in a way relevant to app developers, and are [capitalized, punctuated, and past tense](https://github.com/electron/clerk/blob/main/README.md#examples).

#### Release Notes

Notes: none.

Changed files:
filename: spec/api-session-spec.ts
patch: @@ -53,6 +53,26 @@ describe('session module', () => {
       }
     });
 
+    const collectCookieChanges = async (cookies: Electron.Cookies, action: () => Promise<void>, count: number) => {
+      const changes: Array<{ cause: string, cookie: Electron.Cookie, removed: boolean }> = [];
+      let listener: ((event: Electron.Event, cookie: Electron.Cookie, cause: string, removed: boolean) => void) | undefined;
+
+      const changesPromise = new Promise<typeof changes>(resolve => {
+        listener = (_event, cookie, cause, removed) => {
+          changes.push({ cause, cookie, removed });
+          if (changes.length === count) resolve(changes);
+        };
+        cookies.on('changed', listener);
+      });
+
+      try {
+        await action();
+        return await changesPromise;
+      } finally {
+        if (listener) cookies.removeListener('changed', listener);
+      }
+    };
+
     it('should get cookies', async () => {
       const server = http.createServer((req, res) => {
         res.setHeader('Set-Cookie', [`${name}=${value}`]);
@@ -223,6 +243,60 @@ describe('session module', () => {
       expect(removeEventRemoved).to.equal(true);
     });
 
+    it('emits overwrite and inserted events when a cookie is overwritten with a new value', async () => {
+      const { cookies } = session.fromPartition('cookies-overwrite-changed');
+      const name = 'foo';
+      const oldVal = 'bar';
+      const newVal = 'baz';
+      const expected = [
+        { cause: 'overwrite', name, removed: true, value: oldVal },
+        { cause: 'inserted', name, removed: false, value: newVal }
+      ];
+
+      await cookies.set({ url, name, value: oldVal });
+      const changes = await collectCookieChanges(cookies, async () => {
+        await cookies.set({ url, name, value: newVal });
+      }, 2);
+
+      const actual = changes.map(({ cookie: { name, value }, cause, removed }) => ({ cause, name, removed, value }));
+      expect(actual).to.deep.equal(expected);
+    });
+
+    it('emits inserted-no-value-change-overwrite when a cookie is overwritten with the same value', async () => {
+      const { cookies } = session.fromPartition('cookies-same-value-overwrite-changed');
+      const name = 'foo';
+      const value = 'bar';
+      const nowSec = Date.now() / 1000;
+      const expected = [
+        { cause: 'overwrite', name, removed: true, value },
+        { cause: 'inserted-no-value-change-overwrite', name, removed: false, value }
+      ];
+
+      await cookies.set({ url, name, value, expirationDate: nowSec + 120 });
+      const changes = await collectCookieChanges(cookies, async () => {
+        await cookies.set({ url, name, value, expirationDate: nowSec + 240 });
+      }, 2);
+
+      const actual = changes.map(({ cookie: { name, value }, cause, removed }) => ({ cause, name, removed, value }));
+      expect(actual).to.deep.equal(expected);
+    });
+
+    it('emits expired-overwrite when a cookie is overwritten by an already-expired cookie', async () => {
+      const { cookies } = session.fromPartition('cookies-expired-overwrite-changed');
+      const name = 'foo';
+      const value = 'bar';
+      const nowSec = Date.now() / 1000;
+      const expected = [{ cause: 'expired-overwrite', name, removed: true, value }];
+
+      await cookies.set({ url, name, value, expirationDate: nowSec + 120 });
+      const changes = await collectCookieChanges(cookies, async () => {
+        await cookies.set({ url, name, value, expirationDate: nowSec - 10 });
+      }, 1);
+
+      const actual = changes.map(({ cookie: { name, value }, cause, removed }) => ({ cause, name, removed, value }));
+      expect(actual).to.deep.equal(expected);
+    });
+
     describe('ses.cookies.flushStore()', async () => {
       it('flushes the cookies to disk', async () => {
         const name = 'foo';