Skip to content

Commit

Permalink
[test] Image: test headers related functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
kidroca committed Feb 3, 2023
1 parent bedf028 commit 8533f2d
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -329,14 +329,14 @@ exports[`components/Image prop "style" removes other unsupported View styles 1`]
>
<div
class="css-view-175oi2r r-backgroundColor-1niwhzg r-backgroundPosition-vvn4in r-backgroundRepeat-u6sd8q r-bottom-1p0dtai r-height-1pi2tsx r-left-1d2f490 r-position-u8s1d r-right-zchlnj r-top-ipm5af r-width-13qz1uu r-zIndex-1wyyakw r-backgroundSize-4gszlv"
style="filter: url(#tint-57);"
style="filter: url(#tint-72);"
/>
<svg
style="position: absolute; height: 0px; visibility: hidden; width: 0px;"
>
<defs>
<filter
id="tint-57"
id="tint-72"
>
<feflood
flood-color="blue"
Expand Down Expand Up @@ -378,7 +378,7 @@ exports[`components/Image prop "style" supports "tintcolor" property (convert to
>
<div
class="css-view-175oi2r r-backgroundColor-1niwhzg r-backgroundPosition-vvn4in r-backgroundRepeat-u6sd8q r-bottom-1p0dtai r-height-1pi2tsx r-left-1d2f490 r-position-u8s1d r-right-zchlnj r-top-ipm5af r-width-13qz1uu r-zIndex-1wyyakw r-backgroundSize-4gszlv"
style="background-image: url(https://google.com/favicon.ico); filter: url(#tint-56);"
style="background-image: url(https://google.com/favicon.ico); filter: url(#tint-71);"
/>
<img
alt=""
Expand All @@ -391,7 +391,7 @@ exports[`components/Image prop "style" supports "tintcolor" property (convert to
>
<defs>
<filter
id="tint-56"
id="tint-71"
>
<feflood
flood-color="red"
Expand Down
103 changes: 86 additions & 17 deletions packages/react-native-web/src/exports/Image/__tests__/index-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,24 @@ import Image from '../';
import ImageLoader, { ImageUriCache } from '../../../modules/ImageLoader';
import PixelRatio from '../../PixelRatio';
import React from 'react';
import { render } from '@testing-library/react';
import { render, waitFor } from '@testing-library/react';

const originalImage = window.Image;

describe('components/Image', () => {
beforeEach(() => {
ImageUriCache._entries = {};
window.Image = jest.fn(() => ({}));
ImageLoader.load = jest
.fn()
.mockImplementation((source, onLoad, onError) => {
act(() => onLoad({ source }));
});
ImageLoader.loadWithHeaders = jest.fn().mockImplementation((source) => ({
source,
promise: Promise.resolve(`blob:${Math.random()}`),
cancel: jest.fn()
}));
});

afterEach(() => {
Expand Down Expand Up @@ -106,10 +116,6 @@ describe('components/Image', () => {

describe('prop "onLoad"', () => {
test('is called after image is loaded from network', () => {
jest.useFakeTimers();
ImageLoader.load = jest.fn().mockImplementation((_, onLoad, onError) => {
onLoad();
});
const onLoadStartStub = jest.fn();
const onLoadStub = jest.fn();
const onLoadEndStub = jest.fn();
Expand All @@ -121,15 +127,10 @@ describe('components/Image', () => {
source="https://test.com/img.jpg"
/>
);
jest.runOnlyPendingTimers();
expect(onLoadStub).toBeCalled();
});

test('is called after image is loaded from cache', () => {
jest.useFakeTimers();
ImageLoader.load = jest.fn().mockImplementation((_, onLoad, onError) => {
onLoad();
});
const onLoadStartStub = jest.fn();
const onLoadStub = jest.fn();
const onLoadEndStub = jest.fn();
Expand All @@ -143,7 +144,6 @@ describe('components/Image', () => {
source={uri}
/>
);
jest.runOnlyPendingTimers();
expect(onLoadStub).toBeCalled();
ImageUriCache.remove(uri);
});
Expand Down Expand Up @@ -227,6 +227,34 @@ describe('components/Image', () => {
});
});

describe('prop "onLoadStart"', () => {
test('is called on update if "headers" are modified', () => {
const onLoadStartStub = jest.fn();
const { rerender } = render(
<Image
onLoadStart={onLoadStartStub}
source={{
uri: 'https://test.com/img.jpg',
headers: { 'x-custom-header': 'abc123' }
}}
/>
);
act(() => {
rerender(
<Image
onLoadStart={onLoadStartStub}
source={{
uri: 'https://test.com/img.jpg',
headers: { 'x-custom-header': '123abc' }
}}
/>
);
});

expect(onLoadStartStub.mock.calls.length).toBe(2);
});
});

describe('prop "resizeMode"', () => {
['contain', 'cover', 'none', 'repeat', 'stretch', undefined].forEach(
(resizeMode) => {
Expand All @@ -245,7 +273,8 @@ describe('components/Image', () => {
'',
{},
{ uri: '' },
{ uri: 'https://google.com' }
{ uri: 'https://google.com' },
{ uri: 'https://google.com', headers: { 'x-custom-header': 'abc123' } }
];
sources.forEach((source) => {
expect(() => render(<Image source={source} />)).not.toThrow();
Expand All @@ -261,11 +290,6 @@ describe('components/Image', () => {

test('is set immediately if the image was preloaded', () => {
const uri = 'https://yahoo.com/favicon.ico';
ImageLoader.load = jest
.fn()
.mockImplementationOnce((_, onLoad, onError) => {
onLoad();
});
return Image.prefetch(uri).then(() => {
const source = { uri };
const { container } = render(<Image source={source} />, {
Expand Down Expand Up @@ -346,6 +370,51 @@ describe('components/Image', () => {
'http://localhost/static/[email protected]'
);
});

test('it works with headers in 2 stages', async () => {
const uri = 'https://google.com/favicon.ico';
const headers = { 'x-custom-header': 'abc123' };
const source = { uri, headers };

// Stage 1
const loadRequest = {
promise: Promise.resolve('blob:123'),
cancel: jest.fn(),
source
};

ImageLoader.loadWithHeaders.mockReturnValue(loadRequest);

render(<Image source={source} />);

expect(ImageLoader.loadWithHeaders).toHaveBeenCalledWith(
expect.objectContaining(source)
);

// Stage 2
return waitFor(() => {
expect(ImageLoader.load).toHaveBeenCalledWith(
'blob:123',
expect.any(Function),
expect.any(Function)
);
});
});

// A common case is `source` declared as an inline object, which cause is to be a
// new object (with the same content) each time parent component renders
test('it still loads the image if source object is changed', () => {
const uri = 'https://google.com/favicon.ico';
const headers = { 'x-custom-header': 'abc123' };
const { rerender } = render(<Image source={{ uri, headers }} />);
rerender(<Image source={{ uri, headers }} />);

// when the underlying source didn't change we don't expect more than 1 load calls
return waitFor(() => {
expect(ImageLoader.loadWithHeaders).toHaveBeenCalledTimes(1);
expect(ImageLoader.load).toHaveBeenCalledTimes(1);
});
});
});

describe('prop "style"', () => {
Expand Down

0 comments on commit 8533f2d

Please sign in to comment.