-
Notifications
You must be signed in to change notification settings - Fork 45
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- try email verifier in Business Contact Info - added/updated unit tests
- Loading branch information
1 parent
c65ed59
commit 1c94c42
Showing
5 changed files
with
155 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
export { default as AuthServices } from './auth-services' | ||
export { default as BusinessLookupServices } from './business-lookup-services' | ||
export { default as LegalServices } from './legal-services' | ||
export { default as MillionVerifierService } from './million-verifier-service' | ||
export { default as NaicsServices } from './naics-services' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
// NB: use native axios to pre-empt OPTIONS requests | ||
// because Million Verifier doesn't support them | ||
import axios from 'axios' | ||
|
||
enum ResultCodes { | ||
OK = 'ok', | ||
CATCH_ALL = 'catch_all', | ||
UNKNOWN = 'unknown', | ||
ERROR = 'error', | ||
DISPOSABLE = 'disposable', | ||
INVALID = 'invalid' | ||
} | ||
/** | ||
* Class that provides integration with the Million Verifier API. | ||
* Ref: https://developer.millionverifier.com/ | ||
*/ | ||
export default class MillionVerifierService { | ||
/** | ||
* Verifies an email address in real time. | ||
* @param email the email address to verify | ||
* @param apiUrl the API URL for the Million Verifier API | ||
* @param apiKey the API key for the Million Verifier API | ||
* @param timeout the timeout for the Million Verifier API | ||
* @returns whether the email address is valid | ||
*/ | ||
static async isValidEmail ( | ||
email: string, | ||
apiUrl = 'https://api.millionverifier.com/api/v3', | ||
apiKey = '8I3zB8yBzV3bWdFEclDrXD4I7', | ||
timeout = 5 // seconds | ||
): Promise<boolean> { | ||
// safety checks | ||
if (!email) throw new Error('Email address is required') | ||
if (!apiUrl) throw new Error('API URL is required') | ||
if (!timeout) throw new Error('Timeout is required') | ||
|
||
// accept email if no API key is provided | ||
if (!apiKey) return Promise.resolve(true) | ||
|
||
let url = `${apiUrl}/` | ||
url += `?api=${apiKey}` | ||
url += `&email=${encodeURIComponent(email)}` | ||
url += `&timeout=${timeout}` | ||
|
||
return axios.get(url) | ||
.then(response => { | ||
const result = response?.data?.result | ||
if (!result) throw new Error('Invalid API response') | ||
// accept OK or UNKNOWN status | ||
return (result === ResultCodes.OK || result === ResultCodes.UNKNOWN) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,14 +4,18 @@ import { getVuexStore } from '@/store/' | |
import { mount } from '@vue/test-utils' | ||
import BusinessContactInfo from '@/components/common/YourCompany/BusinessContactInfo.vue' | ||
import AuthServices from '@/services/auth-services' | ||
import MillionVerifierService from '@/services/million-verifier-service' | ||
|
||
Vue.use(Vuetify) | ||
|
||
const vuetify = new Vuetify({}) | ||
const store = getVuexStore() | ||
|
||
// mock services function | ||
const mockUpdateContactInfo = jest.spyOn((AuthServices as any), 'updateContactInfo').mockImplementation() | ||
// mock auth services function | ||
jest.spyOn((AuthServices as any), 'updateContactInfo').mockImplementation() | ||
|
||
// mock million verifier service function | ||
jest.spyOn((MillionVerifierService as any), 'isValidEmail').mockReturnValue(true) | ||
|
||
const contactInfo = { | ||
email: '[email protected]', | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import sinon from 'sinon' | ||
import axios from 'axios' | ||
import MillionVerifierService from '@/services/million-verifier-service' | ||
|
||
describe('Million Verifier Service', () => { | ||
let get: any | ||
|
||
beforeEach(() => { | ||
get = sinon.stub(axios, 'get') | ||
}) | ||
|
||
afterEach(() => { | ||
sinon.restore() | ||
}) | ||
|
||
it('throws an error when there is no email address', async () => { | ||
// test it | ||
await expect(MillionVerifierService.isValidEmail(null, 'https://url', 'KEY', 5)).rejects | ||
.toThrow('Email address is required') | ||
}) | ||
|
||
it('throws an error when there is no API URL', async () => { | ||
// test it | ||
await expect(MillionVerifierService.isValidEmail('[email protected]', null, 'KEY', 5)) | ||
.rejects.toThrow('API URL is required') | ||
}) | ||
|
||
it('throws an error when there is no timeout', async () => { | ||
// test it | ||
await expect(MillionVerifierService.isValidEmail('[email protected]', 'https://url', 'KEY', null)) | ||
.rejects.toThrow('Timeout is required') | ||
}) | ||
|
||
it('returns True when there is no API key', async () => { | ||
// test it | ||
expect(await MillionVerifierService.isValidEmail('[email protected]', 'https://url', null, 5)) | ||
.toBe(true) | ||
}) | ||
|
||
it('returns True when email is ok', async () => { | ||
// mock valid search | ||
get.withArgs('https://url/?api=KEY&email=valid%40example.com&timeout=5') | ||
.returns(Promise.resolve({ data: { result: 'ok' } })) | ||
|
||
// test it | ||
expect(await MillionVerifierService.isValidEmail('[email protected]', 'https://url', 'KEY', 5)) | ||
.toBe(true) | ||
}) | ||
|
||
it('returns True when email is unknown', async () => { | ||
// mock invalid search | ||
get.withArgs('https://url/?api=KEY&email=invalid%40example.com&timeout=5') | ||
.returns(new Promise(resolve => resolve({ data: { result: 'unknown' } }))) | ||
|
||
// test it | ||
expect(await MillionVerifierService.isValidEmail('[email protected]', 'https://url', 'KEY', 5)) | ||
.toBe(true) | ||
}) | ||
|
||
it('returns False when email is invalid', async () => { | ||
// mock invalid search | ||
get.withArgs('https://url/?api=KEY&email=invalid%40example.com&timeout=5') | ||
.returns(new Promise(resolve => resolve({ data: { result: 'invalid' } }))) | ||
|
||
// test it | ||
expect(await MillionVerifierService.isValidEmail('[email protected]', 'https://url', 'KEY', 5)) | ||
.toBe(false) | ||
}) | ||
|
||
it('throws an error when there is an invalid API response', async () => { | ||
// mock invalid API response | ||
get.withArgs('https://url/?api=KEY&email=valid%40example.com&timeout=5') | ||
.returns(Promise.resolve({})) | ||
|
||
// test it | ||
await expect(MillionVerifierService.isValidEmail('[email protected]', 'https://url', 'KEY', 5)) | ||
.rejects.toThrow('Invalid API response') | ||
}) | ||
|
||
it('throws an error when there is a network error', async () => { | ||
// mock network error | ||
get.withArgs('https://url/?api=KEY&email=valid%40example.com&timeout=5') | ||
.returns(Promise.reject(new Error('Network error'))) | ||
|
||
// test it | ||
await expect(MillionVerifierService.isValidEmail('[email protected]', 'https://url', 'KEY', 5)) | ||
.rejects.toThrow('Network error') | ||
}) | ||
}) |