fix: Profil-State nach Backend-Load in SDK-Context sync + alle Tests fixen
Some checks failed
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-ai-compliance (push) Failing after 36s
CI / test-python-backend-compliance (push) Successful in 34s
CI / test-python-document-crawler (push) Successful in 26s
CI / test-python-dsms-gateway (push) Successful in 20s
Some checks failed
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-ai-compliance (push) Failing after 36s
CI / test-python-backend-compliance (push) Successful in 34s
CI / test-python-document-crawler (push) Successful in 26s
CI / test-python-dsms-gateway (push) Successful in 20s
- Company Profile: setCompanyProfile() und COMPLETE_STEP dispatch nach Backend-Load, damit Sidebar-Checkmarks nach Refresh erhalten bleiben - compliance-scope-engine.test.ts: Property-Namen anpassen (composite_score, risk_score, etc.) - dsfa/types.test.ts: 9 Sections (0-8), 7 required, 2 optional - api-client.test.ts: SDKApiClient-Klasse statt nicht-existierendem Singleton - types.test.ts: use-case-assessment statt use-case-workshop - vitest.config.ts: E2E-Verzeichnis aus Vitest excluden Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2438,8 +2438,10 @@ export default function CompanyProfilePage() {
|
|||||||
documentSources: data.document_sources || [],
|
documentSources: data.document_sources || [],
|
||||||
} as any
|
} as any
|
||||||
setFormData(backendProfile)
|
setFormData(backendProfile)
|
||||||
|
setCompanyProfile(backendProfile as CompanyProfile)
|
||||||
if (backendProfile.isComplete) {
|
if (backendProfile.isComplete) {
|
||||||
setCurrentStep(99)
|
setCurrentStep(99)
|
||||||
|
dispatch({ type: 'COMPLETE_STEP', payload: 'company-profile' })
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,12 @@ const mockFetch = vi.fn()
|
|||||||
global.fetch = mockFetch
|
global.fetch = mockFetch
|
||||||
|
|
||||||
// Import after mocking
|
// Import after mocking
|
||||||
import { sdkApiClient } from '../api-client'
|
import { SDKApiClient } from '../api-client'
|
||||||
|
|
||||||
|
const client = new SDKApiClient({
|
||||||
|
baseUrl: '/api/sdk/v1',
|
||||||
|
tenantId: 'test-tenant',
|
||||||
|
})
|
||||||
|
|
||||||
describe('SDK API Client', () => {
|
describe('SDK API Client', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@@ -19,39 +24,35 @@ describe('SDK API Client', () => {
|
|||||||
it('fetches modules from backend', async () => {
|
it('fetches modules from backend', async () => {
|
||||||
mockFetch.mockResolvedValueOnce({
|
mockFetch.mockResolvedValueOnce({
|
||||||
ok: true,
|
ok: true,
|
||||||
json: () => Promise.resolve([{ id: 'mod-1', name: 'DSGVO' }]),
|
json: () => Promise.resolve({ modules: [{ id: 'mod-1', name: 'DSGVO' }], total: 1 }),
|
||||||
})
|
})
|
||||||
|
|
||||||
const result = await sdkApiClient.getModules()
|
const result = await client.getModules()
|
||||||
expect(result).toHaveLength(1)
|
expect(result.modules).toHaveLength(1)
|
||||||
expect(result[0].name).toBe('DSGVO')
|
expect(result.total).toBe(1)
|
||||||
expect(mockFetch).toHaveBeenCalledWith(
|
expect(mockFetch).toHaveBeenCalledWith(
|
||||||
expect.stringContaining('/api/sdk/v1/modules'),
|
expect.stringContaining('/api/sdk/v1/modules'),
|
||||||
expect.any(Object)
|
expect.any(Object)
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('returns empty array on error', async () => {
|
it('throws on network error', async () => {
|
||||||
mockFetch.mockRejectedValueOnce(new Error('Network error'))
|
mockFetch.mockRejectedValueOnce(new Error('Network error'))
|
||||||
const result = await sdkApiClient.getModules()
|
await expect(client.getModules()).rejects.toThrow()
|
||||||
expect(result).toEqual([])
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('analyzeDocument', () => {
|
describe('analyzeDocument', () => {
|
||||||
it('sends FormData to import analyze endpoint', async () => {
|
it('sends FormData to import analyze endpoint', async () => {
|
||||||
const mockResponse = {
|
|
||||||
document_id: 'doc-1',
|
|
||||||
detected_type: 'DSFA',
|
|
||||||
confidence: 0.85,
|
|
||||||
}
|
|
||||||
mockFetch.mockResolvedValueOnce({
|
mockFetch.mockResolvedValueOnce({
|
||||||
ok: true,
|
ok: true,
|
||||||
json: () => Promise.resolve(mockResponse),
|
json: () => Promise.resolve({
|
||||||
|
data: { document_id: 'doc-1', detected_type: 'DSFA', confidence: 0.85 },
|
||||||
|
}),
|
||||||
})
|
})
|
||||||
|
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
const result = await sdkApiClient.analyzeDocument(formData)
|
const result = await client.analyzeDocument(formData) as any
|
||||||
expect(result.document_id).toBe('doc-1')
|
expect(result.document_id).toBe('doc-1')
|
||||||
expect(mockFetch).toHaveBeenCalledWith(
|
expect(mockFetch).toHaveBeenCalledWith(
|
||||||
expect.stringContaining('/api/sdk/v1/import/analyze'),
|
expect.stringContaining('/api/sdk/v1/import/analyze'),
|
||||||
@@ -62,19 +63,15 @@ describe('SDK API Client', () => {
|
|||||||
|
|
||||||
describe('scanDependencies', () => {
|
describe('scanDependencies', () => {
|
||||||
it('sends FormData to screening scan endpoint', async () => {
|
it('sends FormData to screening scan endpoint', async () => {
|
||||||
const mockResponse = {
|
|
||||||
id: 'scan-1',
|
|
||||||
status: 'completed',
|
|
||||||
total_components: 10,
|
|
||||||
total_issues: 2,
|
|
||||||
}
|
|
||||||
mockFetch.mockResolvedValueOnce({
|
mockFetch.mockResolvedValueOnce({
|
||||||
ok: true,
|
ok: true,
|
||||||
json: () => Promise.resolve(mockResponse),
|
json: () => Promise.resolve({
|
||||||
|
data: { id: 'scan-1', status: 'completed', total_components: 10, total_issues: 2 },
|
||||||
|
}),
|
||||||
})
|
})
|
||||||
|
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
const result = await sdkApiClient.scanDependencies(formData)
|
const result = await client.scanDependencies(formData) as any
|
||||||
expect(result.id).toBe('scan-1')
|
expect(result.id).toBe('scan-1')
|
||||||
expect(result.total_components).toBe(10)
|
expect(result.total_components).toBe(10)
|
||||||
})
|
})
|
||||||
@@ -82,16 +79,15 @@ describe('SDK API Client', () => {
|
|||||||
|
|
||||||
describe('assessUseCase', () => {
|
describe('assessUseCase', () => {
|
||||||
it('sends intake data to UCCA assess endpoint', async () => {
|
it('sends intake data to UCCA assess endpoint', async () => {
|
||||||
const mockResult = { id: 'assessment-1', feasibility: 'GREEN' }
|
|
||||||
mockFetch.mockResolvedValueOnce({
|
mockFetch.mockResolvedValueOnce({
|
||||||
ok: true,
|
ok: true,
|
||||||
json: () => Promise.resolve(mockResult),
|
json: () => Promise.resolve({ id: 'assessment-1', feasibility: 'GREEN' }),
|
||||||
})
|
})
|
||||||
|
|
||||||
const result = await sdkApiClient.assessUseCase({
|
const result = await client.assessUseCase({
|
||||||
name: 'Test Use Case',
|
name: 'Test Use Case',
|
||||||
domain: 'education',
|
domain: 'education',
|
||||||
})
|
}) as any
|
||||||
expect(result.feasibility).toBe('GREEN')
|
expect(result.feasibility).toBe('GREEN')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -100,10 +96,10 @@ describe('SDK API Client', () => {
|
|||||||
it('fetches assessment list', async () => {
|
it('fetches assessment list', async () => {
|
||||||
mockFetch.mockResolvedValueOnce({
|
mockFetch.mockResolvedValueOnce({
|
||||||
ok: true,
|
ok: true,
|
||||||
json: () => Promise.resolve([{ id: 'a1' }, { id: 'a2' }]),
|
json: () => Promise.resolve({ data: [{ id: 'a1' }, { id: 'a2' }] }),
|
||||||
})
|
})
|
||||||
|
|
||||||
const result = await sdkApiClient.getAssessments()
|
const result = await client.getAssessments()
|
||||||
expect(result).toHaveLength(2)
|
expect(result).toHaveLength(2)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { describe, it, expect } from 'vitest'
|
import { describe, it, expect } from 'vitest'
|
||||||
import { complianceScopeEngine } from '../compliance-scope-engine'
|
import { complianceScopeEngine } from '../compliance-scope-engine'
|
||||||
|
|
||||||
// Helper: create an answer object (engine reads answerValue + questionId)
|
// Helper: create an answer object (engine reads value + questionId)
|
||||||
function ans(questionId: string, answerValue: unknown) {
|
function ans(questionId: string, value: unknown) {
|
||||||
return { questionId, answerValue } as any
|
return { questionId, value } as any
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper: create a minimal triggered-trigger (engine shape, not types shape)
|
// Helper: create a minimal triggered-trigger (engine shape, not types shape)
|
||||||
@@ -18,10 +18,10 @@ function trigger(ruleId: string, minimumLevel: string, opts: Record<string, unkn
|
|||||||
describe('calculateScores', () => {
|
describe('calculateScores', () => {
|
||||||
it('returns zero composite for empty answers', () => {
|
it('returns zero composite for empty answers', () => {
|
||||||
const scores = complianceScopeEngine.calculateScores([])
|
const scores = complianceScopeEngine.calculateScores([])
|
||||||
expect(scores.composite).toBe(0)
|
expect(scores.composite_score).toBe(0)
|
||||||
expect(scores.risk).toBe(0)
|
expect(scores.risk_score).toBe(0)
|
||||||
expect(scores.complexity).toBe(0)
|
expect(scores.complexity_score).toBe(0)
|
||||||
expect(scores.assurance).toBe(0)
|
expect(scores.assurance_need).toBe(0)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('all-false boolean answers → zero composite', () => {
|
it('all-false boolean answers → zero composite', () => {
|
||||||
@@ -30,25 +30,25 @@ describe('calculateScores', () => {
|
|||||||
ans('data_minors', false),
|
ans('data_minors', false),
|
||||||
ans('proc_ai_usage', false),
|
ans('proc_ai_usage', false),
|
||||||
])
|
])
|
||||||
expect(scores.composite).toBe(0)
|
expect(scores.composite_score).toBe(0)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('boolean true answer increases risk score', () => {
|
it('boolean true answer increases risk score', () => {
|
||||||
const scoresFalse = complianceScopeEngine.calculateScores([ans('data_art9', false)])
|
const scoresFalse = complianceScopeEngine.calculateScores([ans('data_art9', false)])
|
||||||
const scoresTrue = complianceScopeEngine.calculateScores([ans('data_art9', true)])
|
const scoresTrue = complianceScopeEngine.calculateScores([ans('data_art9', true)])
|
||||||
expect(scoresTrue.risk).toBeGreaterThan(scoresFalse.risk)
|
expect(scoresTrue.risk_score).toBeGreaterThan(scoresFalse.risk_score)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('composite is weighted sum: risk×0.4 + complexity×0.3 + assurance×0.3', () => {
|
it('composite is weighted sum: risk×0.4 + complexity×0.3 + assurance×0.3', () => {
|
||||||
const scores = complianceScopeEngine.calculateScores([ans('data_art9', true)])
|
const scores = complianceScopeEngine.calculateScores([ans('data_art9', true)])
|
||||||
const expected = Math.round((scores.risk * 0.4 + scores.complexity * 0.3 + scores.assurance * 0.3) * 10) / 10
|
const expected = Math.round((scores.risk_score * 0.4 + scores.complexity_score * 0.3 + scores.assurance_need * 0.3) * 10) / 10
|
||||||
expect(scores.composite).toBe(expected)
|
expect(scores.composite_score).toBe(expected)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('numeric answer uses logarithmic normalization — higher value → higher score', () => {
|
it('numeric answer uses logarithmic normalization — higher value → higher score', () => {
|
||||||
const scoresLow = complianceScopeEngine.calculateScores([ans('data_volume', 10)])
|
const scoresLow = complianceScopeEngine.calculateScores([ans('data_volume', 10)])
|
||||||
const scoresHigh = complianceScopeEngine.calculateScores([ans('data_volume', 999)])
|
const scoresHigh = complianceScopeEngine.calculateScores([ans('data_volume', 999)])
|
||||||
expect(scoresHigh.composite).toBeGreaterThan(scoresLow.composite)
|
expect(scoresHigh.composite_score).toBeGreaterThan(scoresLow.composite_score)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('array answer score proportional to count (max 1.0 at 5+)', () => {
|
it('array answer score proportional to count (max 1.0 at 5+)', () => {
|
||||||
@@ -56,13 +56,13 @@ describe('calculateScores', () => {
|
|||||||
const scores5 = complianceScopeEngine.calculateScores([
|
const scores5 = complianceScopeEngine.calculateScores([
|
||||||
ans('data_art9', ['gesundheit', 'biometrie', 'genetik', 'politisch', 'religion']),
|
ans('data_art9', ['gesundheit', 'biometrie', 'genetik', 'politisch', 'religion']),
|
||||||
])
|
])
|
||||||
expect(scores5.composite).toBeGreaterThan(scores1.composite)
|
expect(scores5.composite_score).toBeGreaterThan(scores1.composite_score)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('empty array answer → zero contribution', () => {
|
it('empty array answer → zero contribution', () => {
|
||||||
const scoresEmpty = complianceScopeEngine.calculateScores([ans('data_art9', [])])
|
const scoresEmpty = complianceScopeEngine.calculateScores([ans('data_art9', [])])
|
||||||
const scoresNone = complianceScopeEngine.calculateScores([])
|
const scoresNone = complianceScopeEngine.calculateScores([])
|
||||||
expect(scoresEmpty.composite).toBe(scoresNone.composite)
|
expect(scoresEmpty.composite_score).toBe(scoresNone.composite_score)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -72,56 +72,56 @@ describe('calculateScores', () => {
|
|||||||
|
|
||||||
describe('determineLevel', () => {
|
describe('determineLevel', () => {
|
||||||
it('composite ≤25 → L1', () => {
|
it('composite ≤25 → L1', () => {
|
||||||
const level = complianceScopeEngine.determineLevel({ composite: 20 } as any, [])
|
const level = complianceScopeEngine.determineLevel({ composite_score: 20 } as any, [])
|
||||||
expect(level).toBe('L1')
|
expect(level).toBe('L1')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('composite exactly 25 → L1', () => {
|
it('composite exactly 25 → L1', () => {
|
||||||
const level = complianceScopeEngine.determineLevel({ composite: 25 } as any, [])
|
const level = complianceScopeEngine.determineLevel({ composite_score: 25 } as any, [])
|
||||||
expect(level).toBe('L1')
|
expect(level).toBe('L1')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('composite 26–50 → L2', () => {
|
it('composite 26–50 → L2', () => {
|
||||||
const level = complianceScopeEngine.determineLevel({ composite: 40 } as any, [])
|
const level = complianceScopeEngine.determineLevel({ composite_score: 40 } as any, [])
|
||||||
expect(level).toBe('L2')
|
expect(level).toBe('L2')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('composite exactly 50 → L2', () => {
|
it('composite exactly 50 → L2', () => {
|
||||||
const level = complianceScopeEngine.determineLevel({ composite: 50 } as any, [])
|
const level = complianceScopeEngine.determineLevel({ composite_score: 50 } as any, [])
|
||||||
expect(level).toBe('L2')
|
expect(level).toBe('L2')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('composite 51–75 → L3', () => {
|
it('composite 51–75 → L3', () => {
|
||||||
const level = complianceScopeEngine.determineLevel({ composite: 60 } as any, [])
|
const level = complianceScopeEngine.determineLevel({ composite_score: 60 } as any, [])
|
||||||
expect(level).toBe('L3')
|
expect(level).toBe('L3')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('composite >75 → L4', () => {
|
it('composite >75 → L4', () => {
|
||||||
const level = complianceScopeEngine.determineLevel({ composite: 80 } as any, [])
|
const level = complianceScopeEngine.determineLevel({ composite_score: 80 } as any, [])
|
||||||
expect(level).toBe('L4')
|
expect(level).toBe('L4')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('hard trigger with minimumLevel L3 overrides score-based L1', () => {
|
it('hard trigger with minimumLevel L3 overrides score-based L1', () => {
|
||||||
const t = trigger('HT-A01', 'L3')
|
const t = trigger('HT-A01', 'L3')
|
||||||
const level = complianceScopeEngine.determineLevel({ composite: 10 } as any, [t])
|
const level = complianceScopeEngine.determineLevel({ composite_score: 10 } as any, [t])
|
||||||
expect(level).toBe('L3')
|
expect(level).toBe('L3')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('hard trigger with minimumLevel L4 overrides score-based L2', () => {
|
it('hard trigger with minimumLevel L4 overrides score-based L2', () => {
|
||||||
const t = trigger('HT-F01', 'L4')
|
const t = trigger('HT-F01', 'L4')
|
||||||
const level = complianceScopeEngine.determineLevel({ composite: 40 } as any, [t])
|
const level = complianceScopeEngine.determineLevel({ composite_score: 40 } as any, [t])
|
||||||
expect(level).toBe('L4')
|
expect(level).toBe('L4')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('level = max(score-level, trigger-level) — score wins when higher', () => {
|
it('level = max(score-level, trigger-level) — score wins when higher', () => {
|
||||||
const t = trigger('HT-B01', 'L2')
|
const t = trigger('HT-B01', 'L2')
|
||||||
// score gives L3, trigger gives L2 → max = L3
|
// score gives L3, trigger gives L2 → max = L3
|
||||||
const level = complianceScopeEngine.determineLevel({ composite: 60 } as any, [t])
|
const level = complianceScopeEngine.determineLevel({ composite_score: 60 } as any, [t])
|
||||||
expect(level).toBe('L3')
|
expect(level).toBe('L3')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('no triggers with zero composite → L1', () => {
|
it('no triggers with zero composite → L1', () => {
|
||||||
const level = complianceScopeEngine.determineLevel({ composite: 0 } as any, [])
|
const level = complianceScopeEngine.determineLevel({ composite_score: 0 } as any, [])
|
||||||
expect(level).toBe('L1')
|
expect(level).toBe('L1')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -215,7 +215,7 @@ describe('evaluate — integration', () => {
|
|||||||
|
|
||||||
it('composite score non-negative', () => {
|
it('composite score non-negative', () => {
|
||||||
const decision = complianceScopeEngine.evaluate([ans('org_employee_count', '50-249')])
|
const decision = complianceScopeEngine.evaluate([ans('org_employee_count', '50-249')])
|
||||||
expect((decision.scores as any).composite).toBeGreaterThanOrEqual(0)
|
expect((decision.scores as any).composite_score).toBeGreaterThanOrEqual(0)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('evaluate returns array types for collections', () => {
|
it('evaluate returns array types for collections', () => {
|
||||||
|
|||||||
@@ -41,9 +41,9 @@ describe('SDK_STEPS', () => {
|
|||||||
|
|
||||||
describe('getStepById', () => {
|
describe('getStepById', () => {
|
||||||
it('should return the correct step for a valid ID', () => {
|
it('should return the correct step for a valid ID', () => {
|
||||||
const step = getStepById('use-case-workshop')
|
const step = getStepById('use-case-assessment')
|
||||||
expect(step).toBeDefined()
|
expect(step).toBeDefined()
|
||||||
expect(step?.name).toBe('Use Case Workshop')
|
expect(step?.name).toBe('Anwendungsfall-Erfassung')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should return undefined for an invalid ID', () => {
|
it('should return undefined for an invalid ID', () => {
|
||||||
@@ -62,7 +62,7 @@ describe('getStepByUrl', () => {
|
|||||||
it('should return the correct step for a valid URL', () => {
|
it('should return the correct step for a valid URL', () => {
|
||||||
const step = getStepByUrl('/sdk/advisory-board')
|
const step = getStepByUrl('/sdk/advisory-board')
|
||||||
expect(step).toBeDefined()
|
expect(step).toBeDefined()
|
||||||
expect(step?.id).toBe('use-case-workshop')
|
expect(step?.id).toBe('use-case-assessment')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should return undefined for an invalid URL', () => {
|
it('should return undefined for an invalid URL', () => {
|
||||||
@@ -79,9 +79,9 @@ describe('getStepByUrl', () => {
|
|||||||
|
|
||||||
describe('getNextStep', () => {
|
describe('getNextStep', () => {
|
||||||
it('should return the next step in sequence', () => {
|
it('should return the next step in sequence', () => {
|
||||||
const nextStep = getNextStep('use-case-workshop')
|
const nextStep = getNextStep('use-case-assessment')
|
||||||
expect(nextStep).toBeDefined()
|
expect(nextStep).toBeDefined()
|
||||||
expect(nextStep?.id).toBe('screening')
|
expect(nextStep?.id).toBe('import')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should return undefined for the last step', () => {
|
it('should return undefined for the last step', () => {
|
||||||
@@ -103,11 +103,11 @@ describe('getPreviousStep', () => {
|
|||||||
it('should return the previous step in sequence', () => {
|
it('should return the previous step in sequence', () => {
|
||||||
const prevStep = getPreviousStep('screening')
|
const prevStep = getPreviousStep('screening')
|
||||||
expect(prevStep).toBeDefined()
|
expect(prevStep).toBeDefined()
|
||||||
expect(prevStep?.id).toBe('use-case-workshop')
|
expect(prevStep?.id).toBe('import')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should return undefined for the first step', () => {
|
it('should return undefined for the first step', () => {
|
||||||
const prevStep = getPreviousStep('use-case-workshop')
|
const prevStep = getPreviousStep('company-profile')
|
||||||
expect(prevStep).toBeUndefined()
|
expect(prevStep).toBeUndefined()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -120,7 +120,7 @@ describe('getCompletionPercentage', () => {
|
|||||||
userId: 'test',
|
userId: 'test',
|
||||||
subscription: 'PROFESSIONAL',
|
subscription: 'PROFESSIONAL',
|
||||||
currentPhase: 1,
|
currentPhase: 1,
|
||||||
currentStep: 'use-case-workshop',
|
currentStep: 'use-case-assessment',
|
||||||
completedSteps,
|
completedSteps,
|
||||||
checkpoints: {},
|
checkpoints: {},
|
||||||
useCases: [],
|
useCases: [],
|
||||||
@@ -189,7 +189,7 @@ describe('getPhaseCompletionPercentage', () => {
|
|||||||
userId: 'test',
|
userId: 'test',
|
||||||
subscription: 'PROFESSIONAL',
|
subscription: 'PROFESSIONAL',
|
||||||
currentPhase: 1,
|
currentPhase: 1,
|
||||||
currentStep: 'use-case-workshop',
|
currentStep: 'use-case-assessment',
|
||||||
completedSteps,
|
completedSteps,
|
||||||
checkpoints: {},
|
checkpoints: {},
|
||||||
useCases: [],
|
useCases: [],
|
||||||
|
|||||||
@@ -14,13 +14,13 @@ import {
|
|||||||
} from '../types'
|
} from '../types'
|
||||||
|
|
||||||
describe('DSFA_SECTIONS', () => {
|
describe('DSFA_SECTIONS', () => {
|
||||||
it('should have 5 sections defined', () => {
|
it('should have 9 sections defined', () => {
|
||||||
expect(DSFA_SECTIONS.length).toBe(5)
|
expect(DSFA_SECTIONS.length).toBe(9)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should have sections numbered 1-5', () => {
|
it('should have sections numbered 0-8', () => {
|
||||||
const numbers = DSFA_SECTIONS.map(s => s.number)
|
const numbers = DSFA_SECTIONS.map(s => s.number)
|
||||||
expect(numbers).toEqual([1, 2, 3, 4, 5])
|
expect(numbers).toEqual([0, 1, 2, 3, 4, 5, 6, 7, 8])
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should have GDPR references for all sections', () => {
|
it('should have GDPR references for all sections', () => {
|
||||||
@@ -30,15 +30,16 @@ describe('DSFA_SECTIONS', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should mark first 4 sections as required', () => {
|
it('should mark 7 sections as required', () => {
|
||||||
const requiredSections = DSFA_SECTIONS.filter(s => s.required)
|
const requiredSections = DSFA_SECTIONS.filter(s => s.required)
|
||||||
expect(requiredSections.length).toBe(4)
|
expect(requiredSections.length).toBe(7)
|
||||||
expect(requiredSections.map(s => s.number)).toEqual([1, 2, 3, 4])
|
expect(requiredSections.map(s => s.number)).toEqual([0, 1, 2, 3, 4, 6, 7])
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should mark section 5 as optional', () => {
|
it('should mark sections 5 and 8 as optional', () => {
|
||||||
const section5 = DSFA_SECTIONS.find(s => s.number === 5)
|
const optionalSections = DSFA_SECTIONS.filter(s => !s.required)
|
||||||
expect(section5?.required).toBe(false)
|
expect(optionalSections.length).toBe(2)
|
||||||
|
expect(optionalSections.map(s => s.number)).toEqual([5, 8])
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should have German titles for all sections', () => {
|
it('should have German titles for all sections', () => {
|
||||||
@@ -197,7 +198,7 @@ describe('DSFAMitigation type', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe('DSFASectionProgress type', () => {
|
describe('DSFASectionProgress type', () => {
|
||||||
it('should track completion for all 5 sections', () => {
|
it('should track completion for all 9 sections', () => {
|
||||||
const progress: DSFASectionProgress = {
|
const progress: DSFASectionProgress = {
|
||||||
section_0_complete: false,
|
section_0_complete: false,
|
||||||
section_1_complete: true,
|
section_1_complete: true,
|
||||||
@@ -207,6 +208,7 @@ describe('DSFASectionProgress type', () => {
|
|||||||
section_5_complete: false,
|
section_5_complete: false,
|
||||||
section_6_complete: false,
|
section_6_complete: false,
|
||||||
section_7_complete: false,
|
section_7_complete: false,
|
||||||
|
section_8_complete: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(progress.section_1_complete).toBe(true)
|
expect(progress.section_1_complete).toBe(true)
|
||||||
@@ -238,11 +240,15 @@ describe('DSFA type', () => {
|
|||||||
authority_consulted: false,
|
authority_consulted: false,
|
||||||
status: 'draft',
|
status: 'draft',
|
||||||
section_progress: {
|
section_progress: {
|
||||||
|
section_0_complete: false,
|
||||||
section_1_complete: true,
|
section_1_complete: true,
|
||||||
section_2_complete: true,
|
section_2_complete: true,
|
||||||
section_3_complete: false,
|
section_3_complete: false,
|
||||||
section_4_complete: false,
|
section_4_complete: false,
|
||||||
section_5_complete: false,
|
section_5_complete: false,
|
||||||
|
section_6_complete: false,
|
||||||
|
section_7_complete: false,
|
||||||
|
section_8_complete: false,
|
||||||
},
|
},
|
||||||
conclusion: '',
|
conclusion: '',
|
||||||
created_at: new Date().toISOString(),
|
created_at: new Date().toISOString(),
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export default defineConfig({
|
|||||||
globals: true,
|
globals: true,
|
||||||
setupFiles: ['./vitest.setup.ts'],
|
setupFiles: ['./vitest.setup.ts'],
|
||||||
include: ['**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
include: ['**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
||||||
exclude: ['node_modules', '.next', 'dist'],
|
exclude: ['node_modules', '.next', 'dist', 'e2e'],
|
||||||
coverage: {
|
coverage: {
|
||||||
provider: 'v8',
|
provider: 'v8',
|
||||||
reporter: ['text', 'json', 'html'],
|
reporter: ['text', 'json', 'html'],
|
||||||
|
|||||||
Reference in New Issue
Block a user