Verified Commit 59d83e15 authored by Mari's avatar Mari Committed by aguestuser

[215] extract enqueueRecycle into its own module

parent 6fe7e2e3
const signal = require('../../signal')
const { isEmpty } = require('lodash')
const { statuses } = require('../../util')
const { messagesIn } = require('../../dispatcher/strings/messages')
const { findByPhoneNumber, enqueue } = require('../../db/repositories/recycleablePhoneNumber')
const channelRepository = require('../../db/repositories/channel')
// ({ string }) -> SignalboostStatus
const enqueueRecycleablePhoneNumber = async ({ phoneNumbers }) => {
return await Promise.all(
phoneNumbers.split(',').map(async phoneNumber => {
try {
const channel = await channelRepository.findDeep(phoneNumber)
if (isEmpty(channel))
return {
status: statuses.ERROR,
message: `${phoneNumber} must be associated with a channel in order to be recycled.`,
}
const recycleablePhoneNumber = await findByPhoneNumber(phoneNumber)
if (!isEmpty(recycleablePhoneNumber))
return {
status: statuses.ERROR,
message: `${phoneNumber} has already been enqueued for recycling.`,
}
await notifyAdmins(channel)
await enqueue(channel.phoneNumber)
return {
status: statuses.SUCCESS,
message: `Successfully enqueued ${phoneNumber} for recycling.`,
}
} catch (e) {
console.log(e)
return {
status: statuses.ERROR,
message: `There was an error trying to enqueue ${phoneNumber} for recycling.`,
}
}
}),
)
}
const notifyAdmins = async channel => {
await signal.broadcastMessage(
channelRepository.getAdminPhoneNumbers(channel),
signal.sdMessageOf(
channel,
messagesIn(channel.language).notifications.channelEnqueuedForRecycling,
),
)
}
module.exports = { enqueueRecycleablePhoneNumber }
......@@ -4,7 +4,8 @@ const { errors } = require('./common')
const { destroy } = require('./destroy')
const { list } = require('./present')
const { provisionN } = require('./provision')
const { enqueueRecycleablePhoneNumber, recycle } = require('./recycle')
const { recycle } = require('./recycle')
const { enqueueRecycleablePhoneNumber } = require('./enqueueRecycle')
const { register, registerAllPurchased, registerAllUnregistered } = require('./register')
const { handleSms } = require('./sms')
const { purchase, purchaseN } = require('./purchase')
......
const eventRepository = require('../../db/repositories/event')
const common = require('./common')
const { isEmpty } = require('lodash')
const { statuses } = require('../../util')
const { defaultLanguage } = require('../../config')
const signal = require('../../signal')
const { eventTypes } = require('../../db/models/event')
const { messagesIn } = require('../../dispatcher/strings/messages')
const phoneNumberRepository = require('../../db/repositories/phoneNumber')
const { findByPhoneNumber, enqueue } = require('../../db/repositories/recycleablePhoneNumber')
const channelRepository = require('../../db/repositories/channel')
// ({ string }) -> SignalboostStatus
const enqueueRecycleablePhoneNumber = async ({ phoneNumbers }) => {
return await Promise.all(
phoneNumbers.split(',').map(async phoneNumber => {
try {
const channel = await channelRepository.findDeep(phoneNumber)
if (isEmpty(channel))
return {
status: statuses.ERROR,
message: `${phoneNumber} must be associated with a channel in order to be recycled.`,
}
const recycleablePhoneNumber = await findByPhoneNumber(phoneNumber)
if (!isEmpty(recycleablePhoneNumber))
return {
status: statuses.ERROR,
message: `${phoneNumber} has already been enqueued for recycling.`,
}
// notifyAdmins(channel)
await enqueue(channel.phoneNumber)
return {
status: statuses.SUCCESS,
message: `Successfully enqueued ${phoneNumber} for recycling.`,
}
} catch (e) {
return {
status: statuses.ERROR,
message: `There was an error trying to enqueue ${phoneNumber} for recycling.`,
}
}
}),
)
}
// (string) -> SignalboostStatus
const recycle = async channelPhoneNumber => {
const channel = await channelRepository.findDeep(channelPhoneNumber)
......@@ -72,18 +35,6 @@ const notifyMembers = async channel => {
)
}
const notifyAdmins = async channel => {
await signal.broadcastMessage(
channelRepository.getAdminPhoneNumbers(channel),
signal.sdMessageOf(
channel,
messagesIn(channel.language).notifications.channelEnqueuedForRecycling,
),
)
}
// String
// (Database, string, PhoneNumberStatus) -> PhoneNumberStatus
const recordStatusChange = async (phoneNumber, status) =>
phoneNumberRepository.update(phoneNumber, { status }).then(common.extractStatus)
......@@ -99,4 +50,4 @@ const handleRecycleFailure = async (err, phoneNumber) => {
}
}
module.exports = { enqueueRecycleablePhoneNumber, recycle }
module.exports = { recycle }
import { expect } from 'chai'
import { afterEach, beforeEach, describe, it } from 'mocha'
import sinon from 'sinon'
import signal from '../../../../app/signal'
import channelRepository from '../../../../app/db/repositories/channel'
import { genPhoneNumber } from '../../../support/factories/phoneNumber'
import recycleablePhoneNumberRepository from '../../../../app/db/repositories/recycleablePhoneNumber'
import { enqueueRecycleablePhoneNumber } from '../../../../app/registrar/phoneNumber'
describe('phone number services -- recycle module', () => {
const phoneNumbers = ['+11111111111', '+12222222222']
let db = {}
const sock = {}
let channel = {
phoneNumber: genPhoneNumber(),
name: 'beep boop channel',
}
let findChannelStub,
findRecycleablePhoneNumberStub,
enqueueRecycleablePhoneNumberStub,
getAdminPhoneNumbersStub,
broadcastMessageStub
beforeEach(() => {
findChannelStub = sinon.stub(channelRepository, 'findDeep')
findRecycleablePhoneNumberStub = sinon.stub(
recycleablePhoneNumberRepository,
'findByPhoneNumber',
)
enqueueRecycleablePhoneNumberStub = sinon.stub(recycleablePhoneNumberRepository, 'enqueue')
getAdminPhoneNumbersStub = sinon.stub(channelRepository, 'getAdminPhoneNumbers')
broadcastMessageStub = sinon.stub(signal, 'broadcastMessage')
})
afterEach(() => {
sinon.restore()
})
describe('enqueueing recycleable phone numbers', () => {
describe('when a phone number does not belong to a valid channel', () => {
beforeEach(async () => {
findChannelStub.returns(Promise.resolve(null))
})
it('returns an ERROR status and message', async () => {
const response = await enqueueRecycleablePhoneNumber({
phoneNumbers: phoneNumbers.join(','),
})
expect(response).to.eql([
{
message: `${
phoneNumbers[0]
} must be associated with a channel in order to be recycled.`,
status: 'ERROR',
},
{
message: `${
phoneNumbers[1]
} must be associated with a channel in order to be recycled.`,
status: 'ERROR',
},
])
})
})
describe('when the phone number has already been enqueued for recycling', () => {
beforeEach(() => {
// findChannelStub.returns(channel)
findRecycleablePhoneNumberStub.returns({})
})
it('returns an ERROR status and message', async () => {
const response = await enqueueRecycleablePhoneNumber({
phoneNumbers: channel.phoneNumber,
})
expect(response).to.eql({
status: 'ERROR',
message: `${channel.phoneNumber} has already been enqueued for recycling.`,
})
})
})
describe('when the phone number belongs to a valid channel', () => {
beforeEach(() => {
findChannelStub.returns(Promise.resolve(channel))
})
it('returns a SUCCESS status and message', async () => {
const response = await enqueueRecycleablePhoneNumber({
phoneNumbers: phoneNumbers.join(','),
})
expect(enqueueRecycleablePhoneNumberStub.callCount).to.eql(1)
})
it('notifies the channel admins that their channel will be recycled soon', async () => {
const response = await enqueueRecycleablePhoneNumber({
phoneNumbers: phoneNumbers.join(','),
})
expect(broadcastMessageStub.callCount).to.eql(1)
})
})
describe('when updating the DB throws an error', () => {
beforeEach(() => {
findChannelStub.callsFake(() => {
throw 'DB err'
})
})
it('returns an ERROR status and message', async () => {
const response = await enqueueRecycleablePhoneNumber({
phoneNumbers: phoneNumbers[0],
})
expect(response).to.eql([
{
status: 'ERROR',
message: `There was an error trying to enqueue ${phoneNumbers[0]} for recycling.`,
},
])
})
})
})
})
import { expect } from 'chai'
import { afterEach, beforeEach, describe, it } from 'mocha'
import { enqueueRecycleablePhoneNumber, recycle } from '../../../../app/registrar/phoneNumber'
import { recycle } from '../../../../app/registrar/phoneNumber'
import sinon from 'sinon'
import phoneNumberRepository from '../../../../app/db/repositories/phoneNumber'
import channelRepository from '../../../../app/db/repositories/channel'
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment