Skip to content

Conversation

@MartinSchoeler
Copy link
Member

@MartinSchoeler MartinSchoeler commented Oct 15, 2025

Proposed changes (including videos or screenshots)

Adds a new form to be used with the ABAC admin pages.

Screenshot 2025-10-15 at 17 36 55

Issue(s)

ABAC-59

Steps to test or reproduce

Further comments

I've created this in a separate PR due the complexity of this form. This way it is easier to review it

Summary by CodeRabbit

  • New Features

    • Admin form for managing room attributes: add/remove values, required-field validation, read-only locked attributes, Save and Cancel actions, and localized labels/errors.
  • Tests

    • Comprehensive test suite covering accessibility, validation scenarios, dynamic interactions, mixed locked/regular attributes, and submission/cancel flows.
  • Documentation

    • Storybook stories demonstrating new-attribute and locked-attributes states.

@dionisio-bot
Copy link
Contributor

dionisio-bot bot commented Oct 15, 2025

Looks like this PR is ready to merge! 🎉
If you have any trouble, please check the PR guidelines

@changeset-bot
Copy link

changeset-bot bot commented Oct 15, 2025

⚠️ No Changeset found

Latest commit: 737d351

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 15, 2025

Walkthrough

Adds a new AdminABACRoomAttributesForm React component with react-hook-form field arrays for editable and locked attribute values, two Storybook stories, and a comprehensive test suite covering rendering, accessibility, validation, dynamic interactions, and submit/cancel behavior. (49 words)

Changes

Cohort / File(s) Summary
ABAC Room Attributes Form Component
apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.tsx
New React+TypeScript form component using react-hook-form with two field arrays: attributeValues (editable) and lockedAttributes (read-only). Implements per-field validation, add/remove value actions, Save/Cancel callbacks, i18n labels/errors, and exports AdminABACRoomAttributesFormFormData, AdminABACRoomAttributesFormProps, and the default component.
ABAC Room Attributes Storybook Stories
apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.stories.tsx
Adds Storybook meta and two stories (NewAttribute, WithLockedAttributes) that wrap the component in a FormProvider and Contextualbar decorator, seeding locked attributes for one variant and using onChange validation mode.
ABAC Room Attributes Form Tests
apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx
New comprehensive test suite covering story rendering with a FormProvider wrapper, accessibility checks with axe, validation (required name, empty values), dynamic interactions (add/remove values, locked vs editable behavior), submission (onSave) and cancellation (onCancel), snapshot stabilization/UUID normalization, and translation mocks.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant UI as AdminABACRoomAttributesForm
    participant RHF as react-hook-form
    participant Actions as onSave/onCancel

    rect rgba(220,240,220,0.35)
    Note over UI,RHF: Initialize form with name, attributeValues, lockedAttributes
    end

    User->>UI: Edit name / add value / remove value
    UI->>RHF: update field arrays (append/remove)
    RHF-->>UI: updated form state (values, errors, validity)

    alt Form valid
        User->>UI: Click Save
        UI->>Actions: onSave(formData)
    else Cancelled
        User->>UI: Click Cancel
        UI->>Actions: onCancel()
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Areas to focus on:
    • Field-array add/remove logic and index handling in AdminABACRoomAttributesForm.tsx
    • Validation rules and aggregated error messaging for attribute values
    • Disabled rendering and behavior of lockedAttributes
    • Test stability: UUID normalization, FormProvider/story wrappers, and accessibility assertions

Suggested labels

stat: ready to merge, stat: QA assured

Suggested reviewers

  • tassoevan
  • aleksandernsilva
  • dougfabris

Poem

