Patch #42521 » 0002-Add-JavaScript-test-environment-And-dialog-controlle.patch
Gemfile | ||
---|---|---|
94 | 94 | |
95 | 95 |
group :development, :test do |
96 | 96 |
gem 'debug' |
97 |
gem 'importmap_mocha-rails' |
|
97 | 98 |
end |
98 | 99 | |
99 | 100 |
group :development do |
config/application.rb | ||
---|---|---|
109 | 109 |
if File.exist?(File.join(File.dirname(__FILE__), 'additional_environment.rb')) |
110 | 110 |
instance_eval File.read(File.join(File.dirname(__FILE__), 'additional_environment.rb')) |
111 | 111 |
end |
112 | ||
113 |
if Rails.env.local? |
|
114 |
config.importmap_mocha_style = 'tdd' |
|
115 |
end |
|
112 | 116 |
end |
113 | 117 |
end |
test/javascripts/controllers/dialog_controller.test.js | ||
---|---|---|
1 |
/** |
|
2 |
* Redmine - project management software |
|
3 |
* Copyright (C) 2006- Jean-Philippe Lang |
|
4 |
* This code is released under the GNU General Public License. |
|
5 |
*/ |
|
6 | ||
7 |
import { Application } from "@hotwired/stimulus" |
|
8 |
import DialogController from 'controllers/dialog_controller' |
|
9 |
import { assert } from 'chai' |
|
10 | ||
11 |
const html = ` |
|
12 |
<div data-controller="dialog" id="dialog"> |
|
13 |
<div data-action="pointerdown->dialog#start pointerup->dialog#end pointercancel->dialog#end pointermove->dialog#move touchstart->dialog#noop dragstart->dialog#noop" data-dialog-target="handler" id="handler">Drag Here</div> |
|
14 |
<div id="hide">Close</div> |
|
15 |
</div> |
|
16 |
<div id="wrapper"></div> |
|
17 |
<div id="modal-backdrop"></div>` |
|
18 | ||
19 |
suite('dialog controller', () => { |
|
20 | ||
21 |
let container; |
|
22 |
let controller; |
|
23 | ||
24 |
setup(async () => { |
|
25 |
container = document.getElementById('container') |
|
26 |
const app = Application.start(container); |
|
27 |
await app.register('dialog', DialogController); |
|
28 | ||
29 |
container.insertAdjacentHTML('afterbegin', html) |
|
30 |
}); |
|
31 | ||
32 |
teardown(() => { |
|
33 |
const clone = container.cloneNode(false); |
|
34 |
container.parentNode.replaceChild(clone, container); |
|
35 |
}); |
|
36 | ||
37 |
test('connect lifecycle method', () => { |
|
38 |
const dialog = document.getElementById('dialog'); |
|
39 |
controller = dialog.dialog_controller; |
|
40 |
assert.isNotNull(controller); |
|
41 |
assert.isNull(controller.dragging); |
|
42 |
assert.isNull(controller.backdrop); |
|
43 |
}); |
|
44 | ||
45 |
test('start dragging', async () => { |
|
46 |
const handler = document.getElementById('handler'); |
|
47 |
const dialog = document.getElementById('dialog'); |
|
48 |
controller = dialog.dialog_controller; |
|
49 | ||
50 |
const event = new PointerEvent('pointerdown', { button: 0, clientX: 100, clientY: 100 }); |
|
51 |
await handler.dispatchEvent(event); |
|
52 | ||
53 |
assert.isNotNull(controller.dragging); |
|
54 |
assert.isDefined(controller.dragging.dx); |
|
55 |
assert.isDefined(controller.dragging.dy); |
|
56 |
assert.isTrue(handler.classList.contains("dragging")); |
|
57 |
}) |
|
58 | ||
59 |
test('move dialog', async () => { |
|
60 |
const handler = document.getElementById('handler'); |
|
61 |
const dialog = document.getElementById('dialog'); |
|
62 |
controller = dialog.dialog_controller; |
|
63 | ||
64 |
let event = new PointerEvent('pointerdown', { button: 0, clientX: 100, clientY: 100 }); |
|
65 |
await handler.dispatchEvent(event); |
|
66 | ||
67 |
event = new PointerEvent("pointermove", { clientX: 150, clientY: 150 }); |
|
68 |
await handler.dispatchEvent(event); |
|
69 | ||
70 |
const pos = controller.pos; |
|
71 |
assert.isDefined(pos.x); |
|
72 |
assert.isDefined(pos.y); |
|
73 |
assert.notEqual(pos.x, 0); |
|
74 |
assert.notEqual(pos.y, 0); |
|
75 |
}) |
|
76 | ||
77 |
test('end dragging', async () => { |
|
78 |
const handler = document.getElementById('handler'); |
|
79 |
const dialog = document.getElementById('dialog'); |
|
80 |
controller = dialog.dialog_controller; |
|
81 | ||
82 |
let event = new PointerEvent('pointerdown', { button: 0, clientX: 100, clientY: 100 }); |
|
83 |
await handler.dispatchEvent(event); |
|
84 | ||
85 |
event = new PointerEvent("pointerup"); |
|
86 |
await handler.dispatchEvent(event); |
|
87 | ||
88 |
assert.isNull(controller.dragging); |
|
89 |
assert.isFalse(handler.classList.contains("dragging")); |
|
90 |
}); |
|
91 | ||
92 |
test('show dialog', async () => { |
|
93 |
const dialog = document.getElementById('dialog'); |
|
94 |
controller = dialog.dialog_controller; |
|
95 |
controller.show({ width: "500px", backdrop: "modal-backdrop" }); |
|
96 |
const backdrop = document.getElementById("modal-backdrop"); |
|
97 | ||
98 |
assert.equal(dialog.style.display, ""); |
|
99 |
assert.equal(dialog.style.width, "500px"); |
|
100 |
assert.isTrue(backdrop.classList.contains("modal-backdrop-open")); |
|
101 |
}) |
|
102 | ||
103 |
test('hide dialog', () => { |
|
104 |
const dialog = document.getElementById('dialog'); |
|
105 |
controller = dialog.dialog_controller; |
|
106 |
controller.show({ backdrop: "modal-backdrop" }); |
|
107 |
controller.hide(); |
|
108 |
const backdrop = document.getElementById("modal-backdrop"); |
|
109 | ||
110 |
assert.equal(dialog.style.display, 'none'); |
|
111 |
assert.isFalse(backdrop.classList.contains('modal-backdrop-open')); |
|
112 |
}) |
|
113 |
}) |
test/javascripts/controllers/dialog_dispatcher_controller.test.js | ||
---|---|---|
1 |
/** |
|
2 |
* Redmine - project management software |
|
3 |
* Copyright (C) 2006- Jean-Philippe Lang |
|
4 |
* This code is released under the GNU General Public License. |
|
5 |
*/ |
|
6 | ||
7 |
import { Application } from "@hotwired/stimulus" |
|
8 |
import DialogDispatcherController from 'controllers/dialog_dispatcher_controller' |
|
9 |
import DialogController from 'controllers/dialog_controller' |
|
10 |
import { assert } from 'chai' |
|
11 | ||
12 |
const html = `<div id="dialog" data-controller="dialog" style="display:none"> |
|
13 |
<button data-action="dialog#hide">close</button> |
|
14 |
</div> |
|
15 |
<div id="dispatcher" data-controller="dialog-dispatcher" data-dialog-dispatcher-dialog-outlet="#dialog"> |
|
16 |
<button id="button" data-action="dialog-dispatcher#show" data-dialog-dispatcher-width-param="500px">Show Dialog</button> |
|
17 |
</div> |
|
18 |
<div id="wrapper"></div> |
|
19 |
<div id="modal-backdrop"></div>`; |
|
20 | ||
21 |
suite('DialogDispatcherController', () => { |
|
22 | ||
23 |
let container; |
|
24 | ||
25 |
setup(async () => { |
|
26 |
container = document.getElementById('container') |
|
27 |
const app = Application.start(container); |
|
28 |
await app.register('dialog-dispatcher', DialogDispatcherController); |
|
29 |
await app.register('dialog', DialogController); |
|
30 | ||
31 |
container.insertAdjacentHTML('afterbegin', html) |
|
32 |
}); |
|
33 | ||
34 |
teardown(() => { |
|
35 |
const clone = container.cloneNode(false); |
|
36 |
container.parentNode.replaceChild(clone, container); |
|
37 |
}); |
|
38 | ||
39 |
test('show the dialog with the specified width', () => { |
|
40 |
const button = document.getElementById('button') |
|
41 |
button.click(); |
|
42 | ||
43 |
const dialog = document.getElementById('dialog') |
|
44 |
assert.equal(dialog.style.width, '500px'); |
|
45 |
assert.equal(dialog.style.display, ''); |
|
46 |
}); |
|
47 | ||
48 |
test('show the dialog when show target is connected', async () => { |
|
49 |
const html = `<div id="remote-dialog" data-controller="dialog" data-dialog-dispatcher-target="show" style="display:none" data-width="300px"> |
|
50 |
<button data-action="dialog#hide">close</button> |
|
51 |
</div>` |
|
52 | ||
53 |
const dispatcher = document.getElementById('dispatcher') |
|
54 |
dispatcher.insertAdjacentHTML('afterbegin', html) |
|
55 | ||
56 |
const remotedialog = await document.getElementById('remote-dialog') |
|
57 |
assert.equal(remotedialog.style.width, '300px'); |
|
58 |
assert.equal(remotedialog.style.display, ''); |
|
59 |
}); |
|
60 | ||
61 |
test('hide the dialog when hide target is Connected', async () => { |
|
62 |
const button = document.getElementById('button') |
|
63 |
button.click(); |
|
64 | ||
65 |
const dialog = document.getElementById('dialog') |
|
66 |
const dispatcher = document.getElementById('dispatcher') |
|
67 |
await dispatcher.insertAdjacentHTML('afterbegin', '<template data-dialog-dispatcher-target="hide"></template>') |
|
68 |
assert.equal(dialog.style.display, 'none'); |
|
69 | ||
70 |
const target = document.querySelector('[data-dialog-dispatcher-target=hide]') |
|
71 |
assert.isNull(target) |
|
72 |
}); |
|
73 |
}); |
- « Previous
- 1
- 2
- Next »