package at.ac.tuwien.inso;

import at.ac.tuwien.inso.entity.*;
import at.ac.tuwien.inso.repository.LecturerRepository;
import at.ac.tuwien.inso.repository.SubjectRepository;
import org.junit.Before;
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.annotation.DirtiesContext;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;

import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;

import static java.util.Arrays.asList;
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.result.MockMvcResultMatchers.model;

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
@ActiveProfiles("test")
public class SubjectsTest {

    private UserAccount user1 = new UserAccount("lecturer1", "pass", Role.LECTURER);
    private Lecturer lecturer1 = new Lecturer("Lecturer 1", "email", user1);
    private Lecturer lecturer2 = new Lecturer("Lecturer 2", "email", new UserAccount("lecturer2", "pass", Role.LECTURER));
    private Lecturer lecturer3 = new Lecturer("Lecturer 3", "email", new UserAccount("lecturer3", "pass", Role.LECTURER));
    private Subject calculus = new Subject("Calculus", new BigDecimal(3.0));
    private Subject sepm = new Subject("SEPM", new BigDecimal(6.0));
    private Subject ase = new Subject("ASE", new BigDecimal(6.0));

    @Autowired
    MockMvc mockMvc;
    @Autowired
    private SubjectRepository subjectRepository;
    @Autowired
    private LecturerRepository lecturerRepository;


    @Before
    public void setUp() {
        lecturerRepository.save(lecturer1);
        lecturerRepository.save(lecturer2);
        lecturerRepository.save(lecturer3);
    }

    @Test
    @Transactional
    public void adminShouldSeeAllSubjects() throws Exception {

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

        // then the admin should see them all
        mockMvc.perform(
                get("/admin/subjects").with(user("admin").roles("ADMIN"))
        ).andExpect(
                model().attribute("subjects", asList(calculus, sepm, ase))
        );
    }

    @Test
    @Transactional
    public void adminShouldSeeSubjectDetails() throws Exception {

        // when subjects are created and assigned to lecturers
        sepm.addLecturers(lecturer1);
        ase.addRequiredSubjects(sepm);
        ase.addLecturers(lecturer1, lecturer2);
        subjectRepository.save(calculus);
        subjectRepository.save(sepm);
        subjectRepository.save(ase);

        // admin should see subject calculus without any lecturers or prerequisites
        mockMvc.perform(
                get("/admin/subjects").param("id", "1").with(user("admin").roles("ADMIN"))
        ).andExpect(
                model().attribute("subject", calculus)
        ).andExpect(
                model().attribute("lecturers", asList())
        ).andExpect(
                model().attribute("requiredSubjects", asList())
        );

        //admin should see subject sepm with lecturer1 and no required subject sepm
        mockMvc.perform(
                get("/admin/subjects").param("id", "2").with(user("admin").roles("ADMIN"))
        ).andExpect(
                model().attribute("subject", sepm)
        ).andExpect(
                model().attribute("lecturers", asList(lecturer1))
        ).andExpect(
                model().attribute("requiredSubjects", asList())
        );

        //admin should see subject ase with lecturer1 and lecturer2 and required subject sepm
        mockMvc.perform(
                get("/admin/subjects").param("id", "3").with(user("admin").roles("ADMIN"))
        ).andExpect(
                model().attribute("subject", ase)
        ).andExpect(
                model().attribute("lecturers", asList(lecturer1, lecturer2))
        ).andExpect(
                model().attribute("requiredSubjects", asList(sepm))
        );
    }

}

@@ -4574,10 +4574,1167 @@
 %0A    %7D%0A%0A
+    @Test%0A    @Transactional%0A    public void lecturersShouldSeeTheirOwnSubjects() throws Exception %7B%0A%0A        // when subjects are created and assigned to lecturers%0A        sepm.addLecturers(lecturer1);%0A        ase.addRequiredSubjects(sepm);%0A        ase.addLecturers(lecturer1, lecturer2);%0A        subjectRepository.save(calculus);%0A        subjectRepository.save(sepm);%0A        subjectRepository.save(ase);%0A%0A        // lecturer1 should see sepm and ase%0A        mockMvc.perform(%0A                get(%22/lecturer/subjects%22).with(user(%22lecturer1%22).roles(%22LECTURER%22))%0A        ).andExpect(%0A                model().attribute(%22ownedSubjects%22, asList(sepm, ase))%0A        );%0A%0A        // lecturer2 should see ase%0A        mockMvc.perform(%0A                get(%22/lecturer/subjects%22).with(user(%22lecturer2%22).roles(%22LECTURER%22))%0A        ).andExpect(%0A                model().attribute(%22ownedSubjects%22, asList(ase))%0A        );%0A%0A        // lecturer3 should see nothing%0A        mockMvc.perform(%0A                get(%22/lecturer/subjects%22).with(user(%22lecturer3%22).roles(%22LECTURER%22))%0A        ).andExpect(%0A                model().attribute(%22ownedSubjects%22, asList())%0A        );%0A%0A    %7D%0A%0A
 %7D%0A

add one more test.