🐰 I nibble keys and hop through code,
New fields sprout where stories go,
Locked ones rest while others play,
Tests check access and save the day,
I twitch my nose — the form says "hooray!"

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Linked Issues Check ❓ Inconclusive The linked issues section contains only the issue title "ABAC-59: new/edit Room Attributes Form" without providing the actual detailed requirements or acceptance criteria from that issue. While the PR description indicates it addresses ABAC-59 and the component delivers a form for adding and editing room attributes, which aligns with the issue title, the absence of detailed requirements in the linked_issues section prevents a comprehensive validation of whether all specific objectives and requirements have been met. The code changes appear conceptually aligned with the issue, but detailed requirement verification cannot be completed without the full issue specification. To resolve this check, ensure the linked_issues section includes the detailed requirements and acceptance criteria from ABAC-59, or provide the full issue specification so that the code changes can be validated against all stated requirements rather than just the issue title. Alternatively, clarify which specific requirements from the issue are addressed by each file in the changeset.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title "chore: ABAC add/edit room attributes form" directly and accurately summarizes the main change in the changeset. The three new files introduce a complete form component for adding and editing ABAC room attributes, including test coverage and Storybook stories. The title is concise, specific, and clear about what is being added without unnecessary verbosity or vague language.
Out of Scope Changes Check ✅ Passed All changes in this PR are directly scoped to implementing the ABAC room attributes form. The three modified files comprise a cohesive feature: the main form component (AdminABACRoomAttributesForm.tsx), comprehensive test coverage (AdminABACRoomAttributesForm.spec.tsx), and Storybook stories (AdminABACRoomAttributesForm.stories.tsx). No unrelated changes such as modifications to other components, configuration updates, dependency changes, or other feature implementations are present in the changeset.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/abac-room-att-form

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link

codecov bot commented Oct 15, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 68.02%. Comparing base (1229edc) to head (737d351).
⚠️ Report is 1 commits behind head on develop.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           develop   #37244      +/-   ##
===========================================
+ Coverage    66.90%   68.02%   +1.12%     
===========================================
  Files         3413     3361      -52     
  Lines       117501   115580    -1921     
  Branches     21501    20809     -692     
