@Test
  public void registerUserAccount_SocialSignIn_ShouldCreateNewUserAccountAndRenderHomePage()
      throws Exception {
    TestProviderSignInAttempt socialSignIn =
        new TestProviderSignInAttemptBuilder()
            .connectionData()
            .providerId(SOCIAL_MEDIA_SERVICE)
            .userProfile()
            .email(EMAIL)
            .firstName(FIRST_NAME)
            .lastName(LAST_NAME)
            .build();

    User registered =
        new UserBuilder()
            .id(1L)
            .email(EMAIL)
            .firstName(FIRST_NAME)
            .lastName(LAST_NAME)
            .signInProvider(SIGN_IN_PROVIDER)
            .build();

    when(userServiceMock.registerNewUserAccount(isA(RegistrationForm.class)))
        .thenReturn(registered);

    mockMvc
        .perform(
            post("/user/register")
                .contentType(MediaType.APPLICATION_FORM_URLENCODED)
                .param(WebTestConstants.FORM_FIELD_EMAIL, EMAIL)
                .param(WebTestConstants.FORM_FIELD_FIRST_NAME, FIRST_NAME)
                .param(WebTestConstants.FORM_FIELD_LAST_NAME, LAST_NAME)
                .param(WebTestConstants.FORM_FIELD_SIGN_IN_PROVIDER, SIGN_IN_PROVIDER.name())
                .sessionAttr(ProviderSignInAttempt.SESSION_ATTRIBUTE, socialSignIn)
                .sessionAttr(WebTestConstants.MODEL_ATTRIBUTE_USER_FORM, new RegistrationForm()))
        .andExpect(status().isMovedTemporarily())
        .andExpect(redirectedUrl("/"));

    assertThat(SecurityContextHolder.getContext())
        .loggedInUserIs(registered)
        .loggedInUserIsSignedInByUsingSocialProvider(SIGN_IN_PROVIDER);
    assertThatSignIn(socialSignIn).createdConnectionForUserId(EMAIL);

    ArgumentCaptor<RegistrationForm> registrationFormArgument =
        ArgumentCaptor.forClass(RegistrationForm.class);
    verify(userServiceMock, times(1)).registerNewUserAccount(registrationFormArgument.capture());
    verifyNoMoreInteractions(userServiceMock);

    RegistrationForm formObject = registrationFormArgument.getValue();
    assertThatRegistrationForm(formObject)
        .isSocialSignInWithSignInProvider(SIGN_IN_PROVIDER)
        .hasEmail(EMAIL)
        .hasFirstName(FIRST_NAME)
        .hasLastName(LAST_NAME)
        .hasNoPassword()
        .hasNoPasswordVerification();
  }
  @Test
  public void
      registerUserAccount_NormalRegistrationAndEmailExists_ShouldRenderRegistrationFormWithFieldError()
          throws Exception {
    when(userServiceMock.registerNewUserAccount(isA(RegistrationForm.class)))
        .thenThrow(new DuplicateEmailException(""));

    mockMvc
        .perform(
            post("/user/register")
                .contentType(MediaType.APPLICATION_FORM_URLENCODED)
                .param(WebTestConstants.FORM_FIELD_EMAIL, EMAIL)
                .param(WebTestConstants.FORM_FIELD_FIRST_NAME, FIRST_NAME)
                .param(WebTestConstants.FORM_FIELD_LAST_NAME, LAST_NAME)
                .param(WebTestConstants.FORM_FIELD_PASSWORD, PASSWORD)
                .param(WebTestConstants.FORM_FIELD_PASSWORD_VERIFICATION, PASSWORD)
                .sessionAttr(WebTestConstants.SESSION_ATTRIBUTE_USER_FORM, new RegistrationForm()))
        .andExpect(status().isOk())
        .andExpect(view().name("user/registrationForm"))
        .andExpect(forwardedUrl("/WEB-INF/jsp/user/registrationForm.jsp"))
        .andExpect(
            model()
                .attribute(
                    WebTestConstants.MODEL_ATTRIBUTE_USER_FORM,
                    allOf(
                        hasProperty(WebTestConstants.FORM_FIELD_EMAIL, is(EMAIL)),
                        hasProperty(WebTestConstants.FORM_FIELD_FIRST_NAME, is(FIRST_NAME)),
                        hasProperty(WebTestConstants.FORM_FIELD_LAST_NAME, is(LAST_NAME)),
                        hasProperty(WebTestConstants.FORM_FIELD_PASSWORD, is(PASSWORD)),
                        hasProperty(WebTestConstants.FORM_FIELD_PASSWORD, is(PASSWORD)),
                        hasProperty(
                            WebTestConstants.FORM_FIELD_SIGN_IN_PROVIDER, isEmptyOrNullString()))))
        .andExpect(
            model()
                .attributeHasFieldErrors(
                    WebTestConstants.MODEL_ATTRIBUTE_USER_FORM, WebTestConstants.FORM_FIELD_EMAIL));

    assertThat(SecurityContextHolder.getContext()).userIsAnonymous();

    ArgumentCaptor<RegistrationForm> registrationFormArgument =
        ArgumentCaptor.forClass(RegistrationForm.class);
    verify(userServiceMock, times(1)).registerNewUserAccount(registrationFormArgument.capture());
    verifyNoMoreInteractions(userServiceMock);

    RegistrationForm formObject = registrationFormArgument.getValue();
    assertThatRegistrationForm(formObject)
        .isNormalRegistration()
        .hasEmail(EMAIL)
        .hasFirstName(FIRST_NAME)
        .hasLastName(LAST_NAME)
        .hasPassword(PASSWORD)
        .hasPasswordVerification(PASSWORD);
  }
  @Test
  public void registerUserAccount_NormalRegistration_ShouldCreateNewUserAccountAndRenderHomePage()
      throws Exception {
    User registered =
        new UserBuilder()
            .id(1L)
            .email(EMAIL)
            .firstName(FIRST_NAME)
            .lastName(LAST_NAME)
            .password(PASSWORD)
            .build();

    when(userServiceMock.registerNewUserAccount(isA(RegistrationForm.class)))
        .thenReturn(registered);

    mockMvc
        .perform(
            post("/user/register")
                .contentType(MediaType.APPLICATION_FORM_URLENCODED)
                .param(WebTestConstants.FORM_FIELD_EMAIL, EMAIL)
                .param(WebTestConstants.FORM_FIELD_FIRST_NAME, FIRST_NAME)
                .param(WebTestConstants.FORM_FIELD_LAST_NAME, LAST_NAME)
                .param(WebTestConstants.FORM_FIELD_PASSWORD, PASSWORD)
                .param(WebTestConstants.FORM_FIELD_PASSWORD_VERIFICATION, PASSWORD)
                .sessionAttr(WebTestConstants.SESSION_ATTRIBUTE_USER_FORM, new RegistrationForm()))
        .andExpect(status().isMovedTemporarily())
        .andExpect(redirectedUrl("/"));

    assertThat(SecurityContextHolder.getContext())
        .loggedInUserIs(registered)
        .loggedInUserHasPassword(registered.getPassword())
        .loggedInUserIsRegisteredByUsingNormalRegistration();

    ArgumentCaptor<RegistrationForm> registrationFormArgument =
        ArgumentCaptor.forClass(RegistrationForm.class);
    verify(userServiceMock, times(1)).registerNewUserAccount(registrationFormArgument.capture());
    verifyNoMoreInteractions(userServiceMock);

    RegistrationForm formObject = registrationFormArgument.getValue();
    assertThatRegistrationForm(formObject)
        .isNormalRegistration()
        .hasEmail(EMAIL)
        .hasFirstName(FIRST_NAME)
        .hasLastName(LAST_NAME)
        .hasPassword(PASSWORD)
        .hasPasswordVerification(PASSWORD);
  }