mirror of
https://github.com/wekan/wekan.git
synced 2026-11-08 03:22:32 -05:00
- #2769: refresh drag geometry when the DOM changes mid-drag - cards no longer drop into the wrong swimlane while someone adds a card. - #1992: board import restores all five card date fields (and creator) with fallbacks; receivedAt/endAt were never imported at all. - #2292: archiving a swimlane archives its cards (mirroring lists); restore brings back exactly the cards archived with it. - #2494: client noCache card lookup returned a Promise since the Meteor 3 port - multi-select board moves wrote sort: NaN everywhere. - #1853: subtask "View it" falls back to the subtask's boardId when the deposit board is not loaded, instead of silently doing nothing. - #1554: restore the reactive dependency lost in7673c77c5so cards added after board render accept sidebar label/member drops. - #2306: "filter to selection" and every bulk action are board-scoped; foreign-board cards can no longer be silently archived. - #1437: new POST /users/logout API endpoint revokes the presented resume token, or all tokens with {"all": true}. All with positive+negative regression tests (see tests/*.test.cjs). Closes #1389: already fixed - the standalone pencil edit button (0cc63b810) plus the wrapped viewer (bf2b3b40c) guarantee an edit target even when a full-width link fills the description. Thanks to hever, Cactusbone, Vermeille, Vanclief, Miffe, IcedQuinn, ppouliot, GhassenRjab and xet7.
94 lines
3.6 KiB
JavaScript
94 lines
3.6 KiB
JavaScript
/* eslint-env mocha */
|
|
import { expect } from 'chai';
|
|
import { subtaskNavTarget } from '/client/components/cards/subtaskViewHelpers';
|
|
|
|
/**
|
|
* Unit tests for the subtask "View it" navigation target.
|
|
*
|
|
* Regression #3743: "[UX Bug] Subtask 'View it' button opens the parent card
|
|
* instead of the subtask". The js-view-subtask handler must navigate to the
|
|
* SUBTASK card's own board/slug/id, never to the parent (current) card's.
|
|
*
|
|
* subtaskNavTarget(subtask) returns the FlowRouter 'card' route params derived
|
|
* exclusively from the subtask. These tests build a subtask whose own ids are
|
|
* deliberately different from a "parent" card's ids and assert the result
|
|
* carries the subtask's ids, not the parent's.
|
|
*/
|
|
|
|
// A parent card whose ids must NOT leak into the navigation target.
|
|
const parentCard = {
|
|
_id: 'parentCardId',
|
|
boardId: 'parentBoardId',
|
|
};
|
|
|
|
// Build a subtask stub that mimics the Card model surface the helper uses:
|
|
// board() (with _id + slug), getRealId(), swimlaneId and listId.
|
|
function makeSubtask({ withRealId = true } = {}) {
|
|
const subtaskBoard = { _id: 'subtaskBoardId', slug: 'subtask-board-slug' };
|
|
return {
|
|
_id: 'subtaskCardId',
|
|
parentId: parentCard._id,
|
|
boardId: subtaskBoard._id,
|
|
swimlaneId: 'subtaskSwimlaneId',
|
|
listId: 'subtaskListId',
|
|
board() {
|
|
return subtaskBoard;
|
|
},
|
|
getRealId() {
|
|
return withRealId ? 'subtaskRealId' : undefined;
|
|
},
|
|
};
|
|
}
|
|
|
|
describe('subtaskNavTarget (#3743)', function() {
|
|
it('targets the subtask\'s own board, not the parent card\'s board', function() {
|
|
const target = subtaskNavTarget(makeSubtask());
|
|
expect(target.boardId).to.equal('subtaskBoardId');
|
|
expect(target.boardId).to.not.equal(parentCard.boardId);
|
|
});
|
|
|
|
it('targets the subtask card itself, not the parent card', function() {
|
|
const target = subtaskNavTarget(makeSubtask());
|
|
// Uses the subtask's real id and never the parent card id.
|
|
expect(target.cardId).to.equal('subtaskRealId');
|
|
expect(target.cardId).to.not.equal(parentCard._id);
|
|
});
|
|
|
|
it('uses the subtask board slug, swimlane and list', function() {
|
|
const target = subtaskNavTarget(makeSubtask());
|
|
expect(target.slug).to.equal('subtask-board-slug');
|
|
expect(target.swimlaneId).to.equal('subtaskSwimlaneId');
|
|
expect(target.listId).to.equal('subtaskListId');
|
|
});
|
|
|
|
it('falls back to subtask._id when getRealId yields nothing', function() {
|
|
const target = subtaskNavTarget(makeSubtask({ withRealId: false }));
|
|
expect(target.cardId).to.equal('subtaskCardId');
|
|
expect(target.cardId).to.not.equal(parentCard._id);
|
|
});
|
|
|
|
it('falls back to the subtask boardId when its board is not loaded (#1853/#4762)', function() {
|
|
// The deposit/target board is often ANOTHER board that is not in
|
|
// minimongo while the parent board is open; navigation must still work
|
|
// (the card route loads the board), it must not throw or no-op.
|
|
const subtask = makeSubtask();
|
|
subtask.board = () => undefined;
|
|
const target = subtaskNavTarget(subtask);
|
|
expect(target.boardId).to.equal('subtaskBoardId');
|
|
expect(target.slug).to.equal('board');
|
|
expect(target.cardId).to.equal('subtaskRealId');
|
|
});
|
|
|
|
it('returns undefined for a missing subtask', function() {
|
|
expect(subtaskNavTarget(undefined)).to.equal(undefined);
|
|
expect(subtaskNavTarget(null)).to.equal(undefined);
|
|
});
|
|
|
|
it('returns undefined for a broken subtask with no board reference at all', function() {
|
|
const subtask = makeSubtask();
|
|
subtask.board = () => undefined;
|
|
subtask.boardId = undefined;
|
|
expect(subtaskNavTarget(subtask)).to.equal(undefined);
|
|
});
|
|
});
|