• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mozilla / blurts-server / c9ae2591-186f-4294-a5e5-a502a4f2d392

pending completion
c9ae2591-186f-4294-a5e5-a502a4f2d392

push

circleci

Robert Helmer
Merge branch 'MNTOR-983-settings-v2-frontend-additions' into MNTOR-803/settings-v2-integration

282 of 1265 branches covered (22.29%)

Branch coverage included in aggregate %.

95 of 95 new or added lines in 3 files covered. (100.0%)

959 of 3391 relevant lines covered (28.28%)

2.3 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/views/partials/settings.js
1
import AppConstants from '../../app-constants.js'
2
import { getMessage } from '../../utils/fluent.js'
3

4
const emailNeedsVerificationSub = email => `
×
5
  <span class='verification-required'>
6
    ${getMessage('email-verification-required')}
7
  </span>
8

9
  <a class='settings-resend-email' data-email-id='${email.id}' href='#'>
10
    ${getMessage('resend-verification')}
11
  </a>
12
`
13

14
const deleteButton = email => `
×
15
  <button
16
    data-subscriber-id='${email.subscriber_id}'
17
    data-email-id='${email.id}'
18
    class='settings-email-remove-button js-remove-email'
19
  >
20
    <img src='/images/icon-delete.png'>
21
  </button>
22
`
23

24
const createEmailItem = (email, breachCounts) => `
×
25
  <li class='settings-email-item'>
26
    <strong>
27
      ${email.primary
×
28
          ? `${getMessage('email-address-primary', { email: email.email })}`
29
          : email.email}
30
    </strong>
31
    ${email.verified
×
32
        ? getMessage('appears-in-x-breaches', {
33
            breachCount: breachCounts.get(email.email)
34
          })
35
        : emailNeedsVerificationSub(email)}
36

37
    ${email.primary ? '' : deleteButton(email)}
×
38
  </li>
39
`
40

41
// Sort first by presence of `primary` key, then by email address.
42
const getSortedEmails = emails => [...emails].sort((a, b) => (
×
43
  a.primary
×
44
    ? -1
45
    : b.primary
×
46
      ? 1
47
      : 0 || a.email.localeCompare(b.email)
×
48
))
49

50
const createEmailList = (emails, breachCounts) => `
×
51
  <ul class='settings-email-list'>
52
    ${getSortedEmails(emails)
53
      .map(email => createEmailItem(email, breachCounts))
×
54
      .join('')}
55
  </ul>
56
`
57

58
const optionInput = (csrfToken, { commOption, name, isChecked }) => `
×
59
  <input
60
    checked='${isChecked}'
61
    class='radio-comm-option'
62
    data-comm-option='${commOption}'
63
    data-csrf-token='${csrfToken}'
64
    data-form-action='update-comm-option'
65
    name='${name}'
66
    type='radio'
67
  >
68
`
69

70
const alertOptions = (csrfToken, emails) => `
×
71
  <div class='settings-alert-options'>
72
    <label class='settings-radio-input'>
73
    ${optionInput(csrfToken, {
74
      commOption: 0,
75
      name: '1',
76
      isChecked: true
77
    })}
78
    <span class='settings-radio-label'>
79
      ${getMessage('to-affected-email')}
80
    </span>
81
  </label>
82

83
  <label class='settings-radio-input'>
84
    ${optionInput(csrfToken, {
85
      commOption: 1,
86
      name: '1',
87
      isChecked: false
88
    })}
89
    <span class='settings-radio-label'>
90
      ${getMessage('comm-opt-1', {
91
        primaryEmail: emails.find(a => a.primary === true)?.email
×
92
      })}
93
    </span>
94
  </label>
95
  </div>
96
`
97

98
const addEmailModal = limit => `
×
99
  <dialog id='add-email-modal' class='add-email-modal'>
100
    <button id='settings-close'>
101
      <img src='/images/close.png'>
102
    </button>
103
    <img src='/images/email.png'>
104

105
    <h3 class='settings-section-title'>${getMessage('add-another-email')}</h3>
106
    <div id='add-email-modal-content'>
107
      ${getMessage('email-address-limit', { limit })}
108
      ${getMessage('add-another-email')}
109
    </div>
110

111
    <div id='add-email-modal-controls'>
112
      <label>
113
        ${getMessage('email-address')}
114
        <input id='email' type='text'>
115
      </label>
116
      <button id='send-verification' class='primary'>
117
        ${getMessage('send-verification')}
118
      </button>
119
    </div>
120
  </dialog>
121
`
122

123
export const settings = data => {
×
124
  const { breachCounts, csrfToken, emails, limit } = data
×
125

126
  return `
×
127
    <div id='settings' class='settings' data-csrf-token='${csrfToken}'>
128
      <h2 class='settings-title'>${getMessage('settings-title')}</h2>
129

130
      <div class='settings-content'>
131
        <!-- Breach alert preferences -->
132
        <section>
133
          <h3 class='settings-section-title'>
134
            ${getMessage('settings-preferences-title')}
135
          </h3>
136
          ${alertOptions(csrfToken, emails)}
137
        </section>
138

139
        <hr>
140

141
        <!-- Monitored email addresses -->
142
        <section>
143
          <h3 class='settings-section-title'>
144
            ${getMessage('monitored-email-addresses')}
145
          </h3>
146
          <p>${getMessage('email-address-limit', { limit })}</p>
147

148
          ${createEmailList(emails, breachCounts)}
149
          <button
150
            id='settings-add-email'
151
            class='settings-add-email-button primary'
152
          >
153
            ${getMessage('add-new-email')}
154
          </button>
155

156
          ${addEmailModal(limit)}
157
        </section>
158

159
        <hr>
160

161
        <!-- Deactivate account -->
162
        <section>
163
          <h3 class='settings-section-title'>
164
            ${getMessage('deactivate-account-title')}
165
          </h3>
166
          <p>${getMessage('deactivate-account')}</p>
167
          <a
168
            class='settings-link-fxa'
169
            href='${AppConstants.FXA_SETTINGS_URL}'
170
            target='_blank'
171
          >
172
            ${getMessage('firefox-settings')}
173
          </a>
174
        </section>
175
      </div>
176
    </div>
177
  `
178
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc