How to use github.pulls.list method in Cypress

Best JavaScript code snippet using cypress

Run Cypress automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

checkPullRequestJobSpec.js

Source: checkPullRequestJobSpec.js Github

copy
1// Copyright 2020 The Oppia Authors. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS-IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15require('dotenv').config();
16const { createProbot } = require('probot');
17// The plugin refers to the actual app in index.js.
18const oppiaBot = require('../index');
19const checkPullRequestJobModule = require('../lib/checkPullRequestJob');
20const apiForSheetsModule = require('../lib/apiForSheets');
21const checkPullRequestLabelsModule = require('../lib/checkPullRequestLabels');
22const checkPullRequestBranchModule = require('../lib/checkPullRequestBranch');
23const checkCriticalPullRequestModule =
24  require('../lib/checkCriticalPullRequest');
25const checkPullRequestTemplateModule =
26  require('../lib/checkPullRequestTemplate');
27const newCodeOwnerModule = require('../lib/checkForNewCodeowner');
28const scheduler = require('../lib/scheduler');
29const checkCronJobModule = require('../lib/checkNewCronJobs');
30const { JOBS_AND_FETURES_TESTING_WIKI_LINK } = require('../lib/utils');
31
32let payloadData = JSON.parse(
33  JSON.stringify(require('../fixtures/pullRequestPayload.json'))
34);
35
36describe('Pull Request Job Spec', () => {
37  /**
38   * @type {import('probot').Probot} robot
39   */
40  let robot;
41
42  /**
43   * @type {import('probot').Octokit} github
44   */
45  let github;
46
47  /**
48   * @type {import('probot').Application} app
49   */
50  let app;
51
52  const firstNewJobFileObj = {
53    sha: 'd144f32b9812373d5f1bc9f94d9af795f09023ff',
54    filename: 'core/jobs/exp_jobs_one_off.py',
55    status: 'added',
56    additions: 1,
57    deletions: 0,
58    changes: 1,
59    blob_url:
60      'https://github.com/oppia/oppia/blob/67fb4a973b318882af3b5a894130' +
61      'e110d7e9833c/core/jobs/exp_jobs_one_off.py',
62    raw_url:
63      'https://github.com/oppia/oppia/raw/67fb4a973b318882af3b5a894130' +
64      'e110d7e9833c/core/jobs/exp_jobs_one_off.py',
65    contents_url:
66      'https://api.github.com/repos/oppia/oppia/contents/core/jobs/' +
67      'exp_jobs_one_off.py?ref=67fb4a973b318882af3b5a894130e110d7e9833c',
68    patch: '@@ -0,0 +1 @@\n+class FirstTestJob(jobs.JobTestBase):\n' +
69      '+    """One-off job for creating and populating ' +
70      'UserContributionsModels for\n+    ' +
71      'all registered users that have contributed.\n+    """\n+    ' +
72      '@classmethod\n+    def entity_classes_to_map_over(cls)' +
73      ':\n+        """Return a list of datastore class references ' +
74      'to map over."""\n+        return [exp_models.' +
75      'ExplorationSnapshotMetadataModel]\n+\n+    @staticmethod\n+    ' +
76      'def map(item):\n+        """Implements the map function for this ' +
77      'job."""\n+        yield (\n+            item.committer_id, ' +
78      '{\n+                \'exploration_id\': item.' +
79      'get_unversioned_instance_id(),\n+                ' +
80      '\'version_string\': item.get_version_string(),\n+            ' +
81      '})\n+\n+\n+    @staticmethod\n+    def reduce(key, ' +
82      'version_and_exp_ids):\n+        """Implements the reduce ' +
83      'function for this job."""\n+        created_exploration_ids = ' +
84      'set()\n+        edited_exploration_ids = set()\n+\n+        ' +
85      'edits = [ast.literal_eval(v) for v in version_and_exp_ids]' +
86      '\n+\n+        for edit in edits:\n+            ' +
87      'edited_exploration_ids.add(edit[\'exploration_id\'])' +
88      '\n+            if edit[\'version_string\'] == \'1\'' +
89      ':\n+                created_exploration_ids.add(edit' +
90      '[\'exploration_id\'])\n+\n+        if user_services.' +
91      'get_user_contributions(key, strict=False) is not None' +
92      ':\n+            user_services.update_user_contributions' +
93      '(\n+                key, list(created_exploration_ids), ' +
94      'list(\n+                    edited_exploration_ids))\n+        ' +
95      'else:\n+            user_services.create_user_contributions' +
96      '(\n+                key, list(created_exploration_ids), list' +
97      '(\n+                    edited_exploration_ids))\n',
98  };
99
100  const secondNewJobFileObj = {
101    sha: 'd144f32b9812373d5f1bc9f94d9af795f09023ff',
102    filename: 'core/jobs/exp_jobs_oppiabot_off.py',
103    status: 'added',
104    additions: 1,
105    deletions: 0,
106    changes: 1,
107    blob_url:
108      'https://github.com/oppia/oppia/blob/67fb4a973b318882af3b5a894130' +
109      'e110d7e9833c/core/jobs/exp_jobs_oppiabot_off.py',
110    raw_url:
111      'https://github.com/oppia/oppia/raw/67fb4a973b318882af3b5a894130' +
112      'e110d7e9833c/core/jobs/exp_jobs_oppiabot_off.py',
113    contents_url:
114      'https://api.github.com/repos/oppia/oppia/contents/core/jobs/' +
115      'exp_jobs_oppiabot_off.py?ref=67fb4a973b318882af3b5a894130e110d7e9833c',
116    patch: '@@ -0,0 +1 @@\n+class SecondTestJob(jobs.JobTestBase):\n' +
117      '+    """One-off job for creating and populating ' +
118      'UserContributionsModels for\n' +
119      '+    all registered users that have contributed.\n+    ' +
120      '"""\n+    @classmethod\n+    def entity_classes_to_map_over' +
121      '(cls):\n+        """Return a list of datastore class references ' +
122      'to map over."""\n+        return [exp_models.' +
123      'ExplorationSnapshotMetadataModel]\n+\n+    @staticmethod\n+    ' +
124      'def map(item):\n+        """Implements the map function for this ' +
125      'job."""\n+        yield (\n+            item.committer_id, ' +
126      '{\n+                \'exploration_id\': item.' +
127      'get_unversioned_instance_id(),\n+                \'version_string\'' +
128      ': item.get_version_string(),\n+            })\n+\n+\n+    ' +
129      '@staticmethod\n+    def reduce(key, version_and_exp_ids)' +
130      ':\n+        """Implements the reduce function for this job.' +
131      '"""\n+        created_exploration_ids = set()\n+        ' +
132      'edited_exploration_ids = set()\n+\n+        edits = ' +
133      '[ast.literal_eval(v) for v in version_and_exp_ids]\n+\n+        ' +
134      'for edit in edits:\n+            edited_exploration_ids.add' +
135      '(edit[\'exploration_id\'])\n+            if edit' +
136      '[\'version_string\'] == \'1\':\n+                ' +
137      'created_exploration_ids.add(edit[\'exploration_id\'])' +
138      '\n+\n+        if user_services.get_user_contributions' +
139      '(key, strict=False) is not None:\n+            user_services.' +
140      'update_user_contributions(\n+                key, list' +
141      '(created_exploration_ids), list(\n+                    ' +
142      'edited_exploration_ids))\n+        else:\n+            ' +
143      'user_services.create_user_contributions(\n+                ' +
144      'key, list(created_exploration_ids), list(\n+                    ' +
145      'edited_exploration_ids))\n',
146  };
147
148  const modifiedExistingJobFileObj = {
149    sha: 'f06a0d3ea104733080c4dad4a4e5aa7fb76d8f5d',
150    filename: 'core/jobs/user_jobs_one_off.py',
151    status: 'modified',
152    additions: 43,
153    deletions: 0,
154    changes: 43,
155    blob_url:
156      'https://github.com/oppia/oppia/blob/5b0e633fa1b9a00771a3b88302fa' +
157      '3ff048d7240c/core/jobs/user_jobs_one_off.py',
158    raw_url:
159      'https://github.com/oppia/oppia/raw/5b0e633fa1b9a00771a3b88302fa' +
160      '3ff048d7240c/core/jobs/user_jobs_one_off.py',
161    contents_url:
162      'https://api.github.com/repos/oppia/oppia/contents/core/jobs/' +
163      'user_jobs_one_off.py?ref=5b0e633fa1b9a00771a3b88302fa3ff048d7240c',
164    patch:
165      '@@ -80,6 +80,49 @@ def reduce(key, version_and_exp_ids)' +
166      ':\n                     edited_exploration_ids))\n \n ' +
167      '\n+class OppiabotContributionsJob(jobs.JobTestBase):\n' +
168      '+    """One-off job for creating and populating ' +
169      'UserContributionsModels for' +
170      '\n+    all registered users that have contributed.\n+    ' +
171      '"""\n+    @classmethod\n+    def entity_classes_to_map_over' +
172      '(cls):\n+        """Return a list of datastore class ' +
173      'references to map over."""\n+        return ' +
174      '[exp_models.ExplorationSnapshotMetadataModel]\n+\n+    ' +
175      '@staticmethod\n+    def map(item):\n+        """Implements ' +
176      'the map function for this job."""\n+        yield ' +
177      '(\n+            item.committer_id, {\n+                ' +
178      '\'exploration_id\': item.get_unversioned_instance_id(),' +
179      '\n+                \'version_string\': item.' +
180      'get_version_string(),\n+            })\n+\n+\n+    ' +
181      '@staticmethod\n+    def reduce(key, version_and_exp_ids)' +
182      ':\n+        """Implements the reduce function for this ' +
183      'job."""\n+        created_exploration_ids = set()' +
184      '\n+        edited_exploration_ids = set()\n+\n+        ' +
185      'edits = [ast.literal_eval(v) for v in version_and_exp_ids]' +
186      '\n+\n+        for edit in edits:\n+            ' +
187      'edited_exploration_ids.add(edit[\'exploration_id\'])' +
188      '\n+            if edit[\'version_string\'] == \'1\'' +
189      ':\n+                created_exploration_ids.add(edit' +
190      '[\'exploration_id\'])\n+\n+        if user_services.' +
191      'get_user_contributions(key, strict=False) is not None' +
192      ':\n+            user_services.update_user_contributions' +
193      '(\n+                key, list(created_exploration_ids), ' +
194      'list(\n+                    edited_exploration_ids))' +
195      '\n+        else:\n+            user_services.' +
196      'create_user_contributions(\n+                key, ' +
197      'list(created_exploration_ids), list(' +
198      '\n+                    edited_exploration_ids))\n',
199  };
200  const modifiedExistingJobFileObjWithJobClassInPatch = {
201    sha: 'd144f32b9812373d5f1bc9f94d9af795f09023ff',
202    filename: 'core/jobs/exp_jobs_oppiabot_off.py',
203    status: 'modified',
204    additions: 1,
205    deletions: 0,
206    changes: 1,
207    blob_url:
208      'https://github.com/oppia/oppia/blob/67fb4a973b318882af3b5a894130' +
209      'e110d7e9833c/core/jobs/exp_jobs_oppiabot_off.py',
210    raw_url:
211      'https://github.com/oppia/oppia/raw/67fb4a973b318882af3b5a894130' +
212      'e110d7e9833c/core/jobs/exp_jobs_oppiabot_off.py',
213    contents_url:
214      'https://api.github.com/repos/oppia/oppia/contents/core/jobs/' +
215      'exp_jobs_oppiabot_off.py?ref=67fb4a973b318882af3b5a894130e110d7e9833c',
216    patch: '@@ -0,0 +1 @@class SecondTestJob(jobs.JobTestBase)  ' +
217      'def reduce(key, version_and_exp_ids):\n' +
218      '                     edited_exploration_ids))\n ',
219  };
220
221  const jobFileObjWithJobClassInPatchAndNewJob = {
222    sha: 'd144f32b9812373d5f1bc9f94d9af795f09023ff',
223    filename: 'core/jobs/exp_jobs_oppiabot_off.py',
224    status: 'modified',
225    additions: 1,
226    deletions: 0,
227    changes: 1,
228    blob_url:
229      'https://github.com/oppia/oppia/blob/67fb4a973b318882af3b5a894130' +
230      'e110d7e9833c/core/jobs/exp_jobs_oppiabot_off.py',
231    raw_url:
232      'https://github.com/oppia/oppia/raw/67fb4a973b318882af3b5a89413' +
233      '0e110d7e9833c/core/jobs/exp_jobs_oppiabot_off.py',
234    contents_url:
235      'https://api.github.com/repos/oppia/oppia/contents/core/jobs/' +
236      'exp_jobs_oppiabot_off.py?ref=' +
237      '67fb4a973b318882af3b5a894130e110d7e9833c',
238    patch: '@@ -0,0 +1 @@class SecondTestJob(jobs.JobTestBase)  ' +
239      'def reduce(key, version_and_exp_ids):\n' +
240      '                     edited_exploration_ids))\n' +
241      ' \n' +
242      '+class AnotherTestJob(jobs.JobTestBase):\n' +
243      '+    """\n' +
244      '+    @classmethod\n' +
245      '+    def entity_classes_to_map_over ',
246  };
247
248  const jobFromTestDir = {
249    sha: 'd144f32b9812373d5f1bc9f94d9af795f09023ff',
250    filename: 'core/tests/linter_tests/exp_jobs_oppiabot_off.py',
251    status: 'added',
252    additions: 1,
253    deletions: 0,
254    changes: 1,
255    blob_url:
256      'https://github.com/oppia/oppia/blob/67fb4a973b318882af3b5a894130' +
257      'e110d7e9833c/core/tests/linter_tests/exp_jobs_oppiabot_off.py',
258    raw_url:
259      'https://github.com/oppia/oppia/raw/67fb4a973b318882af3b5a894130' +
260      'e110d7e9833c/core/tests/linter_tests/exp_jobs_oppiabot_off.py',
261    contents_url:
262      'https://api.github.com/repos/oppia/oppia/contents/core/tests/' +
263      'linter_tests/exp_jobs_oppiabot_off.py?ref=' +
264      '67fb4a973b318882af3b5a894130e110d7e9833c',
265    patch: '@@ -0,0 +1 @@\n+class LintTestJob(jobs.JobTestBase):\n' +
266      '+    """One-off job for creating and populating' +
267      ' UserContributionsModels for\n' +
268      '+    all registered users that have contributed.\n+    ' +
269      '"""\n+    @classmethod\n+    def entity_classes_to_map_over' +
270      '(cls):\n+        """Return a list of datastore class ' +
271      'references to map over."""\n+        return [exp_models.' +
272      'ExplorationSnapshotMetadataModel]\n+\n+    @staticmethod' +
273      '\n+    def map(item):\n+        """Implements the map function ' +
274      'for this job."""\n+        yield (\n+            item.' +
275      'committer_id, {\n+                \'exploration_id\': ' +
276      'item.get_unversioned_instance_id(),\n+                ' +
277      '\'version_string\': item.get_version_string(),\n+            ' +
278      '})\n+\n+\n+    @staticmethod\n+    def reduce(key, ' +
279      'version_and_exp_ids):\n+        """Implements the reduce ' +
280      'function for this job."""\n+        created_exploration_ids ' +
281      '= set()\n+        edited_exploration_ids = set()\n+\n+        ' +
282      'edits = [ast.literal_eval(v) for v in version_and_exp_ids]' +
283      '\n+\n+        for edit in edits:\n+            ' +
284      'edited_exploration_ids.add(edit[\'exploration_id\'])' +
285      '\n+            if edit[\'version_string\'] == \'1\'' +
286      ':\n+                created_exploration_ids.add(edit' +
287      '[\'exploration_id\'])\n+\n+        if user_services.' +
288      'get_user_contributions(key, strict=False) is not None' +
289      ':\n+            user_services.update_user_contributions' +
290      '(\n+                key, list(created_exploration_ids), ' +
291      'list(\n+                    edited_exploration_ids))\n+        ' +
292      'else:\n+            user_services.create_user_contributions' +
293      '(\n+                key, list(created_exploration_ids), list' +
294      '(\n+                    edited_exploration_ids))\n',
295  };
296
297  const fileWithMultipleJobs = {
298    sha: 'd144f32b9812373d5f1bc9f94d9af795f09023ff',
299    filename: 'core/jobs/exp_jobs_oppiabot_off.py',
300    status: 'added',
301    additions: 1,
302    deletions: 0,
303    changes: 1,
304    blob_url:
305      'https://github.com/oppia/oppia/blob/67fb4a973b318882af3b5a894130' +
306      'e110d7e9833c/core/jobs/exp_jobs_oppiabot_off.py',
307    raw_url:
308      'https://github.com/oppia/oppia/raw/67fb4a973b318882af3b5a894130' +
309      'e110d7e9833c/core/jobs/exp_jobs_oppiabot_off.py',
310    contents_url:
311      'https://api.github.com/repos/oppia/oppia/contents/core/jobs/' +
312      'exp_jobs_oppiabot_off.py?ref=' +
313      '67fb4a973b318882af3b5a894130e110d7e9833c',
314    patch: '@@ -0,0 +1 @@\n+class TestJob(jobs.JobTestBase):\n' +
315      '+    """One-off job for creating and ' +
316      'populating UserContributionsModels for \n+class ' +
317      'AnotherTestJob(jobs.JobTestBase):\n' +
318      '+    """\n+    @classmethod\n+    def ' +
319      'entity_classes_to_map_over(cls):\n+        """Return a list' +
320      ' of datastore class references to map over."""\n+        ' +
321      'return [exp_models.ExplorationSnapshotMetadataModel]\n+\n+    ' +
322      '@staticmethod\n+    def map(item):\n+        """Implements ' +
323      'the map function for this job."""\n+        yield ' +
324      '(\n+            item.committer_id, {\n+                ' +
325      '\'exploration_id\': item.get_unversioned_instance_id(),\n+' +
326      '                \'version_string\': item.get_version_string(),' +
327      '\n+            })\n+\n+\n+    @staticmethod\n+    ' +
328      'def reduce(key, version_and_exp_ids):\n+        ' +
329      '"""Implements the reduce function for this job."""\n+        ' +
330      'created_exploration_ids = set()\n+        ' +
331      'edited_exploration_ids = set()\n+\n+        edits = ' +
332      '[ast.literal_eval(v) for v in version_and_exp_ids]' +
333      '\n+\n+        for edit in edits:\n+            ' +
334      'edited_exploration_ids.add(edit[\'exploration_id\'])' +
335      '\n+            if edit[\'version_string\'] == \'1\':\n+' +
336      '                created_exploration_ids.add(edit' +
337      '[\'exploration_id\'])\n+\n+        if user_services.' +
338      'get_user_contributions(key, strict=False) is not None' +
339      ':\n+            user_services.update_user_contributions' +
340      '(\n+                key, list(created_exploration_ids), ' +
341      'list(\n+                    edited_exploration_ids))' +
342      '\n+        else:\n+            user_services.' +
343      'create_user_contributions(\n+                key, list(' +
344      'created_exploration_ids), list(\n+                    ' +
345      'edited_exploration_ids))\n',
346  };
347
348  const jobTestFile = {
349    sha: 'd144f32b9812373d5f1bc9f94d9af795f09023ff',
350    filename: 'core/jobs/exp_jobs_oppiabot_off_test.py',
351    status: 'added',
352    additions: 1,
353    deletions: 0,
354    changes: 1,
355    blob_url:
356      'https://github.com/oppia/oppia/blob/67fb4a973b318882af3b5a894130' +
357      'e110d7e9833c/core/jobs/exp_jobs_oppiabot_off.py',
358    raw_url:
359      'https://github.com/oppia/oppia/raw/67fb4a973b318882af3b5a894130' +
360      'e110d7e9833c/core/jobs/exp_jobs_oppiabot_off.py',
361    contents_url:
362      'https://api.github.com/repos/oppia/oppia/contents/core/jobs/' +
363      'exp_jobs_oppiabot_off.py?ref=67fb4a973b318882af3b5a894130e110d7e9833c',
364    patch: '@@ -0,0 +1 @@\n+class TestJobTests(jobs.JobTestBase):\n' +
365      '+    """One-off job for creating and populating ' +
366      'UserContributionsModels for \n' +
367      '+class AnotherTestJobTests(jobs.JobTestBase):\n' +
368      '+    """\n+    ' +
369      '@classmethod\n+    def entity_classes_to_map_over(cls):' +
370      '\n+        """Return a list of datastore class references to ' +
371      'map over."""\n+        return [exp_models.' +
372      'ExplorationSnapshotMetadataModel]\n+\n+    @staticmethod\n+    ' +
373      'def map(item):\n+        """Implements the map function for this ' +
374      'job."""\n+        yield (\n+            item.committer_id, ' +
375      '{\n+                \'exploration_id\': item.get_unversioned_' +
376      'instance_id(),\n+                \'version_string\': item.' +
377      'get_version_string(),\n+            })\n+\n+\n+    ' +
378      '@staticmethod\n+    def reduce(key, version_and_exp_ids):\n+' +
379      '        """Implements the reduce function for this job."""\n+' +
380      '        created_exploration_ids = set()\n+        ' +
381      'edited_exploration_ids = set()\n+\n+        edits ' +
382      '= [ast.literal_eval(v) for v in version_and_exp_ids]\n+\n+        ' +
383      'for edit in edits:\n+            edited_exploration_ids.add(edit' +
384      '[\'exploration_id\'])\n+            if edit[\'version_string\'] == ' +
385      '\'1\':\n+                created_exploration_ids.add(edit' +
386      '[\'exploration_id\'])\n+\n+        if user_services.' +
387      'get_user_contributions(key, strict=False) is not None:\n+            ' +
388      'user_services.update_user_contributions(\n+                key, list' +
389      '(created_exploration_ids), list(\n+                    ' +
390      'edited_exploration_ids))\n+        else:\n+            ' +
391      'user_services.create_user_contributions(\n+                ' +
392      'key, list(created_exploration_ids), list(\n+                    ' +
393      'edited_exploration_ids))\n',
394  };
395
396  const nonJobFile = {
397    sha: 'd144f32b9812373d5f1bc9f94d9af795f09023ff',
398    filename: 'core/domain/exp_fetchers.py',
399    status: 'added',
400    additions: 1,
401    deletions: 0,
402    changes: 1,
403    blob_url:
404      'https://github.com/oppia/oppia/blob/67fb4a973b318882af3b5a894130' +
405      'e110d7e9833c/core/domain/exp_fetchers.py',
406    raw_url:
407      'https://github.com/oppia/oppia/raw/67fb4a973b318882af3b5a894130' +
408      'e110d7e9833c/core/domain/exp_fetchers.py',
409    contents_url:
410      'https://api.github.com/repos/oppia/oppia/contents/core/domain/' +
411      'exp_fetchers.py?ref=67fb4a973b318882af3b5a894130e110d7e9833c',
412    patch: '@@ -0,0 +1 @@\n+# def _migrate_states_schema' +
413      '(versioned_exploration_states, exploration_id):',
414  };
415
416  beforeEach(() => {
417    spyOn(scheduler, 'createScheduler').and.callFake(() => { });
418
419    github = {
420      issues: {
421        createComment: jasmine.createSpy('createComment').and.returnValue({}),
422        addLabels: jasmine.createSpy('addLabels').and.returnValue({}),
423        addAssignees: jasmine.createSpy('addAssignees').and.returnValue({})
424      },
425    };
426
427    robot = createProbot({
428      id: 1,
429      cert: 'test',
430      githubToken: 'test',
431    });
432
433    app = robot.load(oppiaBot);
434    spyOn(app, 'auth').and.resolveTo(github);
435    spyOn(checkPullRequestJobModule, 'checkForNewJob').and.callThrough();
436    spyOn(apiForSheetsModule, 'checkClaStatus').and.callFake(() => { });
437    spyOn(
438      checkPullRequestLabelsModule, 'checkChangelogLabel'
439    ).and.callFake(() => { });
440    spyOn(
441      checkCriticalPullRequestModule, 'checkIfPRAffectsDatastoreLayer'
442    ).and.callFake(() => { });
443    spyOn(checkPullRequestBranchModule, 'checkBranch').and.callFake(() => { });
444    spyOn(checkCronJobModule, 'checkForNewCronJob').and.callFake(() => { });
445    spyOn(
446      checkPullRequestTemplateModule, 'checkTemplate'
447    ).and.callFake(() => { });
448    spyOn(newCodeOwnerModule, 'checkForNewCodeowner').and.callFake(() => { });
449  });
450
451  describe('When a new job file is created in a pull request', () => {
452    beforeEach(async () => {
453      github.pulls = {
454        listFiles: jasmine.createSpy('listFiles').and.resolveTo({
455          data: [nonJobFile, firstNewJobFileObj],
456        }),
457      };
458      payloadData.payload.pull_request.changed_files = 2;
459      await robot.receive(payloadData);
460    });
461
462    it('should check for jobs', () => {
463      expect(checkPullRequestJobModule.checkForNewJob).toHaveBeenCalled();
464    });
465
466    it('should get modified files', () => {
467      expect(github.pulls.listFiles).toHaveBeenCalled();
468    });
469
470    it('should ping server jobs admin', () => {
471      const author = payloadData.payload.pull_request.user.login;
472      const formText = (
473        'server jobs form'.link(
474          'https://goo.gl/forms/XIj00RJ2h5L55XzU2')
475      );
476      const newLineFeed = '<br>';
477      const wikiLinkText = 'this guide'.link(
478        JOBS_AND_FETURES_TESTING_WIKI_LINK);
479      const jobNameLink = (
480        'FirstTestJob'.link(firstNewJobFileObj.blob_url)
481      );
482
483      expect(github.issues.createComment).toHaveBeenCalledWith({
484        issue_number: payloadData.payload.pull_request.number,
485        body:
486          'Hi @vojtechjelinek, PTAL at this PR, ' +
487          'it adds a new job. The name of the job is ' + jobNameLink + '.' +
488          newLineFeed +
489          'Also @' + author + ', please make sure to fill in the ' + formText +
490          ' for the new job to be tested on the backup server. ' +
491          'This PR can be merged only after the test run is successful. ' +
492          'Please refer to ' + wikiLinkText + ' for details.' +
493          newLineFeed + 'Thanks!',
494        repo: payloadData.payload.repository.name,
495        owner: payloadData.payload.repository.owner.login,
496      });
497    });
498
499    it('should assign server jobs admin', () => {
500      expect(github.issues.addAssignees).toHaveBeenCalled();
501      expect(github.issues.addAssignees).toHaveBeenCalledWith({
502        issue_number: payloadData.payload.pull_request.number,
503        repo: payloadData.payload.repository.name,
504        owner: payloadData.payload.repository.owner.login,
505        assignees: ['vojtechjelinek']
506      });
507    });
508
509    it('should add datastore label', () => {
510      expect(github.issues.addLabels).toHaveBeenCalled();
511      expect(github.issues.addLabels).toHaveBeenCalledWith({
512        issue_number: payloadData.payload.pull_request.number,
513        repo: payloadData.payload.repository.name,
514        owner: payloadData.payload.repository.owner.login,
515        labels: ['PR: Affects datastore layer']
516      });
517    });
518  });
519
520  describe('When multiple job files are created in a pull request', () => {
521    beforeEach(async () => {
522      github.pulls = {
523        listFiles: jasmine.createSpy('listFiles').and.resolveTo({
524          data: [
525            nonJobFile,
526            firstNewJobFileObj,
527            secondNewJobFileObj
528          ],
529        }),
530      };
531
532      payloadData.payload.pull_request.changed_files = 3;
533      await robot.receive(payloadData);
534    });
535
536    it('should check for jobs', () => {
537      expect(checkPullRequestJobModule.checkForNewJob).toHaveBeenCalled();
538    });
539
540    it('should get modified files', () => {
541      expect(github.pulls.listFiles).toHaveBeenCalled();
542    });
543
544    it('should ping server jobs admin', () => {
545      expect(github.issues.createComment).toHaveBeenCalled();
546      const author = payloadData.payload.pull_request.user.login;
547      const formText = (
548        'server jobs form'.link('https://goo.gl/forms/XIj00RJ2h5L55XzU2')
549      );
550      const newLineFeed = '<br>';
551      const wikiLinkText = 'this guide'.link(
552        JOBS_AND_FETURES_TESTING_WIKI_LINK);
553      const jobRegistryLink = (
554        'job registry'.link(
555          'https://github.com/oppia/oppia/blob/develop/core/jobs_registry.py')
556      );
557      const firstJobNameLink = (
558        'FirstTestJob'.link(firstNewJobFileObj.blob_url)
559      );
560      const secondJobNameLink = (
561        'SecondTestJob'.link(secondNewJobFileObj.blob_url)
562      );
563      expect(github.issues.createComment).toHaveBeenCalledWith({
564        issue_number: payloadData.payload.pull_request.number,
565        body:
566          'Hi @vojtechjelinek, PTAL at this PR, ' +
567          'it adds new jobs. The jobs are ' + firstJobNameLink +
568          ', ' + secondJobNameLink + '.' + newLineFeed + 'Also @' +
569          author + ', please make sure to fill in the ' +
570          formText + ' for the new jobs to be tested on the backup server. ' +
571          'This PR can be merged only after the test run is successful. ' +
572          'Please refer to ' + wikiLinkText + ' for details.' +
573          newLineFeed + 'Thanks!',
574        repo: payloadData.payload.repository.name,
575        owner: payloadData.payload.repository.owner.login,
576      });
577    });
578
579    it('should assign server jobs admin', () => {
580      expect(github.issues.addAssignees).toHaveBeenCalled();
581      expect(github.issues.addAssignees).toHaveBeenCalledWith({
582        issue_number: payloadData.payload.pull_request.number,
583        repo: payloadData.payload.repository.name,
584        owner: payloadData.payload.repository.owner.login,
585        assignees: ['vojtechjelinek']
586      });
587    });
588
589    it('should add datastore label', () => {
590      expect(github.issues.addLabels).toHaveBeenCalled();
591      expect(github.issues.addLabels).toHaveBeenCalledWith({
592        issue_number: payloadData.payload.pull_request.number,
593        repo: payloadData.payload.repository.name,
594        owner: payloadData.payload.repository.owner.login,
595        labels: ['PR: Affects datastore layer']
596      });
597    });
598  });
599
600  describe('When a new job file is created and registry is ' +
601    'updated in a pull request',
602  () => {
603    beforeEach(async () => {
604      github.pulls = {
605        listFiles: jasmine.createSpy('listFiles').and.resolveTo({
606          data: [
607            nonJobFile,
608            firstNewJobFileObj
609          ],
610        }),
611      };
612      payloadData.payload.pull_request.changed_files = 2;
613      await robot.receive(payloadData);
614    });
615
616    it('should check for jobs', () => {
617      expect(checkPullRequestJobModule.checkForNewJob).toHaveBeenCalled();
618    });
619
620    it('should get modified files', () => {
621      expect(github.pulls.listFiles).toHaveBeenCalled();
622    });
623
624    it('should ping server jobs admin', () => {
625      expect(github.issues.createComment).toHaveBeenCalled();
626      const author = payloadData.payload.pull_request.user.login;
627      const formText = (
628        'server jobs form'.link('https://goo.gl/forms/XIj00RJ2h5L55XzU2')
629      );
630      const newLineFeed = '<br>';
631      const wikiLinkText = 'this guide'.link(
632        JOBS_AND_FETURES_TESTING_WIKI_LINK);
633      const jobNameLink = (
634        'FirstTestJob'.link(firstNewJobFileObj.blob_url)
635      );
636      expect(github.issues.createComment).toHaveBeenCalledWith({
637        issue_number: payloadData.payload.pull_request.number,
638        body:
639            'Hi @vojtechjelinek, PTAL at this PR, ' +
640            'it adds a new job. The name of the job is ' + jobNameLink + '.' +
641            newLineFeed + 'Also @' + author +
642            ', please make sure to fill in the ' + formText +
643            ' for the new job to be tested on the backup server. ' +
644            'This PR can be merged only after the test run is successful. ' +
645            'Please refer to ' + wikiLinkText + ' for details.' +
646            newLineFeed + 'Thanks!',
647        repo: payloadData.payload.repository.name,
648        owner: payloadData.payload.repository.owner.login,
649      });
650    });
651
652    it('should assign server jobs admin', () => {
653      expect(github.issues.addAssignees).toHaveBeenCalled();
654      expect(github.issues.addAssignees).toHaveBeenCalledWith({
655        issue_number: payloadData.payload.pull_request.number,
656        repo: payloadData.payload.repository.name,
657        owner: payloadData.payload.repository.owner.login,
658        assignees: ['vojtechjelinek']
659      });
660    });
661
662    it('should add datastore label', () => {
663      expect(github.issues.addLabels).toHaveBeenCalled();
664      expect(github.issues.addLabels).toHaveBeenCalledWith({
665        issue_number: payloadData.payload.pull_request.number,
666        repo: payloadData.payload.repository.name,
667        owner: payloadData.payload.repository.owner.login,
668        labels: ['PR: Affects datastore layer']
669      });
670    });
671  }
672  );
673
674  describe('When a new job is added in an existing job file', () => {
675    beforeEach(async () => {
676      github.pulls = {
677        listFiles: jasmine.createSpy('listFiles').and.resolveTo({
678          data: [
679            modifiedExistingJobFileObj,
680          ],
681        }),
682      };
683      payloadData.payload.pull_request.changed_files = 1;
684      await robot.receive(payloadData);
685    });
686
687    it('should check for jobs', () => {
688      expect(checkPullRequestJobModule.checkForNewJob).toHaveBeenCalled();
689    });
690
691    it('should get modified files', () => {
692      expect(github.pulls.listFiles).toHaveBeenCalled();
693    });
694
695
696    it('should ping server jobs admin', () => {
697      expect(github.issues.createComment).toHaveBeenCalled();
698      const author = payloadData.payload.pull_request.user.login;
699      const formText = (
700        'server jobs form'.link('https://goo.gl/forms/XIj00RJ2h5L55XzU2')
701      );
702      const newLineFeed = '<br>';
703      const wikiLinkText = 'this guide'.link(
704        JOBS_AND_FETURES_TESTING_WIKI_LINK);
705      const jobRegistryLink = (
706        'job registry'.link(
707          'https://github.com/oppia/oppia/blob/develop/core/jobs_registry.py')
708      );
709      const jobNameLink = (
710        'OppiabotContributionsJob'
711          .link(modifiedExistingJobFileObj.blob_url)
712      );
713      expect(github.issues.createComment).toHaveBeenCalledWith({
714        issue_number: payloadData.payload.pull_request.number,
715        body:
716          'Hi @vojtechjelinek, PTAL at this PR, ' +
717          'it adds a new job. The name of the job is ' + jobNameLink +
718          '.' + newLineFeed + 'Also @' + author + ', please make sure to ' +
719          'fill in the ' + formText + ' for the new job to be tested on the ' +
720          'backup server. ' + 'This PR can be merged only after the test ' +
721          'run is successful. ' + 'Please refer to ' + wikiLinkText +
722          ' for details.' + newLineFeed + 'Thanks!',
723        repo: payloadData.payload.repository.name,
724        owner: payloadData.payload.repository.owner.login,
725      });
726    });
727
728    it('should assign server jobs admin', () => {
729      expect(github.issues.addAssignees).toHaveBeenCalled();
730      expect(github.issues.addAssignees).toHaveBeenCalledWith({
731        issue_number: payloadData.payload.pull_request.number,
732        repo: payloadData.payload.repository.name,
733        owner: payloadData.payload.repository.owner.login,
734        assignees: ['vojtechjelinek']
735      });
736    });
737
738    it('should add datastore label', () => {
739      expect(github.issues.addLabels).toHaveBeenCalled();
740      expect(github.issues.addLabels).toHaveBeenCalledWith({
741        issue_number: payloadData.payload.pull_request.number,
742        repo: payloadData.payload.repository.name,
743        owner: payloadData.payload.repository.owner.login,
744        labels: ['PR: Affects datastore layer']
745      });
746    });
747  });
748
749  describe('When an existing job file is modified with no new job', () => {
750    beforeEach(async () => {
751      github.pulls = {
752        listFiles: jasmine.createSpy('listFiles').and.resolveTo({
753          data: [
754            {
755              ...firstNewJobFileObj,
756              status: 'modified',
757              patch: '\n+# No job files present in the changes',
758            },
759          ],
760        }),
761      };
762
763      payloadData.payload.pull_request.changed_files = 1;
764      await robot.receive(payloadData);
765    });
766
767    it('should check for jobs', () => {
768      expect(checkPullRequestJobModule.checkForNewJob).toHaveBeenCalled();
769    });
770
771    it('should get modified files', () => {
772      expect(github.pulls.listFiles).toHaveBeenCalled();
773    });
774
775
776    it('should not ping server jobs admin', () => {
777      expect(github.issues.createComment).not.toHaveBeenCalled();
778    });
779    it('should not add datastore label', () => {
780      expect(github.issues.addLabels).not.toHaveBeenCalled();
781    });
782    it('should not assign server jobs admin', () => {
783      expect(github.issues.addAssignees).not.toHaveBeenCalled();
784    });
785  });
786
787  describe('When no job file is modified in a pull request', () => {
788    beforeEach(async () => {
789      github.pulls = {
790        listFiles: jasmine.createSpy('listFiles').and.resolveTo({
791          data: [
792            nonJobFile
793          ],
794        }),
795      };
796
797      payloadData.payload.pull_request.changed_files = 1;
798      await robot.receive(payloadData);
799    });
800
801    it('should check for jobs', () => {
802      expect(checkPullRequestJobModule.checkForNewJob).toHaveBeenCalled();
803    });
804
805    it('should not get modified files', () => {
806      expect(github.pulls.listFiles).toHaveBeenCalled();
807    });
808
809    it('should not ping server job admin', () => {
810      expect(github.issues.createComment).not.toHaveBeenCalled();
811    });
812  });
813
814  describe('Does not comment on job from test dir', () => {
815    beforeEach(async () => {
816      github.pulls = {
817        listFiles: jasmine.createSpy('listFiles').and.resolveTo({
818          data: [
819            jobFromTestDir
820          ],
821        }),
822      };
823
824      payloadData.payload.pull_request.changed_files = 1;
825      await robot.receive(payloadData);
826    });
827
828    it('should check for jobs', () => {
829      expect(checkPullRequestJobModule.checkForNewJob).toHaveBeenCalled();
830    });
831
832    it('should get modified files', () => {
833      expect(github.pulls.listFiles).toHaveBeenCalled();
834    });
835
836    it('should not ping server job admin', () => {
837      expect(github.issues.createComment).not.toHaveBeenCalled();
838    });
839  });
840
841  describe('When job test file gets added', () => {
842    beforeEach(async () => {
843      github.pulls = {
844        listFiles: jasmine.createSpy('listFiles').and.resolveTo({
845          data: [
846            jobTestFile
847          ],
848        }),
849      };
850
851      payloadData.payload.pull_request.changed_files = 1;
852      await robot.receive(payloadData);
853    });
854
855    it('should check for jobs', () => {
856      expect(checkPullRequestJobModule.checkForNewJob).toHaveBeenCalled();
857    });
858
859    it('should get modified files', () => {
860      expect(github.pulls.listFiles).toHaveBeenCalled();
861    });
862
863    it('should not ping server job admin', () => {
864      expect(github.issues.createComment).not.toHaveBeenCalled();
865    });
866  });
867
868  describe('When pull request has datastore label', () => {
869    beforeEach(async () => {
870      payloadData.payload.pull_request.labels = [{
871        name: 'PR: Affects datastore layer'
872      }];
873      github.pulls = {
874        listFiles: jasmine.createSpy('listFiles').and.resolveTo({
875          data: [
876            nonJobFile, firstNewJobFileObj
877          ],
878        }),
879      };
880
881      payloadData.payload.pull_request.changed_files = 2;
882      await robot.receive(payloadData);
883    });
884
885    it('should check for jobs', () => {
886      expect(checkPullRequestJobModule.checkForNewJob).toHaveBeenCalled();
887    });
888
889    it('should not get modified files', () => {
890      expect(github.pulls.listFiles).not.toHaveBeenCalled();
891    });
892
893    it('should not ping server job admin', () => {
894      expect(github.issues.createComment).not.toHaveBeenCalled();
895    });
896  });
897
898  describe('Returns appropriate job name', () => {
899    it('should return the correct job created in the file', () => {
900      let jobs = checkPullRequestJobModule.getNewJobsFromFile(
901        firstNewJobFileObj
902      );
903      expect(jobs.length).toBe(1);
904      expect(jobs[0]).toBe('FirstTestJob');
905
906      jobs = checkPullRequestJobModule.getNewJobsFromFile(secondNewJobFileObj);
907      expect(jobs.length).toBe(1);
908      expect(jobs[0]).toBe('SecondTestJob');
909
910      jobs = checkPullRequestJobModule.getNewJobsFromFile(
911        modifiedExistingJobFileObj
912      );
913      expect(jobs.length).toBe(1);
914      expect(jobs[0]).toBe('OppiabotContributionsJob');
915
916      jobs = checkPullRequestJobModule.getNewJobsFromFile(fileWithMultipleJobs);
917      expect(jobs.length).toBe(2);
918      expect(jobs[0]).toBe('TestJob');
919      expect(jobs[1]).toBe('AnotherTestJob');
920
921      jobs = checkPullRequestJobModule.getNewJobsFromFile(jobTestFile);
922      expect(jobs.length).toBe(0);
923
924      jobs = checkPullRequestJobModule.getNewJobsFromFile(
925        modifiedExistingJobFileObjWithJobClassInPatch);
926      expect(jobs.length).toBe(0);
927
928      jobs = checkPullRequestJobModule.getNewJobsFromFile(
929        jobFileObjWithJobClassInPatchAndNewJob);
930      expect(jobs.length).toBe(1);
931      expect(jobs[0]).toBe('AnotherTestJob');
932    });
933  });
934});
935
Full Screen

utilsSpec.js

Source: utilsSpec.js Github

copy
1// Copyright 2020 The Oppia Authors. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS-IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15/**
16 * @fileoverview Tests for the helper module.
17 */
18const { 'default': Axios } = require('axios');
19const utilityModule = require('../lib/utils');
20const pullRequest = require('../fixtures/pullRequestPayload.json').payload
21  .pull_request;
22const CODE_OWNERS_FILE_URL =
23  'https://raw.githubusercontent.com/oppia/oppia/develop/.github/CODEOWNERS';
24
25describe('Utility module tests', () => {
26  const firstModelFileObj = {
27    sha: 'd144f32b9812373d5f1bc9f94d9af795f09023ff',
28    filename: 'core/storage/skill/gae_models.py',
29    status: 'added',
30    additions: 1,
31    deletions: 0,
32    changes: 1,
33    blob_url:
34      'https://github.com/oppia/oppia/blob/67fb4a973b318882af3b5a894130' +
35      'e110d7e9833c/core/storage/skill/gae_models.py',
36    raw_url:
37      'https://github.com/oppia/oppia/raw/67fb4a973b318882af3b5a894130e' +
38      '110d7e9833c/core/storage/skill/gae_models.py',
39    contents_url:
40      'https://api.github.com/repos/oppia/oppia/contents/core/storage/s' +
41      'kill/gae_models.py?ref=67fb4a973b318882af3b5a894130e110d7e9833c',
42    patch:
43      '@@ -353,6 +353,11 @@ def export_data(user_id):\r\n         }\r\n ' +
44      '\r\n \r\n+class OppiabotTestActivitiesModel(base_models.BaseModel):' +
45      '\r\n+    "Does some things right"\r\n+    pass\r\n+\r\n+\r\n class ' +
46      'IncompleteActivitiesModel(base_models.BaseModel):\r\n     """Keeps ' +
47      'track of all the activities currently being completed by the\r\n   ' +
48      'learner.\r\n',
49  };
50
51  const firstJobFileObj = {
52    sha: 'd144f32b9812373d5f1bc9f94d9af795f09023ff',
53    filename: 'core/domain/exp_jobs_one_off.py',
54    status: 'added',
55    additions: 1,
56    deletions: 0,
57    changes: 1,
58    blob_url:
59      'https://github.com/oppia/oppia/blob/67fb4a973b318882af3b5a894130e11' +
60      '0d7e9833c/core/domain/exp_jobs_one_off.py',
61    raw_url:
62      'https://github.com/oppia/oppia/raw/67fb4a973b318882af3b5a894130e110d' +
63      '7e9833c/core/domain/exp_jobs_one_off.py',
64    contents_url:
65      'https://api.github.com/repos/oppia/oppia/contents/core/domain/exp_job' +
66      's_one_off.py?ref=67fb4a973b318882af3b5a894130e110d7e9833c',
67    patch:
68      '@@ -0,0 +1 @@\n+class FirstTestOneOffJob(jobs.BaseMapReduceOneOffJobM' +
69      ') for v in version_and_exp_ids]\n+\n+        for edit in edits:\n+   ',
70  };
71
72  const secondModelFileObj = {
73    sha: 'd144f32b9812373d5f1bc9f94d9af795f09023ff',
74    filename: 'core/storage/skill/gae_models.py',
75    status: 'modified',
76    additions: 1,
77    deletions: 0,
78    changes: 1,
79    blob_url:
80      'https://github.com/oppia/oppia/blob/67fb4a973b318882af3b5a894130e110' +
81      'd7e9833c/core/storage/skill/gae_models.py',
82    raw_url:
83      'https://github.com/oppia/oppia/raw/67fb4a973b318882af3b5a894130e110d' +
84      '7e9833c/core/storage/skill/gae_models.py',
85    contents_url:
86      'https://api.github.com/repos/oppia/oppia/contents/core/storage/skill/' +
87      'gae_models.py?ref=67fb4a973b318882af3b5a894130e110d7e9833c',
88    patch:
89      '@@ -39,6 +39,20 @@ class SkillSnapshotContentModel(base_models.BaseSn' +
90      'apshotContentModel):\r\n     pass\r\n \r\n \r\n+class OppiabotSnapsho' +
91      'tContentModel(base_models.BaseSnapshotContentModel):\r\n+    """Oppia' +
92      'bot testing."""\r\n+\r\n+    pass\r\n+\r\n+\r\n+class OppiabotSnapsho' +
93      'tTestingModel(base_models.BaseSnapshotContentModel):\r\n+    """Anoth' +
94      'er Oppiabot model."""\r\n+\r\n+    pass\r\n+\r\n+\r\n+\r\n+\r\n class' +
95      ' SkillModel(base_models.VersionedModel):\r\n     """Model for storing' +
96      ' Skills.\r\n',
97  };
98
99  const secondJobFileObj = {
100    sha: 'd144f32b9812373d5f1bc9f94d9af795f09023ff',
101    filename: 'core/domain/exp_jobs_oppiabot_off.py',
102    status: 'added',
103    additions: 1,
104    deletions: 0,
105    changes: 1,
106    blob_url:
107      'https://github.com/oppia/oppia/blob/67fb4a973b318882af3b5a894130e11' +
108      '0d7e9833c/core/domain/exp_jobs_oppiabot_off.py',
109    raw_url:
110      'https://github.com/oppia/oppia/raw/67fb4a973b318882af3b5a894130e110' +
111      'd7e9833c/core/domain/exp_jobs_oppiabot_off.py',
112    contents_url:
113      'https://api.github.com/repos/oppia/oppia/contents/core/domain/exp_jo' +
114      'bs_oppiabot_off.py?ref=67fb4a973b318882af3b5a894130e110d7e9833c',
115    patch:
116      '@@ -0,0 +1 @@\n+class SecondTestOneOffJob(jobs.BaseMapReduceOneOffJob' +
117      'Manager):\n+    """One-off job for creating and populating UserContri' +
118      'butionsModels for\n+    all registered users that have contributed.\n' +
119      '+    """\n+    @classmethod\n+    def entity_classes_to_map_over(cls)' +
120      ':\n+        """Return a list of datastore class references to map ove' +
121      'r."""\n+        return [exp_models.ExplorationSnapshotMetadataModel]\n+',
122  };
123
124  const jobRegex = new RegExp(
125    [
126      '(?<addition>\\+)(?<classDefinition>class\\s)',
127      '(?<name>[a-zA-Z]{2,256})(?<suffix>OneOffJob)(?<funDef>\\()',
128    ].join('')
129  );
130
131  const modelRegex = new RegExp(
132    [
133      '(?<addition>\\+)(?<classDefinition>class\\s)',
134      '(?<name>[a-zA-Z]{2,256})(?<suffix>Model)(?<funDef>\\()',
135    ].join('')
136  );
137
138  it('should check for datastore labels', () => {
139    let result = utilityModule.hasDatastoreLabel(pullRequest);
140    expect(result).toBe(false);
141
142    result = utilityModule.hasDatastoreLabel({
143      ...pullRequest,
144      labels: [{ name: 'PR: Affects datastore layer' }],
145    });
146    expect(result).toBe(true);
147  });
148
149  it('should return appropriate name string', () => {
150    let result = utilityModule.getNameString(
151      [firstModelFileObj],
152      {
153        singular: 'model',
154        plural: 'models',
155      },
156      modelRegex
157    );
158    let itemLink = 'OppiabotTestActivitiesModel'.link(
159      firstModelFileObj.blob_url
160    );
161    expect(result).toBe(' The name of the model is ' + itemLink + '.');
162
163    result = utilityModule.getNameString(
164      [firstModelFileObj, secondModelFileObj],
165      {
166        singular: 'model',
167        plural: 'models',
168      },
169      modelRegex
170    );
171    firstItemLink = 'OppiabotTestActivitiesModel'.link(
172      firstModelFileObj.blob_url
173    );
174    let secondItemLink =
175    'OppiabotSnapshotContentModel, OppiabotSnapshotTestingModel'
176      .link(
177        secondModelFileObj.blob_url
178      );
179    expect(result).toBe(
180      ' The models are ' + itemLink + ', ' + secondItemLink + '.'
181    );
182
183    result = utilityModule.getNameString(
184      [firstJobFileObj],
185      {
186        singular: 'job',
187        plural: 'jobs',
188      },
189      jobRegex
190    );
191    itemLink = 'FirstTestOneOffJob'.link(firstJobFileObj.blob_url);
192    expect(result).toBe(' The name of the job is ' + itemLink + '.');
193
194    result = utilityModule.getNameString(
195      [firstJobFileObj, secondJobFileObj],
196      {
197        singular: 'job',
198        plural: 'jobs',
199      },
200      jobRegex
201    );
202    itemLink = 'FirstTestOneOffJob'.link(firstJobFileObj.blob_url);
203    secondItemLink = 'SecondTestOneOffJob'.link(secondJobFileObj.blob_url);
204    expect(result).toBe(
205      ' The jobs are ' + itemLink + ', ' + secondItemLink + '.'
206    );
207  });
208
209  it('should return appropriate items by regex', () => {
210    let result = utilityModule.getNewItemsFromFileByRegex(
211      modelRegex,
212      firstModelFileObj
213    );
214    expect(result.length).toBe(1);
215    expect(result[0]).toBe('OppiabotTestActivitiesModel');
216
217    result = utilityModule.getNewItemsFromFileByRegex(
218      modelRegex,
219      secondModelFileObj
220    );
221    expect(result.length).toBe(2);
222    expect(result[0]).toBe('OppiabotSnapshotContentModel');
223    expect(result[1]).toBe('OppiabotSnapshotTestingModel');
224
225    result = utilityModule.getNewItemsFromFileByRegex(
226      jobRegex,
227      firstJobFileObj
228    );
229    expect(result.length).toBe(1);
230    expect(result[0]).toBe('FirstTestOneOffJob');
231
232    result = utilityModule.getNewItemsFromFileByRegex(
233      jobRegex,
234      secondJobFileObj
235    );
236    expect(result.length).toBe(1);
237    expect(result[0]).toBe('SecondTestOneOffJob');
238  });
239
240  it('should get all changed files', async () => {
241    const context = {
242      repo: (obj) => {
243        return {
244          ...obj,
245          repo: 'oppia',
246          owner: 'oppia',
247        };
248      },
249      payload: {
250        pull_request: { ...pullRequest, changed_files: 2 },
251      },
252      github: {
253        pulls: {
254          listFiles: () => {
255            return {
256              data: [firstModelFileObj, firstJobFileObj],
257            };
258          },
259        },
260      },
261    };
262
263    const result = await utilityModule.getAllChangedFiles(context);
264    expect(result.length).toBe(2);
265    expect(result).toEqual([firstModelFileObj, firstJobFileObj]);
266  });
267
268  it('should get main code owner file from develop', async () => {
269    spyOn(Axios, 'get').and.resolveTo({
270      data: 'Contents of code owner file.',
271    });
272    const response = await utilityModule.getMainCodeOwnerfile();
273    expect(Axios.get).toHaveBeenCalled();
274    expect(Axios.get).toHaveBeenCalledWith(CODE_OWNERS_FILE_URL);
275    expect(response).toBe('Contents of code owner file.');
276  });
277
278  it('should check if a label is a changelog label', () => {
279    let response = utilityModule.isChangelogLabel(
280      'PR CHANGELOG: Angular Migration'
281    );
282    expect(response).toBe(true);
283    response = utilityModule.isChangelogLabel('An invalid label');
284    expect(response).toBe(false);
285  });
286
287  it('should get all open pull requests', async () => {
288    const context = {
289      github: {
290        pulls: {
291          list: jasmine.createSpy('list').and.resolveTo({
292            data: [
293              {
294                number: 101,
295                body: 'sample pull request body',
296              },
297            ],
298          }),
299        },
300      },
301      repo: jasmine.createSpy('repo').and.callFake((params) => {
302        return {
303          repo: 'oppia',
304          owner: 'oppia',
305          ...params,
306        };
307      }),
308    };
309
310    let openPRs = await utilityModule.getAllOpenPullRequests(context);
311    expect(openPRs.length).toBe(1);
312    expect(openPRs[0].number).toBe(101);
313    expect(context.github.pulls.list).toHaveBeenCalled();
314    expect(context.github.pulls.list).toHaveBeenCalledWith({
315      repo: 'oppia',
316      owner: 'oppia',
317      per_page: 60,
318      state: 'open',
319    });
320
321    context.github.pulls.list = jasmine.createSpy('list').and.resolveTo({
322      data: [
323        {
324          number: 101,
325          body: 'sample pull request body',
326        },
327        {
328          number: 102,
329          body: 'another sample pull request body',
330        },
331      ],
332    });
333
334    openPRs = await utilityModule.getAllOpenPullRequests(context);
335    expect(openPRs.length).toBe(2);
336    expect(openPRs[0].number).toBe(101);
337    expect(openPRs[1].number).toBe(102);
338  });
339
340  it('should check that a pull request has been approved', async () => {
341    const context = {
342      payload: {
343        repository: {
344          full_name: 'oppia/oppia',
345        },
346      },
347      github: {
348        search: {
349          issuesAndPullRequests: jasmine
350            .createSpy('issuesAndPullRequests')
351            .and.resolveTo({
352              status: 200,
353              data: {
354                items: [pullRequest],
355              },
356            }),
357        },
358      },
359      repo: jasmine.createSpy('repo').and.callFake((params) => {
360        return {
361          repo: 'oppia',
362          owner: 'oppia',
363          ...params,
364        };
365      }),
366    };
367
368    let response = await utilityModule.hasPullRequestBeenApproved(context, 101);
369    expect(response).toBe(true);
370    expect(context.github.search.issuesAndPullRequests).toHaveBeenCalled();
371    expect(context.github.search.issuesAndPullRequests).toHaveBeenCalledWith({
372      repo: 'oppia',
373      owner: 'oppia',
374      q: 'repo:oppia/oppia review:approved 101',
375    });
376
377    context.github.search.issuesAndPullRequests = jasmine
378      .createSpy('issuesAndPullRequests')
379      .and.resolveTo({
380        status: 200,
381        data: {
382          items: [],
383        },
384      });
385
386    response = await utilityModule.hasPullRequestBeenApproved(context, 102);
387    expect(response).toBe(false);
388    expect(context.github.search.issuesAndPullRequests).toHaveBeenCalled();
389    expect(context.github.search.issuesAndPullRequests).toHaveBeenCalledWith({
390      repo: 'oppia',
391      owner: 'oppia',
392      q: 'repo:oppia/oppia review:approved 102',
393    });
394  });
395
396  it('should check that a pull request has changes requested', async () => {
397    const context = {
398      payload: {
399        repository: {
400          full_name: 'oppia/oppia',
401        },
402      },
403      github: {
404        search: {
405          issuesAndPullRequests: jasmine
406            .createSpy('issuesAndPullRequests')
407            .and.resolveTo({
408              status: 200,
409              data: {
410                items: [pullRequest],
411              },
412            }),
413        },
414      },
415      repo: jasmine.createSpy('repo').and.callFake((params) => {
416        return {
417          repo: 'oppia',
418          owner: 'oppia',
419          ...params,
420        };
421      }),
422    };
423
424    let response = await utilityModule.doesPullRequestHaveChangesRequested(
425      context,
426      101
427    );
428    expect(response).toBe(true);
429    expect(context.github.search.issuesAndPullRequests).toHaveBeenCalled();
430    expect(context.github.search.issuesAndPullRequests).toHaveBeenCalledWith({
431      repo: 'oppia',
432      owner: 'oppia',
433      q: 'repo:oppia/oppia review:changes_requested 101',
434    });
435
436    context.github.search.issuesAndPullRequests = jasmine
437      .createSpy('issuesAndPullRequests')
438      .and.resolveTo({
439        status: 200,
440        data: {
441          items: [],
442        },
443      });
444    response = await utilityModule.doesPullRequestHaveChangesRequested(
445      context,
446      102
447    );
448    expect(response).toBe(false);
449    expect(context.github.search.issuesAndPullRequests).toHaveBeenCalled();
450    expect(context.github.search.issuesAndPullRequests).toHaveBeenCalledWith({
451      repo: 'oppia',
452      owner: 'oppia',
453      q: 'repo:oppia/oppia review:changes_requested 102',
454    });
455  });
456
457  it('should check if a user is a member of the organisation', async () => {
458    const context = {
459      github: {
460        orgs: {
461          checkMembership: jasmine.createSpy('checkMembership').and.resolveTo({
462            status: 204,
463          }),
464        },
465      },
466    };
467
468    let response = await utilityModule.isUserAMemberOfTheOrganisation(
469      context,
470      'testuser'
471    );
472    expect(response).toBe(true);
473    expect(context.github.orgs.checkMembership).toHaveBeenCalled();
474    expect(context.github.orgs.checkMembership).toHaveBeenCalledWith({
475      org: 'oppia',
476      username: 'testuser',
477    });
478
479    context.github.orgs.checkMembership = jasmine
480      .createSpy('checkMembership')
481      .and.callFake(() => {
482        throw new Error(
483          'User does not exist or is not a public member of ' +
484            'the organization.'
485        );
486      });
487    response = await utilityModule.isUserAMemberOfTheOrganisation(
488      context,
489      'testuser'
490    );
491    expect(response).toBe(false);
492  });
493
494  it('should check if a user is a collaborator', async () => {
495    const context = {
496      repo() {
497        return {
498          owner: 'oppia',
499          repo: 'oppia'
500        };
501      },
502      github: {
503        repos: {
504          checkCollaborator: jasmine
505            .createSpy('checkCollaborator')
506            .and.resolveTo({
507              status: 204,
508            }),
509        },
510      },
511    };
512
513    let response = await utilityModule.isUserCollaborator(
514      context,
515      'testuser'
516    );
517    expect(response).toBe(true);
518    expect(context.github.repos.checkCollaborator).toHaveBeenCalled();
519    expect(context.github.repos.checkCollaborator).toHaveBeenCalledWith({
520      owner: 'oppia',
521      repo: 'oppia',
522      username: 'testuser',
523    });
524
525    context.github.repos.checkCollaborator = jasmine
526      .createSpy('checkCollaborator')
527      .and.callFake(() => {
528        throw new Error(
529          'User is not a collaborator.'
530        );
531      });
532    response = await utilityModule.isUserCollaborator(
533      context,
534      'testuser'
535    );
536    expect(response).toBe(false);
537  });
538
539  it('should get changelog label from a pull request', () => {
540    const label = {
541      name: 'PR CHANGELOG: Angular Migration',
542    };
543    pullRequest.labels.push(label);
544
545    let response = utilityModule.getChangelogLabelFromPullRequest(pullRequest);
546    expect(response).toBe('PR CHANGELOG: Angular Migration');
547
548    pullRequest.labels = [];
549    response = utilityModule.getChangelogLabelFromPullRequest(pullRequest);
550    expect(response).toBe(undefined);
551  });
552
553  it('should get progect owner from a changelog label', () => {
554    let response = utilityModule.getProjectOwnerFromLabel(
555      'PR CHANGELOG: Miscellaneous -- @ankita240796'
556    );
557    expect(response).toBe('ankita240796');
558  });
559
560  it('should get github usernames from text', () => {
561    let text = '@U8NWXD PTAL!';
562    let usernames = utilityModule.getUsernamesFromText(text);
563    expect(usernames.length).toBe(1);
564    expect(usernames[0]).toBe('U8NWXD');
565
566    text = '@aks681 @seanlip PTAL!';
567    usernames = utilityModule.getUsernamesFromText(text);
568    expect(usernames.length).toBe(2);
569    expect(usernames[0]).toBe('aks681');
570    expect(usernames[1]).toBe('seanlip');
571
572    text = `@DubeySandeep, done I've created the issue(#10419 )
573      and addressed your comments.
574      @seanlip @aks681 PTAL`;
575    usernames = utilityModule.getUsernamesFromText(text);
576    expect(usernames.length).toBe(3);
577    expect(usernames[0]).toBe('DubeySandeep');
578    expect(usernames[1]).toBe('seanlip');
579    expect(usernames[2]).toBe('aks681');
580
581    text = 'Hi @U8NWXD, please take a look, thanks!';
582    usernames = utilityModule.getUsernamesFromText(text);
583    expect(usernames.length).toBe(1);
584    expect(usernames[0]).toBe('U8NWXD');
585
586    text = "@aks681 @seanlip I've addressed all comments, please take a look.!";
587    usernames = utilityModule.getUsernamesFromText(text);
588    expect(usernames.length).toBe(2);
589    expect(usernames[0]).toBe('aks681');
590    expect(usernames[1]).toBe('seanlip');
591
592    text = `@DubeySandeep, done I've created the issue(#10419 )
593      and addressed your comments.
594      @seanlip @aks681 please take a look`;
595    usernames = utilityModule.getUsernamesFromText(text);
596    expect(usernames.length).toBe(3);
597    expect(usernames[0]).toBe('DubeySandeep');
598    expect(usernames[1]).toBe('seanlip');
599    expect(usernames[2]).toBe('aks681');
600
601    text = 'A random text containing no users';
602    usernames = utilityModule.getUsernamesFromText(text);
603    expect(usernames.length).toBe(0);
604  });
605});
606
Full Screen

