# Path: sitegate/decorators.py
# def signin_view(*args, **kwargs):
#     """Decorator to mark views used for sign in."""
#     return FlowBuilder(ModernSignin, args, kwargs)
# 
# def signup_view(*args, **kwargs):
#     """Decorator to mark views used for signup."""
#     return FlowBuilder(ModernSignup, args, kwargs)
# 
# def redirect_signedin(*args, **kwargs):
#     """Decorator to mark views which should not be accessed by signed in users.
#     Example: sign in & sign up pages.
# 
#     """
#     return RedirectBuilder(args, kwargs)
# 
# def sitegate_view(*args_dec, **kwargs_dec):
#     """Decorator to mark views used both for signup & sign in."""
#     if len(args_dec):  # simple decoration w/o parameters
#         return signup_view(signin_view(redirect_signedin(*args_dec, **kwargs_dec)))
# 
#     signin = signin_view(**kwargs_dec)
#     signup = signup_view(**kwargs_dec)
# 
#     return lambda *args, **kwargs: signup(signin(redirect_signedin(*args, **kwargs)))
# 
# Path: sitegate/signin_flows/modern.py
# class ModernSignin(SigninFlow):
#     """Modernized login flow based on classic from Django built-in
#     with username e-mail authentication support."""
# 
#     form = ModernSigninForm
# 
# Path: sitegate/signup_flows/classic.py
# class ClassicSignup(SignupFlow):
#     """Classic registration flow borrowed from Django built-in UserCreationForm."""
# 
#     form = ClassicSignupForm
# 
#     def add_user(self, request: HttpRequest, form: ModelForm) -> 'User':
#         return form.save()
# 
#     def sign_in(self, request: HttpRequest, form: ModelForm, signup_result: 'User') -> bool:
#         form_data = form.cleaned_data
#         return self.login_generic(request, form_data['username'], form_data['password1'])
# 
# Path: sitegate/signup_flows/modern.py
# class ModernSignup(SimpleClassicWithEmailSignup):
#     """Modernized registration flow based on classic from Django built-in
#     with unique e-mail field, without username and second password fields.
# 
#     """
#     form = ModernSignupForm
# 
#     def sign_in(self, request: HttpRequest, form: ModelForm, signup_result: 'User') -> bool:
#         form_data = form.cleaned_data
#         return self.login_generic(request, form_data['email'], form_data['password1'])
# 
#     def add_user(self, request: HttpRequest, form: ModelForm) -> 'User':
# 
#         user = super(form.__class__, form).save(commit=False)
# 
#         if not hasattr(user, 'USERNAME_FIELD') or user.USERNAME_FIELD == 'username':
#             user.username = form.cleaned_data['email']
# 
#         user.email = form.cleaned_data['email']
#         user.set_password(form.cleaned_data['password1'])
#         user.save()
# 
#         self.send_email(request, user)
# 
#         return user


from django.http import HttpResponseRedirect
from sitegate.decorators import signin_view, signup_view, redirect_signedin, sitegate_view
from sitegate.signin_flows.classic import ClassicSignin
from sitegate.signin_flows.modern import ModernSignin
from sitegate.signup_flows.classic import ClassicSignup
from sitegate.signup_flows.modern import ModernSignup



def test_signin(request_get):
    # simple decoration
    response = signin_view(lambda req: req)(request_get('/signin/'))
    assert hasattr(response, 'sitegate')
    assert 'signin_forms' in response.sitegate
    assert 'signup_forms' not in response.sitegate

    # simple decoration + view with args
    response = signin_view(lambda req, a1, a2='b': (req, a1, a2))(request_get('/signin/'), 10, a2=20)
    assert hasattr(response[0], 'sitegate')
    assert 'signin_forms' in response[0].sitegate
    assert 'signup_forms' not in response[0].sitegate
    assert response[1] == 10
    assert response[2] == 20

    # stacking
    signin_view1 = signin_view(flow=ClassicSignin)
    signin_view2 = signin_view(flow=ModernSignin)
    response = signin_view1(signin_view2(lambda req: req))(request_get('/signin/'))
    assert hasattr(response, 'sitegate')
    assert 'signin_forms' in response.sitegate
    assert 'signup_forms' not in response.sitegate
    assert len(response.sitegate['signin_forms']) == 2
    dict_keys = list(response.sitegate['signin_forms'].keys())
    assert isinstance(response.sitegate['signin_forms'][dict_keys[0]], ClassicSignin.form)

