package fi.vincit.multiusertest.rule.expection.call;

import static fi.vincit.multiusertest.util.UserIdentifiers.ifAnyOf;

import java.io.IOException;

import org.junit.Test;
import org.springframework.security.access.AccessDeniedException;

import fi.vincit.multiusertest.rule.expection.Expectations;
import fi.vincit.multiusertest.rule.expection.FunctionCall;
import fi.vincit.multiusertest.util.UserIdentifier;

public class ExpectCallTest {

    void throwAccessDenied() throws AccessDeniedException {
        throw new AccessDeniedException("Denied");
    }

    void notThrow() throws AccessDeniedException {
    }

    void throwIOException() throws IOException {
        throw new IOException("IO Exception");
    }

    @Test
    public void testExpectCallToFail() throws Throwable {
        Expectations.call(new FunctionCall() {
            @Override
            public void call() throws Throwable {
                throwAccessDenied();
            }
        })
                .toFail(ifAnyOf("role:ROLE_USER"))
                .execute(UserIdentifier.parse("role:ROLE_USER"));
    }

    @Test(expected = AssertionError.class)
    public void testExpectCallToFail_OtherRole() throws Throwable {
        Expectations.call(new FunctionCall() {
            @Override
            public void call() throws Throwable {
                throwAccessDenied();
            }
        })
                .toFail(ifAnyOf("role:ROLE_USER"))
                .execute(UserIdentifier.parse("role:ROLE_ADMIN"));
    }

    @Test
    public void testNoThrow() throws Throwable {
        Expectations.call(new FunctionCall() {
            @Override
            public void call() throws Throwable {
                notThrow();
            }
        }).execute(UserIdentifier.parse("role:ROLE_ADMIN"));
    }

    @Test(expected = AssertionError.class)
    public void testNoThrow_ExpectToFail() throws Throwable {
        Expectations.call(new FunctionCall() {
            @Override
            public void call() throws Throwable {
                notThrow();
            }
        })
                .toFail(ifAnyOf("role:ROLE_USER"))
                .execute(UserIdentifier.parse("role:ROLE_USER"));
    }

    @Test(expected = AssertionError.class)
    public void testThrowsUnexpectedException() throws Throwable {
        Expectations.call(new FunctionCall() {
            @Override
            public void call() throws Throwable {
                throwIOException();
            }
        })
                .toFail(ifAnyOf("role:ROLE_USER"))
                .execute(UserIdentifier.parse("role:ROLE_USER"));
    }

    @Test
    public void testNotExpectToFail() throws Throwable {
        Expectations.call(new FunctionCall() {
            @Override
            public void call() throws Throwable {
                notThrow();
            }
        })
                .notToFail(ifAnyOf("role:ROLE_USER"))
                .execute(UserIdentifier.parse("role:ROLE_USER"));
    }

    @Test(expected = AssertionError.class)
    public void testNotExpectToFail_ButFails() throws Throwable {
        Expectations.call(new FunctionCall() {
            @Override
            public void call() throws Throwable {
                throwAccessDenied();
            }
        })
                .notToFail(ifAnyOf("role:ROLE_USER"))
                .execute(UserIdentifier.parse("role:ROLE_USER"));
    }

    @Test(expected = AssertionError.class)
    public void testNotExpectToFail_ButFailsWithUnexpected() throws Throwable {
        Expectations.call(new FunctionCall() {
            @Override
            public void call() throws Throwable {
                throwIOException();
            }
        })
                .notToFail(ifAnyOf("role:ROLE_USER"))
                .execute(UserIdentifier.parse("role:ROLE_USER"));
    }
}
@@ -710,32 +710,137 @@
 ption%22);%0A    %7D%0A%0A
+    void throwIllegalStateException() %7B%0A        throw new IllegalStateException(%22Illegal state%22);%0A    %7D%0A%0A
     @Test%0A    pu
@@ -3927,10 +3927,1878 @@
 );%0A    %7D
+%0A%0A    @Test(expected = AssertionError.class)%0A    public void testExpectToFail_WithCustomException_ButDoesntFail() throws Throwable %7B%0A        Expectations.call(new FunctionCall() %7B%0A            @Override%0A            public void call() throws Throwable %7B%0A                notThrow();%0A            %7D%0A        %7D)%0A                .toFailWithException(IllegalStateException.class, ifAnyOf(%22role:ROLE_USER%22))%0A                .execute(UserIdentifier.parse(%22role:ROLE_USER%22));%0A    %7D%0A%0A    @Test%0A    public void testExpectToFail_WithCustomException() throws Throwable %7B%0A        Expectations.call(new FunctionCall() %7B%0A            @Override%0A            public void call() throws Throwable %7B%0A                throwIllegalStateException();%0A            %7D%0A        %7D)%0A                .toFailWithException(IllegalStateException.class, ifAnyOf(%22role:ROLE_USER%22))%0A                .execute(UserIdentifier.parse(%22role:ROLE_USER%22));%0A    %7D%0A%0A    @Test(expected = AssertionError.class)%0A    public void testExpectToFail_WithCustomException_ButFails() throws Throwable %7B%0A        Expectations.call(new FunctionCall() %7B%0A            @Override%0A            public void call() throws Throwable %7B%0A                throwAccessDenied();%0A            %7D%0A        %7D)%0A                .toFailWithException(IllegalStateException.class, ifAnyOf(%22role:ROLE_USER%22))%0A                .execute(UserIdentifier.parse(%22role:ROLE_USER%22));%0A    %7D%0A%0A    @Test(expected = AssertionError.class)%0A    public void testExpectToFail_WithCustomException_ButFailsWithUnexpected() throws Throwable %7B%0A        Expectations.call(new FunctionCall() %7B%0A            @Override%0A            public void call() throws Throwable %7B%0A                throwIOException();%0A            %7D%0A        %7D)%0A                .toFailWithException(IllegalStateException.class, ifAnyOf(%22role:ROLE_USER%22))%0A                .execute(UserIdentifier.parse(%22role:ROLE_USER%22));%0A    %7D
 %0A%7D

Add tests for ExcpectCall.toFailWithException