Skip to content

Commit 1f076e2

Browse files
committed
support switching to non-English community forums
1 parent b8ada97 commit 1f076e2

File tree

4 files changed

+103
-10
lines changed

4 files changed

+103
-10
lines changed

kitsune/questions/jinja2/questions/includes/aaq_macros.html

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -225,9 +225,16 @@ <h2 class="sumo-page-subheading">{{ _('Topics') }}</h2>
225225
{{ _('You can also post your question directly to our support team for assistance.') }}
226226
{% endif %}
227227
</p>
228-
<a href="{{ url('questions.aaq_step3', product_slug=current_product.slug) | urlparams(support_type=switch_to_type, next=next_url) }}" class="sumo-button secondary-button">
229-
{{ _('Continue') }}
230-
</a>
228+
<div class="switcher-actions">
229+
<a href="{{ url('questions.aaq_step3', product_slug=current_product.slug) | urlparams(support_type=switch_to_type, next=next_url) }}" class="sumo-button secondary-button">
230+
{{ _('Continue') }}
231+
</a>
232+
{% if localized_forum_link %}
233+
<a href="{{ url('questions.aaq_step3', product_slug=current_product.slug, locale=localized_forum_link.locale) | urlparams(support_type=switch_to_type, next=next_url) }}">
234+
{{ localized_forum_link.text }}
235+
</a>
236+
{% endif %}
237+
</div>
231238
</div>
232239
{%- endmacro %}
233240

kitsune/questions/tests/test_views.py

Lines changed: 70 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@
77

88
from kitsune.flagit.models import FlaggedObject
99
from kitsune.products.models import ProductSupportConfig
10-
from kitsune.products.tests import ProductFactory, ProductSupportConfigFactory, TopicFactory
10+
from kitsune.products.tests import (
11+
ProductFactory,
12+
ProductSupportConfigFactory,
13+
TopicFactory,
14+
ZendeskConfigFactory,
15+
)
1116
from kitsune.questions.models import (
1217
AAQConfig,
1318
Answer,
@@ -43,7 +48,7 @@ def test_ratelimit(self):
4348
product=p,
4449
forum_config=aaq_config,
4550
is_active=True,
46-
default_support_type=ProductSupportConfig.SUPPORT_TYPE_FORUM
51+
default_support_type=ProductSupportConfig.SUPPORT_TYPE_FORUM,
4752
)
4853
topic = TopicFactory(slug="troubleshooting", products=[p], in_aaq=True)
4954
data = {
@@ -99,7 +104,7 @@ def setUp(self):
99104
product=product,
100105
forum_config=aaq_config,
101106
is_active=True,
102-
default_support_type=ProductSupportConfig.SUPPORT_TYPE_FORUM
107+
default_support_type=ProductSupportConfig.SUPPORT_TYPE_FORUM,
103108
)
104109

105110
def test_non_authenticated_user(self):
@@ -138,6 +143,68 @@ def test_authenticated_user(self):
138143
assert template_used(response, "questions/new_question.html")
139144

140145

