Skip to content

Commit

Permalink
pass collection to model when initializing the model
Browse files Browse the repository at this point in the history
  • Loading branch information
ivandotv committed Jul 1, 2022
1 parent 9885620 commit 8a3bf02
Show file tree
Hide file tree
Showing 12 changed files with 72 additions and 73 deletions.
5 changes: 5 additions & 0 deletions .changeset/flat-pillows-repeat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@fuerte/core': major
---

If the model is added in to the collection when it is initialized, assign `collection` property to the model.
64 changes: 16 additions & 48 deletions packages/core/src/__tests__/__fixtures__/TestCollection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,65 +19,33 @@ export class TestCollection extends Collection<
typeof testModelFactory,
TestTransport
> {
onReset(added: TestModel[], removed: TestModel[], fromLoad = false): void {
super.onReset(added, removed)
}
onReset(added: TestModel[], removed: TestModel[], fromLoad = false): void {}

onRemoved(model: TestModel): void {
super.onRemoved(model)
}
onRemoved(model: TestModel): void {}

onAdded(model: TestModel): void {
super.onAdded(model)
}
onAdded(model: TestModel): void {}

onModelCreateData(data: any): void {
super.onModelCreateData(data)
onSaveSuccess(data: SaveSuccessCallback<TestModel, TestTransport>): void {}

return data
}
onSaveStart(data: SaveStartCallback<TestModel, TestTransport>): void {}

onSaveSuccess(data: SaveSuccessCallback<TestModel, TestTransport>): void {
super.onSaveSuccess(data)
}
onSaveError(data: SaveErrorCallback<TestModel, TestTransport>): void {}

onSaveStart(data: SaveStartCallback<TestModel, TestTransport>): void {
super.onSaveStart(data)
}
onDeleteStart(data: DeleteStartCallback<TestModel, TestTransport>): void {}

onSaveError(data: SaveErrorCallback<TestModel, TestTransport>): void {
super.onSaveError(data)
}
onDeleteSuccess(
data: DeleteSuccessCallback<TestModel, TestTransport>
): void {}

onDeleteStart(data: DeleteStartCallback<TestModel, TestTransport>): void {
super.onDeleteStart(data)
}
onDeleteError(data: DeleteErrorCallback<TestModel, TestTransport>): void {}

onDeleteSuccess(data: DeleteSuccessCallback<TestModel, TestTransport>): void {
super.onDeleteSuccess(data)
}
onLoadStart(data: LoadStartCallback<TestModel, TestTransport>): void {}

onDeleteError(data: DeleteErrorCallback<TestModel, TestTransport>): void {
super.onDeleteError(data)
}
onLoadSuccess(data: LoadSuccessCallback<TestModel, TestTransport>): void {}

onLoadStart(data: LoadStartCallback<TestModel, TestTransport>): void {
super.onLoadStart(data)
}
onLoadError(data: LoadErrorCallback<TestModel, TestTransport>): void {}

onLoadSuccess(data: LoadSuccessCallback<TestModel, TestTransport>): void {
super.onLoadSuccess(data)
}
onSerialize() {}

onLoadError(data: LoadErrorCallback<TestModel, TestTransport>): void {
super.onLoadError(data)
}

onSerialize() {
super.onSerialize()
}

onDestroy() {
super.onDestroy()
}
onDestroy() {}
}
2 changes: 0 additions & 2 deletions packages/core/src/__tests__/__fixtures__/TestModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,5 +96,3 @@ export class TestModel extends Model<TestCollection> {
super.onDestroy()
}
}

const model = new TestModel()
2 changes: 1 addition & 1 deletion packages/core/src/__tests__/__fixtures__/TestTransport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export class TestTransport implements Transport<TestModel> {
return Promise.resolve({ data: { id: nanoid() } })
}

delete(_model: TestModel, config: any) {
delete(_model: TestModel, config: any): Promise<{ data: any }> {
return Promise.resolve({ data: undefined })
}

Expand Down
1 change: 1 addition & 0 deletions packages/core/src/__tests__/collection-add.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ describe('Collection - add #add #collection', () => {
expect(collection.models).toHaveLength(1)
expect(collection.models[0]).toBe(model)
expect(addedModel).toBe(model)
expect(addedModel?.getCollection()).toBe(collection)
})

test('When adding a single model, return undefined if the model is already in the collection', () => {
Expand Down
5 changes: 5 additions & 0 deletions packages/core/src/__tests__/collection-load.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,11 @@ describe('Collection - load #load #collection', () => {
expect.objectContaining({ foo: 'oldModelTwo' })
])
)

for (const model of result.added!) {
expect(model.getCollection()).toBe(collection)
}

expect(collection.models).toHaveLength(fixtures.rawModelData.length)
})

Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/__tests__/collection-reset.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ describe('Collection - reset #reset #collection', () => {
await collection.reset(fixtures.rawModelData)

expect(collection.models).toHaveLength(fixtures.rawModelData.length)
expect(collection.models).toHaveLength(fixtures.rawModelData.length)
for (const model of collection.models) {
expect(model.getCollection()).toBe(collection)
}
})

