entityManager.test.ts 25 KB

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