===========================================
+ Hits         78610    78627      +17     
+ Misses       36209    34270    -1939     
- Partials      2682     2683       +1     
Flag Coverage Δ
e2e 57.47% <ø> (+0.02%) ⬆️
unit 72.08% <100.00%> (+0.09%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@MartinSchoeler MartinSchoeler force-pushed the feat/abac-room-att-form branch from 1b12e37 to f45a4b5 Compare October 16, 2025 18:01
@MartinSchoeler MartinSchoeler changed the base branch from feat/abac to develop October 16, 2025 18:01
@MartinSchoeler MartinSchoeler force-pushed the feat/abac-room-att-form branch from f45a4b5 to a7c4d90 Compare October 28, 2025 17:06
@MartinSchoeler MartinSchoeler changed the title chore: Abac room attributes form chore: ABAC add/edit room attributes form Oct 28, 2025
@MartinSchoeler MartinSchoeler added this to the 7.13.0 milestone Oct 28, 2025
@MartinSchoeler MartinSchoeler marked this pull request as ready for review October 29, 2025 16:33
@MartinSchoeler MartinSchoeler requested a review from a team as a code owner October 29, 2025 16:33
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 (1)
apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.tsx (1)

25-29: Consider strengthening type safety for onSave parameter.

The onSave callback is typed with data: unknown, but you have a well-defined AdminABACRoomAttributesFormFormData type. Using the specific type would provide better type safety for both the component and its consumers.

Apply this diff to improve type safety:

 type AdminABACRoomAttributesFormProps = {
-	onSave: (data: unknown) => void;
+	onSave: (data: AdminABACRoomAttributesFormFormData) => void;
 	onCancel: () => void;
 	description: string;
 };
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 157c0d1 and 07deda5.

⛔ Files ignored due to path filters (1)
  • apps/meteor/client/views/admin/ABAC/__snapshots__/AdminABACRoomAttributesForm.spec.tsx.snap is excluded by !**/*.snap
📒 Files selected for processing (3)
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.stories.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.tsx (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx (2)
packages/mock-providers/src/index.ts (1)
  • mockAppRoot (3-3)
apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.tsx (1)
  • AdminABACRoomAttributesFormFormData (19-23)
apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.stories.tsx (2)
packages/mock-providers/src/index.ts (1)
  • mockAppRoot (3-3)
apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.tsx (1)
  • AdminABACRoomAttributesFormFormData (19-23)
apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.tsx (1)
apps/meteor/client/components/Contextualbar/index.ts (2)
  • ContextualbarScrollableContent (35-35)
  • ContextualbarFooter (32-32)
🔇 Additional comments (11)
apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.stories.tsx (1)

21-44: LGTM! Clean story setup.

The Default story properly initializes the form with an empty name and a single empty attribute value, which demonstrates the basic use case effectively.

apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx (5)

1-72: Excellent test setup and infrastructure!

The test suite demonstrates strong testing practices:

  • UUID normalization (lines 60-63) elegantly handles react-hook-form's random field IDs for stable snapshots
  • Accessibility checks with jest-axe ensure a11y compliance across all stories
  • Comprehensive translation mocks cover the form's i18n requirements

74-107: Validation tests are thorough and well-structured.

These tests properly verify that required field validation works correctly for both the name field and attribute values, using appropriate async handling with waitFor.


109-171: Interaction tests comprehensively verify add/remove functionality.

The tests correctly verify:

  • Adding new attribute values
  • Removing editable attribute values
  • Removing locked attributes (correctly accounting for the restriction that the first locked attribute cannot be removed)

173-200: Button state tests ensure good UX.

These tests verify that the Add Value button is appropriately disabled when there are empty values, preventing users from accumulating unfilled fields.


202-259: Form submission and mixed attribute tests are comprehensive.

These tests properly verify:

  • Form submission flow with onSave callback
  • Cancel button functionality
  • Mixed locked/regular attributes with correct disabled states
apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.tsx (5)

43-48: Verify that field array validation errors are properly displayed.

The minLength: 1 rule (line 46) creates validation errors at errors.attributeValues.root, but getAttributeValuesError() only checks for errors.attributeValues?.length (line 57), which detects individual field errors, not the field array root error.

Consider whether the field array root error should be displayed. If the UI logic (preventing removal of the last field) already ensures at least one value exists, the minLength rule may be redundant. Otherwise, update getAttributeValuesError to check for root-level errors:

 const getAttributeValuesError = useCallback(() => {
+	if (errors.attributeValues?.root?.message) {
+		return errors.attributeValues.root.message;
+	}
 	if (errors.attributeValues?.length && errors.attributeValues?.length > 0) {
 		return t('Required_field', { field: t('Values') });
 	}
 	return '';
 }, [errors.attributeValues, t]);

Also applies to: 56-61


91-102: Confirm that preventing removal of the first locked attribute is intentional.

Line 100 prevents the first locked attribute (index 0) from being removed by not rendering its remove button. This ensures at least one locked attribute remains when locked attributes are present.

Verify this is the intended UX behavior. If users should be able to remove all locked attributes, adjust the condition:

-{index !== 0 && <IconButton aria-label={t('Remove')} icon='trash' onClick={() => removeLockedAttribute(index)} />}
+<IconButton aria-label={t('Remove')} icon='trash' onClick={() => removeLockedAttribute(index)} />

103-115: Attribute value removal logic maintains form integrity.

The conditional removal button logic (line 111) ensures at least one attribute value field is always present when there are no locked attributes, while allowing full flexibility when locked attributes exist. This maintains good form UX by preventing an empty state.


117-123: Add Value button logic provides good UX.

The disabled condition (line 120) prevents users from adding new fields when existing ones are empty or have validation errors. The comment on line 119 helpfully explains the need for direct value checking due to react-hook-form's behavior after append().


70-134: Form structure and submission logic are well-implemented.

The form properly uses handleSubmit for validation, disables the Save button when errors are detected, and correctly separates scrollable content from the footer actions.

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 (1)
apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx (1)

203-225: Consider simplifying the save test for better clarity.

The test removes a value (lines 216-217) before submitting the form, which adds unnecessary complexity. For a focused test of the save functionality, consider either:

  • Remove the trash button interaction to test pure save behavior, or
  • Rename the test to indicate it's testing "remove and save" if that specific workflow is important

Example of a more focused save test:

 it('should call onSave with correct data when form is submitted', async () => {
 	const defaultValues = {
 		name: 'Test Attribute',
 		attributeValues: [{ value: 'Value 1' }, { value: 'Value 2' }],
 	};
 
 	render(
 		<FormProviderWrapper defaultValues={defaultValues}>
 			<AdminABACRoomAttributesForm {...defaultProps} />
 		</FormProviderWrapper>,
 		{ wrapper: appRoot },
 	);
 
-	const trashButtons = screen.queryAllByRole('button', { name: 'Remove' });
-	await userEvent.click(trashButtons[0]);
-
 	const saveButton = screen.getByRole('button', { name: 'Save' });
 	await userEvent.click(saveButton);
 
 	await waitFor(() => {
 		expect(defaultProps.onSave).toHaveBeenCalled();
 	});
 });
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 07deda5 and 7197941.

📒 Files selected for processing (1)
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx (1 hunks)
🧰 Additional context used
🧠 Learnings (11)
📓 Common learnings
Learnt from: KevLehman
PR: RocketChat/Rocket.Chat#37303
File: apps/meteor/tests/end-to-end/api/abac.ts:1125-1137
Timestamp: 2025-10-27T14:38:46.994Z
Learning: In Rocket.Chat ABAC feature, when ABAC is disabled globally (ABAC_Enabled setting is false), room-level ABAC attributes are not evaluated when changing room types. This means converting a private room to public will succeed even if the room has ABAC attributes, as long as the global ABAC setting is disabled.
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Use descriptive test names that clearly communicate expected behavior

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Group related tests in the same file

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Utilize Playwright fixtures (test, page, expect) consistently

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Maintain test isolation between test cases

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Ensure tests run reliably in parallel without shared state conflicts

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: When generating tests, provide complete runnable TypeScript test files with proper imports, clear describe/test blocks, and adherence to these guidelines

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.{ts,tsx,js,jsx} : Write concise, technical TypeScript/JavaScript with accurate typing

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Use expect matchers (toEqual, toContain, toBeTruthy, toHaveLength, etc.) instead of assert statements

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : All Playwright test files must be located under apps/meteor/tests/e2e/ and use the .spec.ts extension (e.g., login.spec.ts)

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.{ts,tsx} : Follow the Page Object Model pattern consistently

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx
🧬 Code graph analysis (1)
apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx (2)
packages/mock-providers/src/index.ts (1)
  • mockAppRoot (3-3)
apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.tsx (1)
  • AdminABACRoomAttributesFormFormData (19-23)
🔇 Additional comments (4)
apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx (4)

57-66: Good approach to handling dynamic UUIDs in snapshots.

The UUID normalization strategy is a pragmatic solution for dealing with react-hook-form's dynamic field IDs. The regex pattern correctly matches UUID v4 format and ensures stable snapshots.


26-44: Well-designed test utility for form context.

The FormProviderWrapper is cleanly implemented and properly typed, making tests more maintainable by centralizing the react-hook-form setup. Good use of mode: 'onChange' for validation testing.


46-261: Comprehensive test coverage with good testing practices.

The test suite demonstrates strong coverage including:

  • Storybook story rendering and snapshots
  • Accessibility validation with jest-axe
  • Form validation and error states
  • Dynamic interactions (add/remove values)
  • Edge cases (locked attributes, mixed states, button states)

The use of Storybook stories for testing and accessibility checks aligns with best practices.


1-1: Remove the unnecessary ESLint disable comment.

The eslint-disable comment on line 1 is not needed. The stories file imports the same type without this disable and no other identifiers in the test file violate naming conventions. This comment can be safely removed.

Likely an incorrect or invalid review comment.

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

♻️ Duplicate comments (1)
apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx (1)

147-167: The past review comment is incorrect; this test logic is actually correct.

The test has 2 locked attributes and 1 empty regular attribute. Based on the component logic:

  • Trash buttons appear for: lockedAttributes[1] (second locked) and attributeValues[0] (first regular, because locked attributes exist)
  • In DOM order, trashButtons[0] is the trash button for lockedAttributes[1]
  • Clicking trashButtons[0] calls removeLockedAttribute(1), removing the item at index 1 ('Locked Value 2')
  • The assertions correctly verify that 'Locked Value 1' remains and 'Locked Value 2' is removed
🧹 Nitpick comments (1)
apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.tsx (1)

25-29: Consider using typed onSave parameter.

The onSave callback accepts unknown, which loses type safety. Consider using the defined form data type instead.

Apply this diff to improve type safety:

 type AdminABACRoomAttributesFormProps = {
-	onSave: (data: unknown) => void;
+	onSave: (data: AdminABACRoomAttributesFormFormData) => void;
 	onCancel: () => void;
 	description: string;
 };
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 7197941 and 7fe95ee.

⛔ Files ignored due to path filters (1)
  • apps/meteor/client/views/admin/ABAC/__snapshots__/AdminABACRoomAttributesForm.spec.tsx.snap is excluded by !**/*.snap
📒 Files selected for processing (2)
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.tsx (1 hunks)
🧰 Additional context used
🧠 Learnings (15)
📓 Common learnings
Learnt from: KevLehman
PR: RocketChat/Rocket.Chat#37303
File: apps/meteor/tests/end-to-end/api/abac.ts:1125-1137
Timestamp: 2025-10-27T14:38:46.994Z
Learning: In Rocket.Chat ABAC feature, when ABAC is disabled globally (ABAC_Enabled setting is false), room-level ABAC attributes are not evaluated when changing room types. This means converting a private room to public will succeed even if the room has ABAC attributes, as long as the global ABAC setting is disabled.
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Use descriptive test names that clearly communicate expected behavior

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Group related tests in the same file

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Utilize Playwright fixtures (test, page, expect) consistently

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Maintain test isolation between test cases

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Ensure tests run reliably in parallel without shared state conflicts

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.{ts,tsx,js,jsx} : Write concise, technical TypeScript/JavaScript with accurate typing

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: When generating tests, provide complete runnable TypeScript test files with proper imports, clear describe/test blocks, and adherence to these guidelines

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : All Playwright test files must be located under apps/meteor/tests/e2e/ and use the .spec.ts extension (e.g., login.spec.ts)

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Use expect matchers (toEqual, toContain, toBeTruthy, toHaveLength, etc.) instead of assert statements

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.{ts,tsx} : Follow the Page Object Model pattern consistently

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Prefer web-first assertions (e.g., toBeVisible, toHaveText)

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx
📚 Learning: 2025-09-23T19:22:59.217Z
Learnt from: dougfabris
PR: RocketChat/Rocket.Chat#36987
File: apps/meteor/tests/e2e/page-objects/fragments/room-toolbar.ts:10-20
Timestamp: 2025-09-23T19:22:59.217Z
Learning: In Playwright e2e tests, prefer stable selectors like data-qa-id attributes over localized text in getByRole() or getByText() calls to prevent test failures when UI language changes. Test translations separately by validating actual text content after ensuring UI interactions work with stable selectors.

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.{ts,tsx} : Avoid using page.locator(); prefer semantic locators like page.getByRole, page.getByLabel, page.getByText, and page.getByTitle

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.{ts,tsx,js,jsx} : Follow DRY by extracting reusable logic into helper functions or page objects

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx
🧬 Code graph analysis (2)
apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx (2)
packages/mock-providers/src/index.ts (1)
  • mockAppRoot (3-3)
apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.tsx (1)
  • AdminABACRoomAttributesFormFormData (19-23)
apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.tsx (1)
apps/meteor/client/components/Contextualbar/index.ts (2)
  • ContextualbarScrollableContent (35-35)
  • ContextualbarFooter (32-32)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: 🔨 Test Unit / Unit Tests
  • GitHub Check: 🔎 Code Check / Code Lint
  • GitHub Check: 🔎 Code Check / TypeScript
  • GitHub Check: 📦 Meteor Build - coverage
  • GitHub Check: CodeQL-Build
  • GitHub Check: CodeQL-Build
🔇 Additional comments (13)
apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx (8)

1-24: LGTM! Clean test setup.

The test setup properly uses Storybook composition, mock providers with translations, and jest-axe for accessibility testing.


26-44: LGTM! Proper FormProvider wrapper for testing.

The wrapper correctly provides form context with appropriate default values and onChange validation mode.


57-68: LGTM! Comprehensive story testing.

Testing all Storybook stories for both snapshots and accessibility violations ensures consistent quality across variants.


70-103: LGTM! Proper validation testing.

The tests correctly verify required field validation with translated error messages and proper async handling.


105-145: LGTM! Dynamic field array operations tested correctly.

The tests properly verify adding and removing values, correctly expecting only 1 trash button when the first value must be preserved.


169-196: LGTM! Button state tests are correct.

The tests properly verify that the Add Value button is disabled when there are empty values and enabled when all values are filled.


198-234: LGTM! Callback tests are correct.

The tests properly verify form submission and cancellation flows with appropriate mock assertions.


236-256: LGTM! Mixed attributes scenario tested correctly.

The test properly verifies that locked inputs are disabled, regular inputs are enabled, and trash buttons appear only where appropriate (1 button for the regular value since the locked value is at index 0).

apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.tsx (5)

31-54: LGTM! Proper react-hook-form setup.

The component correctly uses useFormContext, useFieldArray, and useId for form management and accessibility.


56-68: LGTM! Comprehensive error handling.

The error checking logic properly handles both array-level and item-level validation errors for both editable and locked attributes.


70-86: LGTM! Proper form structure and Name field.

The form correctly uses handleSubmit, and the Name field has proper validation, error display, and accessibility attributes.


87-122: LGTM! Well-designed field array logic.

The Values field correctly handles both locked and editable attributes with smart trash button logic that ensures at least one value is always present. The Add Value button appropriately prevents adding new values when existing ones are empty or invalid.


124-133: LGTM! Proper form footer implementation.

The footer buttons correctly handle cancellation and submission, with the Save button appropriately disabled based on validation state.

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

♻️ Duplicate comments (1)
apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx (1)

148-170: Fix incorrect test assertions for locked attribute removal.

The test clicks the first trash button (trashButtons[0]) but expects the second item to be removed. This logic is backwards—clicking the first trash button should remove the first item ('Locked Value 1'), not the second item ('Locked Value 2').

Apply this diff to fix the assertions:

 	await userEvent.click(trashButtons[0]);
 
-	expect(screen.getByDisplayValue('Locked Value 1')).toBeInTheDocument();
-	expect(screen.queryByDisplayValue('Locked Value 2')).not.toBeInTheDocument();
+	expect(screen.queryByDisplayValue('Locked Value 1')).not.toBeInTheDocument();
+	expect(screen.getByDisplayValue('Locked Value 2')).toBeInTheDocument();
 });
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 579a048 and 5ad306b.

