github.com/bcampbell/scrapeomat@v0.0.0-20220820232205-23e64141c89e/store/sqlstore/sqlstore_test.go (about) 1 package sqlstore 2 3 import ( 4 "fmt" 5 "reflect" 6 "testing" 7 "time" 8 9 "github.com/bcampbell/scrapeomat/store" 10 ) 11 12 // TODO: break all these tests into individual functions. 13 14 func performDBTests(t *testing.T, ss *SQLStore) { 15 16 testArts := []*store.Article{ 17 { 18 CanonicalURL: "http://example.com/foo-bar-wibble", 19 Headline: "Foo Bar Wibble", 20 Content: "<p>Foo, bar and Wibble.</p>", 21 Published: "2019-04-01", 22 Updated: "2019-04-01", 23 Publication: store.Publication{Code: "example"}, 24 Authors: []store.Author{ 25 {Name: "Bob Smith"}, 26 {Name: "Fred Door"}, 27 }, 28 }, 29 { 30 CanonicalURL: "http://example.com/blah-blah", 31 Headline: "Blah Blah", 32 Content: "<p>Blah blah blah. Blah.</p>", 33 Published: "2019-04-02", 34 Updated: "2019-04-02", 35 Publication: store.Publication{Code: "example"}, 36 }, 37 } 38 39 // 40 ids, err := ss.Stash(testArts...) 41 if err != nil { 42 t.Fatalf("stash failed: %s", err) 43 } 44 if len(ids) != len(testArts) { 45 t.Fatalf("wrong article count (got %d, expected %d)", 46 len(ids), len(testArts)) 47 } 48 // the test articles now have IDs 49 for idx, id := range ids { 50 testArts[idx].ID = id 51 } 52 53 checkArticles(t, ss, testArts) 54 55 // Update an article 56 testArts[0].Headline = "A Revised Headline" 57 ids, err = ss.Stash(testArts[0]) 58 if err != nil { 59 t.Fatalf("stash failed: %s", err) 60 } 61 62 // 63 checkArticles(t, ss, testArts) 64 65 // Very basic FetchSummary() check 66 mustDay := func(s string) time.Time { 67 t, err := time.ParseInLocation("2006-01-02", s, time.UTC) 68 if err != nil { 69 panic("bad time: " + s) 70 } 71 return t 72 } 73 expectedCounts := []store.DatePubCount{ 74 {mustDay("2019-04-01"), "example", 1}, 75 {mustDay("2019-04-02"), "example", 1}, 76 } 77 counts, err := ss.FetchSummary(&store.Filter{}, "published") 78 if !reflect.DeepEqual(expectedCounts, counts) { 79 fmt.Printf("BUGGER.\n") 80 t.Fatalf("FetchSummary: expected %v, got %v", expectedCounts, counts) 81 } 82 83 // Check FetchCount runs with a non-null filter 84 cnt, err := ss.FetchCount(&store.Filter{ 85 PubFrom: mustDay("1821-01-01"), 86 PubTo: mustDay("2050-01-01"), 87 }) 88 if err != nil { 89 t.Fatalf("FetchCount fail: %s", err) 90 } 91 if cnt != len(testArts) { 92 t.Fatalf("FetchCount wrong (got %d, expected %d)", 93 cnt, len(testArts)) 94 } 95 } 96 97 func checkArticles(t *testing.T, ss *SQLStore, testArts []*store.Article) { 98 // check FetchCount() 99 cnt, err := ss.FetchCount(&store.Filter{}) 100 if err != nil { 101 t.Fatalf("FetchCount fail: %s", err) 102 } 103 if cnt != len(testArts) { 104 t.Fatalf("FetchCount wrong (got %d, expected %d)", 105 cnt, len(testArts)) 106 } 107 108 // Now read them back 109 lookup := map[string]*store.Article{} 110 for _, art := range testArts { 111 lookup[art.CanonicalURL] = art 112 } 113 114 it := ss.Fetch(&store.Filter{}) 115 fetchCnt := 0 116 for it.Next() { 117 got := it.Article() 118 expect, ok := lookup[got.CanonicalURL] 119 if !ok { 120 t.Fatal("Fetch returned unexpected article") 121 } 122 if got.CanonicalURL != expect.CanonicalURL { 123 t.Fatal("Fetch: mismatch canonical_url") 124 } 125 if !equalStrings(expect.URLs, got.URLs) { 126 t.Fatalf("Fetch: mismatch urls (expect: %v got: %v)", expect.URLs, got.URLs) 127 } 128 if got.Headline != expect.Headline { 129 t.Fatal("Fetch: mismatch headline") 130 } 131 132 //slice might be nil or [] empty... 133 if len(expect.Authors) != 0 || len(got.Authors) != 0 { 134 if !reflect.DeepEqual(expect.Authors, got.Authors) { 135 t.Fatal("Fetch: mismatch authors") 136 } 137 } 138 if got.Content != expect.Content { 139 t.Fatal("Fetch: mismatch content") 140 } 141 if got.Section != expect.Section { 142 t.Fatal("Fetch: mismatch section") 143 } 144 // TODO: check 145 // - Published, Updated fields here (requires parsing) 146 // - keywords 147 fetchCnt++ 148 } 149 if it.Err() != nil { 150 t.Fatalf("Fetch failed: %s", it.Err()) 151 } 152 if fetchCnt != len(testArts) { 153 t.Fatalf("Fetch count wrong (got %d, expected %d)", 154 fetchCnt, len(testArts)) 155 } 156 } 157 158 func equalStrings(a []string, b []string) bool { 159 //slice might be nil or [] empty... 160 if len(a) != len(b) { 161 return false 162 } 163 for i := 0; i < len(a); i++ { 164 if a[i] != b[i] { 165 return false 166 } 167 } 168 return true 169 } 170 171 func ExampleBuildWhere() { 172 173 filt := &store.Filter{ 174 PubFrom: time.Date(2010, 1, 1, 0, 0, 0, 0, time.UTC), 175 PubTo: time.Date(2010, 2, 1, 0, 0, 0, 0, time.UTC), 176 PubCodes: []string{"dailynews", "dailyshoes"}, 177 } 178 s, p := buildWhere(filt) 179 180 fmt.Println(s) 181 fmt.Println(rebind(bindType("sqllite3"), s)) 182 fmt.Println(rebind(bindType("postgres"), s)) 183 fmt.Println(p) 184 // Output: 185 // WHERE a.published>=? AND a.published<? AND p.code IN (?,?) 186 // WHERE a.published>=? AND a.published<? AND p.code IN (?,?) 187 // WHERE a.published>=$1 AND a.published<$2 AND p.code IN ($3,$4) 188 // [2010-01-01 00:00:00 +0000 UTC 2010-02-01 00:00:00 +0000 UTC dailynews dailyshoes] 189 }