Skip to content

Commit 42e1299

Browse files
committed
Remove get_sorted_departments from careers helpers.
Order of deparments is now implicit because they are read them from a static dict.
1 parent 53923bc commit 42e1299

3 files changed

Lines changed: 191 additions & 41 deletions

File tree

tests/test_careers.py

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
import logging
2+
import unittest
3+
from types import SimpleNamespace
4+
from unittest.mock import MagicMock
5+
6+
from webapp.careers import (
7+
DEPARTMENT_LIST,
8+
get_all_departments,
9+
group_by_department,
10+
)
11+
12+
13+
logging.getLogger("talisker.context").disabled = True
14+
15+
16+
def _make_vacancy(*department_slugs):
17+
"""
18+
Build a minimal vacancy-like object.
19+
20+
``group_by_department`` only relies on each vacancy exposing a
21+
``departments`` list whose items have a ``slug`` attribute, so we
22+
avoid constructing full ``Vacancy`` instances here.
23+
"""
24+
departments = [SimpleNamespace(slug=slug) for slug in department_slugs]
25+
return SimpleNamespace(departments=departments)
26+
27+
28+
class TestGroupByDepartment(unittest.TestCase):
29+
def test_includes_every_known_department(self):
30+
"""
31+
Every department in DEPARTMENT_LIST should be present as a key,
32+
even when there are no vacancies at all.
33+
"""
34+
grouped = group_by_department([])
35+
36+
self.assertEqual(list(grouped.keys()), list(DEPARTMENT_LIST.keys()))
37+
38+
def test_order_matches_department_list(self):
39+
"""
40+
The order of the returned dict should always match the order of
41+
DEPARTMENT_LIST, regardless of the vacancy data.
42+
"""
43+
vacancies = [
44+
_make_vacancy("legal"),
45+
_make_vacancy("engineering"),
46+
_make_vacancy("sales"),
47+
]
48+
49+
grouped = group_by_department(vacancies)
50+
51+
self.assertEqual(list(grouped.keys()), list(DEPARTMENT_LIST.keys()))
52+
53+
def test_preserves_department_metadata(self):
54+
"""
55+
Each grouped department should keep its original metadata and gain
56+
an empty "vacancies" list when no vacancies match.
57+
"""
58+
grouped = group_by_department([])
59+
60+
engineering = grouped["engineering"]
61+
self.assertEqual(engineering["name"], "Engineering")
62+
self.assertEqual(engineering["slug"], "engineering")
63+
self.assertEqual(
64+
engineering["icon"], DEPARTMENT_LIST["engineering"]["icon"]
65+
)
66+
self.assertEqual(engineering["vacancies"], [])
67+
68+
def test_assigns_vacancies_to_their_department(self):
69+
"""
70+
Vacancies should be appended to the department that matches their
71+
department slug.
72+
"""
73+
engineering_vacancy = _make_vacancy("engineering")
74+
sales_vacancy = _make_vacancy("sales")
75+
76+
grouped = group_by_department([engineering_vacancy, sales_vacancy])
77+
78+
self.assertEqual(
79+
grouped["engineering"]["vacancies"], [engineering_vacancy]
80+
)
81+
self.assertEqual(grouped["sales"]["vacancies"], [sales_vacancy])
82+
self.assertEqual(grouped["legal"]["vacancies"], [])
83+
84+
def test_vacancy_in_multiple_departments(self):
85+
"""
86+
A vacancy that belongs to several departments should appear under
87+
each matching department.
88+
"""
89+
vacancy = _make_vacancy("engineering", "product")
90+
91+
grouped = group_by_department([vacancy])
92+
93+
self.assertIn(vacancy, grouped["engineering"]["vacancies"])
94+
self.assertIn(vacancy, grouped["product"]["vacancies"])
95+
96+
def test_ignores_unknown_department_slugs(self):
97+
"""
98+
Vacancies belonging to an unknown department should be dropped and
99+
must not create new keys.
100+
"""
101+
vacancy = _make_vacancy("nonexistent-department")
102+
103+
grouped = group_by_department([vacancy])
104+
105+
self.assertNotIn("nonexistent-department", grouped)
106+
self.assertEqual(list(grouped.keys()), list(DEPARTMENT_LIST.keys()))
107+
for department in grouped.values():
108+
self.assertEqual(department["vacancies"], [])
109+
110+
111+
class TestGetAllDepartments(unittest.TestCase):
112+
def _make_greenhouse(self, vacancies):
113+
greenhouse = MagicMock()
114+
greenhouse.get_vacancies.return_value = vacancies
115+
return greenhouse
116+
117+
def test_returns_grouped_departments_and_overview(self):
118+
"""
119+
get_all_departments should return a (grouped, overview) tuple where
120+
the overview summarises each department.
121+
"""
122+
greenhouse = self._make_greenhouse(
123+
[_make_vacancy("engineering"), _make_vacancy("engineering")]
124+
)
125+
126+
all_departments, overview = get_all_departments(greenhouse)
127+
128+
self.assertEqual(
129+
list(all_departments.keys()), list(DEPARTMENT_LIST.keys())
130+
)
131+
self.assertEqual(len(overview), len(DEPARTMENT_LIST))
132+
133+
def test_overview_entry_shape_and_counts(self):
134+
"""
135+
Each overview entry should expose name, count, slug and icon, and
136+
the count should reflect the number of matching vacancies.
137+
"""
138+
greenhouse = self._make_greenhouse(
139+
[
140+
_make_vacancy("engineering"),
141+
_make_vacancy("engineering"),
142+
_make_vacancy("sales"),
143+
]
144+
)
145+
146+
_, overview = get_all_departments(greenhouse)
147+
overview_by_slug = {entry["slug"]: entry for entry in overview}
148+
149+
self.assertEqual(
150+
set(overview_by_slug["engineering"].keys()),
151+
{"name", "count", "slug", "icon"},
152+
)
153+
self.assertEqual(overview_by_slug["engineering"]["count"], 2)
154+
self.assertEqual(overview_by_slug["sales"]["count"], 1)
155+
self.assertEqual(overview_by_slug["legal"]["count"], 0)
156+
self.assertEqual(
157+
overview_by_slug["engineering"]["name"], "Engineering"
158+
)
159+
self.assertEqual(
160+
overview_by_slug["engineering"]["icon"],
161+
DEPARTMENT_LIST["engineering"]["icon"],
162+
)
163+
164+
def test_overview_order_matches_department_list(self):
165+
"""
166+
The overview order should follow DEPARTMENT_LIST.
167+
"""
168+
greenhouse = self._make_greenhouse([])
169+
170+
_, overview = get_all_departments(greenhouse)
171+
172+
self.assertEqual(
173+
[entry["slug"] for entry in overview],
174+
list(DEPARTMENT_LIST.keys()),
175+
)
176+
177+
178+
if __name__ == "__main__":
179+
unittest.main()

