160 lines
4.9 KiB
Go
160 lines
4.9 KiB
Go
package meteo_test
|
|
|
|
import (
|
|
"os"
|
|
"servicea/internal/domains/meteo"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func Test_CSV_ParseFile(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
filePath string
|
|
expectedInserted int
|
|
expectedRejected int
|
|
expectError bool
|
|
validateInserted func(t *testing.T, inserted []meteo.MeteoData)
|
|
validateRejected func(t *testing.T, rejected []meteo.RejectedMeteoData)
|
|
}{
|
|
{
|
|
name: "valid record",
|
|
filePath: "./../../../assets/test_1.csv",
|
|
expectedInserted: 1,
|
|
expectedRejected: 0,
|
|
validateInserted: func(t *testing.T, inserted []meteo.MeteoData) {
|
|
assert.Equal(t, 1, len(inserted))
|
|
record := inserted[0]
|
|
assert.Equal(t, time.Date(2025, 10, 12, 0, 0, 0, 0, time.UTC), record.Timestamp)
|
|
assert.Equal(t, "Madrid", record.Location)
|
|
assert.Equal(t, float32(11.55), record.MaxTemp)
|
|
assert.Equal(t, float32(6.25), record.MinTemp)
|
|
assert.Equal(t, float32(0), record.Rainfall)
|
|
assert.Equal(t, int(10), record.Cloudiness)
|
|
},
|
|
validateRejected: func(t *testing.T, rejected []meteo.RejectedMeteoData) {
|
|
assert.Empty(t, rejected)
|
|
},
|
|
},
|
|
{
|
|
name: "record with leading spaces",
|
|
filePath: "./../../../assets/test_2.csv",
|
|
expectedInserted: 1,
|
|
expectedRejected: 0,
|
|
validateInserted: func(t *testing.T, inserted []meteo.MeteoData) {
|
|
assert.Equal(t, 1, len(inserted))
|
|
assert.Equal(t, "Madrid", inserted[0].Location)
|
|
},
|
|
validateRejected: func(t *testing.T, rejected []meteo.RejectedMeteoData) {
|
|
assert.Empty(t, rejected)
|
|
},
|
|
},
|
|
{
|
|
name: "missing city column",
|
|
filePath: "./../../../assets/test_3.csv",
|
|
expectedInserted: 0,
|
|
expectedRejected: 1,
|
|
validateInserted: func(t *testing.T, inserted []meteo.MeteoData) {
|
|
assert.Empty(t, inserted)
|
|
},
|
|
validateRejected: func(t *testing.T, rejected []meteo.RejectedMeteoData) {
|
|
assert.Equal(t, 1, len(rejected))
|
|
assert.Contains(t, rejected[0].Reason, "missing or invalid location")
|
|
assert.Equal(t, "2025/10/12;11,55;6,25;0;10", rejected[0].RowValue)
|
|
},
|
|
},
|
|
{
|
|
name: "empty file with only header",
|
|
filePath: "./../../../assets/test_4.csv",
|
|
expectedInserted: 0,
|
|
expectedRejected: 0,
|
|
validateInserted: func(t *testing.T, inserted []meteo.MeteoData) {
|
|
assert.Empty(t, inserted)
|
|
},
|
|
validateRejected: func(t *testing.T, rejected []meteo.RejectedMeteoData) {
|
|
assert.Empty(t, rejected)
|
|
},
|
|
},
|
|
{
|
|
name: "missing max temp field value",
|
|
filePath: "./../../../assets/test_5.csv",
|
|
expectedInserted: 0,
|
|
expectedRejected: 1,
|
|
validateInserted: func(t *testing.T, inserted []meteo.MeteoData) {
|
|
assert.Empty(t, inserted)
|
|
},
|
|
validateRejected: func(t *testing.T, rejected []meteo.RejectedMeteoData) {
|
|
assert.Equal(t, 1, len(rejected))
|
|
assert.Contains(t, rejected[0].Reason, "missing or invalid max temp")
|
|
assert.Equal(t, "2025/10/12;Madrid;;6,25;0;10", rejected[0].RowValue)
|
|
},
|
|
},
|
|
{
|
|
name: "missing city field value",
|
|
filePath: "./../../../assets/test_6.csv",
|
|
expectedInserted: 0,
|
|
expectedRejected: 1,
|
|
validateInserted: func(t *testing.T, inserted []meteo.MeteoData) {
|
|
assert.Empty(t, inserted)
|
|
},
|
|
validateRejected: func(t *testing.T, rejected []meteo.RejectedMeteoData) {
|
|
assert.Equal(t, 1, len(rejected))
|
|
assert.Contains(t, rejected[0].Reason, "missing or invalid location")
|
|
assert.Equal(t, "2025/10/12;;11,55;6,25;0;10", rejected[0].RowValue)
|
|
},
|
|
},
|
|
{
|
|
name: "missing date field value",
|
|
filePath: "./../../../assets/test_7.csv",
|
|
expectedInserted: 0,
|
|
expectedRejected: 1,
|
|
expectError: false,
|
|
validateInserted: func(t *testing.T, inserted []meteo.MeteoData) {
|
|
assert.Empty(t, inserted)
|
|
},
|
|
validateRejected: func(t *testing.T, rejected []meteo.RejectedMeteoData) {
|
|
assert.Equal(t, 1, len(rejected))
|
|
assert.Contains(t, rejected[0].Reason, "missing or invalid date")
|
|
assert.Equal(t, ";Madrid;11,55;6,25;0;10", rejected[0].RowValue)
|
|
},
|
|
},
|
|
{
|
|
name: "invalid separator comma instead of semicolon",
|
|
filePath: "./../../../assets/test_8.csv",
|
|
expectedInserted: 0,
|
|
expectedRejected: 0,
|
|
expectError: true,
|
|
validateInserted: nil,
|
|
validateRejected: nil,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
file, err := os.Open(tt.filePath)
|
|
assert.NoError(t, err)
|
|
defer file.Close()
|
|
|
|
csvIngest := &meteo.CSV{}
|
|
inserted, rejected, err := csvIngest.Parse(file)
|
|
|
|
if tt.expectError {
|
|
assert.Error(t, err)
|
|
assert.ErrorIs(t, err, meteo.ErrCannotParseFile)
|
|
return
|
|
}
|
|
|
|
assert.NoError(t, err)
|
|
|
|
if tt.validateInserted != nil {
|
|
tt.validateInserted(t, inserted)
|
|
}
|
|
if tt.validateRejected != nil {
|
|
tt.validateRejected(t, rejected)
|
|
}
|
|
})
|
|
}
|
|
}
|