fix coverage for image utils

This commit is contained in:
SeinopSys 2022-04-03 03:01:15 +02:00 committed by Luna D
parent dc2037ee75
commit 8ca4a99a1c
No known key found for this signature in database
GPG key ID: 4B1C63448394F688
2 changed files with 94 additions and 35 deletions

View file

@ -54,6 +54,22 @@ describe('Image utils', () => {
mockSpoilerOverlay,
};
};
const imageFilteredClass = 'image-filtered';
const imageShowClass = 'image-show';
const spoilerPendingClass = 'spoiler-pending';
const createImageFilteredElement = (mockElement: HTMLDivElement) => {
const mockFilteredImageElement = document.createElement('div');
mockFilteredImageElement.classList.add(imageFilteredClass);
mockElement.appendChild(mockFilteredImageElement);
return { mockFilteredImageElement };
};
const createImageShowElement = (mockElement: HTMLDivElement) => {
const mockShowElement = document.createElement('div');
mockShowElement.classList.add(imageShowClass);
mockShowElement.classList.add(hiddenClass);
mockElement.appendChild(mockShowElement);
return { mockShowElement };
};
describe('showThumb', () => {
let mockServeHidpiValue: string | null = null;
@ -146,6 +162,26 @@ describe('Image utils', () => {
expect(result).toBe(true);
});
['data-size', 'data-uris'].forEach(missingAttributeName => {
it(`should return early if the ${missingAttributeName} attribute is missing`, () => {
const { mockElement } = createMockElements({
extension: 'webm',
});
const jsonParseSpy = jest.spyOn(JSON, 'parse');
mockElement.removeAttribute(missingAttributeName);
try {
const result = showThumb(mockElement);
expect(result).toBe(false);
expect(jsonParseSpy).not.toHaveBeenCalled();
}
finally {
jsonParseSpy.mockRestore();
}
});
});
it('should return early if there is no video element', () => {
const { mockElement, mockVideo, playSpy } = createMockElements({
extension: 'webm',
@ -304,24 +340,21 @@ describe('Image utils', () => {
const result = showThumb(mockElement);
expect(result).toBe(false);
});
it('should return false if overlay is missing', () => {
const { mockElement, mockSpoilerOverlay } = createMockElementWithPicture('jpg');
mockSpoilerOverlay.parentNode?.removeChild(mockSpoilerOverlay);
const result = showThumb(mockElement);
expect(result).toBe(false);
});
});
describe('showBlock', () => {
const imageFilteredClass = 'image-filtered';
const imageShowClass = 'image-show';
const spoilerPendingClass = 'spoiler-pending';
it('should hide the filtered image element and show the image', () => {
const mockElement = document.createElement('div');
const mockFilteredImageElement = document.createElement('div');
mockFilteredImageElement.classList.add(imageFilteredClass);
mockElement.appendChild(mockFilteredImageElement);
const mockShowElement = document.createElement('div');
mockShowElement.classList.add(imageShowClass);
mockShowElement.classList.add(hiddenClass);
mockElement.appendChild(mockShowElement);
const { mockFilteredImageElement } = createImageFilteredElement(mockElement);
const { mockShowElement } = createImageShowElement(mockElement);
showBlock(mockElement);
@ -329,6 +362,18 @@ describe('Image utils', () => {
expect(mockShowElement).not.toHaveClass(hiddenClass);
expect(mockShowElement).toHaveClass(spoilerPendingClass);
});
it('should not throw if image-filtered element is missing', () => {
const mockElement = document.createElement('div');
createImageShowElement(mockElement);
expect(() => showBlock(mockElement)).not.toThrow();
});
it('should not throw if image-show element is missing', () => {
const mockElement = document.createElement('div');
createImageFilteredElement(mockElement);
expect(() => showBlock(mockElement)).not.toThrow();
});
});
describe('hideThumb', () => {
@ -528,9 +573,7 @@ describe('Image utils', () => {
});
describe('spoilerBlock', () => {
const imageFilteredClass = 'image-filtered';
const filterExplanationClass = 'filter-explanation';
const imageShowClass = 'image-show';
const createFilteredImageElement = () => {
const mockImageFiltered = document.createElement('div');
mockImageFiltered.classList.add(imageFilteredClass, hiddenClass);
@ -541,22 +584,31 @@ describe('Image utils', () => {
return { mockImageFiltered, mockImage };
};
it('should do nothing if image element is missing', () => {
const createMockElement = (appendImageShow = true, appendImageFiltered = true) => {
const mockElement = document.createElement('div');
const { mockImageFiltered, mockImage } = createFilteredImageElement();
if (appendImageFiltered) mockElement.appendChild(mockImageFiltered);
const mockExplanation = document.createElement('span');
mockExplanation.classList.add(filterExplanationClass);
mockElement.appendChild(mockExplanation);
const mockImageShow = document.createElement('div');
mockImageShow.classList.add(imageShowClass);
if (appendImageShow) mockElement.appendChild(mockImageShow);
return { mockElement, mockImage, mockExplanation, mockImageShow, mockImageFiltered };
};
it('should not throw if image element is missing', () => {
const mockElement = document.createElement('div');
const { mockImageFiltered, mockImage } = createFilteredImageElement();
mockImage.parentNode?.removeChild(mockImage);
mockElement.appendChild(mockImageFiltered);
expect(() => spoilerBlock(mockElement, mockSpoilerUri, mockSpoilerReason)).not.toThrow();
});
it('should update the elements with the parameters and set classes if image element is found', () => {
const mockElement = document.createElement('div');
const { mockImageFiltered, mockImage } = createFilteredImageElement();
mockElement.appendChild(mockImageFiltered);
const mockExplanation = document.createElement('span');
mockExplanation.classList.add(filterExplanationClass);
mockElement.appendChild(mockExplanation);
const mockImageShow = document.createElement('div');
mockImageShow.classList.add(imageShowClass);
mockElement.appendChild(mockImageShow);
const { mockElement, mockImage, mockExplanation, mockImageShow, mockImageFiltered } = createMockElement();
spoilerBlock(mockElement, mockSpoilerUri, mockSpoilerReason);
@ -565,5 +617,15 @@ describe('Image utils', () => {
expect(mockImageShow).toHaveClass(hiddenClass);
expect(mockImageFiltered).not.toHaveClass(hiddenClass);
});
it('should not throw if image-filtered element is missing', () => {
const { mockElement } = createMockElement(true, false);
expect(() => spoilerBlock(mockElement, mockSpoilerUri, mockSpoilerReason)).not.toThrow();
});
it('should not throw if image-show element is missing', () => {
const { mockElement } = createMockElement(false, true);
expect(() => spoilerBlock(mockElement, mockSpoilerUri, mockSpoilerReason)).not.toThrow();
});
});
});

View file

@ -1,11 +1,7 @@
import { clearEl } from './dom';
import store from './store';
function showVideoThumb(img: HTMLDivElement) {
const size = img.dataset.size;
const urisString = img.dataset.uris;
if (!size || !urisString) return;
function showVideoThumb(img: HTMLDivElement, size: string, urisString: string) {
const uris = JSON.parse(urisString);
const thumbUri = uris[size];
@ -33,13 +29,13 @@ function showVideoThumb(img: HTMLDivElement) {
export function showThumb(img: HTMLDivElement) {
const size = img.dataset.size;
const urisString = img.dataset.uris;
if (!size || !urisString) return;
if (!size || !urisString) return false;
const uris = JSON.parse(urisString);
const thumbUri = uris[size].replace(/webm$/, 'gif');
const picEl = img.querySelector('picture');
if (!picEl) return showVideoThumb(img);
if (!picEl) return showVideoThumb(img, size, urisString);
const imgEl = picEl.querySelector('img');
if (!imgEl || imgEl.src.indexOf(thumbUri) !== -1) return false;
@ -53,7 +49,7 @@ export function showThumb(img: HTMLDivElement) {
imgEl.src = thumbUri;
const overlay = img.querySelector('.js-spoiler-info-overlay');
if (!overlay) return;
if (!overlay) return false;
if (uris[size].indexOf('.webm') !== -1) {
overlay.classList.remove('hidden');
@ -130,7 +126,8 @@ export function spoilerThumb(img: HTMLDivElement, spoilerUri: string, reason: st
}
export function spoilerBlock(img: HTMLDivElement, spoilerUri: string, reason: string) {
const imgEl = img.querySelector<HTMLImageElement>('.image-filtered img');
const imgFiltered = img.querySelector('.image-filtered');
const imgEl = imgFiltered?.querySelector<HTMLImageElement>('img');
const imgReason = img.querySelector<HTMLElement>('.filter-explanation');
if (!imgEl) return;
@ -141,5 +138,5 @@ export function spoilerBlock(img: HTMLDivElement, spoilerUri: string, reason: st
}
img.querySelector('.image-show')?.classList.add('hidden');
img.querySelector('.image-filtered')?.classList.remove('hidden');
if (imgFiltered) imgFiltered.classList.remove('hidden');
}