Skip to content

Commit fbbd747

Browse files
committed
AC-15336: Ajax 401 error load on Warning screen in admin panel while Login as Customer permission revoked
Fix ajax response 403 when permission(Login as customer) is revoked
1 parent 36d4d6f commit fbbd747

File tree

2 files changed

+357
-1
lines changed

2 files changed

+357
-1
lines changed

app/code/Magento/LoginAsCustomerAdminUi/view/adminhtml/web/js/confirmation-popup.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,14 @@ define([
109109
* @param {Object} jqXHR
110110
*/
111111
error: function (jqXHR) {
112+
let message = jqXHR.responseText;
113+
// If it's HTML (403 page), show only the status text
114+
if (jqXHR.status === 403) {
115+
message = 'Access denied (403 Forbidden). ' +
116+
'You may not have permission or your session expired.';
117+
}
112118
alert({
113-
content: _.escape(jqXHR.responseText)
119+
content: _.escape(message)
114120
});
115121
}
116122
});
Lines changed: 350 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,350 @@
1+
/**
2+
* Copyright © Magento, Inc. All rights reserved.
3+
* See COPYING.txt for license details.
4+
*/
5+
6+
define([
7+
'jquery',
8+
'underscore',
9+
'squire'
10+
], function ($, _, Squire) {
11+
//'use strict';
12+
13+
var injector = new Squire(),
14+
component;
15+
16+
describe('Magento_LoginAsCustomerAdminUi/js/confirmation-popup', function () {
17+
18+
beforeEach(function (done) {
19+
// Clear global function
20+
window.lacConfirmationPopup = undefined;
21+
22+
// Simple mocks - just spy functions
23+
injector.mock({
24+
'Magento_Ui/js/modal/confirm': jasmine.createSpy('confirm'),
25+
'Magento_Ui/js/modal/alert': jasmine.createSpy('alert'),
26+
'mage/translate': function(text) { return text; },
27+
'mage/template': function(template, data) { return '<div>Mock Template</div>'; },
28+
'text!Magento_LoginAsCustomerAdminUi/template/confirmation-popup/store-view-ptions.html': '<div>Mock Template</div>'
29+
});
30+
31+
injector.require([
32+
'Magento_LoginAsCustomerAdminUi/js/confirmation-popup'
33+
], function (Component) {
34+
component = Component;
35+
done();
36+
});
37+
});
38+
39+
afterEach(function () {
40+
window.lacConfirmationPopup = undefined;
41+
try {
42+
injector.clean();
43+
injector.remove();
44+
} catch (e) {
45+
// Ignore cleanup errors
46+
}
47+
});
48+
49+
describe('Component initialization', function () {
50+
it('Should be defined', function () {
51+
expect(component).toBeDefined();
52+
expect(typeof component).toBe('function');
53+
});
54+
55+
it('Should create lacConfirmationPopup global function after initialization', function () {
56+
var instance = new component({
57+
title: 'Test Title',
58+
content: 'Test Content'
59+
});
60+
61+
instance.initialize();
62+
63+
expect(window.lacConfirmationPopup).toBeDefined();
64+
expect(typeof window.lacConfirmationPopup).toBe('function');
65+
});
66+
67+
it('Should return false when called', function () {
68+
var instance = new component({
69+
title: 'Test Title',
70+
content: 'Test Content'
71+
});
72+
73+
instance.initialize();
74+
75+
var result = window.lacConfirmationPopup('http://test.url');
76+
expect(result).toBe(false);
77+
});
78+
});
79+
80+
describe('Modal configuration', function () {
81+
it('Should call confirm modal with correct configuration', function (done) {
82+
// Create a fresh injector for this test
83+
var testInjector = new Squire();
84+
var confirmSpy = jasmine.createSpy('confirm');
85+
86+
testInjector.mock({
87+
'Magento_Ui/js/modal/confirm': confirmSpy,
88+
'Magento_Ui/js/modal/alert': jasmine.createSpy('alert'),
89+
'mage/translate': function(text) { return text; },
90+
'mage/template': function(template, data) { return '<div>Mock Template</div>'; },
91+
'text!Magento_LoginAsCustomerAdminUi/template/confirmation-popup/store-view-ptions.html': '<div>Mock Template</div>'
92+
});
93+
94+
testInjector.require([
95+
'Magento_LoginAsCustomerAdminUi/js/confirmation-popup'
96+
], function (TestComponent) {
97+
var instance = new TestComponent({
98+
title: 'Login as Customer',
99+
content: 'Are you sure?'
100+
});
101+
102+
instance.initialize();
103+
window.lacConfirmationPopup('http://test.url');
104+
105+
expect(confirmSpy).toHaveBeenCalled();
106+
107+
var modalConfig = confirmSpy.calls.argsFor(0)[0];
108+
expect(modalConfig.title).toBe('Login as Customer');
109+
expect(modalConfig.modalClass).toBe('confirm lac-confirm');
110+
expect(modalConfig.content).toContain('<div class="message message-warning">Are you sure?</div>');
111+
expect(modalConfig.buttons).toBeDefined();
112+
expect(modalConfig.buttons.length).toBe(2);
113+
114+
testInjector.clean();
115+
testInjector.remove();
116+
done();
117+
});
118+
});
119+
});
120+
121+
describe('AJAX functionality', function () {
122+
it('Should make AJAX request when confirm action is triggered', function (done) {
123+
// Mock AJAX FIRST, before creating the component
124+
var ajaxSpy = jasmine.createSpy('ajax');
125+
var originalAjax = $.ajax;
126+
$.ajax = ajaxSpy;
127+
128+
// Mock DOM elements
129+
$('body').append('<input name="form_key" value="test_form_key">');
130+
$('body').append('<select id="lac-confirmation-popup-store-id"><option value="2" selected>Store 2</option></select>');
131+
132+
// Create a fresh injector for this test
133+
var testInjector = new Squire();
134+
135+
var confirmSpy = jasmine.createSpy('confirm').and.callFake(function (config) {
136+
// Simulate user clicking confirm - trigger the confirm action
137+
if (config.actions && config.actions.confirm) {
138+
config.actions.confirm();
139+
}
140+
});
141+
142+
// Mock jQuery itself to ensure the component uses our mocked ajax
143+
var mockJQuery = $;
144+
mockJQuery.ajax = ajaxSpy;
145+
146+
testInjector.mock({
147+
'jquery': mockJQuery,
148+
'Magento_Ui/js/modal/confirm': confirmSpy,
149+
'Magento_Ui/js/modal/alert': jasmine.createSpy('alert'),
150+
'mage/translate': function(text) { return text; },
151+
'mage/template': function(template, data) { return '<div>Mock Template</div>'; },
152+
'text!Magento_LoginAsCustomerAdminUi/template/confirmation-popup/store-view-ptions.html': '<div>Mock Template</div>'
153+
});
154+
155+
testInjector.require([
156+
'Magento_LoginAsCustomerAdminUi/js/confirmation-popup'
157+
], function (TestComponent) {
158+
var instance = new TestComponent({
159+
title: 'Test Title',
160+
content: 'Test Content'
161+
});
162+
163+
instance.initialize();
164+
window.lacConfirmationPopup('http://test.url/login');
165+
166+
// Verify confirm was called
167+
expect(confirmSpy).toHaveBeenCalled();
168+
169+
// Verify AJAX was called
170+
expect(ajaxSpy).toHaveBeenCalled();
171+
expect(ajaxSpy.calls.argsFor(0)[0].url).toBe('http://test.url/login');
172+
expect(ajaxSpy.calls.argsFor(0)[0].type).toBe('POST');
173+
expect(ajaxSpy.calls.argsFor(0)[0].dataType).toBe('json');
174+
175+
// Verify form data
176+
var ajaxData = ajaxSpy.calls.argsFor(0)[0].data;
177+
expect(ajaxData.form_key).toBe('test_form_key');
178+
expect(ajaxData.store_id).toBe('2');
179+
180+
// Cleanup
181+
$('input[name="form_key"]').remove();
182+
$('#lac-confirmation-popup-store-id').remove();
183+
$.ajax = originalAjax;
184+
testInjector.clean();
185+
testInjector.remove();
186+
done();
187+
});
188+
});
189+
190+
it('Should handle successful response with redirect URL', function (done) {
191+
var ajaxSpy = jasmine.createSpy('ajax');
192+
var originalAjax = $.ajax;
193+
$.ajax = ajaxSpy;
194+
195+
spyOn(window, 'open');
196+
197+
var testInjector = new Squire();
198+
199+
var confirmSpy = jasmine.createSpy('confirm').and.callFake(function (config) {
200+
if (config.actions && config.actions.confirm) {
201+
config.actions.confirm();
202+
}
203+
});
204+
205+
// Mock AJAX to call success callback
206+
ajaxSpy.and.callFake(function (options) {
207+
options.success({
208+
redirectUrl: 'http://customer.frontend.url'
209+
});
210+
});
211+
212+
// Mock jQuery with our ajax spy
213+
var mockJQuery = $;
214+
mockJQuery.ajax = ajaxSpy;
215+
216+
testInjector.mock({
217+
'jquery': mockJQuery,
218+
'Magento_Ui/js/modal/confirm': confirmSpy,
219+
'Magento_Ui/js/modal/alert': jasmine.createSpy('alert'),
220+
'mage/translate': function(text) { return text; },
221+
'mage/template': function(template, data) { return '<div>Mock Template</div>'; },
222+
'text!Magento_LoginAsCustomerAdminUi/template/confirmation-popup/store-view-ptions.html': '<div>Mock Template</div>'
223+
});
224+
225+
testInjector.require([
226+
'Magento_LoginAsCustomerAdminUi/js/confirmation-popup'
227+
], function (TestComponent) {
228+
var instance = new TestComponent({
229+
title: 'Test Title',
230+
content: 'Test Content'
231+
});
232+
233+
instance.initialize();
234+
window.lacConfirmationPopup('http://test.url');
235+
236+
expect(window.open).toHaveBeenCalledWith('http://customer.frontend.url');
237+
238+
// Cleanup
239+
$.ajax = originalAjax;
240+
testInjector.clean();
241+
testInjector.remove();
242+
done();
243+
});
244+
});
245+
246+
it('Should handle error response', function (done) {
247+
var ajaxSpy = jasmine.createSpy('ajax');
248+
var originalAjax = $.ajax;
249+
$.ajax = ajaxSpy;
250+
251+
var alertSpy = jasmine.createSpy('alert');
252+
253+
var testInjector = new Squire();
254+
255+
var confirmSpy = jasmine.createSpy('confirm').and.callFake(function (config) {
256+
if (config.actions && config.actions.confirm) {
257+
config.actions.confirm();
258+
}
259+
});
260+
261+
// Mock AJAX to call error callback
262+
ajaxSpy.and.callFake(function (options) {
263+
options.error({
264+
responseText: 'Error message',
265+
status: 500
266+
});
267+
});
268+
269+
// Mock jQuery with our ajax spy
270+
var mockJQuery = $;
271+
mockJQuery.ajax = ajaxSpy;
272+
273+
testInjector.mock({
274+
'jquery': mockJQuery,
275+
'Magento_Ui/js/modal/confirm': confirmSpy,
276+
'Magento_Ui/js/modal/alert': alertSpy,
277+
'mage/translate': function(text) { return text; },
278+
'mage/template': function(template, data) { return '<div>Mock Template</div>'; },
279+
'text!Magento_LoginAsCustomerAdminUi/template/confirmation-popup/store-view-ptions.html': '<div>Mock Template</div>'
280+
});
281+
282+
testInjector.require([
283+
'Magento_LoginAsCustomerAdminUi/js/confirmation-popup'
284+
], function (TestComponent) {
285+
var instance = new TestComponent({
286+
title: 'Test Title',
287+
content: 'Test Content'
288+
});
289+
290+
instance.initialize();
291+
window.lacConfirmationPopup('http://test.url');
292+
293+
expect(alertSpy).toHaveBeenCalled();
294+
expect(alertSpy.calls.argsFor(0)[0].content).toBe('Error message');
295+
296+
// Cleanup
297+
$.ajax = originalAjax;
298+
testInjector.clean();
299+
testInjector.remove();
300+
done();
301+
});
302+
});
303+
});
304+
305+
describe('Button click handlers', function () {
306+
it('Should handle button clicks correctly', function (done) {
307+
var testInjector = new Squire();
308+
var confirmSpy = jasmine.createSpy('confirm');
309+
310+
testInjector.mock({
311+
'Magento_Ui/js/modal/confirm': confirmSpy,
312+
'Magento_Ui/js/modal/alert': jasmine.createSpy('alert'),
313+
'mage/translate': function(text) { return text; },
314+
'mage/template': function(template, data) { return '<div>Mock Template</div>'; },
315+
'text!Magento_LoginAsCustomerAdminUi/template/confirmation-popup/store-view-ptions.html': '<div>Mock Template</div>'
316+
});
317+
318+
testInjector.require([
319+
'Magento_LoginAsCustomerAdminUi/js/confirmation-popup'
320+
], function (TestComponent) {
321+
var instance = new TestComponent({
322+
title: 'Test Title',
323+
content: 'Test Content'
324+
});
325+
326+
instance.initialize();
327+
window.lacConfirmationPopup('http://test.url');
328+
329+
var modalConfig = confirmSpy.calls.argsFor(0)[0];
330+
331+
// Test cancel button
332+
var mockModal = {
333+
closeModal: jasmine.createSpy('closeModal')
334+
};
335+
modalConfig.buttons[0].click.call(mockModal, {});
336+
expect(mockModal.closeModal).toHaveBeenCalledWith({});
337+
338+
// Test confirm button
339+
mockModal.closeModal.calls.reset();
340+
modalConfig.buttons[1].click.call(mockModal, {});
341+
expect(mockModal.closeModal).toHaveBeenCalledWith({}, true);
342+
343+
testInjector.clean();
344+
testInjector.remove();
345+
done();
346+
});
347+
});
348+
});
349+
});
350+
});

0 commit comments

Comments
 (0)