@@ -4,213 +4,134 @@ import assert from "node:assert/strict";
4
4
import path from "node:path" ;
5
5
import { after , afterEach , before , beforeEach , describe , it } from "node:test" ;
6
6
7
- import { getConfigDir } from "@ignored/hardhat-vnext-core/global-dir" ;
8
- import {
9
- copy ,
10
- exists ,
11
- readJsonFile ,
12
- remove ,
13
- writeJsonFile ,
14
- } from "@ignored/hardhat-vnext-utils/fs" ;
7
+ import { readJsonFile , remove } from "@ignored/hardhat-vnext-utils/fs" ;
15
8
16
9
import {
17
10
sendTaskAnalytics ,
18
11
sendTelemetryConsentAnalytics ,
19
12
} from "../../../../../src/internal/cli/telemetry/analytics/analytics.js" ;
20
13
import { getHardhatVersion } from "../../../../../src/internal/utils/package.js" ;
14
+ import {
15
+ checkIfSubprocessWasExecuted ,
16
+ ROOT_PATH_TO_FIXTURE ,
17
+ } from "../helpers.js" ;
21
18
22
- // The analytics logic uses a detached subprocess to send the payload via HTTP call.
23
- // We cannot test the HTTP call directly, but we can use a test subprocess to verify if the payload is correctly created.
24
- // This is possible because the analytics code attempts to execute a subprocess file of type 'JS'. JS files are only available after compilation.
25
- // During the tests, no JS file is available, so the expected subprocess does not exist. Therefore, we can copy a test subprocess file
26
- // to the expected location instead of the original one and check if it receives the correct payload.
27
-
28
- const PATH_TO_FIXTURE = path . join (
29
- process . cwd ( ) ,
30
- "test" ,
31
- "fixture-projects" ,
32
- "cli" ,
33
- "telemetry" ,
34
- "analytics" ,
35
- ) ;
36
-
37
- const SOURCE_PATH_TEST_SUBPROCESS_FILE = path . join (
38
- PATH_TO_FIXTURE ,
39
- "analytics-subprocess.js" ,
40
- ) ;
41
-
42
- const DEST_PATH_TEST_SUBPROCESS_FILE = path . join (
43
- process . cwd ( ) ,
44
- "src" ,
45
- "internal" ,
46
- "cli" ,
47
- "telemetry" ,
48
- "analytics" ,
49
- "analytics-subprocess.js" ,
50
- ) ;
51
-
19
+ const PATH_TO_FIXTURE = path . join ( ROOT_PATH_TO_FIXTURE , "analytics" ) ;
52
20
const RESULT_FILE_PATH = path . join ( PATH_TO_FIXTURE , "result.json" ) ;
53
21
54
- async function copyTestSubprocessFile ( ) {
55
- await copy ( SOURCE_PATH_TEST_SUBPROCESS_FILE , DEST_PATH_TEST_SUBPROCESS_FILE ) ;
56
- }
57
-
58
- async function removeTestSubprocessFile ( ) {
59
- remove ( DEST_PATH_TEST_SUBPROCESS_FILE ) ;
60
- }
61
-
62
- async function setTelemetryConsentFile ( consent : boolean ) {
63
- const configDir = await getConfigDir ( ) ;
64
- const filePath = path . join ( configDir , "telemetry-consent.json" ) ;
65
- await writeJsonFile ( filePath , { consent } ) ;
66
- }
67
-
68
- async function checkIfSubprocessWasExecuted ( ) {
69
- // Checks if the subprocess was executed by waiting for a file to be created.
70
- // Uses an interval to periodically check for the file. If the file isn't found
71
- // within a specified number of attempts, an error is thrown, indicating a failure in subprocess execution.
72
- const MAX_COUNTER = 20 ;
73
-
74
- return new Promise ( ( resolve , reject ) => {
75
- let counter = 0 ;
76
-
77
- const intervalId = setInterval ( async ( ) => {
78
- counter ++ ;
79
-
80
- if ( await exists ( RESULT_FILE_PATH ) ) {
81
- clearInterval ( intervalId ) ;
82
- resolve ( true ) ;
83
- } else if ( counter > MAX_COUNTER ) {
84
- clearInterval ( intervalId ) ;
85
- reject ( "Subprocess was not executed in the expected time" ) ;
86
- }
87
- } , 100 ) ;
88
- } ) ;
89
- }
90
-
91
22
describe ( "analytics" , ( ) => {
92
- before ( async ( ) => {
93
- copyTestSubprocessFile ( ) ;
23
+ beforeEach ( async ( ) => {
24
+ process . env . HARDHAT_TEST_TELEMETRY_CONSENT_VALUE = "true" ;
94
25
} ) ;
95
26
96
- after ( async ( ) => {
97
- await removeTestSubprocessFile ( ) ;
27
+ afterEach ( async ( ) => {
28
+ delete process . env . HARDHAT_TEST_TELEMETRY_CONSENT_VALUE ;
98
29
} ) ;
99
30
100
- beforeEach ( async ( ) => {
101
- await remove ( RESULT_FILE_PATH ) ;
102
- } ) ;
31
+ describe ( "running in non interactive environment" , ( ) => {
32
+ it ( "should not send consent because the environment is non interactive" , async ( ) => {
33
+ const wasSent = await sendTelemetryConsentAnalytics ( true ) ;
34
+ assert . equal ( wasSent , false ) ;
35
+ } ) ;
103
36
104
- afterEach ( async ( ) => {
105
- await remove ( RESULT_FILE_PATH ) ;
37
+ it ( "should not send analytics because the environment is not interactive" , async ( ) => {
38
+ const wasSent = await sendTaskAnalytics ( [ "task" , "subtask" ] ) ;
39
+ assert . equal ( wasSent , false ) ;
40
+ } ) ;
106
41
} ) ;
107
42
108
- describe ( "analytics payload" , async ( ) => {
109
- const ORIGINAL_PROCESS_ENV = { ...process } ;
43
+ describe ( "running in an interactive environment (simulated with ENV variables)" , ( ) => {
44
+ before ( ( ) => {
45
+ process . env . HARDHAT_TEST_INTERACTIVE_ENV = "true" ;
46
+ process . env . HARDHAT_TEST_SUBPROCESS_RESULT_PATH = RESULT_FILE_PATH ;
47
+ } ) ;
48
+
49
+ after ( ( ) => {
50
+ delete process . env . HARDHAT_TEST_INTERACTIVE_ENV ;
51
+ } ) ;
110
52
111
- describe ( "not running in CI" , ( ) => {
112
- before ( ( ) => {
113
- // Force Ci to not be detected as Ci so the test can run (Ci is blocked for analytics)
114
- process . env . HARDHAT_ENABLE_TELEMETRY_IN_TEST = "true" ;
115
- } ) ;
53
+ beforeEach ( async ( ) => {
54
+ await remove ( RESULT_FILE_PATH ) ;
55
+ } ) ;
116
56
117
- after ( ( ) => {
118
- delete process . env . HARDHAT_ENABLE_TELEMETRY_IN_TEST ;
119
- process = ORIGINAL_PROCESS_ENV ;
120
- } ) ;
57
+ afterEach ( async ( ) => {
58
+ await remove ( RESULT_FILE_PATH ) ;
59
+ } ) ;
121
60
122
- it ( "should create the correct payload for the telemetry consent (positive consent)" , async ( ) => {
123
- await sendTelemetryConsentAnalytics ( true ) ;
61
+ it ( "should create the correct payload for the telemetry consent (positive consent)" , async ( ) => {
62
+ await sendTelemetryConsentAnalytics ( true ) ;
124
63
125
- await checkIfSubprocessWasExecuted ( ) ;
64
+ await checkIfSubprocessWasExecuted ( RESULT_FILE_PATH ) ;
126
65
127
- const result = await readJsonFile ( RESULT_FILE_PATH ) ;
66
+ const result = await readJsonFile ( RESULT_FILE_PATH ) ;
128
67
129
- assert . deepEqual ( result , {
130
- client_id : "hardhat_telemetry_consent" ,
131
- user_id : "hardhat_telemetry_consent" ,
132
- user_properties : { } ,
133
- events : [
134
- {
135
- name : "TelemetryConsentResponse" ,
136
- params : {
137
- userConsent : "yes" ,
138
- } ,
68
+ assert . deepEqual ( result , {
69
+ client_id : "hardhat_telemetry_consent" ,
70
+ user_id : "hardhat_telemetry_consent" ,
71
+ user_properties : { } ,
72
+ events : [
73
+ {
74
+ name : "TelemetryConsentResponse" ,
75
+ params : {
76
+ userConsent : "yes" ,
139
77
} ,
140
- ] ,
141
- } ) ;
78
+ } ,
79
+ ] ,
142
80
} ) ;
81
+ } ) ;
143
82
144
- it ( "should create the correct payload for the telemetry consent (negative consent)" , async ( ) => {
145
- await sendTelemetryConsentAnalytics ( false ) ;
83
+ it ( "should create the correct payload for the telemetry consent (negative consent)" , async ( ) => {
84
+ await sendTelemetryConsentAnalytics ( false ) ;
146
85
147
- await checkIfSubprocessWasExecuted ( ) ;
86
+ await checkIfSubprocessWasExecuted ( RESULT_FILE_PATH ) ;
148
87
149
- const result = await readJsonFile ( RESULT_FILE_PATH ) ;
88
+ const result = await readJsonFile ( RESULT_FILE_PATH ) ;
150
89
151
- assert . deepEqual ( result , {
152
- client_id : "hardhat_telemetry_consent" ,
153
- user_id : "hardhat_telemetry_consent" ,
154
- user_properties : { } ,
155
- events : [
156
- {
157
- name : "TelemetryConsentResponse" ,
158
- params : {
159
- userConsent : "no" ,
160
- } ,
90
+ assert . deepEqual ( result , {
91
+ client_id : "hardhat_telemetry_consent" ,
92
+ user_id : "hardhat_telemetry_consent" ,
93
+ user_properties : { } ,
94
+ events : [
95
+ {
96
+ name : "TelemetryConsentResponse" ,
97
+ params : {
98
+ userConsent : "no" ,
161
99
} ,
162
- ] ,
163
- } ) ;
164
- } ) ;
165
-
166
- it ( "should create the correct payload for the task analytics" , async ( ) => {
167
- await setTelemetryConsentFile ( true ) ;
168
-
169
- const wasSent = await sendTaskAnalytics ( [ "task" , "subtask" ] ) ;
170
-
171
- await checkIfSubprocessWasExecuted ( ) ;
172
-
173
- const result : Payload = await readJsonFile ( RESULT_FILE_PATH ) ;
174
-
175
- assert . equal ( wasSent , true ) ;
176
-
177
- // Check payload properties
178
- assert . notEqual ( result . client_id , undefined ) ;
179
- assert . notEqual ( result . user_id , undefined ) ;
180
- assert . equal ( result . user_properties . projectId . value , "hardhat-project" ) ;
181
- assert . equal (
182
- result . user_properties . hardhatVersion . value ,
183
- await getHardhatVersion ( ) ,
184
- ) ;
185
- assert . notEqual (
186
- result . user_properties . operatingSystem . value ,
187
- undefined ,
188
- ) ;
189
- assert . notEqual ( result . user_properties . nodeVersion . value , undefined ) ;
190
- assert . equal ( result . events [ 0 ] . name , "task" ) ;
191
- assert . equal ( result . events [ 0 ] . params . engagement_time_msec , "10000" ) ;
192
- assert . notEqual ( result . events [ 0 ] . params . session_id , undefined ) ;
193
- assert . equal ( result . events [ 0 ] . params . task , "task, subtask" ) ;
100
+ } ,
101
+ ] ,
194
102
} ) ;
103
+ } ) ;
195
104
196
- it ( "should not send analytics because the consent is not given" , async ( ) => {
197
- await setTelemetryConsentFile ( false ) ;
198
- const wasSent = await sendTaskAnalytics ( [ "task" , "subtask" ] ) ;
199
- assert . equal ( wasSent , false ) ;
200
- } ) ;
105
+ it ( "should create the correct payload for the task analytics" , async ( ) => {
106
+ const wasSent = await sendTaskAnalytics ( [ "task" , "subtask" ] ) ;
107
+
108
+ await checkIfSubprocessWasExecuted ( RESULT_FILE_PATH ) ;
109
+
110
+ const result : Payload = await readJsonFile ( RESULT_FILE_PATH ) ;
111
+
112
+ assert . equal ( wasSent , true ) ;
113
+
114
+ // Check payload properties
115
+ assert . notEqual ( result . client_id , undefined ) ;
116
+ assert . notEqual ( result . user_id , undefined ) ;
117
+ assert . equal ( result . user_properties . projectId . value , "hardhat-project" ) ;
118
+ assert . equal (
119
+ result . user_properties . hardhatVersion . value ,
120
+ await getHardhatVersion ( ) ,
121
+ ) ;
122
+ assert . notEqual ( result . user_properties . operatingSystem . value , undefined ) ;
123
+ assert . notEqual ( result . user_properties . nodeVersion . value , undefined ) ;
124
+ assert . equal ( result . events [ 0 ] . name , "task" ) ;
125
+ assert . equal ( result . events [ 0 ] . params . engagement_time_msec , "10000" ) ;
126
+ assert . notEqual ( result . events [ 0 ] . params . session_id , undefined ) ;
127
+ assert . equal ( result . events [ 0 ] . params . task , "task, subtask" ) ;
201
128
} ) ;
202
129
203
- describe ( "running in non interactive environment" , ( ) => {
204
- it ( "should not send consent because the environment is non interactive" , async ( ) => {
205
- const wasSent = await sendTelemetryConsentAnalytics ( true ) ;
206
- assert . equal ( wasSent , false ) ;
207
- } ) ;
130
+ it ( "should not send analytics because the consent is not given" , async ( ) => {
131
+ process . env . HARDHAT_TEST_TELEMETRY_CONSENT_VALUE = "false" ;
208
132
209
- it ( "should not send analytics because the environment is not interactive" , async ( ) => {
210
- await setTelemetryConsentFile ( true ) ;
211
- const wasSent = await sendTaskAnalytics ( [ "task" , "subtask" ] ) ;
212
- assert . equal ( wasSent , false ) ;
213
- } ) ;
133
+ const wasSent = await sendTaskAnalytics ( [ "task" , "subtask" ] ) ;
134
+ assert . equal ( wasSent , false ) ;
214
135
} ) ;
215
136
} ) ;
216
137
} ) ;
0 commit comments