From: Ruben Beltran del Rio
Date: Sat, 30 Apr 2022 23:02:58 +0000 (+0200)
Subject: Apply formatting
X-Git-Url: https://git.r.bdr.sh/rbdr/forum/commitdiff_plain/cac85db02ff00732cf75d473dc3411332f33d845?hp=a7cf03c192470cbab13edeb1aec99e0c66dede10
Apply formatting
---
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 703003c..b1f4357 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -5,7 +5,7 @@ stages:
- test
before_script:
- - npm install
+ - npm install
lint:
stage: lint
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6395a24..40512a2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,11 +1,14 @@
# Changelog
+
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased]
+
### Added
+
- Svelte based frontend
- Koa based backend
- RethinkDB for backend
@@ -17,4 +20,4 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- NPM tasks to lint and install git hooks
- A gitignore file
-[Unreleased]: https://gitlab.com/rbdr/forum/compare/master...develop
+[unreleased]: https://gitlab.com/rbdr/forum/compare/master...develop
diff --git a/README.md b/README.md
index e8b6201..3e0f099 100644
--- a/README.md
+++ b/README.md
@@ -20,10 +20,11 @@ You can run tests with `npm test`. The tests use `testing-library`, `pact`,
and `jest`.
Here's some short guidelines:
- - Every component that receives props or changes state should be tested.
- - Test expected outcomes, not implementation details.
- - Avoid mocking unless it's an external call
- - Stores that interact with the API should be tested using pact
+
+- Every component that receives props or changes state should be tested.
+- Test expected outcomes, not implementation details.
+- Avoid mocking unless it's an external call
+- Stores that interact with the API should be tested using pact
[node]: https://nodejs.org/en/
[forum-server]: https://gitlab.com/rbdr/forum-server
diff --git a/doc/COVERAGE.md b/doc/COVERAGE.md
index dd1f5ef..09d8810 100644
--- a/doc/COVERAGE.md
+++ b/doc/COVERAGE.md
@@ -1,31 +1,29 @@
-# Code Quality Report
-Thu Nov 15 2018 01:45:42 GMT+0100 (Central European Standard Time)
-
+# Code Quality Report
+
+Thu Nov 15 2018 01:45:42 GMT+0100 (Central European Standard Time)
+
## Tests
-
+
**Application Loader**
-â 1) Should instantiate and start Forum on window load (18 ms)
-
-
+â 1) Should instantiate and start Forum on window load (18 ms)
+
1 test
0 tests failed
-0 tests skipped
-
-Test duration: 27 ms
-
-
-## Leaks
-The following global variable leaks were detected:_registeredHandlers, _eventHandlers, DOMException, NamedNodeMap, Attr, Node, Element, DocumentFragment, HTMLDocument, Document, XMLDocument, CharacterData, Text, CDATASection, ProcessingInstruction, Comment, DocumentType, DOMImplementation, NodeList, HTMLCollection, HTMLOptionsCollection, DOMStringMap, DOMTokenList, SVGAnimatedString, SVGNumber, SVGStringList, Event, CloseEvent, CustomEvent, MessageEvent, ErrorEvent, HashChangeEvent, FocusEvent, PopStateEvent, UIEvent, MouseEvent, KeyboardEvent, TouchEvent, ProgressEvent, CompositionEvent, WheelEvent, EventTarget, BarProp, Location, History, Screen, Performance, Blob, File, FileList, DOMParser, FormData, XMLHttpRequestEventTarget, XMLHttpRequestUpload, NodeIterator, TreeWalker, HTMLElement, HTMLAnchorElement, HTMLAreaElement, HTMLAudioElement, HTMLBaseElement, HTMLBodyElement, HTMLBRElement, HTMLButtonElement, HTMLCanvasElement, HTMLDataElement, HTMLDataListElement, HTMLDetailsElement, HTMLDialogElement, HTMLDirectoryElement, HTMLDivElement, HTMLDListElement, HTMLEmbedElement, HTMLFieldSetElement, HTMLFontElement, HTMLFormElement, HTMLFrameElement, HTMLFrameSetElement, HTMLHeadingElement, HTMLHeadElement, HTMLHRElement, HTMLHtmlElement, HTMLIFrameElement, HTMLImageElement, HTMLInputElement, HTMLLabelElement, HTMLLegendElement, HTMLLIElement, HTMLLinkElement, HTMLMapElement, HTMLMarqueeElement, HTMLMediaElement, HTMLMenuElement, HTMLMetaElement, HTMLMeterElement, HTMLModElement, HTMLObjectElement, HTMLOListElement, HTMLOptGroupElement, HTMLOptionElement, HTMLOutputElement, HTMLParagraphElement, HTMLParamElement, HTMLPictureElement, HTMLPreElement, HTMLProgressElement, HTMLQuoteElement, HTMLScriptElement, HTMLSelectElement, HTMLSourceElement, HTMLSpanElement, HTMLStyleElement, HTMLTableCaptionElement, HTMLTableCellElement, HTMLTableColElement, HTMLTableElement, HTMLTimeElement, HTMLTitleElement, HTMLTableRowElement, HTMLTableSectionElement, HTMLTemplateElement, HTMLTextAreaElement, HTMLTrackElement, HTMLUListElement, HTMLUnknownElement, HTMLVideoElement, SVGElement, SVGGraphicsElement, SVGSVGElement, StyleSheet, MediaList, CSSStyleSheet, CSSRule, CSSStyleRule, CSSMediaRule, CSSImportRule, CSSStyleDeclaration, StyleSheetList, XPathException, XPathExpression, XPathResult, XPathEvaluator, NodeFilter, Window, _globalProxy, _document, _sessionHistory, _virtualConsole, _runScripts, _top, _parent, _frameElement, _length, _pretendToBeVisual, length, window, frameElement, frames, self, parent, top, document, external, location, history, navigator, locationbar, menubar, personalbar, scrollbars, statusbar, toolbar, performance, screen, addEventListener, removeEventListener, dispatchEvent, __stopAllTimers, Option, Image, Audio, postMessage, atob, btoa, FileReader, WebSocket, AbortSignal, AbortController, XMLHttpRequest, stop, close, getComputedStyle, captureEvents, releaseEvents, name, devicePixelRatio, innerWidth, innerHeight, outerWidth, outerHeight, pageXOffset, pageYOffset, screenX, screenY, scrollX, scrollY, screenLeft, screenTop, alert, blur, confirm, focus, moveBy, moveTo, open, print, prompt, resizeBy, resizeTo, scroll, scrollBy, scrollTo
-
-
-## Coverage
+0 tests skipped
+
+Test duration: 27 ms
+
+## Leaks
+
+The following global variable leaks were detected:\_registeredHandlers, \_eventHandlers, DOMException, NamedNodeMap, Attr, Node, Element, DocumentFragment, HTMLDocument, Document, XMLDocument, CharacterData, Text, CDATASection, ProcessingInstruction, Comment, DocumentType, DOMImplementation, NodeList, HTMLCollection, HTMLOptionsCollection, DOMStringMap, DOMTokenList, SVGAnimatedString, SVGNumber, SVGStringList, Event, CloseEvent, CustomEvent, MessageEvent, ErrorEvent, HashChangeEvent, FocusEvent, PopStateEvent, UIEvent, MouseEvent, KeyboardEvent, TouchEvent, ProgressEvent, CompositionEvent, WheelEvent, EventTarget, BarProp, Location, History, Screen, Performance, Blob, File, FileList, DOMParser, FormData, XMLHttpRequestEventTarget, XMLHttpRequestUpload, NodeIterator, TreeWalker, HTMLElement, HTMLAnchorElement, HTMLAreaElement, HTMLAudioElement, HTMLBaseElement, HTMLBodyElement, HTMLBRElement, HTMLButtonElement, HTMLCanvasElement, HTMLDataElement, HTMLDataListElement, HTMLDetailsElement, HTMLDialogElement, HTMLDirectoryElement, HTMLDivElement, HTMLDListElement, HTMLEmbedElement, HTMLFieldSetElement, HTMLFontElement, HTMLFormElement, HTMLFrameElement, HTMLFrameSetElement, HTMLHeadingElement, HTMLHeadElement, HTMLHRElement, HTMLHtmlElement, HTMLIFrameElement, HTMLImageElement, HTMLInputElement, HTMLLabelElement, HTMLLegendElement, HTMLLIElement, HTMLLinkElement, HTMLMapElement, HTMLMarqueeElement, HTMLMediaElement, HTMLMenuElement, HTMLMetaElement, HTMLMeterElement, HTMLModElement, HTMLObjectElement, HTMLOListElement, HTMLOptGroupElement, HTMLOptionElement, HTMLOutputElement, HTMLParagraphElement, HTMLParamElement, HTMLPictureElement, HTMLPreElement, HTMLProgressElement, HTMLQuoteElement, HTMLScriptElement, HTMLSelectElement, HTMLSourceElement, HTMLSpanElement, HTMLStyleElement, HTMLTableCaptionElement, HTMLTableCellElement, HTMLTableColElement, HTMLTableElement, HTMLTimeElement, HTMLTitleElement, HTMLTableRowElement, HTMLTableSectionElement, HTMLTemplateElement, HTMLTextAreaElement, HTMLTrackElement, HTMLUListElement, HTMLUnknownElement, HTMLVideoElement, SVGElement, SVGGraphicsElement, SVGSVGElement, StyleSheet, MediaList, CSSStyleSheet, CSSRule, CSSStyleRule, CSSMediaRule, CSSImportRule, CSSStyleDeclaration, StyleSheetList, XPathException, XPathExpression, XPathResult, XPathEvaluator, NodeFilter, Window, \_globalProxy, \_document, \_sessionHistory, \_virtualConsole, \_runScripts, \_top, \_parent, \_frameElement, \_length, \_pretendToBeVisual, length, window, frameElement, frames, self, parent, top, document, external, location, history, navigator, locationbar, menubar, personalbar, scrollbars, statusbar, toolbar, performance, screen, addEventListener, removeEventListener, dispatchEvent, \_\_stopAllTimers, Option, Image, Audio, postMessage, atob, btoa, FileReader, WebSocket, AbortSignal, AbortController, XMLHttpRequest, stop, close, getComputedStyle, captureEvents, releaseEvents, name, devicePixelRatio, innerWidth, innerHeight, outerWidth, outerHeight, pageXOffset, pageYOffset, screenX, screenY, scrollX, scrollY, screenLeft, screenTop, alert, blur, confirm, focus, moveBy, moveTo, open, print, prompt, resizeBy, resizeTo, scroll, scrollBy, scrollTo
+
+## Coverage
+
Threshold: 100%
-Coverage: 0.00% (0/0)
-
-
-
-## Linting
+Coverage: 0.00% (0/0)
+
+## Linting
+
Warnings threshold: 0
Errors threshold: 0
-No issues
-
+No issues
diff --git a/doc/README.md b/doc/README.md
index f294b0f..d3119e0 100644
--- a/doc/README.md
+++ b/doc/README.md
@@ -25,16 +25,17 @@ the forum object.
## Forum
-The Forum class is the main entry point for the backend application.
+The Forum class is the main entry point for the backend application.
-| Param | Type | Description |
-| --- | --- | --- |
+| Param | Type | Description |
+| ------ | ---------------------------------------------------------------------- | ------------------------------------------------- |
| config | [tForumBackendConfiguration
](#tForumBackendConfiguration) | the initialization options to extend the instance |
### forum.run()
+
Initializes the application and starts listening. Also prints a
nice robotic banner with information.
@@ -42,6 +43,7 @@ nice robotic banner with information.
## tForumBackendConfiguration : object
+
The main configuration object for the Forum backend. It will be used to
initialize all of the sub-components. It can extend any property of
the forum object.
@@ -49,37 +51,38 @@ the forum object.
**Kind**: global typedef
**Properties**
-| Name | Type | Default | Description |
-| --- | --- | --- | --- |
-| [port] | number
| 1978
| the port where the app will listen on |
-| [staticDirectory] | string
| "static"
| the path, relative to the project root, where static assets live |
-| [ttl] | number
| 180
| the time in seconds that posts remain alive |
-| rethinkDB | [tRethinkDBConfiguration
](#tRethinkDBConfiguration) | | the configuration to connect to the rethinkDB server |
-| jwt | [tJWTConfiguration
](#tJWTConfiguration) | | the configuration for the JWT authentication |
+| Name | Type | Default | Description |
+| ----------------- | ---------------------------------------------------------------- | ------------------------------- | ---------------------------------------------------------------- |
+| [port] | number
| 1978
| the port where the app will listen on |
+| [staticDirectory] | string
| "static"
| the path, relative to the project root, where static assets live |
+| [ttl] | number
| 180
| the time in seconds that posts remain alive |
+| rethinkDB | [tRethinkDBConfiguration
](#tRethinkDBConfiguration) | | the configuration to connect to the rethinkDB server |
+| jwt | [tJWTConfiguration
](#tJWTConfiguration) | | the configuration for the JWT authentication |
## tJWTConfiguration : object
+
Configures the behavior of the JWT token.
**Kind**: global typedef
**Properties**
-| Name | Type | Default | Description |
-| --- | --- | --- | --- |
+| Name | Type | Default | Description |
+| ---------- | ------------------- | ------------------ | ---------------------------------- |
| [duration] | number
| 86400
| the duration of the JWT in seconds |
-| secret | string
| | the secret used to sign the JWT |
+| secret | string
| | the secret used to sign the JWT |
## tRethinkDBConfiguration : object
+
Information required to connect to the rethinkDB server
**Kind**: global typedef
**Properties**
-| Name | Type | Default | Description |
-| --- | --- | --- | --- |
-| host | string
| | the location of the rethinkDB host |
+| Name | Type | Default | Description |
+| ------ | ------------------- | ----------------- | ---------------------------------------- |
+| host | string
| | the location of the rethinkDB host |
| [post] | string
| 6379
| port where rethinkDB server is listening |
-
diff --git a/jest.config.js b/jest.config.js
index 6b808fc..0e21d6b 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -1,24 +1,24 @@
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
export default {
- preset: "ts-jest",
- transform: {
- "^.+\\.svelte$": [
- "svelte-jester",
- {
- "preprocess": true
- }
- ]
- },
- moduleNameMapper: {
- "^\\$lib(.*)$": "/src/lib$1",
- "^\\$app(.*)$": [".svelte/dev/runtime/app/*", ".svelte/build/runtime/app/*"]
- },
- moduleFileExtensions: ["ts", "js", "svelte"],
- globals: {
- 'ts-jest': {
- diagnostics: {
- ignoreCodes: [ 'TS151001' ],
- },
- },
- },
-}
+ preset: 'ts-jest',
+ transform: {
+ '^.+\\.svelte$': [
+ 'svelte-jester',
+ {
+ preprocess: true
+ }
+ ]
+ },
+ moduleNameMapper: {
+ '^\\$lib(.*)$': '/src/lib$1',
+ '^\\$app(.*)$': ['.svelte/dev/runtime/app/*', '.svelte/build/runtime/app/*']
+ },
+ moduleFileExtensions: ['ts', 'js', 'svelte'],
+ globals: {
+ 'ts-jest': {
+ diagnostics: {
+ ignoreCodes: ['TS151001']
+ }
+ }
+ }
+};
diff --git a/pacts/forumclient-forumserver.json b/pacts/forumclient-forumserver.json
index 9ec37f8..c4d529c 100644
--- a/pacts/forumclient-forumserver.json
+++ b/pacts/forumclient-forumserver.json
@@ -1,983 +1,972 @@
{
- "consumer": {
- "name": "ForumClient"
- },
- "provider": {
- "name": "ForumServer"
- },
- "interactions": [
- {
- "description": "a request to list the forums",
- "providerState": "there's data",
- "request": {
- "method": "POST",
- "path": "/graphql",
- "headers": {
- "content-type": "application/json"
- },
- "body": {
- "operationName": "GetForums",
- "query": "query GetForums {\n forums {\n id\n glyph\n label\n position\n __typename\n }\n }",
- "variables": {
- }
- },
- "matchingRules": {
- "$.body.query": {
- "match": "regex",
- "regex": "query\\s*GetForums\\s*\\{\\s*forums\\s*\\{\\s*id\\s*glyph\\s*label\\s*position\\s*__typename\\s*\\}\\s*\\}"
- }
- }
- },
- "response": {
- "status": 200,
- "headers": {
- "Content-Type": "application/json; charset=utf-8"
- },
- "body": {
- "data": {
- "forums": [
- {
- "id": "butter",
- "glyph": "â",
- "label": "test_forums.butter",
- "position": 1
- }
- ]
- }
- },
- "matchingRules": {
- "$.body.data.forums": {
- "min": 1
- },
- "$.body.data.forums[*].*": {
- "match": "type"
- },
- "$.body.data.forums[*].id": {
- "match": "type"
- },
- "$.body.data.forums[*].glyph": {
- "match": "type"
- },
- "$.body.data.forums[*].label": {
- "match": "type"
- },
- "$.body.data.forums[*].position": {
- "match": "type"
- }
- }
- }
- },
- {
- "description": "a request to get a single forum",
- "providerState": "there's data",
- "request": {
- "method": "POST",
- "path": "/graphql",
- "headers": {
- "content-type": "application/json"
- },
- "body": {
- "operationName": "GetForum",
- "query": "query GetForum($id: ID!) {\n forum(id: $id) {\n id\n glyph\n label\n position\n topics {\n id\n title\n updated_at\n ttl\n __typename\n }\n __typename\n }\n }",
- "variables": {
- "id": "freezer"
- }
- },
- "matchingRules": {
- "$.body.query": {
- "match": "regex",
- "regex": "query\\s*GetForum\\(\\$id:\\s*ID!\\)\\s*\\{\\s*forum\\(id:\\s*\\$id\\)\\s*\\{\\s*id\\s*glyph\\s*label\\s*position\\s*topics\\s*\\{\\s*id\\s*title\\s*updated_at\\s*ttl\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*\\}"
- }
- }
- },
- "response": {
- "status": 200,
- "headers": {
- "Content-Type": "application/json; charset=utf-8"
- },
- "body": {
- "data": {
- "forum": {
- "id": "freezer",
- "glyph": "â",
- "label": "test_forums.freezer",
- "position": 3,
- "topics": [
- {
- "id": "629de02c-151a-4db7-bb86-43b2add8a15a",
- "title": "Very pacty topic",
- "updated_at": 1619954611616,
- "ttl": 3601
- }
- ]
- }
- }
- },
- "matchingRules": {
- "$.body.data.forum": {
- "match": "type"
- },
- "$.body.data.forum.glyph": {
- "match": "type"
- },
- "$.body.data.forum.label": {
- "match": "type"
- },
- "$.body.data.forum.position": {
- "match": "type"
- },
- "$.body.data.forum.topics": {
- "min": 1
- },
- "$.body.data.forum.topics[*].*": {
- "match": "type"
- },
- "$.body.data.forum.topics[*].id": {
- "match": "type"
- },
- "$.body.data.forum.topics[*].title": {
- "match": "type"
- },
- "$.body.data.forum.topics[*].updated_at": {
- "match": "type"
- },
- "$.body.data.forum.topics[*].ttl": {
- "match": "type"
- }
- }
- }
- },
- {
- "description": "a request to list the forums",
- "providerState": "there's no data",
- "request": {
- "method": "POST",
- "path": "/graphql",
- "headers": {
- "content-type": "application/json"
- },
- "body": {
- "operationName": "GetForums",
- "query": "query GetForums {\n forums {\n id\n glyph\n label\n position\n __typename\n }\n }",
- "variables": {
- }
- },
- "matchingRules": {
- "$.body.query": {
- "match": "regex",
- "regex": "query\\s*GetForums\\s*\\{\\s*forums\\s*\\{\\s*id\\s*glyph\\s*label\\s*position\\s*__typename\\s*\\}\\s*\\}"
- }
- }
- },
- "response": {
- "status": 200,
- "headers": {
- "Content-Type": "application/json; charset=utf-8"
- },
- "body": {
- "data": {
- "forums": [
-
- ]
- }
- }
- }
- },
- {
- "description": "a request to get a single forum",
- "providerState": "there's no data",
- "request": {
- "method": "POST",
- "path": "/graphql",
- "headers": {
- "content-type": "application/json"
- },
- "body": {
- "operationName": "GetForum",
- "query": "query GetForum($id: ID!) {\n forum(id: $id) {\n id\n glyph\n label\n position\n topics {\n id\n title\n updated_at\n ttl\n __typename\n }\n __typename\n }\n }",
- "variables": {
- "id": "freezer"
- }
- },
- "matchingRules": {
- "$.body.query": {
- "match": "regex",
- "regex": "query\\s*GetForum\\(\\$id:\\s*ID!\\)\\s*\\{\\s*forum\\(id:\\s*\\$id\\)\\s*\\{\\s*id\\s*glyph\\s*label\\s*position\\s*topics\\s*\\{\\s*id\\s*title\\s*updated_at\\s*ttl\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*\\}"
- }
- }
- },
- "response": {
- "status": 200,
- "headers": {
- "Content-Type": "application/json; charset=utf-8"
- },
- "body": {
- "data": {
- "forum": null
- }
- }
- }
- },
- {
- "description": "a request to list the forums",
- "providerState": "there's a server error",
- "request": {
- "method": "POST",
- "path": "/graphql",
- "headers": {
- "content-type": "application/json"
- },
- "body": {
- "operationName": "GetForums",
- "query": "query GetForums {\n forums {\n id\n glyph\n label\n position\n __typename\n }\n }",
- "variables": {
- }
- },
- "matchingRules": {
- "$.body.query": {
- "match": "regex",
- "regex": "query\\s*GetForums\\s*\\{\\s*forums\\s*\\{\\s*id\\s*glyph\\s*label\\s*position\\s*__typename\\s*\\}\\s*\\}"
- }
- }
- },
- "response": {
- "status": 500,
- "headers": {
- }
- }
- },
- {
- "description": "a request to get a single forum",
- "providerState": "there's a server error",
- "request": {
- "method": "POST",
- "path": "/graphql",
- "headers": {
- "content-type": "application/json"
- },
- "body": {
- "operationName": "GetForum",
- "query": "query GetForum($id: ID!) {\n forum(id: $id) {\n id\n glyph\n label\n position\n topics {\n id\n title\n updated_at\n ttl\n __typename\n }\n __typename\n }\n }",
- "variables": {
- "id": "freezer"
- }
- },
- "matchingRules": {
- "$.body.query": {
- "match": "regex",
- "regex": "query\\s*GetForum\\(\\$id:\\s*ID!\\)\\s*\\{\\s*forum\\(id:\\s*\\$id\\)\\s*\\{\\s*id\\s*glyph\\s*label\\s*position\\s*topics\\s*\\{\\s*id\\s*title\\s*updated_at\\s*ttl\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*\\}"
- }
- }
- },
- "response": {
- "status": 500,
- "headers": {
- }
- }
- },
- {
- "description": "a request to list the forums",
- "providerState": "there's an error in the response",
- "request": {
- "method": "POST",
- "path": "/graphql",
- "headers": {
- "content-type": "application/json"
- },
- "body": {
- "operationName": "GetForums",
- "query": "query GetForums {\n forums {\n id\n glyph\n label\n position\n __typename\n }\n }",
- "variables": {
- }
- },
- "matchingRules": {
- "$.body.query": {
- "match": "regex",
- "regex": "query\\s*GetForums\\s*\\{\\s*forums\\s*\\{\\s*id\\s*glyph\\s*label\\s*position\\s*__typename\\s*\\}\\s*\\}"
- }
- }
- },
- "response": {
- "status": 200,
- "headers": {
- "Content-Type": "application/json; charset=utf-8"
- },
- "body": {
- "errors": [
- {
- "message": "An error occurred when fetching forums"
- }
- ]
- },
- "matchingRules": {
- "$.body.errors": {
- "min": 1
- },
- "$.body.errors[*].*": {
- "match": "type"
- },
- "$.body.errors[*].message": {
- "match": "type"
- }
- }
- }
- },
- {
- "description": "a request to get a single forum",
- "providerState": "there's an error in the response",
- "request": {
- "method": "POST",
- "path": "/graphql",
- "headers": {
- "content-type": "application/json"
- },
- "body": {
- "operationName": "GetForum",
- "query": "query GetForum($id: ID!) {\n forum(id: $id) {\n id\n glyph\n label\n position\n topics {\n id\n title\n updated_at\n ttl\n __typename\n }\n __typename\n }\n }",
- "variables": {
- "id": "freezer"
- }
- },
- "matchingRules": {
- "$.body.query": {
- "match": "regex",
- "regex": "query\\s*GetForum\\(\\$id:\\s*ID!\\)\\s*\\{\\s*forum\\(id:\\s*\\$id\\)\\s*\\{\\s*id\\s*glyph\\s*label\\s*position\\s*topics\\s*\\{\\s*id\\s*title\\s*updated_at\\s*ttl\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*\\}"
- }
- }
- },
- "response": {
- "status": 200,
- "headers": {
- "Content-Type": "application/json; charset=utf-8"
- },
- "body": {
- "errors": [
- {
- "message": "An error occurred when fetching the forum"
- }
- ]
- },
- "matchingRules": {
- "$.body.errors": {
- "min": 1
- },
- "$.body.errors[*].*": {
- "match": "type"
- },
- "$.body.errors[*].message": {
- "match": "type"
- }
- }
- }
- },
- {
- "description": "a request to get a single topic",
- "providerState": "there's data",
- "request": {
- "method": "POST",
- "path": "/graphql",
- "headers": {
- "content-type": "application/json"
- },
- "body": {
- "operationName": "GetTopic",
- "query": "query GetTopic($id: ID!) {\n topic(id: $id) {\n id\n title\n updated_at\n ttl\n forum {\n id\n glyph\n label\n __typename\n }\n tags {\n id\n weight\n __typename\n }\n posts {\n id\n text\n created_at\n author {\n id\n handle\n __typename\n }\n __typename\n }\n __typename\n }\n }",
- "variables": {
- "id": "0b58959d-d448-4a4e-84b6-35e5ac0028d1"
- }
- },
- "matchingRules": {
- "$.body.query": {
- "match": "regex",
- "regex": "query\\s*GetTopic\\(\\$id:\\s*ID!\\)\\s*\\{\\s*topic\\(id:\\s*\\$id\\)\\s*\\{\\s*id\\s*title\\s*updated_at\\s*ttl\\s*forum\\s*\\{\\s*id\\s*glyph\\s*label\\s*__typename\\s*\\}\\s*tags\\s*\\{\\s*id\\s*weight\\s*__typename\\s*\\}\\s*posts\\s*\\{\\s*id\\s*text\\s*created_at\\s*author\\s*\\{\\s*id\\s*handle\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*\\}"
- }
- }
- },
- "response": {
- "status": 200,
- "headers": {
- "Content-Type": "application/json; charset=utf-8"
- },
- "body": {
- "data": {
- "topic": {
- "id": "0b58959d-d448-4a4e-84b6-35e5ac0028d1",
- "title": "The pacty topic of the day",
- "updated_at": 1619979888906,
- "ttl": 3399,
- "forum": {
- "id": "cucumber",
- "glyph": "â½",
- "label": "test_forums.cucumber"
- },
- "tags": [
- {
- "id": "skunk",
- "weight": 44
- }
- ],
- "posts": [
- {
- "id": "ed93530e-6f9c-4701-91ef-14f9e0ed3e26",
- "text": "The content of this post is very relevant",
- "created_at": 1619979889798,
- "author": {
- "id": "07fb2ba0-0945-464a-b215-873296710c8c",
- "handle": "cucumber_fan92"
- }
- }
- ]
- }
- }
- },
- "matchingRules": {
- "$.body.data.topic.id": {
- "match": "type"
- },
- "$.body.data.topic.title": {
- "match": "type"
- },
- "$.body.data.topic.updated_at": {
- "match": "type"
- },
- "$.body.data.topic.ttl": {
- "match": "type"
- },
- "$.body.data.topic.forum.id": {
- "match": "type"
- },
- "$.body.data.topic.forum.glyph": {
- "match": "type"
- },
- "$.body.data.topic.forum.label": {
- "match": "type"
- },
- "$.body.data.topic.tags": {
- "min": 1
- },
- "$.body.data.topic.tags[*].*": {
- "match": "type"
- },
- "$.body.data.topic.tags[*].id": {
- "match": "type"
- },
- "$.body.data.topic.tags[*].weight": {
- "match": "type"
- },
- "$.body.data.topic.posts": {
- "min": 1
- },
- "$.body.data.topic.posts[*].*": {
- "match": "type"
- },
- "$.body.data.topic.posts[*].id": {
- "match": "type"
- },
- "$.body.data.topic.posts[*].text": {
- "match": "type"
- },
- "$.body.data.topic.posts[*].created_at": {
- "match": "type"
- },
- "$.body.data.topic.posts[*].author": {
- "match": "type"
- },
- "$.body.data.topic.posts[*].author.id": {
- "match": "type"
- },
- "$.body.data.topic.posts[*].author.handle": {
- "match": "type"
- }
- }
- }
- },
- {
- "description": "a request to get a single topic",
- "providerState": "there's no data",
- "request": {
- "method": "POST",
- "path": "/graphql",
- "headers": {
- "content-type": "application/json"
- },
- "body": {
- "operationName": "GetTopic",
- "query": "query GetTopic($id: ID!) {\n topic(id: $id) {\n id\n title\n updated_at\n ttl\n forum {\n id\n glyph\n label\n __typename\n }\n tags {\n id\n weight\n __typename\n }\n posts {\n id\n text\n created_at\n author {\n id\n handle\n __typename\n }\n __typename\n }\n __typename\n }\n }",
- "variables": {
- "id": "0b58959d-d448-4a4e-84b6-35e5ac0028d1"
- }
- },
- "matchingRules": {
- "$.body.query": {
- "match": "regex",
- "regex": "query\\s*GetTopic\\(\\$id:\\s*ID!\\)\\s*\\{\\s*topic\\(id:\\s*\\$id\\)\\s*\\{\\s*id\\s*title\\s*updated_at\\s*ttl\\s*forum\\s*\\{\\s*id\\s*glyph\\s*label\\s*__typename\\s*\\}\\s*tags\\s*\\{\\s*id\\s*weight\\s*__typename\\s*\\}\\s*posts\\s*\\{\\s*id\\s*text\\s*created_at\\s*author\\s*\\{\\s*id\\s*handle\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*\\}"
- }
- }
- },
- "response": {
- "status": 200,
- "headers": {
- "Content-Type": "application/json; charset=utf-8"
- },
- "body": {
- "data": {
- "topic": null
- }
- }
- }
- },
- {
- "description": "a request to get a single topic",
- "providerState": "there's a server error",
- "request": {
- "method": "POST",
- "path": "/graphql",
- "headers": {
- "content-type": "application/json"
- },
- "body": {
- "operationName": "GetTopic",
- "query": "query GetTopic($id: ID!) {\n topic(id: $id) {\n id\n title\n updated_at\n ttl\n forum {\n id\n glyph\n label\n __typename\n }\n tags {\n id\n weight\n __typename\n }\n posts {\n id\n text\n created_at\n author {\n id\n handle\n __typename\n }\n __typename\n }\n __typename\n }\n }",
- "variables": {
- "id": "0b58959d-d448-4a4e-84b6-35e5ac0028d1"
- }
- },
- "matchingRules": {
- "$.body.query": {
- "match": "regex",
- "regex": "query\\s*GetTopic\\(\\$id:\\s*ID!\\)\\s*\\{\\s*topic\\(id:\\s*\\$id\\)\\s*\\{\\s*id\\s*title\\s*updated_at\\s*ttl\\s*forum\\s*\\{\\s*id\\s*glyph\\s*label\\s*__typename\\s*\\}\\s*tags\\s*\\{\\s*id\\s*weight\\s*__typename\\s*\\}\\s*posts\\s*\\{\\s*id\\s*text\\s*created_at\\s*author\\s*\\{\\s*id\\s*handle\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*\\}"
- }
- }
- },
- "response": {
- "status": 500,
- "headers": {
- }
- }
- },
- {
- "description": "a request to get a single topic",
- "providerState": "there's an error in the response",
- "request": {
- "method": "POST",
- "path": "/graphql",
- "headers": {
- "content-type": "application/json"
- },
- "body": {
- "operationName": "GetTopic",
- "query": "query GetTopic($id: ID!) {\n topic(id: $id) {\n id\n title\n updated_at\n ttl\n forum {\n id\n glyph\n label\n __typename\n }\n tags {\n id\n weight\n __typename\n }\n posts {\n id\n text\n created_at\n author {\n id\n handle\n __typename\n }\n __typename\n }\n __typename\n }\n }",
- "variables": {
- "id": "0b58959d-d448-4a4e-84b6-35e5ac0028d1"
- }
- },
- "matchingRules": {
- "$.body.query": {
- "match": "regex",
- "regex": "query\\s*GetTopic\\(\\$id:\\s*ID!\\)\\s*\\{\\s*topic\\(id:\\s*\\$id\\)\\s*\\{\\s*id\\s*title\\s*updated_at\\s*ttl\\s*forum\\s*\\{\\s*id\\s*glyph\\s*label\\s*__typename\\s*\\}\\s*tags\\s*\\{\\s*id\\s*weight\\s*__typename\\s*\\}\\s*posts\\s*\\{\\s*id\\s*text\\s*created_at\\s*author\\s*\\{\\s*id\\s*handle\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*\\}"
- }
- }
- },
- "response": {
- "status": 200,
- "headers": {
- "Content-Type": "application/json; charset=utf-8"
- },
- "body": {
- "errors": [
- {
- "message": "An error occurred when fetching the topic"
- }
- ]
- },
- "matchingRules": {
- "$.body.errors": {
- "min": 1
- },
- "$.body.errors[*].*": {
- "match": "type"
- },
- "$.body.errors[*].message": {
- "match": "type"
- }
- }
- }
- },
- {
- "description": "a request to get a single tag",
- "providerState": "there's data",
- "request": {
- "method": "POST",
- "path": "/graphql",
- "headers": {
- "content-type": "application/json"
- },
- "body": {
- "operationName": "GetTag",
- "query": "query GetTag($id: ID!) {\n tag(id: $id) {\n id\n topics {\n id\n title\n updated_at\n ttl\n __typename\n }\n __typename\n }\n }",
- "variables": {
- "id": "pineapple"
- }
- },
- "matchingRules": {
- "$.body.query": {
- "match": "regex",
- "regex": "query\\s*GetTag\\(\\$id:\\s*ID!\\)\\s*\\{\\s*tag\\(id:\\s*\\$id\\)\\s*\\{\\s*id\\s*topics\\s*\\{\\s*id\\s*title\\s*updated_at\\s*ttl\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*\\}"
- }
- }
- },
- "response": {
- "status": 200,
- "headers": {
- "Content-Type": "application/json; charset=utf-8"
- },
- "body": {
- "data": {
- "tag": {
- "id": "pineapple",
- "topics": [
- {
- "id": "cd038ae7-e8b4-4e38-9543-3d697e69ac34",
- "title": "This topic is about pineapples",
- "updated_at": 1619978944077,
- "ttl": 3555
- }
- ]
- }
- }
- },
- "matchingRules": {
- "$.body.data.tag.id": {
- "match": "type"
- },
- "$.body.data.tag.topics": {
- "min": 1
- },
- "$.body.data.tag.topics[*].*": {
- "match": "type"
- },
- "$.body.data.tag.topics[*].id": {
- "match": "type"
- },
- "$.body.data.tag.topics[*].title": {
- "match": "type"
- },
- "$.body.data.tag.topics[*].updated_at": {
- "match": "type"
- },
- "$.body.data.tag.topics[*].ttl": {
- "match": "type"
- }
- }
- }
- },
- {
- "description": "a request to get a single tag",
- "providerState": "there's no data",
- "request": {
- "method": "POST",
- "path": "/graphql",
- "headers": {
- "content-type": "application/json"
- },
- "body": {
- "operationName": "GetTag",
- "query": "query GetTag($id: ID!) {\n tag(id: $id) {\n id\n topics {\n id\n title\n updated_at\n ttl\n __typename\n }\n __typename\n }\n }",
- "variables": {
- "id": "pineapple"
- }
- },
- "matchingRules": {
- "$.body.query": {
- "match": "regex",
- "regex": "query\\s*GetTag\\(\\$id:\\s*ID!\\)\\s*\\{\\s*tag\\(id:\\s*\\$id\\)\\s*\\{\\s*id\\s*topics\\s*\\{\\s*id\\s*title\\s*updated_at\\s*ttl\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*\\}"
- }
- }
- },
- "response": {
- "status": 200,
- "headers": {
- "Content-Type": "application/json; charset=utf-8"
- },
- "body": {
- "data": {
- "tag": null
- }
- }
- }
- },
- {
- "description": "a request to get a single tag",
- "providerState": "there's a server error",
- "request": {
- "method": "POST",
- "path": "/graphql",
- "headers": {
- "content-type": "application/json"
- },
- "body": {
- "operationName": "GetTag",
- "query": "query GetTag($id: ID!) {\n tag(id: $id) {\n id\n topics {\n id\n title\n updated_at\n ttl\n __typename\n }\n __typename\n }\n }",
- "variables": {
- "id": "pineapple"
- }
- },
- "matchingRules": {
- "$.body.query": {
- "match": "regex",
- "regex": "query\\s*GetTag\\(\\$id:\\s*ID!\\)\\s*\\{\\s*tag\\(id:\\s*\\$id\\)\\s*\\{\\s*id\\s*topics\\s*\\{\\s*id\\s*title\\s*updated_at\\s*ttl\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*\\}"
- }
- }
- },
- "response": {
- "status": 500,
- "headers": {
- }
- }
- },
- {
- "description": "a request to get a single tag",
- "providerState": "there's an error in the response",
- "request": {
- "method": "POST",
- "path": "/graphql",
- "headers": {
- "content-type": "application/json"
- },
- "body": {
- "operationName": "GetTag",
- "query": "query GetTag($id: ID!) {\n tag(id: $id) {\n id\n topics {\n id\n title\n updated_at\n ttl\n __typename\n }\n __typename\n }\n }",
- "variables": {
- "id": "pineapple"
- }
- },
- "matchingRules": {
- "$.body.query": {
- "match": "regex",
- "regex": "query\\s*GetTag\\(\\$id:\\s*ID!\\)\\s*\\{\\s*tag\\(id:\\s*\\$id\\)\\s*\\{\\s*id\\s*topics\\s*\\{\\s*id\\s*title\\s*updated_at\\s*ttl\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*\\}"
- }
- }
- },
- "response": {
- "status": 200,
- "headers": {
- "Content-Type": "application/json; charset=utf-8"
- },
- "body": {
- "errors": [
- {
- "message": "An error occurred when fetching the tag"
- }
- ]
- },
- "matchingRules": {
- "$.body.errors": {
- "min": 1
- },
- "$.body.errors[*].*": {
- "match": "type"
- },
- "$.body.errors[*].message": {
- "match": "type"
- }
- }
- }
- },
- {
- "description": "a request to get a single post",
- "providerState": "there's data",
- "request": {
- "method": "POST",
- "path": "/graphql",
- "headers": {
- "content-type": "application/json"
- },
- "body": {
- "operationName": "GetPost",
- "query": "query GetPost($id: ID!) {\n post(id: $id) {\n id\n text\n created_at\n author {\n id\n handle\n __typename\n }\n topic {\n id\n title\n __typename\n }\n __typename\n }\n }",
- "variables": {
- "id": "8f75eba5-6989-4dd3-b466-e464546ce374"
- }
- },
- "matchingRules": {
- "$.body.query": {
- "match": "regex",
- "regex": "query\\s*GetPost\\(\\$id:\\s*ID!\\)\\s*\\{\\s*post\\(id:\\s*\\$id\\)\\s*\\{\\s*id\\s*text\\s*created_at\\s*author\\s*\\{\\s*id\\s*handle\\s*__typename\\s*\\}\\s*topic\\s*\\{\\s*id\\s*title\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*\\}"
- }
- }
- },
- "response": {
- "status": 200,
- "headers": {
- "Content-Type": "application/json; charset=utf-8"
- },
- "body": {
- "data": {
- "post": {
- "id": "8f75eba5-6989-4dd3-b466-e464546ce374",
- "text": "This is a very pacty post",
- "created_at": 1619976194937,
- "author": {
- "id": "a805b3de-cac4-451c-a1e6-f078869c9db9",
- "handle": "pacts_person"
- },
- "topic": {
- "id": "5c283ce1-0470-4b98-86f5-1fec9a22c9ac",
- "title": "The parent pacts topic"
- }
- }
- }
- },
- "matchingRules": {
- "$.body.data.post": {
- "match": "type"
- },
- "$.body.data.post.id": {
- "match": "type"
- },
- "$.body.data.post.text": {
- "match": "type"
- },
- "$.body.data.post.created_at": {
- "match": "type"
- },
- "$.body.data.post.author": {
- "match": "type"
- },
- "$.body.data.post.author.id": {
- "match": "type"
- },
- "$.body.data.post.author.handle": {
- "match": "type"
- },
- "$.body.data.post.topic": {
- "match": "type"
- },
- "$.body.data.post.topic.id": {
- "match": "type"
- },
- "$.body.data.post.topic.title": {
- "match": "type"
- }
- }
- }
- },
- {
- "description": "a request to get a single post",
- "providerState": "there's no data",
- "request": {
- "method": "POST",
- "path": "/graphql",
- "headers": {
- "content-type": "application/json"
- },
- "body": {
- "operationName": "GetPost",
- "query": "query GetPost($id: ID!) {\n post(id: $id) {\n id\n text\n created_at\n author {\n id\n handle\n __typename\n }\n topic {\n id\n title\n __typename\n }\n __typename\n }\n }",
- "variables": {
- "id": "8f75eba5-6989-4dd3-b466-e464546ce374"
- }
- },
- "matchingRules": {
- "$.body.query": {
- "match": "regex",
- "regex": "query\\s*GetPost\\(\\$id:\\s*ID!\\)\\s*\\{\\s*post\\(id:\\s*\\$id\\)\\s*\\{\\s*id\\s*text\\s*created_at\\s*author\\s*\\{\\s*id\\s*handle\\s*__typename\\s*\\}\\s*topic\\s*\\{\\s*id\\s*title\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*\\}"
- }
- }
- },
- "response": {
- "status": 200,
- "headers": {
- "Content-Type": "application/json; charset=utf-8"
- },
- "body": {
- "data": {
- "post": null
- }
- }
- }
- },
- {
- "description": "a request to get a single post",
- "providerState": "there's a server error",
- "request": {
- "method": "POST",
- "path": "/graphql",
- "headers": {
- "content-type": "application/json"
- },
- "body": {
- "operationName": "GetPost",
- "query": "query GetPost($id: ID!) {\n post(id: $id) {\n id\n text\n created_at\n author {\n id\n handle\n __typename\n }\n topic {\n id\n title\n __typename\n }\n __typename\n }\n }",
- "variables": {
- "id": "8f75eba5-6989-4dd3-b466-e464546ce374"
- }
- },
- "matchingRules": {
- "$.body.query": {
- "match": "regex",
- "regex": "query\\s*GetPost\\(\\$id:\\s*ID!\\)\\s*\\{\\s*post\\(id:\\s*\\$id\\)\\s*\\{\\s*id\\s*text\\s*created_at\\s*author\\s*\\{\\s*id\\s*handle\\s*__typename\\s*\\}\\s*topic\\s*\\{\\s*id\\s*title\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*\\}"
- }
- }
- },
- "response": {
- "status": 500,
- "headers": {
- }
- }
- },
- {
- "description": "a request to get a single post",
- "providerState": "there's an error in the response",
- "request": {
- "method": "POST",
- "path": "/graphql",
- "headers": {
- "content-type": "application/json"
- },
- "body": {
- "operationName": "GetPost",
- "query": "query GetPost($id: ID!) {\n post(id: $id) {\n id\n text\n created_at\n author {\n id\n handle\n __typename\n }\n topic {\n id\n title\n __typename\n }\n __typename\n }\n }",
- "variables": {
- "id": "8f75eba5-6989-4dd3-b466-e464546ce374"
- }
- },
- "matchingRules": {
- "$.body.query": {
- "match": "regex",
- "regex": "query\\s*GetPost\\(\\$id:\\s*ID!\\)\\s*\\{\\s*post\\(id:\\s*\\$id\\)\\s*\\{\\s*id\\s*text\\s*created_at\\s*author\\s*\\{\\s*id\\s*handle\\s*__typename\\s*\\}\\s*topic\\s*\\{\\s*id\\s*title\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*\\}"
- }
- }
- },
- "response": {
- "status": 200,
- "headers": {
- "Content-Type": "application/json; charset=utf-8"
- },
- "body": {
- "errors": [
- {
- "message": "An error occurred when fetching the post"
- }
- ]
- },
- "matchingRules": {
- "$.body.errors": {
- "min": 1
- },
- "$.body.errors[*].*": {
- "match": "type"
- },
- "$.body.errors[*].message": {
- "match": "type"
- }
- }
- }
- }
- ],
- "metadata": {
- "pactSpecification": {
- "version": "2.0.0"
- }
- }
-}
\ No newline at end of file
+ "consumer": {
+ "name": "ForumClient"
+ },
+ "provider": {
+ "name": "ForumServer"
+ },
+ "interactions": [
+ {
+ "description": "a request to list the forums",
+ "providerState": "there's data",
+ "request": {
+ "method": "POST",
+ "path": "/graphql",
+ "headers": {
+ "content-type": "application/json"
+ },
+ "body": {
+ "operationName": "GetForums",
+ "query": "query GetForums {\n forums {\n id\n glyph\n label\n position\n __typename\n }\n }",
+ "variables": {}
+ },
+ "matchingRules": {
+ "$.body.query": {
+ "match": "regex",
+ "regex": "query\\s*GetForums\\s*\\{\\s*forums\\s*\\{\\s*id\\s*glyph\\s*label\\s*position\\s*__typename\\s*\\}\\s*\\}"
+ }
+ }
+ },
+ "response": {
+ "status": 200,
+ "headers": {
+ "Content-Type": "application/json; charset=utf-8"
+ },
+ "body": {
+ "data": {
+ "forums": [
+ {
+ "id": "butter",
+ "glyph": "â",
+ "label": "test_forums.butter",
+ "position": 1
+ }
+ ]
+ }
+ },
+ "matchingRules": {
+ "$.body.data.forums": {
+ "min": 1
+ },
+ "$.body.data.forums[*].*": {
+ "match": "type"
+ },
+ "$.body.data.forums[*].id": {
+ "match": "type"
+ },
+ "$.body.data.forums[*].glyph": {
+ "match": "type"
+ },
+ "$.body.data.forums[*].label": {
+ "match": "type"
+ },
+ "$.body.data.forums[*].position": {
+ "match": "type"
+ }
+ }
+ }
+ },
+ {
+ "description": "a request to get a single forum",
+ "providerState": "there's data",
+ "request": {
+ "method": "POST",
+ "path": "/graphql",
+ "headers": {
+ "content-type": "application/json"
+ },
+ "body": {
+ "operationName": "GetForum",
+ "query": "query GetForum($id: ID!) {\n forum(id: $id) {\n id\n glyph\n label\n position\n topics {\n id\n title\n updated_at\n ttl\n __typename\n }\n __typename\n }\n }",
+ "variables": {
+ "id": "freezer"
+ }
+ },
+ "matchingRules": {
+ "$.body.query": {
+ "match": "regex",
+ "regex": "query\\s*GetForum\\(\\$id:\\s*ID!\\)\\s*\\{\\s*forum\\(id:\\s*\\$id\\)\\s*\\{\\s*id\\s*glyph\\s*label\\s*position\\s*topics\\s*\\{\\s*id\\s*title\\s*updated_at\\s*ttl\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*\\}"
+ }
+ }
+ },
+ "response": {
+ "status": 200,
+ "headers": {
+ "Content-Type": "application/json; charset=utf-8"
+ },
+ "body": {
+ "data": {
+ "forum": {
+ "id": "freezer",
+ "glyph": "â",
+ "label": "test_forums.freezer",
+ "position": 3,
+ "topics": [
+ {
+ "id": "629de02c-151a-4db7-bb86-43b2add8a15a",
+ "title": "Very pacty topic",
+ "updated_at": 1619954611616,
+ "ttl": 3601
+ }
+ ]
+ }
+ }
+ },
+ "matchingRules": {
+ "$.body.data.forum": {
+ "match": "type"
+ },
+ "$.body.data.forum.glyph": {
+ "match": "type"
+ },
+ "$.body.data.forum.label": {
+ "match": "type"
+ },
+ "$.body.data.forum.position": {
+ "match": "type"
+ },
+ "$.body.data.forum.topics": {
+ "min": 1
+ },
+ "$.body.data.forum.topics[*].*": {
+ "match": "type"
+ },
+ "$.body.data.forum.topics[*].id": {
+ "match": "type"
+ },
+ "$.body.data.forum.topics[*].title": {
+ "match": "type"
+ },
+ "$.body.data.forum.topics[*].updated_at": {
+ "match": "type"
+ },
+ "$.body.data.forum.topics[*].ttl": {
+ "match": "type"
+ }
+ }
+ }
+ },
+ {
+ "description": "a request to list the forums",
+ "providerState": "there's no data",
+ "request": {
+ "method": "POST",
+ "path": "/graphql",
+ "headers": {
+ "content-type": "application/json"
+ },
+ "body": {
+ "operationName": "GetForums",
+ "query": "query GetForums {\n forums {\n id\n glyph\n label\n position\n __typename\n }\n }",
+ "variables": {}
+ },
+ "matchingRules": {
+ "$.body.query": {
+ "match": "regex",
+ "regex": "query\\s*GetForums\\s*\\{\\s*forums\\s*\\{\\s*id\\s*glyph\\s*label\\s*position\\s*__typename\\s*\\}\\s*\\}"
+ }
+ }
+ },
+ "response": {
+ "status": 200,
+ "headers": {
+ "Content-Type": "application/json; charset=utf-8"
+ },
+ "body": {
+ "data": {
+ "forums": []
+ }
+ }
+ }
+ },
+ {
+ "description": "a request to get a single forum",
+ "providerState": "there's no data",
+ "request": {
+ "method": "POST",
+ "path": "/graphql",
+ "headers": {
+ "content-type": "application/json"
+ },
+ "body": {
+ "operationName": "GetForum",
+ "query": "query GetForum($id: ID!) {\n forum(id: $id) {\n id\n glyph\n label\n position\n topics {\n id\n title\n updated_at\n ttl\n __typename\n }\n __typename\n }\n }",
+ "variables": {
+ "id": "freezer"
+ }
+ },
+ "matchingRules": {
+ "$.body.query": {
+ "match": "regex",
+ "regex": "query\\s*GetForum\\(\\$id:\\s*ID!\\)\\s*\\{\\s*forum\\(id:\\s*\\$id\\)\\s*\\{\\s*id\\s*glyph\\s*label\\s*position\\s*topics\\s*\\{\\s*id\\s*title\\s*updated_at\\s*ttl\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*\\}"
+ }
+ }
+ },
+ "response": {
+ "status": 200,
+ "headers": {
+ "Content-Type": "application/json; charset=utf-8"
+ },
+ "body": {
+ "data": {
+ "forum": null
+ }
+ }
+ }
+ },
+ {
+ "description": "a request to list the forums",
+ "providerState": "there's a server error",
+ "request": {
+ "method": "POST",
+ "path": "/graphql",
+ "headers": {
+ "content-type": "application/json"
+ },
+ "body": {
+ "operationName": "GetForums",
+ "query": "query GetForums {\n forums {\n id\n glyph\n label\n position\n __typename\n }\n }",
+ "variables": {}
+ },
+ "matchingRules": {
+ "$.body.query": {
+ "match": "regex",
+ "regex": "query\\s*GetForums\\s*\\{\\s*forums\\s*\\{\\s*id\\s*glyph\\s*label\\s*position\\s*__typename\\s*\\}\\s*\\}"
+ }
+ }
+ },
+ "response": {
+ "status": 500,
+ "headers": {}
+ }
+ },
+ {
+ "description": "a request to get a single forum",
+ "providerState": "there's a server error",
+ "request": {
+ "method": "POST",
+ "path": "/graphql",
+ "headers": {
+ "content-type": "application/json"
+ },
+ "body": {
+ "operationName": "GetForum",
+ "query": "query GetForum($id: ID!) {\n forum(id: $id) {\n id\n glyph\n label\n position\n topics {\n id\n title\n updated_at\n ttl\n __typename\n }\n __typename\n }\n }",
+ "variables": {
+ "id": "freezer"
+ }
+ },
+ "matchingRules": {
+ "$.body.query": {
+ "match": "regex",
+ "regex": "query\\s*GetForum\\(\\$id:\\s*ID!\\)\\s*\\{\\s*forum\\(id:\\s*\\$id\\)\\s*\\{\\s*id\\s*glyph\\s*label\\s*position\\s*topics\\s*\\{\\s*id\\s*title\\s*updated_at\\s*ttl\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*\\}"
+ }
+ }
+ },
+ "response": {
+ "status": 500,
+ "headers": {}
+ }
+ },
+ {
+ "description": "a request to list the forums",
+ "providerState": "there's an error in the response",
+ "request": {
+ "method": "POST",
+ "path": "/graphql",
+ "headers": {
+ "content-type": "application/json"
+ },
+ "body": {
+ "operationName": "GetForums",
+ "query": "query GetForums {\n forums {\n id\n glyph\n label\n position\n __typename\n }\n }",
+ "variables": {}
+ },
+ "matchingRules": {
+ "$.body.query": {
+ "match": "regex",
+ "regex": "query\\s*GetForums\\s*\\{\\s*forums\\s*\\{\\s*id\\s*glyph\\s*label\\s*position\\s*__typename\\s*\\}\\s*\\}"
+ }
+ }
+ },
+ "response": {
+ "status": 200,
+ "headers": {
+ "Content-Type": "application/json; charset=utf-8"
+ },
+ "body": {
+ "errors": [
+ {
+ "message": "An error occurred when fetching forums"
+ }
+ ]
+ },
+ "matchingRules": {
+ "$.body.errors": {
+ "min": 1
+ },
+ "$.body.errors[*].*": {
+ "match": "type"
+ },
+ "$.body.errors[*].message": {
+ "match": "type"
+ }
+ }
+ }
+ },
+ {
+ "description": "a request to get a single forum",
+ "providerState": "there's an error in the response",
+ "request": {
+ "method": "POST",
+ "path": "/graphql",
+ "headers": {
+ "content-type": "application/json"
+ },
+ "body": {
+ "operationName": "GetForum",
+ "query": "query GetForum($id: ID!) {\n forum(id: $id) {\n id\n glyph\n label\n position\n topics {\n id\n title\n updated_at\n ttl\n __typename\n }\n __typename\n }\n }",
+ "variables": {
+ "id": "freezer"
+ }
+ },
+ "matchingRules": {
+ "$.body.query": {
+ "match": "regex",
+ "regex": "query\\s*GetForum\\(\\$id:\\s*ID!\\)\\s*\\{\\s*forum\\(id:\\s*\\$id\\)\\s*\\{\\s*id\\s*glyph\\s*label\\s*position\\s*topics\\s*\\{\\s*id\\s*title\\s*updated_at\\s*ttl\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*\\}"
+ }
+ }
+ },
+ "response": {
+ "status": 200,
+ "headers": {
+ "Content-Type": "application/json; charset=utf-8"
+ },
+ "body": {
+ "errors": [
+ {
+ "message": "An error occurred when fetching the forum"
+ }
+ ]
+ },
+ "matchingRules": {
+ "$.body.errors": {
+ "min": 1
+ },
+ "$.body.errors[*].*": {
+ "match": "type"
+ },
+ "$.body.errors[*].message": {
+ "match": "type"
+ }
+ }
+ }
+ },
+ {
+ "description": "a request to get a single topic",
+ "providerState": "there's data",
+ "request": {
+ "method": "POST",
+ "path": "/graphql",
+ "headers": {
+ "content-type": "application/json"
+ },
+ "body": {
+ "operationName": "GetTopic",
+ "query": "query GetTopic($id: ID!) {\n topic(id: $id) {\n id\n title\n updated_at\n ttl\n forum {\n id\n glyph\n label\n __typename\n }\n tags {\n id\n weight\n __typename\n }\n posts {\n id\n text\n created_at\n author {\n id\n handle\n __typename\n }\n __typename\n }\n __typename\n }\n }",
+ "variables": {
+ "id": "0b58959d-d448-4a4e-84b6-35e5ac0028d1"
+ }
+ },
+ "matchingRules": {
+ "$.body.query": {
+ "match": "regex",
+ "regex": "query\\s*GetTopic\\(\\$id:\\s*ID!\\)\\s*\\{\\s*topic\\(id:\\s*\\$id\\)\\s*\\{\\s*id\\s*title\\s*updated_at\\s*ttl\\s*forum\\s*\\{\\s*id\\s*glyph\\s*label\\s*__typename\\s*\\}\\s*tags\\s*\\{\\s*id\\s*weight\\s*__typename\\s*\\}\\s*posts\\s*\\{\\s*id\\s*text\\s*created_at\\s*author\\s*\\{\\s*id\\s*handle\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*\\}"
+ }
+ }
+ },
+ "response": {
+ "status": 200,
+ "headers": {
+ "Content-Type": "application/json; charset=utf-8"
+ },
+ "body": {
+ "data": {
+ "topic": {
+ "id": "0b58959d-d448-4a4e-84b6-35e5ac0028d1",
+ "title": "The pacty topic of the day",
+ "updated_at": 1619979888906,
+ "ttl": 3399,
+ "forum": {
+ "id": "cucumber",
+ "glyph": "â½",
+ "label": "test_forums.cucumber"
+ },
+ "tags": [
+ {
+ "id": "skunk",
+ "weight": 44
+ }
+ ],
+ "posts": [
+ {
+ "id": "ed93530e-6f9c-4701-91ef-14f9e0ed3e26",
+ "text": "The content of this post is very relevant",
+ "created_at": 1619979889798,
+ "author": {
+ "id": "07fb2ba0-0945-464a-b215-873296710c8c",
+ "handle": "cucumber_fan92"
+ }
+ }
+ ]
+ }
+ }
+ },
+ "matchingRules": {
+ "$.body.data.topic.id": {
+ "match": "type"
+ },
+ "$.body.data.topic.title": {
+ "match": "type"
+ },
+ "$.body.data.topic.updated_at": {
+ "match": "type"
+ },
+ "$.body.data.topic.ttl": {
+ "match": "type"
+ },
+ "$.body.data.topic.forum.id": {
+ "match": "type"
+ },
+ "$.body.data.topic.forum.glyph": {
+ "match": "type"
+ },
+ "$.body.data.topic.forum.label": {
+ "match": "type"
+ },
+ "$.body.data.topic.tags": {
+ "min": 1
+ },
+ "$.body.data.topic.tags[*].*": {
+ "match": "type"
+ },
+ "$.body.data.topic.tags[*].id": {
+ "match": "type"
+ },
+ "$.body.data.topic.tags[*].weight": {
+ "match": "type"
+ },
+ "$.body.data.topic.posts": {
+ "min": 1
+ },
+ "$.body.data.topic.posts[*].*": {
+ "match": "type"
+ },
+ "$.body.data.topic.posts[*].id": {
+ "match": "type"
+ },
+ "$.body.data.topic.posts[*].text": {
+ "match": "type"
+ },
+ "$.body.data.topic.posts[*].created_at": {
+ "match": "type"
+ },
+ "$.body.data.topic.posts[*].author": {
+ "match": "type"
+ },
+ "$.body.data.topic.posts[*].author.id": {
+ "match": "type"
+ },
+ "$.body.data.topic.posts[*].author.handle": {
+ "match": "type"
+ }
+ }
+ }
+ },
+ {
+ "description": "a request to get a single topic",
+ "providerState": "there's no data",
+ "request": {
+ "method": "POST",
+ "path": "/graphql",
+ "headers": {
+ "content-type": "application/json"
+ },
+ "body": {
+ "operationName": "GetTopic",
+ "query": "query GetTopic($id: ID!) {\n topic(id: $id) {\n id\n title\n updated_at\n ttl\n forum {\n id\n glyph\n label\n __typename\n }\n tags {\n id\n weight\n __typename\n }\n posts {\n id\n text\n created_at\n author {\n id\n handle\n __typename\n }\n __typename\n }\n __typename\n }\n }",
+ "variables": {
+ "id": "0b58959d-d448-4a4e-84b6-35e5ac0028d1"
+ }
+ },
+ "matchingRules": {
+ "$.body.query": {
+ "match": "regex",
+ "regex": "query\\s*GetTopic\\(\\$id:\\s*ID!\\)\\s*\\{\\s*topic\\(id:\\s*\\$id\\)\\s*\\{\\s*id\\s*title\\s*updated_at\\s*ttl\\s*forum\\s*\\{\\s*id\\s*glyph\\s*label\\s*__typename\\s*\\}\\s*tags\\s*\\{\\s*id\\s*weight\\s*__typename\\s*\\}\\s*posts\\s*\\{\\s*id\\s*text\\s*created_at\\s*author\\s*\\{\\s*id\\s*handle\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*\\}"
+ }
+ }
+ },
+ "response": {
+ "status": 200,
+ "headers": {
+ "Content-Type": "application/json; charset=utf-8"
+ },
+ "body": {
+ "data": {
+ "topic": null
+ }
+ }
+ }
+ },
+ {
+ "description": "a request to get a single topic",
+ "providerState": "there's a server error",
+ "request": {
+ "method": "POST",
+ "path": "/graphql",
+ "headers": {
+ "content-type": "application/json"
+ },
+ "body": {
+ "operationName": "GetTopic",
+ "query": "query GetTopic($id: ID!) {\n topic(id: $id) {\n id\n title\n updated_at\n ttl\n forum {\n id\n glyph\n label\n __typename\n }\n tags {\n id\n weight\n __typename\n }\n posts {\n id\n text\n created_at\n author {\n id\n handle\n __typename\n }\n __typename\n }\n __typename\n }\n }",
+ "variables": {
+ "id": "0b58959d-d448-4a4e-84b6-35e5ac0028d1"
+ }
+ },
+ "matchingRules": {
+ "$.body.query": {
+ "match": "regex",
+ "regex": "query\\s*GetTopic\\(\\$id:\\s*ID!\\)\\s*\\{\\s*topic\\(id:\\s*\\$id\\)\\s*\\{\\s*id\\s*title\\s*updated_at\\s*ttl\\s*forum\\s*\\{\\s*id\\s*glyph\\s*label\\s*__typename\\s*\\}\\s*tags\\s*\\{\\s*id\\s*weight\\s*__typename\\s*\\}\\s*posts\\s*\\{\\s*id\\s*text\\s*created_at\\s*author\\s*\\{\\s*id\\s*handle\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*\\}"
+ }
+ }
+ },
+ "response": {
+ "status": 500,
+ "headers": {}
+ }
+ },
+ {
+ "description": "a request to get a single topic",
+ "providerState": "there's an error in the response",
+ "request": {
+ "method": "POST",
+ "path": "/graphql",
+ "headers": {
+ "content-type": "application/json"
+ },
+ "body": {
+ "operationName": "GetTopic",
+ "query": "query GetTopic($id: ID!) {\n topic(id: $id) {\n id\n title\n updated_at\n ttl\n forum {\n id\n glyph\n label\n __typename\n }\n tags {\n id\n weight\n __typename\n }\n posts {\n id\n text\n created_at\n author {\n id\n handle\n __typename\n }\n __typename\n }\n __typename\n }\n }",
+ "variables": {
+ "id": "0b58959d-d448-4a4e-84b6-35e5ac0028d1"
+ }
+ },
+ "matchingRules": {
+ "$.body.query": {
+ "match": "regex",
+ "regex": "query\\s*GetTopic\\(\\$id:\\s*ID!\\)\\s*\\{\\s*topic\\(id:\\s*\\$id\\)\\s*\\{\\s*id\\s*title\\s*updated_at\\s*ttl\\s*forum\\s*\\{\\s*id\\s*glyph\\s*label\\s*__typename\\s*\\}\\s*tags\\s*\\{\\s*id\\s*weight\\s*__typename\\s*\\}\\s*posts\\s*\\{\\s*id\\s*text\\s*created_at\\s*author\\s*\\{\\s*id\\s*handle\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*\\}"
+ }
+ }
+ },
+ "response": {
+ "status": 200,
+ "headers": {
+ "Content-Type": "application/json; charset=utf-8"
+ },
+ "body": {
+ "errors": [
+ {
+ "message": "An error occurred when fetching the topic"
+ }
+ ]
+ },
+ "matchingRules": {
+ "$.body.errors": {
+ "min": 1
+ },
+ "$.body.errors[*].*": {
+ "match": "type"
+ },
+ "$.body.errors[*].message": {
+ "match": "type"
+ }
+ }
+ }
+ },
+ {
+ "description": "a request to get a single tag",
+ "providerState": "there's data",
+ "request": {
+ "method": "POST",
+ "path": "/graphql",
+ "headers": {
+ "content-type": "application/json"
+ },
+ "body": {
+ "operationName": "GetTag",
+ "query": "query GetTag($id: ID!) {\n tag(id: $id) {\n id\n topics {\n id\n title\n updated_at\n ttl\n __typename\n }\n __typename\n }\n }",
+ "variables": {
+ "id": "pineapple"
+ }
+ },
+ "matchingRules": {
+ "$.body.query": {
+ "match": "regex",
+ "regex": "query\\s*GetTag\\(\\$id:\\s*ID!\\)\\s*\\{\\s*tag\\(id:\\s*\\$id\\)\\s*\\{\\s*id\\s*topics\\s*\\{\\s*id\\s*title\\s*updated_at\\s*ttl\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*\\}"
+ }
+ }
+ },
+ "response": {
+ "status": 200,
+ "headers": {
+ "Content-Type": "application/json; charset=utf-8"
+ },
+ "body": {
+ "data": {
+ "tag": {
+ "id": "pineapple",
+ "topics": [
+ {
+ "id": "cd038ae7-e8b4-4e38-9543-3d697e69ac34",
+ "title": "This topic is about pineapples",
+ "updated_at": 1619978944077,
+ "ttl": 3555
+ }
+ ]
+ }
+ }
+ },
+ "matchingRules": {
+ "$.body.data.tag.id": {
+ "match": "type"
+ },
+ "$.body.data.tag.topics": {
+ "min": 1
+ },
+ "$.body.data.tag.topics[*].*": {
+ "match": "type"
+ },
+ "$.body.data.tag.topics[*].id": {
+ "match": "type"
+ },
+ "$.body.data.tag.topics[*].title": {
+ "match": "type"
+ },
+ "$.body.data.tag.topics[*].updated_at": {
+ "match": "type"
+ },
+ "$.body.data.tag.topics[*].ttl": {
+ "match": "type"
+ }
+ }
+ }
+ },
+ {
+ "description": "a request to get a single tag",
+ "providerState": "there's no data",
+ "request": {
+ "method": "POST",
+ "path": "/graphql",
+ "headers": {
+ "content-type": "application/json"
+ },
+ "body": {
+ "operationName": "GetTag",
+ "query": "query GetTag($id: ID!) {\n tag(id: $id) {\n id\n topics {\n id\n title\n updated_at\n ttl\n __typename\n }\n __typename\n }\n }",
+ "variables": {
+ "id": "pineapple"
+ }
+ },
+ "matchingRules": {
+ "$.body.query": {
+ "match": "regex",
+ "regex": "query\\s*GetTag\\(\\$id:\\s*ID!\\)\\s*\\{\\s*tag\\(id:\\s*\\$id\\)\\s*\\{\\s*id\\s*topics\\s*\\{\\s*id\\s*title\\s*updated_at\\s*ttl\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*\\}"
+ }
+ }
+ },
+ "response": {
+ "status": 200,
+ "headers": {
+ "Content-Type": "application/json; charset=utf-8"
+ },
+ "body": {
+ "data": {
+ "tag": null
+ }
+ }
+ }
+ },
+ {
+ "description": "a request to get a single tag",
+ "providerState": "there's a server error",
+ "request": {
+ "method": "POST",
+ "path": "/graphql",
+ "headers": {
+ "content-type": "application/json"
+ },
+ "body": {
+ "operationName": "GetTag",
+ "query": "query GetTag($id: ID!) {\n tag(id: $id) {\n id\n topics {\n id\n title\n updated_at\n ttl\n __typename\n }\n __typename\n }\n }",
+ "variables": {
+ "id": "pineapple"
+ }
+ },
+ "matchingRules": {
+ "$.body.query": {
+ "match": "regex",
+ "regex": "query\\s*GetTag\\(\\$id:\\s*ID!\\)\\s*\\{\\s*tag\\(id:\\s*\\$id\\)\\s*\\{\\s*id\\s*topics\\s*\\{\\s*id\\s*title\\s*updated_at\\s*ttl\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*\\}"
+ }
+ }
+ },
+ "response": {
+ "status": 500,
+ "headers": {}
+ }
+ },
+ {
+ "description": "a request to get a single tag",
+ "providerState": "there's an error in the response",
+ "request": {
+ "method": "POST",
+ "path": "/graphql",
+ "headers": {
+ "content-type": "application/json"
+ },
+ "body": {
+ "operationName": "GetTag",
+ "query": "query GetTag($id: ID!) {\n tag(id: $id) {\n id\n topics {\n id\n title\n updated_at\n ttl\n __typename\n }\n __typename\n }\n }",
+ "variables": {
+ "id": "pineapple"
+ }
+ },
+ "matchingRules": {
+ "$.body.query": {
+ "match": "regex",
+ "regex": "query\\s*GetTag\\(\\$id:\\s*ID!\\)\\s*\\{\\s*tag\\(id:\\s*\\$id\\)\\s*\\{\\s*id\\s*topics\\s*\\{\\s*id\\s*title\\s*updated_at\\s*ttl\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*\\}"
+ }
+ }
+ },
+ "response": {
+ "status": 200,
+ "headers": {
+ "Content-Type": "application/json; charset=utf-8"
+ },
+ "body": {
+ "errors": [
+ {
+ "message": "An error occurred when fetching the tag"
+ }
+ ]
+ },
+ "matchingRules": {
+ "$.body.errors": {
+ "min": 1
+ },
+ "$.body.errors[*].*": {
+ "match": "type"
+ },
+ "$.body.errors[*].message": {
+ "match": "type"
+ }
+ }
+ }
+ },
+ {
+ "description": "a request to get a single post",
+ "providerState": "there's data",
+ "request": {
+ "method": "POST",
+ "path": "/graphql",
+ "headers": {
+ "content-type": "application/json"
+ },
+ "body": {
+ "operationName": "GetPost",
+ "query": "query GetPost($id: ID!) {\n post(id: $id) {\n id\n text\n created_at\n author {\n id\n handle\n __typename\n }\n topic {\n id\n title\n __typename\n }\n __typename\n }\n }",
+ "variables": {
+ "id": "8f75eba5-6989-4dd3-b466-e464546ce374"
+ }
+ },
+ "matchingRules": {
+ "$.body.query": {
+ "match": "regex",
+ "regex": "query\\s*GetPost\\(\\$id:\\s*ID!\\)\\s*\\{\\s*post\\(id:\\s*\\$id\\)\\s*\\{\\s*id\\s*text\\s*created_at\\s*author\\s*\\{\\s*id\\s*handle\\s*__typename\\s*\\}\\s*topic\\s*\\{\\s*id\\s*title\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*\\}"
+ }
+ }
+ },
+ "response": {
+ "status": 200,
+ "headers": {
+ "Content-Type": "application/json; charset=utf-8"
+ },
+ "body": {
+ "data": {
+ "post": {
+ "id": "8f75eba5-6989-4dd3-b466-e464546ce374",
+ "text": "This is a very pacty post",
+ "created_at": 1619976194937,
+ "author": {
+ "id": "a805b3de-cac4-451c-a1e6-f078869c9db9",
+ "handle": "pacts_person"
+ },
+ "topic": {
+ "id": "5c283ce1-0470-4b98-86f5-1fec9a22c9ac",
+ "title": "The parent pacts topic"
+ }
+ }
+ }
+ },
+ "matchingRules": {
+ "$.body.data.post": {
+ "match": "type"
+ },
+ "$.body.data.post.id": {
+ "match": "type"
+ },
+ "$.body.data.post.text": {
+ "match": "type"
+ },
+ "$.body.data.post.created_at": {
+ "match": "type"
+ },
+ "$.body.data.post.author": {
+ "match": "type"
+ },
+ "$.body.data.post.author.id": {
+ "match": "type"
+ },
+ "$.body.data.post.author.handle": {
+ "match": "type"
+ },
+ "$.body.data.post.topic": {
+ "match": "type"
+ },
+ "$.body.data.post.topic.id": {
+ "match": "type"
+ },
+ "$.body.data.post.topic.title": {
+ "match": "type"
+ }
+ }
+ }
+ },
+ {
+ "description": "a request to get a single post",
+ "providerState": "there's no data",
+ "request": {
+ "method": "POST",
+ "path": "/graphql",
+ "headers": {
+ "content-type": "application/json"
+ },
+ "body": {
+ "operationName": "GetPost",
+ "query": "query GetPost($id: ID!) {\n post(id: $id) {\n id\n text\n created_at\n author {\n id\n handle\n __typename\n }\n topic {\n id\n title\n __typename\n }\n __typename\n }\n }",
+ "variables": {
+ "id": "8f75eba5-6989-4dd3-b466-e464546ce374"
+ }
+ },
+ "matchingRules": {
+ "$.body.query": {
+ "match": "regex",
+ "regex": "query\\s*GetPost\\(\\$id:\\s*ID!\\)\\s*\\{\\s*post\\(id:\\s*\\$id\\)\\s*\\{\\s*id\\s*text\\s*created_at\\s*author\\s*\\{\\s*id\\s*handle\\s*__typename\\s*\\}\\s*topic\\s*\\{\\s*id\\s*title\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*\\}"
+ }
+ }
+ },
+ "response": {
+ "status": 200,
+ "headers": {
+ "Content-Type": "application/json; charset=utf-8"
+ },
+ "body": {
+ "data": {
+ "post": null
+ }
+ }
+ }
+ },
+ {
+ "description": "a request to get a single post",
+ "providerState": "there's a server error",
+ "request": {
+ "method": "POST",
+ "path": "/graphql",
+ "headers": {
+ "content-type": "application/json"
+ },
+ "body": {
+ "operationName": "GetPost",
+ "query": "query GetPost($id: ID!) {\n post(id: $id) {\n id\n text\n created_at\n author {\n id\n handle\n __typename\n }\n topic {\n id\n title\n __typename\n }\n __typename\n }\n }",
+ "variables": {
+ "id": "8f75eba5-6989-4dd3-b466-e464546ce374"
+ }
+ },
+ "matchingRules": {
+ "$.body.query": {
+ "match": "regex",
+ "regex": "query\\s*GetPost\\(\\$id:\\s*ID!\\)\\s*\\{\\s*post\\(id:\\s*\\$id\\)\\s*\\{\\s*id\\s*text\\s*created_at\\s*author\\s*\\{\\s*id\\s*handle\\s*__typename\\s*\\}\\s*topic\\s*\\{\\s*id\\s*title\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*\\}"
+ }
+ }
+ },
+ "response": {
+ "status": 500,
+ "headers": {}
+ }
+ },
+ {
+ "description": "a request to get a single post",
+ "providerState": "there's an error in the response",
+ "request": {
+ "method": "POST",
+ "path": "/graphql",
+ "headers": {
+ "content-type": "application/json"
+ },
+ "body": {
+ "operationName": "GetPost",
+ "query": "query GetPost($id: ID!) {\n post(id: $id) {\n id\n text\n created_at\n author {\n id\n handle\n __typename\n }\n topic {\n id\n title\n __typename\n }\n __typename\n }\n }",
+ "variables": {
+ "id": "8f75eba5-6989-4dd3-b466-e464546ce374"
+ }
+ },
+ "matchingRules": {
+ "$.body.query": {
+ "match": "regex",
+ "regex": "query\\s*GetPost\\(\\$id:\\s*ID!\\)\\s*\\{\\s*post\\(id:\\s*\\$id\\)\\s*\\{\\s*id\\s*text\\s*created_at\\s*author\\s*\\{\\s*id\\s*handle\\s*__typename\\s*\\}\\s*topic\\s*\\{\\s*id\\s*title\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*\\}"
+ }
+ }
+ },
+ "response": {
+ "status": 200,
+ "headers": {
+ "Content-Type": "application/json; charset=utf-8"
+ },
+ "body": {
+ "errors": [
+ {
+ "message": "An error occurred when fetching the post"
+ }
+ ]
+ },
+ "matchingRules": {
+ "$.body.errors": {
+ "min": 1
+ },
+ "$.body.errors[*].*": {
+ "match": "type"
+ },
+ "$.body.errors[*].message": {
+ "match": "type"
+ }
+ }
+ }
+ }
+ ],
+ "metadata": {
+ "pactSpecification": {
+ "version": "2.0.0"
+ }
+ }
+}
diff --git a/postcss.config.cjs b/postcss.config.cjs
index 33ad091..054c147 100644
--- a/postcss.config.cjs
+++ b/postcss.config.cjs
@@ -1,6 +1,6 @@
module.exports = {
- plugins: {
- tailwindcss: {},
- autoprefixer: {},
- },
-}
+ plugins: {
+ tailwindcss: {},
+ autoprefixer: {}
+ }
+};
diff --git a/src/lib/animations/blink.test.ts b/src/lib/animations/blink.test.ts
index 32dc872..b4d9f33 100644
--- a/src/lib/animations/blink.test.ts
+++ b/src/lib/animations/blink.test.ts
@@ -6,102 +6,88 @@ import { blink } from './blink';
import { sineOut } from 'svelte/easing';
const internals = {
- response: null
+ response: null
};
describe('blink', () => {
-
- test('it has a default delay of 0ms', () => {
-
- const response = blink(document.createElement('div'), {});
-
- expect(response.delay).toBe(0);
- });
-
- test('it allows delay to be overridden', () => {
-
- const response = blink(document.createElement('div'), {
- delay: 300
- });
-
- expect(response.delay).toBe(300);
- });
-
- test('it has a default duration of 400ms', () => {
-
- const response = blink(document.createElement('div'), {});
-
- expect(response.duration).toBe(400);
- });
-
- test('it allows delay to be overridden', () => {
-
- const response = blink(document.createElement('div'), {
- duration: 999
- });
-
- expect(response.duration).toBe(999);
- });
-
- test('it uses sineOut as the default easing function', () => {
-
- const response = blink(document.createElement('div'), {});
-
- expect(response.easing).toBe(sineOut);
- });
-
- test('it allows easing function to be overridden', () => {
-
- const response = blink(document.createElement('div'), {
- easing: () => 666
- });
-
- expect(response.easing(0)).toBe(666);
- });
-
- describe('css animation function', () => {
-
- beforeEach(() => {
-
- const div = document.createElement('div');
- div.style.width = '100px';
- div.style.height = '200px';
- internals.response = blink(div, {});
- });
-
- test('It starts with with zeroed width and height', () => {
-
- const css = internals.response.css(0, 1);
- expect(css).toContain('width: 0px');
- expect(css).toContain('height: 0px');
- });
-
- test('It grows to full height and 0 width in first 20%', () => {
-
- const css = internals.response.css(0.2, 0.8);
- expect(css).toContain('width: 0px');
- expect(css).toContain('height: 200px');
- });
-
- test('It expands to full height by the end', () => {
-
- const css = internals.response.css(1, 0);
- expect(css).toContain('width: 100px');
- expect(css).toContain('height: 200px');
- });
-
- test('It keeps element vertically centered by adjusting the margin', () => {
-
- const css = internals.response.css(0.1, 0.9);
- expect(css).toContain('margin: 50px 50px');
- expect(css).toContain('height: 100px');
- });
-
- test('It keeps element horizontally centered by adjusting the margin', () => {
-
- const css = internals.response.css(0.6, 0.4);
- expect(css).toContain('margin: 0px 25px');
- expect(css).toContain('width: 50px');
- });
- });
+ test('it has a default delay of 0ms', () => {
+ const response = blink(document.createElement('div'), {});
+
+ expect(response.delay).toBe(0);
+ });
+
+ test('it allows delay to be overridden', () => {
+ const response = blink(document.createElement('div'), {
+ delay: 300
+ });
+
+ expect(response.delay).toBe(300);
+ });
+
+ test('it has a default duration of 400ms', () => {
+ const response = blink(document.createElement('div'), {});
+
+ expect(response.duration).toBe(400);
+ });
+
+ test('it allows delay to be overridden', () => {
+ const response = blink(document.createElement('div'), {
+ duration: 999
+ });
+
+ expect(response.duration).toBe(999);
+ });
+
+ test('it uses sineOut as the default easing function', () => {
+ const response = blink(document.createElement('div'), {});
+
+ expect(response.easing).toBe(sineOut);
+ });
+
+ test('it allows easing function to be overridden', () => {
+ const response = blink(document.createElement('div'), {
+ easing: () => 666
+ });
+
+ expect(response.easing(0)).toBe(666);
+ });
+
+ describe('css animation function', () => {
+ beforeEach(() => {
+ const div = document.createElement('div');
+ div.style.width = '100px';
+ div.style.height = '200px';
+ internals.response = blink(div, {});
+ });
+
+ test('It starts with with zeroed width and height', () => {
+ const css = internals.response.css(0, 1);
+ expect(css).toContain('width: 0px');
+ expect(css).toContain('height: 0px');
+ });
+
+ test('It grows to full height and 0 width in first 20%', () => {
+ const css = internals.response.css(0.2, 0.8);
+ expect(css).toContain('width: 0px');
+ expect(css).toContain('height: 200px');
+ });
+
+ test('It expands to full height by the end', () => {
+ const css = internals.response.css(1, 0);
+ expect(css).toContain('width: 100px');
+ expect(css).toContain('height: 200px');
+ });
+
+ test('It keeps element vertically centered by adjusting the margin', () => {
+ const css = internals.response.css(0.1, 0.9);
+ expect(css).toContain('margin: 50px 50px');
+ expect(css).toContain('height: 100px');
+ });
+
+ test('It keeps element horizontally centered by adjusting the margin', () => {
+ const css = internals.response.css(0.6, 0.4);
+ expect(css).toContain('margin: 0px 25px');
+ expect(css).toContain('width: 50px');
+ });
+ });
});
diff --git a/src/lib/animations/blink.ts b/src/lib/animations/blink.ts
index c291b06..623489a 100644
--- a/src/lib/animations/blink.ts
+++ b/src/lib/animations/blink.ts
@@ -1,25 +1,23 @@
import { sineOut } from 'svelte/easing';
import type { AnimationConfig } from 'svelte/animate';
-export const blink = function blink(node: HTMLElement, params: AnimationConfig): AnimationConfig{
+export const blink = function blink(node: HTMLElement, params: AnimationConfig): AnimationConfig {
+ const originalWidth = parseFloat(getComputedStyle(node).width);
+ const originalHeight = parseFloat(getComputedStyle(node).height);
- const originalWidth = parseFloat(getComputedStyle(node).width);
- const originalHeight = parseFloat(getComputedStyle(node).height);
+ return {
+ delay: params.delay || 0,
+ duration: params.duration || 400,
+ easing: params.easing || sineOut,
+ css: (t: number): string => {
+ const halfWidth = originalWidth / 2;
+ const halfHeight = originalHeight / 2;
+ const height = Math.round(t <= 0.2 ? (originalHeight * t) / 0.2 : originalHeight);
+ const marginY = Math.round(t <= 0.2 ? halfHeight * (1 - t / 0.2) : 0);
+ const width = Math.round(t > 0.2 ? ((t - 0.2) / 0.8) * originalWidth : 0);
+ const marginX = Math.round(t > 0.2 ? (1 - (t - 0.2) / 0.8) * halfWidth : halfWidth);
- return {
- delay: params.delay || 0,
- duration: params.duration || 400,
- easing: params.easing || sineOut,
- css: (t: number): string => {
-
- const halfWidth = originalWidth / 2;
- const halfHeight = originalHeight / 2;
- const height = Math.round(t <= 0.2 ? (originalHeight * t) / 0.2 : originalHeight);
- const marginY = Math.round(t <= 0.2 ? halfHeight * (1 - t / 0.2) : 0);
- const width = Math.round(t > 0.2 ? ((t - 0.2) / 0.8) * originalWidth : 0);
- const marginX = Math.round(t > 0.2 ? (1 - (t - 0.2) / 0.8) * halfWidth : halfWidth);
-
- return `width: ${width}px; height: ${height}px; margin: ${marginY}px ${marginX}px`;
- }
- };
+ return `width: ${width}px; height: ${height}px; margin: ${marginY}px ${marginX}px`;
+ }
+ };
};
diff --git a/src/lib/components/actions/topic.svelte b/src/lib/components/actions/topic.svelte
index 1311d06..a3cba3b 100644
--- a/src/lib/components/actions/topic.svelte
+++ b/src/lib/components/actions/topic.svelte
@@ -1,14 +1,14 @@
-
- {@html $_('header.action.reply.display')}
-
+
+ {@html $_('header.action.reply.display')}
+