github.js

Source: github.js Github

copy
1const { Octokit } = require("@octokit/rest");
2
3module.exports = { getOpenPRs, postComment };
4
5async function getOpenPRs(token, owner, repo) {
6  const github = githubAuth(token);
7
8  const res = await github.pulls.list({
9    state: "open",
10    owner,
11    repo,
12  });
13
14  return res.data.map((pr) => pr.number);
15}
16
17async function postComment(token, owner, repo, pullRequestNumber, surgeURI) {
18  const github = githubAuth(token);
19
20  await github.issues.createComment({
21    owner,
22    repo,
23    // eslint-disable-next-line camelcase
24    issue_number: pullRequestNumber,
25    body: `Deployment for QA: [${surgeURI}](http://${surgeURI})`,
26  });
27}
28
29function githubAuth(token) {
30  return new Octokit({
31    auth: token,
32  });
33}
34
Full Screen

Accelerate Your Automation Test Cycles With LambdaTest

Leverage LambdaTest’s cloud-based platform to execute your automation tests in parallel and trim down your test execution time significantly. Your first 100 automation testing minutes are on us.

Try LambdaTest

Run JavaScript Tests on LambdaTest Cloud Grid

Execute automation tests with Cypress on a cloud-based Grid of 3000+ real browsers and operating systems for both web and mobile applications.

Test now for Free
LambdaTestX

We use cookies to give you the best experience. Cookies help to provide a more personalized experience and relevant advertising for you, and web analytics for us. Learn More in our Cookies policy, Privacy & Terms of service

Allow Cookie
Sarah

I hope you find the best code examples for your project.

If you want to accelerate automated browser testing, try LambdaTest. Your first 100 automation testing minutes are FREE.

Sarah Elson (Product & Growth Lead)