Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 6 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ jobs:
node-version: 18

- name: Install lstk
run: npm install -g @localstack/lstk
run: |
npm install -g @localstack/lstk
lstk setup aws --force --non-interactive

- name: Start LocalStack
env:
Expand Down Expand Up @@ -63,6 +65,9 @@ jobs:
command: |
yarn cdklocal deploy

- name: Run tests
run: make test

- name: Send a Slack notification
if: failure() || github.event_name != 'pull_request'
uses: ravsamhq/notify-slack-action@v2
Expand Down
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ bootstrap-frontend:
deploy-frontend:
yarn cdklocal deploy --app="node dist/aws-sdk-js-notes-app-frontend.js";

## Create, read, update and delete a note through the API
test:
./test.sh

## Stop the Running LocalStack container
stop:
@echo
Expand All @@ -63,4 +67,4 @@ setup-challenge:
make prepare-frontend-local
make hotreload

.PHONY: usage install run start stop logs
.PHONY: usage install run start stop logs test
65 changes: 65 additions & 0 deletions test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#!/bin/bash
# Walk a note through the REST API: create, read, list, update, delete.
# Each route is its own Lambda function backed by the same DynamoDB table.
set -euo pipefail

STACK=aws-sdk-js-notes-app
CONTENT="note from CI $(date +%s)"

API_URL=$(lstk aws cloudformation describe-stacks --stack-name "$STACK" \
--query "Stacks[0].Outputs[?starts_with(OutputKey, 'endpointEndpoint')].OutputValue | [0]" --output text)
NOTES="${API_URL%/}/notes"
echo "API: $NOTES"

# Print the body, or fail with the status and body on a non-2xx response
request() {
local body status
body=$(curl -s -m 30 -w '\n%{http_code}' "$@")
status=${body##*$'\n'}
body=${body%$'\n'*}
if [ "${status:0:1}" != "2" ]; then
echo "Test failed: $* returned HTTP $status: $body" >&2
return 1
fi
echo "$body"
}

created=$(request -X POST "$NOTES" -H 'Content-Type: application/json' -d "{\"content\":\"$CONTENT\"}")
ID=$(echo "$created" | jq -r '.noteId.S')
if [ -z "$ID" ] || [ "$ID" = "null" ]; then
echo "Test failed: create returned $created"
exit 1
fi
echo "PASS: created note $ID"

note=$(request "$NOTES/$ID")
if ! echo "$note" | jq -e --arg c "$CONTENT" '.content == $c' > /dev/null; then
echo "Test failed: get returned $note"
exit 1
fi
echo "PASS: read note back"

if ! request "$NOTES" | jq -e --arg id "$ID" 'any(.[]; .noteId == $id)' > /dev/null; then
echo "Test failed: note $ID missing from the list"
exit 1
fi
echo "PASS: note appears in the list"

request -X PUT "$NOTES/$ID" -H 'Content-Type: application/json' -d '{"content":"updated by CI"}' > /dev/null
note=$(request "$NOTES/$ID")
if ! echo "$note" | jq -e '.content == "updated by CI"' > /dev/null; then
echo "Test failed: update not applied, got $note"
exit 1
fi
echo "PASS: updated note"

request -X DELETE "$NOTES/$ID" > /dev/null
# getNote answers 500 "Item not found." once the note is gone
status=$(curl -s -m 30 -o /dev/null -w '%{http_code}' "$NOTES/$ID")
if [ "$status" != "500" ]; then
echo "Test failed: note still readable after delete (HTTP $status)"
exit 1
fi
echo "PASS: deleted note"

echo "Test passed: notes API handled the full CRUD cycle"
Loading