entityManager.test.ts 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841
  1. import { describe, test, it, expect } from 'vitest'
  2. import EntityManager from "~/services/data/entityManager";
  3. import ApiResource from "~/models/ApiResource";
  4. import ApiModel from "~/models/ApiModel";
  5. import ApiRequestService from "~/services/data/apiRequestService";
  6. import {Element, Repository} from "pinia-orm";
  7. class DummyApiResource extends ApiResource {
  8. static entity = 'dummyResource'
  9. }
  10. class DummyApiModel extends ApiModel {
  11. static entity = 'dummyModel'
  12. }
  13. let _console: any = {
  14. 'log': console.log,
  15. 'warn': console.warn,
  16. 'error': console.error,
  17. }
  18. vi.mock("~/models/models", async () => {
  19. class MyModel {
  20. static entity = 'myModel'
  21. }
  22. const models: Record<string, any> = {'myModel': MyModel}
  23. return {
  24. default: models
  25. }
  26. })
  27. let apiRequestService: ApiRequestService
  28. let entityManager: EntityManager
  29. let repo: Repository<ApiResource>
  30. let _getRepo: (model: typeof ApiResource) => Repository<ApiResource>
  31. beforeEach(() => {
  32. // @ts-ignore
  33. repo = vi.fn() as Repository<ApiResource>
  34. // @ts-ignore
  35. apiRequestService = vi.fn() as ApiRequestService
  36. _getRepo = vi.fn((model: typeof ApiResource) => repo)
  37. entityManager = new EntityManager(apiRequestService, _getRepo)
  38. })
  39. afterEach(() => {
  40. // Reset console methods after mock
  41. console.log = _console['log']
  42. console.warn = _console['warn']
  43. console.error = _console['error']
  44. })
  45. describe('getRepository', () => {
  46. test('simple call', () => {
  47. entityManager.getRepository(DummyApiResource)
  48. expect(_getRepo).toHaveBeenCalledWith(DummyApiResource)
  49. })
  50. })
  51. describe('cast', () => {
  52. test('simple cast', () => {
  53. // @ts-ignore
  54. const result = entityManager.cast(DummyApiResource, { id: 1 })
  55. expect(result instanceof DummyApiResource).toEqual(true)
  56. })
  57. })
  58. describe('getModelFor', () => {
  59. test('simple call', () => {
  60. expect(entityManager.getModelFor('myModel').entity).toEqual('myModel')
  61. })
  62. })
  63. describe('getModelFromIri', () => {
  64. test('simple call', () => {
  65. // @ts-ignore
  66. entityManager.getModelFor = vi.fn((entityName: string) => entityName === 'dummy' ? DummyApiResource : null)
  67. // @ts-ignore
  68. const result = entityManager.getModelFromIri('/api/dummy/123')
  69. expect(result).toEqual(DummyApiResource)
  70. })
  71. test('invalide Iri', () => {
  72. expect(() => entityManager.getModelFromIri('/invalid')).toThrowError('cannot parse the IRI')
  73. })
  74. })
  75. describe('newInstance', () => {
  76. test('simple call', () => {
  77. const properties = { 'id': 1 }
  78. // @ts-ignore
  79. entityManager.getRepository = vi.fn((model: typeof ApiResource) => {
  80. return model === DummyApiResource ? repo : null
  81. })
  82. // @ts-ignore
  83. const entity = new DummyApiResource(properties)
  84. // @ts-ignore
  85. repo.make = vi.fn((properties: object) => {
  86. // @ts-ignore
  87. entity.id = properties.id
  88. return entity
  89. })
  90. // @ts-ignore
  91. entityManager.save = vi.fn((model: typeof ApiResource, entity: ApiResource, permanent: boolean) => entity)
  92. const result = entityManager.newInstance(DummyApiResource, properties)
  93. expect(repo.make).toHaveBeenCalledWith(properties)
  94. expect(entityManager.save).toHaveBeenCalledWith(DummyApiResource, entity, true)
  95. expect(result.id).toEqual(properties.id)
  96. })
  97. test('with no id provided', () => {
  98. const properties = { 'name': 'bob' }
  99. // @ts-ignore
  100. const repo = vi.fn() as Repository<ApiResource>
  101. // @ts-ignore
  102. entityManager.getRepository = vi.fn((model: typeof ApiResource) => {
  103. return model === DummyApiResource ? repo : null
  104. })
  105. // @ts-ignore
  106. entityManager.saveInitialState = vi.fn((model: typeof ApiResource, entity: ApiResource) => null)
  107. // @ts-ignore
  108. const entity = new DummyApiResource(properties)
  109. entity.setModel = vi.fn((model: typeof ApiResource) => null)
  110. // @ts-ignore
  111. repo.make = vi.fn((properties: object) => {
  112. // @ts-ignore
  113. entity.name = properties.name
  114. return entity
  115. })
  116. // @ts-ignore
  117. repo.save = vi.fn((record: Element) => entity)
  118. const result = entityManager.newInstance(DummyApiResource, properties)
  119. expect(
  120. result.id,
  121. 'id is \'tmp\' followed by a valid uuid-V4'
  122. ).toMatch(/tmp[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}/)
  123. expect(result.name).toEqual(properties.name)
  124. })
  125. })
  126. describe('save', () => {
  127. test('simple call', () => {
  128. // @ts-ignore
  129. const repo = vi.fn() as Repository<ApiResource>
  130. // @ts-ignore
  131. entityManager.getRepository = vi.fn((model: typeof ApiResource) => {
  132. return model === DummyApiResource ? repo : null
  133. })
  134. // @ts-ignore
  135. repo.save = vi.fn((record: Element) => entity)
  136. const entity = new DummyApiResource()
  137. entityManager.save(DummyApiResource, entity)
  138. expect(repo.save).toHaveBeenCalledWith(entity)
  139. })
  140. })
  141. describe('find', () => {
  142. test('simple call', () => {
  143. // @ts-ignore
  144. const repo = vi.fn() as Repository<ApiResource>
  145. // @ts-ignore
  146. entityManager.getRepository = vi.fn((model: typeof ApiResource) => {
  147. return model === DummyApiResource ? repo : null
  148. })
  149. const entity = new DummyApiResource({ id: 1 })
  150. // @ts-ignore
  151. repo.find = vi.fn((id: string | number) => entity)
  152. entityManager.find(DummyApiResource, 1)
  153. expect(entityManager.getRepository).toHaveBeenCalledWith(DummyApiResource)
  154. expect(repo.find).toHaveBeenCalledWith(1)
  155. })
  156. })
  157. describe('fetch', () => {
  158. test('not in store, no force refresh', async () => {
  159. const properties = { id: 1 }
  160. const entity = new DummyApiResource({ id: 1 })
  161. // @ts-ignore
  162. entityManager.find = vi.fn((model: typeof ApiResource, id: number) => undefined)
  163. // @ts-ignore
  164. apiRequestService.get = vi.fn(async (url: string) => properties)
  165. // @ts-ignore
  166. entityManager.newInstance = vi.fn((model: typeof ApiResource, props: object) => entity)
  167. const result = await entityManager.fetch(DummyApiResource, 1)
  168. expect(entityManager.find).toHaveBeenCalledWith(DummyApiResource, 1)
  169. expect(apiRequestService.get).toHaveBeenCalledWith('api/dummyResource/1')
  170. expect(entityManager.newInstance).toHaveBeenCalledWith(DummyApiResource, properties)
  171. expect(result).toEqual(entity)
  172. })
  173. test('in store, no force refresh', async () => {
  174. const properties = { id: 1 }
  175. const entity = new DummyApiResource({ id: 1 })
  176. // @ts-ignore
  177. entityManager.find = vi.fn((model: typeof ApiResource, id: number) => entity)
  178. const result = await entityManager.fetch(DummyApiResource, 1)
  179. expect(entityManager.find).toHaveBeenCalledWith(DummyApiResource, 1)
  180. expect(result).toEqual(entity)
  181. })
  182. test('in store, but with force refresh', async () => {
  183. const properties = { id: 1 }
  184. const entity = new DummyApiResource({ id: 1 })
  185. // @ts-ignore
  186. entityManager.find = vi.fn((model: typeof ApiResource, id: number) => undefined)
  187. // @ts-ignore
  188. apiRequestService.get = vi.fn(async (url: string) => properties)
  189. // @ts-ignore
  190. entityManager.newInstance = vi.fn((model: typeof ApiResource, props: object) => entity)
  191. const result = await entityManager.fetch(DummyApiResource, 1, true)
  192. expect(entityManager.find).toHaveBeenCalledTimes(0)
  193. expect(apiRequestService.get).toHaveBeenCalledWith('api/dummyResource/1')
  194. expect(entityManager.newInstance).toHaveBeenCalledWith(DummyApiResource, properties)
  195. expect(result).toEqual(entity)
  196. })
  197. })
  198. describe('fetchCollection', () => {
  199. test('simple call', async () => {
  200. const collection = {
  201. '@type': 'hydra:Collection',
  202. 'hydra:totalItems': 3,
  203. 'hydra:member': [
  204. {id: 1},
  205. {id: 2},
  206. {id: 3},
  207. ]
  208. }
  209. // @ts-ignore
  210. apiRequestService.get = vi.fn(async (url: string) => collection)
  211. // @ts-ignore
  212. entityManager.newInstance = vi.fn((model: typeof ApiResource, props: object) => {
  213. return new DummyApiResource(props)
  214. })
  215. const result = await entityManager.fetchCollection(DummyApiResource, null)
  216. expect(apiRequestService.get).toHaveBeenCalledWith('api/dummyResource', null)
  217. expect(entityManager.newInstance).toHaveBeenCalledTimes(3)
  218. expect(entityManager.newInstance).toHaveBeenCalledWith(DummyApiResource, {id: 1})
  219. expect(entityManager.newInstance).toHaveBeenCalledWith(DummyApiResource, {id: 2})
  220. expect(entityManager.newInstance).toHaveBeenCalledWith(DummyApiResource, {id: 3})
  221. expect(result.items).toEqual([
  222. new DummyApiResource({id: 1}),
  223. new DummyApiResource({id: 2}),
  224. new DummyApiResource({id: 3})
  225. ])
  226. expect(result.pagination, 'default pagination').toEqual({
  227. first: 1,
  228. last: 1,
  229. next: undefined,
  230. previous: undefined
  231. })
  232. })
  233. test('with a parent', async () => {
  234. const collection = {
  235. '@type': 'hydra:Collection',
  236. 'hydra:totalItems': 3,
  237. 'hydra:member': [
  238. {id: 1},
  239. {id: 2},
  240. {id: 3},
  241. ]
  242. }
  243. // @ts-ignore
  244. apiRequestService.get = vi.fn(async (url: string) => collection)
  245. // @ts-ignore
  246. entityManager.newInstance = vi.fn((model: typeof ApiResource, props: object) => {
  247. return new DummyApiResource(props)
  248. })
  249. const parent = new DummyApiModel()
  250. parent.id = 100
  251. parent.entity = 'dummyModel' // TODO: je ne comprend pas pqoi cette ligne est nécessaire...
  252. await entityManager.fetchCollection(DummyApiResource, parent)
  253. expect(apiRequestService.get).toHaveBeenCalledWith('api/dummyModel/100/dummyResource', null)
  254. })
  255. test('with a query', async () => {
  256. const collection = {
  257. '@type': 'hydra:Collection',
  258. 'hydra:totalItems': 3,
  259. 'hydra:member': [
  260. {id: 1},
  261. {id: 2},
  262. {id: 3},
  263. ]
  264. }
  265. // @ts-ignore
  266. apiRequestService.get = vi.fn(async (url: string) => collection)
  267. // @ts-ignore
  268. entityManager.newInstance = vi.fn((model: typeof ApiResource, props: object) => {
  269. return new DummyApiResource(props)
  270. })
  271. await entityManager.fetchCollection(DummyApiResource, null, { page: 10 })
  272. expect(apiRequestService.get).toHaveBeenCalledWith('api/dummyResource', { page: 10 })
  273. })
  274. test('with pagination', async () => {
  275. const collection = {
  276. '@type': 'hydra:Collection',
  277. 'hydra:totalItems': 1000,
  278. 'hydra:member': [],
  279. 'hydra:view': {
  280. "@id": "/api/subdomains?organization=498&page=50",
  281. 'hydra:first': '/api/subdomains?organization=498&page=1',
  282. 'hydra:last': '/api/subdomains?organization=498&page=100',
  283. 'hydra:next': '/api/subdomains?organization=498&page=51',
  284. 'hydra:previous': '/api/subdomains?organization=498&page=49'
  285. }
  286. }
  287. // @ts-ignore
  288. apiRequestService.get = vi.fn(async (url: string) => collection)
  289. const result = await entityManager.fetchCollection(DummyApiResource, null)
  290. expect(result.totalItems).toEqual(1000)
  291. expect(result.pagination.first).toEqual(1)
  292. expect(result.pagination.last).toEqual(100)
  293. expect(result.pagination.previous).toEqual(49)
  294. expect(result.pagination.next).toEqual(51)
  295. })
  296. })
  297. describe('persist', () => {
  298. test('new entity (POST)', async () => {
  299. const instance = new DummyApiModel({id: 'tmp1', name: 'bob'})
  300. instance.isNew = vi.fn(() => true)
  301. // @ts-ignore
  302. instance.$toJson = vi.fn(() => {
  303. return {id: 'tmp1', name: 'bob'}
  304. })
  305. // TODO: attendre de voir si cet appel est nécessaire dans l'entity manager
  306. // entityManager.cast = vi.fn((model: typeof ApiResource, entity: ApiResource): ApiResource => entity)
  307. const response = { id: 1, name: 'bob' }
  308. // @ts-ignore
  309. apiRequestService.post = vi.fn((url, data) => response)
  310. // @ts-ignore
  311. entityManager.newInstance = vi.fn((model, response) => {
  312. const newEntity = new DummyApiModel(response)
  313. // @ts-ignore
  314. newEntity.id = response.id
  315. // @ts-ignore
  316. newEntity.name = response.name
  317. return newEntity
  318. })
  319. // @ts-ignore
  320. entityManager.removeTempAfterPersist = vi.fn()
  321. const result = await entityManager.persist(DummyApiModel, instance)
  322. // temp id should have been purged from the posted data
  323. expect(apiRequestService.post).toHaveBeenCalledWith('api/dummyModel', {name: 'bob'})
  324. expect(entityManager.newInstance).toHaveBeenCalledWith(DummyApiModel, response)
  325. // @ts-ignore
  326. expect(entityManager.removeTempAfterPersist).toHaveBeenCalledWith(DummyApiModel, instance.id)
  327. expect(result.id).toEqual(1)
  328. expect(result.name).toEqual('bob')
  329. })
  330. test('existing entity (PUT)', async () => {
  331. const props = {id: 1, name: 'bob'}
  332. const entity = new DummyApiModel(props)
  333. entity.id = 1
  334. entity.isNew = vi.fn(() => false)
  335. // @ts-ignore
  336. entity.$toJson = vi.fn(() => props)
  337. // TODO: attendre de voir si cet appel est nécessaire dans l'entity manager
  338. // entityManager.cast = vi.fn((model: typeof ApiResource, entity: ApiResource): ApiResource => entity)
  339. // @ts-ignore
  340. apiRequestService.put = vi.fn((url, data) => props)
  341. // @ts-ignore
  342. entityManager.newInstance = vi.fn((model, response) => {
  343. const newEntity = new DummyApiModel(response)
  344. // @ts-ignore
  345. newEntity.id = response.id
  346. // @ts-ignore
  347. newEntity.name = response.name
  348. return newEntity
  349. })
  350. // @ts-ignore
  351. entityManager.removeTempAfterPersist = vi.fn()
  352. const result = await entityManager.persist(DummyApiModel, entity)
  353. expect(apiRequestService.put).toHaveBeenCalledWith('api/dummyModel/1', {id: 1, name: 'bob'})
  354. expect(entityManager.newInstance).toHaveBeenCalledWith(DummyApiModel, props)
  355. // @ts-ignore
  356. expect(entityManager.removeTempAfterPersist).toHaveBeenCalledTimes(0)
  357. expect(result.id).toEqual(1)
  358. expect(result.name).toEqual('bob')
  359. })
  360. })
  361. describe('patch', () => {
  362. test('simple call', async () => {
  363. const props = {id: 1, name: 'bobby'}
  364. // @ts-ignore
  365. apiRequestService.put = vi.fn((url, data) => props)
  366. // @ts-ignore
  367. entityManager.newInstance = vi.fn((model, response) => {
  368. const newEntity = new DummyApiModel(response)
  369. // @ts-ignore
  370. newEntity.id = response.id
  371. // @ts-ignore
  372. newEntity.name = response.name
  373. return newEntity
  374. })
  375. const result = await entityManager.patch(DummyApiModel, 1, {name: 'bobby'})
  376. expect(apiRequestService.put).toHaveBeenCalledWith('api/dummyModel/1', '{"name":"bobby"}')
  377. expect(entityManager.newInstance).toHaveBeenCalledWith(DummyApiModel, {id: 1, name: 'bobby'})
  378. expect(result.id).toEqual(1)
  379. expect(result.name).toEqual('bobby')
  380. })
  381. })
  382. describe('delete', () => {
  383. test('delete non persisted entity', () => {
  384. const entity = new DummyApiModel()
  385. entity.isNew = vi.fn(() => true)
  386. entity.id = 'tmp123'
  387. // @ts-ignore
  388. const repo = vi.fn() as Repository<ApiResource>
  389. // @ts-ignore
  390. entityManager.getRepository = vi.fn((model: typeof ApiResource) => {
  391. return model === DummyApiModel ? repo : null
  392. })
  393. apiRequestService.delete = vi.fn()
  394. // @ts-ignore
  395. repo.destroy = vi.fn((id: number) => null)
  396. entityManager.delete(DummyApiModel, entity)
  397. expect(entityManager.getRepository).toHaveBeenCalledWith(DummyApiModel)
  398. expect(apiRequestService.delete).toHaveBeenCalledTimes(0)
  399. expect(repo.destroy).toHaveBeenCalledWith('tmp123')
  400. })
  401. test('delete persisted entity', async () => {
  402. const entity = new DummyApiModel()
  403. entity.isNew = vi.fn(() => false)
  404. entity.id = 1
  405. // @ts-ignore
  406. const repo = vi.fn() as Repository<ApiResource>
  407. // @ts-ignore
  408. entityManager.getRepository = vi.fn((model: typeof ApiResource) => {
  409. return model === DummyApiModel ? repo : null
  410. })
  411. // @ts-ignore
  412. apiRequestService.delete = vi.fn((id: number) => null)
  413. // @ts-ignore
  414. repo.destroy = vi.fn((id: number) => null)
  415. await entityManager.delete(DummyApiModel, entity)
  416. expect(entityManager.getRepository).toHaveBeenCalledWith(DummyApiModel)
  417. expect(apiRequestService.delete).toHaveBeenCalledWith('api/dummyModel/1')
  418. expect(repo.destroy).toHaveBeenCalledWith(1)
  419. })
  420. })
  421. describe('reset', () => {
  422. test('simple call', () => {
  423. const entity = new DummyApiModel()
  424. entity.id = 1
  425. entity.name = 'paul'
  426. const initialEntity = new DummyApiModel()
  427. initialEntity.id = 1
  428. initialEntity.name = 'serges'
  429. // @ts-ignore
  430. entityManager.getInitialStateOf = vi.fn((model: typeof ApiResource, id: string | number) => initialEntity)
  431. // @ts-ignore
  432. const repo = vi.fn() as Repository<ApiResource>
  433. // @ts-ignore
  434. entityManager.getRepository = vi.fn((model: typeof ApiResource) => {
  435. return model === DummyApiModel ? repo : null
  436. })
  437. // @ts-ignore
  438. repo.save = vi.fn((data: any) => null)
  439. const result = entityManager.reset(DummyApiModel, entity)
  440. // @ts-ignore
  441. expect(entityManager.getInitialStateOf).toHaveBeenCalledWith(DummyApiModel, 1)
  442. expect(repo.save).toHaveBeenCalledWith(initialEntity)
  443. expect(result).toEqual(initialEntity)
  444. })
  445. test('no initial state stored', () => {
  446. const entity = new DummyApiModel()
  447. entity.id = 1
  448. // @ts-ignore
  449. entityManager.getInitialStateOf = vi.fn((model: typeof ApiResource, id: string | number) => null)
  450. expect(() => entityManager.reset(DummyApiModel, entity)).toThrowError(
  451. 'no initial state recorded for this object - abort [dummyModel/1]'
  452. )
  453. })
  454. })
  455. describe('flush', () => {
  456. test('simple call', () => {
  457. // @ts-ignore
  458. const repo = vi.fn() as Repository<ApiResource>
  459. // @ts-ignore
  460. entityManager.getRepository = vi.fn((model: typeof ApiResource) => {
  461. return model === DummyApiModel ? repo : null
  462. })
  463. repo.flush = vi.fn()
  464. entityManager.flush(DummyApiModel)
  465. expect(repo.flush).toHaveBeenCalled()
  466. })
  467. })
  468. describe('isNewEntity', () => {
  469. test('with new entity', () => {
  470. const entity = new DummyApiModel()
  471. entity.isNew = vi.fn(() => true)
  472. // @ts-ignore
  473. const repo = vi.fn() as Repository<ApiResource>
  474. // @ts-ignore
  475. entityManager.getRepository = vi.fn((model: typeof ApiResource) => {
  476. return model === DummyApiModel ? repo : null
  477. })
  478. // @ts-ignore
  479. repo.find = vi.fn((id: number) => entity)
  480. const result = entityManager.isNewInstance(DummyApiModel, 1)
  481. expect(result).toBeTruthy()
  482. })
  483. test('with existing entity', () => {
  484. const entity = new DummyApiModel()
  485. entity.isNew = vi.fn(() => false)
  486. // @ts-ignore
  487. const repo = vi.fn() as Repository<ApiResource>
  488. // @ts-ignore
  489. entityManager.getRepository = vi.fn((model: typeof ApiResource) => {
  490. return model === DummyApiModel ? repo : null
  491. })
  492. // @ts-ignore
  493. repo.find = vi.fn((id: number) => entity)
  494. const result = entityManager.isNewInstance(DummyApiModel, 1)
  495. expect(result).toBeFalsy()
  496. })
  497. test('non-existing entity', () => {
  498. // @ts-ignore
  499. const repo = vi.fn() as Repository<ApiResource>
  500. // @ts-ignore
  501. entityManager.getRepository = vi.fn((model: typeof ApiResource) => {
  502. return model === DummyApiModel ? repo : null
  503. })
  504. // @ts-ignore
  505. repo.find = vi.fn((id: number) => null)
  506. console.error = vi.fn()
  507. const result = entityManager.isNewInstance(DummyApiModel, 1)
  508. expect(result).toBeFalsy()
  509. expect(console.error).toHaveBeenCalledWith('dummyModel/1 does not exist!')
  510. })
  511. })
  512. describe('saveInitialState', () => {
  513. test('simple call', () => {
  514. // @ts-ignore
  515. const entity = { id: 1, name: 'bob' } as DummyApiResource
  516. // @ts-ignore
  517. const repo = vi.fn() as Repository<ApiResource>
  518. // @ts-ignore
  519. entityManager.getRepository = vi.fn((model: typeof ApiResource) => {
  520. return model === DummyApiResource ? repo : null
  521. })
  522. // @ts-ignore
  523. repo.save = vi.fn((record: Element) => null)
  524. // @ts-ignore
  525. entityManager.saveInitialState(DummyApiResource, entity)
  526. expect(repo.save).toHaveBeenCalledWith({ id: '_clone_1', name: 'bob' })
  527. expect(entity.id).toEqual(1)
  528. })
  529. })
  530. describe('getInitialStateOf', () => {
  531. test('with initial state', () => {
  532. // @ts-ignore
  533. const entity = { id: 1, name: 'bob' } as DummyApiResource
  534. // @ts-ignore
  535. const repo = vi.fn() as Repository<ApiResource>
  536. // @ts-ignore
  537. entityManager.getRepository = vi.fn((model: typeof ApiResource) => {
  538. return model === DummyApiResource ? repo : null
  539. })
  540. // @ts-ignore
  541. repo.find = vi.fn((id: number | string) => {
  542. // @ts-ignore
  543. return { id: 1, name: 'robert' } as DummyApiResource
  544. })
  545. // @ts-ignore
  546. const result = entityManager.getInitialStateOf(DummyApiResource, 1) as DummyApiResource
  547. expect(repo.find).toHaveBeenCalledWith('_clone_1')
  548. expect(result.id).toEqual(1)
  549. expect(result.name).toEqual('robert')
  550. })
  551. test('without initial state', () => {
  552. // @ts-ignore
  553. const repo = vi.fn() as Repository<ApiResource>
  554. // @ts-ignore
  555. entityManager.getRepository = vi.fn((model: typeof ApiResource) => {
  556. return model === DummyApiResource ? repo : null
  557. })
  558. // @ts-ignore
  559. repo.find = vi.fn((id: number | string) => null)
  560. // @ts-ignore
  561. const result = entityManager.getInitialStateOf(DummyApiResource, 1) as DummyApiResource
  562. expect(repo.find).toHaveBeenCalledWith('_clone_1')
  563. expect(result).toEqual(null)
  564. })
  565. })
  566. describe('removeTempAfterPersist', () => {
  567. test('simple call', () => {
  568. // @ts-ignore
  569. const entity = new DummyApiResource()
  570. entity.id = 'tmp123'
  571. entity.isNew = vi.fn(() => true)
  572. // @ts-ignore
  573. const repo = vi.fn() as Repository<ApiResource>
  574. // @ts-ignore
  575. entityManager.getRepository = vi.fn((model: typeof ApiResource) => {
  576. return model === DummyApiResource ? repo : null
  577. })
  578. // @ts-ignore
  579. repo.find = vi.fn((id: number | string) => entity)
  580. // @ts-ignore
  581. repo.destroy = vi.fn()
  582. // @ts-ignore
  583. entityManager.removeTempAfterPersist(DummyApiResource, 'tmp123')
  584. expect(repo.destroy).toHaveBeenCalledWith('tmp123')
  585. expect(repo.destroy).toHaveBeenCalledWith('_clone_tmp123')
  586. })
  587. test('entity is not temporary', () => {
  588. // @ts-ignore
  589. const entity = new DummyApiResource()
  590. entity.id = 1
  591. entity.isNew = vi.fn(() => false)
  592. // @ts-ignore
  593. const repo = vi.fn() as Repository<ApiResource>
  594. // @ts-ignore
  595. entityManager.getRepository = vi.fn((model: typeof ApiResource) => {
  596. return model === DummyApiResource ? repo : null
  597. })
  598. // @ts-ignore
  599. repo.find = vi.fn((id: number | string) => entity)
  600. // @ts-ignore
  601. repo.destroy = vi.fn()
  602. // @ts-ignore
  603. expect(() => entityManager.removeTempAfterPersist(DummyApiResource, 'tmp123')).toThrowError(
  604. 'Error: Can not remove a non-temporary model instance'
  605. )
  606. expect(repo.destroy).toHaveBeenCalledTimes(0)
  607. })
  608. test('entity does not exist', () => {
  609. // @ts-ignore
  610. const repo = vi.fn() as Repository<ApiResource>
  611. // @ts-ignore
  612. entityManager.getRepository = vi.fn((model: typeof ApiResource) => {
  613. return model === DummyApiResource ? repo : null
  614. })
  615. // @ts-ignore
  616. repo.find = vi.fn((id: number | string) => null)
  617. // @ts-ignore
  618. repo.destroy = vi.fn()
  619. console.error = vi.fn()
  620. // @ts-ignore
  621. entityManager.removeTempAfterPersist(DummyApiResource, 'tmp123')
  622. expect(repo.destroy).toHaveBeenCalledTimes(0)
  623. expect(console.error).toHaveBeenCalledWith('dummyResource/tmp123 does not exist!')
  624. })
  625. })