# Path: sitegate/decorators.py
# def signin_view(*args, **kwargs):
#     """Decorator to mark views used for sign in."""
#     return FlowBuilder(ModernSignin, args, kwargs)
# 
# def signup_view(*args, **kwargs):
#     """Decorator to mark views used for signup."""
#     return FlowBuilder(ModernSignup, args, kwargs)
# 
# def redirect_signedin(*args, **kwargs):
#     """Decorator to mark views which should not be accessed by signed in users.
#     Example: sign in & sign up pages.
# 
#     """
#     return RedirectBuilder(args, kwargs)
# 
# def sitegate_view(*args_dec, **kwargs_dec):
#     """Decorator to mark views used both for signup & sign in."""
#     if len(args_dec):  # simple decoration w/o parameters
#         return signup_view(signin_view(redirect_signedin(*args_dec, **kwargs_dec)))
# 
#     signin = signin_view(**kwargs_dec)
#     signup = signup_view(**kwargs_dec)
# 
#     return lambda *args, **kwargs: signup(signin(redirect_signedin(*args, **kwargs)))
# 
# Path: sitegate/signin_flows/modern.py
# class ModernSignin(SigninFlow):
#     """Modernized login flow based on classic from Django built-in
#     with username e-mail authentication support."""
# 
#     form = ModernSigninForm
# 
# Path: sitegate/signup_flows/classic.py
# class ClassicSignup(SignupFlow):
#     """Classic registration flow borrowed from Django built-in UserCreationForm."""
# 
#     form = ClassicSignupForm
# 
#     def add_user(self, request: HttpRequest, form: ModelForm) -> 'User':
#         return form.save()
# 
#     def sign_in(self, request: HttpRequest, form: ModelForm, signup_result: 'User') -> bool:
#         form_data = form.cleaned_data
#         return self.login_generic(request, form_data['username'], form_data['password1'])
# 
# Path: sitegate/signup_flows/modern.py
# class ModernSignup(SimpleClassicWithEmailSignup):
#     """Modernized registration flow based on classic from Django built-in
#     with unique e-mail field, without username and second password fields.
# 
#     """
#     form = ModernSignupForm
# 
#     def sign_in(self, request: HttpRequest, form: ModelForm, signup_result: 'User') -> bool:
#         form_data = form.cleaned_data
#         return self.login_generic(request, form_data['email'], form_data['password1'])
# 
#     def add_user(self, request: HttpRequest, form: ModelForm) -> 'User':
# 
#         user = super(form.__class__, form).save(commit=False)
# 
#         if not hasattr(user, 'USERNAME_FIELD') or user.USERNAME_FIELD == 'username':
#             user.username = form.cleaned_data['email']
# 
#         user.email = form.cleaned_data['email']
#         user.set_password(form.cleaned_data['password1'])
#         user.save()
# 
#         self.send_email(request, user)
# 
#         return user


# Path: sitegate/tests/test_decorators.py
from django.http import HttpResponseRedirect
from sitegate.decorators import signin_view, signup_view, redirect_signedin, sitegate_view
from sitegate.signin_flows.classic import ClassicSignin
from sitegate.signin_flows.modern import ModernSignin
from sitegate.signup_flows.classic import ClassicSignup
from sitegate.signup_flows.modern import ModernSignup




def test_signin(request_get):
    # simple decoration
    response = signin_view(lambda req: req)(request_get('/signin/'))
    assert hasattr(response, 'sitegate')
    assert 'signin_forms' in response.sitegate
    assert 'signup_forms' not in response.sitegate

    # simple decoration + view with args
    response = signin_view(lambda req, a1, a2='b': (req, a1, a2))(request_get('/signin/'), 10, a2=20)
    assert hasattr(response[0], 'sitegate')
    assert 'signin_forms' in response[0].sitegate
    assert 'signup_forms' not in response[0].sitegate
    assert response[1] == 10
    assert response[2] == 20

    # stacking
    signin_view1 = signin_view(flow=ClassicSignin)
    signin_view2 = signin_view(flow=ModernSignin)
    response = signin_view1(signin_view2(lambda req: req))(request_get('/signin/'))
    assert hasattr(response, 'sitegate')
    assert 'signin_forms' in response.sitegate
    assert 'signup_forms' not in response.sitegate
    assert len(response.sitegate['signin_forms']) == 2
    dict_keys = list(response.sitegate['signin_forms'].keys())
    assert isinstance(response.sitegate['signin_forms'][dict_keys[0]], ClassicSignin.form)

    assert isinstance(response.sitegate['signin_forms'][dict_keys[1]], ModernSignin.form)