Commit a67e5809 authored by Josianne Hyson's avatar Josianne Hyson

Add internal API to destroy UpcomingReconciliation

We want to be able to destroy upcoming reconciliation records on .com
namespaces when the reconciliation will no longer be taking place. For
instance this is currently intended to be called when we receive
notification that the customer has cancelled their subscription. Without
this change, users will continue to see an alert up until their original
reconciliation date.

Issue: https://gitlab.com/gitlab-org/customers-gitlab-com/-/issues/3722
MR: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/76068
parent 566c32f9
......@@ -826,6 +826,32 @@ Example response:
200
```
### Deleting an `upcoming_reconciliation`
Use a DELETE command to delete an `upcoming_reconciliation`.
```plaintext
DELETE /internal/upcoming_reconciliations
```
| Attribute | Type | Required | Description |
|:---------------|:--------|:---------|:----------------------------------------------------------------------------------|
| `namespace_id` | integer | yes | The ID of the GitLab.com namespace that no longer has an upcoming reconciliation. |
Example request:
```shell
curl --request DELETE \
--url "http://localhost:3000/api/v4/internal/upcoming_reconciliations?namespace_id=22" \
--header 'PRIVATE-TOKEN: <admin_access_token>'
```
Example response:
```plaintext
204
```
### Known consumers
- CustomersDot
......@@ -30,6 +30,21 @@ module API
render_api_error!({ error: response.errors.first }, 400)
end
end
desc 'Destroy upcoming reconciliation record'
params do
requires :namespace_id, type: Integer, allow_blank: false
end
delete '/' do
upcoming_reconciliation = GitlabSubscriptions::UpcomingReconciliation.next(params[:namespace_id])
not_found! if upcoming_reconciliation.blank?
upcoming_reconciliation.destroy!
no_content!
end
end
end
end
......
......@@ -89,4 +89,80 @@ RSpec.describe API::Internal::UpcomingReconciliations, :api do
end
end
end
describe 'DELETE /internal/upcoming_reconciliations' do
let_it_be(:namespace) { create(:namespace) }
before do
stub_application_setting(check_namespace_plan: true)
end
context 'when the request is not authenticated' do
it 'returns authentication error' do
delete api("/internal/upcoming_reconciliations?namespace_id=#{namespace.id}")
expect(response).to have_gitlab_http_status(:unauthorized)
end
end
context 'when authenticated as user' do
it 'returns authentication error', :aggregate_failures do
user = create(:user)
expect { delete api("/internal/upcoming_reconciliations?namespace_id=#{namespace.id}", user) }
.not_to change(GitlabSubscriptions::UpcomingReconciliation, :count)
expect(response).to have_gitlab_http_status(:forbidden)
end
end
context 'when authenticated as an admin' do
let_it_be(:admin) { create(:admin) }
context 'when the request is not for .com' do
before do
stub_application_setting(check_namespace_plan: false)
end
it 'returns an error', :aggregate_failures do
expect { delete api("/internal/upcoming_reconciliations?namespace_id=#{namespace.id}", admin) }
.not_to change(GitlabSubscriptions::UpcomingReconciliation, :count)
expect(response).to have_gitlab_http_status(:forbidden)
expect(response.body).to include('403 Forbidden - This API is gitlab.com only!')
end
end
context 'when the namespace_id is missing' do
it 'returns a 400 error', :aggregate_failures do
expect { delete api("/internal/upcoming_reconciliations", admin) }
.not_to change(GitlabSubscriptions::UpcomingReconciliation, :count)
expect(response).to have_gitlab_http_status(:bad_request)
expect(response.body).to include 'namespace_id is missing'
end
end
context 'when there is an upcoming reconciliation for the namespace' do
it 'destroys the reconciliation and returns success', :aggregate_failures do
create(:upcoming_reconciliation, namespace_id: namespace.id)
expect { delete api("/internal/upcoming_reconciliations?namespace_id=#{namespace.id}", admin) }
.to change { GitlabSubscriptions::UpcomingReconciliation.where(namespace_id: namespace.id).count }
.by(-1)
expect(response).to have_gitlab_http_status(:no_content)
end
end
context 'when the namespace_id does not have an upcoming reconciliation' do
it 'returns a not found error' do
expect { delete api("/internal/upcoming_reconciliations?namespace_id=#{namespace.id}", admin) }
.not_to change(GitlabSubscriptions::UpcomingReconciliation, :count)
expect(response).to have_gitlab_http_status(:not_found)
end
end
end
end
end
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