Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: properly handle missing fields when evaluating @@validate model-level rules #1097

Merged
merged 2 commits into from
Mar 7, 2024

Conversation

ymc9
Copy link
Member

@ymc9 ymc9 commented Mar 7, 2024

Summary by CodeRabbit

  • New Features
    • Enhanced validation capabilities in schema generation to support simple field references and improved handling of undefined values.
  • Bug Fixes
    • Improved boolean expression handling in typescript expression transformer for validation contexts.
  • Tests
    • Added integration tests for model-level validation and regression tests for issue 1078.
  • Chores
    • Enabled preservation of TypeScript files in the zod plugin configuration for better debugging and tooling support.

Copy link
Contributor

coderabbitai bot commented Mar 7, 2024

Walkthrough

Walkthrough

The recent updates focus on enhancing validation capabilities within the schema generation and transformation framework. A notable addition is the makeValidationRefinements function within schema-gen.ts, which now incorporates a check for simple field references, treating undefined as valid. The updates also refine TypeScript expression handling for validation rules, particularly in boolean contexts and binary expressions. Additionally, testing infrastructure sees improvements with the re-enabling of TypeScript file preservation and the introduction of new tests for model-level validation and regression scenarios.

Changes

Files Change Summary
.../schema-gen.ts
.../typescript-expression-transformer.ts
Updated makeValidationRefinements to include isDataModelFieldReference check; modified methods for improved validation rule handling.
.../testtools/src/schema.ts Uncommented preserveTsFiles in the zod plugin configuration.
.../tests/enhancements/with-policy/field-validation.test.ts
.../tests/regression/issue-1078.test.ts
Added tests for model-level validation and regression scenarios.
.../cli/plugins.test.ts Added skipLibCheck: true to TypeScript compiler options.

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share

Tips

Chat

There are 3 ways to chat with CodeRabbit:

Note: Auto-reply has been disabled for this repository by the repository owner. The CodeRabbit bot will not respond to your replies unless it is explicitly tagged.

  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit tests for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit tests.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • The JSON schema for the configuration file is available here.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/coderabbit-overrides.v2.json

CodeRabbit Discord Community

Join our Discord Community to get help, request features, and share feedback.

@ymc9
Copy link
Member Author

ymc9 commented Mar 7, 2024

Fixes #1078

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Review Status

Actionable comments generated: 2

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 0f9f025 and 5524bb6.
Files selected for processing (5)
  • packages/schema/src/plugins/zod/utils/schema-gen.ts (2 hunks)
  • packages/schema/src/utils/typescript-expression-transformer.ts (5 hunks)
  • packages/testtools/src/schema.ts (1 hunks)
  • tests/integration/tests/enhancements/with-policy/field-validation.test.ts (1 hunks)
  • tests/integration/tests/regression/issue-1078.test.ts (1 hunks)
Additional comments: 7
tests/integration/tests/regression/issue-1078.test.ts (1)
  • 32-51: The 'read' test case appears to focus on testing permissions (@allow attribute) rather than the handling of missing fields in model-level validations. While it's important to ensure comprehensive testing, this test case might be slightly off-topic for the PR's main objective. Consider the following:
  • Clarify the relevance of this test case to the PR objectives if it indirectly relates to the handling of missing fields in validations.
  • If the test case is primarily focused on permissions rather than validation, it might be beneficial to document its purpose clearly or move it to a more relevant test suite focused on permissions.
packages/testtools/src/schema.ts (1)
  • 108-108: Uncommenting the preserveTsFiles setting and setting it to true in the zod plugin configuration is a positive change for enhancing testing and debugging capabilities. This allows for the preservation of TypeScript files, which can be beneficial for more detailed analysis and troubleshooting.
  • Ensure that this change is consistently applied across all relevant test configurations to maintain uniformity in testing practices.
  • Consider documenting the implications of this setting for developers, especially regarding how it affects the build and testing process.
