@jperezmart/nest-casl-testing 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +63 -0
  2. package/package.json +6 -6
package/README.md ADDED
@@ -0,0 +1,63 @@
1
+ # @jperezmart/nest-casl-testing
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@jperezmart/nest-casl-testing.svg)](https://www.npmjs.com/package/@jperezmart/nest-casl-testing)
4
+ [![license](https://img.shields.io/npm/l/@jperezmart/nest-casl-testing.svg)](./LICENSE)
5
+
6
+ Testing utilities for [`@jperezmart/nest-casl`](https://github.com/jperezmart/nest-casl/tree/main/packages/core).
7
+ Build a CASL ability straight from a permissions map and a user, so permission
8
+ definitions can be unit-tested without booting a Nest application.
9
+
10
+ ## Install
11
+
12
+ ```bash
13
+ pnpm add -D @jperezmart/nest-casl-testing
14
+ ```
15
+
16
+ `@casl/ability` and `@jperezmart/nest-casl` are peer dependencies.
17
+
18
+ ## `buildAbilityForTest(permissions, user, options?)`
19
+
20
+ Takes the same `permissions` map you pass to `CaslModule.forFeature` and the
21
+ user you would otherwise have to authenticate, and returns the ability CASL
22
+ would have built:
23
+
24
+ ```ts
25
+ import { buildAbilityForTest } from '@jperezmart/nest-casl-testing';
26
+ import { subject } from '@casl/ability';
27
+
28
+ const permissions = {
29
+ author: (user, { can }) => {
30
+ can('read', 'Article');
31
+ can('update', 'Article', { authorId: user.id });
32
+ },
33
+ };
34
+
35
+ const ability = buildAbilityForTest(permissions, {
36
+ id: '1',
37
+ roles: ['author'],
38
+ });
39
+
40
+ expect(ability.can('read', 'Article')).toBe(true);
41
+ expect(ability.can('update', subject('Article', { authorId: '1' }))).toBe(true);
42
+ expect(ability.can('update', subject('Article', { authorId: '2' }))).toBe(
43
+ false,
44
+ );
45
+ ```
46
+
47
+ ### Options
48
+
49
+ Both mirror `CaslModule.forRoot`, so a test builds the same ability the running
50
+ application would:
51
+
52
+ | Option | Type | Effect |
53
+ | ------------------- | ----------------------------- | ------------------------------------------------------------------------------------ |
54
+ | `superuserRole` | `string` | A user holding this role gets `can('manage', 'all')` and no other rule is evaluated. |
55
+ | `detectSubjectType` | `(subject: object) => string` | Custom subject-type detection, for subjects CASL cannot name on its own. |
56
+
57
+ A role whose definition is `true` rather than a function also grants
58
+ `manage all`. A user whose `roles` is missing or not an array is treated as
59
+ having no roles, which is what `AbilityFactory` does.
60
+
61
+ ## License
62
+
63
+ MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jperezmart/nest-casl-testing",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Testing utilities for @jperezmart/nest-casl — build and assert abilities without booting Nest.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -34,17 +34,17 @@
34
34
  ],
35
35
  "devDependencies": {
36
36
  "@casl/ability": "^7.0.0",
37
+ "@jperezmart/eslint-config": "^1.0.0",
38
+ "@jperezmart/nest-casl": "0.1.2",
39
+ "@jperezmart/typescript-config": "^1.0.0",
37
40
  "eslint": "^10.3.0",
38
41
  "tsdown": "^0.22.2",
39
42
  "typescript": "^6.0.3",
40
- "vitest": "^4.1.9",
41
- "@jperezmart/eslint-config": "0.0.0",
42
- "@jperezmart/typescript-config": "0.0.0",
43
- "@jperezmart/nest-casl": "0.1.1"
43
+ "vitest": "^4.1.9"
44
44
  },
45
45
  "peerDependencies": {
46
46
  "@casl/ability": "^7.0.0",
47
- "@jperezmart/nest-casl": "^0.1.1"
47
+ "@jperezmart/nest-casl": "^0.1.2"
48
48
  },
49
49
  "publishConfig": {
50
50
  "access": "public"