Skip to content

Commit

Permalink
lambda
Browse files Browse the repository at this point in the history
  • Loading branch information
Dieg0Code committed Aug 11, 2024
1 parent a715ace commit c2ac4f7
Show file tree
Hide file tree
Showing 18 changed files with 695 additions and 115 deletions.
83 changes: 83 additions & 0 deletions .github/workflows/cicd.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
name: CI/CD Pipeline

on:
push:
branches:
- main

jobs:
test-and-build:
name: Test and Build
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: '1.22.4'

- name: Cache dependencies
uses: actions/cache@v2
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
- name: Install dependencies
run: go mod download

- name: Run tests
run: go test -coverprofile=coverage.out ./...

- name: Upload coverage to codecov
uses: codecov/codecov-action@v2
with:
token: ${{ secrets.CODECOV_TOKEN }}

- name: Build binary
run: GOOS=linux GOARCH=amd64 go build -o api_scraper_lambda

- name: Zip binary
run: zip api_scraper_lambda.zip api_scraper_lambda

- name: Upload artifact
uses: actions/upload-artifact@v2
with:
name: api_scraper_lambda
path: api_scraper_lambda.zip

deploy:
name: Deploy
runs-on: ubuntu-latest
needs: test-and-build
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Download artifact
uses: actions/download-artifact@v2
with:
name: api_scraper_lambda
path: .

- name: Set up Terraform
uses: hashicorp/setup-terraform@v1

- name: Initialize Terraform
working-directory: ./terraform
run: terraform init

- name: Apply Terraform
working-directory: ./terraform
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
run: terraform apply -auto-approve -var="aws_region=${{ secrets.AWS_REGION }}" -var="aws_account_id=${{ secrets.AWS_ACCOUNT_ID }}"

- name: Get API Gateway URL
working-directory: ./terraform
run: echo "API Gateway URL => https://$(terraform output -json | jq -r '.api_gateway_invoke_url')"

9 changes: 8 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
compile_lambda:
set GOOS=linux&& set GOARCH=amd64&& set CGO_ENABLED=0&& go build -o main main.go
set GOOS=linux&& set GOARCH=amd64&& set CGO_ENABLED=0&& go build -o api_scraper_lambda main.go

zip_lambda:
zip api_scraper_lambda.zip api_scraper_lambda


start_db:
docker run -d --name dynamodb -p 8000:8000 amazon/dynamodb-local


create_table:
aws dynamodb create-table \
--table-name products \
Expand Down
135 changes: 135 additions & 0 deletions api/controller/product_controller_impl_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package controller

import (
"bytes"
"encoding/json"
"net/http"
"net/http/httptest"
"testing"

"github.com/dieg0code/serverles-api-scraper/api/data/request"
"github.com/dieg0code/serverles-api-scraper/api/data/response"
"github.com/gin-gonic/gin"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)

type MockProductService struct {
mock.Mock
}

func (m *MockProductService) GetAll() ([]response.ProductResponse, error) {
args := m.Called()
return args.Get(0).([]response.ProductResponse), args.Error(1)
}
func (m *MockProductService) GetByID(productID string) (response.ProductResponse, error) {
args := m.Called(productID)
return args.Get(0).(response.ProductResponse), args.Error(1)
}
func (m *MockProductService) UpdateData(updateData request.UpdateDataRequest) (bool, error) {
args := m.Called(updateData)
return args.Bool(0), args.Error(1)
}

