Skip to content

Commit

Permalink
testing added
Browse files Browse the repository at this point in the history
  • Loading branch information
Neliz3 committed May 13, 2024
1 parent 5edbdee commit 18d1456
Show file tree
Hide file tree
Showing 10 changed files with 236 additions and 98 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,8 @@ jobs:
run: |
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.58.1
golangci-lint run
- name: Test
run: |
go test ./api
go test ./pkg/parser
40 changes: 40 additions & 0 deletions api/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package api

import (
"NEOs/configs"
"io"
"log"
"net/http"
)

type Body struct {
Body []byte
Err error
}

func GetAPI(link ...string) *http.Response {
// Read Configs
configs := configs.ReadConfigs()

// Send GET request
if link != nil {
configs.Link = link[0]
}
resp, err := http.Get(configs.Link)

if err != nil {
log.Fatalf("No response from request")
}
return resp
}

func GetResp() *Body {

// Read Response
body, err := io.ReadAll(GetAPI().Body)
if err != nil {
log.Fatalf("Unable to read a JSON due to %s", err)
}

return &Body{body, err}
}
24 changes: 24 additions & 0 deletions api/api_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package api

import (
"net/http"
"testing"

"github.com/stretchr/testify/suite"
)

type APISuite struct {
suite.Suite
response *http.Response
}

func (suite *APISuite) TestGetAPI() {
link := "https://api.nasa.gov/neo/rest/v1/feed?start_date=2015-09-07&end_date=2015-09-08&api_key=DEMO_KEY"

suite.response = GetAPI(link)
suite.Equal(suite.response.StatusCode, http.StatusOK)
}

func TestGetAPISuite(t *testing.T) {
suite.Run(t, new(APISuite))
}
94 changes: 7 additions & 87 deletions cmd/main.go
Original file line number Diff line number Diff line change
@@ -1,102 +1,22 @@
package main

import (
"NEOs/configs"
"encoding/json"
"NEOs/api"
"NEOs/pkg/parser"
"fmt"
"io"
"log"
"net/http"
"sync"
)

type Response struct {
Total interface{} `json:"element_count"`
Near_earth_objects Near_earth_objects `json:"near_earth_objects"`
}

type Near_earth_objects []struct {
Date interface{} `json:"date"`
ID interface{} `json:"id"`
Name interface{} `json:"name"`
Check interface{} `json:"is_potentially_hazardous_asteroid"`
}

func NewResponse(total interface{}, near_earth_objects Near_earth_objects) *Response {
return &Response{
Total: total,
Near_earth_objects: near_earth_objects,
}
}

var data map[string]interface{}
"github.com/joho/godotenv"
)

func main() {

// Read Configs
configs := configs.ReadConfigs()

// Send GET request
resp, err := http.Get(configs.Link)

if err != nil {
fmt.Println("No response from request")
}

// Read Response
body, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatalf("Unable to read a JSON due to %s", err)
}
err := godotenv.Load(".env")

// Decode a Json
err = json.Unmarshal([]byte(body), &data)
if err != nil {
log.Fatalf("Unable to marshal JSON due to %s", err)
log.Fatalf("Failed to read .env: %v", err)
}

// Assigning a Total value
result := NewResponse(data["element_count"], Near_earth_objects{})

// Creating a Wait Group and Mutex
wg := sync.WaitGroup{}
mutex := sync.Mutex{}

// Iteration through data
for date, value := range data["near_earth_objects"].(map[string]interface{}) {
var id, name, check interface{}
wg.Add(1)

// Concurrent data fetching for each day
go getDay(&id, &name, &check, value, &date, &wg, &mutex, result)
}
wg.Wait()
fmt.Println(string(parser.Parser(api.GetResp())))

// Returning a result
jsonResult, _ := json.MarshalIndent(result, "", "\t")
fmt.Println(string(jsonResult))
}

// Assigning received data to Response object
func addResponse(date *string, id, name, check *interface{}, wg *sync.WaitGroup, result *Response) {
result.Near_earth_objects = append(result.Near_earth_objects, struct {
Date interface{} "json:\"date\""
ID interface{} "json:\"id\""
Name interface{} "json:\"name\""
Check interface{} "json:\"is_potentially_hazardous_asteroid\""
}{date, id, name, check})
}

