Skip to content

Commit

Permalink
Merge pull request #145 from meteorrn/feature/optional-netinfo
Browse files Browse the repository at this point in the history
feature: make NetInfo injectable/truly optional
  • Loading branch information
jankapunkt committed Jan 23, 2024
2 parents 3e2d91f + 63671a1 commit 7be893a
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 20 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@meteorrn/core",
"version": "2.7.1",
"version": "2.8.0-rc.0",
"description": "Full Meteor Client for React Native",
"main": "src/index.js",
"repository": {
Expand Down
45 changes: 28 additions & 17 deletions src/Meteor.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,29 +109,37 @@ const Meteor = {
...options,
});

try {
const NetInfo = require('@react-native-community/netinfo').default;

if (options.reachabilityUrl) {
NetInfo.configure({
reachabilityUrl: options.reachabilityUrl,
useNativeReachability: true,
});
}
if (options.NetInfo !== null) {
try {
const NetInfo = getNetInfo(options.NetInfo);

if (options.reachabilityUrl) {
NetInfo.configure({
reachabilityUrl: options.reachabilityUrl,
useNativeReachability: true,
});
}

// Reconnect if we lose internet
// Reconnect if we lose internet

NetInfo.addEventListener(
({ type, isConnected, isInternetReachable, isWifiEnabled }) => {
if (isConnected && Data.ddp.autoReconnect) {
Data.ddp.connect();
NetInfo.addEventListener(
({ type, isConnected, isInternetReachable, isWifiEnabled }) => {
if (isConnected && Data.ddp.autoReconnect) {
Data.ddp.connect();
}
}
}
);
} catch (e) {
);
} catch (e) {
console.warn(
'Warning: NetInfo not installed, so DDP will not automatically reconnect'
);
Data.ddp.connect();
}
} else {
console.warn(
'Warning: NetInfo not installed, so DDP will not automatically reconnect'
);
Data.ddp.connect();
}

Data.ddp.on('connected', () => {
Expand Down Expand Up @@ -426,4 +434,7 @@ const Meteor = {
},
};

const getNetInfo = (NetInfo) =>
NetInfo ? NetInfo : require('@react-native-community/netinfo').default;

export default Meteor;
50 changes: 50 additions & 0 deletions test/src/Meteor.tests.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { expect } from 'chai';
import Meteor from '../../src/Meteor';
import { awaitDisconnected, stub, restoreAll } from '../testHelpers';
import DDP from '../../lib/ddp';

describe('Meteor - integration', function () {
it('uses the default async storage if none is defined', function () {
Expand All @@ -8,4 +10,52 @@ describe('Meteor - integration', function () {
const { AsyncStorage } = Meteor.packageInterface();
expect(AsyncStorage).to.equal(fallback);
});

describe(Meteor.connect.name, () => {
before(awaitDisconnected);
afterEach(() => {
restoreAll();
});
it('allows to bypass NetInfo', (done) => {
stub(DDP.prototype, 'on', () => {});
stub(DDP.prototype, 'connect', done);

const AsyncStorage = {
getItem: async () => {},
setItem: async () => {},
removeItem: async () => {},
};

const endpoint = `ws://localhost:3000/websocket`;
Meteor.connect(endpoint, {
AsyncStorage,
NetInfo: null,
autoConnect: false,
});
});
it('allows to pass a custom configured NetInfo', (done) => {
stub(DDP.prototype, 'on', () => {});
stub(DDP.prototype, 'connect', done);

const AsyncStorage = {
getItem: async () => {},
setItem: async () => {},
removeItem: async () => {},
};

const NetInfo = {
addEventListener: (cb) => {
setTimeout(() => cb({ isConnected: true }), 300);
},
};

const endpoint = `ws://localhost:3000/websocket`;
Meteor.connect(endpoint, {
AsyncStorage,
NetInfo,
autoConnect: false,
autoReconnect: true,
});
});
});
});
49 changes: 49 additions & 0 deletions test/testHelpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import sinon from 'sinon';
import Meteor from '../src/Meteor';

export const stubs = new Map();

export const stub = (target, name, handler) => {
if (stubs.get(target)) {
throw new Error(`already stubbed: ${name}`);
}
const stubbedTarget = sinon.stub(target, name);
if (typeof handler === 'function') {
stubbedTarget.callsFake(handler);
} else {
stubbedTarget.value(handler);
}
stubs.set(stubbedTarget, name);
};

export const restore = (target, name) => {
if (!target[name] || !target[name].restore) {
throw new Error(`not stubbed: ${name}`);
}
target[name].restore();
stubs.delete(target);
};

export const overrideStub = (target, name, handler) => {
restore(target, name);
stub(target, name, handler);
};

export const restoreAll = () => {
stubs.forEach((name, target) => {
stubs.delete(target);
target.restore();
});
};

export const awaitDisconnected = async () => {
Meteor.disconnect();
await new Promise((resolve) => {
let timer = setInterval(() => {
if (Meteor.status().status === 'disconnected') {
clearInterval(timer);
resolve();
}
}, 100);
});
};

0 comments on commit 7be893a

Please sign in to comment.