test('If the collection is not empty, clear it', async () => {
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/__tests__/collection-save.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ describe('Collection - save #save #collection', () => {
await collection.save(model)

expect(collection.models[0]).toBe(model)
expect(model.getCollection()).toBe(collection)
})

test('When save is in progress, we can retrieve all the models that are in the process of saving', async () => {
Expand Down
7 changes: 3 additions & 4 deletions packages/core/src/__tests__/collection.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,16 +70,15 @@ describe('Collection #collection', () => {
expect(model.bar).toBe(modelData.bar)
expect(model.id).toBe(modelData.id)
})
test('Create the model via the create method', () => {
test('When model is created it is not added to the collection', () => {
const collection = fixtures.collection()
const modelData = { foo: 'new foo', bar: 'new bar', id: 'new id' }

const model = collection.create(modelData)

expect(model).toBeInstanceOf(TestModel)
expect(model.foo).toBe(modelData.foo)
expect(model.bar).toBe(modelData.bar)
expect(model.id).toBe(modelData.id)
expect(model.getCollection()).toBeUndefined()
expect(collection.models).toHaveLength(0)
})

test('Retrieve new models', () => {
Expand Down
25 changes: 25 additions & 0 deletions packages/core/src/__tests__/model.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,23 @@ describe('Model #model', () => {
expect(collection.models).toHaveLength(0)
})

test('when there is a delete error, it can be retrieved later from the model', async () => {
const transport = fixtures.transport()
const collection = fixtures.collection(fixtures.factory(), transport)
const model = fixtures.model()

const errorResponse = 'internal_server_error'
jest
.spyOn(transport, 'delete')
.mockImplementation(() => Promise.reject(errorResponse))
await collection.save(model)

await model.delete(undefined)

expect(model.deleteError).toBe(errorResponse)
expect(model.hasErrors).toBe(true)
})

test('calling model.delete will throw if the model is not a part of the collection', async () => {
const model = fixtures.model()

Expand All @@ -93,4 +110,12 @@ describe('Model #model', () => {

expect(model.getCollection()).toBe(collection)
})

test('model "isNew" property can be changed', () => {
const model = fixtures.model()

model.setIsNew(false)

expect(model.isNew).toBe(false)
})
})
26 changes: 10 additions & 16 deletions packages/core/src/collection/Collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,7 @@ export class Collection<
continue
}
const model = await Promise.resolve(
this.createModel(modifiedData, false)
this._create(modifiedData, false, this)
)
if (this.notPresent(model)) {
modelsToAdd.push(model)
Expand Down Expand Up @@ -851,29 +851,21 @@ export class Collection<
* @returns newly created model
*/
create(data: Parameters<TFactory>[0]): ReturnType<TFactory> {
const result = this.factory(data)
if (isPromise(result)) {
result.then((model: TModel) => {
model.init()
})
} else {
result.init()
}

return this.createModel(data, true)
return this._create(data, true)
}

protected createModel(
protected _create(
data: Parameters<TFactory>[0],
asNew = true
asNew = true,
collection?: this
): ReturnType<TFactory> {
const result = this.factory(data)
if (isPromise(result)) {
result.then((model: TModel) => {
model.init(asNew)
model.init(asNew, collection)
})
} else {
result.init(asNew)
result.init(asNew, collection)
}

return result as ReturnType<TFactory>
Expand Down Expand Up @@ -1104,7 +1096,9 @@ export class Collection<
continue
}

const model = await Promise.resolve(this.createModel(modifiedData))
const model = await Promise.resolve(
this._create(modifiedData, true, this)
)

modelsToAdd.push(model)
}
Expand Down
3 changes: 1 addition & 2 deletions packages/core/src/model/Model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,6 @@ export abstract class Model<

abstract serialize(): any

//TODO - add collection
// @internal
init(asNew = true, collection?: TCollection): void {
if (this.initialized) return
Expand Down Expand Up @@ -386,7 +385,7 @@ export abstract class Model<

/**
* Set `isNew` property on the model. This method should generally not be used by the client code.
* Transport layer can check this property in order to determine if it should use `POST` or `PATCH` methods
* Transport layer could use this property in order to determine if it should use `POST` or `PATCH` methods
* for persistence.
*
* @param isNew - true if the model should be marked as new
Expand Down

0 comments on commit 8a3bf02

Please sign in to comment.