Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
276cd84
Adds customer.subscription.updated event to list of subscribed to Str…
Nov 4, 2019
70c504a
Adds handling of Stripe events related to subscription renewal
Nov 4, 2019
da10988
Adds client API for reattemptng the renewal of a subscription that
Nov 4, 2019
dceb366
Adds acceptance tests for recurring payment
Nov 4, 2019
e4bc0da
Merge branch 'develop' into feature/payment-recurring
Nov 4, 2019
ebf5bd5
Merge branch 'develop' into feature/payment-recurring
Nov 4, 2019
7034e7e
Merge branch 'develop' into feature/payment-recurring
Nov 4, 2019
5e6a6ed
Merge branch 'develop' into feature/payment-recurring
Nov 4, 2019
e4c3038
Renames data class 'SubscriptionStateInfo' to 'SubscriptionPaymentInfo'
Nov 4, 2019
3443ba5
Moves 'subscription' tag from product 'product-class' to product 'pay…
Nov 5, 2019
c0b1601
Minor fixes and clarifications
Nov 5, 2019
2c5231c
Merge branch 'develop' into feature/payment-recurring
Nov 5, 2019
6aef3b0
Merge branch 'develop' into feature/payment-recurring
Nov 6, 2019
90d5ae7
Renames functions related to payment subscriptions in order to
Nov 6, 2019
af8c633
Switch from ngrok.io to serveo.net for supporting webhook in acceptan…
Nov 6, 2019
3570590
Merge branch 'develop' into feature/payment-recurring
Nov 6, 2019
2e6ba10
Merge remote-tracking branch 'origin/feature/payment-recurring' into …
Nov 6, 2019
7ee9cbc
Merge branch 'develop' into feature/payment-recurring
Nov 6, 2019
5d2f1d4
Merge branch 'develop' into feature/payment-recurring
Nov 7, 2019
cec7894
Make check of STRIPE_ENDPOINT_SECRET variable more explisit in condit…
Nov 7, 2019
9ac190c
Switch from serveo.net to stripe-cli Docker image for supporting webh…
Nov 7, 2019
bee078d
Merge branch 'develop' into feature/payment-recurring
Nov 7, 2019
23d539e
Adds documentation for test setup ot the recurring payment acceptance…
Nov 7, 2019
1cd7024
Disable the recurring payment acceptance tests
Nov 7, 2019
34877e2
Merge branch 'develop' into feature/payment-recurring
Nov 8, 2019
6373e07
Adds fixes for using Stripe CLI as proxy for Stripe events
Nov 8, 2019
99e98c3
Adds missing Stripe proxy Dockerfile files
Nov 8, 2019
84f2c6a
Adds fixes to test setup using Stripe proxy
Nov 8, 2019
f0be5a0
Merge branch 'develop' into feature/payment-recurring
Nov 11, 2019
fd92961
Merge branch 'develop' into feature/payment-recurring
Nov 12, 2019
46b0e8e
Merge branch 'develop' into feature/payment-recurring
Nov 13, 2019
cadd83c
Merge branch 'develop' into feature/payment-recurring
Nov 13, 2019
b9a74c4
Merge branch 'develop' into feature/payment-recurring
Nov 14, 2019
cfb0ad9
Merge branch 'develop' into feature/payment-recurring
Nov 15, 2019
9475579
Merge branch 'develop' into feature/payment-recurring
Nov 18, 2019
07ab623
Merge branch 'develop' into feature/payment-recurring
Nov 20, 2019
bcff504
Merge branch 'develop' into feature/payment-recurring
Nov 20, 2019
c6a2c48
Merge branch 'develop' into feature/payment-recurring
Nov 21, 2019
902a477
Merge branch 'develop' into feature/payment-recurring
Nov 22, 2019
6ca644d
Fixes overlooked incorrect class name from last manual merge with dev…
Nov 22, 2019
85aa0c6
Merge branch 'develop' into feature/payment-recurring
Nov 26, 2019
c28c812
Merge branch 'develop' into feature/payment-recurring
Nov 27, 2019
aa5009c
Merge branch 'develop' into feature/payment-recurring
Nov 28, 2019
35de8b1
Merge branch 'develop' into feature/payment-recurring
Nov 28, 2019
41e499f
Merge branch 'develop' into feature/payment-recurring
Nov 28, 2019
514c3cc
Merge branch 'develop' into feature/payment-recurring
Nov 28, 2019
bb0989d
Merge branch 'develop' into feature/payment-recurring
Nov 29, 2019
2a6d2d3
Merge branch 'develop' into feature/payment-recurring
Dec 2, 2019
44b99bf
Fixes after last merge with develop
Dec 2, 2019
79b24d9
Adds 'us' as the third region to acceptance tests as it is used
Dec 2, 2019
266943d
Merge branch 'develop' into feature/payment-recurring
Dec 3, 2019
6defbb0
Merge branch 'develop' into feature/payment-recurring
Dec 3, 2019
32d21bd
Merge branch 'develop' into feature/payment-recurring
Dec 4, 2019
e30cee3
Merge branch 'develop' into feature/payment-recurring
Dec 5, 2019
2e1dd56
Merge branch 'develop' into feature/payment-recurring
Dec 6, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions acceptance-tests/Dockerfile.stripe
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM stripe/stripe-cli

