package at.ac.tuwien.inso.integration_tests;

import static java.util.Arrays.asList;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user;
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.MockMvcResultMatchers.model;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;

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.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;

import at.ac.tuwien.inso.entity.Course;
import at.ac.tuwien.inso.entity.Semester;
import at.ac.tuwien.inso.entity.SemesterType;
import at.ac.tuwien.inso.entity.Subject;
import at.ac.tuwien.inso.repository.CourseRepository;
import at.ac.tuwien.inso.repository.SemesterRepository;

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
@ActiveProfiles("test")
@Transactional
public class AdminSubjectsTests extends AbstractSubjectsTests {

    @Autowired
    private CourseRepository courseRepository;

    @Autowired
    private SemesterRepository semesterRepository;

    @Test
    public void adminShouldSeeSubjectsOfFirstPage() throws Exception {

        // when subjects are created
        subjectRepository.save(calculus);
        subjectRepository.save(sepm);
        subjectRepository.save(ase);

        // then the admin should see them all in the first page
        mockMvc.perform(
                get("/admin/subjects").with(user("admin").roles("ADMIN")))
                .andExpect(model().attribute("subjects", asList(calculus, sepm, ase))
        );
    }
    
    @Test
    public void adminShouldBeAbleToDeleteSubjects() throws Exception {

        Subject cal = subjectRepository.save(calculus);
        subjectRepository.save(sepm);
        subjectRepository.save(ase);

        // then the admin should see them all in the first page
        mockMvc.perform(
                post("/admin/subjects/remove/"+cal.getId())
                        .with(user("admin").roles("ADMIN"))
                        .with(csrf())
        ).andExpect(
            redirectedUrl("/admin/subjects/page/0")
        );
        
        assertFalse(subjectRepository.exists(cal.getId()));
    }
    
    @Test
    public void adminSubjectShouldNotBeRemovedIfItContainsCourses() throws Exception {

        Subject cal = subjectRepository.save(calculus);
        subjectRepository.save(sepm);
        subjectRepository.save(ase);
        
        Semester ws2016 = new Semester(2016, SemesterType.WinterSemester);
        semesterRepository.save(ws2016);
        Course calculusWS2016o = new Course(cal, ws2016);
        
        Course calculusWS2016 = courseRepository.save(calculusWS2016o);
        
        

        // then the admin should see them all in the first page
        mockMvc.perform(
                post("/admin/subjects/remove/"+cal.getId())
                        .with(user("admin").roles("ADMIN"))
                        .with(csrf())
        ).andExpect(
            redirectedUrl("/admin/subjects")
        );
        
        assertTrue(subjectRepository.exists(cal.getId()));
    }


    @Test
    public void adminShouldSeeSubjectDetails() throws Exception {

        // when subjects are created and assigned to lecturers
        sepm.addLecturers(lecturer1);
        ase.addLecturers(lecturer1, lecturer2);
        Long id1 = subjectRepository.save(calculus).getId();
        Long id2 = subjectRepository.save(sepm).getId();
        Long id3 = subjectRepository.save(ase).getId();

        // admin should see subject calculus without any lecturers
        mockMvc.perform(
                get("/admin/subjects/"+id1).with(user("admin").roles("ADMIN"))
        ).andExpect(
                model().attribute("subject", calculus)
        ).andExpect(
                model().attribute("lecturers", asList())
        );

        //admin should see subject sepm with lecturer1
        mockMvc.perform(
                get("/admin/subjects/"+id2).with(user("admin").roles("ADMIN"))
        ).andExpect(
                model().attribute("subject", sepm)
        ).andExpect(
                model().attribute("lecturers", asList(lecturer1))
        );

        //admin should see subject ase with lecturer1 and lecturer2
        mockMvc.perform(
                get("/admin/subjects/"+id3).with(user("admin").roles("ADMIN"))
        ).andExpect(
                model().attribute("subject", ase)
        ).andExpect(
                model().attribute("lecturers", asList(lecturer1, lecturer2))
        );
    }

    @Test
    public void adminCreateSubjectTest() {
        //TODO
    }

    @Test
    public void adminListSubjectsForPageSearchNullAndPageNumberOneTest() {
        //TODO
    }

    @Test
    public void adminListSubjectsForPageSearchEmptyTest() {
        //TODO
    }

    @Test
    public void adminListSubjectsForPagePageNumberOneTest() {
        //TODO
    }



}

@@ -74,24 +74,69 @@
 ays.asList;%0A
+import static org.junit.Assert.assertEquals;%0A
 import stati
@@ -786,24 +786,59 @@
 rectedUrl;%0A%0A
+import at.ac.tuwien.inso.entity.*;%0A
 import org.j
@@ -1277,177 +1277,8 @@
 l;%0A%0A
-import at.ac.tuwien.inso.entity.Course;%0Aimport at.ac.tuwien.inso.entity.Semester;%0Aimport at.ac.tuwien.inso.entity.SemesterType;%0Aimport at.ac.tuwien.inso.entity.Subject;%0A
 impo
@@ -1384,16 +1384,46 @@
 itory;%0A%0A
+import java.math.BigDecimal;%0A%0A
 @RunWith
@@ -5239,32 +5239,590 @@
 tTest() 
-%7B%0A        //TODO
+throws Exception %7B%0A%0A        String name = %22maths%22;%0A        BigDecimal ects = new BigDecimal(6.0);%0A%0A        mockMvc.perform(%0A                post(%22/admin/subjects/create%22)%0A                        .with(user(%22admin%22).roles(Role.ADMIN.name()))%0A                        .param(%22name%22, name)%0A                        .param(%22ects%22, ects.toString())%0A                        .with(csrf())%0A        );%0A%0A        Subject subject = subjectRepository.findByNameContainingIgnoreCase(name).get(0);%0A        assertEquals(name, subject.getName());%0A        assertEquals(ects, subject.getEcts());
 %0A    %7D%0A%0A

test for creating a new subject.