<commit_before>package com.intuit.karate.core;

import static com.intuit.karate.TestUtils.*;
import static com.intuit.karate.TestUtils.runScenario;
import com.intuit.karate.http.HttpServer;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author pthomas3
 */
class KarateHttpMockHandlerTest {

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

    MockHandler handler;
    HttpServer server;
    FeatureBuilder mock;
    ScenarioRuntime runtime;

    String urlStep() {
        return "url 'http://localhost:" + server.getPort() + "'";
    }

    void startMockServer() {
        handler = new MockHandler(mock.build());
        server = HttpServer.handler(handler).build();
    }

    FeatureBuilder background(String... lines) {
        mock = FeatureBuilder.background(lines);
        return mock;
    }

    Object get(String name) {
        return runtime.engine.vars.get(name).getValue();
    }

    ScenarioRuntime run(String... lines) {
        runtime = runScenario(null, lines);
        return runtime;
    }

    private void matchVar(String name, Object expected) {
        match(get(name), expected);
    }

    private void matchVarContains(String name, Object expected) {
        matchContains(get(name), expected);
    }

    @AfterEach
    void afterEach() {
        server.stop();
    }

    @Test
    void testSimpleGet() {
        background().scenario(
                "pathMatches('/hello')",
                "def response = 'hello world'");
        startMockServer();
        run(
                urlStep(),
                "path 'hello'",
                "method get"
        );
        matchVar("response", "hello world");
    }
    
    @Test
    void testUrlWithTrailingSlashAndPath() {
        background().scenario(
                "pathMatches('/hello/world')",
                "def response = requestUri");
        startMockServer();
        run(
                "url 'http://localhost:" + server.getPort() + "/hello'",
                "path '/world/'",
                "method get",
                "match response == 'hello/world'"
        );
        matchVar("response", "hello/world");
    }     

    @Test
    void testRequestBodyAsInteger() {
        background().scenario(
                "pathMatches('/hello')",
                "def response = requestHeaders");
        startMockServer();
        run(
                urlStep(),
                "path '/hello'",
                "request 42",
                "method post"
        );
        // for some reason, apache assumes this encoding if the request body is raw bytes TODO
        matchVarContains("response", "{ 'content-type': ['application/octet-stream'] }");
    }

    @Test
    void testThatCookieIsPartOfRequest() {
        background().scenario(
                "pathMatches('/hello')",
                "def response = requestHeaders");
        startMockServer();
        run(
                urlStep(),
                "path 'hello'",
                "cookie foo = 'bar'",
                "method get"
        );
        matchVarContains("response", "{ cookie: ['foo=bar'] }");
    }

    @Test
    void testSameSiteSecureCookieRequest() {
        background().scenario(
                "pathMatches('/hello')",
                "def response = requestHeaders");
        startMockServer();
        run(
                urlStep(),
                "path 'hello'",
                "cookie foo = { value: 'bar', samesite: 'Strict', secure: true }",
                "method get"
        );
        matchVarContains("response", "{ cookie: ['foo=bar'] }");
    }

