Coverage for sm/views_onboarding.py: 74%
46 statements
« prev ^ index » next coverage.py v7.17.0, created at 2026-10-24 19:06 +0000
« prev ^ index » next coverage.py v7.17.0, created at 2026-10-24 19:06 +0000
1from django.contrib import messages
2from django.contrib.auth.mixins import LoginRequiredMixin
3from django.shortcuts import redirect
4from django.utils.translation import gettext as _
5from django.views.generic import TemplateView
6from typing import Any
8from .models import Invitation
9from uuid import UUID
12def user_has_real_groups(user) -> bool:
13 """
14 A user is considered on-boarded once they are a member of at least one
15 group that is not their automatically-created personal workspace.
16 """
17 for group in user.groups.all():
18 if not group.name.endswith("'s Workspace"):
19 return True
20 return False
23class GroupOnboardingView(LoginRequiredMixin, TemplateView):
24 template_name = "group/onboarding.html"
26 def get_context_data(self, **kwargs: Any) -> Any:
27 context = super().get_context_data(**kwargs)
28 context["onboarding_needed"] = not user_has_real_groups(self.request.user)
29 return context
31 def post(self, request: Any, *args: Any, **kwargs: Any) -> Any:
32 action = request.POST.get("action")
33 if action == "join":
34 token = request.POST.get("token", "").strip()
35 try:
36 UUID(token)
37 except (ValueError, TypeError):
38 messages.error(request, _("Invalid invitation token."))
39 return self.get(request, *args, **kwargs)
40 invitation = Invitation.objects.filter(token=token).first()
41 if invitation is None:
42 messages.error(request, _("Invalid invitation token."))
43 return self.get(request, *args, **kwargs)
44 return redirect("accept_invitation", token=token)
45 if action == "create":
46 return redirect("group_create")
47 messages.warning(request, _("Please choose an action."))
48 return self.get(request, *args, **kwargs)
51class OnboardingBannerContext:
52 """
53 Small helper so templates can render an onboarding banner via the
54 ``onboarding_needed`` context variable.
55 """
57 def __init__(self, request):
58 self.request = request
60 @property
61 def needs_onboarding(self) -> bool:
62 user = getattr(self.request, "user", None)
63 if user is None or not user.is_authenticated:
64 return False
65 return not user_has_real_groups(user)