Skip to content

Common api - Add field create input validation integration testing#15026

Merged
etiennejouan merged 14 commits intomainfrom
ej/field-value-validation-integration-testing
Oct 20, 2025
Merged

Common api - Add field create input validation integration testing#15026
etiennejouan merged 14 commits intomainfrom
ej/field-value-validation-integration-testing

Conversation

@etiennejouan
Copy link
Copy Markdown
Contributor

@etiennejouan etiennejouan commented Oct 10, 2025

@etiennejouan etiennejouan changed the title Common - Add field create input validation integration testing Common api - Add field create input validation integration testing Oct 10, 2025
Copy link
Copy Markdown
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Greptile Overview

Greptile Summary

This PR introduces comprehensive field create input validation integration testing by restructuring the test directory from args-validation to inputs-validation and adding extensive validation coverage for all field metadata types. The changes include:

  1. Directory restructuring: Moved all existing filter validation tests from args-validation/ to inputs-validation/filter-validation/ with updated import paths and terminology (changing "args validation" to "input validation" throughout)

  2. New create input validation suite: Added a complete inputs-validation/create-validation/ directory with dedicated integration test files for each field metadata type (TEXT, NUMBER, BOOLEAN, UUID, ARRAY, etc.), each testing both GraphQL and REST API endpoints for successful and failing validation scenarios

  3. Shared testing infrastructure: Added utility functions for testing GraphQL and REST scenarios, constants for test data, and helper functions for setup/teardown of test objects with comprehensive field coverage

  4. Type system updates: Introduced new type definitions to categorize which field metadata types should be tested for create vs filter input validation, replacing the previous more generic type system

The new testing framework ensures consistent validation behavior across all field types and API interfaces, providing comprehensive coverage for input validation scenarios in the Twenty CRM system.

Important Files Changed

Changed Files
Filename Score Overview
packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/constants/failing-create-input-by-field-metadata-type.constant.ts 2/5 New test data file with field validation bugs - incorrect field names used in NUMBER and BOOLEAN test cases
packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/constants/successful-create-input-by-field-metadata-type.constant.ts 2/5 New test data file with validation bugs in MULTI_SELECT, PHONES, and LINKS field validation functions
packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/utils/test-rest-successful-scenario.util.ts 3/5 New utility function with type safety issues and missing null checks
packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/utils/test-gql-failing-scenario.util.ts 3/5 New utility function with naming inconsistencies and missing error bounds checking
packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/utils/test-rest-failing-scenario.util.ts 3/5 New utility function with type safety issues and brittle error message validation
packages/twenty-server/test/integration/graphql/suites/inputs-validation/utils/get-field-metadata-creation-inputs.util.ts 4/5 Moved and updated utility with new field type support but complex union type handling
packages/twenty-server/test/integration/graphql/suites/inputs-validation/utils/setup-test-objects-with-all-field-types.util.ts 4/5 Core setup utility with good restructuring but simplified GraphQL field selection
packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/actor-field-create-input.integration-spec.ts 4/5 New test file with good structure but missing failing test scenarios
packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/full-name-field-create-input-validation.integration-spec.ts 4/5 New test file with good structure but missing failing test scenarios
packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/address-field-create-input-validation.integration-spec.ts 4/5 New test file with good structure but missing failing test scenarios
packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/currency-field-create-input-validation.integration-spec.ts 4/5 New test file with good structure but missing failing test scenarios
packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/rich-text-v2-field-create-input-validation.integration-spec.ts 4/5 New test file with good structure but only covers successful scenarios
packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/constants/failing-filter-input-by-field-metadata-type.constant.ts 4/5 Moved constants file with comprehensive test data but many commented TODO sections
All other create validation test files 5/5 Comprehensive integration test files following consistent patterns with proper setup/teardown
All moved filter validation test files 5/5 Successfully moved and updated files with consistent structural changes
packages/twenty-server/test/integration/graphql/suites/inputs-validation/types/field-metadata-type-to-test.ts 5/5 New type definitions that properly categorize testable field types

Confidence score: 2/5

  • This PR has significant issues that prevent safe merging due to critical bugs in test data constants
  • Score reflects serious validation bugs in multiple test constant files that would cause tests to fail or produce incorrect results
  • Pay close attention to the constant files with field name mismatches and validation function bugs that must be fixed before deployment

Sequence Diagram

sequenceDiagram
    participant User
    participant TestSuite
    participant SetupUtil
    participant ObjectMetadataAPI
    participant FieldMetadataAPI
    participant GraphQLAPI
    participant RestAPI
    participant ValidationEngine
    participant Database

    User->>TestSuite: "Run field validation tests"
    
    TestSuite->>SetupUtil: "setupTestObjectsWithAllFieldTypes()"
    SetupUtil->>ObjectMetadataAPI: "createOneObjectMetadata() - main object"
    ObjectMetadataAPI->>Database: "Create test object metadata"
    Database-->>ObjectMetadataAPI: "Object metadata created"
    ObjectMetadataAPI-->>SetupUtil: "objectMetadataId"
    
    SetupUtil->>ObjectMetadataAPI: "createOneObjectMetadata() - target object"
    ObjectMetadataAPI->>Database: "Create target object metadata"
    Database-->>ObjectMetadataAPI: "Target object metadata created"
    ObjectMetadataAPI-->>SetupUtil: "targetObjectMetadataId"
    
    loop For each field type (TEXT, UUID, SELECT, etc.)
        SetupUtil->>FieldMetadataAPI: "createOneFieldMetadata()"
        FieldMetadataAPI->>Database: "Create field metadata"
        Database-->>FieldMetadataAPI: "Field created"
        FieldMetadataAPI-->>SetupUtil: "Field metadata created"
    end
    
    SetupUtil->>GraphQLAPI: "createMany() - seed test records"
    GraphQLAPI->>Database: "Insert test records"
    Database-->>GraphQLAPI: "Records inserted"
    GraphQLAPI-->>SetupUtil: "Test data seeded"
    
    SetupUtil-->>TestSuite: "Setup complete with object IDs"
    
    loop For each field type and test case
        alt Successful Create Input Tests
            TestSuite->>GraphQLAPI: "testGqlSuccessfulScenario()"
            GraphQLAPI->>ValidationEngine: "Validate input"
            ValidationEngine-->>GraphQLAPI: "Input valid"
            GraphQLAPI->>Database: "Create record with input"
            Database-->>GraphQLAPI: "Record created"
            GraphQLAPI-->>TestSuite: "Success response"
            
            TestSuite->>RestAPI: "testRestSuccessfulScenario()"
            RestAPI->>ValidationEngine: "Validate input"
            ValidationEngine-->>RestAPI: "Input valid"
            RestAPI->>Database: "Create record via REST"
            Database-->>RestAPI: "Record created"
            RestAPI-->>TestSuite: "Success response"
        else
            alt Failing Create Input Tests
                TestSuite->>GraphQLAPI: "testGqlFailingScenario()"
                GraphQLAPI->>ValidationEngine: "Validate invalid input"
                ValidationEngine-->>GraphQLAPI: "Validation error"
                GraphQLAPI-->>TestSuite: "Error response with message"
                
                TestSuite->>RestAPI: "testRestFailingScenario()"
                RestAPI->>ValidationEngine: "Validate invalid input"
                ValidationEngine-->>RestAPI: "Validation error"
                RestAPI-->>TestSuite: "Error response with message"
            end
        end
    end
    
    loop For each field type and filter test case
        TestSuite->>GraphQLAPI: "testGqlSuccessfulFilterScenario()"
        GraphQLAPI->>ValidationEngine: "Validate filter input"
        ValidationEngine-->>GraphQLAPI: "Filter valid"
        GraphQLAPI->>Database: "Query with filter"
        Database-->>GraphQLAPI: "Filtered results"
        GraphQLAPI-->>TestSuite: "Filtered records"
        
        TestSuite->>RestAPI: "testRestSuccessfulFilterScenario()"
        RestAPI->>ValidationEngine: "Validate filter input"
        ValidationEngine-->>RestAPI: "Filter valid"
        RestAPI->>Database: "Query with filter via REST"
        Database-->>RestAPI: "Filtered results"
        RestAPI-->>TestSuite: "Filtered records"
    end
    
    TestSuite->>SetupUtil: "destroyManyObjectsMetadata()"
    SetupUtil->>ObjectMetadataAPI: "updateOneObjectMetadata() - deactivate"
    ObjectMetadataAPI->>Database: "Deactivate objects"
    Database-->>ObjectMetadataAPI: "Objects deactivated"
    
    SetupUtil->>ObjectMetadataAPI: "deleteOneObjectMetadata()"
    ObjectMetadataAPI->>Database: "Delete test objects"
    Database-->>ObjectMetadataAPI: "Objects deleted"
    ObjectMetadataAPI-->>SetupUtil: "Cleanup complete"
    
    SetupUtil-->>TestSuite: "Test cleanup finished"
    TestSuite-->>User: "All validation tests completed"
