TestGrid.tsx 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. import React from 'react';
  2. import { SelectOptionCellDataPB, ViewLayoutTypePB } from '../../../services/backend';
  3. import { Log } from '../../utils/log';
  4. import {
  5. assertFieldName,
  6. assertNumberOfFields,
  7. assertNumberOfRows,
  8. assertTextCell,
  9. createTestDatabaseView,
  10. editTextCell,
  11. makeSingleSelectCellController,
  12. openTestDatabase,
  13. } from './DatabaseTestHelper';
  14. import { SelectOptionBackendService } from '../../stores/effects/database/cell/select_option_bd_svc';
  15. import { TypeOptionController } from '../../stores/effects/database/field/type_option/type_option_controller';
  16. import { None, Some } from 'ts-results';
  17. import { RowBackendService } from '../../stores/effects/database/row/row_bd_svc';
  18. export const TestCreateGrid = () => {
  19. async function createBuildInGrid() {
  20. const view = await createTestDatabaseView(ViewLayoutTypePB.Grid);
  21. const databaseController = await openTestDatabase(view.id);
  22. databaseController.subscribe({
  23. onViewChanged: (databasePB) => {
  24. Log.debug('Did receive database:' + databasePB);
  25. },
  26. onRowsChanged: async (rows) => {
  27. if (rows.length !== 3) {
  28. throw Error('Expected number of rows is 3, but receive ' + rows.length);
  29. }
  30. },
  31. onFieldsChanged: (fields) => {
  32. if (fields.length !== 3) {
  33. throw Error('Expected number of fields is 3, but receive ' + fields.length);
  34. }
  35. },
  36. });
  37. await databaseController.open().then((result) => result.unwrap());
  38. }
  39. return TestButton('Test create build-in grid', createBuildInGrid);
  40. };
  41. export const TestEditCell = () => {
  42. async function testGridRow() {
  43. const view = await createTestDatabaseView(ViewLayoutTypePB.Grid);
  44. const databaseController = await openTestDatabase(view.id);
  45. await databaseController.open().then((result) => result.unwrap());
  46. for (const [index, row] of databaseController.databaseViewCache.rowInfos.entries()) {
  47. const cellContent = index.toString();
  48. await editTextCell(row, databaseController, cellContent);
  49. await assertTextCell(row, databaseController, cellContent);
  50. }
  51. }
  52. return TestButton('Test editing cell', testGridRow);
  53. };
  54. export const TestCreateRow = () => {
  55. async function testCreateRow() {
  56. const view = await createTestDatabaseView(ViewLayoutTypePB.Grid);
  57. const databaseController = await openTestDatabase(view.id);
  58. await databaseController.open().then((result) => result.unwrap());
  59. await assertNumberOfRows(view.id, 3);
  60. // Create a row from a DatabaseController or create using the RowBackendService
  61. await databaseController.createRow();
  62. await assertNumberOfRows(view.id, 4);
  63. await databaseController.dispose();
  64. }
  65. return TestButton('Test create row', testCreateRow);
  66. };
  67. export const TestDeleteRow = () => {
  68. async function testDeleteRow() {
  69. const view = await createTestDatabaseView(ViewLayoutTypePB.Grid);
  70. const databaseController = await openTestDatabase(view.id);
  71. await databaseController.open().then((result) => result.unwrap());
  72. const rows = databaseController.databaseViewCache.rowInfos;
  73. const svc = new RowBackendService(view.id);
  74. await svc.deleteRow(rows[0].row.id);
  75. await assertNumberOfRows(view.id, 2);
  76. // Wait the databaseViewCache get the change notification and
  77. // update the rows.
  78. await new Promise((resolve) => setTimeout(resolve, 200));
  79. if (databaseController.databaseViewCache.rowInfos.length !== 2) {
  80. throw Error('The number of rows is not match');
  81. }
  82. await databaseController.dispose();
  83. }
  84. return TestButton('Test delete row', testDeleteRow);
  85. };
  86. export const TestCreateSelectOption = () => {
  87. async function testCreateOption() {
  88. const view = await createTestDatabaseView(ViewLayoutTypePB.Grid);
  89. const databaseController = await openTestDatabase(view.id);
  90. await databaseController.open().then((result) => result.unwrap());
  91. for (const [index, row] of databaseController.databaseViewCache.rowInfos.entries()) {
  92. if (index === 0) {
  93. const cellController = await makeSingleSelectCellController(row, databaseController).then((result) =>
  94. result.unwrap()
  95. );
  96. cellController.subscribeChanged({
  97. onCellChanged: (value) => {
  98. const option: SelectOptionCellDataPB = value.unwrap();
  99. console.log(option);
  100. },
  101. });
  102. const backendSvc = new SelectOptionBackendService(cellController.cellIdentifier);
  103. await backendSvc.createOption({ name: 'option' + index });
  104. await cellController.dispose();
  105. }
  106. }
  107. await databaseController.dispose();
  108. }
  109. return TestButton('Test create a select option', testCreateOption);
  110. };
  111. export const TestEditField = () => {
  112. async function testEditField() {
  113. const view = await createTestDatabaseView(ViewLayoutTypePB.Grid);
  114. const databaseController = await openTestDatabase(view.id);
  115. await databaseController.open().then((result) => result.unwrap());
  116. const fieldInfos = databaseController.fieldController.fieldInfos;
  117. // Modify the name of the field
  118. const firstFieldInfo = fieldInfos[0];
  119. const controller = new TypeOptionController(view.id, Some(firstFieldInfo));
  120. await controller.initialize();
  121. const newName = 'hello world';
  122. await controller.setFieldName(newName);
  123. await assertFieldName(view.id, firstFieldInfo.field.id, firstFieldInfo.field.field_type, newName);
  124. await databaseController.dispose();
  125. }
  126. return TestButton('Test edit the column name', testEditField);
  127. };
  128. export const TestCreateNewField = () => {
  129. async function testCreateNewField() {
  130. const view = await createTestDatabaseView(ViewLayoutTypePB.Grid);
  131. const databaseController = await openTestDatabase(view.id);
  132. await databaseController.open().then((result) => result.unwrap());
  133. await assertNumberOfFields(view.id, 3);
  134. // Modify the name of the field
  135. const controller = new TypeOptionController(view.id, None);
  136. await controller.initialize();
  137. await assertNumberOfFields(view.id, 4);
  138. await databaseController.dispose();
  139. }
  140. return TestButton('Test create a new column', testCreateNewField);
  141. };
  142. export const TestDeleteField = () => {
  143. async function testDeleteField() {
  144. const view = await createTestDatabaseView(ViewLayoutTypePB.Grid);
  145. const databaseController = await openTestDatabase(view.id);
  146. await databaseController.open().then((result) => result.unwrap());
  147. // Modify the name of the field.
  148. // The fieldInfos[0] is the primary field by default, we can't delete it.
  149. // So let choose the second fieldInfo.
  150. const fieldInfo = databaseController.fieldController.fieldInfos[1];
  151. const controller = new TypeOptionController(view.id, Some(fieldInfo));
  152. await controller.initialize();
  153. await assertNumberOfFields(view.id, 3);
  154. await controller.deleteField();
  155. await assertNumberOfFields(view.id, 2);
  156. await databaseController.dispose();
  157. }
  158. return TestButton('Test delete a new column', testDeleteField);
  159. };
  160. const TestButton = (title: string, onClick: () => void) => {
  161. return (
  162. <React.Fragment>
  163. <div>
  164. <button className='rounded-md bg-gray-300 p-4' type='button' onClick={() => onClick()}>
  165. {title}
  166. </button>
  167. </div>
  168. </React.Fragment>
  169. );
  170. };