webapp/app.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@
6969
)
7070
from webapp.careers import (
7171
DEPARTMENT_LIST,
72-
get_sorted_departments,
72+
group_by_department,
7373
get_all_departments,
7474
)
7575
from webapp.greenhouse import Greenhouse, Harvest
@@ -598,9 +598,7 @@ def handle_careers_index():
598598

599599

600600
def careers_index(greenhouse):
601-
all_departments, departments_overview = get_all_departments(
602-
greenhouse
603-
)
601+
all_departments, departments_overview = get_all_departments(greenhouse)
604602

605603
return flask.render_template(
606604
"/careers/index.html",
@@ -621,7 +619,7 @@ def handle_all_careers():
621619

622620

623621
def all_careers(greenhouse):
624-
sorted_departments = get_sorted_departments(greenhouse)
622+
sorted_departments = group_by_department(greenhouse.get_vacancies())
625623

626624
return flask.render_template(
627625
"/careers/all.html",
@@ -658,9 +656,7 @@ def handle_careers_progression():
658656

659657

660658
def careers_progression(greenhouse):
661-
all_departments, departments_overview = get_all_departments(
662-
greenhouse
663-
)
659+
all_departments, departments_overview = get_all_departments(greenhouse)
664660

665661
return flask.render_template(
666662
"/careers/company-culture/progression.html",
@@ -723,7 +719,7 @@ def handle_department_group(department_slug):
723719

724720

725721
def department_group(greenhouse, department_slug):
726-
departments = get_sorted_departments(greenhouse)
722+
departments = group_by_department(greenhouse.get_vacancies())
727723

728724
if department_slug not in departments:
729725
flask.abort(404)
@@ -739,7 +735,9 @@ def department_group(greenhouse, department_slug):
739735
formatted_slug = department_name.replace(" ", "+")
740736

741737
featured_jobs = [job for job in department["vacancies"] if job.featured]
742-
fast_track_jobs = [job for job in department["vacancies"] if job.fast_track]
738+
fast_track_jobs = [
739+
job for job in department["vacancies"] if job.fast_track
740+
]
743741

744742
templates = []
745743

webapp/careers.py

Lines changed: 4 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -59,16 +59,16 @@
5959
}
6060

6161

62-
def _group_by_department(vacancies):
62+
def group_by_department(vacancies):
6363
"""
6464
Return a dictionary of departments by slug,
6565
where each department will have a new
6666
"vacancies" property of all the vacancies in
6767
that department
6868
"""
6969
departments_by_slug = {
70-
key: {**department, "vacancies": []}
71-
for key, department in DEPARTMENT_LIST.items()
70+
department["slug"]: {**department, "vacancies": []}
71+
for department in DEPARTMENT_LIST.values()
7272
}
7373

7474
for vacancy in vacancies:
@@ -80,38 +80,11 @@ def _group_by_department(vacancies):
8080
return departments_by_slug
8181

8282

83-
def get_sorted_departments(greenhouse):
84-
departments = _group_by_department(greenhouse.get_vacancies())
85-
86-
sort_order = [
87-
"engineering",
88-
"support-engineering",
89-
"marketing",
90-
"web-and-design",
91-
"project-management",
92-
"commercial-operations",
93-
"product",
94-
"sales",
95-
"finance",
96-
"people",
97-
"administration",
98-
"legal",
99-
"alliances-and-channels",
100-
]
101-
102-
sorted = {slug: departments[slug] for slug in sort_order}
103-
remaining_slugs = set(departments.keys()).difference(sort_order)
104-
remaining = {slug: departments[slug] for slug in remaining_slugs}
105-
sorted_departments = {**sorted, **remaining}
106-
107-
return sorted_departments
108-
109-
11083
def get_all_departments(greenhouse) -> tuple:
11184
"""
11285
Refactor for careers search section
11386
"""
114-
all_departments = _group_by_department(greenhouse.get_vacancies())
87+
all_departments = group_by_department(greenhouse.get_vacancies())
11588

11689
departments_overview = []
11790
for department in all_departments.values():

0 commit comments

Comments
 (0)