feat(KAN-34): rework blocker and ticket history
This commit is contained in:
@@ -101,6 +101,102 @@ try {
|
||||
}
|
||||
await page.setViewportSize({ width: 390, height: 1000 });
|
||||
await visit();
|
||||
const blocker = content().locator('#ticket-blocker');
|
||||
const blockerToggle = blocker.getByRole('checkbox', {
|
||||
name: 'Mark ticket as blocked',
|
||||
exact: true,
|
||||
});
|
||||
const blockerComment = blocker.getByLabel('Blocker comment', {
|
||||
exact: true,
|
||||
});
|
||||
assert.equal(await blockerToggle.isChecked(), true);
|
||||
assert.equal(
|
||||
await blocker.getByText('Alex Morgan', { exact: true }).count(),
|
||||
0,
|
||||
);
|
||||
assert.equal(
|
||||
await content()
|
||||
.locator('#ticket-history')
|
||||
.getByText('Alex Morgan', { exact: true })
|
||||
.count(),
|
||||
1,
|
||||
);
|
||||
assert.equal(
|
||||
await content()
|
||||
.locator('#ticket-history')
|
||||
.getByText('Status changed', { exact: true })
|
||||
.count(),
|
||||
1,
|
||||
);
|
||||
await blockerComment.fill('');
|
||||
assert.equal(
|
||||
await blockerComment.evaluate(
|
||||
(element) => element.validity.valueMissing,
|
||||
),
|
||||
true,
|
||||
);
|
||||
await blockerComment.fill('Waiting for a production decision.');
|
||||
await blocker.getByRole('button', { name: 'Save blocker' }).click();
|
||||
await page.getByText('Ticket updated.', { exact: true }).waitFor();
|
||||
assert.equal(
|
||||
await blockerComment.inputValue(),
|
||||
'Waiting for a production decision.',
|
||||
);
|
||||
for (const label of ['Assignee', 'Reviewer']) {
|
||||
const field = content()
|
||||
.locator('#ticket-metadata dl > div')
|
||||
.filter({ has: page.getByText(label, { exact: true }) });
|
||||
assert.match(await field.locator('dd').innerText(), /Alex Morgan/);
|
||||
}
|
||||
await blockerToggle.uncheck();
|
||||
await blocker.getByRole('button', { name: 'Unblock ticket' }).click();
|
||||
await blocker
|
||||
.getByText('This ticket currently has no active blocker.', {
|
||||
exact: true,
|
||||
})
|
||||
.waitFor();
|
||||
assert.equal(await blocker.getByLabel('Blocker comment').count(), 0);
|
||||
await content().getByRole('button', { name: 'Change parent' }).click();
|
||||
await page.waitForFunction(
|
||||
() => document.activeElement?.id === 'parent_ticket_id',
|
||||
);
|
||||
const saveTicket = content().getByRole('button', {
|
||||
name: 'Save changes',
|
||||
exact: true,
|
||||
});
|
||||
assert.equal(
|
||||
await content()
|
||||
.getByRole('button', { name: 'Discard changes', exact: true })
|
||||
.isDisabled(),
|
||||
true,
|
||||
'Saving the blocker must also update the ticket form defaults.',
|
||||
);
|
||||
await page
|
||||
.getByLabel('Title', { exact: true })
|
||||
.fill('Updated title after unblocking');
|
||||
const ticketUpdate = page.waitForRequest(
|
||||
(request) =>
|
||||
request.method() === 'PATCH' &&
|
||||
new URL(request.url()).pathname === '/projects/7/tickets/42',
|
||||
);
|
||||
await saveTicket.click();
|
||||
const savedTicket = (await ticketUpdate).postDataJSON();
|
||||
assert.equal(savedTicket.is_blocked, false);
|
||||
assert.equal(savedTicket.blocked_comment, '');
|
||||
assert.equal(Number(savedTicket.parent_ticket_id), 40);
|
||||
assert.deepEqual(savedTicket.acceptance_criteria, [
|
||||
{ id: 10, text: 'Cache requests safely', checked: false, indent: 0 },
|
||||
{
|
||||
id: 11,
|
||||
text: 'Invalidate when records change',
|
||||
checked: false,
|
||||
indent: 1,
|
||||
},
|
||||
]);
|
||||
await page
|
||||
.getByRole('heading', { name: 'Updated title after unblocking' })
|
||||
.waitFor();
|
||||
await visit();
|
||||
await tabTo(edit());
|
||||
await page.keyboard.press('Enter');
|
||||
await page.getByLabel('Title', { exact: true }).fill('Unsaved title draft');
|
||||
|
||||
@@ -108,9 +108,18 @@ const ticket = {
|
||||
},
|
||||
],
|
||||
worklog_entries: [
|
||||
{
|
||||
id: 2,
|
||||
actor: null,
|
||||
actor_id: null,
|
||||
entry_type: 'status_changed',
|
||||
summary: 'Moved from Backlog to Delivery / In progress.',
|
||||
created_at: '2026-09-11T13:00:00Z',
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
actor: user,
|
||||
actor_id: user.id,
|
||||
entry_type: 'created',
|
||||
summary: 'Ticket created in the project backlog.',
|
||||
created_at: '2026-09-11T12:00:00Z',
|
||||
@@ -395,7 +404,19 @@ if (serve) {
|
||||
if (params.has('reject')) {
|
||||
params.set('rejected', '1');
|
||||
} else {
|
||||
savedForm = data;
|
||||
savedForm = {
|
||||
...data,
|
||||
blocked_comment: data.is_blocked
|
||||
? data.blocked_comment
|
||||
: null,
|
||||
field_values: data.field_values.map((fieldValue) => ({
|
||||
...fieldValue,
|
||||
user_value:
|
||||
Number(fieldValue.value_user_id) === user.id
|
||||
? user
|
||||
: null,
|
||||
})),
|
||||
};
|
||||
params.set('saved', data.title);
|
||||
}
|
||||
}
|
||||
@@ -476,6 +497,9 @@ if (serve) {
|
||||
'feature/ENG-42-cache',
|
||||
'Cache implementation',
|
||||
'Ticket created in the project backlog.',
|
||||
'Ticket created',
|
||||
'Status changed',
|
||||
'System',
|
||||
]) {
|
||||
assert.ok(
|
||||
html.includes(text),
|
||||
@@ -486,6 +510,7 @@ if (serve) {
|
||||
'description',
|
||||
'checklist',
|
||||
'metadata',
|
||||
'blocker',
|
||||
'relationships',
|
||||
'history',
|
||||
'git',
|
||||
|
||||
Reference in New Issue
Block a user