packages/schema/src/utils/typescript-expression-transformer.ts (4)
  • 20-20: The addition of isDataModelFieldReference to the import list from @zenstackhq/sdk is crucial for the new logic introduced in this file to handle missing fields correctly during model-level validation. This utility function will be used to check if a given expression references a data model field, which is essential for the changes made in the ensureBoolean, unary, and transformBinary methods.
  • 261-267: The modification to the ensureBoolean method to handle ExpressionContext.ValidationRule differently is a significant improvement. By treating undefined as true in a validation context, it aligns with the principle that missing fields should not automatically cause a validation rule to fail. This change ensures that validation rules are applied more intuitively, especially in scenarios where optional fields are involved.
  • 309-320: The update to the unary method to handle specific cases based on context and operand, particularly for the ! operator in ExpressionContext.ValidationRule, is well thought out. By treating unary operations involving undefined as true in a validation context, it further enhances the handling of missing fields. This adjustment ensures that negation operations in validation rules behave as expected when fields are missing.
  • 336-346: The adjustments made in the transformBinary method to handle binary expressions differently based on ExpressionContext.ValidationRule are crucial for correctly evaluating model-level validation rules. By treating binary operations involving undefined as true in a validation context, it ensures that comparisons and logical operations in validation rules are interpreted correctly when fields are missing. This change is essential for achieving the desired behavior in model-level validations.
tests/integration/tests/enhancements/with-policy/field-validation.test.ts (1)
  • 613-765: The addition of comprehensive tests for model-level validation in the context of the With Policy feature is a significant enhancement. These tests cover a wide range of scenarios, including validation rules involving optional fields, boolean values, comparisons, complex expressions, and negation. By ensuring that these scenarios are thoroughly tested, the changes contribute to the robustness and reliability of the validation mechanism. The tests are well-structured and clearly demonstrate the intended behavior of the validation rules under various conditions.

Comment on lines +3 to +30
describe('issue 1078', () => {
it('regression', async () => {
const { prisma, enhance } = await loadSchema(
`
model Counter {
id String @id

name String
value Int

@@validate(value >= 0)
@@allow('all', true)
}
`
);

const db = enhance();

const counter = await db.counter.create({
data: { id: '1', name: 'It should create', value: 1 },
});

//! This query fails validation
const updated = await db.counter.update({
where: { id: '1' },
data: { name: 'It should update' },
});
});
Copy link
Contributor

Choose a reason for hiding this comment

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

The 'regression' test case effectively demonstrates the handling of missing fields during model-level validation, specifically testing the scenario where the 'value' field is omitted in an update operation. This aligns well with the PR objectives of ensuring that missing fields are correctly handled in validation rules.

  • Ensure that the expected behavior (e.g., passing or failing validation) is explicitly asserted in the test. Currently, the test performs operations but does not assert the outcome. Adding assertions will make the test more robust and clear about the expected behavior.
  • Consider adding negative test cases where the validation should fail, to ensure that the validation logic is not overly permissive.

Comment on lines +209 to +218
let expr = new TypeScriptExpressionTransformer({
context: ExpressionContext.ValidationRule,
fieldReferenceContext: 'value',
}).transform(valueArg);

if (isDataModelFieldReference(valueArg)) {
// if the expression is a simple field reference, treat undefined
// as true since the all fields are optional in validation context
expr = `${expr} ?? true`;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

The update to the makeValidationRefinements function introduces a check for simple field references using isDataModelFieldReference. This logic treats undefined fields as true in the validation context, which aligns with the PR objectives of correctly handling missing fields in model-level validations.

  • Ensure that this change does not inadvertently affect other validation scenarios where undefined should not be treated as true. It might be beneficial to add more tests covering various validation scenarios to ensure the change's correctness and prevent regressions.
  • Consider documenting this behavior in the code comments or the project's documentation to make it clear to other developers how undefined fields are treated in validation rules.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 5524bb6 and ae586bb.
Files selected for processing (1)
  • tests/integration/tests/cli/plugins.test.ts (1 hunks)
Additional comments: 1
tests/integration/tests/cli/plugins.test.ts (1)
  • 119-119: The addition of skipLibCheck: true to the TypeScript compiler options can significantly speed up the compilation process by skipping type checks on declaration files from external libraries. This is particularly beneficial in test environments where the focus is more on the project's code rather than external dependencies. However, it's important to ensure that this does not inadvertently mask potential type-related issues with dependencies.
  • Ensure that this change aligns with the project's overall TypeScript configuration strategy and does not conflict with the need for thorough type checking in other contexts.
  • Consider periodically reviewing the necessity of this option, especially if significant changes are made to the project's dependencies or TypeScript version.

@ymc9 ymc9 merged commit e8268d0 into dev Mar 7, 2024
3 checks passed
@ymc9 ymc9 deleted the fix/issue-1078 branch March 7, 2024 22:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant