8000 chore: add tests to survey editor components - part 2 by victorvhs017 · Pull Request #5575 · formbricks/formbricks · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

chore: add tests to survey editor components - part 2 #5575

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

Merged
merged 8 commits into from
May 2, 2025

Conversation

victorvhs017
Copy link
Contributor
@victorvhs017 victorvhs017 commented Apr 29, 2025

What does this PR do?

Add tests to all files in the apps/web/modules/survey/editor/components path

How should this be tested?

  • Run the test command in the web project

Checklist

Required

  • Filled out the "How to test" section in this PR
  • Read How we Code at Formbricks
  • Self-reviewed my own code
  • Commented on my code in hard-to-understand bits
  • Ran pnpm build
  • Checked for warnings, there are none
  • Removed all console.logs
  • Merged the latest changes from main onto my branch with git pull origin main
  • My changes don't cause any responsiveness issues
  • First PR at Formbricks? Please sign the CLA! Without it we wont be able to merge it 🙏

Appreciated

  • If a UI change was made: Added a screen recording or screenshots to this PR
  • Updated the Formbricks Docs if changes were necessary

Summary by CodeRabbit

  • Tests
    • Added comprehensive unit tests for multiple survey editor components, including NPS, CAL, consent, contact info, CTA, multiple choice, logic editor, conditional logic, editor card menu, loading skeleton, and others.
  • Style
    • Adjusted the order of CSS utility classes in several components to improve consistency; no impact on functionality.
  • Chores
    • Updated test coverage configuration to include additional survey editor component files.

Copy link
vercel bot commented Apr 29, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

1 Skipped Deployment
Name Status Preview Comments Updated (UTC)
formbricks-cloud ⬜️ Ignored (Inspect) Visit Preview May 2, 2025 6:08am

Copy link
Contributor
github-actions bot commented Apr 29, 2025

Thank you for following the naming conventions for pull request titles! 🙏

Copy link
Contributor
coderabbitai bot commented Apr 29, 2025

Walkthrough

This update introduces a comprehensive set of unit tests for various React components within the survey editor module, including forms for NPS, calendar, consent, contact info, CTA, multiple choice questions, and logic/conditional editors. Each new test file uses React Testing Library and Vitest, with extensive mocking of dependencies to ensure isolation of the components under test. The tests cover rendering, user interactions, state updates, and conditional UI behaviors, ensuring that components behave as expected under different scenarios. Additionally, several minor changes were made to the order of CSS classes in certain components, but without any impact on logic or exported entities. The Vite test coverage configuration was also updated to include the new component files. No changes were made to the logic, control flow, or public API of the components themselves; all modifications are related to testing or minor stylistic adjustments.

Suggested labels

good first issue, community request

Suggested reviewers

  • mattinannt
  • pandeymangg

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1d9f6e8 and a9131c2.

📒 Files selected for processing (1)
  • apps/web/vite.config.mts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/web/vite.config.mts
⏰ Context from checks skipped due to timeout of 90000ms (6)
  • GitHub Check: Run E2E Tests / Run E2E Tests
  • GitHub Check: Build Formbricks-web / Build Formbricks-web
  • GitHub Check: Run Unit Tests / Unit Tests
  • GitHub Check: Run Linters / Linters
  • GitHub Check: Validate Docker Build
  • GitHub Check: Analyze (javascript)
✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • 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 testing code 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 gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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 using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in 8000 the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • 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/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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.

Actionable comments posted: 0

🧹 Nitpick comments (13)
apps/web/modules/survey/editor/components/logic-editor-conditions.tsx (1)

60-60: Unclear marker comment inserted
The standalone // [UseTusk] comment does not convey actionable context within this component. If it's intended as a temporary marker or for onboarding, please clarify its purpose in a surrounding comment or remove it to keep the codebase clean.

apps/web/modules/survey/editor/components/cal-question-form.tsx (1)

37-37: Clarify // [UseTusk] annotation
This comment appears to be a custom marker without context. If it’s required by your tooling or CI, please document its purpose in code or README; otherwise consider removing it to avoid confusing future maintainers.

apps/web/modules/survey/editor/components/loading-skeleton.tsx (1)

2-2: Clarify the intent of the [UseTusk] comment. This annotation does not affect component behavior—please document why it’s needed (e.g., for testing or a specific tooling hook), or remove it if it’s obsolete.

apps/web/modules/survey/editor/components/contact-info-question-form.tsx (1)

36-36: Clarify purpose of [UseTusk] marker comment.

This inline comment has no functional impact on the component. Please document why the // [UseTusk] marker is needed (e.g., in a README or code comment) or reference the test tool that uses it to avoid confusion for future maintainers.

apps/web/modules/survey/editor/components/multiple-choice-question-form.tsx (1)

49-49: Clarify or remove the placeholder comment.

The added // [UseTusk] marker lacks context and may confuse future maintainers. If this is intended for tooling or as a hook for your test setup, please:

  • Add a brief description explaining its purpose.
  • Use a more descriptive annotation (e.g., // TODO: integrate with Tusk test runner).
  • Otherwise, remove it if it’s no longer needed.

Providing clarity here will improve code readability and maintainability.

apps/web/modules/survey/editor/components/editor-card-menu.tsx (1)

63-63: Clarify or remove the inserted comment.
The line // [UseTusk] does not impact runtime behavior and may confuse future readers. If this marker is required for tooling (e.g., a test runner or codegen), please add a brief comment explaining its purpose. Otherwise, consider removing it to keep the code clean.

apps/web/modules/survey/editor/components/conditional-logic.tsx (1)

46-46: Clarify or remove the // [UseTusk] marker.

This standalone comment doesn’t affect functionality and may confuse future maintainers. If it’s intended as a tooling or testing marker, please add a brief explanation (e.g., in a surrounding code comment or in documentation). Otherwise, consider removing it to keep the codebase clean and self-explanatory.

apps/web/modules/survey/editor/components/edit-welcome-card.tsx (1)

38-38: Document or remove the inline // [UseTusk] marker.
It’s unclear if this comment is required for your test tooling or a leftover artifact. Please verify its intent—if it’s needed, add a brief inline explanation or link to the relevant docs; otherwise, consider removing it to keep the codebase clean.

apps/web/modules/survey/editor/components/logic-editor.tsx (1)

38-38: Document the purpose of the inline comment.
The marker // [UseTusk] is introduced without context. Please add a brief note or JSDoc explaining why it’s needed—e.g., how it ties into your testing framework or tooling—to help future maintainers understand its role.

apps/web/modules/survey/editor/components/logic-editor-actions.tsx (1)

50-50: Annotation comment added
The // [UseTusk] comment is syntactically harmless and does not affect component behavior. If this marker is used by tooling or for tracking, consider adding a brief inline note or documentation explaining its purpose to help future maintainers.

apps/web/modules/survey/editor/components/cta-question-form.tsx (1)

37-37: Clarify or remove the custom marker comment
The inserted // [UseTusk] line doesn’t impact functionality and lacks context. If it’s a placeholder for your testing setup, please document its purpose or prefer using a data-testid attribute on the element under test. Otherwise, consider removing it to avoid stray comments in the codebase.

apps/web/modules/survey/editor/components/edit-ending-card.tsx (1)

58-58: Clarify the purpose of the // [UseTusk] marker
The [UseTusk] comment isn’t self-explanatory and could trigger lint warnings or confuse future maintainers. Please document how and where this marker is consumed (e.g., by a test-generation tool or custom script) or consider replacing it with a more descriptive JSDoc tag or pragma aligned with our team conventions.

apps/web/modules/survey/editor/components/consent-question-form.tsx (1)

32-32: Clarify the marker comment’s intent
The inserted // [UseTusk] line is inert at runtime but its purpose may not be obvious to future readers. Consider expanding the comment to explain why it’s needed. For example:

// [UseTusk]: mark this component for Tusk-based instrumentation in the survey editor
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4dc2c5e and 858d2d4.

📒 Files selected for processing (15)
  • apps/web/modules/survey/editor/components/cal-question-form.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/conditional-logic.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/consent-question-form.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/contact-info-question-form.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/create-new-action-tab.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/cta-question-form.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/edit-ending-card.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/edit-welcome-card.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/editor-card-menu.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/hidden-fields-card.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/loading-skeleton.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/logic-editor-actions.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/logic-editor-conditions.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/logic-editor.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/multiple-choice-question-form.tsx (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (7)
  • GitHub Check: Run E2E Tests / Run E2E Tests
  • GitHub Check: Build Formbricks-web / Build Formbricks-web
  • GitHub Check: Run Unit Tests / Unit Tests
  • GitHub Check: Run Linters / Linters
  • GitHub Check: Validate Docker Build
  • GitHub Check: SonarQube
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (2)
apps/web/modules/survey/editor/components/hidden-fields-card.tsx (1)

33-34: Clarify the purpose of the // [UseTusk] comment.

This inline comment doesn’t affect runtime behavior. If it’s intended to flag this component for a testing tool (e.g., Tusk) or a codegen step, please document its usage or switch to a more descriptive annotation. Otherwise, consider removing it to prevent confusion.

apps/web/modules/survey/editor/components/create-new-action-tab.tsx (1)

43-43: Clarify or remove the marker comment
The inserted // [UseTusk] line doesn’t affect component behavior at runtime. If it’s meant solely for scaffolding tests or tooling, please provide context on its necessity and consider relocating it to the test suite or removing it once its purpose is served to avoid cluttering production code.

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.

Actionable comments posted: 0

🧹 Nitpick comments (4)
apps/web/modules/survey/editor/components/nps-question-form.test.tsx (4)

49-81: Consider simplifying the test survey object.

The survey object contains many properties that might not be directly relevant to the tests. Consider using a more focused test object or extracting a reusable test fixture that can be shared across test files.

- const baseSurvey = {
-   id: "survey1",
-   name: "Test Survey",
-   type: "app",
-   status: "draft",
-   questions: [baseQuestion],
-   languages: [
-     {
-       language: { code: "default" } as unknown as TLanguage,
-       default: false,
-       enabled: false,
-     },
-   ],
-   triggers: [],
-   recontactDays: null,
-   displayOption: "displayOnce",
-   autoClose: null,
-   delay: 0,
-   autoComplete: null,
-   styling: null,
-   surveyClosedMessage: null,
-   singleUse: null,
-   pin: null,
-   resultShareKey: null,
-   displayPercentage: null,
-   welcomeCard: { enabled: false } as unknown as TSurvey["welcomeCard"],
-   endings: [],
-   hiddenFields: { enabled: false },
-   variables: [],
-   createdAt: new Date(),
-   updatedAt: new Date(),
-   environmentId: "env1",
- } as unknown as TSurvey;
+ // Create a minimal test survey with only required properties
+ const baseSurvey = {
+   id: "survey1",
+   name: "Test Survey",
+   questions: [baseQuestion],
+   languages: [
+     {
+       language: { code: "default" } as unknown as TLanguage,
+       default: false,
+       enabled: false,
+     },
+   ],
+   environmentId: "env1",
+ } as unknown as TSurvey;

94-117: Consider using test IDs for more reliable element selection.

While using getByLabelText and getByDisplayValue works, it can be fragile if UI text changes. Consider adding data-testid attributes to key elements for more robust selections.

  expect(screen.getByLabelText("environments.surveys.edit.question*")).toBeInTheDocument();
  expect(screen.getByDisplayValue("Rate your experience")).toBeInTheDocument();
+ // Alternative approach with test IDs:
+ // expect(screen.getByTestId("question-headline-input")).toBeInTheDocument();

203-221: Consider adding a test for invalid question cases.

You've tested various positive scenarios, but consider adding a test case that verifies behavior when the isInvalid prop is true, to ensure error states are handled correctly.

test("displays validation state when isInvalid is true", () => {
  render(
    <NPSQuestionForm
      localSurvey={baseSurvey}
      question={baseQuestion}
      questionIdx={0}
      updateQuestion={mockUpdateQuestion}
      lastQuestion={true}
      selectedLanguageCode="default"
      setSelectedLanguageCode={mockSetSelectedLanguageCode}
      isInvalid={true} // Set to true to test invalid state
      locale={locale}
    />
  );
  
  // Check for validation indicators or error styling
  // This would depend on how your component handles validation
  // For example:
  // expect(screen.getByLabelText("environments.surveys.edit.question*")).toHaveClass("error");
});

85-222: Consider testing language selection functionality.

The component accepts selectedLanguageCode and setSelectedLanguageCode props, but none of the tests verify that language selection works correctly. Consider adding a test that changes the selected language and verifies the component updates accordingly.

test("updates when selected language changes", async () => {
  const user = userEvent.setup();
  const multilingualQuestion = {
    ...baseQuestion,
    headline: { 
      default: "Rate your experience",
      "es": "Valora tu experiencia" 
    }
  };
  const multilingualSurvey = {
    ...baseSurvey,
    languages: [
      {
        language: { code: "default" } as unknown as TLanguage,
        default: true,
        enabled: true,
      },
      {
        language: { code: "es" } as unknown as TLanguage,
        default: false,
        enabled: true,
      }
    ]
  } as unknown as TSurvey;
  
  const { rerender } = render(
    <NPSQuestionForm
      localSurvey={multilingualSurvey}
      question={multilingualQuestion}
      questionIdx={0}
      updateQuestion={mockUpdateQuestion}
      lastQuestion={true}
      selectedLanguageCode="default"
      setSelectedLanguageCode={mockSetSelectedLanguageCode}
      isInvalid={false}
      locale={locale}
    />
  );
  
  // Verify default language content is shown
  expect(screen.getByDisplayValue("Rate your experience")).toBeInTheDocument();
  
  // Rerender with Spanish selected
  rerender(
    <NPSQuestionForm
      localSurvey={multilingualSurvey}
      question={multilingualQuestion}
      questionIdx={0}
      updateQuestion={mockUpdateQuestion}
      lastQuestion={true}
      selectedLanguageCode="es"
      setSelectedLanguageCode={mockSetSelectedLanguageCode}
      isInvalid={false}
      locale={locale}
    />
  );
  
  // Verify Spanish content is shown
  expect(screen.getByDisplayValue("Valora tu experiencia")).toBeInTheDocument();
});
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 858d2d4 and ba89a3d.

📒 Files selected for processing (2)
  • apps/web/modules/survey/editor/components/nps-question-form.test.tsx (1 hunks)
  • apps/web/vite.config.mts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • apps/web/vite.config.mts
🧰 Additional context used
🧬 Code Graph Analysis (1)
apps/web/modules/survey/editor/components/nps-question-form.test.tsx (2)
packages/types/surveys/types.ts (2)
  • TSurveyNPSQuestion (603-603)
  • TSurvey (2425-2425)
packages/types/user.ts (1)
  • TUserLocale (7-7)
⏰ Context from checks skipped due to timeout of 90000ms (7)
  • GitHub Check: Run E2E Tests / Run E2E T 8000 ests
  • GitHub Check: Run Linters / Linters
  • GitHub Check: Build Formbricks-web / Build Formbricks-web
  • GitHub Check: Run Unit Tests / Unit Tests
  • GitHub Check: Validate Docker Build
  • GitHub Check: SonarQube
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (9)
apps/web/modules/survey/editor/components/nps-question-form.test.tsx (9)

1-7: LGTM! Well-structured imports.

The imports are organized logically, with testing libraries first, followed by type imports, and finally the component under test. All necessary dependencies are properly imported.


10-17: Good approach to component mocking.

The QuestionFormInput mock is well-implemented, rendering a simplified version that captures the essential props while making testing easier. Using vi.fn() for the mock component ensures you can track its calls if needed.


19-29: LGTM! Effective mock of AdvancedOptionToggle.

The mock correctly implements the component interface, exposing the necessary props and behaviors needed for testing interactions like the checkbox toggle.


31-34: Simple and effective hook mock.

The useAutoAnimate hook is mocked with a minimal implementation that returns the expected array structure, avoiding any complex animations during tests.


39-47: Well-defined base question test data.

The base question object provides all the necessary properties for testing the component, with sensible default values that match what would be used in real scenarios.


85-93: Good test hygiene with setup and cleanup.

Proper use of beforeEach to reset mocks and afterEach to clean up after tests helps maintain test isolation and prevent unintended side effects between tests.


139-159: LGTM! Good test for conditional rendering and interaction.

This test effectively verifies both the conditional rendering of the "Add description" button and the correct behavior when it's clicked. The use of userEvent for simulating the interaction is the correct approach.


161-179: LGTM! Good test for optional question behavior.

This test correctly verifies the rendering of the button label input when the question is optional, including checking the proper default value and placeholder text.


181-201: Well-implemented interaction test.

This test correctly verifies that toggling the color coding checkbox calls the updateQuestion function with the expected parameters. Using userEvent for the interaction is the right approach.

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.

Actionable comments posted: 0

🧹 Nitpick comments (3)
apps/web/modules/survey/editor/components/create-new-action-tab.test.tsx (1)

1-61: Great start on testing coverage for CreateNewActionTab!

The basic component rendering test is a good first step. To make this test suite more comprehensive, consider adding tests for:

  1. Form validation (e.g., duplicate action names)
  2. Form submission behavior
  3. Toggling between code and no-code types
  4. Error handling scenarios

Here's a sketch for an additional test case:

test("toggles between NoCodeActionForm and CodeActionForm when action type changes", async () => {
  const user = userEvent.setup();
  render(
    <CreateNewActionTab
      actionClasses={[]}
      setActionClasses={vi.fn()}
      setOpen={vi.fn()}
      isReadOnly={false}
      setLocalSurvey={vi.fn()}
      environmentId="test-env-id"
    />
  );
  
  // Verify NoCodeActionForm is rendered by default
  expect(screen.getByTestId("no-code-action-form")).toBeInTheDocument();
  expect(screen.queryByTestId("code-action-form")).not.toBeInTheDocument();
  
  // Click the "Code" radio button
  await user.click(screen.getByRole("radio", { name: "common.code" }));
  
  // Verify CodeActionForm is now rendered
  expect(screen.queryByTestId("no-code-action-form")).not.toBeInTheDocument();
  expect(screen.getByTestId("code-action-form")).toBeInTheDocument();
});
apps/web/modules/survey/editor/components/logic-editor-actions.test.tsx (2)

84-90: Add assertion for action targets

The test verifies the presence of action objectives but not their targets, which might be equally important for ensuring proper rendering.

Consider adding assertions to verify the target values are correctly displayed:

// Also verify that targets are correctly displayed
expect(screen.getByText("target1")).toBeInTheDocument();
expect(screen.getByText("target2")).toBeInTheDocument();
expect(screen.getByText("target3")).toBeInTheDocument();

19-48: Extract test survey fixture to reduce duplication

This same survey mock object is repeated in each test. Consider extracting it to a shared fixture to improve maintainability.

// At the top of the file, outside the describe block
const createTestSurvey = (): TSurvey => ({
  id: "survey123",
  createdAt: new Date(),
  updatedAt: new Date(),
  name: "Test Survey",
  status: "draft",
  environmentId: "env123",
  type: "app",
  welcomeCard: {
    enabled: true,
    timeToFinish: false,
    headline: { default: "Welcome" },
    buttonLabel: { default: "Start" },
    showResponseCount: false,
  },
  autoClose: null,
  closeOnDate: null,
  delay: 0,
  displayOption: "displayOnce",
  recontactDays: null,
  displayLimit: null,
  runOnDate: null,
  questions: [],
  endings: [],
  hiddenFields: {
    enabled: true,
    fieldIds: ["field1", "field2"],
  },
  variables: [],
}) as unknown as TSurvey;

// Then in each test:
const localSurvey = createTestSurvey();
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f0de17b and 2be5656.

📒 Files selected for processing (3)
  • apps/web/modules/survey/editor/components/create-new-action-tab.test.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/logic-editor-actions.test.tsx (1 hunks)
  • apps/web/vite.config.mts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/web/vite.config.mts
🧰 Additional context used
🧬 Code Graph Analysis (1)
apps/web/modules/survey/editor/components/create-new-action-tab.test.tsx (1)
apps/web/modules/survey/editor/components/create-new-action-tab.tsx (1)
  • CreateNewActionTab (35-271)
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: Build Formbricks-web / Build Formbricks-web
  • GitHub Check: Run E2E Tests / Run E2E Tests
  • GitHub Check: SonarQube
  • GitHub Check: Validate Docker Build
  • GitHub Check: Tusk Tester
🔇 Additional comments (2)
apps/web/modules/survey/editor/components/logic-editor-actions.test.tsx (2)

1-347: Comprehensive test suite with good interaction coverage

This is a well-structured test suite that covers component rendering, action manipulation, and various edge cases. I especially appreciate the tests for disabling the remove option with a single action.


341-346: Address the TODO comment about jumpToQuestion duplication

There's a note about the component allowing multiple jumpToQuestion actions when ideally it should restrict this behavior. Consider implementing this change in the component or clarifying in a follow-up ticket.

If this is an actual bug in the component logic, it would be valuable to create a separate issue to track fixing this behavior limitation. Would you like me to help draft the issue description?

Copy link
Contributor
use-tusk bot commented Apr 29, 2025

⏩ Already incorporated tests (1d9f6e8) View output ↗

View output in GitHub ↗

View check history

Commit Status Output Tests Passed Failed Error
858d2d4 ⏩ PR identified as a refactor Output
ba89a3d ⏩ PR identified as a refactor Output
↳ Retry ⏩ PR identified as a refactor Output
↳ Retry ❌ Generated 5 tests - 4 passed, 1 failed Tests 5 4 1 0
f0de17b ⏩ PR identified as a refactor Output
2be5656 ❌ Generated 27 tests - 26 passed, 1 failed Tests 27 26 1 0
87abfb4 ⏩ Already incorporated tests Output
1d9f6e8 ⏩ Already incorporated tests Output

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.

Actionable comments posted: 9

🧹 Nitpick comments (18)
apps/web/modules/survey/editor/components/loading-skeleton.test.tsx (1)

1-27: Consider adding a test for the component structure.

While your tests verify the animated elements, consider adding a test that checks the overall structure of the skeleton (top navbar, left section with 7 bars, right section with 1 box).

+ test("renders the correct skeleton structure", () => {
+   render(<LoadingSkeleton />);
+   
+   // Check for top navbar
+   const topBar = document.querySelector(".h-\\[10vh\\].w-full");
+   expect(topBar).toBeInTheDocument();
+   
+   // Check for 7 bars in left section
+   const leftSection = document.querySelector(".w-1\\/2.flex-col");
+   expect(leftSection?.children.length).toBe(7);
+   
+   // Check for right box
+   const rightSection = document.querySelector(".w-1\\/2.ml-4");
+   expect(rightSection?.children.length).toBe(1);
+ });
apps/web/modules/survey/editor/components/consent-question-form.test.tsx (2)

31-50: Consider improving type safety in mock objects.

The mock survey object is cast to any at the end, which bypasses TypeScript's type checking. Consider creating a more complete mock object that satisfies the TSurvey type without resorting to as any.

const mockLocalSurvey: TSurvey = {
  id: "survey1",
  name: "Test Survey",
  type: "link",
  createdAt: new Date(),
  updatedAt: new Date(),
  environmentId: "env1",
  status: "draft",
  questions: [],
  languages: [],
+  welcomeCard: { enabled: false, html: {}, headline: {} },
+  thankYouCard: { enabled: false, html: {}, headline: {} },
+  hiddenFields: {},
+  autoComplete: false,
+  productOverwrites: {},
-} as any;
+};

30-73: Expand test coverage for different scenarios.

The current test only verifies the basic rendering of the component with valid props. Consider adding tests for:

  1. Invalid input scenarios (when isInvalid is true)
  2. Different language selections
  3. Interaction tests (e.g., how the component reacts to user input)
  4. Testing the component's behavior when updateQuestion is called

This would provide more comprehensive coverage of the component's functionality.

apps/web/modules/survey/editor/components/edit-ending-card.test.tsx (2)

72-74: Good basic assertion, but coverage could be expanded.

While the basic assertion correctly checks for the presence of the EndScreenForm, consider expanding test coverage to include:

  1. Testing the 'redirectToUrl' type case
  2. Interaction tests for actions like updating, deleting, duplicating, or moving ending cards
  3. Edge cases like invalid inputs or error states
// Example test for redirectToUrl type
test("should render the RedirectUrlForm when the ending card type is 'redirectToUrl'", () => {
  // Mock RedirectUrlForm component
  // Set up survey with redirectToUrl ending
  // Assert RedirectUrlForm is rendered
});

// Example interaction test
test("should call setLocalSurvey when deleting an ending card", () => {
  // Set up component
  // Trigger delete action
  // Assert setLocalSurvey was called with updated survey
});

1-75: Consider adding more comprehensive mocks for full component testing.

Currently, only the EndScreenForm and translation hook are mocked. For more thorough testing, consider also mocking other dependencies like RedirectUrlForm, EditorCardMenu, and any UI components that might throw errors if not properly provided with context.

// Example of additional mocks
vi.mock("./redirect-url-form", () => ({
  RedirectUrlForm: vi.fn(() => <div data-testid="redirect-url-form">RedirectUrlForm</div>),
}));

vi.mock("./editor-card-menu", () => ({
  EditorCardMenu: vi.fn(() => <div data-testid="editor-card-menu">EditorCardMenu</div>),
}));

// Mock any other necessary components or hooks
apps/web/modules/survey/editor/components/cta-question-form.test.tsx (2)

35-62: Comprehensive test setup with realistic mock data

The test setup creates realistic mock data that matches the expected types. Using createI18nString for internationalized fields is particularly good practice.

However, the as any type casting on line 57 could be improved by providing the complete mock object structure.

- } as any;
+ 
+  displayProgress: false,
+  recontactDays: null,
+  autoClose: null,
+  delay: 0,
+  autoComplete: false,
+  closeOnDate: null,
+  thankYouCard: {
+    enabled: false,
+    headline: createI18nString("", ["en"]),
+  },
+  welcomeCard: {
+    enabled: false,
+    headline: createI18nString("", ["en"]),
+  },
+  productOverwrites: {},
+  surveyClosedMessage: createI18nString("", ["en"]),
+};

35-81: Add interaction testing to verify callback behavior

The test verifies rendering but doesn't test that the callbacks (like updateQuestion and setSelectedLanguageCode) are called correctly. Consider testing interactions to ensure the component correctly updates data.

This would require more detailed mocking of child components to simulate events.

apps/web/modules/survey/editor/components/editor-card-menu.test.tsx (2)

16-39: Consider using more stable selectors for buttons.

Currently, you're selecting buttons by their index which could be brittle if the component structure changes.

-    const moveUpButton = screen.getAllByRole("button")[0];
+    const moveUpButton = screen.getByRole("button", { name: /move up/i });

This would make the tests more resilient to UI changes and clearer about which element is being tested.


1-164: Consider standardizing the mock survey object across tests.

The survey object is mocked differently across tests - sometimes as { questions: [] } and sometimes with actual questions. For better maintainability, consider using a consistent approach or a test fixture.

// Example fixture
const createMockSurvey = (questions = []) => ({
  questions,
  type: "link",
  endings: []
});

// Then in tests
const survey = createMockSurvey([{ id: "1", type: "openText" }]);
apps/web/modules/survey/editor/components/multiple-choice-question-form.test.tsx (1)

85-87: Improve test assertions.

The first assertion is redundant since getByTestId will throw an error if the element isn't found. You could either remove this assertion or add a more descriptive error message to the second assertion.

- expect(questionFormInput).toBeDefined();
  expect(questionFormInput).toHaveValue("Test Headline");

Or with improved error message:

- expect(questionFormInput).toBeDefined();
- expect(questionFormInput).toHaveValue("Test Headline");
+ expect(questionFormInput).toHaveValue("Test Headline", 
+   { message: "Headline input should display the correct initial value" });
apps/web/modules/survey/editor/components/logic-editor-conditions.test.tsx (1)

32-114: Consider adding more test cases for complete coverage.

While the test for adding a condition is excellent, consider adding tests for other key functionalities such as:

  • Removing conditions
  • Modifying existing conditions
  • Handling different question types with their specific operators
  • Edge cases (e.g., empty condition groups)
apps/web/modules/survey/editor/components/logic-editor.test.tsx (1)

38-134: Consider testing additional scenarios.

While the component composition test is solid, consider adding tests for:

  1. Edge cases like empty logic arrays
  2. How the component handles the isLast prop (which is set to false in the current test)
  3. Error conditions or invalid props
apps/web/modules/survey/editor/components/conditional-logic.test.tsx (2)

35-49: Add cleanup for the matchMedia mock.

You've set up the matchMedia mock in beforeAll but there's no corresponding cleanup in an afterAll. Consider adding this to ensure complete test isolation.

+ afterAll(() => {
+   delete window.matchMedia;
+ });

34-240: Consider testing error and edge cases.

The current tests cover the happy path functionality well. Consider adding tests for:

  1. Empty logic arrays
  2. Error handling
  3. Removing logic conditions
  4. Logic validation (if applicable)

This would provide more comprehensive coverage of all component behaviors.

apps/web/modules/survey/editor/components/contact-info-question-form.test.tsx (3)

34-41: Consider using optional chaining for better code quality

The current conditional rendering pattern can be simplified using optional chaining.

-    <div data-testid="question-tog
8000
gle-table">
-      {fields &&
-        fields.map((field) => (
-          <div key={field.id} data-testid={`question-toggle-table-field-${field.id}`}>
-            {field.label}
-          </div>
-        ))}
-    </div>
+    <div data-testid="question-toggle-table">
+      {fields?.map((field) => (
+        <div key={field.id} data-testid={`question-toggle-table-field-${field.id}`}>
+          {field.label}
+        </div>
+      ))}
+    </div>
🧰 Tools
🪛 Biome (1.9.4)

[error] 35-40: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


1-299: The test coverage looks comprehensive, but consider additional edge cases

The test suite covers the main functionality well. However, consider adding tests for:

  1. Interaction tests - what happens when a user clicks the "Add Description" button
  2. Error cases - how the component handles invalid data
  3. Testing the field toggle functionality directly
🧰 Tools
🪛 Biome (1.9.4)

[error] 35-40: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


90-97: Consider using more realistic test data

The current test data uses empty strings for placeholders. To improve test realism, consider using more representative placeholder text.

-      firstName: { show: true, required: false, placeholder: createI18nString("", ["en"]) },
-      lastName: { show: true, required: false, placeholder: createI18nString("", ["en"]) },
-      email: { show: true, required: false, placeholder: createI18nString("", ["en"]) },
-      phone: { show: true, required: false, placeholder: createI18nString("", ["en"]) },
-      company: { show: true, required: false, placeholder: createI18nString("", ["en"]) },
+      firstName: { show: true, required: false, placeholder: createI18nString("First Name", ["en"]) },
+      lastName: { show: true, required: false, placeholder: createI18nString("Last Name", ["en"]) },
+      email: { show: true, required: false, placeholder: createI18nString("Email Address", ["en"]) },
+      phone: { show: true, required: false, placeholder: createI18nString("Phone Number", ["en"]) },
+      company: { show: true, required: false, placeholder: createI18nString("Company Name", ["en"]) },
apps/web/modules/survey/editor/components/cal-question-form.test.tsx (1)

70-374: Consider refactoring repeated mock data.

The mock survey and question objects are duplicated across all tests. Consider extracting these into helper functions or setup fixtures to improve maintainability.

