-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
City of London registration info #108
Changes from 5 commits
594abf4
0c41884
0b8fb4a
787304a
2594c7a
8720b28
6d8956b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -151,9 +151,12 @@ def context(self): | |
context["can_register_vac"] = self.timetable.is_before( | ||
TimetableEvent.VAC_APPLICATION_DEADLINE | ||
) | ||
context["htag"] = "h2" | ||
context["htag_primary"] = "h2" | ||
context["htag_secondary"] = "h3" | ||
if self.response_type == ResponseTypes.MULTIPLE_DATES: | ||
context["htag"] = "h3" | ||
context["htag_primary"] = "h3" | ||
context["htag_secondary"] = "h4" | ||
context["toc_id"] = self.toc_id | ||
return context | ||
|
||
@property | ||
|
@@ -162,7 +165,34 @@ def toc_label(self): | |
|
||
@property | ||
def toc_id(self): | ||
return "voter-registration" | ||
return f"voter-registration-{self.timetable.registration_deadline}" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I think this should make it unique There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I actually realised when I came back to this we need to account for both polling day and the registration deadline to ensure uniqueness |
||
|
||
|
||
class CityOfLondonRegistrationDateSection(RegistrationDateSection): | ||
template_name = "includes/registration_timetable_col.html" | ||
|
||
def __init__(self, *args, **kwargs) -> None: | ||
self.with_headers = kwargs.pop("with_headers") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Basically: If we're showing 2 "register to vote" CTAs, we need a way to say "don't show the headers on the second one" |
||
super().__init__(*args, **kwargs) | ||
|
||
@property | ||
def weight(self): | ||
parent_weight = super().weight | ||
return 0 if parent_weight == 0 else parent_weight + 1 | ||
|
||
@property | ||
def context(self): | ||
context = super().context | ||
context["with_headers"] = self.with_headers | ||
return context | ||
|
||
@property | ||
def toc_label(self): | ||
return _("Voter registration") | ||
|
||
@property | ||
def toc_id(self): | ||
return f"voter-registration-col-{self.timetable.registration_deadline}" | ||
|
||
|
||
class ElectionDateTemplateSorter: | ||
|
@@ -199,7 +229,7 @@ def __init__( | |
|
||
self.polling_station_opening_times_str = _("7am – 10pm") | ||
if any( | ||
"city-of-london" in ballot.ballot_paper_id | ||
ballot.ballot_paper_id.startswith("local.city-of-london.") | ||
for ballot in self.date_data.ballots | ||
): | ||
self.polling_station_opening_times_str = _("8am – 8pm") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Declaring this out of scope for this PR 🏃 |
||
|
@@ -217,18 +247,50 @@ def __init__( | |
"timetable": self.timetable, | ||
} | ||
|
||
enabled_sections = [BallotSection] | ||
if not self.all_cancelled: | ||
enabled_sections.append(RegistrationDateSection) | ||
enabled_sections = [BallotSection(**section_kwargs)] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Previously we were making a list of classes and then constructing them all into objects at the end with the same kwargs. I've switched to constructing objects as I go. This allows me to pass in custom timetable into each registration section instead of having on global one. |
||
|
||
city_of_london_ballots = [ | ||
b | ||
for b in self.date_data.ballots | ||
if not b.cancelled | ||
and b.ballot_paper_id.startswith("local.city-of-london.") | ||
] | ||
other_ballots = [ | ||
b | ||
for b in self.date_data.ballots | ||
if not b.cancelled | ||
and not b.ballot_paper_id.startswith("local.city-of-london.") | ||
] | ||
if len(other_ballots) > 0: | ||
enabled_sections.append( | ||
RegistrationDateSection( | ||
data=self.date_data, | ||
mode=self.current_mode, | ||
response_type=self.response_type, | ||
current_date=self.current_date, | ||
timetable=from_election_id( | ||
other_ballots[0].election_id, country=country | ||
), | ||
) | ||
) | ||
if len(city_of_london_ballots) > 0: | ||
enabled_sections.append( | ||
CityOfLondonRegistrationDateSection( | ||
data=self.date_data, | ||
mode=self.current_mode, | ||
response_type=self.response_type, | ||
current_date=self.current_date, | ||
timetable=from_election_id( | ||
city_of_london_ballots[0].election_id, country=country | ||
), | ||
with_headers=len(other_ballots) == 0, | ||
) | ||
) | ||
|
||
if self.first_upcoming_date: | ||
enabled_sections.append(PollingStationSection) | ||
enabled_sections.append(PollingStationSection(**section_kwargs)) | ||
|
||
self.sections = sorted( | ||
[section(**section_kwargs) for section in enabled_sections], | ||
key=lambda sec: sec.weight, | ||
# reverse=True, | ||
) | ||
self.sections = sorted(enabled_sections, key=lambda sec: sec.weight) | ||
|
||
|
||
class TemplateSorter: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nitpick: I first read this as "column" not "City Of London". Would you mind calling this |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
{% if section.context.with_headers %} | ||
<{{ section.context.htag_primary }} id="{{toc_id}}">{% trans %}Voter registration{% endtrans %}</{{ section.context.htag_primary }}> | ||
{% endif %} | ||
{% if section.context.can_register %} | ||
{% if section.context.with_headers %} | ||
<{{ section.context.htag_secondary }}>{% trans %}Register to vote{% endtrans %}</{{ section.context.htag_secondary }}> | ||
{% endif %} | ||
<p>{% trans %}City of London council elections do not use the same electoral register as other elections.{% endtrans %}</p> | ||
<p> | ||
{% trans %} | ||
Both residents and city workers are eligible to vote. There is one register | ||
published annually, and the deadline to apply is 30 November each year. | ||
The new register comes into force on 16 February each year, | ||
and cannot be modified after that date. | ||
{% endtrans %} | ||
</p> | ||
<p> | ||
<a href="https://www.speakforthecity.com/" class="o-button o-button--primary o-button--dark o-external-link"> | ||
{% trans %}Register to vote in the City of London{% endtrans %} | ||
</a> | ||
</p> | ||
{% else %} | ||
<{{ section.context.htag_secondary }} id="{{toc_id}}">{% trans %}Registration in the City of London{% endtrans %}</{{ section.context.htag_secondary }}> | ||
<p>{% trans %}City of London council elections do not use the same electoral register as other elections.{% endtrans %}</p> | ||
{% | ||
trans | ||
date=section.data.date|date_filter, | ||
registration_deadline=section.timetable.registration_deadline|date_filter | ||
%} | ||
<p>The deadline to register to vote in City of London local elections on {{ date }} | ||
was {{ registration_deadline }}.</p> | ||
<p>If you registered to vote before the deadline, then you will be able to vote in this election. <a | ||
href="#electoral_services">Contact City of London</a> to check if you are on the register.</p> | ||
<p>You can <a href="https://www.speakforthecity.com/">register to vote in the City of London</a> in future elections.</p> | ||
{% endtrans %} | ||
{% endif %} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I haven't updated any translations in this PR. See #110 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, all this text is open to change if it needs it. I've mostly used the same text Peter gave me that we used in DemocracyClub/WhoCanIVoteFor#2071 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,13 @@ | |
import uvicorn | ||
from app import app | ||
from starlette.testclient import TestClient | ||
from template_sorter import ( | ||
ApiModes, | ||
ElectionDateTemplateSorter, | ||
TemplateSorter, | ||
) | ||
from uk_election_timetables.calendars import Country | ||
from uk_election_timetables.election_ids import from_election_id | ||
|
||
|
||
@pytest.fixture(scope="function") | ||
|
@@ -33,3 +40,46 @@ def uvicorn_server(): | |
time.sleep(0.3) | ||
yield f"http://localhost:{port}" | ||
proc.kill() | ||
|
||
|
||
@pytest.fixture | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here I am just moving these fixtures into |
||
def template_sorter(): | ||
def get_template_sorter(mock_response, date): | ||
api_response = mock_response | ||
# The dates exist in the api_response, but not | ||
# in the format that matches the RootBuilder: | ||
# dates = api_response._values["dates"] vs | ||
# dates = api_response.dates so I've set it here. | ||
api_response.dates = api_response._values["dates"] | ||
mode = ApiModes.UPCOMING_ELECTIONS | ||
|
||
sorter = TemplateSorter( | ||
api_response=api_response, mode=mode, current_date=date | ||
) | ||
sorter.country = Country.ENGLAND | ||
sorter.dates = api_response.dates | ||
|
||
return sorter | ||
|
||
return get_template_sorter | ||
|
||
|
||
@pytest.fixture | ||
def election_date_template_sorter(): | ||
def get_election_date_template_sorter(template_sorter, date): | ||
election_date_sorter = ElectionDateTemplateSorter( | ||
date_data=date, | ||
country=template_sorter.country, | ||
current_date=template_sorter.current_date, | ||
response_type=template_sorter.response_type, | ||
) | ||
election_date_sorter.current_date = template_sorter.current_date | ||
|
||
election_date_sorter.timetable = from_election_id( | ||
template_sorter.dates[0].ballots[0].election_id, | ||
country=template_sorter.country, | ||
) | ||
|
||
return election_date_sorter | ||
|
||
return get_election_date_template_sorter |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was a little issue I fixed while I was here.
Previously if
htag
wash3
we'd render the next heading as ah3
too