|
4 | 4 | * For full license text, see the license.txt file in the repo root or http://www.apache.org/licenses/LICENSE-2.0 |
5 | 5 | */ |
6 | 6 |
|
| 7 | +import fs from 'node:fs'; |
| 8 | +import os from 'node:os'; |
| 9 | +import path from 'node:path'; |
7 | 10 | import {expect} from 'chai'; |
8 | 11 | import {ux} from '@oclif/core'; |
9 | 12 | import {afterEach, beforeEach} from 'mocha'; |
@@ -131,4 +134,92 @@ describe('content validate', () => { |
131 | 134 |
|
132 | 135 | expect(result.totalFiles).to.equal(2); |
133 | 136 | }); |
| 137 | + |
| 138 | + describe('with real validator (no SDK stub)', () => { |
| 139 | + let tmpDir: string; |
| 140 | + |
| 141 | + beforeEach(() => { |
| 142 | + tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'content-validate-')); |
| 143 | + }); |
| 144 | + |
| 145 | + afterEach(() => { |
| 146 | + fs.rmSync(tmpDir, {force: true, recursive: true}); |
| 147 | + }); |
| 148 | + |
| 149 | + it('reports valid pagetype file as valid', async () => { |
| 150 | + const filePath = path.join(tmpDir, 'home.json'); |
| 151 | + // Minimal valid pagetype: only region_definitions is required by the schema |
| 152 | + fs.writeFileSync(filePath, JSON.stringify({region_definitions: []})); |
| 153 | + |
| 154 | + const command: any = await createCommand({type: 'pagetype'}, [filePath]); |
| 155 | + // Use real glob - the file actually exists on disk |
| 156 | + sinon.stub(command, 'jsonEnabled').returns(true); |
| 157 | + |
| 158 | + const result = await command.run(); |
| 159 | + |
| 160 | + expect(result.totalFiles).to.equal(1); |
| 161 | + expect(result.validFiles).to.equal(1); |
| 162 | + expect(result.totalErrors).to.equal(0); |
| 163 | + expect(result.results[0].valid).to.equal(true); |
| 164 | + expect(result.results[0].schemaType).to.equal('pagetype'); |
| 165 | + }); |
| 166 | + |
| 167 | + it('reports invalid pagetype file (missing required region_definitions) with errors', async () => { |
| 168 | + const filePath = path.join(tmpDir, 'broken.json'); |
| 169 | + // Pagetype requires region_definitions - omitting it triggers a real validator error |
| 170 | + fs.writeFileSync(filePath, JSON.stringify({name: {default: 'Bad'}})); |
| 171 | + |
| 172 | + const command: any = await createCommand({type: 'pagetype'}, [filePath]); |
| 173 | + // Non-JSON mode is required to exercise the post-render `this.error('Validation failed')` branch |
| 174 | + sinon.stub(command, 'jsonEnabled').returns(false); |
| 175 | + const stdoutStub = sinon.stub(ux, 'stdout'); |
| 176 | + const errorStub = sinon.stub(command, 'error').throws(new Error('Validation failed')); |
| 177 | + |
| 178 | + let caught: unknown; |
| 179 | + try { |
| 180 | + await command.run(); |
| 181 | + } catch (error) { |
| 182 | + caught = error; |
| 183 | + } |
| 184 | + |
| 185 | + // The validator must have produced at least one error -> command.error called |
| 186 | + expect(errorStub.called, 'command.error should be called for invalid file').to.equal(true); |
| 187 | + expect(caught).to.exist; |
| 188 | + |
| 189 | + const stdoutOutput = stdoutStub |
| 190 | + .getCalls() |
| 191 | + .map((c) => String(c.args[0] ?? '')) |
| 192 | + .join('\n'); |
| 193 | + expect(stdoutOutput).to.include('FAIL'); |
| 194 | + // The real validator surfaces the missing required property |
| 195 | + expect(stdoutOutput).to.include('region_definitions'); |
| 196 | + }); |
| 197 | + |
| 198 | + it('reports invalid JSON content with a JSON parse error', async () => { |
| 199 | + const filePath = path.join(tmpDir, 'bad-json.json'); |
| 200 | + fs.writeFileSync(filePath, '{not valid json'); |
| 201 | + |
| 202 | + const command: any = await createCommand({type: 'pagetype'}, [filePath]); |
| 203 | + sinon.stub(command, 'jsonEnabled').returns(false); |
| 204 | + const stdoutStub = sinon.stub(ux, 'stdout'); |
| 205 | + const errorStub = sinon.stub(command, 'error').throws(new Error('Validation failed')); |
| 206 | + |
| 207 | + let caught: unknown; |
| 208 | + try { |
| 209 | + await command.run(); |
| 210 | + } catch (error) { |
| 211 | + caught = error; |
| 212 | + } |
| 213 | + |
| 214 | + expect(errorStub.called).to.equal(true); |
| 215 | + expect(caught).to.exist; |
| 216 | + |
| 217 | + const stdoutOutput = stdoutStub |
| 218 | + .getCalls() |
| 219 | + .map((c) => String(c.args[0] ?? '')) |
| 220 | + .join('\n'); |
| 221 | + expect(stdoutOutput).to.include('FAIL'); |
| 222 | + expect(stdoutOutput.toLowerCase()).to.include('invalid json'); |
| 223 | + }); |
| 224 | + }); |
134 | 225 | }); |
0 commit comments