Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/dotnet-core-master.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ jobs:
strategy:
fail-fast: false
matrix:
test: [a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,b1m,c1m,d1m,e1m,f1m,h1m,i1m,j1m]
test: [a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,b1m,c1m,d1m,e1m,f1m,h1m,i1m,j1m,l1m]
steps:
- uses: actions/checkout@v3
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/dotnet-core-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ jobs:
strategy:
fail-fast: false
matrix:
test: [a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,b1m,c1m,d1m,e1m,f1m,h1m,i1m,j1m]
test: [a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,b1m,c1m,d1m,e1m,f1m,h1m,i1m,j1m,l1m]
steps:
- uses: actions/checkout@v3
with:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,22 @@ public class TimePlanningPlanningPrDayModel
public int? Pause4ExactMinutes { get; set; }
public int? Pause5ExactMinutes { get; set; }

// Request-only: exact-minute start/stop times under UseOneMinuteIntervals=true.
// Null means the client did not send the new field; backend falls back to the
// legacy Start*Id/Stop*Id (5-minute slot) write path. When set, backend
// translates the minutes-of-day into Start*StartedAt/Stop*StoppedAt timestamps
// (anchor: planning.Date; cross-midnight on Stop when value <= matching Start).
public int? Start1ExactMinutes { get; set; }
public int? Start2ExactMinutes { get; set; }
public int? Start3ExactMinutes { get; set; }
public int? Start4ExactMinutes { get; set; }
public int? Start5ExactMinutes { get; set; }
public int? Stop1ExactMinutes { get; set; }
public int? Stop2ExactMinutes { get; set; }
public int? Stop3ExactMinutes { get; set; }
public int? Stop4ExactMinutes { get; set; }
public int? Stop5ExactMinutes { get; set; }

public int Break1Shift { get; set; }
public int Break2Shift { get; set; }
public int Break3Shift { get; set; }
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -166,4 +166,56 @@ test.describe('Dashboard edit values', () => {
await expect(page.locator('#planHours')).toHaveValue('22');
await expect(page.locator('#todaysFlex')).toHaveValue('0.00');
});

/**
* Flag-off regression guard for the admin-edit exact-minute work:
* setting a clean 5-min-aligned actual pair (`03:00 → 11:00`) on a
* flag-off worker must still save and reload correctly. The additive
* `Start{N}ExactMinutes` / `Stop{N}ExactMinutes` DTO fields plus the
* server-side `ApplyExactMinuteStart/Stop` helpers were introduced
* for the flag-on path — this test locks the contract that the
* flag-off path is bit-identical to before (i.e. our `Math.round`
* change and the additive DTO fields did NOT alter flag-off
* behavior). A regression in either direction (e.g. ExactMinutes
* leaking into the flag-off save path or the DTO change altering
* serialization defaults) would surface here as a `toHaveValue`
* mismatch or a save-button-disabled stall.
*
* 03:00 → 11:00 = 480 min ⇒ start1Id = (180/5)+1 = 37; stop1Id =
* (660/5)+1 = 133; (133-37)*5 = 480 min ⇒ actualHours = 8.00.
*/
test('flag-off: clean 5-min actual pair 03:00 -> 11:00 round-trips through save + reopen', async ({ page }) => {
await setTimepickerValue(page, 'plannedStartOfShift1', '03', '00');
await setTimepickerValue(page, 'plannedEndOfShift1', '11', '00');
await setTimepickerValue(page, 'start1StartedAt', '03', '00');
await setTimepickerValue(page, 'stop1StoppedAt', '11', '00');

await expect(page.locator('#saveButton')).toBeEnabled({ timeout: 10000 });
const updatePromise = page.waitForResponse(r =>
r.url().includes('/api/time-planning-pn/plannings/') && r.request().method() === 'PUT');
const reindexPromise = page.waitForResponse(r =>
r.url().includes('/api/time-planning-pn/plannings/index') && r.request().method() === 'POST');
await page.locator('#saveButton').click();
const updateResponse = await updatePromise;
await reindexPromise;
if (await page.locator('.overlay-spinner').count() > 0) {
await page.locator('.overlay-spinner').waitFor({ state: 'hidden', timeout: 30000 });
}
await page.waitForTimeout(500);
expect(updateResponse.status(), 'flag-off PUT must succeed with clean 5-min actuals').toBeLessThan(400);

// Re-open the cell and assert the picker shows the saved clean values.
await page.locator('#cell0_0').scrollIntoViewIfNeeded();
await page.locator('#cell0_0').click();
await expect(page.locator('#planHours')).toBeVisible();
await expect(
page.locator('[data-testid="start1StartedAt"]'),
'flag-off shift1 start must round-trip 03:00 unchanged',
).toHaveValue('03:00');
await expect(
page.locator('[data-testid="stop1StoppedAt"]'),
'flag-off shift1 stop must round-trip 11:00 unchanged',
).toHaveValue('11:00');
await page.locator('#cancelButton').click();
});
});
2,778 changes: 2,778 additions & 0 deletions eform-client/playwright/e2e/plugins/time-planning-pn/l1m/420_SDK.sql

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Loading
Loading