Skip to content
This repository has been archived by the owner on Apr 12, 2022. It is now read-only.

Throw error when mapping to source's own property while primary key belongs to another source #2574

Merged
merged 2 commits into from
Nov 29, 2021

Conversation

edmundito
Copy link
Contributor

This change ensures that it's not possible to set a mapping to a property in the source when another source owns the primary key by throwing an error.

When running grouparoo config where two different sources (PG users and PG purchases) in the same model point to their own properties in the mapping, we see an error such as:

warning: [ config ] error with Source `PG users` (pg_users): 'PG users' cannot map 'id' to own
Property 'userId'. 'PG users' must map to a Property from primary Source 'Pg purchases'. 

Related: #2572

Change description

Description here

Checklists

Development

  • Application changes have been tested appropriately

Impact

  • Code follows company security practices and guidelines
  • Security impact of change has been considered
  • Performance impact of change has been considered
  • Possible migration needs considered (model migrations, config migrations, etc.)

Please explain any security, performance, migration, or other impacts if relevant:

In the case that a customer had already setup a configuration where two sources were mapping to their own keys, they would need to update the mapping in the config files.

Code review

  • Pull request has a descriptive title and context useful to a reviewer. Screenshots or screencasts are attached where applicable.
  • Relevant tags have been added to the PR (bug, enhancement, internal, etc.)

@edmundito edmundito added the bug Something isn't working label Nov 24, 2021
Comment on lines 118 to 124
if (otherSourcePrimaryKey && property.sourceId === instance.id) {
throw new Error(
`'${instance.name}' cannot map '${remoteKey}' to own Property '${key}'. '${source.name}' must map to a Property from primary Source '${otherSourcePrimaryKey.source.name}'.`
);
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still thinking about the wording. I think in the case this happen the primary source is ambiguous. For example if the Users and Purchases source point to their own properties, it's not clear which is the primary source. I'm open for feedback.

Maybe it should just say while {sourceB} is mapping to its own property {propertyB} ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about something like

`${otherSourcePrimaryKey.soruce.name} is the primary source for the ${instance.model.name} Model - ${instance.name} requires a mapping back to ${otherSourcePrimaryKey.soruce.name}`

users-table is the primary source for the profiles - purchases-table requires a mapping back to users-table`

@@ -634,9 +634,18 @@ describe("models/property", () => {
});

describe("with plugin", () => {
// let model: GrouparooModel;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can remove

Comment on lines +744 to +748
test("will throw error when mapping to own property and primary key is owned by other source", async () => {
await expect(source.setMapping({ email: "myEmail" })).rejects.toThrow(
/cannot map 'email' to own Property 'myEmail'/
);
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the new test - the other changes are cleanup / clarifications based on this new behavior. Initially I would have guessed this change would have required a more complex series of tests... but... it doesn't! We've got other tests confirming that the first property (bootstrap) still works like expect

Comment on lines +78 to +92
? await Property.findOne({
include: {
model: Source,
required: true,
where: {
modelId: instance.modelId,
},
},
where: {
isPrimaryKey: true,
sourceId: {
[Op.ne]: instance.id,
},
},
})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 great single query to find this!

Comment on lines 118 to 124
if (otherSourcePrimaryKey && property.sourceId === instance.id) {
throw new Error(
`'${instance.name}' cannot map '${remoteKey}' to own Property '${key}'. '${source.name}' must map to a Property from primary Source '${otherSourcePrimaryKey.source.name}'.`
);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about something like

`${otherSourcePrimaryKey.soruce.name} is the primary source for the ${instance.model.name} Model - ${instance.name} requires a mapping back to ${otherSourcePrimaryKey.soruce.name}`

users-table is the primary source for the profiles - purchases-table requires a mapping back to users-table`

…elongs to another source

* Update tests
* Add new test to verify conditon
* Improve error logging in Property when checking for uniue property
@edmundito edmundito force-pushed the 180403934-primarykey-cfg-validation branch from 8e8aa34 to e22196f Compare November 29, 2021 14:47
@edmundito edmundito merged commit 7059590 into main Nov 29, 2021
@edmundito edmundito deleted the 180403934-primarykey-cfg-validation branch November 29, 2021 16:33
@edmundito edmundito linked an issue Jan 10, 2022 that may be closed by this pull request
1 task
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Feature]: Update UI to be more model-centric
2 participants