mirror of
https://github.com/inaturalist/iNaturalistReactNative.git
synced 2025-12-23 22:18:36 -05:00
Add eslint rules for React Query (#319)
* Use eslint rules to clean up useQuery code * Code cleanup for useAuthenticatedMutation * Add realm deletion and clear mock before each test in DeleteObservationDialog
This commit is contained in:
committed by
GitHub
parent
d51685b488
commit
310d2e743d
@@ -7,12 +7,17 @@ module.exports = {
|
||||
presets: ["@babel/preset-react"]
|
||||
}
|
||||
},
|
||||
extends: ["airbnb", "plugin:i18next/recommended"],
|
||||
extends: [
|
||||
"airbnb",
|
||||
"plugin:i18next/recommended",
|
||||
"plugin:@tanstack/eslint-plugin-query/recommended"
|
||||
],
|
||||
plugins: [
|
||||
"module-resolver",
|
||||
"react-hooks",
|
||||
"react-native",
|
||||
"simple-import-sort"
|
||||
"simple-import-sort",
|
||||
"@tanstack/query"
|
||||
],
|
||||
globals: {
|
||||
FormData: true
|
||||
|
||||
17
package-lock.json
generated
17
package-lock.json
generated
@@ -88,6 +88,7 @@
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.12.9",
|
||||
"@babel/runtime": "^7.12.5",
|
||||
"@tanstack/eslint-plugin-query": "^4.20.8",
|
||||
"@testing-library/react-native": "^10.0.0",
|
||||
"babel-jest": "^26.6.3",
|
||||
"babel-plugin-module-resolver": "^4.1.0",
|
||||
@@ -4708,6 +4709,16 @@
|
||||
"@sinonjs/commons": "^1.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tanstack/eslint-plugin-query": {
|
||||
"version": "4.20.8",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/eslint-plugin-query/-/eslint-plugin-query-4.20.8.tgz",
|
||||
"integrity": "sha512-JnAxUAC9DNmL9fwcfY3UjeFjjQwzV7cmPtf/Iac2o/p1Pmavul/L5bjo95zQNsBiBtJddHg+M17ximjpRybWJg==",
|
||||
"dev": true,
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/tannerlinsley"
|
||||
}
|
||||
},
|
||||
"node_modules/@tanstack/query-core": {
|
||||
"version": "4.10.3",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-4.10.3.tgz",
|
||||
@@ -22930,6 +22941,12 @@
|
||||
"@sinonjs/commons": "^1.7.0"
|
||||
}
|
||||
},
|
||||
"@tanstack/eslint-plugin-query": {
|
||||
"version": "4.20.8",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/eslint-plugin-query/-/eslint-plugin-query-4.20.8.tgz",
|
||||
"integrity": "sha512-JnAxUAC9DNmL9fwcfY3UjeFjjQwzV7cmPtf/Iac2o/p1Pmavul/L5bjo95zQNsBiBtJddHg+M17ximjpRybWJg==",
|
||||
"dev": true
|
||||
},
|
||||
"@tanstack/query-core": {
|
||||
"version": "4.10.3",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-4.10.3.tgz",
|
||||
|
||||
@@ -94,6 +94,7 @@
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.12.9",
|
||||
"@babel/runtime": "^7.12.5",
|
||||
"@tanstack/eslint-plugin-query": "^4.20.8",
|
||||
"@testing-library/react-native": "^10.0.0",
|
||||
"babel-jest": "^26.6.3",
|
||||
"babel-plugin-module-resolver": "^4.1.0",
|
||||
|
||||
@@ -19,7 +19,6 @@ const Messages = ( ): Node => {
|
||||
} = useAuthenticatedQuery(
|
||||
["searchMessages"],
|
||||
optsWithAuth => searchMessages( { page: 1 }, optsWithAuth ),
|
||||
{ },
|
||||
{
|
||||
enabled: !!currentUser
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// @flow
|
||||
|
||||
import { View } from "components/styledComponents";
|
||||
import type { Node } from "react";
|
||||
import React from "react";
|
||||
import NetworkLogger from "react-native-network-logger";
|
||||
@@ -10,6 +11,7 @@ import ViewWithFooter from "./SharedComponents/ViewWithFooter";
|
||||
const NetworkLogging = ( ): Node => (
|
||||
<ViewWithFooter>
|
||||
<NetworkLogger />
|
||||
<View className="pb-40" />
|
||||
</ViewWithFooter>
|
||||
);
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@ const ObsList = ( ): Node => {
|
||||
} = useAuthenticatedQuery(
|
||||
["fetchObservationUpdates"],
|
||||
optsWithAuth => fetchObservationUpdates( updateParams, optsWithAuth ),
|
||||
{},
|
||||
{ enabled: !!currentUser }
|
||||
);
|
||||
|
||||
|
||||
@@ -33,7 +33,6 @@ const useInfiniteScroll = ( idBelow: ?number ): boolean => {
|
||||
} = useAuthenticatedQuery(
|
||||
["searchObservations", idBelow],
|
||||
optsWithAuth => searchObservations( params, optsWithAuth ),
|
||||
{},
|
||||
{
|
||||
enabled: !!currentUser
|
||||
}
|
||||
|
||||
@@ -6,19 +6,20 @@ import { getJWTToken } from "components/LoginSignUp/AuthenticationService";
|
||||
// Should work like React Query's useMutation except it calls the queryFunction
|
||||
// with an object that includes the JWT
|
||||
const useAuthenticatedMutation = (
|
||||
queryFunction: Function,
|
||||
mutationOptions: Object,
|
||||
queryOptions: Object = {}
|
||||
): any => useMutation( async id => {
|
||||
mutationFunction: Function,
|
||||
mutationOptions: Object = {}
|
||||
): any => useMutation( {
|
||||
mutationFn: async id => {
|
||||
// Note, getJWTToken() takes care of fetching a new token if the existing
|
||||
// one is expired. We *could* store the token in state with useState if
|
||||
// fetching from RNSInfo becomes a performance issue
|
||||
const apiToken = await getJWTToken( );
|
||||
const options = {
|
||||
...queryOptions,
|
||||
api_token: apiToken
|
||||
};
|
||||
return queryFunction( id, options );
|
||||
}, mutationOptions );
|
||||
const apiToken = await getJWTToken( );
|
||||
const options = {
|
||||
api_token: apiToken
|
||||
};
|
||||
return mutationFunction( id, options );
|
||||
},
|
||||
...mutationOptions
|
||||
} );
|
||||
|
||||
export default useAuthenticatedMutation;
|
||||
|
||||
@@ -8,18 +8,20 @@ import { getJWTToken } from "components/LoginSignUp/AuthenticationService";
|
||||
const useAuthenticatedQuery = (
|
||||
queryKey: Array<mixed>,
|
||||
queryFunction: Function,
|
||||
queryOptions: Object = {},
|
||||
useQueryOptions: Object = {}
|
||||
): any => useQuery( [queryKey], async ( ) => {
|
||||
// Note, getJWTToken() takes care of fetching a new token if the existing
|
||||
// one is expired. We *could* store the token in state with useState if
|
||||
// fetching from RNSInfo becomes a performance issue
|
||||
const apiToken = await getJWTToken( );
|
||||
const options = {
|
||||
...queryOptions,
|
||||
api_token: apiToken
|
||||
};
|
||||
return queryFunction( options );
|
||||
}, useQueryOptions );
|
||||
queryOptions: Object = {}
|
||||
): any => useQuery( {
|
||||
queryKey,
|
||||
queryFn: async ( ) => {
|
||||
// Note, getJWTToken() takes care of fetching a new token if the existing
|
||||
// one is expired. We *could* store the token in state with useState if
|
||||
// fetching from RNSInfo becomes a performance issue
|
||||
const apiToken = await getJWTToken( );
|
||||
const options = {
|
||||
api_token: apiToken
|
||||
};
|
||||
return queryFunction( options );
|
||||
},
|
||||
...queryOptions
|
||||
} );
|
||||
|
||||
export default useAuthenticatedQuery;
|
||||
|
||||
@@ -13,7 +13,6 @@ const useUserMe = ( ): Object => {
|
||||
} = useAuthenticatedQuery(
|
||||
["fetchUserMe"],
|
||||
optsWithAuth => fetchUserMe( { }, optsWithAuth ),
|
||||
{},
|
||||
{
|
||||
enabled: !!currentUser
|
||||
}
|
||||
|
||||
@@ -10,6 +10,16 @@ import { renderComponent } from "../../../helpers/render";
|
||||
|
||||
jest.useFakeTimers( );
|
||||
|
||||
beforeEach( async ( ) => {
|
||||
global.realm.write( ( ) => {
|
||||
global.realm.deleteAll( );
|
||||
} );
|
||||
} );
|
||||
|
||||
afterEach( ( ) => {
|
||||
jest.clearAllMocks( );
|
||||
} );
|
||||
|
||||
jest.mock( "providers/ObsEditProvider" );
|
||||
|
||||
jest.mock( "@react-navigation/native", ( ) => {
|
||||
|
||||
Reference in New Issue
Block a user