@Configuration
@EnableDiscoveryClient
@EnableHystrix
@EnableFeignClients
@SpringBootApplication
@EnableScheduling
@EnableJpaRepositories(basePackages = {"eu.nimble.core.infrastructure.identity"})
@EntityScan(basePackageClasses = {UaaUser.class, PartyType.class, PersonType.class, CodeType.class})
@EnableCaching
@ComponentScan(basePackages = {"eu.nimble.utility", "eu.nimble.utility.persistence.initalizer", "eu.nimble.core.infrastructure.identity"},excludeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = EmailService.class), @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = ThymeleafConfig.class)})
public class IdentityServiceApplication extends SpringBootServletInitializer {



    @Bean
    public HystrixCommandAspect hystrixAspect() {
        return new HystrixCommandAspect();
    }

    private static final Logger logger = LoggerFactory.getLogger(IdentityServiceApplication.class);

    @Value("${nimble.corsEnabled}")
    private String corsEnabled;

    @Bean
    @Primary
    @ConfigurationProperties(prefix="spring.datasource")
    public DataSource primaryDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    public WebMvcConfigurer corsConfigurer() {

        return new WebMvcConfigurerAdapter() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                if (corsEnabled.equals("true")) {
                    logger.info("Enabling CORS...");
                    registry.addMapping("/**").allowedMethods("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH");
                }
            }
        };
    }

    public static void main(String[] args) {
        new SpringApplicationBuilder(IdentityServiceApplication.class).web(true).run(args);
    }
} @Profile("test")
@TestConfiguration
public class DefaultTestConfiguration {

    @Bean
    @Primary
    public IdentityService identityResolver() throws IOException {

        IdentityService identityServiceMock = Mockito.mock(IdentityService.class);

        // mock user query
        when(identityServiceMock.getUserfromBearer(anyString())).thenReturn(new UaaUser());

        // mock company query
        when(identityServiceMock.getCompanyOfUser(anyObject())).then((Answer<Optional<PartyType>>) invocationOnMock -> {
            PartyType mockParty = new PartyType();
            return Optional.of(mockParty);
        });

        // mock verification of roles
        when(identityServiceMock.hasAnyRole(any(), anyVararg())).thenReturn(true);

        return identityServiceMock;
    }

    @Bean
    @Primary
    public KeycloakAdmin keycloakAdmin() {
        return Mockito.mock(KeycloakAdmin.class);
    }

    @Bean
    @Primary
    public EmailService emailService() {
        return Mockito.mock(EmailService.class);
    }

    @Bean
    @Primary
    public OAuthClient oAuthClient() {
        OAuthClient oAuthClient = Mockito.mock(OAuthClient.class);
        when(oAuthClient.refreshToken(anyString())).thenReturn(new DefaultOAuth2AccessToken("dummy token"));
        return oAuthClient;
    }

    @Bean
    @Primary
    public HttpSession httpSession() {
        HttpSession httpSession = Mockito.mock(HttpSession.class);
        when(httpSession.getAttribute(same(REFRESH_TOKEN_SESSION_KEY))).thenReturn("random string");
        return httpSession;
    }

    @Bean
    @Primary
    public CustomDbInitializer customDbInitializer(){
        return Mockito.mock(CustomDbInitializer.class);
    }
} @Entity
public class UaaUser implements Serializable {

    @Id
    @Column(nullable = false, unique = true)
    private String externalID;

    private String username;

    @OneToOne
    private PersonType ublPerson;

    @ColumnDefault("false")
    private Boolean showWelcomeInfo = false;

    public UaaUser() {
    }

    public UaaUser(String username, PersonType ublPerson, String externalID) {
        this.username = username;
        this.ublPerson = ublPerson;
        this.externalID = externalID;
        this.showWelcomeInfo = true;
    }

    public String getUsername() {
        return username;
    }

    public String getExternalID() {
        return externalID;
    }

    public PersonType getUBLPerson() {
        return this.ublPerson;
    }

    public Boolean getShowWelcomeInfo() {
        return showWelcomeInfo;
    }

    public void setShowWelcomeInfo(Boolean showWelcomeInfo) {
        this.showWelcomeInfo = showWelcomeInfo;
    }
} @ApiModel(value = "CompanyRegistration")
public class CompanyRegistration   {

    @ApiModelProperty(value = "Identifier of requesting user", required = true)
    private Long userID;

    @ApiModelProperty(value = "Identifier of registered company (will be set in response)")
    private Long companyID;// will be set after successful registration

    @ApiModelProperty(value = "Updated access token after registration")
    private String accessToken;

    @ApiModelProperty(value = "Settings of company")
    private CompanySettings settings;

    public Long getUserID() {
        return userID;
    }

    public void setUserID(Long userID) {
        this.userID = userID;
    }

    public Long getCompanyID() {
        return companyID;
    }

    public void setCompanyID(Long companyID) {
        this.companyID = companyID;
    }

    public String getAccessToken() {
        return accessToken;
    }

    public void setAccessToken(String accessToken) {
        this.accessToken = accessToken;
    }

    public CompanySettings getSettings() {
        return settings;
    }

