feat: Add AssociateAcademyStep to ProvisionNewCustomerWorkflow#197
feat: Add AssociateAcademyStep to ProvisionNewCustomerWorkflow#197vshaikismail-sonata wants to merge 5 commits into
Conversation
Codecov Report❌ Patch coverage is
❌ Your patch check has failed because the patch coverage (85.71%) is below the target coverage (95.00%). You can increase the patch coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## main #197 +/- ##
==========================================
+ Coverage 86.17% 86.28% +0.10%
==========================================
Files 152 153 +1
Lines 12584 12771 +187
Branches 1200 1225 +25
==========================================
+ Hits 10844 11019 +175
- Misses 1425 1432 +7
- Partials 315 320 +5 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR extends the provisioning workflow to optionally associate an “Academy” with the newly created enterprise catalog, wiring the request/response through the v1 provisioning endpoint and adding Enterprise Catalog client support + tests.
Changes:
- Add
AssociateAcademySteptoProvisionNewCustomerWorkflowimmediately after catalog creation and persist its input/output. - Expose a new optional
academyobject on the provisioning create API (request + response) and thread it through workflow input/output plumbing. - Add an
EnterpriseCatalogApiClientmethod + provisioning API wrapper to call the enterprise-catalog “associate catalog” endpoint, with supporting unit tests.
Reviewed changes
Copilot reviewed 12 out of 13 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| enterprise_access/apps/provisioning/tests/test_models.py | Adds unit tests for AssociateAcademyStep behavior and verifies workflow step ordering. |
| enterprise_access/apps/provisioning/tests/test_api.py | Adds tests for the new associate_academy_with_catalog() provisioning API function. |
| enterprise_access/apps/provisioning/tests/factories.py | Updates workflow factory input/output fixtures to include academy association step data. |
| enterprise_access/apps/provisioning/models.py | Introduces new workflow step input/output + step model; inserts the step into workflow order; adds accessors for step output. |
| enterprise_access/apps/provisioning/migrations/0007_associateacademystep.py | Adds the database model for the new workflow step. |
| enterprise_access/apps/provisioning/api.py | Adds a provisioning-layer API helper that calls enterprise-catalog to associate academy ↔ catalog. |
| enterprise_access/apps/provisioning/admin.py | Registers the new step in Django admin and updates workflow-trigger input generation to include the new step’s input dict. |
| enterprise_access/apps/api/v1/views/provisioning.py | Plumbs academy from request into workflow input and returns academy association output in the response. |
| enterprise_access/apps/api/v1/tests/test_provisioning_views.py | Adds an integration-style test ensuring academy request data is threaded into the workflow and response. |
| enterprise_access/apps/api/serializers/provisioning.py | Adds request/response serializers for the new academy object and includes it in provisioning response schema. |
| enterprise_access/apps/api_client/tests/test_enterprise_catalog_client.py | Adds tests for new academies/catalogs listing helpers and academy-catalog association client call. |
| enterprise_access/apps/api_client/enterprise_catalog_client.py | Adds pagination-merging fetch helpers and a v1 endpoint call to associate an academy with a catalog. |
| GetCreateCustomerStep, | ||
| GetCreateEnterpriseAdminUsersStep, | ||
| GetCreateCatalogStep, | ||
| AssociateAcademyStep, | ||
| GetCreateCustomerAgreementStep, |
| return response.json()['count'] | ||
|
|
||
| @backoff.on_exception(wait_gen=backoff.expo, exception=autoretry_for_exceptions) | ||
| def get_academies(self, academy_uuid: str | None = None) -> dict: |
| return self._fetch_all_pages(self.academies_endpoint, params=params) | ||
|
|
||
| @backoff.on_exception(wait_gen=backoff.expo, exception=autoretry_for_exceptions) | ||
| def get_catalogs(self, enterprise_customer_uuid: str | None = None) -> dict: |
| """ | ||
| Tests for the ``associate_academy_with_catalog()`` function. | ||
| """ |
| description='Preceding academy association step' | ||
| ) | ||
| def preceding_step_link(self, obj): | ||
| """ | ||
| Returns a link to the preceding catalog step for this customer agreement step. | ||
| Returns a link to the preceding academy association step for this customer agreement step. |
|
|
||
| def __init__(self): | ||
| self.api_base_url = urljoin(settings.ENTERPRISE_CATALOG_URL, f'api/{self.api_version}/') | ||
| self.api_v1_base_url = urljoin(settings.ENTERPRISE_CATALOG_URL, 'api/v1/') |
There was a problem hiding this comment.
Remove this 22 & 24 lines of code and use the self.academies_endpoint variable and update the code accordingly.
69bcba7 to
4c578b4
Compare
There was a problem hiding this comment.
⚠️ Not ready to approve
The new EnterpriseCatalogApiClient.get_academies() implementation will raise on non-dict/non-list responses and doesn’t handle an empty endpoint as required by the added unit tests.
Copilot's findings
- Files reviewed: 14/14 changed files
- Comments generated: 2
Note
Your feedback helps us improve the quality of this feature.
Please use 👍 or 👎 to tell us whether this assessment is correct.
| @backoff.on_exception(wait_gen=backoff.expo, exception=autoretry_for_exceptions) | ||
| def get_academies(self, academy_uuid: str = None): | ||
| """ | ||
| Fetch a list of academies, optionally filtered by academy_uuid. | ||
|
|
||
| Returns a paginated-style dict. If the response contains a `next` | ||
| link, subsequent pages will be fetched and merged into a single | ||
| results list. | ||
| """ | ||
| params = {'academy_uuid': academy_uuid} if academy_uuid else None | ||
| response = self.client.get(self.academies_endpoint, params=params) | ||
| response.raise_for_status() | ||
| data = response.json() | ||
|
|
||
| # Merge paginated results if necessary | ||
| next_url = data.get('next') | ||
| while next_url: | ||
| next_resp = self.client.get(next_url) | ||
| next_resp.raise_for_status() | ||
| next_data = next_resp.json() | ||
| data['results'].extend(next_data.get('results', [])) | ||
| data['next'] = next_data.get('next') | ||
| next_url = data['next'] | ||
|
|
||
| return data |
| @admin.display( | ||
| description='Preceding catalog creation step' | ||
| description='Preceding academy association step' | ||
| ) | ||
| def preceding_step_link(self, obj): | ||
| """ |
Description:
Adds a new AssociateAcademyStep to the ProvisionNewCustomerWorkflow, enabling optional academy-to-catalog association during enterprise customer provisioning. The step executes after catalog creation and before customer agreement creation, calling the enterprise-catalog service to link an academy when an academy_uuid is provided in the request. The API serializers, view, client, admin, and migration are all updated end-to-end to support the new field. Comprehensive unit tests cover the model, API layer, serializers, client methods (including pagination merging), and full view-level plumbing.
Jira:
ENT-11883