// Fetching data from one day
func getDay(id, name, check *interface{}, value interface{}, date *string, wg *sync.WaitGroup, mutex *sync.Mutex, result *Response) {
mutex.Lock()
for _, element := range value.([]interface{}) {
*id = element.(map[string]interface{})["id"]
*name = element.(map[string]interface{})["name"]
*check = element.(map[string]interface{})["is_potentially_hazardous_asteroid"]

addResponse(date, id, name, check, wg, result)
}
mutex.Unlock()
wg.Done()
}
16 changes: 7 additions & 9 deletions configs/configs.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,23 @@ package configs

import (
"fmt"
"log"
"os"
"time"

"github.com/joho/godotenv"
)

type Config struct {
API_KEY string
Link string
}

func ReadConfigs() *Config {
err := godotenv.Load()
if err != nil {
log.Fatalf("Failed to read .env: %v", err)
}
func ReadConfigs(api_key ...string) *Config {
var API_KEY string

API_KEY := os.Getenv("API_KEY")
if api_key != nil {
API_KEY = api_key[0]
} else {
API_KEY = os.Getenv("DEMO_API_KEY")
}

config := Config{
API_KEY: API_KEY,
Expand Down
2 changes: 1 addition & 1 deletion example.env
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
API_KEY="your_api_key"
DEMO_API_KEY="DEMO_KEY"
BaseLink="https://api.nasa.gov/neo/rest/v1/feed?start_date=%s&end_date=%s&api_key=%s"
9 changes: 8 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,20 @@ module NEOs
go 1.22.2

require (
github.com/joho/godotenv v1.5.1
github.com/stretchr/testify v1.9.0
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/joho/godotenv v1.5.1
github.com/miladibra10/vjson v0.3.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/tidwall/gjson v1.17.1 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
9 changes: 9 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
Expand All @@ -11,10 +13,17 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tidwall/gjson v1.17.1 h1:wlYEnwqAHgzmhNUFfw7Xalt2JzQvsMx2Se4PcoFCT/U=
github.com/tidwall/gjson v1.17.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
82 changes: 82 additions & 0 deletions pkg/parser/parser.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package parser

import (
"NEOs/api"
"encoding/json"
"log"
"sync"
)

type Neo interface {
AddNeo(obj Near_earth_objects)
}

type Response struct {
Total interface{} `json:"element_count"`
Near_earth_objects []Near_earth_objects `json:"near_earth_objects"`
}

type Near_earth_objects struct {
Date interface{} `json:"date"`
ID interface{} `json:"id"`
Name interface{} `json:"name"`
Check interface{} `json:"is_potentially_hazardous_asteroid"`
}

func NewResponse(total interface{}, near_earth_objects []Near_earth_objects) *Response {
return &Response{
Total: total,
Near_earth_objects: near_earth_objects,
}
}

func (res *Response) AddNeo(obj Near_earth_objects) []Near_earth_objects {
res.Near_earth_objects = append(res.Near_earth_objects, obj)
return res.Near_earth_objects
}

func Parser(body *api.Body) []byte {

// Decode a Json
var inputJson map[string]interface{}

body.Err = json.Unmarshal([]byte(body.Body), &inputJson)
if body.Err != nil {
log.Fatalf("Unable to marshal JSON due to %s", body.Err)
}

// Assigning a Total value
response := NewResponse(inputJson["element_count"], []Near_earth_objects{})

// Creating a Wait Group and Mutex
wg := sync.WaitGroup{}
mutex := sync.Mutex{}

// Iteration through data
for date, value := range inputJson["near_earth_objects"].(map[string]interface{}) {
wg.Add(1)

// Concurrent data fetching for each day
go getDay(value, &date, &wg, &mutex, response)
}
wg.Wait()

// Returning a result
jsonResponse, _ := json.MarshalIndent(response, "", "\t")
return jsonResponse
}

// Fetching data from one day
func getDay(value interface{}, date *string, wg *sync.WaitGroup, mut *sync.Mutex, res *Response) {
mut.Lock()
for _, element := range value.([]interface{}) {
id := element.(map[string]interface{})["id"]
name := element.(map[string]interface{})["name"]
check := element.(map[string]interface{})["is_potentially_hazardous_asteroid"]

neo := Near_earth_objects{Date: date, ID: id, Name: name, Check: check}
res.AddNeo(neo)
}
mut.Unlock()
wg.Done()
}
Loading

0 comments on commit 18d1456

Please sign in to comment.