Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

chore(deps): update react (major) #998

Merged
merged 4 commits into from
Jan 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
fetch-depth: 2
- uses: pnpm/action-setup@v2
with:
version: 8.4.0
version: 9.15.2
run_install: false
- name: Get pnpm store directory
id: pnpm-cache
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
uses: actions/checkout@v3
- uses: pnpm/action-setup@v2
with:
version: 8.4.0
version: 9.15.2
run_install: false
- name: Get pnpm store directory
id: pnpm-cache
Expand Down
51 changes: 25 additions & 26 deletions packages/casl-ability/src/matchers/conditions.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,38 @@
import {
$all,
$elemMatch,
$eq,
eq,
$ne,
ne,
$lt,
lt,
$lte,
lte,
$exists,
$gt,
gt,
$gte,
gte,
$in,
within,
$lt,
$lte,
$ne,
$nin,
nin,
$all,
all,
$size,
size,
$regex,
$options,
regex,
$elemMatch,
elemMatch,
$exists,
exists,
$regex,
$size,
all,
and,
createFactory,
BuildMongoQuery,
createFactory,
DefaultOperators,
elemMatch,
eq,
exists,
gt,
gte,
lt,
lte,
ne,
nin,
regex,
size,
within
} from '@ucast/mongo2js';
import { ConditionsMatcher, AnyObject } from '../types';
import { Container, GenericFactory } from '../hkt';
import { AnyObject, ConditionsMatcher } from '../types';