Loading

Additional Comments (5)

  1. packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/utils/test-rest-successful-scenario.util.ts, line 8 (link)

    style: Consider validating that the filter parameter is properly serializable before encoding to prevent runtime errors

  2. packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/utils/test-rest-successful-scenario.util.ts, line 21 (link)

    logic: The optional chaining validateFilter?.(record) could return undefined, which would make the every() call return false unexpectedly. Consider using validateFilter && validateFilter(record) or providing a default validator

  3. packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/utils/test-rest-failing-scenario.util.ts, line 5 (link)

    style: The filter parameter uses any type which loses type safety. Consider using a more specific type or generic constraint.

    Context Used: Context from dashboard - Ensure that type assertions are safe and consider using type guards instead of direct assertions. (source)

  4. packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/utils/test-rest-failing-scenario.util.ts, line 8 (link)

    logic: Consider handling potential encodeURIComponent failures when filter is not serializable to string.

  5. packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/utils/test-rest-failing-scenario.util.ts, line 15 (link)

    style: Using JSON.stringify on error messages may be brittle. Consider checking response.body.messages directly or using a more robust error message validation.

56 files reviewed, 21 comments

Edit Code Review Agent Settings | Greptile

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Oct 10, 2025

🚀 Preview Environment Ready!

Your preview environment is available at: http://bore.pub:54160

This environment will automatically shut down when the PR is closed or after 5 hours.

Copy link
Copy Markdown
Contributor

@ijreilly ijreilly left a comment

Choose a reason for hiding this comment

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

Overall looks good, but there is a lot of commented code, are they intended to be removed in the near future?

I also wonder whether we would want to tie the running of these tests to the modification of certain files - it feels like we are adding a lot lot of tests on code that we will rarely touch (dynamic schema endpoints). is this something we have impemented @prastoin / @Weiko ?

gqlErrorMessage: 'violates not-null constraint',
restErrorMessage: 'violates not-null constraint',
},
// {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

what is the commented part for?

Copy link
Copy Markdown
Contributor Author

@etiennejouan etiennejouan Oct 15, 2025

Choose a reason for hiding this comment

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

A TODO is left, each time a scenario is comment. Commented scenarii are unregular behaviour we need to fix with validation.
After validation layer added in common, it will be uncomment (it's in common refactor scope, so comment should be removed soon).
It was easier to build all the expected behaviour and comment them when not failing. It shows what to work on for validation.

gqlErrorMessage: 'violates not-null constraint',
restErrorMessage: 'violates not-null constraint',
},
// {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

same remark about comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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


const FIELD_METADATA_TYPE = FieldMetadataType.ADDRESS;

const successfulTestCases =
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

what's the rationale with having only successfulTestCases for some field types and both failing and successful for others? It's because adress relies on the same rules as text field under the hood?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Composite fields don't have failing tests as subfields rely on atomic type, already tested.
For specific composite field validation (phones, links, email) we could add failing tests. I think it can be done in a second time.

@@ -53,7 +53,7 @@ describe(`Filter args validation - ${FIELD_METADATA_TYPE}`, () => {
// });

// // TODO : Refacto-common - Uncomment this
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

is this planned to be tackled later?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, all "Refacto-common" comment will be address and removed during common refactor

Copy link
Copy Markdown
Contributor

@prastoin prastoin left a comment

Choose a reason for hiding this comment

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

Hey there, will review this PR in depth a bit later ! left few comments on the global ftm !
Cool to see strong dynamic coverage though !\

Note: centralizing every tests cases in the same files might be a bit redundant, we could store them in their dedicated tests suite instead + strict type with a centralized testCase type

@etiennejouan etiennejouan force-pushed the ej/field-value-validation-integration-testing branch from 5e257b0 to e65e912 Compare October 16, 2025 08:41
@etiennejouan etiennejouan merged commit 580ce31 into main Oct 20, 2025
48 of 52 checks passed
@etiennejouan etiennejouan deleted the ej/field-value-validation-integration-testing branch October 20, 2025 16:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Common - Add integration tests on field value

4 participants