git ssb

0+

Piet / ssb-loomio



Tree: ebad2e906b7c5bfaaf2ef70e09eb2ed8b39f698d

Files: ebad2e906b7c5bfaaf2ef70e09eb2ed8b39f698d / test / results / sync / buildResults.test.js

6572 bytesRaw
1const test = require('tape')
2const pull = require('pull-stream')
3const ChooseOne = require('../../../position/async/buildChooseOne')()
4const ChooseOnePoll = require('../../../poll/sync/buildChooseOne')
5const chooseOneResults = require('../../../results/sync/buildResults')
6const {isPosition, isPoll} = require('ssb-poll-schema')
7const {ERROR_POSITION_CHOICE, ERROR_POSITION_LATE} = require('../../../types')
8
9const pietId = '@Mq8D3YC6VdErKQzV3oi2oK5hHSoIwR0hUQr4M46wr/0=.ed25519'
10const mixId = '@Mq8D3YC6VdErKQzV3oi2oK5hHSoIwR0hUQr4M46wr/1=.ed25519'
11const mikeyId = '@Mq8D3YC6VdErKQzV3oi2oK5hHSoIwR0hUQr4M46wr/2=.ed25519'
12const timmyId = '@Mq8D3YC6VdErKQzV3oi2oK5hHSoIwR0hUQr4M46wr/3=.ed25519'
13const tommyId = '@Mq8D3YC6VdErKQzV3oi2oK5hHSoIwR0hUQr4M46wr/4=.ed25519'
14const sallyId = '@Mq8D3YC6VdErKQzV3oi2oK5hHSoIwR0hUQr4M46wr/5=.ed25519'
15
16const poll = '%t+PhrNxxXkw/jMo6mnwUWfFjJapoPWxzsQoe0Np+nYw=.sha256'
17
18const now = new Date().toISOString()
19
20const validPoll = {
21 key: '%t+PhrNxxXkw/jMo6mnwUWfFjJapoPWxzsQoe0Np+nYw=.sha256',
22 value: {
23 content: ChooseOnePoll({
24 choices: [1, 2, 'three'],
25 title: 'how many food',
26 closesAt: now
27 })
28 }
29}
30
31test('ChooseOneResults - ChooseOneResults', function (t) {
32 const positions = [
33 { value: { content: {choice: 0, poll}, author: pietId } },
34 { value: { content: {choice: 0, poll}, author: mixId } },
35 { value: { content: {choice: 0, poll}, author: mikeyId } },
36 { value: { content: {choice: 1, poll}, author: timmyId } },
37 { value: { content: {choice: 1, poll}, author: tommyId } },
38 { value: { content: {choice: 2, poll}, author: sallyId } }
39 ]
40
41 const expected = {
42 results: [
43 {
44 choice: 1,
45 voters: {
46 [pietId]: positions[0],
47 [mixId]: positions[1],
48 [mikeyId]: positions[2]
49 }
50 },
51 {
52 choice: 2,
53 voters: {
54 [timmyId]: positions[3],
55 [tommyId]: positions[4]
56 }
57 },
58 {
59 choice: 'three',
60 voters: {
61 [sallyId]: positions[5]
62 }
63 }
64 ],
65 errors: {}
66 }
67
68 pull(
69 pull.values(positions),
70 pull.asyncMap((fullPosition, cb) => {
71 ChooseOne(fullPosition.value.content, (err, position) => {
72 fullPosition.value.content = position
73 cb(err, fullPosition)
74 })
75 }),
76 pull.collect(postions => {
77 const actual = chooseOneResults({positions, poll: validPoll})
78 t.deepEqual(actual, expected, 'results are correct')
79 t.end()
80 })
81 )
82})
83
84test('ChooseOneResults - a position stated for an invalid choice index is not counted', function (t) {
85 const positions = [
86 { value: { content: {choice: 3, poll}, author: pietId } }
87 ]
88
89 pull(
90 pull.values(positions),
91 pull.asyncMap((fullPosition, cb) => {
92 ChooseOne(fullPosition.value.content, (err, position) => {
93 fullPosition.value.content = position
94 cb(err, fullPosition)
95 })
96 }),
97 pull.collect(postions => {
98 const actual = chooseOneResults({positions, poll: validPoll})
99 t.false(actual.results[3], 'invalid vote is not counted')
100 t.end()
101 })
102 )
103})
104
105test('ChooseOneResults - a position stated for an invalid choice index is included in the errors object', function (t) {
106 const positions = [
107 { value: { content: {choice: 3, poll}, author: pietId } }
108 ]
109
110 pull(
111 pull.values(positions),
112 pull.asyncMap((fullPosition, cb) => {
113 ChooseOne(fullPosition.value.content, (err, position) => {
114 fullPosition.value.content = position
115 cb(err, fullPosition)
116 })
117 }),
118 pull.collect(postions => {
119 const actual = chooseOneResults({positions, poll: validPoll})
120 t.deepEqual(actual.errors[0].type, ERROR_POSITION_CHOICE, 'invalid vote is on error object')
121 t.end()
122 })
123 )
124})
125
126test('ChooseOneResults - A position stated before the closing time of the poll is counted', function (t) {
127 const positions = [
128 { value: { content: {choice: 0, poll}, author: pietId, timestamp: now - 1 } }
129 ]
130
131 pull(
132 pull.values(positions),
133 pull.asyncMap((fullPosition, cb) => {
134 ChooseOne(fullPosition.value.content, (err, position) => {
135 fullPosition.value.content = position
136 cb(err, fullPosition)
137 })
138 }),
139 pull.collect(postions => {
140 const actual = chooseOneResults({positions, poll: validPoll})
141 t.ok(actual.results[0].voters[pietId], 'valid vote is counted')
142 t.end()
143 })
144 )
145})
146
147test('ChooseOneResults - A position stated after the closing time of the poll is not counted', function (t) {
148 const positions = [
149 { value: { content: {choice: 0, poll}, author: pietId, timestamp: now + 1 } }
150 ]
151
152 pull(
153 pull.values(positions),
154 pull.asyncMap((fullPosition, cb) => {
155 ChooseOne(fullPosition.value.content, (err, position) => {
156 fullPosition.value.content = position
157 cb(err, fullPosition)
158 })
159 }),
160 pull.collect(postions => {
161 const actual = chooseOneResults({positions, poll: validPoll})
162 t.deepEqual(actual.results[0].voters, {}, 'invalid vote is not counted')
163 t.end()
164 })
165 )
166})
167
168test('ChooseOneResults - A position stated after the closing time of the poll is included in the error object', function (t) {
169 const positions = [
170 { value: { content: {choice: 0, poll}, author: pietId, timestamp: now + 1 } }
171 ]
172
173 pull(
174 pull.values(positions),
175 pull.asyncMap((fullPosition, cb) => {
176 ChooseOne(fullPosition.value.content, (err, position) => {
177 fullPosition.value.content = position
178 cb(err, fullPosition)
179 })
180 }),
181 pull.collect(postions => {
182 const actual = chooseOneResults({positions, poll: validPoll})
183 t.deepEqual(actual.errors[0].type, ERROR_POSITION_LATE, 'invalid vote is on error object')
184 t.end()
185 })
186 )
187})
188
189test('ChooseOneResults - ChooseOneResults only counts latest vote by an author', function (t) {
190 const positions = [
191 { value: { content: {choice: 2, poll}, author: pietId } },
192 { value: { content: {choice: 0, poll}, author: pietId } }
193 ]
194
195 pull(
196 pull.values(positions),
197 pull.asyncMap((fullPosition, cb) => {
198 ChooseOne(fullPosition.value.content, (err, position) => {
199 fullPosition.value.content = position
200 cb(err, fullPosition)
201 })
202 }),
203 pull.collect(postions => {
204 const actual = chooseOneResults({positions, poll: validPoll})
205 t.false(actual.results[2].voters[pietId], 'old vote is deleted')
206 t.true(actual.results[0].voters[pietId], 'new vote is counted')
207 t.end()
208 })
209 )
210})
211

Built with git-ssb-web