const defaultInstructions = {
$eq,
Expand Down Expand Up @@ -87,7 +87,6 @@ export const buildMongoQueryMatcher = ((instructions, interpreters, options) =>

export const mongoQueryMatcher = createFactory(defaultInstructions, defaultInterpreters);
export type {
MongoQueryFieldOperators,
MongoQueryTopLevelOperators,
MongoQueryOperators,
MongoQueryFieldOperators, MongoQueryOperators, MongoQueryTopLevelOperators
} from '@ucast/mongo2js';

15 changes: 8 additions & 7 deletions packages/casl-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"build": "npm run build.prepare && BUILD_TYPES=es5m,es6m,umd dx rollup -n casl.react -g react:React,prop-types:React.PropTypes,@casl/ability:casl",
"build.types": "dx tsc",
"lint": "dx eslint src/ spec/",
"test": "dx jest --env jsdom --config ../dx/config/jest.chai.config.js",
"test": "dx jest --env jsdom",
"release.prepare": "npm run lint && npm test && NODE_ENV=production npm run build",
"release": "npm run release.prepare && dx semantic-release"
},
Expand All @@ -41,20 +41,21 @@
"author": "Sergii Stotskyi <[email protected]>",
"license": "MIT",
"peerDependencies": {
"@casl/ability": "^3.0.0 || ^4.0.0 || ^5.1.0 || ^6.0.0",
"react": "^16.0.0 || ^17.0.0 || ^18.0.0"
"@casl/ability": "^4.0.0 || ^5.1.0 || ^6.0.0",
"react": "^17.0.0 || ^18.0.0 || ^19.0.0"
},
"devDependencies": {
"@casl/ability": "^6.0.0",
"@casl/dx": "workspace:^1.0.0",
"@testing-library/react-hooks": "^4.0.1",
"@testing-library/dom": "^10.4.0",
"@testing-library/react": "^16.1.0",
"@types/jest": "^29.0.0",
"@types/node": "^22.0.0",
"@types/react": "^18.0.0",
"@types/react": "^19.0.0",
"chai": "^4.1.0",
"chai-spies": "^1.0.0",
"react": "^18.0.0",
"react-test-renderer": "^18.0.0"
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"files": [
"dist",
Expand Down
121 changes: 0 additions & 121 deletions packages/casl-react/spec/Can.spec.js

This file was deleted.

111 changes: 111 additions & 0 deletions packages/casl-react/spec/Can.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import React from 'react'
import { defineAbility, MongoAbility } from '@casl/ability'
import { Can } from '../src'
import { act, render, screen } from '@testing-library/react'

describe('`Can` component', () => {
let ability: MongoAbility

beforeEach(() => {
ability = defineAbility(can => can('read', 'Post'))
})

it('passes ability check value and instance as arguments to "children" function', () => {
const children = jest.fn()
render(<Can I="read" a="Post" ability={ability}>{children}</Can>)

expect(children).toHaveBeenCalledWith(ability.can('read', 'Post'), ability)
})

it('unsubscribes from ability updates when unmounted', () => {
jest.spyOn(ability, 'can')
const component = render(<Can I='read' a='Post' ability={ability}>test</Can>)

component.unmount()
act(() => ability.update([]))

expect(ability.can).toHaveBeenCalledTimes(1)
})

describe('rendering', () => {
it('renders children if ability allows to perform an action', () => {
render(<Can I='read' a='Post' ability={ability}>I can see it</Can>)

expect(screen.queryByText('I can see it')).toBeTruthy()
})

it('does not render children if ability does not allow to perform an action', () => {
render(<Can I="update" a="Post" ability={ability}>I can see it</Can>)

expect(screen.queryByText('I can see it')).not.toBeTruthy()
})

it('does not render children if ability allows to perform an action, but `not` is set to true', () => {
render(<Can not={true} I="read" a="Post" ability={ability}>I can see it</Can>)

expect(screen.queryByText('I can see it')).not.toBeTruthy()
})

it('rerenders when ability rules are changed', () => {
render(<Can I="read" a="Post" ability={ability}>I can see it</Can>)
expect(screen.queryByText('I can see it')).toBeTruthy()

act(() => ability.update([]))
expect(screen.findByText('I can see it')).toBeTruthy()
})

it('rerenders when `I` prop is changed', () => {
const component = render(<Can I="update" a="Post" ability={ability}>I can see it</Can>)
expect(screen.queryByText('I can see it')).not.toBeTruthy()

component.rerender(<Can I="read" a="Post" ability={ability}>I can see it</Can>)
expect(screen.queryByText('I can see it')).toBeTruthy()
})

it('rerenders when `a` or `an` or `this` prop is changed', () => {
const component = render(<Can I="read" a="User" ability={ability}>I can see it</Can>)
expect(screen.queryByText('I can see it')).not.toBeTruthy()

component.rerender(<Can I="read" a="Post" ability={ability}>I can see it</Can>)
expect(screen.queryByText('I can see it')).toBeTruthy()
})

it('rerenders when `not` prop is changed', () => {
const component = render(<Can not={true} I="read" a="Post" ability={ability}>I can see it</Can>)
expect(screen.queryByText('I can see it')).not.toBeTruthy()

component.rerender(<Can not={false} I="read" a="Post" ability={ability}>I can see it</Can>)
expect(screen.queryByText('I can see it')).toBeTruthy()
})

it('does not rerender itself when previous ability rules are changed', () => {
const component = render(<Can I="read" a="Post" ability={ability}>I can see it</Can>)
const anotherAbility = defineAbility(can => can('manage', 'Post'))

jest.spyOn(ability, 'can')
component.rerender(<Can I="read" a="Post" ability={anotherAbility}>I can see it</Can>)
act(() => ability.update([]))

expect(screen.queryByText('I can see it')).toBeTruthy()
expect(ability.can).not.toHaveBeenCalled()
})

it('can render multiple children with `React.Fragment`', () => {
render(<Can I="read" a="Post" ability={ability}><>
<p>line 1</p>
<p>line 2</p>
</></Can>)

expect(screen.queryByText('line 1')).toBeTruthy()
expect(screen.queryByText('line 2')).toBeTruthy()
})

it('always renders children if `passThrough` prop is `true`', () => {
const children = jest.fn()
render(<Can I="delete" a="Post" passThrough={true} ability={ability}>{children}</Can>)

expect(ability.can('delete', 'Post')).toBe(false)
expect(children).toHaveBeenCalledWith(false, ability)
})
})
})
Loading
Loading