Update careers to support single position, multiple listings
Description
This PR uses the internal_job_id as a grouping field to display all postings with the same internal_job_id as one position with multiple apply buttons linking to each position's location's apply page.
Issue / Bugzilla link
https://github.com/mozilla/bedrock/issues/11215
Testing
Temporarily add this environment setting to your .env file:
`GREENHOUSE_BOARD=mozillasandbox`
Run these 2 commands inside the container:
-
manage.py migrateto add a new column to the database. -
manage.py sync_greenhouseto pull in the job listings from the sandbox account.
One of the 2 positions will have 3 postings while the other will only have 1.
Codecov Report
Base: 77.39% // Head: 77.39% // No change to project coverage :thumbsup:
Coverage data is based on head (
816a393) compared to base (d08587e). Patch coverage: 100.00% of modified lines in pull request are covered.
:exclamation: Current head 816a393 differs from pull request most recent head 94e550a. Consider uploading reports for the commit 94e550a to get more accurate results
Additional details and impacted files
@@ Coverage Diff @@
## main #11322 +/- ##
=======================================
Coverage 77.39% 77.39%
=======================================
Files 147 147
Lines 7749 7749
=======================================
Hits 5997 5997
Misses 1752 1752
| Impacted Files | Coverage Δ | |
|---|---|---|
| bedrock/careers/feeds.py | 100.00% <100.00%> (ø) |
|
| ...ock/careers/management/commands/sync_greenhouse.py | 100.00% <100.00%> (ø) |
|
| bedrock/careers/models.py | 97.14% <100.00%> (+0.08%) |
:arrow_up: |
| bedrock/careers/views.py | 100.00% <100.00%> (ø) |
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.
:umbrella: View full report at Codecov.
:loudspeaker: Do you have feedback about the report comment? Let us know in this issue.
I've put multiple listings into a dropdown (and resisted the temptation to refactor the entire base template). It doesn't quite jump out the way the button does so we could fancy it up a bit more, but really the whole thing could use a redesign and that's out of scope for the moment so maybe this is good enough for now?
@robhudson Spotted an edge case, I think: if you go to the careers listings and there are no jobs yet imported from Greenhouse (which might also be if, for some reason, we had no jobs listed in Greenhouse, I'm wondering...)
app_1 | Traceback (most recent call last):
app_1 | File "/venv/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
app_1 | response = get_response(request)
app_1 | File "/venv/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
app_1 | response = wrapped_callback(request, *callback_args, **callback_kwargs)
app_1 | File "/venv/lib/python3.9/site-packages/sentry_sdk/integrations/django/views.py", line 67, in sentry_wrapped_callback
app_1 | return callback(request, *args, **kwargs)
app_1 | File "/venv/lib/python3.9/site-packages/django/views/generic/base.py", line 70, in view
app_1 | return self.dispatch(request, *args, **kwargs)
app_1 | File "/venv/lib/python3.9/site-packages/django/views/generic/base.py", line 98, in dispatch
app_1 | return handler(request, *args, **kwargs)
app_1 | File "/venv/lib/python3.9/site-packages/django/views/generic/list.py", line 158, in get
app_1 | return self.render_to_response(context)
app_1 | File "/app/lib/l10n_utils/__init__.py", line 247, in render_to_response
app_1 | return render(
app_1 | File "/app/lib/l10n_utils/__init__.py", line 146, in render
app_1 | return django_render(request, template, context, **kwargs)
app_1 | File "/venv/lib/python3.9/site-packages/sentry_sdk/integrations/django/templates.py", line 95, in render
app_1 | return real_render(request, template_name, context, *args, **kwargs)
app_1 | File "/venv/lib/python3.9/site-packages/django/shortcuts.py", line 19, in render
app_1 | content = loader.render_to_string(template_name, context, request, using=using)
app_1 | File "/venv/lib/python3.9/site-packages/django/template/loader.py", line 62, in render_to_string
app_1 | return template.render(context, request)
app_1 | File "/venv/lib/python3.9/site-packages/django_jinja/backend.py", line 59, in render
app_1 | return mark_safe(self._process_template(self.template.render, context, request))
app_1 | File "/venv/lib/python3.9/site-packages/django_jinja/backend.py", line 105, in _process_template
app_1 | return handler(context)
app_1 | File "/venv/lib/python3.9/site-packages/jinja2/environment.py", line 1291, in render
app_1 | self.environment.handle_exception()
app_1 | File "/venv/lib/python3.9/site-packages/jinja2/environment.py", line 925, in handle_exception
app_1 | raise rewrite_traceback_stack(source=source)
app_1 | File "/app/bedrock/careers/templates/careers/listings.html", line 7, in top-level template code
app_1 | {% extends "careers/base.html" %}
app_1 | File "/app/bedrock/careers/templates/careers/base.html", line 7, in top-level template code
app_1 | {% extends "base-protocol-mozilla.html" %}
app_1 | File "/app/bedrock/base/templates/base-protocol-mozilla.html", line 7, in top-level template code
app_1 | {% extends 'base-protocol.html' %}
app_1 | File "/app/bedrock/base/templates/base-protocol.html", line 100, in top-level template code
app_1 | {% block content %}{% endblock %}
app_1 | File "/app/bedrock/careers/templates/careers/base.html", line 40, in block 'content'
app_1 | {% block careers_content %}{% endblock %}
app_1 | File "/app/bedrock/careers/templates/careers/listings.html", line 58, in block 'careers_content'
app_1 | {% for internal_job_id, postings in positions | groupby("internal_job_id") %}
app_1 | File "/venv/lib/python3.9/site-packages/jinja2/async_utils.py", line 36, in wrapper
app_1 | return normal_func(*args, **kwargs)
app_1 | File "/venv/lib/python3.9/site-packages/jinja2/filters.py", line 1238, in sync_do_groupby
app_1 | for key, values in groupby(sorted(value, key=expr), expr)
app_1 | TypeError: '<' not supported between instances of 'NoneType' and 'NoneType'```
You can replicate this by doing a `make clean pull build run` then shelling in and doing the migration (which should have already been applie, but worth a check just to be safe), then going to http://localhost:8080/en-US/careers/listings/ it will 500.
If you then sync_greenhouse, it all works as expected
@craigcook The drop-down for picking a location works just fine, but I hit exactly what you mean by
It doesn't quite jump out the way the button does so we could fancy it up a bit more.
I'll leave it you you and Rob, but it's a +1 from me on trying to get the action triggers look pretty similar if it's not a nightmare
Good catch on testing no positions. I'll test and come up with a fix for that case. Thanks!
The issue if we migrate but don't run the greenhouse sync is that the migration sets the value of the new column to None. And the template groupby tries to sort the values before grouping, so it is trying to do None < None. I will update the migration to set a more sensible default value. But this should be very interim since the deployment runs the migration plus the db-update script (which will run the greenhouse sync).
I tested this again today against the production greenhouse listings and found some issues:
- The migration needs to be updated to clear the current set of listings. When the new column is added the existing rows end up with an
internal_job_idof zero. Then when the migration runs the listings get checked against the current records, which now include theinternal_job_idbut since Greenhouse has none that match zero, all listings are considered new and are inserted rather than updated. The solution to this would be to just clear out the existing listings before the new column is created, and possibly force a sync with greenhouse. - The production Greenhouse currently has 1 position posted with 2 listings (i.e. 2 positions that have the same
internal_job_id). But these listings also have a comma separated list of locations. Whereas the sandbox had 1 location per listing. Because of this the apply now button looks a bit off. We will need to sync up with the team to ensure the Greenhouse is set up correctly and ready to go, or update our code to match expectations.