Add force enable/disable machine functionality for department lanes

- Introduced endpoints to handle force enable/disable machine actions (`/modules/self-serve/lane/force/machine/enable`, `/disable`).
- Updated OpenAPI spec to document the new endpoints.
- Extended `DepartmentLane.vue` and `departmentLanesTable.vue` with buttons for force enable/disable, including loading states and toast notifications.
- Added corresponding i18n translations for force control actions.
- Created E2E tests to verify translation keys, non-empty values, and source file functionality in `department-lane-force-machine.spec.js`.
This commit is contained in:
Jeppe Bundgaard
2026-02-19 11:39:36 +01:00
parent fe5140f74a
commit 2ede884959
6 changed files with 380 additions and 1 deletions
@@ -0,0 +1,144 @@
/**
* Test to verify the force enable/disable machine functionality for department lanes.
* Tests i18n translations for the feature.
*/
describe('Department Lane Force Machine Controls', () => {
const translationKeys = [
'force_enable_machine',
'force_disable_machine',
'force_enable_success',
'force_disable_success',
'force_error'
];
it('should have all force machine translations defined in Danish', async () => {
await browser.url('/');
const result = await browser.executeAsync(async (keys, done) => {
try {
const response = await fetch('/src/i18n/locales/da.json');
const data = await response.json();
if (!data.superuser || !data.superuser.department_lane) {
done({ success: false, error: 'superuser.department_lane namespace not found' });
return;
}
const missingKeys = [];
for (const key of keys) {
if (!data.superuser.department_lane[key]) {
missingKeys.push(key);
}
}
if (missingKeys.length > 0) {
done({ success: false, error: 'Missing keys: ' + missingKeys.join(', ') });
} else {
done({ success: true, keyCount: Object.keys(data.superuser.department_lane).length });
}
} catch (e) {
done({ success: false, error: e.message });
}
}, translationKeys);
console.log('Danish department_lane result:', JSON.stringify(result));
expect(result.success).toBe(true);
});
it('should have translation values that are non-empty strings', async () => {
await browser.url('/');
const result = await browser.executeAsync(async (keys, done) => {
try {
const daResponse = await fetch('/src/i18n/locales/da.json');
const daData = await daResponse.json();
const daDeptLane = daData.superuser?.department_lane || {};
// Verify all translation values are non-empty strings
const emptyValues = [];
for (const key of keys) {
const value = daDeptLane[key];
if (typeof value !== 'string' || value.trim() === '') {
emptyValues.push(key);
}
}
if (emptyValues.length > 0) {
done({ success: false, error: 'Empty values for keys: ' + emptyValues.join(', ') });
return;
}
done({ success: true, translatedKeys: keys.length });
} catch (e) {
done({ success: false, error: e.message });
}
}, translationKeys);
console.log('Translation values result:', JSON.stringify(result));
expect(result.success).toBe(true);
});
it('should have DepartmentLanes source file containing forceEnableMachine function', async () => {
await browser.url('/');
const result = await browser.executeAsync(async (done) => {
try {
const response = await fetch('/src/components/session/token/SessionUser/Objects/DepartmentLanes.vue');
const sourceCode = await response.text();
const hasForceEnableMachine = sourceCode.includes('forceEnableMachine');
const hasEndpoint = sourceCode.includes('/modules/self-serve/lane/force/machine/enable');
if (!hasForceEnableMachine) {
done({ success: false, error: 'forceEnableMachine function not found in source' });
return;
}
if (!hasEndpoint) {
done({ success: false, error: 'force enable endpoint not found in source' });
return;
}
done({ success: true });
} catch (e) {
done({ success: false, error: e.message });
}
});
console.log('forceEnableMachine source check result:', JSON.stringify(result));
expect(result.success).toBe(true);
});
it('should have DepartmentLanes source file containing forceDisableMachine function', async () => {
await browser.url('/');
const result = await browser.executeAsync(async (done) => {
try {
const response = await fetch('/src/components/session/token/SessionUser/Objects/DepartmentLanes.vue');
const sourceCode = await response.text();
const hasForceDisableMachine = sourceCode.includes('forceDisableMachine');
const hasEndpoint = sourceCode.includes('/modules/self-serve/lane/force/machine/disable');
if (!hasForceDisableMachine) {
done({ success: false, error: 'forceDisableMachine function not found in source' });
return;
}
if (!hasEndpoint) {
done({ success: false, error: 'force disable endpoint not found in source' });
return;
}
done({ success: true });
} catch (e) {
done({ success: false, error: e.message });
}
});
console.log('forceDisableMachine source check result:', JSON.stringify(result));
expect(result.success).toBe(true);
});
});