|
9 | 9 | * OF ANY KIND, either express or implied. See the License for the specific language |
10 | 10 | * governing permissions and limitations under the License. |
11 | 11 | */ |
12 | | -import { expect } from "chai"; |
13 | | -import BaseValidator from "../base.js"; |
14 | | - |
15 | | -describe("BaseValidator", () => { |
16 | | - describe("fieldNames property", () => { |
17 | | - let validator; |
18 | | - const testPath = [{ type: "TestType" }]; |
19 | | - |
20 | | - beforeEach(() => { |
21 | | - validator = new BaseValidator({ |
22 | | - dataFormat: "jsonld", |
23 | | - path: testPath, |
24 | | - }); |
25 | | - }); |
26 | | - |
27 | | - describe("required()", () => { |
28 | | - it("should include fieldNames when required attribute is missing", () => { |
29 | | - const condition = validator.required("price"); |
30 | | - const result = condition({}); |
31 | | - |
32 | | - expect(result).to.deep.include({ |
33 | | - severity: "ERROR", |
34 | | - issueMessage: 'Required attribute "price" is missing', |
35 | | - }); |
36 | | - expect(result.fieldNames).to.deep.equal(["price"]); |
37 | | - expect(result.path).to.deep.equal(testPath); |
38 | | - }); |
39 | | - |
40 | | - it("should include fieldNames when required attribute has invalid type", () => { |
41 | | - const condition = validator.required("price", "number"); |
42 | | - const result = condition({ price: "not-a-number" }); |
43 | | - |
44 | | - expect(result).to.deep.include({ |
45 | | - severity: "ERROR", |
46 | | - issueMessage: 'Invalid type for attribute "price"', |
47 | | - }); |
48 | | - expect(result.fieldNames).to.deep.equal(["price"]); |
49 | | - }); |
50 | | - |
51 | | - it("should return null when required attribute is valid", () => { |
52 | | - const condition = validator.required("name"); |
53 | | - const result = condition({ name: "Test Product" }); |
54 | | - |
55 | | - expect(result).to.be.null; |
56 | | - }); |
57 | | - }); |
58 | | - |
59 | | - describe("recommended()", () => { |
60 | | - it("should include fieldNames when recommended attribute is missing", () => { |
61 | | - const condition = validator.recommended("description"); |
62 | | - const result = condition({}); |
63 | | - |
64 | | - expect(result).to.deep.include({ |
65 | | - severity: "WARNING", |
66 | | - issueMessage: 'Missing field "description" (optional)', |
67 | | - }); |
68 | | - expect(result.fieldNames).to.deep.equal(["description"]); |
69 | | - expect(result.path).to.deep.equal(testPath); |
70 | | - }); |
71 | | - |
72 | | - it("should include fieldNames when recommended attribute has invalid type", () => { |
73 | | - const condition = validator.recommended("image", "url"); |
74 | | - const result = condition({ image: "data:invalid" }); |
75 | | - |
76 | | - expect(result).to.deep.include({ |
77 | | - severity: "WARNING", |
78 | | - issueMessage: 'Invalid type for attribute "image"', |
79 | | - }); |
80 | | - expect(result.fieldNames).to.deep.equal(["image"]); |
81 | | - }); |
82 | | - |
83 | | - it("should return null when recommended attribute is valid", () => { |
84 | | - const condition = validator.recommended("description"); |
85 | | - const result = condition({ description: "A great product" }); |
86 | | - |
87 | | - expect(result).to.be.null; |
88 | | - }); |
89 | | - }); |
90 | | - |
91 | | - describe("or()", () => { |
92 | | - it("should include fieldNames when or conditions fail", () => { |
93 | | - const condition = validator.or( |
94 | | - validator.required("price"), |
95 | | - validator.required("priceSpecification.price") |
96 | | - ); |
97 | | - const result = condition({}); |
98 | | - |
99 | | - expect(result.severity).to.equal("ERROR"); |
100 | | - expect(result.fieldNames).to.deep.equal([ |
101 | | - "price", |
102 | | - "priceSpecification.price", |
103 | | - ]); |
104 | | - expect(result.path).to.deep.equal(testPath); |
105 | | - }); |
106 | | - |
107 | | - it("should return null when at least one or condition passes", () => { |
108 | | - const condition = validator.or( |
109 | | - validator.required("price"), |
110 | | - validator.required("priceSpecification.price") |
111 | | - ); |
112 | | - const result = condition({ price: "19.99" }); |
113 | | - |
114 | | - expect(result).to.be.null; |
115 | | - }); |
116 | | - |
117 | | - it("should handle single failing condition in or()", () => { |
118 | | - const condition = validator.or( |
119 | | - validator.required("availability") |
120 | | - ); |
121 | | - const result = condition({}); |
122 | | - |
123 | | - expect(result.fieldNames).to.deep.equal(["availability"]); |
124 | | - }); |
125 | | - }); |
126 | | - |
127 | | - describe("nested path fieldNames", () => { |
128 | | - it("should include fieldNames for nested attributes", () => { |
129 | | - const condition = validator.required("offers.price"); |
130 | | - const result = condition({ offers: {} }); |
131 | | - |
132 | | - expect(result).to.deep.include({ |
133 | | - severity: "ERROR", |
134 | | - }); |
135 | | - expect(result.fieldNames).to.deep.equal(["offers.price"]); |
136 | | - }); |
137 | | - }); |
138 | | - }); |
| 12 | +import { expect } from 'chai'; |
| 13 | +import BaseValidator from '../base.js'; |
| 14 | + |
| 15 | +describe('BaseValidator', () => { |
| 16 | + describe('fieldNames property', () => { |
| 17 | + let validator; |
| 18 | + const testPath = [{ type: 'TestType' }]; |
| 19 | + |
| 20 | + beforeEach(() => { |
| 21 | + validator = new BaseValidator({ |
| 22 | + dataFormat: 'jsonld', |
| 23 | + path: testPath, |
| 24 | + }); |
| 25 | + }); |
| 26 | + |
| 27 | + describe('required()', () => { |
| 28 | + it('should include fieldNames when required attribute is missing', () => { |
| 29 | + const condition = validator.required('price'); |
| 30 | + const result = condition({}); |
| 31 | + |
| 32 | + expect(result).to.deep.include({ |
| 33 | + severity: 'ERROR', |
| 34 | + issueMessage: 'Required attribute "price" is missing', |
| 35 | + }); |
| 36 | + expect(result.fieldNames).to.deep.equal(['price']); |
| 37 | + expect(result.path).to.deep.equal(testPath); |
| 38 | + }); |
| 39 | + |
| 40 | + it('should include fieldNames when required attribute has invalid type', () => { |
| 41 | + const condition = validator.required('price', 'number'); |
| 42 | + const result = condition({ price: 'not-a-number' }); |
| 43 | + |
| 44 | + expect(result).to.deep.include({ |
| 45 | + severity: 'ERROR', |
| 46 | + issueMessage: 'Invalid type for attribute "price"', |
| 47 | + }); |
| 48 | + expect(result.fieldNames).to.deep.equal(['price']); |
| 49 | + }); |
| 50 | + |
| 51 | + it('should return null when required attribute is valid', () => { |
| 52 | + const condition = validator.required('name'); |
| 53 | + const result = condition({ name: 'Test Product' }); |
| 54 | + |
| 55 | + expect(result).to.be.null; |
| 56 | + }); |
| 57 | + }); |
| 58 | + |
| 59 | + describe('recommended()', () => { |
| 60 | + it('should include fieldNames when recommended attribute is missing', () => { |
| 61 | + const condition = validator.recommended('description'); |
| 62 | + const result = condition({}); |
| 63 | + |
| 64 | + expect(result).to.deep.include({ |
| 65 | + severity: 'WARNING', |
| 66 | + issueMessage: 'Missing field "description" (optional)', |
| 67 | + }); |
| 68 | + expect(result.fieldNames).to.deep.equal(['description']); |
| 69 | + expect(result.path).to.deep.equal(testPath); |
| 70 | + }); |
| 71 | + |
| 72 | + it('should include fieldNames when recommended attribute has invalid type', () => { |
| 73 | + const condition = validator.recommended('image', 'url'); |
| 74 | + const result = condition({ image: 'data:invalid' }); |
| 75 | + |
| 76 | + expect(result).to.deep.include({ |
| 77 | + severity: 'WARNING', |
| 78 | + issueMessage: 'Invalid type for attribute "image"', |
| 79 | + }); |
| 80 | + expect(result.fieldNames).to.deep.equal(['image']); |
| 81 | + }); |
| 82 | + |
| 83 | + it('should return null when recommended attribute is valid', () => { |
| 84 | + const condition = validator.recommended('description'); |
| 85 | + const result = condition({ description: 'A great product' }); |
| 86 | + |
| 87 | + expect(result).to.be.null; |
| 88 | + }); |
| 89 | + }); |
| 90 | + |
| 91 | + describe('or()', () => { |
| 92 | + it('should include fieldNames when or conditions fail', () => { |
| 93 | + const condition = validator.or( |
| 94 | + validator.required('price'), |
| 95 | + validator.required('priceSpecification.price'), |
| 96 | + ); |
| 97 | + const result = condition({}); |
| 98 | + |
| 99 | + expect(result.severity).to.equal('ERROR'); |
| 100 | + expect(result.fieldNames).to.deep.equal([ |
| 101 | + 'price', |
| 102 | + 'priceSpecification.price', |
| 103 | + ]); |
| 104 | + expect(result.path).to.deep.equal(testPath); |
| 105 | + }); |
| 106 | + |
| 107 | + it('should return null when at least one or condition passes', () => { |
| 108 | + const condition = validator.or( |
| 109 | + validator.required('price'), |
| 110 | + validator.required('priceSpecification.price'), |
| 111 | + ); |
| 112 | + const result = condition({ price: '19.99' }); |
| 113 | + |
| 114 | + expect(result).to.be.null; |
| 115 | + }); |
| 116 | + |
| 117 | + it('should handle single failing condition in or()', () => { |
| 118 | + const condition = validator.or(validator.required('availability')); |
| 119 | + const result = condition({}); |
| 120 | + |
| 121 | + expect(result.fieldNames).to.deep.equal(['availability']); |
| 122 | + }); |
| 123 | + }); |
| 124 | + |
| 125 | + describe('nested path fieldNames', () => { |
| 126 | + it('should include fieldNames for nested attributes', () => { |
| 127 | + const condition = validator.required('offers.price'); |
| 128 | + const result = condition({ offers: {} }); |
| 129 | + |
| 130 | + expect(result).to.deep.include({ |
| 131 | + severity: 'ERROR', |
| 132 | + }); |
| 133 | + expect(result.fieldNames).to.deep.equal(['offers.price']); |
| 134 | + }); |
| 135 | + }); |
| 136 | + }); |
139 | 137 | }); |
0 commit comments