@operato/graphql 10.29.71 → 10.29.76

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@operato/graphql",
3
3
  "description": "Webcomponent graphql-client following open-wc recommendations",
4
4
  "author": "heartyoh@hatiolab.com",
5
- "version": "10.29.71",
5
+ "version": "10.29.76",
6
6
  "type": "module",
7
7
  "main": "dist/src/index.js",
8
8
  "module": "dist/src/index.js",
@@ -64,7 +64,7 @@
64
64
  "dependencies": {
65
65
  "@apollo/client": "^3.6.9",
66
66
  "@operato/i18n": "^10.29.27",
67
- "@operato/utils": "^10.29.71",
67
+ "@operato/utils": "^10.29.76",
68
68
  "apollo-upload-client": "^18.0.0",
69
69
  "graphql-tag": "^2.12.6",
70
70
  "graphql-ws": "^5.14.0",
@@ -127,5 +127,5 @@
127
127
  "prettier --write"
128
128
  ]
129
129
  },
130
- "gitHead": "7aaaa24d63c807bb0d45155b58a197e225549352"
130
+ "gitHead": "08d33aec6fbe7c55cbb8e5018781a8500c792d4d"
131
131
  }
@@ -1 +0,0 @@
1
- export {};
@@ -1,42 +0,0 @@
1
- import { expect } from '@open-wc/testing';
2
- import gql from 'graphql-tag';
3
- import { client } from '../src/graphql-client.js';
4
- /**
5
- * A read its page replaced or left is aborted on purpose (PageView.reads, ADR-0190): the error link says nothing about
6
- * it. A read that failed on its own is still reported.
7
- */
8
- describe('an aborted read', () => {
9
- const query = gql `
10
- query {
11
- ping
12
- }
13
- `;
14
- let notified;
15
- let fetched;
16
- const listen = (event) => notified.push(event.detail);
17
- beforeEach(() => {
18
- notified = [];
19
- fetched = window.fetch;
20
- document.addEventListener('notify', listen);
21
- });
22
- afterEach(() => {
23
- window.fetch = fetched;
24
- document.removeEventListener('notify', listen);
25
- });
26
- it('notifies nothing', async () => {
27
- window.fetch = (_input, init) => new Promise((_, reject) => init.signal.addEventListener('abort', () => reject(new DOMException('aborted', 'AbortError'))));
28
- const controller = new AbortController();
29
- const read = client
30
- .query({ query, fetchPolicy: 'no-cache', context: { fetchOptions: { signal: controller.signal } } })
31
- .catch(error => error);
32
- controller.abort();
33
- await read;
34
- expect(notified).to.deep.equal([]);
35
- });
36
- it('while a read that failed on its own is reported', async () => {
37
- window.fetch = () => Promise.reject(new TypeError('Failed to fetch'));
38
- await client.query({ query, fetchPolicy: 'no-cache' }).catch(error => error);
39
- expect(notified.length).to.equal(1);
40
- });
41
- });
42
- //# sourceMappingURL=aborted-read.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"aborted-read.test.js","sourceRoot":"","sources":["../../test/aborted-read.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACzC,OAAO,GAAG,MAAM,aAAa,CAAA;AAE7B,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAA;AAEjD;;;GAGG;AACH,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,MAAM,KAAK,GAAG,GAAG,CAAA;;;;GAIhB,CAAA;IACD,IAAI,QAAmB,CAAA;IACvB,IAAI,OAA4B,CAAA;IAChC,MAAM,MAAM,GAAG,CAAC,KAAY,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAE,KAAqB,CAAC,MAAM,CAAC,CAAA;IAE7E,UAAU,CAAC,GAAG,EAAE;QACd,QAAQ,GAAG,EAAE,CAAA;QACb,OAAO,GAAG,MAAM,CAAC,KAAK,CAAA;QACtB,QAAQ,CAAC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;IAC7C,CAAC,CAAC,CAAA;IAEF,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,CAAC,KAAK,GAAG,OAAO,CAAA;QACtB,QAAQ,CAAC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;IAChD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,kBAAkB,EAAE,KAAK,IAAI,EAAE;QAChC,MAAM,CAAC,KAAK,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CAC9B,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CACxB,IAAK,CAAC,MAAO,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,YAAY,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC,CAAC,CACjG,CAAA;QACH,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAA;QACxC,MAAM,IAAI,GAAG,MAAM;aAChB,KAAK,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,YAAY,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,EAAE,EAAE,CAAC;aACnG,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,CAAA;QACxB,UAAU,CAAC,KAAK,EAAE,CAAA;QAClB,MAAM,IAAI,CAAA;QACV,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;IACpC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;QAC/D,MAAM,CAAC,KAAK,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAA;QACrE,MAAM,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,CAAA;QAC5E,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IACrC,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA","sourcesContent":["import { expect } from '@open-wc/testing'\nimport gql from 'graphql-tag'\n\nimport { client } from '../src/graphql-client.js'\n\n/**\n * A read its page replaced or left is aborted on purpose (PageView.reads, ADR-0190): the error link says nothing about\n * it. A read that failed on its own is still reported.\n */\ndescribe('an aborted read', () => {\n const query = gql`\n query {\n ping\n }\n `\n let notified: unknown[]\n let fetched: typeof window.fetch\n const listen = (event: Event) => notified.push((event as CustomEvent).detail)\n\n beforeEach(() => {\n notified = []\n fetched = window.fetch\n document.addEventListener('notify', listen)\n })\n\n afterEach(() => {\n window.fetch = fetched\n document.removeEventListener('notify', listen)\n })\n\n it('notifies nothing', async () => {\n window.fetch = (_input, init) =>\n new Promise((_, reject) =>\n init!.signal!.addEventListener('abort', () => reject(new DOMException('aborted', 'AbortError')))\n )\n const controller = new AbortController()\n const read = client\n .query({ query, fetchPolicy: 'no-cache', context: { fetchOptions: { signal: controller.signal } } })\n .catch(error => error)\n controller.abort()\n await read\n expect(notified).to.deep.equal([])\n })\n\n it('while a read that failed on its own is reported', async () => {\n window.fetch = () => Promise.reject(new TypeError('Failed to fetch'))\n await client.query({ query, fetchPolicy: 'no-cache' }).catch(error => error)\n expect(notified.length).to.equal(1)\n })\n})\n"]}
@@ -1 +0,0 @@
1
- export {};
@@ -1,31 +0,0 @@
1
- import { expect } from '@open-wc/testing';
2
- import { ADDRESS_REFUSED, forbiddenMeaning, REFUSAL_HEADER, resetAddressRefusalSaid, sayAddressRefused } from '../src/forbidden.js';
3
- /**
4
- * A 403 that says the address was refused is not sent to check-in - check-in cannot let the address
5
- * in, and the screen would go round between the two. It is said once, however many queries got it.
6
- */
7
- describe('what a 403 means', () => {
8
- it('★ the refusal header means the address was refused', () => {
9
- expect(forbiddenMeaning(new Headers({ [REFUSAL_HEADER]: ADDRESS_REFUSED }))).to.equal('address-refused');
10
- });
11
- it('★ anything else is still "domain required" - the check-in path stays as it was', () => {
12
- expect(forbiddenMeaning(new Headers())).to.equal('domain-required');
13
- expect(forbiddenMeaning(new Headers({ [REFUSAL_HEADER]: 'something-else' }))).to.equal('domain-required');
14
- expect(forbiddenMeaning(undefined)).to.equal('domain-required');
15
- });
16
- });
17
- describe('saying the address was refused', () => {
18
- beforeEach(() => resetAddressRefusalSaid());
19
- it('★ is said once, as an error, however many queries were refused', () => {
20
- const target = new EventTarget();
21
- const said = [];
22
- target.addEventListener('notify', event => said.push(event.detail));
23
- expect(sayAddressRefused(target)).to.equal(true);
24
- expect(sayAddressRefused(target)).to.equal(false);
25
- expect(sayAddressRefused(target)).to.equal(false);
26
- expect(said.length).to.equal(1);
27
- expect(said[0].level).to.equal('error');
28
- expect(said[0].message).to.be.a('string').and.not.equal('');
29
- });
30
- });
31
- //# sourceMappingURL=forbidden.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"forbidden.test.js","sourceRoot":"","sources":["../../test/forbidden.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAEzC,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,cAAc,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAEnI;;;GAGG;AAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,CAAC,gBAAgB,CAAC,IAAI,OAAO,CAAC,EAAE,CAAC,cAAc,CAAC,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAA;IAC1G,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,gFAAgF,EAAE,GAAG,EAAE;QACxF,MAAM,CAAC,gBAAgB,CAAC,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAA;QACnE,MAAM,CAAC,gBAAgB,CAAC,IAAI,OAAO,CAAC,EAAE,CAAC,cAAc,CAAC,EAAE,gBAAgB,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAA;QACzG,MAAM,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAA;IACjE,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,gCAAgC,EAAE,GAAG,EAAE;IAC9C,UAAU,CAAC,GAAG,EAAE,CAAC,uBAAuB,EAAE,CAAC,CAAA;IAE3C,EAAE,CAAC,gEAAgE,EAAE,GAAG,EAAE;QACxE,MAAM,MAAM,GAAG,IAAI,WAAW,EAAE,CAAA;QAChC,MAAM,IAAI,GAAU,EAAE,CAAA;QACtB,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAE,KAAqB,CAAC,MAAM,CAAC,CAAC,CAAA;QAEpF,MAAM,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAChD,MAAM,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QACjD,MAAM,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QAEjD,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAC/B,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QACvC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;IAC7D,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA","sourcesContent":["import { expect } from '@open-wc/testing'\n\nimport { ADDRESS_REFUSED, forbiddenMeaning, REFUSAL_HEADER, resetAddressRefusalSaid, sayAddressRefused } from '../src/forbidden.js'\n\n/**\n * A 403 that says the address was refused is not sent to check-in - check-in cannot let the address\n * in, and the screen would go round between the two. It is said once, however many queries got it.\n */\n\ndescribe('what a 403 means', () => {\n it('★ the refusal header means the address was refused', () => {\n expect(forbiddenMeaning(new Headers({ [REFUSAL_HEADER]: ADDRESS_REFUSED }))).to.equal('address-refused')\n })\n\n it('★ anything else is still \"domain required\" - the check-in path stays as it was', () => {\n expect(forbiddenMeaning(new Headers())).to.equal('domain-required')\n expect(forbiddenMeaning(new Headers({ [REFUSAL_HEADER]: 'something-else' }))).to.equal('domain-required')\n expect(forbiddenMeaning(undefined)).to.equal('domain-required')\n })\n})\n\ndescribe('saying the address was refused', () => {\n beforeEach(() => resetAddressRefusalSaid())\n\n it('★ is said once, as an error, however many queries were refused', () => {\n const target = new EventTarget()\n const said: any[] = []\n target.addEventListener('notify', event => said.push((event as CustomEvent).detail))\n\n expect(sayAddressRefused(target)).to.equal(true)\n expect(sayAddressRefused(target)).to.equal(false)\n expect(sayAddressRefused(target)).to.equal(false)\n\n expect(said.length).to.equal(1)\n expect(said[0].level).to.equal('error')\n expect(said[0].message).to.be.a('string').and.not.equal('')\n })\n})\n"]}
@@ -1 +0,0 @@
1
- export {};
@@ -1,22 +0,0 @@
1
- import { expect } from '@open-wc/testing';
2
- import { isHandledRefusal } from '../src/handled-refusal.js';
3
- const refusal = (code) => ({ message: 'refused', extensions: { code: 'BAD_USER_INPUT', refusal: { code, params: {} } } });
4
- describe('isHandledRefusal', () => {
5
- it('a refusal the query names is handled by the screen', () => {
6
- expect(isHandledRefusal({ handledRefusals: ['twin-model-no-production-spec'] }, [refusal('twin-model-no-production-spec')])).to.equal(true);
7
- });
8
- it('a refusal the query does not name is still reported', () => {
9
- expect(isHandledRefusal({ handledRefusals: ['twin-model-no-production-spec'] }, [refusal('other')])).to.equal(false);
10
- });
11
- it('an error without a refusal code is still reported', () => {
12
- expect(isHandledRefusal({ handledRefusals: ['twin-model-no-production-spec'] }, [{ message: 'boom', extensions: { code: 'INTERNAL_SERVER_ERROR' } }])).to.equal(false);
13
- });
14
- it('one unnamed error among named refusals is still reported', () => {
15
- expect(isHandledRefusal({ handledRefusals: ['twin-model-no-production-spec'] }, [refusal('twin-model-no-production-spec'), { message: 'boom' }])).to.equal(false);
16
- });
17
- it('a query that names nothing has every error reported', () => {
18
- expect(isHandledRefusal({}, [refusal('twin-model-no-production-spec')])).to.equal(false);
19
- expect(isHandledRefusal(undefined, [refusal('twin-model-no-production-spec')])).to.equal(false);
20
- });
21
- });
22
- //# sourceMappingURL=handled-refusal.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"handled-refusal.test.js","sourceRoot":"","sources":["../../test/handled-refusal.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAEzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAE5D,MAAM,OAAO,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAA;AAEjI,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,CAAC,gBAAgB,CAAC,EAAE,eAAe,EAAE,CAAC,+BAA+B,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,+BAA+B,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAC7I,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,CAAC,gBAAgB,CAAC,EAAE,eAAe,EAAE,CAAC,+BAA+B,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IACtH,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,MAAM,CAAC,gBAAgB,CAAC,EAAE,eAAe,EAAE,CAAC,+BAA+B,CAAC,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,uBAAuB,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IACxK,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;QAClE,MAAM,CACJ,gBAAgB,CAAC,EAAE,eAAe,EAAE,CAAC,+BAA+B,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,+BAA+B,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,CAC1I,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IACnB,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,CAAC,gBAAgB,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,+BAA+B,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QACxF,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,OAAO,CAAC,+BAA+B,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IACjG,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA","sourcesContent":["import { expect } from '@open-wc/testing'\n\nimport { isHandledRefusal } from '../src/handled-refusal.js'\n\nconst refusal = (code: string) => ({ message: 'refused', extensions: { code: 'BAD_USER_INPUT', refusal: { code, params: {} } } })\n\ndescribe('isHandledRefusal', () => {\n it('a refusal the query names is handled by the screen', () => {\n expect(isHandledRefusal({ handledRefusals: ['twin-model-no-production-spec'] }, [refusal('twin-model-no-production-spec')])).to.equal(true)\n })\n\n it('a refusal the query does not name is still reported', () => {\n expect(isHandledRefusal({ handledRefusals: ['twin-model-no-production-spec'] }, [refusal('other')])).to.equal(false)\n })\n\n it('an error without a refusal code is still reported', () => {\n expect(isHandledRefusal({ handledRefusals: ['twin-model-no-production-spec'] }, [{ message: 'boom', extensions: { code: 'INTERNAL_SERVER_ERROR' } }])).to.equal(false)\n })\n\n it('one unnamed error among named refusals is still reported', () => {\n expect(\n isHandledRefusal({ handledRefusals: ['twin-model-no-production-spec'] }, [refusal('twin-model-no-production-spec'), { message: 'boom' }])\n ).to.equal(false)\n })\n\n it('a query that names nothing has every error reported', () => {\n expect(isHandledRefusal({}, [refusal('twin-model-no-production-spec')])).to.equal(false)\n expect(isHandledRefusal(undefined, [refusal('twin-model-no-production-spec')])).to.equal(false)\n })\n})\n"]}
@@ -1 +0,0 @@
1
- export {};
@@ -1,341 +0,0 @@
1
- import { expect, fixture } from '@open-wc/testing';
2
- import gql from 'graphql-tag';
3
- import { html, LitElement } from 'lit';
4
- import { MutationController } from '../src/mutation-controller.js';
5
- import { QueryController, refetchWithin } from '../src/query-controller.js';
6
- let answers;
7
- let fetched;
8
- const respond = (body) => new Response(JSON.stringify(body), { headers: { 'content-type': 'application/json' } });
9
- beforeEach(() => {
10
- answers = [];
11
- fetched = window.fetch;
12
- window.fetch = (_input, init) => new Promise((resolve, reject) => {
13
- var _a;
14
- const body = JSON.parse(String(init.body));
15
- answers.push({
16
- id: (_a = body.variables) === null || _a === void 0 ? void 0 : _a.id,
17
- operation: body.query.trim().split(/\s/)[0],
18
- resolve: data => resolve(respond({ data })),
19
- fail: message => resolve(respond({ data: null, errors: [{ message }] })),
20
- drop: () => reject(new TypeError('Failed to fetch')),
21
- refuse: code => resolve(respond({ data: null, errors: [{ message: 'refused', extensions: { refusal: { code } } }] }))
22
- });
23
- });
24
- });
25
- afterEach(() => (window.fetch = fetched));
26
- const settle = () => new Promise(resolve => setTimeout(resolve, 20));
27
- const RULE = gql `
28
- query ($id: String!) {
29
- rule(id: $id) {
30
- name
31
- }
32
- }
33
- `;
34
- const RENAME = gql `
35
- mutation ($id: String!) {
36
- rename(id: $id)
37
- }
38
- `;
39
- class RuleView extends LitElement {
40
- constructor() {
41
- super(...arguments);
42
- this.rule = new QueryController(this, RULE, {
43
- variables: () => (this.ruleId ? { id: this.ruleId } : undefined)
44
- });
45
- this.rename = new MutationController(this, RENAME, { refetch: () => [this.rule] });
46
- }
47
- render() {
48
- var _a, _b;
49
- return html `${(_b = (_a = this.rule.data) === null || _a === void 0 ? void 0 : _a.rule.name) !== null && _b !== void 0 ? _b : ''}`;
50
- }
51
- }
52
- RuleView.properties = { ruleId: {} };
53
- customElements.define('rule-view', RuleView);
54
- class KeptRuleView extends LitElement {
55
- constructor() {
56
- super(...arguments);
57
- this.rule = new QueryController(this, RULE, {
58
- variables: () => (this.ruleId ? { id: this.ruleId } : undefined),
59
- keepPrevious: true
60
- });
61
- this.rename = new MutationController(this, RENAME, { showsError: true });
62
- }
63
- render() {
64
- var _a, _b;
65
- return html `${(_b = (_a = this.rule.data) === null || _a === void 0 ? void 0 : _a.rule.name) !== null && _b !== void 0 ? _b : ''}`;
66
- }
67
- }
68
- KeptRuleView.properties = { ruleId: {} };
69
- customElements.define('kept-rule-view', KeptRuleView);
70
- /** A host that takes what it read into its own state before it draws - in `willUpdate`, ahead of its controllers. */
71
- class DerivingRuleView extends LitElement {
72
- constructor() {
73
- super(...arguments);
74
- this.seen = [];
75
- this.rule = new QueryController(this, RULE, {
76
- variables: () => (this.ruleId ? { id: this.ruleId } : undefined)
77
- });
78
- }
79
- willUpdate() {
80
- var _a;
81
- this.seen.push({ loading: this.rule.loading, name: (_a = this.rule.data) === null || _a === void 0 ? void 0 : _a.rule.name });
82
- }
83
- }
84
- DerivingRuleView.properties = { ruleId: {} };
85
- customElements.define('deriving-rule-view', DerivingRuleView);
86
- const open = async (ruleId) => {
87
- const view = await fixture(html `<rule-view .ruleId=${ruleId}></rule-view>`);
88
- await settle();
89
- return view;
90
- };
91
- describe('QueryController', () => {
92
- it('reads nothing while its variables are undefined', async () => {
93
- const view = await open();
94
- expect(answers.length).to.equal(0);
95
- expect(view.rule.loading).to.equal(false);
96
- });
97
- it('an answer for the variables before never reaches the screen, whatever order it comes in', async () => {
98
- var _a;
99
- const view = await open('a');
100
- view.ruleId = 'b';
101
- await view.updateComplete;
102
- await settle();
103
- expect(answers.map(one => one.id)).to.deep.equal(['a', 'b']);
104
- answers[1].resolve({ rule: { name: 'B' } });
105
- await settle();
106
- answers[0].resolve({ rule: { name: 'A' } });
107
- await settle();
108
- expect((_a = view.rule.data) === null || _a === void 0 ? void 0 : _a.rule.name).to.equal('B');
109
- expect(view.rule.loading).to.equal(false);
110
- expect(view.rule.answeredAt).to.be.instanceOf(Date);
111
- });
112
- it('shows nothing of the variables before while the new ones are read', async () => {
113
- const view = await open('a');
114
- answers[0].resolve({ rule: { name: 'A' } });
115
- await settle();
116
- view.ruleId = 'b';
117
- await view.updateComplete;
118
- expect(view.rule.data).to.equal(undefined);
119
- expect(view.rule.loading).to.equal(true);
120
- });
121
- it("the failure of the variables shown is the controller's error; it reads again only when asked", async () => {
122
- var _a;
123
- const view = await open('a');
124
- answers[0].fail('refused');
125
- await settle();
126
- expect(view.rule.error.message).to.include('refused');
127
- view.requestUpdate();
128
- await view.updateComplete;
129
- await settle();
130
- expect(answers.length).to.equal(1);
131
- await Promise.all([view.rule.refetch(), settle().then(() => answers[1].resolve({ rule: { name: 'A' } }))]);
132
- expect(view.rule.error).to.equal(undefined);
133
- expect((_a = view.rule.data) === null || _a === void 0 ? void 0 : _a.rule.name).to.equal('A');
134
- });
135
- it('a host deriving its state before its controllers update sees the new variables loading, never the answer before', async () => {
136
- const view = await fixture(html `<deriving-rule-view .ruleId=${'a'}></deriving-rule-view>`);
137
- await settle();
138
- answers[0].resolve({ rule: { name: 'A' } });
139
- await settle();
140
- view.seen = [];
141
- view.ruleId = 'b';
142
- await view.updateComplete;
143
- expect(view.seen[0]).to.deep.equal({ loading: true, name: undefined });
144
- });
145
- for (const kept of [false, true]) {
146
- it(`variables gone while the host was away read nothing, and give nothing of what was read${kept ? ' (keepPrevious)' : ''}`, async () => {
147
- const view = await fixture(kept ? html `<kept-rule-view .ruleId=${'a'}></kept-rule-view>` : html `<rule-view .ruleId=${'a'}></rule-view>`);
148
- await settle();
149
- answers[0].resolve({ rule: { name: 'A' } });
150
- await settle();
151
- const parent = view.parentNode;
152
- view.remove();
153
- view.ruleId = undefined;
154
- parent.appendChild(view);
155
- await view.updateComplete;
156
- expect(view.rule.data).to.equal(undefined);
157
- expect(view.rule.loading).to.equal(false);
158
- expect(answers.length).to.equal(1);
159
- });
160
- }
161
- it('a host that leaves stops watching, and reads the same variables again when it comes back', async () => {
162
- var _a;
163
- const view = await open('a');
164
- const parent = view.parentNode;
165
- view.remove();
166
- answers[0].resolve({ rule: { name: 'stale' } });
167
- await settle();
168
- expect(view.rule.data).to.equal(undefined);
169
- parent.appendChild(view);
170
- await settle();
171
- expect(answers.length).to.equal(2);
172
- answers[1].resolve({ rule: { name: 'A' } });
173
- await settle();
174
- expect((_a = view.rule.data) === null || _a === void 0 ? void 0 : _a.rule.name).to.equal('A');
175
- });
176
- it('a page refresh reads again what is shown inside it', async () => {
177
- var _a;
178
- const view = await open('a');
179
- answers[0].resolve({ rule: { name: 'A' } });
180
- await settle();
181
- const refreshed = refetchWithin(view.parentNode);
182
- await settle();
183
- expect(answers.length).to.equal(2);
184
- answers[1].resolve({ rule: { name: 'A2' } });
185
- await refreshed;
186
- await settle();
187
- expect((_a = view.rule.data) === null || _a === void 0 ? void 0 : _a.rule.name).to.equal('A2');
188
- });
189
- });
190
- describe('a refresh that fails after a success', () => {
191
- it('★ keeps the previous answer and its time, and reports the failure', async () => {
192
- var _a, _b;
193
- const view = await open('a');
194
- answers[0].resolve({ rule: { name: 'A' } });
195
- await settle();
196
- const readAt = view.rule.answeredAt;
197
- await new Promise(resolve => setTimeout(resolve, 5));
198
- void view.rule.refetch();
199
- await settle();
200
- expect(view.rule.loading).to.equal(true);
201
- expect((_a = view.rule.data) === null || _a === void 0 ? void 0 : _a.rule.name).to.equal('A');
202
- answers[1].drop();
203
- await settle();
204
- expect(view.rule.loading).to.equal(false);
205
- expect((_b = view.rule.data) === null || _b === void 0 ? void 0 : _b.rule.name).to.equal('A');
206
- expect(view.rule.error).to.not.equal(undefined);
207
- expect(view.rule.answeredAt).to.equal(readAt);
208
- });
209
- it('★ keepPrevious: a refused refresh keeps the time the answer shown was read', async () => {
210
- var _a;
211
- const view = await fixture(html `<kept-rule-view .ruleId=${'a'}></kept-rule-view>`);
212
- await settle();
213
- answers[0].resolve({ rule: { name: 'A' } });
214
- await settle();
215
- const readAt = view.rule.answeredAt;
216
- await new Promise(resolve => setTimeout(resolve, 5));
217
- void view.rule.refetch();
218
- await settle();
219
- answers[1].fail('down');
220
- await settle();
221
- expect((_a = view.rule.data) === null || _a === void 0 ? void 0 : _a.rule.name).to.equal('A');
222
- expect(view.rule.error.message).to.include('down');
223
- expect(view.rule.answeredAt).to.equal(readAt);
224
- });
225
- });
226
- describe('QueryController on a network failure', () => {
227
- it('stops, and reads again only when asked - never on its own at every update', async () => {
228
- var _a;
229
- const view = await open('a');
230
- answers[0].drop();
231
- await settle();
232
- expect(view.rule.error).to.not.equal(undefined);
233
- for (let i = 0; i < 3; i++) {
234
- view.requestUpdate();
235
- await view.updateComplete;
236
- }
237
- await settle();
238
- expect(answers.length).to.equal(1);
239
- void view.rule.refetch();
240
- await settle();
241
- expect(answers.length).to.equal(2);
242
- answers[1].resolve({ rule: { name: 'A' } });
243
- await settle();
244
- expect((_a = view.rule.data) === null || _a === void 0 ? void 0 : _a.rule.name).to.equal('A');
245
- });
246
- });
247
- describe('MutationController', () => {
248
- it('is pending while out, then reads again the queries it names', async () => {
249
- var _a;
250
- const view = await open('a');
251
- answers[0].resolve({ rule: { name: 'A' } });
252
- await settle();
253
- const saving = view.rename.run({ id: 'a' });
254
- expect(view.rename.pending).to.equal(true);
255
- await settle();
256
- answers[1].resolve({ rename: true });
257
- await settle();
258
- expect(answers[2].operation).to.equal('query');
259
- answers[2].resolve({ rule: { name: 'A renamed' } });
260
- expect(await saving).to.deep.equal({ rename: true });
261
- expect(view.rename.pending).to.equal(false);
262
- expect((_a = view.rule.data) === null || _a === void 0 ? void 0 : _a.rule.name).to.equal('A renamed');
263
- });
264
- it('one save at a time: another run while one is out sends nothing', async () => {
265
- var _a;
266
- const view = await open('a');
267
- answers[0].resolve({ rule: { name: 'A' } });
268
- await settle();
269
- const first = view.rename.run({ id: 'a' });
270
- expect(await view.rename.run({ id: 'b' })).to.equal(undefined);
271
- await settle();
272
- expect(answers.filter(answer => answer.operation === 'mutation').map(answer => answer.id)).to.deep.equal(['a']);
273
- answers[1].resolve({ rename: true });
274
- await settle();
275
- (_a = answers[2]) === null || _a === void 0 ? void 0 : _a.resolve({ rule: { name: 'A' } });
276
- expect(await first).to.deep.equal({ rename: true });
277
- });
278
- it('a refused save resolves to undefined with its error, and reads nothing again', async () => {
279
- const view = await open('a');
280
- answers[0].resolve({ rule: { name: 'A' } });
281
- await settle();
282
- const saving = view.rename.run({ id: 'a' });
283
- await settle();
284
- answers[1].fail('no');
285
- expect(await saving).to.equal(undefined);
286
- expect(view.rename.error.message).to.include('no');
287
- expect(view.rename.error.graphQLErrors[0].message).to.equal('no');
288
- expect(answers.length).to.equal(2);
289
- });
290
- });
291
- describe('keepPrevious and showsError', () => {
292
- let notified;
293
- const listen = (event) => notified.push(event.detail);
294
- beforeEach(() => {
295
- notified = [];
296
- document.addEventListener('notify', listen);
297
- });
298
- afterEach(() => document.removeEventListener('notify', listen));
299
- it('keeps the previous answer while new variables are read, and when they fail', async () => {
300
- var _a, _b;
301
- const view = await fixture(html `<kept-rule-view .ruleId=${'a'}></kept-rule-view>`);
302
- await settle();
303
- answers[0].resolve({ rule: { name: 'A' } });
304
- await settle();
305
- view.ruleId = 'b';
306
- await view.updateComplete;
307
- expect(view.rule.loading).to.equal(true);
308
- expect((_a = view.rule.data) === null || _a === void 0 ? void 0 : _a.rule.name).to.equal('A');
309
- await settle();
310
- answers[1].fail('refused');
311
- await settle();
312
- expect((_b = view.rule.data) === null || _b === void 0 ? void 0 : _b.rule.name).to.equal('A');
313
- expect(view.rule.error.message).to.include('refused');
314
- });
315
- it('a save that shows its own error is not reported by the link; one that does not still is', async () => {
316
- const kept = await fixture(html `<kept-rule-view></kept-rule-view>`);
317
- const saving = kept.rename.run({ id: 'a' });
318
- await settle();
319
- answers[0].fail('no');
320
- await saving;
321
- expect(kept.rename.error.message).to.include('no');
322
- expect(notified).to.deep.equal([]);
323
- const plain = await open();
324
- const plainSave = plain.rename.run({ id: 'a' });
325
- await settle();
326
- answers[1].fail('no');
327
- await plainSave;
328
- expect(notified.length).to.equal(1);
329
- });
330
- it('names the refusal the server gave, and keeps the failure as it came', async () => {
331
- var _a;
332
- const view = await open('a');
333
- const saving = view.rename.run({ id: 'a' });
334
- await settle();
335
- answers[answers.length - 1].refuse('rename-closed');
336
- await saving;
337
- expect((_a = view.rename.refusal) === null || _a === void 0 ? void 0 : _a.code).to.equal('rename-closed');
338
- expect(view.rename.error.graphQLErrors[0].extensions.refusal.code).to.equal('rename-closed');
339
- });
340
- });
341
- //# sourceMappingURL=query-controller.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"query-controller.test.js","sourceRoot":"","sources":["../../test/query-controller.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect, fixture } from '@open-wc/testing'\nimport gql from 'graphql-tag'\nimport { html, LitElement } from 'lit'\n\nimport { MutationController } from '../src/mutation-controller.js'\nimport { QueryController, refetchWithin } from '../src/query-controller.js'\n\n/**\n * A screen declares what it reads (ADR-0190): the controller reads the variables shown now, and only their answer\n * reaches the screen - whatever order the answers come back in.\n */\n\ntype Answer = {\n resolve: (data: unknown) => void\n fail: (message: string) => void\n drop: () => void\n refuse: (code: string) => void\n id: unknown\n operation: string\n}\n\nlet answers: Answer[]\nlet fetched: typeof window.fetch\n\nconst respond = (body: unknown) =>\n new Response(JSON.stringify(body), { headers: { 'content-type': 'application/json' } })\n\nbeforeEach(() => {\n answers = []\n fetched = window.fetch\n window.fetch = (_input, init) =>\n new Promise((resolve, reject) => {\n const body = JSON.parse(String(init!.body))\n answers.push({\n id: body.variables?.id,\n operation: body.query.trim().split(/\\s/)[0],\n resolve: data => resolve(respond({ data })),\n fail: message => resolve(respond({ data: null, errors: [{ message }] })),\n drop: () => reject(new TypeError('Failed to fetch')),\n refuse: code =>\n resolve(respond({ data: null, errors: [{ message: 'refused', extensions: { refusal: { code } } }] }))\n })\n })\n})\n\nafterEach(() => (window.fetch = fetched))\n\nconst settle = () => new Promise(resolve => setTimeout(resolve, 20))\n\nconst RULE = gql`\n query ($id: String!) {\n rule(id: $id) {\n name\n }\n }\n`\nconst RENAME = gql`\n mutation ($id: String!) {\n rename(id: $id)\n }\n`\n\nclass RuleView extends LitElement {\n static properties = { ruleId: {} }\n ruleId?: string\n rule = new QueryController<{ rule: { name: string } }>(this, RULE, {\n variables: () => (this.ruleId ? { id: this.ruleId } : undefined)\n })\n rename = new MutationController(this, RENAME, { refetch: () => [this.rule] })\n render() {\n return html`${this.rule.data?.rule.name ?? ''}`\n }\n}\ncustomElements.define('rule-view', RuleView)\n\nclass KeptRuleView extends LitElement {\n static properties = { ruleId: {} }\n ruleId?: string\n rule = new QueryController<{ rule: { name: string } }>(this, RULE, {\n variables: () => (this.ruleId ? { id: this.ruleId } : undefined),\n keepPrevious: true\n })\n rename = new MutationController(this, RENAME, { showsError: true })\n render() {\n return html`${this.rule.data?.rule.name ?? ''}`\n }\n}\ncustomElements.define('kept-rule-view', KeptRuleView)\n\n/** A host that takes what it read into its own state before it draws - in `willUpdate`, ahead of its controllers. */\nclass DerivingRuleView extends LitElement {\n static properties = { ruleId: {} }\n ruleId?: string\n seen: { loading: boolean; name?: string }[] = []\n rule = new QueryController<{ rule: { name: string } }>(this, RULE, {\n variables: () => (this.ruleId ? { id: this.ruleId } : undefined)\n })\n willUpdate() {\n this.seen.push({ loading: this.rule.loading, name: this.rule.data?.rule.name })\n }\n}\ncustomElements.define('deriving-rule-view', DerivingRuleView)\n\nconst open = async (ruleId?: string) => {\n const view = await fixture<RuleView>(html`<rule-view .ruleId=${ruleId}></rule-view>`)\n await settle()\n return view\n}\n\ndescribe('QueryController', () => {\n it('reads nothing while its variables are undefined', async () => {\n const view = await open()\n expect(answers.length).to.equal(0)\n expect(view.rule.loading).to.equal(false)\n })\n\n it('an answer for the variables before never reaches the screen, whatever order it comes in', async () => {\n const view = await open('a')\n view.ruleId = 'b'\n await view.updateComplete\n await settle()\n expect(answers.map(one => one.id)).to.deep.equal(['a', 'b'])\n answers[1].resolve({ rule: { name: 'B' } })\n await settle()\n answers[0].resolve({ rule: { name: 'A' } })\n await settle()\n expect(view.rule.data?.rule.name).to.equal('B')\n expect(view.rule.loading).to.equal(false)\n expect(view.rule.answeredAt).to.be.instanceOf(Date)\n })\n\n it('shows nothing of the variables before while the new ones are read', async () => {\n const view = await open('a')\n answers[0].resolve({ rule: { name: 'A' } })\n await settle()\n view.ruleId = 'b'\n await view.updateComplete\n expect(view.rule.data).to.equal(undefined)\n expect(view.rule.loading).to.equal(true)\n })\n\n it(\"the failure of the variables shown is the controller's error; it reads again only when asked\", async () => {\n const view = await open('a')\n answers[0].fail('refused')\n await settle()\n expect((view.rule.error as Error).message).to.include('refused')\n view.requestUpdate()\n await view.updateComplete\n await settle()\n expect(answers.length).to.equal(1)\n await Promise.all([view.rule.refetch(), settle().then(() => answers[1].resolve({ rule: { name: 'A' } }))])\n expect(view.rule.error).to.equal(undefined)\n expect(view.rule.data?.rule.name).to.equal('A')\n })\n\n it('a host deriving its state before its controllers update sees the new variables loading, never the answer before', async () => {\n const view = await fixture<DerivingRuleView>(html`<deriving-rule-view .ruleId=${'a'}></deriving-rule-view>`)\n await settle()\n answers[0].resolve({ rule: { name: 'A' } })\n await settle()\n view.seen = []\n view.ruleId = 'b'\n await view.updateComplete\n expect(view.seen[0]).to.deep.equal({ loading: true, name: undefined })\n })\n\n for (const kept of [false, true]) {\n it(`variables gone while the host was away read nothing, and give nothing of what was read${kept ? ' (keepPrevious)' : ''}`, async () => {\n const view: any = await fixture(kept ? html`<kept-rule-view .ruleId=${'a'}></kept-rule-view>` : html`<rule-view .ruleId=${'a'}></rule-view>`)\n await settle()\n answers[0].resolve({ rule: { name: 'A' } })\n await settle()\n const parent = view.parentNode\n view.remove()\n view.ruleId = undefined\n parent.appendChild(view)\n await view.updateComplete\n expect(view.rule.data).to.equal(undefined)\n expect(view.rule.loading).to.equal(false)\n expect(answers.length).to.equal(1)\n })\n }\n\n it('a host that leaves stops watching, and reads the same variables again when it comes back', async () => {\n const view = await open('a')\n const parent = view.parentNode!\n view.remove()\n answers[0].resolve({ rule: { name: 'stale' } })\n await settle()\n expect(view.rule.data).to.equal(undefined)\n parent.appendChild(view)\n await settle()\n expect(answers.length).to.equal(2)\n answers[1].resolve({ rule: { name: 'A' } })\n await settle()\n expect(view.rule.data?.rule.name).to.equal('A')\n })\n\n it('a page refresh reads again what is shown inside it', async () => {\n const view = await open('a')\n answers[0].resolve({ rule: { name: 'A' } })\n await settle()\n const refreshed = refetchWithin(view.parentNode!)\n await settle()\n expect(answers.length).to.equal(2)\n answers[1].resolve({ rule: { name: 'A2' } })\n await refreshed\n await settle()\n expect(view.rule.data?.rule.name).to.equal('A2')\n })\n})\n\ndescribe('a refresh that fails after a success', () => {\n it('★ keeps the previous answer and its time, and reports the failure', async () => {\n const view = await open('a')\n answers[0].resolve({ rule: { name: 'A' } })\n await settle()\n const readAt = view.rule.answeredAt\n await new Promise(resolve => setTimeout(resolve, 5))\n void view.rule.refetch()\n await settle()\n expect(view.rule.loading).to.equal(true)\n expect(view.rule.data?.rule.name).to.equal('A')\n answers[1].drop()\n await settle()\n expect(view.rule.loading).to.equal(false)\n expect(view.rule.data?.rule.name).to.equal('A')\n expect(view.rule.error).to.not.equal(undefined)\n expect(view.rule.answeredAt).to.equal(readAt)\n })\n\n it('★ keepPrevious: a refused refresh keeps the time the answer shown was read', async () => {\n const view = await fixture<KeptRuleView>(html`<kept-rule-view .ruleId=${'a'}></kept-rule-view>`)\n await settle()\n answers[0].resolve({ rule: { name: 'A' } })\n await settle()\n const readAt = view.rule.answeredAt\n await new Promise(resolve => setTimeout(resolve, 5))\n void view.rule.refetch()\n await settle()\n answers[1].fail('down')\n await settle()\n expect(view.rule.data?.rule.name).to.equal('A')\n expect((view.rule.error as Error).message).to.include('down')\n expect(view.rule.answeredAt).to.equal(readAt)\n })\n})\n\ndescribe('QueryController on a network failure', () => {\n it('stops, and reads again only when asked - never on its own at every update', async () => {\n const view = await open('a')\n answers[0].drop()\n await settle()\n expect(view.rule.error).to.not.equal(undefined)\n for (let i = 0; i < 3; i++) {\n view.requestUpdate()\n await view.updateComplete\n }\n await settle()\n expect(answers.length).to.equal(1)\n void view.rule.refetch()\n await settle()\n expect(answers.length).to.equal(2)\n answers[1].resolve({ rule: { name: 'A' } })\n await settle()\n expect(view.rule.data?.rule.name).to.equal('A')\n })\n})\n\ndescribe('MutationController', () => {\n it('is pending while out, then reads again the queries it names', async () => {\n const view = await open('a')\n answers[0].resolve({ rule: { name: 'A' } })\n await settle()\n const saving = view.rename.run({ id: 'a' })\n expect(view.rename.pending).to.equal(true)\n await settle()\n answers[1].resolve({ rename: true })\n await settle()\n expect(answers[2].operation).to.equal('query')\n answers[2].resolve({ rule: { name: 'A renamed' } })\n expect(await saving).to.deep.equal({ rename: true })\n expect(view.rename.pending).to.equal(false)\n expect(view.rule.data?.rule.name).to.equal('A renamed')\n })\n\n it('one save at a time: another run while one is out sends nothing', async () => {\n const view = await open('a')\n answers[0].resolve({ rule: { name: 'A' } })\n await settle()\n const first = view.rename.run({ id: 'a' })\n expect(await view.rename.run({ id: 'b' })).to.equal(undefined)\n await settle()\n expect(answers.filter(answer => answer.operation === 'mutation').map(answer => answer.id)).to.deep.equal(['a'])\n answers[1].resolve({ rename: true })\n await settle()\n answers[2]?.resolve({ rule: { name: 'A' } })\n expect(await first).to.deep.equal({ rename: true })\n })\n\n it('a refused save resolves to undefined with its error, and reads nothing again', async () => {\n const view = await open('a')\n answers[0].resolve({ rule: { name: 'A' } })\n await settle()\n const saving = view.rename.run({ id: 'a' })\n await settle()\n answers[1].fail('no')\n expect(await saving).to.equal(undefined)\n expect((view.rename.error as Error).message).to.include('no')\n expect((view.rename.error as any).graphQLErrors[0].message).to.equal('no')\n expect(answers.length).to.equal(2)\n })\n})\n\ndescribe('keepPrevious and showsError', () => {\n let notified: unknown[]\n const listen = (event: Event) => notified.push((event as CustomEvent).detail)\n beforeEach(() => {\n notified = []\n document.addEventListener('notify', listen)\n })\n afterEach(() => document.removeEventListener('notify', listen))\n\n it('keeps the previous answer while new variables are read, and when they fail', async () => {\n const view = await fixture<KeptRuleView>(html`<kept-rule-view .ruleId=${'a'}></kept-rule-view>`)\n await settle()\n answers[0].resolve({ rule: { name: 'A' } })\n await settle()\n view.ruleId = 'b'\n await view.updateComplete\n expect(view.rule.loading).to.equal(true)\n expect(view.rule.data?.rule.name).to.equal('A')\n await settle()\n answers[1].fail('refused')\n await settle()\n expect(view.rule.data?.rule.name).to.equal('A')\n expect((view.rule.error as Error).message).to.include('refused')\n })\n\n it('a save that shows its own error is not reported by the link; one that does not still is', async () => {\n const kept = await fixture<KeptRuleView>(html`<kept-rule-view></kept-rule-view>`)\n const saving = kept.rename.run({ id: 'a' })\n await settle()\n answers[0].fail('no')\n await saving\n expect((kept.rename.error as Error).message).to.include('no')\n expect(notified).to.deep.equal([])\n\n const plain = await open()\n const plainSave = plain.rename.run({ id: 'a' })\n await settle()\n answers[1].fail('no')\n await plainSave\n expect(notified.length).to.equal(1)\n })\n\n it('names the refusal the server gave, and keeps the failure as it came', async () => {\n const view = await open('a')\n const saving = view.rename.run({ id: 'a' })\n await settle()\n answers[answers.length - 1].refuse('rename-closed')\n await saving\n expect(view.rename.refusal?.code).to.equal('rename-closed')\n expect((view.rename.error as any).graphQLErrors[0].extensions.refusal.code).to.equal('rename-closed')\n })\n})\n"]}
@@ -1 +0,0 @@
1
- export {};