    public void setSettings(CompanySettings settings) {
        this.settings = settings;
    }
} public interface PartyRepository extends PagingAndSortingRepository<PartyType, Long>, JpaSpecificationExecutor<PartyType> {

    @Transactional
    Iterable<PartyType> findAll(Sort sort);

    @Transactional
    Iterable<PartyType> findAllByDeletedIsFalse(Sort sort);

    @Transactional
    Page<PartyType> findAll(Pageable pageable);

    List<PartyType> findByHjid(Long hijd);

    List<PartyType> findByPerson(PersonType person);

    @Modifying
    @Transactional
    long deleteByHjid(Long hijd);

    @Query(value = "select hjid from document_reference_type where document_reference_party_typ_0 = ?1 and document_type = ?2", nativeQuery = true)
    List<BigInteger> findDocumentIds(Long companyId, String documentType);

    @Query(value = "FROM PartyType WHERE stripeAccountId = ?1")
    List<PartyType> findByStripeAccountId(String accountId);

    @Query(value = "FROM PartyType WHERE productPublishSubscription is not null")
    List<PartyType> findAllWithSubscriptions();

    @Query(value = "select pt.hjid from document_reference_type drt,trading_preferences tp,party_type pt where drt.id = ?1 and tp.hjid = drt.document_reference_trading_p_0 and pt.sales_terms_party_type_hjid = tp .hjid",nativeQuery = true)
    List<BigInteger> findByTermsAndConditionsDocumentReferenceId(String id);
} public interface PersonRepository extends PagingAndSortingRepository<PersonType, Long> {
    List<PersonType> findByHjid(Long hijd);
} public interface QualifyingPartyRepository extends PagingAndSortingRepository<QualifyingPartyType, Long> {

    List<QualifyingPartyType> findByHjid(Long hijd);

    List<QualifyingPartyType> findByParty(PartyType party);

    @Modifying
    @Transactional
    long deleteByParty(PartyType party);
} public interface UaaUserRepository extends PagingAndSortingRepository<UaaUser, Long> {
    Page<UaaUser> findAll(Pageable pageable);

    List<UaaUser> findByUsername(String username);

    UaaUser findOneByUsername(String username);

    UaaUser findByExternalID(String externalId);

    @Modifying
    @Transactional
    long deleteByUblPerson(PersonType ublPerson);

    List<UaaUser> findByUblPerson(PersonType ublPerson);
} public static final String JSON_DATE_FORMAT = "yyyy-MM-dd";
 public static CompanyRegistration createCompanyRegistration(String legalName, PersonType user) {

    HashMap<NimbleConfigurationProperties.LanguageID, String> industrySectors = new HashMap<>();
    industrySectors.put(ENGLISH, "industrySector");

    HashMap<NimbleConfigurationProperties.LanguageID, String> companyStatement = new HashMap<>();
    companyStatement.put(ENGLISH, "industrySector");

    CompanyDetails companyDetails = new CompanyDetails(Collections.singletonMap(ENGLISH, "brand name"),
            Collections.singletonMap(ENGLISH, legalName), "vat number", "verification info",
            new Address(), "business type", Collections.singletonMap(ENGLISH, "business type"), 1970,
            industrySectors,new ArrayList<>(),new ArrayList<>());
    CompanyDescription companyDescription = new CompanyDescription(companyStatement, "website",
            Collections.singletonList("photos"), "imageId", Collections.singletonList("social media"),
            Collections.singletonList(new CompanyEvent()), Collections.singletonList("test"));
    CompanyTradeDetails companyTradeDetails = new CompanyTradeDetails();
    CompanySettings companySettings = new CompanySettings("123", companyDetails, companyDescription,
            companyTradeDetails, Collections.singletonList(new CompanyCertificate()), Collections.singleton("category 1"), Collections.singleton("category 2"),null,null);
    CompanyRegistration companyRegistration = new CompanyRegistration();
    companyRegistration.setCompanyID(123L);
    companyRegistration.setUserID(user.getHjid());
    companyRegistration.setAccessToken("DUMMY ACCESSTOKEN");
    companyRegistration.setSettings(companySettings);

    return companyRegistration;
}

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import eu.nimble.core.infrastructure.identity.IdentityServiceApplication;
import eu.nimble.core.infrastructure.identity.config.DefaultTestConfiguration;
import eu.nimble.core.infrastructure.identity.entity.UaaUser;
import eu.nimble.core.infrastructure.identity.entity.dto.CompanyRegistration;
import eu.nimble.core.infrastructure.identity.repository.PartyRepository;
import eu.nimble.core.infrastructure.identity.repository.PersonRepository;
import eu.nimble.core.infrastructure.identity.repository.QualifyingPartyRepository;
import eu.nimble.core.infrastructure.identity.repository.UaaUserRepository;
import eu.nimble.service.model.ubl.commonaggregatecomponents.PersonType;
import org.hamcrest.Matchers;
import org.junit.ClassRule;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Import;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.kafka.test.rule.KafkaEmbedded;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import static eu.nimble.core.infrastructure.identity.TestUtils.JSON_DATE_FORMAT;
import static eu.nimble.core.infrastructure.identity.TestUtils.createCompanyRegistration;
import static org.hamcrest.Matchers.is;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
package eu.nimble.core.infrastructure.identity.controller;




/**
 * Created by Johannes Innerbichler on 2019-02-01.
 */
@SuppressWarnings("OptionalGetWithoutIsPresent")
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK, classes = IdentityServiceApplication.class)
@AutoConfigureMockMvc
@ActiveProfiles("test")
@FixMethodOrder
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS)
@Import(DefaultTestConfiguration.class)
public class PartyControllerTests {

    @Autowired
    private MockMvc mockMvc;

    @Autowired
    private PartyRepository partyRepository;

    @Autowired
    private QualifyingPartyRepository qualifyingPartyRepository;