Repository: badges/shields
Pull request #3008 (2019-02-17 11:30:47)

refactor [bugzilla] service

shields-ci: 
<!--
  0 failure: 
  0 warning: 
  1 messages
  
  DangerID: danger-id-default;
-->



<table>
  <thead>
    <tr>
      <th width="50"></th>
      <th width="100%" data-danger-table="true">Messages</th>
    </tr>
  </thead>
  <tbody><tr>
      <td>:book:</td>
      <td>:sparkles: Thanks for your contribution to Shields, @chris48s!</td>
    </tr>
  </tbody>
</table>


<p align="right">
  Generated by :no_entry_sign: <a href="https://danger.systems/js">dangerJS</a> against dc596a9f28e77afa9deebefcab58f9576ad46842
</p>


Patch:
diff --git a/services/bugzilla/bugzilla.service.js b/services/bugzilla/bugzilla.service.js
index 06d602ba54..069dda299f 100644
--- a/services/bugzilla/bugzilla.service.js
+++ b/services/bugzilla/bugzilla.service.js
@@ -1,8 +1,9 @@
 'use strict'
 
-const LegacyService = require('../legacy-service')
-const { makeBadgeData: getBadgeData } = require('../../lib/badge-data')
-const { checkErrorResponse } = require('../../lib/error-helper')
+const Joi = require('joi')
+const { BaseJsonService } = require('..')
+
+const schema = Joi.any()
 
 const documentation = `
 <p>
@@ -10,13 +11,7 @@ const documentation = `
 </p>
 `
 
-// This legacy service should be rewritten to use e.g. BaseJsonService.
-//
-// Tips for rewriting:
-// https://github.com/badges/shields/blob/master/doc/rewriting-services.md
-//
-// Do not base new services on this code.
-module.exports = class Bugzilla extends LegacyService {
+module.exports = class Bugzilla extends BaseJsonService {
   static get category() {
     return 'issue-tracking'
   }
@@ -33,82 +28,73 @@ module.exports = class Bugzilla extends LegacyService {
       {
         title: 'Bugzilla bug status',
         namedParams: { bugNumber: '996038' },
-        staticPreview: {
-          label: 'bug 996038',
-          message: 'fixed',
-          color: 'brightgreen',
-        },
+        staticPreview: this.render({
+          bugNumber: 996038,
+          status: 'FIXED',
+          resolution: '',
+        }),
         documentation,
       },
     ]
   }
 
-  static registerLegacyRouteHandler({ camp, cache }) {
-    camp.route(
-      /^\/bugzilla\/(\d+)\.(svg|png|gif|jpg|json)$/,
-      cache((data, match, sendBadge, request) => {
-        const bugNumber = match[1] // eg, 1436739
-        const format = match[2]
-        const options = {
-          method: 'GET',
-          json: true,
-          uri: `https://bugzilla.mozilla.org/rest/bug/${bugNumber}`,
-        }
-        const badgeData = getBadgeData(`bug ${bugNumber}`, data)
-        request(options, (err, res, json) => {
-          if (checkErrorResponse(badgeData, err, res)) {
-            sendBadge(format, badgeData)
-            return
-          }
-          try {
-            const bug = json.bugs[0]
+  static get defaultBadgeData() {
+    return { label: 'bugzilla' }
+  }
+
+  async fetch({ bugNumber }) {
+    return this._requestJson({
+      schema,
+      url: `https://bugzilla.mozilla.org/rest/bug/${bugNumber}`,
+    })
+  }
+
+  static getDisplayStatus({ status, resolution }) {
+    let displayStatus =
+      status === 'RESOLVED' ? resolution.toLowerCase() : status.toLowerCase()
+    if (displayStatus === 'worksforme') {
+      displayStatus = 'works for me'
+    }
+    if (displayStatus === 'wontfix') {
+      displayStatus = "won't fix"
+    }
+    return displayStatus
+  }
+
+  static getColor({ displayStatus }) {
+    const colorMap = {
+      unconfirmed: 'blue',
+      new: 'blue',
+      assigned: 'green',
+      fixed: 'brightgreen',
+      invalid: 'yellow',
+      "won't fix": 'orange',
+      duplicate: 'lightgrey',
+      'works for me': 'yellowgreen',
+      incomplete: 'red',
+    }
+    if (displayStatus in colorMap) {
+      return colorMap[displayStatus]
+    }
+    return 'lightgrey'
+  }
+
+  static render({ bugNumber, status, resolution }) {
+    const displayStatus = this.getDisplayStatus({ status, resolution })
+    const color = this.getColor({ displayStatus })
+    return {
+      label: `bug ${bugNumber}`,
+      message: displayStatus,
+      color,
+    }
+  }
 
-            switch (bug.status) {
-              case 'UNCONFIRMED':
-                badgeData.text[1] = 'unconfirmed'
-                badgeData.colorscheme = 'blue'
-                break
-              case 'NEW':
-                badgeData.text[1] = 'new'
-                badgeData.colorscheme = 'blue'
-                break
-              case 'ASSIGNED':
-                badgeData.text[1] = 'assigned'
-                badgeData.colorscheme = 'green'
-                break
-              case 'RESOLVED':
-                if (bug.resolution === 'FIXED') {
-                  badgeData.text[1] = 'fixed'
-                  badgeData.colorscheme = 'brightgreen'
-                } else if (bug.resolution === 'INVALID') {
-                  badgeData.text[1] = 'invalid'
-                  badgeData.colorscheme = 'yellow'
-                } else if (bug.resolution === 'WONTFIX') {
-                  badgeData.text[1] = "won't fix"
-                  badgeData.colorscheme = 'orange'
-                } else if (bug.resolution === 'DUPLICATE') {
-                  badgeData.text[1] = 'duplicate'
-                  badgeData.colorscheme = 'lightgrey'
-                } else if (bug.resolution === 'WORKSFORME') {
-                  badgeData.text[1] = 'works for me'
-                  badgeData.colorscheme = 'yellowgreen'
-                } else if (bug.resolution === 'INCOMPLETE') {
-                  badgeData.text[1] = 'incomplete'
-                  badgeData.colorscheme = 'red'
-                } else {
-                  badgeData.text[1] = 'unknown'
-                }
-                break
-              default:
-                badgeData.text[1] = 'unknown'
-            }
-            sendBadge(format, badgeData)
-          } catch (e) {
-            badgeData.text[1] = 'unknown'
-            sendBadge(format, badgeData)
-          }
-        })
-      })
-    )
+  async handle({ bugNumber }) {
+    const data = await this.fetch({ bugNumber })
+    return this.constructor.render({
+      bugNumber,
+      status: data.bugs[0].status,
+      resolution: data.bugs[0].resolution,
+    })
   }
 }
