/*
 * Copyright (C) 2011 Thomas Akehurst
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.github.tomakehurst.wiremock;

import com.github.tomakehurst.wiremock.junit.WireMockClassRule;
import com.github.tomakehurst.wiremock.junit.WireMockRule;
import com.github.tomakehurst.wiremock.testsupport.WireMockTestClient;
import org.junit.ClassRule;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.runners.Enclosed;
import org.junit.runner.RunWith;

import static com.github.tomakehurst.wiremock.client.WireMock.*;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;

@RunWith(Enclosed.class)
public class WireMockJUnitRuleTest {

    public static class BasicWireMockRule {
    
    	@Rule
    	public WireMockRule wireMockRule = new WireMockRule(wireMockConfig().port(8089));
	
    	@Test
    	public void canRegisterStubAndFetchOnCorrectPort() {
    		givenThat(get(urlEqualTo("/rule/test")).willReturn(aResponse().withBody("Rule test body")));
    		
    		WireMockTestClient testClient = new WireMockTestClient(8089);
    		
    		assertThat(testClient.get("/rule/test").content(), is("Rule test body"));
    	}
    	
    }
    
    public static class WireMockRuleFailThenPass {
        
        @Ignore("Generates a failure to illustrate a Rule bug whereby a failed test would cause BindExceptions on subsequent (otherwise passing) tests")
        @Test
        public void fail() {
            assertTrue(false);
        }
    
        @Test
        public void succeed() {
            assertTrue(true);
        }
        
    }
    
    public static class WireMockRuleAsClassRule {
        
        @ClassRule
        @Rule
        public static WireMockClassRule wireMockRule = new WireMockClassRule(wireMockConfig().port(8089));
        
        @Test
        public void testStubAndFetchOnce() {
            assertNoReviousRequestsReceived();
            assertCanRegisterStubAndFetchOnCorrectPort();
        }
        
        @Test
        public void testStubAndFetchAgain() {
            assertNoReviousRequestsReceived(); // Will fail if reset() not called after the previous test case
            assertCanRegisterStubAndFetchOnCorrectPort();
        }

        private void assertNoReviousRequestsReceived() {
            verify(0, getRequestedFor(urlMatching(".*")));
        }
    
        public void assertCanRegisterStubAndFetchOnCorrectPort() {
            givenThat(get(urlEqualTo("/rule/test")).willReturn(aResponse().withBody("Rule test body")));
            
            WireMockTestClient testClient = new WireMockTestClient(8089);
            
            assertThat(testClient.get("/rule/test").content(), is("Rule test body"));
        }

    }
}

@@ -634,16 +634,127 @@
 emock;%0A%0A
+import com.github.tomakehurst.wiremock.junit.Stubbing;%0Aimport com.github.tomakehurst.wiremock.junit.Verifying;%0A
 import c
@@ -3502,20 +3502,1665 @@
 %0A        %7D%0A%0A
+    %7D%0A%0A    public static class RuleStubbing %7B%0A%0A        @ClassRule%0A        public static WireMockClassRule serviceOne = new WireMockClassRule(wireMockConfig().port(9091));%0A        @ClassRule%0A        public static WireMockClassRule serviceTwo = new WireMockClassRule(wireMockConfig().port(9092));%0A        @Rule%0A        public static WireMockRule serviceThree = new WireMockRule(wireMockConfig().port(9093));%0A        @Rule%0A        public static WireMockRule serviceFour = new WireMockRule(wireMockConfig().port(9094));%0A%0A        @Test%0A        public void canStubAndVerifyMultipleWireMockRulesWithoutInterferenceBetweenRuleInstances() %7B%0A            setupStubbing(serviceOne, %22service one%22);%0A            setupStubbing(serviceTwo, %22service two%22);%0A            setupStubbing(serviceThree, %22service three%22);%0A            setupStubbing(serviceFour, %22service four%22);%0A%0A            stubIsCalledAndResponseIsCorrect(serviceOne, 9091, %22service one%22);%0A            stubIsCalledAndResponseIsCorrect(serviceTwo, 9092, %22service two%22);%0A            stubIsCalledAndResponseIsCorrect(serviceThree, 9093, %22service three%22);%0A            stubIsCalledAndResponseIsCorrect(serviceFour, 9094, %22service four%22);%0A        %7D%0A%0A        private void setupStubbing(Stubbing stubbing, String body) %7B%0A            stubbing.stubFor(get(urlEqualTo(%22/test%22)).willReturn(aResponse().withBody(body)));%0A        %7D%0A%0A        private void stubIsCalledAndResponseIsCorrect(Verifying verifying, int port, String expectedText) %7B%0A            assertThat(new WireMockTestClient(port).get(%22/test%22).content(), is(expectedText));%0A            verifying.verify(getRequestedFor(urlEqualTo(%22/test%22)));%0A        %7D%0A%0A
     %7D%0A%7D%0A

test for rule based stubbing and verification across multiple rule instances