-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch '#3' into [email protected]
# Conflicts: # bin/mock-config-server.ts # package.json # src/utils/helpers/isPlainObject.ts # src/utils/types/configs.ts # yarn.lock
- Loading branch information
Showing
36 changed files
with
649 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { Request } from 'express'; | ||
|
||
import { getGraphQLInput } from '../getGraphQLInput/getGraphQLInput'; | ||
import { parseQuery } from '../parseQuery/parseQuery'; | ||
|
||
export const parseGraphQLRequest = (request: Request): ReturnType<typeof parseQuery> => { | ||
const graphQLInput = getGraphQLInput(request); | ||
if (!graphQLInput.query) return null; | ||
|
||
return parseQuery(graphQLInput.query); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
import express from 'express'; | ||
import path from 'path'; | ||
import request from 'supertest'; | ||
|
||
import { createGraphQLRoutes } from '../graphql/createGraphQLRoutes/createGraphQLRoutes'; | ||
import { createRestRoutes } from '../rest/createRestRoutes/createRestRoutes'; | ||
import type { MockServerConfig } from '../utils/types'; | ||
|
||
import { notFoundMiddleware } from './notFoundMiddleware'; | ||
|
||
describe('notFoundMiddleware', () => { | ||
const baseUrl: MockServerConfig['baseUrl'] = '/base'; | ||
|
||
const rest: MockServerConfig['rest'] = { | ||
baseUrl: '/rest', | ||
configs: [ | ||
{ | ||
path: '/posts', | ||
method: 'get', | ||
routes: [{ data: {} }] | ||
}, | ||
{ | ||
path: '/posts/:postId', | ||
method: 'get', | ||
routes: [{ data: {}, entities: { params: { postId: 1 } } }] | ||
}, | ||
|
||
{ | ||
path: '/developers', | ||
method: 'get', | ||
routes: [{ data: {} }] | ||
}, | ||
{ | ||
path: '/developers/:developerId', | ||
method: 'get', | ||
routes: [{ data: {}, entities: { params: { developerId: 1 } } }] | ||
} | ||
] | ||
}; | ||
|
||
const graphql: MockServerConfig['graphql'] = { | ||
baseUrl: '/graphql', | ||
configs: [ | ||
{ | ||
operationName: 'GetPosts', | ||
operationType: 'query', | ||
routes: [{ data: {} }] | ||
}, | ||
{ | ||
operationName: 'GetDevelopers', | ||
operationType: 'query', | ||
routes: [{ data: {} }] | ||
} | ||
] | ||
}; | ||
|
||
const createServer = ( | ||
mockServerConfig: Pick<MockServerConfig, 'rest' | 'graphql' | 'interceptors' | 'baseUrl'> | ||
) => { | ||
const { baseUrl, rest, interceptors, graphql } = mockServerConfig; | ||
|
||
const server = express(); | ||
|
||
const serverBaseUrl = baseUrl ?? '/'; | ||
|
||
const restBaseUrl = path.join(serverBaseUrl, rest?.baseUrl ?? '/'); | ||
const routerWithRestRoutes = createRestRoutes( | ||
express.Router(), | ||
rest?.configs ?? [], | ||
interceptors | ||
); | ||
server.use(restBaseUrl, routerWithRestRoutes); | ||
|
||
const graphqlBaseUrl = path.join(serverBaseUrl, graphql?.baseUrl ?? '/'); | ||
const routerWithGraphqlRoutes = createGraphQLRoutes( | ||
express.Router(), | ||
graphql?.configs ?? [], | ||
interceptors | ||
); | ||
server.use(graphqlBaseUrl, routerWithGraphqlRoutes); | ||
|
||
server.set('view engine', 'ejs'); | ||
server.use(express.json()); | ||
|
||
notFoundMiddleware({ | ||
server, | ||
mockServerConfig | ||
}); | ||
|
||
return server; | ||
}; | ||
|
||
test('Should send correct REST suggestions', async () => { | ||
const server = createServer({ | ||
baseUrl, | ||
rest, | ||
graphql | ||
}); | ||
|
||
const response = await request(server).get('/bas/rst/pstss'); | ||
|
||
expect(response.statusCode).toBe(404); | ||
expect(response.text).toContain('<h3>REST</h3>'); | ||
expect(response.text).toContain('/base/rest/posts'); | ||
}); | ||
|
||
test('Should send correct GraphQL suggestions', async () => { | ||
const server = createServer({ | ||
baseUrl, | ||
rest, | ||
graphql | ||
}); | ||
|
||
const response = await request(server).get('/bse/graql?query=query posts { posts }'); | ||
|
||
expect(response.statusCode).toBe(404); | ||
expect(response.text).toContain('<h3>GraphQL</h3>'); | ||
expect(response.text).toContain('/base/graphql/GetPosts'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import type { Express, Request, Response } from 'express'; | ||
|
||
import { parseGraphQLRequest } from '../graphql/parseGraphQLRequest/parseGraphQLRequest'; | ||
import type { MockServerConfig, RestMethod } from '../utils/types'; | ||
|
||
import { getGraphqlUrlSuggestions, getRestUrlSuggestions } from './urlSuggestions'; | ||
|
||
interface NotFoundMiddlewareParams { | ||
server: Express; | ||
mockServerConfig: Pick<MockServerConfig, 'baseUrl' | 'rest' | 'graphql'>; | ||
} | ||
|
||
export const notFoundMiddleware = ({ server, mockServerConfig }: NotFoundMiddlewareParams) => { | ||
const { baseUrl: serverBaseUrl, rest, graphql } = mockServerConfig; | ||
|
||
const operationNames = graphql?.configs.map(({ operationName }) => operationName) ?? []; | ||
const graphqlPatternUrlMeaningfulStrings = Array.from( | ||
operationNames.reduce((acc, operationName) => { | ||
if (typeof operationName === 'string') | ||
acc.add(`${serverBaseUrl}${graphql?.baseUrl}/${operationName}`); | ||
return acc; | ||
}, new Set<string>()) | ||
); | ||
|
||
const restPaths = rest?.configs.map(({ path }) => path) ?? []; | ||
const patternUrls = Array.from( | ||
restPaths.reduce((acc, patternPath) => { | ||
if (typeof patternPath === 'string') | ||
acc.add(`${serverBaseUrl}${rest?.baseUrl}${patternPath}`); | ||
return acc; | ||
}, new Set<string>()) | ||
); | ||
|
||
server.use((request: Request, response: Response) => { | ||
const url = new URL(`${request.protocol}://${request.get('host')}${request.originalUrl}`); | ||
|
||
let graphqlUrlSuggestions: string[] = []; | ||
if (graphql) { | ||
const graphqlQuery = parseGraphQLRequest(request); | ||
|
||
if (graphqlQuery) { | ||
graphqlUrlSuggestions = getGraphqlUrlSuggestions({ | ||
url, | ||
graphqlPatternUrlMeaningfulStrings | ||
}); | ||
} | ||
} | ||
|
||
let restUrlSuggestions: string[] = []; | ||
if (rest) { | ||
restUrlSuggestions = getRestUrlSuggestions({ | ||
url, | ||
patternUrls | ||
}); | ||
} | ||
|
||
response.status(404).render('notFound', { | ||
requestMethod: request.method as RestMethod, | ||
url: `${url.pathname}${url.search}`, | ||
restUrlSuggestions, | ||
graphqlUrlSuggestions | ||
}); | ||
}); | ||
}; |
Oops, something went wrong.