146+
class AAQZendeskRedirectLocaleTests(TestCase):
147+
"""Tests that the Zendesk redirect preserves the original locale for the community switcher."""
148+
149+
def setUp(self):
150+
self.product = ProductFactory(title="Firefox", slug="firefox")
151+
en_locale, _ = QuestionLocale.objects.get_or_create(locale="en-US")
152+
fr_locale, _ = QuestionLocale.objects.get_or_create(locale="fr")
153+
aaq_config = AAQConfigFactory(
154+
product=self.product,
155+
enabled_locales=[en_locale, fr_locale],
156+
is_active=True,
157+
)
158+
ProductSupportConfigFactory(
159+
product=self.product,
160+
forum_config=aaq_config,
161+
zendesk_config=ZendeskConfigFactory(),
162+
is_active=True,
163+
default_support_type=ProductSupportConfig.SUPPORT_TYPE_ZENDESK,
164+
)
165+
self.user = UserFactory(is_superuser=False)
166+
self.client.login(username=self.user.username, password="testpass")
167+
168+
def test_zendesk_redirect_includes_from_locale(self):
169+
"""When a non-English user hits the Zendesk form, the redirect includes from_locale."""
170+
url = reverse("questions.aaq_step3", locale="fr", args=["firefox"])
171+
response = self.client.get(url)
172+
self.assertEqual(response.status_code, 302)
173+
self.assertIn("from_locale=fr", response["Location"])
174+
175+
def test_localized_forum_link_set_when_forum_enabled(self):
176+
"""When from_locale differs from current locale and the forum supports it,
177+
a localized forum link appears in the switcher widget."""
178+
url = reverse("questions.aaq_step3", locale="en-US", args=["firefox"])
179+
response = self.client.get(url, {"from_locale": "fr"})
180+
self.assertEqual(response.status_code, 200)
181+
doc = pq(response.content)
182+
# The widget is rendered twice (sidebar + inline), so expect 2 links.
183+
links = doc(".switcher-actions a:not(.sumo-button)")
184+
self.assertEqual(len(links), 2)
185+
for link in links.items():
186+
self.assertIn("/fr/questions/new/firefox/form", link.attr("href"))
187+
self.assertIn(settings.LANGUAGES_DICT["fr"], link.text())
188+
189+
def test_no_localized_forum_link_without_from_locale(self):
190+
"""When from_locale is absent, no localized forum link appears."""
191+
url = reverse("questions.aaq_step3", locale="en-US", args=["firefox"])
192+
response = self.client.get(url)
193+
self.assertEqual(response.status_code, 200)
194+
doc = pq(response.content)
195+
links = doc(".switcher-actions a:not(.sumo-button)")
196+
self.assertEqual(len(links), 0)
197+
198+
def test_no_localized_forum_link_for_unsupported_locale(self):
199+
"""When from_locale is a locale the forum doesn't support, no localized link appears."""
200+
url = reverse("questions.aaq_step3", locale="en-US", args=["firefox"])
201+
response = self.client.get(url, {"from_locale": "de"})
202+
self.assertEqual(response.status_code, 200)
203+
doc = pq(response.content)
204+
links = doc(".switcher-actions a:not(.sumo-button)")
205+
self.assertEqual(len(links), 0)
206+
207+
141208
class TestQuestionUpdates(TestCase):
142209
"""Tests that questions are only updated in the right cases."""
143210

kitsune/questions/views.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
)
2727
from django.shortcuts import get_object_or_404, redirect, render
2828
from django.template.loader import render_to_string
29-
from django.utils import timezone
29+
from django.utils import timezone, translation
3030
from django.utils.translation import gettext as _
3131
from django.utils.translation import gettext_lazy as _lazy
3232
from django.views.decorators.http import require_GET, require_http_methods, require_POST
@@ -681,15 +681,29 @@ def aaq(request, product_slug=None, step=1, is_loginless=False):
681681

682682
messages.add_message(request, messages.WARNING, msg)
683683

684+
params = request.GET.copy()
685+
params["from_locale"] = request.LANGUAGE_CODE
684686
return HttpResponseRedirect(
685687
reverse(
686688
"questions.aaq_step3",
687689
locale=settings.WIKI_DEFAULT_LANGUAGE,
688690
args=[product.slug],
689691
)
690-
+ (f"?{request.GET.urlencode()}" if request.GET else "")
692+
+ f"?{params.urlencode()}"
691693
)
692694

695+
if (
696+
(from_locale := request.GET.get("from_locale"))
697+
and from_locale != request.LANGUAGE_CODE
698+
and product.questions_enabled(locale=from_locale)
699+
):
700+
language = settings.LANGUAGES_DICT[from_locale.lower()]
701+
with translation.override(from_locale):
702+
context["localized_forum_link"] = {
703+
"locale": from_locale,
704+
"text": _("Continue in {language}").format(language=language),
705+
}
706+
693707
context["next_url"] = next_url = get_next_url(request)
694708

695709
context["cancel_url"] = next_url or (

kitsune/sumo/static/sumo/scss/layout/_aaq.scss

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,13 @@ aside .aaq-widget {
153153
color: var(--color-text);
154154
}
155155

156-
// Continue button - centered but not stretched
157-
text-align: center;
156+
// Actions area with button and optional localized link
157+
.switcher-actions {
158+
display: flex;
159+
flex-direction: column;
160+
align-items: center;
161+
gap: p.$spacing-lg;
162+
}
158163

159164
// Reduced motion support
160165
@media (prefers-reduced-motion: reduce) {

0 commit comments

Comments
 (0)