Merge pull request #1671 from mozilla/pb/1071-subhub-delete-customer

https://github.com/mozilla/fxa/pull/1671
r=vbudhram
This commit is contained in:
Phil Booth 2019-07-09 12:20:50 +00:00 коммит произвёл GitHub
Родитель 437489925f 14314844e4
Коммит 1c4df4feb4
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
6 изменённых файлов: 74 добавлений и 40 удалений

Просмотреть файл

@ -1429,18 +1429,7 @@ module.exports = (
const { uid } = emailRecord;
if (config.subscriptions && config.subscriptions.enabled) {
// TODO: We should probably delete the upstream customer for
// subscriptions, but no such API exists in subhub yet.
// https://github.com/mozilla/subhub/issues/61
// Cancel all subscriptions before deletion, if any exist
// Subscription records will be deleted from DB as part of account
// deletion, but we have to trigger cancellation in payment systems
const subscriptions = await db.fetchAccountSubscriptions(uid);
for (const subscription of subscriptions) {
const { subscriptionId } = subscription;
await subhub.cancelSubscription(uid, subscriptionId);
}
await subhub.deleteCustomer(uid);
}
// We fetch the devices to notify before deleteAccount()

Просмотреть файл

@ -42,6 +42,7 @@ module.exports = function(log, config) {
'createSubscription',
'getCustomer',
'updateCustomer',
'deleteCustomer',
'cancelSubscription',
'reactivateSubscription',
].reduce(
@ -110,6 +111,17 @@ module.exports = function(log, config) {
},
},
deleteCustomer: {
path: '/v1/customer/:uid',
method: 'DELETE',
validate: {
params: {
uid: isA.string().required(),
},
response: isA.alternatives(MessageValidator, ErrorValidator),
},
},
createSubscription: {
path: '/v1/customer/:uid/subscriptions',
method: 'POST',
@ -290,5 +302,19 @@ module.exports = function(log, config) {
throw err;
}
},
async deleteCustomer(uid) {
try {
return await api.deleteCustomer(uid);
} catch (err) {
log.error('subhub.deleteCustomer.failed', { uid, err });
if (err.statusCode === 404) {
throw error.unknownCustomer(uid);
}
throw err;
}
},
};
};

Просмотреть файл

@ -86,5 +86,9 @@ module.exports.buildStubAPI = function buildStubAPI(log, config) {
customer.payment_type = pmt_token;
return {};
},
async deleteCustomer(uid) {
return {};
},
};
};

Просмотреть файл

@ -2727,19 +2727,13 @@ describe('/account/destroy', () => {
assert.equal(args[1].email, email);
assert.equal(args[1].uid, uid);
assert.equal(
mockDB.fetchAccountSubscriptions.callCount,
1,
'subscriptions were fetched'
);
const cancelArgs = expectedSubscriptions.map(
({ uid, subscriptionId }) => [uid, subscriptionId]
);
assert.deepEqual(
mockSubhub.cancelSubscription.args,
cancelArgs,
'active subscriptions were all cancelled'
);
assert.equal(mockSubhub.deleteCustomer.callCount, 1);
args = mockSubhub.deleteCustomer.args[0];
assert.lengthOf(args, 1);
assert.equal(args[0], uid);
assert.equal(mockDB.fetchAccountSubscriptions.callCount, 0);
assert.equal(mockSubhub.cancelSubscription.callCount, 0);
assert.equal(mockDB.deleteAccountSubscription.callCount, 0);
assert.equal(mockPush.notifyAccountDestroyed.callCount, 1);
@ -2789,21 +2783,10 @@ describe('/account/destroy', () => {
it('should not attempt to cancel subscriptions with config.subscriptions.enabled = false', async () => {
const route = buildRoute(false);
return runTest(route, mockRequest, () => {
assert.equal(
mockDB.fetchAccountSubscriptions.callCount,
0,
'subscriptions were not fetched'
);
assert.equal(
mockSubhub.cancelSubscription.callCount,
0,
'subscriptions were not fetched'
);
assert.equal(
mockDB.deleteAccountSubscription.args,
0,
'no subscriptions deleted'
);
assert.equal(mockSubhub.deleteCustomer.callCount, 0);
assert.equal(mockDB.fetchAccountSubscriptions.callCount, 0);
assert.equal(mockSubhub.cancelSubscription.callCount, 0);
assert.equal(mockDB.deleteAccountSubscription.args, 0);
});
});
});

Просмотреть файл

@ -74,6 +74,7 @@ describe('subhub client', () => {
'createSubscription',
'getCustomer',
'updateCustomer',
'deleteCustomer',
'cancelSubscription',
'reactivateSubscription',
];
@ -555,4 +556,34 @@ describe('subhub client', () => {
}
});
});
describe('deleteCustomer', () => {
it('should not fail for valid user', async () => {
mockServer
.delete(`/v1/customer/${UID}`)
.reply(200, { message: 'wibble' });
const { subhub } = makeSubject();
const response = await subhub.deleteCustomer(UID);
assert.deepEqual(response, { message: 'wibble' });
});
it('should throw on unknown user', async () => {
mockServer
.delete(`/v1/customer/${UID}`)
.reply(404, { message: 'invalid uid' });
const { subhub } = makeSubject();
let failed = false;
try {
await subhub.deleteCustomer(UID);
} catch (err) {
failed = true;
assert.equal(err.errno, error.ERRNO.UNKNOWN_SUBSCRIPTION_CUSTOMER);
}
assert.isTrue(failed);
});
});
});

Просмотреть файл

@ -168,6 +168,7 @@ const SUBHUB_METHOD_NAMES = [
'listPlans',
'getCustomer',
'updateCustomer',
'deleteCustomer',
'listSubscriptions',
'createSubscription',
'cancelSubscription',