diff --git a/CHANGELOG.md b/CHANGELOG.md
index a407930..133b3dc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -14,6 +14,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- Update Docker Compose configuration file to V2
+- [#44](https://github.com/green-code-initiative/ecoCode-javascript/pull/44) Implement the rule EC523 for React Native
+
+### Deleted
+
+- [#44](https://github.com/green-code-initiative/ecoCode-javascript/pull/44) Merge the rule EC8 with EC523
## [1.5.0] - 2024-03-13
diff --git a/eslint-plugin/docs/rules/avoid-high-accuracy-geolocation.md b/eslint-plugin/docs/rules/avoid-high-accuracy-geolocation.md
index fea7b49..49e4072 100644
--- a/eslint-plugin/docs/rules/avoid-high-accuracy-geolocation.md
+++ b/eslint-plugin/docs/rules/avoid-high-accuracy-geolocation.md
@@ -15,6 +15,7 @@ usage.
If the application or service does not critically require pinpoint accuracy, opting for a less accurate geolocation can
help minimize the strain on the device's CPU.
+## Web
```js
var options = { enableHighAccuracy: true, timeout: 5000, maximumAge: 0 }; // Non-compliant
navigator.geolocation.getCurrentPosition(
@@ -40,6 +41,21 @@ navigator.geolocation.getCurrentPosition(
);
```
+## React Native
+In this example, we ask the user to turn on high accuracy location mode which enables network provider that uses Google Play services to improve location accuracy and location-based services:
+```js
+import * as Location from 'expo-location';
+
+Location.enableNetworkProviderAsync(); // Non-compliant
+```
+
+Prefer to ask the user to turn on lower-accuracy geolocation to conserve resources:
+```js
+import * as Location from 'expo-location';
+
+Location.requestPermissionsAsync(); // Compliant
+```
+
## Resources
### Documentation
diff --git a/eslint-plugin/lib/rules/avoid-high-accuracy-geolocation.js b/eslint-plugin/lib/rules/avoid-high-accuracy-geolocation.js
index 3f70b2d..341fe59 100644
--- a/eslint-plugin/lib/rules/avoid-high-accuracy-geolocation.js
+++ b/eslint-plugin/lib/rules/avoid-high-accuracy-geolocation.js
@@ -18,6 +18,10 @@
"use strict";
+const geolocationLibrariesMethods = {
+ "expo-location": ["enableNetworkProviderAsync"],
+};
+
/** @type {import("eslint").Rule.RuleModule} */
module.exports = {
meta: {
@@ -33,15 +37,41 @@ module.exports = {
schema: [],
},
create: function (context) {
+ const librariesFoundInImports = [];
+
return {
+ ImportDeclaration(node) {
+ const currentLibrary = node.source.value;
+
+ if (geolocationLibrariesMethods[currentLibrary]) {
+ librariesFoundInImports.push(currentLibrary);
+ }
+ },
+ MemberExpression(node) {
+ if (librariesFoundInImports.length === 0) {
+ return;
+ }
+
+ if (
+ librariesFoundInImports.some((library) =>
+ geolocationLibrariesMethods[library].includes(node.property.name),
+ )
+ ) {
+ reportAvoidUsingAccurateGeolocation(context, node);
+ }
+ },
Property(node) {
if (
node?.key.name === "enableHighAccuracy" &&
node?.value.value === true
) {
- context.report({ node, messageId: "AvoidUsingAccurateGeolocation" });
+ reportAvoidUsingAccurateGeolocation(context, node);
}
},
};
},
};
+
+function reportAvoidUsingAccurateGeolocation(context, node) {
+ context.report({ node, messageId: "AvoidUsingAccurateGeolocation" });
+}
diff --git a/eslint-plugin/tests/lib/rules/avoid-high-accuracy-geolocation.js b/eslint-plugin/tests/lib/rules/avoid-high-accuracy-geolocation.js
index 09e0077..a08b154 100644
--- a/eslint-plugin/tests/lib/rules/avoid-high-accuracy-geolocation.js
+++ b/eslint-plugin/tests/lib/rules/avoid-high-accuracy-geolocation.js
@@ -29,11 +29,20 @@ const RuleTester = require("eslint").RuleTester;
// Tests
//------------------------------------------------------------------------------
-const ruleTester = new RuleTester();
-const expectedError = {
+const ruleTester = new RuleTester({
+ parserOptions: {
+ ecmaVersion: 6,
+ sourceType: "module",
+ },
+});
+const expectedErrorOnProperty = {
messageId: "AvoidUsingAccurateGeolocation",
type: "Property",
};
+const expectedErrorOnMemberExpression = {
+ messageId: "AvoidUsingAccurateGeolocation",
+ type: "MemberExpression",
+};
ruleTester.run("avoid-high-accuracy-geolocation", rule, {
valid: [
@@ -60,6 +69,15 @@ ruleTester.run("avoid-high-accuracy-geolocation", rule, {
`
navigator.geolocation.getCurrentPosition(success, error, {enableHighAccuracy: false});
`,
+
+ `
+ import axios from 'axios';
+ `,
+ `
+ import * as Location from 'expo-location';
+
+ Location.requestPermissionsAsync();
+ `,
],
invalid: [
@@ -77,13 +95,21 @@ ruleTester.run("avoid-high-accuracy-geolocation", rule, {
navigator.geolocation.getCurrentPosition(success, error, options);
`,
- errors: [expectedError],
+ errors: [expectedErrorOnProperty],
},
{
code: `
navigator.geolocation.getCurrentPosition(success, error, {enableHighAccuracy: true});
`,
- errors: [expectedError],
+ errors: [expectedErrorOnProperty],
+ },
+ {
+ code: `
+ import * as Location from 'expo-location';
+
+ Location.enableNetworkProviderAsync();
+ `,
+ errors: [expectedErrorOnMemberExpression],
},
],
});
diff --git a/sonar-plugin/pom.xml b/sonar-plugin/pom.xml
index 676913f..9dc55de 100644
--- a/sonar-plugin/pom.xml
+++ b/sonar-plugin/pom.xml
@@ -49,7 +49,7 @@
${encoding}
${encoding}
- 1.5.0
+ 1.6.0
9.4.0.54424
9.13.0.20537
1.23.0.740
diff --git a/sonar-plugin/src/main/java/io/ecocode/javascript/checks/AvoidHighAccuracyGeolocation.java b/sonar-plugin/src/main/java/io/ecocode/javascript/checks/AvoidHighAccuracyGeolocation.java
index ef76f24..1ae7485 100644
--- a/sonar-plugin/src/main/java/io/ecocode/javascript/checks/AvoidHighAccuracyGeolocation.java
+++ b/sonar-plugin/src/main/java/io/ecocode/javascript/checks/AvoidHighAccuracyGeolocation.java
@@ -21,13 +21,15 @@
import org.sonar.plugins.javascript.api.EslintBasedCheck;
import org.sonar.plugins.javascript.api.JavaScriptRule;
import org.sonar.plugins.javascript.api.TypeScriptRule;
+import org.sonarsource.analyzer.commons.annotations.DeprecatedRuleKey;
@JavaScriptRule
@TypeScriptRule
@Rule(key = AvoidHighAccuracyGeolocation.RULE_KEY)
+@DeprecatedRuleKey(repositoryKey = "ecocode-javascript", ruleKey = "EC8")
public class AvoidHighAccuracyGeolocation implements EslintBasedCheck {
- public static final String RULE_KEY = "EC8";
+ public static final String RULE_KEY = "EC523";
@Override
public String eslintKey() {
diff --git a/sonar-plugin/src/main/resources/io/ecocode/profiles/ecocode_javascript_profile.json b/sonar-plugin/src/main/resources/io/ecocode/profiles/ecocode_javascript_profile.json
index 2e3da99..81e71c1 100644
--- a/sonar-plugin/src/main/resources/io/ecocode/profiles/ecocode_javascript_profile.json
+++ b/sonar-plugin/src/main/resources/io/ecocode/profiles/ecocode_javascript_profile.json
@@ -1,7 +1,6 @@
{
"name": "ecoCode",
"ruleKeys": [
- "EC8",
"EC9",
"EC11",
"EC12",
@@ -9,6 +8,7 @@
"EC25",
"EC26",
"EC29",
- "EC30"
+ "EC30",
+ "EC523"
]
}