HATEOAS-first backend framework.
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

default.test.ts 4.2 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. import {
  2. describe,
  3. beforeAll,
  4. afterAll,
  5. it,
  6. expect,
  7. Mock,
  8. } from 'vitest';
  9. import {
  10. statusCodes
  11. } from '@modal-sh/yasumi';
  12. import {
  13. DataSource,
  14. Server,
  15. } from '@modal-sh/yasumi/backend';
  16. import {Client} from '@modal-sh/yasumi/client';
  17. import {client} from '@modal-sh/yasumi-extender-http/client';
  18. import {ResourceItemFetchedResponse, ResourceCreatedResponse} from '@modal-sh/yasumi-recipe-resource';
  19. import {createDummyDataSource, NEW_ID} from './fixtures/data-source';
  20. import {setupApp} from '../src/setup';
  21. const connectionParams = {
  22. port: 3001,
  23. };
  24. describe('default', () => {
  25. let theClient: Client;
  26. let theServer: Server;
  27. let dataSource: Record<keyof DataSource, Mock>;
  28. beforeAll(() => {
  29. dataSource = createDummyDataSource();
  30. });
  31. afterAll(() => {
  32. dataSource.getById.mockReset();
  33. });
  34. beforeAll(async () => {
  35. const {
  36. app: theApp,
  37. server: createdServer,
  38. } = setupApp(dataSource);
  39. theServer = createdServer;
  40. await theServer.serve(connectionParams);
  41. theClient = client({
  42. app: theApp,
  43. });
  44. await theClient.connect(connectionParams);
  45. });
  46. afterAll(async () => {
  47. await theClient.disconnect();
  48. await theServer.close();
  49. });
  50. describe('fetch', () => {
  51. it('works', async () => {
  52. const theEndpoint = theClient.app.endpoints.get('users');
  53. const theOperation = theClient.app.operations.get('fetch');
  54. // TODO create wrapper for fetch's Response here
  55. //
  56. // should we create a helper object to process client-side received response from server's sent response?
  57. //
  58. // the motivation is to remove the manual deserialization from the client (provide serialization on the response
  59. // object so as the client is not limited to .text(), .json(), .arrayBuffer() etc)
  60. const responseRaw = await theClient
  61. .at(theEndpoint)
  62. .makeRequest(
  63. theOperation
  64. .search({
  65. foo: 'bar',
  66. })
  67. );
  68. const response = ResourceItemFetchedResponse.fromFetchResponse(responseRaw);
  69. const body = await response['deserialize']();
  70. expect(response).toHaveProperty('statusCode', statusCodes.HTTP_STATUS_OK);
  71. expect(response).toHaveProperty('statusMessage', 'Resource Collection Fetched');
  72. expect(body).toEqual([]);
  73. });
  74. it('works for items', async () => {
  75. const theEndpoint = theClient.app.endpoints.get('users');
  76. const theOperation = theClient.app.operations.get('fetch');
  77. // TODO create wrapper for fetch's Response here
  78. //
  79. // should we create a helper object to process client-side received response from server's sent response?
  80. //
  81. // the motivation is to remove the manual deserialization from the client (provide serialization on the response
  82. // object so as the client is not limited to .text(), .json(), .arrayBuffer() etc)
  83. const responseRaw = await theClient
  84. .at(theEndpoint, { resourceId: 3 })
  85. // TODO how to inject extra data (e.g. headers, body) in the operation (e.g. auth)?
  86. .makeRequest(
  87. theOperation
  88. .search({
  89. foo: 'bar',
  90. }) // allow multiple calls of .search() to add to search params
  91. );
  92. const response = ResourceItemFetchedResponse.fromFetchResponse(responseRaw);
  93. expect(response).toHaveProperty('statusCode', statusCodes.HTTP_STATUS_OK);
  94. expect(response).toHaveProperty('statusMessage', 'Resource Fetched');
  95. });
  96. });
  97. describe('create', () => {
  98. it('works', async () => {
  99. const theEndpoint = theClient.app.endpoints.get('users');
  100. const theOperation = theClient.app.operations.get('create');
  101. // TODO create wrapper for fetch's Response here
  102. //
  103. // should we create a helper object to process client-side received response from server's sent response?
  104. //
  105. // the motivation is to remove the manual deserialization from the client (provide serialization on the response
  106. // object so as the client is not limited to .text(), .json(), .arrayBuffer() etc)
  107. const responseRaw = await theClient
  108. .at(theEndpoint)
  109. .makeRequest(
  110. theOperation
  111. .setBody({})
  112. );
  113. const response = ResourceCreatedResponse.fromFetchResponse(responseRaw);
  114. const body = await response['deserialize']();
  115. expect(response).toHaveProperty('statusCode', statusCodes.HTTP_STATUS_CREATED);
  116. expect(response).toHaveProperty('statusMessage', 'Resource Created');
  117. expect(body).toEqual({ id: NEW_ID });
  118. });
  119. });
  120. });