LABEL maintainer="[email protected]"

COPY script/stripe-proxy.sh /proxy.sh

ENTRYPOINT []

CMD ["/proxy.sh"]
81 changes: 63 additions & 18 deletions acceptance-tests/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#Acceptance tests
# Acceptance tests

PRELIMINARY, EXTREMELY INCOMPLETE DOCUMENTATION, MUST BE IMPROVED!
_PRELIMINARY, EXTREMELY INCOMPLETE DOCUMENTATION, MUST BE IMPROVED!_

The ostelco system is complex in that it consists of multiple components that
communicate both with internal components and external components.
Expand All @@ -13,46 +13,91 @@ a context where all the external components are also present either as
externally hosted test instances, or as mocked out-components running
locally.

The acceptance tests themselves are run using "docker compose", and
are implemented as a separate docker container that is run in the
docker compose environment.
The acceptance tests themselves are run using `docker compose`, and are
implemented as a separate docker container that is run in the docker
compose environment.

## Docker compose files

## The various docker compose files
### The various docker compose files

There are in fact multiple docker compose files present in the
top level directory, and they have different usecases:

* `docker-compose.yaml`: The main file. Will run a set of tests exercising
most of the components.

* docker-compose.yaml: The most commonly used file. Will
run a set of tests for most of the components.

* docker-compose.esp.yaml: A test that is simplar to docker-compose.yaml,
* `docker-compose.esp.yaml`: A test that is similar to `docker-compose.yaml`,
but also includes the google ESP components. We usually don't run this test
since the complications of running ESP for the most part don't outweigh
its utility.

* docker-compose.ocs.yaml: tbd
* docker-compose.seagull.yaml: tbd
* `docker-compose.ocs.yaml`: tbd

## Structure of the docker compose files
* `docker-compose.seagull.yaml`: tbd

## Components started by docker compose
### Structure of the docker compose files

... tbd (also a PUML diagram showing call relationships)
### Components started by docker compose

... tbd (also a PUML diagram showing call relationships)

## Prerequisites for running the acceptance tests

... tbd

... tbd

## How to run the acceptance tests

... tbd, but should include: Just running them, running them while developing new tests, how to attach a test being developed to an IDE's debugger.
For the main Docker compose file:

$ docker-compose up --build --abort-on-container-exit

To run one of the other Docker compose files, use the `-f` option. Example:

$ docker-compose -f docker-compose.esp.yaml up --build --abort-on-container-exit

... tbd, how to run them while developing new tests, how to attach a test
being developed to an IDE's debugger.