func TestProductController_GetAll(t *testing.T) {
gin.SetMode(gin.TestMode)
mockService := new(MockProductService)
productController := NewProductControllerImpl(mockService)

router := gin.Default()
router.GET("/products", productController.GetAll)

mockService.On("GetAll").Return([]response.ProductResponse{
{
ProductID: "test-id",
Name: "Test Product",
Category: "Test Category",
OriginalPrice: 100,
DiscountedPrice: 90,
},
{
ProductID: "test-id-2",
Name: "Test Product 2",
Category: "Test Category 2",
OriginalPrice: 200,
DiscountedPrice: 180,
},
}, nil)

req, err := http.NewRequest(http.MethodGet, "/products", nil)
assert.NoError(t, err, "Expected no error creating request")

rec := httptest.NewRecorder()
router.ServeHTTP(rec, req)

assert.Equal(t, http.StatusOK, rec.Code, "Expected status code 200")

var response response.BaseResponse
err = json.Unmarshal(rec.Body.Bytes(), &response)
assert.NoError(t, err, "Expected no error unmarshalling response")
assert.Equal(t, 200, response.Code, "Response code should be 200")
assert.Equal(t, "OK", response.Status, "Response status should be Success")
}

func TestProductController_GetByID(t *testing.T) {
gin.SetMode(gin.TestMode)
mockService := new(MockProductService)
productController := NewProductControllerImpl(mockService)

router := gin.Default()
router.GET("/products/:productId", productController.GetByID)

mockService.On("GetByID", "test-id").Return(response.ProductResponse{
ProductID: "test-id",
Name: "Test Product",
Category: "Test Category",
OriginalPrice: 100,
DiscountedPrice: 90,
}, nil)

req, err := http.NewRequest(http.MethodGet, "/products/test-id", nil)
assert.NoError(t, err, "Expected no error creating request")

rec := httptest.NewRecorder()
router.ServeHTTP(rec, req)

assert.Equal(t, http.StatusOK, rec.Code, "Expected status code 200")

var response response.BaseResponse
err = json.Unmarshal(rec.Body.Bytes(), &response)
assert.NoError(t, err, "Expected no error unmarshalling response")
assert.Equal(t, 200, response.Code, "Response code should be 200")
assert.Equal(t, "OK", response.Status, "Response status should be Success")
}

func TestProductController_UpdateData(t *testing.T) {
gin.SetMode(gin.TestMode)
mockService := new(MockProductService)
productController := NewProductControllerImpl(mockService)

router := gin.Default()
router.PUT("/products", productController.UpdateData)

mockService.On("UpdateData", request.UpdateDataRequest{
UpdateData: true,
}).Return(true, nil)

reqBody, err := json.Marshal(request.UpdateDataRequest{
UpdateData: true,
})
assert.NoError(t, err, "Expected no error marshalling request")

req, err := http.NewRequest(http.MethodPut, "/products", bytes.NewBuffer(reqBody))
assert.NoError(t, err, "Expected no error creating request")

rec := httptest.NewRecorder()
router.ServeHTTP(rec, req)

assert.Equal(t, http.StatusOK, rec.Code, "Expected status code 200")

var response response.BaseResponse
err = json.Unmarshal(rec.Body.Bytes(), &response)
assert.NoError(t, err, "Expected no error unmarshalling response")
assert.Equal(t, 200, response.Code, "Response code should be 200")
assert.Equal(t, "OK", response.Status, "Response status should be Success")
}
5 changes: 3 additions & 2 deletions api/repository/product_repository_impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/dynamodb"
"github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute"
"github.com/aws/aws-sdk-go/service/dynamodb/dynamodbiface"
"github.com/dieg0code/serverles-api-scraper/api/models"
"github.com/sirupsen/logrus"
)

type ProductRepositoryImpl struct {
db *dynamodb.DynamoDB
db dynamodbiface.DynamoDBAPI
tableName string
}

Expand Down Expand Up @@ -138,7 +139,7 @@ func (p *ProductRepositoryImpl) GetByID(id string) (models.Product, error) {
return product, nil
}

func NewProductRepositoryImpl(db *dynamodb.DynamoDB, tableName string) ProductRepository {
func NewProductRepositoryImpl(db dynamodbiface.DynamoDBAPI, tableName string) ProductRepository {
return &ProductRepositoryImpl{
db: db,
tableName: tableName,
Expand Down
Loading

0 comments on commit c2ac4f7

Please sign in to comment.