Skip to content

Commit

Permalink
warn from using one-to-many association
Browse files Browse the repository at this point in the history
  • Loading branch information
ivy-lgi committed Dec 12, 2024
1 parent 93eb8d2 commit a85d1de
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Association, EntityClassField } from '@axonivy/dataclass-editor-protocol';
import { customRenderHook } from '../../../context/test-utils/test-utils';
import { useCardinality, useMappedByFieldName } from './FieldEntityAssociation';
import { cardinalityMessage, useCardinality, useMappedByFieldName } from './FieldEntityAssociation';

describe('useMappedByFieldName', () => {
test('clear modifiers', () => {
Expand Down Expand Up @@ -137,3 +137,15 @@ describe('useCardinality', () => {
expect(newField.entity.orphanRemoval).toBeFalsy();
});
});

describe('cardinalityMessage', () => {
test('one-to-many association returns a warning', () => {
expect(cardinalityMessage('ONE_TO_MANY')).toBeDefined();
});

test('other associations return nothing', () => {
expect(cardinalityMessage()).toBeUndefined();
expect(cardinalityMessage('ONE_TO_ONE')).toBeUndefined();
expect(cardinalityMessage('MANY_TO_ONE')).toBeUndefined();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,16 @@ const cardinalityItems: Array<{ value: Association; label: string }> = [
{ value: 'MANY_TO_ONE', label: 'Many-to-One' }
] as const;

export const cardinalityMessage = (cardinality?: Association) => {
if (cardinality === 'ONE_TO_MANY') {
return {
message: 'A One-to-Many association comes with a significant performance impact. Only use it if it is absolutely necessary.',
variant: 'warning'
};
}
return;
};

export const FieldEntityAssociation = () => {
const { context } = useAppContext();
const { field, setProperty } = useFieldEntityProperty();
Expand All @@ -58,7 +68,7 @@ export const FieldEntityAssociation = () => {
<CollapsibleTrigger>Association</CollapsibleTrigger>
<CollapsibleContent>
<Flex direction='column' gap={4}>
<BasicField label='Cardinality'>
<BasicField label='Cardinality' message={cardinalityMessage(cardinality)} aria-label='Cardinality'>
<BasicSelect value={cardinality} emptyItem items={cardinalities} onValueChange={setCardinality} />
</BasicField>
<BasicField label='Cascade'>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,20 @@ test.beforeEach(async ({ page }) => {

test('cardinality', async () => {
const cardinality = editor.detail.field.entity.association.cardinality;
const cardinalityMessage = editor.detail.field.entity.association.cardinalityMessage;

await editor.detail.dataClass.general.classType.fillValues('Entity');
await editor.table.row(5).locator.click();
await editor.detail.field.entity.accordion.open();

await cardinality.expectToHaveOptions('One-to-One', 'Many-to-One');

await editor.table.row(6).locator.click();
await editor.detail.field.entity.accordion.open();

await expect(cardinalityMessage.locator).toBeHidden();
await cardinality.choose('One-to-Many');
await cardinalityMessage.expectToHaveWarningMessage('A One-to-Many association comes with a significant performance impact. Only use it if it is absolutely necessary.');
});

test('cascade', async () => {
Expand Down
5 changes: 5 additions & 0 deletions playwright/tests/pageobjects/abstract/FieldMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,9 @@ export class FieldMessage {
await expect(this.locator).toHaveText(message);
await expect(this.locator).toHaveAttribute('data-state', 'error');
}

async expectToHaveWarningMessage(message: string) {
await expect(this.locator).toHaveText(message);
await expect(this.locator).toHaveAttribute('data-state', 'warning');
}
}
3 changes: 3 additions & 0 deletions playwright/tests/pageobjects/field/entity/FieldAssociation.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { expect, type Locator, type Page } from '@playwright/test';
import { Collapsible } from '../../abstract/Collapsible';
import { FieldMessage } from '../../abstract/FieldMessage';
import { Select } from '../../abstract/Select';

export type FieldAssociationCascadeTypes = { [K in keyof FieldAssociation['cascadeTypes']]: boolean };

export class FieldAssociation {
readonly collapsible: Collapsible;
readonly cardinality: Select;
readonly cardinalityMessage: FieldMessage;
readonly cascadeTypes: {
all: Locator;
persist: Locator;
Expand All @@ -20,6 +22,7 @@ export class FieldAssociation {
constructor(page: Page, parentLocator: Locator) {
this.collapsible = new Collapsible(page, parentLocator, { label: 'Association' });
this.cardinality = new Select(page, this.collapsible.locator, { label: 'Cardinality' });
this.cardinalityMessage = new FieldMessage(this.collapsible.locator, { label: 'Cardinality' });
this.cascadeTypes = {
all: this.collapsible.locator.getByLabel('All'),
persist: this.collapsible.locator.getByLabel('Persist'),
Expand Down

0 comments on commit a85d1de

Please sign in to comment.