From fd5b7a264f43321c44a9b22a304e9c7012d056de Mon Sep 17 00:00:00 2001 From: Artem-Sergeevi4 Date: Wed, 20 Nov 2024 16:23:27 +0300 Subject: [PATCH 1/2] --- main.go | 40 +++----------- parcel.go | 105 ++++++++++++++++++++++------------- parcel_test.go | 144 ++++++++++++++++++++++++------------------------ test_tracker.db | Bin 0 -> 12288 bytes tracker.db | Bin 61440 -> 61440 bytes 5 files changed, 147 insertions(+), 142 deletions(-) create mode 100644 test_tracker.db diff --git a/main.go b/main.go index 44c32b3f..ba7a3633 100644 --- a/main.go +++ b/main.go @@ -3,6 +3,7 @@ package main import ( "database/sql" "fmt" + "log" "time" _ "modernc.org/sqlite" @@ -44,7 +45,6 @@ func (s ParcelService) Register(client int, address string) (Parcel, error) { } parcel.Number = id - fmt.Printf("Новая посылка № %d на адрес %s от клиента с идентификатором %d зарегистрирована %s\n", parcel.Number, parcel.Address, parcel.Client, parcel.CreatedAt) @@ -84,7 +84,6 @@ func (s ParcelService) NextStatus(number int) error { } fmt.Printf("У посылки № %d новый статус: %s\n", number, nextStatus) - return s.store.SetStatus(number, nextStatus) } @@ -97,12 +96,15 @@ func (s ParcelService) Delete(number int) error { } func main() { - // настройте подключение к БД + db, err := sql.Open("sqlite", "tracker.db") + if err != nil { + log.Fatalf("Ошибка подключения к БД: %v", err) + } + defer db.Close() - store := // создайте объект ParcelStore функцией NewParcelStore + store := NewParcelStore(db) service := NewParcelService(store) - // регистрация посылки client := 1 address := "Псков, д. Пушкина, ул. Колотушкина, д. 5" p, err := service.Register(client, address) @@ -111,7 +113,6 @@ func main() { return } - // изменение адреса newAddress := "Саратов, д. Верхние Зори, ул. Козлова, д. 25" err = service.ChangeAddress(p.Number, newAddress) if err != nil { @@ -119,51 +120,24 @@ func main() { return } - // изменение статуса err = service.NextStatus(p.Number) if err != nil { fmt.Println(err) return } - // вывод посылок клиента err = service.PrintClientParcels(client) if err != nil { fmt.Println(err) return } - // попытка удаления отправленной посылки - err = service.Delete(p.Number) - if err != nil { - fmt.Println(err) - return - } - - // вывод посылок клиента - // предыдущая посылка не должна удалиться, т.к. её статус НЕ «зарегистрирована» - err = service.PrintClientParcels(client) - if err != nil { - fmt.Println(err) - return - } - - // регистрация новой посылки - p, err = service.Register(client, address) - if err != nil { - fmt.Println(err) - return - } - - // удаление новой посылки err = service.Delete(p.Number) if err != nil { fmt.Println(err) return } - // вывод посылок клиента - // здесь не должно быть последней посылки, т.к. она должна была успешно удалиться err = service.PrintClientParcels(client) if err != nil { fmt.Println(err) diff --git a/parcel.go b/parcel.go index db6c815d..0d01509b 100644 --- a/parcel.go +++ b/parcel.go @@ -4,57 +4,86 @@ import ( "database/sql" ) -type ParcelStore struct { - db *sql.DB +type ParcelStore interface { + Add(parcel Parcel) (int, error) + GetByClient(client int) ([]Parcel, error) + Get(number int) (Parcel, error) + SetStatus(number int, status string) error + SetAddress(number int, address string) error + Delete(number int) error } -func NewParcelStore(db *sql.DB) ParcelStore { - return ParcelStore{db: db} +type SQLiteParcelStore struct { + db *sql.DB } -func (s ParcelStore) Add(p Parcel) (int, error) { - // реализуйте добавление строки в таблицу parcel, используйте данные из переменной p - - // верните идентификатор последней добавленной записи - return 0, nil +func NewParcelStore(db *sql.DB) *SQLiteParcelStore { + return &SQLiteParcelStore{db: db} } -func (s ParcelStore) Get(number int) (Parcel, error) { - // реализуйте чтение строки по заданному number - // здесь из таблицы должна вернуться только одна строка - - // заполните объект Parcel данными из таблицы - p := Parcel{} - - return p, nil +func (s *SQLiteParcelStore) Add(parcel Parcel) (int, error) { + stmt, err := s.db.Prepare("INSERT INTO parcel (client, status, address, created_at) VALUES (?, ?, ?, ?)") + if err != nil { + return 0, err + } + res, err := stmt.Exec(parcel.Client, parcel.Status, parcel.Address, parcel.CreatedAt) + if err != nil { + return 0, err + } + id, err := res.LastInsertId() + return int(id), err } -func (s ParcelStore) GetByClient(client int) ([]Parcel, error) { - // реализуйте чтение строк из таблицы parcel по заданному client - // здесь из таблицы может вернуться несколько строк - - // заполните срез Parcel данными из таблицы - var res []Parcel - - return res, nil +func (s *SQLiteParcelStore) GetByClient(client int) ([]Parcel, error) { + rows, err := s.db.Query("SELECT number, client, status, address, created_at FROM parcel WHERE client = ?", client) + if err != nil { + return nil, err + } + defer rows.Close() + + var parcels []Parcel + for rows.Next() { + var parcel Parcel + if err := rows.Scan(&parcel.Number, &parcel.Client, &parcel.Status, &parcel.Address, &parcel.CreatedAt); err != nil { + return nil, err + } + parcels = append(parcels, parcel) + } + return parcels, nil } -func (s ParcelStore) SetStatus(number int, status string) error { - // реализуйте обновление статуса в таблице parcel - - return nil +func (s *SQLiteParcelStore) Get(number int) (Parcel, error) { + row := s.db.QueryRow("SELECT number, client, status, address, created_at FROM parcel WHERE number = ?", number) + var parcel Parcel + if err := row.Scan(&parcel.Number, &parcel.Client, &parcel.Status, &parcel.Address, &parcel.CreatedAt); err != nil { + return Parcel{}, err + } + return parcel, nil } -func (s ParcelStore) SetAddress(number int, address string) error { - // реализуйте обновление адреса в таблице parcel - // менять адрес можно только если значение статуса registered - - return nil +func (s *SQLiteParcelStore) SetStatus(number int, status string) error { + stmt, err := s.db.Prepare("UPDATE parcel SET status = ? WHERE number = ?") + if err != nil { + return err + } + _, err = stmt.Exec(status, number) + return err } -func (s ParcelStore) Delete(number int) error { - // реализуйте удаление строки из таблицы parcel - // удалять строку можно только если значение статуса registered +func (s *SQLiteParcelStore) SetAddress(number int, address string) error { + stmt, err := s.db.Prepare("UPDATE parcel SET address = ? WHERE number = ?") + if err != nil { + return err + } + _, err = stmt.Exec(address, number) + return err +} - return nil +func (s *SQLiteParcelStore) Delete(number int) error { + stmt, err := s.db.Prepare("DELETE FROM parcel WHERE number = ?") + if err != nil { + return err + } + _, err = stmt.Exec(number) + return err } diff --git a/parcel_test.go b/parcel_test.go index d1b93827..672d0913 100644 --- a/parcel_test.go +++ b/parcel_test.go @@ -10,112 +10,114 @@ import ( ) var ( - // randSource источник псевдо случайных чисел. - // Для повышения уникальности в качестве seed - // используется текущее время в unix формате (в виде числа) randSource = rand.NewSource(time.Now().UnixNano()) - // randRange использует randSource для генерации случайных чисел - randRange = rand.New(randSource) + randRange = rand.New(randSource) ) -// getTestParcel возвращает тестовую посылку func getTestParcel() Parcel { return Parcel{ - Client: 1000, + Client: randRange.Intn(1000), Status: ParcelStatusRegistered, - Address: "test", + Address: "Test Address", CreatedAt: time.Now().UTC().Format(time.RFC3339), } } -// TestAddGetDelete проверяет добавление, получение и удаление посылки +func setupDatabase(t *testing.T) *sql.DB { + db, err := sql.Open("sqlite", "test_tracker.db") + require.NoError(t, err) + + _, err = db.Exec(`CREATE TABLE IF NOT EXISTS parcel ( + number INTEGER PRIMARY KEY AUTOINCREMENT, + client INTEGER, + status TEXT, + address TEXT, + created_at TEXT + )`) + require.NoError(t, err) + + return db +} + func TestAddGetDelete(t *testing.T) { - // prepare - db, err := // настройте подключение к БД + db := setupDatabase(t) + defer db.Close() + store := NewParcelStore(db) parcel := getTestParcel() - // add - // добавьте новую посылку в БД, убедитесь в отсутствии ошибки и наличии идентификатора + id, err := store.Add(parcel) + require.NoError(t, err) + require.NotZero(t, id) - // get - // получите только что добавленную посылку, убедитесь в отсутствии ошибки - // проверьте, что значения всех полей в полученном объекте совпадают со значениями полей в переменной parcel + fetchedParcel, err := store.Get(id) + require.NoError(t, err) + require.Equal(t, parcel.Client, fetchedParcel.Client) + require.Equal(t, parcel.Status, fetchedParcel.Status) + require.Equal(t, parcel.Address, fetchedParcel.Address) - // delete - // удалите добавленную посылку, убедитесь в отсутствии ошибки - // проверьте, что посылку больше нельзя получить из БД + err = store.Delete(id) + require.NoError(t, err) + + _, err = store.Get(id) + require.Error(t, err) } -// TestSetAddress проверяет обновление адреса func TestSetAddress(t *testing.T) { - // prepare - db, err := // настройте подключение к БД + db := setupDatabase(t) + defer db.Close() - // add - // добавьте новую посылку в БД, убедитесь в отсутствии ошибки и наличии идентификатора + store := NewParcelStore(db) + parcel := getTestParcel() - // set address - // обновите адрес, убедитесь в отсутствии ошибки - newAddress := "new test address" + id, err := store.Add(parcel) + require.NoError(t, err) - // check - // получите добавленную посылку и убедитесь, что адрес обновился + newAddress := "New Test Address" + err = store.SetAddress(id, newAddress) + require.NoError(t, err) + + fetchedParcel, err := store.Get(id) + require.NoError(t, err) + require.Equal(t, newAddress, fetchedParcel.Address) } -// TestSetStatus проверяет обновление статуса func TestSetStatus(t *testing.T) { - // prepare - db, err := // настройте подключение к БД + db := setupDatabase(t) + defer db.Close() - // add - // добавьте новую посылку в БД, убедитесь в отсутствии ошибки и наличии идентификатора + store := NewParcelStore(db) + parcel := getTestParcel() + + id, err := store.Add(parcel) + require.NoError(t, err) - // set status - // обновите статус, убедитесь в отсутствии ошибки + err = store.SetStatus(id, ParcelStatusSent) + require.NoError(t, err) - // check - // получите добавленную посылку и убедитесь, что статус обновился + fetchedParcel, err := store.Get(id) + require.NoError(t, err) + require.Equal(t, ParcelStatusSent, fetchedParcel.Status) } -// TestGetByClient проверяет получение посылок по идентификатору клиента func TestGetByClient(t *testing.T) { - // prepare - db, err := // настройте подключение к БД + db := setupDatabase(t) + defer db.Close() + store := NewParcelStore(db) + + clientID := randRange.Intn(1000) parcels := []Parcel{ - getTestParcel(), - getTestParcel(), - getTestParcel(), + {Client: clientID, Status: ParcelStatusRegistered, Address: "Address 1", CreatedAt: time.Now().UTC().Format(time.RFC3339)}, + {Client: clientID, Status: ParcelStatusRegistered, Address: "Address 2", CreatedAt: time.Now().UTC().Format(time.RFC3339)}, } - parcelMap := map[int]Parcel{} - - // задаём всем посылкам один и тот же идентификатор клиента - client := randRange.Intn(10_000_000) - parcels[0].Client = client - parcels[1].Client = client - parcels[2].Client = client - // add - for i := 0; i < len(parcels); i++ { - id, err := // добавьте новую посылку в БД, убедитесь в отсутствии ошибки и наличии идентификатора - - // обновляем идентификатор добавленной у посылки - parcels[i].Number = id - - // сохраняем добавленную посылку в структуру map, чтобы её можно было легко достать по идентификатору посылки - parcelMap[id] = parcels[i] + for _, p := range parcels { + _, err := store.Add(p) + require.NoError(t, err) } - // get by client - storedParcels, err := // получите список посылок по идентификатору клиента, сохранённого в переменной client - // убедитесь в отсутствии ошибки - // убедитесь, что количество полученных посылок совпадает с количеством добавленных - - // check - for _, parcel := range storedParcels { - // в parcelMap лежат добавленные посылки, ключ - идентификатор посылки, значение - сама посылка - // убедитесь, что все посылки из storedParcels есть в parcelMap - // убедитесь, что значения полей полученных посылок заполнены верно - } + fetchedParcels, err := store.GetByClient(clientID) + require.NoError(t, err) + require.Equal(t, len(parcels), len(fetchedParcels)) } diff --git a/test_tracker.db b/test_tracker.db new file mode 100644 index 0000000000000000000000000000000000000000..ba6d03223fd0b12d844c9e5a6a9e4ff2ad00d78d GIT binary patch literal 12288 zcmeI2zi!h|6vpqhs}$PCWhn3|*-oy2uqC~DAo)%@6qMZ``ro13P00ck)1V8`;KmY_l00ck) z1VG@g64+A;rAmbk1NUGm{Nt${d-r{Dyb$wIda2$WSf*_;+q|=5u~hEn+?|Q4RBpXC z>1wH5rf;5})jV>&k(fqT<);eK9@|`Fam*L91L3h=-?r{q1GYEl?V5ujyKfDd`PhEY z>r45r)wiqP6{G1y%!8#O+4loCSoqAgp8SyPj>n$x)4L;2xPch&%Q-(xKP$Zz&gL7% z_eB4opXd|4qZ93u_D(y}I@)^ivwVR70T2KI5C8!X009sH0T2KI5cszQ>RN#)S1uds zEl)g~_<``m*o@~q&Kta4Yc^}m8#d?Nw$W`joO&@^(EOdCvQZ%P;#K37FDFe~_yLRS z|B~D?obC0ndd;9;lXm*zCCk(I7a|V?2!H?xfB*=900@8p2!H?xfB*=9z<)$wjjClD{ga@50|6Wa3;+NC literal 0 HcmV?d00001 diff --git a/tracker.db b/tracker.db index b6ba48a148daa7c8c4727d4bfc1c868229d7fb24..4aa765bb7953d8e7dd737d1f7a069c759874f192 100644 GIT binary patch delta 182 zcmZp8z})bFd4e>f-9#B@Ryzj0v{xHb7RhsbVc`G5e}n(VW;`GLumPgQ$kfQd Z$VAuBP}k5h#K_3X*v!hvB5IMt1_0nrOE>@k delta 60 zcmV-C0K@-)-~)i*1CSd5Dv=yR1u6h8Zn&{zq8|wL01x#K*bmsV5fI7`lh`jD3}FcY S0~rW#VRB<-Y@!elqCl{GdK7*D From 0dd4803914067099194257b8ff0cac687b3be163 Mon Sep 17 00:00:00 2001 From: Artem-Sergeevi4 Date: Sat, 23 Nov 2024 22:32:33 +0300 Subject: [PATCH 2/2] first commit --- main.go | 38 +++++++++++++-- parcel.go | 99 ++++++++++++++++++++------------------ parcel_test.go | 125 ++++++++++++++++++++++++++++++++++-------------- test_tracker.db | Bin 12288 -> 0 bytes tracker.db | Bin 61440 -> 61440 bytes 5 files changed, 176 insertions(+), 86 deletions(-) delete mode 100644 test_tracker.db diff --git a/main.go b/main.go index ba7a3633..8153cd32 100644 --- a/main.go +++ b/main.go @@ -3,7 +3,6 @@ package main import ( "database/sql" "fmt" - "log" "time" _ "modernc.org/sqlite" @@ -45,6 +44,7 @@ func (s ParcelService) Register(client int, address string) (Parcel, error) { } parcel.Number = id + fmt.Printf("Новая посылка № %d на адрес %s от клиента с идентификатором %d зарегистрирована %s\n", parcel.Number, parcel.Address, parcel.Client, parcel.CreatedAt) @@ -84,6 +84,7 @@ func (s ParcelService) NextStatus(number int) error { } fmt.Printf("У посылки № %d новый статус: %s\n", number, nextStatus) + return s.store.SetStatus(number, nextStatus) } @@ -96,15 +97,18 @@ func (s ParcelService) Delete(number int) error { } func main() { + // настройте подключение к БД db, err := sql.Open("sqlite", "tracker.db") if err != nil { - log.Fatalf("Ошибка подключения к БД: %v", err) + fmt.Println(err) + return } defer db.Close() - store := NewParcelStore(db) + store := NewParcelStore(db) // создайте объект ParcelStore функцией NewParcelStore service := NewParcelService(store) + // регистрация посылки client := 1 address := "Псков, д. Пушкина, ул. Колотушкина, д. 5" p, err := service.Register(client, address) @@ -113,6 +117,7 @@ func main() { return } + // изменение адреса newAddress := "Саратов, д. Верхние Зори, ул. Козлова, д. 25" err = service.ChangeAddress(p.Number, newAddress) if err != nil { @@ -120,24 +125,51 @@ func main() { return } + // изменение статуса err = service.NextStatus(p.Number) if err != nil { fmt.Println(err) return } + // вывод посылок клиента err = service.PrintClientParcels(client) if err != nil { fmt.Println(err) return } + // попытка удаления отправленной посылки + err = service.Delete(p.Number) + if err != nil { + fmt.Println(err) + return + } + + // вывод посылок клиента + // предыдущая посылка не должна удалиться, т.к. её статус НЕ «зарегистрирована» + err = service.PrintClientParcels(client) + if err != nil { + fmt.Println(err) + return + } + + // регистрация новой посылки + p, err = service.Register(client, address) + if err != nil { + fmt.Println(err) + return + } + + // удаление новой посылки err = service.Delete(p.Number) if err != nil { fmt.Println(err) return } + // вывод посылок клиента + // здесь не должно быть последней посылки, т.к. она должна была успешно удалиться err = service.PrintClientParcels(client) if err != nil { fmt.Println(err) diff --git a/parcel.go b/parcel.go index 0d01509b..0df99929 100644 --- a/parcel.go +++ b/parcel.go @@ -4,86 +4,93 @@ import ( "database/sql" ) -type ParcelStore interface { - Add(parcel Parcel) (int, error) - GetByClient(client int) ([]Parcel, error) - Get(number int) (Parcel, error) - SetStatus(number int, status string) error - SetAddress(number int, address string) error - Delete(number int) error -} - -type SQLiteParcelStore struct { +type ParcelStore struct { db *sql.DB } -func NewParcelStore(db *sql.DB) *SQLiteParcelStore { - return &SQLiteParcelStore{db: db} +func NewParcelStore(db *sql.DB) ParcelStore { + return ParcelStore{db: db} } -func (s *SQLiteParcelStore) Add(parcel Parcel) (int, error) { - stmt, err := s.db.Prepare("INSERT INTO parcel (client, status, address, created_at) VALUES (?, ?, ?, ?)") +func (s ParcelStore) Add(p Parcel) (int, error) { + result, err := s.db.Exec("INSERT INTO parcel (client, status, address, created_at) VALUES (:client, :status, :address, :created_at)", + sql.Named("client", p.Client), + sql.Named("status", p.Status), + sql.Named("address", p.Address), + sql.Named("created_at", p.CreatedAt)) if err != nil { return 0, err } - res, err := stmt.Exec(parcel.Client, parcel.Status, parcel.Address, parcel.CreatedAt) + + id, err := result.LastInsertId() if err != nil { return 0, err } - id, err := res.LastInsertId() - return int(id), err + + return int(id), nil } -func (s *SQLiteParcelStore) GetByClient(client int) ([]Parcel, error) { - rows, err := s.db.Query("SELECT number, client, status, address, created_at FROM parcel WHERE client = ?", client) +func (s ParcelStore) Get(number int) (Parcel, error) { + p := Parcel{} + err := s.db.QueryRow("SELECT number, client, status, address, created_at FROM parcel WHERE number = :number", + sql.Named("number", number)). + Scan(&p.Number, &p.Client, &p.Status, &p.Address, &p.CreatedAt) + if err != nil { + return Parcel{}, err + } + + return p, nil +} + +func (s ParcelStore) GetByClient(client int) ([]Parcel, error) { + rows, err := s.db.Query("SELECT number, client, status, address, created_at FROM parcel WHERE client = :client", + sql.Named("client", client)) if err != nil { return nil, err } defer rows.Close() - var parcels []Parcel + var res []Parcel for rows.Next() { - var parcel Parcel - if err := rows.Scan(&parcel.Number, &parcel.Client, &parcel.Status, &parcel.Address, &parcel.CreatedAt); err != nil { + var p Parcel + if err := rows.Scan(&p.Number, &p.Client, &p.Status, &p.Address, &p.CreatedAt); err != nil { return nil, err } - parcels = append(parcels, parcel) + res = append(res, p) } - return parcels, nil -} - -func (s *SQLiteParcelStore) Get(number int) (Parcel, error) { - row := s.db.QueryRow("SELECT number, client, status, address, created_at FROM parcel WHERE number = ?", number) - var parcel Parcel - if err := row.Scan(&parcel.Number, &parcel.Client, &parcel.Status, &parcel.Address, &parcel.CreatedAt); err != nil { - return Parcel{}, err + if err = rows.Err(); err != nil { + return nil, err } - return parcel, nil + + return res, nil } -func (s *SQLiteParcelStore) SetStatus(number int, status string) error { - stmt, err := s.db.Prepare("UPDATE parcel SET status = ? WHERE number = ?") - if err != nil { - return err - } - _, err = stmt.Exec(status, number) +func (s ParcelStore) SetStatus(number int, status string) error { + _, err := s.db.Exec("UPDATE parcel SET status = :status WHERE number = :number", + sql.Named("status", status), + sql.Named("number", number)) return err } -func (s *SQLiteParcelStore) SetAddress(number int, address string) error { - stmt, err := s.db.Prepare("UPDATE parcel SET address = ? WHERE number = ?") +func (s ParcelStore) SetAddress(number int, address string) error { + _, err := s.db.Exec("UPDATE parcel SET address = :address WHERE number = :number AND status = :status", + sql.Named("address", address), + sql.Named("number", number), + sql.Named("status", ParcelStatusRegistered)) if err != nil { return err } - _, err = stmt.Exec(address, number) - return err + + return nil } -func (s *SQLiteParcelStore) Delete(number int) error { - stmt, err := s.db.Prepare("DELETE FROM parcel WHERE number = ?") +func (s ParcelStore) Delete(number int) error { + _, err := s.db.Exec("DELETE FROM parcel WHERE number = :number AND status = :status", + sql.Named("number", number), + sql.Named("status", ParcelStatusRegistered)) if err != nil { return err } - _, err = stmt.Exec(number) - return err + + return nil } diff --git a/parcel_test.go b/parcel_test.go index 672d0913..0b78e15e 100644 --- a/parcel_test.go +++ b/parcel_test.go @@ -6,7 +6,10 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + _ "modernc.org/sqlite" ) var ( @@ -16,108 +19,156 @@ var ( func getTestParcel() Parcel { return Parcel{ - Client: randRange.Intn(1000), + Client: 1000, Status: ParcelStatusRegistered, - Address: "Test Address", + Address: "test", CreatedAt: time.Now().UTC().Format(time.RFC3339), } } -func setupDatabase(t *testing.T) *sql.DB { - db, err := sql.Open("sqlite", "test_tracker.db") - require.NoError(t, err) - - _, err = db.Exec(`CREATE TABLE IF NOT EXISTS parcel ( - number INTEGER PRIMARY KEY AUTOINCREMENT, - client INTEGER, - status TEXT, - address TEXT, - created_at TEXT - )`) - require.NoError(t, err) - - return db +func createParcelTable(db *sql.DB) error { + _, err := db.Exec(` + CREATE TABLE IF NOT EXISTS parcel ( + number INTEGER PRIMARY KEY AUTOINCREMENT, + client INTEGER, + status TEXT, + address TEXT, + created_at TEXT + ) + `) + return err } func TestAddGetDelete(t *testing.T) { - db := setupDatabase(t) + db, err := sql.Open("sqlite", ":memory:") + require.NoError(t, err) defer db.Close() + err = createParcelTable(db) + require.NoError(t, err) + store := NewParcelStore(db) parcel := getTestParcel() + // add id, err := store.Add(parcel) require.NoError(t, err) require.NotZero(t, id) - fetchedParcel, err := store.Get(id) + parcel.Number = id + + // get + storedParcel, err := store.Get(id) require.NoError(t, err) - require.Equal(t, parcel.Client, fetchedParcel.Client) - require.Equal(t, parcel.Status, fetchedParcel.Status) - require.Equal(t, parcel.Address, fetchedParcel.Address) + require.Equal(t, parcel, storedParcel) + // delete err = store.Delete(id) require.NoError(t, err) _, err = store.Get(id) require.Error(t, err) + assert.ErrorIs(t, err, sql.ErrNoRows) } func TestSetAddress(t *testing.T) { - db := setupDatabase(t) + db, err := sql.Open("sqlite", ":memory:") + require.NoError(t, err) defer db.Close() + err = createParcelTable(db) + require.NoError(t, err) + store := NewParcelStore(db) parcel := getTestParcel() + // add id, err := store.Add(parcel) require.NoError(t, err) + require.NotZero(t, id) - newAddress := "New Test Address" + // set address + newAddress := "new test address" err = store.SetAddress(id, newAddress) require.NoError(t, err) - fetchedParcel, err := store.Get(id) + // check + storedParcel, err := store.Get(id) require.NoError(t, err) - require.Equal(t, newAddress, fetchedParcel.Address) + require.Equal(t, newAddress, storedParcel.Address) } func TestSetStatus(t *testing.T) { - db := setupDatabase(t) + db, err := sql.Open("sqlite", ":memory:") + require.NoError(t, err) defer db.Close() + err = createParcelTable(db) + require.NoError(t, err) + store := NewParcelStore(db) parcel := getTestParcel() + // add id, err := store.Add(parcel) require.NoError(t, err) + require.NotZero(t, id) - err = store.SetStatus(id, ParcelStatusSent) + // set status + newStatus := ParcelStatusSent + err = store.SetStatus(id, newStatus) require.NoError(t, err) - fetchedParcel, err := store.Get(id) + // check + storedParcel, err := store.Get(id) require.NoError(t, err) - require.Equal(t, ParcelStatusSent, fetchedParcel.Status) + assert.Equal(t, newStatus, storedParcel.Status) } func TestGetByClient(t *testing.T) { - db := setupDatabase(t) + db, err := sql.Open("sqlite", ":memory:") + require.NoError(t, err) defer db.Close() + err = createParcelTable(db) + require.NoError(t, err) + store := NewParcelStore(db) - clientID := randRange.Intn(1000) parcels := []Parcel{ - {Client: clientID, Status: ParcelStatusRegistered, Address: "Address 1", CreatedAt: time.Now().UTC().Format(time.RFC3339)}, - {Client: clientID, Status: ParcelStatusRegistered, Address: "Address 2", CreatedAt: time.Now().UTC().Format(time.RFC3339)}, + getTestParcel(), + getTestParcel(), + getTestParcel(), + } + parcelMap := map[int]Parcel{} + + client := randRange.Intn(10_000_000) + for i := range parcels { + parcels[i].Client = client } - for _, p := range parcels { - _, err := store.Add(p) + // add + for i := 0; i < len(parcels); i++ { + id, err := store.Add(parcels[i]) require.NoError(t, err) + require.NotZero(t, id) + + parcels[i].Number = id + parcelMap[id] = parcels[i] } - fetchedParcels, err := store.GetByClient(clientID) + // get by client + storedParcels, err := store.GetByClient(client) require.NoError(t, err) - require.Equal(t, len(parcels), len(fetchedParcels)) + assert.Len(t, storedParcels, len(parcels)) + + // check + for _, parcel := range storedParcels { + originalParcel, exists := parcelMap[parcel.Number] + require.True(t, exists) + require.Equal(t, originalParcel.Client, parcel.Client) + require.Equal(t, originalParcel.Status, parcel.Status) + require.Equal(t, originalParcel.Address, parcel.Address) + require.Equal(t, originalParcel.CreatedAt, parcel.CreatedAt) + } } diff --git a/test_tracker.db b/test_tracker.db deleted file mode 100644 index ba6d03223fd0b12d844c9e5a6a9e4ff2ad00d78d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI2zi!h|6vpqhs}$PCWhn3|*-oy2uqC~DAo)%@6qMZ``ro13P00ck)1V8`;KmY_l00ck) z1VG@g64+A;rAmbk1NUGm{Nt${d-r{Dyb$wIda2$WSf*_;+q|=5u~hEn+?|Q4RBpXC z>1wH5rf;5})jV>&k(fqT<);eK9@|`Fam*L91L3h=-?r{q1GYEl?V5ujyKfDd`PhEY z>r45r)wiqP6{G1y%!8#O+4loCSoqAgp8SyPj>n$x)4L;2xPch&%Q-(xKP$Zz&gL7% z_eB4opXd|4qZ93u_D(y}I@)^ivwVR70T2KI5C8!X009sH0T2KI5cszQ>RN#)S1uds zEl)g~_<``m*o@~q&Kta4Yc^}m8#d?Nw$W`joO&@^(EOdCvQZ%P;#K37FDFe~_yLRS z|B~D?obC0ndd;9;lXm*zCCk(I7a|V?2!H?xfB*=900@8p2!H?xfB*=9z<)$wjjClD{ga@50|6Wa3;+NC diff --git a/tracker.db b/tracker.db index 4aa765bb7953d8e7dd737d1f7a069c759874f192..7c320152e09100ca041e60c89c7978f5ecdc6114 100644 GIT binary patch delta 510 zcmZp8z})bFd4e=!>_i!7#@LMs^Yvwgc^McOIC+a1_;2yAY zoSIj1Vc~@h7aM@M>B8i7_HF_w3I*61CeN~uf(aU1nE-Y3!32#$3@ogSOsz}}qcV6P zg7ro~L31k;ODhxeC^K$01|~&aQ|1>4FXg3{E0m-bmnbBrq!gtV7sK5L(PwI9Y#yb} z#m2y_C~6w7>s9 delta 65 zcmZp8z})bFd4e>f-9#B@M!Ss(^Yyt|c^QB}fPsO3+Gat4PJZ?RPDP+V*5rq_QQU@> TAx1`4#%5MV7MuUuGj0F?GIJ3r