@pbvision/fastify-firestore-service 0.0.17 → 0.0.18

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/README.md CHANGED
@@ -14,7 +14,6 @@ provides a way to define APIs, including managing data.
14
14
  - [Components](#components)
15
15
  - [Customizing Component Registration](#customizing-component-registration)
16
16
  - [Unit testing](#unit-testing)
17
- - [Setup](#setup)
18
17
  - [Generating SDKs](#generating-sdks)
19
18
  - [Swagger UI](#swagger-ui)
20
19
  - [OpenAPI SDKs](#openapi-sdks)
@@ -175,10 +174,6 @@ workflow with custom components. For example, to add a new type of component
175
174
  `makeService({ components: { ExampleComponent } })`
176
175
 
177
176
  # Unit testing
178
- ## Setup
179
- Apps store data in Firestore. You must start the Firestore emulator before
180
- running tests. You can run `yarn start-local-db` to start the local emulator.
181
-
182
177
  # Generating SDKs
183
178
  ## Swagger UI
184
179
  This library generates an interactive Swagger UI for all APIs at /[service]/docs.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pbvision/fastify-firestore-service",
3
- "version": "0.0.17",
3
+ "version": "0.0.18",
4
4
  "description": "Web Framework using Fastify and Firestore ORM",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -11,9 +11,10 @@
11
11
  "scripts": {
12
12
  "build-doc": "./docs/build.sh",
13
13
  "debug": "./node_modules/nodemon/bin/nodemon.js --no-lazy --legacy-watch --watch ./src --watch ./examples --watch ./test --inspect=9229 ./node_modules/jest/bin/jest.js --coverage --config=./jest.config.json --runInBand",
14
- "test": "node --experimental-vm-modules ./node_modules/jest/bin/jest.js --config=./jest.config.json --coverage",
15
14
  "setup": "yarn install --frozen-lockfile && pip install -r requirements.txt",
16
- "start-local-db": "./node_modules/@pbvision/firestore-orm/scripts/start-local-db.sh"
15
+ "start-local-db": "./node_modules/@pbvision/firestore-orm/scripts/start-local-db.sh",
16
+ "test": "yarn -s start-local-db && yarn -s test-without-starting-db",
17
+ "test-without-starting-db": "node --experimental-vm-modules ./node_modules/jest/bin/jest.js --config=./jest.config.json --coverage"
17
18
  },
18
19
  "contributors": [
19
20
  "David Underhill",
@@ -41,7 +42,7 @@
41
42
  "@fastify/static": "^6.12",
42
43
  "@fastify/swagger": "^8.1.0",
43
44
  "@fastify/swagger-ui": "^2.0.1",
44
- "@pbvision/firestore-orm": "^0.0.6",
45
+ "@pbvision/firestore-orm": "^0.0.7",
45
46
  "@pbvision/schema": "^0.2.15",
46
47
  "@sentry/node": "^7.91.0",
47
48
  "fastify": "^4.10.0",
@@ -3,23 +3,24 @@ import zlib from 'node:zlib'
3
3
 
4
4
  import realFetch from 'node-fetch'
5
5
 
6
- async function fetchWrapper (options, mockedFetch) {
7
- const { compress = true, method = 'POST', url, qsParams, json } = options
8
- let { body, headers } = options
6
+ async function fetchWrapper (request, mockedFetch) {
7
+ const { compress = true, method = 'POST', url, qsParams, json } = request
8
+ let { body, headers } = request
9
9
  headers = { ...headers } // copy the headers before we change them
10
10
 
11
11
  // compress the body using brotli
12
12
  if (json) {
13
13
  headers['content-type'] = 'application/json'
14
- body = JSON.stringify(options.json)
14
+ body = JSON.stringify(request.json)
15
15
  }
16
16
  if (body && compress) {
17
17
  body = zlib.brotliCompressSync(body)
18
18
  headers['content-encoding'] = 'br'
19
19
  }
20
20
 
21
- // istanbul ignore next
22
- const fetch = mockedFetch ?? fetchWrapper.__mock ?? realFetch
21
+ const fetch = (mockedFetch === false)
22
+ ? realFetch
23
+ : (mockedFetch ?? fetchWrapper.__mock ?? realFetch)
23
24
 
24
25
  // compute the full URL including search params
25
26
  let fullURL = url
@@ -29,7 +30,8 @@ async function fetchWrapper (options, mockedFetch) {
29
30
  fullURL += `?${qsStr}`
30
31
  }
31
32
  }
32
- return fetch(fullURL, { body, headers, method, compress: false })
33
+ const options = { body, headers, method, compress: false }
34
+ return fetch(fullURL, options)
33
35
  }
34
36
 
35
37
  export default fetchWrapper
package/test/base-test.js CHANGED
@@ -1,3 +1,4 @@
1
+ import querystring from 'node:querystring'
1
2
  import zlib from 'node:zlib'
2
3
 
3
4
  import { jest } from '@jest/globals'
@@ -27,6 +28,10 @@ class BaseAppTest extends BaseTest {
27
28
  beforeEach () {
28
29
  this.fetchMock = fetchWrapper.__mock
29
30
  fetchWrapper.__mock.mockClear()
31
+
32
+ // default response is a weird error to help make it obvious the unit test
33
+ // author forgot to provide a custom mock value
34
+ this.fetchMock.mockResp('custom mock value not set', 555)
30
35
  }
31
36
 
32
37
  async beforeAll () {
@@ -73,15 +78,15 @@ function makeHeadersObj (headers) {
73
78
  // so you can pass the output of app.post(), etc. as the promise here as is
74
79
  function makeNodeFetchMockValueFromPromise (promise) {
75
80
  const mockValue = new Promise(resolve => {
76
- promise.then(desiredHttpResponse => {
77
- let body = desiredHttpResponse.text || desiredHttpResponse.body || ''
81
+ promise.then(httpResponse => {
82
+ let body = httpResponse.text || httpResponse.body || ''
78
83
  const headers = {}
79
84
  if (typeof body !== 'string') {
80
85
  body = JSON.stringify(body)
81
86
  headers['content-type'] = 'application/json'
82
87
  }
83
88
  resolve({
84
- status: desiredHttpResponse.status || 200,
89
+ status: httpResponse.status || 200,
85
90
  headers: makeHeadersObj(headers),
86
91
  text: async () => body
87
92
  })
@@ -120,9 +125,7 @@ function makeNodeFetchMockValue (body, status, callback) {
120
125
  }
121
126
 
122
127
  function mockNodeFetch () {
123
- const nodeFetchMock = jest.fn().mockImplementation(({ body }) => {
124
- expect(body).toEqual(zlib.brotliCompressSync('321'))
125
- })
128
+ const nodeFetchMock = jest.fn().mockImplementation()
126
129
 
127
130
  nodeFetchMock.mockResp = (body = '', statusCode = 200, callback) => {
128
131
  nodeFetchMock.mockReturnValue(makeNodeFetchMockValue(body, statusCode, callback))
@@ -136,12 +139,34 @@ function mockNodeFetch () {
136
139
  * provides a mock response then an error will be thrown
137
140
  */
138
141
  nodeFetchMock.mockRespWithCallback = (...callbacks) => {
139
- nodeFetchMock.mockImplementation(request => {
142
+ nodeFetchMock.mockImplementation((fullURL, options) => {
143
+ // construct the fetchWrapper's request parameter from the fullURL and
144
+ // options passed as parameters to node-fetch
145
+ const [baseUrl, qsParams] = fullURL.split('?', 2)
146
+ const request = {
147
+ compress: options.headers['content-encoding'] === 'br',
148
+ method: options.method,
149
+ url: baseUrl,
150
+ qsParams: querystring.parse(qsParams),
151
+ headers: options.headers
152
+ }
153
+ delete request.headers['content-encoding']
154
+ const body = options.body
155
+ ? (request.compress
156
+ ? zlib.brotliDecompressSync(options.body)
157
+ : options.body)
158
+ : options.body
159
+ if (options.headers['content-type'] === 'application/json') {
160
+ delete options.headers['content-type']
161
+ request.json = JSON.parse(body)
162
+ } else {
163
+ request.body = body // may be undefined
164
+ }
165
+
140
166
  for (const callback of callbacks) {
141
167
  const desiredHTTPResponse = callback(request)
142
168
  if (desiredHTTPResponse === true) {
143
- const unmockedFetch = jest.requireActual('../src/fetch-wrapper.js')
144
- return unmockedFetch(request)
169
+ return fetchWrapper(request, false)
145
170
  }
146
171
  if (desiredHTTPResponse) {
147
172
  if (desiredHTTPResponse.then) {
@@ -162,10 +187,11 @@ function mockNodeFetch () {
162
187
  let idx = 0
163
188
  function setupNextResponse () {
164
189
  if (idx < responses.length) {
165
- nodeFetchMock.mockResp(...responses[idx], setupNextResponse)
166
- } else if (idx > responses.length) {
190
+ const [body, code] = responses[idx]
191
+ nodeFetchMock.mockResp(body ?? '', code ?? 200, setupNextResponse)
192
+ } else {
167
193
  // exactly equal means we just got our last callback (okay)
168
- throw new Error('more requests made than we had mock responses')
194
+ nodeFetchMock.mockResp('ran out of mocked responses', 556)
169
195
  }
170
196
  idx += 1
171
197
  }