-
Notifications
You must be signed in to change notification settings - Fork 2
Fix sharing.test.ts for discriminated union schema #130
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -9,7 +9,7 @@ import { | |||||
|
|
||||||
| describe('SharingRuleType', () => { | ||||||
| it('should accept valid sharing rule types', () => { | ||||||
| const validTypes = ['owner', 'criteria', 'manual', 'guest']; | ||||||
| const validTypes = ['owner', 'criteria']; | ||||||
|
|
||||||
| validTypes.forEach(type => { | ||||||
| expect(() => SharingRuleType.parse(type)).not.toThrow(); | ||||||
|
|
@@ -19,13 +19,15 @@ describe('SharingRuleType', () => { | |||||
| it('should reject invalid sharing rule types', () => { | ||||||
| expect(() => SharingRuleType.parse('automatic')).toThrow(); | ||||||
| expect(() => SharingRuleType.parse('public')).toThrow(); | ||||||
| expect(() => SharingRuleType.parse('manual')).toThrow(); | ||||||
| expect(() => SharingRuleType.parse('guest')).toThrow(); | ||||||
| expect(() => SharingRuleType.parse('')).toThrow(); | ||||||
| }); | ||||||
| }); | ||||||
|
|
||||||
| describe('SharingLevel', () => { | ||||||
| it('should accept valid sharing levels', () => { | ||||||
| const validLevels = ['read', 'edit']; | ||||||
| const validLevels = ['read', 'edit', 'full']; | ||||||
|
|
||||||
| validLevels.forEach(level => { | ||||||
| expect(() => SharingLevel.parse(level)).not.toThrow(); | ||||||
|
|
@@ -35,7 +37,6 @@ describe('SharingLevel', () => { | |||||
| it('should reject invalid sharing levels', () => { | ||||||
| expect(() => SharingLevel.parse('write')).toThrow(); | ||||||
| expect(() => SharingLevel.parse('delete')).toThrow(); | ||||||
| expect(() => SharingLevel.parse('full')).toThrow(); | ||||||
| }); | ||||||
| }); | ||||||
|
|
||||||
|
|
@@ -60,7 +61,12 @@ describe('SharingRuleSchema', () => { | |||||
| const rule: SharingRule = { | ||||||
| name: 'sales_team_access', | ||||||
| object: 'opportunity', | ||||||
| sharedWith: 'group_sales_team', | ||||||
| type: 'criteria', | ||||||
| condition: 'status = "Open"', | ||||||
| sharedWith: { | ||||||
| type: 'group', | ||||||
| value: 'sales_team', | ||||||
| }, | ||||||
| }; | ||||||
|
|
||||||
| expect(() => SharingRuleSchema.parse(rule)).not.toThrow(); | ||||||
|
|
@@ -70,27 +76,35 @@ describe('SharingRuleSchema', () => { | |||||
| expect(() => SharingRuleSchema.parse({ | ||||||
| name: 'valid_rule_name', | ||||||
| object: 'account', | ||||||
| sharedWith: 'group_id', | ||||||
| type: 'criteria', | ||||||
| condition: 'status = "Active"', | ||||||
| sharedWith: { type: 'group', value: 'group_id' }, | ||||||
| })).not.toThrow(); | ||||||
|
|
||||||
| expect(() => SharingRuleSchema.parse({ | ||||||
| name: 'InvalidRule', | ||||||
| object: 'account', | ||||||
| sharedWith: 'group_id', | ||||||
| type: 'criteria', | ||||||
| condition: 'status = "Active"', | ||||||
| sharedWith: { type: 'group', value: 'group_id' }, | ||||||
| })).toThrow(); | ||||||
|
|
||||||
| expect(() => SharingRuleSchema.parse({ | ||||||
| name: 'invalid-rule', | ||||||
| object: 'account', | ||||||
| sharedWith: 'group_id', | ||||||
| type: 'criteria', | ||||||
| condition: 'status = "Active"', | ||||||
| sharedWith: { type: 'group', value: 'group_id' }, | ||||||
| })).toThrow(); | ||||||
| }); | ||||||
|
|
||||||
| it('should apply default values', () => { | ||||||
| const rule = SharingRuleSchema.parse({ | ||||||
| name: 'test_rule', | ||||||
| object: 'account', | ||||||
| sharedWith: 'group_id', | ||||||
| type: 'criteria', | ||||||
| condition: 'status = "Active"', | ||||||
| sharedWith: { type: 'group', value: 'group_id' }, | ||||||
| }); | ||||||
|
|
||||||
| expect(rule.active).toBe(true); | ||||||
|
|
@@ -105,38 +119,48 @@ describe('SharingRuleSchema', () => { | |||||
| active: true, | ||||||
| object: 'opportunity', | ||||||
| type: 'criteria', | ||||||
| criteria: "stage = 'Closed Won' AND amount > 100000", | ||||||
| condition: "stage = 'Closed Won' AND amount > 100000", | ||||||
| accessLevel: 'edit', | ||||||
| sharedWith: 'group_executive_team', | ||||||
| sharedWith: { type: 'group', value: 'executive_team' }, | ||||||
| }); | ||||||
|
|
||||||
| expect(rule.label).toBe('Full Sharing Rule'); | ||||||
| expect(rule.criteria).toContain('Closed Won'); | ||||||
| expect(rule.condition).toContain('Closed Won'); | ||||||
| }); | ||||||
|
|
||||||
| it('should accept different sharing rule types', () => { | ||||||
| const types: Array<SharingRule['type']> = ['owner', 'criteria', 'manual', 'guest']; | ||||||
| // Test criteria-based rule | ||||||
| const criteriaRule = SharingRuleSchema.parse({ | ||||||
| name: 'test_criteria_rule', | ||||||
| object: 'account', | ||||||
| type: 'criteria', | ||||||
| condition: 'status = "Active"', | ||||||
| sharedWith: { type: 'group', value: 'group_id' }, | ||||||
| }); | ||||||
| expect(criteriaRule.type).toBe('criteria'); | ||||||
|
|
||||||
| types.forEach(type => { | ||||||
| const rule = SharingRuleSchema.parse({ | ||||||
| name: 'test_rule', | ||||||
| object: 'account', | ||||||
| type, | ||||||
| sharedWith: 'group_id', | ||||||
| }); | ||||||
| expect(rule.type).toBe(type); | ||||||
| // Test owner-based rule | ||||||
| const ownerRule = SharingRuleSchema.parse({ | ||||||
| name: 'test_owner_rule', | ||||||
| object: 'account', | ||||||
| type: 'owner', | ||||||
| ownedBy: { type: 'role', value: 'sales_rep' }, | ||||||
| sharedWith: { type: 'group', value: 'group_id' }, | ||||||
| }); | ||||||
| expect(ownerRule.type).toBe('owner'); | ||||||
| }); | ||||||
|
|
||||||
| it('should accept different access levels', () => { | ||||||
| const levels: Array<SharingRule['accessLevel']> = ['read', 'edit']; | ||||||
| const levels: Array<SharingRule['accessLevel']> = ['read', 'edit', 'full']; | ||||||
|
|
||||||
| levels.forEach(level => { | ||||||
| const rule = SharingRuleSchema.parse({ | ||||||
| name: 'test_rule', | ||||||
| object: 'account', | ||||||
| type: 'criteria', | ||||||
| condition: 'status = "Active"', | ||||||
| accessLevel: level, | ||||||
| sharedWith: 'group_id', | ||||||
| sharedWith: { type: 'group', value: 'group_id' }, | ||||||
| }); | ||||||
| expect(rule.accessLevel).toBe(level); | ||||||
| }); | ||||||
|
|
@@ -147,8 +171,9 @@ describe('SharingRuleSchema', () => { | |||||
| name: 'owner_hierarchy_rule', | ||||||
| object: 'account', | ||||||
| type: 'owner', | ||||||
| ownedBy: { type: 'role', value: 'sales_rep' }, | ||||||
| accessLevel: 'read', | ||||||
| sharedWith: 'role_sales_manager', | ||||||
| sharedWith: { type: 'role', value: 'sales_manager' }, | ||||||
| }); | ||||||
|
|
||||||
| expect(rule.type).toBe('owner'); | ||||||
|
|
@@ -159,45 +184,49 @@ describe('SharingRuleSchema', () => { | |||||
| name: 'high_value_accounts', | ||||||
| object: 'account', | ||||||
| type: 'criteria', | ||||||
| criteria: "annual_revenue > 1000000 AND status = 'Active'", | ||||||
| condition: "annual_revenue > 1000000 AND status = 'Active'", | ||||||
| accessLevel: 'read', | ||||||
| sharedWith: 'group_executive_team', | ||||||
| sharedWith: { type: 'group', value: 'executive_team' }, | ||||||
| }); | ||||||
|
|
||||||
| expect(rule.type).toBe('criteria'); | ||||||
| expect(rule.criteria).toBeDefined(); | ||||||
| expect(rule.condition).toBeDefined(); | ||||||
| }); | ||||||
|
|
||||||
| it('should accept manual sharing rule', () => { | ||||||
| it('should accept user-specific sharing rule', () => { | ||||||
| const rule = SharingRuleSchema.parse({ | ||||||
| name: 'manual_share', | ||||||
| name: 'user_specific_share', | ||||||
| object: 'opportunity', | ||||||
| type: 'manual', | ||||||
| type: 'criteria', | ||||||
| condition: 'stage != "Closed Won"', | ||||||
| accessLevel: 'edit', | ||||||
| sharedWith: 'user_john_doe', | ||||||
| sharedWith: { type: 'user', value: 'john_doe' }, | ||||||
| }); | ||||||
|
|
||||||
| expect(rule.type).toBe('manual'); | ||||||
| expect(rule.sharedWith.type).toBe('user'); | ||||||
| }); | ||||||
|
|
||||||
| it('should accept guest sharing rule', () => { | ||||||
|
||||||
| it('should accept guest sharing rule', () => { | |
| it('should accept criteria rule with guest recipient', () => { |
Copilot
AI
Jan 25, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The tests don't cover the 'role_and_subordinates' recipient type, which is defined in ShareRecipientType enum (sharing.zod.ts:41). Consider adding a test case to validate that sharing rules can use this recipient type, e.g., sharedWith: { type: 'role_and_subordinates', value: 'sales_manager' }
Copilot
AI
Jan 25, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test coverage for required fields should include validating that discriminated union requirements are enforced. Specifically, missing tests for:
- Owner-based rule without
ownedByfield should be rejected - Criteria-based rule without
conditionfield should be rejected
These are critical validations for the discriminated union schema. Consider adding test cases like:
- Testing that
{ name: 'test', object: 'account', type: 'owner', sharedWith: {...} }(missingownedBy) throws an error - Testing that
{ name: 'test', object: 'account', type: 'criteria', sharedWith: {...} }(missingcondition) throws an error
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test name "should accept user-specific sharing rule" is misleading. This test is actually validating a criteria-based sharing rule that happens to share with a user recipient. The test name suggests it's testing a different rule type, but 'user-specific' is not a rule type in the schema - it's just using 'user' as a recipient type. Consider renaming to something like "should accept criteria rule with user recipient" to more accurately describe what's being tested.