diff --git a/services/bugzilla/bugzilla.spec.js b/services/bugzilla/bugzilla.spec.js
new file mode 100644
index 0000000000..89453c32ae
--- /dev/null
+++ b/services/bugzilla/bugzilla.spec.js
@@ -0,0 +1,16 @@
+'use strict'
+
+const { test, given } = require('sazerac')
+const Bugzilla = require('./bugzilla.service')
+
+describe('getDisplayStatus function', function() {
+  it('formats status correctly', async function() {
+    test(Bugzilla.getDisplayStatus, () => {
+      given({ status: 'RESOLVED', resolution: 'WORKSFORME' }).expect(
+        'works for me'
+      )
+      given({ status: 'RESOLVED', resolution: 'WONTFIX' }).expect("won't fix")
+      given({ status: 'ASSIGNED', resolution: '' }).expect('assigned')
+    })
+  })
+})


Test patch:
diff --git a/services/bugzilla/bugzilla.tester.js b/services/bugzilla/bugzilla.tester.js
index 24b0a41eef..9d2d4ebd37 100644
--- a/services/bugzilla/bugzilla.tester.js
+++ b/services/bugzilla/bugzilla.tester.js
@@ -1,7 +1,7 @@
 'use strict'
 
 const Joi = require('joi')
-const { ServiceTester } = require('../tester')
+const t = (module.exports = require('../tester').createServiceTester())
 
 const bzBugStatus = Joi.equal(
   'unconfirmed',
@@ -15,11 +15,6 @@ const bzBugStatus = Joi.equal(
   'incomplete'
 )
 
-const t = (module.exports = new ServiceTester({
-  id: 'bugzilla',
-  title: 'Bugzilla',
-}))
-
 t.create('Bugzilla valid bug status')
   .get('/996038.json')
   .expectJSONTypes(
@@ -31,9 +26,4 @@ t.create('Bugzilla valid bug status')
 
 t.create('Bugzilla invalid bug status')
   .get('/83548978974387943879.json')
-  .expectJSON({ name: 'bug 83548978974387943879', value: 'not found' })
-
-t.create('Bugzilla failed request bug status')
-  .get('/996038.json')
-  .networkOff()
-  .expectJSON({ name: 'bug 996038', value: 'inaccessible' })
+  .expectJSON({ name: 'bugzilla', value: 'not found' })