Skip to content

Commit

Permalink
Merge pull request #36 from dkpoult/fix/stop-creating-unnecessary-ass…
Browse files Browse the repository at this point in the history
…ociation

fix: stop factory creating unused initial association
  • Loading branch information
thiagomini authored Aug 14, 2024
2 parents 33c60c3 + 59229d7 commit 525a883
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 1 deletion.
10 changes: 9 additions & 1 deletion src/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ export class Factory<Model, Attributes, Params = any, ReturnType = Model> {
): Promise<ReturnType> {
const defaultAttributesWithAssociations = await this.resolveAssociations(
'create',
override,
additionalParams,
);

Expand Down Expand Up @@ -190,6 +191,7 @@ export class Factory<Model, Attributes, Params = any, ReturnType = Model> {

const attributesWithAssociations = await this.resolveAssociations(
'build',
override,
additionalParams,
);

Expand Down Expand Up @@ -409,11 +411,17 @@ export class Factory<Model, Attributes, Params = any, ReturnType = Model> {

private async resolveAssociations(
associationType: 'build' | 'create',
override?: Override<Attributes, ReturnType>,
additionalParams?: Params,
): Promise<Attributes> {
const attributes = await this.defaultAttributesFactory({
const rawAttributes = await this.defaultAttributesFactory({
transientParams: additionalParams,
});
const attributes = mergeDeep<Override<Attributes, ReturnType>>(
rawAttributes as Override<Attributes, ReturnType>,
override,
);

const defaultWithAssociations: Dictionary = {};

for (const prop in attributes as Dictionary) {
Expand Down
54 changes: 54 additions & 0 deletions test/factory.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { FactoryGirl } from '@src/factory-girl';
import { plainObject } from '@src/utils';
import { PartialDeep } from 'type-fest';
import { ModelAdapter, ObjectAdapter, SequelizeAdapter } from '../lib';
import { InstanceOrInterface } from '../lib/types/instance-or-interface.type';
import { Association, DeepPartialAttributes } from '../src';

type User = {
Expand Down Expand Up @@ -488,6 +490,58 @@ describe('Factory', () => {
expect(address).toMatchObject(addressAttributes);
expect(address.userId).toBe(userAttributes.id);
});

it('it should not create overridden associations', async () => {
// Arrange
let createdAdditionalUser = false;

class TestableUserAdapter implements ObjectAdapter<User> {
build(
model: User,
props: PartialDeep<
InstanceOrInterface<User>,
{ recurseIntoArrays: true }
>,
): User {
return props as User;
}
async save(user: User): Promise<User> {
if (user.id !== 100) {
createdAdditionalUser = true;
}
return user;
}
get<K extends keyof User>(model: User, key: K): User[K] {
return model[key];
}
}

const userAttributes = buildUserAttributes();
const addressAttributes = buildAddressAttributes();

const userFactory = FactoryGirl.define(
plainObject<User>(),
() => userAttributes,
new TestableUserAdapter(),
);
const addressFactory = FactoryGirl.define(plainObject<Address>(), () => ({
...addressAttributes,
userId: userFactory.associate('id'),
}));

// Act
const user = await userFactory.create({
id: 100,
});
const address = await addressFactory.create({
userId: user.id,
});

// Assert
expect(createdAdditionalUser).toBeFalsy();
expect(address).toMatchObject(addressAttributes);
expect(address.userId).toBe(user.id);
});
});

describe('createMany', () => {
Expand Down

0 comments on commit 525a883

Please sign in to comment.