Skip to content

Commit

Permalink
Apply QueryRenderer tests from master
Browse files Browse the repository at this point in the history
  • Loading branch information
Juan Tejada committed Oct 30, 2018
1 parent 25e5b11 commit a723d6e
Showing 1 changed file with 291 additions and 41 deletions.
332 changes: 291 additions & 41 deletions packages/react-relay/modern/__tests__/ReactRelayQueryRenderer-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,53 +113,230 @@ describe('ReactRelayQueryRenderer', () => {
});

describe('when constructor fires multiple times', () => {
it('fetches the query only once', () => {
const fetch = jest.fn().mockReturnValue(response);
store = new Store(new RecordSource());
environment = new Environment({
network: Network.create(fetch),
store,
});

function Child(props) {
// NOTE the unstable_yield method will move to the static renderer.
// When React sync runs we need to update this.
renderer.unstable_yield(props.children);
return props.children;
}
describe('when store does not have snapshot and fetch does not return snapshot', () => {
it('fetches the query only once, renders loading state', () => {
environment.mockClear();
function Child(props) {
// NOTE the unstable_yield method will move to the static renderer.
// When React sync runs we need to update this.
renderer.unstable_yield(props.children);
return props.children;
}

class Example extends React.Component {
render() {
return (
<React.Fragment>
<Child>A</Child>
<ReactRelayQueryRenderer
query={TestQuery}
cacheConfig={cacheConfig}
environment={environment}
render={render}
variables={variables}
/>
<Child>B</Child>
<Child>C</Child>
</React.Fragment>
);
class Example extends React.Component {
render() {
return (
<React.Fragment>
<Child>A</Child>
<ReactRelayQueryRenderer
query={TestQuery}
cacheConfig={cacheConfig}
environment={environment}
render={render}
variables={variables}
/>
<Child>B</Child>
<Child>C</Child>
</React.Fragment>
);
}
}
}
const renderer = ReactTestRenderer.create(<Example />, {
unstable_isAsync: true,
const renderer = ReactTestRenderer.create(<Example />, {
unstable_isAsync: true,
});

// Flush some of the changes, but don't commit
expect(renderer.unstable_flushThrough(['A', 'B'])).toEqual([
'A',
'B',
]);
expect(renderer.toJSON()).toEqual(null);
expect({
error: null,
props: null,
retry: null,
}).toBeRendered();
expect(environment.execute.mock.calls.length).toBe(1);
render.mockClear();

// Interrupt with higher priority updates
renderer.unstable_flushSync(() => {
renderer.update(<Example />);
});
expect(environment.execute.mock.calls.length).toBe(1);
expect({
error: null,
props: null,
retry: null,
}).toBeRendered();
});
});
describe('when store has a snapshot', () => {
it('fetches the query only once, renders snapshot from store', () => {
environment.mockClear();
environment.applyUpdate({
storeUpdater: _store => {
let root = _store.get(ROOT_ID);
if (!root) {
root = _store.create(ROOT_ID, ROOT_TYPE);
}
const user = _store.create('4', 'User');
user.setValue('4', 'id');
user.setValue('Zuck', 'name');
root.setLinkedRecord(user, 'node', {id: '4'});
},
});

// Flush some of the changes, but don't commit
expect(renderer.unstable_flushThrough(['A', 'B'])).toEqual(['A', 'B']);
expect(renderer.toJSON()).toEqual(null);
function Child(props) {
// NOTE the unstable_yield method will move to the static renderer.
// When React sync runs we need to update this.
renderer.unstable_yield(props.children);
return props.children;
}

// Interrupt with higher priority updates
renderer.unstable_flushSync(() => {
renderer.update(<Example />);
class Example extends React.Component {
render() {
return (
<React.Fragment>
<Child>A</Child>
<ReactRelayQueryRenderer
query={TestQuery}
dataFrom="STORE_THEN_NETWORK"
environment={environment}
render={render}
variables={variables}
/>
<Child>B</Child>
<Child>C</Child>
</React.Fragment>
);
}
}
const renderer = ReactTestRenderer.create(<Example />, {
unstable_isAsync: true,
});

// Flush some of the changes, but don't commit
expect(renderer.unstable_flushThrough(['A', 'B'])).toEqual([
'A',
'B',
]);
expect(renderer.toJSON()).toEqual(null);
expect({
error: null,
props: {
node: {
id: '4',
__fragments: {
TestFragment: {},
},
__id: '4',
},
},
retry: jasmine.any(Function),
}).toBeRendered();
expect(environment.execute.mock.calls.length).toBe(1);
render.mockClear();

// Interrupt with higher priority updates
renderer.unstable_flushSync(() => {
renderer.update(<Example />);
});
expect(environment.execute.mock.calls.length).toBe(1);
expect({
error: null,
props: {
node: {
id: '4',
__fragments: {
TestFragment: {},
},
__id: '4',
},
},
retry: jasmine.any(Function),
}).toBeRendered();
});
});
describe('when fetch returns a response synchronously first time', () => {
it('fetches the query once, always renders snapshot returned by fetch', () => {
const fetch = jest.fn().mockReturnValueOnce(response);
store = new Store(new RecordSource());
environment = new Environment({
network: Network.create(fetch),
store,
});

function Child(props) {
// NOTE the unstable_yield method will move to the static renderer.
// When React sync runs we need to update this.
renderer.unstable_yield(props.children);
return props.children;
}

expect(fetch.mock.calls.length).toBe(1);
class Example extends React.Component {
render() {
return (
<React.Fragment>
<Child>A</Child>
<ReactRelayQueryRenderer
query={TestQuery}
dataFrom="STORE_THEN_NETWORK"
environment={environment}
render={render}
variables={variables}
/>
<Child>B</Child>
<Child>C</Child>
</React.Fragment>
);
}
}
const renderer = ReactTestRenderer.create(<Example />, {
unstable_isAsync: true,
});

// Flush some of the changes, but don't commit
expect(renderer.unstable_flushThrough(['A', 'B'])).toEqual([
'A',
'B',
]);
expect(renderer.toJSON()).toEqual(null);
expect({
error: null,
props: {
node: {
id: '4',
__fragments: {
TestFragment: {},
},
__id: '4',
},
},
retry: jasmine.any(Function),
}).toBeRendered();
expect(fetch.mock.calls.length).toBe(1);
render.mockClear();

// Interrupt with higher priority updates
renderer.unstable_flushSync(() => {
renderer.update(<Example />);
});
expect(fetch.mock.calls.length).toBe(1);
expect({
error: null,
props: {
node: {
id: '4',
__fragments: {
TestFragment: {},
},
__id: '4',
},
},
retry: jasmine.any(Function),
}).toBeRendered();
});
});
});

Expand Down Expand Up @@ -752,6 +929,80 @@ describe('ReactRelayQueryRenderer', () => {
});
});

describe('with two identical query fetchers', () => {
// Regression test for T32896427
describe('when the fetch succeeds', () => {
it('renders the query results', () => {
const mockA = jest.fn().mockReturnValue('A');
const mockB = jest.fn().mockReturnValue('B');
class Example extends React.Component {
render() {
return (
<React.Fragment>
<ReactRelayQueryRenderer
query={TestQuery}
cacheConfig={cacheConfig}
environment={environment}
render={mockA}
variables={variables}
/>
<ReactRelayQueryRenderer
query={TestQuery}
cacheConfig={cacheConfig}
environment={environment}
render={mockB}
variables={variables}
/>
</React.Fragment>
);
}
}
const renderer = ReactTestRenderer.create(<Example />);
expect.assertions(3);
mockA.mockClear();
mockB.mockClear();
environment.mock.resolve(TestQuery, response);
const mockACalls = mockA.mock.calls;
const mockBCalls = mockB.mock.calls;
expect(mockACalls).toEqual([
[
{
error: null,
props: {
node: {
id: '4',
__fragments: {
TestFragment: {},
},
__id: '4',
},
},
retry: jasmine.any(Function),
},
],
]);
expect(mockBCalls).toEqual([
[
{
error: null,
props: {
node: {
id: '4',
__fragments: {
TestFragment: {},
},
__id: '4',
},
},
retry: jasmine.any(Function),
},
],
]);
expect(renderer.toJSON()).toEqual(['A', 'B']);
});
});
});

describe('when the fetch succeeds', () => {
beforeEach(() => {
ReactTestRenderer.create(
Expand Down Expand Up @@ -810,7 +1061,6 @@ describe('ReactRelayQueryRenderer', () => {
);
});
});

describe('when props change during a fetch', () => {
let NextQuery;
let renderer;
Expand Down

0 comments on commit a723d6e

Please sign in to comment.