import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Router } from '@angular/router'; import { ConfirmationService } from 'primeng/api'; import { environment } from '../../../../environments/environment'; import { ToastService } from '../../../core/services/toast.service'; import { PollConfig } from '../config/PollConfig'; import { PollUtilities } from '../config/PollUtilities'; import { mockPoll3 } from '../mocks/mock-poll3'; import { mockSuccessVote } from '../mocks/mock-success-vote'; import { mockMyPolls } from '../mocks/mockmypolls'; /** * le service transverse à chaque page qui permet de syncroniser la configuration de sondage souhaitée */ @Injectable({ providedIn: 'root', }) export class ConfigService extends PollConfig { loading = false; apiBaseHref: any = environment.api.baseHref; constructor( private http: HttpClient, private toastService: ToastService, private router: Router, private utils: PollUtilities, private confirmationService: ConfirmationService ) { super(); this.fillValuesOnDevEnv(); } set(key, val) { // TODO: à supprimer this[key] = val; } // fill in mock values if we are not in production environment fillValuesOnDevEnv() { if (!environment.production) { // TODO: on poussera les données mockées directement dans le service avec un .next(mockPoll3) this.currentPoll = mockPoll3; this.myPolls = mockMyPolls; } } /** * add some days to a date, to compute intervals * @param days * @param date */ addDaysToDate(days: number, date: Date) { // TODO: -> DateUtilsService date = new Date(date.valueOf()); date.setDate(date.getDate() + days); return date; } /** ================================== * * poll public calls to get non authenticated info * * ==================================/ /** * convert current poll config to a payload to send to the backend API */ getPollConfig() { // TODO: la logique m'échappe. Un service ne devrait pas étendre une entité. const jsonConfig = { owner: { email: this.myEmail, pseudo: this.myName, }, title: this.title, description: this.description, pollType: this.pollType, visibility: this.visibility, voteChoices: this.voteChoices, allowSeveralHours: this.allowSeveralHours, expirationDate: this.expirationDate, passwordAccess: this.passwordAccess, password: this.password, customUrl: this.customUrl, canModifyAnswers: this.canModifyAnswers, whoModifiesAnswers: this.whoModifiesAnswers, dateList: this.dateList, timeList: this.timeList, answers: this.answers, expiracyDateDefaultInDays: this.expiracyDateDefaultInDays, deletionDateAfterLastModification: this.deletionDateAfterLastModification, }; return jsonConfig; } checkIfSlugIsUniqueInDatabase(slug = '') { // TODO: http requests moved to apiService this.customUrlIsUnique = null; if (!slug) { slug = this.utils.makeSlug(this); } this.loading = true; // TODO this.todo('check slug is unique'); this.http .get(`${this.apiBaseHref}/check-slug-is-uniq/${slug}`, this.utils.makeHeaders({ slug: this.customUrl })) .subscribe( (res: any) => { this.customUrlIsUnique = res.poll.isUnique; this.loading = false; }, (e) => this.handleError(e) ); } /** * search in localstorage, fallback asking the backend to send an email to the owner if it exists * @param email */ findPollsByEmail(email: string) { // TODO: http requests moved to apiService this.findLocalStorageData(); // If no key is found in the localstorage, ask the backend to send an email to the user this.myEmail = email; this.todo('send email for real : TODO'); this.loading = true; this.http.get(`${this.apiBaseHref}/send-polls-to-user/${this.myEmail}`, this.utils.makeHeaders()).subscribe( (res) => { // message: 'Trouvé! Allez voir votre boite email', this.myPolls = res; this.loading = false; this.toastService.display( `Succès : vos infos de sondages vous ont été transmises. Allez voir votre boite email ${this.myEmail}` ); }, (e) => { this.handleError(e); } ); } /** * display error message depending on the response of the backend * @param err */ handleError(err: any) { // TODO: inutile, l'utilisateur ne veut pas savoir ce que le backend répond console.error('err', err); this.loading = false; this.toastService.display(`Erreur lors de l'appel : ${err.message}`); } findLocalStorageData() { // TODO check if the person has a key to retrieve her polls console.log('localStorage', localStorage); if (localStorage) { console.log('localStorage', localStorage); } } /** * get one poll by its slug choice_label * @param url */ getPollByURL(url: string) { // TODO: http requests moved to apiService this.todo(); return this.http.get(`${this.apiBaseHref}/poll/slug/${url}`, this.utils.makeHeaders()); } /** * GET * api/v1/poll/{id} * @param id */ getPollById(id: string, password?: string) { // TODO: http requests moved to apiService return this.http.get(`${this.apiBaseHref}/poll/${id}`, this.utils.makeHeaders({ body: password })); } fetchPollFromRoute(event) { // console.log('time to fetch poll', event); } /** * GET * api/v1/my-polls * @param ownerEmail */ getMyPolls(ownerEmail: string) { // TODO: http requests moved to apiService this.http.get(`${this.apiBaseHref}/my-polls`, this.utils.makeHeaders({ ownerEmail })).subscribe( (res: any) => { // this.myPolls = res.poll; }, (e) => { this.handleError(e); } ); } /** * launch creation call to the api */ createPoll() { // TODO: to be dispatched between pollService & AdministrationModule this.loading = true; this.createPollFromConfig(this.getPollConfig()); } updateCurrentPollFromResponse(res: any) { // TODO: handled by ApiService & PollService console.log('update res', res); this.currentPoll = res; this.pollId = res.poll.id; this.owner_modifier_token = res.owner_modifier_token; this.urlPublic = this.apiBaseHref + '/vote/poll/id/' + res.poll.id; this.urlSlugPublic = this.apiBaseHref + '/vote/poll/slug/' + res.poll.id; if (res.poll.customUrl) { this.urlSlugPublic = this.apiBaseHref + '/vote/poll/id/' + res.poll.customUrl; } if (res.vote_stack) { this.loadVoteStack(res.vote_stack); } this.adminKey = res.admin_key; this.urlAdmin = this.apiBaseHref + '/admin/' + res.admin_key; } resetCurrentChoicesAnswers() { // TODO: to be handled directly in component this.currentPoll.choices.map((choice) => { choice.answer = null; }); } /** * update current answers with a previous vote * @param voteStack */ loadVoteStack(voteStack: any) { // TODO: to be handled in component (ParticipationModule) // load the pseudo and email this.myName = voteStack.pseudo; this.myEmail = voteStack.email; this.voteStackId = voteStack.id; this.myVoteStack = voteStack; const keys = Object.keys(voteStack.votes); console.log('voteStack', voteStack); this.resetCurrentChoicesAnswers(); keys.forEach((id: any) => { const voteItem = voteStack.votes[id]; /** * the display of the poll uses the choices data, so we update the choices answers of the current poll to reflect the vote stack we have taken */ if (voteItem.choice_id && voteItem.value) { const foundChoiceToModify = this.currentPoll.choices.find((choicesItem) => { return voteItem.choice_id == choicesItem.id; }); console.log('foundChoiceToModify', foundChoiceToModify); if (foundChoiceToModify) { foundChoiceToModify.answer = voteItem.value; } } }); } /** * POST * /api/v1/poll/{id}/poll * @param config */ createPollFromConfig(config: any) { // TODO: http requests moved to apiService this.loading = true; console.log('config', config); return this.http.post(`${this.apiBaseHref}/poll`, config, this.utils.makeHeaders()).subscribe( (res: any) => { // redirect to the page to administrate the new poll this.toastService.display('Sondage Créé'); this.updateCurrentPollFromResponse(res); this.loading = false; if (!this.myPolls) { this.myPolls = []; } this.myPolls.push(res); this.router.navigate(['step/end']); // TODO save new poll to localstorage // reset all fields in current config this.resetConfig(); }, (e) => { this.handleError(e); } ); } /** * conversion to send to back * @param choiceList */ convertChoicesAnsweredToSend(choiceList) { // TODO: move logic to a component (ParticipationModule) choiceList = choiceList.filter((c) => (c.answer ? c : null)); // remove choices where we did not answer const converted = choiceList.map((elem) => { if (elem.answer) { return { choice_id: elem.id, value: elem.answer, }; } }); console.log('converted', converted); return converted; } /** * POST * /api/v1/poll/{id}/vote * @param voteStack */ addVote(voteStack?: any) { // TODO: move logic to a component (ParticipationModule) // TODO: http request moved to ApiService if (!voteStack) { voteStack = { pseudo: this.myName, email: this.myEmail, votes: this.convertChoicesAnsweredToSend(this.currentPoll.choices), }; } this.myVoteStack = voteStack; if (!environment.production) { this.handleVoteAdded(mockSuccessVote); return; } this.http.post(`${this.apiBaseHref}/poll/${this.pollId}/vote`, voteStack, this.utils.makeHeaders()).subscribe( (res: any) => { this.handleVoteAdded(res); }, (e) => { this.handleError(e); } ); } handleVoteAdded(res) { if (this.isAdmin) { // TODO : REFACTO, displayConfirmVoteModalAdmin exists only in voting-summary.component // this.displayConfirmVoteModalAdmin = true; } // save modifier token this.myVoteStack.modifier_token = res.modifier_token; this.myVoteStack.id = res.vote_stack.id; this.updateCurrentPollFromResponse(res); } /** * UPDATE * /api/v1/poll/{id}/vote * @param voteStack */ updateVote(voteStack?: any) { if (!this.myVoteStack) { return; } else { voteStack = this.myVoteStack; } this.http .patch( `${this.apiBaseHref}/vote-stack/${voteStack.id}/token/${this.owner_modifier_token}`, voteStack, this.utils.makeHeaders() ) .subscribe( (res: any) => { this.toastService.display('Vote mis à jour'); this.updateCurrentPollFromResponse(res); }, (e) => { this.handleError(e); } ); } /** * POST * /api/v1/poll/{id}/comment * @param comment */ addComment(comment?: any) { if (!comment && this.myComment) { comment = { name: this.myName, pseudo: this.myName, email: this.myEmail, date: new Date(), text: this.myComment, }; } console.log('comment', comment); this.http.post(`${this.apiBaseHref}/poll/${this.pollId}/comment`, comment, this.utils.makeHeaders()).subscribe( (res: any) => { this.toastService.display(`Commentaire créé: ${comment.text}`); // empty comment after success this.myComment = ''; comment.date = { date: comment.date, }; this.currentPoll.comments.push(comment); }, (e) => { this.handleError(e); } ); } /** * administrator calls */ deleteComments() { // prompt for confirmation this.confirmationService.confirm({ message: 'Are you sure that you want to completely delete the comments of this poll (' + this.title + ') permanentely?', accept: () => { this.http .delete(`${this.apiBaseHref}/poll/${this.pollId}/comments`, this.utils.makeHeaders()) .subscribe( (res: any) => { this.toastService.display(`Les commentaires du sondage ${this.title} ont été supprimés`); }, (e) => { this.handleError(e); } ); }, }); } deleteVotes() { // prompt for confirmation this.confirmationService.confirm({ message: 'Are you sure that you want to completely delete the votes of this poll (' + this.title + ') permanentely?', accept: () => { this.http.delete(`${this.apiBaseHref}/poll/${this.pollId}/votes`, this.utils.makeHeaders()).subscribe( (res: any) => { this.toastService.display(`Les participations aux sondage ${this.title} ont été supprimées.`); }, (e) => { this.handleError(e); } ); }, }); } deletePoll() { if (!this.pollId) { this.toastService.display(`this poll is not administrable, it has no ID`); return; } const self = this; // prompt for confirmation this.confirmationService.confirm({ message: 'Are you sure that you want to completely delete this poll (' + self.title + ') and all is data permanentely?', accept: () => { this.http.delete(`${this.apiBaseHref}/poll/${this.pollId}`, this.utils.makeHeaders()).subscribe( (res: any) => { this.toastService.display(`Le sondage ${this.title} a été supprimé.`); this.router.navigate(['home']); }, (e) => { this.handleError(e); } ); }, }); } /** * UPDATE * /api/v1/poll/{id}/vote * @param voteStack * TODO */ updatePoll(voteStack: any) { this.http.put(`${this.apiBaseHref}/poll/${this.pollId}`, voteStack, this.utils.makeHeaders()).subscribe( (res: any) => { this.toastService.display(`Le sondage a été mis à jour.`); this.updateCurrentPollFromResponse(res); }, (e) => { this.handleError(e); } ); } /** * export all the poll data available to the public as a CSV single file */ exportCSV() { let rows = []; const now = new Date(); const headers = [ ['export de sondage Framadate ', this.customUrl], ['le', now.toISOString()], [this.currentPoll.pollId, this.currentPoll.title, this.customUrl, this.creationDate], ['pseudo'], ]; const listOfChoices = ['choices : ']; this.currentPoll.choices.map((choice) => { listOfChoices.push(choice.text); }); listOfChoices.push('pseudo'); this.currentPoll.stacks.map((voteStack) => { const voteStackInArray = [voteStack.pseudo]; const keysVotes = Object.keys(voteStack.votes); keysVotes.map((id) => { voteStackInArray.push(voteStack.votes[id].value ? voteStack.votes[id].value : ''); }); rows.push(voteStackInArray); }); const headersComments = [['comments'], ['pseudo', 'text', 'creation_date']]; const comments = []; this.currentPoll.comments.map((item) => { comments.push([item.pseudo, item.text, item.date.date, '\n']); }); headers.push(listOfChoices); rows = [headers, listOfChoices, rows, headersComments, comments]; const convertedCsv = rows .map((elem) => { console.log('elem', elem); return elem .map((item) => { console.log('item', item); if (typeof item === typeof Array) { return item.join('\n'); } return item; }) .join('\n'); }) .join('\n'); console.log('rows', rows); console.log('convertedCsv', convertedCsv); const csvContent = 'data:text/csv;charset=utf-8,' + convertedCsv; console.log('csvContent', csvContent); const encodedUri = encodeURI(csvContent); const link = document.createElement('a'); link.setAttribute('href', encodedUri); const exportFileName = (this.urlPublic ? this.urlPublic : this.utils.makeSlug(this)) + '_export_' + new Date() + '.csv'; link.setAttribute('download', exportFileName); document.body.appendChild(link); // Required for FF link.click(); // This will download the data file named "my_data.csv". } exportJson() { this.download( 'export_poll_' + this.pollSlug + '.json', JSON.stringify({ export_date: new Date(), creation_date: this.creationDate, title: this.title, description: this.description, pollType: this.pollType, urlPublic: this.urlPublic, currentPoll: this.currentPoll, votes: this.voteChoices, }) ); } download(filename, text) { const element = document.createElement('a'); element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text)); element.setAttribute('download', filename); element.style.display = 'none'; document.body.appendChild(element); element.click(); document.body.removeChild(element); } print() { alert('TODO'); } todo(message = '') { this.toastService.display( `INFO : ${message}. Cette fonctionnalité n'est pas encore disponible. Venez en discuter sur framateam.org / Ux et design libre / Framasoft` ); } execStuff() { const mockResponse = { message: 'you created a vote stack from an existing owner : tktest@tktest.com', poll: { id: 3, title: 'dessin animé préféré', customUrl: null, description: 'choisissez votre animé préféré', creationDate: { date: '2020-01-22 14:28:19.000000', timezone_type: 3, timezone: 'Europe/Paris', }, expiracyDate: { date: '2020-01-22 14:28:19.000000', timezone_type: 3, timezone: 'Europe/Paris', }, owner: { __initializer__: null, __cloner__: null, __isInitialized__: true, pseudo: 'tk_TEST', email: 'tktest@tktest.com', }, kind: 'text', allowedAnswers: ['yes'], modificationPolicy: 'self', mailOnComment: null, mailOnVote: null, hideResults: null, showResultEvenIfPasswords: null, votes: {}, stacksOfVotes: {}, choices: {}, comments: {}, defaultExpiracyDaysFromNow: 60, }, vote_stack: { id: 43, modifier_token: 'b88Qnb1A515Sfedee8b74d726A32444m87cn9Zc0f9t6Ued516f76235V93tBKcJVJearh061S8I0o5l24wbIaMe2v4wg76dhEBBi9m-28Qa601b664L', pseudo: 'tk_TEST', creation_date: { date: '2020-04-02 17:55:45.201475', timezone_type: 3, timezone: 'Europe/Paris', }, votes: { 5: { id: 93, value: 'yes', choice_id: 5, text: 'Vic le viking', stack_id: 43, }, 6: { id: 94, value: 'yes', choice_id: 6, text: 'Boumbo petite automobile', stack_id: 43, }, 7: { id: 95, value: 'yes', choice_id: 7, text: "Les mystérieuses cités d'or", stack_id: 43, }, 8: { id: 96, value: 'yes', choice_id: 8, text: 'Les mondes engloutis', stack_id: 43, }, 9: { id: 97, value: 'yes', choice_id: 9, text: 'Foot 2 rue', stack_id: 43, }, 10: { choice_id: 10, }, 11: { choice_id: 11, }, }, }, stacks: [ { id: 3, modifier_token: 'sfdH00Fy17bt5c3Y5zYk5GDsX7Cl67cgec14Qd06V87g74JFOr2UOC2ZL8E919eBmI72W8f5keYDeWfrV7SQW35fw0Vg452k25w9BrS62MtOs89JjLQ', pseudo: 'voting_people_TEST', creation_date: { date: '2020-01-22 14:28:19.000000', timezone_type: 3, timezone: 'Europe/Paris', }, votes: { 5: { choice_id: 5, }, 6: { id: 5, value: 'maybe', choice_id: 6, text: 'Boumbo petite automobile', stack_id: 3, }, 7: { id: 4, value: 'yes', choice_id: 7, text: "Les mystérieuses cités d'or", stack_id: 3, }, 8: { choice_id: 8, }, 9: { choice_id: 9, }, 10: { choice_id: 10, }, 11: { choice_id: 11, }, }, }, { id: 4, modifier_token: 'sfdH00Fy17bt5c3Y5zYk5GDsX7Cl67cgec14Qd06V87g74JFOr2UOC2ZL8E919eBmI72W8f5keYDeWfrV7SQW35fw0Vg452k25w9BrS62MtOs89JjLQ', pseudo: 'voting_people_TEST', creation_date: { date: '2020-01-22 14:28:19.000000', timezone_type: 3, timezone: 'Europe/Paris', }, votes: { 5: { choice_id: 5, }, 6: { id: 6, value: 'yes', choice_id: 6, text: 'Boumbo petite automobile', stack_id: 4, }, 7: { id: 8, value: 'no', choice_id: 7, text: "Les mystérieuses cités d'or", stack_id: 4, }, 8: { choice_id: 8, }, 9: { choice_id: 9, }, 10: { choice_id: 10, }, 11: { choice_id: 11, }, }, }, { id: 5, modifier_token: 'sfdH00Fy17bt5c3Y5zYk5GDsX7Cl67cgec14Qd06V87g74JFOr2UOC2ZL8E919eBmI72W8f5keYDeWfrV7SQW35fw0Vg452k25w9BrS62MtOs89JjLQ', pseudo: 'voting_people_TEST', creation_date: { date: '2020-01-22 16:00:50.000000', timezone_type: 3, timezone: 'Europe/Paris', }, votes: { 5: { id: 9, value: 'no', choice_id: 5, text: 'Vic le viking', stack_id: 5, }, 6: { id: 10, value: 'maybe', choice_id: 6, text: 'Boumbo petite automobile', stack_id: 5, }, 7: { id: 11, value: 'yes', choice_id: 7, text: "Les mystérieuses cités d'or", stack_id: 5, }, 8: { choice_id: 8, }, 9: { choice_id: 9, }, 10: { choice_id: 10, }, 11: { choice_id: 11, }, }, }, { id: 6, modifier_token: 'W1275k1tOh7CA9e9F0VbD58teW3Z451848Sh14imcr90QY1d3tK415mHw9Ib8II8S91F2n8dhk135-20d9cT2mX3UfZ92aeuQdwcj32e17E0bc50fp3d', pseudo: '', creation_date: { date: '2020-01-22 16:01:10.000000', timezone_type: 3, timezone: 'Europe/Paris', }, votes: { 5: { id: 12, value: 'yes', choice_id: 5, text: 'Vic le viking', stack_id: 6, }, 6: { id: 13, value: 'maybe', choice_id: 6, text: 'Boumbo petite automobile', stack_id: 6, }, 7: { id: 14, value: 'no', choice_id: 7, text: "Les mystérieuses cités d'or", stack_id: 6, }, 8: { choice_id: 8, }, 9: { choice_id: 9, }, 10: { choice_id: 10, }, 11: { choice_id: 11, }, }, }, { id: 7, modifier_token: 'b88Qnb1A515Sfedee8b74d726A32444m87cn9Zc0f9t6Ued516f76235V93tBKcJVJearh061S8I0o5l24wbIaMe2v4wg76dhEBBi9m-28Qa601b664L', pseudo: 'tk_TEST', creation_date: { date: '2020-01-23 16:19:29.000000', timezone_type: 3, timezone: 'Europe/Paris', }, votes: { 5: { choice_id: 5, }, 6: { id: 15, value: 'yes', choice_id: 6, text: 'Boumbo petite automobile', stack_id: 7, }, 7: { choice_id: 7, }, 8: { choice_id: 8, }, 9: { choice_id: 9, }, 10: { id: 16, value: 'yes', choice_id: 10, text: "Le chat, la vache, et l'océan", stack_id: 7, }, 11: { choice_id: 11, }, }, }, { id: 12, modifier_token: 'b88Qnb1A515Sfedee8b74d726A32444m87cn9Zc0f9t6Ued516f76235V93tBKcJVJearh061S8I0o5l24wbIaMe2v4wg76dhEBBi9m-28Qa601b664L', pseudo: 'tk_TEST', creation_date: { date: '2020-01-24 11:34:54.000000', timezone_type: 3, timezone: 'Europe/Paris', }, votes: { 5: { id: 21, value: 'yes', choice_id: 5, text: 'Vic le viking', stack_id: 12, }, 6: { choice_id: 6, }, 7: { choice_id: 7, }, 8: { choice_id: 8, }, 9: { choice_id: 9, }, 10: { choice_id: 10, }, 11: { id: 22, value: 'yes', choice_id: 11, text: 'Digimon', stack_id: 12, }, }, }, { id: 13, modifier_token: 'b88Qnb1A515Sfedee8b74d726A32444m87cn9Zc0f9t6Ued516f76235V93tBKcJVJearh061S8I0o5l24wbIaMe2v4wg76dhEBBi9m-28Qa601b664L', pseudo: 'tk_TEST', creation_date: { date: '2020-01-24 12:00:47.000000', timezone_type: 3, timezone: 'Europe/Paris', }, votes: { 5: { choice_id: 5, }, 6: { id: 23, value: 'yes', choice_id: 6, text: 'Boumbo petite automobile', stack_id: 13, }, 7: { id: 24, value: 'yes', choice_id: 7, text: "Les mystérieuses cités d'or", stack_id: 13, }, 8: { choice_id: 8, }, 9: { id: 25, value: 'yes', choice_id: 9, text: 'Foot 2 rue', stack_id: 13, }, 10: { choice_id: 10, }, 11: { choice_id: 11, }, }, }, { id: 14, modifier_token: 'b88Qnb1A515Sfedee8b74d726A32444m87cn9Zc0f9t6Ued516f76235V93tBKcJVJearh061S8I0o5l24wbIaMe2v4wg76dhEBBi9m-28Qa601b664L', pseudo: 'tk_TEST', creation_date: { date: '2020-01-24 12:01:47.000000', timezone_type: 3, timezone: 'Europe/Paris', }, votes: { 5: { id: 26, value: 'yes', choice_id: 5, text: 'Vic le viking', stack_id: 14, }, 6: { choice_id: 6, }, 7: { choice_id: 7, }, 8: { choice_id: 8, }, 9: { choice_id: 9, }, 10: { choice_id: 10, }, 11: { choice_id: 11, }, }, }, { id: 15, modifier_token: 'b88Qnb1A515Sfedee8b74d726A32444m87cn9Zc0f9t6Ued516f76235V93tBKcJVJearh061S8I0o5l24wbIaMe2v4wg76dhEBBi9m-28Qa601b664L', pseudo: 'tk_TEST', creation_date: { date: '2020-01-24 12:07:15.000000', timezone_type: 3, timezone: 'Europe/Paris', }, votes: { 5: { choice_id: 5, }, 6: { id: 27, value: 'yes', choice_id: 6, text: 'Boumbo petite automobile', stack_id: 15, }, 7: { choice_id: 7, }, 8: { choice_id: 8, }, 9: { choice_id: 9, }, 10: { choice_id: 10, }, 11: { choice_id: 11, }, }, }, { id: 16, modifier_token: 'b88Qnb1A515Sfedee8b74d726A32444m87cn9Zc0f9t6Ued516f76235V93tBKcJVJearh061S8I0o5l24wbIaMe2v4wg76dhEBBi9m-28Qa601b664L', pseudo: 'tk_TEST', creation_date: { date: '2020-01-24 12:08:58.000000', timezone_type: 3, timezone: 'Europe/Paris', }, votes: { 5: { choice_id: 5, }, 6: { id: 28, value: 'yes', choice_id: 6, text: 'Boumbo petite automobile', stack_id: 16, }, 7: { choice_id: 7, }, 8: { choice_id: 8, }, 9: { choice_id: 9, }, 10: { choice_id: 10, }, 11: { choice_id: 11, }, }, }, { id: 17, modifier_token: 'b88Qnb1A515Sfedee8b74d726A32444m87cn9Zc0f9t6Ued516f76235V93tBKcJVJearh061S8I0o5l24wbIaMe2v4wg76dhEBBi9m-28Qa601b664L', pseudo: 'tk_TEST', creation_date: { date: '2020-01-24 12:09:15.000000', timezone_type: 3, timezone: 'Europe/Paris', }, votes: { 5: { choice_id: 5, }, 6: { choice_id: 6, }, 7: { id: 29, value: 'yes', choice_id: 7, text: "Les mystérieuses cités d'or", stack_id: 17, }, 8: { choice_id: 8, }, 9: { choice_id: 9, }, 10: { choice_id: 10, }, 11: { choice_id: 11, }, }, }, { id: 18, modifier_token: 'b88Qnb1A515Sfedee8b74d726A32444m87cn9Zc0f9t6Ued516f76235V93tBKcJVJearh061S8I0o5l24wbIaMe2v4wg76dhEBBi9m-28Qa601b664L', pseudo: 'tk_TEST', creation_date: { date: '2020-01-24 12:15:45.000000', timezone_type: 3, timezone: 'Europe/Paris', }, votes: { 5: { choice_id: 5, }, 6: { choice_id: 6, }, 7: { id: 30, value: 'yes', choice_id: 7, text: "Les mystérieuses cités d'or", stack_id: 18, }, 8: { choice_id: 8, }, 9: { choice_id: 9, }, 10: { choice_id: 10, }, 11: { choice_id: 11, }, }, }, { id: 19, modifier_token: 'b88Qnb1A515Sfedee8b74d726A32444m87cn9Zc0f9t6Ued516f76235V93tBKcJVJearh061S8I0o5l24wbIaMe2v4wg76dhEBBi9m-28Qa601b664L', pseudo: 'tk_TEST', creation_date: { date: '2020-01-24 12:16:50.000000', timezone_type: 3, timezone: 'Europe/Paris', }, votes: { 5: { id: 31, value: 'yes', choice_id: 5, text: 'Vic le viking', stack_id: 19, }, 6: { id: 32, value: 'yes', choice_id: 6, text: 'Boumbo petite automobile', stack_id: 19, }, 7: { id: 33, value: 'yes', choice_id: 7, text: "Les mystérieuses cités d'or", stack_id: 19, }, 8: { choice_id: 8, }, 9: { choice_id: 9, }, 10: { choice_id: 10, }, 11: { choice_id: 11, }, }, }, { id: 25, modifier_token: 'b88Qnb1A515Sfedee8b74d726A32444m87cn9Zc0f9t6Ued516f76235V93tBKcJVJearh061S8I0o5l24wbIaMe2v4wg76dhEBBi9m-28Qa601b664L', pseudo: 'tk_TEST', creation_date: { date: '2020-01-29 17:55:42.000000', timezone_type: 3, timezone: 'Europe/Paris', }, votes: { 5: { choice_id: 5, }, 6: { id: 44, value: 'yes', choice_id: 6, text: 'Boumbo petite automobile', stack_id: 25, }, 7: { choice_id: 7, }, 8: { choice_id: 8, }, 9: { id: 45, value: 'yes', choice_id: 9, text: 'Foot 2 rue', stack_id: 25, }, 10: { id: 46, value: 'yes', choice_id: 10, text: "Le chat, la vache, et l'océan", stack_id: 25, }, 11: { choice_id: 11, }, }, }, { id: 26, modifier_token: 'b88Qnb1A515Sfedee8b74d726A32444m87cn9Zc0f9t6Ued516f76235V93tBKcJVJearh061S8I0o5l24wbIaMe2v4wg76dhEBBi9m-28Qa601b664L', pseudo: 'tk_TEST', creation_date: { date: '2020-01-30 10:20:06.000000', timezone_type: 3, timezone: 'Europe/Paris', }, votes: { 5: { id: 47, value: 'yes', choice_id: 5, text: 'Vic le viking', stack_id: 26, }, 6: { id: 48, value: 'yes', choice_id: 6, text: 'Boumbo petite automobile', stack_id: 26, }, 7: { id: 49, value: 'yes', choice_id: 7, text: "Les mystérieuses cités d'or", stack_id: 26, }, 8: { id: 50, value: 'yes', choice_id: 8, text: 'Les mondes engloutis', stack_id: 26, }, 9: { choice_id: 9, }, 10: { choice_id: 10, }, 11: { choice_id: 11, }, }, }, { id: 28, modifier_token: 'b88Qnb1A515Sfedee8b74d726A32444m87cn9Zc0f9t6Ued516f76235V93tBKcJVJearh061S8I0o5l24wbIaMe2v4wg76dhEBBi9m-28Qa601b664L', pseudo: 'tk_TEST', creation_date: { date: '2020-01-30 17:23:48.000000', timezone_type: 3, timezone: 'Europe/Paris', }, votes: { 5: { id: 53, value: 'yes', choice_id: 5, text: 'Vic le viking', stack_id: 28, }, 6: { id: 54, value: 'yes', choice_id: 6, text: 'Boumbo petite automobile', stack_id: 28, }, 7: { id: 55, value: 'yes', choice_id: 7, text: "Les mystérieuses cités d'or", stack_id: 28, }, 8: { choice_id: 8, }, 9: { choice_id: 9, }, 10: { id: 56, value: 'yes', choice_id: 10, text: "Le chat, la vache, et l'océan", stack_id: 28, }, 11: { choice_id: 11, }, }, }, { id: 35, modifier_token: 'b88Qnb1A515Sfedee8b74d726A32444m87cn9Zc0f9t6Ued516f76235V93tBKcJVJearh061S8I0o5l24wbIaMe2v4wg76dhEBBi9m-28Qa601b664L', pseudo: 'tk_TEST', creation_date: { date: '2020-01-31 09:42:28.000000', timezone_type: 3, timezone: 'Europe/Paris', }, votes: { 5: { choice_id: 5, }, 6: { id: 69, value: 'yes', choice_id: 6, text: 'Boumbo petite automobile', stack_id: 35, }, 7: { id: 70, value: 'yes', choice_id: 7, text: "Les mystérieuses cités d'or", stack_id: 35, }, 8: { choice_id: 8, }, 9: { choice_id: 9, }, 10: { choice_id: 10, }, 11: { choice_id: 11, }, }, }, { id: 37, modifier_token: 'b88Qnb1A515Sfedee8b74d726A32444m87cn9Zc0f9t6Ued516f76235V93tBKcJVJearh061S8I0o5l24wbIaMe2v4wg76dhEBBi9m-28Qa601b664L', pseudo: 'tk_TEST', creation_date: { date: '2020-02-05 10:38:47.000000', timezone_type: 3, timezone: 'Europe/Paris', }, votes: { 5: { choice_id: 5, }, 6: { choice_id: 6, }, 7: { choice_id: 7, }, 8: { id: 74, value: 'yes', choice_id: 8, text: 'Les mondes engloutis', stack_id: 37, }, 9: { id: 75, value: 'yes', choice_id: 9, text: 'Foot 2 rue', stack_id: 37, }, 10: { choice_id: 10, }, 11: { choice_id: 11, }, }, }, { id: 40, modifier_token: 'b88Qnb1A515Sfedee8b74d726A32444m87cn9Zc0f9t6Ued516f76235V93tBKcJVJearh061S8I0o5l24wbIaMe2v4wg76dhEBBi9m-28Qa601b664L', pseudo: 'tk_TEST', creation_date: { date: '2020-02-22 17:53:57.000000', timezone_type: 3, timezone: 'Europe/Paris', }, votes: { 5: { id: 82, value: 'no', choice_id: 5, text: 'Vic le viking', stack_id: 40, }, 6: { id: 83, value: 'yes', choice_id: 6, text: 'Boumbo petite automobile', stack_id: 40, }, 7: { choice_id: 7, }, 8: { id: 84, value: 'yes', choice_id: 8, text: 'Les mondes engloutis', stack_id: 40, }, 9: { id: 85, value: 'yes', choice_id: 9, text: 'Foot 2 rue', stack_id: 40, }, 10: { choice_id: 10, }, 11: { choice_id: 11, }, }, }, { id: 41, modifier_token: 'b88Qnb1A515Sfedee8b74d726A32444m87cn9Zc0f9t6Ued516f76235V93tBKcJVJearh061S8I0o5l24wbIaMe2v4wg76dhEBBi9m-28Qa601b664L', pseudo: 'tk_TEST', creation_date: { date: '2020-04-01 12:24:37.000000', timezone_type: 3, timezone: 'Europe/Paris', }, votes: { 5: { id: 86, value: 'yes', choice_id: 5, text: 'Vic le viking', stack_id: 41, }, 6: { id: 87, value: 'yes', choice_id: 6, text: 'Boumbo petite automobile', stack_id: 41, }, 7: { id: 88, value: 'yes', choice_id: 7, text: "Les mystérieuses cités d'or", stack_id: 41, }, 8: { choice_id: 8, }, 9: { id: 89, value: 'yes', choice_id: 9, text: 'Foot 2 rue', stack_id: 41, }, 10: { id: 90, value: 'yes', choice_id: 10, text: "Le chat, la vache, et l'océan", stack_id: 41, }, 11: { choice_id: 11, }, }, }, { id: 43, modifier_token: 'b88Qnb1A515Sfedee8b74d726A32444m87cn9Zc0f9t6Ued516f76235V93tBKcJVJearh061S8I0o5l24wbIaMe2v4wg76dhEBBi9m-28Qa601b664L', pseudo: 'tk_TEST', creation_date: { date: '2020-04-02 17:55:45.201475', timezone_type: 3, timezone: 'Europe/Paris', }, votes: { 5: { id: 93, value: 'yes', choice_id: 5, text: 'Vic le viking', stack_id: 43, }, 6: { id: 94, value: 'yes', choice_id: 6, text: 'Boumbo petite automobile', stack_id: 43, }, 7: { id: 95, value: 'yes', choice_id: 7, text: "Les mystérieuses cités d'or", stack_id: 43, }, 8: { id: 96, value: 'yes', choice_id: 8, text: 'Les mondes engloutis', stack_id: 43, }, 9: { id: 97, value: 'yes', choice_id: 9, text: 'Foot 2 rue', stack_id: 43, }, 10: { choice_id: 10, }, 11: { choice_id: 11, }, }, }, ], comments: [ { id: 4, text: 'wouah trop bien framadate HOUHOUUUU!', pseudo: 'tk_TEST', date: { date: '2020-01-22 16:00:22.000000', timezone_type: 3, timezone: 'Europe/Paris', }, }, { id: 6, text: 'wouah trop bien framadate! zerf zrg ergetetht', pseudo: 'tk_TEST', date: { date: '2020-01-22 16:09:32.000000', timezone_type: 3, timezone: 'Europe/Paris', }, }, { id: 7, text: 'comment numléro 4\n', pseudo: 'tk_TEST', date: { date: '2020-01-22 16:09:51.000000', timezone_type: 3, timezone: 'Europe/Paris', }, }, { id: 8, text: 'wouah trop bien framadate!', pseudo: 'tk_TEST', date: { date: '2020-01-22 16:15:24.000000', timezone_type: 3, timezone: 'Europe/Paris', }, }, { id: 9, text: 'wouah trop bien framadate zef ret r e re!', pseudo: 'tk_TEST', date: { date: '2020-01-23 14:11:21.000000', timezone_type: 3, timezone: 'Europe/Paris', }, }, { id: 13, text: 'OUAIIII', pseudo: 'tk_TEST', date: { date: '2020-01-23 16:35:52.000000', timezone_type: 3, timezone: 'Europe/Paris', }, }, { id: 14, text: 'MAAAAHAHAHAHHAA', pseudo: 'tk_TEST', date: { date: '2020-01-23 16:36:04.000000', timezone_type: 3, timezone: 'Europe/Paris', }, }, { id: 16, text: 'Meeeeeh', pseudo: 'tk_TEST', date: { date: '2020-01-23 18:37:49.000000', timezone_type: 3, timezone: 'Europe/Paris', }, }, { id: 18, text: 'wouah trop bien framadate!', pseudo: 'tk_TEST', date: { date: '2020-01-24 11:34:58.000000', timezone_type: 3, timezone: 'Europe/Paris', }, }, { id: 19, text: 'Ndjdjkddkld', pseudo: 'tk_TEST', date: { date: '2020-01-24 11:35:08.000000', timezone_type: 3, timezone: 'Europe/Paris', }, }, { id: 20, text: 'wouah trop bien framadate!', pseudo: 'tk_TEST', date: { date: '2020-01-24 12:16:24.000000', timezone_type: 3, timezone: 'Europe/Paris', }, }, { id: 21, text: 'encore un commentaire ', pseudo: 'tk_TEST', date: { date: '2020-01-24 12:16:38.000000', timezone_type: 3, timezone: 'Europe/Paris', }, }, ], choices: [ { id: 5, date: { date: '2020-01-22 14:28:19.000000', timezone_type: 3, timezone: 'Europe/Paris', }, text: 'Vic le viking', url: null, }, { id: 6, date: { date: '2020-01-22 14:28:19.000000', timezone_type: 3, timezone: 'Europe/Paris', }, text: 'Boumbo petite automobile', url: null, }, { id: 7, date: { date: '2020-01-22 14:28:19.000000', timezone_type: 3, timezone: 'Europe/Paris', }, text: "Les mystérieuses cités d'or", url: null, }, { id: 8, date: { date: '2020-01-22 14:28:19.000000', timezone_type: 3, timezone: 'Europe/Paris', }, text: 'Les mondes engloutis', url: null, }, { id: 9, date: { date: '2020-01-22 14:28:19.000000', timezone_type: 3, timezone: 'Europe/Paris', }, text: 'Foot 2 rue', url: null, }, { id: 10, date: { date: '2020-01-22 14:28:19.000000', timezone_type: 3, timezone: 'Europe/Paris', }, text: "Le chat, la vache, et l'océan", url: null, }, { id: 11, date: { date: '2020-01-22 14:28:19.000000', timezone_type: 3, timezone: 'Europe/Paris', }, text: 'Digimon', url: null, }, ], choices_count: { counts: { 5: { choice_id: 5, choice_text: 'Vic le viking', id: 9, score: 8, yes: { count: 8, people: ['', 'tk_TEST', 'tk_TEST', 'tk_TEST', 'tk_TEST', 'tk_TEST', 'tk_TEST', 'tk_TEST'], }, maybe: { count: 0, people: [], }, no: { count: 2, people: ['voting_people_TEST', 'tk_TEST'], }, }, 6: { choice_id: 6, choice_text: 'Boumbo petite automobile', id: 5, score: 14.5, yes: { count: 13, people: [ 'voting_people_TEST', 'tk_TEST', 'tk_TEST', 'tk_TEST', 'tk_TEST', 'tk_TEST', 'tk_TEST', 'tk_TEST', 'tk_TEST', 'tk_TEST', 'tk_TEST', 'tk_TEST', 'tk_TEST', ], }, maybe: { count: 3, people: ['voting_people_TEST', 'voting_people_TEST', ''], }, no: { count: 0, people: [], }, }, 7: { choice_id: 7, choice_text: "Les mystérieuses cités d'or", id: 4, score: 12, yes: { count: 12, people: [ 'voting_people_TEST', 'voting_people_TEST', 'voting_people_TEST', 'tk_TEST', 'tk_TEST', 'tk_TEST', 'tk_TEST', 'tk_TEST', 'tk_TEST', 'tk_TEST', 'tk_TEST', 'tk_TEST', ], }, maybe: { count: 0, people: [], }, no: { count: 2, people: ['voting_people_TEST', ''], }, }, 8: { choice_id: 8, choice_text: 'Les mondes engloutis', id: 50, score: 4, yes: { count: 4, people: ['tk_TEST', 'tk_TEST', 'tk_TEST', 'tk_TEST'], }, maybe: { count: 0, people: [], }, no: { count: 0, people: [], }, }, 9: { choice_id: 9, choice_text: 'Foot 2 rue', id: 25, score: 6, yes: { count: 6, people: ['tk_TEST', 'tk_TEST', 'tk_TEST', 'tk_TEST', 'tk_TEST', 'tk_TEST'], }, maybe: { count: 0, people: [], }, no: { count: 0, people: [], }, }, 10: { choice_id: 10, choice_text: "Le chat, la vache, et l'océan", id: 16, score: 4, yes: { count: 4, people: ['tk_TEST', 'tk_TEST', 'tk_TEST', 'tk_TEST'], }, maybe: { count: 0, people: [], }, no: { count: 0, people: [], }, }, 11: { choice_id: 11, choice_text: 'Digimon', id: 22, score: 1, yes: { count: 1, people: ['tk_TEST'], }, maybe: { count: 0, people: [], }, no: { count: 0, people: [], }, }, }, maxScore: 14.5, }, vote_count: 21, owner: { __initializer__: null, __cloner__: null, __isInitialized__: true, pseudo: 'tk_TEST', email: 'tktest@tktest.com', }, owner_modifier_token: 'b88Qnb1A515Sfedee8b74d726A32444m87cn9Zc0f9t6Ued516f76235V93tBKcJVJearh061S8I0o5l24wbIaMe2v4wg76dhEBBi9m-28Qa601b664L', admin_key: 'A8jZ9oc1jsFGZJ024c457f0Wj1bYca5m6537cm9nCg7catZdc18ke5Kqd449eL290oHCqdu3SNmkC7yIHj96n6dnU7ca7qdaf2VSRMI48eXd61O9a3U', json_you_sent: { pseudo: 'mon pseudo', email: 'tktest@tktest.com', votes: [ { choice_id: 5, value: 'yes', }, { choice_id: 6, value: 'yes', }, { choice_id: 7, value: 'yes', }, { choice_id: 8, value: 'yes', }, { choice_id: 9, value: 'yes', }, ], }, }; this.updateCurrentPollFromResponse(mockResponse); } }