Skip to content

Commit 60cc0fb

Browse files
authored
fix: support number ID field generation in StubDatabaseAdapter (#43)
1 parent 0445d3e commit 60cc0fb

File tree

4 files changed

+178
-1
lines changed

4 files changed

+178
-1
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import Entity from '../Entity';
2+
import {
3+
DatabaseAdapterFlavor,
4+
CacheAdapterFlavor,
5+
EntityCompanionDefinition,
6+
} from '../EntityCompanionProvider';
7+
import EntityConfiguration from '../EntityConfiguration';
8+
import { DateField } from '../EntityFields';
9+
import EntityPrivacyPolicy from '../EntityPrivacyPolicy';
10+
import ViewerContext from '../ViewerContext';
11+
import AlwaysAllowPrivacyPolicyRule from '../rules/AlwaysAllowPrivacyPolicyRule';
12+
13+
export type DateIDTestFields = {
14+
id: Date;
15+
};
16+
17+
export const dateIDTestEntityConfiguration = new EntityConfiguration<DateIDTestFields>({
18+
idField: 'id',
19+
tableName: 'simple_test_entity_should_not_write_to_db',
20+
schema: {
21+
id: new DateField({
22+
columnName: 'custom_id',
23+
}),
24+
},
25+
});
26+
27+
export class DateIDTestEntityPrivacyPolicy extends EntityPrivacyPolicy<
28+
DateIDTestFields,
29+
Date,
30+
ViewerContext,
31+
DateIDTestEntity
32+
> {
33+
protected readonly readRules = [
34+
new AlwaysAllowPrivacyPolicyRule<DateIDTestFields, Date, ViewerContext, DateIDTestEntity>(),
35+
];
36+
protected readonly createRules = [
37+
new AlwaysAllowPrivacyPolicyRule<DateIDTestFields, Date, ViewerContext, DateIDTestEntity>(),
38+
];
39+
protected readonly updateRules = [
40+
new AlwaysAllowPrivacyPolicyRule<DateIDTestFields, Date, ViewerContext, DateIDTestEntity>(),
41+
];
42+
protected readonly deleteRules = [
43+
new AlwaysAllowPrivacyPolicyRule<DateIDTestFields, Date, ViewerContext, DateIDTestEntity>(),
44+
];
45+
}
46+
47+
export default class DateIDTestEntity extends Entity<DateIDTestFields, Date, ViewerContext> {
48+
static getCompanionDefinition(): EntityCompanionDefinition<
49+
DateIDTestFields,
50+
Date,
51+
ViewerContext,
52+
DateIDTestEntity,
53+
DateIDTestEntityPrivacyPolicy
54+
> {
55+
return dateIDTestEntityCompanion;
56+
}
57+
}
58+
59+
export const dateIDTestEntityCompanion = {
60+
entityClass: DateIDTestEntity,
61+
entityConfiguration: dateIDTestEntityConfiguration,
62+
databaseAdaptorFlavor: DatabaseAdapterFlavor.POSTGRES,
63+
cacheAdaptorFlavor: CacheAdapterFlavor.REDIS,
64+
privacyPolicyClass: DateIDTestEntityPrivacyPolicy,
65+
};
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import Entity from '../Entity';
2+
import {
3+
DatabaseAdapterFlavor,
4+
CacheAdapterFlavor,
5+
EntityCompanionDefinition,
6+
} from '../EntityCompanionProvider';
7+
import EntityConfiguration from '../EntityConfiguration';
8+
import { NumberField } from '../EntityFields';
9+
import EntityPrivacyPolicy from '../EntityPrivacyPolicy';
10+
import ViewerContext from '../ViewerContext';
11+
import AlwaysAllowPrivacyPolicyRule from '../rules/AlwaysAllowPrivacyPolicyRule';
12+
13+
export type NumberKeyFields = {
14+
id: number;
15+
};
16+
17+
export const numberKeyEntityConfiguration = new EntityConfiguration<NumberKeyFields>({
18+
idField: 'id',
19+
tableName: 'simple_test_entity_should_not_write_to_db',
20+
schema: {
21+
id: new NumberField({
22+
columnName: 'custom_id',
23+
}),
24+
},
25+
});
26+
27+
export class NumberKeyPrivacyPolicy extends EntityPrivacyPolicy<
28+
NumberKeyFields,
29+
number,
30+
ViewerContext,
31+
NumberKeyEntity
32+
> {
33+
protected readonly readRules = [
34+
new AlwaysAllowPrivacyPolicyRule<NumberKeyFields, number, ViewerContext, NumberKeyEntity>(),
35+
];
36+
protected readonly createRules = [
37+
new AlwaysAllowPrivacyPolicyRule<NumberKeyFields, number, ViewerContext, NumberKeyEntity>(),
38+
];
39+
protected readonly updateRules = [
40+
new AlwaysAllowPrivacyPolicyRule<NumberKeyFields, number, ViewerContext, NumberKeyEntity>(),
41+
];
42+
protected readonly deleteRules = [
43+
new AlwaysAllowPrivacyPolicyRule<NumberKeyFields, number, ViewerContext, NumberKeyEntity>(),
44+
];
45+
}
46+
47+
export default class NumberKeyEntity extends Entity<NumberKeyFields, number, ViewerContext> {
48+
static getCompanionDefinition(): EntityCompanionDefinition<
49+
NumberKeyFields,
50+
number,
51+
ViewerContext,
52+
NumberKeyEntity,
53+
NumberKeyPrivacyPolicy
54+
> {
55+
return numberKeyEntityCompanion;
56+
}
57+
}
58+
59+
export const numberKeyEntityCompanion = {
60+
entityClass: NumberKeyEntity,
61+
entityConfiguration: numberKeyEntityConfiguration,
62+
databaseAdaptorFlavor: DatabaseAdapterFlavor.POSTGRES,
63+
cacheAdaptorFlavor: CacheAdapterFlavor.REDIS,
64+
privacyPolicyClass: NumberKeyPrivacyPolicy,
65+
};

packages/entity/src/utils/testing/StubDatabaseAdapter.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import EntityDatabaseAdapter, {
88
TableQuerySelectionModifiers,
99
OrderByOrdering,
1010
} from '../../EntityDatabaseAdapter';
11+
import { StringField, NumberField } from '../../EntityFields';
1112
import {
1213
getDatabaseFieldForEntityField,
1314
FieldTransformerMap,
@@ -127,6 +128,20 @@ export default class StubDatabaseAdapter<T> extends EntityDatabaseAdapter<T> {
127128
throw new Error('Raw WHERE clauses not supported for StubDatabaseAdapter');
128129
}
129130

131+
private generateRandomID(): any {
132+
const idSchemaField = this.entityConfiguration2.schema.get(this.entityConfiguration2.idField);
133+
invariant(idSchemaField, `No schema field found for ${this.entityConfiguration2.idField}`);
134+
if (idSchemaField instanceof StringField) {
135+
return uuidv4();
136+
} else if (idSchemaField instanceof NumberField) {
137+
return Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
138+
} else {
139+
throw new Error(
140+
`Unsupported ID type for StubDatabaseAdapter: ${idSchemaField.constructor.name}`
141+
);
142+
}
143+
}
144+
130145
protected async insertInternalAsync(
131146
_queryInterface: any,
132147
_tableName: string,
@@ -137,7 +152,7 @@ export default class StubDatabaseAdapter<T> extends EntityDatabaseAdapter<T> {
137152
this.entityConfiguration2.idField
138153
);
139154
const objectToInsert = {
140-
[idField]: uuidv4(),
155+
[idField]: this.generateRandomID(),
141156
...object,
142157
};
143158
this.objects.push(objectToInsert);

packages/entity/src/utils/testing/__tests__/StubDatabaseAdapter-test.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,19 @@ import { instance, mock } from 'ts-mockito';
22

33
import { OrderByOrdering } from '../../../EntityDatabaseAdapter';
44
import { EntityNonTransactionalQueryContext } from '../../../EntityQueryContext';
5+
import {
6+
DateIDTestFields,
7+
dateIDTestEntityConfiguration,
8+
} from '../../../testfixtures/DateIDTestEntity';
9+
import {
10+
SimpleTestFields,
11+
simpleTestEntityConfiguration,
12+
} from '../../../testfixtures/SimpleTestEntity';
513
import { TestFields, testEntityConfiguration } from '../../../testfixtures/TestEntity';
14+
import {
15+
NumberKeyFields,
16+
numberKeyEntityConfiguration,
17+
} from '../../../testfixtures/TestEntityNumberKey';
618
import StubDatabaseAdapter from '../StubDatabaseAdapter';
719

820
describe(StubDatabaseAdapter, () => {
@@ -206,4 +218,24 @@ describe(StubDatabaseAdapter, () => {
206218
expect(databaseAdapter.getAllObjectsForTest()).toHaveLength(0);
207219
});
208220
});
221+
222+
it('supports string and number IDs', async () => {
223+
const queryContext = instance(mock(EntityNonTransactionalQueryContext));
224+
const databaseAdapter1 = new StubDatabaseAdapter<SimpleTestFields>(
225+
simpleTestEntityConfiguration
226+
);
227+
const insertedObject1 = await databaseAdapter1.insertAsync(queryContext, {});
228+
expect(typeof insertedObject1.id).toBe('string');
229+
230+
const databaseAdapter2 = new StubDatabaseAdapter<NumberKeyFields>(numberKeyEntityConfiguration);
231+
const insertedObject2 = await databaseAdapter2.insertAsync(queryContext, {});
232+
expect(typeof insertedObject2.id).toBe('number');
233+
234+
const databaseAdapter3 = new StubDatabaseAdapter<DateIDTestFields>(
235+
dateIDTestEntityConfiguration
236+
);
237+
await expect(databaseAdapter3.insertAsync(queryContext, {})).rejects.toThrowError(
238+
'Unsupported ID type for StubDatabaseAdapter: DateField'
239+
);
240+
});
209241
});

0 commit comments

Comments
 (0)