## Running tests that depends on webhooks configured at Stripe

Currently the "recurring payment" tests depends on webhooks being enabled at Stripe
and the events being proxy forwarded the Prime backend. For enabling proxy forward
of the events the
[stripe/stripe-cli](https://hub.docker.com/r/stripe/stripe-cli) Docker image is used.

For the tests to work the following two evnironment variables must be set to their
correct value.

- `STRIPE_API_KEY`
- `STRIPE_ENDPOINT_SECRET`

For the `STRIPE_API_KEY` variable go to the Stripe console and list the value at
Developer -> API keys -> Secret key.

To get the correct `STRIPE_ENDPOINT_SECRET` value do as follows:

$ export STRIPE_API_KEY=<secret value obtained earlier>
$ docker run --rm -e STRIPE_API_KEY=$STRIPE_API_KEY stripe/stripe-cli listen
Checking for new versions...

Getting ready...
Ready! Your webhook signing secret is whsec_secretvaluesecretvalue0123456789 (^C to quit)

Alternatively download the `stripe` command line program from
[https://stripe.com/docs/stripe-cli](https://stripe.com/docs/stripe-cli) and run
the command:

$ stripe listen

(with the `STRIPE_API_KEY` environment variable set).

Set the `STRIPE_ENDPOINT_SECRET` environment variable to the string starting with
"`whsec_`".

$ export STRIPE_ENDPOINT_SECRET=whsec_secretvaluesecretvalue0123456789

This will cause the tests that depends upon Stripe events to run.

To disiable the tests, set the `STRIPE_ENDPOINT_SECRET` to some dummy value that
don't start with the "`whsec_`" string.
3 changes: 3 additions & 0 deletions acceptance-tests/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ dependencies {
implementation(kotlin("test-junit"))

implementation("io.dropwizard:dropwizard-testing:${Version.dropwizard}")

implementation("org.junit.jupiter:junit-jupiter-api:${Version.junit5}")
runtimeOnly("org.junit.jupiter:junit-jupiter-engine:${Version.junit5}")
}

application {
Expand Down
20 changes: 20 additions & 0 deletions acceptance-tests/script/stripe-proxy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#! /bin/sh

# Only start the Stripe CLI tool in proxy forward mode
# if the STRIPE_ENDPOINT_SECRET environmentvariable is
# set to what looks like an actual secret.
#
# If not set, block until stopped by SIGTERM or similar.

echo $STRIPE_ENDPOINT_SECRET | grep -q ^whsec_

if [ $? -eq 0 ]
then
echo Starting Stripe CLI in proxy forward mode...
stripe listen \
--forward-to prime:8080/stripe/event \
--events customer.subscription.updated,invoice.created,invoice.payment_succeeded,invoice.upcoming
else
echo Not starting Stripe CLI.
sleep 2147483647 # block for 2^31-1 seconds
fi
13 changes: 12 additions & 1 deletion acceptance-tests/script/wait.sh
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,18 @@ EOF
echo " ... HLR preactivated rofiles loaded into prime"


##
## Creating pub-sub subscriptions for recurring payments tests (plans).
## Have to create one subscription per test, as the tests runs in parallel.
##

echo "Creating pub-sub subscriptions for recurring payment tests"
curl -X PUT -H "Content-Type: application/json" -d '{"topic":"projects/'${GCP_PROJECT_ID}'/topics/stripe-event","ackDeadlineSeconds":10}' pubsub-emulator:8085/v1/projects/${GCP_PROJECT_ID}/subscriptions/stripe-event-okhttp-purchase-ok-sub
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is so much repeated code that it now arguably would make sense to factor this out into a function. Or not. Your call.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will try to move the curl call into a function.

curl -X PUT -H "Content-Type: application/json" -d '{"topic":"projects/'${GCP_PROJECT_ID}'/topics/stripe-event","ackDeadlineSeconds":10}' pubsub-emulator:8085/v1/projects/${GCP_PROJECT_ID}/subscriptions/stripe-event-okhttp-purchase-fail-sub
curl -X PUT -H "Content-Type: application/json" -d '{"topic":"projects/'${GCP_PROJECT_ID}'/topics/stripe-event","ackDeadlineSeconds":10}' pubsub-emulator:8085/v1/projects/${GCP_PROJECT_ID}/subscriptions/stripe-event-jersey-purchase-ok-sub
curl -X PUT -H "Content-Type: application/json" -d '{"topic":"projects/'${GCP_PROJECT_ID}'/topics/stripe-event","ackDeadlineSeconds":10}' pubsub-emulator:8085/v1/projects/${GCP_PROJECT_ID}/subscriptions/stripe-event-jersey-purchase-fail-sub

##
## Finally run acceptance tests
##
java -cp '/acceptance-tests.jar' org.junit.runner.JUnitCore org.ostelco.at.TestSuite
java -cp '/acceptance-tests.jar' org.junit.runner.JUnitCore org.ostelco.at.TestSuite
41 changes: 40 additions & 1 deletion acceptance-tests/src/main/kotlin/org/ostelco/at/TestSuite.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import org.junit.Test
import org.junit.experimental.ParallelComputer
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable
import org.junit.runner.JUnitCore
import org.ostelco.at.common.StripePayment
import org.ostelco.at.common.getLogger
import kotlin.test.assertTrue

Expand Down Expand Up @@ -49,6 +51,43 @@ class TestSuite {
}
}

/**
* Test of recurring payments requires that:
* 1) The webhook-stripe service docker instance is running.
* 2) The STRIPE_ENDPOINT_SECRET env. variable set.
* If the STRIPE_ENDPOINT_SECRET variable is not set the tests will be skipped.
*/
@Test
@EnabledIfEnvironmentVariable(named = "STRIPE_ENDPOINT_SECRET", matches="whsec_\\S+")
fun `run recurring payment tests`() {

/**
* TODO: For some reason the '@EnabledIfEnvironmentVariable' annotation
* is not working...
* Remove the check below when this is fixed.
*/
val secret = System.getenv("STRIPE_ENDPOINT_SECRET") ?: "not_set"

if (!secret.matches(Regex("whsec_\\S+"))) {
logger.info("Skipping the 'recurring payment tests' as the STRIPE_ENDPOINT_SECRET environment variable " +
"is not set or set to a value not matching a secret.")
return
}

runBlocking {

launch {
checkResult(
JUnitCore.runClasses(
ParallelComputer(true, true),
org.ostelco.at.okhttp.RenewPlanTest::class.java,
org.ostelco.at.jersey.RenewPlanTest::class.java
)
)
}
}
}

private fun checkResult(result: org.junit.runner.Result) {

println()
Expand All @@ -60,4 +99,4 @@ class TestSuite {

assertTrue(result.wasSuccessful(), "${result.failureCount} tests failed!")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ fun expectedProducts(): List<Product> {
)
}

val expectedPlanProduct: Product = Product()
val expectedPlanProductSG: Product = Product()
.sku("PLAN_1000SGD_YEAR")
.price(Price().amount(1_000_00).currency("SGD"))
.properties(
Expand All @@ -32,6 +32,24 @@ val expectedPlanProduct: Product = Product()
)
.presentation(emptyMap<String, String>())

val expectedPlanProductUS: Product = Product()
.sku("PLAN_10USD_DAY")
.price(Price().amount(10_00).currency("USD"))
.properties(
mapOf(
"productClass" to "MEMBERSHIP",
"segmentIds" to "country-us"
)
)
.payment(
mapOf(
"type" to "SUBSCRIPTION",
"label" to "Daily subscription plan",
"taxRegionId" to "us"
)
)
.presentation(emptyMap<String, String>())

private val dfs = DecimalFormatSymbols().apply {
groupingSeparator = '_'
}
Expand Down
Loading