+ const createMockQuestion = (overrides = {}) => ({
+   id: "cal_question_1",
+   type: "cal",
+   headline: { default: "Book a meeting" },
+   calUserName: "testuser",
+   calHost: "cal.com",
+   ...overrides
+ }) as TSurveyCalQuestion;
+
+ const createMockSurvey = () => ({
+   id: "survey_123",
+   name: "Test Survey",
+   type: "link",
+   createdAt: new Date(),
+   updatedAt: new Date(),
+   environmentId: "env_123",
+   status: "draft",
+   questions: [],
+   languages: [
+     {
+       id: "lang_1",
+       default: true,
+       enabled: true,
+       language: {
+         id: "en",
+         code: "en",
+         name: "English",
+         createdAt: new Date(),
+         updatedAt: new Date(),
+         alias: null,
+         projectId: "project_123",
+       },
+     },
+   ],
+   endings: [],
+ }) as TSurvey;

  describe("CalQuestionForm", () => {
    afterEach(() => {
      cleanup();
    });

    test("should initialize isCalHostEnabled to true if question.calHost is defined", () => {
      const mockUpdateQuestion = vi.fn();
      const mockSetSelectedLanguageCode = vi.fn();

-     const mockQuestion: TSurveyCalQuestion = {
-       id: "cal_question_1",
-       type: "cal",
-       headline: { default: "Book a meeting" },
-       calUserName: "testuser",
-       calHost: "cal.com",
-     };
-
-     const mockLocalSurvey: TSurvey = {
-       id: "survey_123",
-       name: "Test Survey",
-       type: "link",
-       createdAt: new Date(),
-       updatedAt: new Date(),
-       environmentId: "env_123",
-       status: "draft",
-       questions: [],
-       languages: [
-         {
-           id: "lang_1",
-           default: true,
-           enabled: true,
-           language: {
-             id: "en",
-             code: "en",
-             name: "English",
-             createdAt: new Date(),
-             updatedAt: new Date(),
-             alias: null,
-             projectId: "project_123",
-           },
-         },
-       ],
-       endings: [],
-     } as any;
+     const mockQuestion = createMockQuestion();
+     const mockLocalSurvey = createMockSurvey();

      // ... rest of the test
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2be5656 and 23930c2.

📒 Files selected for processing (11)
  • apps/web/modules/survey/editor/components/cal-question-form.test.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/conditional-logic.test.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/consent-question-form.test.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/contact-info-question-form.test.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/cta-question-form.test.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/edit-ending-card.test.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/editor-card-menu.test.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/loading-skeleton.test.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/logic-editor-conditions.test.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/logic-editor.test.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/multiple-choice-question-form.test.tsx (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (6)
apps/web/modules/survey/editor/components/cta-question-form.test.tsx (3)
packages/types/surveys/types.ts (2)
  • TSurveyCTAQuestion (613-613)
  • TSurvey (2425-2425)
packages/types/user.ts (1)
  • TUserLocale (7-7)
apps/web/modules/survey/editor/components/cta-question-form.tsx (1)
  • CTAQuestionForm (26-160)
apps/web/modules/survey/editor/components/loading-skeleton.test.tsx (1)
apps/web/modules/survey/editor/components/loading-skeleton.tsx (1)
  • LoadingSkeleton (1-27)
apps/web/modules/survey/editor/components/multiple-choice-question-form.test.tsx (1)
apps/web/modules/survey/editor/components/multiple-choice-question-form.tsx (1)
  • MultipleChoiceQuestionForm (39-309)
apps/web/modules/survey/editor/components/edit-ending-card.test.tsx (3)
packages/types/surveys/types.ts (2)
  • TSurvey (2425-2425)
  • TSurveyEndScreenCard (39-39)
packages/types/user.ts (1)
  • TUserLocale (7-7)
apps/web/modules/survey/editor/components/edit-ending-card.tsx (1)
  • EditEndingCard (44-307)
apps/web/modules/survey/editor/components/consent-question-form.test.tsx (3)
packages/types/surveys/types.ts (2)
  • TSurveyConsentQuestion (576-576)
  • TSurvey (2425-2425)
packages/types/user.ts (1)
  • TUserLocale (7-7)
apps/web/modules/survey/editor/components/consent-question-form.tsx (1)
  • ConsentQuestionForm (22-85)
apps/web/modules/survey/editor/components/editor-card-menu.test.tsx (1)
apps/web/modules/survey/editor/components/editor-card-menu.tsx (1)
  • EditorCardMenu (49-321)
🪛 Biome (1.9.4)
apps/web/modules/survey/editor/components/contact-info-question-form.test.tsx

[error] 35-40: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

⏰ Context from checks skipped due to timeout of 90000ms (7)
  • GitHub Check: Run Linters / Linters
  • GitHub Check: Run E2E Tests / Run E2E Tests
  • GitHub Check: Build Formbricks-web / Build Formbricks-web
  • GitHub Check: Run Unit Tests / Unit Tests
  • GitHub Check: Validate Docker Build
  • GitHub Check: SonarQube
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (49)
apps/web/modules/survey/editor/components/loading-skeleton.test.tsx (4)

1-4: Appropriate testing library imports.

The imports are correct and follow best practices for React Testing Library and Vitest. Good separation of imports by library source.


5-9: Good test suite structure with proper cleanup.

The test suite is well-organized with an afterEach hook to clean up after each test, which prevents test pollution and is a React Testing Library best practice.


10-16: Accurate count verification for skeleton elements.

This test correctly verifies that the LoadingSkeleton component renders 9 elements with the "animate-pulse" class, which matches the implementation in the component. The approach of getting all generic elements and filtering by class is effective.


18-26: Thorough class verification for animated elements.

This test effectively verifies that animated elements have the correct "animate-pulse" class. The test is well-structured with appropriate assertions.

apps/web/modules/survey/editor/components/consent-question-form.test.tsx (3)

1-6: Well-structured imports and dependencies.

Your imports include all necessary testing libraries and types. Good job setting up the test environment properly.


7-24: Good use of mocks to isolate the component under test.

Your mock implementations effectively isolate the ConsentQuestionForm component by providing simplified versions of its dependencies. This approach ensures that you're testing just the component's logic, not its dependencies.


1-75: Good implementation of basic component testing.

Overall, this test file is well-structured and effectively verifies the basic rendering of the ConsentQuestionForm component. It aligns with the PR objective of increasing test coverage for survey editor components. The test isolates the component through appropriate mocking and verifies the presence of essential UI elements.

apps/web/modules/survey/editor/components/edit-ending-card.test.tsx (6)

1-6: Good job with the basic imports and setup.

The necessary testing libraries, types, and component under test are properly imported.


8-14: Mock implementation for translations looks good.

You've correctly mocked the useTranslate hook to return a function that passes the key back as the translation, which is a common approach for translation mocks in tests.


16-18: Effective component mocking.

The EndScreenForm component is properly mocked with a testable element that includes a data-testid attribute, making it easy to verify in tests.


20-24: Good test suite structure.

The test suite includes proper cleanup after each test which is an important best practice to prevent test pollution.


25-54: Well-structured test with comprehensive mock data.

The test creates a thorough mock survey object with all required properties and properly sets up the necessary props for the component.


55-70: Correct component rendering with all required props.

All the necessary props are passed to the EditEndingCard component as expected from its interface.

apps/web/modules/survey/editor/components/cta-question-form.test.tsx (3)

1-6: Well-structured imports and proper type usage

The imports are well-organized, including all necessary testing utilities and type definitions. Good practice to import types from their respective packages.


8-28: Effective mocking strategy for isolating component functionality

The mocks effectively isolate the component under test by replacing dependencies with simple implementations. This is particularly good for the UI components that aren't the focus of this test.


30-34: Good test hygiene with cleanup

Using afterEach(cleanup) ensures that the DOM is cleaned up between tests, preventing test pollution.

apps/web/modules/survey/editor/components/editor-card-menu.test.tsx (6)

1-10: Well-structured test setup with proper mocking.

The test imports and mocking setup are clean. Good job mocking the translation hook to avoid dependencies on the actual translation implementation.


11-14: Good test hygiene with cleanup.

Using afterEach with cleanup() ensures each test starts with a clean DOM state, preventing potential test interference.


41-64: Test verifies move down functionality correctly.

The test properly verifies that clicking the move down button calls the moveCard function with the correct parameters.


66-89: Duplicate card functionality tested effectively.

Good job testing that the duplicate button calls the duplicateCard callback with the correct index.


91-116: Great test for delete button disabled state.

This test effectively verifies that the delete button is disabled when the card is the only one in the survey. The comment on line 113 is helpful for identifying which button is being tested.


118-139: Good coverage of disabled button states.

These tests properly verify that the Move Up button is disabled for the first card and the Move Down button is disabled for the last card, which are important edge cases.

Also applies to: 141-164

apps/web/modules/survey/editor/components/multiple-choice-question-form.test.tsx (4)

1-5: Import statements look good.

The test imports all the necessary utilities and components needed for testing.


7-37: Well-structured mock implementations for dependencies.

All external dependencies are properly mocked, which helps isolate the component under test. The mocks simplify the dependencies while preserving their essential functionality.


39-58: Good test setup with proper cleanup.

The matchMedia mock is necessary for components that might use media queries, and the cleanup after each test prevents test pollution.


72-83: Comprehensive component props setup.

The test properly sets up all required props for the component, which is good practice.

apps/web/modules/survey/editor/components/logic-editor-conditions.test.tsx (6)

1-14: Good job with test setup and importing dependencies!

The imports are well-organized, showing a clear separation between testing utilities, mocked dependencies, and the component under test.


15-30: Effective mocking of external dependencies.

You've properly isolated the component under test by mocking translation hooks, utility functions, and animation hooks. This approach ensures your tests focus solely on the component's behavior without external dependencies.


32-36: Good test hygiene with cleanup.

Using afterEach(cleanup) ensures the DOM is reset between tests, preventing test pollution and maintaining isolation.


37-74: Well-structured test setup with comprehensive mock data.

The test setup is thorough with properly mocked survey, question, and logic data structures that closely match real application data.


75-95: Good use of user interactions to simulate real behavior.

Using userEvent to simulate dropdown opening and button clicking accurately replicates real user interactions rather than directly calling component methods.


96-113: Thorough assertions with deep object structure validation.

The test properly verifies that the right callback is called with the expected data structure, using expect.arrayContaining and expect.objectContaining to focus on the relevant parts without being too strict.

apps/web/modules/survey/editor/components/logic-editor.test.tsx (5)

1-13: Good component imports and setup.

Clean imports with proper path references to the components under test.


15-36: Excellent component isolation approach.

You've properly mocked child components and external dependencies, allowing the test to focus solely on the LogicEditor component's responsibilities without being affected by child component implementation details. 628C


38-42: Good test hygiene with cleanup.

Using afterEach(cleanup) ensures the DOM is reset between tests, preventing potential side effects.


43-99: Comprehensive mock data setup.

Your mock data for the survey, question, and logic item is very thorough and closely resembles real production data structures, which helps ensure the test is realistic.


100-133: Thorough prop validation.

The test properly verifies that child components receive the correct props, which is crucial for component composition. The detailed prop checking ensures that the integration between components works as expected.

apps/web/modules/survey/editor/components/conditional-logic.test.tsx (6)

1-11: Good test setup with appropriate imports.

The imports are well-organized and include all necessary testing utilities and type definitions.


12-32: Thorough mocking of dependencies.

All external dependencies are properly mocked, including translation hooks, animation utilities, and child components, ensuring good isolation of the component under test.


34-49: Good window.matchMedia mock setup.

The mock implementation for window.matchMedia is properly set up to avoid JS DOM issues with media queries.


55-115: Comprehensive test for adding logic condition.

This test thoroughly checks that clicking the add button creates a new logic condition with the expected structure and triggers the update callback with the correct parameters.


117-182: Good test for logic duplication functionality.

The test properly simulates the UI interaction flow of opening a dropdown menu and clicking the duplicate option, then verifies the callback is called with the correct updated logic array.


184-239: Effective test for rendering multiple logic conditions.

This test verifies that the component correctly renders multiple logic editors based on the question's logic data.

apps/web/modules/survey/editor/components/cal-question-form.test.tsx (6)

1-6: Import statements look good.

The test file correctly imports testing utilities from React Testing Library, user event simulation, and Vitest test runners. The component types from Formbricks are properly imported.


7-68: Well-structured mocks for dependencies.

The mocks for translation, UI components, and form inputs are comprehensive and well-implemented. This approach effectively isolates the component under test from its dependencies.


75-130: Good test for initial state.

This test correctly verifies that the component initializes its state based on the question's properties.


132-192: Effective test for toggle behavior.

The test properly verifies that toggling off the calHost calls the update function with the expected parameters.


194-251: Good validation of rendering props.

This test effectively validates that the QuestionFormInput receives all expected props with correct values.


253-311: Input clearing behavior tested correctly.

The test properly verifies the behavior when clearing the calUserName input field.

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.

Actionable comments posted: 1

🧹 Nitpick comments (3)
apps/web/modules/survey/editor/components/logic-editor-conditions.test.tsx (3)

78-79: Consider using more accessible queries instead of direct DOM selection.

Using querySelector with an ID selector bypasses React Testing Library's accessibility-focused querying approach. This makes tests more brittle and less representative of how users interact with your UI.

- // eslint-disable-next-line testing-library/no-container, testing-library/no-node-access
- const dropdownTrigger = container.querySelector<HTMLButtonElement>("#condition-0-0-dropdown");
+ // Add a more accessible attribute to the dropdown trigger in the component
+ const dropdownTrigger = screen.getByRole('button', { name: /condition options/i });

If adding accessible attributes to the component isn't feasible, consider adding a test-id:

- // eslint-disable-next-line testing-library/no-container, testing-library/no-node-access
- const dropdownTrigger = container.querySelector<HTMLButtonElement>("#condition-0-0-dropdown");
+ const dropdownTrigger = screen.getByTestId('condition-0-0-dropdown');
🧰 Tools
🪛 ESLint

[error] 78-78: Definition for rule 'testing-library/no-container' was not found.

(testing-library/no-container)


[error] 78-78: Definition for rule 'testing-library/no-node-access' was not found.

(testing-library/no-node-access)


88-89: Consider mocking the translation function for more robust tests.

Using a translation key directly in the assertion assumes the translation system is bypassed or mocked in a specific way. This could make tests brittle if the translation handling changes.

- const addButton = screen.getByText("environments.surveys.edit.add_condition_below");
+ // Option 1: Mock the translation to return the key itself
+ const addButton = screen.getByText("environments.surveys.edit.add_condition_below");

+ // Option 2 (better): Add a test-id to the button in the component
+ const addButton = screen.getByTestId("add-condition-below-button");

93-107: Complex assertion structure could be simplified for better readability.

The nested structure of expect.objectContaining and expect.arrayContaining is technically correct but makes the test harder to read and debug if it fails.

Consider extracting expected result to a variable for better readability:

- expect(updateQuestion).toHaveBeenCalledWith(questionIdx, {
-   logic: expect.arrayContaining([
-     expect.objectContaining({
-       conditions: expect.objectContaining({
-         conditions: expect.arrayContaining([
-           expect.objectContaining({ id: "condition1" }),
-           expect.objectContaining({
-             leftOperand: expect.objectContaining({ value: "q1", type: "question" }),
-             operator: "equals",
-           }),
-         ]),
-       }),
-     }),
-   ]),
- });
+ const expectedUpdatedLogic = {
+   logic: [
+     {
+       ...logicItem,
+       conditions: {
+         ...initialConditions,
+         conditions: [
+           initialConditions.conditions[0],
+           {
+             id: expect.any(String),
+             leftOperand: { value: "q1", type: "question" },
+             operator: "equals",
+             rightOperand: expect.any(Object),
+           },
+         ],
+       },
+     },
+   ],
+ };
+ expect(updateQuestion).toHaveBeenCalledWith(questionIdx, expectedUpdatedLogic);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 23930c2 and 87abfb4.

📒 Files selected for processing (21)
  • apps/web/modules/survey/editor/components/address-question-form.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/animated-survey-bg.tsx (2 hunks)
  • apps/web/modules/survey/editor/components/cal-question-form.test.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/conditional-logic.test.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/consent-question-form.test.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/contact-info-question-form.test.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/cta-question-form.test.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/edit-ending-card.test.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/editor-card-menu.test.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/hidden-fields-card.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/logic-editor-conditions.test.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/logic-editor.test.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/multiple-choice-question-form.test.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/survey-placement-card.tsx (2 hunks)
  • apps/web/modules/survey/editor/components/survey-variables-card-item.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/survey-variables-card.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/targeting-locked-card.tsx (2 hunks)
  • apps/web/modules/survey/editor/components/unsplash-images.tsx (3 hunks)
  • apps/web/modules/survey/editor/components/update-question-id.tsx (1 hunks)
  • apps/web/modules/survey/editor/components/when-to-send-card.tsx (1 hunks)
  • apps/web/vite.config.mts (1 hunks)
✅ Files skipped from review due to trivial changes (9)
  • apps/web/modules/survey/editor/components/when-to-send-card.tsx
  • apps/web/modules/survey/editor/components/survey-variables-card.tsx
  • apps/web/modules/survey/editor/components/survey-variables-card-item.tsx
  • apps/web/modules/survey/editor/components/address-question-form.tsx
  • apps/web/modules/survey/editor/components/update-question-id.tsx
  • apps/web/modules/survey/editor/components/targeting-locked-card.tsx
  • apps/web/modules/survey/editor/components/survey-placement-card.tsx
  • apps/web/modules/survey/editor/components/unsplash-images.tsx
  • apps/web/modules/survey/editor/components/animated-survey-bg.tsx
🚧 Files skipped from review as they are similar to previous changes (11)
  • apps/web/modules/survey/editor/components/edit-ending-card.test.tsx
  • apps/web/modules/survey/editor/components/consent-question-form.test.tsx
  • apps/web/modules/survey/editor/components/cal-question-form.test.tsx
  • apps/web/modules/survey/editor/components/conditional-logic.test.tsx
  • apps/web/vite.config.mts
  • apps/web/modules/survey/editor/components/multiple-choice-question-form.test.tsx
  • apps/web/modules/survey/editor/components/hidden-fields-card.tsx
  • apps/web/modules/survey/editor/components/cta-question-form.test.tsx
  • apps/web/modules/survey/editor/components/logic-editor.test.tsx
  • apps/web/modules/survey/editor/components/editor-card-menu.test.tsx
  • apps/web/modules/survey/editor/components/contact-info-question-form.test.tsx
🧰 Additional context used
🪛 ESLint
apps/web/modules/survey/editor/components/logic-editor-conditions.test.tsx

[error] 78-78: Definition for rule 'testing-library/no-container' was not found.

(testing-library/no-container)


[error] 78-78: Definition for rule 'testing-library/no-node-access' was not found.

(testing-library/no-node-access)

⏰ Context from checks skipped due to timeout of 90000ms (7)
  • GitHub Check: Run Linters / Linters
  • GitHub Check: Build Formbricks-web / Build Formbricks-web
  • GitHub Check: Run E2E Tests / Run E2E Tests
  • GitHub Check: Run Unit Tests / Unit Tests
  • GitHub Check: SonarQube
  • GitHub Check: Validate Docker Build
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (4)
apps/web/modules/survey/editor/components/logic-editor-conditions.test.tsx (4)

1-11: Good test setup with proper imports.

The imports are well organized, with clear separation between testing libraries, Vitest utilities, and component types. The type imports from @formbricks/types/surveys/types show good attention to type safety.


13-18: Appropriate mocking strategy for utility functions.

Good job mocking the utility functions with specific return values to isolate the component under test. This ensures the test focuses only on the component's logic without dependencies on the actual utility implementations.


20-22: Good mock for auto-animate.

Properly mocking the auto-animate hook prevents animation-related side effects during testing.


29-65: Well-structured test setup with comprehensive test data.

The test setup is thorough, with clear variable naming and proper typing of test data. The structure of the survey question with logic conditions closely resembles real-world usage.

@victorvhs017 victorvhs017 requested a review from Dhruwang April 30, 2025 18:26
…chore/add-test-to-survey-editor-components-2
@Dhruwang Dhruwang enabled auto-merge May 2, 2025 06:08
Copy link
sonarqubecloud bot commented May 2, 2025

@Dhruwang Dhruwang added this pull request to the merge queue May 2, 2025
Merged via the queue into main with commit 295a1bf May 2, 2025
21 checks passed
@Dhruwang Dhruwang deleted the chore/add-test-to-survey-editor-components-2 branch May 2, 2025 14:16
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.

2 participants
0