1 | ger_tests = (ESM) ->
|
2 | ns = global.default_namespace
|
3 |
|
4 | describe 'recommending for a thing', ->
|
5 | it 'works never returns null weight', ->
|
6 | init_ger(ESM)
|
7 | .then (ger) ->
|
8 | bb.all([
|
9 | ger.event(ns, 'p1','view','a', expires_at: tomorrow),
|
10 | ger.event(ns, 'p1','view','b', expires_at: tomorrow),
|
11 | ger.event(ns, 'p1','view','c', expires_at: tomorrow),
|
12 | ])
|
13 | .then(-> ger.recommendations_for_thing(ns, 'a', actions: {view: 1}))
|
14 | .then((recs) ->
|
15 |
|
16 | recs = recs.recommendations
|
17 | for r in recs
|
18 | if r.weight != 0
|
19 | (!!r.weight).should.equal true
|
20 | )
|
21 |
|
22 | it 'should not recommend the same thing', ->
|
23 | init_ger(ESM)
|
24 | .then (ger) ->
|
25 | bb.all([
|
26 | ger.event(ns, 'p1','view','a', expires_at: tomorrow),
|
27 | ger.event(ns, 'p1','view','b', expires_at: tomorrow),
|
28 | ])
|
29 | .then(-> ger.recommendations_for_thing(ns, 'a', actions: {view: 2}))
|
30 | .then((recs) ->
|
31 |
|
32 | recs = recs.recommendations
|
33 | recs.length.should.equal 1
|
34 | recs[0].thing.should.equal 'b'
|
35 | )
|
36 |
|
37 | it 'doesnt return expired things', ->
|
38 | init_ger(ESM)
|
39 | .then (ger) ->
|
40 | bb.all([
|
41 | ger.event(ns, 'p1','view','a', expires_at: tomorrow),
|
42 | ger.event(ns, 'p1','view','b', expires_at: tomorrow),
|
43 | ger.event(ns, 'p1','view','c', expires_at: yesterday),
|
44 | ])
|
45 | .then(-> ger.recommendations_for_thing(ns, 'a', actions: {view: 1}))
|
46 | .then((recs) ->
|
47 |
|
48 | recs = recs.recommendations
|
49 | recs.length.should.equal 1
|
50 | recs[0].thing.should.equal 'b'
|
51 | )
|
52 |
|
53 |
|
54 | it 'should not more highly rate bad recommendations', ->
|
55 | init_ger(ESM)
|
56 | .then (ger) ->
|
57 | bb.all([
|
58 | ger.event(ns, 'p1','view','a'),
|
59 | ger.event(ns, 'p2','view','a'),
|
60 | ger.event(ns, 'p3','view','a'),
|
61 |
|
62 | ger.event(ns, 'p1','view','c', expires_at: tomorrow),
|
63 |
|
64 | ger.event(ns, 'p2','view','b', expires_at: tomorrow),
|
65 | ger.event(ns, 'p3','view','b', expires_at: tomorrow),
|
66 |
|
67 | ])
|
68 | .then(-> ger.recommendations_for_thing(ns, 'a', actions: {view: 1}))
|
69 | .then((recs) ->
|
70 |
|
71 | recs = recs.recommendations
|
72 | recs.length.should.equal 2
|
73 | recs[0].thing.should.equal 'b'
|
74 | recs[1].thing.should.equal 'c'
|
75 | recs[0].weight.should.be.greaterThan(recs[1].weight)
|
76 | )
|
77 |
|
78 |
|
79 | it 'should not just recommend the popular things', ->
|
80 | init_ger(ESM)
|
81 | .then (ger) ->
|
82 | bb.all([
|
83 | ger.event(ns, 'p1','view','a', expires_at: tomorrow),
|
84 | ger.event(ns, 'p1','view','b', expires_at: tomorrow),
|
85 | ger.event(ns, 'p2','view','a', expires_at: tomorrow),
|
86 | ger.event(ns, 'p2','view','b', expires_at: tomorrow),
|
87 | ger.event(ns, 'p3','view','a', expires_at: tomorrow),
|
88 | ger.event(ns, 'p3','view','c', expires_at: tomorrow),
|
89 | ger.event(ns, 'p4','view','c', expires_at: tomorrow),
|
90 | ger.event(ns, 'p5','view','c', expires_at: tomorrow),
|
91 | ger.event(ns, 'p6','view','c', expires_at: tomorrow),
|
92 | ])
|
93 | .then(-> ger.recommendations_for_thing(ns, 'a', actions: {view: 1}))
|
94 | .then((recs) ->
|
95 |
|
96 | recs = recs.recommendations
|
97 | recs.length.should.equal 2
|
98 | recs[0].thing.should.equal 'b'
|
99 | recs[1].thing.should.equal 'c'
|
100 | recs[0].weight.should.be.greaterThan(recs[1].weight)
|
101 | )
|
102 |
|
103 |
|
104 | describe 'thing exploits', ->
|
105 | it 'should not be altered by a single person doing the same thing a lot', ->
|
106 | init_ger(ESM)
|
107 | .then (ger) ->
|
108 | events = []
|
109 | for x in [1..100]
|
110 | events.push ger.event(ns, "bad_person",'view','t2', expires_at: tomorrow)
|
111 | events.push ger.event(ns, "bad_person",'buy','t2', expires_at: tomorrow)
|
112 |
|
113 | bb.all(events)
|
114 | .then( ->
|
115 | bb.all([
|
116 | ger.event(ns, 'bad_person', 'view', 't1')
|
117 | ger.event(ns, 'real_person', 'view', 't1')
|
118 |
|
119 | ger.event(ns, 'real_person', 'view', 't3', expires_at: tomorrow)
|
120 | ger.event(ns, 'real_person', 'buy', 't3', expires_at: tomorrow)
|
121 |
|
122 | ])
|
123 | )
|
124 | .then( ->
|
125 | ger.recommendations_for_thing(ns, 't1', actions: {buy:1, view:1})
|
126 | )
|
127 | .then((recs) ->
|
128 | item_weights = recs.recommendations
|
129 | temp = {}
|
130 | (temp[tw.thing] = tw.weight for tw in item_weights)
|
131 | temp['t2'].should.equal temp['t3']
|
132 | )
|
133 |
|
134 |
|
135 |
|
136 | it 'should not return any recommendations if none are there', ->
|
137 | init_ger(ESM)
|
138 | .then (ger) ->
|
139 | bb.all([
|
140 | ger.event(ns, 'p1','view','a')
|
141 | ])
|
142 | .then(-> ger.recommendations_for_thing(ns, 'a', actions: {view: 1}))
|
143 | .then((recs) ->
|
144 | recs.recommendations.length.should.equal 0
|
145 |
|
146 | throw "BAD Confidence #{recommendations_object.confidence}" if not _.isFinite(recs.confidence)
|
147 | )
|
148 |
|
149 | describe 'time_until_expiry', ->
|
150 | it 'should not return recommendations that will expire within time_until_expiry seconds', ->
|
151 | one_hour = 60*60
|
152 | one_day = 24*one_hour
|
153 | a1day = moment().add(1, 'days').format()
|
154 | a2days = moment().add(2, 'days').format()
|
155 | a3days = moment().add(3, 'days').format()
|
156 |
|
157 | init_ger(ESM)
|
158 | .then (ger) ->
|
159 | bb.all([
|
160 | ger.event(ns, 'p1','view','a'),
|
161 | ger.event(ns, 'p1','buy','x', expires_at: a1day),
|
162 | ger.event(ns, 'p1','buy','y', expires_at: a2days),
|
163 | ger.event(ns, 'p1','buy','z', expires_at: a3days)
|
164 | ])
|
165 | .then(-> ger.recommendations_for_thing(ns, 'a', time_until_expiry: (one_day + one_hour), actions: {view: 1, buy: 1}))
|
166 | .then((recs) ->
|
167 | recs = recs.recommendations
|
168 | recs.length.should.equal 2
|
169 | sorted_recs = [recs[0].thing, recs[1].thing].sort()
|
170 | sorted_recs[0].should.equal 'y'
|
171 | sorted_recs[1].should.equal 'z'
|
172 | )
|
173 |
|
174 | describe "confidence", ->
|
175 | it 'should return a confidence ', ->
|
176 | init_ger(ESM)
|
177 | .then (ger) ->
|
178 | bb.all([
|
179 | ger.event(ns, 'p1','a','t1'),
|
180 | ger.event(ns, 'p2','a','t2', expires_at: tomorrow),
|
181 | ])
|
182 | .then(-> ger.recommendations_for_thing(ns, 't1', actions: {a: 1}))
|
183 | .then((recs) ->
|
184 | recs.confidence.should.exist
|
185 | _.isFinite(recs.confidence).should.equal true
|
186 | )
|
187 |
|
188 |
|
189 | describe "weights", ->
|
190 | it "weights should determine the order of the recommendations", ->
|
191 | init_ger(ESM)
|
192 | .then (ger) ->
|
193 | bb.all([
|
194 | ger.event(ns, 'p1','view','a'),
|
195 | ger.event(ns, 'p2','buy','a'),
|
196 |
|
197 | ger.event(ns, 'p1','view','b', expires_at: tomorrow)
|
198 |
|
199 | ger.event(ns, 'p2','view','c', expires_at: tomorrow)
|
200 | ])
|
201 | .then(-> ger.recommendations_for_thing(ns, 'a', actions: {view: 1, buy: 1}))
|
202 | .then((recs) ->
|
203 | item_weights = recs.recommendations
|
204 | item_weights.length.should.equal 2
|
205 | item_weights[0].weight.should.equal item_weights[1].weight
|
206 |
|
207 | ger.recommendations_for_thing(ns, 'a', actions: {view: 1, buy: 2})
|
208 | )
|
209 | .then((recs) ->
|
210 | item_weights = recs.recommendations
|
211 | item_weights[0].weight.should.be.greaterThan item_weights[1].weight
|
212 | item_weights[0].thing.should.equal 'c'
|
213 | item_weights[1].thing.should.equal 'b'
|
214 | )
|
215 |
|
216 | module.exports = ger_tests; |
\ | No newline at end of file |