- What language is this for?
Typescript
- Which rule?
Deprecated APIs should not be used typescript:S1874
- Why do you believe it’s a false-positive/false-negative?
I’m not using the deprecated document.createElement, but the result shows that it is being used.
- Are you using
SonarQube - Community Edition Version 9.9.1 (build 69595)
- How can we reproduce the problem? Give us a self-contained snippet of code (formatted text, no screenshots)
export class FileDownloadUtils {
/**
* A utility function to download the file.
*
* @param fileName string
* @param data string
*/
public static downloadFile(fileName: string, data: Blob): void {
const downloadLink = document.createElement('a');
document.body.appendChild(downloadLink);
const url = window.URL.createObjectURL(data);
downloadLink.href = url;
downloadLink.download = fileName;
downloadLink.click();
window.URL.revokeObjectURL(url);
}
}
‘a’ tag is one of members of HTMLElementTagNameMap, so I’m not using the deprecated document.createElement.
import { FileDownloadUtils } from './file-download-utils';
describe('FileDownloadUtils', () => {
describe('downloadFile()', () => {
it('should download a file', async () => {
const mockElement = {} as HTMLAnchorElement;
mockElement.click = jest.fn();
jest.spyOn(document, 'createElement').mockImplementation(() => {
return mockElement;
});
jest.spyOn(document.body, 'appendChild').mockImplementation();
// Mock these methods as we cannot spyOn.
const createObjectURL = window.URL.createObjectURL;
const revokeObjectURL = window.URL.revokeObjectURL;
window.URL.createObjectURL = jest.fn(() => {
return 'TestFile.json';
});
window.URL.revokeObjectURL = jest.fn();
// The data to be downloaded.
const data = new Blob(['{Contents: "The Test Json File"}'], {
type: 'application/json'
});
// Download.
FileDownloadUtils.downloadFile('TestFile.json', data);
expect(document.createElement).toHaveBeenCalledTimes(1); // !! HERE SonarQube complains "You're using the deprecated createElement!"
expect(document.body.appendChild).toHaveBeenCalledTimes(1);
expect(window.URL.createObjectURL).toHaveBeenCalledTimes(1);
expect(window.URL.createObjectURL).toHaveBeenCalledWith(data);
expect(mockElement['href']).toBe('TestFile.json');
expect(mockElement['download']).toBe('TestFile.json');
expect(mockElement.click).toHaveBeenCalledTimes(1);
expect(window.URL.revokeObjectURL).toHaveBeenCalledTimes(1);
expect(window.URL.revokeObjectURL).toHaveBeenCalledWith('TestFile.json');
// Reset.
window.URL.createObjectURL = createObjectURL;
window.URL.revokeObjectURL = revokeObjectURL;
});
});
});
From my personal observation, if you use the document.createElement function with no-parenthesis, it seems to unconditionally recognize it as a deprecated createElement.