    @Test
    void testSameSiteSecureCookieResponse() {
        background().scenario(
                "pathMatches('/hello')",
                "def responseHeaders = { 'Set-Cookie': 'foo=bar; expires=Wed, 30-Dec-20 09:25:45 GMT; path=/; domain=.example.com; HttpOnly; SameSite=Lax; Secure' }");
        startMockServer();
        run(
                urlStep(),
                "path 'hello'",
                "method get"
        );
        matchVarContains("responseHeaders", "{ set-cookie: ['foo=bar; expires=Wed, 30-Dec-20 09:25:45 GMT; path=/; domain=.example.com; HttpOnly; SameSite=Lax; Secure'] }");<commit_msg>add test to investigate #1680<commit_after>package com.intuit.karate.core;

import static com.intuit.karate.TestUtils.*;
import static com.intuit.karate.TestUtils.runScenario;
import com.intuit.karate.http.HttpServer;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author pthomas3
 */
class KarateHttpMockHandlerTest {

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

    MockHandler handler;
    HttpServer server;
    FeatureBuilder mock;
    ScenarioRuntime runtime;

    String urlStep() {
        return "url 'http://localhost:" + server.getPort() + "'";
    }

    void startMockServer() {
        handler = new MockHandler(mock.build());
        server = HttpServer.handler(handler).build();
    }

    FeatureBuilder background(String... lines) {
        mock = FeatureBuilder.background(lines);
        return mock;
    }

    Object get(String name) {
        return runtime.engine.vars.get(name).getValue();
    }

    ScenarioRuntime run(String... lines) {
        runtime = runScenario(null, lines);
        return runtime;
    }

    private void matchVar(String name, Object expected) {
        match(get(name), expected);
    }

    private void matchVarContains(String name, Object expected) {
        matchContains(get(name), expected);
    }

    @AfterEach
    void afterEach() {
        server.stop();
    }

    @Test
    void testSimpleGet() {
        background().scenario(
                "pathMatches('/hello')",
                "def response = 'hello world'");
        startMockServer();
        run(
                urlStep(),
                "path 'hello'",
                "method get"
        );
        matchVar("response", "hello world");
    }

    @Test
    void testUrlWithTrailingSlashAndPath() {
        background().scenario(
                "pathMatches('/hello/world')",
                "def response = requestUri");
        startMockServer();
        run(
                "url 'http://localhost:" + server.getPort() + "/hello'",
                "path '/world/'",
                "method get",
                "match response == 'hello/world'"
        );
        matchVar("response", "hello/world");
    }

    @Test
    void testRequestBodyAsInteger() {
        background().scenario(
                "pathMatches('/hello')",
                "def response = requestHeaders");
        startMockServer();
        run(
                urlStep(),
                "path '/hello'",
                "request 42",
                "method post"
        );
        // for some reason, apache assumes this encoding if the request body is raw bytes TODO
        matchVarContains("response", "{ 'content-type': ['application/octet-stream'] }");
    }

    @Test
    void testThatCookieIsPartOfRequest() {
        background().scenario(
                "pathMatches('/hello')",
                "def response = requestHeaders");
        startMockServer();
        run(
                urlStep(),
                "path 'hello'",
                "cookie foo = 'bar'",
                "method get"
        );
        matchVarContains("response", "{ cookie: ['foo=bar'] }");
    }

    @Test
    void testSameSiteSecureCookieRequest() {
        background().scenario(
                "pathMatches('/hello')",
                "def response = requestHeaders");
        startMockServer();
        run(
                urlStep(),
                "path 'hello'",
                "cookie foo = { value: 'bar', samesite: 'Strict', secure: true }",
                "method get"
        );
        matchVarContains("response", "{ cookie: ['foo=bar'] }");
    }

    @Test
    void testSameSiteSecureCookieResponse() {
        background().scenario(
                "pathMatches('/hello')",
                "def responseHeaders = { 'Set-Cookie': 'foo=bar; expires=Wed, 30-Dec-20 09:25:45 GMT; path=/; domain=.example.com; HttpOnly; SameSite=Lax; Secure' }");
        startMockServer();
        run(
                urlStep(),
                "path 'hello'",
                "method get"
        );
        matchVarContains("responseHeaders", "{ set-cookie: ['foo=bar; expires=Wed, 30-Dec-20 09:25:45 GMT; path=/; domain=.example.com; HttpOnly; SameSite=Lax; Secure'] }");
    }

    @Test
    void testMultipleCookies() {
        background().scenario(
                "pathMatches('/hello')",
                "def response = requestHeaders");
        startMockServer();
        run(
                urlStep(),
                "path 'hello'",
                "cookie cookie1 = 'foo'",
                "cookie cookie2 = 'bar'",
                "method get"
        );
        matchVarContains("response", "{ cookie: ['cookie1=foo; cookie2=bar'] }");
{'fraction_non_alphanumeric': 0.1348012889366273, 'fraction_numerical': 0.006229860365198711, 'mean_word_length': 1.935372005044136, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1376544', 'n_tokens_mistral': 2647, 'n_tokens_neox': 2493, 'n_words': 541}