ducky/devices

Paddy 2015-11-15 Parent:408abf6e48d3 Child:f5a9d5f8f28d

8:34130c700842 Go to Latest

ducky/devices/storer_test.go

Implement ListDevicesByOwner. Write a unit test for listing Devices by their Owner property, as per our Storer interface. Basically, if we insert Devices into the datastore, we need to be able to retrieve the Devices that someone owns. Simple enough. This meant that I needed to implement the Memstore version, past the barebones stub, so the tests would continue to pass.

History
paddy@2 1 package devices
paddy@2 2
paddy@2 3 import (
paddy@2 4 "testing"
paddy@2 5 "time"
paddy@2 6
paddy@2 7 "code.secondbit.org/uuid.hg"
paddy@2 8 "golang.org/x/net/context"
paddy@2 9 )
paddy@2 10
paddy@2 11 var storers []Storer
paddy@2 12
paddy@2 13 func compareDevices(device1, device2 Device) (ok bool, field string, expected, result interface{}) {
paddy@2 14 if !device1.ID.Equal(device2.ID) {
paddy@2 15 return false, "ID", device1.ID, device2.ID
paddy@2 16 }
paddy@2 17 if device1.Name != device2.Name {
paddy@2 18 return false, "Name", device1.Name, device2.Name
paddy@2 19 }
paddy@2 20 if !device1.Owner.Equal(device2.Owner) {
paddy@2 21 return false, "Owner", device1.Owner, device2.Owner
paddy@2 22 }
paddy@2 23 if device1.Type != device2.Type {
paddy@2 24 return false, "Type", device1.Type, device2.Type
paddy@2 25 }
paddy@2 26 if !device1.Created.Equal(device2.Created) {
paddy@2 27 return false, "Created", device1.Created, device2.Created
paddy@2 28 }
paddy@2 29 if !device1.LastSeen.Equal(device2.LastSeen) {
paddy@2 30 return false, "LastSeen", device1.LastSeen, device2.LastSeen
paddy@2 31 }
paddy@2 32 if device1.PushToken != device2.PushToken {
paddy@2 33 return false, "PushToken", device1.PushToken, device2.PushToken
paddy@2 34 }
paddy@2 35 return true, "", nil, nil
paddy@2 36 }
paddy@2 37
paddy@5 38 func TestCreateAndGetDevices(t *testing.T) {
paddy@2 39 for _, storer := range storers {
paddy@2 40 storer, err := storer.Factory(context.TODO())
paddy@2 41 if err != nil {
paddy@2 42 t.Fatalf("Fatal error creating %T: %+v\n", storer, err)
paddy@2 43 }
paddy@2 44
paddy@2 45 devices := []Device{
paddy@2 46 {ID: uuid.NewID(), Name: "Test 1", Owner: uuid.NewID(), Type: TypeAndroidPhone, Created: time.Now(), LastSeen: time.Now(), PushToken: "test token"},
paddy@2 47 {ID: uuid.NewID(), Name: "Test 2", Owner: uuid.NewID(), Type: TypeAndroidTablet, Created: time.Now(), LastSeen: time.Now(), PushToken: "test token"},
paddy@2 48 {ID: uuid.NewID(), Name: "Test 3", Owner: uuid.NewID(), Type: TypeChromeExtension, Created: time.Now(), LastSeen: time.Now(), PushToken: "test token"},
paddy@2 49 }
paddy@3 50
paddy@3 51 err = storer.CreateDevices(devices, context.TODO())
paddy@3 52 if err != nil {
paddy@5 53 t.Errorf("Error creating devices in %T: %+v\n", storer, err)
paddy@3 54 }
paddy@3 55
paddy@2 56 ids := make([]uuid.ID, 0, len(devices))
paddy@2 57 for _, device := range devices {
paddy@2 58 ids = append(ids, device.ID)
paddy@2 59 }
paddy@2 60
paddy@2 61 results, err := storer.GetDevices(ids, context.TODO())
paddy@2 62 if err != nil {
paddy@2 63 t.Errorf("Unexpected error retrieving devices from %T: %+v\n", storer, err)
paddy@2 64 }
paddy@2 65 for _, device := range devices {
paddy@2 66 d, returned := results[device.ID.String()]
paddy@2 67 if !returned {
paddy@2 68 t.Errorf("Expected device %s to be in results from %T, but wasn't present\n", device.Name, storer)
paddy@2 69 }
paddy@2 70 ok, field, expected, result := compareDevices(device, d)
paddy@2 71 if !ok {
paddy@2 72 t.Errorf("Expected %s of %s to be %v, got %v from %T\n", field, device.Name, expected, result, storer)
paddy@2 73 }
paddy@2 74 }
paddy@2 75 err = storer.Destroy(context.TODO())
paddy@2 76 if err != nil {
paddy@2 77 t.Errorf("Error cleaning up after %T: %+v\n", storer, err)
paddy@2 78 }
paddy@2 79 }
paddy@2 80 }
paddy@5 81
paddy@5 82 func TestGetDevicesNoErrorForMissing(t *testing.T) {
paddy@5 83 for _, storer := range storers {
paddy@5 84 storer, err := storer.Factory(context.TODO())
paddy@5 85 if err != nil {
paddy@5 86 t.Fatalf("Fatal error creatng %T: %+v\n", storer, err)
paddy@5 87 }
paddy@5 88
paddy@5 89 results, err := storer.GetDevices([]uuid.ID{uuid.NewID()}, context.TODO())
paddy@5 90 if err != nil {
paddy@5 91 t.Errorf("Unexpected error retrieving devices from %T: %+v\n", storer, err)
paddy@5 92 }
paddy@5 93 if len(results) != 0 {
paddy@5 94 t.Errorf("Expected results to be empty, got %+v from %T instead\n", results, storer)
paddy@5 95 }
paddy@5 96 err = storer.Destroy(context.TODO())
paddy@5 97 if err != nil {
paddy@5 98 t.Errorf("Error cleaning up after %T: %+v\n", storer, err)
paddy@5 99 }
paddy@5 100 }
paddy@5 101 }
paddy@5 102
paddy@5 103 func TestCreateDevicesDuplicates(t *testing.T) {
paddy@5 104 for _, storer := range storers {
paddy@5 105 storer, err := storer.Factory(context.TODO())
paddy@5 106 if err != nil {
paddy@5 107 t.Fatalf("Fatal error creating %T: %+v\n", storer, err)
paddy@5 108 }
paddy@5 109
paddy@5 110 devices := []Device{
paddy@5 111 {ID: uuid.NewID(), Name: "Test 1", Owner: uuid.NewID(), Type: TypeAndroidPhone, Created: time.Now(), LastSeen: time.Now(), PushToken: "test token"},
paddy@5 112 {ID: uuid.NewID(), Name: "Test 2", Owner: uuid.NewID(), Type: TypeAndroidTablet, Created: time.Now(), LastSeen: time.Now(), PushToken: "test token"},
paddy@5 113 {ID: uuid.NewID(), Name: "Test 3", Owner: uuid.NewID(), Type: TypeChromeExtension, Created: time.Now(), LastSeen: time.Now(), PushToken: "test token"},
paddy@5 114 }
paddy@5 115
paddy@5 116 err = storer.CreateDevices(devices, context.TODO())
paddy@5 117 if err != nil {
paddy@5 118 t.Errorf("Unexpected error creating devices in %T: %+v\n", storer, err)
paddy@5 119 }
paddy@5 120
paddy@5 121 newDevices := []Device{
paddy@5 122 {ID: uuid.NewID(), Name: "Test 4", Owner: uuid.NewID(), Type: TypeAndroidPhone, Created: time.Now(), LastSeen: time.Now(), PushToken: "test token"},
paddy@5 123 {ID: uuid.NewID(), Name: "Test 5", Owner: uuid.NewID(), Type: TypeAndroidPhone, Created: time.Now(), LastSeen: time.Now(), PushToken: "test token"},
paddy@5 124 }
paddy@5 125
paddy@5 126 err = storer.CreateDevices([]Device{newDevices[0], devices[1], newDevices[1]}, context.TODO())
paddy@5 127 daeErr, ok := err.(ErrDeviceAlreadyExists)
paddy@5 128 if !ok {
paddy@5 129 t.Errorf("Expected ErrDeviceAlreadyExists creating duplicate device in %T, got %+v\n", storer, err)
paddy@5 130 }
paddy@5 131 if !uuid.ID(daeErr).Equal(devices[1].ID) {
paddy@5 132 t.Errorf("Expected ErrDeviceAlreadyExists to be %+v, got %+v from %T\n", devices[1].ID, daeErr, storer)
paddy@5 133 }
paddy@5 134
paddy@5 135 // inserts should be a transaction; they either all make it, or none do
paddy@5 136 results, err := storer.GetDevices([]uuid.ID{newDevices[0].ID, newDevices[1].ID}, context.TODO())
paddy@5 137 if err != nil {
paddy@5 138 t.Errorf("Error retrieving devices from %T: %+v\n", storer, err)
paddy@5 139 }
paddy@5 140 if len(results) != 0 {
paddy@5 141 t.Errorf("Expected new inserts to not be in results, got %+v from %T\n", results, storer)
paddy@5 142 }
paddy@5 143
paddy@5 144 err = storer.Destroy(context.TODO())
paddy@5 145 if err != nil {
paddy@5 146 t.Errorf("Error cleaning up after %T: %+v\n", storer, err)
paddy@5 147 }
paddy@5 148 }
paddy@5 149 }
paddy@8 150
paddy@8 151 func TestCreateAndListDevicesByOwner(t *testing.T) {
paddy@8 152 for _, storer := range storers {
paddy@8 153 storer, err := storer.Factory(context.TODO())
paddy@8 154 if err != nil {
paddy@8 155 t.Fatalf("Fatal error creating %T: %+v\n", storer, err)
paddy@8 156 }
paddy@8 157
paddy@8 158 owner1, owner2 := uuid.NewID(), uuid.NewID()
paddy@8 159 devices := []Device{
paddy@8 160 {ID: uuid.NewID(), Name: "Test 1", Owner: owner1, Type: TypeAndroidPhone, Created: time.Now(), LastSeen: time.Now(), PushToken: "test token"},
paddy@8 161 {ID: uuid.NewID(), Name: "Test 2", Owner: owner2, Type: TypeAndroidTablet, Created: time.Now(), LastSeen: time.Now(), PushToken: "test token"},
paddy@8 162 {ID: uuid.NewID(), Name: "Test 3", Owner: owner1, Type: TypeChromeExtension, Created: time.Now().Add(time.Minute), LastSeen: time.Now(), PushToken: "test token"},
paddy@8 163 }
paddy@8 164
paddy@8 165 err = storer.CreateDevices(devices, context.TODO())
paddy@8 166 if err != nil {
paddy@8 167 t.Errorf("Error creating devices in %T: %+v\n", storer, err)
paddy@8 168 }
paddy@8 169
paddy@8 170 results, err := storer.ListDevicesByOwner(owner1, context.TODO())
paddy@8 171 if err != nil {
paddy@8 172 t.Errorf("Error listing devices for owner1 from %T: %+v\n", storer, err)
paddy@8 173 }
paddy@8 174 if len(results) != 2 {
paddy@8 175 t.Errorf("Expected %d results for owner1, got %d from %T\n", 2, len(results), storer)
paddy@8 176 }
paddy@8 177 resultMap := ToMap(results)
paddy@8 178 d, ok := resultMap[devices[0].ID.String()]
paddy@8 179 if !ok {
paddy@8 180 t.Errorf("Expected to get %s in results, got %+v from %T\n", devices[0].Name, results, storer)
paddy@8 181 }
paddy@8 182 ok, field, expected, result := compareDevices(devices[0], d)
paddy@8 183 if !ok {
paddy@8 184 t.Errorf("Expected %s of %s to be %v, got %v from %T\n", field, devices[0].Name, expected, result, storer)
paddy@8 185 }
paddy@8 186 d, ok = resultMap[devices[2].ID.String()]
paddy@8 187 if !ok {
paddy@8 188 t.Errorf("Expected to get %s in results, got %+v from %T\n", devices[2].Name, results, storer)
paddy@8 189 }
paddy@8 190 ok, field, expected, result = compareDevices(devices[2], d)
paddy@8 191 if !ok {
paddy@8 192 t.Errorf("Expected %s of %s to be %v, got %v from %T\n", field, devices[2].Name, expected, result, storer)
paddy@8 193 }
paddy@8 194
paddy@8 195 results, err = storer.ListDevicesByOwner(owner2, context.TODO())
paddy@8 196 if err != nil {
paddy@8 197 t.Errorf("Error listing devices for owner2 from %T: %+v\n", storer, err)
paddy@8 198 }
paddy@8 199 if len(results) != 1 {
paddy@8 200 t.Errorf("Expected %d results for owner2, got %d from %T\n", 1, len(results), storer)
paddy@8 201 }
paddy@8 202 ok, field, expected, result = compareDevices(devices[1], results[0])
paddy@8 203 if !ok {
paddy@8 204 t.Errorf("Expected %s of %s to be %v, got %v from %T\n", field, devices[1].Name, expected, result, storer)
paddy@8 205 }
paddy@8 206
paddy@8 207 err = storer.Destroy(context.TODO())
paddy@8 208 if err != nil {
paddy@8 209 t.Errorf("Error cleaning up after %T: %+v\n", storer, err)
paddy@8 210 }
paddy@8 211 }
paddy@8 212 }