⛔ Files ignored due to path filters (1)
  • apps/meteor/client/views/admin/ABAC/__snapshots__/AdminABACRoomAttributesForm.spec.tsx.snap is excluded by !**/*.snap
📒 Files selected for processing (1)
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx (1 hunks)
🧰 Additional context used
🧠 Learnings (14)
📓 Common learnings
Learnt from: KevLehman
PR: RocketChat/Rocket.Chat#37303
File: apps/meteor/tests/end-to-end/api/abac.ts:1125-1137
Timestamp: 2025-10-27T14:38:46.994Z
Learning: In Rocket.Chat ABAC feature, when ABAC is disabled globally (ABAC_Enabled setting is false), room-level ABAC attributes are not evaluated when changing room types. This means converting a private room to public will succeed even if the room has ABAC attributes, as long as the global ABAC setting is disabled.
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Use descriptive test names that clearly communicate expected behavior

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Group related tests in the same file

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Utilize Playwright fixtures (test, page, expect) consistently

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Ensure tests run reliably in parallel without shared state conflicts

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Maintain test isolation between test cases

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.{ts,tsx,js,jsx} : Write concise, technical TypeScript/JavaScript with accurate typing

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: When generating tests, provide complete runnable TypeScript test files with proper imports, clear describe/test blocks, and adherence to these guidelines

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : All Playwright test files must be located under apps/meteor/tests/e2e/ and use the .spec.ts extension (e.g., login.spec.ts)

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Use expect matchers (toEqual, toContain, toBeTruthy, toHaveLength, etc.) instead of assert statements

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.{ts,tsx} : Follow the Page Object Model pattern consistently

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Prefer web-first assertions (e.g., toBeVisible, toHaveText)

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx
📚 Learning: 2025-09-23T19:22:59.217Z
Learnt from: dougfabris
PR: RocketChat/Rocket.Chat#36987
File: apps/meteor/tests/e2e/page-objects/fragments/room-toolbar.ts:10-20
Timestamp: 2025-09-23T19:22:59.217Z
Learning: In Playwright e2e tests, prefer stable selectors like data-qa-id attributes over localized text in getByRole() or getByText() calls to prevent test failures when UI language changes. Test translations separately by validating actual text content after ensuring UI interactions work with stable selectors.

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.{ts,tsx} : Avoid using page.locator(); prefer semantic locators like page.getByRole, page.getByLabel, page.getByText, and page.getByTitle

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx
🧬 Code graph analysis (1)
apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx (2)
packages/mock-providers/src/index.ts (1)
  • mockAppRoot (3-3)
apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.tsx (1)
  • AdminABACRoomAttributesFormFormData (19-23)
🔇 Additional comments (7)
apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx (7)

1-44: LGTM!

The test setup is well-structured with proper imports, mock translations, and a reusable FormProviderWrapper that correctly initializes react-hook-form context with appropriate default values and validation mode.


46-68: LGTM!

Excellent test coverage with parameterized tests for all Storybook stories, including both snapshot and accessibility validation using jest-axe.


70-103: LGTM!

The validation tests properly verify required field validation for both the name field and attribute values, using appropriate async assertions with waitFor.


105-123: LGTM!

The test correctly verifies that clicking the Add Value button adds a new field to the form.


172-199: LGTM!

The tests correctly verify that the Add Value button is disabled when there are empty values and enabled when all values are filled, ensuring good UX for preventing duplicate empty fields.


201-237: LGTM!

The tests correctly verify the form submission flow with onSave being called with form data and onCancel being invoked when the Cancel button is clicked.


239-258: The behavior is intentional and consistent across both test scenarios—the review comment is incorrect.

The component's Remove button logic ensures that:

  • The first locked attribute can never be removed (index !== 0)
  • Regular attributes can be removed when they're the first item IF locked attributes exist (index !== 0 || lockedAttributesFields.length > 0)

In the locked-only scenario (lines 148-170): Only the second locked attribute has a Remove button.

In the mixed scenario (lines 239-258): The first locked attribute has no button, but the first regular attribute has one (because lockedAttributesFields.length > 0 is true).

Both cases result in exactly 1 Remove button, which is consistent and intentional design—it prevents scenarios where zero attributes remain while allowing controlled removal of non-first items.

@MartinSchoeler MartinSchoeler added the stat: QA assured Means it has been tested and approved by a company insider label Nov 3, 2025
@dionisio-bot dionisio-bot bot added the stat: ready to merge PR tested and approved waiting for merge label Nov 3, 2025
@dionisio-bot dionisio-bot bot removed the stat: ready to merge PR tested and approved waiting for merge label Nov 3, 2025
@MartinSchoeler MartinSchoeler added the stat: ready to merge PR tested and approved waiting for merge label Nov 4, 2025
@kodiakhq kodiakhq bot merged commit 6e128f3 into develop Nov 4, 2025
85 of 87 checks passed
@kodiakhq kodiakhq bot deleted the feat/abac-room-att-form branch November 4, 2025 17:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stat: QA assured Means it has been tested and approved by a company insider stat: ready to merge PR tested and approved waiting for merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants