@api-client/core 0.18.56 → 0.18.58
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.
- package/build/src/modeling/ApiModel.d.ts +7 -5
- package/build/src/modeling/ApiModel.d.ts.map +1 -1
- package/build/src/modeling/ApiModel.js +35 -16
- package/build/src/modeling/ApiModel.js.map +1 -1
- package/build/src/modeling/ExposedEntity.d.ts +5 -2
- package/build/src/modeling/ExposedEntity.d.ts.map +1 -1
- package/build/src/modeling/ExposedEntity.js +11 -8
- package/build/src/modeling/ExposedEntity.js.map +1 -1
- package/build/src/modeling/actions/Action.d.ts +41 -0
- package/build/src/modeling/actions/Action.d.ts.map +1 -0
- package/build/src/modeling/actions/Action.js +64 -0
- package/build/src/modeling/actions/Action.js.map +1 -0
- package/build/src/modeling/actions/CreateAction.d.ts +18 -0
- package/build/src/modeling/actions/CreateAction.d.ts.map +1 -0
- package/build/src/modeling/actions/CreateAction.js +37 -0
- package/build/src/modeling/actions/CreateAction.js.map +1 -0
- package/build/src/modeling/actions/DeleteAction.d.ts +34 -0
- package/build/src/modeling/actions/DeleteAction.d.ts.map +1 -0
- package/build/src/modeling/actions/DeleteAction.js +57 -0
- package/build/src/modeling/actions/DeleteAction.js.map +1 -0
- package/build/src/modeling/actions/ListAction.d.ts +37 -0
- package/build/src/modeling/actions/ListAction.d.ts.map +1 -0
- package/build/src/modeling/actions/ListAction.js +70 -0
- package/build/src/modeling/actions/ListAction.js.map +1 -0
- package/build/src/modeling/actions/ReadAction.d.ts +18 -0
- package/build/src/modeling/actions/ReadAction.d.ts.map +1 -0
- package/build/src/modeling/actions/ReadAction.js +37 -0
- package/build/src/modeling/actions/ReadAction.js.map +1 -0
- package/build/src/modeling/actions/SearchAction.d.ts +24 -0
- package/build/src/modeling/actions/SearchAction.d.ts.map +1 -0
- package/build/src/modeling/actions/SearchAction.js +47 -0
- package/build/src/modeling/actions/SearchAction.js.map +1 -0
- package/build/src/modeling/actions/UpdateAction.d.ts +27 -0
- package/build/src/modeling/actions/UpdateAction.d.ts.map +1 -0
- package/build/src/modeling/actions/UpdateAction.js +47 -0
- package/build/src/modeling/actions/UpdateAction.js.map +1 -0
- package/build/src/modeling/actions/index.d.ts +24 -0
- package/build/src/modeling/actions/index.d.ts.map +1 -0
- package/build/src/modeling/actions/index.js +9 -0
- package/build/src/modeling/actions/index.js.map +1 -0
- package/build/src/modeling/helpers/Intelisense.d.ts +1 -0
- package/build/src/modeling/helpers/Intelisense.d.ts.map +1 -1
- package/build/src/modeling/helpers/Intelisense.js +23 -0
- package/build/src/modeling/helpers/Intelisense.js.map +1 -1
- package/build/src/modeling/index.d.ts +12 -0
- package/build/src/modeling/index.d.ts.map +1 -0
- package/build/src/modeling/index.js +12 -0
- package/build/src/modeling/index.js.map +1 -0
- package/build/src/modeling/rules/AccessRule.d.ts +17 -0
- package/build/src/modeling/rules/AccessRule.d.ts.map +1 -0
- package/build/src/modeling/rules/AccessRule.js +19 -0
- package/build/src/modeling/rules/AccessRule.js.map +1 -0
- package/build/src/modeling/rules/AllowAuthenticated.d.ts +19 -0
- package/build/src/modeling/rules/AllowAuthenticated.d.ts.map +1 -0
- package/build/src/modeling/rules/AllowAuthenticated.js +14 -0
- package/build/src/modeling/rules/AllowAuthenticated.js.map +1 -0
- package/build/src/modeling/rules/AllowPublic.d.ts +19 -0
- package/build/src/modeling/rules/AllowPublic.d.ts.map +1 -0
- package/build/src/modeling/rules/AllowPublic.js +14 -0
- package/build/src/modeling/rules/AllowPublic.js.map +1 -0
- package/build/src/modeling/rules/MatchEmailDomain.d.ts +25 -0
- package/build/src/modeling/rules/MatchEmailDomain.d.ts.map +1 -0
- package/build/src/modeling/rules/MatchEmailDomain.js +40 -0
- package/build/src/modeling/rules/MatchEmailDomain.js.map +1 -0
- package/build/src/modeling/rules/MatchResourceOwner.d.ts +29 -0
- package/build/src/modeling/rules/MatchResourceOwner.d.ts.map +1 -0
- package/build/src/modeling/rules/MatchResourceOwner.js +40 -0
- package/build/src/modeling/rules/MatchResourceOwner.js.map +1 -0
- package/build/src/modeling/rules/MatchUserProperty.d.ts +28 -0
- package/build/src/modeling/rules/MatchUserProperty.d.ts.map +1 -0
- package/build/src/modeling/rules/MatchUserProperty.js +49 -0
- package/build/src/modeling/rules/MatchUserProperty.js.map +1 -0
- package/build/src/modeling/rules/MatchUserRole.d.ts +29 -0
- package/build/src/modeling/rules/MatchUserRole.d.ts.map +1 -0
- package/build/src/modeling/rules/MatchUserRole.js +40 -0
- package/build/src/modeling/rules/MatchUserRole.js.map +1 -0
- package/build/src/modeling/rules/RateLimitRule.d.ts +61 -0
- package/build/src/modeling/rules/RateLimitRule.d.ts.map +1 -0
- package/build/src/modeling/rules/RateLimitRule.js +101 -0
- package/build/src/modeling/rules/RateLimitRule.js.map +1 -0
- package/build/src/modeling/rules/RateLimitingConfiguration.d.ts +18 -0
- package/build/src/modeling/rules/RateLimitingConfiguration.d.ts.map +1 -0
- package/build/src/modeling/rules/RateLimitingConfiguration.js +35 -0
- package/build/src/modeling/rules/RateLimitingConfiguration.js.map +1 -0
- package/build/src/modeling/rules/index.d.ts +13 -0
- package/build/src/modeling/rules/index.d.ts.map +1 -0
- package/build/src/modeling/rules/index.js +10 -0
- package/build/src/modeling/rules/index.js.map +1 -0
- package/build/src/modeling/types.d.ts +6 -257
- package/build/src/modeling/types.d.ts.map +1 -1
- package/build/src/modeling/types.js.map +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/data/models/example-generator-api.json +27 -27
- package/package.json +2 -7
- package/src/modeling/ApiModel.ts +21 -19
- package/src/modeling/ExposedEntity.ts +13 -18
- package/src/modeling/actions/Action.ts +64 -0
- package/src/modeling/actions/CreateAction.ts +30 -0
- package/src/modeling/actions/DeleteAction.ts +51 -0
- package/src/modeling/actions/ListAction.ts +58 -0
- package/src/modeling/actions/ReadAction.ts +32 -0
- package/src/modeling/actions/SearchAction.ts +38 -0
- package/src/modeling/actions/UpdateAction.ts +41 -0
- package/src/modeling/helpers/Intelisense.ts +23 -0
- package/src/modeling/rules/AccessRule.ts +29 -0
- package/src/modeling/rules/AllowAuthenticated.ts +24 -0
- package/src/modeling/rules/AllowPublic.ts +24 -0
- package/src/modeling/rules/MatchEmailDomain.ts +39 -0
- package/src/modeling/rules/MatchResourceOwner.ts +43 -0
- package/src/modeling/rules/MatchUserProperty.ts +44 -0
- package/src/modeling/rules/MatchUserRole.ts +43 -0
- package/src/modeling/rules/RateLimitRule.ts +104 -0
- package/src/modeling/rules/RateLimitingConfiguration.ts +32 -0
- package/src/modeling/types.ts +6 -276
- package/tests/unit/modeling/actions/Action.spec.ts +109 -0
- package/tests/unit/modeling/actions/CreateAction.spec.ts +65 -0
- package/tests/unit/modeling/actions/DeleteAction.spec.ts +78 -0
- package/tests/unit/modeling/actions/ListAction.spec.ts +106 -0
- package/tests/unit/modeling/actions/ReadAction.spec.ts +77 -0
- package/tests/unit/modeling/actions/SearchAction.spec.ts +73 -0
- package/tests/unit/modeling/actions/UpdateAction.spec.ts +73 -0
- package/tests/unit/modeling/api_model.spec.ts +48 -3
- package/tests/unit/modeling/exposed_entity.spec.ts +73 -0
- package/tests/unit/modeling/helpers/intellisense.spec.ts +46 -0
- package/tests/unit/modeling/rules/AccessRule.spec.ts +42 -0
- package/tests/unit/modeling/rules/AllowAuthenticated.spec.ts +28 -0
- package/tests/unit/modeling/rules/AllowPublic.spec.ts +28 -0
- package/tests/unit/modeling/rules/MatchEmailDomain.spec.ts +52 -0
- package/tests/unit/modeling/rules/MatchResourceOwner.spec.ts +37 -0
- package/tests/unit/modeling/rules/MatchUserProperty.spec.ts +58 -0
- package/tests/unit/modeling/rules/MatchUserRole.spec.ts +52 -0
- package/tests/unit/modeling/rules/RateLimitRule.spec.ts +70 -0
- package/tests/unit/modeling/rules/RateLimitingConfiguration.spec.ts +61 -0
- package/build/src/modeling/templates/index.d.ts +0 -21
- package/build/src/modeling/templates/index.d.ts.map +0 -1
- package/build/src/modeling/templates/index.js +0 -176
- package/build/src/modeling/templates/index.js.map +0 -1
- package/build/src/modeling/templates/meta/blog-publishing-platform.json +0 -1
- package/build/src/modeling/templates/meta/ecommerce-platform.json +0 -1
- package/build/src/modeling/templates/meta/education-management-platform.json +0 -1
- package/build/src/modeling/templates/meta/financial-services-platform.json +0 -1
- package/build/src/modeling/templates/meta/gaming-platform.json +0 -1
- package/build/src/modeling/templates/meta/healthcare-management-platform.json +0 -1
- package/build/src/modeling/templates/meta/hospitality-platform.json +0 -1
- package/build/src/modeling/templates/meta/index.d.ts +0 -64
- package/build/src/modeling/templates/meta/index.d.ts.map +0 -1
- package/build/src/modeling/templates/meta/index.js +0 -150
- package/build/src/modeling/templates/meta/index.js.map +0 -1
- package/build/src/modeling/templates/meta/iot-smart-home-platform.json +0 -1
- package/build/src/modeling/templates/meta/legal-services-platform.json +0 -1
- package/build/src/modeling/templates/meta/manufacturing-platform.json +0 -1
- package/build/src/modeling/templates/meta/non-profit-platform.json +0 -1
- package/build/src/modeling/templates/meta/real-estate-management-platform.json +0 -1
- package/build/src/modeling/templates/template-registry.d.ts +0 -55
- package/build/src/modeling/templates/template-registry.d.ts.map +0 -1
- package/build/src/modeling/templates/template-registry.js +0 -111
- package/build/src/modeling/templates/template-registry.js.map +0 -1
- package/build/src/modeling/templates/types.d.ts +0 -167
- package/build/src/modeling/templates/types.d.ts.map +0 -1
- package/build/src/modeling/templates/types.js +0 -2
- package/build/src/modeling/templates/types.js.map +0 -1
- package/build/src/modeling/templates/verticals/business-services/ecommerce-domain.d.ts +0 -39
- package/build/src/modeling/templates/verticals/business-services/ecommerce-domain.d.ts.map +0 -1
- package/build/src/modeling/templates/verticals/business-services/ecommerce-domain.js +0 -672
- package/build/src/modeling/templates/verticals/business-services/ecommerce-domain.js.map +0 -1
- package/build/src/modeling/templates/verticals/business-services/financial-services-domain.d.ts +0 -40
- package/build/src/modeling/templates/verticals/business-services/financial-services-domain.d.ts.map +0 -1
- package/build/src/modeling/templates/verticals/business-services/financial-services-domain.js +0 -942
- package/build/src/modeling/templates/verticals/business-services/financial-services-domain.js.map +0 -1
- package/build/src/modeling/templates/verticals/business-services/hospitality-domain.d.ts +0 -45
- package/build/src/modeling/templates/verticals/business-services/hospitality-domain.d.ts.map +0 -1
- package/build/src/modeling/templates/verticals/business-services/hospitality-domain.js +0 -797
- package/build/src/modeling/templates/verticals/business-services/hospitality-domain.js.map +0 -1
- package/build/src/modeling/templates/verticals/business-services/index.d.ts +0 -21
- package/build/src/modeling/templates/verticals/business-services/index.d.ts.map +0 -1
- package/build/src/modeling/templates/verticals/business-services/index.js +0 -50
- package/build/src/modeling/templates/verticals/business-services/index.js.map +0 -1
- package/build/src/modeling/templates/verticals/business-services/legal-services-domain.d.ts +0 -46
- package/build/src/modeling/templates/verticals/business-services/legal-services-domain.d.ts.map +0 -1
- package/build/src/modeling/templates/verticals/business-services/legal-services-domain.js +0 -837
- package/build/src/modeling/templates/verticals/business-services/legal-services-domain.js.map +0 -1
- package/build/src/modeling/templates/verticals/education-training/education-domain.d.ts +0 -40
- package/build/src/modeling/templates/verticals/education-training/education-domain.d.ts.map +0 -1
- package/build/src/modeling/templates/verticals/education-training/education-domain.js +0 -725
- package/build/src/modeling/templates/verticals/education-training/education-domain.js.map +0 -1
- package/build/src/modeling/templates/verticals/education-training/index.d.ts +0 -18
- package/build/src/modeling/templates/verticals/education-training/index.d.ts.map +0 -1
- package/build/src/modeling/templates/verticals/education-training/index.js +0 -21
- package/build/src/modeling/templates/verticals/education-training/index.js.map +0 -1
- package/build/src/modeling/templates/verticals/healthcare-life-sciences/healthcare-domain.d.ts +0 -40
- package/build/src/modeling/templates/verticals/healthcare-life-sciences/healthcare-domain.d.ts.map +0 -1
- package/build/src/modeling/templates/verticals/healthcare-life-sciences/healthcare-domain.js +0 -859
- package/build/src/modeling/templates/verticals/healthcare-life-sciences/healthcare-domain.js.map +0 -1
- package/build/src/modeling/templates/verticals/healthcare-life-sciences/index.d.ts +0 -18
- package/build/src/modeling/templates/verticals/healthcare-life-sciences/index.d.ts.map +0 -1
- package/build/src/modeling/templates/verticals/healthcare-life-sciences/index.js +0 -21
- package/build/src/modeling/templates/verticals/healthcare-life-sciences/index.js.map +0 -1
- package/build/src/modeling/templates/verticals/index.d.ts +0 -79
- package/build/src/modeling/templates/verticals/index.d.ts.map +0 -1
- package/build/src/modeling/templates/verticals/index.js +0 -186
- package/build/src/modeling/templates/verticals/index.js.map +0 -1
- package/build/src/modeling/templates/verticals/manufacturing-logistics/index.d.ts +0 -18
- package/build/src/modeling/templates/verticals/manufacturing-logistics/index.d.ts.map +0 -1
- package/build/src/modeling/templates/verticals/manufacturing-logistics/index.js +0 -22
- package/build/src/modeling/templates/verticals/manufacturing-logistics/index.js.map +0 -1
- package/build/src/modeling/templates/verticals/manufacturing-logistics/manufacturing-domain.d.ts +0 -45
- package/build/src/modeling/templates/verticals/manufacturing-logistics/manufacturing-domain.d.ts.map +0 -1
- package/build/src/modeling/templates/verticals/manufacturing-logistics/manufacturing-domain.js +0 -710
- package/build/src/modeling/templates/verticals/manufacturing-logistics/manufacturing-domain.js.map +0 -1
- package/build/src/modeling/templates/verticals/public-sector/index.d.ts +0 -18
- package/build/src/modeling/templates/verticals/public-sector/index.d.ts.map +0 -1
- package/build/src/modeling/templates/verticals/public-sector/index.js +0 -22
- package/build/src/modeling/templates/verticals/public-sector/index.js.map +0 -1
- package/build/src/modeling/templates/verticals/public-sector/non-profit-domain.d.ts +0 -47
- package/build/src/modeling/templates/verticals/public-sector/non-profit-domain.d.ts.map +0 -1
- package/build/src/modeling/templates/verticals/public-sector/non-profit-domain.js +0 -864
- package/build/src/modeling/templates/verticals/public-sector/non-profit-domain.js.map +0 -1
- package/build/src/modeling/templates/verticals/real-estate-construction/index.d.ts +0 -18
- package/build/src/modeling/templates/verticals/real-estate-construction/index.d.ts.map +0 -1
- package/build/src/modeling/templates/verticals/real-estate-construction/index.js +0 -21
- package/build/src/modeling/templates/verticals/real-estate-construction/index.js.map +0 -1
- package/build/src/modeling/templates/verticals/real-estate-construction/real-estate-domain.d.ts +0 -40
- package/build/src/modeling/templates/verticals/real-estate-construction/real-estate-domain.d.ts.map +0 -1
- package/build/src/modeling/templates/verticals/real-estate-construction/real-estate-domain.js +0 -727
- package/build/src/modeling/templates/verticals/real-estate-construction/real-estate-domain.js.map +0 -1
- package/build/src/modeling/templates/verticals/technology-media/blog-domain.d.ts +0 -40
- package/build/src/modeling/templates/verticals/technology-media/blog-domain.d.ts.map +0 -1
- package/build/src/modeling/templates/verticals/technology-media/blog-domain.js +0 -629
- package/build/src/modeling/templates/verticals/technology-media/blog-domain.js.map +0 -1
- package/build/src/modeling/templates/verticals/technology-media/gaming-domain.d.ts +0 -46
- package/build/src/modeling/templates/verticals/technology-media/gaming-domain.d.ts.map +0 -1
- package/build/src/modeling/templates/verticals/technology-media/gaming-domain.js +0 -1033
- package/build/src/modeling/templates/verticals/technology-media/gaming-domain.js.map +0 -1
- package/build/src/modeling/templates/verticals/technology-media/index.d.ts +0 -21
- package/build/src/modeling/templates/verticals/technology-media/index.d.ts.map +0 -1
- package/build/src/modeling/templates/verticals/technology-media/index.js +0 -42
- package/build/src/modeling/templates/verticals/technology-media/index.js.map +0 -1
- package/build/src/modeling/templates/verticals/technology-media/iot-smart-home-domain.d.ts +0 -47
- package/build/src/modeling/templates/verticals/technology-media/iot-smart-home-domain.d.ts.map +0 -1
- package/build/src/modeling/templates/verticals/technology-media/iot-smart-home-domain.js +0 -1029
- package/build/src/modeling/templates/verticals/technology-media/iot-smart-home-domain.js.map +0 -1
- package/src/modeling/templates/meta/blog-publishing-platform.json +0 -1
- package/src/modeling/templates/meta/ecommerce-platform.json +0 -1
- package/src/modeling/templates/meta/education-management-platform.json +0 -1
- package/src/modeling/templates/meta/financial-services-platform.json +0 -1
- package/src/modeling/templates/meta/gaming-platform.json +0 -1
- package/src/modeling/templates/meta/healthcare-management-platform.json +0 -1
- package/src/modeling/templates/meta/hospitality-platform.json +0 -1
- package/src/modeling/templates/meta/iot-smart-home-platform.json +0 -1
- package/src/modeling/templates/meta/legal-services-platform.json +0 -1
- package/src/modeling/templates/meta/manufacturing-platform.json +0 -1
- package/src/modeling/templates/meta/non-profit-platform.json +0 -1
- package/src/modeling/templates/meta/real-estate-management-platform.json +0 -1
- package/src/modeling/templates/readme.md +0 -260
- package/src/modeling/templates/template-registry.ts +0 -140
- package/src/modeling/templates/types.ts +0 -175
- package/src/modeling/templates/verticals/README.md +0 -122
- package/src/modeling/templates/verticals/business-services/ecommerce-domain.ts +0 -844
- package/src/modeling/templates/verticals/business-services/financial-services-domain.ts +0 -1177
- package/src/modeling/templates/verticals/business-services/hospitality-domain.ts +0 -994
- package/src/modeling/templates/verticals/business-services/legal-services-domain.ts +0 -1059
- package/src/modeling/templates/verticals/education-training/education-domain.ts +0 -922
- package/src/modeling/templates/verticals/healthcare-life-sciences/healthcare-domain.ts +0 -1111
- package/src/modeling/templates/verticals/manufacturing-logistics/manufacturing-domain.ts +0 -895
- package/src/modeling/templates/verticals/public-sector/non-profit-domain.ts +0 -1109
- package/src/modeling/templates/verticals/real-estate-construction/real-estate-domain.ts +0 -944
- package/src/modeling/templates/verticals/technology-media/blog-domain.ts +0 -796
- package/src/modeling/templates/verticals/technology-media/gaming-domain.ts +0 -1290
- package/src/modeling/templates/verticals/technology-media/iot-smart-home-domain.ts +0 -1289
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { test } from '@japa/runner'
|
|
2
|
+
import { ReadAction } from '../../../../src/modeling/actions/ReadAction.js'
|
|
3
|
+
import { AccessRule } from '../../../../src/modeling/rules/index.js'
|
|
4
|
+
|
|
5
|
+
test.group('ReadAction', () => {
|
|
6
|
+
test('initializes with default values', ({ assert }) => {
|
|
7
|
+
const action = new ReadAction()
|
|
8
|
+
assert.equal(action.kind, 'read')
|
|
9
|
+
assert.isEmpty(action.accessRule) // Inherited from Action
|
|
10
|
+
}).tags(['@modeling', '@action', '@read-action'])
|
|
11
|
+
|
|
12
|
+
test('initializes with inherited values', ({ assert }) => {
|
|
13
|
+
const action = new ReadAction({
|
|
14
|
+
accessRule: [{ type: 'public' }],
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
assert.equal(action.kind, 'read')
|
|
18
|
+
assert.lengthOf(action.accessRule, 1)
|
|
19
|
+
assert.equal(action.accessRule[0].type, 'public')
|
|
20
|
+
}).tags(['@modeling', '@action', '@read-action'])
|
|
21
|
+
|
|
22
|
+
test('constructor copies arrays (immutability)', ({ assert }) => {
|
|
23
|
+
const rules = [{ type: 'public' }]
|
|
24
|
+
|
|
25
|
+
const action = new ReadAction({
|
|
26
|
+
accessRule: rules,
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
// Modify original source
|
|
30
|
+
rules.push({ type: 'admin' })
|
|
31
|
+
rules[0].type = 'changed'
|
|
32
|
+
|
|
33
|
+
assert.lengthOf(action.accessRule, 1)
|
|
34
|
+
assert.equal(action.accessRule[0].type, 'public')
|
|
35
|
+
}).tags(['@modeling', '@action', '@read-action', '@immutability'])
|
|
36
|
+
|
|
37
|
+
test('toJSON returns valid schema', ({ assert }) => {
|
|
38
|
+
const action = new ReadAction({
|
|
39
|
+
accessRule: [{ type: 'public' }],
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
const json = action.toJSON()
|
|
43
|
+
|
|
44
|
+
assert.equal(json.kind, 'read')
|
|
45
|
+
if (json.accessRule) {
|
|
46
|
+
assert.lengthOf(json.accessRule, 1)
|
|
47
|
+
assert.equal(json.accessRule[0].type, 'public')
|
|
48
|
+
} else {
|
|
49
|
+
assert.fail('accessRule should be present in JSON')
|
|
50
|
+
}
|
|
51
|
+
}).tags(['@modeling', '@action', '@read-action', '@serialization'])
|
|
52
|
+
|
|
53
|
+
test('notifies change when inherited property changes', async ({ assert }) => {
|
|
54
|
+
const action = new ReadAction()
|
|
55
|
+
let notified = false
|
|
56
|
+
action.addEventListener('change', () => {
|
|
57
|
+
notified = true
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
// Modify inherited property
|
|
61
|
+
action.accessRule = [new AccessRule({ type: 'admin' })]
|
|
62
|
+
await Promise.resolve()
|
|
63
|
+
assert.isTrue(notified)
|
|
64
|
+
}).tags(['@modeling', '@action', '@read-action', '@observed'])
|
|
65
|
+
|
|
66
|
+
test('notifies change when accessRule value change', async ({ assert }) => {
|
|
67
|
+
const action = new ReadAction()
|
|
68
|
+
let notified = false
|
|
69
|
+
action.addEventListener('change', () => {
|
|
70
|
+
notified = true
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
action.accessRule.push(new AccessRule({ type: 'admin' }))
|
|
74
|
+
await Promise.resolve()
|
|
75
|
+
assert.isTrue(notified)
|
|
76
|
+
}).tags(['@modeling', '@action', '@read-action', '@observed'])
|
|
77
|
+
})
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { test } from '@japa/runner'
|
|
2
|
+
import { SearchAction } from '../../../../src/modeling/actions/SearchAction.js'
|
|
3
|
+
|
|
4
|
+
test.group('SearchAction', () => {
|
|
5
|
+
test('initializes with default values', ({ assert }) => {
|
|
6
|
+
const action = new SearchAction()
|
|
7
|
+
assert.equal(action.kind, 'search')
|
|
8
|
+
assert.deepEqual(action.fields, [])
|
|
9
|
+
assert.isEmpty(action.accessRule)
|
|
10
|
+
}).tags(['@modeling', '@action', '@search-action'])
|
|
11
|
+
|
|
12
|
+
test('initializes with provided values', ({ assert }) => {
|
|
13
|
+
const fields = ['name', 'description']
|
|
14
|
+
const action = new SearchAction({
|
|
15
|
+
fields,
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
assert.equal(action.kind, 'search')
|
|
19
|
+
assert.deepEqual(action.fields, fields)
|
|
20
|
+
}).tags(['@modeling', '@action', '@search-action'])
|
|
21
|
+
|
|
22
|
+
test('constructor copies arrays (immutability)', ({ assert }) => {
|
|
23
|
+
const fields = ['name']
|
|
24
|
+
|
|
25
|
+
const action = new SearchAction({
|
|
26
|
+
fields,
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
// Modify original source
|
|
30
|
+
fields.push('age')
|
|
31
|
+
|
|
32
|
+
assert.deepEqual(action.fields, ['name'])
|
|
33
|
+
}).tags(['@modeling', '@action', '@search-action', '@immutability'])
|
|
34
|
+
|
|
35
|
+
test('toJSON returns valid schema', ({ assert }) => {
|
|
36
|
+
const action = new SearchAction({
|
|
37
|
+
fields: ['name'],
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
const json = action.toJSON()
|
|
41
|
+
|
|
42
|
+
// Modify JSON
|
|
43
|
+
json.fields.push('new')
|
|
44
|
+
|
|
45
|
+
assert.equal(json.kind, 'search')
|
|
46
|
+
assert.lengthOf(action.fields, 1) // Ensure immutability
|
|
47
|
+
assert.equal(action.fields[0], 'name')
|
|
48
|
+
}).tags(['@modeling', '@action', '@search-action', '@serialization', '@immutability'])
|
|
49
|
+
|
|
50
|
+
test('notifies change when fields changes', async ({ assert }) => {
|
|
51
|
+
const action = new SearchAction()
|
|
52
|
+
let notified = false
|
|
53
|
+
action.addEventListener('change', () => {
|
|
54
|
+
notified = true
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
action.fields = ['name']
|
|
58
|
+
await Promise.resolve()
|
|
59
|
+
assert.isTrue(notified)
|
|
60
|
+
}).tags(['@modeling', '@action', '@search-action', '@observed'])
|
|
61
|
+
|
|
62
|
+
test('notifies change when fields value change', async ({ assert }) => {
|
|
63
|
+
const action = new SearchAction()
|
|
64
|
+
let notified = false
|
|
65
|
+
action.addEventListener('change', () => {
|
|
66
|
+
notified = true
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
action.fields.push('name')
|
|
70
|
+
await Promise.resolve()
|
|
71
|
+
assert.isTrue(notified)
|
|
72
|
+
}).tags(['@modeling', '@action', '@search-action', '@observed'])
|
|
73
|
+
})
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { test } from '@japa/runner'
|
|
2
|
+
import { UpdateAction } from '../../../../src/modeling/actions/UpdateAction.js'
|
|
3
|
+
|
|
4
|
+
test.group('UpdateAction', () => {
|
|
5
|
+
test('initializes with default values', ({ assert }) => {
|
|
6
|
+
const action = new UpdateAction()
|
|
7
|
+
assert.equal(action.kind, 'update')
|
|
8
|
+
assert.deepEqual(action.allowedMethods, ['PATCH'])
|
|
9
|
+
assert.isEmpty(action.accessRule)
|
|
10
|
+
}).tags(['@modeling', '@action', '@update-action'])
|
|
11
|
+
|
|
12
|
+
test('initializes with provided values', ({ assert }) => {
|
|
13
|
+
const methods: ('PUT' | 'PATCH')[] = ['PUT', 'PATCH']
|
|
14
|
+
const action = new UpdateAction({
|
|
15
|
+
allowedMethods: methods,
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
assert.equal(action.kind, 'update')
|
|
19
|
+
assert.deepEqual(action.allowedMethods, methods)
|
|
20
|
+
}).tags(['@modeling', '@action', '@update-action'])
|
|
21
|
+
|
|
22
|
+
test('constructor copies arrays (immutability)', ({ assert }) => {
|
|
23
|
+
const methods: ('PUT' | 'PATCH')[] = ['PUT']
|
|
24
|
+
|
|
25
|
+
const action = new UpdateAction({
|
|
26
|
+
allowedMethods: methods,
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
// Modify original source
|
|
30
|
+
methods.push('PATCH')
|
|
31
|
+
|
|
32
|
+
assert.deepEqual(action.allowedMethods, ['PUT'])
|
|
33
|
+
}).tags(['@modeling', '@action', '@update-action', '@immutability'])
|
|
34
|
+
|
|
35
|
+
test('toJSON returns valid schema', ({ assert }) => {
|
|
36
|
+
const action = new UpdateAction({
|
|
37
|
+
allowedMethods: ['PUT'],
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
const json = action.toJSON()
|
|
41
|
+
|
|
42
|
+
// Modify JSON
|
|
43
|
+
json.allowedMethods.push('PATCH')
|
|
44
|
+
|
|
45
|
+
assert.equal(json.kind, 'update')
|
|
46
|
+
assert.lengthOf(action.allowedMethods, 1) // Ensure immutability
|
|
47
|
+
assert.equal(action.allowedMethods[0], 'PUT')
|
|
48
|
+
}).tags(['@modeling', '@action', '@update-action', '@serialization', '@immutability'])
|
|
49
|
+
|
|
50
|
+
test('notifies change when allowedMethods changes', async ({ assert }) => {
|
|
51
|
+
const action = new UpdateAction()
|
|
52
|
+
let notified = false
|
|
53
|
+
action.addEventListener('change', () => {
|
|
54
|
+
notified = true
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
action.allowedMethods = ['PUT', 'PATCH']
|
|
58
|
+
await Promise.resolve()
|
|
59
|
+
assert.isTrue(notified)
|
|
60
|
+
}).tags(['@modeling', '@action', '@update-action', '@observed'])
|
|
61
|
+
|
|
62
|
+
test('notifies change when allowedMethods value change', async ({ assert }) => {
|
|
63
|
+
const action = new UpdateAction()
|
|
64
|
+
let notified = false
|
|
65
|
+
action.addEventListener('change', () => {
|
|
66
|
+
notified = true
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
action.allowedMethods.push('PUT')
|
|
70
|
+
await Promise.resolve()
|
|
71
|
+
assert.isTrue(notified)
|
|
72
|
+
}).tags(['@modeling', '@action', '@update-action', '@observed'])
|
|
73
|
+
})
|
|
@@ -11,6 +11,9 @@ import {
|
|
|
11
11
|
ExposedEntityKind,
|
|
12
12
|
ExposedEntity,
|
|
13
13
|
} from '../../../src/index.js'
|
|
14
|
+
import { AllowPublicAccessRule } from '../../../src/modeling/rules/AllowPublic.js'
|
|
15
|
+
import { RateLimitingConfiguration } from '../../../src/modeling/rules/RateLimitingConfiguration.js'
|
|
16
|
+
import { Action } from '../../../src/modeling/index.js'
|
|
14
17
|
|
|
15
18
|
test.group('ApiModel.createSchema()', () => {
|
|
16
19
|
test('creates a schema with default values', ({ assert }) => {
|
|
@@ -99,7 +102,7 @@ test.group('ApiModel.constructor()', () => {
|
|
|
99
102
|
assert.isUndefined(model.authentication)
|
|
100
103
|
assert.isUndefined(model.authorization)
|
|
101
104
|
assert.isUndefined(model.session)
|
|
102
|
-
assert.
|
|
105
|
+
assert.isEmpty(model.accessRule)
|
|
103
106
|
assert.isUndefined(model.rateLimiting)
|
|
104
107
|
assert.isUndefined(model.termsOfService)
|
|
105
108
|
assert.isUndefined(model.contact)
|
|
@@ -144,8 +147,8 @@ test.group('ApiModel.constructor()', () => {
|
|
|
144
147
|
assert.deepEqual(model.authentication, { strategy: 'UsernamePassword' })
|
|
145
148
|
assert.deepEqual(model.authorization, { strategy: 'RBAC', roleKey: 'role' })
|
|
146
149
|
assert.deepEqual(model.session, { secret: 'secret', properties: ['email'] })
|
|
147
|
-
assert.deepEqual(model.accessRule, [
|
|
148
|
-
assert.deepEqual(model.rateLimiting,
|
|
150
|
+
assert.deepEqual(model.accessRule, [new AllowPublicAccessRule()])
|
|
151
|
+
assert.deepEqual(model.rateLimiting, new RateLimitingConfiguration())
|
|
149
152
|
assert.equal(model.termsOfService, 'https://example.com/terms')
|
|
150
153
|
assert.deepEqual(model.contact, { name: 'John Doe', email: 'john.doe@example.com' })
|
|
151
154
|
assert.deepEqual(model.license, { name: 'MIT', url: 'https://opensource.org/licenses/MIT' })
|
|
@@ -193,6 +196,30 @@ test.group('ApiModel.constructor()', () => {
|
|
|
193
196
|
await Promise.resolve() // Allow microtask to run
|
|
194
197
|
assert.isTrue(notified)
|
|
195
198
|
}).tags(['@modeling', '@api', '@creation'])
|
|
199
|
+
|
|
200
|
+
test('notifies change when nested action changes', async ({ assert }) => {
|
|
201
|
+
const model = new ApiModel({
|
|
202
|
+
exposes: [
|
|
203
|
+
{
|
|
204
|
+
kind: ExposedEntityKind,
|
|
205
|
+
key: 'e1',
|
|
206
|
+
entity: { key: 'e1' },
|
|
207
|
+
resourcePath: '/e1',
|
|
208
|
+
hasCollection: false,
|
|
209
|
+
actions: [{ kind: 'read' }],
|
|
210
|
+
},
|
|
211
|
+
],
|
|
212
|
+
})
|
|
213
|
+
|
|
214
|
+
let notified = false
|
|
215
|
+
model.addEventListener('change', () => {
|
|
216
|
+
notified = true
|
|
217
|
+
})
|
|
218
|
+
|
|
219
|
+
model.exposes[0].actions[0].kind = 'write'
|
|
220
|
+
await Promise.resolve()
|
|
221
|
+
assert.isTrue(notified)
|
|
222
|
+
}).tags(['@modeling', '@api', '@observed'])
|
|
196
223
|
})
|
|
197
224
|
|
|
198
225
|
test.group('ApiModel.toJSON()', () => {
|
|
@@ -260,6 +287,24 @@ test.group('ApiModel.toJSON()', () => {
|
|
|
260
287
|
assert.deepEqual(json.contact, { name: 'John Doe', email: 'john.doe@example.com' })
|
|
261
288
|
assert.deepEqual(json.license, { name: 'MIT', url: 'https://opensource.org/licenses/MIT' })
|
|
262
289
|
}).tags(['@modeling', '@api', '@serialization'])
|
|
290
|
+
|
|
291
|
+
test('actions are immutable', ({ assert }) => {
|
|
292
|
+
const model = new ApiModel()
|
|
293
|
+
const action = new Action({ kind: 'read' })
|
|
294
|
+
const entityKey = 'get-entity'
|
|
295
|
+
const exposed: ExposedEntitySchema = {
|
|
296
|
+
key: entityKey,
|
|
297
|
+
actions: [action.toJSON()],
|
|
298
|
+
hasCollection: true,
|
|
299
|
+
kind: ExposedEntityKind,
|
|
300
|
+
resourcePath: '/',
|
|
301
|
+
entity: { key: entityKey },
|
|
302
|
+
}
|
|
303
|
+
model.exposes.push(new ExposedEntity(model, exposed))
|
|
304
|
+
const json = model.toJSON()
|
|
305
|
+
json.exposes[0].actions[0].kind = 'write'
|
|
306
|
+
assert.equal(model.exposes[0].actions[0].kind, 'read')
|
|
307
|
+
}).tags(['@modeling', '@api', '@serialization'])
|
|
263
308
|
})
|
|
264
309
|
|
|
265
310
|
test.group('ApiModel.getExposedEntity()', () => {
|
|
@@ -152,4 +152,77 @@ test.group('ExposedEntity', () => {
|
|
|
152
152
|
await Promise.resolve()
|
|
153
153
|
assert.isAtLeast(notified, 1)
|
|
154
154
|
}).tags(['@modeling', '@exposed-entity', '@observed'])
|
|
155
|
+
|
|
156
|
+
test('restores actions and rules from schema', ({ assert }) => {
|
|
157
|
+
const model = new ApiModel()
|
|
158
|
+
const ex = new ExposedEntity(model, {
|
|
159
|
+
actions: [{ kind: 'read', accessRule: [{ type: 'public' }] }],
|
|
160
|
+
accessRule: [{ type: 'admin' }],
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
assert.lengthOf(ex.actions, 1)
|
|
164
|
+
assert.equal(ex.actions[0].kind, 'read')
|
|
165
|
+
assert.lengthOf(ex.actions[0].accessRule, 1)
|
|
166
|
+
assert.equal(ex.actions[0].accessRule[0].type, 'public')
|
|
167
|
+
|
|
168
|
+
assert.lengthOf(ex.accessRule!, 1)
|
|
169
|
+
assert.equal(ex.accessRule![0].type, 'admin')
|
|
170
|
+
}).tags(['@modeling', '@exposed-entity'])
|
|
171
|
+
|
|
172
|
+
test('serializes actions and rules', ({ assert }) => {
|
|
173
|
+
const model = new ApiModel()
|
|
174
|
+
const ex = new ExposedEntity(model, {
|
|
175
|
+
actions: [{ kind: 'read' }],
|
|
176
|
+
accessRule: [{ type: 'admin' }],
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
const json = ex.toJSON()
|
|
180
|
+
assert.deepInclude(json.actions[0], { kind: 'read' })
|
|
181
|
+
assert.deepInclude(json.accessRule![0], { type: 'admin' })
|
|
182
|
+
}).tags(['@modeling', '@exposed-entity'])
|
|
183
|
+
|
|
184
|
+
test('notifies change when action property changes', async ({ assert }) => {
|
|
185
|
+
const model = new ApiModel()
|
|
186
|
+
const ex = new ExposedEntity(model, {
|
|
187
|
+
actions: [{ kind: 'read' }],
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
let notified = false
|
|
191
|
+
ex.addEventListener('change', () => {
|
|
192
|
+
notified = true
|
|
193
|
+
})
|
|
194
|
+
|
|
195
|
+
ex.actions[0].kind = 'write'
|
|
196
|
+
await Promise.resolve()
|
|
197
|
+
assert.isTrue(notified)
|
|
198
|
+
}).tags(['@modeling', '@exposed-entity', '@observed'])
|
|
199
|
+
|
|
200
|
+
test('constructor copies actions array (immutability)', ({ assert }) => {
|
|
201
|
+
const model = new ApiModel()
|
|
202
|
+
const actions = [{ kind: 'read' }]
|
|
203
|
+
const ex = new ExposedEntity(model, { actions })
|
|
204
|
+
|
|
205
|
+
// Modify original array
|
|
206
|
+
actions.push({ kind: 'write' })
|
|
207
|
+
actions[0].kind = 'changed'
|
|
208
|
+
|
|
209
|
+
assert.lengthOf(ex.actions, 1)
|
|
210
|
+
assert.equal(ex.actions[0].kind, 'read')
|
|
211
|
+
}).tags(['@modeling', '@exposed-entity', '@immutability'])
|
|
212
|
+
|
|
213
|
+
test('constructor copies accessRule array (immutability)', ({ assert }) => {
|
|
214
|
+
const model = new ApiModel()
|
|
215
|
+
const rules = [{ type: 'public' }]
|
|
216
|
+
const ex = new ExposedEntity(model, {
|
|
217
|
+
actions: [],
|
|
218
|
+
accessRule: rules,
|
|
219
|
+
})
|
|
220
|
+
|
|
221
|
+
// Modify original array
|
|
222
|
+
rules.push({ type: 'admin' })
|
|
223
|
+
rules[0].type = 'changed'
|
|
224
|
+
|
|
225
|
+
assert.lengthOf(ex.accessRule!, 1)
|
|
226
|
+
assert.equal(ex.accessRule![0].type, 'public')
|
|
227
|
+
}).tags(['@modeling', '@exposed-entity', '@immutability'])
|
|
155
228
|
})
|
|
@@ -39,6 +39,7 @@ import {
|
|
|
39
39
|
addStreetAddressField,
|
|
40
40
|
addCityField,
|
|
41
41
|
addRegionField,
|
|
42
|
+
addStreetAddressSupplementalField,
|
|
42
43
|
} from '../../../../src/modeling/helpers/Intelisense.js'
|
|
43
44
|
import { SemanticType } from '../../../../src/modeling/Semantics.js'
|
|
44
45
|
import { createCountrySemantic } from '../../../../src/modeling/definitions/Country.js'
|
|
@@ -1237,3 +1238,48 @@ test.group('addRegionField()', () => {
|
|
|
1237
1238
|
assert.equal(field.info.description, 'Region XXX')
|
|
1238
1239
|
})
|
|
1239
1240
|
})
|
|
1241
|
+
|
|
1242
|
+
test.group('addStreetAddressSupplementalField()', () => {
|
|
1243
|
+
test('creates first supplemental field when none exists', ({ assert }) => {
|
|
1244
|
+
const entity = createTestEntity()
|
|
1245
|
+
const field = addStreetAddressSupplementalField(entity)
|
|
1246
|
+
assert.instanceOf(field, DomainProperty)
|
|
1247
|
+
assert.equal(field.info.name, 'street_address_1')
|
|
1248
|
+
assert.equal(field.info.displayName, 'Street Address 1')
|
|
1249
|
+
assert.equal(field.type, 'string')
|
|
1250
|
+
assert.isFalse(field.required)
|
|
1251
|
+
assert.isTrue(field.hasSemantic(SemanticType.StreetAddressSupplemental))
|
|
1252
|
+
})
|
|
1253
|
+
|
|
1254
|
+
test('increments supplemental field index', ({ assert }) => {
|
|
1255
|
+
const entity = createTestEntity()
|
|
1256
|
+
const field1 = addStreetAddressSupplementalField(entity)
|
|
1257
|
+
const field2 = addStreetAddressSupplementalField(entity)
|
|
1258
|
+
|
|
1259
|
+
assert.equal(field1.info.name, 'street_address_1')
|
|
1260
|
+
assert.equal(field2.info.name, 'street_address_2')
|
|
1261
|
+
assert.equal(field2.info.displayName, 'Street Address 2')
|
|
1262
|
+
})
|
|
1263
|
+
|
|
1264
|
+
test('handles gaps in numbering', ({ assert }) => {
|
|
1265
|
+
const entity = createTestEntity()
|
|
1266
|
+
// Manually add a field mimicking a higher number
|
|
1267
|
+
const manualField = entity.addProperty({
|
|
1268
|
+
info: { name: 'street_address_5', displayName: 'Street Address 5' },
|
|
1269
|
+
type: 'string',
|
|
1270
|
+
required: false,
|
|
1271
|
+
})
|
|
1272
|
+
manualField.addSemantic({ id: SemanticType.StreetAddressSupplemental })
|
|
1273
|
+
|
|
1274
|
+
const field = addStreetAddressSupplementalField(entity)
|
|
1275
|
+
assert.equal(field.info.name, 'street_address_6')
|
|
1276
|
+
assert.equal(field.info.displayName, 'Street Address 6')
|
|
1277
|
+
})
|
|
1278
|
+
|
|
1279
|
+
test('merges custom info', ({ assert }) => {
|
|
1280
|
+
const entity = createTestEntity()
|
|
1281
|
+
const field = addStreetAddressSupplementalField(entity, { description: 'Extra line' })
|
|
1282
|
+
assert.equal(field.info.name, 'street_address_1')
|
|
1283
|
+
assert.equal(field.info.description, 'Extra line')
|
|
1284
|
+
})
|
|
1285
|
+
})
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { test } from '@japa/runner'
|
|
2
|
+
import { AccessRule, type AccessRuleSchema } from '../../../../src/modeling/index.js'
|
|
3
|
+
|
|
4
|
+
test.group('AccessRule', () => {
|
|
5
|
+
test('initializes with default values', ({ assert }) => {
|
|
6
|
+
const rule = new AccessRule()
|
|
7
|
+
assert.equal(rule.type, '')
|
|
8
|
+
}).tags(['@modeling', '@access-rule'])
|
|
9
|
+
|
|
10
|
+
test('initializes with provided values', ({ assert }) => {
|
|
11
|
+
const schema: AccessRuleSchema = { type: 'public' }
|
|
12
|
+
const rule = new AccessRule(schema)
|
|
13
|
+
assert.equal(rule.type, 'public')
|
|
14
|
+
}).tags(['@modeling', '@access-rule'])
|
|
15
|
+
|
|
16
|
+
test('serializes to JSON', ({ assert }) => {
|
|
17
|
+
const rule = new AccessRule({ type: 'authenticated' })
|
|
18
|
+
const json = rule.toJSON()
|
|
19
|
+
assert.deepEqual(json, { type: 'authenticated' })
|
|
20
|
+
}).tags(['@modeling', '@access-rule'])
|
|
21
|
+
|
|
22
|
+
test('notifies change', async ({ assert }) => {
|
|
23
|
+
const rule = new AccessRule({ type: 'public' })
|
|
24
|
+
let notified = false
|
|
25
|
+
rule.addEventListener('change', () => {
|
|
26
|
+
notified = true
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
rule.notifyChange()
|
|
30
|
+
assert.isTrue(notified)
|
|
31
|
+
}).tags(['@modeling', '@access-rule'])
|
|
32
|
+
|
|
33
|
+
test('toJSON returns safe copy (immutability)', ({ assert }) => {
|
|
34
|
+
const rule = new AccessRule({ type: 'public' })
|
|
35
|
+
const json = rule.toJSON()
|
|
36
|
+
|
|
37
|
+
// Modify JSON (simulate runtime mutation)
|
|
38
|
+
json.type = 'changed'
|
|
39
|
+
|
|
40
|
+
assert.equal(rule.type, 'public')
|
|
41
|
+
}).tags(['@modeling', '@access-rule', '@immutability'])
|
|
42
|
+
})
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { test } from '@japa/runner'
|
|
2
|
+
import { AllowAuthenticatedAccessRule } from '../../../../src/modeling/rules/AllowAuthenticated.js'
|
|
3
|
+
|
|
4
|
+
test.group('AllowAuthenticatedAccessRule', () => {
|
|
5
|
+
test('initializes with correct type', ({ assert }) => {
|
|
6
|
+
const rule = new AllowAuthenticatedAccessRule()
|
|
7
|
+
assert.equal(rule.type, 'authenticated')
|
|
8
|
+
}).tags(['@modeling', '@rule', '@allow-authenticated'])
|
|
9
|
+
|
|
10
|
+
test('toJSON returns valid schema', ({ assert }) => {
|
|
11
|
+
const rule = new AllowAuthenticatedAccessRule()
|
|
12
|
+
const json = rule.toJSON()
|
|
13
|
+
|
|
14
|
+
assert.equal(json.type, 'authenticated')
|
|
15
|
+
}).tags(['@modeling', '@rule', '@allow-authenticated', '@serialization'])
|
|
16
|
+
|
|
17
|
+
test('notifies change', async ({ assert }) => {
|
|
18
|
+
const rule = new AllowAuthenticatedAccessRule()
|
|
19
|
+
let notified = false
|
|
20
|
+
rule.addEventListener('change', () => {
|
|
21
|
+
notified = true
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
rule.notifyChange()
|
|
25
|
+
await Promise.resolve()
|
|
26
|
+
assert.isTrue(notified)
|
|
27
|
+
}).tags(['@modeling', '@rule', '@allow-authenticated', '@observed'])
|
|
28
|
+
})
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { test } from '@japa/runner'
|
|
2
|
+
import { AllowPublicAccessRule } from '../../../../src/modeling/rules/AllowPublic.js'
|
|
3
|
+
|
|
4
|
+
test.group('AllowPublicAccessRule', () => {
|
|
5
|
+
test('initializes with correct type', ({ assert }) => {
|
|
6
|
+
const rule = new AllowPublicAccessRule()
|
|
7
|
+
assert.equal(rule.type, 'public')
|
|
8
|
+
}).tags(['@modeling', '@rule', '@allow-public'])
|
|
9
|
+
|
|
10
|
+
test('toJSON returns valid schema', ({ assert }) => {
|
|
11
|
+
const rule = new AllowPublicAccessRule()
|
|
12
|
+
const json = rule.toJSON()
|
|
13
|
+
|
|
14
|
+
assert.equal(json.type, 'public')
|
|
15
|
+
}).tags(['@modeling', '@rule', '@allow-public', '@serialization'])
|
|
16
|
+
|
|
17
|
+
test('notifies change', async ({ assert }) => {
|
|
18
|
+
const rule = new AllowPublicAccessRule()
|
|
19
|
+
let notified = false
|
|
20
|
+
rule.addEventListener('change', () => {
|
|
21
|
+
notified = true
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
rule.notifyChange()
|
|
25
|
+
await Promise.resolve()
|
|
26
|
+
assert.isTrue(notified)
|
|
27
|
+
}).tags(['@modeling', '@rule', '@allow-public', '@observed'])
|
|
28
|
+
})
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { test } from '@japa/runner'
|
|
2
|
+
import { MatchEmailDomainAccessRule } from '../../../../src/modeling/rules/MatchEmailDomain.js'
|
|
3
|
+
|
|
4
|
+
test.group('MatchEmailDomainAccessRule', () => {
|
|
5
|
+
test('initializes with default values', ({ assert }) => {
|
|
6
|
+
const rule = new MatchEmailDomainAccessRule()
|
|
7
|
+
assert.equal(rule.type, 'matchEmailDomain')
|
|
8
|
+
assert.deepEqual(rule.domains, [])
|
|
9
|
+
}).tags(['@modeling', '@rule', '@match-email-domain'])
|
|
10
|
+
|
|
11
|
+
test('initializes with provided values', ({ assert }) => {
|
|
12
|
+
const domains = ['example.com', 'test.org']
|
|
13
|
+
const rule = new MatchEmailDomainAccessRule({ domains })
|
|
14
|
+
|
|
15
|
+
assert.equal(rule.type, 'matchEmailDomain')
|
|
16
|
+
assert.deepEqual(rule.domains, domains)
|
|
17
|
+
}).tags(['@modeling', '@rule', '@match-email-domain'])
|
|
18
|
+
|
|
19
|
+
test('constructor copies arrays (immutability)', ({ assert }) => {
|
|
20
|
+
const domains = ['example.com']
|
|
21
|
+
const rule = new MatchEmailDomainAccessRule({ domains })
|
|
22
|
+
|
|
23
|
+
// Modify original source
|
|
24
|
+
domains.push('hacker.com')
|
|
25
|
+
|
|
26
|
+
assert.deepEqual(rule.domains, ['example.com'])
|
|
27
|
+
}).tags(['@modeling', '@rule', '@match-email-domain', '@immutability'])
|
|
28
|
+
|
|
29
|
+
test('toJSON returns valid schema', ({ assert }) => {
|
|
30
|
+
const rule = new MatchEmailDomainAccessRule({ domains: ['example.com'] })
|
|
31
|
+
const json = rule.toJSON()
|
|
32
|
+
|
|
33
|
+
// Modify JSON
|
|
34
|
+
json.domains.push('hacker.com')
|
|
35
|
+
|
|
36
|
+
assert.equal(json.type, 'matchEmailDomain')
|
|
37
|
+
assert.lengthOf(rule.domains, 1) // Ensure immutability
|
|
38
|
+
assert.equal(rule.domains[0], 'example.com')
|
|
39
|
+
}).tags(['@modeling', '@rule', '@match-email-domain', '@serialization', '@immutability'])
|
|
40
|
+
|
|
41
|
+
test('notifies change when domains changes', async ({ assert }) => {
|
|
42
|
+
const rule = new MatchEmailDomainAccessRule()
|
|
43
|
+
let notified = false
|
|
44
|
+
rule.addEventListener('change', () => {
|
|
45
|
+
notified = true
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
rule.domains = ['example.com']
|
|
49
|
+
await Promise.resolve()
|
|
50
|
+
assert.isTrue(notified)
|
|
51
|
+
}).tags(['@modeling', '@rule', '@match-email-domain', '@observed'])
|
|
52
|
+
})
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { test } from '@japa/runner'
|
|
2
|
+
import { MatchResourceOwnerAccessRule } from '../../../../src/modeling/rules/MatchResourceOwner.js'
|
|
3
|
+
|
|
4
|
+
test.group('MatchResourceOwnerAccessRule', () => {
|
|
5
|
+
test('initializes with default values', ({ assert }) => {
|
|
6
|
+
const rule = new MatchResourceOwnerAccessRule()
|
|
7
|
+
assert.equal(rule.type, 'resourceOwner')
|
|
8
|
+
assert.equal(rule.property, '')
|
|
9
|
+
}).tags(['@modeling', '@rule', '@match-resource-owner'])
|
|
10
|
+
|
|
11
|
+
test('initializes with provided values', ({ assert }) => {
|
|
12
|
+
const rule = new MatchResourceOwnerAccessRule({ property: 'creatorId' })
|
|
13
|
+
|
|
14
|
+
assert.equal(rule.type, 'resourceOwner')
|
|
15
|
+
assert.equal(rule.property, 'creatorId')
|
|
16
|
+
}).tags(['@modeling', '@rule', '@match-resource-owner'])
|
|
17
|
+
|
|
18
|
+
test('toJSON returns valid schema', ({ assert }) => {
|
|
19
|
+
const rule = new MatchResourceOwnerAccessRule({ property: 'creatorId' })
|
|
20
|
+
const json = rule.toJSON()
|
|
21
|
+
|
|
22
|
+
assert.equal(json.type, 'resourceOwner')
|
|
23
|
+
assert.equal(json.property, 'creatorId')
|
|
24
|
+
}).tags(['@modeling', '@rule', '@match-resource-owner', '@serialization'])
|
|
25
|
+
|
|
26
|
+
test('notifies change when property changes', async ({ assert }) => {
|
|
27
|
+
const rule = new MatchResourceOwnerAccessRule()
|
|
28
|
+
let notified = false
|
|
29
|
+
rule.addEventListener('change', () => {
|
|
30
|
+
notified = true
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
rule.property = 'ownerId'
|
|
34
|
+
await Promise.resolve()
|
|
35
|
+
assert.isTrue(notified)
|
|
36
|
+
}).tags(['@modeling', '@rule', '@match-resource-owner', '@observed'])
|
|
37
|
+
})
|