Giter Club home page Giter Club logo

ersatz's People

Contributors

cjstehno avatar musketyr avatar sdelamo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

ersatz's Issues

Add Digest server feature

Add a ServerFeature to support DIGEST authentication. Undertow seems to support it already so this should be similar to the BASIC auth feature as far as implementation goes.

Truncate the logged body content

When posting multipart file content, the logged body is way too big... truncate the to-string on that down to like 1k or something manageable.

Test with Groovy 2.5

Groovy 2.5 is coming out soon - it would be nice to know how things work before it's released.

Not sure we would want to upgrade right away but it would be good to have a test (shell) and some docs around using it - if there is any difference - I would think it would just work without any notes.

Will the new Java 8 lambda integration make the extra Groovy vs Java methods obsolete?

Come up with a support timeline for 2.5 - hopefully it will just work with both until I start using new features.

binary compatibility with Undertow 1.3.x

If not really necessary it would be nice if Ersatz server is compatible with Undertow 1.3.x (namely 1.3.15.Final) which is used by various spring boot related libraries (https://mvnrepository.com/artifact/io.undertow/undertow-core/1.3.25.Final/usages). This disqualifies from using Ersatz with Spring Boot or Grails 3. The construct offending the compatibility is currently server.listenerInfo:

            actualHttpPort = (server.listenerInfo[0].address as InetSocketAddress).port

            if (httpsEnabled) {
                actualHttpsPort = (server.listenerInfo[1].address as InetSocketAddress).port
            }

Explore using in Kotlin

Explore how Ersatz may be used from Kotlin.

  • Are there any issues with using it? If so, what can be done to resolve them?
  • Document how it may be used in the User Guide

Cookie Tesing Features

@cjstehno

  1. Ability to specify more than key/value for cookies. Especially path and expiration would be very handy.
  2. Ability to assert that cookies are not present in a request. This may be possible already with Hamcrest matchers. If so, I would like to add them to the http-builder-ng tests.

Better logging of unmatched requests

It would be invaluable if the actual and expected requests were logged in more detail and if possible, identify where they didn't match. I think mock-server does this and prints out which part of the request did not match (whether it was the method, body, headers etc).

Also consider making the output Spock and/or JUnit friendly so that IDEs (esp IntelliJ) can show a diff.

Java 9 Support

Java 9 is out and it's not pretty. I upgraded, tried to build the project only to fail with odd errors... I then did a similar pattern on my other projects and got the same result. I then downgraded back to Java 8.

At this point, I don't have a Java 9 upgrade plan. My original understanding was that the modularization was an optional piece of functionality - it appears that it is not and that it also seems to break pretty much everything.

If you are comfortable with Java 9 and want to take a whack and getting Ersatz to compile and work, feel free to submit a Pull Request. If not for that, it might be a while unless I get a lot of outside pressure.

Allow global config of request decoders

Currently the encoders/decoders are configured on a per-request/response basis. While a shared collection of them may be injected, it would be better to allow for global configuration of the desired defaults at the server or expectations configuration level.

Also ensure that there is a set of reusable common encoders/decoders for standard scenarios.

Multiple value headers not matching

It seems that request with multiple value headers are not matched. Below is the expectation.

server.expectations {
    get('/api/hello') {
        called 1
        header 'Accept', 'application/json'
        header 'Accept', 'application/vnd.company+json'
        responder {
            code 200
                content  'msg': 'World', 'application/vnd.company+json'
            }
        }
}

However, this does not seem to match. Looking at the code it appears that only the first value is compared:

static RequestMatcher header(final String name, final Matcher<String> m) {
    new RequestMatcher(m, { ClientRequest cr -> cr.headers.getFirst(name) })
}
public String getFirst(String headerName) {
    HeaderValues headerValues = getEntry(headerName);
    if (headerValues == null) return null;
    return headerValues.getFirst();
}

Can this be fixed, or would you prefer I send a PR ?

Thanks

Cleanup unit testing

  • Cleanup and simplify testing
  • increase coverage a bit without being silly about it

Request recording

Consider/investigate request/response recording such that you can use Ersatz as a proxy in front of a live server, run a test or other requests against it and record the request/response captured as expectations.

  • http://betamax.software/ - a Java library that does this sort of recording. I wonder if it could be used to do the heavy lifting or if it does things well enough that I don't need to integrate the functionality here.

Auto-start with expectations

The pattern of:

ersatzServer.expectations {
    // expectation code..
}.start()

is common enough that it might be useful to provide a means of auto-starting after calling one of the expectation configuration methods (maybe a global config):

def ersatzServer = new ErsatzServer({
    autoStart true
})

Should still be false by default, and it should not cause errors if its enabled and start() is called - it should just be ignored in this case.

This will allow for cleaner code.

Finish unit testing

At this point there is just a quick cross-section of unit testing... finish this and then finish the integration testing in the HttpBuilder-NG project.

Allow Closures as Matchers

It would be nice if a Closure<Boolean> could be used as an alternative to a Hamcrest matcher where they are allowed... I guess a Supplier<Boolean> could also be allowed.

Either adjust the interfaces to allow this or make a ClosureMatcher and a ConsumerMatcher implementation of the Matcher interface.

More documentation

  • Add more to the user guide
  • Better groovy doc text
  • More examples
  • Clean up web site a bit

Consider adding a shadow jar distribution

It would be interesting and helpful to provide a distribution version of the library as a shadow jar as an alternate dependency to the standard. This would keep the dependencies of this project from affecting the using project.

More complex header support

Currently, the request and response headers are simply Strings... HTTP headers can be more complicated. Consider adding support for more types of headers - is this even needed or will Strings work well enough?

Add JUnit Java example to Getting Started

The Java example is weak in the Getting Started section. Expand it to a full Java JUnit test example as the Groovy Spock example.

Also add simple Java example to the site landing page.

Request `body` matcher methods need to allow hamcrest matcher for content-type

The Request.body content matcher methods allow for Hamcrest matchers as values, but not for content types. It would be useful (especially in multipart matching) to allow for Hamcrest matchers in the content type fields. So that you could have something like:

expectations {
    post('/foo').body( any(), startsWith('text/') ).responds().code(201)
}

Support for http 2

Undertow should already support this but I need to figure out how to enable and expose as an option.

Gather requirements for 1.0

I think this project is nearing the point for a true 1.0 release - use this issue to gather a list of features required for 1.0.

support for clearing expectations

Currently expecations are additive. Add support for clearing them and investigate possibility of having a test share a server for all test methods without rebuilding it, but only clearing the expectations.

Move authentication support into core

The BASIC and DIGEST authentication support should be converted to config properties rather than "features"

  • the feature mechanism should be deprecated and removed by 1.0 with a migration strategy for existing code (probably just HttpBuilder-NG)
  • it would be nice to be able to define BASIC, DIGEST and non-authenticated expectations on the same server but this would not be a requirement

Add something like:

def server = new ErsatzServer({
    basicAuthentication true
    digestAuthentication true
})

Ability to delay or time-out response

It might be useful to have the ability to timeout or delay the response for testing how the client handles this.

expectations {
    get('/foo').responds {
        delay '1 min'
        code 200
    }
    get('/bar').responds {
        delay 3600 // ms
        code 200
    }
}

Use the time duration parsing from Vanilla for rich string times or just allow ms (maybe TimeCategory too).
This would slow down tests that use it, but I could see this being something a client would want to test.

Rework user guide

Rework the user guide to have better organization and more details and examples about each feature.

  • Make sure the GroovyDocs have documentation links from override methods
  • Add package info to GroovyDocs
  • Try to find a way to get Markdown or AsciiDoc to work in GroovyDocs (maybe there is a way now)
  • Re-align the sections of the User Guide (see comment below)
  • More inline examples in GroovyDocs
  • Add more content type examples for request/response transforming
  • Examples of using Closures as Hamcrest matchers
  • Information about using with Kotlin
  • Any relevant information about using with Groovy 2.5
  • add contributors section to user guide

Documentation

Documentation needs to be written:

  • site
  • user guide
  • source code docs

Add `any` method matcher

It would be useful to add an any request matcher such that it would match any request method - with the ability to refine the match with the rest of the configuration (query, headers, etc).

server.expectations {
    any('/foo').responds().body('ok', TEXT_PLAIN)
}

so that GET /foo and POST /foo would both be matched by this expectation.

Create standalone embedded proxy server

The proxy support added to HttpBuilder-NG has exposed the need for a more realistic yet still simple embedded proxy server. Undertow can be used as a proxy server so it would be nice to provide a simple interface for setting up a small embedded testing proxy server outside of the Ersatz server itself.

Https support

Add support for configuring HTTPS endpoints either via extension or other means.

  • should be able to work out of the box or with provided keys/certs
  • would be nice to be able to configure both HTTP and HTTPS on the same server - this may require refactoring of the extension mechanism (not a bad thing)

Raw request handling

It might be useful to add a means of writing a matcher directly against a request, something like:

server.expectations {
    match( matcher ).responds().body('ok', TEXT_PLAIN)
}

where matcher would be a hamcrest matcher given the ClientRequest object to match against. This would allow another level of flexibility in match configuration.

Note: that the match method would be generic to handle whatever the matcher matches, including the request method.

EncoderChain fails to resolve an encoder if object is a Map

If we try to encode a Map instance using the response encoder, the encoder chain logic fails to resolve it.

static final def JSON_ENCODER = { Object object ->
    toJson(object)
} as Function

def server = new ErsatzServer({
    encoder 'application/json', LinkedHashMap, JSON_ENCODER
})

I believe this is because in the ErsatzResponse class the getContent method tries to evaluate content.class but if content is a Map, Groovy thinks class is a key of the Map rather than a property accessor for getClass method.

@Override
String getContent() {
    if (content != null) {
        return encoderChain.resolve(contentType, content.class)?.apply(content) ?: (content as String)
    }
    return ''
}

The proposed solution is to use the method accessor rather than property shorthand in this instance.

return encoderChain.resolve(contentType, content.getClass())?.apply(content) ?: (content as String)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.