- <%= t("welcome.debates.title") %>
- <%= t("welcome.debates.description") %>
-
- <%= t("welcome.proposal.title") %>
- <%= t("welcome.proposal.description") %>
-
- <%= t("welcome.decide.title") %>
- <%= t("welcome.decide.description") %>
-
- <%= t("welcome.do.title") %>
- <%= t("welcome.do.description") %>
-
<%= t("welcome.debates.title") %>
+<%= t("welcome.debates.description") %>
+<%= t("welcome.proposal.title") %>
+<%= t("welcome.proposal.description") %>
+<%= t("welcome.decide.title") %>
+<%= t("welcome.decide.description") %>
+<%= t("welcome.do.title") %>
+<%= t("welcome.do.description") %>
+Please check the marked fields to know how to correct them:" policy: Privacy Policy proposal: Proposal proposal_notification: "Notification" spending_proposal: Spending proposal budget/investment: Investment + budget/heading: Budget Heading poll/shift: Shift + poll/question/answer: Answer user: Account verification/sms: phone signature_sheet: Signature sheet document: Document topic: Topic + image: Image geozones: none: All city all: All scopes @@ -258,6 +263,7 @@ en: one: Someone commented on other: There are %{count} new comments on empty_notifications: You don't have new notifications. + notifiable_hidden: This resource is not available anymore. mark_all_as_read: Mark all as read proposal_notification: one: There is one new notification on @@ -277,7 +283,8 @@ en: sign_up: Sign up with Facebook name: Facebook finish_signup: - title: Add your email address + title: "Additional details" + username_warning: "Due to a change in the way we interact with social networks, it is possible that your username now appears as 'already in use'. If that is your case, please choose a different username." google_oauth2: sign_in: Sign in with Google sign_up: Sign up with Google @@ -289,9 +296,6 @@ en: info_sign_in: "Sign in with:" info_sign_up: "Sign up with:" or_fill: "Or fill the following form:" - finish_signup: - title: "Additional details" - username_warning: "Due to a change in the way we interact with social networks, it is possible that your username now appears as 'already in use'. If that is your case, please choose a different username." proposals: create: form: @@ -332,6 +336,10 @@ en: tags_instructions: "Tag this proposal. You can choose from proposed categories or add your own" tags_label: Tags tags_placeholder: "Enter the tags you would like to use, separated by commas (',')" + map_location: "Map location" + map_location_instructions: "Navigate the map to the location and place the marker." + map_remove_marker: "Remove map marker" + map_skip_checkbox: "This proposal doesn't have a concrete location or I'm not aware of it." index: featured_proposals: Featured filter_topic: @@ -343,7 +351,11 @@ en: hot_score: most active most_commented: most commented relevance: relevance - archival_date: Archived + archival_date: archived + recommendations: recommendations + recommendations: + without_results: There are not proposals related to your interests + without_interests: Follow proposals so we can give you recommendations retired_proposals: Retired proposals retired_proposals_link: "Proposals retired by the author" retired_links: @@ -407,6 +419,10 @@ en: one: 1 support other: "%{count} supports" zero: No supports + votes: + one: 1 vote + other: "%{count} votes" + zero: No votes supports_necessary: "%{number} supports needed" total_percent: 100% archived: "This proposal has been archived and can't collect supports." @@ -454,10 +470,6 @@ en: no_geozone_restricted: "All city" geozone_restricted: "Districts" geozone_info: "Can participate people in the Census of: " - can_answer: "You can participate in this poll!" - cant_answer: "This poll is not available on your geozone" - cant_answer_not_logged_in: "You must sign in or sign up to participate" - cant_answer_verify: "You must verify your account in order to answer" already_answer: "You already have participated in this poll" section_header: icon_alt: Voting icon @@ -469,24 +481,12 @@ en: help_text_1: "Voting takes place when a citizen proposal supports reaches 1% of the census with voting rights. Voting can also include questions that the City Council ask to the citizens decision." help_text_2: "To participate in the next vote you have to sign up on %{org} and verify your account. All registered voters in the city over 16 years old can vote. The results of all votes are binding on the government." show: - dates_title: "Participation dates" + already_voted_in_booth: "You have already participated in a physical booth. You can not participate again." + already_voted_in_web: "You have already participated in this poll. If you vote again it will be overwritten." + back: Back to voting cant_answer_not_logged_in: "You must %{signin} or %{signup} to participate." - signin: Sign in - signup: Sign up - cant_answer_verify_html: "You must %{verify_link} in order to answer." - verify_link: "verify your account" - cant_answer_incoming: "This poll has not yet started." - cant_answer_expired: "This poll has finished." - poll_questions: - create_question: "Create question" - default_valid_answers: "Yes, No" - show: - answer_this_question: "Answer this question" - original_proposal: "Original proposal" - author: "Created by" - dates_title: "Participation dates" - more_info: "More information" - not_logged_in: "You must %{signin} or %{signup} to participate." + comments_tab: Comments + login_to_comment: You must %{signin} or %{signup} to leave a comment. signin: Sign in signup: Sign up cant_answer_verify_html: "You must %{verify_link} in order to answer." @@ -494,9 +494,36 @@ en: cant_answer_incoming: "This poll has not yet started." cant_answer_expired: "This poll has finished." cant_answer_wrong_geozone: "This question is not available on your geozone." + more_info_title: "More information" + documents: Documents + zoom_plus: Expand image + read_more: "Read more about %{answer}" + read_less: "Read less about %{answer}" + participate_in_other_polls: Participate in other polls + videos: "External video" + info_menu: "Information" + stats_menu: "Participation statistics" + results_menu: "Poll results" + stats: + title: "Participation data" + total_participation: "Total participation" + total_votes: "Total amount of given votes" + votes: "VOTES" + web: "WEB" + booth: "BOOTH" + total: "TOTAL" + valid: "Valid" + white: "White votes" + null_votes: "Invalid" + results: + title: "Questions" + most_voted_answer: "Most voted answer: " + poll_questions: + create_question: "Create question" + show: vote_answer: "Vote %{answer}" voted: "You have voted %{answer}" - poll: "Poll" + voted_token: "You can write down this vote identifier, to check your vote on the final results:" proposal_notifications: new: title: "Send message" @@ -511,9 +538,6 @@ en: edit: 'Edit' save: 'Save' delete: 'Delete' - comments: - title: 'Comments' - login_to_comment: 'You must %{signin} or %{signup} to leave a comment.' "yes": "Yes" "no": "No" search_results: "Search results" @@ -544,6 +568,7 @@ en: collective: Collective flag: Flag as inappropriate follow: "Follow" + following: "Following" follow_entity: "Follow %{entity}" followable: budget_investment: @@ -588,12 +613,16 @@ en: target_blank_html: " (link opens in new window)" you_are_in: "You are in" unflag: Unflag - unfollow: "Unfollow" unfollow_entity: "Unfollow %{entity}" outline: budget: Participatory budget searcher: Searcher go_to_page: "Go to page of " + share: Share + orbit: + previous_slide: Previous Slide + next_slide: Next Slide + documentation: Additional documentation social: blog: "%{org} Blog" facebook: "%{org} Facebook" @@ -685,7 +714,12 @@ en: deleted: Deleted deleted_debate: This debate has been deleted deleted_proposal: This proposal has been deleted - deleted_budget_investment: This investment has been deleted + deleted_budget_investment: This investment project has been deleted + proposals: Proposals + debates: Debates + budget_investments: Budget investments + comments: Comments + actions: Actions filters: comments: one: 1 Comment @@ -704,7 +738,7 @@ en: other: "%{count} Following" no_activity: User has no public activity no_private_messages: "This user doesn't accept private messages." - private_activity: This user decided to keep the activity list private + private_activity: This user decided to keep the activity list private. send_private_message: "Send private message" proposals: send_notification: "Send notification" @@ -749,6 +783,16 @@ en: proposal: description: Open space for citizen proposals about the kind of city we want to live in. title: You propose + recommended: + title: Recommendations that may interest you + debates: + title: Recommended debates + btn_text_link: All recommended debates + proposals: + title: Recommended proposals + btn_text_link: All recommended proposals + budget_investments: + title: Recommended investments verification: i_dont_have_an_account: I don't have an account i_have_an_account: I already have an account @@ -768,3 +812,18 @@ en: invisible_captcha: sentence_for_humans: "If you are human, ignore this field" timestamp_error_message: "Sorry, that was too quick! Please resubmit." + related_content: + title: "Related content" + add: "Add related content" + label: "Link to related content" + placeholder: "%{url}" + help: "You can add links of %{models} inside of %{org}." + submit: "Add" + error: "Link not valid. Remember to start with %{url}." + success: "You added a new related content" + is_related: "¿Is it related content?" + score_positive: "Yes" + score_negative: "No" + content_title: + proposal: "Proposal" + debate: "Debate" diff --git a/config/locales/en/images.yml b/config/locales/en/images.yml new file mode 100644 index 000000000..63132647d --- /dev/null +++ b/config/locales/en/images.yml @@ -0,0 +1,22 @@ +en: + images: + remove_image: Remove image + form: + title: Descriptive image + title_placeholder: Add a descriptive title for the image + attachment_label: Choose image + delete_button: Remove image + note: "You can upload one image of following content types: %{accepted_content_types}, up to %{max_file_size} MB." + add_new_image: Add image + title_placeholder: Add a descriptive title for the image + admin_title: "Image" + admin_alt_text: "Alternative text for the image" + actions: + destroy: + notice: Image was deleted successfully. + alert: Cannot destroy image. + confirm: Are you sure you want to delete the image? This action cannot be undone! + errors: + messages: + in_between: must be in between %{min} and %{max} + wrong_content_type: content type %{content_type} does not match any of accepted content types %{accepted_content_types} \ No newline at end of file diff --git a/config/locales/en/kaminari.yml b/config/locales/en/kaminari.yml index aa04df74c..d4789a4a5 100644 --- a/config/locales/en/kaminari.yml +++ b/config/locales/en/kaminari.yml @@ -1,4 +1,3 @@ ---- en: helpers: page_entries_info: @@ -15,9 +14,9 @@ en: zero: "%{entry_name} cannot be found" views: pagination: + current: You're on page first: First last: Last next: Next previous: Previous - truncate: "…" - current: You're on page \ No newline at end of file + truncate: "…" \ No newline at end of file diff --git a/config/locales/en/legislation.yml b/config/locales/en/legislation.yml index 37f9c02aa..57929670a 100644 --- a/config/locales/en/legislation.yml +++ b/config/locales/en/legislation.yml @@ -1,4 +1,3 @@ ---- en: legislation: annotations: @@ -49,6 +48,8 @@ en: processes: header: view_process_information: View process information + proposals: + empty_proposals: There are no proposals debate: empty_questions: There aren't any questions participate: Participate in the debate @@ -86,6 +87,7 @@ en: draft_publication_date: Draft publication allegations_dates: Allegations result_publication_date: Final result publication + proposals_dates: Proposals questions: comments: comment_button: Publish answer @@ -117,3 +119,8 @@ en: shared: share: Share share_comment: Comment on %{version_name} from process draft %{process_name} + proposals: + form: + tags_label: "Categories" + not_verified: "For vote proposals %{verify_account}." + closed: "This process has been closed and can not receive votes." \ No newline at end of file diff --git a/config/locales/en/mailers.yml b/config/locales/en/mailers.yml index 3b6706929..2000cd9a5 100644 --- a/config/locales/en/mailers.yml +++ b/config/locales/en/mailers.yml @@ -1,4 +1,3 @@ ---- en: mailers: no_reply: "This message was sent from an email address that does not accept replies." @@ -100,4 +99,4 @@ en: participate_url: "participate in the final voting" thanks: "Thank you again for participating." sincerely: "Sincererly" - signatory: "DEPARTMENT OF PUBLIC PARTICIPATION" + signatory: "DEPARTMENT OF PUBLIC PARTICIPATION" \ No newline at end of file diff --git a/config/locales/en/management.yml b/config/locales/en/management.yml index 8aabd7994..ced2d0644 100644 --- a/config/locales/en/management.yml +++ b/config/locales/en/management.yml @@ -1,4 +1,3 @@ ---- en: management: account: @@ -130,4 +129,4 @@ en: title: User's invites create: success_html: %{count} invitations have been sent. - title: User's invites + title: User's invites \ No newline at end of file diff --git a/config/locales/en/moderation.yml b/config/locales/en/moderation.yml index 66697f5e4..f6648d49d 100644 --- a/config/locales/en/moderation.yml +++ b/config/locales/en/moderation.yml @@ -1,8 +1,5 @@ ---- en: moderation: - header: - title: Moderation comments: index: block_authors: Block authors @@ -44,6 +41,8 @@ en: created_at: Newest flags: Most flagged title: Debates + header: + title: Moderation menu: flagged_comments: Comments flagged_debates: Debates @@ -75,4 +74,4 @@ en: search: Search search_placeholder: email or name of user title: Block users - notice_hide: User blocked. All of this user's debates and comments have been hidden. + notice_hide: User blocked. All of this user's debates and comments have been hidden. \ No newline at end of file diff --git a/config/locales/en/officing.yml b/config/locales/en/officing.yml index 2dfc29ac3..42003da98 100644 --- a/config/locales/en/officing.yml +++ b/config/locales/en/officing.yml @@ -1,4 +1,3 @@ ---- en: officing: header: @@ -21,15 +20,13 @@ en: create: "Results saved" error_create: "Results NOT saved. Error in data." error_wrong_booth: "Wrong booth. Results NOT saved." - error_wrong_date: "Wrong date. Results NOT saved." new: title: "%{poll} - Add results" not_allowed: "You are allowed to add results for this poll" booth: "Booth" date: "Date" select_booth: "Select booth" - select_date: "Select date" - ballots_white: "Blank ballots" + ballots_white: "Totally blank ballots" ballots_null: "Invalid ballots" ballots_total: "Total ballots" submit: "Save" @@ -40,7 +37,7 @@ en: results: Results table_answer: Answer table_votes: Votes - table_whites: "Blank ballots" + table_whites: "Totally blank ballots" table_nulls: "Invalid ballots" table_total: "Total ballots" residence: @@ -58,9 +55,12 @@ en: new: title: Polls table_poll: Poll - table_actions: Polls status + table_status: Polls status + table_actions: Actions show: can_vote: Can vote error_already_voted: Has already participated in this poll submit: Confirm vote success: "Vote introduced!" + can_vote: + submit_disable_with: "Wait, confirming vote..." \ No newline at end of file diff --git a/config/locales/en/pages.yml b/config/locales/en/pages.yml index d1884cbad..c0b8f3a0b 100644 --- a/config/locales/en/pages.yml +++ b/config/locales/en/pages.yml @@ -1,4 +1,3 @@ ---- en: pages: census_terms: To confirm the account, you must be 16 or older and be registered, having provided the information requested previously, will verify. By accepting the verification process, you also consent to the verification of this information, as well as the contact methods featuring in said files. The data provided will be acquired and processed in a file mentioned previously in the terms and conditions of use for the Portal. @@ -81,4 +80,4 @@ en: info_code: 'Now introduce the code you received in letter:' password: Password submit: Verify my account - title: Verify your account + title: Verify your account \ No newline at end of file diff --git a/config/locales/en/rails.yml b/config/locales/en/rails.yml index 27ae10dbf..403552887 100644 --- a/config/locales/en/rails.yml +++ b/config/locales/en/rails.yml @@ -18,8 +18,6 @@ # # To learn more, please read the Rails Internationalization guide # available at http://guides.rubyonrails.org/i18n.html. - ---- en: date: abbr_day_names: @@ -225,4 +223,5 @@ en: default: "%a, %d %b %Y %H:%M:%S %z" long: "%B %d, %Y %H:%M" short: "%d %b %H:%M" - pm: pm + api: "%Y-%m-%d %H" + pm: pm \ No newline at end of file diff --git a/config/locales/en/responders.yml b/config/locales/en/responders.yml index 203d5700e..bbee89b5e 100644 --- a/config/locales/en/responders.yml +++ b/config/locales/en/responders.yml @@ -1,4 +1,3 @@ ---- en: flash: actions: @@ -8,6 +7,8 @@ en: direct_message: "You message has been sent successfully." poll: "Poll created successfully." poll_booth: "Booth created successfully." + poll_question_answer: "Answer created successfully" + poll_question_answer_video: "Video created successfully" proposal: "Proposal created successfully." proposal_notification: "Your message has been sent correctly." spending_proposal: "Spending proposal created successfully. You can access it from %{activity}" @@ -30,3 +31,4 @@ en: budget_investment: "Investment project deleted succesfully." error: "Could not delete" topic: "Topic deleted successfully." + poll_question_answer_video: "Answer video deleted successfully." \ No newline at end of file diff --git a/config/locales/en/settings.yml b/config/locales/en/settings.yml index e1d84393f..531393e65 100644 --- a/config/locales/en/settings.yml +++ b/config/locales/en/settings.yml @@ -32,6 +32,7 @@ en: twitter_login: Twitter login facebook_login: Facebook login google_login: Google login + proposals: Proposals debates: Debates polls: Polls signature_sheets: Signature sheets @@ -39,11 +40,19 @@ en: spending_proposal_features: voting_allowed: Voting on investment projects legislation: Legislation + user: + recommendations: Recommendeds community: Community on proposals and investments + map: Proposals and budget investments geolocation + allow_images: Allow upload and show images + map_latitude: Latitude + map_longitude: Longitude + map_zoom: Zoom mailer_from_name: Origin email name mailer_from_address: Origin email address + meta_title: "Site title (SEO)" meta_description: "Site description (SEO)" meta_keywords: "Keywords (SEO)" verification_offices_url: Verification offices URL min_age_to_participate: Minimum age needed to participate - proposal_improvement_path: Proposal improvement info internal link + proposal_improvement_path: Proposal improvement info internal link \ No newline at end of file diff --git a/config/locales/en/social_share_button.yml b/config/locales/en/social_share_button.yml index 2715c46ab..b2aa209fd 100644 --- a/config/locales/en/social_share_button.yml +++ b/config/locales/en/social_share_button.yml @@ -17,4 +17,4 @@ en: plurk: "Plurk" pinterest: "Pinterest" email: "Email" - telegram: "Telegram" + telegram: "Telegram" \ No newline at end of file diff --git a/config/locales/en/valuation.yml b/config/locales/en/valuation.yml index e07cbc520..761ac2154 100644 --- a/config/locales/en/valuation.yml +++ b/config/locales/en/valuation.yml @@ -1,4 +1,3 @@ ---- en: valuation: header: @@ -122,6 +121,4 @@ en: internal_comments_html: Internal comments save: Save changes notice: - valuate: "Dossier updated" - - + valuate: "Dossier updated" \ No newline at end of file diff --git a/config/locales/en/verification.yml b/config/locales/en/verification.yml index 598532354..ec29a50ff 100644 --- a/config/locales/en/verification.yml +++ b/config/locales/en/verification.yml @@ -1,4 +1,3 @@ ---- en: verification: alert: @@ -109,4 +108,4 @@ en: explanation: We currently hold the following details on the Register; please select a method for your confirmation code to be sent. phone_title: Phone numbers title: Available information - use_another_phone: Use other phone + use_another_phone: Use other phone \ No newline at end of file diff --git a/config/locales/es/activerecord.yml b/config/locales/es/activerecord.yml index 2315fc65a..18296b7bf 100644 --- a/config/locales/es/activerecord.yml +++ b/config/locales/es/activerecord.yml @@ -31,21 +31,27 @@ es: administrator: one: "Administrador" other: "Administradores" + valuator: + one: "Evaluador" + other: "Evaluadores" + manager: + one: "Gestor" + other: "Gestores" vote: one: "Voto" other: "Votos" organization: one: "Organización" other: "Organizaciones" - proposal: - one: "Propuesta ciudadana" - other: "Propuestas ciudadanas" poll/booth: one: "urna" other: "urnas" poll/officer: one: "presidente de mesa" other: "presidentes de mesa" + proposal: + one: "Propuesta ciudadana" + other: "Propuestas ciudadanas" spending_proposal: one: "Propuesta de inversión" other: "Propuestas de inversión" @@ -59,11 +65,11 @@ es: one: Bloque other: Bloques legislation/process: - one: "Proceso" - other: "Procesos" + one: "Proceso" + other: "Procesos" legislation/draft_versions: - one: "Versión borrador" - other: "Versiones borrador" + one: "Versión borrador" + other: "Versiones borrador" legislation/draft_texts: one: "Borrador" other: "Borradores" @@ -79,6 +85,15 @@ es: documents: one: "Documento" other: "Documentos" + images: + one: "Imagen" + other: "Imágenes" + topic: + one: "Tema" + other: "Temas" + poll: + one: "Votación" + other: "Votaciones" attributes: budget: name: "Nombre" @@ -92,23 +107,26 @@ es: phase: "Fase" currency_symbol: "Divisa" budget/investment: - administrator_id: "Administrador" - description: "Descripción" - external_url: "Enlace a documentación adicional" heading_id: "Partida presupuestaria" title: "Título" + description: "Descripción" + external_url: "Enlace a documentación adicional" location: "Ubicación" + administrator_id: "Administrador" organization_name: "Si estás proponiendo en nombre de una organización o colectivo, escribe su nombre" + image: "Imagen descriptiva de la propuesta de inversión" + image_title: "Título de la imagen" budget/heading: name: "Nombre de la partida" price: "Cantidad" population: "Población" - comment: - body: "Comentario" - user: "Usuario" budget/investment/milestone: title: "Título" description: "Descripción" + publication_date: "Fecha de publicación" + comment: + body: "Comentario" + user: "Usuario" debate: author: "Autor" description: "Opinión" @@ -121,7 +139,7 @@ es: description: "Descripción" terms_of_service: "Términos de servicio" user: - login: Email o nombre de usuario + login: "Email o nombre de usuario" email: "Correo electrónico" username: "Nombre de usuario" password_confirmation: "Confirmación de contraseña" @@ -146,9 +164,10 @@ es: starts_at: "Fecha de apertura" ends_at: "Fecha de cierre" geozone_restricted: "Restringida por zonas" + summary: "Resumen" + description: "Descripción" poll/question: title: "Pregunta" - valid_answers: "Posibles respuestas" summary: "Resumen" description: "Descripción" external_url: "Enlace a documentación adicional" @@ -202,6 +221,15 @@ es: document: title: Título attachment: Archivo adjunto + image: + title: Título + attachment: Archivo adjunto + poll/question/answer: + title: Respuesta + description: Descripción + poll/question/answer/video: + title: Título + url: Vídeo externo errors: models: user: @@ -216,6 +244,15 @@ es: attributes: max_per_day: invalid: "Has llegado al número máximo de mensajes privados por día" + image: + attributes: + attachment: + min_image_width: "La imagen debe tener al menos %{required_min_width}px de largo" + min_image_height: "La imagen debe tener al menos %{required_min_height}px de alto" + map_location: + attributes: + map: + invalid: El mapa no puede estar en blanco. Añade un punto al mapa o marca la casilla si no hace falta un mapa. poll/voter: attributes: document_number: @@ -255,3 +292,8 @@ es: image: image_width: "Debe tener %{required_width}px de ancho" image_height: "Debe tener %{required_height}px de alto" + messages: + record_invalid: "La validación falló: %{errors}" + restrict_dependent_destroy: + has_one: No se puede eliminar el registro porque existe un %{record} dependiente + has_many: No se puede eliminar el registro porque existen %{record} dependientes diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 5f8c73341..456b78ab3 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -1,11 +1,10 @@ ---- es: admin: header: title: Administración actions: actions: Acciones - confirm: "¿Estás seguro?" + confirm: '¿Estás seguro?' confirm_hide: Confirmar hide: Ocultar hide_author: Bloquear al autor @@ -27,8 +26,8 @@ es: preview: Vista previa banner: title: Título - description: Descripción - target_url: Enlace + description: Descripción + target_url: Enlace style: Estilo image: Imagen post_started_at: Inicio de publicación @@ -41,7 +40,7 @@ es: form: error: one: "error impidió guardar el banner" - other: "errores impidieron guardar el banner." + other: 'errores impidieron guardar el banner.' new: creating: Crear banner activity: @@ -62,10 +61,12 @@ es: on_users: Usuarios title: Actividad de los Moderadores type: Tipo + no_activity: No hay actividad de moderadores. budgets: index: title: Presupuestos participativos new_link: Crear nuevo presupuesto + filter: Filtro filters: current: Abiertos finished: Terminados @@ -78,11 +79,16 @@ es: edit_groups: Editar grupos de partidas edit_budget: Editar presupuesto create: - notice: ¡Nueva campaña de presupuestos participativos creada con éxito! + notice: '¡Nueva campaña de presupuestos participativos creada con éxito!' update: notice: Campaña de presupuestos participativos actualizada edit: title: Editar campaña de presupuestos participativos + delete: Borrar campaña + destroy: + success_notice: Campaña eliminada correctamente + unable_notice: No se pueden eliminar campañas con presupuestos asociados + new: title: Nuevo presupuesto ciudadano show: @@ -103,6 +109,7 @@ es: table_heading: Partida table_amount: Cantidad table_population: Población + population_info: "El campo población de las partidas presupuestarias se usa con fines estadísticos únicamente, con el objetivo de mostrar el porcentaje de votos habidos en cada partida que represente un área con población. Es un campo opcional, así que puedes dejarlo en blanco si no aplica." winners: calculate: Calcular propuestas ganadoras calculated: Calculando ganadoras, puede tardar un minuto. @@ -146,7 +153,7 @@ es: assigned_admin: Administrador asignado assigned_valuators: Evaluadores asignados classification: Clasificación - info: "%{budget_name} - Grupo: %{group_name} - Propuesta de inversión %{id}" + info: '%{budget_name} - Grupo: %{group_name} - Propuesta de inversión %{id}' edit: Editar edit_classification: Editar clasificación by: Autor @@ -156,6 +163,7 @@ es: dossier: Informe edit_dossier: Editar informe tags: Etiquetas + user_tags: Etiquetas del usuario undefined: Sin definir milestone: Seguimiento new_milestone: Crear nuevo hito @@ -168,7 +176,7 @@ es: "true": Seleccionado "false": No seleccionado winner: - title: Ganador + title: Ganadora "true": "Si" "false": "No" edit: @@ -180,6 +188,7 @@ es: assigned_valuators: Evaluadores select_heading: Seleccionar partida submit_button: Actualizar + user_tags: Etiquetas asignadas por el usuario tags: Etiquetas tags_placeholder: "Escribe las etiquetas que desees separadas por comas (,)" undefined: Sin definir @@ -189,11 +198,16 @@ es: table_id: "ID" table_title: "Título" table_description: "Descripción" + table_publication_date: "Fecha de publicación" table_actions: "Acciones" delete: "Eliminar hito" no_milestones: "No hay hitos definidos" + image: "Imagen" + show_image: "Ver imagen" + documents: "Documentos" new: creating: Crear hito + date: Fecha edit: title: Editar hito create: @@ -212,10 +226,12 @@ es: hidden_debate: Debate oculto hidden_proposal: Propuesta oculta title: Comentarios ocultos + no_hidden_comments: No hay comentarios ocultos. dashboard: index: - back: Volver a + back: Volver a %{org} title: Administración + description: Bienvenido al panel de administración de %{org}. debates: index: filter: Filtro @@ -224,6 +240,7 @@ es: with_confirmed_hide: Confirmados without_confirmed_hide: Pendientes title: Debates ocultos + no_hidden_debates: No hay debates ocultos. hidden_users: index: filter: Filtro @@ -232,6 +249,8 @@ es: with_confirmed_hide: Confirmados without_confirmed_hide: Pendientes title: Usuarios bloqueados + user: Usuario + no_hidden_users: No hay uusarios bloqueados. show: email: 'Email:' hidden_at: 'Bloqueado:' @@ -258,6 +277,7 @@ es: process: Proceso debate_phase: Fase previa allegations_phase: Fase de alegaciones + proposals_phase: Fase de propuestas start: Inicio end: Fin use_markdown: Usa Markdown para formatear el texto @@ -290,6 +310,17 @@ es: info: Información draft_texts: Texto questions: Debate + proposals: Propuestas + proposals: + index: + title: Propuestas + back: Volver + form: + header_information: Encabezado de información + header_information_description: Proporciona información sobre el recorrido de las propuestas. Este texto se mostrará como una alerta en el encabezado de la sección de Propuestas dentro de este proceso. Usa Markdown para formatear el texto. + header_information_placeholder: Añade información para el encabezado de las las propuestas + custom_categories: Categorías + custom_categories_description: Categorías que el usuario puede seleccionar al crear la propuesta. draft_versions: create: notice: 'Borrador creado correctamente. Haz click para verlo' @@ -373,47 +404,38 @@ es: comments_count: Número de comentarios question_option_fields: remove_option: Eliminar - administrators: - index: - title: Administradores - administrator: - add: Añadir como Administrador - delete: Borrar - restricted_removal: "Lo sentimos, no puedes eliminarte a ti mismo de la lista" - search: - email_placeholder: Buscar usuario por email - search: Buscar - user_not_found: Usuario no encontrado managers: index: title: Gestores + name: Nombre + email: Email + no_managers: No hay gestores. manager: add: Añadir como Gestor delete: Borrar search: - email_placeholder: Buscar usuario por email - search: Buscar - user_not_found: Usuario no encontrado + title: 'Gestores: Búsqueda de usuarios' menu: activity: Actividad de moderadores admin: Menú de administración banner: Gestionar banners - proposals_topics: Temas de propuestas poll_questions: Preguntas ciudadanas + proposals_topics: Temas de propuestas budgets: Presupuestos participativos geozones: Gestionar distritos hidden_comments: Comentarios ocultos hidden_debates: Debates ocultos hidden_proposals: Propuestas ocultas hidden_users: Usuarios bloqueados - managers: Gestores administrators: Administradores + managers: Gestores moderators: Moderadores newsletter: Envío de Newsletters valuators: Evaluadores poll_officers: Presidentes de mesa polls: Votaciones poll_booths: Ubicación de urnas + poll_booth_assignments: Asignación de urnas poll_shifts: Asignar turnos officials: Cargos públicos organizations: Organizaciones @@ -434,16 +456,29 @@ es: title_site_customization: Personalizar sitio legislation: Legislación colaborativa users: Usuarios + administrators: + index: + title: Administradores + name: Nombre + email: Email + no_administrators: No hay administradores. + administrator: + add: Añadir como Administrador + delete: Borrar + restricted_removal: "Lo sentimos, no puedes eliminarte a ti mismo de la lista" + search: + title: 'Administradores: Búsqueda de usuarios' moderators: index: title: Moderadores + name: Nombre + email: Email + no_moderators: No hay moderadores. moderator: add: Añadir como Moderador delete: Borrar search: - email_placeholder: Buscar usuario por email - search: Buscar - user_not_found: Usuario no encontrado + title: 'Moderadores: Búsqueda de usuarios' newsletters: index: title: Envío de newsletters @@ -451,14 +486,17 @@ es: valuators: index: title: Evaluadores + name: Nombre + email: Email + description: Descripción + no_description: Sin descripción + no_valuators: No hay evaluadores. valuator: - description_placeholder: "Descripción (opcional)" - user_found: Usuario encontrado + description_placeholder: 'Descripción (opcional)' add: Añadir como evaluador + delete: Borrar search: - email_placeholder: Buscar usuario por email - search: Buscar - user_not_found: Usuario no encontrado + title: 'Evaluadores: Búsqueda de usuarios' summary: title: Resumen de evaluación de propuestas de inversión valuator_name: Evaluador @@ -487,21 +525,18 @@ es: no_officers: "No hay presidentes de mesa asignados a esta votación." table_name: "Nombre" table_email: "Email" - add_officer_assignments: "Añadir turnos como presidente de mesa" - edit_officer_assignments: "Editar turnos" by_officer: date: "Fecha" booth: "Urna" assignments: "Turnos como presidente de mesa en esta votación" no_assignments: "No tiene turnos como presidente de mesa en esta votación." - total_recounts: "Recuentos totales" - total_recount: "Recuento total (presidente de mesa)" poll_shifts: new: add_shift: "Añadir turno" shift: "Asignación" shifts: "Turnos en esta urna" date: "Fecha" + task: "Tarea" edit_shifts: Asignar turno new_shift: "Nuevo turno" no_shifts: "Esta urna no tiene turnos asignados" @@ -511,13 +546,31 @@ es: search_officer_placeholder: Buscar presidentes de mesa search_officer_text: Busca al presidente de mesa para asignar un turno select_date: "Seleccionar día" + no_voting_days: "Voting days ended" + select_task: "Seleccionar tarea" table_shift: "Turno" table_email: "Email" table_name: "Nombre" flash: create: "Añadido turno de presidente de mesa" destroy: "Eliminado turno de presidente de mesa" + date_missing: "Debe seleccionarse una fecha" + vote_collection: Recoger Votos + recount_scrutiny: Recuento & Escrutinio + booth_assignments: + manage_assignments: Gestionar asignaciones + manage: + assignments_list: "Asignaciones para la votación '%{poll}'" + status: + assign_status: Asignación + assigned: Asignada + unassigned: No asignada + actions: + assign: Asignar urna + unassign: Desasignar urna poll_booth_assignments: + alert: + shifts: "Hay turnos asignados para esta urna. Si la desasignas, esos turnos se eliminarán. ¿Deseas continuar?" flash: destroy: "Urna desasignada" create: "Urna asignada" @@ -530,17 +583,16 @@ es: no_officers: "No hay presidentes de mesa para esta urna" recounts: "Recuentos" recounts_list: "Lista de recuentos de esta urna" + results: "Resultados" date: "Fecha" - total_recount: "Recuento total (presidente de mesa)" - count_by_system: "Votos (automático)" + count_final: "Recuento final (presidente de mesa)" + count_by_system: "Votos (automático)" + total_system: Votos totales acumulados(automático) index: booths_title: "Listado de urnas asignadas" no_booths: "No hay urnas asignadas a esta votación." table_name: "Nombre" table_location: "Ubicación" - table_assignment: "Asignación" - remove_booth: "Desasignar urna" - add_booth: "Asignar urna" polls: index: title: "Listado de votaciones" @@ -548,8 +600,13 @@ es: create: "Crear votación" name: "Nombre" dates: "Fechas" + geozone_restricted: "Restringida a los distritos" new: title: "Nueva votación" + show_results_and_stats: "Mostrar resultados y estadísticas" + show_results: "Mostrar resultados" + show_stats: "Mostrar estadísticas" + results_and_stats_reminder: "Si marcas estas casillas los resultados y/o estadísticas de esta votación serán públicos y podrán verlos todos los usuarios." submit_button: "Crear votación" edit: title: "Editar votación" @@ -562,24 +619,18 @@ es: results_tab: Resultados no_questions: "No hay preguntas asignadas a esta votación." questions_title: "Listado de preguntas asignadas" - remove_question: "Desasignar pregunta" - add_question: "Incluir pregunta" table_title: "Título" - table_assignment: "Asignación" - table_name: "Nombre" flash: question_added: "Pregunta añadida a esta votación" error_on_question_added: "No se pudo asignar la pregunta" - question_removed: "Pregunta eliminada de esta votación" - error_on_question_removed: "No se pudo quitar la pregunta" questions: index: - title: "Preguntas ciudadanas" + title: "Preguntas de votaciones" create: "Crear pregunta ciudadana" no_questions: "No hay ninguna pregunta ciudadana." - filter_poll: "Filtrar por votación" - select_poll: "Seleccionar votación" - questions_tab: "Preguntas ciudadanas" + filter_poll: Filtrar por votación + select_poll: Seleccionar votación + questions_tab: "Preguntas" successful_proposals_tab: "Propuestas que han superado el umbral" create_question: "Crear pregunta para votación" table_proposal: "Propuesta" @@ -589,16 +640,50 @@ es: new: title: "Crear pregunta ciudadana" poll_label: "Votación" - valid_answers_note: "Escribe las respuestas separadas por comas (,)" + answers: + images: + add_image: "Añadir imagen" + save_image: "Guardar imagen" show: proposal: Propuesta ciudadana original author: Autor - title: Título + question: Pregunta + edit_question: Editar pregunta valid_answers: Respuestas válidas - description: Descripción + add_answer: Añadir respuesta video_url: Video externo - documents: Documentos - preview: Ver en la web + answers: + title: Respuesta + description: Descripción + videos: Vídeos + video_list: Lista de vídeos + images: Imágenes + images_list: Lista de imágenes + documents: Documentos + documents_list: Lista de documentos + document_title: Título + document_actions: Acciones + answers: + new: + title: Nueva respuesta + show: + title: Título + description: Descripción + images: Imágenes + images_list: Lista de imágenes + edit: Editar respuesta + edit: + title: Editar respuesta + videos: + index: + title: Vídeos + add_video: Añadir vídeo + video_title: Título + video_url: Vídeo externo + new: + title: Nuevo video + edit: + title: Editar vídeo recounts: index: title: "Recuentos" @@ -610,11 +695,17 @@ es: index: title: "Resultados" no_results: "No hay resultados" - table_whites: Papeletas en blanco - table_nulls: Papeletas nulas - table_total: Papeletas totales + result: + table_whites: "Papeletas totalmente en blanco" + table_nulls: "Papeletas nulas" + table_total: "Papeletas totales" table_answer: Respuesta table_votes: Votos + results_by_booth: + booth: Urna + results: Resultados + see_results: Ver resultados + title: "Resultados por urna" booths: index: title: "Lista de urnas" @@ -622,6 +713,7 @@ es: add_booth: "Añadir urna" name: "Nombre" location: "Ubicación" + no_location: "Sin Ubicación" new: title: "Nueva urna" name: "Nombre" @@ -634,6 +726,7 @@ es: location: "Ubicación" booth: shifts: "Asignar turnos" + edit: "Editar urna" officials: edit: destroy: Eliminar condición de 'Cargo Público' @@ -643,6 +736,10 @@ es: official_updated: Datos del cargo público guardados index: title: Cargos Públicos + no_officials: No hay cargos públicos. + name: Nombre + official_position: Cargo público + official_level: Nivel level_0: No es cargo público level_1: Nivel 1 level_2: Nivel 2 @@ -653,6 +750,7 @@ es: edit_official: Editar cargo público make_official: Convertir en cargo público title: 'Cargos Públicos: Búsqueda de usuarios' + no_results: No se han encontrado cargos públicos. organizations: index: filter: Filtro @@ -664,6 +762,12 @@ es: hidden_count_html: one: Hay además una organización sin usuario o con el usuario bloqueado. other: Hay %{count} organizaciones sin usuario o con el usuario bloqueado. + name: Nombre + email: Email + phone_number: Teléfono + responsible_name: Responsable + status: Estado + no_organizations: No hay organizaciones. reject: Rechazar rejected: Rechazada search: Buscar @@ -671,8 +775,10 @@ es: title: Organizaciones verified: Verificada verify: Verificar + pending: Pendiente search: title: Buscar Organizaciones + no_results: No se han encontrado organizaciones. proposals: index: filter: Filtro @@ -681,6 +787,7 @@ es: with_confirmed_hide: Confirmadas without_confirmed_hide: Pendientes title: Propuestas ocultas + no_hidden_proposals: No hay propuestas ocultas. settings: flash: updated: Valor actualizado @@ -695,6 +802,13 @@ es: disabled: "Funcionalidad desactivada" enable: "Activar" disable: "Desactivar" + map: + title: Configuración del mapa + help: Aquí puedes personalizar la manera en la que se muestra el mapa a los usuarios. Arrastra el marcador o pulsa sobre cualquier parte del mapa, ajusta el zoom y pulsa el botón 'Actualizar'. + flash: + update: La configuración del mapa se ha guardado correctamente. + form: + submit: Actualizar shared: booths_search: button: Buscar @@ -716,6 +830,9 @@ es: placeholder: Buscar usuario por nombre o email search_results: "Resultados de la búsqueda" no_search_results: "No se han encontrado resultados." + actions: Acciones + title: Título + description: Descripción spending_proposals: index: geozone_filter_all: Todos los ámbitos de actuación @@ -744,7 +861,7 @@ es: assigned_valuators: Evaluadores asignados back: Volver classification: Clasificación - heading: Propuesta de inversión %{id} + heading: "Propuesta de inversión %{id}" edit: Editar edit_classification: Editar clasificación association_name: Asociación @@ -787,7 +904,7 @@ es: form: error: one: "error impidió guardar el distrito" - other: "errores impidieron guardar el distrito." + other: 'errores impidieron guardar el distrito.' edit: form: submit_button: Guardar cambios @@ -851,6 +968,7 @@ es: direct_messages: Mensajes directos proposal_notifications: Notificaciones de propuestas incomplete_verifications: Verificaciones incompletas + polls: Votaciones direct_messages: title: Mensajes directos total: Total @@ -859,12 +977,24 @@ es: title: Notificaciones de propuestas total: Total proposals_with_notifications: Propuestas con notificaciones + polls: + title: Estadísticas de votaciones + all: Votaciones + web_participants: Participantes en Web + total_participants: Participantes totales + poll_questions: "Preguntas de votación: %{poll}" + table: + poll_name: Votación + question_name: Pregunta + origin_web: Participantes Web + origin_total: Participantes Totales tags: - create: Crear Tema - destroy: Eliminar Tema + create: Crear tema + destroy: Eliminar tema index: add_tag: Añade un nuevo tema de propuesta title: Temas de propuesta + topic: Tema name: placeholder: Escribe el nombre del tema users: @@ -876,6 +1006,7 @@ es: verification_level: Nivel de verficación index: title: Usuarios + no_users: No hay usuarios. search: placeholder: Buscar usuario por email, nombre o DNI search: Buscar diff --git a/config/locales/es/budgets.yml b/config/locales/es/budgets.yml index 78b81fbd3..b85f0ec47 100644 --- a/config/locales/es/budgets.yml +++ b/config/locales/es/budgets.yml @@ -11,7 +11,7 @@ es: one: "Has votado una propuesta." other: "Has votado %{count} propuestas." voted_info_html: "Puedes cambiar tus votos en cualquier momento hasta el cierre de esta fase.
No hace falta que gastes todo el dinero disponible." - zero: "Todavía no has votado ninguna propuesta de inversión." + zero: Todavía no has votado ninguna propuesta de inversión. reasons_for_not_balloting: not_logged_in: Necesitas %{signin} o %{signup} para continuar. not_verified: Las propuestas de inversión sólo pueden ser apoyadas por usuarios verificados, %{verify_account}. @@ -29,6 +29,7 @@ es: unselected_title: Propuestas no seleccionadas para la votación final unselected: Ver las propuestas no seleccionadas para la votación final phase: + drafting: Borrador (No visible para el público) accepting: Presentación de proyectos reviewing: Revisión interna de proyectos selecting: Fase de apoyos @@ -51,16 +52,20 @@ es: help_text_4: "Para conseguir el mayor número de apoyos y votos posible, elige un titular descriptivo y comprensible de tu proyecto. Después tienes un espacio para desarrollar el planteamiento de tu propuesta. Aporta todos los datos y explicaciones, e incluso documentos e imágenes, para ayudar a otras personas participantes a entender mejor lo que planteas." investments: form: - tags_instructions: "Etiqueta esta propuesta. Puedes elegir entre las categorías propuestas o introducir las que desees" - tags_label: Temas tag_category_label: "Categorías" + tags_instructions: "Etiqueta esta propuesta. Puedes elegir entre las categorías propuestas o introducir las que desees" + tags_label: Etiquetas tags_placeholder: "Escribe las etiquetas que desees separadas por una coma (',')" + map_location: "Ubicación en el mapa" + map_location_instructions: "Navega por el mapa hasta la ubicación y coloca el marcador." + map_remove_marker: "Eliminar el marcador" + location: "Información adicional de la ubicación" index: title: Presupuestos participativos unfeasible: Propuestas de inversión no viables - unfeasible_text: Las propuestas presentadas deben cumplir una serie de criterios (legalidad, concreción, ser competencia del Ayuntamiento, no superar el tope del presupuesto; %{definitions}) para ser declaradas viables y llegar hasta la fase de votación final. Todas las propuestas que no cumplen estos criterios son marcadas como inviables y publicadas en la siguiente lista, junto con su informe de inviabilidad. + unfeasible_text: "Las propuestas presentadas deben cumplir una serie de criterios (legalidad, concreción, ser competencia del Ayuntamiento, no superar el tope del presupuesto; %{definitions}) para ser declaradas viables y llegar hasta la fase de votación final. Todas las propuestas que no cumplen estos criterios son marcadas como inviables y publicadas en la siguiente lista, junto con su informe de inviabilidad." unfeasible_text_definitions: ver definiciones aquí - by_heading: "Propuestas de inversión con ámbito: %{heading}" + by_heading: 'Propuestas de inversión con ámbito: %{heading}' search_form: button: Buscar placeholder: Buscar propuestas de inversión... @@ -75,10 +80,10 @@ es: other: "Has votado %{count} propuestas por un valor de %{amount_spent}" voted_info: Puedes %{link} en cualquier momento hasta el cierre de esta fase. No hace falta que gastes todo el dinero disponible. voted_info_link: cambiar tus votos - different_heading_assigned_html: "Ya apoyaste propuestas de otra sección del presupuesto: %{heading_link}" + different_heading_assigned_html: 'Ya apoyaste propuestas de otra sección del presupuesto: %{heading_link}' change_ballot: "Si cambias de opinión puedes borrar tus votos en %{check_ballot} y volver a empezar." check_ballot_link: "revisar mis votos" - zero: "Todavía no has votado ninguna propuesta de inversión en este ámbito del presupuesto." + zero: Todavía no has votado ninguna propuesta de inversión en este ámbito del presupuesto. verified_only: "Para crear una nueva propuesta de inversión %{verify}." verify_account: "verifica tu cuenta" create: "Crear propuesta de inversión" @@ -91,7 +96,7 @@ es: orders: random: Aleatorias confidence_score: Mejor valoradas - price: Por coste + price: Por precio show: author_deleted: Usuario eliminado price_explanation: Informe de coste @@ -103,30 +108,30 @@ es: title: Propuesta de inversión supports: Apoyos votes: Votos - price: Coste + price: Precio comments_tab: Comentarios milestones_tab: Seguimiento no_milestones: No hay hitos definidos - milestone_publish_date: "Publicado el %{publish_date}" + milestone_publication_date: "Publicado el %{publication_date}" wrong_price_format: Solo puede incluir caracteres numéricos investment: add: Votar - already_added: "Ya has añadido esta propuesta de inversión" + already_added: Ya has añadido esta propuesta de inversión already_supported: Ya has apoyado esta propuesta. ¡Compártelo! support_title: Apoyar esta propuesta confirm_group: "Sólo puedes apoyar propuestas en un distrito. Si sigues adelante no podrás cambiar esta decisión. ¿Estás seguro?" supports: + zero: Sin apoyos one: 1 apoyo other: "%{count} apoyos" - zero: Sin apoyos give_support: Apoyar header: check_ballot: Revisar mis votos - different_heading_assigned_html: "Ya apoyaste propuestas de otra sección del presupuesto: %{heading_link}" + different_heading_assigned_html: 'Ya apoyaste propuestas de otra sección del presupuesto: %{heading_link}' change_ballot: "Si cambias de opinión puedes borrar tus votos en %{check_ballot} y volver a empezar." check_ballot_link: "revisar mis votos" progress_bar: - available: "Disponible: " + available: 'Disponible: ' show: group: Grupo phase: Fase actual @@ -144,8 +149,8 @@ es: ballot_lines_count: Votos hide_discarded_link: Ocultar descartadas show_all_link: Mostrar todas - price: Coste + price: Precio total amount_available: Presupuesto disponible - accepted: "Propuesta de inversión aceptada: " - discarded: "Propuesta de inversión descartada: " + accepted: 'Propuesta de inversión aceptada: ' + discarded: 'Propuesta de inversión descartada: ' incompatibles: Incompatibles diff --git a/config/locales/es/community.yml b/config/locales/es/community.yml index 8013c116c..f08a4918a 100644 --- a/config/locales/es/community.yml +++ b/config/locales/es/community.yml @@ -14,29 +14,31 @@ es: proposal: Participa en la comunidad de esta propuesta. Una comunidad activa puede ayudar a mejorar el contenido de la propuesta así como a dinamizar su difusión para conseguir más apoyos. investment: Participa en la comunidad de este proyecto de inversión. Una comunidad activa puede ayudar a mejorar el contenido del proyecto de inversión así como a dinamizar su difusión para conseguir más apoyos. create_first_community_topic: - first_theme_not_logged_in: Aún no hay ningun tema disponible, participa creando el primero. Haz click en el botón crear nuevo tema. + first_theme_not_logged_in: No hay ningún tema disponible, participa creando el primero. first_theme: Crea el primer tema de la comunidad - sub_first_theme: Para crear un tema tienes que %{link} - sign_link: "acceder a %{org_name}" + sub_first_theme: "Para crear un tema debes %{sign_in} o %{sign_up}." + sign_in: "iniciar sesión" + sign_up: "registrarte" tab: participants: Participantes sidebar: participate: Participa new_topic: Crea un tema - disabled_info_title: Necesitas estar logueado para crear un nuevo tema topic: - edit_button: Editar - destroy_button: Eliminar + edit: Editar tema + destroy: Eliminar tema comments: + zero: Sin comentarios one: 1 Comentario other: "%{count} Comentarios" - zero: Sin comentarios + author: Autor + back: Volver a %{community} %{proposal} topic: create: Crear un tema edit: Editar tema form: - topic_title: Titulo del tema - topic_description: Descripción + topic_title: Título + topic_text: Texto inicial new: submit_button: Crear tema edit: diff --git a/config/locales/es/devise.yml b/config/locales/es/devise.yml index 6ede31f7d..4b6983051 100644 --- a/config/locales/es/devise.yml +++ b/config/locales/es/devise.yml @@ -37,11 +37,7 @@ es: updated: "Tu contraseña ha cambiado correctamente. Has sido identificado correctamente." updated_not_active: "Tu contraseña se ha cambiado correctamente." registrations: - destroyed: - "¡Adiós! Tu cuenta ha sido cancelada. Esperamos volver a verte pronto. Le informamos que de conformidad con su petición, - sus datos personales registrados como usuario de la Web y que forman parte del fichero 'Fichero' - cuyo responsable es 'Responsable', han sido cancelados en los términos de lo previsto en el artículo 16 de la - Ley Orgánica 15/1999 de Protección de Datos de Carácter Personal y del artículo 31 de su Reglamento de desarrollo (RD 1720/2007)." + destroyed: "¡Adiós! Tu cuenta ha sido cancelada. Esperamos volver a verte pronto. Le informamos que de conformidad con su petición, sus datos personales registrados como usuario de la Web y que forman parte del fichero 'Fichero' cuyo responsable es 'Responsable', han sido cancelados en los términos de lo previsto en el artículo 16 de la Ley Orgánica 15/1999 de Protección de Datos de Carácter Personal y del artículo 31 de su Reglamento de desarrollo (RD 1720/2007)." signed_up: "¡Bienvenido! Has sido identificado." signed_up_but_inactive: "Te has registrado correctamente, pero no has podido iniciar sesión porque tu cuenta no ha sido activada." signed_up_but_locked: "Te has registrado correctamente, pero no has podido iniciar sesión porque tu cuenta está bloqueada." @@ -64,6 +60,6 @@ es: not_found: "no se ha encontrado." not_locked: "no estaba bloqueado." not_saved: - one: "1 error impidió que este %{resource} fuera guardado:" - other: "%{count} errores impidieron que este %{resource} fuera guardado:" + one: "1 error impidió que este %{resource} fuera guardado. Por favor revisa los campos marcados para saber cómo corregirlos:" + other: "%{count} errores impidieron que este %{resource} fuera guardado. Por favor revisa los campos marcados para saber cómo corregirlos:" equal_to_current_password: "debe ser diferente a la contraseña actual" diff --git a/config/locales/es/devise_views.yml b/config/locales/es/devise_views.yml index 184454654..aee940d5f 100644 --- a/config/locales/es/devise_views.yml +++ b/config/locales/es/devise_views.yml @@ -1,4 +1,3 @@ ---- es: devise_views: confirmations: @@ -42,8 +41,8 @@ es: new: email_label: Email organization_name_label: Nombre de la organización - password_confirmation_label: Confirmar contraseña - password_label: Contraseña + password_confirmation_label: Repite la contraseña anterior + password_label: Contraseña que utilizarás para acceder a este sitio web phone_number_label: Teléfono responsible_name_label: Nombre y apellidos de la persona responsable del colectivo responsible_name_note: Será la persona representante de la asociación/colectivo en cuyo nombre se presenten las propuestas @@ -51,7 +50,7 @@ es: title: Registrarse como organización / colectivo success: back_to_index: Entendido, volver a la página principal - instructions_1_html: En breve nos pondremos en contacto contigo para verificar que realmente representas a este colectivo. + instructions_1_html: "En breve nos pondremos en contacto contigo para verificar que realmente representas a este colectivo." instructions_2_html: Mientras revisa tu correo electrónico, te hemos enviado un enlace para confirmar tu cuenta. instructions_3_html: Una vez confirmado, podrás empezar a participar como colectivo no verificado. thank_you_html: Gracias por registrar tu colectivo en la web. Ahora está pendiente de verificación. @@ -65,22 +64,22 @@ es: new: email_label: Email send_submit: Recibir instrucciones - title: "¿Has olvidado tu contraseña?" + title: '¿Has olvidado tu contraseña?' sessions: new: login_label: Email o nombre de usuario - password_label: Contraseña + password_label: Contraseña que utilizarás para acceder a este sitio web remember_me: Recordarme submit: Entrar - title: Entrar + title: Iniciar sesión shared: links: login: Entrar - new_confirmation: "¿No has recibido instrucciones para confirmar tu cuenta?" - new_password: "¿Olvidaste tu contraseña?" - new_unlock: "¿No has recibido instrucciones para desbloquear?" + new_confirmation: '¿No has recibido instrucciones para confirmar tu cuenta?' + new_password: '¿Olvidaste tu contraseña?' + new_unlock: '¿No has recibido instrucciones para desbloquear?' signin_with_provider: Entrar con %{provider} - signup: "¿No tienes una cuenta? %{signup_link}" + signup: '¿No tienes una cuenta? %{signup_link}' signup_link: Regístrate unlocks: new: @@ -91,13 +90,13 @@ es: registrations: delete_form: erase_reason_label: Razón de la baja - info: Esta acción no se puede deshacer. Una vez que des de baja tu cuenta, no podrás volver a hacer login con ella. - info_reason: Si quieres, escribe el motivo por el que te das de baja (opcional). - submit: Borrar mi cuenta + info: Esta acción no se puede deshacer. Una vez que des de baja tu cuenta, no podrás volver a entrar con ella. + info_reason: Si quieres, escribe el motivo por el que te das de baja (opcional) + submit: Darme de baja title: Darme de baja edit: current_password_label: Contraseña actual - edit: Editar + edit: Editar propuesta email_label: Email leave_blank: Dejar en blanco si no deseas cambiarla need_current: Necesitamos tu contraseña actual para confirmar los cambios @@ -108,7 +107,7 @@ es: new: cancel: Cancelar login email_label: Tu correo electrónico - organization_signup: "¿Representas a una organización / colectivo? %{signup_link}" + organization_signup: '¿Representas a una organización / colectivo? %{signup_link}' organization_signup_link: Regístrate aquí password_confirmation_label: Repite la contraseña anterior password_label: Contraseña que utilizarás para acceder a este sitio web @@ -118,8 +117,8 @@ es: terms_link: condiciones de uso terms_title: Al registrarte aceptas las condiciones de uso title: Registrarse - username_is_available: "Nombre de usuario disponible" - username_is_not_available: "Nombre de usuario ya existente" + username_is_available: Nombre de usuario disponible + username_is_not_available: Nombre de usuario ya existente username_label: Nombre de usuario username_note: Nombre público que aparecerá en tus publicaciones success: diff --git a/config/locales/es/documents.yml b/config/locales/es/documents.yml index a0b646ecc..bd3866137 100644 --- a/config/locales/es/documents.yml +++ b/config/locales/es/documents.yml @@ -2,33 +2,23 @@ es: documents: tab: Documentos no_documents: No hay documentos subidos - upload_document: Subir documento - max_documents_allowed_reached_html: ¡Has alcanzado el número máximo de documentos permitidos! Tienes que eliminar uno antes de poder subir otro. + max_documents_allowed_reached_html: '¡Has alcanzado el número máximo de documentos permitidos! Tienes que eliminar uno antes de poder subir otro.' form: title: Documentos + title_placeholder: Añade un título descriptivo para el documento attachment_label: Selecciona un documento - submit_button: Subir documento delete_button: Eliminar documento - note: "Puedes subir hasta un máximo de %{max_documents_allowed} documentos en los formatos: %{accepted_content_types}, y de hasta %{max_file_size} MB por archivo." + note: 'Puedes subir hasta un máximo de %{max_documents_allowed} documentos en los formatos: %{accepted_content_types}, y de hasta %{max_file_size} MB por archivo.' add_new_document: Añadir nuevo documento - new: - title: Subir un documento - recommendations_title: Consejos para subir archivos - recommendation_one_html: Puedes subir hasta un máximo de %{max_documents_allowed} documentos - recommendation_two_html: Sólo puedes subir archivos %{accepted_content_types}. - recommendation_three_html: Puedes subir archivos de hasta %{max_file_size} MB actions: - create: - notice: "El documento se ha creado correctamente." - alert: "El documento no se ha podido crear. Revise los errores del formulario." destroy: - notice: "El documento se ha eliminado correctamente." - alert: "El documento no se ha podido eliminar." - confirm: "¿Está seguro de que desea eliminar el documento? Esta acción no se puede deshacer!" + notice: El documento se ha eliminado correctamente. + alert: El documento no se ha podido eliminar. + confirm: '¿Está seguro de que desea eliminar el documento? Esta acción no se puede deshacer!' buttons: download_document: Descargar archivo destroy_document: Eliminar errors: messages: in_between: debe estar entre %{min} y %{max} - wrong_content_type: El tipo de contenido %{content_type} del archivo no coincide con ninguno de los tipos de contenido aceptados %{accepted_content_types} + wrong_content_type: El tipo de contenido %{content_type} del archivo no coincide con ninguno de los tipos de contenido aceptados %{accepted_content_types} \ No newline at end of file diff --git a/config/locales/es/general.yml b/config/locales/es/general.yml index 9f52ccc38..adc6aed49 100644 --- a/config/locales/es/general.yml +++ b/config/locales/es/general.yml @@ -1,4 +1,3 @@ ---- es: account: show: @@ -13,11 +12,9 @@ es: personal: Datos personales phone_number_label: Teléfono public_activity_label: Mostrar públicamente mi lista de actividades - public_interests_label: Mostrar públicamente mis intereses - public_interests_my_title_list: Lista de intereses (Etiquetas de los elementos que sigues) - public_interests_user_title_list: Lista de intereses (Etiquetas de los elementos seguidos este usuario) - public_interests_my_empty_list: Aún no sigues ningún elemento. - public_interests_user_empty_list: Este usuario no sigue ningún elemento todavía. + public_interests_label: Mostrar públicamente las etiquetas de los elementos que sigo + public_interests_my_title_list: Etiquetas de los elementos que sigues + public_interests_user_title_list: Etiquetas de los elementos que sigue este usuario save_changes_submit: Guardar cambios subscription_to_website_newsletter_label: Recibir emails con información interesante sobre la web email_on_direct_message_label: Recibir emails con mensajes privados @@ -48,14 +45,14 @@ es: deleted: Este comentario ha sido eliminado moderator: Moderador responses: + zero: Sin respuestas one: 1 Respuesta other: "%{count} Respuestas" - zero: Sin respuestas user_deleted: Usuario eliminado votes: + zero: Sin votos one: 1 voto other: "%{count} votos" - zero: Sin votos form: comment_as_admin: Comentar como administrador comment_as_moderator: Comentar como moderador @@ -80,13 +77,13 @@ es: submit_button: Empieza un debate debate: comments: + zero: Sin comentarios one: 1 Comentario other: "%{count} Comentarios" - zero: Sin comentarios votes: + zero: Sin votos one: 1 voto other: "%{count} votos" - zero: Sin votos edit: editing: Editar debate form: @@ -99,7 +96,7 @@ es: tags_label: Temas tags_placeholder: "Escribe las etiquetas que desees separadas por coma (',')" index: - featured_debates: Destacados + featured_debates: Destacar filter_topic: one: " con el tema '%{topic}'" other: " con el tema '%{topic}'" @@ -109,6 +106,10 @@ es: hot_score: Más activos hoy most_commented: Más comentados relevance: Más relevantes + recommendations: Recomendaciones + recommendations: + without_results: No existen debates relacionados con tus intereses + without_interests: Sigue propuestas para que podamos darte recomendaciones search_form: button: Buscar placeholder: Buscar debates... @@ -146,20 +147,21 @@ es: show: author_deleted: Usuario eliminado comments: + zero: Sin comentarios one: 1 Comentario other: "%{count} Comentarios" - zero: Sin comentarios comments_title: Comentarios edit_debate_link: Editar debate flag: Este debate ha sido marcado como inapropiado por varios usuarios. login_to_comment: Necesitas %{signin} o %{signup} para comentar. share: Compartir + author: Autor update: form: submit_button: Guardar cambios errors: messages: - user_not_found: No se encontró el usuario + user_not_found: Usuario no encontrado invalid_date_range: "El rango de fechas no es válido" form: accept_terms: Acepto la %{policy} y las %{conditions} @@ -169,18 +171,21 @@ es: direct_message: el mensaje privado error: error errors: errores - not_saved: 'impidieron guardar %{resource}:' + not_saved_html: "impidieron guardar %{resource}.
Por favor revisa los campos marcados para saber cómo corregirlos:" policy: Política de privacidad proposal: la propuesta proposal_notification: "la notificación" spending_proposal: la propuesta de gasto budget/investment: la propuesta de inversión + budget/heading: la partida presupuestaria poll/shift: el turno + poll/question/answer: la respuesta user: la cuenta verification/sms: el teléfono signature_sheet: la hoja de firmas document: el documento topic: Tema + image: Imagen geozones: none: Toda la ciudad all: Todos los ámbitos de actuación @@ -194,34 +199,34 @@ es: accessibility: Accesibilidad conditions: Condiciones de uso consul: aplicación CONSUL - consul_url: https://github.com/consul/consul + consul_url: 'https://github.com/consul/consul' contact_us: Para asistencia técnica entra en copyright: CONSUL, %{year} description: Este portal usa la %{consul} que es %{open_source}. faq: Asistencia técnica open_data_text: Todos los datos del Ayuntamiento son tuyos. open_data_title: Datos Abiertos - open_source: software libre - open_source_url: http://www.gnu.org/licenses/agpl-3.0.html + open_source: software de código abierto + open_source_url: 'http://www.gnu.org/licenses/agpl-3.0.html' participation_text: Decide cómo debe ser la ciudad que quieres. participation_title: Participación privacy: Política de privacidad transparency_text: Obtén cualquier información sobre la ciudad. transparency_title: Transparencia - transparency_url: https://transparency.consul + transparency_url: 'https://transparency.consul' header: administration_menu: Admin - administration: Administrar + administration: Administración available_locales: Idiomas disponibles collaborative_legislation: Procesos legislativos debates: Debates external_link_blog: Blog external_link_opendata: Datos abiertos - external_link_opendata_url: https://opendata.consul + external_link_opendata_url: 'https://opendata.consul' external_link_transparency: Transparencia - external_link_transparency_url: https://transparency.consul + external_link_transparency_url: 'https://transparency.consul' locale: 'Idioma:' - logo: CONSUL logo + logo: Logo de CONSUL management: Gestión moderation: Moderar valuation: Evaluación @@ -233,7 +238,7 @@ es: new_notifications: one: Tienes una nueva notificación other: Tienes %{count} notificaciones nuevas - no_notifications: No tienes notificaciones nuevas + no_notifications: "No tienes notificaciones nuevas" open: abierto open_city_slogan_html: Existen ciudades gobernadas directamente por sus habitantes, que debaten sobre temas que les preocupan, proponen ideas para mejorar sus vidas y deciden entre todas y todos las que se llevan a cabo. open_city_title: La ciudad que quieres será la ciudad que quieras @@ -241,7 +246,7 @@ es: proposals: Propuestas poll_questions: Votaciones budgets: Presupuestos participativos - spending_proposals: "Propuestas de inversión" + spending_proposals: Propuestas de inversión admin: watch_form_message: 'Has realizado cambios que no han sido guardados. ¿Seguro que quieres abandonar la página?' legacy_legislation: @@ -250,7 +255,7 @@ es: text: Para comentar este documento debes %{sign_in} o %{sign_up}. Después selecciona el texto que quieres comentar y pulsa en el botón con el lápiz. text_sign_in: iniciar sesión text_sign_up: registrarte - title: "¿Cómo puedo comentar este documento?" + title: '¿Cómo puedo comentar este documento?' locale: Español notifications: index: @@ -258,6 +263,7 @@ es: one: Hay un nuevo comentario en other: Hay %{count} comentarios nuevos en empty_notifications: No tienes notificaciones nuevas. + notifiable_hidden: Este elemento ya no está disponible. mark_all_as_read: Marcar todas como leídas proposal_notification: one: Hay una nueva notificación en @@ -269,7 +275,7 @@ es: map: title: "Distritos" proposal_for_district: "Crea una propuesta para tu distrito" - select_district: "Ámbito de actuación" + select_district: Ámbito de actuación start_proposal: Crea una propuesta omniauth: facebook: @@ -277,7 +283,8 @@ es: sign_up: Regístrate con Facebook name: Facebook finish_signup: - title: Añade tu email + title: "Detalles adicionales de tu cuenta" + username_warning: "Debido a que hemos cambiado la forma en la que nos conectamos con redes sociales y es posible que tu nombre de usuario aparezca como 'ya en uso', incluso si antes podías acceder con él. Si es tu caso, por favor elige un nombre de usuario distinto." google_oauth2: sign_in: Entra con Google sign_up: Regístrate con Google @@ -289,9 +296,6 @@ es: info_sign_in: "Entra con:" info_sign_up: "Regístrate con:" or_fill: "O rellena el siguiente formulario:" - finish_signup: - title: "Detalles adicionales de tu cuenta" - username_warning: "Debido a que hemos cambiado la forma en la que nos conectamos con redes sociales y es posible que tu nombre de usuario aparezca como 'ya en uso', incluso si antes podías acceder con él. Si es tu caso, por favor elige un nombre de usuario distinto." proposals: create: form: @@ -316,7 +320,7 @@ es: done: Realizada other: Otra form: - geozone: "Ámbito de actuación" + geozone: Ámbito de actuación proposal_external_url: Enlace a documentación adicional proposal_question: Pregunta de la propuesta proposal_question_example_html: "Debe ser resumida en una pregunta cuya respuesta sea Sí o No.
Ej. '¿Está usted de acuerdo en peatonalizar la calle Mayor?'" @@ -328,10 +332,14 @@ es: proposal_title: Título de la propuesta proposal_video_url: Enlace a vídeo externo proposal_video_url_note: Puedes añadir un enlace a YouTube o Vimeo + tag_category_label: "Categorías" tags_instructions: "Etiqueta esta propuesta. Puedes elegir entre las categorías propuestas o introducir las que desees" tags_label: Temas - tag_category_label: "Categorías" tags_placeholder: "Escribe las etiquetas que desees separadas por una coma (',')" + map_location: "Ubicación en el mapa" + map_location_instructions: "Navega por el mapa hasta la ubicación y coloca el marcador." + map_remove_marker: "Eliminar el marcador" + map_skip_checkbox: "Esta propuesta no tiene una ubicación concreta o no la conozco." index: featured_proposals: Destacadas filter_topic: @@ -344,6 +352,10 @@ es: most_commented: Más comentadas relevance: Más relevantes archival_date: Archivadas + recommendations: Recomendaciones + recommendations: + without_results: No existen propuestas relacionadas con tus intereses + without_interests: Sigue propuestas para que podamos darte recomendaciones retired_proposals: Propuestas retiradas retired_proposals_link: "Propuestas retiradas por sus autores" retired_links: @@ -361,7 +373,7 @@ es: one: " que contiene '%{search_term}'" other: " que contienen '%{search_term}'" select_order: Ordenar por - select_order_long: Estas viendo las propuestas + select_order_long: 'Estas viendo las propuestas' start_proposal: Crea una propuesta title: Propuestas ciudadanas top: Top semanal @@ -379,7 +391,7 @@ es: new: form: submit_button: Crear propuesta - more_info: "¿Cómo funcionan las propuestas ciudadanas?" + more_info: '¿Cómo funcionan las propuestas ciudadanas?' recommendation_one: No escribas el título de la propuesta o frases enteras en mayúsculas. En internet eso se considera gritar. Y a nadie le gusta que le griten. recommendation_three: Disfruta de este espacio, de las voces que lo llenan, también es tuyo. recommendation_two: Cualquier propuesta o comentario que implique una acción ilegal será eliminada, también las que tengan la intención de sabotear los espacios de propuesta, todo lo demás está permitido. @@ -390,23 +402,27 @@ es: proposal: created: "¡Has creado una propuesta!" share: - guide: "Compártela para que la gente empieze a apoyarla." + guide: "Compártela para que la gente empiece a apoyarla." edit: "Antes de que se publique podrás modificar el texto a tu gusto." - view_proposal: "Ahora no, ir a mi propuesta" + view_proposal: Ahora no, ir a mi propuesta improve_info: "Mejora tu campaña y consigue más apoyos" improve_info_link: "Ver más información" - already_supported: "¡Ya has apoyado esta propuesta, compártela!" + already_supported: '¡Ya has apoyado esta propuesta, compártela!' comments: + zero: Sin comentarios one: 1 Comentario other: "%{count} Comentarios" - zero: Sin comentarios reason_for_supports_necessary: 1% del Censo support: Apoyar support_title: Apoyar esta propuesta supports: + zero: Sin apoyos one: 1 apoyo other: "%{count} apoyos" - zero: Sin apoyos + votes: + zero: Sin votos + one: 1 voto + other: "%{count} votos" supports_necessary: "%{number} apoyos necesarios" total_percent: 100% archived: "Esta propuesta ha sido archivada y ya no puede recoger apoyos." @@ -416,9 +432,9 @@ es: author_deleted: Usuario eliminado code: 'Código de la propuesta:' comments: + zero: Sin comentarios one: 1 Comentario other: "%{count} Comentarios" - zero: Sin comentarios comments_tab: Comentarios edit_proposal_link: Editar propuesta flag: Esta propuesta ha sido marcada como inapropiada por varios usuarios. @@ -427,8 +443,8 @@ es: retired_warning: "El autor de esta propuesta considera que ya no debe seguir recogiendo apoyos." retired_warning_link_to_explanation: Revisa su explicación antes de apoyarla. retired: Propuesta retirada por el autor - send_notification: Enviar notificación share: Compartir + send_notification: Enviar notificación no_notifications: "Esta propuesta no tiene notificaciones." embed_video_title: "Vídeo en %{proposal}" title_external_url: "Documentación adicional" @@ -453,11 +469,7 @@ es: participate_button_expired: "Votación terminada" no_geozone_restricted: "Toda la ciudad" geozone_restricted: "Distritos" - geozone_info: "Pueden participar las personas empadronadas en: " - can_answer: "¡Puedes participar en esta votación!" - cant_answer: "Esta votación no está disponible en tu zona" - cant_answer_not_logged_in: "Necesitas iniciar sesión o registrarte para participar" - cant_answer_verify: "Por favor verifica tu cuenta para poder responder" + geozone_info: 'Pueden participar las personas empadronadas en: ' already_answer: "Ya has participado en esta votación" section_header: icon_alt: Icono de Votaciones @@ -469,24 +481,12 @@ es: help_text_1: "Las votaciones se convocan cuando una propuesta ciudadana alcanza el 1% de apoyos del censo con derecho a voto. En las votaciones también se pueden incluir cuestiones que el Ayuntamiento somete a decisión directa de la ciudadanía." help_text_2: "Para participar en la próxima votación tienes que registrarte en %{org} y verificar tu cuenta. Pueden votar todas las personas empadronadas en la ciudad mayores de 16 años. Los resultados de todas las votaciones serán vinculantes para el gobierno." show: - dates_title: "Fechas de participación" + already_voted_in_booth: "Ya has participado en esta votación en urnas presenciales, no puedes volver a participar." + already_voted_in_web: "Ya has participado en esta votación. Si vuelves a votar se sobreescribirá tu resultado anterior." + back: Volver a votaciones cant_answer_not_logged_in: "Necesitas %{signin} o %{signup} para participar." - signin: iniciar sesión - signup: registrarte - cant_answer_verify_html: "Por favor %{verify_link} para poder responder." - verify_link: "verifica tu cuenta" - cant_answer_incoming: "Esta votación todavía no ha comenzado." - cant_answer_expired: "Esta votación ha terminado." - poll_questions: - create_question: "Crear pregunta para votación" - default_valid_answers: "Sí, No" - show: - answer_this_question: "Responder a esta pregunta" - original_proposal: "Propuesta original" - author: "Creado por" - dates_title: "Fechas de participación" - more_info: "Más información" - not_logged_in: "Necesitas %{signin} o %{signup} para participar." + comments_tab: Comentarios + login_to_comment: Necesitas %{signin} o %{signup} para comentar. signin: iniciar sesión signup: registrarte cant_answer_verify_html: "Por favor %{verify_link} para poder responder." @@ -494,9 +494,36 @@ es: cant_answer_incoming: "Esta votación todavía no ha comenzado." cant_answer_expired: "Esta votación ha terminado." cant_answer_wrong_geozone: "Esta votación no está disponible en tu zona." + more_info_title: "Más información" + documents: Documentación + zoom_plus: Ampliar imagen + read_more: "Leer más sobre %{answer}" + read_less: "Leer menos sobre %{answer}" + participate_in_other_polls: Participar en otras votaciones + videos: "Vídeo externo" + info_menu: "Información" + stats_menu: "Estadísticas de participación" + results_menu: "Resultados de la votación" + stats: + title: "Datos de participación" + total_participation: "Participación total" + total_votes: "Nº total de votos emitidos" + votes: "VOTOS" + web: "WEB" + booth: "URNAS" + total: "TOTAL" + valid: "Válidos" + white: "En blanco" + null_votes: "Nulos" + results: + title: "Preguntas" + most_voted_answer: 'Respuesta más votada: ' + poll_questions: + create_question: "Crear pregunta" + show: vote_answer: "Votar %{answer}" voted: "Has votado %{answer}" - poll: "Votación" + voted_token: "Puedes apuntar este identificador de voto, para comprobar tu votación en el resultado final:" proposal_notifications: new: title: "Enviar mensaje" @@ -510,13 +537,10 @@ es: shared: edit: 'Editar' save: 'Guardar' - delete: 'Borrar' - comments: - title: 'Comentarios' - login_to_comment: 'Necesitas %{signin} o %{signup} para comentar.' - "yes": "Sí" + delete: Borrar + "yes": "Si" "no": "No" - search_results: "Resultados de búsqueda" + search_results: "Resultados de la búsqueda" advanced_search: author_type: 'Por categoría de autor' author_type_blank: 'Elige una categoría' @@ -534,7 +558,6 @@ es: search: 'Filtrar' title: 'Búsqueda avanzada' to: 'Hasta' - delete: 'Borrar' author_info: author_deleted: Usuario eliminado back: Volver @@ -544,6 +567,7 @@ es: collective: Colectivo flag: Denunciar como inapropiado follow: "Seguir" + following: "Siguiendo" follow_entity: "Seguir %{entity}" followable: budget_investment: @@ -552,10 +576,10 @@ es: destroy: notice_html: "¡Has dejado de seguir este proyecto de inverisión! Ya no recibirás más notificaciones relacionadas con este proyecto." proposal: - create: - notice_html: "¡Ahora estás siguiendo esta propuesta ciudadana! Te notificaremos los cambios a medida que se produzcan para que estés al día." - destroy: - notice_html: "¡Has dejado de seguir esta propuesta ciudadana! Ya no recibirás más notificaciones relacionadas con esta propuesta." + create: + notice_html: "¡Ahora estás siguiendo esta propuesta ciudadana! Te notificaremos los cambios a medida que se produzcan para que estés al día." + destroy: + notice_html: "¡Has dejado de seguir esta propuesta ciudadana! Ya no recibirás más notificaciones relacionadas con esta propuesta." hide: Ocultar print: print_button: Imprimir esta información @@ -588,12 +612,16 @@ es: target_blank_html: " (se abre en ventana nueva)" you_are_in: "Estás en" unflag: Deshacer denuncia - unfollow: Dejar de seguir unfollow_entity: "Dejar de seguir %{entity}" outline: budget: Presupuestos participativos searcher: Buscador go_to_page: "Ir a la página de " + share: Compartir + orbit: + previous_slide: Imagen anterior + next_slide: Siguiente imagen + documentation: Documentación adicional social: blog: "Blog de %{org}" facebook: "Facebook de %{org}" @@ -608,7 +636,7 @@ es: association_name: 'Nombre de la asociación' description: Descripción detallada external_url: Enlace a documentación adicional - geozone: "Ámbito de actuación" + geozone: Ámbito de actuación submit_buttons: create: Crear new: Crear @@ -616,7 +644,7 @@ es: index: title: Presupuestos participativos unfeasible: Propuestas de inversión no viables - by_geozone: "Propuestas de inversión con ámbito: %{geozone}" + by_geozone: 'Propuestas de inversión con ámbito: %{geozone}' search_form: button: Buscar placeholder: Propuestas de inversión... @@ -630,7 +658,7 @@ es: unfeasible: No viables start_spending_proposal: Crea una propuesta de inversión new: - more_info: "¿Cómo funcionan los presupuestos participativos?" + more_info: '¿Cómo funcionan los presupuestos participativos?' recommendation_one: Es fundamental que haga referencia a una actuación presupuestable. recommendation_three: Intenta detallar lo máximo posible la propuesta para que el equipo de gobierno encargado de estudiarla tenga las menor dudas posibles. recommendation_two: Cualquier propuesta o comentario que implique acciones ilegales será eliminada. @@ -647,9 +675,9 @@ es: support: Apoyar support_title: Apoyar este proyecto supports: + zero: Sin apoyos one: 1 apoyo other: "%{count} apoyos" - zero: Sin apoyos stats: index: visits: Visitas @@ -669,11 +697,11 @@ es: users: direct_messages: new: - body_label: "Mensaje" + body_label: Mensaje direct_messages_bloqued: "Este usuario ha decidido no recibir mensajes privados" - submit_button: "Enviar mensaje" + submit_button: Enviar mensaje title: Enviar mensaje privado a %{receiver} - title_label: "Título" + title_label: Título verified_only: Para enviar un mensaje privado %{verify_account} verify_account: verifica tu cuenta authenticate: Necesitas %{signin} o %{signup}. @@ -686,6 +714,11 @@ es: deleted_debate: Este debate ha sido eliminado deleted_proposal: Esta propuesta ha sido eliminada deleted_budget_investment: Esta propuesta de inversión ha sido eliminada + proposals: Propuestas + debates: Debates + budget_investments: Proyectos de presupuestos participativos + comments: Comentarios + actions: Acciones filters: comments: one: 1 Comentario @@ -704,7 +737,7 @@ es: other: "%{count} Siguiendo" no_activity: Usuario sin actividad pública no_private_messages: "Este usuario no acepta mensajes privados." - private_activity: Este usuario ha decidido mantener en privado su lista de actividades + private_activity: Este usuario ha decidido mantener en privado su lista de actividades. send_private_message: "Enviar un mensaje privado" proposals: send_notification: "Enviar notificación" @@ -749,10 +782,20 @@ es: proposal: description: Espacio abierto para propuestas ciudadanas sobre el tipo de ciudad en el que queremos vivir. title: Propones + recommended: + title: Recomendaciones que te pueden interesar + debates: + title: Debates recomendados + btn_text_link: Todos los debates recomendados + proposals: + title: Propuestas recomendadas + btn_text_link: Todas las propuestas recomendadas + budget_investments: + title: Presupuestos recomendados verification: i_dont_have_an_account: No tengo cuenta, quiero crear una y verificarla i_have_an_account: Ya tengo una cuenta que quiero verificar - question: ¿Tienes ya una cuenta en %{org_name}? + question: '¿Tienes ya una cuenta en %{org_name}?' title: Verificación de cuenta welcome: go_to_index: Ahora no, ver propuestas @@ -768,3 +811,18 @@ es: invisible_captcha: sentence_for_humans: "Si eres humano, por favor ignora este campo" timestamp_error_message: "Eso ha sido demasiado rápido. Por favor, reenvía el formulario." + related_content: + title: "Contenido relacionado" + add: "Añadir contenido relacionado" + label: "Enlace a contenido relacionado" + placeholder: "%{url}" + help: "Puedes introducir cualquier enlace de %{models} que esté dentro de %{org}." + submit: "Añadir" + error: "Enlace no válido. Recuerda que debe empezar por %{url}." + success: "Has añadido un nuevo contenido relacionado" + is_related: "¿Es contenido relacionado?" + score_positive: "Sí" + score_negative: "No" + content_title: + proposal: "Propuesta" + debate: "Debate" diff --git a/config/locales/es/images.yml b/config/locales/es/images.yml new file mode 100644 index 000000000..290de6563 --- /dev/null +++ b/config/locales/es/images.yml @@ -0,0 +1,21 @@ +es: + images: + remove_image: Eliminar imagen + form: + title: Imagen descriptiva + title_placeholder: Añade un título descriptivo para la imagen + attachment_label: Selecciona una imagen + delete_button: Eliminar imagen + note: 'Puedes subir una imagen en los formatos: %{accepted_content_types}, y de hasta %{max_file_size} MB por archivo.' + add_new_image: Añadir imagen + admin_title: "Imagen" + admin_alt_text: "Texto alternativo para la imagen" + actions: + destroy: + notice: La imagen se ha eliminado correctamente. + alert: La imagen no se ha podido eliminar. + confirm: '¿Está seguro de que desea eliminar la imagen? Esta acción no se puede deshacer!' + errors: + messages: + in_between: debe estar entre %{min} y %{max} + wrong_content_type: El tipo de contenido %{content_type} de la imagen no coincide con ninguno de los tipos de contenido aceptados %{accepted_content_types} diff --git a/config/locales/es/kaminari.yml b/config/locales/es/kaminari.yml index 7cf5bf57e..81c74af68 100644 --- a/config/locales/es/kaminari.yml +++ b/config/locales/es/kaminari.yml @@ -1,23 +1,22 @@ ---- es: helpers: page_entries_info: entry: + zero: Entradas one: entrada other: entradas - zero: entradas more_pages: display_entries: Mostrando %{first} - %{last} de un total de %{total} %{entry_name} one_page: display_entries: + zero: "No se han encontrado %{entry_name}" one: Hay 1 %{entry_name} other: Hay %{count} %{entry_name} - zero: No se han encontrado %{entry_name} views: pagination: + current: Estás en la página first: Primera last: Última next: Siguiente previous: Anterior truncate: "…" - current: Estás en la página diff --git a/config/locales/es/legislation.yml b/config/locales/es/legislation.yml index 4d2a72cf5..e2a6a63a6 100644 --- a/config/locales/es/legislation.yml +++ b/config/locales/es/legislation.yml @@ -1,4 +1,3 @@ ---- es: legislation: annotations: @@ -20,8 +19,8 @@ es: signup: registrarte index: title: Comentarios - see_in_context: Ver en contexto comments_about: Comentarios sobre + see_in_context: Ver en contexto comments_count: one: "%{count} comentario" other: "%{count} comentarios" @@ -49,6 +48,8 @@ es: processes: header: view_process_information: Ver información del proceso + proposals: + empty_proposals: No hay propuestas debate: empty_questions: No hay preguntas participate: Realiza tus aportaciones al debate previo participando en los siguientes temas. @@ -76,7 +77,7 @@ es: phase_not_open: not_open: Esta fase del proceso todavía no está abierta phase_empty: - empty: No hay nada publicado todavía + empty: No hay nada publicado todavía process: see_latest_comments: Ver últimas aportaciones see_latest_comments_title: Aportar a este proceso @@ -86,6 +87,7 @@ es: draft_publication_date: Publicación borrador allegations_dates: Alegaciones result_publication_date: Publicación resultados + proposals_dates: Propuestas questions: comments: comment_button: Publicar respuesta @@ -117,3 +119,8 @@ es: shared: share: Compartir share_comment: Comentario sobre la %{version_name} del borrador del proceso %{process_name} + proposals: + form: + tags_label: "Categorías" + not_verified: "Para votar propuestas %{verify_account}." + closed: "Este proceso se ha cerrado y ya no puede recoger votos." diff --git a/config/locales/es/mailers.yml b/config/locales/es/mailers.yml index dc51148f8..e92774d2b 100644 --- a/config/locales/es/mailers.yml +++ b/config/locales/es/mailers.yml @@ -1,4 +1,3 @@ ---- es: mailers: no_reply: "Este mensaje se ha enviado desde una dirección de correo electrónico que no admite respuestas." @@ -23,7 +22,7 @@ es: title: Nueva respuesta a tu comentario unfeasible_spending_proposal: hi: "Estimado usuario," - new_html: "Por todo ello, te invitamos a que elabores una nueva propuesta que se ajuste a las condiciones de este proceso. Esto lo puedes hacer en este enlace: %{url}." + new_html: 'Por todo ello, te invitamos a que elabores una nueva propuesta que se ajuste a las condiciones de este proceso. Esto lo puedes hacer en este enlace: %{url}.' new_href: "nueva propuesta de inversión" reconsider_html: "Si consideras que la propuesta rechazada cumple los requisitos para mantenerla como propuesta de inversión, podrás comunicarlo, en el plazo de 48 horas, al correo example@consul.es, indicando necesariamente para su tramitación el código %{code} como asunto del correo, correspondiente a tu propuesta." sincerely: "Atentamente" @@ -31,6 +30,16 @@ es: sorry: "Sentimos las molestias ocasionadas y volvemos a darte las gracias por tu inestimable participación." subject: "Tu propuesta de inversión '%{code}' ha sido marcada como inviable" unfeasible_html: "Desde el Ayuntamiento queremos agradecer tu participación en los Presupuestos Participativos. Lamentamos informarte de que tu propuesta '%{title}' quedará excluida de este proceso participativo por el siguiente motivo:" + budget_investment_unfeasible: + hi: "Estimado usuario," + new_html: 'Por todo ello, te invitamos a que elabores un nuevo proyecto de gasto que se ajuste a las condiciones de este proceso. Esto lo puedes hacer en este enlace: %{url}.' + new_href: "nueva propuesta de inversión" + reconsider_html: "Si consideras que el proyecto rechazado cumple los requisitos para mantenerlo como proyecto de gasto, podrás comunicarlo, en el plazo de 48 horas, al correo example@consul.es, indicando necesariamente para su tramitación el código %{code} como asunto del correo, correspondiente a tu proyecto." + sincerely: "Atentamente" + signatory: "DIRECCIÓN GENERAL DE PARTICIPACIÓN CIUDADANA" + sorry: "Sentimos las molestias ocasionadas y volvemos a darte las gracias por tu inestimable participación." + subject: "Tu propuesta de inversión '%{code}' ha sido marcada como inviable" + unfeasible_html: "Desde el Ayuntamiento queremos agradecer tu participación en los Presupuestos Participativos. Lamentamos informarte de que tu proyecto '%{title}' quedará excluido de este proceso participativo por el siguiente motivo:" proposal_notification_digest: info: "A continuación te mostramos las nuevas notificaciones que han publicado los autores de las propuestas que estás apoyando en %{org_name}." title: "Notificaciones de propuestas en %{org_name}" @@ -63,16 +72,6 @@ es: sincerely: "Atentamente," signatory: "DIRECCIÓN GENERAL DE PARTICIPACIÓN CIUDADANA" share: "Comparte tu proyecto" - budget_investment_unfeasible: - hi: "Estimado usuario," - new_html: "Por todo ello, te invitamos a que elabores un nuevo proyecto de gasto que se ajuste a las condiciones de este proceso. Esto lo puedes hacer en este enlace: %{url}." - new_href: "nueva propuesta de inversión" - reconsider_html: "Si consideras que el proyecto rechazado cumple los requisitos para mantenerlo como proyecto de gasto, podrás comunicarlo, en el plazo de 48 horas, al correo example@consul.es, indicando necesariamente para su tramitación el código %{code} como asunto del correo, correspondiente a tu proyecto." - sincerely: "Atentamente" - signatory: "DIRECCIÓN GENERAL DE PARTICIPACIÓN CIUDADANA" - sorry: "Sentimos las molestias ocasionadas y volvemos a darte las gracias por tu inestimable participación." - subject: "Tu propuesta de inversión '%{code}' ha sido marcada como inviable" - unfeasible_html: "Desde el Ayuntamiento queremos agradecer tu participación en los Presupuestos Participativos. Lamentamos informarte de que tu proyecto '%{title}' quedará excluido de este proceso participativo por el siguiente motivo:" budget_investment_selected: subject: "Tu propuesta de inversión '%{code}' ha sido seleccionada" hi: "Estimado/a usuario/a" diff --git a/config/locales/es/management.yml b/config/locales/es/management.yml index 87358a438..5b889f2aa 100644 --- a/config/locales/es/management.yml +++ b/config/locales/es/management.yml @@ -1,4 +1,3 @@ ---- es: management: account: @@ -29,7 +28,7 @@ es: not_in_census_info: 'Las personas no empadronadas pueden participar en el Portal de Gobierno Abierto con las siguientes posibilidades:' please_check_account_data: Compruebe que los datos anteriores son correctos para proceder a verificar la cuenta completamente. title: Gestión de usuarios - under_age: No tienes edad suficiente para verificar tu cuenta. + under_age: "No tienes edad suficiente para verificar tu cuenta." verify: Verificar usuario email_label: Email date_of_birth: Fecha de nacimiento @@ -63,12 +62,12 @@ es: support_proposals: Apoyar propuestas vote_proposals: Participar en las votaciones finales print: - proposals_info: Haz tu propuesta en http://url.consul + proposals_info: 'Haz tu propuesta en http://url.consul' proposals_note: Las propuestas más apoyadas serán llevadas a votación. Y si las acepta una mayoría, el Ayuntamiento las llevará a cabo. proposals_title: 'Propuestas:' - spending_proposals_info: Participa en http://url.consul + spending_proposals_info: 'Participa en http://url.consul' spending_proposals_note: Los presupuestos participativos se invertirán en las propuestas de inversión más apoyadas. - budget_investments_info: Participa en http://url.consul + budget_investments_info: 'Participa en http://url.consul' budget_investments_note: Los presupuestos participativos se invertirán en las propuestas de inversión más apoyadas. print_info: Imprimir esta información proposals: @@ -99,7 +98,7 @@ es: create: Crear propuesta de inversión filters: unfeasible: Propuestas de inversión no viables - by_geozone: "Propuestas de inversión con ámbito: %{geozone}" + by_geozone: 'Propuestas de inversión con ámbito: %{geozone}' print: print_button: Imprimir search_results: @@ -115,17 +114,17 @@ es: create_user_submit: Crear usuario create_user_success_html: Hemos enviado un correo electrónico a %{email} para verificar que es suya. El correo enviado contiene un link que el usuario deberá pulsar. Entonces podrá seleccionar una clave de acceso, y entrar en la web de participación. autogenerated_password_html: "Se ha asignado la contraseña %{password} a este usuario. Puede modificarla desde el apartado 'Mi cuenta' de la web." - email_optional_label: "Email (recomendado pero opcional)" + email_optional_label: Email (recomendado pero opcional) erased_notice: Cuenta de usuario borrada. - erased_by_manager: "Borrada por el manager: %{manager}" + erased_by_manager: 'Borrada por el manager: %{manager}' erase_account_link: Borrar cuenta - erase_account_confirm: ¿Seguro que quieres borrar a este usuario? Esta acción no se puede deshacer - erase_warning: Esta acción no se puede deshacer. Por favor asegurese de que quiere eliminar esta cuenta. + erase_account_confirm: '¿Seguro que quieres borrar a este usuario? Esta acción no se puede deshacer' + erase_warning: Esta acción no se puede deshacer. Por favor asegúrese de que quiere eliminar esta cuenta. erase_submit: Borrar cuenta user_invites: new: label: Emails - info: "Introduce los emails separados por ','" + info: "Introduce los emails separados por comas (',')" submit: Enviar invitaciones title: Invitaciones para usuarios create: diff --git a/config/locales/es/moderation.yml b/config/locales/es/moderation.yml index b41ba0fbf..43fc98790 100644 --- a/config/locales/es/moderation.yml +++ b/config/locales/es/moderation.yml @@ -1,13 +1,10 @@ ---- es: moderation: - header: - title: Moderación comments: index: block_authors: Bloquear autores - confirm: "¿Estás seguro?" - filter: Filtrar + confirm: '¿Estás seguro?' + filter: Filtro filters: all: Todos pending_flag_review: Pendientes @@ -24,11 +21,11 @@ es: title: Comentarios dashboard: index: - title: Moderación + title: Moderar debates: index: block_authors: Bloquear autores - confirm: "¿Estás seguro?" + confirm: '¿Estás seguro?' filter: Filtrar filters: all: Todos @@ -44,6 +41,8 @@ es: created_at: Más nuevos flags: Más denunciados title: Debates + header: + title: Moderación menu: flagged_comments: Comentarios flagged_debates: Debates @@ -52,7 +51,7 @@ es: proposals: index: block_authors: Bloquear autores - confirm: "¿Estás seguro?" + confirm: '¿Estás seguro?' filter: Filtro filters: all: Todas diff --git a/config/locales/es/officing.yml b/config/locales/es/officing.yml index 74358ab56..6832311a7 100644 --- a/config/locales/es/officing.yml +++ b/config/locales/es/officing.yml @@ -1,4 +1,3 @@ ---- es: officing: header: @@ -8,28 +7,26 @@ es: title: Presidir mesa de votaciones info: Aquí puedes validar documentos de ciudadanos y guardar los resultados de las urnas menu: - voters: "Validar documento y votar" - total_recounts: "Recuento total y escrutinio" + voters: Validar documento y votar + total_recounts: Recuento total y escrutinio polls: final: - title: "Listado de votaciones finalizadas" - no_polls: "No tienes permiso para recuento final en ninguna votación reciente" - select_poll: "Selecciona votación" - add_results: "Añadir resultados" + title: Listado de votaciones finalizadas + no_polls: No tienes permiso para recuento final en ninguna votación reciente + select_poll: Selecciona votación + add_results: Añadir resultados results: flash: create: "Datos guardados" error_create: "Resultados NO añadidos. Error en los datos" error_wrong_booth: "Urna incorrecta. Resultados NO guardados." - error_wrong_date: "Fecha incorrecta. Resultados NO guardados." new: title: "%{poll} - Añadir resultados" not_allowed: "No tienes permiso para introducir resultados" booth: "Urna" date: "Día" select_booth: "Elige urna" - select_date: "Elige día" - ballots_white: "Papeletas en blanco" + ballots_white: "Papeletas totalmente en blanco" ballots_null: "Papeletas nulas" ballots_total: "Papeletas totales" submit: "Guardar" @@ -37,12 +34,12 @@ es: see_results: "Ver resultados" index: no_results: "No hay resultados" - results: "Resultados" + results: Resultados table_answer: Respuesta table_votes: Votos - table_whites: Papeletas en blanco - table_nulls: Papeletas nulas - table_total: Papeletas totales + table_whites: "Papeletas totalmente en blanco" + table_nulls: "Papeletas nulas" + table_total: "Papeletas totales" residence: flash: create: "Documento verificado con el Padrón" @@ -51,16 +48,19 @@ es: title: Validar documento document_number: "Número de documento (incluida letra)" submit: Validar documento - error_verifying_census: El Padrón no pudo verificar este documento. + error_verifying_census: "El Padrón no pudo verificar este documento." form_errors: evitaron verificar este documento no_assignments: "Hoy no tienes turno de presidente de mesa" voters: new: title: Votaciones table_poll: Votación - table_actions: Estado de las votaciones + table_status: Estado de las votaciones + table_actions: Acciones show: can_vote: Puede votar - error_already_voted: "Ya ha participado en esta votación." + error_already_voted: Ya ha participado en esta votación. submit: Confirmar voto success: "¡Voto introducido!" + can_vote: + submit_disable_with: "Espera, confirmando voto..." diff --git a/config/locales/es/pages.yml b/config/locales/es/pages.yml index d67568b2d..a3e0db7e0 100644 --- a/config/locales/es/pages.yml +++ b/config/locales/es/pages.yml @@ -1,4 +1,3 @@ ---- es: pages: census_terms: Para verificar la cuenta hay que tener 16 años o más y estar empadronado aportando los datos indicados anteriormente, los cuales serán contrastados. Aceptando el proceso de verificación acepta dar su consentimiento para contrastar dicha información, así como medios de contacto que figuren en dichos ficheros. Los datos aportados serán incorporados y tratados en un fichero indicado anteriormente en las condiciones de uso del portal. @@ -53,7 +52,7 @@ es: button: "Ver preguntas frecuentes" page: title: "Preguntas Frecuentes" - description: "Utiliza esta página para resolver las Preguntas frencuentes a los usuarios del sitio." + description: "Utiliza esta página para resolver las Preguntas frecuentes a los usuarios del sitio." faq_1_title: "Pregunta 1" faq_1_description: "Este es un ejemplo para la descripción de la pregunta uno." other: @@ -62,13 +61,13 @@ es: how_to_use: text: |- Utilízalo en tu municipio libremente o ayúdanos a mejorarlo, es software libre. - + Este Portal de Gobierno Abierto usa la [aplicación CONSUL](https://github.com/consul/consul 'github consul') que es software libre, con [licencia AGPLv3](http://www.gnu.org/licenses/agpl-3.0.html 'AGPLv3 gnu' ), esto significa en palabras sencillas, que cualquiera puede libremente usar el código, copiarlo, verlo en detalle, modificarlo, y redistribuirlo al mundo con las modificaciones que quiera (manteniendo el que otros puedan a su vez hacer lo mismo). Porque creemos que la cultura es mejor y más rica cuando se libera. - + Si eres programador, puedes ver el código y ayudarnos a mejorarlo en [aplicación CONSUL](https://github.com/consul/consul 'github consul'). titles: how_to_use: Utilízalo en tu municipio - privacy: Política de Privacidad + privacy: Política de privacidad titles: accessibility: Accesibilidad conditions: Condiciones de uso diff --git a/config/locales/es/rails.yml b/config/locales/es/rails.yml index 31cc02e92..e7fa6dd42 100644 --- a/config/locales/es/rails.yml +++ b/config/locales/es/rails.yml @@ -1,58 +1,55 @@ ---- es: date: abbr_day_names: - - dom - - lun - - mar - - mié - - jue - - vie - - sáb + - dom + - lun + - mar + - mié + - jue + - vie + - sáb abbr_month_names: - - - - ene - - feb - - mar - - abr - - may - - jun - - jul - - ago - - sep - - oct - - nov - - dic + - ene + - feb + - mar + - abr + - may + - jun + - jul + - ago + - sep + - oct + - nov + - dic day_names: - - domingo - - lunes - - martes - - miércoles - - jueves - - viernes - - sábado + - domingo + - lunes + - martes + - miércoles + - jueves + - viernes + - sábado formats: default: "%d/%m/%Y" long: "%d de %B de %Y" short: "%d de %b" month_names: - - - - enero - - febrero - - marzo - - abril - - mayo - - junio - - julio - - agosto - - septiembre - - octubre - - noviembre - - diciembre + - enero + - febrero + - marzo + - abril + - mayo + - junio + - julio + - agosto + - septiembre + - octubre + - noviembre + - diciembre order: - - :day - - :month - - :year + - :day + - :month + - :year datetime: distance_in_words: about_x_hours: @@ -86,6 +83,9 @@ es: x_months: one: 1 mes other: "%{count} meses" + x_years: + one: '%{count} año' + other: "%{count} años" x_seconds: one: 1 segundo other: "%{count} segundos" @@ -113,24 +113,27 @@ es: invalid: no es válido less_than: debe ser menor que %{count} less_than_or_equal_to: debe ser menor que o igual a %{count} + model_invalid: 'Error de validación: %{errors}' not_a_number: no es un número not_an_integer: debe ser un entero odd: debe ser impar - record_invalid: 'La validación falló: %{errors}' - restrict_dependent_destroy: - one: No se puede eliminar el registro porque existe un %{record} dependiente - many: No se puede eliminar el registro porque existen %{record} dependientes + required: debe existir taken: ya está en uso - too_long: es demasiado largo (%{count} caracteres máximo) - too_short: es demasiado corto (%{count} caracteres mínimo) - wrong_length: no tiene la longitud correcta (%{count} caracteres exactos) + too_long: + one: es demasiado largo (máximo %{count} caracteres) + other: es demasiado largo (máximo %{count} caracteres) + too_short: + one: es demasiado corto (mínimo %{count} caracteres) + other: es demasiado corto (mínimo %{count} caracteres) + wrong_length: + one: longitud inválida (debería tener %{count} caracteres) + other: longitud inválida (debería tener %{count} caracteres) other_than: debe ser distinto de %{count} - invalid_date: "no es una fecha valida" template: body: 'Se encontraron problemas con los siguientes campos:' header: one: No se pudo guardar este/a %{model} porque se encontró 1 error - other: No se pudo guardar este/a %{model} porque se encontraron %{count} errores + other: "No se pudo guardar este/a %{model} porque se encontraron %{count} errores" helpers: select: prompt: Por favor seleccione @@ -163,10 +166,8 @@ es: quadrillion: mil billones thousand: mil trillion: billón - unit: '' format: - delimiter: '' - precision: 1 + precision: 3 significant: true strip_insignificant_zeros: true storage_units: @@ -174,17 +175,14 @@ es: units: byte: one: Byte - other: Bytes + other: Byte gb: GB kb: KB mb: MB tb: TB percentage: format: - delimiter: '' - precision: - format: - delimiter: '' + format: "%n%" support: array: last_word_connector: " y " @@ -193,8 +191,9 @@ es: time: am: am formats: + datetime: "%d/%m/%Y %H:%M:%S" default: "%A, %d de %B de %Y %H:%M:%S %z" long: "%d de %B de %Y %H:%M" short: "%d de %b %H:%M" - datetime: "%d/%m/%Y %H:%M:%S" + api: "%d-%m-%Y %H" pm: pm \ No newline at end of file diff --git a/config/locales/es/responders.yml b/config/locales/es/responders.yml index 74e3ea20a..cf3d11d6f 100644 --- a/config/locales/es/responders.yml +++ b/config/locales/es/responders.yml @@ -1,4 +1,3 @@ ---- es: flash: actions: @@ -8,8 +7,10 @@ es: direct_message: "Tu mensaje ha sido enviado correctamente." poll: "Votación creada correctamente." poll_booth: "Urna creada correctamente." + poll_question_answer: "Respuesta creada correctamente" + poll_question_answer_video: "Vídeo creado correctamente" proposal: "Propuesta creada correctamente." - proposal_notification: "Tu message ha sido enviado correctamente." + proposal_notification: "Tu mensaje ha sido enviado correctamente." spending_proposal: "Propuesta de inversión creada correctamente. Puedes acceder a ella desde %{activity}" budget_investment: "Propuesta de inversión creada correctamente." signature_sheet: "Hoja de firmas creada correctamente" @@ -19,9 +20,9 @@ es: update: notice: "%{resource_name} actualizado correctamente." debate: "Debate actualizado correctamente." - proposal: "Propuesta actualizada correctamente." poll: "Votación actualizada correctamente." poll_booth: "Urna actualizada correctamente." + proposal: "Propuesta actualizada correctamente." spending_proposal: "Propuesta de inversión actualizada correctamente." budget_investment: "Propuesta de inversión actualizada correctamente" topic: "Tema actualizado correctamente." @@ -30,3 +31,4 @@ es: budget_investment: "Propuesta de inversión eliminada." error: "No se pudo borrar" topic: "Tema eliminado." + poll_question_answer_video: "Vídeo de respuesta eliminado." diff --git a/config/locales/es/settings.yml b/config/locales/es/settings.yml index f0a7b53a2..3473a99dd 100644 --- a/config/locales/es/settings.yml +++ b/config/locales/es/settings.yml @@ -32,6 +32,7 @@ es: twitter_login: Registro con Twitter facebook_login: Registro con Facebook google_login: Registro con Google + proposals: Propuestas debates: Debates polls: Votaciones signature_sheets: Hojas de firmas @@ -39,9 +40,17 @@ es: spending_proposal_features: voting_allowed: Votaciones sobre propuestas de inversión legislation: Legislación + user: + recommendations: Recomendaciones community: Comunidad en propuestas y proyectos de inversión + map: Geolocalización de propuestas y proyectos de inversión + allow_images: Permitir subir y mostrar imágenes + map_latitude: Latitud + map_longitude: Longitud + map_zoom: Zoom mailer_from_name: Nombre email remitente mailer_from_address: Dirección email remitente + meta_title: "Título del sitio (SEO)" meta_description: "Descripción del sitio (SEO)" meta_keywords: "Palabras clave (SEO)" verification_offices_url: URL oficinas verificación diff --git a/config/locales/es/social_share_button.yml b/config/locales/es/social_share_button.yml index 1c49ef4f5..d624f0b0b 100644 --- a/config/locales/es/social_share_button.yml +++ b/config/locales/es/social_share_button.yml @@ -7,7 +7,7 @@ es: douban: "Douban" qq: "Qzone" tqq: "Tqq" - delicious: "Delicious" + delicious: "Delicioso" baidu: "Baidu.com" kaixin001: "Kaixin001.com" renren: "Renren.com" diff --git a/config/locales/es/valuation.yml b/config/locales/es/valuation.yml index b3a5c32ca..5b4f6efd1 100644 --- a/config/locales/es/valuation.yml +++ b/config/locales/es/valuation.yml @@ -1,4 +1,3 @@ ---- es: valuation: header: @@ -25,8 +24,8 @@ es: valuation_open: Abiertas valuating: En evaluación valuation_finished: Evaluación finalizada - title: Propuestas de inversión assigned_to: "Asignadas a %{valuator}" + title: Propuestas de inversión edit: Editar informe valuators_assigned: one: Evaluador asignado @@ -45,7 +44,7 @@ es: heading: Partida dossier: Informe edit_dossier: Editar informe - price: Coste + price: Precio price_first_year: Coste en el primer año currency: "€" feasibility: Viabilidad @@ -60,18 +59,18 @@ es: assigned_valuators: Evaluadores asignados edit: dossier: Informe - price_html: "Coste (%{currency}) (dato público)" + price_html: "Precio (%{currency}) (dato público)" price_first_year_html: "Coste en el primer año (%{currency}) (opcional, dato no público)" - price_explanation_html: "Informe de coste (opcional, dato público)" + price_explanation_html: Informe de coste (opcional, dato público) feasibility: Viabilidad feasible: Viable unfeasible: Inviable undefined_feasible: Sin decidir - feasible_explanation_html: "Informe de inviabilidad (en caso de que lo sea, dato público)" + feasible_explanation_html: Informe de inviabilidad (en caso de que lo sea, dato público) valuation_finished: Informe finalizado - duration_html: "Plazo de ejecución (opcional, dato no público)" - internal_comments_html: "Comentarios y observaciones (para responsables internos, dato no público)" - save: Guardar cambios + duration_html: Plazo de ejecución (opcional, dato no público) + internal_comments_html: Comentarios y observaciones (para responsables internos, dato no público) + save: Guardar Cambios notice: valuate: "Dossier actualizado" spending_proposals: @@ -93,7 +92,7 @@ es: geozone: Ámbito dossier: Informe edit_dossier: Editar informe - price: Coste + price: Precio price_first_year: Coste en el primer año currency: "€" feasibility: Viabilidad @@ -108,18 +107,18 @@ es: assigned_valuators: Evaluadores asignados edit: dossier: Informe - price_html: "Coste (%{currency}) (dato público)" + price_html: "Precio (%{currency}) (dato público)" price_first_year_html: "Coste en el primer año (%{currency}) (opcional, privado)" currency: "€" - price_explanation_html: "Informe de coste (opcional, dato público)" + price_explanation_html: Informe de coste (opcional, dato público) feasibility: Viabilidad feasible: Viable not_feasible: Inviable undefined_feasible: Sin decidir - feasible_explanation_html: "Informe de inviabilidad (en caso de que lo sea, dato público)" + feasible_explanation_html: Informe de inviabilidad (en caso de que lo sea, dato público) valuation_finished: Informe finalizado - time_scope_html: "Plazo de ejecución (opcional, dato no público)" - internal_comments_html: "Comentarios y observaciones (para responsables internos, dato no público)" + time_scope_html: Plazo de ejecución (opcional, dato no público) + internal_comments_html: Comentarios y observaciones (para responsables internos, dato no público) save: Guardar cambios notice: valuate: "Informe actualizado" diff --git a/config/locales/es/verification.yml b/config/locales/es/verification.yml index c08900cdf..120cad17a 100644 --- a/config/locales/es/verification.yml +++ b/config/locales/es/verification.yml @@ -1,4 +1,3 @@ ---- es: verification: alert: @@ -33,7 +32,7 @@ es: office: Verificarte presencialmente en cualquier %{office} offices: Oficina de Atención al Ciudadano send_letter: Solicitar una carta por correo postal - title: "¡Felicidades!" + title: '¡Felicidades!' user_permission_info: Con tu cuenta ya puedes... update: flash: @@ -51,7 +50,7 @@ es: accept_terms_text: Acepto %{terms_url} al Padrón accept_terms_text_title: Acepto los términos de acceso al Padrón date_of_birth: Fecha de nacimiento - document_number: Número de documento + document_number: DNI/Pasaporte/Tarjeta de residencia document_number_help_title: Ayuda document_number_help_text_html: 'DNI: 12345678A
Pasaporte: AAA000001
Tarjeta de residencia: X1234567P' document_type: @@ -76,14 +75,14 @@ es: edit: confirmation_code: Introduce el código que has recibido en tu móvil resend_sms_link: Solicitar un nuevo código - resend_sms_text: "¿No has recibido un mensaje de texto con tu código de confirmación?" + resend_sms_text: '¿No has recibido un mensaje de texto con tu código de confirmación?' submit_button: Enviar title: SMS de confirmación new: phone: Introduce tu teléfono móvil para recibir el código - phone_format_html: "(Ejemplo: 612345678 ó +34612345678)" + phone_format_html: '(Ejemplo: 612345678 ó +34612345678)' phone_note: Sólo usaremos tu teléfono para enviarte un código, nunca te contactaremos. - phone_placeholder: "Ejemplo: 612345678 ó +34612345678" + phone_placeholder: 'Ejemplo: 612345678 ó +34612345678' submit_button: Enviar title: SMS de confirmación update: @@ -100,7 +99,7 @@ es: user_permission_info: Al verificar tus datos podrás... user_permission_proposal: Crear nuevas propuestas user_permission_support_proposal: Apoyar propuestas - user_permission_votes: Participar en las votaciones finales + user_permission_votes: Participar en las votaciones finales* verified_user: form: submit_button: Enviar código @@ -109,4 +108,4 @@ es: explanation: Actualmente disponemos de los siguientes datos en el Padrón, selecciona donde quieres que enviemos el código de confirmación. phone_title: Teléfonos title: Información disponible - use_another_phone: Utilizar otro teléfono + use_another_phone: Utilizar otro teléfono \ No newline at end of file diff --git a/config/locales/fr/activemodel.yml b/config/locales/fr/activemodel.yml index 8cfc22a2e..f22b0077e 100644 --- a/config/locales/fr/activemodel.yml +++ b/config/locales/fr/activemodel.yml @@ -14,10 +14,5 @@ fr: sms: phone: "Téléphone" confirmation_code: "Code de confirmation" - email: - recipient: "Courriel" officing/residence: - document_type: "Type de document" - document_number: "Numéro du document (en incluant les lettres)" year_of_birth: "Année de naissance" - diff --git a/config/locales/fr/activerecord.yml b/config/locales/fr/activerecord.yml index b588d37dc..82e9d180e 100644 --- a/config/locales/fr/activerecord.yml +++ b/config/locales/fr/activerecord.yml @@ -147,6 +147,12 @@ fr: name: Nom locale: Langue body: Contenu + poll/question/answer: + title: Réponse + description: Description + poll/question/answer/video: + title: Titre + url: Vidéo externe errors: models: user: diff --git a/config/locales/fr/admin.yml b/config/locales/fr/admin.yml index ae9a44277..b9cdfcfd3 100644 --- a/config/locales/fr/admin.yml +++ b/config/locales/fr/admin.yml @@ -377,14 +377,39 @@ fr: new: title: "Créer une question" poll_label: "Vote" - valid_answers_note: "Saisir les réponses séparées par des virgules (,)" show: proposal: Proposition originale author: Auteur title: Titre valid_answers: Réponses valides - description: Description + add_answer: Ajouter une réponse + documents: Documents (1) preview: Voir l'aperçu + answers: + title: Réponse + description: Description + videos: Vidéos + video_list: Liste des vidéos + answers: + show: + title: Titre + description: Description + images: Images + images_list: Liste des images + new: + title: Nouvelle réponse + edit: + title: Modifier réponse + videos: + index: + title: Vidéos + add_video: Ajouter une vidéo + video_title: Titre + video_url: Vidéo externe + new: + title: Nouveau vidéo + edit: + title: Modifier la vidéo recounts: index: title: "Dépouillements" diff --git a/config/locales/fr/pages.yml b/config/locales/fr/pages.yml index dcb57d400..61f86a360 100644 --- a/config/locales/fr/pages.yml +++ b/config/locales/fr/pages.yml @@ -1,4 +1,3 @@ ---- fr: pages: census_terms: Pour confirmer ce compte, vous devez être âgé(e) de 16 ans ou plus, et avoir été recensé avec les données indiquées ci-dessus, lesquelles seront vérifiées. En acceptant le processus de vérification, vous donnez également votre consentement au recoupement de cette information, ainsi que les moyens de communication qui figurent dans ce fichier. Les données fournies seront intégrées et traitées dans le fichier indiqué dans les conditions d'utilisations du portail. @@ -7,7 +6,7 @@ fr: more_info: title: "Découvrez %{org_name}" subtitle: "Découvrez tout ce qu'il est possible de faire avec ce site" - guide: "Ce guide explique chaque section de %{org_name}. Vous pouvez avoir plus d'information dans les liens 'Informations détaillées'." + guide: 'Ce guide explique chaque section de %{org_name}. Vous pouvez avoir plus d''information dans les liens ''Informations détaillées''.' menu: debates: "Débats" proposals: "Propositions" @@ -20,7 +19,7 @@ fr: feature_1_link: "vous inscrire sur %{org_name}" feature_2_html: "Les débats peuvent être notés en utilisant les boutons Je suis d'accord ou Je ne suis pas d'accord que vous trouverez dans chacun d'eux." image_alt: "Boutons pour noter les débats" - figcaption: "Les boutons 'Je suis d'accord' et 'Je ne suis pas d'accord' pour noter les débats." + figcaption: 'Les boutons ''Je suis d''accord'' et ''Je ne suis pas d''accord'' pour noter les débats.' proposals: title: "Propositions" description: "Faites une proposition sur ce que vous souhaitez que la mairie entreprenne et soutenez les propositions d'autres personnes." @@ -53,28 +52,12 @@ fr: button: "Voir les questions fréquemment posées" other: how_to_use: "Utiliser %{org_name} dans votre ville" - world: "Participation citoyenne dans le monde" - facts: "Éléments sur la participation citoyenne et la démocratie directe" how_to_use: text: |- Utilisez le librement pour votre gouvernement ou aider nous à l'améliorer, c'est un logiciel libre. - + Ce portail de Gouvernement Ouvert utilise l'[application Consul](https://github.com/consul/consul 'consul github') qui est un logiciel libre, sous [licence AGPLv3](http://www.gnu.org/licenses/agpl-3.0.html 'AGPLv3 gnu' ), ce qui, en quelques mots, signifie que tout le monde peut utiliser le code librement, le copier, le voir en détail, le modifier et le redistribuer avec ces modifications (permettant à d'autres d'en faire de même). Car nous pensons que la culture est meilleure et plus riche quand elle est libre. - + Si vous êtes un développeur, vous pouvez voir le code et nous aider à l'améliorer en allant sur l'[applicationConsul](https://github.com/consul/consul 'consul github'). - titles: - how_to_use: Utilisez-le pour votre gouvernement - privacy: Politique de confidentialité - titles: - accessibility: Accessibilité - conditions: Conditions d'utilisations - more_info: "Plus d'information à propos %{org_name}" - privacy: Politique de confidentialité verify: - code: Code que vous avez reçu par lettre - email: Courriel - info: "Pour vérifier votre compte saisissez vos données d'accès :" - info_code: 'Saisissez maintenant le code reçu par lettre :' - password: Mot de passe - submit: Confirmer mon compte - title: Confirmer mon compte + email: Email diff --git a/config/locales/fr/rails.yml b/config/locales/fr/rails.yml index 43561ec2d..a9ec187bd 100644 --- a/config/locales/fr/rails.yml +++ b/config/locales/fr/rails.yml @@ -1,160 +1,69 @@ -# Files in the config/locales directory are used for internationalization -# and are automatically loaded by Rails. If you want to use locales other -# than English, add the necessary files in this directory. -# -# To use the locales, use `I18n.t`: -# -# I18n.t 'hello' -# -# In views, this is aliased to just `t`: -# -# <%= t('hello') %> -# -# To use a different locale, set it with `I18n.locale`: -# -# I18n.locale = :es -# -# This would use the information in config/locales/es.yml. -# -# To learn more, please read the Rails Internationalization guide -# available at http://guides.rubyonrails.org/i18n.html. - fr: date: abbr_day_names: - - dim - - lun - - mar - - mer - - jeu - - ven - - sam + - dim + - lun + - mar + - mer + - jeu + - ven + - sam abbr_month_names: - - jan - - fév - - mar - - avr - - mai - - jun - - jul - - aoû - - sep - - oct - - nov - - déc + - fév + - mar + - avr + - mai + - jun + - jul + - aoû + - sep + - oct + - nov + - déc + - Déc day_names: - - dimanche - - lundi - - mardi - - mercredi - - jeudi - - vendredi - - samedi + - dimanche + - lundi + - mardi + - mercredi + - jeudi + - vendredi + - samedi formats: default: "%d/%m/%Y" long: "%d %B %Y" short: "%d %b" month_names: - - janvier - - février - - mars - - avril - - mai - - juin - - juillet - - août - - septembre - - octobre - - novembre - - décembre - order: - - :jour - - :mois - - :année + - février + - mars + - avril + - mai + - juin + - Décembre datetime: distance_in_words: - about_x_hours: - one: environ 1 heure - other: environ %{count} heures - about_x_months: - one: environ 1 mois - other: environ %{count} mois - about_x_years: - one: environ 1 an - other: environ %{count} ans - almost_x_years: - one: presque 1 an - other: presque %{count} ans - half_a_minute: demi-minute - less_than_x_minutes: - one: moins d'1 minute - other: moins de %{count} minutes - less_than_x_seconds: - one: moins d'1 seconde - other: moins de %{count} secondes - over_x_years: - one: plus d'1 an - other: plus de %{count} ans - x_days: - one: 1 jour - other: "%{count} jours" x_minutes: one: 1 minute - other: "%{count} minutes" - x_months: - one: 1 mois other: "%{count} mois" - x_seconds: - one: 1 seconde - other: "%{count} secondes" - prompts: - day: Jour - hour: Heure - minute: Minutes - month: Mois - second: Secondes - year: Année + x_years: + one: 1 an + other: "%{count} jours" errors: format: "%{attribute} %{message}" messages: - accepted: doit être accepté - blank: ne peut pas être vide - present: doit être vide - confirmation: ne coïncide pas - empty: ne peut pas être vide - equal_to: doit être égal à %{count} - even: doit être pair - exclusion: est réservé - greater_than: doit être plus grand que %{count} - greater_than_or_equal_to: doit être plus grand que ou égal à %{count} - inclusion: n'est pas inclus dans la liste - invalid: n'est pas valide - less_than: doit être plus petit que %{count} - less_than_or_equal_to: doit être plus petit que ou égal à %{count} - not_a_number: n'est pas un nombre - not_an_integer: doit être un nombre entier - odd: doit être impair - record_invalid: 'La validation a échoué: %{errors}' - restrict_dependent_destroy: - one: Impossible de supprimer l'enregistrement car il existe un %{record} dépendant - many: Impossible de supprimer l'enregistrement car il existe des %{record} dépendants - taken: est déjà utilisé - too_long: est trop long (%{count} caractères maximum) - too_short: est trop court (%{count} caractères minimum) - wrong_length: n'a pas la bonne longueur (%{count} caractères attendus) - other_than: doit être différent de %{count} - invalid_date: "n'est pas une date valide" - template: - body: 'Des problèmes ont été trouvés avec les champs suivants :' - header: - one: Impossible d'enregistrer ce/cette %{model} car 1 erreur a été trouvée - other: Impossible d'enregistrer ce/cette %{model} car %{count} erreurs ont été trouvées + model_invalid: 'La validation omise : %{errors}' + required: doit exister + too_long: + one: est trop long (maximum est de 1 caractère) + other: est trop long (maximum est %{count} caractères) + too_short: + one: est trop long (maximum est de 1 caractère) + other: est trop long (maximum est %{count} caractères) + wrong_length: + one: est la mauvaise longueur (soit 1 caractère) + other: est la longueur incorrecte (devrait être %{count} caractères) helpers: - select: - prompt: Veuillez sélectionner submit: - create: Créer %{model} - submit: Enregistrer %{model} update: Actualiser %{model} number: currency: @@ -181,9 +90,7 @@ fr: quadrillion: quadrillion thousand: mille trillion: trillion - unit: '' format: - delimiter: '' precision: 1 significant: true strip_insignificant_zeros: true @@ -199,10 +106,7 @@ fr: tb: TO percentage: format: - delimiter: '' - precision: - format: - delimiter: '' + format: "%n %" support: array: last_word_connector: " et " @@ -211,8 +115,8 @@ fr: time: am: du matin formats: + datetime: "%d/%m/%Y %H:%M:%S" default: "%A, %d %B %Y %H:%M:%S %z" long: "%d %B %Y %H:%M" short: "%d %b %H:%M" - datetime: "%d/%m/%Y %H:%M:%S" - pm: "de l'après-midi" + pm: de l'après-midi diff --git a/config/locales/fr/responders.yml b/config/locales/fr/responders.yml index 9897e3455..1d1cfae0c 100644 --- a/config/locales/fr/responders.yml +++ b/config/locales/fr/responders.yml @@ -8,6 +8,8 @@ fr: direct_message: "Votre message a été envoyé avec succès." poll: "Vote créé avec succès." poll_booth: "Urne créée avec succès." + poll_question_answer: "Réponse créée avec succès" + poll_question_answer_video: "Vidéo créée avec succès" proposal: "Proposition créée avec succès." proposal_notification: "Votre message a correctement été envoyé." spending_proposal: "Proposition de dépense créée avec succès. Vous pouvez y accéder depuis %{activity}" @@ -27,3 +29,4 @@ fr: spending_proposal: "Proposition de dépense supprimée avec succès." budget_investment: "Budget d'investissement supprimé avec succès." error: "Suppression impossible" + poll_question_answer_video: "Réponse vidéo supprimée avec succès." diff --git a/config/locales/fr/settings.yml b/config/locales/fr/settings.yml index 4eb20ecc5..174d468f5 100644 --- a/config/locales/fr/settings.yml +++ b/config/locales/fr/settings.yml @@ -32,6 +32,7 @@ fr: twitter_login: Se connecter avec Twitter facebook_login: Se connecter avec Facebook google_login: Se connecter avec Google + proposals: Propositions debates: Débats polls: Votes signature_sheets: Feuilles de signature diff --git a/config/locales/fr/valuation.yml b/config/locales/fr/valuation.yml index 1e1941ce2..2894f2393 100644 --- a/config/locales/fr/valuation.yml +++ b/config/locales/fr/valuation.yml @@ -1,4 +1,3 @@ ---- fr: valuation: header: @@ -14,9 +13,9 @@ fr: current: Ouvert finished: Terminé table_name: Nom - table_phase: Phase + table_phase: Phase de table_assigned_investments_valuation_open: Propositions d'investissement assignées avec une évaluation ouverte - table_actions: Actions + table_actions: Statut des votes evaluate: Évaluer budget_investments: index: @@ -35,7 +34,7 @@ fr: table_id: ID table_title: Titre table_heading_name: Nom du titre - table_actions: Actions + table_actions: Statut des votes show: back: Retour title: Propositions d'investissement @@ -62,15 +61,15 @@ fr: dossier: Rapport price_html: "Coût (%{currency})" price_first_year_html: "Coût durant la première année (%{currency}) (optionnel, données non publiques)" - price_explanation_html: "Informations sur le coût (optionnel, données publiques)" + price_explanation_html: Informations sur le coût (optionnel, données publiques) feasibility: Faisabilité feasible: Faisable unfeasible: Infaisable undefined_feasible: Indécis - feasible_explanation_html: "Informations sur la non-viabilité (le cas échéant, données publiques)" + feasible_explanation_html: Informations sur la non-viabilité (le cas échéant, données publiques) valuation_finished: Évaluation terminée - duration_html: "Délai d'exécution (optionnel, données non publiques)" - internal_comments_html: "Commentaires et observations (pour les responsables internes, données non publiques)" + duration_html: Délai d'exécution (optionnel, données non publiques) + internal_comments_html: Commentaires et observations (pour les responsables internes, données non publiques) save: Enregistrer les changements notice: valuate: "Rapport mis-à-jour" @@ -111,17 +110,15 @@ fr: price_html: "Coût (%{currency}) (données publiques)" price_first_year_html: "Coût durant la première année (%{currency}) (optionnel, données non publiques)" currency: "€" - price_explanation_html: "Informations sur le coût (optionnel, données publiques)" + price_explanation_html: Informations sur le coût (optionnel, données publiques) feasibility: Faisabilité feasible: Faisable not_feasible: Infaisable undefined_feasible: Indécis - feasible_explanation_html: "Informations sur la non-viabilité (le cas échéant, données publiques)" + feasible_explanation_html: Informations sur la non-viabilité (le cas échéant, données publiques) valuation_finished: Évaluation terminée - time_scope_html: "Délai d'exécution (optionnel, données non publiques)" - internal_comments_html: "Commentaires et observations (pour les responsables internes, données non publiques)" + time_scope_html: Délai d'exécution (optionnel, données non publiques) + internal_comments_html: Commentaires et observations (pour les responsables internes, données non publiques) save: Enregistrer les changements notice: valuate: "Informations actualisées" - - diff --git a/config/locales/gl/rails.yml b/config/locales/gl/rails.yml new file mode 100644 index 000000000..9dda51249 --- /dev/null +++ b/config/locales/gl/rails.yml @@ -0,0 +1,13 @@ +gl: + number: + currency: + format: + significant: false + strip_insignificant_zeros: false + format: + significant: false + strip_insignificant_zeros: false + human: + format: + significant: true + strip_insignificant_zeros: true diff --git a/config/locales/he/rails.yml b/config/locales/he/rails.yml new file mode 100644 index 000000000..853576daa --- /dev/null +++ b/config/locales/he/rails.yml @@ -0,0 +1,13 @@ +he: + number: + currency: + format: + significant: false + strip_insignificant_zeros: false + format: + significant: false + strip_insignificant_zeros: false + human: + format: + significant: true + strip_insignificant_zeros: true diff --git a/config/locales/it/activemodel.yml b/config/locales/it/activemodel.yml new file mode 100644 index 000000000..9a8b71a8b --- /dev/null +++ b/config/locales/it/activemodel.yml @@ -0,0 +1,22 @@ +it: + activemodel: + models: + verification: + residence: "Residenza" + sms: "SMS" + attributes: + verification: + residence: + document_type: "Tipo Documento di identità" + document_number: "N. Documento" + date_of_birth: "Data di nascita" + postal_code: "CAP" + sms: + phone: "Telefono" + confirmation_code: "Codice di conferma" + email: + recipient: "E-mail" + officing/residence: + document_type: "Tipo Documento di identità" + document_number: "Numero del documento (lettere incluse)" + year_of_birth: "Anno di nascita" diff --git a/config/locales/it/community.yml b/config/locales/it/community.yml new file mode 100644 index 000000000..c976b29ee --- /dev/null +++ b/config/locales/it/community.yml @@ -0,0 +1,4 @@ +it: + community: + sidebar: + title: Comunità diff --git a/config/locales/it/documents.yml b/config/locales/it/documents.yml new file mode 100644 index 000000000..565fb4d90 --- /dev/null +++ b/config/locales/it/documents.yml @@ -0,0 +1,3 @@ +it: + documents: + tab: Documenti diff --git a/config/locales/it/general.yml b/config/locales/it/general.yml new file mode 100644 index 000000000..c0309e872 --- /dev/null +++ b/config/locales/it/general.yml @@ -0,0 +1,756 @@ +it: + account: + show: + email_on_comment_label: "" + email_on_comment_reply_label: "" + erase_account_link: "" + finish_verification: "" + notifications: "" + organization_name_label: "" + organization_responsible_name_placeholder: "" + personal: "" + phone_number_label: "" + public_activity_label: "" + public_interests_label: "" + public_interests_my_title_list: "" + public_interests_user_title_list: "" + public_interests_my_empty_list: "" + public_interests_user_empty_list: "" + save_changes_submit: "" + subscription_to_website_newsletter_label: "" + email_on_direct_message_label: "" + email_digest_label: "" + official_position_badge_label: "" + title: "" + user_permission_debates: "" + user_permission_info: "" + user_permission_proposal: "" + user_permission_support_proposal: "" + user_permission_title: "" + user_permission_verify: "" + user_permission_verify_info: "" + user_permission_votes: "" + username_label: "" + verified_account: "" + verify_my_account: "" + application: + close: "" + menu: "" + comments: + comments_closed: "" + verified_only: "" + verify_account: "" + comment: + admin: "" + author: "" + deleted: "" + moderator: "" + responses: + one: "" + other: "" + user_deleted: "" + votes: + one: "" + other: "" + form: + comment_as_admin: "" + comment_as_moderator: "" + leave_comment: "" + orders: + most_voted: "" + newest: "" + oldest: "" + most_commented: "" + select_order: "" + show: + return_to_commentable: '' + comments_helper: + comment_button: "" + comment_link: "" + comments_title: "" + reply_button: "" + reply_link: "" + debates: + create: + form: + submit_button: "" + debate: + comments: + one: "" + other: "" + votes: + one: "" + other: "" + edit: + editing: "" + form: + submit_button: "" + show_link: "" + form: + debate_text: "" + debate_title: "" + tags_instructions: "" + tags_label: "" + tags_placeholder: "" + index: + featured_debates: "" + filter_topic: + one: "" + other: "" + orders: + confidence_score: "" + created_at: "" + hot_score: "" + most_commented: "" + relevance: "" + search_form: + button: "" + placeholder: "" + title: "" + search_results_html: + one: "" + other: "" + select_order: "" + start_debate: "" + title: "" + section_header: + icon_alt: "" + title: "" + help: "" + section_footer: + title: "" + description: "" + help_text_1: "" + help_text_2: '' + help_text_3: "" + proposals_link: "" + budget_link: "" + new: + form: + submit_button: "" + info: "" + info_link: "" + more_info: "" + recommendation_four: "" + recommendation_one: "" + recommendation_three: "" + recommendation_two: "" + recommendations_title: "" + start_new: "" + show: + author_deleted: "" + comments: + one: "" + other: "" + comments_title: "" + edit_debate_link: "" + flag: "" + login_to_comment: "" + share: "" + update: + form: + submit_button: "" + errors: + messages: + user_not_found: "" + invalid_date_range: "" + form: + accept_terms: "" + accept_terms_title: "" + conditions: "" + debate: "" + direct_message: "" + error: "" + errors: "" + not_saved: '' + policy: "" + proposal: "" + proposal_notification: "" + spending_proposal: "" + budget/investment: "" + poll/shift: "" + user: "" + verification/sms: "" + signature_sheet: "" + document: "" + topic: "" + geozones: + none: "" + all: "" + layouts: + application: + chrome: "" + firefox: "" + ie: "" + ie_title: "" + footer: + accessibility: "" + conditions: "" + consul: "" + consul_url: "" + contact_us: "" + copyright: "" + description: "" + faq: "" + open_data_text: "" + open_data_title: "" + open_source: "" + open_source_url: "" + participation_text: "" + participation_title: "" + privacy: "" + transparency_text: "" + transparency_title: "" + transparency_url: "" + header: + administration_menu: "" + administration: "" + available_locales: "" + collaborative_legislation: "" + debates: "" + external_link_blog: "" + external_link_opendata: "" + external_link_opendata_url: "" + external_link_transparency: "" + external_link_transparency_url: "" + locale: '' + logo: "" + management: "" + moderation: "" + valuation: "" + officing: "" + more_info: "" + my_account_link: "" + my_activity_link: "" + notifications: "" + new_notifications: + one: "" + other: "" + no_notifications: "" + open: "" + open_city_slogan_html: "" + open_city_title: "" + open_gov: "" + proposals: "" + poll_questions: "" + budgets: "" + spending_proposals: "" + admin: + watch_form_message: '' + legacy_legislation: + help: + alt: "" + text: "" + text_sign_in: "" + text_sign_up: "" + title: "" + locale: "" + notifications: + index: + comments_on: + one: "" + other: "" + empty_notifications: "" + mark_all_as_read: "" + proposal_notification: + one: "" + other: "" + replies_to: + one: "" + other: "" + title: "" + map: + title: "" + proposal_for_district: "" + select_district: "" + start_proposal: "" + omniauth: + facebook: + sign_in: "" + sign_up: "" + name: "" + finish_signup: + title: "" + username_warning: "" + google_oauth2: + sign_in: "" + sign_up: "" + name: "" + twitter: + sign_in: "" + sign_up: "" + name: "" + info_sign_in: "" + info_sign_up: "" + or_fill: "" + proposals: + create: + form: + submit_button: "" + edit: + editing: "" + form: + submit_button: "" + show_link: "" + retire_form: + title: "" + warning: "" + retired_reason_label: "" + retired_reason_blank: "" + retired_explanation_label: "" + retired_explanation_placeholder: "" + submit_button: "" + retire_options: + duplicated: "" + started: "" + unfeasible: "" + done: "" + other: "" + form: + geozone: "" + proposal_external_url: "" + proposal_question: "" + proposal_question_example_html: "" + proposal_responsible_name: "" + proposal_responsible_name_note: "" + proposal_summary: "" + proposal_summary_note: "" + proposal_text: "" + proposal_title: "" + proposal_video_url: "" + proposal_video_url_note: "" + tag_category_label: "" + tags_instructions: "" + tags_label: "" + tags_placeholder: "" + index: + featured_proposals: "" + filter_topic: + one: "" + other: "" + orders: + confidence_score: "" + created_at: "" + hot_score: "" + most_commented: "" + relevance: "" + archival_date: "" + retired_proposals: "" + retired_proposals_link: "" + retired_links: + all: "" + duplicated: "" + started: "" + unfeasible: "" + done: "" + other: "" + search_form: + button: "" + placeholder: "" + title: "" + search_results_html: + one: "" + other: "" + select_order: "" + select_order_long: '' + start_proposal: "" + title: "" + top: "" + top_link_proposals: "" + section_header: + icon_alt: "" + title: "" + help: "" + section_footer: + title: "" + description: "" + help_text_1: "" + help_text_2: "" + help_text_3: "" + new: + form: + submit_button: "" + more_info: "" + recommendation_one: "" + recommendation_three: "" + recommendation_two: "" + recommendations_title: "" + start_new: "" + notice: + retired: "" + proposal: + created: "" + share: + guide: "" + edit: "" + view_proposal: "" + improve_info: "" + improve_info_link: "" + already_supported: "" + comments: + one: "" + other: "" + reason_for_supports_necessary: "" + support: "" + support_title: "" + supports: + one: "" + other: "" + supports_necessary: "" + total_percent: "" + archived: "" + successful: "" + voting: "" + show: + author_deleted: "" + code: '' + comments: + one: "" + other: "" + comments_tab: "" + edit_proposal_link: "" + flag: "" + login_to_comment: "" + notifications_tab: "" + retired_warning: "" + retired_warning_link_to_explanation: "" + retired: "" + share: "" + send_notification: "" + no_notifications: "" + embed_video_title: "" + title_external_url: "" + title_video_url: "" + author: "" + update: + form: + submit_button: "" + polls: + all: "" + no_dates: "" + dates: "" + final_date: "" + index: + filters: + current: "" + incoming: "" + expired: "" + title: "" + participate_button: "" + participate_button_incoming: "" + participate_button_expired: "" + no_geozone_restricted: "" + geozone_restricted: "" + geozone_info: "" + can_answer: "" + cant_answer: "" + cant_answer_not_logged_in: "" + cant_answer_verify: "" + already_answer: "" + section_header: + icon_alt: "" + title: "" + help: "" + section_footer: + title: "" + description: "" + help_text_1: "" + help_text_2: "" + show: + dates_title: "" + cant_answer_not_logged_in: "" + signin: "" + signup: "" + cant_answer_verify_html: "" + verify_link: "" + cant_answer_incoming: "" + cant_answer_expired: "" + poll_questions: + create_question: "" + default_valid_answers: "" + show: + answer_this_question: "" + original_proposal: "" + author: "" + dates_title: "" + more_info: "" + not_logged_in: "" + signin: "" + signup: "" + cant_answer_verify_html: "" + verify_link: "" + cant_answer_incoming: "" + cant_answer_expired: "" + cant_answer_wrong_geozone: "" + vote_answer: "" + voted: "" + poll: "" + proposal_notifications: + new: + title: "" + title_label: "" + body_label: "" + submit_button: "" + info_about_receivers_html: "" + proposal_page: "" + show: + back: "" + shared: + edit: '' + save: '' + delete: "" + comments: + title: '' + login_to_comment: '' + "yes": "" + "no": "" + search_results: "" + advanced_search: + author_type: '' + author_type_blank: '' + date: '' + date_placeholder: '' + date_range_blank: '' + date_1: '' + date_2: '' + date_3: '' + date_4: '' + date_5: '' + from: '' + general: '' + general_placeholder: '' + search: '' + title: '' + to: '' + author_info: + author_deleted: "" + back: "" + check: "" + check_all: "" + check_none: "" + collective: "" + flag: "" + follow: "" + follow_entity: "" + followable: + budget_investment: + create: + notice_html: "" + destroy: + notice_html: "" + proposal: + create: + notice_html: "" + destroy: + notice_html: "" + hide: "" + print: + print_button: "" + search: "" + show: "" + suggest: + debate: + found: + one: "" + other: "" + message: "" + see_all: "" + budget_investment: + found: + one: "" + other: "" + message: "" + see_all: "" + proposal: + found: + one: "" + other: "" + message: "" + see_all: "" + tags_cloud: + tags: "" + districts: "" + districts_list: "" + categories: "" + target_blank_html: "" + you_are_in: "" + unflag: "" + unfollow: "" + unfollow_entity: "" + outline: + budget: "" + searcher: "" + go_to_page: "" + social: + blog: "" + facebook: "" + twitter: "" + youtube: "" + whatsapp: "" + telegram: "" + instagram: "" + spending_proposals: + form: + association_name_label: '' + association_name: '' + description: "" + external_url: "" + geozone: "" + submit_buttons: + create: "" + new: "" + title: "" + index: + title: "" + unfeasible: "" + by_geozone: "" + search_form: + button: "" + placeholder: "" + title: "" + search_results: + one: "" + other: "" + sidebar: + geozones: "" + feasibility: "" + unfeasible: "" + start_spending_proposal: "" + new: + more_info: "" + recommendation_one: "" + recommendation_three: "" + recommendation_two: "" + recommendations_title: "" + start_new: "" + show: + author_deleted: "" + code: '' + share: "" + wrong_price_format: "" + spending_proposal: + spending_proposal: "" + already_supported: "" + support: "" + support_title: "" + supports: + one: "" + other: "" + stats: + index: + visits: "" + debates: "" + proposals: "" + comments: "" + proposal_votes: "" + debate_votes: "" + comment_votes: "" + votes: "" + verified_users: "" + unverified_users: "" + unauthorized: + default: "" + manage: + all: "" + users: + direct_messages: + new: + body_label: "" + direct_messages_bloqued: "" + submit_button: "" + title: "" + title_label: "" + verified_only: "" + verify_account: "" + authenticate: "" + signin: "" + signup: "" + show: + receiver: "" + show: + deleted: "" + deleted_debate: "" + deleted_proposal: "" + deleted_budget_investment: "" + filters: + comments: + one: "" + other: "" + debates: + one: "" + other: "" + proposals: + one: "" + other: "" + budget_investments: + one: "" + other: "" + follows: + one: "" + other: "" + no_activity: "" + no_private_messages: "" + private_activity: "" + send_private_message: "" + proposals: + send_notification: "" + retire: "" + retired: "" + see: "" + votes: + agree: "" + anonymous: "" + comment_unauthenticated: "" + disagree: "" + organizations: "" + signin: "" + signup: "" + supports: "" + unauthenticated: "" + verified_only: "" + verify_account: "" + spending_proposals: + not_logged_in: "" + not_verified: "" + organization: "" + unfeasible: "" + not_voting_allowed: "" + budget_investments: + not_logged_in: "" + not_verified: "" + organization: "" + unfeasible: "" + not_voting_allowed: "" + different_heading_assigned: "" + welcome: + debates: + description: "" + title: "" + decide: + description: "" + title: "" + do: + description: "" + title: "" + proposal: + description: "" + title: "" + verification: + i_dont_have_an_account: "" + i_have_an_account: "" + question: "" + title: "" + welcome: + go_to_index: "" + title: "" + user_permission_debates: "" + user_permission_info: "" + user_permission_proposal: "" + user_permission_support_proposal: "" + user_permission_verify: "" + user_permission_verify_info: "" + user_permission_verify_my_account: "" + user_permission_votes: "" + invisible_captcha: + sentence_for_humans: "" + timestamp_error_message: "" diff --git a/config/locales/it/images.yml b/config/locales/it/images.yml new file mode 100644 index 000000000..7698aa371 --- /dev/null +++ b/config/locales/it/images.yml @@ -0,0 +1,3 @@ +it: + images: + remove_image: Rimuovere immagine diff --git a/config/locales/it/rails.yml b/config/locales/it/rails.yml new file mode 100644 index 000000000..6500a297e --- /dev/null +++ b/config/locales/it/rails.yml @@ -0,0 +1,13 @@ +it: + number: + currency: + format: + significant: false + strip_insignificant_zeros: false + format: + significant: false + strip_insignificant_zeros: false + human: + format: + significant: true + strip_insignificant_zeros: true diff --git a/config/locales/nl/rails.yml b/config/locales/nl/rails.yml index d5613a3d7..574380f47 100644 --- a/config/locales/nl/rails.yml +++ b/config/locales/nl/rails.yml @@ -1,81 +1,55 @@ -# Files in the config/locales directory are used for internationalization -# and are automatically loaded by Rails. If you want to use locales other -# than English, add the necessary files in this directory. -# -# To use the locales, use `I18n.t`: -# -# I18n.t 'hello' -# -# In views, this is aliased to just `t`: -# -# <%= t('hello') %> -# -# To use a different locale, set it with `I18n.locale`: -# -# I18n.locale = :es -# -# This would use the information in config/locales/es.yml. -# -# To learn more, please read the Rails Internationalization guide -# available at http://guides.rubyonrails.org/i18n.html. - nl: - time: - formats: - datetime: "%Y-%m-%d %H:%M:%S" date: abbr_day_names: - - zo - - ma - - di - - wo - - do - - vr - - za + - zo + - ma + - di + - wo + - do + - vr + - za abbr_month_names: - - - - jan - - feb - - mrt - - apr - - mei - - jun - - jul - - aug - - sep - - okt - - nov - - dec + - jan + - feb + - mrt + - apr + - mei + - jun + - jul + - aug + - sep + - okt + - nov + - dec day_names: - - zondag - - maandag - - dinsdag - - woensdag - - donderdag - - vrijdag - - zaterdag + - zondag + - maandag + - dinsdag + - woensdag + - donderdag + - vrijdag + - zaterdag formats: default: "%d-%m-%Y" long: "%e %B %Y" short: "%e %b" month_names: - - - - januari - - februari - - maart - - april - - mei - - juni - - juli - - augustus - - september - - oktober - - november - - december + - januari + - februari + - maart + - april + - mei + - juni + - juli + - augustus + - september + - oktober + - november + - december order: - - :day - - :month - - :year + - :day + - ': month' + - :year datetime: distance_in_words: about_x_hours: @@ -109,6 +83,9 @@ nl: x_months: one: 1 maand other: "%{count} maanden" + x_years: + one: '%{count} jaar' + other: "%{count} jaar" x_seconds: one: 1 seconde other: "%{count} seconden" @@ -136,14 +113,10 @@ nl: invalid: is ongeldig less_than: moet minder zijn dan %{count} less_than_or_equal_to: moet minder dan of gelijk zijn aan %{count} - model_invalid: "Validatie mislukt: %{errors}" + model_invalid: 'Validatie mislukt: %{errors}' not_a_number: is geen getal not_an_integer: moet een geheel getal zijn odd: moet oneven zijn - record_invalid: 'Validatie mislukt: %{errors}' - restrict_dependent_destroy: - one: Kan item niet verwijderen omdat %{record} afhankelijk is - many: Kan item niet verwijderen omdat afhankelijke %{record} bestaan required: moet bestaan taken: is al in gebruik too_long: @@ -159,15 +132,15 @@ nl: template: body: 'Er zijn problemen met de volgende velden:' header: - one: "%{model} niet opgeslagen: 1 fout gevonden" + one: '%{model} niet opgeslagen: 1 fout gevonden' other: "%{model} niet opgeslagen: %{count} fouten gevonden" helpers: select: prompt: Maak een keuze submit: - create: "%{model} toevoegen" - submit: "%{model} opslaan" - update: "%{model} bijwerken" + create: '%{model} toevoegen' + submit: '%{model} opslaan' + update: '%{model} bijwerken' number: currency: format: @@ -193,9 +166,7 @@ nl: quadrillion: biljard thousand: duizend trillion: biljoen - unit: '' format: - delimiter: '' precision: 3 significant: true strip_insignificant_zeros: true @@ -211,20 +182,17 @@ nl: tb: TB percentage: format: - delimiter: '' format: "%n%" - precision: - format: - delimiter: '' support: array: last_word_connector: " en " two_words_connector: " en " words_connector: ", " time: - am: "'s ochtends" + am: '''s ochtends' formats: + datetime: "%Y-%m-%d %H:%M:%S" default: "%a %d %b %Y %H:%M:%S %Z" long: "%d %B %Y %H:%M" short: "%d %b %H:%M" - pm: "'s middags" + pm: '''s middags' diff --git a/config/locales/nl/settings.yml b/config/locales/nl/settings.yml index 32938a8d3..83f6b5a10 100644 --- a/config/locales/nl/settings.yml +++ b/config/locales/nl/settings.yml @@ -31,6 +31,7 @@ nl: twitter_login: Twitter login facebook_login: Facebook login google_login: Google login + proposals: Proposals debates: Debates polls: Polls signature_sheets: Signature sheets diff --git a/config/locales/nl/valuation.yml b/config/locales/nl/valuation.yml deleted file mode 100644 index 5ff8a79c8..000000000 --- a/config/locales/nl/valuation.yml +++ /dev/null @@ -1,127 +0,0 @@ ---- -nl: - valuation: - header: - title: Valuation - menu: - title: Valuation - budgets: Participatory budgets - spending_proposals: Spending proposals - budgets: - index: - title: Participatory budgets - filters: - current: Open - finished: Finished - table_name: Name - table_phase: Phase - table_assigned_investments_valuation_open: Investment projects assigned with valuation open - table_actions: Actions - evaluate: Evaluate - budget_investments: - index: - headings_filter_all: All headings - filters: - valuation_open: Open - valuating: Under valuation - valuation_finished: Valuation finished - assigned_to: "Assigned to %{valuator}" - title: Investment projects - edit: Edit dossier - valuators_assigned: - one: Assigned valuator - other: "%{count} valuators assigned" - no_valuators_assigned: No valuators assigned - table_id: ID - table_title: Title - table_heading_name: Heading name - table_actions: Actions - show: - back: Back - title: Investment project - info: Author info - by: Sent by - sent: Sent at - heading: Heading - dossier: Dossier - edit_dossier: Edit dossier - price: Price - price_first_year: Cost during the first year - currency: "€" - feasibility: Feasibility - feasible: Feasible - unfeasible: Unfeasible - undefined: Undefined - valuation_finished: Valuation finished - duration: Time scope - internal_comments: Internal comments - responsibles: Responsibles - assigned_admin: Assigned admin - assigned_valuators: Assigned valuators - edit: - dossier: Dossier - price_html: "Price (%{currency})" - price_first_year_html: "Cost during the first year (%{currency}) (optional, data not public)" - price_explanation_html: Price explanation - feasibility: Feasibility - feasible: Feasible - unfeasible: Not feasible - undefined_feasible: Pending - feasible_explanation_html: Feasibility explanation - valuation_finished: Valuation finished - duration_html: Time scope - internal_comments_html: Internal comments - save: Save changes - notice: - valuate: "Dossier updated" - spending_proposals: - index: - geozone_filter_all: All zones - filters: - valuation_open: Open - valuating: Under valuation - valuation_finished: Valuation finished - title: Investment projects for participatory budgeting - edit: Edit - show: - back: Back - heading: Investment project - info: Author info - association_name: Asociación - by: Sent by - sent: Sent at - geozone: Scope - dossier: Dossier - edit_dossier: Edit dossier - price: Price - price_first_year: Cost during the first year - currency: "€" - feasibility: Feasibility - feasible: Feasible - not_feasible: Not feasible - undefined: Undefined - valuation_finished: Valuation finished - time_scope: Time scope - internal_comments: Internal comments - responsibles: Responsibles - assigned_admin: Assigned admin - assigned_valuators: Assigned valuators - edit: - dossier: Dossier - price_html: "Price (%{currency})" - price_first_year_html: "Cost during the first year (%{currency})" - currency: "€" - price_explanation_html: Price explanation - feasibility: Feasibility - feasible: Feasible - not_feasible: Not feasible - undefined_feasible: Pending - feasible_explanation_html: Feasibility explanation - valuation_finished: Valuation finished - time_scope_html: Time scope - internal_comments_html: Internal comments - save: Save changes - notice: - valuate: "Dossier updated" - - diff --git a/config/locales/pt-BR/general.yml b/config/locales/pt-BR/general.yml index 816c14fa2..bfe4124f7 100644 --- a/config/locales/pt-BR/general.yml +++ b/config/locales/pt-BR/general.yml @@ -362,7 +362,6 @@ pt-BR: - Sex - Sab abbr_month_names: - - - Jan - Fev - Mar diff --git a/config/locales/pt-BR/rails.yml b/config/locales/pt-BR/rails.yml new file mode 100644 index 000000000..2a5eab69c --- /dev/null +++ b/config/locales/pt-BR/rails.yml @@ -0,0 +1,13 @@ +pt-BR: + number: + currency: + format: + significant: false + strip_insignificant_zeros: false + format: + significant: false + strip_insignificant_zeros: false + human: + format: + significant: true + strip_insignificant_zeros: true diff --git a/config/locales/sv-SE/rails.yml b/config/locales/sv-SE/rails.yml new file mode 100644 index 000000000..9d92c753c --- /dev/null +++ b/config/locales/sv-SE/rails.yml @@ -0,0 +1,13 @@ +sv: + number: + currency: + format: + significant: false + strip_insignificant_zeros: false + format: + significant: false + strip_insignificant_zeros: false + human: + format: + significant: true + strip_insignificant_zeros: true diff --git a/config/maintenance.yml.example b/config/maintenance.yml.example new file mode 100644 index 000000000..540bc8bb7 --- /dev/null +++ b/config/maintenance.yml.example @@ -0,0 +1,12 @@ +--- +app_root: '.' +allowed_ips: + - 127.0.0.1 + - x.x.x.x + +allowed_paths: + - your/custom/route + +reason: 'Website down for maintenance' +response_code: 503 +retry_after: 3600 diff --git a/config/routes.rb b/config/routes.rb index a02384ced..fb1535b6c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -6,17 +6,17 @@ Rails.application.routes.draw do end devise_for :users, controllers: { - registrations: 'users/registrations', - sessions: 'users/sessions', - confirmations: 'users/confirmations', - omniauth_callbacks: 'users/omniauth_callbacks' - } + registrations: 'users/registrations', + sessions: 'users/sessions', + confirmations: 'users/confirmations', + omniauth_callbacks: 'users/omniauth_callbacks' + } devise_for :organizations, class_name: 'User', - controllers: { - registrations: 'organizations/registrations', - sessions: 'devise/sessions', - }, - skip: [:omniauth_callbacks] + controllers: { + registrations: 'organizations/registrations', + sessions: 'devise/sessions' + }, + skip: [:omniauth_callbacks] devise_scope :organization do get 'organizations/sign_up/success', to: 'organizations/registrations#success' @@ -36,6 +36,8 @@ Rails.application.routes.draw do get '/welcome', to: 'welcome#welcome' get '/cuentasegura', to: 'welcome#verification', as: :cuentasegura + get '/consul.json', to: "installation#details" + resources :debates do member do post :vote @@ -78,7 +80,9 @@ Rails.application.routes.draw do resources :budgets, only: [:show, :index] do resources :groups, controller: "budgets/groups", only: [:show] resources :investments, controller: "budgets/investments", only: [:index, :new, :create, :show, :destroy] do - member { post :vote } + member do + post :vote + end collection { get :suggest } end resource :ballot, only: :show, controller: "budgets/ballots" do @@ -95,13 +99,12 @@ Rails.application.routes.draw do resources :follows, only: [:create, :destroy] - resources :documents, only: [:new, :create, :destroy] do - collection do - get :new_nested - delete :destroy_upload - post :upload - end - end + resources :documents, only: [:destroy] + + resources :images, only: [:destroy] + + resources :direct_uploads, only: [:create] + delete "direct_uploads/destroy", to: "direct_uploads#destroy", as: :direct_upload_destroy resources :stats, only: [:index] @@ -112,7 +115,11 @@ Rails.application.routes.draw do end resources :polls, only: [:show, :index] do - resources :questions, only: [:show], controller: 'polls/questions', shallow: true do + member do + get :stats + get :results + end + resources :questions, controller: 'polls/questions', shallow: true do post :answer, on: :member end end @@ -124,10 +131,22 @@ Rails.application.routes.draw do get :draft_publication get :allegations get :result_publication + get :proposals end resources :questions, only: [:show] do resources :answers, only: [:create] end + resources :proposals do + member do + post :vote + put :flag + put :unflag + end + collection do + get :map + get :suggest + end + end resources :draft_versions, only: [:show] do get :go_to_version, on: :collection get :changes @@ -168,6 +187,11 @@ Rails.application.routes.draw do resource :letter, controller: "letter", only: [:new, :create, :show, :edit, :update] end + resources :tags do + collection do + get :suggest + end + end namespace :admin do root to: "dashboard#index" @@ -244,11 +268,13 @@ Rails.application.routes.draw do end resources :settings, only: [:index, :update] + put :update_map, to: "settings#update_map" + resources :moderators, only: [:index, :create, :destroy] do get :search, on: :collection end - resources :valuators, only: [:index, :create] do + resources :valuators, only: [:index, :create, :destroy] do get :search, on: :collection get :summary, on: :collection end @@ -265,12 +291,12 @@ Rails.application.routes.draw do scope module: :poll do resources :polls do - get :search_questions, on: :member + get :booth_assignments, on: :collection patch :add_question, on: :member - patch :remove_question, on: :member resources :booth_assignments, only: [:index, :show, :create, :destroy] do get :search_booths, on: :collection + get :manage, on: :collection end resources :officer_assignments, only: [:index, :create, :destroy] do @@ -294,7 +320,14 @@ Rails.application.routes.draw do end end - resources :questions + resources :questions, shallow: true do + resources :answers, except: [:index, :destroy], controller: 'questions/answers', shallow: true do + resources :images, controller: 'questions/answers/images' + resources :videos, controller: 'questions/answers/videos' + get :documents, to: 'questions/answers#documents' + end + post '/answers/order_answers', to: 'questions/answers#order_answers' + end end resources :verifications, controller: :verifications, only: :index do @@ -308,11 +341,13 @@ Rails.application.routes.draw do resource :stats, only: :show do get :proposal_notifications, on: :collection get :direct_messages, on: :collection + get :polls, on: :collection end namespace :legislation do resources :processes do resources :questions + resources :proposals resources :draft_versions end end @@ -427,13 +462,18 @@ Rails.application.routes.draw do root to: "dashboard#index" end + resources :related_contents, only: [:create] do + member do + put :score_positive + put :score_negative + end + end + # GraphQL get '/graphql', to: 'graphql#query' post '/graphql', to: 'graphql#query' - if Rails.env.development? - mount LetterOpenerWeb::Engine, at: "/letter_opener" - end + mount LetterOpenerWeb::Engine, at: "/letter_opener" if Rails.env.development? mount GraphiQL::Rails::Engine, at: '/graphiql', graphql_path: '/graphql' diff --git a/config/secrets.yml.example b/config/secrets.yml.example index f67ea65c0..3939d7b80 100644 --- a/config/secrets.yml.example +++ b/config/secrets.yml.example @@ -1,41 +1,74 @@ default: &default - secret_key_base: "56792feef405a59b18ea7db57b4777e855103882b926413d4afdfb8c0ea8aa86ea6649da4e729c5f5ae324c0ab9338f789174cf48c544173bc18fdc3b14262e4" + secret_key_base: 56792feef405a59b18ea7db57b4777e855103882b926413d4afdfb8c0ea8aa86ea6649da4e729c5f5ae324c0ab9338f789174cf48c544173bc18fdc3b14262e4 -development: - <<: *default - -test: - <<: *default - -staging: - server_name: "" - <<: *default - -production: &production - secret_key_base: "817232feef405a59b18ea7db57b4777e855103882b926413d4afdfb8c0ea8aa86ea6649da4e729c5f5ae324c0ab9338f789174cf48c544173bc18fdc3b14262e4" +maps: &maps + map_tiles_provider: "//{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" + map_tiles_provider_attribution: "© OpenStreetMap contributors" +apis: &apis census_api_end_point: "" census_api_institution_code: "" census_api_portal_name: "" census_api_user_code: "" - sms_end_point: "" sms_username: "" sms_password: "" +http_basic_auth: &http_basic_auth + http_basic_auth: true + + +development: + http_basic_username: "dev" + http_basic_password: "pass" + <<: *default + +test: + <<: *default + <<: *maps + +staging: + secret_key_base: "" + server_name: "" + rollbar_server_token: "" http_basic_username: "" http_basic_password: "" + managers_url: "" + managers_application_key: "" + <<: *default + <<: *maps + <<: *apis +preproduction: + secret_key_base: "" + server_name: "" + rollbar_server_token: "" + http_basic_username: "" + http_basic_password: "" + managers_url: "" + managers_application_key: "" twitter_key: "" twitter_secret: "" facebook_key: "" facebook_secret: "" google_oauth2_key: "" google_oauth2_secret: "" + <<: *maps + <<: *apis +production: + secret_key_base: "" + server_name: "" rollbar_server_token: "" - server_name: "" - -preproduction: - server_name: "" - <<: *production + http_basic_username: "" + http_basic_password: "" + managers_url: "" + managers_application_key: "" + twitter_key: "" + twitter_secret: "" + facebook_key: "" + facebook_secret: "" + google_oauth2_key: "" + google_oauth2_secret: "" + <<: *maps + <<: *apis diff --git a/config/sitemap.rb b/config/sitemap.rb index 95fa9bfa1..e60cee617 100644 --- a/config/sitemap.rb +++ b/config/sitemap.rb @@ -9,11 +9,7 @@ SitemapGenerator::Sitemap.default_host = Setting["url"] # sitemap generator SitemapGenerator::Sitemap.create do - pages = ["accessibility", - "census_terms", - "conditions", - "general_terms", - "privacy"] + pages = ["general_terms"] pages.each do |page| add page_path(id: page) end @@ -32,11 +28,6 @@ SitemapGenerator::Sitemap.create do add proposal_path(proposal), lastmod: proposal.updated_at end - add spending_proposals_path, priority: 0.7, changefreq: "daily" - SpendingProposal.find_each do |spending_proposal| - add spending_proposal_path(spending_proposal), lastmod: spending_proposal.updated_at - end - add budgets_path, priority: 0.7, changefreq: "daily" Budget.find_each do |budget| add budget_path(budget), lastmod: budget.updated_at @@ -46,4 +37,10 @@ SitemapGenerator::Sitemap.create do Poll.find_each do |poll| add poll_path(poll), lastmod: poll.starts_at end + + add legislation_processes_path, priority: 0.7, changefreq: "daily" + Legislation::Process.find_each do |process| + add legislation_process_path(process), lastmod: process.start_date + end + end diff --git a/db/dev_seeds.rb b/db/dev_seeds.rb index 1223d94a4..8ed80d5cb 100644 --- a/db/dev_seeds.rb +++ b/db/dev_seeds.rb @@ -1,353 +1,380 @@ require 'database_cleaner' - DatabaseCleaner.clean_with :truncation +@logger = Logger.new(STDOUT) +@logger.formatter = proc { |_severity, _datetime, _progname, msg| msg } -print "Creating Settings" -Setting.create(key: 'official_level_1_name', value: 'Empleados públicos') -Setting.create(key: 'official_level_2_name', value: 'Organización Municipal') -Setting.create(key: 'official_level_3_name', value: 'Directores generales') -Setting.create(key: 'official_level_4_name', value: 'Concejales') -Setting.create(key: 'official_level_5_name', value: 'Alcaldesa') -Setting.create(key: 'max_ratio_anon_votes_on_debates', value: '50') -Setting.create(key: 'max_votes_for_debate_edit', value: '1000') -Setting.create(key: 'max_votes_for_proposal_edit', value: '1000') -Setting.create(key: 'proposal_code_prefix', value: 'MAD') -Setting.create(key: 'votes_for_proposal_success', value: '100') -Setting.create(key: 'months_to_archive_proposals', value: '12') -Setting.create(key: 'comments_body_max_length', value: '1000') - -Setting.create(key: 'twitter_handle', value: '@consul_dev') -Setting.create(key: 'twitter_hashtag', value: '#consul_dev') -Setting.create(key: 'facebook_handle', value: 'CONSUL') -Setting.create(key: 'youtube_handle', value: 'CONSUL') -Setting.create(key: 'telegram_handle', value: 'CONSUL') -Setting.create(key: 'instagram_handle', value: 'CONSUL') -Setting.create(key: 'blog_url', value: '/blog') -Setting.create(key: 'url', value: 'http://localhost:3000') -Setting.create(key: 'org_name', value: 'CONSUL') -Setting.create(key: 'place_name', value: 'City') -Setting.create(key: 'feature.debates', value: "true") -Setting.create(key: 'feature.polls', value: "true") -Setting.create(key: 'feature.spending_proposals', value: nil) -Setting.create(key: 'feature.spending_proposal_features.voting_allowed', value: nil) -Setting.create(key: 'feature.budgets', value: "true") -Setting.create(key: 'feature.twitter_login', value: "true") -Setting.create(key: 'feature.facebook_login', value: "true") -Setting.create(key: 'feature.google_login', value: "true") -Setting.create(key: 'feature.signature_sheets', value: "true") -Setting.create(key: 'feature.legislation', value: "true") -Setting.create(key: 'feature.community', value: "true") -Setting.create(key: 'per_page_code_head', value: "") -Setting.create(key: 'per_page_code_body', value: "") -Setting.create(key: 'comments_body_max_length', value: '1000') -Setting.create(key: 'mailer_from_name', value: 'CONSUL') -Setting.create(key: 'mailer_from_address', value: 'noreply@consul.dev') -Setting.create(key: 'meta_description', value: 'Citizen Participation and Open Government Application') -Setting.create(key: 'meta_keywords', value: 'citizen participation, open government') -Setting.create(key: 'verification_offices_url', value: 'http://oficinas-atencion-ciudadano.url/') -Setting.create(key: 'min_age_to_participate', value: '16') -Setting.create(key: 'proposal_improvement_path', value: nil) - -puts " ✅" -print "Creating Geozones" - -Geozone.create(name: "city") -Geozone.create(name: "Existent District", census_code: "01") -('A'..'Z').each { |i| Geozone.create(name: "District #{i}", external_code: i.ord, census_code: i.ord) } - -puts " ✅" -print "Creating Users" - -def create_user(email, username = Faker::Name.name) - pwd = '12345678' - User.create!( - username: username, - email: email, - password: pwd, - password_confirmation: pwd, - confirmed_at: Time.current, - terms_of_service: "1", - gender: ['Male', 'Female'].sample, - date_of_birth: rand((Time.current - 80.years) .. (Time.current - 16.years)), - public_activity: (rand(1..100) > 30) - ) +def section(section_title) + @logger.info section_title + yield + log(' ✅') end -admin = create_user('admin@consul.dev', 'admin') -admin.create_administrator -admin.update(residence_verified_at: Time.current, confirmed_phone: Faker::PhoneNumber.phone_number, document_type: "1", verified_at: Time.current, document_number: "1111111111") +def log(msg) + @logger.info "#{msg}\n" +end -moderator = create_user('mod@consul.dev', 'mod') -moderator.create_moderator +section "Creating Settings" do + Setting.create(key: 'official_level_1_name', value: 'Empleados públicos') + Setting.create(key: 'official_level_2_name', value: 'Organización Municipal') + Setting.create(key: 'official_level_3_name', value: 'Directores generales') + Setting.create(key: 'official_level_4_name', value: 'Concejales') + Setting.create(key: 'official_level_5_name', value: 'Alcaldesa') + Setting.create(key: 'max_ratio_anon_votes_on_debates', value: '50') + Setting.create(key: 'max_votes_for_debate_edit', value: '1000') + Setting.create(key: 'max_votes_for_proposal_edit', value: '1000') + Setting.create(key: 'proposal_code_prefix', value: 'MAD') + Setting.create(key: 'votes_for_proposal_success', value: '100') + Setting.create(key: 'months_to_archive_proposals', value: '12') + Setting.create(key: 'comments_body_max_length', value: '1000') -manager = create_user('manager@consul.dev', 'manager') -manager.create_manager + Setting.create(key: 'twitter_handle', value: '@consul_dev') + Setting.create(key: 'twitter_hashtag', value: '#consul_dev') + Setting.create(key: 'facebook_handle', value: 'CONSUL') + Setting.create(key: 'youtube_handle', value: 'CONSUL') + Setting.create(key: 'telegram_handle', value: 'CONSUL') + Setting.create(key: 'instagram_handle', value: 'CONSUL') + Setting.create(key: 'blog_url', value: '/blog') + Setting.create(key: 'url', value: 'http://localhost:3000') + Setting.create(key: 'org_name', value: 'CONSUL') + Setting.create(key: 'place_name', value: 'City') + Setting.create(key: 'feature.debates', value: "true") + Setting.create(key: 'feature.proposals', value: "true") + Setting.create(key: 'feature.polls', value: "true") + Setting.create(key: 'feature.spending_proposals', value: nil) + Setting.create(key: 'feature.spending_proposal_features.voting_allowed', value: nil) + Setting.create(key: 'feature.budgets', value: "true") + Setting.create(key: 'feature.twitter_login', value: "true") + Setting.create(key: 'feature.facebook_login', value: "true") + Setting.create(key: 'feature.google_login', value: "true") + Setting.create(key: 'feature.signature_sheets', value: "true") + Setting.create(key: 'feature.legislation', value: "true") + Setting.create(key: 'feature.user.recommendations', value: "true") + Setting.create(key: 'feature.community', value: "true") + Setting.create(key: 'feature.map', value: "true") + Setting.create(key: 'feature.allow_images', value: "true") + Setting.create(key: 'feature.public_stats', value: "true") + Setting.create(key: 'per_page_code_head', value: "") + Setting.create(key: 'per_page_code_body', value: "") + Setting.create(key: 'comments_body_max_length', value: '1000') + Setting.create(key: 'mailer_from_name', value: 'CONSUL') + Setting.create(key: 'mailer_from_address', value: 'noreply@consul.dev') + Setting.create(key: 'meta_title', value: 'CONSUL') + Setting.create(key: 'meta_description', value: 'Citizen Participation and Open Government Application') + Setting.create(key: 'meta_keywords', value: 'citizen participation, open government') + Setting.create(key: 'verification_offices_url', value: 'http://oficinas-atencion-ciudadano.url/') + Setting.create(key: 'min_age_to_participate', value: '16') + Setting.create(key: 'proposal_improvement_path', value: nil) + Setting.create(key: 'map_latitude', value: 51.48) + Setting.create(key: 'map_longitude', value: 0.0) + Setting.create(key: 'map_zoom', value: 10) + Setting.create(key: 'related_content_score_threshold', value: -0.3) +end -valuator = create_user('valuator@consul.dev', 'valuator') -valuator.create_valuator -valuator.update(residence_verified_at: Time.current, confirmed_phone: Faker::PhoneNumber.phone_number, document_type: "1", verified_at: Time.current, document_number: "2111111111") +section "Creating Geozones" do + Geozone.create(name: "city") + Geozone.create(name: "Existent District", census_code: "01") + ('A'..'Z').each { |i| Geozone.create(name: "District #{i}", external_code: i.ord, census_code: i.ord) } +end -poll_officer = create_user('poll_officer@consul.dev', 'Paul O. Fisher') -poll_officer.create_poll_officer -poll_officer.update(residence_verified_at: Time.current, confirmed_phone: Faker::PhoneNumber.phone_number, document_type: "1", verified_at: Time.current, document_number: "2211111111") +section "Creating Users" do + def create_user(email, username = Faker::Name.name) + pwd = '12345678' + User.create!( + username: username, + email: email, + password: pwd, + password_confirmation: pwd, + confirmed_at: Time.current, + terms_of_service: "1", + gender: ['Male', 'Female'].sample, + date_of_birth: rand((Time.current - 80.years)..(Time.current - 16.years)), + public_activity: (rand(1..100) > 30) + ) + end -create_user('unverified@consul.dev', 'unverified') + def unique_document_number + @document_number ||= 12345678 + @document_number += 1 + "#{@document_number}#{[*'A'..'Z'].sample}" + end -level_2 = create_user('leveltwo@consul.dev', 'level 2') -level_2.update(residence_verified_at: Time.current, confirmed_phone: Faker::PhoneNumber.phone_number, document_number: "2222222222", document_type: "1") + admin = create_user('admin@consul.dev', 'admin') + admin.create_administrator + admin.update(residence_verified_at: Time.current, confirmed_phone: Faker::PhoneNumber.phone_number, document_type: "1", + verified_at: Time.current, document_number: unique_document_number) -verified = create_user('verified@consul.dev', 'verified') -verified.update(residence_verified_at: Time.current, confirmed_phone: Faker::PhoneNumber.phone_number, document_type: "1", verified_at: Time.current, document_number: "3333333333") + moderator = create_user('mod@consul.dev', 'mod') + moderator.create_moderator -(1..10).each do |i| - org_name = Faker::Company.name - org_user = create_user("org#{i}@consul.dev", org_name) - org_responsible_name = Faker::Name.name - org = org_user.create_organization(name: org_name, responsible_name: org_responsible_name) + manager = create_user('manager@consul.dev', 'manager') + manager.create_manager - verified = [true, false].sample - if verified - org.verify - else - org.reject + valuator = create_user('valuator@consul.dev', 'valuator') + valuator.create_valuator + valuator.update(residence_verified_at: Time.current, confirmed_phone: Faker::PhoneNumber.phone_number, document_type: "1", + verified_at: Time.current, document_number: unique_document_number) + + poll_officer = create_user('poll_officer@consul.dev', 'Paul O. Fisher') + poll_officer.create_poll_officer + poll_officer.update(residence_verified_at: Time.current, confirmed_phone: Faker::PhoneNumber.phone_number, document_type: "1", + verified_at: Time.current, document_number: unique_document_number) + + poll_officer2 = create_user('poll_officer2@consul.dev', 'Pauline M. Espinosa') + poll_officer2.create_poll_officer + poll_officer2.update(residence_verified_at: Time.current, confirmed_phone: Faker::PhoneNumber.phone_number, document_type: "1", + verified_at: Time.current, document_number: unique_document_number) + + create_user('unverified@consul.dev', 'unverified') + + level_2 = create_user('leveltwo@consul.dev', 'level 2') + level_2.update(residence_verified_at: Time.current, confirmed_phone: Faker::PhoneNumber.phone_number, + document_number: unique_document_number, document_type: "1") + + verified = create_user('verified@consul.dev', 'verified') + + verified.update(residence_verified_at: Time.current, confirmed_phone: Faker::PhoneNumber.phone_number, document_type: "1", + verified_at: Time.current, document_number: unique_document_number) + + (1..10).each do |i| + org_name = Faker::Company.name + org_user = create_user("org#{i}@consul.dev", org_name) + org_responsible_name = Faker::Name.name + org = org_user.create_organization(name: org_name, responsible_name: org_responsible_name) + + verified = [true, false].sample + if verified + org.verify + else + org.reject + end + end + + (1..5).each do |i| + official = create_user("official#{i}@consul.dev") + official.update(official_level: i, official_position: "Official position #{i}") + end + + (1..100).each do |i| + user = create_user("user#{i}@consul.dev") + level = [1, 2, 3].sample + if level >= 2 + user.update(residence_verified_at: Time.current, confirmed_phone: Faker::PhoneNumber.phone_number, + document_number: unique_document_number, document_type: "1", geozone: Geozone.all.sample) + end + if level == 3 + user.update(verified_at: Time.current, document_number: unique_document_number) + end end end -(1..5).each do |i| - official = create_user("official#{i}@consul.dev") - official.update(official_level: i, official_position: "Official position #{i}") +section "Creating Tags Categories" do + ActsAsTaggableOn::Tag.category.create!(name: "Asociaciones") + ActsAsTaggableOn::Tag.category.create!(name: "Cultura") + ActsAsTaggableOn::Tag.category.create!(name: "Deportes") + ActsAsTaggableOn::Tag.category.create!(name: "Derechos Sociales") + ActsAsTaggableOn::Tag.category.create!(name: "Economía") + ActsAsTaggableOn::Tag.category.create!(name: "Empleo") + ActsAsTaggableOn::Tag.category.create!(name: "Equidad") + ActsAsTaggableOn::Tag.category.create!(name: "Sostenibilidad") + ActsAsTaggableOn::Tag.category.create!(name: "Participación") + ActsAsTaggableOn::Tag.category.create!(name: "Movilidad") + ActsAsTaggableOn::Tag.category.create!(name: "Medios") + ActsAsTaggableOn::Tag.category.create!(name: "Salud") + ActsAsTaggableOn::Tag.category.create!(name: "Transparencia") + ActsAsTaggableOn::Tag.category.create!(name: "Seguridad y Emergencias") + ActsAsTaggableOn::Tag.category.create!(name: "Medio Ambiente") end -(1..100).each do |i| - user = create_user("user#{i}@consul.dev") - level = [1, 2, 3].sample - if level >= 2 - user.update(residence_verified_at: Time.current, confirmed_phone: Faker::PhoneNumber.phone_number, document_number: Faker::Number.number(10), document_type: "1", geozone: Geozone.reorder("RANDOM()").first) +section "Creating Debates" do + tags = Faker::Lorem.words(25) + 30.times do + author = User.all.sample + description = "
#{Faker::Lorem.paragraphs.join('
')}
" + debate = Debate.create!(author: author, + title: Faker::Lorem.sentence(3).truncate(60), + created_at: rand((Time.current - 1.week)..Time.current), + description: description, + tag_list: tags.sample(3).join(','), + geozone: Geozone.all.sample, + terms_of_service: "1") end - if level == 3 - user.update(verified_at: Time.current, document_number: Faker::Number.number(10)) + + tags = ActsAsTaggableOn::Tag.where(kind: 'category') + 30.times do + author = User.all.sample + description = "#{Faker::Lorem.paragraphs.join('
')}
" + debate = Debate.create!(author: author, + title: Faker::Lorem.sentence(3).truncate(60), + created_at: rand((Time.current - 1.week)..Time.current), + description: description, + tag_list: tags.sample(3).join(','), + geozone: Geozone.all.sample, + terms_of_service: "1") end end -org_user_ids = User.organizations.pluck(:id) -not_org_users = User.where(['users.id NOT IN(?)', org_user_ids]) - -puts " ✅" -print "Creating Tags Categories" - -ActsAsTaggableOn::Tag.category.create!(name: "Asociaciones") -ActsAsTaggableOn::Tag.category.create!(name: "Cultura") -ActsAsTaggableOn::Tag.category.create!(name: "Deportes") -ActsAsTaggableOn::Tag.category.create!(name: "Derechos Sociales") -ActsAsTaggableOn::Tag.category.create!(name: "Economía") -ActsAsTaggableOn::Tag.category.create!(name: "Empleo") -ActsAsTaggableOn::Tag.category.create!(name: "Equidad") -ActsAsTaggableOn::Tag.category.create!(name: "Sostenibilidad") -ActsAsTaggableOn::Tag.category.create!(name: "Participación") -ActsAsTaggableOn::Tag.category.create!(name: "Movilidad") -ActsAsTaggableOn::Tag.category.create!(name: "Medios") -ActsAsTaggableOn::Tag.category.create!(name: "Salud") -ActsAsTaggableOn::Tag.category.create!(name: "Transparencia") -ActsAsTaggableOn::Tag.category.create!(name: "Seguridad y Emergencias") -ActsAsTaggableOn::Tag.category.create!(name: "Medio Ambiente") - -puts " ✅" -print "Creating Debates" - -tags = Faker::Lorem.words(25) -30.times do - author = User.reorder("RANDOM()").first - description = "#{Faker::Lorem.paragraphs.join('
')}
" - debate = Debate.create!(author: author, - title: Faker::Lorem.sentence(3).truncate(60), - created_at: rand((Time.current - 1.week)..Time.current), - description: description, - tag_list: tags.sample(3).join(','), - geozone: Geozone.reorder("RANDOM()").first, - terms_of_service: "1") +section "Creating Proposals" do + tags = Faker::Lorem.words(25) + 30.times do + author = User.all.sample + description = "#{Faker::Lorem.paragraphs.join('
')}
" + proposal = Proposal.create!(author: author, + title: Faker::Lorem.sentence(3).truncate(60), + question: Faker::Lorem.sentence(3) + "?", + summary: Faker::Lorem.sentence(3), + responsible_name: Faker::Name.name, + external_url: Faker::Internet.url, + description: description, + created_at: rand((Time.current - 1.week)..Time.current), + tag_list: tags.sample(3).join(','), + geozone: Geozone.all.sample, + skip_map: "1", + terms_of_service: "1") + end end -tags = ActsAsTaggableOn::Tag.where(kind: 'category') -30.times do - author = User.reorder("RANDOM()").first - description = "#{Faker::Lorem.paragraphs.join('
')}
" - debate = Debate.create!(author: author, - title: Faker::Lorem.sentence(3).truncate(60), - created_at: rand((Time.current - 1.week)..Time.current), - description: description, - tag_list: tags.sample(3).join(','), - geozone: Geozone.reorder("RANDOM()").first, - terms_of_service: "1") +section "Creating Archived Proposals" do + tags = Faker::Lorem.words(25) + 5.times do + author = User.all.sample + description = "#{Faker::Lorem.paragraphs.join('
')}
" + proposal = Proposal.create!(author: author, + title: Faker::Lorem.sentence(3).truncate(60), + question: Faker::Lorem.sentence(3) + "?", + summary: Faker::Lorem.sentence(3), + responsible_name: Faker::Name.name, + external_url: Faker::Internet.url, + description: description, + tag_list: tags.sample(3).join(','), + geozone: Geozone.all.sample, + skip_map: "1", + terms_of_service: "1", + created_at: Setting["months_to_archive_proposals"].to_i.months.ago) + end end -puts " ✅" -print "Creating Proposals" +section "Creating Successful Proposals" do + tags = Faker::Lorem.words(25) + 10.times do + author = User.all.sample + description = "#{Faker::Lorem.paragraphs.join('
')}
" + proposal = Proposal.create!(author: author, + title: Faker::Lorem.sentence(3).truncate(60), + question: Faker::Lorem.sentence(3) + "?", + summary: Faker::Lorem.sentence(3), + responsible_name: Faker::Name.name, + external_url: Faker::Internet.url, + description: description, + created_at: rand((Time.current - 1.week)..Time.current), + tag_list: tags.sample(3).join(','), + geozone: Geozone.all.sample, + skip_map: "1", + terms_of_service: "1", + cached_votes_up: Setting["votes_for_proposal_success"]) + end -tags = Faker::Lorem.words(25) -30.times do - author = User.reorder("RANDOM()").first - description = "#{Faker::Lorem.paragraphs.join('
')}
" - proposal = Proposal.create!(author: author, - title: Faker::Lorem.sentence(3).truncate(60), - question: Faker::Lorem.sentence(3) + "?", - summary: Faker::Lorem.sentence(3), - responsible_name: Faker::Name.name, - external_url: Faker::Internet.url, - description: description, - created_at: rand((Time.current - 1.week)..Time.current), - tag_list: tags.sample(3).join(','), - geozone: Geozone.reorder("RANDOM()").first, - terms_of_service: "1") + tags = ActsAsTaggableOn::Tag.where(kind: 'category') + 30.times do + author = User.all.sample + description = "#{Faker::Lorem.paragraphs.join('
')}
" + proposal = Proposal.create!(author: author, + title: Faker::Lorem.sentence(4).truncate(60), + question: Faker::Lorem.sentence(6) + "?", + summary: Faker::Lorem.sentence(3), + responsible_name: Faker::Name.name, + external_url: Faker::Internet.url, + description: description, + created_at: rand((Time.current - 1.week)..Time.current), + tag_list: tags.sample(3).join(','), + geozone: Geozone.all.sample, + skip_map: "1", + terms_of_service: "1") + end end -puts " ✅" -print "Creating Archived Proposals" - -tags = Faker::Lorem.words(25) -5.times do - author = User.reorder("RANDOM()").first - description = "#{Faker::Lorem.paragraphs.join('
')}
" - proposal = Proposal.create!(author: author, - title: Faker::Lorem.sentence(3).truncate(60), - question: Faker::Lorem.sentence(3) + "?", - summary: Faker::Lorem.sentence(3), - responsible_name: Faker::Name.name, - external_url: Faker::Internet.url, - description: description, - tag_list: tags.sample(3).join(','), - geozone: Geozone.reorder("RANDOM()").first, - terms_of_service: "1", - created_at: Setting["months_to_archive_proposals"].to_i.months.ago) +section "Commenting Debates" do + 100.times do + author = User.all.sample + debate = Debate.all.sample + Comment.create!(user: author, + created_at: rand(debate.created_at..Time.current), + commentable: debate, + body: Faker::Lorem.sentence) + end end -puts " ✅" -print "Creating Successful Proposals" - -tags = Faker::Lorem.words(25) -10.times do - author = User.reorder("RANDOM()").first - description = "#{Faker::Lorem.paragraphs.join('
')}
" - proposal = Proposal.create!(author: author, - title: Faker::Lorem.sentence(3).truncate(60), - question: Faker::Lorem.sentence(3) + "?", - summary: Faker::Lorem.sentence(3), - responsible_name: Faker::Name.name, - external_url: Faker::Internet.url, - description: description, - created_at: rand((Time.current - 1.week)..Time.current), - tag_list: tags.sample(3).join(','), - geozone: Geozone.reorder("RANDOM()").first, - terms_of_service: "1", - cached_votes_up: Setting["votes_for_proposal_success"]) +section "Commenting Proposals" do + 100.times do + author = User.all.sample + proposal = Proposal.all.sample + Comment.create!(user: author, + created_at: rand(proposal.created_at..Time.current), + commentable: proposal, + body: Faker::Lorem.sentence) + end end -tags = ActsAsTaggableOn::Tag.where(kind: 'category') -30.times do - author = User.reorder("RANDOM()").first - description = "#{Faker::Lorem.paragraphs.join('
')}
" - proposal = Proposal.create!(author: author, - title: Faker::Lorem.sentence(3).truncate(60), - question: Faker::Lorem.sentence(3) + "?", - summary: Faker::Lorem.sentence(3), - responsible_name: Faker::Name.name, - external_url: Faker::Internet.url, - description: description, - created_at: rand((Time.current - 1.week)..Time.current), - tag_list: tags.sample(3).join(','), - geozone: Geozone.reorder("RANDOM()").first, - terms_of_service: "1") +section "Commenting Comments" do + 200.times do + author = User.all.sample + parent = Comment.all.sample + Comment.create!(user: author, + created_at: rand(parent.created_at..Time.current), + commentable_id: parent.commentable_id, + commentable_type: parent.commentable_type, + body: Faker::Lorem.sentence, + parent: parent) + end end -puts " ✅" -print "Commenting Debates" +section "Voting Debates, Proposals & Comments" do + not_org_users = User.where(['users.id NOT IN(?)', User.organizations.pluck(:id)]) + 100.times do + voter = not_org_users.level_two_or_three_verified.all.sample + vote = [true, false].sample + debate = Debate.all.sample + debate.vote_by(voter: voter, vote: vote) + end -100.times do - author = User.reorder("RANDOM()").first - debate = Debate.reorder("RANDOM()").first - Comment.create!(user: author, - created_at: rand(debate.created_at..Time.current), - commentable: debate, - body: Faker::Lorem.sentence) + 100.times do + voter = not_org_users.all.sample + vote = [true, false].sample + comment = Comment.all.sample + comment.vote_by(voter: voter, vote: vote) + end + + 100.times do + voter = not_org_users.level_two_or_three_verified.all.sample + proposal = Proposal.all.sample + proposal.vote_by(voter: voter, vote: true) + end end -puts " ✅" -print "Commenting Proposals" +section "Flagging Debates & Comments" do + 40.times do + debate = Debate.all.sample + flagger = User.where(["users.id <> ?", debate.author_id]).all.sample + Flag.flag(flagger, debate) + end -100.times do - author = User.reorder("RANDOM()").first - proposal = Proposal.reorder("RANDOM()").first - Comment.create!(user: author, - created_at: rand(proposal.created_at..Time.current), - commentable: proposal, - body: Faker::Lorem.sentence) + 40.times do + comment = Comment.all.sample + flagger = User.where(["users.id <> ?", comment.user_id]).all.sample + Flag.flag(flagger, comment) + end + + 40.times do + proposal = Proposal.all.sample + flagger = User.where(["users.id <> ?", proposal.author_id]).all.sample + Flag.flag(flagger, proposal) + end end -puts " ✅" -print "Commenting Comments" - -200.times do - author = User.reorder("RANDOM()").first - parent = Comment.reorder("RANDOM()").first - Comment.create!(user: author, - created_at: rand(parent.created_at..Time.current), - commentable_id: parent.commentable_id, - commentable_type: parent.commentable_type, - body: Faker::Lorem.sentence, - parent: parent) -end - -puts " ✅" -print "Voting Debates, Proposals & Comments" - -100.times do - voter = not_org_users.level_two_or_three_verified.reorder("RANDOM()").first - vote = [true, false].sample - debate = Debate.reorder("RANDOM()").first - debate.vote_by(voter: voter, vote: vote) -end - -100.times do - voter = not_org_users.reorder("RANDOM()").first - vote = [true, false].sample - comment = Comment.reorder("RANDOM()").first - comment.vote_by(voter: voter, vote: vote) -end - -100.times do - voter = not_org_users.level_two_or_three_verified.reorder("RANDOM()").first - proposal = Proposal.reorder("RANDOM()").first - proposal.vote_by(voter: voter, vote: true) -end - -puts " ✅" -print "Flagging Debates & Comments" - -40.times do - debate = Debate.reorder("RANDOM()").first - flagger = User.where(["users.id <> ?", debate.author_id]).reorder("RANDOM()").first - Flag.flag(flagger, debate) -end - -40.times do - comment = Comment.reorder("RANDOM()").first - flagger = User.where(["users.id <> ?", comment.user_id]).reorder("RANDOM()").first - Flag.flag(flagger, comment) -end - -40.times do - proposal = Proposal.reorder("RANDOM()").first - flagger = User.where(["users.id <> ?", proposal.author_id]).reorder("RANDOM()").first - Flag.flag(flagger, proposal) -end - -puts " ✅" -print "Creating Spending Proposals" - +section "Creating Spending Proposals" do tags = Faker::Lorem.words(10) - 60.times do - geozone = Geozone.reorder("RANDOM()").first - author = User.reorder("RANDOM()").first + geozone = Geozone.all.sample + author = User.all.sample description = "#{Faker::Lorem.paragraphs.join('
')}
" feasible_explanation = "#{Faker::Lorem.paragraphs.join('
')}
" valuation_finished = [true, false].sample @@ -365,295 +392,385 @@ tags = Faker::Lorem.words(10) price: rand(1000000), terms_of_service: "1") end - -puts " ✅" -print "Creating Valuation Assignments" - -(1..17).to_a.sample.times do - SpendingProposal.reorder("RANDOM()").first.valuators << valuator.valuator end -puts " ✅" -print "Creating Budgets" +section "Creating Valuation Assignments" do + (1..17).to_a.sample.times do + SpendingProposal.all.sample.valuators << Valuator.first + end +end -Budget::PHASES.each_with_index do |phase, i| - descriptions = Hash[Budget::PHASES.map do |p| - ["description_#{p}", - "#{Faker::Lorem.paragraphs(2).join('
')}
"] - end] - budget = Budget.create!( - descriptions.merge( - name: (Date.current - 10 + i).to_s, - currency_symbol: "€", - phase: phase +section "Creating Budgets" do + Budget::PHASES.each_with_index do |phase, i| + descriptions = Hash[Budget::PHASES.map do |p| + ["description_#{p}", + "#{Faker::Lorem.paragraphs(2).join('
')}
"] + end] + budget = Budget.create!( + descriptions.merge( + name: (Date.current - 10 + i).to_s, + currency_symbol: "€", + phase: phase + ) ) - ) - (1..([1, 2, 3].sample)).each do |i| - group = budget.groups.create!(name: "#{Faker::StarWars.planet} #{i}") + (1..([1, 2, 3].sample)).each do |k| + group = budget.groups.create!(name: "#{Faker::StarWars.planet} #{k}") - geozones = Geozone.reorder("RANDOM()").limit([2, 5, 6, 7].sample) - geozones.each do |geozone| - group.headings << group.headings.create!(name: "#{geozone.name} #{i}", - price: rand(1..100) * 100000, - population: rand(1..50) * 10000) + geozones = Geozone.reorder("RANDOM()").limit([2, 5, 6, 7].sample) + geozones.each do |geozone| + group.headings << group.headings.create!(name: "#{geozone.name} #{k}", + price: rand(1..100) * 100000, + population: rand(1..50) * 10000) + end end end end -puts " ✅" -print "Creating Investments" -tags = Faker::Lorem.words(10) -100.times do - heading = Budget::Heading.reorder("RANDOM()").first +section "Creating Investments" do + tags = Faker::Lorem.words(10) + 100.times do + heading = Budget::Heading.all.sample - investment = Budget::Investment.create!( - author: User.reorder("RANDOM()").first, - heading: heading, - group: heading.group, - budget: heading.group.budget, - title: Faker::Lorem.sentence(3).truncate(60), - external_url: Faker::Internet.url, - description: "#{Faker::Lorem.paragraphs.join('
')}
", - created_at: rand((Time.current - 1.week)..Time.current), - feasibility: %w{undecided unfeasible feasible feasible feasible feasible}.sample, - unfeasibility_explanation: Faker::Lorem.paragraph, - valuation_finished: [false, true].sample, - tag_list: tags.sample(3).join(','), - price: rand(1..100) * 100000, - terms_of_service: "1" - ) -end - -puts " ✅" -print "Balloting Investments" -Budget.balloting.last.investments.each do |investment| - investment.update(selected: true, feasibility: "feasible") -end - -puts " ✅" -print "Winner Investments" - -budget = Budget.where(phase: "finished").last -100.times do - heading = budget.headings.reorder("RANDOM()").first - investment = Budget::Investment.create!( - author: User.reorder("RANDOM()").first, - heading: heading, - group: heading.group, - budget: heading.group.budget, - title: Faker::Lorem.sentence(3).truncate(60), - external_url: Faker::Internet.url, - description: "#{Faker::Lorem.paragraphs.join('
')}
", - created_at: rand((Time.current - 1.week)..Time.current), - feasibility: "feasible", - valuation_finished: true, - selected: true, - price: rand(10000..heading.price), - terms_of_service: "1" - ) -end -budget.headings.each do |heading| - Budget::Result.new(budget, heading).calculate_winners -end - -puts " ✅" -print "Creating Valuation Assignments" - -(1..50).to_a.sample.times do - Budget::Investment.reorder("RANDOM()").first.valuators << valuator.valuator -end - -puts " ✅" -print "Ignoring flags in Debates, comments & proposals" - -Debate.flagged.reorder("RANDOM()").limit(10).each(&:ignore_flag) -Comment.flagged.reorder("RANDOM()").limit(30).each(&:ignore_flag) -Proposal.flagged.reorder("RANDOM()").limit(10).each(&:ignore_flag) - -puts " ✅" -print "Hiding debates, comments & proposals" - -Comment.with_hidden.flagged.reorder("RANDOM()").limit(30).each(&:hide) -Debate.with_hidden.flagged.reorder("RANDOM()").limit(5).each(&:hide) -Proposal.with_hidden.flagged.reorder("RANDOM()").limit(10).each(&:hide) - -puts " ✅" -print "Confirming hiding in debates, comments & proposals" - -Comment.only_hidden.flagged.reorder("RANDOM()").limit(10).each(&:confirm_hide) -Debate.only_hidden.flagged.reorder("RANDOM()").limit(5).each(&:confirm_hide) -Proposal.only_hidden.flagged.reorder("RANDOM()").limit(5).each(&:confirm_hide) - -puts " ✅" -print "Creating banners" - -Proposal.last(3).each do |proposal| - title = Faker::Lorem.sentence(word_count = 3) - description = Faker::Lorem.sentence(word_count = 12) - banner = Banner.create!(title: title, - description: description, - style: ["banner-style banner-style-one", "banner-style banner-style-two", - "banner-style banner-style-three"].sample, - image: ["banner-img banner-img-one", "banner-img banner-img-two", - "banner-img banner-img-three"].sample, - target_url: Rails.application.routes.url_helpers.proposal_path(proposal), - post_started_at: rand((Time.current - 1.week)..(Time.current - 1.day)), - post_ended_at: rand((Time.current - 1.day)..(Time.current + 1.week)), - created_at: rand((Time.current - 1.week)..Time.current)) -end - -puts " ✅" -print "Creating proposal notifications" - -100.times do |i| - ProposalNotification.create!(title: "Proposal notification title #{i}", - body: "Proposal notification body #{i}", - author: User.reorder("RANDOM()").first, - proposal: Proposal.reorder("RANDOM()").first) -end - -puts " ✅" -print "Creating polls" - -puts " ✅" -print "Active Polls" -(1..3).each do |i| - poll = Poll.create(name: "Active Poll #{i}", - starts_at: 1.month.ago, - ends_at: 1.month.from_now, - geozone_restricted: false) -end -(1..5).each do |i| - poll = Poll.create(name: "Active Poll #{i}", - starts_at: 1.month.ago, - ends_at: 1.month.from_now, - geozone_restricted: true, - geozones: Geozone.reorder("RANDOM()").limit(3)) -end - -puts " ✅" -print "Upcoming Poll" -poll = Poll.create(name: "Upcoming Poll", - starts_at: 1.month.from_now, - ends_at: 2.months.from_now) - -puts " ✅" -print "Expired Poll" -poll = Poll.create(name: "Expired Poll", - starts_at: 2.months.ago, - ends_at: 1.month.ago) - -puts " ✅" -print "Creating Poll Questions" - -50.times do - poll = Poll.reorder("RANDOM()").first - author = User.reorder("RANDOM()").first - description = "#{Faker::Lorem.paragraphs.join('
')}
" - open_at = rand(2.months.ago..2.months.from_now) - question = Poll::Question.create!(author: author, - title: Faker::Lorem.sentence(3).truncate(60), - description: description, - valid_answers: Faker::Lorem.words((2..7).to_a.sample).join(', '), - poll: poll) -end - -puts " ✅" -print "Creating Poll Booths" -30.times.each_with_index do |i| - Poll::Booth.create(name: "Booth #{i}", polls: [Poll.all.sample]) -end - -puts " ✅" -print "Creating Booth Assignments" -Poll::Booth.all.each do |booth| - Poll::BoothAssignment.create(booth: booth, poll: Poll.all.sample) -end - -puts " ✅" -print "Creating Poll Officer Assignments" -(1..15).to_a.sample.times do |i| - Poll::BoothAssignment.all.sample(i).each do |booth_assignment| - Poll::OfficerAssignment.create(officer: poll_officer.poll_officer, - booth_assignment: booth_assignment, - date: booth_assignment.poll.starts_at) + investment = Budget::Investment.create!( + author: User.all.sample, + heading: heading, + group: heading.group, + budget: heading.group.budget, + title: Faker::Lorem.sentence(3).truncate(60), + description: "#{Faker::Lorem.paragraphs.join('
')}
", + created_at: rand((Time.current - 1.week)..Time.current), + feasibility: %w{undecided unfeasible feasible feasible feasible feasible}.sample, + unfeasibility_explanation: Faker::Lorem.paragraph, + valuation_finished: [false, true].sample, + tag_list: tags.sample(3).join(','), + price: rand(1..100) * 100000, + skip_map: "1", + terms_of_service: "1" + ) end end -puts " ✅" -print "Creating Poll Questions from Proposals" - -3.times do - proposal = Proposal.reorder("RANDOM()").first - poll = Poll.current.first - question = Poll::Question.create(valid_answers: "Yes, No", poll: poll) - question.copy_attributes_from_proposal(proposal) - question.save! -end - -puts " ✅" -print "Creating Successful Proposals" - -10.times do - proposal = Proposal.reorder("RANDOM()").first - poll = Poll.current.first - question = Poll::Question.create(valid_answers: "Yes, No", poll: poll) - question.copy_attributes_from_proposal(proposal) - question.save! -end - -puts " ✅" -print "Commenting Poll Questions" - -30.times do - author = User.reorder("RANDOM()").first - question = Poll::Question.reorder("RANDOM()").first - Comment.create!(user: author, - created_at: rand(question.created_at..Time.current), - commentable: question, - body: Faker::Lorem.sentence) -end - -puts " ✅" -print "Creating Poll Voters" - -10.times do - poll = Poll.all.sample - user = User.level_two_verified.sample - Poll::Voter.create(poll: poll, user: user) -end - -puts " ✅" -print "Creating legislation processes" - -5.times do - process = ::Legislation::Process.create!(title: Faker::Lorem.sentence(3).truncate(60), - description: Faker::Lorem.paragraphs.join("\n\n"), - summary: Faker::Lorem.paragraph, - additional_info: Faker::Lorem.paragraphs.join("\n\n"), - start_date: Date.current - 3.days, - end_date: Date.current + 3.days, - debate_start_date: Date.current - 3.days, - debate_end_date: Date.current - 1.day, - draft_publication_date: Date.current + 1.day, - allegations_start_date: Date.current + 2.days, - allegations_end_date: Date.current + 3.days, - result_publication_date: Date.current + 4.days, - debate_phase_enabled: true, - allegations_phase_enabled: true, - draft_publication_enabled: true, - result_publication_enabled: true, - published: true - ) -end - -::Legislation::Process.all.each do |process| - (1..3).each do |i| - version = process.draft_versions.create!(title: "Version #{i}", - body: Faker::Lorem.paragraphs.join("\n\n")) +section "Balloting Investments" do + Budget.balloting.last.investments.each do |investment| + investment.update(selected: true, feasibility: "feasible") end end -puts " ✅" -puts "All dev seeds created successfuly 👍" +section "Winner Investments" do + budget = Budget.where(phase: "finished").last + 100.times do + heading = budget.headings.all.sample + investment = Budget::Investment.create!( + author: User.all.sample, + heading: heading, + group: heading.group, + budget: heading.group.budget, + title: Faker::Lorem.sentence(3).truncate(60), + description: "#{Faker::Lorem.paragraphs.join('
')}
", + created_at: rand((Time.current - 1.week)..Time.current), + feasibility: "feasible", + valuation_finished: true, + selected: true, + price: rand(10000..heading.price), + skip_map: "1", + terms_of_service: "1" + ) + end + budget.headings.each do |heading| + Budget::Result.new(budget, heading).calculate_winners + end +end + +section "Creating Valuation Assignments" do + (1..50).to_a.sample.times do + Budget::Investment.all.sample.valuators << Valuator.first + end +end + +section "Ignoring flags in Debates, comments & proposals" do + Debate.flagged.reorder("RANDOM()").limit(10).each(&:ignore_flag) + Comment.flagged.reorder("RANDOM()").limit(30).each(&:ignore_flag) + Proposal.flagged.reorder("RANDOM()").limit(10).each(&:ignore_flag) +end + +section "Hiding debates, comments & proposals" do + Comment.with_hidden.flagged.reorder("RANDOM()").limit(30).each(&:hide) + Debate.with_hidden.flagged.reorder("RANDOM()").limit(5).each(&:hide) + Proposal.with_hidden.flagged.reorder("RANDOM()").limit(10).each(&:hide) +end + +section "Confirming hiding in debates, comments & proposals" do + Comment.only_hidden.flagged.reorder("RANDOM()").limit(10).each(&:confirm_hide) + Debate.only_hidden.flagged.reorder("RANDOM()").limit(5).each(&:confirm_hide) + Proposal.only_hidden.flagged.reorder("RANDOM()").limit(5).each(&:confirm_hide) +end + +section "Creating banners" do + Proposal.last(3).each do |proposal| + title = Faker::Lorem.sentence(word_count = 3) + description = Faker::Lorem.sentence(word_count = 12) + banner = Banner.create!(title: title, + description: description, + style: ["banner-style banner-style-one", "banner-style banner-style-two", + "banner-style banner-style-three"].sample, + image: ["banner-img banner-img-one", "banner-img banner-img-two", + "banner-img banner-img-three"].sample, + target_url: Rails.application.routes.url_helpers.proposal_path(proposal), + post_started_at: rand((Time.current - 1.week)..(Time.current - 1.day)), + post_ended_at: rand((Time.current - 1.day)..(Time.current + 1.week)), + created_at: rand((Time.current - 1.week)..Time.current)) + end +end + +section "Creating proposal notifications" do + 100.times do |i| + ProposalNotification.create!(title: "Proposal notification title #{i}", + body: "Proposal notification body #{i}", + author: User.all.sample, + proposal: Proposal.all.sample) + end +end + +section "Creating polls" do + + Poll.create(name: "Current Poll", + starts_at: 7.days.ago, + ends_at: 7.days.from_now, + geozone_restricted: false) + + Poll.create(name: "Current Poll Geozone Restricted", + starts_at: 5.days.ago, + ends_at: 5.days.from_now, + geozone_restricted: true, + geozones: Geozone.reorder("RANDOM()").limit(3)) + + Poll.create(name: "Incoming Poll", + starts_at: 1.month.from_now, + ends_at: 2.months.from_now) + + Poll.create(name: "Recounting Poll", + starts_at: 15.days.ago, + ends_at: 2.days.ago) + + Poll.create(name: "Expired Poll without Stats & Results", + starts_at: 2.months.ago, + ends_at: 1.month.ago) + + Poll.create(name: "Expired Poll with Stats & Results", + starts_at: 2.months.ago, + ends_at: 1.month.ago, + results_enabled: true, + stats_enabled: true) +end + +section "Creating Poll Questions & Answers" do + Poll.all.each do |poll| + (1..4).to_a.sample.times do + question = Poll::Question.create!(author: User.all.sample, + title: Faker::Lorem.sentence(3).truncate(60) + '?', + poll: poll) + Faker::Lorem.words((2..4).to_a.sample).each do |answer| + Poll::Question::Answer.create!(question: question, + title: answer.capitalize, + description: "#{Faker::Lorem.paragraphs.join('
')}
") + end + end + end +end + +section "Creating Poll Booths & BoothAssignments" do + 20.times do |i| + Poll::Booth.create(name: "Booth #{i}", location: Faker::Address.street_address, polls: [Poll.all.sample]) + end +end + +section "Creating Poll Shifts for Poll Officers" do + Poll.all.each do |poll| + Poll::BoothAssignment.where(poll: poll).each do |booth_assignment| + Poll::Officer.all.each do |poll_officer| + { + vote_collection: (poll.starts_at.to_datetime..poll.ends_at.to_datetime), + recount_scrutiny: (poll.ends_at.to_datetime..poll.ends_at.to_datetime + Poll::RECOUNT_DURATION) + }.each do |task_name, task_dates| + task_dates.each do |shift_date| + Poll::Shift.create(booth: booth_assignment.booth, + officer: poll_officer, + date: shift_date, + officer_name: poll_officer.name, + officer_email: poll_officer.email, + task: task_name) + end + end + end + end + end +end + +section "Creating Communities" do + Proposal.all.each { |proposal| proposal.update(community: Community.create) } + Budget::Investment.all.each { |investment| investment.update(community: Community.create) } +end + +section "Creating Communities Topics" do + Community.all.each do |community| + Topic.create(community: community, author: User.all.sample, + title: Faker::Lorem.sentence(3).truncate(60), description: Faker::Lorem.sentence) + end +end + +section "Commenting Polls" do + 30.times do + author = User.all.sample + poll = Poll.all.sample + Comment.create!(user: author, + created_at: rand(poll.created_at..Time.current), + commentable: poll, + body: Faker::Lorem.sentence) + end +end + +section "Commenting Community Topics" do + 30.times do + author = User.all.sample + topic = Topic.all.sample + Comment.create!(user: author, + created_at: rand(topic.created_at..Time.current), + commentable: topic, + body: Faker::Lorem.sentence) + end +end + +section "Creating Poll Voters" do + + def vote_poll_on_booth(user, poll) + Poll::Voter.create!(document_type: user.document_type, + document_number: user.document_number, + user: user, + poll: poll, + origin: 'booth', + officer: Poll::Officer.all.sample) + end + + def vote_poll_on_web(user, poll) + randomly_answer_questions(poll, user) + Poll::Voter.create!(document_type: user.document_type, + document_number: user.document_number, + user: user, + poll: poll, + origin: 'web', + token: SecureRandom.hex(32)) + end + + def randomly_answer_questions(poll, user) + poll.questions.each do |question| + next unless [true, false].sample + Poll::Answer.create!(question_id: question.id, author: user, answer: question.question_answers.sample.title) + end + end + + (Poll.expired + Poll.current + Poll.recounting).uniq.each do |poll| + level_two_verified_users = User.level_two_verified + level_two_verified_users = level_two_verified_users.where(geozone_id: poll.geozone_ids) if poll.geozone_restricted? + user_groups = level_two_verified_users.in_groups(2) + user_groups.first.each { |user| vote_poll_on_booth(user, poll) } + user_groups.second.compact.each { |user| vote_poll_on_web(user, poll) } + end +end + +section "Creating Poll Recounts" do + Poll.all.each do |poll| + poll.booth_assignments.each do |booth_assignment| + officer_assignment = poll.officer_assignments.first + author = Poll::Officer.first.user + + Poll::Recount.create!(officer_assignment: officer_assignment, + booth_assignment: booth_assignment, + author: author, + date: poll.ends_at, + white_amount: rand(0..10), + null_amount: rand(0..10), + total_amount: rand(100..9999), + origin: "booth") + end + end +end + +section "Creating Poll Results" do + Poll.all.each do |poll| + poll.booth_assignments.each do |booth_assignment| + officer_assignment = poll.officer_assignments.first + author = Poll::Officer.first.user + + poll.questions.each do |question| + question.question_answers.each do |answer| + Poll::PartialResult.create!(officer_assignment: officer_assignment, + booth_assignment: booth_assignment, + date: Date.current, + question: question, + answer: answer.title, + author: author, + amount: rand(999), + origin: "booth") + end + end + end + end +end + +section "Creating Poll Questions from Proposals" do + 3.times do + proposal = Proposal.all.sample + poll = Poll.current.first + question = Poll::Question.create(poll: poll) + Faker::Lorem.words((2..4).to_a.sample).each do |answer| + Poll::Question::Answer.create!(question: question, title: answer.capitalize, description: Faker::ChuckNorris.fact) + end + question.copy_attributes_from_proposal(proposal) + question.save! + end +end + +section "Creating Successful Proposals" do + 10.times do + proposal = Proposal.all.sample + poll = Poll.current.first + question = Poll::Question.create(poll: poll) + Faker::Lorem.words((2..4).to_a.sample).each do |answer| + Poll::Question::Answer.create!(question: question, title: answer.capitalize, description: Faker::ChuckNorris.fact) + end + question.copy_attributes_from_proposal(proposal) + question.save! + end +end + +section "Creating legislation processes" do + 5.times do + process = ::Legislation::Process.create!(title: Faker::Lorem.sentence(3).truncate(60), + description: Faker::Lorem.paragraphs.join("\n\n"), + summary: Faker::Lorem.paragraph, + additional_info: Faker::Lorem.paragraphs.join("\n\n"), + start_date: Date.current - 3.days, + end_date: Date.current + 3.days, + debate_start_date: Date.current - 3.days, + debate_end_date: Date.current - 1.day, + draft_publication_date: Date.current + 1.day, + allegations_start_date: Date.current + 2.days, + allegations_end_date: Date.current + 3.days, + result_publication_date: Date.current + 4.days, + debate_phase_enabled: true, + allegations_phase_enabled: true, + draft_publication_enabled: true, + result_publication_enabled: true, + published: true) + end + + ::Legislation::Process.all.each do |process| + (1..3).each do |i| + version = process.draft_versions.create!(title: "Version #{i}", + body: Faker::Lorem.paragraphs.join("\n\n")) + end + end +end + +log "All dev seeds created successfuly 👍" diff --git a/db/migrate/20170627113331_create_images.rb b/db/migrate/20170627113331_create_images.rb new file mode 100644 index 000000000..66567845a --- /dev/null +++ b/db/migrate/20170627113331_create_images.rb @@ -0,0 +1,14 @@ +class CreateImages < ActiveRecord::Migration + def up + create_table :images do |t| + t.references :imageable, polymorphic: true, index: true + t.string :title, limit: 80 + t.timestamps null: false + end + add_attachment :images, :attachment + end + + def down + remove_attachment :images, :attachment + end +end diff --git a/db/migrate/20170805132736_create_map_locations.rb b/db/migrate/20170805132736_create_map_locations.rb new file mode 100644 index 000000000..a75820d54 --- /dev/null +++ b/db/migrate/20170805132736_create_map_locations.rb @@ -0,0 +1,11 @@ +class CreateMapLocations < ActiveRecord::Migration + def change + create_table :map_locations do |t| + t.float :latitude + t.float :longitude + t.integer :zoom + t.integer :proposal_id, index: true + t.integer :investment_id, index: true + end + end +end diff --git a/db/migrate/20170911110109_add_user_id_to_images.rb b/db/migrate/20170911110109_add_user_id_to_images.rb new file mode 100644 index 000000000..31467acee --- /dev/null +++ b/db/migrate/20170911110109_add_user_id_to_images.rb @@ -0,0 +1,5 @@ +class AddUserIdToImages < ActiveRecord::Migration + def change + add_reference :images, :user, index: true, foreign_key: true + end +end diff --git a/db/migrate/20170913101029_add_proposals_phase_to_legislation_processes.rb b/db/migrate/20170913101029_add_proposals_phase_to_legislation_processes.rb new file mode 100644 index 000000000..b3ecfe3f1 --- /dev/null +++ b/db/migrate/20170913101029_add_proposals_phase_to_legislation_processes.rb @@ -0,0 +1,7 @@ +class AddProposalsPhaseToLegislationProcesses < ActiveRecord::Migration + def change + add_column :legislation_processes, :proposals_phase_start_date, :date + add_column :legislation_processes, :proposals_phase_end_date, :date + add_column :legislation_processes, :proposals_phase_enabled, :boolean + end +end diff --git a/db/migrate/20170913130803_add_proposals_description_to_legislation_processes.rb b/db/migrate/20170913130803_add_proposals_description_to_legislation_processes.rb new file mode 100644 index 000000000..d5e4f9c5d --- /dev/null +++ b/db/migrate/20170913130803_add_proposals_description_to_legislation_processes.rb @@ -0,0 +1,5 @@ +class AddProposalsDescriptionToLegislationProcesses < ActiveRecord::Migration + def change + add_column :legislation_processes, :proposals_description, :text + end +end diff --git a/db/migrate/20170914102634_create_legislation_proposals.rb b/db/migrate/20170914102634_create_legislation_proposals.rb new file mode 100644 index 000000000..defe9f1dd --- /dev/null +++ b/db/migrate/20170914102634_create_legislation_proposals.rb @@ -0,0 +1,32 @@ +class CreateLegislationProposals < ActiveRecord::Migration + def change + create_table :legislation_proposals do |t| + t.references :legislation_process, index: true, foreign_key: true + t.string :title, limit: 80 + t.text :description + t.string :question + t.string :external_url + t.integer :author_id + t.datetime :hidden_at + t.integer :flags_count, default: 0 + t.datetime :ignored_flag_at + t.integer :cached_votes_up, default: 0 + t.integer :comments_count, default: 0 + t.datetime :confirmed_hide_at + t.integer :hot_score, limit: 8, default: 0 + t.integer :confidence_score, default: 0 + t.string :responsible_name, limit: 60 + t.text :summary + t.string :video_url + t.tsvector :tsv + t.integer :geozone_id + t.datetime :retired_at + t.string :retired_reason + t.text :retired_explanation + t.integer :community_id + + t.datetime :created_at, null: false + t.datetime :updated_at, null: false + end + end +end diff --git a/db/migrate/20170915101519_add_legislation_proposals_count_to_tags.rb b/db/migrate/20170915101519_add_legislation_proposals_count_to_tags.rb new file mode 100644 index 000000000..9ce6ace89 --- /dev/null +++ b/db/migrate/20170915101519_add_legislation_proposals_count_to_tags.rb @@ -0,0 +1,6 @@ +class AddLegislationProposalsCountToTags < ActiveRecord::Migration + def change + add_column :tags, "legislation/proposals_count", :integer, default: 0 + add_index :tags, "legislation/proposals_count" + end +end diff --git a/db/migrate/20170922101247_add_legislation_processes_count_to_tags.rb b/db/migrate/20170922101247_add_legislation_processes_count_to_tags.rb new file mode 100644 index 000000000..698a66af6 --- /dev/null +++ b/db/migrate/20170922101247_add_legislation_processes_count_to_tags.rb @@ -0,0 +1,6 @@ +class AddLegislationProcessesCountToTags < ActiveRecord::Migration + def change + add_column :tags, "legislation/processes_count", :integer, default: 0 + add_index :tags, "legislation/processes_count" + end +end diff --git a/db/migrate/20170927110953_add_shift_task.rb b/db/migrate/20170927110953_add_shift_task.rb new file mode 100644 index 000000000..8adf23dd1 --- /dev/null +++ b/db/migrate/20170927110953_add_shift_task.rb @@ -0,0 +1,5 @@ +class AddShiftTask < ActiveRecord::Migration + def change + add_column :poll_shifts, :task, :integer, null: false, default: 0 + end +end diff --git a/db/migrate/20170928132402_add_summary_and_description_to_polls.rb b/db/migrate/20170928132402_add_summary_and_description_to_polls.rb new file mode 100644 index 000000000..6fb965346 --- /dev/null +++ b/db/migrate/20170928132402_add_summary_and_description_to_polls.rb @@ -0,0 +1,6 @@ +class AddSummaryAndDescriptionToPolls < ActiveRecord::Migration + def change + add_column :polls, :summary, :text + add_column :polls, :description, :text + end +end diff --git a/db/migrate/20171002103314_add_poll_shift_task_index.rb b/db/migrate/20171002103314_add_poll_shift_task_index.rb new file mode 100644 index 000000000..d15275556 --- /dev/null +++ b/db/migrate/20171002103314_add_poll_shift_task_index.rb @@ -0,0 +1,7 @@ +class AddPollShiftTaskIndex < ActiveRecord::Migration + def change + remove_index "poll_shifts", name: "index_poll_shifts_on_booth_id_and_officer_id" + add_index :poll_shifts, :task + add_index :poll_shifts, [:booth_id, :officer_id, :task], unique: true + end +end diff --git a/db/migrate/20171002121658_add_origin_to_poll_voters.rb b/db/migrate/20171002121658_add_origin_to_poll_voters.rb new file mode 100644 index 000000000..845c1b774 --- /dev/null +++ b/db/migrate/20171002121658_add_origin_to_poll_voters.rb @@ -0,0 +1,5 @@ +class AddOriginToPollVoters < ActiveRecord::Migration + def change + add_column :poll_voters, :origin, :string + end +end diff --git a/db/migrate/20171002122312_create_poll_recount.rb b/db/migrate/20171002122312_create_poll_recount.rb new file mode 100644 index 000000000..807f1c84e --- /dev/null +++ b/db/migrate/20171002122312_create_poll_recount.rb @@ -0,0 +1,24 @@ +class CreatePollRecount < ActiveRecord::Migration + def change + create_table :poll_recounts do |t| + t.integer :author_id + t.string :origin + t.date :date + t.integer :booth_assignment_id + t.integer :officer_assignment_id + t.text :officer_assignment_id_log, default: "" + t.text :author_id_log, default: "" + t.integer :white_amount + t.text :white_amount_log, default: "" + t.integer :null_amount + t.text :null_amount_log, default: "" + t.integer :total_amount + t.text :total_amount_log, default: "" + end + + add_index :poll_recounts, :booth_assignment_id + add_index :poll_recounts, :officer_assignment_id + add_foreign_key :poll_recounts, :poll_booth_assignments, column: :booth_assignment_id + add_foreign_key :poll_recounts, :poll_officer_assignments, column: :officer_assignment_id + end +end diff --git a/db/migrate/20171002133547_remove_poll_white_null_total_results.rb b/db/migrate/20171002133547_remove_poll_white_null_total_results.rb new file mode 100644 index 000000000..5fff82ef3 --- /dev/null +++ b/db/migrate/20171002133547_remove_poll_white_null_total_results.rb @@ -0,0 +1,16 @@ +class RemovePollWhiteNullTotalResults < ActiveRecord::Migration + def change + remove_index :poll_null_results, column: [:booth_assignment_id] + remove_index :poll_null_results, column: [:officer_assignment_id] + + remove_index :poll_white_results, column: [:booth_assignment_id] + remove_index :poll_white_results, column: [:officer_assignment_id] + + remove_index :poll_total_results, column: [:booth_assignment_id] + remove_index :poll_total_results, column: [:officer_assignment_id] + + drop_table :poll_null_results + drop_table :poll_total_results + drop_table :poll_white_results + end +end diff --git a/db/migrate/20171002191347_add_default_to_recount_amounts.rb b/db/migrate/20171002191347_add_default_to_recount_amounts.rb new file mode 100644 index 000000000..b90e86aae --- /dev/null +++ b/db/migrate/20171002191347_add_default_to_recount_amounts.rb @@ -0,0 +1,7 @@ +class AddDefaultToRecountAmounts < ActiveRecord::Migration + def change + change_column_default :poll_recounts, :white_amount, 0 + change_column_default :poll_recounts, :null_amount, 0 + change_column_default :poll_recounts, :total_amount, 0 + end +end diff --git a/db/migrate/20171003095936_remove_officer_assigment_composed_index.rb b/db/migrate/20171003095936_remove_officer_assigment_composed_index.rb new file mode 100644 index 000000000..874672f84 --- /dev/null +++ b/db/migrate/20171003095936_remove_officer_assigment_composed_index.rb @@ -0,0 +1,5 @@ +class RemoveOfficerAssigmentComposedIndex < ActiveRecord::Migration + def change + remove_index "poll_officer_assignments", name: "index_poll_officer_assignments_on_officer_id_and_date" + end +end diff --git a/db/migrate/20171003143034_add_comments_count_to_polls.rb b/db/migrate/20171003143034_add_comments_count_to_polls.rb new file mode 100644 index 000000000..675acae3f --- /dev/null +++ b/db/migrate/20171003143034_add_comments_count_to_polls.rb @@ -0,0 +1,7 @@ +class AddCommentsCountToPolls < ActiveRecord::Migration + def change + add_column :polls, :comments_count, :integer, default: 0 + add_column :polls, :author_id, :integer + add_column :polls, :hidden_at, :datetime + end +end diff --git a/db/migrate/20171003170029_remove_description_from_poll_questions.rb b/db/migrate/20171003170029_remove_description_from_poll_questions.rb new file mode 100644 index 000000000..31e1b9578 --- /dev/null +++ b/db/migrate/20171003170029_remove_description_from_poll_questions.rb @@ -0,0 +1,5 @@ +class RemoveDescriptionFromPollQuestions < ActiveRecord::Migration + def change + remove_column :poll_questions, :description + end +end diff --git a/db/migrate/20171003212958_add_date_to_poll_shift_composed_index.rb b/db/migrate/20171003212958_add_date_to_poll_shift_composed_index.rb new file mode 100644 index 000000000..b59a859c1 --- /dev/null +++ b/db/migrate/20171003212958_add_date_to_poll_shift_composed_index.rb @@ -0,0 +1,7 @@ +class AddDateToPollShiftComposedIndex < ActiveRecord::Migration + def change + remove_index "poll_shifts", name: "index_poll_shifts_on_booth_id_and_officer_id_and_task" + remove_index "poll_shifts", name: "index_poll_shifts_on_task" + add_index :poll_shifts, [:booth_id, :officer_id, :date, :task], unique: true + end +end diff --git a/db/migrate/20171003223152_add_officer_to_poll_voter.rb b/db/migrate/20171003223152_add_officer_to_poll_voter.rb new file mode 100644 index 000000000..99f9cd3e3 --- /dev/null +++ b/db/migrate/20171003223152_add_officer_to_poll_voter.rb @@ -0,0 +1,5 @@ +class AddOfficerToPollVoter < ActiveRecord::Migration + def change + add_column :poll_voters, :officer_id, :integer + end +end diff --git a/db/migrate/20171004025903_create_poll_question_answers.rb b/db/migrate/20171004025903_create_poll_question_answers.rb new file mode 100644 index 000000000..834421f5f --- /dev/null +++ b/db/migrate/20171004025903_create_poll_question_answers.rb @@ -0,0 +1,9 @@ +class CreatePollQuestionAnswers < ActiveRecord::Migration + def change + create_table :poll_question_answers do |t| + t.string :title + t.text :description + t.references :poll_question, index: true, foreign_key: true + end + end +end diff --git a/db/migrate/20171004151553_rename_poll_question_id_to_question_id.rb b/db/migrate/20171004151553_rename_poll_question_id_to_question_id.rb new file mode 100644 index 000000000..c53298bfb --- /dev/null +++ b/db/migrate/20171004151553_rename_poll_question_id_to_question_id.rb @@ -0,0 +1,5 @@ +class RenamePollQuestionIdToQuestionId < ActiveRecord::Migration + def change + rename_column :poll_question_answers, :poll_question_id, :question_id + end +end diff --git a/db/migrate/20171004210108_create_poll_question_answer_videos.rb b/db/migrate/20171004210108_create_poll_question_answer_videos.rb new file mode 100644 index 000000000..7cce33b29 --- /dev/null +++ b/db/migrate/20171004210108_create_poll_question_answer_videos.rb @@ -0,0 +1,11 @@ +class CreatePollQuestionAnswerVideos < ActiveRecord::Migration + def change + create_table :poll_question_answer_videos do |t| + t.string :title + t.string :url + t.integer :answer_id, index: true + end + + add_foreign_key :poll_question_answer_videos, :poll_question_answers, column: :answer_id + end +end diff --git a/db/migrate/20171006145053_add_token_to_poll_voters.rb b/db/migrate/20171006145053_add_token_to_poll_voters.rb new file mode 100644 index 000000000..5d07f5065 --- /dev/null +++ b/db/migrate/20171006145053_add_token_to_poll_voters.rb @@ -0,0 +1,5 @@ +class AddTokenToPollVoters < ActiveRecord::Migration + def change + add_column :poll_voters, :token, :string + end +end diff --git a/db/migrate/20171010143623_add_given_order_to_poll_question_answers.rb b/db/migrate/20171010143623_add_given_order_to_poll_question_answers.rb new file mode 100644 index 000000000..6161e55e4 --- /dev/null +++ b/db/migrate/20171010143623_add_given_order_to_poll_question_answers.rb @@ -0,0 +1,5 @@ +class AddGivenOrderToPollQuestionAnswers < ActiveRecord::Migration + def change + add_column :poll_question_answers, :given_order, :integer, default: 1 + end +end diff --git a/db/migrate/20171017221546_remove_poll_question_valid_answers.rb b/db/migrate/20171017221546_remove_poll_question_valid_answers.rb new file mode 100644 index 000000000..e4c1ebb11 --- /dev/null +++ b/db/migrate/20171017221546_remove_poll_question_valid_answers.rb @@ -0,0 +1,5 @@ +class RemovePollQuestionValidAnswers < ActiveRecord::Migration + def change + remove_column :poll_questions, :valid_answers + end +end diff --git a/db/migrate/20171019095042_add_most_voted_to_poll_question_answer.rb b/db/migrate/20171019095042_add_most_voted_to_poll_question_answer.rb new file mode 100644 index 000000000..e4650643b --- /dev/null +++ b/db/migrate/20171019095042_add_most_voted_to_poll_question_answer.rb @@ -0,0 +1,5 @@ +class AddMostVotedToPollQuestionAnswer < ActiveRecord::Migration + def change + add_column :poll_question_answers, :most_voted, :boolean, default: false + end +end diff --git a/db/migrate/20171020163240_add_results_and_stats_to_polls.rb b/db/migrate/20171020163240_add_results_and_stats_to_polls.rb new file mode 100644 index 000000000..af6f82aaa --- /dev/null +++ b/db/migrate/20171020163240_add_results_and_stats_to_polls.rb @@ -0,0 +1,6 @@ +class AddResultsAndStatsToPolls < ActiveRecord::Migration + def change + add_column :polls, :results_enabled, :boolean, default: false + add_column :polls, :stats_enabled, :boolean, default: false + end +end diff --git a/db/migrate/20171025142440_add_cached_votes_to_legislation_proposals.rb b/db/migrate/20171025142440_add_cached_votes_to_legislation_proposals.rb new file mode 100644 index 000000000..92544ddb6 --- /dev/null +++ b/db/migrate/20171025142440_add_cached_votes_to_legislation_proposals.rb @@ -0,0 +1,6 @@ +class AddCachedVotesToLegislationProposals < ActiveRecord::Migration + def change + add_column :legislation_proposals, :cached_votes_total, :integer, default: 0 + add_column :legislation_proposals, :cached_votes_down, :integer, default: 0 + end +end diff --git a/db/migrate/20171115164152_add_time_zone_to_default_datetimes.rb b/db/migrate/20171115164152_add_time_zone_to_default_datetimes.rb new file mode 100644 index 000000000..13bc51264 --- /dev/null +++ b/db/migrate/20171115164152_add_time_zone_to_default_datetimes.rb @@ -0,0 +1,6 @@ +class AddTimeZoneToDefaultDatetimes < ActiveRecord::Migration + def change + change_column_default :users, :password_changed_at, DateTime.new(2015, 1, 1, 1, 1, 1, '+00:00') + change_column_default :locks, :locked_until, DateTime.new(2000, 1, 1, 1, 1, 1, '+00:00') + end +end diff --git a/db/migrate/20171127171925_create_related_content.rb b/db/migrate/20171127171925_create_related_content.rb new file mode 100644 index 000000000..2944938e2 --- /dev/null +++ b/db/migrate/20171127171925_create_related_content.rb @@ -0,0 +1,12 @@ +class CreateRelatedContent < ActiveRecord::Migration + def change + create_table :related_contents do |t| + t.references :parent_relationable, polymorphic: true, index: { name: 'index_related_contents_on_parent_relationable' } + t.references :child_relationable, polymorphic: true, index: { name: 'index_related_contents_on_child_relationable' } + t.references :related_content, index: { name: 'opposite_related_content' } + t.timestamps + end + + add_index :related_contents, [:parent_relationable_id, :parent_relationable_type, :child_relationable_id, :child_relationable_type], name: "unique_parent_child_related_content", unique: true, using: :btree + end +end diff --git a/db/migrate/20171127230716_add_time_reported_to_related_content.rb b/db/migrate/20171127230716_add_time_reported_to_related_content.rb new file mode 100644 index 000000000..5cca12cf3 --- /dev/null +++ b/db/migrate/20171127230716_add_time_reported_to_related_content.rb @@ -0,0 +1,5 @@ +class AddTimeReportedToRelatedContent < ActiveRecord::Migration + def change + add_column :related_contents, :times_reported, :integer, default: 0 + end +end diff --git a/db/migrate/20171212154048_add_publication_date_to_milestones.rb b/db/migrate/20171212154048_add_publication_date_to_milestones.rb new file mode 100644 index 000000000..e5e37bb24 --- /dev/null +++ b/db/migrate/20171212154048_add_publication_date_to_milestones.rb @@ -0,0 +1,13 @@ +class AddPublicationDateToMilestones < ActiveRecord::Migration + def up + change_table :budget_investment_milestones do |t| + t.datetime :publication_date + end + end + + def down + change_table :budget_investment_milestones do |t| + t.remove :publication_date + end + end +end diff --git a/db/migrate/20171212193323_add_timestamps_to_polls.rb b/db/migrate/20171212193323_add_timestamps_to_polls.rb new file mode 100644 index 000000000..9c955b278 --- /dev/null +++ b/db/migrate/20171212193323_add_timestamps_to_polls.rb @@ -0,0 +1,5 @@ +class AddTimestampsToPolls < ActiveRecord::Migration + def change + add_timestamps :polls, null: true + end +end diff --git a/db/migrate/20171215152244_change_related_content_times_reported_column.rb b/db/migrate/20171215152244_change_related_content_times_reported_column.rb new file mode 100644 index 000000000..7da58bba5 --- /dev/null +++ b/db/migrate/20171215152244_change_related_content_times_reported_column.rb @@ -0,0 +1,5 @@ +class ChangeRelatedContentTimesReportedColumn < ActiveRecord::Migration + def change + rename_column :related_contents, :times_reported, :flags_count + end +end diff --git a/db/migrate/20171219111046_remove_related_contents_flags_count.rb b/db/migrate/20171219111046_remove_related_contents_flags_count.rb new file mode 100644 index 000000000..b0f5aead5 --- /dev/null +++ b/db/migrate/20171219111046_remove_related_contents_flags_count.rb @@ -0,0 +1,5 @@ +class RemoveRelatedContentsFlagsCount < ActiveRecord::Migration + def change + remove_column :related_contents, :flags_count + end +end diff --git a/db/migrate/20171219184209_create_related_content_scores.rb b/db/migrate/20171219184209_create_related_content_scores.rb new file mode 100644 index 000000000..7a54ba56d --- /dev/null +++ b/db/migrate/20171219184209_create_related_content_scores.rb @@ -0,0 +1,11 @@ +class CreateRelatedContentScores < ActiveRecord::Migration + def change + create_table :related_content_scores do |t| + t.references :user, index: true, foreign_key: true + t.references :related_content, index: true, foreign_key: true + t.integer :value + end + + add_index :related_content_scores, [:user_id, :related_content_id], name: "unique_user_related_content_scoring", unique: true, using: :btree + end +end diff --git a/db/migrate/20171219235102_add_hidden_at_to_related_contents.rb b/db/migrate/20171219235102_add_hidden_at_to_related_contents.rb new file mode 100644 index 000000000..423eeb1f1 --- /dev/null +++ b/db/migrate/20171219235102_add_hidden_at_to_related_contents.rb @@ -0,0 +1,6 @@ +class AddHiddenAtToRelatedContents < ActiveRecord::Migration + def change + add_column :related_contents, :hidden_at, :datetime + add_index :related_contents, :hidden_at + end +end diff --git a/db/migrate/20171220002802_add_related_content_scores_counter_to_related_content.rb b/db/migrate/20171220002802_add_related_content_scores_counter_to_related_content.rb new file mode 100644 index 000000000..497d4f7a1 --- /dev/null +++ b/db/migrate/20171220002802_add_related_content_scores_counter_to_related_content.rb @@ -0,0 +1,5 @@ +class AddRelatedContentScoresCounterToRelatedContent < ActiveRecord::Migration + def change + add_column :related_contents, :related_content_scores_count, :integer, default: 0 + end +end diff --git a/db/migrate/20171220010000_add_author_to_related_content.rb b/db/migrate/20171220010000_add_author_to_related_content.rb new file mode 100644 index 000000000..4ca621845 --- /dev/null +++ b/db/migrate/20171220010000_add_author_to_related_content.rb @@ -0,0 +1,5 @@ +class AddAuthorToRelatedContent < ActiveRecord::Migration + def change + add_column :related_contents, :author_id, :integer + end +end diff --git a/db/migrate/20180108182839_add_drafting_phase_to_budget.rb b/db/migrate/20180108182839_add_drafting_phase_to_budget.rb new file mode 100644 index 000000000..9a8febb97 --- /dev/null +++ b/db/migrate/20180108182839_add_drafting_phase_to_budget.rb @@ -0,0 +1,5 @@ +class AddDraftingPhaseToBudget < ActiveRecord::Migration + def change + add_column :budgets, :description_drafting, :text + end +end diff --git a/db/schema.rb b/db/schema.rb index 240abcdaa..d599658c1 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170918231410) do +ActiveRecord::Schema.define(version: 20180108182839) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -119,10 +119,11 @@ ActiveRecord::Schema.define(version: 20170918231410) do create_table "budget_investment_milestones", force: :cascade do |t| t.integer "investment_id" - t.string "title", limit: 80 + t.string "title", limit: 80 t.text "description" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.datetime "publication_date" end create_table "budget_investments", force: :cascade do |t| @@ -200,6 +201,7 @@ ActiveRecord::Schema.define(version: 20170918231410) do t.text "description_reviewing_ballots" t.text "description_finished" t.string "slug" + t.text "description_drafting" end create_table "campaigns", force: :cascade do |t| @@ -388,6 +390,22 @@ ActiveRecord::Schema.define(version: 20170918231410) do add_index "identities", ["user_id"], name: "index_identities_on_user_id", using: :btree + create_table "images", force: :cascade do |t| + t.integer "imageable_id" + t.string "imageable_type" + t.string "title", limit: 80 + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "attachment_file_name" + t.string "attachment_content_type" + t.integer "attachment_file_size" + t.datetime "attachment_updated_at" + t.integer "user_id" + end + + add_index "images", ["imageable_type", "imageable_id"], name: "index_images_on_imageable_type_and_imageable_id", using: :btree + add_index "images", ["user_id"], name: "index_images_on_user_id", using: :btree + create_table "legacy_legislations", force: :cascade do |t| t.string "title" t.text "body" @@ -470,6 +488,10 @@ ActiveRecord::Schema.define(version: 20170918231410) do t.boolean "draft_publication_enabled", default: false t.boolean "result_publication_enabled", default: false t.boolean "published", default: true + t.date "proposals_phase_start_date" + t.date "proposals_phase_end_date" + t.boolean "proposals_phase_enabled" + t.text "proposals_description" end add_index "legislation_processes", ["allegations_end_date"], name: "index_legislation_processes_on_allegations_end_date", using: :btree @@ -482,6 +504,38 @@ ActiveRecord::Schema.define(version: 20170918231410) do add_index "legislation_processes", ["result_publication_date"], name: "index_legislation_processes_on_result_publication_date", using: :btree add_index "legislation_processes", ["start_date"], name: "index_legislation_processes_on_start_date", using: :btree + create_table "legislation_proposals", force: :cascade do |t| + t.integer "legislation_process_id" + t.string "title", limit: 80 + t.text "description" + t.string "question" + t.string "external_url" + t.integer "author_id" + t.datetime "hidden_at" + t.integer "flags_count", default: 0 + t.datetime "ignored_flag_at" + t.integer "cached_votes_up", default: 0 + t.integer "comments_count", default: 0 + t.datetime "confirmed_hide_at" + t.integer "hot_score", limit: 8, default: 0 + t.integer "confidence_score", default: 0 + t.string "responsible_name", limit: 60 + t.text "summary" + t.string "video_url" + t.tsvector "tsv" + t.integer "geozone_id" + t.datetime "retired_at" + t.string "retired_reason" + t.text "retired_explanation" + t.integer "community_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "cached_votes_total", default: 0 + t.integer "cached_votes_down", default: 0 + end + + add_index "legislation_proposals", ["legislation_process_id"], name: "index_legislation_proposals_on_legislation_process_id", using: :btree + create_table "legislation_question_options", force: :cascade do |t| t.integer "legislation_question_id" t.string "value" @@ -520,7 +574,7 @@ ActiveRecord::Schema.define(version: 20170918231410) do create_table "locks", force: :cascade do |t| t.integer "user_id" t.integer "tries", default: 0 - t.datetime "locked_until", default: '2000-01-01 00:01:01', null: false + t.datetime "locked_until", default: '2000-01-01 01:01:01', null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false end @@ -533,6 +587,17 @@ ActiveRecord::Schema.define(version: 20170918231410) do add_index "managers", ["user_id"], name: "index_managers_on_user_id", using: :btree + create_table "map_locations", force: :cascade do |t| + t.float "latitude" + t.float "longitude" + t.integer "zoom" + t.integer "proposal_id" + t.integer "investment_id" + end + + add_index "map_locations", ["investment_id"], name: "index_map_locations_on_investment_id", using: :btree + add_index "map_locations", ["proposal_id"], name: "index_map_locations_on_proposal_id", using: :btree + create_table "moderators", force: :cascade do |t| t.integer "user_id" end @@ -586,21 +651,6 @@ ActiveRecord::Schema.define(version: 20170918231410) do t.string "location" end - create_table "poll_null_results", force: :cascade do |t| - t.integer "author_id" - t.integer "amount" - t.string "origin" - t.date "date" - t.integer "booth_assignment_id" - t.integer "officer_assignment_id" - t.text "amount_log", default: "" - t.text "officer_assignment_id_log", default: "" - t.text "author_id_log", default: "" - end - - add_index "poll_null_results", ["booth_assignment_id"], name: "index_poll_null_results_on_booth_assignment_id", using: :btree - add_index "poll_null_results", ["officer_assignment_id"], name: "index_poll_null_results_on_officer_assignment_id", using: :btree - create_table "poll_officer_assignments", force: :cascade do |t| t.integer "booth_assignment_id" t.integer "officer_id" @@ -612,7 +662,6 @@ ActiveRecord::Schema.define(version: 20170918231410) do end add_index "poll_officer_assignments", ["booth_assignment_id"], name: "index_poll_officer_assignments_on_booth_assignment_id", using: :btree - add_index "poll_officer_assignments", ["officer_id", "date"], name: "index_poll_officer_assignments_on_officer_id_and_date", using: :btree add_index "poll_officer_assignments", ["officer_id"], name: "index_poll_officer_assignments_on_officer_id", using: :btree create_table "poll_officers", force: :cascade do |t| @@ -642,14 +691,30 @@ ActiveRecord::Schema.define(version: 20170918231410) do add_index "poll_partial_results", ["origin"], name: "index_poll_partial_results_on_origin", using: :btree add_index "poll_partial_results", ["question_id"], name: "index_poll_partial_results_on_question_id", using: :btree + create_table "poll_question_answer_videos", force: :cascade do |t| + t.string "title" + t.string "url" + t.integer "answer_id" + end + + add_index "poll_question_answer_videos", ["answer_id"], name: "index_poll_question_answer_videos_on_answer_id", using: :btree + + create_table "poll_question_answers", force: :cascade do |t| + t.string "title" + t.text "description" + t.integer "question_id" + t.integer "given_order", default: 1 + t.boolean "most_voted", default: false + end + + add_index "poll_question_answers", ["question_id"], name: "index_poll_question_answers_on_question_id", using: :btree + create_table "poll_questions", force: :cascade do |t| t.integer "proposal_id" t.integer "poll_id" t.integer "author_id" t.string "author_visible_name" t.string "title" - t.string "valid_answers" - t.text "description" t.integer "comments_count" t.datetime "hidden_at" t.datetime "created_at" @@ -663,6 +728,25 @@ ActiveRecord::Schema.define(version: 20170918231410) do add_index "poll_questions", ["proposal_id"], name: "index_poll_questions_on_proposal_id", using: :btree add_index "poll_questions", ["tsv"], name: "index_poll_questions_on_tsv", using: :gin + create_table "poll_recounts", force: :cascade do |t| + t.integer "author_id" + t.string "origin" + t.date "date" + t.integer "booth_assignment_id" + t.integer "officer_assignment_id" + t.text "officer_assignment_id_log", default: "" + t.text "author_id_log", default: "" + t.integer "white_amount", default: 0 + t.text "white_amount_log", default: "" + t.integer "null_amount", default: 0 + t.text "null_amount_log", default: "" + t.integer "total_amount", default: 0 + t.text "total_amount_log", default: "" + end + + add_index "poll_recounts", ["booth_assignment_id"], name: "index_poll_recounts_on_booth_assignment_id", using: :btree + add_index "poll_recounts", ["officer_assignment_id"], name: "index_poll_recounts_on_officer_assignment_id", using: :btree + create_table "poll_shifts", force: :cascade do |t| t.integer "booth_id" t.integer "officer_id" @@ -671,27 +755,13 @@ ActiveRecord::Schema.define(version: 20170918231410) do t.datetime "updated_at" t.string "officer_name" t.string "officer_email" + t.integer "task", default: 0, null: false end - add_index "poll_shifts", ["booth_id", "officer_id"], name: "index_poll_shifts_on_booth_id_and_officer_id", using: :btree + add_index "poll_shifts", ["booth_id", "officer_id", "date", "task"], name: "index_poll_shifts_on_booth_id_and_officer_id_and_date_and_task", unique: true, using: :btree add_index "poll_shifts", ["booth_id"], name: "index_poll_shifts_on_booth_id", using: :btree add_index "poll_shifts", ["officer_id"], name: "index_poll_shifts_on_officer_id", using: :btree - create_table "poll_total_results", force: :cascade do |t| - t.integer "author_id" - t.integer "amount" - t.string "origin" - t.date "date" - t.integer "booth_assignment_id" - t.integer "officer_assignment_id" - t.text "amount_log", default: "" - t.text "officer_assignment_id_log", default: "" - t.text "author_id_log", default: "" - end - - add_index "poll_total_results", ["booth_assignment_id"], name: "index_poll_total_results_on_booth_assignment_id", using: :btree - add_index "poll_total_results", ["officer_assignment_id"], name: "index_poll_total_results_on_officer_assignment_id", using: :btree - create_table "poll_voters", force: :cascade do |t| t.string "document_number" t.string "document_type" @@ -705,6 +775,9 @@ ActiveRecord::Schema.define(version: 20170918231410) do t.integer "answer_id" t.integer "officer_assignment_id" t.integer "user_id" + t.string "origin" + t.integer "officer_id" + t.string "token" end add_index "poll_voters", ["booth_assignment_id"], name: "index_poll_voters_on_booth_assignment_id", using: :btree @@ -714,27 +787,21 @@ ActiveRecord::Schema.define(version: 20170918231410) do add_index "poll_voters", ["poll_id"], name: "index_poll_voters_on_poll_id", using: :btree add_index "poll_voters", ["user_id"], name: "index_poll_voters_on_user_id", using: :btree - create_table "poll_white_results", force: :cascade do |t| - t.integer "author_id" - t.integer "amount" - t.string "origin" - t.date "date" - t.integer "booth_assignment_id" - t.integer "officer_assignment_id" - t.text "amount_log", default: "" - t.text "officer_assignment_id_log", default: "" - t.text "author_id_log", default: "" - end - - add_index "poll_white_results", ["booth_assignment_id"], name: "index_poll_white_results_on_booth_assignment_id", using: :btree - add_index "poll_white_results", ["officer_assignment_id"], name: "index_poll_white_results_on_officer_assignment_id", using: :btree - create_table "polls", force: :cascade do |t| t.string "name" t.datetime "starts_at" t.datetime "ends_at" t.boolean "published", default: false t.boolean "geozone_restricted", default: false + t.text "summary" + t.text "description" + t.integer "comments_count", default: 0 + t.integer "author_id" + t.datetime "hidden_at" + t.boolean "results_enabled", default: false + t.boolean "stats_enabled", default: false + t.datetime "created_at" + t.datetime "updated_at" end add_index "polls", ["starts_at", "ends_at"], name: "index_polls_on_starts_at_and_ends_at", using: :btree @@ -788,6 +855,35 @@ ActiveRecord::Schema.define(version: 20170918231410) do add_index "proposals", ["title"], name: "index_proposals_on_title", using: :btree add_index "proposals", ["tsv"], name: "index_proposals_on_tsv", using: :gin + create_table "related_content_scores", force: :cascade do |t| + t.integer "user_id" + t.integer "related_content_id" + t.integer "value" + end + + add_index "related_content_scores", ["related_content_id"], name: "index_related_content_scores_on_related_content_id", using: :btree + add_index "related_content_scores", ["user_id", "related_content_id"], name: "unique_user_related_content_scoring", unique: true, using: :btree + add_index "related_content_scores", ["user_id"], name: "index_related_content_scores_on_user_id", using: :btree + + create_table "related_contents", force: :cascade do |t| + t.integer "parent_relationable_id" + t.string "parent_relationable_type" + t.integer "child_relationable_id" + t.string "child_relationable_type" + t.integer "related_content_id" + t.datetime "created_at" + t.datetime "updated_at" + t.datetime "hidden_at" + t.integer "related_content_scores_count", default: 0 + t.integer "author_id" + end + + add_index "related_contents", ["child_relationable_type", "child_relationable_id"], name: "index_related_contents_on_child_relationable", using: :btree + add_index "related_contents", ["hidden_at"], name: "index_related_contents_on_hidden_at", using: :btree + add_index "related_contents", ["parent_relationable_id", "parent_relationable_type", "child_relationable_id", "child_relationable_type"], name: "unique_parent_child_related_content", unique: true, using: :btree + add_index "related_contents", ["parent_relationable_type", "parent_relationable_id"], name: "index_related_contents_on_parent_relationable", using: :btree + add_index "related_contents", ["related_content_id"], name: "opposite_related_content", using: :btree + create_table "settings", force: :cascade do |t| t.string "key" t.string "value" @@ -894,16 +990,20 @@ ActiveRecord::Schema.define(version: 20170918231410) do add_index "taggings", ["taggable_id", "taggable_type", "context"], name: "index_taggings_on_taggable_id_and_taggable_type_and_context", using: :btree create_table "tags", force: :cascade do |t| - t.string "name", limit: 40 - t.integer "taggings_count", default: 0 - t.integer "debates_count", default: 0 - t.integer "proposals_count", default: 0 - t.integer "spending_proposals_count", default: 0 + t.string "name", limit: 40 + t.integer "taggings_count", default: 0 + t.integer "debates_count", default: 0 + t.integer "proposals_count", default: 0 + t.integer "spending_proposals_count", default: 0 t.string "kind" - t.integer "budget/investments_count", default: 0 + t.integer "budget/investments_count", default: 0 + t.integer "legislation/proposals_count", default: 0 + t.integer "legislation/processes_count", default: 0 end add_index "tags", ["debates_count"], name: "index_tags_on_debates_count", using: :btree + add_index "tags", ["legislation/processes_count"], name: "index_tags_on_legislation/processes_count", using: :btree + add_index "tags", ["legislation/proposals_count"], name: "index_tags_on_legislation/proposals_count", using: :btree add_index "tags", ["name"], name: "index_tags_on_name", unique: true, using: :btree add_index "tags", ["proposals_count"], name: "index_tags_on_proposals_count", using: :btree add_index "tags", ["spending_proposals_count"], name: "index_tags_on_spending_proposals_count", using: :btree @@ -975,7 +1075,7 @@ ActiveRecord::Schema.define(version: 20170918231410) do t.boolean "email_digest", default: true t.boolean "email_on_direct_message", default: true t.boolean "official_position_badge", default: false - t.datetime "password_changed_at", default: '2015-01-01 00:01:01', null: false + t.datetime "password_changed_at", default: '2015-01-01 01:01:01', null: false t.boolean "created_from_signature", default: false t.integer "failed_email_digests_count", default: 0 t.text "former_users_data_log", default: "" @@ -1079,7 +1179,9 @@ ActiveRecord::Schema.define(version: 20170918231410) do add_foreign_key "geozones_polls", "geozones" add_foreign_key "geozones_polls", "polls" add_foreign_key "identities", "users" + add_foreign_key "images", "users" add_foreign_key "legislation_draft_versions", "legislation_processes" + add_foreign_key "legislation_proposals", "legislation_processes" add_foreign_key "locks", "users" add_foreign_key "managers", "users" add_foreign_key "moderators", "users" @@ -1087,20 +1189,22 @@ ActiveRecord::Schema.define(version: 20170918231410) do add_foreign_key "organizations", "users" add_foreign_key "poll_answers", "poll_questions", column: "question_id" add_foreign_key "poll_booth_assignments", "polls" - add_foreign_key "poll_null_results", "poll_booth_assignments", column: "booth_assignment_id" - add_foreign_key "poll_null_results", "poll_officer_assignments", column: "officer_assignment_id" add_foreign_key "poll_officer_assignments", "poll_booth_assignments", column: "booth_assignment_id" add_foreign_key "poll_partial_results", "poll_booth_assignments", column: "booth_assignment_id" add_foreign_key "poll_partial_results", "poll_officer_assignments", column: "officer_assignment_id" add_foreign_key "poll_partial_results", "poll_questions", column: "question_id" add_foreign_key "poll_partial_results", "users", column: "author_id" + add_foreign_key "poll_question_answer_videos", "poll_question_answers", column: "answer_id" + add_foreign_key "poll_question_answers", "poll_questions", column: "question_id" add_foreign_key "poll_questions", "polls" add_foreign_key "poll_questions", "proposals" add_foreign_key "poll_questions", "users", column: "author_id" + add_foreign_key "poll_recounts", "poll_booth_assignments", column: "booth_assignment_id" + add_foreign_key "poll_recounts", "poll_officer_assignments", column: "officer_assignment_id" add_foreign_key "poll_voters", "polls" - add_foreign_key "poll_white_results", "poll_booth_assignments", column: "booth_assignment_id" - add_foreign_key "poll_white_results", "poll_officer_assignments", column: "officer_assignment_id" add_foreign_key "proposals", "communities" + add_foreign_key "related_content_scores", "related_contents" + add_foreign_key "related_content_scores", "users" add_foreign_key "users", "geozones" add_foreign_key "valuators", "users" end diff --git a/db/seeds.rb b/db/seeds.rb index 96916f29a..529aaa925 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -65,11 +65,13 @@ Setting["org_name"] = "CONSUL" Setting["place_name"] = "CONSUL-land" # Meta tags for SEO +Setting["meta_title"] = nil Setting["meta_description"] = nil Setting["meta_keywords"] = nil # Feature flags Setting['feature.debates'] = true +Setting['feature.proposals'] = true Setting['feature.spending_proposals'] = nil Setting['feature.polls'] = true Setting['feature.twitter_login'] = true @@ -79,7 +81,10 @@ Setting['feature.public_stats'] = true Setting['feature.budgets'] = true Setting['feature.signature_sheets'] = true Setting['feature.legislation'] = true +Setting['feature.user.recommendations'] = true Setting['feature.community'] = true +Setting['feature.map'] = nil +Setting['feature.allow_images'] = true # Spending proposals feature flags Setting['feature.spending_proposal_features.voting_allowed'] = nil @@ -108,3 +113,11 @@ Setting['min_age_to_participate'] = 16 # Proposal improvement url path ('/more-information/proposal-improvement') Setting['proposal_improvement_path'] = nil + +# City map feature default configuration (Greenwich) +Setting['map_latitude'] = 51.48 +Setting['map_longitude'] = 0.0 +Setting['map_zoom'] = 10 + +# Related content +Setting['related_content_score_threshold'] = -0.3 diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..d5399089e --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,31 @@ +# service configuration for our database +database: + + # use the preferred version of the official Postgres image + # see https://hub.docker.com/_/postgres/ + image: postgres:9.4.5 + + # persist the database between containers by storing it in a volume + volumes: + - docker-example-postgres:/var/lib/postgresql/data + +# service configuration for our dockerized Rails app +app: + + # use the Dockerfile next to this file + build: . + + # rely on the RAILS_ENV value of the host machine + # environment: + #RAILS_ENV: $RAILS_ENV + + # makes the app container aware of the DB container + links: + - database + + # expose the port we configured Unicorn to bind to + ports: + - "3000:3000" + # map our application source code, in full, to the application root of our container + volumes: + - .:/var/www/consul diff --git a/knapsack_rspec_report.json b/knapsack_rspec_report.json index 595276b2b..5f1fc06b5 100644 --- a/knapsack_rspec_report.json +++ b/knapsack_rspec_report.json @@ -1,226 +1,227 @@ { - "spec/helpers/comments_helper_spec.rb": 0.010898828506469727, - "spec/controllers/graphql_controller_spec.rb": 0.7817962169647217, - "spec/controllers/concerns/has_orders_spec.rb": 0.09597063064575195, - "spec/features/officing/results_spec.rb": 2.6492855548858643, - "spec/models/poll/question_spec.rb": 0.09519433975219727, - "spec/features/organizations_spec.rb": 1.9025108814239502, - "spec/models/legislation/process_spec.rb": 0.09253501892089844, - "spec/lib/acts_as_paranoid_aliases_spec.rb": 0.2438969612121582, - "spec/features/officing_spec.rb": 1.4767742156982422, - "spec/lib/age_spec.rb": 0.0006227493286132812, - "spec/models/proposal_spec.rb": 5.535696983337402, - "spec/models/abilities/administrator_spec.rb": 2.2431821823120117, - "spec/models/poll/final_recount_spec.rb": 0.1787703037261963, - "spec/lib/graph_ql/query_type_creator_spec.rb": 0.012041091918945312, - "spec/models/verification/management/email_spec.rb": 0.06403493881225586, - "spec/models/flag_spec.rb": 0.46442556381225586, - "spec/features/tags/budget_investments_spec.rb": 23.748523235321045, - "spec/features/campaigns_spec.rb": 1.3289697170257568, - "spec/features/admin/activity_spec.rb": 7.763890743255615, - "spec/features/polls/questions_spec.rb": 2.61055326461792, - "spec/features/polls/polls_spec.rb": 2.313369035720825, - "spec/features/home_spec.rb": 0.9780440330505371, - "spec/models/poll/partial_result_spec.rb": 0.3302469253540039, - "spec/models/lock_spec.rb": 0.09437012672424316, - "spec/lib/graph_ql/api_types_creator_spec.rb": 0.0069005489349365234, - "spec/helpers/users_helper_spec.rb": 0.3229796886444092, - "spec/lib/local_census_spec.rb": 0.011091947555541992, - "spec/helpers/text_helper_spec.rb": 0.0005347728729248047, - "spec/customization_engine_spec.rb": 1.3630127906799316, - "spec/models/legislation/answer_spec.rb": 0.6906075477600098, - "spec/models/budget/ballot/line_spec.rb": 0.5054352283477783, - "spec/features/admin/proposals_spec.rb": 1.6710176467895508, - "spec/features/proposal_ballots_spec.rb": 0.3399386405944824, - "spec/models/site_customization/content_block_spec.rb": 0.014521121978759766, - "spec/features/admin/site_customization/content_blocks_spec.rb": 1.2890841960906982, - "spec/models/site_customization/page_spec.rb": 0.011090993881225586, - "spec/features/verification/email_spec.rb": 1.0991628170013428, - "spec/models/proposal_notification_spec.rb": 0.2569601535797119, - "spec/features/registration_form_spec.rb": 0.7285032272338867, - "spec/features/communities_spec.rb": 1.7133822441101074, - "spec/features/admin/moderators_spec.rb": 1.2922589778900146, - "spec/helpers/geozones_helper_spec.rb": 0.09812736511230469, - "spec/features/welcome_spec.rb": 1.5019774436950684, - "spec/controllers/comments_controller_spec.rb": 0.36508607864379883, - "spec/features/admin/legislation/questions_spec.rb": 3.81538724899292, - "spec/controllers/users/registrations_controller_spec.rb": 0.018311023712158203, - "spec/features/comments/debates_spec.rb": 12.265411615371704, - "spec/features/users_spec.rb": 11.05901050567627, - "spec/models/budget/group_spec.rb": 0.04957008361816406, - "spec/features/admin/poll/questions_spec.rb": 1.9041199684143066, - "spec/helpers/admin_helper_spec.rb": 0.00651097297668457, - "spec/models/abilities/organization_spec.rb": 0.24821996688842773, - "spec/features/moderation/comments_spec.rb": 6.318082332611084, - "spec/features/admin/poll/polls_spec.rb": 8.88325023651123, - "spec/models/activity_spec.rb": 0.9704892635345459, - "spec/features/verification/level_two_verification_spec.rb": 0.421832799911499, - "spec/models/poll/officer_assignment_spec.rb": 0.029267072677612305, - "spec/features/admin/verifications_spec.rb": 0.507885217666626, - "spec/mailers/mailer_spec.rb": 0.07406282424926758, - "spec/models/legislation/draft_version_spec.rb": 0.025011777877807617, - "spec/models/budget/investment_spec.rb": 9.084597826004028, - "spec/features/proposals_spec.rb": 183.71455550193787, - "spec/features/tags_spec.rb": 2.949070453643799, - "spec/features/tags/debates_spec.rb": 4.345250368118286, - "spec/features/admin/geozones_spec.rb": 1.935765027999878, - "spec/features/admin/feature_flags_spec.rb": 0.8357558250427246, - "spec/models/user_spec.rb": 2.436626434326172, - "spec/features/moderation/debates_spec.rb": 6.05112886428833, - "spec/models/legislation/annotation_spec.rb": 0.21427702903747559, - "spec/features/comments/proposals_spec.rb": 32.52879500389099, - "spec/controllers/legislation/answers_controller_spec.rb": 0.3481717109680176, - "spec/features/verification/sms_spec.rb": 1.2817349433898926, - "spec/features/admin/budget_investments_spec.rb": 16.1332266330719, - "spec/features/notifications_spec.rb": 14.857182264328003, - "spec/lib/tag_sanitizer_spec.rb": 0.0005936622619628906, - "spec/controllers/admin/api/stats_controller_spec.rb": 0.3948392868041992, - "spec/features/comments/topics_spec.rb": 29.646622896194458, - "spec/models/debate_spec.rb": 5.2278876304626465, - "spec/lib/email_digests_spec.rb": 0.6660604476928711, - "spec/models/abilities/everyone_spec.rb": 0.06328749656677246, - "spec/features/direct_messages_spec.rb": 1.3006987571716309, - "spec/features/debates_spec.rb": 28.736626386642456, - "spec/models/setting_spec.rb": 0.07938265800476074, - "spec/models/legislation/question_option_spec.rb": 0.058206796646118164, - "spec/models/verification/management/document_spec.rb": 0.013574600219726562, - "spec/models/poll/booth_spec.rb": 0.07824325561523438, - "spec/features/admin/legislation/draft_versions_spec.rb": 3.750009059906006, - "spec/features/admin/poll/officers_spec.rb": 1.4151291847229004, - "spec/features/moderation_spec.rb": 1.9578778743743896, - "spec/features/legislation/questions_spec.rb": 1.7689197063446045, - "spec/features/officing/residence_spec.rb": 0.971078634262085, - "spec/models/follow_spec.rb": 0.12199592590332031, - "spec/lib/census_api_spec.rb": 0.0019702911376953125, - "spec/models/tag_cloud_spec.rb": 1.5725350379943848, - "spec/models/budget_spec.rb": 0.2335052490234375, - "spec/features/management/localization_spec.rb": 1.1911811828613281, - "spec/features/legislation/draft_versions_spec.rb": 8.151643514633179, - "spec/models/budget/heading_spec.rb": 0.09901237487792969, - "spec/models/poll/poll_spec.rb": 0.46999382972717285, - "spec/models/custom/residence_spec.rb": 0.050164222717285156, - "spec/models/notification_spec.rb": 0.39408183097839355, - "spec/features/budgets/ballots_spec.rb": 27.406018257141113, - "spec/mailers/devise_mailer_spec.rb": 0.16486406326293945, - "spec/features/admin/debates_spec.rb": 1.546919345855713, - "spec/features/valuation/budgets_spec.rb": 0.2552778720855713, - "spec/models/abilities/common_spec.rb": 6.724466562271118, - "spec/models/residence_spec.rb": 0.24986696243286133, - "spec/features/officing/voters_spec.rb": 2.954087257385254, - "spec/models/vote_spec.rb": 1.3241477012634277, - "spec/lib/migrate_spending_proposals_to_investments_spec.rb": 1.1774518489837646, - "spec/controllers/management/users_controller_spec.rb": 0.007733821868896484, - "spec/helpers/proposals_helper_spec.rb": 0.21885180473327637, - "spec/features/ckeditor_spec.rb": 0.7726309299468994, - "spec/lib/census_caller_spec.rb": 0.009332895278930664, - "spec/features/tracks_spec.rb": 2.7082908153533936, - "spec/features/admin/budgets_spec.rb": 4.468225002288818, - "spec/features/admin/valuators_spec.rb": 1.3326430320739746, - "spec/features/admin/banners_spec.rb": 3.302579164505005, - "spec/features/account_spec.rb": 2.30243182182312, - "spec/features/budgets/budgets_spec.rb": 1.0318260192871094, - "spec/models/poll/answer_spec.rb": 0.11362218856811523, - "spec/features/comments/budget_investments_spec.rb": 16.92409658432007, - "spec/features/budgets/results_spec.rb": 2.589841365814209, - "spec/features/valuation_spec.rb": 2.126727819442749, - "spec/features/stats_spec.rb": 0.8516559600830078, - "spec/features/admin/poll/booths_spec.rb": 1.766916275024414, - "spec/models/legislation/process/phase_spec.rb": 0.0886683464050293, - "spec/models/budget/investment/milestone_spec.rb": 0.1419520378112793, - "spec/models/letter_spec.rb": 0.08197903633117676, - "spec/features/admin/stats_spec.rb": 3.6946730613708496, - "spec/models/identity_spec.rb": 0.004762887954711914, - "spec/features/verification/letter_spec.rb": 1.7480952739715576, - "spec/models/topic_spec.rb": 0.30414509773254395, - "spec/features/users_auth_spec.rb": 7.242254257202148, - "spec/lib/acts_as_taggable_on_spec.rb": 0.7477433681488037, - "spec/features/official_positions_spec.rb": 1.9427640438079834, - "spec/features/admin/newsletters_spec.rb": 0.22768402099609375, - "spec/features/admin/hidden_users_spec.rb": 1.4156956672668457, - "spec/features/comments/legislation_annotations_spec.rb": 18.616747856140137, - "spec/features/admin/site_customization/pages_spec.rb": 1.0219447612762451, - "spec/models/poll/shift_spec.rb": 0.2051677703857422, - "spec/models/geozone_spec.rb": 0.12972474098205566, - "spec/helpers/verification_helper_spec.rb": 0.0009250640869140625, - "spec/lib/cache_spec.rb": 0.06447911262512207, - "spec/features/verification/verification_path_spec.rb": 1.2300751209259033, - "spec/features/sessions_spec.rb": 0.3665180206298828, - "spec/controllers/management/base_controller_spec.rb": 0.019928932189941406, - "spec/features/verification/verified_user_spec.rb": 0.787623405456543, - "spec/models/direct_message_spec.rb": 0.49156641960144043, - "spec/features/admin/tags_spec.rb": 1.045637845993042, - "spec/features/admin/comments_spec.rb": 3.4312756061553955, - "spec/features/moderation/users_spec.rb": 1.1841027736663818, - "spec/models/budget/reclassified_vote_spec.rb": 0.22663235664367676, - "spec/features/admin/organizations_spec.rb": 3.4465878009796143, - "spec/features/proposal_notifications_spec.rb": 4.40612268447876, - "spec/features/emails_spec.rb": 13.047018051147461, - "spec/controllers/debates_controller_spec.rb": 0.3078582286834717, - "spec/features/budgets/investments_spec.rb": 126.55784440040588, - "spec/features/verification/residence_spec.rb": 1.8894774913787842, - "spec/models/abilities/moderator_spec.rb": 2.7029502391815186, - "spec/helpers/votes_helper_spec.rb": 0.363523006439209, - "spec/features/tags/proposals_spec.rb": 8.272820949554443, - "spec/models/signature_spec.rb": 1.6858570575714111, - "spec/models/legislation/process/publication_spec.rb": 0.0707387924194336, - "spec/models/community_spec.rb": 0.13965797424316406, - "spec/models/sms_spec.rb": 0.024147987365722656, - "spec/lib/graphql_spec.rb": 3.7293970584869385, - "spec/lib/tasks/communities_spec.rb": 0.17484474182128906, - "spec/features/management/proposals_spec.rb": 4.549585580825806, - "spec/models/document_spec.rb": 1.2667145729064941, - "spec/features/site_customization/content_blocks_spec.rb": 0.3020951747894287, - "spec/features/localization_spec.rb": 0.5679850578308105, - "spec/models/signature_sheet_spec.rb": 0.7970001697540283, - "spec/features/budgets/votes_spec.rb": 4.38911509513855, - "spec/features/verification/level_three_verification_spec.rb": 1.2754230499267578, - "spec/features/admin/users_spec.rb": 0.3584918975830078, - "spec/models/abilities/valuator_spec.rb": 1.1300320625305176, - "spec/models/officing/residence_spec.rb": 0.3599817752838135, - "spec/features/admin/officials_spec.rb": 0.940401554107666, - "spec/features/admin/settings_spec.rb": 0.37268495559692383, - "spec/models/ahoy/data_source_spec.rb": 0.04887723922729492, - "spec/helpers/settings_helper_spec.rb": 0.020088911056518555, - "spec/models/budget/result_spec.rb": 0.7962813377380371, - "spec/models/poll/null_result_spec.rb": 0.17995309829711914, - "spec/models/valuator_spec.rb": 0.02411341667175293, - "spec/lib/manager_authenticator_spec.rb": 0.0031435489654541016, - "spec/lib/tasks/settings_spec.rb": 0.07562613487243652, - "spec/controllers/legislation/annotations_controller_spec.rb": 0.712010383605957, - "spec/models/comment_spec.rb": 1.7274408340454102, - "spec/features/comments/legislation_questions_spec.rb": 15.219935894012451, - "spec/features/admin_spec.rb": 1.1390578746795654, - "spec/features/admin/poll/booth_assigments_spec.rb": 3.737426280975342, - "spec/controllers/pages_controller_spec.rb": 0.3043200969696045, - "spec/features/admin/administrators_spec.rb": 2.7916433811187744, - "spec/models/poll/total_result_spec.rb": 0.549537181854248, - "spec/features/management/managed_users_spec.rb": 4.38576078414917, - "spec/models/poll/officer_spec.rb": 0.49225711822509766, - "spec/features/user_invites_spec.rb": 0.21891093254089355, - "spec/helpers/application_helper_spec.rb": 0.13661718368530273, - "spec/features/management/account_spec.rb": 0.9717822074890137, - "spec/features/management/document_verifications_spec.rb": 1.0395607948303223, - "spec/features/admin/site_customization/images_spec.rb": 1.2623581886291504, - "spec/models/organization_spec.rb": 0.16587495803833008, - "spec/features/management/email_verifications_spec.rb": 0.46370506286621094, - "spec/features/legislation/processes_spec.rb": 3.2473270893096924, - "spec/features/admin/managers_spec.rb": 1.1836414337158203, - "spec/models/legislation/question_spec.rb": 0.4404168128967285, - "spec/features/management/budget_investments_spec.rb": 7.179029703140259, - "spec/features/admin/signature_sheets_spec.rb": 1.4004056453704834, - "spec/features/admin/poll/shifts_spec.rb": 2.6800806522369385, - "spec/i18n_spec.rb": 58.107173204422, - "spec/features/site_customization/custom_pages_spec.rb": 0.454498291015625, - "spec/features/admin/legislation/processes_spec.rb": 3.3492519855499268, - "spec/features/votes_spec.rb": 16.538654088974, - "spec/features/admin/budget_investment_milestones_spec.rb": 1.3747622966766357, - "spec/models/poll/white_result_spec.rb": 0.23045921325683594, - "spec/controllers/management/sessions_controller_spec.rb": 0.06758952140808105, - "spec/features/management/users_spec.rb": 2.044326066970825, - "spec/controllers/concerns/has_filters_spec.rb": 0.275907039642334, - "spec/features/moderation/proposals_spec.rb": 5.00596022605896, - "spec/lib/wysiwyg_sanitizer_spec.rb": 0.0016448497772216797, - "spec/models/budget/ballot_spec.rb": 0.6595156192779541, - "spec/models/poll/voter_spec.rb": 0.2982313632965088, - "spec/features/valuation/budget_investments_spec.rb": 6.490516185760498 + "spec/models/setting_spec.rb": 0.07869887351989746, + "spec/features/admin/managers_spec.rb": 5.029380798339844, + "spec/features/management/managed_users_spec.rb": 3.1642160415649414, + "spec/features/admin/poll/booths_spec.rb": 1.4152588844299316, + "spec/features/admin/comments_spec.rb": 3.889301061630249, + "spec/helpers/admin_helper_spec.rb": 0.005057334899902344, + "spec/models/abilities/moderator_spec.rb": 2.3274271488189697, + "spec/controllers/admin/api/stats_controller_spec.rb": 0.4249396324157715, + "spec/features/admin/organizations_spec.rb": 3.339292049407959, + "spec/features/admin/newsletters_spec.rb": 0.2460641860961914, + "spec/helpers/geozones_helper_spec.rb": 0.08249163627624512, + "spec/lib/graph_ql/api_types_creator_spec.rb": 0.006573915481567383, + "spec/features/emails_spec.rb": 18.91256046295166, + "spec/features/admin/hidden_users_spec.rb": 1.3854436874389648, + "spec/features/welcome_spec.rb": 1.1956276893615723, + "spec/features/sessions_spec.rb": 0.3943772315979004, + "spec/models/custom/residence_spec.rb": 0.07002687454223633, + "spec/models/poll/booth_spec.rb": 0.05489993095397949, + "spec/models/direct_message_spec.rb": 0.3973381519317627, + "spec/features/valuation/budget_investments_spec.rb": 7.6013023853302, + "spec/models/map_location_spec.rb": 0.12476563453674316, + "spec/models/budget/heading_spec.rb": 0.09248590469360352, + "spec/models/user_spec.rb": 2.9006423950195312, + "spec/features/admin/site_customization/content_blocks_spec.rb": 1.6733989715576172, + "spec/mailers/mailer_spec.rb": 0.08513784408569336, + "spec/models/site_customization/page_spec.rb": 0.015056133270263672, + "spec/features/management/budget_investments_spec.rb": 8.112786293029785, + "spec/features/admin/activity_spec.rb": 12.442089080810547, + "spec/features/registration_form_spec.rb": 1.0509357452392578, + "spec/controllers/legislation/annotations_controller_spec.rb": 0.8151364326477051, + "spec/lib/census_caller_spec.rb": 0.018165111541748047, + "spec/features/users_auth_spec.rb": 6.5102221965789795, + "spec/features/tags/proposals_spec.rb": 10.001718521118164, + "spec/features/account_spec.rb": 2.2510504722595215, + "spec/features/admin/users_spec.rb": 0.4342050552368164, + "spec/lib/cache_spec.rb": 0.057682037353515625, + "spec/features/valuation_spec.rb": 1.3436784744262695, + "spec/models/budget/investment_spec.rb": 12.89230751991272, + "spec/lib/migrate_spending_proposals_to_investments_spec.rb": 0.904367208480835, + "spec/helpers/settings_helper_spec.rb": 0.02300858497619629, + "spec/helpers/application_helper_spec.rb": 0.09152626991271973, + "spec/models/legislation/draft_version_spec.rb": 0.020322084426879883, + "spec/models/legislation/question_spec.rb": 0.3402721881866455, + "spec/models/document_spec.rb": 1.3238348960876465, + "spec/models/poll/question_spec.rb": 0.12588191032409668, + "spec/features/admin/poll/polls_spec.rb": 11.77881646156311, + "spec/lib/manager_authenticator_spec.rb": 0.006296873092651367, + "spec/features/admin/debates_spec.rb": 1.688420295715332, + "spec/features/moderation/debates_spec.rb": 5.343512773513794, + "spec/controllers/debates_controller_spec.rb": 0.40573883056640625, + "spec/models/tag_cloud_spec.rb": 1.6984672546386719, + "spec/models/budget/investment/milestone_spec.rb": 0.15051603317260742, + "spec/models/proposal_notification_spec.rb": 0.2914905548095703, + "spec/features/budgets/investments_spec.rb": 93.5263159275055, + "spec/i18n_spec.rb": 96.26275777816772, + "spec/models/community_spec.rb": 0.16270899772644043, + "spec/controllers/graphql_controller_spec.rb": 0.5831413269042969, + "spec/models/legislation/annotation_spec.rb": 0.16232728958129883, + "spec/lib/acts_as_taggable_on_spec.rb": 0.5747356414794922, + "spec/lib/census_api_spec.rb": 0.0021581649780273438, + "spec/features/moderation/comments_spec.rb": 6.70704984664917, + "spec/models/poll/voter_spec.rb": 0.32018303871154785, + "spec/features/proposal_notifications_spec.rb": 3.906450033187866, + "spec/models/budget/result_spec.rb": 0.8468267917633057, + "spec/helpers/users_helper_spec.rb": 0.25751638412475586, + "spec/features/valuation/budgets_spec.rb": 0.2564871311187744, + "spec/controllers/users/registrations_controller_spec.rb": 0.022383689880371094, + "spec/controllers/management/base_controller_spec.rb": 0.06711888313293457, + "spec/features/admin/officials_spec.rb": 0.893528938293457, + "spec/features/comments/topics_spec.rb": 29.998314142227173, + "spec/features/users_spec.rb": 11.885858297348022, + "spec/models/topic_spec.rb": 0.27634167671203613, + "spec/models/follow_spec.rb": 0.1256728172302246, + "spec/lib/local_census_spec.rb": 0.005529880523681641, + "spec/features/verification/sms_spec.rb": 1.5214743614196777, + "spec/helpers/comments_helper_spec.rb": 0.010879278182983398, + "spec/models/valuator_spec.rb": 0.02650904655456543, + "spec/features/proposal_ballots_spec.rb": 0.3937220573425293, + "spec/features/proposals_spec.rb": 142.48229122161865, + "spec/features/legislation/processes_spec.rb": 2.863476514816284, + "spec/features/ckeditor_spec.rb": 0.8433480262756348, + "spec/models/letter_spec.rb": 0.0695810317993164, + "spec/features/admin/budget_investments_spec.rb": 18.484699964523315, + "spec/models/officing/residence_spec.rb": 0.3402073383331299, + "spec/controllers/concerns/has_orders_spec.rb": 0.1844041347503662, + "spec/features/admin/legislation/processes_spec.rb": 4.020649433135986, + "spec/features/management/users_spec.rb": 2.288966178894043, + "spec/lib/tasks/communities_spec.rb": 0.15353775024414062, + "spec/models/abilities/organization_spec.rb": 0.24793481826782227, + "spec/features/polls/polls_spec.rb": 2.591568946838379, + "spec/features/communities_spec.rb": 1.6137127876281738, + "spec/models/legislation/process/phase_spec.rb": 0.07121586799621582, + "spec/features/officing_spec.rb": 0.979363203048706, + "spec/features/site_customization/custom_pages_spec.rb": 0.5588700771331787, + "spec/features/comments/legislation_questions_spec.rb": 14.133169889450073, + "spec/features/organizations_spec.rb": 0.46280837059020996, + "spec/controllers/legislation/answers_controller_spec.rb": 0.39082813262939453, + "spec/models/image_spec.rb": 7.636544466018677, + "spec/features/management/account_spec.rb": 1.150636911392212, + "spec/models/abilities/common_spec.rb": 5.959435701370239, + "spec/features/comments/debates_spec.rb": 13.69457721710205, + "spec/models/poll/shift_spec.rb": 0.19109749794006348, + "spec/features/site_customization/content_blocks_spec.rb": 0.3058288097381592, + "spec/models/poll/recount_spec.rb": 0.1983809471130371, + "spec/features/verification/level_two_verification_spec.rb": 0.4596068859100342, + "spec/features/verification/level_three_verification_spec.rb": 1.456559658050537, + "spec/lib/tasks/settings_spec.rb": 0.04654407501220703, + "spec/features/admin/budget_investment_milestones_spec.rb": 1.3974273204803467, + "spec/features/management/localization_spec.rb": 1.1653187274932861, + "spec/features/admin/tags_spec.rb": 1.0751111507415771, + "spec/features/officing/results_spec.rb": 1.2672057151794434, + "spec/features/admin/poll/booth_assigments_spec.rb": 4.1742753982543945, + "spec/models/poll/officer_assignment_spec.rb": 0.024514198303222656, + "spec/controllers/management/sessions_controller_spec.rb": 0.07244610786437988, + "spec/features/admin/signature_sheets_spec.rb": 1.4268932342529297, + "spec/models/debate_spec.rb": 4.550540924072266, + "spec/features/comments/proposals_spec.rb": 25.726442337036133, + "spec/models/poll/partial_result_spec.rb": 0.32181620597839355, + "spec/features/admin/legislation/draft_versions_spec.rb": 3.4613990783691406, + "spec/models/budget_spec.rb": 0.14807415008544922, + "spec/models/sms_spec.rb": 0.018825769424438477, + "spec/features/admin/proposals_spec.rb": 1.837270975112915, + "spec/models/geozone_spec.rb": 0.11852264404296875, + "spec/features/admin/banners_spec.rb": 3.0584604740142822, + "spec/models/legislation/process/publication_spec.rb": 0.06270265579223633, + "spec/lib/graph_ql/query_type_creator_spec.rb": 0.009456157684326172, + "spec/features/moderation_spec.rb": 1.001516342163086, + "spec/features/campaigns_spec.rb": 0.8359789848327637, + "spec/features/admin/verifications_spec.rb": 0.6421175003051758, + "spec/features/localization_spec.rb": 0.756089448928833, + "spec/features/admin/poll/questions_spec.rb": 41.59848093986511, + "spec/features/tags/debates_spec.rb": 3.4022486209869385, + "spec/helpers/text_helper_spec.rb": 0.0006229877471923828, + "spec/features/admin/moderators_spec.rb": 1.3467354774475098, + "spec/models/flag_spec.rb": 0.5202171802520752, + "spec/mailers/devise_mailer_spec.rb": 0.2588930130004883, + "spec/features/user_invites_spec.rb": 0.18819189071655273, + "spec/features/legislation/draft_versions_spec.rb": 9.352471828460693, + "spec/features/home_spec.rb": 3.0868682861328125, + "spec/features/budgets/results_spec.rb": 2.4918482303619385, + "spec/features/budgets/votes_spec.rb": 4.285862922668457, + "spec/features/comments/budget_investments_spec.rb": 16.1397545337677, + "spec/features/admin/stats_spec.rb": 2.678718090057373, + "spec/features/polls/questions_spec.rb": 2.594414472579956, + "spec/features/admin/poll/shifts_spec.rb": 4.629284143447876, + "spec/helpers/votes_helper_spec.rb": 0.31733107566833496, + "spec/models/ahoy/data_source_spec.rb": 0.04695439338684082, + "spec/models/residence_spec.rb": 0.20260858535766602, + "spec/features/admin_spec.rb": 0.6963987350463867, + "spec/controllers/comments_controller_spec.rb": 0.2683417797088623, + "spec/lib/age_spec.rb": 0.0007379055023193359, + "spec/models/legislation/answer_spec.rb": 0.14532899856567383, + "spec/features/tags_spec.rb": 3.0131027698516846, + "spec/features/admin/valuators_spec.rb": 1.0099408626556396, + "spec/models/notification_spec.rb": 0.37938618659973145, + "spec/views/welcome/index.html.erb_spec.rb": 0.1471250057220459, + "spec/customization_engine_spec.rb": 1.5587348937988281, + "spec/models/poll/officer_spec.rb": 0.2980079650878906, + "spec/features/budgets/ballots_spec.rb": 25.24861741065979, + "spec/controllers/concerns/has_filters_spec.rb": 0.1412961483001709, + "spec/features/moderation/proposals_spec.rb": 5.947849273681641, + "spec/features/management/document_verifications_spec.rb": 0.9574480056762695, + "spec/features/legislation/questions_spec.rb": 1.605849027633667, + "spec/models/proposal_spec.rb": 5.872406482696533, + "spec/models/legislation/question_option_spec.rb": 0.0395960807800293, + "spec/features/budgets/budgets_spec.rb": 0.8722023963928223, + "spec/lib/email_digests_spec.rb": 0.440814733505249, + "spec/features/official_positions_spec.rb": 1.5717194080352783, + "spec/features/officing/residence_spec.rb": 0.9819045066833496, + "spec/features/officing/voters_spec.rb": 2.078903913497925, + "spec/features/direct_messages_spec.rb": 1.6070659160614014, + "spec/models/abilities/everyone_spec.rb": 0.059804677963256836, + "spec/lib/acts_as_paranoid_aliases_spec.rb": 0.33096909523010254, + "spec/features/debates_spec.rb": 32.84718298912048, + "spec/features/votes_spec.rb": 18.217467069625854, + "spec/models/activity_spec.rb": 1.0154414176940918, + "spec/controllers/pages_controller_spec.rb": 0.19468045234680176, + "spec/features/admin/feature_flags_spec.rb": 0.726452112197876, + "spec/models/signature_sheet_spec.rb": 0.6403882503509521, + "spec/features/admin/poll/officers_spec.rb": 1.2912020683288574, + "spec/models/lock_spec.rb": 0.08562397956848145, + "spec/helpers/proposals_helper_spec.rb": 0.17275524139404297, + "spec/features/tags/budget_investments_spec.rb": 14.154245615005493, + "spec/models/vote_spec.rb": 0.9258472919464111, + "spec/features/admin/site_customization/pages_spec.rb": 1.0365827083587646, + "spec/features/moderation/users_spec.rb": 1.3000907897949219, + "spec/features/comments/legislation_annotations_spec.rb": 19.67066717147827, + "spec/features/admin/legislation/questions_spec.rb": 4.043334007263184, + "spec/models/comment_spec.rb": 1.6633994579315186, + "spec/features/admin/site_customization/images_spec.rb": 1.2299704551696777, + "spec/models/abilities/valuator_spec.rb": 1.1985805034637451, + "spec/models/organization_spec.rb": 0.12121891975402832, + "spec/models/budget/ballot_spec.rb": 0.6403298377990723, + "spec/lib/wysiwyg_sanitizer_spec.rb": 0.0018651485443115234, + "spec/features/stats_spec.rb": 0.8169982433319092, + "spec/models/poll/answer_spec.rb": 0.13266730308532715, + "spec/features/admin/settings_spec.rb": 3.1228368282318115, + "spec/features/verification/verification_path_spec.rb": 1.1146795749664307, + "spec/controllers/management/users_controller_spec.rb": 0.004178762435913086, + "spec/models/direct_upload_spec.rb": 1.1311051845550537, + "spec/features/management/email_verifications_spec.rb": 0.3727388381958008, + "spec/models/abilities/administrator_spec.rb": 2.355985164642334, + "spec/models/budget/ballot/line_spec.rb": 0.49976515769958496, + "spec/features/verification/letter_spec.rb": 1.5464122295379639, + "spec/features/notifications_spec.rb": 19.54401397705078, + "spec/features/admin/administrators_spec.rb": 1.7901337146759033, + "spec/models/signature_spec.rb": 1.5397937297821045, + "spec/models/identity_spec.rb": 0.0023458003997802734, + "spec/models/verification/management/document_spec.rb": 0.017922163009643555, + "spec/models/legislation/process_spec.rb": 0.09648776054382324, + "spec/models/budget/group_spec.rb": 0.049637794494628906, + "spec/models/verification/management/email_spec.rb": 0.057023048400878906, + "spec/helpers/verification_helper_spec.rb": 0.0009088516235351562, + "spec/features/verification/residence_spec.rb": 2.2246382236480713, + "spec/features/tracks_spec.rb": 2.320988178253174, + "spec/lib/tag_sanitizer_spec.rb": 0.0005729198455810547, + "spec/features/admin/budgets_spec.rb": 4.4486541748046875, + "spec/models/site_customization/content_block_spec.rb": 0.010473012924194336, + "spec/features/verification/email_spec.rb": 0.5266687870025635, + "spec/models/budget/reclassified_vote_spec.rb": 0.19786882400512695, + "spec/features/management/proposals_spec.rb": 4.107697486877441, + "spec/models/poll/poll_spec.rb": 0.38217735290527344, + "spec/features/admin/geozones_spec.rb": 1.561723232269287, + "spec/lib/graphql_spec.rb": 3.063258647918701, + "spec/features/verification/verified_user_spec.rb": 0.8179008960723877 } \ No newline at end of file diff --git a/lib/capistrano/tasks/maintenance.cap b/lib/capistrano/tasks/maintenance.cap new file mode 100644 index 000000000..a7e3ca41e --- /dev/null +++ b/lib/capistrano/tasks/maintenance.cap @@ -0,0 +1,15 @@ +namespace :maintenance do + desc "Start maintenance mode (edit config/maintenance.yml to provide parameters)" + task :start do + on roles(:app) do + upload! "config/maintenance.yml", "#{current_path}/tmp/maintenance.yml" + end + end + + desc "Stop maintenance mode" + task :stop do + on roles(:app) do + execute "rm #{current_path}/tmp/maintenance.yml" + end + end +end diff --git a/lib/census_api.rb b/lib/census_api.rb index 066c0be95..4fdbd37cb 100644 --- a/lib/census_api.rb +++ b/lib/census_api.rb @@ -84,7 +84,7 @@ class CensusApi end def stubbed_response(document_type, document_number) - if document_number == "12345678Z" && document_type == "1" + if (document_number == "12345678Z" || document_number == "12345678Y") && document_type == "1" stubbed_valid_response else stubbed_invalid_response @@ -119,7 +119,7 @@ class CensusApi {get_habita_datos_response: {get_habita_datos_return: {datos_habitante: {}, datos_vivienda: {}}}} end - def is_dni?(document_type) + def dni?(document_type) document_type.to_s == "1" end diff --git a/lib/document_parser.rb b/lib/document_parser.rb index c60b180dc..9e59c6b75 100644 --- a/lib/document_parser.rb +++ b/lib/document_parser.rb @@ -5,7 +5,7 @@ module DocumentParser document_number = document_number.to_s.gsub(/[^0-9A-Za-z]/i, '') variants = [] - if is_dni?(document_type) + if dni?(document_type) document_number, letter = split_letter_from(document_number) number_variants = get_number_variants_with_leading_zeroes_from(document_number) letter_variants = get_letter_variants(number_variants, letter) diff --git a/lib/local_census.rb b/lib/local_census.rb index 6c6e8fe12..1a0428787 100644 --- a/lib/local_census.rb +++ b/lib/local_census.rb @@ -63,7 +63,7 @@ class LocalCensus LocalCensusRecord.find_by(document_type: document_type, document_number: document_number) end - def is_dni?(document_type) + def dni?(document_type) document_type.to_s == "1" end diff --git a/lib/tasks/polls.rake b/lib/tasks/polls.rake new file mode 100644 index 000000000..e87e171d3 --- /dev/null +++ b/lib/tasks/polls.rake @@ -0,0 +1,6 @@ +namespace :polls do + desc "Adds created_at and updated_at values to existing polls" + task initialize_timestamps: :environment do + Poll.update_all(created_at: Time.current, updated_at: Time.current) + end +end diff --git a/lib/tasks/votes.rake b/lib/tasks/votes.rake new file mode 100644 index 000000000..0cc595662 --- /dev/null +++ b/lib/tasks/votes.rake @@ -0,0 +1,16 @@ +namespace :votes do + + desc "Resets cached_votes_up counter to its latest value" + task reset_vote_counter: :environment do + models = [Proposal, Budget::Investment] + + models.each do |model| + model.find_each do |resource| + resource.update_cached_votes + print "." + end + end + + end + +end diff --git a/spec/controllers/admin/api/stats_controller_spec.rb b/spec/controllers/admin/api/stats_controller_spec.rb index 8dd948086..97ad5d0be 100644 --- a/spec/controllers/admin/api/stats_controller_spec.rb +++ b/spec/controllers/admin/api/stats_controller_spec.rb @@ -6,17 +6,17 @@ describe Admin::Api::StatsController do let(:user) { create(:administrator).user } context 'events or visits not present' do - it 'should respond with bad_request' do + it 'responds with bad_request' do sign_in user get :show - expect(response).to_not be_ok + expect(response).not_to be_ok expect(response.status).to eq 400 end end context 'events present' do - before :each do + before do time_1 = DateTime.parse("2015-01-01").in_time_zone time_2 = DateTime.parse("2015-01-02").in_time_zone time_3 = DateTime.parse("2015-01-03").in_time_zone @@ -29,7 +29,7 @@ describe Admin::Api::StatsController do create :ahoy_event, name: 'bar', time: time_3 end - it 'should return single events formated for working with c3.js' do + it 'returns single events formated for working with c3.js' do sign_in user get :show, events: 'foo' @@ -39,7 +39,7 @@ describe Admin::Api::StatsController do expect(data).to eq "x" => ["2015-01-01", "2015-01-02"], "Foo" => [2, 1] end - it 'should return combined comma separated events formated for working with c3.js' do + it 'returns combined comma separated events formated for working with c3.js' do sign_in user get :show, events: 'foo,bar' @@ -51,7 +51,7 @@ describe Admin::Api::StatsController do end context 'visits present' do - it 'should return visits formated for working with c3.js' do + it 'returns visits formated for working with c3.js' do time_1 = DateTime.parse("2015-01-01").in_time_zone time_2 = DateTime.parse("2015-01-02").in_time_zone @@ -70,7 +70,7 @@ describe Admin::Api::StatsController do end context 'visits and events present' do - it 'should return combined events and visits formated for working with c3.js' do + it 'returns combined events and visits formated for working with c3.js' do time_1 = DateTime.parse("2015-01-01").in_time_zone time_2 = DateTime.parse("2015-01-02").in_time_zone @@ -93,7 +93,7 @@ describe Admin::Api::StatsController do end context 'budget investments present' do - it 'should return budget investments formated for working with c3.js' do + it 'returns budget investments formated for working with c3.js' do time_1 = DateTime.parse("2017-04-01").in_time_zone time_2 = DateTime.parse("2017-04-02").in_time_zone diff --git a/spec/controllers/comments_controller_spec.rb b/spec/controllers/comments_controller_spec.rb index d06e1900f..047e76e85 100644 --- a/spec/controllers/comments_controller_spec.rb +++ b/spec/controllers/comments_controller_spec.rb @@ -3,14 +3,14 @@ require 'rails_helper' describe CommentsController do describe 'POST create' do - before(:each) do + before do @process = create(:legislation_process, debate_start_date: Date.current - 3.days, debate_end_date: Date.current + 2.days) @question = create(:legislation_question, process: @process, title: "Question 1") @user = create(:user, :level_two) @unverified_user = create(:user) end - it 'should create an comment if the comments are open' do + it 'creates an comment if the comments are open' do sign_in @user expect do @@ -18,21 +18,21 @@ describe CommentsController do end.to change { @question.reload.comments_count }.by(1) end - it 'should not create a comment if the comments are closed' do + it 'does not create a comment if the comments are closed' do sign_in @user @process.update_attribute(:debate_end_date, Date.current - 1.day) expect do xhr :post, :create, comment: {commentable_id: @question.id, commentable_type: "Legislation::Question", body: "a comment"} - end.to_not change { @question.reload.comments_count } + end.not_to change { @question.reload.comments_count } end - it 'should not create a comment for unverified users when the commentable requires it' do + it 'does not create a comment for unverified users when the commentable requires it' do sign_in @unverified_user expect do xhr :post, :create, comment: {commentable_id: @question.id, commentable_type: "Legislation::Question", body: "a comment"} - end.to_not change { @question.reload.comments_count } + end.not_to change { @question.reload.comments_count } end end end diff --git a/spec/controllers/concerns/has_filters_spec.rb b/spec/controllers/concerns/has_filters_spec.rb index af094e9ec..d0bfdf1e7 100644 --- a/spec/controllers/concerns/has_filters_spec.rb +++ b/spec/controllers/concerns/has_filters_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe 'HasFilters' do +describe HasFilters do class FakeController < ActionController::Base; end diff --git a/spec/controllers/concerns/has_orders_spec.rb b/spec/controllers/concerns/has_orders_spec.rb index fa2c49b07..b94cc2dba 100644 --- a/spec/controllers/concerns/has_orders_spec.rb +++ b/spec/controllers/concerns/has_orders_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe 'HasOrders' do +describe HasOrders do class FakeController < ActionController::Base; end diff --git a/spec/controllers/debates_controller_spec.rb b/spec/controllers/debates_controller_spec.rb index 1744dfd82..64d1fa597 100644 --- a/spec/controllers/debates_controller_spec.rb +++ b/spec/controllers/debates_controller_spec.rb @@ -3,15 +3,15 @@ require 'rails_helper' describe DebatesController do describe 'POST create' do - before(:each) do + before do InvisibleCaptcha.timestamp_enabled = false end - after(:each) do + after do InvisibleCaptcha.timestamp_enabled = true end - it 'should create an ahoy event' do + it 'creates an ahoy event' do sign_in create(:user) @@ -26,7 +26,7 @@ describe DebatesController do Setting['max_ratio_anon_votes_on_debates'] = 50 end - it 'should allow vote if user is allowed' do + it 'allows vote if user is allowed' do Setting["max_ratio_anon_votes_on_debates"] = 100 debate = create(:debate) sign_in create(:user) @@ -36,14 +36,14 @@ describe DebatesController do end.to change { debate.reload.votes_for.size }.by(1) end - it 'should not allow vote if user is not allowed' do + it 'does not allow vote if user is not allowed' do Setting["max_ratio_anon_votes_on_debates"] = 0 debate = create(:debate, cached_votes_total: 1000) sign_in create(:user) expect do xhr :post, :vote, id: debate.id, value: 'yes' - end.to_not change { debate.reload.votes_for.size } + end.not_to change { debate.reload.votes_for.size } end end end diff --git a/spec/controllers/installation_controller_spec.rb b/spec/controllers/installation_controller_spec.rb new file mode 100644 index 000000000..4ad446cd4 --- /dev/null +++ b/spec/controllers/installation_controller_spec.rb @@ -0,0 +1,57 @@ +require 'rails_helper' + +describe InstallationController, type: :request do + + describe "consul.json" do + let(:feature_settings) do + { + 'debates' => nil, + 'spending_proposals' => 't', + 'polls' => nil, + 'proposals' => 't', + 'twitter_login' => nil, + 'facebook_login' => nil, + 'google_login' => nil, + 'public_stats' => nil, + 'budgets' => nil, + 'signature_sheets' => nil, + 'legislation' => nil, + 'user.recommendations' => nil, + 'community' => nil, + 'map' => 't', + 'spending_proposal_features.voting_allowed' => 't', + 'allow_images' => 't' + } + end + + before do + feature_settings.each { |feature_name, feature_value| Setting["feature.#{feature_name}"] = feature_value } + end + + after do + Setting['feature.debates'] = true + Setting['feature.spending_proposals'] = nil + Setting['feature.polls'] = true + Setting['feature.twitter_login'] = true + Setting['feature.facebook_login'] = true + Setting['feature.google_login'] = true + Setting['feature.public_stats'] = true + Setting['feature.budgets'] = true + Setting['feature.signature_sheets'] = true + Setting['feature.legislation'] = true + Setting['feature.user.recommendations'] = true + Setting['feature.community'] = true + Setting['feature.map'] = nil + Setting['feature.spending_proposal_features.voting_allowed'] = nil + Setting['feature.allow_images'] = true + end + + specify "with query string inside query params" do + get '/consul.json' + + expect(response).to have_http_status(:ok) + expect(JSON.parse(response.body)['release']).not_to be_empty + expect(JSON.parse(response.body)['features']).to eq(feature_settings) + end + end +end diff --git a/spec/controllers/legislation/annotations_controller_spec.rb b/spec/controllers/legislation/annotations_controller_spec.rb index 834ec046f..80335a209 100644 --- a/spec/controllers/legislation/annotations_controller_spec.rb +++ b/spec/controllers/legislation/annotations_controller_spec.rb @@ -3,14 +3,14 @@ require 'rails_helper' describe Legislation::AnnotationsController do describe 'POST create' do - before(:each) do + before do @process = create(:legislation_process, allegations_start_date: Date.current - 3.days, allegations_end_date: Date.current + 2.days) @draft_version = create(:legislation_draft_version, :published, process: @process, title: "Version 1") @final_version = create(:legislation_draft_version, :published, :final_version, process: @process, title: "Final version") @user = create(:user, :level_two) end - it 'should create an ahoy event' do + it 'creates an ahoy event' do sign_in @user post :create, process_id: @process.id, @@ -24,7 +24,7 @@ describe Legislation::AnnotationsController do expect(Ahoy::Event.last.properties['legislation_annotation_id']).to eq Legislation::Annotation.last.id end - it 'should not create an annotation if the draft version is a final version' do + it 'does not create an annotation if the draft version is a final version' do sign_in @user post :create, process_id: @process.id, @@ -38,7 +38,7 @@ describe Legislation::AnnotationsController do expect(response).to have_http_status(:not_found) end - it 'should create an annotation if the process allegations phase is open' do + it 'creates an annotation if the process allegations phase is open' do sign_in @user expect do @@ -52,7 +52,7 @@ describe Legislation::AnnotationsController do end.to change { @draft_version.annotations.count }.by(1) end - it 'should not create an annotation if the process allegations phase is not open' do + it 'does not create an annotation if the process allegations phase is not open' do sign_in @user @process.update_attribute(:allegations_end_date, Date.current - 1.day) @@ -64,10 +64,10 @@ describe Legislation::AnnotationsController do "ranges" => [{"start" => "/p[1]", "startOffset" => 6, "end" => "/p[1]", "endOffset" => 11}], "text": "una anotacion" } - end.to_not change { @draft_version.annotations.count } + end.not_to change { @draft_version.annotations.count } end - it 'should create an annotation by parsing parameters in JSON' do + it 'creates an annotation by parsing parameters in JSON' do sign_in @user expect do @@ -81,7 +81,7 @@ describe Legislation::AnnotationsController do end.to change { @draft_version.annotations.count }.by(1) end - it 'should create a new comment on an existing annotation when range is the same' do + it 'creates a new comment on an existing annotation when range is the same' do annotation = create(:legislation_annotation, draft_version: @draft_version, text: "my annotation", ranges: [{"start" => "/p[1]", "startOffset" => 6, "end" => "/p[1]", "endOffset" => 11}], range_start: "/p[1]", range_start_offset: 6, range_end: "/p[1]", range_end_offset: 11) @@ -95,7 +95,7 @@ describe Legislation::AnnotationsController do "ranges" => [{"start" => "/p[1]", "startOffset" => 6, "end" => "/p[1]", "endOffset" => 11}], "text": "una anotacion" } - end.to_not change { @draft_version.annotations.count } + end.not_to change { @draft_version.annotations.count } expect(annotation.reload.comments_count).to eq(2) expect(annotation.comments.last.body).to eq("una anotacion") diff --git a/spec/controllers/legislation/answers_controller_spec.rb b/spec/controllers/legislation/answers_controller_spec.rb index 629935643..466a90eb8 100644 --- a/spec/controllers/legislation/answers_controller_spec.rb +++ b/spec/controllers/legislation/answers_controller_spec.rb @@ -3,14 +3,14 @@ require 'rails_helper' describe Legislation::AnswersController do describe 'POST create' do - before(:each) do + before do @process = create(:legislation_process, debate_start_date: Date.current - 3.days, debate_end_date: Date.current + 2.days) @question = create(:legislation_question, process: @process, title: "Question 1") @question_option = create(:legislation_question_option, question: @question, value: "Yes") @user = create(:user, :level_two) end - it 'should create an ahoy event' do + it 'creates an ahoy event' do sign_in @user post :create, process_id: @process.id, question_id: @question.id, @@ -19,7 +19,7 @@ describe Legislation::AnswersController do expect(Ahoy::Event.last.properties['legislation_answer_id']).to eq Legislation::Answer.last.id end - it 'should create an answer if the process debate phase is open' do + it 'creates an answer if the process debate phase is open' do sign_in @user expect do @@ -28,14 +28,14 @@ describe Legislation::AnswersController do end.to change { @question.reload.answers_count }.by(1) end - it 'should not create an answer if the process debate phase is not open' do + it 'does not create an answer if the process debate phase is not open' do sign_in @user @process.update_attribute(:debate_end_date, Date.current - 1.day) expect do xhr :post, :create, process_id: @process.id, question_id: @question.id, legislation_answer: { legislation_question_option_id: @question_option.id } - end.to_not change { @question.reload.answers_count } + end.not_to change { @question.reload.answers_count } end end end diff --git a/spec/controllers/management/base_controller_spec.rb b/spec/controllers/management/base_controller_spec.rb index 0f4a95d7e..60b4678f8 100644 --- a/spec/controllers/management/base_controller_spec.rb +++ b/spec/controllers/management/base_controller_spec.rb @@ -4,7 +4,7 @@ describe Management::BaseController do describe 'managed_user' do - it "should return existent user with session document info if present" do + it "returns existent user with session document info if present" do session[:document_type] = "1" session[:document_number] = "333333333E" user = create(:user, :level_two, document_number: "333333333E") @@ -13,7 +13,7 @@ describe Management::BaseController do expect(managed_user).to eq user end - it "should return new user if no user have the session document info" do + it "returns new user if no user have the session document info" do session[:document_type] = "1" session[:document_number] = "333333333E" managed_user = subject.send(:managed_user) diff --git a/spec/controllers/management/sessions_controller_spec.rb b/spec/controllers/management/sessions_controller_spec.rb index 0e2a18544..25d0afc6b 100644 --- a/spec/controllers/management/sessions_controller_spec.rb +++ b/spec/controllers/management/sessions_controller_spec.rb @@ -3,13 +3,13 @@ require 'rails_helper' describe Management::SessionsController do describe 'Sign in' do - it "should deny access if wrong manager credentials" do + it "denies access if wrong manager credentials" do allow_any_instance_of(ManagerAuthenticator).to receive(:auth).and_return(false) expect { get :create, login: "nonexistent", clave_usuario: "wrong"}.to raise_error CanCan::AccessDenied expect(session[:manager]).to be_nil end - it "should redirect to management root path if authorized manager with right credentials" do + it "redirects to management root path if authorized manager with right credentials" do manager = {login: "JJB033", user_key: "31415926", date: "20151031135905"} allow_any_instance_of(ManagerAuthenticator).to receive(:auth).and_return(manager) @@ -18,7 +18,7 @@ describe Management::SessionsController do expect(session[:manager][:login]).to eq "JJB033" end - it "should redirect to management root path if user is admin" do + it "redirects to management root path if user is admin" do user = create(:administrator).user sign_in user get :create @@ -26,7 +26,7 @@ describe Management::SessionsController do expect(session[:manager][:login]).to eq "admin_user_#{user.id}" end - it "should redirect to management root path if user is manager" do + it "redirects to management root path if user is manager" do user = create(:manager).user sign_in user get :create @@ -34,7 +34,7 @@ describe Management::SessionsController do expect(session[:manager][:login]).to eq "manager_user_#{user.id}" end - it "should deny access if user is not admin or manager" do + it "denies access if user is not admin or manager" do sign_in create(:user) expect { get :create}.to raise_error CanCan::AccessDenied expect(session[:manager]).to be_nil @@ -42,7 +42,7 @@ describe Management::SessionsController do end describe 'Sign out' do - it "should destroy the session data and redirect" do + it "destroys the session data and redirect" do session[:manager] = {user_key: "31415926", date: "20151031135905", login: "JJB033"} session[:document_type] = "1" session[:document_number] = "12345678Z" diff --git a/spec/controllers/management/users_controller_spec.rb b/spec/controllers/management/users_controller_spec.rb index 221d302b6..d30e5f27c 100644 --- a/spec/controllers/management/users_controller_spec.rb +++ b/spec/controllers/management/users_controller_spec.rb @@ -3,7 +3,7 @@ require 'rails_helper' describe Management::UsersController do describe 'logout' do - it "should remove user data from the session" do + it "removes user data from the session" do session[:manager] = {user_key: "31415926", date: "20151031135905", login: "JJB033"} session[:document_type] = "1" session[:document_number] = "12345678Z" diff --git a/spec/controllers/pages_controller_spec.rb b/spec/controllers/pages_controller_spec.rb index 9ea61e9bb..17a17dc3c 100644 --- a/spec/controllers/pages_controller_spec.rb +++ b/spec/controllers/pages_controller_spec.rb @@ -3,27 +3,27 @@ require 'rails_helper' describe PagesController do describe 'Static pages' do - it 'should include a privacy page' do + it 'includes a privacy page' do get :show, id: :privacy expect(response).to be_ok end - it 'should include a conditions page' do + it 'includes a conditions page' do get :show, id: :conditions expect(response).to be_ok end - it 'should include a general terms page' do + it 'includes a general terms page' do get :show, id: :general_terms expect(response).to be_ok end - it 'should include a terms page' do + it 'includes a terms page' do get :show, id: :census_terms expect(response).to be_ok end - it 'should include a accessibility page' do + it 'includes a accessibility page' do get :show, id: :accessibility expect(response).to be_ok end @@ -31,24 +31,24 @@ describe PagesController do describe 'More info pages' do - it 'should include a more info page' do + it 'includes a more info page' do get :show, id: 'more_info/index' expect(response).to be_ok end - it 'should include a how_to_use page' do + it 'includes a how_to_use page' do get :show, id: 'more_info/how_to_use/index' expect(response).to be_ok end - it 'should include a faq page' do + it 'includes a faq page' do get :show, id: 'more_info/faq/index' expect(response).to be_ok end end describe 'Not found pages' do - it 'should return a 404 message' do + it 'returns a 404 message' do get :show, id: "nonExistentPage" expect(response).to be_missing end diff --git a/spec/controllers/users/registrations_controller_spec.rb b/spec/controllers/users/registrations_controller_spec.rb index ea73428f5..b8454678c 100644 --- a/spec/controllers/users/registrations_controller_spec.rb +++ b/spec/controllers/users/registrations_controller_spec.rb @@ -4,12 +4,12 @@ describe Users::RegistrationsController do describe "POST check_username" do - before(:each) do + before do @request.env["devise.mapping"] = Devise.mappings[:user] end context "when username is available" do - it "should return true with no error message" do + it "returns true with no error message" do get :check_username, username: "available username" data = JSON.parse response.body, symbolize_names: true @@ -19,7 +19,7 @@ describe Users::RegistrationsController do end context "when username is not available" do - it "should return false with an error message" do + it "returns false with an error message" do user = create(:user) get :check_username, username: user.username diff --git a/spec/customization_engine_spec.rb b/spec/customization_engine_spec.rb index a18130543..c36ee68a7 100644 --- a/spec/customization_engine_spec.rb +++ b/spec/customization_engine_spec.rb @@ -3,26 +3,38 @@ require 'rails_helper' # This module tests functionality related with custom application files # TODO test models, controllers, etc... -describe 'CustomizationEngine' do +describe 'Customization Engine' do let(:test_key) { I18n.t('account.show.change_credentials_link') } let!(:default_path) { I18n.load_path } - it "should load custom and override original locales" do - I18n.load_path += Dir[Rails.root.join('spec', 'support', 'locales', 'custom', '*.{rb,yml}')] - I18n.reload! + before do + reset_load_path_and_reload(default_path) + end + + after do + reset_load_path_and_reload(default_path) + end + + it "loads custom and override original locales" do + increase_load_path_and_reload(Dir[Rails.root.join('spec', 'support', + 'locales', 'custom', '*.{rb,yml}')]) expect(test_key).to eq 'Overriden string with custom locales' end - it "should not override original locales" do - I18n.load_path.delete_if {|item| item =~ /spec\/support\/locales\/custom/ } - I18n.load_path += Dir[Rails.root.join('spec', 'support', 'locales', '**', '*.{rb,yml}')] - I18n.reload! + it "does not override original locales" do + increase_load_path_and_reload(Dir[Rails.root.join('spec', 'support', + 'locales', '**', '*.{rb,yml}')]) expect(test_key).to eq 'Not overriden string with custom locales' end - after(:each) do - I18n.load_path = default_path + def reset_load_path_and_reload(path) + I18n.load_path = path + I18n.reload! + end + + def increase_load_path_and_reload(path) + I18n.load_path += path I18n.reload! end diff --git a/spec/factories.rb b/spec/factories.rb index b90f68175..252e40f5c 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -1,4 +1,4 @@ -FactoryGirl.define do +FactoryBot.define do factory :local_census_record, class: 'LocalCensusRecord' do document_number '12345678A' document_type 1 @@ -50,6 +50,13 @@ FactoryGirl.define do end trait :verified do + residence_verified_at Time.current + verified_at Time.current + end + + trait :in_census do + document_number "12345678Z" + document_type "1" verified_at Time.current end end @@ -129,7 +136,7 @@ FactoryGirl.define do trait :flagged do after :create do |debate| - Flag.flag(FactoryGirl.create(:user), debate) + Flag.flag(create(:user), debate) end end @@ -143,7 +150,7 @@ FactoryGirl.define do trait :conflictive do after :create do |debate| - Flag.flag(FactoryGirl.create(:user), debate) + Flag.flag(create(:user), debate) 4.times { create(:vote, votable: debate) } end end @@ -158,6 +165,7 @@ FactoryGirl.define do video_url 'https://youtu.be/nhuNb0XtRhQ' responsible_name 'John Snow' terms_of_service '1' + skip_map '1' association :author, factory: :user trait :hidden do @@ -174,7 +182,7 @@ FactoryGirl.define do trait :flagged do after :create do |proposal| - Flag.flag(FactoryGirl.create(:user), proposal) + Flag.flag(create(:user), proposal) end end @@ -192,7 +200,7 @@ FactoryGirl.define do trait :conflictive do after :create do |debate| - Flag.flag(FactoryGirl.create(:user), debate) + Flag.flag(create(:user), debate) 4.times { create(:vote, votable: debate) } end end @@ -215,6 +223,7 @@ FactoryGirl.define do sequence(:name) { |n| "Budget #{n}" } currency_symbol "€" phase 'accepting' + description_drafting "This budget is drafting" description_accepting "This budget is accepting" description_reviewing "This budget is reviewing" description_selecting "This budget is selecting" @@ -223,6 +232,10 @@ FactoryGirl.define do description_reviewing_ballots "This budget is reviewing ballots" description_finished "This budget is finished" + trait :drafting do + phase 'drafting' + end + trait :accepting do phase 'accepting' end @@ -271,7 +284,7 @@ FactoryGirl.define do description 'Spend money on this' price 10 unfeasibility_explanation '' - external_url 'http://external_documention.org' + skip_map '1' terms_of_service '1' incompatible false @@ -318,6 +331,21 @@ FactoryGirl.define do feasibility "feasible" valuation_finished true end + + end + + factory :image do + attachment { File.new("spec/fixtures/files/clippy.jpg") } + title "Lorem ipsum dolor sit amet" + association :user, factory: :user + + trait :proposal_image do + association :imageable, factory: :proposal + end + + trait :budget_investment_image do + association :imageable, factory: :budget_investment + end end factory :budget_ballot, class: 'Budget::Ballot' do @@ -340,6 +368,7 @@ FactoryGirl.define do association :investment, factory: :budget_investment sequence(:title) { |n| "Budget investment milestone #{n} title" } description 'Milestone description' + publication_date Time.zone.today end factory :vote do @@ -405,7 +434,7 @@ FactoryGirl.define do trait :flagged do after :create do |debate| - Flag.flag(FactoryGirl.create(:user), debate) + Flag.flag(create(:user), debate) end end @@ -468,6 +497,11 @@ FactoryGirl.define do ends_at { 15.days.ago } end + trait :recounting do + starts_at { 1.month.ago } + ends_at { Date.current } + end + trait :published do published true end @@ -477,8 +511,25 @@ FactoryGirl.define do poll association :author, factory: :user sequence(:title) { |n| "Question title #{n}" } - sequence(:description) { |n| "Question description #{n}" } - valid_answers { Faker::Lorem.words(3).join(', ') } + + trait :with_answers do + after(:create) do |question, _evaluator| + create(:poll_question_answer, question: question, title: "Yes") + create(:poll_question_answer, question: question, title: "No") + end + end + end + + factory :poll_question_answer, class: 'Poll::Question::Answer' do + association :question, factory: :poll_question + sequence(:title) { |n| "Answer title #{n}" } + sequence(:description) { |n| "Answer description #{n}" } + end + + factory :poll_answer_video, class: 'Poll::Question::Answer::Video' do + association :answer, factory: :poll_question_answer + title "Sample video title" + url "https://youtu.be/nhuNb0XtRhQ" end factory :poll_booth, class: 'Poll::Booth' do @@ -505,11 +556,21 @@ FactoryGirl.define do association :booth, factory: :poll_booth association :officer, factory: :poll_officer date Date.current + + trait :vote_collection_task do + task 0 + end + + trait :recount_scrutiny_task do + task 1 + end end factory :poll_voter, class: 'Poll::Voter' do poll association :user, :level_two + association :officer, factory: :poll_officer + origin "web" trait :from_booth do association :booth_assignment, factory: :poll_booth_assignment @@ -527,29 +588,19 @@ FactoryGirl.define do end factory :poll_answer, class: 'Poll::Answer' do - association :question, factory: :poll_question + association :question, factory: [:poll_question, :with_answers] association :author, factory: [:user, :level_two] - answer { question.valid_answers.sample } + answer { question.question_answers.sample.title } end factory :poll_partial_result, class: 'Poll::PartialResult' do - association :question, factory: :poll_question + association :question, factory: [:poll_question, :with_answers] association :author, factory: :user origin { 'web' } - answer { question.valid_answers.sample } + answer { question.question_answers.sample.title } end - factory :poll_white_result, class: 'Poll::WhiteResult' do - association :author, factory: :user - origin { 'web' } - end - - factory :poll_null_result, class: 'Poll::NullResult' do - association :author, factory: :user - origin { 'web' } - end - - factory :poll_total_result, class: 'Poll::TotalResult' do + factory :poll_recount, class: 'Poll::Recount' do association :author, factory: :user origin { 'web' } end @@ -665,7 +716,7 @@ FactoryGirl.define do start_date Date.current - 5.days end_date Date.current + 5.days debate_start_date Date.current - 5.days - debate_end_date Date.current - 2.days + debate_end_date Date.current + 2.days draft_publication_date Date.current - 1.day allegations_start_date Date.current allegations_end_date Date.current + 3.days @@ -773,6 +824,14 @@ LOREM_IPSUM user end + factory :legislation_proposal, class: 'Legislation::Proposal' do + title "Example proposal for a legislation" + summary "This law should include..." + terms_of_service '1' + process factory: :legislation_process + author factory: :user + end + factory :site_customization_page, class: 'SiteCustomization::Page' do slug "example-page" title "Example page" @@ -804,4 +863,42 @@ LOREM_IPSUM association :author, factory: :user end + factory :direct_upload do + user + + trait :proposal do + resource_type "Proposal" + end + trait :budget_investment do + resource_type "Budget::Investment" + end + + trait :documents do + resource_relation "documents" + attachment { File.new("spec/fixtures/files/empty.pdf") } + end + trait :image do + resource_relation "image" + attachment { File.new("spec/fixtures/files/clippy.jpg") } + end + initialize_with { new(attributes) } + end + + factory :map_location do + latitude 51.48 + longitude 0.0 + zoom 10 + + trait :proposal_map_location do + proposal + end + + trait :budget_investment_map_location do + association :investment, factory: :budget_investment + end + end + + factory :related_content do + end + end diff --git a/spec/features/account_spec.rb b/spec/features/account_spec.rb index 1ed0a4a01..469ec6b70 100644 --- a/spec/features/account_spec.rb +++ b/spec/features/account_spec.rb @@ -12,7 +12,7 @@ feature 'Account' do click_link "My account" - expect(current_path).to eq(account_path) + expect(page).to have_current_path(account_path, only_path: true) expect(page).to have_selector("input[value='Manuela Colau']") expect(page).to have_selector(avatar('Manuela Colau'), count: 1) @@ -24,7 +24,7 @@ feature 'Account' do visit account_path expect(page).to have_selector("input[value='Manuela Corp']") - expect(page).to_not have_selector("input[value='Manuela Colau']") + expect(page).not_to have_selector("input[value='Manuela Colau']") expect(page).to have_selector(avatar('Manuela Corp'), count: 1) end @@ -46,8 +46,8 @@ feature 'Account' do expect(page).to have_selector("input[value='Larry Bird']") expect(find("#account_email_on_comment")).to be_checked expect(find("#account_email_on_comment_reply")).to be_checked - expect(find("#account_email_digest")).to_not be_checked - expect(find("#account_email_on_direct_message")).to_not be_checked + expect(find("#account_email_digest")).not_to be_checked + expect(find("#account_email_on_direct_message")).not_to be_checked end scenario 'Edit Organization' do @@ -92,12 +92,12 @@ feature 'Account' do login_as(official_user2) visit account_path - expect(page).to_not have_css '#account_official_position_badge' + expect(page).not_to have_css '#account_official_position_badge' login_as(official_user3) visit account_path - expect(page).to_not have_css '#account_official_position_badge' + expect(page).not_to have_css '#account_official_position_badge' end end @@ -116,7 +116,7 @@ feature 'Account' do click_link 'My account' - expect(current_path).to eq(account_path) + expect(page).to have_current_path(account_path, only_path: true) expect(page).to have_link('Change my credentials') click_link 'Change my credentials' diff --git a/spec/features/admin/activity_spec.rb b/spec/features/admin/activity_spec.rb index 9a1f8aaf8..3020d2520 100644 --- a/spec/features/admin/activity_spec.rb +++ b/spec/features/admin/activity_spec.rb @@ -46,7 +46,7 @@ feature 'Admin activity' do visit admin_activity_path expect(page).to have_content(proposal1.title) - expect(page).to_not have_content(proposal2.title) + expect(page).not_to have_content(proposal2.title) expect(page).to have_content(proposal3.title) end @@ -108,7 +108,7 @@ feature 'Admin activity' do visit admin_activity_path expect(page).to have_content(debate1.title) - expect(page).to_not have_content(debate2.title) + expect(page).not_to have_content(debate2.title) expect(page).to have_content(debate3.title) end @@ -171,7 +171,7 @@ feature 'Admin activity' do visit admin_activity_path expect(page).to have_content(comment1.body) - expect(page).to_not have_content(comment2.body) + expect(page).not_to have_content(comment2.body) expect(page).to have_content(comment3.body) end @@ -256,7 +256,7 @@ feature 'Admin activity' do expect(page).to have_content(proposal1.author.email) expect(page).to have_content(proposal3.author.username) expect(page).to have_content(proposal3.author.email) - expect(page).to_not have_content(proposal2.author.username) + expect(page).not_to have_content(proposal2.author.username) end scenario "Shows moderation activity from debates moderation screen" do @@ -282,7 +282,7 @@ feature 'Admin activity' do expect(page).to have_content(debate1.author.email) expect(page).to have_content(debate3.author.username) expect(page).to have_content(debate3.author.email) - expect(page).to_not have_content(debate2.author.username) + expect(page).not_to have_content(debate2.author.username) end scenario "Shows moderation activity from comments moderation screen" do @@ -308,7 +308,7 @@ feature 'Admin activity' do expect(page).to have_content(comment1.author.email) expect(page).to have_content(comment3.author.username) expect(page).to have_content(comment3.author.email) - expect(page).to_not have_content(comment2.author.username) + expect(page).not_to have_content(comment2.author.username) end scenario "Shows admin restores" do diff --git a/spec/features/admin/administrators_spec.rb b/spec/features/admin/administrators_spec.rb index bef57b75d..d775aaa74 100644 --- a/spec/features/admin/administrators_spec.rb +++ b/spec/features/admin/administrators_spec.rb @@ -12,11 +12,11 @@ feature 'Admin administrators' do scenario 'Index' do expect(page).to have_content @administrator.name expect(page).to have_content @administrator.email - expect(page).to_not have_content @user.name + expect(page).not_to have_content @user.name end scenario 'Create Administrator', :js do - fill_in 'email', with: @user.email + fill_in 'name_or_email', with: @user.email click_button 'Search' expect(page).to have_content @user.name @@ -30,7 +30,7 @@ feature 'Admin administrators' do find(:xpath, "//tr[contains(.,'#{@administrator.name}')]/td/a", text: 'Delete').click within("#administrators") do - expect(page).to_not have_content @administrator.name + expect(page).not_to have_content @administrator.name end end @@ -41,5 +41,53 @@ feature 'Admin administrators' do expect(page).to have_content I18n.t("admin.administrators.administrator.restricted_removal") end end -end + context 'Search' do + + background do + user = create(:user, username: 'Bernard Sumner', email: 'bernard@sumner.com') + user2 = create(:user, username: 'Tony Soprano', email: 'tony@soprano.com') + @administrator1 = create(:administrator, user: user) + @administrator2 = create(:administrator, user: user2) + visit admin_administrators_path + end + + scenario 'returns no results if search term is empty' do + expect(page).to have_content(@administrator1.name) + expect(page).to have_content(@administrator2.name) + + fill_in 'name_or_email', with: ' ' + click_button 'Search' + + expect(page).to have_content('Administrators: User search') + expect(page).to have_content('No results found') + expect(page).not_to have_content(@administrator1.name) + expect(page).not_to have_content(@administrator2.name) + end + + scenario 'search by name' do + expect(page).to have_content(@administrator1.name) + expect(page).to have_content(@administrator2.name) + + fill_in 'name_or_email', with: 'Sumn' + click_button 'Search' + + expect(page).to have_content('Administrators: User search') + expect(page).to have_content(@administrator1.name) + expect(page).not_to have_content(@administrator2.name) + end + + scenario 'search by email' do + expect(page).to have_content(@administrator1.email) + expect(page).to have_content(@administrator2.email) + + fill_in 'name_or_email', with: @administrator2.email + click_button 'Search' + + expect(page).to have_content('Administrators: User search') + expect(page).to have_content(@administrator2.email) + expect(page).not_to have_content(@administrator1.email) + end + end + +end diff --git a/spec/features/admin/banners_spec.rb b/spec/features/admin/banners_spec.rb index 28a105bed..70e1469d3 100644 --- a/spec/features/admin/banners_spec.rb +++ b/spec/features/admin/banners_spec.rb @@ -136,8 +136,8 @@ feature 'Admin banners magement' do expect(page).to have_content 'Modified title' expect(page).to have_content 'Edited text' - expect(page).to_not have_content 'Hello' - expect(page).to_not have_content 'Wrong text' + expect(page).not_to have_content 'Hello' + expect(page).not_to have_content 'Wrong text' end scenario 'Delete a banner' do @@ -160,7 +160,7 @@ feature 'Admin banners magement' do click_link "Delete banner" visit admin_root_path - expect(page).to_not have_content 'Ugly banner' + expect(page).not_to have_content 'Ugly banner' end end diff --git a/spec/features/admin/budget_investment_milestones_spec.rb b/spec/features/admin/budget_investment_milestones_spec.rb index 9bcb78479..4221d5647 100644 --- a/spec/features/admin/budget_investment_milestones_spec.rb +++ b/spec/features/admin/budget_investment_milestones_spec.rb @@ -12,12 +12,17 @@ feature 'Admin budget investment milestones' do context "Index" do scenario 'Displaying milestones' do milestone = create(:budget_investment_milestone, investment: @investment) + create(:image, imageable: milestone) + document = create(:document, documentable: milestone) visit admin_budget_budget_investment_path(@investment.budget, @investment) expect(page).to have_content("Milestone") expect(page).to have_content(milestone.title) expect(page).to have_content(milestone.id) + expect(page).to have_content(milestone.publication_date.to_date) + expect(page).to have_link 'Show image' + expect(page).to have_link document.title end scenario 'Displaying no_milestones text' do @@ -34,13 +39,13 @@ feature 'Admin budget investment milestones' do click_link 'Create new milestone' - fill_in 'budget_investment_milestone_title', with: 'New title milestone' fill_in 'budget_investment_milestone_description', with: 'New description milestone' + fill_in 'budget_investment_milestone_publication_date', with: Time.zone.today click_button 'Create milestone' - expect(page).to have_content 'New title milestone' expect(page).to have_content 'New description milestone' + expect(page).to have_content Time.zone.today end scenario "Show validation errors on milestone form" do @@ -53,27 +58,35 @@ feature 'Admin budget investment milestones' do click_button 'Create milestone' within "#new_budget_investment_milestone" do - expect(page).to have_content "can't be blank" + expect(page).to have_content "can't be blank", count: 1 expect(page).to have_content 'New description milestone' end end end context "Edit" do - scenario "Change title and description" do + scenario "Change title, description and document names" do milestone = create(:budget_investment_milestone, investment: @investment) + create(:image, imageable: milestone) + document = create(:document, documentable: milestone) visit admin_budget_budget_investment_path(@investment.budget, @investment) + expect(page).to have_link document.title click_link milestone.title - fill_in 'budget_investment_milestone_title', with: 'Changed title' + expect(page).to have_css("img[alt='#{milestone.image.title}']") + fill_in 'budget_investment_milestone_description', with: 'Changed description' + fill_in 'budget_investment_milestone_publication_date', with: Time.zone.today.to_date + fill_in 'budget_investment_milestone_documents_attributes_0_title', with: 'New document title' click_button 'Update milestone' - expect(page).to have_content 'Changed title' expect(page).to have_content 'Changed description' + expect(page).to have_content Time.zone.today.to_date + expect(page).to have_link 'Show image' + expect(page).to have_link 'New document title' end end @@ -85,7 +98,7 @@ feature 'Admin budget investment milestones' do click_link "Delete milestone" - expect(page).to_not have_content 'Title will it remove' + expect(page).not_to have_content 'Title will it remove' end end diff --git a/spec/features/admin/budget_investments_spec.rb b/spec/features/admin/budget_investments_spec.rb index 7252e2660..c3fc69473 100644 --- a/spec/features/admin/budget_investments_spec.rb +++ b/spec/features/admin/budget_investments_spec.rb @@ -36,6 +36,21 @@ feature 'Admin budget investments' do expect(page).to have_content(budget_investment.total_votes) end + scenario 'If budget is finished do not show "Selected" button' do + finished_budget = create(:budget, :finished) + budget_investment = create(:budget_investment, budget: finished_budget, cached_votes_up: 77) + + visit admin_budget_budget_investments_path(budget_id: finished_budget.id) + + within("#budget_investment_#{budget_investment.id}") do + expect(page).to have_content(budget_investment.title) + expect(page).to have_content(budget_investment.heading.name) + expect(page).to have_content(budget_investment.id) + expect(page).to have_content(budget_investment.total_votes) + expect(page).to_not have_link("Selected") + end + end + scenario 'Displaying assignments info' do budget_investment1 = create(:budget_investment, budget: @budget) budget_investment2 = create(:budget_investment, budget: @budget) @@ -88,8 +103,8 @@ feature 'Admin budget investments' do select "Parks: Central Park", from: "heading_id" - expect(page).to_not have_link("Realocate visitors") - expect(page).to_not have_link("Change name") + expect(page).not_to have_link("Realocate visitors") + expect(page).not_to have_link("Change name") expect(page).to have_link("Plant trees") select "All headings", from: "heading_id" @@ -101,14 +116,14 @@ feature 'Admin budget investments' do select "Streets: Main Avenue", from: "heading_id" expect(page).to have_link("Realocate visitors") - expect(page).to_not have_link("Change name") - expect(page).to_not have_link("Plant trees") + expect(page).not_to have_link("Change name") + expect(page).not_to have_link("Plant trees") select "Streets: Mercy Street", from: "heading_id" - expect(page).to_not have_link("Realocate visitors") + expect(page).not_to have_link("Realocate visitors") expect(page).to have_link("Change name") - expect(page).to_not have_link("Plant trees") + expect(page).not_to have_link("Plant trees") end scenario "Filtering by admin", :js do @@ -125,7 +140,7 @@ feature 'Admin budget investments' do select "Admin 1", from: "administrator_id" expect(page).to have_content('There is 1 investment') - expect(page).to_not have_link("Destroy the city") + expect(page).not_to have_link("Destroy the city") expect(page).to have_link("Realocate visitors") select "All administrators", from: "administrator_id" @@ -136,7 +151,7 @@ feature 'Admin budget investments' do select "Admin 1", from: "administrator_id" expect(page).to have_content('There is 1 investment') - expect(page).to_not have_link("Destroy the city") + expect(page).not_to have_link("Destroy the city") expect(page).to have_link("Realocate visitors") end @@ -156,7 +171,7 @@ feature 'Admin budget investments' do select "Valuator 1", from: "valuator_id" expect(page).to have_content('There is 1 investment') - expect(page).to_not have_link("Destroy the city") + expect(page).not_to have_link("Destroy the city") expect(page).to have_link("Realocate visitors") select "All valuators", from: "valuator_id" @@ -167,7 +182,7 @@ feature 'Admin budget investments' do select "Valuator 1", from: "valuator_id" expect(page).to have_content('There is 1 investment') - expect(page).to_not have_link("Destroy the city") + expect(page).not_to have_link("Destroy the city") expect(page).to have_link("Realocate visitors") end @@ -181,13 +196,13 @@ feature 'Admin budget investments' do visit admin_budget_budget_investments_path(budget_id: @budget.id) - expect(page).to_not have_link(filters_links.values.first) + expect(page).not_to have_link(filters_links.values.first) filters_links.keys.drop(1).each { |filter| expect(page).to have_link(filters_links[filter]) } filters_links.each_pair do |current_filter, link| visit admin_budget_budget_investments_path(budget_id: @budget.id, filter: current_filter) - expect(page).to_not have_link(link) + expect(page).not_to have_link(link) (filters_links.keys - [current_filter]).each do |filter| expect(page).to have_link(filters_links[filter]) @@ -208,12 +223,12 @@ feature 'Admin budget investments' do visit admin_budget_budget_investments_path(budget_id: @budget.id, filter: 'without_admin') expect(page).to have_content("Evaluating...") - expect(page).to_not have_content("Assigned idea") + expect(page).not_to have_content("Assigned idea") visit admin_budget_budget_investments_path(budget_id: @budget.id, filter: 'managed') expect(page).to have_content("Assigned idea") - expect(page).to_not have_content("Evaluating...") + expect(page).not_to have_content("Evaluating...") end scenario "Filtering by valuation status" do @@ -225,16 +240,16 @@ feature 'Admin budget investments' do visit admin_budget_budget_investments_path(budget_id: @budget.id, filter: 'valuation_open') expect(page).to have_content("Ongoing valuation") - expect(page).to_not have_content("Old idea") + expect(page).not_to have_content("Old idea") visit admin_budget_budget_investments_path(budget_id: @budget.id, filter: 'valuating') expect(page).to have_content("Ongoing valuation") - expect(page).to_not have_content("Old idea") + expect(page).not_to have_content("Old idea") visit admin_budget_budget_investments_path(budget_id: @budget.id, filter: 'valuation_finished') - expect(page).to_not have_content("Ongoing valuation") + expect(page).not_to have_content("Ongoing valuation") expect(page).to have_content("Old idea") visit admin_budget_budget_investments_path(budget_id: @budget.id, filter: 'all') @@ -256,7 +271,7 @@ feature 'Admin budget investments' do visit admin_budget_budget_investments_path(budget_id: @budget.id, tag_name: 'Education') - expect(page).to_not have_content("More hospitals") + expect(page).not_to have_content("More hospitals") expect(page).to have_css(".budget_investment", count: 2) expect(page).to have_content("Educate the children") expect(page).to have_content("More schools") @@ -279,33 +294,55 @@ feature 'Admin budget investments' do end - scenario 'Show' do - administrator = create(:administrator, user: create(:user, username: 'Ana', email: 'ana@admins.org')) - valuator = create(:valuator, user: create(:user, username: 'Rachel', email: 'rachel@valuators.org')) - budget_investment = create(:budget_investment, - price: 1234, - price_first_year: 1000, - feasibility: "unfeasible", - unfeasibility_explanation: 'It is impossible', - administrator: administrator) - budget_investment.valuators << valuator + context 'Show' do + background do + @administrator = create(:administrator, user: create(:user, username: 'Ana', email: 'ana@admins.org')) + end - visit admin_budget_budget_investments_path(budget_investment.budget) + scenario 'Show the investment details' do + valuator = create(:valuator, user: create(:user, username: 'Rachel', email: 'rachel@valuators.org')) + budget_investment = create(:budget_investment, + price: 1234, + price_first_year: 1000, + feasibility: "unfeasible", + unfeasibility_explanation: 'It is impossible', + administrator: @administrator) + budget_investment.valuators << valuator - click_link budget_investment.title + visit admin_budget_budget_investments_path(budget_investment.budget) - expect(page).to have_content(budget_investment.title) - expect(page).to have_content(budget_investment.description) - expect(page).to have_content(budget_investment.author.name) - expect(page).to have_content(budget_investment.heading.name) - expect(page).to have_content('1234') - expect(page).to have_content('1000') - expect(page).to have_content('Unfeasible') - expect(page).to have_content('It is impossible') - expect(page).to have_content('Ana (ana@admins.org)') + click_link budget_investment.title - within('#assigned_valuators') do - expect(page).to have_content('Rachel (rachel@valuators.org)') + expect(page).to have_content(budget_investment.title) + expect(page).to have_content(budget_investment.description) + expect(page).to have_content(budget_investment.author.name) + expect(page).to have_content(budget_investment.heading.name) + expect(page).to have_content('1234') + expect(page).to have_content('1000') + expect(page).to have_content('Unfeasible') + expect(page).to have_content('It is impossible') + expect(page).to have_content('Ana (ana@admins.org)') + + within('#assigned_valuators') do + expect(page).to have_content('Rachel (rachel@valuators.org)') + end + end + + scenario "If budget is finished, investment cannot be edited" do + # Only milestones can be managed + + finished_budget = create(:budget, :finished) + budget_investment = create(:budget_investment, + budget: finished_budget, + administrator: @administrator) + visit admin_budget_budget_investments_path(budget_investment.budget) + + click_link budget_investment.title + + expect(page).to_not have_link "Edit" + expect(page).to_not have_link "Edit classification" + expect(page).to_not have_link "Edit dossier" + expect(page).to have_link "Create new milestone" end end @@ -378,8 +415,8 @@ feature 'Admin budget investments' do within('#assigned_valuators') do expect(page).to have_content('Valentina (v1@valuators.org)') expect(page).to have_content('Val (v3@valuators.org)') - expect(page).to_not have_content('Undefined') - expect(page).to_not have_content('Valerian (v2@valuators.org)') + expect(page).not_to have_content('Undefined') + expect(page).not_to have_content('Valerian (v2@valuators.org)') end end @@ -400,7 +437,7 @@ feature 'Admin budget investments' do within "#tags" do expect(page).to have_content 'Education' - expect(page).to_not have_content 'Health' + expect(page).not_to have_content 'Health' end end @@ -421,20 +458,37 @@ feature 'Admin budget investments' do end end - scenario "Only displays valuation tags" do + scenario "Changes valuation and user generated tags" do budget_investment = create(:budget_investment, tag_list: 'Park') budget_investment.set_tag_list_on(:valuation, 'Education') budget_investment.save visit admin_budget_budget_investment_path(budget_investment.budget, budget_investment) - expect(page).to have_content "Education" - expect(page).to_not have_content "Park" + within("#user-tags") do + expect(page).not_to have_content "Education" + expect(page).to have_content "Park" + end click_link 'Edit classification' - expect(page).to have_content "Education" - expect(page).to_not have_content "Park" + fill_in 'budget_investment_tag_list', with: 'Park, Trees' + fill_in 'budget_investment_valuation_tag_list', with: 'Education, Environment' + click_button 'Update' + + visit admin_budget_budget_investment_path(budget_investment.budget, budget_investment) + + within("#user-tags") do + expect(page).not_to have_content "Education" + expect(page).not_to have_content "Environment" + expect(page).to have_content "Park, Trees" + end + + within("#tags") do + expect(page).to have_content "Education, Environment" + expect(page).not_to have_content "Park" + expect(page).not_to have_content "Trees" + end end scenario "Maintains user tags" do @@ -451,7 +505,7 @@ feature 'Admin budget investments' do visit budget_investment_path(budget_investment.budget, budget_investment) expect(page).to have_content "Park" - expect(page).to_not have_content "Refugees, Solidarity" + expect(page).not_to have_content "Refugees, Solidarity" end scenario "Errors on update" do @@ -481,31 +535,31 @@ feature 'Admin budget investments' do visit admin_budget_budget_investments_path(@budget) within('#filter-subnav') { click_link 'Valuation finished' } - expect(page).to_not have_content(unfeasible_bi.title) - expect(page).to_not have_content(feasible_bi.title) + expect(page).not_to have_content(unfeasible_bi.title) + expect(page).not_to have_content(feasible_bi.title) expect(page).to have_content(feasible_vf_bi.title) expect(page).to have_content(selected_bi.title) expect(page).to have_content(winner_bi.title) within('#filter-subnav') { click_link 'Val. fin. Feasible' } - expect(page).to_not have_content(unfeasible_bi.title) - expect(page).to_not have_content(feasible_bi.title) + expect(page).not_to have_content(unfeasible_bi.title) + expect(page).not_to have_content(feasible_bi.title) expect(page).to have_content(feasible_vf_bi.title) expect(page).to have_content(selected_bi.title) expect(page).to have_content(winner_bi.title) within('#filter-subnav') { click_link 'Selected' } - expect(page).to_not have_content(unfeasible_bi.title) - expect(page).to_not have_content(feasible_bi.title) - expect(page).to_not have_content(feasible_vf_bi.title) + expect(page).not_to have_content(unfeasible_bi.title) + expect(page).not_to have_content(feasible_bi.title) + expect(page).not_to have_content(feasible_vf_bi.title) expect(page).to have_content(selected_bi.title) expect(page).to have_content(winner_bi.title) within('#filter-subnav') { click_link 'Winners' } - expect(page).to_not have_content(unfeasible_bi.title) - expect(page).to_not have_content(feasible_bi.title) - expect(page).to_not have_content(feasible_vf_bi.title) - expect(page).to_not have_content(selected_bi.title) + expect(page).not_to have_content(unfeasible_bi.title) + expect(page).not_to have_content(feasible_bi.title) + expect(page).not_to have_content(feasible_vf_bi.title) + expect(page).not_to have_content(selected_bi.title) expect(page).to have_content(winner_bi.title) end @@ -514,22 +568,22 @@ feature 'Admin budget investments' do within('#filter-subnav') { click_link 'All' } within("#budget_investment_#{unfeasible_bi.id}") do - expect(page).to_not have_link('Select') - expect(page).to_not have_link('Selected') + expect(page).not_to have_link('Select') + expect(page).not_to have_link('Selected') end within("#budget_investment_#{feasible_bi.id}") do - expect(page).to_not have_link('Select') - expect(page).to_not have_link('Selected') + expect(page).not_to have_link('Select') + expect(page).not_to have_link('Selected') end within("#budget_investment_#{feasible_vf_bi.id}") do expect(page).to have_link('Select') - expect(page).to_not have_link('Selected') + expect(page).not_to have_link('Selected') end within("#budget_investment_#{selected_bi.id}") do - expect(page).to_not have_link('Select') + expect(page).not_to have_link('Select') expect(page).to have_link('Selected') end end @@ -546,7 +600,7 @@ feature 'Admin budget investments' do within('#filter-subnav') { click_link 'Selected' } within("#budget_investment_#{feasible_vf_bi.id}") do - expect(page).to_not have_link('Select') + expect(page).not_to have_link('Select') expect(page).to have_link('Selected') end end @@ -561,17 +615,67 @@ feature 'Admin budget investments' do click_link('Selected') end - expect(page).to_not have_content(selected_bi.title) + expect(page).not_to have_content(selected_bi.title) expect(page).to have_content('There is 1 investment') within('#filter-subnav') { click_link 'All' } within("#budget_investment_#{selected_bi.id}") do expect(page).to have_link('Select') - expect(page).to_not have_link('Selected') + expect(page).not_to have_link('Selected') end end + end + context "Selecting csv" do + + scenario "Downloading CSV file" do + investment = create(:budget_investment, :feasible, budget: @budget, + price: 100) + valuator = create(:valuator, user: create(:user, username: 'Rachel', + email: 'rachel@val.org')) + investment.valuators << valuator + + admin = create(:administrator, user: create(:user, username: 'Gema')) + investment.update(administrator_id: admin.id) + + visit admin_budget_budget_investments_path(@budget, format: :csv) + + header = page.response_headers['Content-Disposition'] + expect(header).to match(/^attachment/) + expect(header).to match(/filename="budget_investments.csv"$/) + + valuators = investment.valuators.collect(&:description_or_name).join(', ') + feasibility_string = "admin.budget_investments.index"\ + ".feasibility.#{investment.feasibility}" + price = I18n.t(feasibility_string, price: investment.formatted_price) + + expect(page).to have_content investment.title + expect(page).to have_content investment.total_votes.to_s + expect(page).to have_content investment.id.to_s + expect(page).to have_content investment.heading.name + + expect(page).to have_content investment.administrator.name + expect(page).to have_content valuators + expect(page).to have_content price + expect(page).to have_content I18n.t('shared.no') + end + + scenario "Downloading CSV file with applied filter" do + investment1 = create(:budget_investment, :unfeasible, budget: @budget, + title: 'compatible') + investment2 = create(:budget_investment, :finished, budget: @budget, + title: 'finished') + visit admin_budget_budget_investments_path(@budget, format: :csv, + filter: :valuation_finished) + + header = page.response_headers['Content-Disposition'] + header.should match(/^attachment/) + header.should match(/filename="budget_investments.csv"$/) + + expect(page).to have_content investment2.title + expect(page).to_not have_content investment1.title + end end end diff --git a/spec/features/admin/budgets_spec.rb b/spec/features/admin/budgets_spec.rb index e21db46df..239865317 100644 --- a/spec/features/admin/budgets_spec.rb +++ b/spec/features/admin/budgets_spec.rb @@ -34,32 +34,32 @@ feature 'Admin budgets' do end scenario 'Filters by phase' do - budget1 = create(:budget) - budget2 = create(:budget, :accepting) - budget3 = create(:budget, :selecting) - budget4 = create(:budget, :balloting) - budget5 = create(:budget, :finished) + drafting_budget = create(:budget, :drafting) + accepting_budget = create(:budget, :accepting) + selecting_budget = create(:budget, :selecting) + balloting_budget = create(:budget, :balloting) + finished_budget = create(:budget, :finished) visit admin_budgets_path - expect(page).to have_content(budget1.name) - expect(page).to have_content(budget2.name) - expect(page).to have_content(budget3.name) - expect(page).to have_content(budget4.name) - expect(page).to_not have_content(budget5.name) + expect(page).to have_content(drafting_budget.name) + expect(page).to have_content(accepting_budget.name) + expect(page).to have_content(selecting_budget.name) + expect(page).to have_content(balloting_budget.name) + expect(page).not_to have_content(finished_budget.name) click_link 'Finished' - expect(page).to_not have_content(budget1.name) - expect(page).to_not have_content(budget2.name) - expect(page).to_not have_content(budget3.name) - expect(page).to_not have_content(budget4.name) - expect(page).to have_content(budget5.name) + expect(page).not_to have_content(drafting_budget.name) + expect(page).not_to have_content(accepting_budget.name) + expect(page).not_to have_content(selecting_budget.name) + expect(page).not_to have_content(balloting_budget.name) + expect(page).to have_content(finished_budget.name) click_link 'Open' - expect(page).to have_content(budget1.name) - expect(page).to have_content(budget2.name) - expect(page).to have_content(budget3.name) - expect(page).to have_content(budget4.name) - expect(page).to_not have_content(budget5.name) + expect(page).to have_content(drafting_budget.name) + expect(page).to have_content(accepting_budget.name) + expect(page).to have_content(selecting_budget.name) + expect(page).to have_content(balloting_budget.name) + expect(page).not_to have_content(finished_budget.name) end scenario 'Open filter is properly highlighted' do @@ -67,13 +67,13 @@ feature 'Admin budgets' do visit admin_budgets_path - expect(page).to_not have_link(filters_links.values.first) + expect(page).not_to have_link(filters_links.values.first) filters_links.keys.drop(1).each { |filter| expect(page).to have_link(filters_links[filter]) } filters_links.each_pair do |current_filter, link| visit admin_budgets_path(filter: current_filter) - expect(page).to_not have_link(link) + expect(page).not_to have_link(link) (filters_links.keys - [current_filter]).each do |filter| expect(page).to have_link(filters_links[filter]) @@ -103,12 +103,57 @@ feature 'Admin budgets' do visit new_admin_budget_path click_button 'Create Participatory budget' - expect(page).to_not have_content 'New participatory budget created successfully!' + expect(page).not_to have_content 'New participatory budget created successfully!' expect(page).to have_css("label.error", text: "Name") end end + context 'Destroy' do + + let!(:budget) { create(:budget) } + let(:heading) { create(:budget_heading, group: create(:budget_group, budget: budget)) } + + scenario 'Destroy a budget without investments' do + visit admin_budgets_path + click_link 'Edit budget' + click_button 'Delete budget' + + expect(page).to have_content('Budget deleted successfully') + expect(page).to have_content('participatory budgets cannot be found') + end + + scenario 'Try to destroy a budget with investments' do + create(:budget_investment, heading: heading) + + visit admin_budgets_path + click_link 'Edit budget' + click_button 'Delete budget' + + expect(page).to have_content('You cannot destroy a Budget that has associated investments') + expect(page).to have_content('There is 1 participatory budget') + end + end + + context 'Update' do + + background do + create(:budget) + end + + scenario 'Update budget' do + visit admin_budgets_path + click_link 'Edit budget' + + fill_in 'budget_name', with: 'More trees on the streets' + click_button 'Update Participatory budget' + + expect(page).to have_content('More trees on the streets') + expect(page).to have_current_path(admin_budgets_path) + end + + end + context "Calculate Budget's Winner Investments" do scenario 'For a Budget in reviewing balloting' do @@ -158,7 +203,7 @@ feature 'Admin budgets' do expect(page).to have_content '1 Group of budget headings' expect(page).to have_content 'Health' expect(page).to have_content 'Yearly participatory budget' - expect(page).to_not have_content 'No groups created yet.' + expect(page).not_to have_content 'No groups created yet.' visit admin_budgets_path within("#budget_#{budget.id}") do @@ -168,7 +213,7 @@ feature 'Admin budgets' do expect(page).to have_content '1 Group of budget headings' expect(page).to have_content 'Health' expect(page).to have_content 'Yearly participatory budget' - expect(page).to_not have_content 'No groups created yet.' + expect(page).not_to have_content 'No groups created yet.' end scenario 'Create heading', :js do @@ -187,11 +232,11 @@ feature 'Admin budgets' do click_button 'Save heading' end - expect(page).to_not have_content 'This group has no assigned heading.' + expect(page).not_to have_content 'This group has no assigned heading.' visit admin_budget_path(budget) within("#budget_group_#{group.id}") do - expect(page).to_not have_content 'This group has no assigned heading.' + expect(page).not_to have_content 'This group has no assigned heading.' expect(page).to have_content 'District 9 reconstruction' expect(page).to have_content '6785' diff --git a/spec/features/admin/comments_spec.rb b/spec/features/admin/comments_spec.rb index 3de3395d0..e6e603378 100644 --- a/spec/features/admin/comments_spec.rb +++ b/spec/features/admin/comments_spec.rb @@ -22,7 +22,7 @@ feature 'Admin comments' do end visit admin_comments_path - expect(page).to_not have_content("SPAM from SPAMMER") + expect(page).not_to have_content("SPAM from SPAMMER") expect(page).not_to have_content("Good Proposal!") end @@ -32,9 +32,9 @@ feature 'Admin comments' do click_link 'Restore' - expect(page).to_not have_content(comment.body) + expect(page).not_to have_content(comment.body) - expect(comment.reload).to_not be_hidden + expect(comment.reload).not_to be_hidden expect(comment).to be_ignored_flag end @@ -44,7 +44,7 @@ feature 'Admin comments' do click_link 'Confirm' - expect(page).to_not have_content(comment.body) + expect(page).not_to have_content(comment.body) click_link('Confirmed') expect(page).to have_content(comment.body) @@ -53,24 +53,24 @@ feature 'Admin comments' do scenario "Current filter is properly highlighted" do visit admin_comments_path - expect(page).to_not have_link('Pending') + expect(page).not_to have_link('Pending') expect(page).to have_link('All') expect(page).to have_link('Confirmed') visit admin_comments_path(filter: 'Pending') - expect(page).to_not have_link('Pending') + expect(page).not_to have_link('Pending') expect(page).to have_link('All') expect(page).to have_link('Confirmed') visit admin_comments_path(filter: 'all') expect(page).to have_link('Pending') - expect(page).to_not have_link('All') + expect(page).not_to have_link('All') expect(page).to have_link('Confirmed') visit admin_comments_path(filter: 'with_confirmed_hide') expect(page).to have_link('Pending') expect(page).to have_link('All') - expect(page).to_not have_link('Confirmed') + expect(page).not_to have_link('Confirmed') end scenario "Filtering comments" do @@ -82,7 +82,7 @@ feature 'Admin comments' do expect(page).to have_content('Confirmed comment') visit admin_comments_path(filter: 'with_confirmed_hide') - expect(page).to_not have_content('Unconfirmed comment') + expect(page).not_to have_content('Unconfirmed comment') expect(page).to have_content('Confirmed comment') end diff --git a/spec/features/admin/debates_spec.rb b/spec/features/admin/debates_spec.rb index cb23ee788..45d2040c6 100644 --- a/spec/features/admin/debates_spec.rb +++ b/spec/features/admin/debates_spec.rb @@ -23,9 +23,9 @@ feature 'Admin debates' do click_link 'Restore' - expect(page).to_not have_content(debate.title) + expect(page).not_to have_content(debate.title) - expect(debate.reload).to_not be_hidden + expect(debate.reload).not_to be_hidden expect(debate).to be_ignored_flag end @@ -35,7 +35,7 @@ feature 'Admin debates' do click_link 'Confirm' - expect(page).to_not have_content(debate.title) + expect(page).not_to have_content(debate.title) click_link('Confirmed') expect(page).to have_content(debate.title) @@ -44,24 +44,24 @@ feature 'Admin debates' do scenario "Current filter is properly highlighted" do visit admin_debates_path - expect(page).to_not have_link('Pending') + expect(page).not_to have_link('Pending') expect(page).to have_link('All') expect(page).to have_link('Confirmed') visit admin_debates_path(filter: 'Pending') - expect(page).to_not have_link('Pending') + expect(page).not_to have_link('Pending') expect(page).to have_link('All') expect(page).to have_link('Confirmed') visit admin_debates_path(filter: 'all') expect(page).to have_link('Pending') - expect(page).to_not have_link('All') + expect(page).not_to have_link('All') expect(page).to have_link('Confirmed') visit admin_debates_path(filter: 'with_confirmed_hide') expect(page).to have_link('All') expect(page).to have_link('Pending') - expect(page).to_not have_link('Confirmed') + expect(page).not_to have_link('Confirmed') end scenario "Filtering debates" do @@ -70,14 +70,14 @@ feature 'Admin debates' do visit admin_debates_path(filter: 'pending') expect(page).to have_content('Unconfirmed debate') - expect(page).to_not have_content('Confirmed debate') + expect(page).not_to have_content('Confirmed debate') visit admin_debates_path(filter: 'all') expect(page).to have_content('Unconfirmed debate') expect(page).to have_content('Confirmed debate') visit admin_debates_path(filter: 'with_confirmed_hide') - expect(page).to_not have_content('Unconfirmed debate') + expect(page).not_to have_content('Unconfirmed debate') expect(page).to have_content('Confirmed debate') end diff --git a/spec/features/admin/feature_flags_spec.rb b/spec/features/admin/feature_flags_spec.rb index 99c460477..89d20d052 100644 --- a/spec/features/admin/feature_flags_spec.rb +++ b/spec/features/admin/feature_flags_spec.rb @@ -29,7 +29,7 @@ feature 'Admin feature flags' do within("#edit_setting_#{setting_id}") do expect(page).to have_button "Disable" - expect(page).to_not have_button "Enable" + expect(page).not_to have_button "Enable" click_button 'Disable' end @@ -59,7 +59,7 @@ feature 'Admin feature flags' do within("#edit_setting_#{setting_id}") do expect(page).to have_button "Enable" - expect(page).to_not have_button "Disable" + expect(page).not_to have_button "Disable" click_button 'Enable' end diff --git a/spec/features/admin/hidden_users_spec.rb b/spec/features/admin/hidden_users_spec.rb index f229bd833..0f41e3573 100644 --- a/spec/features/admin/hidden_users_spec.rb +++ b/spec/features/admin/hidden_users_spec.rb @@ -29,9 +29,9 @@ feature 'Admin hidden users' do click_link 'Restore' - expect(page).to_not have_content(user.username) + expect(page).not_to have_content(user.username) - expect(user.reload).to_not be_hidden + expect(user.reload).not_to be_hidden end scenario 'Confirm hide' do @@ -40,7 +40,7 @@ feature 'Admin hidden users' do click_link 'Confirm' - expect(page).to_not have_content(user.username) + expect(page).not_to have_content(user.username) click_link('Confirmed') expect(page).to have_content(user.username) @@ -49,24 +49,24 @@ feature 'Admin hidden users' do scenario "Current filter is properly highlighted" do visit admin_hidden_users_path - expect(page).to_not have_link('Pending') + expect(page).not_to have_link('Pending') expect(page).to have_link('All') expect(page).to have_link('Confirmed') visit admin_hidden_users_path(filter: 'Pending') - expect(page).to_not have_link('Pending') + expect(page).not_to have_link('Pending') expect(page).to have_link('All') expect(page).to have_link('Confirmed') visit admin_hidden_users_path(filter: 'all') expect(page).to have_link('Pending') - expect(page).to_not have_link('All') + expect(page).not_to have_link('All') expect(page).to have_link('Confirmed') visit admin_hidden_users_path(filter: 'with_confirmed_hide') expect(page).to have_link('All') expect(page).to have_link('Pending') - expect(page).to_not have_link('Confirmed') + expect(page).not_to have_link('Confirmed') end scenario "Filtering users" do @@ -78,7 +78,7 @@ feature 'Admin hidden users' do expect(page).to have_content('Confirmed user') visit admin_hidden_users_path(filter: 'with_confirmed_hide') - expect(page).to_not have_content('Unconfirmed') + expect(page).not_to have_content('Unconfirmed') expect(page).to have_content('Confirmed user') end diff --git a/spec/features/admin/legislation/processes_spec.rb b/spec/features/admin/legislation/processes_spec.rb index 8ad2fa456..d968d3e8f 100644 --- a/spec/features/admin/legislation/processes_spec.rb +++ b/spec/features/admin/legislation/processes_spec.rb @@ -34,7 +34,7 @@ feature 'Admin legislation processes' do click_link "Collaborative Legislation" end - expect(page).to_not have_content 'An example legislation process' + expect(page).not_to have_content 'An example legislation process' click_link "New process" diff --git a/spec/features/admin/legislation/questions_spec.rb b/spec/features/admin/legislation/questions_spec.rb index ffbca09b1..d79429e30 100644 --- a/spec/features/admin/legislation/questions_spec.rb +++ b/spec/features/admin/legislation/questions_spec.rb @@ -108,7 +108,7 @@ feature 'Admin legislation questions' do expect(page).to have_content 'Questions' expect(page).to have_content 'Question 1' - expect(page).to_not have_content 'Question 2' + expect(page).not_to have_content 'Question 2' end end end diff --git a/spec/features/admin/managers_spec.rb b/spec/features/admin/managers_spec.rb index 54b8cc77a..24baafca6 100644 --- a/spec/features/admin/managers_spec.rb +++ b/spec/features/admin/managers_spec.rb @@ -12,11 +12,11 @@ feature 'Admin managers' do scenario 'Index' do expect(page).to have_content @manager.name expect(page).to have_content @manager.email - expect(page).to_not have_content @user.name + expect(page).not_to have_content @user.name end scenario 'Create Manager', :js do - fill_in 'email', with: @user.email + fill_in 'name_or_email', with: @user.email click_button 'Search' expect(page).to have_content @user.name @@ -30,8 +30,56 @@ feature 'Admin managers' do click_link 'Delete' within("#managers") do - expect(page).to_not have_content @manager.name + expect(page).not_to have_content @manager.name end end -end \ No newline at end of file + context 'Search' do + + background do + user = create(:user, username: 'Taylor Swift', email: 'taylor@swift.com') + user2 = create(:user, username: 'Stephanie Corneliussen', email: 'steph@mrrobot.com') + @manager1 = create(:manager, user: user) + @manager2 = create(:manager, user: user2) + visit admin_managers_path + end + + scenario 'returns no results if search term is empty' do + expect(page).to have_content(@manager1.name) + expect(page).to have_content(@manager2.name) + + fill_in 'name_or_email', with: ' ' + click_button 'Search' + + expect(page).to have_content('Managers: User search') + expect(page).to have_content('No results found') + expect(page).not_to have_content(@manager1.name) + expect(page).not_to have_content(@manager2.name) + end + + scenario 'search by name' do + expect(page).to have_content(@manager1.name) + expect(page).to have_content(@manager2.name) + + fill_in 'name_or_email', with: 'Taylor' + click_button 'Search' + + expect(page).to have_content('Managers: User search') + expect(page).to have_content(@manager1.name) + expect(page).not_to have_content(@manager2.name) + end + + scenario 'search by email' do + expect(page).to have_content(@manager1.email) + expect(page).to have_content(@manager2.email) + + fill_in 'name_or_email', with: @manager2.email + click_button 'Search' + + expect(page).to have_content('Managers: User search') + expect(page).to have_content(@manager2.email) + expect(page).not_to have_content(@manager1.email) + end + end + +end diff --git a/spec/features/admin/moderators_spec.rb b/spec/features/admin/moderators_spec.rb index e8e29b182..aa45f7011 100644 --- a/spec/features/admin/moderators_spec.rb +++ b/spec/features/admin/moderators_spec.rb @@ -12,11 +12,11 @@ feature 'Admin moderators' do scenario 'Index' do expect(page).to have_content @moderator.name expect(page).to have_content @moderator.email - expect(page).to_not have_content @user.name + expect(page).not_to have_content @user.name end scenario 'Create Moderator', :js do - fill_in 'email', with: @user.email + fill_in 'name_or_email', with: @user.email click_button 'Search' expect(page).to have_content @user.name @@ -30,8 +30,56 @@ feature 'Admin moderators' do click_link 'Delete' within("#moderators") do - expect(page).to_not have_content @moderator.name + expect(page).not_to have_content @moderator.name end end -end + context 'Search' do + + background do + user = create(:user, username: 'Elizabeth Bathory', email: 'elizabeth@bathory.com') + user2 = create(:user, username: 'Ada Lovelace', email: 'ada@lovelace.com') + @moderator1 = create(:moderator, user: user) + @moderator2 = create(:moderator, user: user2) + visit admin_moderators_path + end + + scenario 'returns no results if search term is empty' do + expect(page).to have_content(@moderator1.name) + expect(page).to have_content(@moderator2.name) + + fill_in 'name_or_email', with: ' ' + click_button 'Search' + + expect(page).to have_content('Moderators: User search') + expect(page).to have_content('No results found') + expect(page).not_to have_content(@moderator1.name) + expect(page).not_to have_content(@moderator2.name) + end + + scenario 'search by name' do + expect(page).to have_content(@moderator1.name) + expect(page).to have_content(@moderator2.name) + + fill_in 'name_or_email', with: 'Eliz' + click_button 'Search' + + expect(page).to have_content('Moderators: User search') + expect(page).to have_content(@moderator1.name) + expect(page).not_to have_content(@moderator2.name) + end + + scenario 'search by email' do + expect(page).to have_content(@moderator1.email) + expect(page).to have_content(@moderator2.email) + + fill_in 'name_or_email', with: @moderator2.email + click_button 'Search' + + expect(page).to have_content('Moderators: User search') + expect(page).to have_content(@moderator2.email) + expect(page).not_to have_content(@moderator1.email) + end + end + +end diff --git a/spec/features/admin/officials_spec.rb b/spec/features/admin/officials_spec.rb index 08c7c27a4..5b5a5c32f 100644 --- a/spec/features/admin/officials_spec.rb +++ b/spec/features/admin/officials_spec.rb @@ -13,7 +13,7 @@ feature 'Admin officials' do visit admin_officials_path expect(page).to have_content @official.name - expect(page).to_not have_content @citizen.name + expect(page).not_to have_content @citizen.name expect(page).to have_content @official.official_position expect(page).to have_content @official.official_level end @@ -22,9 +22,9 @@ feature 'Admin officials' do visit admin_officials_path click_link @official.name - expect(current_path).to eq(edit_admin_official_path(@official)) + expect(page).to have_current_path(edit_admin_official_path(@official)) - expect(page).to_not have_content @citizen.name + expect(page).not_to have_content @citizen.name expect(page).to have_content @official.name expect(page).to have_content @official.email @@ -46,8 +46,8 @@ feature 'Admin officials' do fill_in 'name_or_email', with: @citizen.email click_button 'Search' - expect(current_path).to eq(search_admin_officials_path) - expect(page).to_not have_content @official.name + expect(page).to have_current_path(search_admin_officials_path, only_path: true) + expect(page).not_to have_content @official.name click_link @citizen.name @@ -71,8 +71,8 @@ feature 'Admin officials' do click_link "Remove 'Official' status" expect(page).to have_content 'Details saved: the user is no longer an official' - expect(current_path).to eq(admin_officials_path) - expect(page).to_not have_content @citizen.name - expect(page).to_not have_content @official.name + expect(page).to have_current_path(admin_officials_path, only_path: true) + expect(page).not_to have_content @citizen.name + expect(page).not_to have_content @official.name end end diff --git a/spec/features/admin/organizations_spec.rb b/spec/features/admin/organizations_spec.rb index 814aa9df2..baf978ffc 100644 --- a/spec/features/admin/organizations_spec.rb +++ b/spec/features/admin/organizations_spec.rb @@ -20,8 +20,8 @@ feature 'Admin::Organizations' do expect(page).to have_content("Human Rights") expect(page).to have_content(org.user.email) - expect(page).to_not have_content("Greentroll") - expect(page).to_not have_content("trol@troller.com") + expect(page).not_to have_content("Greentroll") + expect(page).not_to have_content("trol@troller.com") expect(page).to have_content("There is also one organisation with no users or with a hidden user") end end @@ -40,15 +40,15 @@ feature 'Admin::Organizations' do fill_in "term", with: " " click_button "Search" - expect(current_path).to eq(search_admin_organizations_path) + expect(page).to have_current_path(search_admin_organizations_path, only_path: true) within("#search-results") do - expect(page).to_not have_content("Get up, Stand up") + expect(page).not_to have_content("Get up, Stand up") end end scenario "finds by name" do visit search_admin_organizations_path - expect(page).to_not have_content("Get up, Stand up") + expect(page).not_to have_content("Get up, Stand up") fill_in "term", with: "Up, sta" click_button "Search" @@ -60,7 +60,7 @@ feature 'Admin::Organizations' do scenario "finds by users email" do visit search_admin_organizations_path - expect(page).to_not have_content("Get up, Stand up") + expect(page).not_to have_content("Get up, Stand up") fill_in "term", with: @user.email click_button "Search" @@ -72,7 +72,7 @@ feature 'Admin::Organizations' do scenario "finds by users phone number" do visit search_admin_organizations_path - expect(page).to_not have_content("Get up, Stand up") + expect(page).not_to have_content("Get up, Stand up") fill_in "term", with: @user.phone_number click_button "Search" @@ -88,14 +88,14 @@ feature 'Admin::Organizations' do visit admin_organizations_path within("#organization_#{organization.id}") do - expect(current_path).to eq(admin_organizations_path) + expect(page).to have_current_path(admin_organizations_path, only_path: true) expect(page).to have_link('Verify') expect(page).to have_link('Reject') click_on 'Verify' end - expect(current_path).to eq(admin_organizations_path) - expect(page).to have_content ('Verified') + expect(page).to have_current_path(admin_organizations_path, only_path: true) + expect(page).to have_content 'Verified' expect(organization.reload.verified?).to eq(true) end @@ -108,18 +108,18 @@ feature 'Admin::Organizations' do click_on "Verified" within("#organization_#{organization.id}") do - expect(page).to have_content ('Verified') - expect(page).to_not have_link('Verify') + expect(page).to have_content 'Verified' + expect(page).not_to have_link('Verify') expect(page).to have_link('Reject') click_on 'Reject' end - expect(current_path).to eq(admin_organizations_path) - expect(page).to_not have_content (organization.name) + expect(page).to have_current_path(admin_organizations_path, only_path: true) + expect(page).not_to have_content organization.name click_on 'Rejected' - expect(page).to have_content ('Rejected') - expect(page).to have_content (organization.name) + expect(page).to have_content 'Rejected' + expect(page).to have_content organization.name expect(organization.reload.rejected?).to eq(true) end @@ -132,49 +132,49 @@ feature 'Admin::Organizations' do within("#organization_#{organization.id}") do expect(page).to have_link('Verify') - expect(page).to_not have_link('Reject', exact: true) + expect(page).not_to have_link('Reject', exact: true) click_on 'Verify' end - expect(current_path).to eq(admin_organizations_path) - expect(page).to_not have_content (organization.name) + expect(page).to have_current_path(admin_organizations_path, only_path: true) + expect(page).not_to have_content organization.name click_on('Verified') - expect(page).to have_content (organization.name) + expect(page).to have_content organization.name expect(organization.reload.verified?).to eq(true) end scenario "Current filter is properly highlighted" do visit admin_organizations_path - expect(page).to_not have_link('Pending') + expect(page).not_to have_link('Pending') expect(page).to have_link('All') expect(page).to have_link('Verified') expect(page).to have_link('Rejected') visit admin_organizations_path(filter: 'all') - expect(page).to_not have_link('All') + expect(page).not_to have_link('All') expect(page).to have_link('Pending') expect(page).to have_link('Verified') expect(page).to have_link('Rejected') visit admin_organizations_path(filter: 'pending') expect(page).to have_link('All') - expect(page).to_not have_link('Pending') + expect(page).not_to have_link('Pending') expect(page).to have_link('Verified') expect(page).to have_link('Rejected') visit admin_organizations_path(filter: 'verified') expect(page).to have_link('All') expect(page).to have_link('Pending') - expect(page).to_not have_link('Verified') + expect(page).not_to have_link('Verified') expect(page).to have_link('Rejected') visit admin_organizations_path(filter: 'rejected') expect(page).to have_link('All') expect(page).to have_link('Pending') expect(page).to have_link('Verified') - expect(page).to_not have_link('Rejected') + expect(page).not_to have_link('Rejected') end scenario "Filtering organizations" do @@ -189,18 +189,18 @@ feature 'Admin::Organizations' do visit admin_organizations_path(filter: 'pending') expect(page).to have_content('Pending Organization') - expect(page).to_not have_content('Rejected Organization') - expect(page).to_not have_content('Verified Organization') + expect(page).not_to have_content('Rejected Organization') + expect(page).not_to have_content('Verified Organization') visit admin_organizations_path(filter: 'verified') - expect(page).to_not have_content('Pending Organization') - expect(page).to_not have_content('Rejected Organization') + expect(page).not_to have_content('Pending Organization') + expect(page).not_to have_content('Rejected Organization') expect(page).to have_content('Verified Organization') visit admin_organizations_path(filter: 'rejected') - expect(page).to_not have_content('Pending Organization') + expect(page).not_to have_content('Pending Organization') expect(page).to have_content('Rejected Organization') - expect(page).to_not have_content('Verified Organization') + expect(page).not_to have_content('Verified Organization') end scenario "Verifying organization links remember the pagination setting and the filter" do diff --git a/spec/features/admin/poll/booth_assigments_spec.rb b/spec/features/admin/poll/booth_assigments_spec.rb index 09a21dd72..9d3f4180b 100644 --- a/spec/features/admin/poll/booth_assigments_spec.rb +++ b/spec/features/admin/poll/booth_assigments_spec.rb @@ -7,66 +7,144 @@ feature 'Admin booths assignments' do login_as(admin.user) end - scenario 'Assign booth to poll', :js do - poll = create(:poll) - booth = create(:poll_booth) + feature 'Admin Booth Assignment management' do - visit admin_poll_path(poll) - within('#poll-resources') do - click_link 'Booths (0)' + let!(:poll) { create(:poll) } + let!(:booth) { create(:poll_booth) } + + scenario 'List Polls and Booths to manage', :js do + second_poll = create(:poll) + second_booth = create(:poll_booth) + + visit booth_assignments_admin_polls_path + + expect(page).to have_content(poll.name) + expect(page).to have_content(second_poll.name) + + within("#poll_#{second_poll.id}") do + click_link 'Manage assignments' + end + + expect(page).to have_content "Assignments for poll '#{second_poll.name}'" + + expect(page).to have_content(booth.name) + expect(page).to have_content(second_booth.name) end - expect(page).to have_content 'There are no booths assigned to this poll.' + scenario 'Assign booth to poll', :js do + visit admin_poll_path(poll) + within('#poll-resources') do + click_link 'Booths (0)' + end - fill_in 'search-booths', with: booth.name - click_button 'Search' - expect(page).to have_content(booth.name) + expect(page).to have_content 'There are no booths assigned to this poll.' + expect(page).not_to have_content booth.name - within('#search-booths-results') do - click_link 'Assign booth' + fill_in 'search-booths', with: booth.name + click_button 'Search' + expect(page).to have_content(booth.name) + + visit manage_admin_poll_booth_assignments_path(poll) + + expect(page).to have_content "Assignments for poll '#{poll.name}'" + + within("#poll_booth_#{booth.id}") do + expect(page).to have_content(booth.name) + expect(page).to have_content "Unassigned" + + click_link 'Assign booth' + + expect(page).not_to have_content "Unassigned" + expect(page).to have_content "Assigned" + expect(page).to have_link "Unassign booth" + end + + visit admin_poll_path(poll) + within('#poll-resources') do + click_link 'Booths (1)' + end + + expect(page).not_to have_content 'There are no booths assigned to this poll.' + expect(page).to have_content booth.name end - expect(page).to have_content 'Booth assigned' + scenario 'Unassign booth from poll', :js do + assignment = create(:poll_booth_assignment, poll: poll, booth: booth) - visit admin_poll_path(poll) - within('#poll-resources') do - click_link 'Booths (1)' + visit admin_poll_path(poll) + within('#poll-resources') do + click_link 'Booths (1)' + end + + expect(page).not_to have_content 'There are no booths assigned to this poll.' + expect(page).to have_content booth.name + + fill_in 'search-booths', with: booth.name + click_button 'Search' + expect(page).to have_content(booth.name) + + visit manage_admin_poll_booth_assignments_path(poll) + + expect(page).to have_content "Assignments for poll '#{poll.name}'" + + within("#poll_booth_#{booth.id}") do + expect(page).to have_content(booth.name) + expect(page).to have_content "Assigned" + + click_link 'Unassign booth' + + expect(page).to have_content "Unassigned" + expect(page).not_to have_content "Assigned" + expect(page).to have_link "Assign booth" + end + + visit admin_poll_path(poll) + within('#poll-resources') do + click_link 'Booths (0)' + end + + expect(page).to have_content 'There are no booths assigned to this poll.' + expect(page).not_to have_content booth.name end - expect(page).to_not have_content 'There are no booths assigned to this poll.' - expect(page).to have_content booth.name - end + scenario 'Unassing booth whith associated shifts', :js do + assignment = create(:poll_booth_assignment, poll: poll, booth: booth) + officer = create(:poll_officer) + create(:poll_officer_assignment, officer: officer, booth_assignment: assignment) + create(:poll_shift, booth: booth, officer: officer) - scenario 'Remove booth from poll', :js do - poll = create(:poll) - booth = create(:poll_booth) - assignment = create(:poll_booth_assignment, poll: poll, booth: booth) + visit manage_admin_poll_booth_assignments_path(poll) - visit admin_poll_path(poll) - within('#poll-resources') do - click_link 'Booths (1)' + within("#poll_booth_#{booth.id}") do + expect(page).to have_content(booth.name) + expect(page).to have_content "Assigned" + + click_link 'Unassign booth' + + expect(page).to have_content "Unassigned" + expect(page).not_to have_content "Assigned" + expect(page).to have_link "Assign booth" + end end - expect(page).to_not have_content 'There are no booths assigned to this poll.' - expect(page).to have_content booth.name + scenario "Cannot unassing booth if poll is expired" do + poll_expired = create(:poll, :expired) + create(:poll_booth_assignment, poll: poll_expired, booth: booth) + + visit manage_admin_poll_booth_assignments_path(poll_expired) + + within("#poll_booth_#{booth.id}") do + expect(page).to have_content(booth.name) + expect(page).to have_content "Assigned" + + expect(page).not_to have_link 'Unassign booth' + end - within("#poll_booth_assignment_#{assignment.id}") do - click_link 'Remove booth from poll' end - - expect(page).to have_content 'Booth not assigned anymore' - - visit admin_poll_path(poll) - within('#poll-resources') do - click_link 'Booths (0)' - end - - expect(page).to have_content 'There are no booths assigned to this poll.' - expect(page).to_not have_content booth.name end feature 'Show' do - scenario 'Lists all assigned poll oficers' do + scenario 'Lists all assigned poll officers' do poll = create(:poll) booth = create(:poll_booth) booth_assignment = create(:poll_booth_assignment, poll: poll, booth: booth) @@ -85,7 +163,7 @@ feature 'Admin booths assignments' do click_link 'Officers' within('#officers_list') do expect(page).to have_content officer.name - expect(page).to_not have_content officer_2.name + expect(page).not_to have_content officer_2.name end end @@ -97,11 +175,8 @@ feature 'Admin booths assignments' do officer_assignment_2 = create(:poll_officer_assignment, booth_assignment: booth_assignment, date: poll.ends_at) final_officer_assignment = create(:poll_officer_assignment, :final, booth_assignment: booth_assignment, date: poll.ends_at) - total_recount = create(:poll_total_result, - booth_assignment: booth_assignment, - officer_assignment: final_officer_assignment, - date: final_officer_assignment.date, - amount: 5678) + create(:poll_voter, poll: poll, booth_assignment: booth_assignment, created_at: poll.starts_at.to_date) + create(:poll_voter, poll: poll, booth_assignment: booth_assignment, created_at: poll.ends_at.to_date) booth_assignment_2 = create(:poll_booth_assignment, poll: poll) @@ -111,12 +186,122 @@ feature 'Admin booths assignments' do within('#assigned_booths_list') { click_link booth.name } click_link 'Recounts' + + within('#totals') do + within("#total_system") { expect(page).to have_content "2" } + end + within('#recounts_list') do - within("#recounting_#{total_recount.date.strftime('%Y%m%d')}") do - expect(page).to have_content total_recount.amount + within("#recounting_#{poll.starts_at.to_date.strftime('%Y%m%d')}") do + expect(page).to have_content 1 + end + within("#recounting_#{(poll.ends_at.to_date - 5.days).strftime('%Y%m%d')}") do + expect(page).to have_content '-' + end + within("#recounting_#{poll.ends_at.to_date.strftime('%Y%m%d')}") do + expect(page).to have_content 1 end end end + scenario 'Results for a booth assignment' do + poll = create(:poll) + booth_assignment = create(:poll_booth_assignment, poll: poll) + other_booth_assignment = create(:poll_booth_assignment, poll: poll) + + question_1 = create(:poll_question, poll: poll) + create(:poll_question_answer, title: 'Yes', question: question_1) + create(:poll_question_answer, title: 'No', question: question_1) + + question_2 = create(:poll_question, poll: poll) + create(:poll_question_answer, title: 'Today', question: question_2) + create(:poll_question_answer, title: 'Tomorrow', question: question_2) + + create(:poll_partial_result, + booth_assignment: booth_assignment, + question: question_1, + answer: 'Yes', + amount: 11) + + create(:poll_partial_result, + booth_assignment: booth_assignment, + question: question_1, + answer: 'No', + amount: 4) + + create(:poll_partial_result, + booth_assignment: booth_assignment, + question: question_2, + answer: 'Today', + amount: 5) + + create(:poll_partial_result, + booth_assignment: booth_assignment, + question: question_2, + answer: 'Tomorrow', + amount: 6) + + create(:poll_partial_result, + booth_assignment: other_booth_assignment, + question: question_1, + answer: 'Yes', + amount: 9999) + + create(:poll_recount, + booth_assignment: booth_assignment, + white_amount: 21, + null_amount: 44, + total_amount: 66) + + create(:poll_recount, + booth_assignment: other_booth_assignment, + white_amount: 999, + null_amount: 999, + total_amount: 999) + + visit admin_poll_booth_assignment_path(poll, booth_assignment) + + click_link 'Results' + + expect(page).to have_content(question_1.title) + + within("#question_#{question_1.id}_0_result") do + expect(page).to have_content("Yes") + expect(page).to have_content(11) + end + + within("#question_#{question_1.id}_1_result") do + expect(page).to have_content("No") + expect(page).to have_content(4) + end + + expect(page).to have_content(question_2.title) + + within("#question_#{question_2.id}_0_result") do + expect(page).to have_content("Today") + expect(page).to have_content(5) + end + + within("#question_#{question_2.id}_1_result") do + expect(page).to have_content("Tomorrow") + expect(page).to have_content(6) + end + + within('#white_results') { expect(page).to have_content('21') } + within('#null_results') { expect(page).to have_content('44') } + within('#total_results') { expect(page).to have_content('66') } + end + + scenario "No results" do + poll = create(:poll) + booth_assignment = create(:poll_booth_assignment, poll: poll) + + visit admin_poll_booth_assignment_path(poll, booth_assignment) + + click_link "Results" + + expect(page).to have_content "There are no results" + end + end end diff --git a/spec/features/admin/poll/booths_spec.rb b/spec/features/admin/poll/booths_spec.rb index 13f3af2ff..ba7ca5cfb 100644 --- a/spec/features/admin/poll/booths_spec.rb +++ b/spec/features/admin/poll/booths_spec.rb @@ -33,7 +33,7 @@ feature 'Admin booths' do expect(page).to have_content booth.location end end - expect(page).to_not have_content "There are no booths" + expect(page).not_to have_content "There are no booths" end scenario "Available" do @@ -59,7 +59,8 @@ feature 'Admin booths' do expect(page).to have_content booth_for_current_poll.name expect(page).to have_content booth_for_incoming_poll.name - expect(page).to_not have_content booth_for_expired_poll.name + expect(page).not_to have_content booth_for_expired_poll.name + expect(page).not_to have_link "Edit booth" end scenario 'Show' do @@ -87,12 +88,15 @@ feature 'Admin booths' do end scenario "Edit" do + poll = create(:poll, :current) booth = create(:poll_booth) + assignment = create(:poll_booth_assignment, poll: poll, booth: booth) visit admin_booths_path within("#booth_#{booth.id}") do - click_link "Edit" + expect(page).not_to have_link "Manage shifts" + click_link "Edit booth" end fill_in "poll_booth_name", with: "Next booth" @@ -109,4 +113,18 @@ feature 'Admin booths' do end end -end \ No newline at end of file + scenario "Back link go back to available list when manage shifts" do + poll = create(:poll, :current) + booth = create(:poll_booth) + assignment = create(:poll_booth_assignment, poll: poll, booth: booth) + + visit available_admin_booths_path + + within("#booth_#{booth.id}") do + click_link "Manage shifts" + end + + click_link "Go back" + expect(page).to have_current_path(available_admin_booths_path) + end +end diff --git a/spec/features/admin/poll/officer_assignments_spec.rb b/spec/features/admin/poll/officer_assignments_spec.rb new file mode 100644 index 000000000..d95fc8aa5 --- /dev/null +++ b/spec/features/admin/poll/officer_assignments_spec.rb @@ -0,0 +1,67 @@ +require 'rails_helper' + +feature 'Officer Assignments' do + + background do + admin = create(:administrator) + login_as(admin.user) + end + + scenario "Index" do + poll = create(:poll) + booth = create(:poll_booth) + + officer1 = create(:poll_officer) + officer2 = create(:poll_officer) + officer3 = create(:poll_officer) + + booth_assignment = create(:poll_booth_assignment, poll: poll, booth: booth) + officer_assignment = create(:poll_officer_assignment, booth_assignment: booth_assignment, officer: officer1) + + booth_assignment_2 = create(:poll_booth_assignment, poll: poll) + officer_assignment_2 = create(:poll_officer_assignment, booth_assignment: booth_assignment_2, officer: officer2) + + visit admin_poll_path(poll) + + click_link 'Officers (2)' + + within('#officer_assignments') do + expect(page).to have_content officer1.name + expect(page).to have_content officer2.name + expect(page).not_to have_content officer3.name + end + end + + scenario "Search", :js do + poll = create(:poll) + booth = create(:poll_booth) + + user1 = create(:user, username: "John Snow") + user2 = create(:user, username: "John Silver") + user3 = create(:user, username: "John Edwards") + + officer1 = create(:poll_officer, user: user1) + officer2 = create(:poll_officer, user: user2) + officer3 = create(:poll_officer, user: user3) + + booth_assignment = create(:poll_booth_assignment, poll: poll, booth: booth) + officer_assignment = create(:poll_officer_assignment, booth_assignment: booth_assignment, officer: officer1) + + booth_assignment_2 = create(:poll_booth_assignment, poll: poll) + officer_assignment_2 = create(:poll_officer_assignment, booth_assignment: booth_assignment_2, officer: officer2) + + visit admin_poll_path(poll) + + click_link 'Officers (2)' + + fill_in "search-officers", with: "John" + click_button "Search" + + within('#search-officers-results') do + expect(page).to have_content officer1.name + expect(page).to have_content officer2.name + expect(page).not_to have_content officer3.name + end + end + +end \ No newline at end of file diff --git a/spec/features/admin/poll/officers_spec.rb b/spec/features/admin/poll/officers_spec.rb index d9ea89638..cfa0ff1ae 100644 --- a/spec/features/admin/poll/officers_spec.rb +++ b/spec/features/admin/poll/officers_spec.rb @@ -13,7 +13,7 @@ feature 'Admin poll officers' do scenario 'Index' do expect(page).to have_content @officer.name expect(page).to have_content @officer.email - expect(page).to_not have_content @user.name + expect(page).not_to have_content @user.name end scenario 'Create', :js do @@ -30,7 +30,7 @@ feature 'Admin poll officers' do scenario 'Delete' do click_link 'Delete position' - expect(page).to_not have_css '#officers' + expect(page).not_to have_css '#officers' end end \ No newline at end of file diff --git a/spec/features/admin/poll/polls_spec.rb b/spec/features/admin/poll/polls_spec.rb index 6eb64f6e1..482d461cc 100644 --- a/spec/features/admin/poll/polls_spec.rb +++ b/spec/features/admin/poll/polls_spec.rb @@ -36,7 +36,7 @@ feature 'Admin polls' do expect(page).to have_content poll.name end end - expect(page).to_not have_content "There are no polls" + expect(page).not_to have_content "There are no polls" end scenario 'Show' do @@ -58,6 +58,12 @@ feature 'Admin polls' do fill_in "poll_name", with: "Upcoming poll" fill_in 'poll_starts_at', with: start_date.strftime("%d/%m/%Y") fill_in 'poll_ends_at', with: end_date.strftime("%d/%m/%Y") + fill_in 'poll_summary', with: "Upcoming poll's summary. This poll..." + fill_in 'poll_description', with: "Upcomming poll's description. This poll..." + + expect(page).not_to have_css("#poll_results_enabled") + expect(page).not_to have_css("#poll_stats_enabled") + click_button "Create poll" expect(page).to have_content "Poll created successfully" @@ -68,19 +74,34 @@ feature 'Admin polls' do scenario "Edit" do poll = create(:poll) + create(:image, imageable: poll) visit admin_poll_path(poll) - click_link "Edit" + click_link "Edit poll" end_date = 1.year.from_now + expect(page).to have_css("img[alt='#{poll.image.title}']") + + expect(page).to have_css("#poll_results_enabled") + expect(page).to have_css("#poll_stats_enabled") + fill_in "poll_name", with: "Next Poll" fill_in 'poll_ends_at', with: end_date.strftime("%d/%m/%Y") + check 'poll_results_enabled' + check 'poll_stats_enabled' + click_button "Update poll" expect(page).to have_content "Poll updated successfully" expect(page).to have_content "Next Poll" expect(page).to have_content I18n.l(end_date.to_date) + + click_link "Edit poll" + + expect(page).to have_field('poll_results_enabled', checked: true) + expect(page).to have_field('poll_stats_enabled', checked: true) + end scenario 'Edit from index' do @@ -91,7 +112,7 @@ feature 'Admin polls' do click_link "Edit" end - expect(current_path).to eq(edit_admin_poll_path(poll)) + expect(page).to have_current_path(edit_admin_poll_path(poll)) end context "Booths" do @@ -121,7 +142,7 @@ feature 'Admin polls' do expect(page).to have_content ba.booth.location end end - expect(page).to_not have_content "There are no booths assigned to this poll." + expect(page).not_to have_content "There are no booths assigned to this poll." end end end @@ -159,7 +180,7 @@ feature 'Admin polls' do expect(page).to have_content officer.email end end - expect(page).to_not have_content "There are no officers assigned to this poll" + expect(page).not_to have_content "There are no officers assigned to this poll" end end end @@ -177,56 +198,8 @@ feature 'Admin polls' do expect(page).to have_content "Questions (1)" expect(page).to have_content question.title - expect(page).to_not have_content other_question.title - expect(page).to_not have_content "There are no questions assigned to this poll" - end - - scenario 'Add question to poll', :js do - poll = create(:poll) - question = create(:poll_question, title: 'Should we rebuild the city?') - - visit admin_poll_path(poll) - - expect(page).to have_content 'Questions (0)' - expect(page).to have_content 'There are no questions assigned to this poll' - - fill_in 'search-questions', with: 'rebuild' - click_button 'Search' - - within('#search-questions-results') do - click_link 'Include question' - end - - expect(page).to have_content 'Question added to this poll' - - visit admin_poll_path(poll) - - expect(page).to have_content 'Questions (1)' - expect(page).to_not have_content 'There are no questions assigned to this poll' - expect(page).to have_content question.title - end - - scenario 'Remove question from poll', :js do - poll = create(:poll) - question = create(:poll_question, poll: poll) - - visit admin_poll_path(poll) - - expect(page).to have_content 'Questions (1)' - expect(page).to_not have_content 'There are no questions assigned to this poll' - expect(page).to have_content question.title - - within("#poll_question_#{question.id}") do - click_link 'Remove question from poll' - end - - expect(page).to have_content 'Question removed from this poll' - - visit admin_poll_path(poll) - - expect(page).to have_content 'Questions (0)' - expect(page).to have_content 'There are no questions assigned to this poll' - expect(page).to_not have_content question.title + expect(page).not_to have_content other_question.title + expect(page).not_to have_content "There are no questions assigned to this poll" end end @@ -249,18 +222,18 @@ feature 'Admin polls' do booth_assignment_final_recounted = create(:poll_booth_assignment, poll: poll) 3.times do |i| - create(:poll_total_result, + create(:poll_recount, booth_assignment: booth_assignment, date: poll.starts_at + i.days, - amount: 21) + total_amount: 21) end 2.times { create(:poll_voter, booth_assignment: booth_assignment_final_recounted) } - create(:poll_total_result, + create(:poll_recount, booth_assignment: booth_assignment_final_recounted, date: poll.ends_at, - amount: 55555) + total_amount: 55555) visit admin_poll_path(poll) @@ -303,8 +276,13 @@ feature 'Admin polls' do booth_assignment_2 = create(:poll_booth_assignment, poll: poll) booth_assignment_3 = create(:poll_booth_assignment, poll: poll) - question_1 = create(:poll_question, poll: poll, valid_answers: "Yes,No") - question_2 = create(:poll_question, poll: poll, valid_answers: "Today,Tomorrow") + question_1 = create(:poll_question, poll: poll) + create(:poll_question_answer, title: 'Yes', question: question_1) + create(:poll_question_answer, title: 'No', question: question_1) + + question_2 = create(:poll_question, poll: poll) + create(:poll_question_answer, title: 'Today', question: question_2) + create(:poll_question_answer, title: 'Tomorrow', question: question_2) [booth_assignment_1, booth_assignment_2, booth_assignment_3].each do |ba| create(:poll_partial_result, @@ -318,35 +296,72 @@ feature 'Admin polls' do answer: 'Tomorrow', amount: 5) end - create(:poll_white_result, + create(:poll_recount, booth_assignment: booth_assignment_1, - amount: 21) - create(:poll_null_result, - booth_assignment: booth_assignment_3, - amount: 44) + white_amount: 21, + null_amount: 44, + total_amount: 66) visit admin_poll_path(poll) click_link "Results" expect(page).to have_content(question_1.title) - question_1.valid_answers.each_with_index do |answer, i| + question_1.question_answers.each_with_index do |answer, i| within("#question_#{question_1.id}_#{i}_result") do - expect(page).to have_content(answer) + expect(page).to have_content(answer.title) expect(page).to have_content([33, 0][i]) end end expect(page).to have_content(question_2.title) - question_2.valid_answers.each_with_index do |answer, i| + question_2.question_answers.each_with_index do |answer, i| within("#question_#{question_2.id}_#{i}_result") do - expect(page).to have_content(answer) + expect(page).to have_content(answer.title) expect(page).to have_content([0, 15][i]) end end within('#white_results') { expect(page).to have_content('21') } within('#null_results') { expect(page).to have_content('44') } + within('#total_results') { expect(page).to have_content('66') } + end + + scenario "Link to results by booth" do + poll = create(:poll) + booth_assignment1 = create(:poll_booth_assignment, poll: poll) + booth_assignment2 = create(:poll_booth_assignment, poll: poll) + + question = create(:poll_question, poll: poll) + create(:poll_question_answer, title: 'Yes', question: question) + create(:poll_question_answer, title: 'No', question: question) + + create(:poll_partial_result, + booth_assignment: booth_assignment1, + question: question, + answer: 'Yes', + amount: 5) + + create(:poll_partial_result, + booth_assignment: booth_assignment2, + question: question, + answer: 'Yes', + amount: 6) + + visit admin_poll_path(poll) + + click_link "Results" + + expect(page).to have_link("See results", count: 2) + + within("#booth_assignment_#{booth_assignment1.id}_result") do + click_link "See results" + end + + expect(page).to have_content booth_assignment1.booth.name + expect(page).to have_content "Results" + expect(page).to have_content "Yes" + expect(page).to have_content "5" end end end diff --git a/spec/features/admin/poll/questions/answers/answers_spec.rb b/spec/features/admin/poll/questions/answers/answers_spec.rb new file mode 100644 index 000000000..288f514a4 --- /dev/null +++ b/spec/features/admin/poll/questions/answers/answers_spec.rb @@ -0,0 +1,71 @@ +require 'rails_helper' + +feature 'Answers' do + + background do + admin = create(:administrator) + login_as admin.user + end + + scenario 'Create' do + question = create(:poll_question) + title = 'Whatever the question may be, the answer is always 42' + description = "The Hitchhiker's Guide To The Universe" + + visit admin_question_path(question) + click_link 'Add answer' + + fill_in 'poll_question_answer_title', with: title + fill_in 'poll_question_answer_description', with: description + + click_button 'Save' + + expect(page).to have_content(title) + expect(page).to have_content(description) + end + + scenario 'Create second answer and place after the first one' do + question = create(:poll_question) + answer = create(:poll_question_answer, title: 'First', question: question, given_order: 1) + title = 'Second' + description = "Description" + + visit admin_question_path(question) + click_link 'Add answer' + + fill_in 'poll_question_answer_title', with: title + fill_in 'poll_question_answer_description', with: description + + click_button 'Save' + + expect(page.body.index('First')).to be < page.body.index('Second') + end + + scenario 'Update' do + question = create(:poll_question) + answer = create(:poll_question_answer, question: question, title: "Answer title", given_order: 2) + answer2 = create(:poll_question_answer, question: question, title: "Another title", given_order: 1) + + visit admin_answer_path(answer) + + click_link 'Edit answer' + + old_title = answer.title + new_title = 'Ex Machina' + + fill_in 'poll_question_answer_title', with: new_title + + click_button 'Save' + + expect(page).to have_content('Changes saved') + expect(page).to have_content(new_title) + + visit admin_question_path(question) + + expect(page).to have_content(new_title) + expect(page).not_to have_content(old_title) + + expect(page.body.index(new_title)).to be < page.body.index(answer2.title) + end + +end diff --git a/spec/features/admin/poll/questions/answers/images/images_spec.rb b/spec/features/admin/poll/questions/answers/images/images_spec.rb new file mode 100644 index 000000000..915c8d6b0 --- /dev/null +++ b/spec/features/admin/poll/questions/answers/images/images_spec.rb @@ -0,0 +1,14 @@ +require 'rails_helper' + +feature 'Images' do + + background do + admin = create(:administrator) + login_as(admin.user) + end + + pending "Index" + pending "Create" + pending "Destroy" + +end \ No newline at end of file diff --git a/spec/features/admin/poll/questions/answers/videos/videos_spec.rb b/spec/features/admin/poll/questions/answers/videos/videos_spec.rb new file mode 100644 index 000000000..35d07f454 --- /dev/null +++ b/spec/features/admin/poll/questions/answers/videos/videos_spec.rb @@ -0,0 +1,33 @@ +require 'rails_helper' + +feature 'Videos' do + + background do + admin = create(:administrator) + login_as(admin.user) + end + + scenario "Create" do + question = create(:poll_question) + answer = create(:poll_question_answer, question: question) + video_title = "'Magical' by Junko Ohashi" + video_url = "https://www.youtube.com/watch?v=-JMf43st-1A" + + visit admin_question_path(question) + + within("#poll_question_answer_#{answer.id}") do + click_link "Video list" + end + + click_link "Add video" + + fill_in 'poll_question_answer_video_title', with: video_title + fill_in 'poll_question_answer_video_url', with: video_url + + click_button "Save" + + expect(page).to have_content(video_title) + expect(page).to have_content(video_url) + end + +end diff --git a/spec/features/admin/poll/questions_spec.rb b/spec/features/admin/poll/questions_spec.rb index 392b2aabf..8b251a440 100644 --- a/spec/features/admin/poll/questions_spec.rb +++ b/spec/features/admin/poll/questions_spec.rb @@ -24,9 +24,7 @@ feature 'Admin poll questions' do visit admin_question_path(question) expect(page).to have_content(question.title) - expect(page).to have_content(question.description) expect(page).to have_content(question.author.name) - expect(page).to have_content(question.valid_answers.join(" ")) end scenario 'Create' do @@ -45,13 +43,11 @@ feature 'Admin poll questions' do select 'Movies', from: 'poll_question_poll_id' fill_in 'poll_question_title', with: title - fill_in 'poll_question_description', with: description fill_in 'poll_question_video_url', with: video_url click_button 'Save' expect(page).to have_content(title) - expect(page).to have_content(description) expect(page).to have_content(video_url) end @@ -62,17 +58,14 @@ feature 'Admin poll questions' do visit proposals_path click_link "Create question" - expect(current_path).to eq(new_admin_question_path) + expect(page).to have_current_path(new_admin_question_path, only_path: true) expect(page).to have_field('poll_question_title', with: proposal.title) - expect(page).to have_field('poll_question_description', with: proposal.description) - expect(page).to have_field('poll_question_valid_answers', with: "Yes, No") select 'Proposals', from: 'poll_question_poll_id' click_button 'Save' expect(page).to have_content(proposal.title) - expect(page).to have_content(proposal.description) expect(page).to have_link(proposal.title, href: proposal_path(proposal)) expect(page).to have_link(proposal.author.name, href: user_path(proposal.author)) end @@ -99,7 +92,7 @@ feature 'Admin poll questions' do visit admin_questions_path expect(page).to have_content(new_title) - expect(page).to_not have_content(old_title) + expect(page).not_to have_content(old_title) end scenario 'Destroy' do @@ -112,7 +105,7 @@ feature 'Admin poll questions' do click_link "Delete" end - expect(page).to_not have_content(question1.title) + expect(page).not_to have_content(question1.title) expect(page).to have_content(question2.title) end diff --git a/spec/features/admin/poll/shifts_spec.rb b/spec/features/admin/poll/shifts_spec.rb index 1e5bb6328..bddd1b6b1 100644 --- a/spec/features/admin/poll/shifts_spec.rb +++ b/spec/features/admin/poll/shifts_spec.rb @@ -30,12 +30,18 @@ feature 'Admin shifts' do expect(page).to have_content officer.name end - scenario "Create", :js do - poll = create(:poll) + scenario "Create Vote Collection Shift and Recount & Scrutiny Shift on same date", :js do + create(:poll) + create(:poll, :incoming) + poll = create(:poll, :current) booth = create(:poll_booth) + create(:poll_booth_assignment, poll: poll, booth: booth) + create(:poll_booth_assignment, poll: create(:poll, :expired), booth: booth) officer = create(:poll_officer) + vote_collection_dates = (Date.current..poll.ends_at.to_date).to_a.map { |date| I18n.l(date, format: :long) } + recount_scrutiny_dates = (poll.ends_at.to_date..poll.ends_at.to_date + 1.week).to_a.map { |date| I18n.l(date, format: :long) } - visit admin_booths_path + visit available_admin_booths_path within("#booth_#{booth.id}") do click_link "Manage shifts" @@ -45,24 +51,85 @@ feature 'Admin shifts' do click_button "Search" click_link "Edit shifts" - select I18n.l(poll.starts_at.to_date, format: :long), from: 'shift_date' + expect(page).to have_select('shift_date_vote_collection_date', options: ["Select day", *vote_collection_dates]) + expect(page).not_to have_select('shift_date_recount_scrutiny_date') + select I18n.l(Date.current, format: :long), from: 'shift_date_vote_collection_date' click_button "Add shift" expect(page).to have_content "Shift added" within("#shifts") do expect(page).to have_css(".shift", count: 1) - expect(page).to have_content(I18n.l(poll.starts_at.to_date, format: :long)) + expect(page).to have_content(I18n.l(Date.current, format: :long)) + expect(page).to have_content("Collect Votes") + expect(page).to have_content(officer.name) + end + + visit available_admin_booths_path + + within("#booth_#{booth.id}") do + click_link "Manage shifts" + end + + fill_in "search", with: officer.email + click_button "Search" + click_link "Edit shifts" + + select "Recount & Scrutiny", from: 'shift_task' + + expect(page).to have_select('shift_date_recount_scrutiny_date', options: ["Select day", *recount_scrutiny_dates]) + expect(page).not_to have_select('shift_date_vote_collection_date') + select I18n.l(poll.ends_at.to_date + 4.days, format: :long), from: 'shift_date_recount_scrutiny_date' + click_button "Add shift" + + expect(page).to have_content "Shift added" + + within("#shifts") do + expect(page).to have_css(".shift", count: 2) + expect(page).to have_content(I18n.l(poll.ends_at.to_date + 4.days, format: :long)) + expect(page).to have_content("Recount & Scrutiny") expect(page).to have_content(officer.name) end end - scenario "Erros on create", :js do - poll = create(:poll) + scenario "Vote Collection Shift and Recount & Scrutiny Shift don't include already assigned dates to officer", :js do + poll = create(:poll, :current) booth = create(:poll_booth) + assignment = create(:poll_booth_assignment, poll: poll, booth: booth) officer = create(:poll_officer) - visit admin_booths_path + shift1 = create(:poll_shift, :vote_collection_task, officer: officer, booth: booth, date: Time.zone.today) + shift2 = create(:poll_shift, :recount_scrutiny_task, officer: officer, booth: booth, date: Time.zone.tomorrow) + + vote_collection_dates = (Date.current..poll.ends_at.to_date).to_a + .reject { |date| date == Time.zone.today } + .map { |date| I18n.l(date, format: :long) } + recount_scrutiny_dates = (poll.ends_at.to_date..poll.ends_at.to_date + 1.week).to_a + .reject { |date| date == Time.zone.tomorrow } + .map { |date| I18n.l(date, format: :long) } + + visit available_admin_booths_path + + within("#booth_#{booth.id}") do + click_link "Manage shifts" + end + + fill_in "search", with: officer.email + click_button "Search" + click_link "Edit shifts" + + expect(page).to have_select('shift_date_vote_collection_date', options: ["Select day", *vote_collection_dates]) + select "Recount & Scrutiny", from: 'shift_task' + expect(page).to have_select('shift_date_recount_scrutiny_date', options: ["Select day", *recount_scrutiny_dates]) + end + + scenario "Error on create", :js do + poll = create(:poll, :current) + booth = create(:poll_booth) + assignment = create(:poll_booth_assignment, poll: poll, booth: booth) + officer = create(:poll_officer) + + visit available_admin_booths_path within("#booth_#{booth.id}") do click_link "Manage shifts" @@ -73,17 +140,18 @@ feature 'Admin shifts' do click_link "Edit shifts" click_button "Add shift" - expect(page).to have_content "can't be blank" + expect(page).to have_content "A date must be selected" end scenario "Destroy" do - poll = create(:poll) + poll = create(:poll, :current) booth = create(:poll_booth) + assignment = create(:poll_booth_assignment, poll: poll, booth: booth) officer = create(:poll_officer) shift = create(:poll_shift, officer: officer, booth: booth) - visit admin_booths_path + visit available_admin_booths_path within("#booth_#{booth.id}") do click_link "Manage shifts" diff --git a/spec/features/admin/proposals_spec.rb b/spec/features/admin/proposals_spec.rb index be859c3e6..0c65aa899 100644 --- a/spec/features/admin/proposals_spec.rb +++ b/spec/features/admin/proposals_spec.rb @@ -7,6 +7,16 @@ feature 'Admin proposals' do login_as(admin.user) end + scenario 'Disabled with a feature flag' do + Setting['feature.proposals'] = nil + admin = create(:administrator) + login_as(admin.user) + + expect{ visit admin_proposals_path }.to raise_exception(FeatureFlags::FeatureDisabled) + + Setting['feature.proposals'] = true + end + scenario 'List shows all relevant info' do proposal = create(:proposal, :hidden) visit admin_proposals_path @@ -25,9 +35,9 @@ feature 'Admin proposals' do click_link 'Restore' - expect(page).to_not have_content(proposal.title) + expect(page).not_to have_content(proposal.title) - expect(proposal.reload).to_not be_hidden + expect(proposal.reload).not_to be_hidden expect(proposal).to be_ignored_flag end @@ -37,7 +47,7 @@ feature 'Admin proposals' do click_link 'Confirm' - expect(page).to_not have_content(proposal.title) + expect(page).not_to have_content(proposal.title) click_link('Confirmed') expect(page).to have_content(proposal.title) @@ -46,24 +56,24 @@ feature 'Admin proposals' do scenario "Current filter is properly highlighted" do visit admin_proposals_path - expect(page).to_not have_link('Pending') + expect(page).not_to have_link('Pending') expect(page).to have_link('All') expect(page).to have_link('Confirmed') visit admin_proposals_path(filter: 'Pending') - expect(page).to_not have_link('Pending') + expect(page).not_to have_link('Pending') expect(page).to have_link('All') expect(page).to have_link('Confirmed') visit admin_proposals_path(filter: 'all') expect(page).to have_link('Pending') - expect(page).to_not have_link('All') + expect(page).not_to have_link('All') expect(page).to have_link('Confirmed') visit admin_proposals_path(filter: 'with_confirmed_hide') expect(page).to have_link('All') expect(page).to have_link('Pending') - expect(page).to_not have_link('Confirmed') + expect(page).not_to have_link('Confirmed') end scenario "Filtering proposals" do @@ -72,14 +82,14 @@ feature 'Admin proposals' do visit admin_proposals_path(filter: 'pending') expect(page).to have_content('Unconfirmed proposal') - expect(page).to_not have_content('Confirmed proposal') + expect(page).not_to have_content('Confirmed proposal') visit admin_proposals_path(filter: 'all') expect(page).to have_content('Unconfirmed proposal') expect(page).to have_content('Confirmed proposal') visit admin_proposals_path(filter: 'with_confirmed_hide') - expect(page).to_not have_content('Unconfirmed proposal') + expect(page).not_to have_content('Unconfirmed proposal') expect(page).to have_content('Confirmed proposal') end diff --git a/spec/features/admin/settings_spec.rb b/spec/features/admin/settings_spec.rb index c92b4b525..40baf6423 100644 --- a/spec/features/admin/settings_spec.rb +++ b/spec/features/admin/settings_spec.rb @@ -28,4 +28,65 @@ feature 'Admin settings' do expect(page).to have_content 'Value updated' end -end \ No newline at end of file + describe "Update map" do + + scenario "Should not be able when map feature deactivated" do + Setting['feature.map'] = false + admin = create(:administrator).user + login_as(admin) + visit admin_settings_path + + expect(page).not_to have_content "Map configuration" + end + + scenario "Should be able when map feature activated" do + Setting['feature.map'] = true + admin = create(:administrator).user + login_as(admin) + visit admin_settings_path + + expect(page).to have_content "Map configuration" + end + + scenario "Should show successful notice" do + Setting['feature.map'] = true + admin = create(:administrator).user + login_as(admin) + visit admin_settings_path + + within "#map-form" do + click_on "Update" + end + + expect(page).to have_content "Map configuration updated succesfully" + end + + scenario "Should display marker by default", :js do + Setting['feature.map'] = true + admin = create(:administrator).user + login_as(admin) + + visit admin_settings_path + + expect(find("#latitude", visible: false).value).to eq "51.48" + expect(find("#longitude", visible: false).value).to eq "0.0" + end + + scenario "Should update marker", :js do + Setting['feature.map'] = true + admin = create(:administrator).user + login_as(admin) + + visit admin_settings_path + find("#admin-map").click + within "#map-form" do + click_on "Update" + end + + expect(find("#latitude", visible: false).value).not_to eq "51.48" + expect(page).to have_content "Map configuration updated succesfully" + end + + end + +end diff --git a/spec/features/admin/site_customization/content_blocks_spec.rb b/spec/features/admin/site_customization/content_blocks_spec.rb index de2155737..eb6098ed4 100644 --- a/spec/features/admin/site_customization/content_blocks_spec.rb +++ b/spec/features/admin/site_customization/content_blocks_spec.rb @@ -23,7 +23,7 @@ feature "Admin custom content blocks" do click_link "Custom content blocks" end - expect(page).to_not have_content "footer (es)" + expect(page).not_to have_content "footer (es)" click_link "Create new content block" @@ -90,8 +90,8 @@ feature "Admin custom content blocks" do click_button "Delete block" - expect(page).to_not have_content("#{block.name} (#{block.locale})") - expect(page).to_not have_content(block.body) + expect(page).not_to have_content("#{block.name} (#{block.locale})") + expect(page).not_to have_content(block.body) end scenario "From edit page" do @@ -100,8 +100,8 @@ feature "Admin custom content blocks" do click_button "Delete block" - expect(page).to_not have_content("#{block.name} (#{block.locale})") - expect(page).to_not have_content(block.body) + expect(page).not_to have_content("#{block.name} (#{block.locale})") + expect(page).not_to have_content(block.body) end end end diff --git a/spec/features/admin/site_customization/images_spec.rb b/spec/features/admin/site_customization/images_spec.rb index 6d180fe8e..cd8c0c065 100644 --- a/spec/features/admin/site_customization/images_spec.rb +++ b/spec/features/admin/site_customization/images_spec.rb @@ -20,7 +20,7 @@ feature "Admin custom images" do end expect(page).to have_css("tr.logo_header img[src*='logo_header.png']") - expect(page).to have_css("img[src*='logo_header.png']", count: 2) # one in the admin form an one in the page header + expect(page).to have_css("img[src*='logo_header.png']", count: 1) end scenario "Upload invalid image" do @@ -57,6 +57,6 @@ feature "Admin custom images" do click_link "Delete" end - expect(page).to_not have_css("img[src*='social_media_icon.png']") + expect(page).not_to have_css("img[src*='social_media_icon.png']") end end diff --git a/spec/features/admin/site_customization/pages_spec.rb b/spec/features/admin/site_customization/pages_spec.rb index 1b09a8f01..d4873be9d 100644 --- a/spec/features/admin/site_customization/pages_spec.rb +++ b/spec/features/admin/site_customization/pages_spec.rb @@ -22,7 +22,7 @@ feature "Admin custom pages" do click_link "Custom Pages" end - expect(page).to_not have_content "An example custom page" + expect(page).not_to have_content "An example custom page" click_link "Create new page" @@ -65,6 +65,6 @@ feature "Admin custom pages" do click_button "Delete page" - expect(page).to_not have_content("An example custom page") + expect(page).not_to have_content("An example custom page") end end diff --git a/spec/features/admin/stats_spec.rb b/spec/features/admin/stats_spec.rb index c0aefe4e5..60dae016b 100644 --- a/spec/features/admin/stats_spec.rb +++ b/spec/features/admin/stats_spec.rb @@ -162,4 +162,99 @@ feature 'Stats' do end + context "Polls" do + + scenario "Total participants by origin" do + oa = create(:poll_officer_assignment) + 3.times { create(:poll_voter, origin: "web") } + + visit admin_stats_path + + within(".stats") do + click_link "Polls" + end + + within("#web_participants") do + expect(page).to have_content "3" + end + end + + scenario "Total participants" do + user = create(:user, :level_two) + 3.times { create(:poll_voter, user: user) } + create(:poll_voter) + + visit admin_stats_path + + within(".stats") do + click_link "Polls" + end + + within("#participants") do + expect(page).to have_content "2" + end + end + + scenario "Participants by poll" do + oa = create(:poll_officer_assignment) + + poll1 = create(:poll) + poll2 = create(:poll) + + 1.times { create(:poll_voter, poll: poll1, origin: "web") } + 2.times { create(:poll_voter, poll: poll2, origin: "web") } + + visit admin_stats_path + + within(".stats") do + click_link "Polls" + end + + within("#polls") do + + within("#poll_#{poll1.id}") do + expect(page).to have_content "1" + end + + within("#poll_#{poll2.id}") do + expect(page).to have_content "2" + end + + end + end + + scenario "Participants by poll question" do + user1 = create(:user, :level_two) + user2 = create(:user, :level_two) + + poll = create(:poll) + + question1 = create(:poll_question, :with_answers, poll: poll) + question2 = create(:poll_question, :with_answers, poll: poll) + + create(:poll_answer, question: question1, author: user1) + create(:poll_answer, question: question2, author: user1) + create(:poll_answer, question: question2, author: user2) + + visit admin_stats_path + + within(".stats") do + click_link "Polls" + end + + within("#poll_question_#{question1.id}") do + expect(page).to have_content "1" + end + + within("#poll_question_#{question2.id}") do + expect(page).to have_content "2" + end + + within("#poll_#{poll.id}_questions_total") do + expect(page).to have_content "2" + end + end + + end + end diff --git a/spec/features/admin/tags_spec.rb b/spec/features/admin/tags_spec.rb index dd9c38c6b..e22637675 100644 --- a/spec/features/admin/tags_spec.rb +++ b/spec/features/admin/tags_spec.rb @@ -19,11 +19,11 @@ feature 'Admin tags' do scenario 'Create' do visit admin_tags_path - expect(page).to_not have_content 'important issues' + expect(page).not_to have_content 'important issues' within("form.new_tag") do fill_in "tag_name", with: 'important issues' - click_button 'Create Topic' + click_button 'Create topic' end visit admin_tags_path @@ -39,13 +39,13 @@ feature 'Admin tags' do expect(page).to have_content @tag1.name expect(page).to have_content tag2.name - within("#edit_tag_#{tag2.id}") do - click_link 'Destroy Topic' + within("#tag_#{tag2.id}") do + click_link 'Destroy topic' end visit admin_tags_path expect(page).to have_content @tag1.name - expect(page).to_not have_content tag2.name + expect(page).not_to have_content tag2.name end scenario 'Delete tag with hidden taggables' do @@ -58,13 +58,13 @@ feature 'Admin tags' do expect(page).to have_content @tag1.name expect(page).to have_content tag2.name - within("#edit_tag_#{tag2.id}") do - click_link 'Destroy Topic' + within("#tag_#{tag2.id}") do + click_link 'Destroy topic' end visit admin_tags_path expect(page).to have_content @tag1.name - expect(page).to_not have_content tag2.name + expect(page).not_to have_content tag2.name end context "Manage only tags of kind category" do @@ -73,7 +73,7 @@ feature 'Admin tags' do visit admin_tags_path expect(page).to have_content @tag1.name - expect(page).to_not have_content "Not a category" + expect(page).not_to have_content "Not a category" end scenario "Create instanciates tags of correct kind" do @@ -81,7 +81,7 @@ feature 'Admin tags' do within("form.new_tag") do fill_in "tag_name", with: "wow_category" - click_button 'Create Topic' + click_button 'Create topic' end expect(ActsAsTaggableOn::Tag.category.where(name: "wow_category")).to exist diff --git a/spec/features/admin/users_spec.rb b/spec/features/admin/users_spec.rb index 4a62a75d0..98058701e 100644 --- a/spec/features/admin/users_spec.rb +++ b/spec/features/admin/users_spec.rb @@ -21,8 +21,8 @@ feature 'Admin users' do expect(page).to have_content @user.name expect(page).to have_content @user.email - expect(page).to_not have_content @admin.name - expect(page).to_not have_content @admin.email + expect(page).not_to have_content @admin.name + expect(page).not_to have_content @admin.email end end diff --git a/spec/features/admin/valuators_spec.rb b/spec/features/admin/valuators_spec.rb index d95432474..25ae57a12 100644 --- a/spec/features/admin/valuators_spec.rb +++ b/spec/features/admin/valuators_spec.rb @@ -2,32 +2,87 @@ require 'rails_helper' feature 'Admin valuators' do background do - @admin = create(:administrator) - @user = create(:user, username: 'Jose Luis Balbin') + @admin = create(:administrator) + @user = create(:user, username: 'Jose Luis Balbin') @valuator = create(:valuator) login_as(@admin.user) visit admin_valuators_path end scenario 'Index' do - expect(page).to have_content @valuator.name - expect(page).to have_content @valuator.email - expect(page).to_not have_content @user.name + expect(page).to have_content(@valuator.name) + expect(page).to have_content(@valuator.email) + expect(page).not_to have_content(@user.name) end scenario 'Create Valuator', :js do - fill_in 'email', with: @user.email + fill_in 'name_or_email', with: @user.email click_button 'Search' - expect(page).to have_content @user.name + expect(page).to have_content(@user.name) fill_in 'valuator_description', with: 'environmental expert' click_button 'Add to valuators' - within("#valuators") do - expect(page).to have_content @user.name - expect(page).to have_content 'environmental expert' + within('#valuators') do + expect(page).to have_content(@user.name) + expect(page).to have_content('environmental expert') + end + end + + scenario 'Delete Valuator' do + click_link 'Delete' + + within('#valuators') do + expect(page).not_to have_content(@valuator.name) + end + end + + context 'Search' do + + background do + user = create(:user, username: 'David Foster Wallace', email: 'david@wallace.com') + user2 = create(:user, username: 'Steven Erikson', email: 'steven@erikson.com') + @valuator1 = create(:valuator, user: user) + @valuator2 = create(:valuator, user: user2) + visit admin_valuators_path + end + + scenario 'returns no results if search term is empty' do + expect(page).to have_content(@valuator1.name) + expect(page).to have_content(@valuator2.name) + + fill_in 'name_or_email', with: ' ' + click_button 'Search' + + expect(page).to have_content('Valuators: User search') + expect(page).to have_content('No results found') + expect(page).not_to have_content(@valuator1.name) + expect(page).not_to have_content(@valuator2.name) + end + + scenario 'search by name' do + expect(page).to have_content(@valuator1.name) + expect(page).to have_content(@valuator2.name) + + fill_in 'name_or_email', with: 'Foster' + click_button 'Search' + + expect(page).to have_content('Valuators: User search') + expect(page).to have_content(@valuator1.name) + expect(page).not_to have_content(@valuator2.name) + end + + scenario 'search by email' do + expect(page).to have_content(@valuator1.email) + expect(page).to have_content(@valuator2.email) + + fill_in 'name_or_email', with: @valuator2.email + click_button 'Search' + + expect(page).to have_content('Valuators: User search') + expect(page).to have_content(@valuator2.email) + expect(page).not_to have_content(@valuator1.email) end end end - diff --git a/spec/features/admin/verifications_spec.rb b/spec/features/admin/verifications_spec.rb index ce455fe87..94218426d 100644 --- a/spec/features/admin/verifications_spec.rb +++ b/spec/features/admin/verifications_spec.rb @@ -17,8 +17,8 @@ feature 'Incomplete verifications' do expect(page).to have_content(incompletely_verified_user1.username) expect(page).to have_content(incompletely_verified_user2.username) - expect(page).to_not have_content(never_tried_to_verify_user.username) - expect(page).to_not have_content(verified_user.username) + expect(page).not_to have_content(never_tried_to_verify_user.username) + expect(page).not_to have_content(verified_user.username) end scenario 'Search' do @@ -32,8 +32,8 @@ feature 'Incomplete verifications' do click_button "Search" expect(page).to have_content("Juan_anonymous") - expect(page).to_not have_content("Juan Carlos") - expect(page).to_not have_content("Isabel_anonymous") + expect(page).not_to have_content("Juan Carlos") + expect(page).not_to have_content("Isabel_anonymous") end scenario "Residence unverified" do diff --git a/spec/features/admin_spec.rb b/spec/features/admin_spec.rb index 9ea2c2390..82130cda4 100644 --- a/spec/features/admin_spec.rb +++ b/spec/features/admin_spec.rb @@ -11,8 +11,8 @@ feature 'Admin' do login_as(user) visit admin_root_path - expect(current_path).not_to eq(admin_root_path) - expect(current_path).to eq(proposals_path) + expect(page).not_to have_current_path(admin_root_path) + expect(page).to have_current_path(root_path) expect(page).to have_content "You do not have permission to access this page" end @@ -21,8 +21,8 @@ feature 'Admin' do login_as(user) visit admin_root_path - expect(current_path).not_to eq(admin_root_path) - expect(current_path).to eq(proposals_path) + expect(page).not_to have_current_path(admin_root_path) + expect(page).to have_current_path(root_path) expect(page).to have_content "You do not have permission to access this page" end @@ -31,8 +31,8 @@ feature 'Admin' do login_as(user) visit admin_root_path - expect(current_path).not_to eq(admin_root_path) - expect(current_path).to eq(proposals_path) + expect(page).not_to have_current_path(admin_root_path) + expect(page).to have_current_path(root_path) expect(page).to have_content "You do not have permission to access this page" end @@ -41,8 +41,8 @@ feature 'Admin' do login_as(user) visit admin_root_path - expect(current_path).not_to eq(admin_root_path) - expect(current_path).to eq(proposals_path) + expect(page).not_to have_current_path(admin_root_path) + expect(page).to have_current_path(root_path) expect(page).to have_content "You do not have permission to access this page" end @@ -51,8 +51,8 @@ feature 'Admin' do login_as(user) visit admin_root_path - expect(current_path).not_to eq(admin_root_path) - expect(current_path).to eq(proposals_path) + expect(page).not_to have_current_path(admin_root_path) + expect(page).to have_current_path(root_path) expect(page).to have_content "You do not have permission to access this page" end @@ -60,8 +60,8 @@ feature 'Admin' do login_as(administrator) visit admin_root_path - expect(current_path).to eq(admin_root_path) - expect(page).to_not have_content "You do not have permission to access this page" + expect(page).to have_current_path(admin_root_path) + expect(page).not_to have_content "You do not have permission to access this page" end scenario "Admin access links" do @@ -84,10 +84,10 @@ feature 'Admin' do click_link 'Administration' - expect(current_path).to eq(admin_root_path) + expect(page).to have_current_path(admin_root_path) expect(page).to have_css('#admin_menu') - expect(page).to_not have_css('#moderation_menu') - expect(page).to_not have_css('#valuation_menu') + expect(page).not_to have_css('#moderation_menu') + expect(page).not_to have_css('#valuation_menu') end end diff --git a/spec/features/budgets/ballots_spec.rb b/spec/features/budgets/ballots_spec.rb index 35e74a9a6..8fd3cfcf0 100644 --- a/spec/features/budgets/ballots_spec.rb +++ b/spec/features/budgets/ballots_spec.rb @@ -156,8 +156,8 @@ feature 'Ballots' do expect(page).to have_css("#amount-available", text: "€1,000,000") within("#sidebar") do - expect(page).to_not have_content investment.title - expect(page).to_not have_content "€10,000" + expect(page).not_to have_content investment.title + expect(page).not_to have_content "€10,000" end end @@ -204,8 +204,8 @@ feature 'Ballots' do expect(page).to have_content investment2.title expect(page).to have_content "€20,000" - expect(page).to_not have_content investment1.title - expect(page).to_not have_content "€10,000" + expect(page).not_to have_content investment1.title + expect(page).not_to have_content "€10,000" end visit budget_path(budget) @@ -218,8 +218,8 @@ feature 'Ballots' do expect(page).to have_content investment1.title expect(page).to have_content "€10,000" - expect(page).to_not have_content investment2.title - expect(page).to_not have_content "€20,000" + expect(page).not_to have_content investment2.title + expect(page).not_to have_content "€20,000" end visit budget_path(budget) @@ -284,7 +284,7 @@ feature 'Ballots' do visit budget_path(budget) click_link "States" expect(page).to have_css("#budget_heading_#{new_york.id}.active") - expect(page).to_not have_css("#budget_heading_#{california.id}.active") + expect(page).not_to have_css("#budget_heading_#{california.id}.active") end scenario 'View another heading' do @@ -295,7 +295,7 @@ feature 'Ballots' do visit budget_investments_path(budget, heading_id: new_york.id) - expect(page).to_not have_css "#progressbar" + expect(page).not_to have_css "#progressbar" expect(page).to have_content "You have active votes in another heading:" expect(page).to have_link california.name, href: budget_investments_path(budget, heading_id: california.id) end @@ -310,7 +310,7 @@ feature 'Ballots' do click_link group.name # No need to click on the heading name expect(page).to have_content("Investment projects with scope: #{heading.name}") - expect(current_path).to eq(budget_investments_path(budget)) + expect(page).to have_current_path(budget_investments_path(budget), only_path: true) end scenario 'Displaying the correct group, heading, count & amount' do @@ -378,7 +378,7 @@ feature 'Ballots' do find(".remove-investment-project").trigger('click') end - expect(current_path).to eq(budget_ballot_path(budget)) + expect(page).to have_current_path(budget_ballot_path(budget)) expect(page).to have_content("You have voted 0 investments") end @@ -411,8 +411,8 @@ feature 'Ballots' do expect(page).to have_css("#amount-available", text: "€980,000") within("#sidebar") do - expect(page).to_not have_content investment1.title - expect(page).to_not have_content "€10,000" + expect(page).not_to have_content investment1.title + expect(page).not_to have_content "€10,000" expect(page).to have_content investment2.title expect(page).to have_content "€20,000" @@ -490,7 +490,7 @@ feature 'Ballots' do click_link states.name click_link new_york.name - expect(page).to_not have_css("#budget_investment_#{investment.id}") + expect(page).not_to have_css("#budget_investment_#{investment.id}") end scenario 'Investments with feasibility undecided are not shown' do @@ -502,8 +502,8 @@ feature 'Ballots' do click_link new_york.name within("#budget-investments") do - expect(page).to_not have_css("div.ballot") - expect(page).to_not have_css("#budget_investment_#{investment.id}") + expect(page).not_to have_css("div.ballot") + expect(page).not_to have_css("#budget_investment_#{investment.id}") end end @@ -550,7 +550,7 @@ feature 'Ballots' do within("#budget_investment_#{bi1.id}") do find("div.ballot").hover - expect(page).to_not have_content('You have already assigned the available budget') + expect(page).not_to have_content('You have already assigned the available budget') expect(page).to have_selector('.in-favor a', visible: true) end @@ -587,7 +587,7 @@ feature 'Ballots' do within("#budget_investment_#{bi2.id}") do find("div.ballot").hover - expect(page).to_not have_content('You have already assigned the available budget') + expect(page).not_to have_content('You have already assigned the available budget') expect(page).to have_selector('.in-favor a', visible: true) end end @@ -612,11 +612,11 @@ feature 'Ballots' do find('.remove-investment-project').trigger('click') end - expect(page).to_not have_css "#budget_investment_#{bi1.id}_sidebar" + expect(page).not_to have_css "#budget_investment_#{bi1.id}_sidebar" within("#budget_investment_#{bi2.id}") do find("div.ballot").hover - expect(page).to_not have_content('You have already assigned the available budget') + expect(page).not_to have_content('You have already assigned the available budget') expect(page).to have_selector('.in-favor a', visible: true) end end @@ -636,7 +636,7 @@ feature 'Ballots' do find('.add a').trigger('click') expect(page.status_code).to eq(200) - expect(page).to_not have_content "Remove" + expect(page).not_to have_content "Remove" expect(page).to have_selector('.participation-not-allowed', visible: false) find("div.ballot").hover expect(page).to have_selector('.participation-not-allowed', visible: true) @@ -653,7 +653,7 @@ feature 'Ballots' do visit budget_investments_path(budget, heading_id: california.id) within("#budget_investment_#{bi1.id}") do - expect(page).to_not have_css("div.ballot") + expect(page).not_to have_css("div.ballot") end end end diff --git a/spec/features/budgets/budgets_spec.rb b/spec/features/budgets/budgets_spec.rb index 81530a43d..ee537a854 100644 --- a/spec/features/budgets/budgets_spec.rb +++ b/spec/features/budgets/budgets_spec.rb @@ -2,6 +2,9 @@ require 'rails_helper' feature 'Budgets' do + let(:budget) { create(:budget) } + let(:level_two_user) { create(:user, :level_two) } + scenario 'Index' do budgets = create_list(:budget, 3) visit budgets_path @@ -11,7 +14,6 @@ feature 'Budgets' do context 'Show' do scenario "List all groups" do - budget = create(:budget) group1 = create(:budget_group, budget: budget) group2 = create(:budget_group, budget: budget) @@ -26,13 +28,13 @@ feature 'Budgets' do visit budget_path(budget) - expect(page).to_not have_link "See unfeasible investments" - expect(page).to_not have_link "See investments not selected for balloting phase" + expect(page).not_to have_link "See unfeasible investments" + expect(page).not_to have_link "See investments not selected for balloting phase" click_link group.name - expect(page).to_not have_link "See unfeasible investments" - expect(page).to_not have_link "See investments not selected for balloting phase" + expect(page).not_to have_link "See unfeasible investments" + expect(page).not_to have_link "See investments not selected for balloting phase" budget.update(phase: :balloting) @@ -61,9 +63,59 @@ feature 'Budgets' do end - context 'Accepting' do + context "In Drafting phase" do - let(:budget) { create(:budget) } + let(:admin) { create(:administrator).user } + + background do + logout + budget.update(phase: 'drafting') + end + + context "Listed" do + scenario "Not listed to guest users at the public budgets list" do + visit budgets_path + + expect(page).not_to have_content(budget.name) + end + + scenario "Not listed to logged users at the public budgets list" do + login_as(level_two_user) + visit budgets_path + + expect(page).not_to have_content(budget.name) + end + + scenario "Is listed to admins at the public budgets list" do + login_as(admin) + visit budgets_path + + expect(page).to have_content(budget.name) + end + end + + context "Shown" do + scenario "Not accesible to guest users" do + expect { visit budget_path(budget) }.to raise_error(ActionController::RoutingError) + end + + scenario "Not accesible to logged users" do + login_as(level_two_user) + + expect { visit budget_path(budget) }.to raise_error(ActionController::RoutingError) + end + + scenario "Is accesible to admin users" do + login_as(admin) + visit budget_path(budget) + + expect(page.status_code).to eq(200) + end + end + + end + + context 'Accepting' do background do budget.update(phase: 'accepting') @@ -72,8 +124,7 @@ feature 'Budgets' do context "Permissions" do scenario "Verified user" do - user = create(:user, :level_two) - login_as(user) + login_as(level_two_user) visit budget_path(budget) @@ -97,4 +148,4 @@ feature 'Budgets' do end end -end \ No newline at end of file +end diff --git a/spec/features/budgets/investments_spec.rb b/spec/features/budgets/investments_spec.rb index 820ebb520..d4c9a0176 100644 --- a/spec/features/budgets/investments_spec.rb +++ b/spec/features/budgets/investments_spec.rb @@ -1,13 +1,27 @@ require 'rails_helper' +require 'sessions_helper' feature 'Budget Investments' do + let(:author) { create(:user, :level_two, username: 'Isabel') } let(:budget) { create(:budget, name: "Big Budget") } let(:other_budget) { create(:budget, name: "What a Budget!") } let(:group) { create(:budget_group, name: "Health", budget: budget) } let!(:heading) { create(:budget_heading, name: "More hospitals", group: group) } + before do + Setting['feature.allow_images'] = true + end + + after do + Setting['feature.allow_images'] = nil + end + + context "Concerns" do + it_behaves_like 'notifiable in-app', Budget::Investment + end + scenario 'Index' do investments = [create(:budget_investment, heading: heading), create(:budget_investment, heading: heading), @@ -23,11 +37,26 @@ feature 'Budget Investments' do within('#budget-investments') do expect(page).to have_content investment.title expect(page).to have_css("a[href='#{budget_investment_path(budget_id: budget.id, id: investment.id)}']", text: investment.title) - expect(page).to_not have_content(unfeasible_investment.title) + expect(page).not_to have_content(unfeasible_investment.title) end end end + scenario 'Index should show investment descriptive image only when is defined' do + investment = create(:budget_investment, heading: heading) + investment_with_image = create(:budget_investment, heading: heading) + image = create(:image, imageable: investment_with_image) + + visit budget_investments_path(budget, heading_id: heading.id) + + within("#budget_investment_#{investment.id}") do + expect(page).not_to have_css("div.with-image") + end + within("#budget_investment_#{investment_with_image.id}") do + expect(page).to have_css("img[alt='#{investment_with_image.image.title}']") + end + end + context("Search") do scenario 'Search by text' do @@ -47,7 +76,7 @@ feature 'Budget Investments' do expect(page).to have_content(investment1.title) expect(page).to have_content(investment2.title) - expect(page).to_not have_content(investment3.title) + expect(page).not_to have_content(investment3.title) end end @@ -67,9 +96,9 @@ feature 'Budget Investments' do expect(page).to have_css('.budget-investment', count: 1) expect(page).to have_content(investment1.title) - expect(page).to_not have_content(investment2.title) - expect(page).to_not have_content(investment3.title) - expect(page).to_not have_content(investment4.title) + expect(page).not_to have_content(investment2.title) + expect(page).not_to have_content(investment3.title) + expect(page).not_to have_content(investment4.title) end end @@ -106,7 +135,7 @@ feature 'Budget Investments' do end context("Orders") do - before(:each) { budget.update(phase: 'selecting') } + before { budget.update(phase: 'selecting') } scenario "Default order is random" do per_page = Kaminari.config.default_per_page @@ -118,7 +147,7 @@ feature 'Budget Investments' do visit budget_investments_path(budget, heading_id: heading.id) new_order = eq(all(".budget-investment h3").collect {|i| i.text }) - expect(order).to_not eq(new_order) + expect(order).not_to eq(new_order) end scenario "Random order after another order" do @@ -134,7 +163,7 @@ feature 'Budget Investments' do visit budget_investments_path(budget, heading_id: heading.id) new_order = eq(all(".budget-investment h3").collect {|i| i.text }) - expect(order).to_not eq(new_order) + expect(order).not_to eq(new_order) end scenario 'Random order maintained with pagination', :js do @@ -155,28 +184,90 @@ feature 'Budget Investments' do expect(order).to eq(new_order) end + scenario "Investments are not repeated with random order", :js do + 12.times { create(:budget_investment, heading: heading) } + # 12 instead of per_page + 2 because in each page there are 10 (in this case), not 25 + + visit budget_investments_path(budget, order: 'random') + + first_page_investments = investments_order + + click_link 'Next' + expect(page).to have_content "You're on page 2" + + second_page_investments = investments_order + + common_values = first_page_investments & second_page_investments + + expect(common_values.length).to eq(0) + + end + scenario 'Proposals are ordered by confidence_score', :js do - create(:budget_investment, heading: heading, title: 'Best proposal').update_column(:confidence_score, 10) - create(:budget_investment, heading: heading, title: 'Worst proposal').update_column(:confidence_score, 2) - create(:budget_investment, heading: heading, title: 'Medium proposal').update_column(:confidence_score, 5) + best_proposal = create(:budget_investment, heading: heading, title: 'Best proposal') + best_proposal.update_column(:confidence_score, 10) + worst_proposal = create(:budget_investment, heading: heading, title: 'Worst proposal') + worst_proposal.update_column(:confidence_score, 2) + medium_proposal = create(:budget_investment, heading: heading, title: 'Medium proposal') + medium_proposal.update_column(:confidence_score, 5) visit budget_investments_path(budget, heading_id: heading.id) click_link 'highest rated' expect(page).to have_selector('a.active', text: 'highest rated') within '#budget-investments' do - expect('Best proposal').to appear_before('Medium proposal') - expect('Medium proposal').to appear_before('Worst proposal') + expect(best_proposal.title).to appear_before(medium_proposal.title) + expect(medium_proposal.title).to appear_before(worst_proposal.title) end expect(current_url).to include('order=confidence_score') expect(current_url).to include('page=1') end + scenario 'Each user as a different and consistent random budget investment order', :js do + (Kaminari.config.default_per_page * 1.3).to_i.times { create(:budget_investment, heading: heading) } + + in_browser(:one) do + visit budget_investments_path(budget, heading: heading) + @first_user_investments_order = investments_order + end + + in_browser(:two) do + visit budget_investments_path(budget, heading: heading) + @second_user_investments_order = investments_order + end + + expect(@first_user_investments_order).not_to eq(@second_user_investments_order) + + in_browser(:one) do + click_link 'Next' + expect(page).to have_content "You're on page 2" + + click_link 'Previous' + expect(page).to have_content "You're on page 1" + + expect(investments_order).to eq(@first_user_investments_order) + end + + in_browser(:two) do + click_link 'Next' + expect(page).to have_content "You're on page 2" + + click_link 'Previous' + expect(page).to have_content "You're on page 1" + + expect(investments_order).to eq(@second_user_investments_order) + end + end + + def investments_order + all(".budget-investment h3").collect {|i| i.text } + end + end context 'Phase I - Accepting' do - before(:each) { budget.update(phase: 'accepting') } + before { budget.update(phase: 'accepting') } scenario 'Create with invisible_captcha honeypot field' do login_as(author) @@ -192,7 +283,7 @@ feature 'Budget Investments' do expect(page.status_code).to eq(200) expect(page.html).to be_empty - expect(current_path).to eq(budget_investments_path(budget_id: budget.id)) + expect(page).to have_current_path(budget_investments_path(budget_id: budget.id)) end scenario 'Create budget investment too fast' do @@ -209,7 +300,7 @@ feature 'Budget Investments' do click_button 'Create Investment' expect(page).to have_content 'Sorry, that was too quick! Please resubmit' - expect(current_path).to eq(new_budget_investment_path(budget_id: budget.id)) + expect(page).to have_current_path(new_budget_investment_path(budget_id: budget.id)) end scenario 'Create' do @@ -220,7 +311,6 @@ feature 'Budget Investments' do select 'Health: More hospitals', from: 'budget_investment_heading_id' fill_in 'budget_investment_title', with: 'Build a skyscraper' fill_in 'budget_investment_description', with: 'I want to live in a high tower over the clouds' - fill_in 'budget_investment_external_url', with: 'http://http://skyscraperpage.com/' fill_in 'budget_investment_location', with: 'City center' fill_in 'budget_investment_organization_name', with: 'T.I.A.' fill_in 'budget_investment_tag_list', with: 'Towers' @@ -231,7 +321,6 @@ feature 'Budget Investments' do expect(page).to have_content 'Investment created successfully' expect(page).to have_content 'Build a skyscraper' expect(page).to have_content 'I want to live in a high tower over the clouds' - expect(page).to have_content 'http://http://skyscraperpage.com/' expect(page).to have_content 'City center' expect(page).to have_content 'T.I.A.' expect(page).to have_content 'Towers' @@ -264,7 +353,7 @@ feature 'Budget Investments' do fill_in "budget_investment_title", with: "search" within("div#js-suggest") do - expect(page).to have_content ("You are seeing 5 of 6 investments containing the term 'search'") + expect(page).to have_content "You are seeing 5 of 6 investments containing the term 'search'" end end @@ -279,7 +368,7 @@ feature 'Budget Investments' do fill_in "budget_investment_title", with: "item" within('div#js-suggest') do - expect(page).to_not have_content ('You are seeing') + expect(page).not_to have_content 'You are seeing' end end @@ -294,7 +383,7 @@ feature 'Budget Investments' do fill_in "budget_investment_title", with: "search" within('div#js-suggest') do - expect(page).to_not have_content ('You are seeing') + expect(page).not_to have_content 'You are seeing' end end end @@ -304,10 +393,10 @@ feature 'Budget Investments' do visit budget_investments_path(budget, heading_id: heading.id) - expect(page).to_not have_link('Check my ballot') - expect(page).to_not have_css('#progress_bar') + expect(page).not_to have_link('Check my ballot') + expect(page).not_to have_css('#progress_bar') within('#sidebar') do - expect(page).to_not have_content('My ballot') + expect(page).not_to have_content('My ballot') end end end @@ -383,9 +472,9 @@ feature 'Budget Investments' do budget.update(phase: "selecting") visit budget_investment_path(budget_id: budget.id, id: investment.id) - expect(page).to_not have_content("Unfeasibility explanation") - expect(page).to_not have_content("Price explanation") - expect(page).to_not have_content(investment.price_explanation) + expect(page).not_to have_content("Unfeasibility explanation") + expect(page).not_to have_content("Price explanation") + expect(page).not_to have_content(investment.price_explanation) end scenario "Budget in balloting phase" do @@ -418,8 +507,9 @@ feature 'Budget Investments' do scenario "Show milestones", :js do user = create(:user) investment = create(:budget_investment) - milestone = create(:budget_investment_milestone, investment: investment, title: "New text to show", - created_at: DateTime.new(2015, 9, 19).utc) + milestone = create(:budget_investment_milestone, investment: investment, title: "New text to show") + image = create(:image, imageable: milestone) + document = create(:document, documentable: milestone) login_as(user) visit budget_investment_path(budget_id: investment.budget.id, id: investment.id) @@ -427,9 +517,10 @@ feature 'Budget Investments' do find("#tab-milestones-label").trigger('click') within("#tab-milestones") do - expect(page).to have_content(milestone.title) expect(page).to have_content(milestone.description) - expect(page).to have_content("Published 2015-09-19") + expect(page).to have_content(Time.zone.today.to_date) + expect(page.find("#image_#{milestone.id}")['alt']).to have_content image.title + expect(page).to have_link document.title end end @@ -449,16 +540,35 @@ feature 'Budget Investments' do it_behaves_like "followable", "budget_investment", "budget_investment_path", { "budget_id": "budget_id", "id": "id" } - it_behaves_like "documentable", "budget_investment", "budget_investment_path", {"budget_id": "budget_id", "id": "id"} + it_behaves_like "imageable", "budget_investment", "budget_investment_path", { "budget_id": "budget_id", "id": "id" } - it_behaves_like "nested documentable", + it_behaves_like "nested imageable", "budget_investment", "new_budget_investment_path", { "budget_id": "budget_id" }, - "fill_new_valid_budget_investment", + "imageable_fill_new_valid_budget_investment", "Create Investment", "Budget Investment created successfully." + it_behaves_like "documentable", "budget_investment", "budget_investment_path", { "budget_id": "budget_id", "id": "id" } + + it_behaves_like "nested documentable", + "user", + "budget_investment", + "new_budget_investment_path", + { "budget_id": "budget_id" }, + "documentable_fill_new_valid_budget_investment", + "Create Investment", + "Budget Investment created successfully." + + it_behaves_like "mappable", + "budget_investment", + "investment", + "new_budget_investment_path", + "", + "budget_investment_path", + { "budget_id": "budget_id" } + context "Destroy" do scenario "Admin cannot destroy budget investments" do @@ -470,7 +580,7 @@ feature 'Budget Investments' do visit user_path(user) within("#budget_investment_#{investment.id}") do - expect(page).to_not have_link "Delete" + expect(page).not_to have_link "Delete" end end @@ -525,7 +635,7 @@ feature 'Budget Investments' do visit budget_investments_path(budget, heading_id: carabanchel.id) within("#budget_investment_#{carabanchel_investment.id}") do - expect(page).to_not have_css(".in-favor a[data-confirm]") + expect(page).not_to have_css(".in-favor a[data-confirm]") end end @@ -631,9 +741,11 @@ feature 'Budget Investments' do end scenario 'Order by cost (only when balloting)' do - create(:budget_investment, :selected, heading: heading, title: 'Build a nice house', price: 1000).update_column(:confidence_score, 10) - create(:budget_investment, :selected, heading: heading, title: 'Build an ugly house', price: 1000).update_column(:confidence_score, 5) - create(:budget_investment, :selected, heading: heading, title: 'Build a skyscraper', price: 20000) + mid_investment = create(:budget_investment, :selected, heading: heading, title: 'Build a nice house', price: 1000) + mid_investment.update_column(:confidence_score, 10) + low_investment = create(:budget_investment, :selected, heading: heading, title: 'Build an ugly house', price: 1000) + low_investment.update_column(:confidence_score, 5) + high_investment = create(:budget_investment, :selected, heading: heading, title: 'Build a skyscraper', price: 20000) visit budget_investments_path(budget, heading_id: heading.id) @@ -641,8 +753,8 @@ feature 'Budget Investments' do expect(page).to have_selector('a.active', text: 'by price') within '#budget-investments' do - expect('Build a skyscraper').to appear_before('Build a nice house') - expect('Build a nice house').to appear_before('Build an ugly house') + expect(high_investment.title).to appear_before(mid_investment.title) + expect(mid_investment.title).to appear_before(low_investment.title) end expect(current_url).to include('order=price') @@ -716,8 +828,8 @@ feature 'Budget Investments' do expect(page).to have_content sp2.title expect(page).to have_content sp2.price - expect(page).to_not have_content sp3.title - expect(page).to_not have_content sp3.price + expect(page).not_to have_content sp3.title + expect(page).not_to have_content sp3.price end within("#budget_group_#{group.id}") do @@ -727,8 +839,8 @@ feature 'Budget Investments' do expect(page).to have_content sp5.title expect(page).to have_content "€10,000" - expect(page).to_not have_content sp6.title - expect(page).to_not have_content "€100,000" + expect(page).not_to have_content sp6.title + expect(page).not_to have_content "€100,000" end end @@ -756,9 +868,9 @@ feature 'Budget Investments' do expect(page).to have_css('.budget-investment', count: 1) expect(page).to have_content(investment1.title) - expect(page).to_not have_content(investment2.title) - expect(page).to_not have_content(investment3.title) - expect(page).to_not have_content(investment4.title) + expect(page).not_to have_content(investment2.title) + expect(page).not_to have_content(investment3.title) + expect(page).not_to have_content(investment4.title) end end @@ -797,7 +909,7 @@ feature 'Budget Investments' do visit budget_investments_path(budget_id: budget.id, heading_id: heading.id, filter: "unselected") expect(page).to have_content investment.title - expect(page).to_not have_link("Vote") + expect(page).not_to have_link("Vote") end scenario "Do not display vote button for unselected investments in show" do @@ -806,7 +918,7 @@ feature 'Budget Investments' do visit budget_investment_path(budget, investment) expect(page).to have_content investment.title - expect(page).to_not have_link("Vote") + expect(page).not_to have_link("Vote") end feature "Reclassification" do diff --git a/spec/features/budgets/results_spec.rb b/spec/features/budgets/results_spec.rb index 62b74d321..5e194a393 100644 --- a/spec/features/budgets/results_spec.rb +++ b/spec/features/budgets/results_spec.rb @@ -11,7 +11,9 @@ feature 'Results' do let!(:investment3) { create(:budget_investment, :incompatible, heading: heading, price: 500, ballot_lines_count: 700) } let!(:investment4) { create(:budget_investment, :selected, heading: heading, price: 600, ballot_lines_count: 600) } - let!(:results) { Budget::Result.new(budget, heading).calculate_winners } + background do + Budget::Result.new(budget, heading).calculate_winners + end scenario "Diplays winner investments" do create(:budget_heading, group: group) @@ -58,12 +60,12 @@ feature 'Results' do within("#budget-investments-compatible") do expect(page).to have_content investment1.title - expect(page).to_not have_content other_investment.title + expect(page).not_to have_content other_investment.title end end scenario "If budget is in a phase different from finished results can't be accessed" do - budget.update phase: (Budget::PHASES - ["finished"]).sample + budget.update(phase: (Budget::PHASES - ['drafting', 'finished']).sample) visit budget_path(budget) expect(page).not_to have_link "See results" diff --git a/spec/features/budgets/votes_spec.rb b/spec/features/budgets/votes_spec.rb index 95f040bb3..b8ae564e8 100644 --- a/spec/features/budgets/votes_spec.rb +++ b/spec/features/budgets/votes_spec.rb @@ -30,11 +30,11 @@ feature 'Votes' do end within("#budget_investment_#{investment2.id}_votes") do - expect(page).to_not have_content "You have already supported this. Share it!" + expect(page).not_to have_content "You have already supported this. Share it!" end within("#budget_investment_#{investment3.id}_votes") do - expect(page).to_not have_content "You have already supported this. Share it!" + expect(page).not_to have_content "You have already supported this. Share it!" end end end @@ -70,7 +70,7 @@ feature 'Votes' do find('.in-favor a').click expect(page).to have_content "1 support" - expect(page).to_not have_selector ".in-favor a" + expect(page).not_to have_selector ".in-favor a" end end @@ -94,13 +94,13 @@ feature 'Votes' do visit budget_investments_path(budget, heading_id: heading.id) within("#budget_investment_#{investment.id}") do - expect(page).to_not have_css("budget_investment_#{investment.id}_votes") + expect(page).not_to have_css("budget_investment_#{investment.id}_votes") end visit budget_investment_path(budget, investment) within("#budget_investment_#{investment.id}") do - expect(page).to_not have_css("budget_investment_#{investment.id}_votes") + expect(page).not_to have_css("budget_investment_#{investment.id}_votes") end end end diff --git a/spec/features/campaigns_spec.rb b/spec/features/campaigns_spec.rb index 6dba2ff09..9a8935fc1 100644 --- a/spec/features/campaigns_spec.rb +++ b/spec/features/campaigns_spec.rb @@ -27,7 +27,7 @@ feature 'Email campaigns' do visit admin_stats_path expect(page).to have_content "#{@campaign1.name} (1)" - expect(page).to_not have_content (@campaign2.name).to_s + expect(page).not_to have_content @campaign2.name.to_s end end \ No newline at end of file diff --git a/spec/features/comments/budget_investments_spec.rb b/spec/features/comments/budget_investments_spec.rb index ae8fc935a..4afb1e680 100644 --- a/spec/features/comments/budget_investments_spec.rb +++ b/spec/features/comments/budget_investments_spec.rb @@ -51,7 +51,7 @@ feature 'Commenting Budget::Investments' do find("#comment_#{child_comment.id}_children_arrow").trigger('click') expect(page).to have_css('.comment', count: 2) - expect(page).to_not have_content grandchild_comment.body + expect(page).not_to have_content grandchild_comment.body find("#comment_#{child_comment.id}_children_arrow").trigger('click') @@ -61,8 +61,8 @@ feature 'Commenting Budget::Investments' do find("#comment_#{parent_comment.id}_children_arrow").trigger('click') expect(page).to have_css('.comment', count: 1) - expect(page).to_not have_content child_comment.body - expect(page).to_not have_content grandchild_comment.body + expect(page).not_to have_content child_comment.body + expect(page).not_to have_content grandchild_comment.body end scenario 'Comment order' do @@ -147,7 +147,7 @@ feature 'Commenting Budget::Investments' do within("ul.pagination") do expect(page).to have_content("1") expect(page).to have_content("2") - expect(page).to_not have_content("3") + expect(page).not_to have_content("3") click_link "Next", exact: false end @@ -161,8 +161,8 @@ feature 'Commenting Budget::Investments' do expect(page).to have_content 'You must Sign in or Sign up to leave a comment' within('#comments') do - expect(page).to_not have_content 'Write a comment' - expect(page).to_not have_content 'Reply' + expect(page).not_to have_content 'Write a comment' + expect(page).not_to have_content 'Reply' end end end @@ -211,7 +211,7 @@ feature 'Commenting Budget::Investments' do expect(page).to have_content 'It will be done next week.' end - expect(page).to_not have_selector("#js-comment-form-comment_#{comment.id}", visible: true) + expect(page).not_to have_selector("#js-comment-form-comment_#{comment.id}", visible: true) end scenario 'Errors on reply', :js do @@ -271,7 +271,7 @@ feature 'Commenting Budget::Investments' do expect(page).to have_css("#flag-expand-comment-#{comment.id}") end - expect(Flag.flagged?(user, comment)).to_not be + expect(Flag.flagged?(user, comment)).not_to be end scenario "Flagging turbolinks sanity check", :js do @@ -343,7 +343,7 @@ feature 'Commenting Budget::Investments' do expect(page).to have_css "img.moderator-avatar" end - expect(page).to_not have_selector("#js-comment-form-comment_#{comment.id}", visible: true) + expect(page).not_to have_selector("#js-comment-form-comment_#{comment.id}", visible: true) end scenario "can not comment as an administrator" do @@ -352,7 +352,7 @@ feature 'Commenting Budget::Investments' do login_as(moderator.user) visit budget_investment_path(investment.budget, investment) - expect(page).to_not have_content "Comment as administrator" + expect(page).not_to have_content "Comment as administrator" end end @@ -399,7 +399,7 @@ feature 'Commenting Budget::Investments' do expect(page).to have_css "img.admin-avatar" end - expect(page).to_not have_selector("#js-comment-form-comment_#{comment.id}", visible: true) + expect(page).not_to have_selector("#js-comment-form-comment_#{comment.id}", visible: true) end scenario "can not comment as a moderator" do @@ -408,7 +408,7 @@ feature 'Commenting Budget::Investments' do login_as(admin.user) visit budget_investment_path(investment.budget, investment) - expect(page).to_not have_content "Comment as moderator" + expect(page).not_to have_content "Comment as moderator" end end diff --git a/spec/features/comments/debates_spec.rb b/spec/features/comments/debates_spec.rb index 77cab01d9..22a719526 100644 --- a/spec/features/comments/debates_spec.rb +++ b/spec/features/comments/debates_spec.rb @@ -51,7 +51,7 @@ feature 'Commenting debates' do find("#comment_#{child_comment.id}_children_arrow").trigger('click') expect(page).to have_css('.comment', count: 2) - expect(page).to_not have_content grandchild_comment.body + expect(page).not_to have_content grandchild_comment.body find("#comment_#{child_comment.id}_children_arrow").trigger('click') @@ -61,8 +61,8 @@ feature 'Commenting debates' do find("#comment_#{parent_comment.id}_children_arrow").trigger('click') expect(page).to have_css('.comment', count: 1) - expect(page).to_not have_content child_comment.body - expect(page).to_not have_content grandchild_comment.body + expect(page).not_to have_content child_comment.body + expect(page).not_to have_content grandchild_comment.body end scenario 'Comment order' do @@ -147,7 +147,7 @@ feature 'Commenting debates' do within("ul.pagination") do expect(page).to have_content("1") expect(page).to have_content("2") - expect(page).to_not have_content("3") + expect(page).not_to have_content("3") click_link "Next", exact: false end @@ -161,8 +161,8 @@ feature 'Commenting debates' do expect(page).to have_content 'You must Sign in or Sign up to leave a comment' within('#comments') do - expect(page).to_not have_content 'Write a comment' - expect(page).to_not have_content 'Reply' + expect(page).not_to have_content 'Write a comment' + expect(page).not_to have_content 'Reply' end end end @@ -208,7 +208,7 @@ feature 'Commenting debates' do expect(page).to have_content 'It will be done next week.' end - expect(page).to_not have_selector("#js-comment-form-comment_#{comment.id}", visible: true) + expect(page).not_to have_selector("#js-comment-form-comment_#{comment.id}", visible: true) end scenario 'Errors on reply', :js do @@ -268,7 +268,7 @@ feature 'Commenting debates' do expect(page).to have_css("#flag-expand-comment-#{comment.id}") end - expect(Flag.flagged?(user, comment)).to_not be + expect(Flag.flagged?(user, comment)).not_to be end scenario "Flagging turbolinks sanity check", :js do @@ -307,7 +307,7 @@ feature 'Commenting debates' do # The button's text should now be "..." # This should be checked before the Ajax request is finished - expect(page).to_not have_button 'Publish comment' + expect(page).not_to have_button 'Publish comment' expect(page).to have_content('Testing submit button!') end @@ -355,7 +355,7 @@ feature 'Commenting debates' do expect(page).to have_css "img.moderator-avatar" end - expect(page).to_not have_selector("#js-comment-form-comment_#{comment.id}", visible: true) + expect(page).not_to have_selector("#js-comment-form-comment_#{comment.id}", visible: true) end scenario "can not comment as an administrator" do @@ -364,7 +364,7 @@ feature 'Commenting debates' do login_as(moderator.user) visit debate_path(debate) - expect(page).to_not have_content "Comment as administrator" + expect(page).not_to have_content "Comment as administrator" end end @@ -411,7 +411,7 @@ feature 'Commenting debates' do expect(page).to have_css "img.admin-avatar" end - expect(page).to_not have_selector("#js-comment-form-comment_#{comment.id}", visible: true) + expect(page).not_to have_selector("#js-comment-form-comment_#{comment.id}", visible: true) end scenario "can not comment as a moderator" do @@ -420,7 +420,7 @@ feature 'Commenting debates' do login_as(admin.user) visit debate_path(debate) - expect(page).to_not have_content "Comment as moderator" + expect(page).not_to have_content "Comment as moderator" end end @@ -501,7 +501,7 @@ feature 'Commenting debates' do find('.in_favor a').click within('.in_favor') do - expect(page).to_not have_content "2" + expect(page).not_to have_content "2" expect(page).to have_content "1" end diff --git a/spec/features/comments/legislation_annotations_spec.rb b/spec/features/comments/legislation_annotations_spec.rb index aad2b90b2..96161c377 100644 --- a/spec/features/comments/legislation_annotations_spec.rb +++ b/spec/features/comments/legislation_annotations_spec.rb @@ -58,7 +58,7 @@ feature 'Commenting legislation questions' do find("#comment_#{child_comment.id}_children_arrow").trigger('click') expect(page).to have_css('.comment', count: 2) - expect(page).to_not have_content grandchild_comment.body + expect(page).not_to have_content grandchild_comment.body find("#comment_#{child_comment.id}_children_arrow").trigger('click') @@ -68,8 +68,8 @@ feature 'Commenting legislation questions' do find("#comment_#{parent_comment.id}_children_arrow").trigger('click') expect(page).to have_css('.comment', count: 1) - expect(page).to_not have_content child_comment.body - expect(page).to_not have_content grandchild_comment.body + expect(page).not_to have_content child_comment.body + expect(page).not_to have_content grandchild_comment.body end scenario 'Comment order' do @@ -178,7 +178,7 @@ feature 'Commenting legislation questions' do within("ul.pagination") do expect(page).to have_content("1") expect(page).to have_content("2") - expect(page).to_not have_content("3") + expect(page).not_to have_content("3") click_link "Next", exact: false end @@ -194,8 +194,8 @@ feature 'Commenting legislation questions' do expect(page).to have_content 'You must Sign in or Sign up to leave a comment' within('#comments') do - expect(page).to_not have_content 'Write a comment' - expect(page).to_not have_content 'Reply' + expect(page).not_to have_content 'Write a comment' + expect(page).not_to have_content 'Reply' end end end @@ -248,7 +248,7 @@ feature 'Commenting legislation questions' do expect(page).to have_content 'It will be done next week.' end - expect(page).to_not have_selector("#js-comment-form-comment_#{comment.id}", visible: true) + expect(page).not_to have_selector("#js-comment-form-comment_#{comment.id}", visible: true) end scenario 'Errors on reply', :js do @@ -317,7 +317,7 @@ feature 'Commenting legislation questions' do expect(page).to have_css("#flag-expand-comment-#{comment.id}") end - expect(Flag.flagged?(user, comment)).to_not be + expect(Flag.flagged?(user, comment)).not_to be end scenario "Flagging turbolinks sanity check", :js do @@ -363,7 +363,7 @@ feature 'Commenting legislation questions' do # The button's text should now be "..." # This should be checked before the Ajax request is finished - expect(page).to_not have_button 'Publish comment' + expect(page).not_to have_button 'Publish comment' expect(page).to have_content('Testing submit button!') end @@ -416,7 +416,7 @@ feature 'Commenting legislation questions' do expect(page).to have_css "img.moderator-avatar" end - expect(page).to_not have_selector("#js-comment-form-comment_#{comment.id}", visible: true) + expect(page).not_to have_selector("#js-comment-form-comment_#{comment.id}", visible: true) end scenario "can not comment as an administrator" do @@ -427,7 +427,7 @@ feature 'Commenting legislation questions' do legislation_annotation.draft_version, legislation_annotation) - expect(page).to_not have_content "Comment as administrator" + expect(page).not_to have_content "Comment as administrator" end end @@ -479,7 +479,7 @@ feature 'Commenting legislation questions' do expect(page).to have_css "img.admin-avatar" end - expect(page).to_not have_selector("#js-comment-form-comment_#{comment.id}", visible: true) + expect(page).not_to have_selector("#js-comment-form-comment_#{comment.id}", visible: true) end scenario "can not comment as a moderator" do @@ -490,7 +490,7 @@ feature 'Commenting legislation questions' do legislation_annotation.draft_version, legislation_annotation) - expect(page).to_not have_content "Comment as moderator" + expect(page).not_to have_content "Comment as moderator" end end @@ -579,7 +579,7 @@ feature 'Commenting legislation questions' do find('.in_favor a').click within('.in_favor') do - expect(page).to_not have_content "2" + expect(page).not_to have_content "2" expect(page).to have_content "1" end diff --git a/spec/features/comments/legislation_questions_spec.rb b/spec/features/comments/legislation_questions_spec.rb index d21cefc4e..d0e341498 100644 --- a/spec/features/comments/legislation_questions_spec.rb +++ b/spec/features/comments/legislation_questions_spec.rb @@ -2,10 +2,15 @@ require 'rails_helper' include ActionView::Helpers::DateHelper feature 'Commenting legislation questions' do + let(:user) { create :user, :level_two } let(:process) { create :legislation_process, :in_debate_phase } let(:legislation_question) { create :legislation_question, process: process } + context "Concerns" do + it_behaves_like 'notifiable in-app', Legislation::Question + end + scenario 'Index' do 3.times { create(:comment, commentable: legislation_question) } @@ -53,7 +58,7 @@ feature 'Commenting legislation questions' do find("#comment_#{child_comment.id}_children_arrow").trigger('click') expect(page).to have_css('.comment', count: 2) - expect(page).to_not have_content grandchild_comment.body + expect(page).not_to have_content grandchild_comment.body find("#comment_#{child_comment.id}_children_arrow").trigger('click') @@ -63,8 +68,8 @@ feature 'Commenting legislation questions' do find("#comment_#{parent_comment.id}_children_arrow").trigger('click') expect(page).to have_css('.comment', count: 1) - expect(page).to_not have_content child_comment.body - expect(page).to_not have_content grandchild_comment.body + expect(page).not_to have_content child_comment.body + expect(page).not_to have_content grandchild_comment.body end scenario 'Comment order' do @@ -149,7 +154,7 @@ feature 'Commenting legislation questions' do within("ul.pagination") do expect(page).to have_content("1") expect(page).to have_content("2") - expect(page).to_not have_content("3") + expect(page).not_to have_content("3") click_link "Next", exact: false end @@ -163,8 +168,8 @@ feature 'Commenting legislation questions' do expect(page).to have_content 'You must Sign in or Sign up to leave a comment' within('#comments') do - expect(page).to_not have_content 'Write a comment' - expect(page).to_not have_content 'Reply' + expect(page).not_to have_content 'Write a comment' + expect(page).not_to have_content 'Reply' end end end @@ -228,7 +233,7 @@ feature 'Commenting legislation questions' do expect(page).to have_content 'It will be done next week.' end - expect(page).to_not have_selector("#js-comment-form-comment_#{comment.id}", visible: true) + expect(page).not_to have_selector("#js-comment-form-comment_#{comment.id}", visible: true) end scenario 'Errors on reply', :js do @@ -288,7 +293,7 @@ feature 'Commenting legislation questions' do expect(page).to have_css("#flag-expand-comment-#{comment.id}") end - expect(Flag.flagged?(user, comment)).to_not be + expect(Flag.flagged?(user, comment)).not_to be end scenario "Flagging turbolinks sanity check", :js do @@ -325,7 +330,7 @@ feature 'Commenting legislation questions' do # The button's text should now be "..." # This should be checked before the Ajax request is finished - expect(page).to_not have_button 'Publish answer' + expect(page).not_to have_button 'Publish answer' expect(page).to have_content('Testing submit button!') end @@ -373,7 +378,7 @@ feature 'Commenting legislation questions' do expect(page).to have_css "img.moderator-avatar" end - expect(page).to_not have_selector("#js-comment-form-comment_#{comment.id}", visible: true) + expect(page).not_to have_selector("#js-comment-form-comment_#{comment.id}", visible: true) end scenario "can not comment as an administrator" do @@ -382,7 +387,7 @@ feature 'Commenting legislation questions' do login_as(moderator.user) visit legislation_process_question_path(legislation_question.process, legislation_question) - expect(page).to_not have_content "Comment as administrator" + expect(page).not_to have_content "Comment as administrator" end end @@ -429,7 +434,7 @@ feature 'Commenting legislation questions' do expect(page).to have_css "img.admin-avatar" end - expect(page).to_not have_selector("#js-comment-form-comment_#{comment.id}", visible: true) + expect(page).not_to have_selector("#js-comment-form-comment_#{comment.id}", visible: true) end scenario "can not comment as a moderator" do @@ -438,7 +443,7 @@ feature 'Commenting legislation questions' do login_as(admin.user) visit legislation_process_question_path(legislation_question.process, legislation_question) - expect(page).to_not have_content "Comment as moderator" + expect(page).not_to have_content "Comment as moderator" end end @@ -519,7 +524,7 @@ feature 'Commenting legislation questions' do find('.in_favor a').click within('.in_favor') do - expect(page).to_not have_content "2" + expect(page).not_to have_content "2" expect(page).to have_content "1" end diff --git a/spec/features/comments/polls_spec.rb b/spec/features/comments/polls_spec.rb new file mode 100644 index 000000000..1a371e9cc --- /dev/null +++ b/spec/features/comments/polls_spec.rb @@ -0,0 +1,522 @@ +require 'rails_helper' +include ActionView::Helpers::DateHelper + +feature 'Commenting polls' do + let(:user) { create :user } + let(:poll) { create(:poll, author: create(:user)) } + + scenario 'Index' do + 3.times { create(:comment, commentable: poll) } + + visit poll_path(poll) + + expect(page).to have_css('.comment', count: 3) + + comment = Comment.last + within first('.comment') do + expect(page).to have_content comment.user.name + expect(page).to have_content I18n.l(comment.created_at, format: :datetime) + expect(page).to have_content comment.body + end + end + + scenario 'Show' do + skip "Feature not implemented yet, review soon" + + parent_comment = create(:comment, commentable: poll) + first_child = create(:comment, commentable: poll, parent: parent_comment) + second_child = create(:comment, commentable: poll, parent: parent_comment) + + visit comment_path(parent_comment) + + expect(page).to have_css(".comment", count: 3) + expect(page).to have_content parent_comment.body + expect(page).to have_content first_child.body + expect(page).to have_content second_child.body + expect(page).to have_link "Go back to #{poll.name}", href: poll_path(poll) + + expect(page).to have_selector("ul#comment_#{parent_comment.id}>li", count: 2) + expect(page).to have_selector("ul#comment_#{first_child.id}>li", count: 1) + expect(page).to have_selector("ul#comment_#{second_child.id}>li", count: 1) + end + + scenario 'Collapsable comments', :js do + parent_comment = create(:comment, body: "Main comment", commentable: poll) + child_comment = create(:comment, body: "First subcomment", commentable: poll, parent: parent_comment) + grandchild_comment = create(:comment, body: "Last subcomment", commentable: poll, parent: child_comment) + + visit poll_path(poll) + + expect(page).to have_css('.comment', count: 3) + + find("#comment_#{child_comment.id}_children_arrow").trigger('click') + + expect(page).to have_css('.comment', count: 2) + expect(page).not_to have_content grandchild_comment.body + + find("#comment_#{child_comment.id}_children_arrow").trigger('click') + + expect(page).to have_css('.comment', count: 3) + expect(page).to have_content grandchild_comment.body + + find("#comment_#{parent_comment.id}_children_arrow").trigger('click') + + expect(page).to have_css('.comment', count: 1) + expect(page).not_to have_content child_comment.body + expect(page).not_to have_content grandchild_comment.body + end + + scenario 'Comment order' do + c1 = create(:comment, :with_confidence_score, commentable: poll, cached_votes_up: 100, + cached_votes_total: 120, created_at: Time.current - 2) + c2 = create(:comment, :with_confidence_score, commentable: poll, cached_votes_up: 10, + cached_votes_total: 12, created_at: Time.current - 1) + c3 = create(:comment, :with_confidence_score, commentable: poll, cached_votes_up: 1, + cached_votes_total: 2, created_at: Time.current) + + visit poll_path(poll, order: :most_voted) + + expect(c1.body).to appear_before(c2.body) + expect(c2.body).to appear_before(c3.body) + + visit poll_path(poll, order: :newest) + + expect(c3.body).to appear_before(c2.body) + expect(c2.body).to appear_before(c1.body) + + visit poll_path(poll, order: :oldest) + + expect(c1.body).to appear_before(c2.body) + expect(c2.body).to appear_before(c3.body) + end + + scenario 'Creation date works differently in roots and in child comments, when sorting by confidence_score' do + old_root = create(:comment, commentable: poll, created_at: Time.current - 10) + new_root = create(:comment, commentable: poll, created_at: Time.current) + old_child = create(:comment, commentable: poll, parent_id: new_root.id, created_at: Time.current - 10) + new_child = create(:comment, commentable: poll, parent_id: new_root.id, created_at: Time.current) + + visit poll_path(poll, order: :most_voted) + + expect(new_root.body).to appear_before(old_root.body) + expect(old_child.body).to appear_before(new_child.body) + + visit poll_path(poll, order: :newest) + + expect(new_root.body).to appear_before(old_root.body) + expect(new_child.body).to appear_before(old_child.body) + + visit poll_path(poll, order: :oldest) + + expect(old_root.body).to appear_before(new_root.body) + expect(old_child.body).to appear_before(new_child.body) + end + + scenario 'Turns links into html links' do + create :comment, commentable: poll, body: 'Built with http://rubyonrails.org/' + + visit poll_path(poll) + + within first('.comment') do + expect(page).to have_content 'Built with http://rubyonrails.org/' + expect(page).to have_link('http://rubyonrails.org/', href: 'http://rubyonrails.org/') + expect(find_link('http://rubyonrails.org/')[:rel]).to eq('nofollow') + expect(find_link('http://rubyonrails.org/')[:target]).to eq('_blank') + end + end + + scenario 'Sanitizes comment body for security' do + create :comment, commentable: poll, + body: " click me http://www.url.com" + + visit poll_path(poll) + + within first('.comment') do + expect(page).to have_content "click me http://www.url.com" + expect(page).to have_link('http://www.url.com', href: 'http://www.url.com') + expect(page).not_to have_link('click me') + end + end + + scenario 'Paginated comments' do + per_page = 10 + (per_page + 2).times { create(:comment, commentable: poll)} + + visit poll_path(poll) + + expect(page).to have_css('.comment', count: per_page) + within("ul.pagination") do + expect(page).to have_content("1") + expect(page).to have_content("2") + expect(page).not_to have_content("3") + click_link "Next", exact: false + end + + expect(page).to have_css('.comment', count: 2) + end + + feature 'Not logged user' do + scenario 'can not see comments forms' do + create(:comment, commentable: poll) + visit poll_path(poll) + + expect(page).to have_content 'You must Sign in or Sign up to leave a comment' + within('#comments') do + expect(page).not_to have_content 'Write a comment' + expect(page).not_to have_content 'Reply' + end + end + end + + scenario 'Create', :js do + login_as(user) + visit poll_path(poll) + + fill_in "comment-body-poll_#{poll.id}", with: 'Have you thought about...?' + click_button 'Publish comment' + + within "#comments" do + expect(page).to have_content 'Have you thought about...?' + end + + within "#tab-comments-label" do + expect(page).to have_content 'Comments (1)' + end + end + + scenario 'Errors on create', :js do + login_as(user) + visit poll_path(poll) + + click_button 'Publish comment' + + expect(page).to have_content "Can't be blank" + end + + scenario 'Reply', :js do + citizen = create(:user, username: 'Ana') + manuela = create(:user, username: 'Manuela') + comment = create(:comment, commentable: poll, user: citizen) + + login_as(manuela) + visit poll_path(poll) + + click_link "Reply" + + within "#js-comment-form-comment_#{comment.id}" do + fill_in "comment-body-comment_#{comment.id}", with: 'It will be done next week.' + click_button 'Publish reply' + end + + within "#comment_#{comment.id}" do + expect(page).to have_content 'It will be done next week.' + end + + expect(page).not_to have_selector("#js-comment-form-comment_#{comment.id}", visible: true) + end + + scenario 'Errors on reply', :js do + comment = create(:comment, commentable: poll, user: user) + + login_as(user) + visit poll_path(poll) + + click_link "Reply" + + within "#js-comment-form-comment_#{comment.id}" do + click_button 'Publish reply' + expect(page).to have_content "Can't be blank" + end + + end + + scenario "N replies", :js do + parent = create(:comment, commentable: poll) + + 7.times do + create(:comment, commentable: poll, parent: parent) + parent = parent.children.first + end + + visit poll_path(poll) + expect(page).to have_css(".comment.comment.comment.comment.comment.comment.comment.comment") + end + + scenario "Flagging as inappropriate", :js do + skip "Feature not implemented yet, review soon" + + comment = create(:comment, commentable: poll) + + login_as(user) + visit poll_path(poll) + + within "#comment_#{comment.id}" do + page.find("#flag-expand-comment-#{comment.id}").click + page.find("#flag-comment-#{comment.id}").click + + expect(page).to have_css("#unflag-expand-comment-#{comment.id}") + end + + expect(Flag.flagged?(user, comment)).to be + end + + scenario "Undoing flagging as inappropriate", :js do + skip "Feature not implemented yet, review soon" + + comment = create(:comment, commentable: poll) + Flag.flag(user, comment) + + login_as(user) + visit poll_path(poll) + + within "#comment_#{comment.id}" do + page.find("#unflag-expand-comment-#{comment.id}").click + page.find("#unflag-comment-#{comment.id}").click + + expect(page).to have_css("#flag-expand-comment-#{comment.id}") + end + + expect(Flag.flagged?(user, comment)).not_to be + end + + scenario "Flagging turbolinks sanity check", :js do + skip "Feature not implemented yet, review soon" + + poll = create(:poll, title: "Should we change the world?") + comment = create(:comment, commentable: poll) + + login_as(user) + visit polls_path + click_link "Should we change the world?" + + within "#comment_#{comment.id}" do + page.find("#flag-expand-comment-#{comment.id}").click + expect(page).to have_selector("#flag-comment-#{comment.id}") + end + end + + scenario "Erasing a comment's author" do + poll = create(:poll) + comment = create(:comment, commentable: poll, body: "this should be visible") + comment.user.erase + + visit poll_path(poll) + within "#comment_#{comment.id}" do + expect(page).to have_content('User deleted') + expect(page).to have_content('this should be visible') + end + end + + feature "Moderators" do + + scenario "can create comment as a moderator", :js do + skip "Feature not implemented yet, review soon" + + moderator = create(:moderator) + + login_as(moderator.user) + visit poll_path(poll) + + fill_in "comment-body-poll_#{poll.id}", with: "I am moderating!" + check "comment-as-moderator-poll_#{poll.id}" + click_button "Publish comment" + + within "#comments" do + expect(page).to have_content "I am moderating!" + expect(page).to have_content "Moderator ##{moderator.id}" + expect(page).to have_css "div.is-moderator" + expect(page).to have_css "img.moderator-avatar" + end + end + + scenario "can create reply as a moderator", :js do + skip "Feature not implemented yet, review soon" + + citizen = create(:user, username: "Ana") + manuela = create(:user, username: "Manuela") + moderator = create(:moderator, user: manuela) + comment = create(:comment, commentable: poll, user: citizen) + + login_as(manuela) + visit poll_path(poll) + + click_link "Reply" + + within "#js-comment-form-comment_#{comment.id}" do + fill_in "comment-body-comment_#{comment.id}", with: "I am moderating!" + check "comment-as-moderator-comment_#{comment.id}" + click_button 'Publish reply' + end + + within "#comment_#{comment.id}" do + expect(page).to have_content "I am moderating!" + expect(page).to have_content "Moderator ##{moderator.id}" + expect(page).to have_css "div.is-moderator" + expect(page).to have_css "img.moderator-avatar" + end + + expect(page).not_to have_selector("#js-comment-form-comment_#{comment.id}", visible: true) + end + + scenario "can not comment as an administrator" do + skip "Feature not implemented yet, review soon" + + moderator = create(:moderator) + + login_as(moderator.user) + visit poll_path(poll) + + expect(page).not_to have_content "Comment as administrator" + end + end + + feature "Administrators" do + scenario "can create comment as an administrator", :js do + skip "Feature not implemented yet, review soon" + + admin = create(:administrator) + + login_as(admin.user) + visit poll_path(poll) + + fill_in "comment-body-poll_#{poll.id}", with: "I am your Admin!" + check "comment-as-administrator-poll_#{poll.id}" + click_button "Publish comment" + + within "#comments" do + expect(page).to have_content "I am your Admin!" + expect(page).to have_content "Administrator ##{admin.id}" + expect(page).to have_css "div.is-admin" + expect(page).to have_css "img.admin-avatar" + end + end + + scenario "can create reply as an administrator", :js do + skip "Feature not implemented yet, review soon" + + citizen = create(:user, username: "Ana") + manuela = create(:user, username: "Manuela") + admin = create(:administrator, user: manuela) + comment = create(:comment, commentable: poll, user: citizen) + + login_as(manuela) + visit poll_path(poll) + + click_link "Reply" + + within "#js-comment-form-comment_#{comment.id}" do + fill_in "comment-body-comment_#{comment.id}", with: "Top of the world!" + check "comment-as-administrator-comment_#{comment.id}" + click_button 'Publish reply' + end + + within "#comment_#{comment.id}" do + expect(page).to have_content "Top of the world!" + expect(page).to have_content "Administrator ##{admin.id}" + expect(page).to have_css "div.is-admin" + expect(page).to have_css "img.admin-avatar" + end + + expect(page).not_to have_selector("#js-comment-form-comment_#{comment.id}", visible: true) + end + + scenario "can not comment as a moderator" do + skip "Feature not implemented yet, review soon" + + admin = create(:administrator) + + login_as(admin.user) + visit poll_path(poll) + + expect(page).not_to have_content "Comment as moderator" + end + end + + feature 'Voting comments' do + + background do + @manuela = create(:user, verified_at: Time.current) + @pablo = create(:user) + @poll = create(:poll) + @comment = create(:comment, commentable: @poll) + + login_as(@manuela) + end + + scenario 'Show' do + create(:vote, voter: @manuela, votable: @comment, vote_flag: true) + create(:vote, voter: @pablo, votable: @comment, vote_flag: false) + + visit poll_path(@poll) + + within("#comment_#{@comment.id}_votes") do + within(".in_favor") do + expect(page).to have_content "1" + end + + within(".against") do + expect(page).to have_content "1" + end + + expect(page).to have_content "2 votes" + end + end + + scenario 'Create', :js do + visit poll_path(@poll) + + within("#comment_#{@comment.id}_votes") do + find(".in_favor a").click + + within(".in_favor") do + expect(page).to have_content "1" + end + + within(".against") do + expect(page).to have_content "0" + end + + expect(page).to have_content "1 vote" + end + end + + scenario 'Update', :js do + visit poll_path(@poll) + + within("#comment_#{@comment.id}_votes") do + find('.in_favor a').click + find('.against a').click + + within('.in_favor') do + expect(page).to have_content "0" + end + + within('.against') do + expect(page).to have_content "1" + end + + expect(page).to have_content "1 vote" + end + end + + scenario 'Trying to vote multiple times', :js do + visit poll_path(@poll) + + within("#comment_#{@comment.id}_votes") do + find('.in_favor a').click + find('.in_favor a').click + + within('.in_favor') do + expect(page).to have_content "1" + end + + within('.against') do + expect(page).to have_content "0" + end + + expect(page).to have_content "1 vote" + end + end + end + +end diff --git a/spec/features/comments/proposals_spec.rb b/spec/features/comments/proposals_spec.rb index acba0bec9..959b4b65b 100644 --- a/spec/features/comments/proposals_spec.rb +++ b/spec/features/comments/proposals_spec.rb @@ -50,7 +50,7 @@ feature 'Commenting proposals' do find("#comment_#{child_comment.id}_children_arrow").trigger('click') expect(page).to have_css('.comment', count: 2) - expect(page).to_not have_content grandchild_comment.body + expect(page).not_to have_content grandchild_comment.body find("#comment_#{child_comment.id}_children_arrow").trigger('click') @@ -60,8 +60,8 @@ feature 'Commenting proposals' do find("#comment_#{parent_comment.id}_children_arrow").trigger('click') expect(page).to have_css('.comment', count: 1) - expect(page).to_not have_content child_comment.body - expect(page).to_not have_content grandchild_comment.body + expect(page).not_to have_content child_comment.body + expect(page).not_to have_content grandchild_comment.body end scenario 'Comment order' do @@ -146,7 +146,7 @@ feature 'Commenting proposals' do within("ul.pagination") do expect(page).to have_content("1") expect(page).to have_content("2") - expect(page).to_not have_content("3") + expect(page).not_to have_content("3") click_link "Next", exact: false end @@ -160,8 +160,8 @@ feature 'Commenting proposals' do expect(page).to have_content 'You must Sign in or Sign up to leave a comment' within('#comments') do - expect(page).to_not have_content 'Write a comment' - expect(page).to_not have_content 'Reply' + expect(page).not_to have_content 'Write a comment' + expect(page).not_to have_content 'Reply' end end end @@ -210,7 +210,7 @@ feature 'Commenting proposals' do expect(page).to have_content 'It will be done next week.' end - expect(page).to_not have_selector("#js-comment-form-comment_#{comment.id}", visible: true) + expect(page).not_to have_selector("#js-comment-form-comment_#{comment.id}", visible: true) end scenario 'Errors on reply', :js do @@ -270,7 +270,7 @@ feature 'Commenting proposals' do expect(page).to have_css("#flag-expand-comment-#{comment.id}") end - expect(Flag.flagged?(user, comment)).to_not be + expect(Flag.flagged?(user, comment)).not_to be end scenario "Flagging turbolinks sanity check", :js do @@ -342,7 +342,7 @@ feature 'Commenting proposals' do expect(page).to have_css "img.moderator-avatar" end - expect(page).to_not have_selector("#js-comment-form-comment_#{comment.id}", visible: true) + expect(page).not_to have_selector("#js-comment-form-comment_#{comment.id}", visible: true) end scenario "can not comment as an administrator" do @@ -351,7 +351,7 @@ feature 'Commenting proposals' do login_as(moderator.user) visit proposal_path(proposal) - expect(page).to_not have_content "Comment as administrator" + expect(page).not_to have_content "Comment as administrator" end end @@ -398,7 +398,7 @@ feature 'Commenting proposals' do expect(page).to have_css "img.admin-avatar" end - expect(page).to_not have_selector("#js-comment-form-comment_#{comment.id}", visible: true) + expect(page).not_to have_selector("#js-comment-form-comment_#{comment.id}", visible: true) end scenario "can not comment as a moderator" do @@ -407,7 +407,7 @@ feature 'Commenting proposals' do login_as(admin.user) visit proposal_path(proposal) - expect(page).to_not have_content "Comment as moderator" + expect(page).not_to have_content "Comment as moderator" end end diff --git a/spec/features/comments/topics_spec.rb b/spec/features/comments/topics_spec.rb index 38971fcff..2d09b5ff4 100644 --- a/spec/features/comments/topics_spec.rb +++ b/spec/features/comments/topics_spec.rb @@ -54,7 +54,7 @@ feature 'Commenting topics from proposals' do find("#comment_#{child_comment.id}_children_arrow").trigger('click') expect(page).to have_css('.comment', count: 2) - expect(page).to_not have_content grandchild_comment.body + expect(page).not_to have_content grandchild_comment.body find("#comment_#{child_comment.id}_children_arrow").trigger('click') @@ -64,8 +64,8 @@ feature 'Commenting topics from proposals' do find("#comment_#{parent_comment.id}_children_arrow").trigger('click') expect(page).to have_css('.comment', count: 1) - expect(page).to_not have_content child_comment.body - expect(page).to_not have_content grandchild_comment.body + expect(page).not_to have_content child_comment.body + expect(page).not_to have_content grandchild_comment.body end scenario 'Comment order' do @@ -160,7 +160,7 @@ feature 'Commenting topics from proposals' do within("ul.pagination") do expect(page).to have_content("1") expect(page).to have_content("2") - expect(page).to_not have_content("3") + expect(page).not_to have_content("3") click_link "Next", exact: false end @@ -177,8 +177,8 @@ feature 'Commenting topics from proposals' do expect(page).to have_content 'You must Sign in or Sign up to leave a comment' within('#comments') do - expect(page).to_not have_content 'Write a comment' - expect(page).to_not have_content 'Reply' + expect(page).not_to have_content 'Write a comment' + expect(page).not_to have_content 'Reply' end end end @@ -233,7 +233,7 @@ feature 'Commenting topics from proposals' do expect(page).to have_content 'It will be done next week.' end - expect(page).to_not have_selector("#js-comment-form-comment_#{comment.id}", visible: true) + expect(page).not_to have_selector("#js-comment-form-comment_#{comment.id}", visible: true) end scenario 'Errors on reply', :js do @@ -301,7 +301,7 @@ feature 'Commenting topics from proposals' do expect(page).to have_css("#flag-expand-comment-#{comment.id}") end - expect(Flag.flagged?(user, comment)).to_not be + expect(Flag.flagged?(user, comment)).not_to be end scenario "Flagging turbolinks sanity check", :js do @@ -384,7 +384,7 @@ feature 'Commenting topics from proposals' do expect(page).to have_css "img.moderator-avatar" end - expect(page).to_not have_selector("#js-comment-form-comment_#{comment.id}", visible: true) + expect(page).not_to have_selector("#js-comment-form-comment_#{comment.id}", visible: true) end scenario "can not comment as an administrator" do @@ -395,7 +395,7 @@ feature 'Commenting topics from proposals' do login_as(moderator.user) visit community_topic_path(community, topic) - expect(page).to_not have_content "Comment as administrator" + expect(page).not_to have_content "Comment as administrator" end end @@ -446,7 +446,7 @@ feature 'Commenting topics from proposals' do expect(page).to have_css "img.admin-avatar" end - expect(page).to_not have_selector("#js-comment-form-comment_#{comment.id}", visible: true) + expect(page).not_to have_selector("#js-comment-form-comment_#{comment.id}", visible: true) end scenario "can not comment as a moderator" do @@ -457,7 +457,7 @@ feature 'Commenting topics from proposals' do login_as(admin.user) visit community_topic_path(community, topic) - expect(page).to_not have_content "Comment as moderator" + expect(page).not_to have_content "Comment as moderator" end end @@ -604,7 +604,7 @@ feature 'Commenting topics from budget investments' do find("#comment_#{child_comment.id}_children_arrow").trigger('click') expect(page).to have_css('.comment', count: 2) - expect(page).to_not have_content grandchild_comment.body + expect(page).not_to have_content grandchild_comment.body find("#comment_#{child_comment.id}_children_arrow").trigger('click') @@ -614,8 +614,8 @@ feature 'Commenting topics from budget investments' do find("#comment_#{parent_comment.id}_children_arrow").trigger('click') expect(page).to have_css('.comment', count: 1) - expect(page).to_not have_content child_comment.body - expect(page).to_not have_content grandchild_comment.body + expect(page).not_to have_content child_comment.body + expect(page).not_to have_content grandchild_comment.body end scenario 'Comment order' do @@ -710,7 +710,7 @@ feature 'Commenting topics from budget investments' do within("ul.pagination") do expect(page).to have_content("1") expect(page).to have_content("2") - expect(page).to_not have_content("3") + expect(page).not_to have_content("3") click_link "Next", exact: false end @@ -727,8 +727,8 @@ feature 'Commenting topics from budget investments' do expect(page).to have_content 'You must Sign in or Sign up to leave a comment' within('#comments') do - expect(page).to_not have_content 'Write a comment' - expect(page).to_not have_content 'Reply' + expect(page).not_to have_content 'Write a comment' + expect(page).not_to have_content 'Reply' end end end @@ -783,7 +783,7 @@ feature 'Commenting topics from budget investments' do expect(page).to have_content 'It will be done next week.' end - expect(page).to_not have_selector("#js-comment-form-comment_#{comment.id}", visible: true) + expect(page).not_to have_selector("#js-comment-form-comment_#{comment.id}", visible: true) end scenario 'Errors on reply', :js do @@ -851,7 +851,7 @@ feature 'Commenting topics from budget investments' do expect(page).to have_css("#flag-expand-comment-#{comment.id}") end - expect(Flag.flagged?(user, comment)).to_not be + expect(Flag.flagged?(user, comment)).not_to be end scenario "Flagging turbolinks sanity check", :js do @@ -934,7 +934,7 @@ feature 'Commenting topics from budget investments' do expect(page).to have_css "img.moderator-avatar" end - expect(page).to_not have_selector("#js-comment-form-comment_#{comment.id}", visible: true) + expect(page).not_to have_selector("#js-comment-form-comment_#{comment.id}", visible: true) end scenario "can not comment as an administrator" do @@ -945,7 +945,7 @@ feature 'Commenting topics from budget investments' do login_as(moderator.user) visit community_topic_path(community, topic) - expect(page).to_not have_content "Comment as administrator" + expect(page).not_to have_content "Comment as administrator" end end @@ -996,7 +996,7 @@ feature 'Commenting topics from budget investments' do expect(page).to have_css "img.admin-avatar" end - expect(page).to_not have_selector("#js-comment-form-comment_#{comment.id}", visible: true) + expect(page).not_to have_selector("#js-comment-form-comment_#{comment.id}", visible: true) end scenario "can not comment as a moderator" do @@ -1007,7 +1007,7 @@ feature 'Commenting topics from budget investments' do login_as(admin.user) visit community_topic_path(community, topic) - expect(page).to_not have_content "Comment as moderator" + expect(page).not_to have_content "Comment as moderator" end end diff --git a/spec/features/communities_spec.rb b/spec/features/communities_spec.rb index 2909f416e..4841a473a 100644 --- a/spec/features/communities_spec.rb +++ b/spec/features/communities_spec.rb @@ -24,16 +24,6 @@ feature 'Communities' do expect(page).to have_content proposal.title expect(page).to have_content "Participate in the community of this proposal" expect(page).to have_link("Create topic", href: new_community_topic_path(community)) - expect(page).not_to have_selector(".button.disabled", text: "Create topic") - end - - scenario 'Should display disabled create topic button when user is not logged' do - proposal = create(:proposal) - community = proposal.community - - visit community_path(community) - - expect(page).to have_selector(".button.disabled", text: "Create topic") end scenario 'Should display without_topics_text and participants when there are not topics' do @@ -100,7 +90,7 @@ feature 'Communities' do expect(topic2.title).to appear_before(topic1.title) end - scenario 'Should display topic edit button when author is logged' do + scenario 'Should display topic edit button on topic show when author is logged' do proposal = create(:proposal) community = proposal.community user = create(:user) @@ -108,15 +98,11 @@ feature 'Communities' do topic2 = create(:topic, community: community) login_as(user) - visit community_path(community) + visit community_topic_path(community, topic1) + expect(page).to have_link("Edit topic", href: edit_community_topic_path(community, topic1)) - within "#topic_#{topic1.id}" do - expect(page).to have_link("Edit", href: edit_community_topic_path(community, topic1)) - end - - within "#topic_#{topic2.id}" do - expect(page).not_to have_link("Edit", href: edit_community_topic_path(community, topic2)) - end + visit community_topic_path(community, topic2) + expect(page).not_to have_link("Edit topic", href: edit_community_topic_path(community, topic2)) end scenario 'Should display participant when there is topics' do @@ -156,7 +142,7 @@ feature 'Communities' do visit community_path(community) - expect(current_path).to eq(root_path) + expect(page).to have_current_path(root_path) end end diff --git a/spec/features/debates_spec.rb b/spec/features/debates_spec.rb index 749c7a373..d05fc12e5 100644 --- a/spec/features/debates_spec.rb +++ b/spec/features/debates_spec.rb @@ -9,6 +9,11 @@ feature 'Debates' do Setting['feature.debates'] = true end + context "Concerns" do + it_behaves_like 'notifiable in-app', Debate + it_behaves_like 'relationable', Debate + end + scenario 'Index' do debates = [create(:debate), create(:debate), create(:debate)] @@ -35,7 +40,7 @@ feature 'Debates' do within("ul.pagination") do expect(page).to have_content("1") expect(page).to have_content("2") - expect(page).to_not have_content("3") + expect(page).not_to have_content("3") click_link "Next", exact: false end @@ -66,7 +71,7 @@ feature 'Debates' do first(:link, debate.title).click link_text = find_link('Go back')[:href] - expect(link_text).to include(debates_path order: :hot_score, page: 1) + expect(link_text).to include(debates_path(order: :hot_score, page: 1)) end context "Show" do @@ -76,7 +81,7 @@ feature 'Debates' do right_path = debate_path(debate) visit right_path - expect(current_path).to eq(right_path) + expect(page).to have_current_path(right_path) end scenario 'When path does not match the friendly url' do @@ -86,8 +91,8 @@ feature 'Debates' do old_path = "#{debates_path}/#{debate.id}-something-else" visit old_path - expect(current_path).to_not eq(old_path) - expect(current_path).to eq(right_path) + expect(page).not_to have_current_path(old_path) + expect(page).to have_current_path(right_path) end end @@ -123,7 +128,7 @@ feature 'Debates' do expect(page.status_code).to eq(200) expect(page.html).to be_empty - expect(current_path).to eq(debates_path) + expect(page).to have_current_path(debates_path) end scenario 'Create debate too fast' do @@ -141,7 +146,7 @@ feature 'Debates' do expect(page).to have_content 'Sorry, that was too quick! Please resubmit' - expect(current_path).to eq(new_debate_path) + expect(page).to have_current_path(new_debate_path) end scenario 'Errors on create' do @@ -167,8 +172,8 @@ feature 'Debates' do expect(page).to have_content 'Debate created successfully.' expect(page).to have_content 'Testing an attack' expect(page.html).to include 'This is alert("an attack");
' - expect(page.html).to_not include '' - expect(page.html).to_not include '<p>This is' + expect(page.html).not_to include '' + expect(page.html).not_to include '<p>This is' end scenario 'Autolinking is applied to description' do @@ -203,13 +208,13 @@ feature 'Debates' do expect(page).to have_content 'Testing auto link' expect(page).to have_link('http://example.org', href: 'http://example.org') expect(page).not_to have_link('click me') - expect(page.html).to_not include "" + expect(page.html).not_to include "" click_link 'Edit' - expect(current_path).to eq edit_debate_path(Debate.last) + expect(page).to have_current_path(edit_debate_path(Debate.last)) expect(page).not_to have_link('click me') - expect(page.html).to_not include "" + expect(page.html).not_to include "" end scenario 'Update should not be posible if logged user is not the author' do @@ -218,8 +223,8 @@ feature 'Debates' do login_as(create(:user)) visit edit_debate_path(debate) - expect(current_path).not_to eq(edit_debate_path(debate)) - expect(current_path).to eq(proposals_path) + expect(page).not_to have_current_path(edit_debate_path(debate)) + expect(page).to have_current_path(root_path) expect(page).to have_content "You do not have permission to carry out the action 'edit' on debate." end @@ -228,13 +233,13 @@ feature 'Debates' do Setting["max_votes_for_debate_edit"] = 2 3.times { create(:vote, votable: debate) } - expect(debate).to_not be_editable + expect(debate).not_to be_editable login_as(debate.author) visit edit_debate_path(debate) - expect(current_path).not_to eq(edit_debate_path(debate)) - expect(current_path).to eq(proposals_path) + expect(page).not_to have_current_path(edit_debate_path(debate)) + expect(page).to have_current_path(root_path) expect(page).to have_content 'You do not have permission to' end @@ -243,7 +248,7 @@ feature 'Debates' do login_as(debate.author) visit edit_debate_path(debate) - expect(current_path).to eq(edit_debate_path(debate)) + expect(page).to have_current_path(edit_debate_path(debate)) fill_in 'debate_title', with: "End child poverty" fill_in 'debate_description', with: "Let's do something to end child poverty" @@ -298,26 +303,32 @@ feature 'Debates' do expect(page).to have_css("#flag-expand-debate-#{debate.id}") end - expect(Flag.flagged?(user, debate)).to_not be + expect(Flag.flagged?(user, debate)).not_to be end feature 'Debate index order filters' do scenario 'Default order is hot_score', :js do - create(:debate, title: 'Best').update_column(:hot_score, 10) - create(:debate, title: 'Worst').update_column(:hot_score, 2) - create(:debate, title: 'Medium').update_column(:hot_score, 5) + best_debate = create(:debate, title: 'Best') + best_debate.update_column(:hot_score, 10) + worst_debate = create(:debate, title: 'Worst') + worst_debate.update_column(:hot_score, 2) + medium_debate = create(:debate, title: 'Medium') + medium_debate.update_column(:hot_score, 5) visit debates_path - expect('Best').to appear_before('Medium') - expect('Medium').to appear_before('Worst') + expect(best_debate.title).to appear_before(medium_debate.title) + expect(medium_debate.title).to appear_before(worst_debate.title) end scenario 'Debates are ordered by confidence_score', :js do - create(:debate, title: 'Best').update_column(:confidence_score, 10) - create(:debate, title: 'Worst').update_column(:confidence_score, 2) - create(:debate, title: 'Medium').update_column(:confidence_score, 5) + best_debate = create(:debate, title: 'Best') + best_debate.update_column(:confidence_score, 10) + worst_debate = create(:debate, title: 'Worst') + worst_debate.update_column(:confidence_score, 2) + medium_debate = create(:debate, title: 'Medium') + medium_debate.update_column(:confidence_score, 5) visit debates_path click_link 'highest rated' @@ -325,8 +336,8 @@ feature 'Debates' do expect(page).to have_selector('a.active', text: 'highest rated') within '#debates' do - expect('Best').to appear_before('Medium') - expect('Medium').to appear_before('Worst') + expect(best_debate.title).to appear_before(medium_debate.title) + expect(medium_debate.title).to appear_before(worst_debate.title) end expect(current_url).to include('order=confidence_score') @@ -334,9 +345,9 @@ feature 'Debates' do end scenario 'Debates are ordered by newest', :js do - create(:debate, title: 'Best', created_at: Time.current) - create(:debate, title: 'Medium', created_at: Time.current - 1.hour) - create(:debate, title: 'Worst', created_at: Time.current - 1.day) + best_debate = create(:debate, title: 'Best', created_at: Time.current) + medium_debate = create(:debate, title: 'Medium', created_at: Time.current - 1.hour) + worst_debate = create(:debate, title: 'Worst', created_at: Time.current - 1.day) visit debates_path click_link 'newest' @@ -344,13 +355,77 @@ feature 'Debates' do expect(page).to have_selector('a.active', text: 'newest') within '#debates' do - expect('Best').to appear_before('Medium') - expect('Medium').to appear_before('Worst') + expect(best_debate.title).to appear_before(medium_debate.title) + expect(medium_debate.title).to appear_before(worst_debate.title) end expect(current_url).to include('order=created_at') expect(current_url).to include('page=1') end + + context 'Recommendations' do + + let!(:best_debate) { create(:debate, title: 'Best', cached_votes_total: 10, tag_list: "Sport") } + let!(:medium_debate) { create(:debate, title: 'Medium', cached_votes_total: 5, tag_list: "Sport") } + let!(:worst_debate) { create(:debate, title: 'Worst', cached_votes_total: 1, tag_list: "Sport") } + + background do + Setting['feature.user.recommendations'] = true + end + + after do + Setting['feature.user.recommendations'] = nil + end + + scenario 'Debates can not ordered by recommendations when there is not an user logged', :js do + visit debates_path + + expect(page).not_to have_selector('a', text: 'recommendations') + end + + scenario 'Should display text when there are not recommendeds results', :js do + user = create(:user) + proposal = create(:proposal, tag_list: "Distinct_to_sport") + create(:follow, followable: proposal, user: user) + login_as(user) + visit debates_path + + click_link 'recommendations' + + expect(page).to have_content "There are not debates related to your interests" + end + + scenario 'Should display text when user has not related interests', :js do + user = create(:user) + login_as(user) + visit debates_path + + click_link 'recommendations' + + expect(page).to have_content "Follow proposals so we can give you recommendations" + end + + scenario 'Debates are ordered by recommendations when there is a user logged', :js do + proposal = create(:proposal, tag_list: "Sport") + user = create(:user) + create(:follow, followable: proposal, user: user) + login_as(user) + + visit debates_path + + click_link 'recommendations' + + expect(page).to have_selector('a.active', text: 'recommendations') + + within '#debates' do + expect(best_debate.title).to appear_before(medium_debate.title) + expect(medium_debate.title).to appear_before(worst_debate.title) + end + + expect(current_url).to include('order=recommendations') + expect(current_url).to include('page=1') + end + end end context "Search" do @@ -374,7 +449,7 @@ feature 'Debates' do expect(page).to have_content(debate1.title) expect(page).to have_content(debate2.title) - expect(page).to_not have_content(debate3.title) + expect(page).not_to have_content(debate3.title) end end @@ -409,7 +484,7 @@ feature 'Debates' do within("#debates") do expect(page).to have_content(debate1.title) expect(page).to have_content(debate2.title) - expect(page).to_not have_content(debate3.title) + expect(page).not_to have_content(debate3.title) end end @@ -434,7 +509,7 @@ feature 'Debates' do within("#debates") do expect(page).to have_content(debate1.title) expect(page).to have_content(debate2.title) - expect(page).to_not have_content(debate3.title) + expect(page).not_to have_content(debate3.title) end end @@ -457,7 +532,7 @@ feature 'Debates' do within("#debates") do expect(page).to have_content(debate1.title) expect(page).to have_content(debate2.title) - expect(page).to_not have_content(debate3.title) + expect(page).not_to have_content(debate3.title) end end @@ -480,7 +555,7 @@ feature 'Debates' do within("#debates") do expect(page).to have_content(debate1.title) expect(page).to have_content(debate2.title) - expect(page).to_not have_content(debate3.title) + expect(page).not_to have_content(debate3.title) end end @@ -503,7 +578,7 @@ feature 'Debates' do within("#debates") do expect(page).to have_content(debate1.title) expect(page).to have_content(debate2.title) - expect(page).to_not have_content(debate3.title) + expect(page).not_to have_content(debate3.title) end end @@ -526,7 +601,7 @@ feature 'Debates' do within("#debates") do expect(page).to have_content(debate1.title) expect(page).to have_content(debate2.title) - expect(page).to_not have_content(debate3.title) + expect(page).not_to have_content(debate3.title) end end @@ -552,7 +627,7 @@ feature 'Debates' do expect(page).to have_content(debate1.title) expect(page).to have_content(debate2.title) - expect(page).to_not have_content(debate3.title) + expect(page).not_to have_content(debate3.title) end end @@ -572,7 +647,7 @@ feature 'Debates' do expect(page).to have_content(debate1.title) expect(page).to have_content(debate2.title) - expect(page).to_not have_content(debate3.title) + expect(page).not_to have_content(debate3.title) end end @@ -592,7 +667,7 @@ feature 'Debates' do expect(page).to have_content(debate1.title) expect(page).to have_content(debate2.title) - expect(page).to_not have_content(debate3.title) + expect(page).not_to have_content(debate3.title) end end @@ -612,7 +687,7 @@ feature 'Debates' do expect(page).to have_content(debate1.title) expect(page).to have_content(debate2.title) - expect(page).to_not have_content(debate3.title) + expect(page).not_to have_content(debate3.title) end end @@ -636,7 +711,7 @@ feature 'Debates' do expect(page).to have_content(debate1.title) expect(page).to have_content(debate2.title) - expect(page).to_not have_content(debate3.title) + expect(page).not_to have_content(debate3.title) end end @@ -755,10 +830,36 @@ feature 'Debates' do expect(all(".debate")[0].text).to match "Show you got" expect(all(".debate")[1].text).to match "Show you got" expect(all(".debate")[2].text).to match "Show what you got" - expect(page).to_not have_content "Do not display" + expect(page).not_to have_content "Do not display" end end + scenario "Reorder by recommendations results maintaing search", :js do + Setting['feature.user.recommendations'] = true + user = create(:user) + login_as(user) + debate1 = create(:debate, title: "Show you got", cached_votes_total: 10, tag_list: "Sport") + debate2 = create(:debate, title: "Show what you got", cached_votes_total: 1, tag_list: "Sport") + debate3 = create(:debate, title: "Do not display with same tag", cached_votes_total: 100, tag_list: "Sport") + debate4 = create(:debate, title: "Do not display", cached_votes_total: 1) + proposal1 = create(:proposal, tag_list: "Sport") + create(:follow, followable: proposal1, user: user) + + visit debates_path + fill_in "search", with: "Show you got" + click_button "Search" + click_link 'recommendations' + expect(page).to have_selector("a.active", text: "recommendations") + + within("#debates") do + expect(all(".debate")[0].text).to match "Show you got" + expect(all(".debate")[1].text).to match "Show what you got" + expect(page).not_to have_content "Do not display with same tag" + expect(page).not_to have_content "Do not display" + end + Setting['feature.user.recommendations'] = nil + end + scenario 'After a search do not show featured debates' do featured_debates = create_featured_debates debate = create(:debate, title: "Abcdefghi") @@ -769,8 +870,8 @@ feature 'Debates' do click_button "Search" end - expect(page).to_not have_selector('#debates .debate-featured') - expect(page).to_not have_selector('#featured-debates') + expect(page).not_to have_selector('#debates .debate-featured') + expect(page).not_to have_selector('#featured-debates') end end @@ -783,7 +884,7 @@ feature 'Debates' do expect(page).to have_content "This debate has been flagged as inappropriate by several users." visit debate_path(good_debate) - expect(page).to_not have_content "This debate has been flagged as inappropriate by several users." + expect(page).not_to have_content "This debate has been flagged as inappropriate by several users." end scenario 'Erased author' do @@ -824,7 +925,7 @@ feature 'Debates' do expect(page).to have_css('.debate', count: 2) expect(page).to have_content(@debate1.title) expect(page).to have_content(@debate2.title) - expect(page).to_not have_content(@debate3.title) + expect(page).not_to have_content(@debate3.title) end end @@ -839,7 +940,7 @@ feature 'Debates' do expect(page).to have_css('.debate', count: 2) expect(page).to have_content(@debate1.title) expect(page).to have_content(@debate2.title) - expect(page).to_not have_content(@debate3.title) + expect(page).not_to have_content(@debate3.title) end end @@ -854,7 +955,7 @@ feature 'Debates' do expect(page).to have_css('.debate', count: 2) expect(page).to have_content(@debate1.title) expect(page).to have_content(@debate2.title) - expect(page).to_not have_content(@debate3.title) + expect(page).not_to have_content(@debate3.title) end end @@ -879,7 +980,7 @@ feature 'Debates' do check "debate_terms_of_service" within('div#js-suggest') do - expect(page).to have_content ("You are seeing 5 of 6 debates containing the term 'debate'") + expect(page).to have_content "You are seeing 5 of 6 debates containing the term 'debate'" end end @@ -895,7 +996,7 @@ feature 'Debates' do check "debate_terms_of_service" within('div#js-suggest') do - expect(page).to_not have_content ('You are seeing') + expect(page).not_to have_content 'You are seeing' end end end @@ -908,7 +1009,7 @@ feature 'Debates' do visit debates_path within('#debates') do - expect(page).to_not have_content 'Featured' + expect(page).not_to have_content 'Featured' end click_link debate.title @@ -929,7 +1030,7 @@ feature 'Debates' do click_link 'Unmark featured' within('#debates') do - expect(page).to_not have_content 'Featured' + expect(page).not_to have_content 'Featured' end end @@ -955,7 +1056,8 @@ feature 'Debates' do visit debates_path within('#debates') do - expect(page).to_not have_content("Featured") + expect(page).not_to have_content("Featured") end end + end diff --git a/spec/features/direct_messages_spec.rb b/spec/features/direct_messages_spec.rb index 3c822de5c..d2ebccd87 100644 --- a/spec/features/direct_messages_spec.rb +++ b/spec/features/direct_messages_spec.rb @@ -34,7 +34,7 @@ feature 'Direct messages' do login_as(sender) visit user_path(sender) - expect(page).to_not have_link "Send private message" + expect(page).not_to have_link "Send private message" end scenario "Do not display link if direct message for user not allowed" do @@ -45,7 +45,7 @@ feature 'Direct messages' do visit user_path(receiver) expect(page).to have_content "This user doesn't accept private messages." - expect(page).to_not have_link "Send private message" + expect(page).not_to have_link "Send private message" end scenario "Unverified user" do @@ -56,7 +56,7 @@ feature 'Direct messages' do visit new_user_direct_message_path(receiver) expect(page).to have_content "To send a private message verify your account" - expect(page).to_not have_link "Send private message" + expect(page).not_to have_link "Send private message" end scenario "User not logged in" do @@ -66,7 +66,7 @@ feature 'Direct messages' do visit new_user_direct_message_path(receiver) expect(page).to have_content "You must sign in or sign up to continue." - expect(page).to_not have_link "Send private message" + expect(page).not_to have_link "Send private message" end scenario "Accessing form directly" do @@ -77,7 +77,7 @@ feature 'Direct messages' do visit new_user_direct_message_path(receiver) expect(page).to have_content("This user has decided not to receive direct messages") - expect(page).to_not have_css("#direct_message_title") + expect(page).not_to have_css("#direct_message_title") end end @@ -114,7 +114,7 @@ feature 'Direct messages' do click_button "Send message" expect(page).to have_content "You have reached the maximum number of private messages per day" - expect(page).to_not have_content "You message has been sent successfully." + expect(page).not_to have_content "You message has been sent successfully." end end diff --git a/spec/features/emails_spec.rb b/spec/features/emails_spec.rb index af7674101..f4bd7e08e 100644 --- a/spec/features/emails_spec.rb +++ b/spec/features/emails_spec.rb @@ -84,6 +84,103 @@ feature 'Emails' do end end + context 'Budget investments comments' do + scenario 'Send email on budget investment comment', :js do + user = create(:user, email_on_comment: true) + investment = create(:budget_investment, author: user, budget: create(:budget)) + comment_on(investment) + + email = open_last_email + expect(email).to have_subject('Someone has commented on your investment') + expect(email).to deliver_to(investment.author) + expect(email).to have_body_text(budget_investment_path(investment, budget_id: investment.budget_id)) + expect(email).to have_body_text(I18n.t('mailers.config.manage_email_subscriptions')) + expect(email).to have_body_text(account_path) + end + + scenario 'Do not send email about own budget investments comments', :js do + user = create(:user, email_on_comment: true) + investment = create(:budget_investment, author: user, budget: create(:budget)) + comment_on(investment, user) + + expect { open_last_email }.to raise_error 'No email has been sent!' + end + + scenario 'Do not send email about budget investment comment unless set in preferences', :js do + user = create(:user, email_on_comment: false) + investment = create(:budget_investment, author: user, budget: create(:budget)) + comment_on(investment) + + expect { open_last_email }.to raise_error 'No email has been sent!' + end + end + + context 'Topic comments' do + before do + @proposal = create(:proposal) + end + + scenario 'Send email on topic comment', :js do + user = create(:user, email_on_comment: true) + topic = create(:topic, author: user, community: @proposal.community) + comment_on(topic) + + email = open_last_email + expect(email).to have_subject('Someone has commented on your topic') + expect(email).to deliver_to(topic.author) + expect(email).to have_body_text(community_topic_path(topic, community_id: topic.community_id)) + expect(email).to have_body_text(I18n.t('mailers.config.manage_email_subscriptions')) + expect(email).to have_body_text(account_path) + end + + scenario 'Do not send email about own topic comments', :js do + user = create(:user, email_on_comment: true) + topic = create(:topic, author: user, community: @proposal.community) + comment_on(topic, user) + + expect { open_last_email }.to raise_error 'No email has been sent!' + end + + scenario 'Do not send email about topic comment unless set in preferences', :js do + user = create(:user, email_on_comment: false) + topic = create(:topic, author: user, community: @proposal.community) + comment_on(topic) + + expect { open_last_email }.to raise_error 'No email has been sent!' + end + end + + context 'Poll comments' do + scenario 'Send email on poll comment', :js do + user = create(:user, email_on_comment: true) + poll = create(:poll, author: user) + comment_on(poll) + + email = open_last_email + expect(email).to have_subject('Someone has commented on your poll') + expect(email).to deliver_to(poll.author) + expect(email).to have_body_text(poll_path(poll)) + expect(email).to have_body_text(I18n.t('mailers.config.manage_email_subscriptions')) + expect(email).to have_body_text(account_path) + end + + scenario 'Do not send email about own poll comments', :js do + user = create(:user, email_on_comment: true) + poll = create(:poll, author: user) + comment_on(poll, user) + + expect { open_last_email }.to raise_error 'No email has been sent!' + end + + scenario 'Do not send email about poll question comment unless set in preferences', :js do + user = create(:user, email_on_comment: false) + poll = create(:poll, author: user) + comment_on(poll) + + expect { open_last_email }.to raise_error 'No email has been sent!' + end + end + context 'Comment replies' do scenario "Send email on comment reply", :js do user = create(:user, email_on_comment_reply: true) @@ -92,7 +189,7 @@ feature 'Emails' do email = open_last_email expect(email).to have_subject('Someone has responded to your comment') expect(email).to deliver_to(user) - expect(email).to_not have_body_text(debate_path(Comment.first.commentable)) + expect(email).not_to have_body_text(debate_path(Comment.first.commentable)) expect(email).to have_body_text(comment_path(Comment.last)) expect(email).to have_body_text(I18n.t("mailers.config.manage_email_subscriptions")) expect(email).to have_body_text(account_path) @@ -113,15 +210,6 @@ feature 'Emails' do end end - scenario "Email depending on user's locale" do - sign_up - - email = open_last_email - expect(email).to have_subject('Confirmation instructions') - expect(email).to deliver_to('manuela@consul.dev') - expect(email).to have_body_text(user_confirmation_path) - end - scenario "Email on unfeasible spending proposal" do Setting["feature.spending_proposals"] = true @@ -230,7 +318,7 @@ feature 'Emails' do expect(email).to have_body_text(/#{proposal_path(proposal2, anchor: 'social-share')}/) expect(email).to have_body_text(proposal2.author.name) - expect(email).to_not have_body_text(proposal3.title) + expect(email).not_to have_body_text(proposal3.title) expect(email).to have_body_text(/#{account_path}/) notification1.reload @@ -278,10 +366,9 @@ feature 'Emails' do login_as(author) visit new_budget_investment_path(budget_id: budget.id) - select 'Health: More hospitals', from: 'budget_investment_heading_id' + select "#{group.name}: #{heading.name}", from: 'budget_investment_heading_id' fill_in 'budget_investment_title', with: 'Build a hospital' fill_in 'budget_investment_description', with: 'We have lots of people that require medical attention' - fill_in 'budget_investment_external_url', with: 'http://http://hospitalsforallthepeople.com/' check 'budget_investment_terms_of_service' click_button 'Create Investment' @@ -335,9 +422,9 @@ feature 'Emails' do reset_mailer budget.email_selected - expect(find_email investment1.author.email).to be - expect(find_email investment2.author.email).to be - expect(find_email investment3.author.email).to_not be + expect(find_email(investment1.author.email)).to be + expect(find_email(investment2.author.email)).to be + expect(find_email(investment3.author.email)).not_to be email = open_last_email investment = investment2 @@ -358,9 +445,9 @@ feature 'Emails' do reset_mailer budget.email_unselected - expect(find_email investment1.author.email).to be - expect(find_email investment2.author.email).to be - expect(find_email investment3.author.email).to_not be + expect(find_email(investment1.author.email)).to be + expect(find_email(investment2.author.email)).to be + expect(find_email(investment3.author.email)).not_to be email = open_last_email investment = investment2 @@ -371,6 +458,39 @@ feature 'Emails' do end + context "Polls" do + + scenario "Send email on poll comment reply", :js do + user1 = create(:user, email_on_comment_reply: true) + user2 = create(:user) + poll = create(:poll, author: create(:user)) + comment = create(:comment, commentable: poll, author: user1) + + login_as(user2) + visit poll_path(poll) + + click_link "Reply" + + within "#js-comment-form-comment_#{comment.id}" do + fill_in "comment-body-comment_#{comment.id}", with: 'It will be done next week.' + click_button 'Publish reply' + end + + within "#comment_#{comment.id}" do + expect(page).to have_content 'It will be done next week.' + end + + email = open_last_email + expect(email).to have_subject('Someone has responded to your comment') + expect(email).to deliver_to(user1) + expect(email).not_to have_body_text(poll_path(poll)) + expect(email).to have_body_text(comment_path(Comment.last)) + expect(email).to have_body_text(I18n.t("mailers.config.manage_email_subscriptions")) + expect(email).to have_body_text(account_path) + end + + end + context "Users without email" do scenario "should not receive emails", :js do user = create(:user, :verified, email_on_comment: true) diff --git a/spec/features/home_spec.rb b/spec/features/home_spec.rb index 4deed36bb..c88f2d590 100644 --- a/spec/features/home_spec.rb +++ b/spec/features/home_spec.rb @@ -3,20 +3,132 @@ require 'rails_helper' feature "Home" do feature "For not logged users" do + scenario 'Welcome message' do visit root_path expect(page).to have_content "Love the city, and it will become a city you love" end + + scenario 'Not display recommended section' do + debate = create(:debate) + + visit root_path + + expect(page).not_to have_content "Recommendations that may interest you" + end + end feature "For signed in users" do - scenario 'Redirect to proposals' do - login_as(create(:user)) - visit root_path - expect(current_path).to eq proposals_path + feature "Recommended" do + + background do + Setting['feature.user.recommendations'] = true + user = create(:user) + proposal = create(:proposal, tag_list: "Sport") + create(:follow, followable: proposal, user: user) + login_as(user) + end + + after do + Setting['feature.user.recommendations'] = nil + end + + scenario 'Display recommended section when feature flag recommended is active' do + debate = create(:debate, tag_list: "Sport") + visit root_path + expect(page).to have_content "Recommendations that may interest you" + end + + scenario 'Not display recommended section when feature flag recommended is not active' do + debate = create(:debate, tag_list: "Sport") + Setting['feature.user.recommendations'] = false + + visit root_path + + expect(page).not_to have_content "Recommendations that may interest you" + end + + scenario 'Display debates' do + debate = create(:debate, tag_list: "Sport") + + visit root_path + + expect(page).to have_content debate.title + expect(page).to have_content debate.description + end + + scenario 'Display all recommended debates link' do + debate = create(:debate, tag_list: "Sport") + visit root_path + expect(page).to have_link("All recommended debates", href: debates_path(order: "recommendations")) + end + + scenario 'Display proposal' do + proposal = create(:proposal, tag_list: "Sport") + + visit root_path + + expect(page).to have_content proposal.title + expect(page).to have_content proposal.description + end + + scenario 'Display all recommended proposals link' do + debate = create(:proposal, tag_list: "Sport") + visit root_path + expect(page).to have_link("All recommended proposals", href: proposals_path(order: "recommendations")) + end + + scenario 'Display orbit carrousel' do + create_list(:debate, 3, tag_list: "Sport") + + visit root_path + + expect(page).to have_selector('li[data-slide="0"]') + expect(page).to have_selector('li[data-slide="1"]', visible: false) + expect(page).to have_selector('li[data-slide="2"]', visible: false) + end + + scenario 'Display recommended show when click on carousel' do + debate = create(:debate, tag_list: "Sport") + + visit root_path + click_on debate.title + + expect(page).to have_current_path(debate_path(debate)) + end + + scenario 'Do not display recommended section when there are not debates and proposals' do + visit root_path + expect(page).not_to have_content "Recommendations that may interest you" + end + + feature 'Carousel size' do + + scenario 'Display debates centered when there are no proposals' do + debate = create(:debate, tag_list: "Sport") + visit root_path + expect(page).to have_selector('.medium-centered.large-centered') + end + + scenario 'Correct display debates and proposals' do + proposal = create(:proposal, tag_list: "Sport") + debates = create(:debate, tag_list: "Sport") + + visit root_path + + expect(page).to have_selector('.debates.medium-offset-2.large-offset-2') + expect(page).not_to have_selector('.proposals.medium-offset-2.large-offset-2') + expect(page).not_to have_selector('.debates.end') + expect(page).to have_selector('.proposals.end') + expect(page).not_to have_selector('.medium-centered.large-centered') + end + + end end + end feature 'IE alert' do diff --git a/spec/features/legislation/draft_versions_spec.rb b/spec/features/legislation/draft_versions_spec.rb index ea2cb854d..2effaa5d0 100644 --- a/spec/features/legislation/draft_versions_spec.rb +++ b/spec/features/legislation/draft_versions_spec.rb @@ -8,7 +8,7 @@ feature 'Legislation Draft Versions' do end context "See draft text page" do - before(:each) do + before do @process = create(:legislation_process) @draft_version_1 = create(:legislation_draft_version, process: @process, title: "Version 1", body: "Body of the first version", status: "published") @@ -26,7 +26,7 @@ feature 'Legislation Draft Versions' do within('select#draft_version_id') do expect(page).to have_content("Version 1") expect(page).to have_content("Version 2") - expect(page).to_not have_content("Version 3") + expect(page).not_to have_content("Version 3") end end @@ -51,7 +51,7 @@ feature 'Legislation Draft Versions' do select("Version 2") click_button "see" - expect(page).to_not have_content("Body of the first version") + expect(page).not_to have_content("Body of the first version") expect(page).to have_content("Body of the second version") end @@ -61,7 +61,7 @@ feature 'Legislation Draft Versions' do select("Version 2") - expect(page).to_not have_content("Body of the first version") + expect(page).not_to have_content("Body of the first version") expect(page).to have_content("Body of the second version") end @@ -73,14 +73,14 @@ feature 'Legislation Draft Versions' do visit legislation_process_draft_version_path(@process, final_version) expect(page).to have_content("Final body") - expect(page).to_not have_content("See all comments") - expect(page).to_not have_content("Comments") + expect(page).not_to have_content("See all comments") + expect(page).not_to have_content("Comments") end end end context "See changes page" do - before(:each) do + before do @process = create(:legislation_process) @draft_version_1 = create(:legislation_draft_version, process: @process, title: "Version 1", body: "Body of the first version", changelog: "Changes for first version", status: "published") @@ -98,7 +98,7 @@ feature 'Legislation Draft Versions' do within('select#draft_version_id') do expect(page).to have_content("Version 1") expect(page).to have_content("Version 2") - expect(page).to_not have_content("Version 3") + expect(page).not_to have_content("Version 3") end end @@ -123,7 +123,7 @@ feature 'Legislation Draft Versions' do select("Version 2") click_button "see" - expect(page).to_not have_content("Changes for first version") + expect(page).not_to have_content("Changes for first version") expect(page).to have_content("Changes for second version") end @@ -133,13 +133,14 @@ feature 'Legislation Draft Versions' do select("Version 2") - expect(page).to_not have_content("Changes for first version") + expect(page).not_to have_content("Changes for first version") expect(page).to have_content("Changes for second version") end end context 'Annotations', :js do let(:user) { create(:user) } + background { login_as user } scenario 'Visit as anonymous' do @@ -150,7 +151,7 @@ feature 'Legislation Draft Versions' do page.find(:css, ".legislation-annotatable").double_click page.find(:css, ".annotator-adder button").click - expect(page).to_not have_css('#legislation_annotation_text') + expect(page).not_to have_css('#legislation_annotation_text') expect(page).to have_content "You must Sign in or Sign up to leave a comment." end @@ -218,6 +219,7 @@ feature 'Legislation Draft Versions' do context "Merged annotations", :js do let(:user) { create(:user) } + background { login_as user } scenario 'View annotations and comments in an included range' do @@ -277,7 +279,7 @@ feature 'Legislation Draft Versions' do select("Version 2") click_button "see" - expect(page).to_not have_content("quote for version 1") + expect(page).not_to have_content("quote for version 1") expect(page).to have_content("quote for version 2") end @@ -287,7 +289,7 @@ feature 'Legislation Draft Versions' do select("Version 2") - expect(page).to_not have_content("quote for version 1") + expect(page).not_to have_content("quote for version 1") expect(page).to have_content("quote for version 2") end end @@ -305,8 +307,8 @@ feature 'Legislation Draft Versions' do scenario "See one annotation with replies for a draft version" do visit legislation_process_draft_version_annotation_path(@draft_version.process, @draft_version, @annotation) - expect(page).to_not have_content "ipsum" - expect(page).to_not have_content "my annotation" + expect(page).not_to have_content "ipsum" + expect(page).not_to have_content "my annotation" expect(page).to have_content "audiam" expect(page).to have_content "my other annotation" diff --git a/spec/features/legislation/processes_spec.rb b/spec/features/legislation/processes_spec.rb index 0ef5e0c7c..6dbc6f475 100644 --- a/spec/features/legislation/processes_spec.rb +++ b/spec/features/legislation/processes_spec.rb @@ -3,6 +3,7 @@ require 'rails_helper' feature 'Legislation' do let!(:administrator) { create(:administrator).user } + shared_examples "not published permissions" do |path| let(:not_published_process) { create(:legislation_process, :not_published, title: "Process not published") } @@ -12,7 +13,7 @@ feature 'Legislation' do visit send(path, not_published_process) expect(page).to have_content not_permission_message - expect(page).to_not have_content("Process not published") + expect(page).not_to have_content("Process not published") end it "is available for an administrator user" do @@ -25,7 +26,7 @@ feature 'Legislation' do context 'processes home page' do - scenario 'Processes can be listed' do + scenario 'No processes to be listed' do visit legislation_processes_path expect(page).to have_text "There aren't open processes" @@ -53,17 +54,17 @@ feature 'Legislation' do visit legislation_processes_path expect(page).to have_content('Process open') - expect(page).to_not have_content('Process next') - expect(page).to_not have_content('Process past') + expect(page).not_to have_content('Process next') + expect(page).not_to have_content('Process past') visit legislation_processes_path(filter: 'next') - expect(page).to_not have_content('Process open') + expect(page).not_to have_content('Process open') expect(page).to have_content('Process next') - expect(page).to_not have_content('Process past') + expect(page).not_to have_content('Process past') visit legislation_processes_path(filter: 'past') - expect(page).to_not have_content('Process open') - expect(page).to_not have_content('Process next') + expect(page).not_to have_content('Process open') + expect(page).not_to have_content('Process next') expect(page).to have_content('Process past') end @@ -79,34 +80,34 @@ feature 'Legislation' do it "aren't listed" do visit legislation_processes_path - expect(page).to_not have_content('not published') + expect(page).not_to have_content('not published') expect(page).to have_content('published') login_as(administrator) visit legislation_processes_path - expect(page).to_not have_content('not published') + expect(page).not_to have_content('not published') expect(page).to have_content('published') end it "aren't listed with next filter" do visit legislation_processes_path(filter: 'next') - expect(page).to_not have_content('not published') + expect(page).not_to have_content('not published') expect(page).to have_content('next published') login_as(administrator) visit legislation_processes_path(filter: 'next') - expect(page).to_not have_content('not published') + expect(page).not_to have_content('not published') expect(page).to have_content('next published') end it "aren't listed with past filter" do visit legislation_processes_path(filter: 'past') - expect(page).to_not have_content('not published') + expect(page).not_to have_content('not published') expect(page).to have_content('past published') login_as(administrator) visit legislation_processes_path(filter: 'past') - expect(page).to_not have_content('not published') + expect(page).not_to have_content('not published') expect(page).to have_content('past published') end end @@ -115,6 +116,14 @@ feature 'Legislation' do context 'process page' do context "show" do include_examples "not published permissions", :legislation_process_path + + scenario '#show view has document present' do + process = create(:legislation_process) + document = create(:document, documentable: process) + visit legislation_process_path(process) + + expect(page).to have_content(document.title) + end end context 'debate phase' do diff --git a/spec/features/legislation/proposals_spec.rb b/spec/features/legislation/proposals_spec.rb new file mode 100644 index 000000000..79eb9c386 --- /dev/null +++ b/spec/features/legislation/proposals_spec.rb @@ -0,0 +1,9 @@ +require 'rails_helper' + +feature 'Legislation Proposals' do + + context "Concerns" do + it_behaves_like 'notifiable in-app', Legislation::Proposal + end + +end diff --git a/spec/features/legislation/questions_spec.rb b/spec/features/legislation/questions_spec.rb index 17d55c16c..42e731fbf 100644 --- a/spec/features/legislation/questions_spec.rb +++ b/spec/features/legislation/questions_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' feature 'Legislation' do context 'process debate page' do - before(:each) do + before do @process = create(:legislation_process, debate_start_date: Date.current - 3.days, debate_end_date: Date.current + 2.days) create(:legislation_question, process: @process, title: "Question 1") create(:legislation_question, process: @process, title: "Question 2") @@ -31,7 +31,7 @@ feature 'Legislation' do click_link "Next question" expect(page).to have_content("Question 3") - expect(page).to_not have_content("Next question") + expect(page).not_to have_content("Next question") end scenario 'shows question page' do @@ -55,7 +55,7 @@ feature 'Legislation' do click_link "Next question" expect(page).to have_content("Question 3") - expect(page).to_not have_content("Next question") + expect(page).not_to have_content("Next question") end scenario 'answer question' do @@ -79,10 +79,10 @@ feature 'Legislation' do within(:css, "label.active") do expect(page).to have_content("I don't know") - expect(page).to_not have_content("Yes") - expect(page).to_not have_content("No") + expect(page).not_to have_content("Yes") + expect(page).not_to have_content("No") end - expect(page).to_not have_selector(:link_or_button, "Submit answer") + expect(page).not_to have_selector(:link_or_button, "Submit answer") expect(question.reload.answers_count).to eq(1) expect(option.reload.answers_count).to eq(1) @@ -104,7 +104,7 @@ feature 'Legislation' do expect(page).to have_selector(:radio_button, "No", disabled: true) expect(page).to have_selector(:radio_button, "I don't know", disabled: true) - expect(page).to_not have_selector(:link_or_button, "Submit answer") + expect(page).not_to have_selector(:link_or_button, "Submit answer") end end end diff --git a/spec/features/localization_spec.rb b/spec/features/localization_spec.rb index 2296aeb6c..5c6098481 100644 --- a/spec/features/localization_spec.rb +++ b/spec/features/localization_spec.rb @@ -29,15 +29,15 @@ feature 'Localization' do select('Español', from: 'locale-switcher') expect(page).to have_content('Idioma') - expect(page).to_not have_content('Language') + expect(page).not_to have_content('Language') expect(page).to have_select('locale-switcher', selected: 'Español') end scenario 'Locale switcher not present if only one locale' do - expect(I18n).to receive(:available_locales).and_return([:en]) + allow(I18n).to receive(:available_locales).and_return([:en]) visit '/' - expect(page).to_not have_content('Language') - expect(page).to_not have_css('div.locale') + expect(page).not_to have_content('Language') + expect(page).not_to have_css('div.locale') end end diff --git a/spec/features/management/budget_investments_spec.rb b/spec/features/management/budget_investments_spec.rb index f0fbbefe3..5a9fa2813 100644 --- a/spec/features/management/budget_investments_spec.rb +++ b/spec/features/management/budget_investments_spec.rb @@ -32,7 +32,6 @@ feature 'Budget Investments' do select "Whole city: Health", from: 'budget_investment_heading_id' fill_in 'budget_investment_title', with: 'Build a park in my neighborhood' fill_in 'budget_investment_description', with: 'There is no parks here...' - fill_in 'budget_investment_external_url', with: 'http://moarparks.com' fill_in 'budget_investment_location', with: 'City center' fill_in 'budget_investment_organization_name', with: 'T.I.A.' fill_in 'budget_investment_tag_list', with: 'green' @@ -44,7 +43,6 @@ feature 'Budget Investments' do expect(page).to have_content 'Health' expect(page).to have_content 'Build a park in my neighborhood' expect(page).to have_content 'There is no parks here...' - expect(page).to have_content 'http://moarparks.com' expect(page).to have_content 'City center' expect(page).to have_content 'T.I.A.' expect(page).to have_content 'green' @@ -83,7 +81,7 @@ feature 'Budget Investments' do within("#budget-investments") do expect(page).to have_css('.budget-investment', count: 1) expect(page).to have_content(budget_investment1.title) - expect(page).to_not have_content(budget_investment2.title) + expect(page).not_to have_content(budget_investment2.title) expect(page).to have_css("a[href='#{management_budget_investment_path(@budget, budget_investment1)}']", text: budget_investment1.title) end @@ -109,7 +107,7 @@ feature 'Budget Investments' do within("#budget-investments") do expect(page).to have_css('.budget-investment', count: 1) - expect(page).to_not have_content(budget_investment1.title) + expect(page).not_to have_content(budget_investment1.title) expect(page).to have_content(budget_investment2.title) expect(page).to have_css("a[href='#{management_budget_investment_path(@budget, budget_investment2)}']", text: budget_investment2.title) @@ -162,12 +160,12 @@ feature 'Budget Investments' do expect(page).to have_content(accepting_budget.name) - expect(page).to_not have_content(reviewing_budget.name) - expect(page).to_not have_content(selecting_budget.name) - expect(page).to_not have_content(valuating_budget.name) - expect(page).to_not have_content(balloting_budget.name) - expect(page).to_not have_content(reviewing_ballots_budget.name) - expect(page).to_not have_content(finished.name) + expect(page).not_to have_content(reviewing_budget.name) + expect(page).not_to have_content(selecting_budget.name) + expect(page).not_to have_content(valuating_budget.name) + expect(page).not_to have_content(balloting_budget.name) + expect(page).not_to have_content(reviewing_ballots_budget.name) + expect(page).not_to have_content(finished.name) end scenario "Listing - admins can see budgets in accepting, reviewing and selecting phases" do @@ -195,10 +193,10 @@ feature 'Budget Investments' do expect(page).to have_content(reviewing_budget.name) expect(page).to have_content(selecting_budget.name) - expect(page).to_not have_content(valuating_budget.name) - expect(page).to_not have_content(balloting_budget.name) - expect(page).to_not have_content(reviewing_ballots_budget.name) - expect(page).to_not have_content(finished.name) + expect(page).not_to have_content(valuating_budget.name) + expect(page).not_to have_content(balloting_budget.name) + expect(page).not_to have_content(reviewing_ballots_budget.name) + expect(page).not_to have_content(finished.name) end context "Supporting" do @@ -275,10 +273,10 @@ feature 'Budget Investments' do scenario "Filtering budget investments by heading to be printed", :js do district_9 = create(:budget_heading, group: @group, name: "District Nine") - create(:budget_investment, budget: @budget, title: 'Change district 9', heading: district_9, cached_votes_up: 10) - create(:budget_investment, budget: @budget, title: 'Destroy district 9', heading: district_9, cached_votes_up: 100) - create(:budget_investment, budget: @budget, title: 'Nuke district 9', heading: district_9, cached_votes_up: 1) - create(:budget_investment, budget: @budget, title: 'Add new districts to the city') + low_investment = create(:budget_investment, budget: @budget, title: 'Nuke district 9', heading: district_9, cached_votes_up: 1) + mid_investment = create(:budget_investment, budget: @budget, title: 'Change district 9', heading: district_9, cached_votes_up: 10) + top_investment = create(:budget_investment, budget: @budget, title: 'Destroy district 9', heading: district_9, cached_votes_up: 100) + unvoted_investment = create(:budget_investment, budget: @budget, title: 'Add new districts to the city') user = create(:user, :level_two) login_managed_user(user) @@ -290,19 +288,19 @@ feature 'Budget Investments' do end within '#budget-investments' do - expect(page).to have_content('Add new districts to the city') - expect(page).to have_content('Change district 9') - expect(page).to have_content('Destroy district 9') - expect(page).to have_content('Nuke district 9') + expect(page).to have_content(unvoted_investment.title) + expect(page).to have_content(mid_investment.title) + expect(page).to have_content(top_investment.title) + expect(page).to have_content(low_investment.title) end select 'Whole city: District Nine', from: 'heading_id' click_button("Search") within '#budget-investments' do - expect(page).to_not have_content('Add new districts to the city') - expect('Destroy district 9').to appear_before('Change district 9') - expect('Change district 9').to appear_before('Nuke district 9') + expect(page).not_to have_content(unvoted_investment.title) + expect(top_investment.title).to appear_before(mid_investment.title) + expect(mid_investment.title).to appear_before(low_investment.title) end end diff --git a/spec/features/management/email_verifications_spec.rb b/spec/features/management/email_verifications_spec.rb index d68d9bd5f..a5bd4d40e 100644 --- a/spec/features/management/email_verifications_spec.rb +++ b/spec/features/management/email_verifications_spec.rb @@ -27,7 +27,7 @@ feature 'EmailVerifications' do expect(page).to have_content "You are a verified user" - expect(page).to_not have_link "Verify my account" + expect(page).not_to have_link "Verify my account" expect(page).to have_content "Account verified" expect(user.reload.document_number).to eq('12345678Z') diff --git a/spec/features/management/localization_spec.rb b/spec/features/management/localization_spec.rb index ba4d7f27f..dacff366e 100644 --- a/spec/features/management/localization_spec.rb +++ b/spec/features/management/localization_spec.rb @@ -34,15 +34,15 @@ feature 'Localization' do select('Español', from: 'locale-switcher') expect(page).to have_content('Idioma') - expect(page).to_not have_content('Language') + expect(page).not_to have_content('Language') expect(page).to have_select('locale-switcher', selected: 'Español') end scenario 'Locale switcher not present if only one locale' do - expect(I18n).to receive(:available_locales).and_return([:en]) + allow(I18n).to receive(:available_locales).and_return([:en]) visit management_root_path - expect(page).to_not have_content('Language') - expect(page).to_not have_css('div.locale') + expect(page).not_to have_content('Language') + expect(page).not_to have_css('div.locale') end -end \ No newline at end of file +end diff --git a/spec/features/management/managed_users_spec.rb b/spec/features/management/managed_users_spec.rb index ef3c539d9..3bd429e0f 100644 --- a/spec/features/management/managed_users_spec.rb +++ b/spec/features/management/managed_users_spec.rb @@ -24,9 +24,9 @@ feature 'Managed User' do within(".account-info") do expect(page).to have_content "Identified as" - expect(page).to have_content (user.username).to_s - expect(page).to have_content (user.email).to_s - expect(page).to have_content (user.document_number).to_s + expect(page).to have_content user.username.to_s + expect(page).to have_content user.email.to_s + expect(page).to have_content user.document_number.to_s end end @@ -45,9 +45,9 @@ feature 'Managed User' do within(".account-info") do expect(page).to have_content "Identified as" - expect(page).to have_content (user.username).to_s - expect(page).to have_content (user.email).to_s - expect(page).to have_content (user.document_number).to_s + expect(page).to have_content user.username.to_s + expect(page).to have_content user.email.to_s + expect(page).to have_content user.document_number.to_s end end @@ -78,9 +78,9 @@ feature 'Managed User' do within(".account-info") do expect(page).to have_content "Identified as" - expect(page).to have_content (user.username).to_s - expect(page).to have_content (user.email).to_s - expect(page).to have_content (user.document_number).to_s + expect(page).to have_content user.username.to_s + expect(page).to have_content user.email.to_s + expect(page).to have_content user.document_number.to_s end end @@ -101,14 +101,14 @@ feature 'Managed User' do click_button 'Create user' expect(page).to have_content "We have sent an email" - expect(page).to_not have_content "Autogenerated password is" + expect(page).not_to have_content "Autogenerated password is" user = User.last within(".account-info") do expect(page).to have_content "Identified as" - expect(page).to have_content (user.username).to_s - expect(page).to have_content (user.email).to_s - expect(page).to have_content (user.document_number).to_s + expect(page).to have_content user.username.to_s + expect(page).to have_content user.email.to_s + expect(page).to have_content user.document_number.to_s end end @@ -128,14 +128,14 @@ feature 'Managed User' do click_button 'Create user' - expect(page).to_not have_content "We have sent an email" + expect(page).not_to have_content "We have sent an email" expect(page).to have_content "Autogenerated password is" user = User.last within(".account-info") do expect(page).to have_content "Identified as" - expect(page).to have_content (user.username).to_s - expect(page).to have_content (user.document_number).to_s + expect(page).to have_content user.username.to_s + expect(page).to have_content user.document_number.to_s end end end @@ -151,15 +151,15 @@ feature 'Managed User' do within(".account-info") do expect(page).to have_content "Identified as" - expect(page).to have_content (user.username).to_s + expect(page).to have_content user.username.to_s click_link "Change user" end expect(page).to have_content "User session signed out successfully." - expect(page).to_not have_content "Identified as" - expect(page).to_not have_content (user.username).to_s - expect(current_path).to eq(management_root_path) + expect(page).not_to have_content "Identified as" + expect(page).not_to have_content user.username.to_s + expect(page).to have_current_path(management_root_path) end -end \ No newline at end of file +end diff --git a/spec/features/management/proposals_spec.rb b/spec/features/management/proposals_spec.rb index 349a4f904..02eaa18c1 100644 --- a/spec/features/management/proposals_spec.rb +++ b/spec/features/management/proposals_spec.rb @@ -16,9 +16,9 @@ feature 'Proposals' do within(".account-info") do expect(page).to have_content "Identified as" - expect(page).to have_content (user.username).to_s - expect(page).to have_content (user.email).to_s - expect(page).to have_content (user.document_number).to_s + expect(page).to have_content user.username.to_s + expect(page).to have_content user.email.to_s + expect(page).to have_content user.document_number.to_s end fill_in 'proposal_title', with: 'Help refugees' @@ -42,7 +42,7 @@ feature 'Proposals' do expect(page).to have_content user.name expect(page).to have_content I18n.l(Proposal.last.created_at.to_date) - expect(current_path).to eq(management_proposal_path(Proposal.last)) + expect(page).to have_current_path(management_proposal_path(Proposal.last)) end scenario "Should not allow unverified users to create proposals" do @@ -65,7 +65,7 @@ feature 'Proposals' do right_path = management_proposal_path(proposal) visit right_path - expect(current_path).to eq(right_path) + expect(page).to have_current_path(right_path) end scenario 'When path does not match the friendly url' do @@ -78,8 +78,8 @@ feature 'Proposals' do old_path = "#{management_proposals_path}/#{proposal.id}-something-else" visit old_path - expect(current_path).to_not eq(old_path) - expect(current_path).to eq(right_path) + expect(page).not_to have_current_path(old_path) + expect(page).to have_current_path(right_path) end end @@ -95,13 +95,13 @@ feature 'Proposals' do fill_in "search", with: "what you got" click_button "Search" - expect(current_path).to eq(management_proposals_path) + expect(page).to have_current_path(management_proposals_path, only_path: true) within(".proposals-list") do expect(page).to have_css('.proposal', count: 1) expect(page).to have_content(proposal1.title) expect(page).to have_content(proposal1.summary) - expect(page).to_not have_content(proposal2.title) + expect(page).not_to have_content(proposal2.title) expect(page).to have_css("a[href='#{management_proposal_path(proposal1)}']", text: proposal1.title) end end @@ -115,13 +115,13 @@ feature 'Proposals' do click_link "Support proposals" - expect(current_path).to eq(management_proposals_path) + expect(page).to have_current_path(management_proposals_path) within(".account-info") do expect(page).to have_content "Identified as" - expect(page).to have_content (user.username).to_s - expect(page).to have_content (user.email).to_s - expect(page).to have_content (user.document_number).to_s + expect(page).to have_content user.username.to_s + expect(page).to have_content user.email.to_s + expect(page).to have_content user.document_number.to_s end within(".proposals-list") do @@ -149,7 +149,7 @@ feature 'Proposals' do expect(page).to have_content "1 support" expect(page).to have_content "You have already supported this proposal. Share it!" end - expect(current_path).to eq(management_proposals_path) + expect(page).to have_current_path(management_proposals_path) end scenario 'Voting proposals on behalf of someone in show view', :js do @@ -167,7 +167,7 @@ feature 'Proposals' do find('.in-favor a').click expect(page).to have_content "1 support" expect(page).to have_content "You have already supported this proposal. Share it!" - expect(current_path).to eq(management_proposal_path(proposal)) + expect(page).to have_current_path(management_proposal_path(proposal)) end scenario "Should not allow unverified users to vote proposals" do @@ -194,9 +194,12 @@ feature 'Proposals' do end scenario "Filtering proposals to be printed", :js do - create(:proposal, title: 'Worst proposal').update_column(:confidence_score, 2) - create(:proposal, title: 'Best proposal').update_column(:confidence_score, 10) - create(:proposal, title: 'Medium proposal').update_column(:confidence_score, 5) + worst_proposal = create(:proposal, title: 'Worst proposal') + worst_proposal.update_column(:confidence_score, 2) + best_proposal = create(:proposal, title: 'Best proposal') + best_proposal.update_column(:confidence_score, 10) + medium_proposal = create(:proposal, title: 'Medium proposal') + medium_proposal.update_column(:confidence_score, 5) user = create(:user, :level_two) login_managed_user(user) @@ -206,8 +209,8 @@ feature 'Proposals' do expect(page).to have_selector('.js-order-selector[data-order="confidence_score"]') within(".proposals-list") do - expect('Best proposal').to appear_before('Medium proposal') - expect('Medium proposal').to appear_before('Worst proposal') + expect(best_proposal.title).to appear_before(medium_proposal.title) + expect(medium_proposal.title).to appear_before(worst_proposal.title) end select 'newest', from: 'order-selector' @@ -218,8 +221,8 @@ feature 'Proposals' do expect(current_url).to include('page=1') within(".proposals-list") do - expect('Medium proposal').to appear_before('Best proposal') - expect('Best proposal').to appear_before('Worst proposal') + expect(medium_proposal.title).to appear_before(best_proposal.title) + expect(best_proposal.title).to appear_before(worst_proposal.title) end end diff --git a/spec/features/management/users_spec.rb b/spec/features/management/users_spec.rb index f50728bfc..0761c3136 100644 --- a/spec/features/management/users_spec.rb +++ b/spec/features/management/users_spec.rb @@ -22,14 +22,14 @@ feature 'Users' do click_button 'Create user' expect(page).to have_content "We have sent an email" - expect(page).to_not have_content "Autogenerated password is" + expect(page).not_to have_content "Autogenerated password is" user = User.find_by(email: 'pepe@gmail.com') expect(user).to be_level_three_verified expect(user).to be_residence_verified - expect(user).to_not be_confirmed - expect(user.date_of_birth).to have_content (Date.new(1980, 12, 31)) + expect(user).not_to be_confirmed + expect(user.date_of_birth).to have_content Date.new(1980, 12, 31) sent_token = /.*confirmation_token=(.*)".*/.match(ActionMailer::Base.deliveries.last.body.to_s)[1] visit user_confirmation_path(confirmation_token: sent_token) @@ -61,7 +61,7 @@ feature 'Users' do click_button 'Create user' - expect(page).to_not have_content "We have sent an email" + expect(page).not_to have_content "We have sent an email" expect(page).to have_content "Autogenerated password is" user = User.find_by(username: 'Kelly Sue') @@ -69,7 +69,7 @@ feature 'Users' do expect(user).to be_level_three_verified expect(user).to be_residence_verified expect(user).to be_confirmed - expect(user.date_of_birth).to have_content (Date.new(1980, 12, 31)) + expect(user.date_of_birth).to have_content Date.new(1980, 12, 31) end scenario 'Delete a level 2 user account from document verification page', :js do @@ -79,7 +79,7 @@ feature 'Users' do fill_in 'document_verification_document_number', with: '12345678Z' click_button 'Check' - expect(page).to_not have_content "This user account is already verified." + expect(page).not_to have_content "This user account is already verified." expect(page).to have_content "This user can participate in the website with the following permissions" click_link "Delete user" diff --git a/spec/features/moderation/comments_spec.rb b/spec/features/moderation/comments_spec.rb index dc3604c3a..72f1f55f9 100644 --- a/spec/features/moderation/comments_spec.rb +++ b/spec/features/moderation/comments_spec.rb @@ -20,8 +20,8 @@ feature 'Moderate comments' do visit debate_path(comment.commentable) expect(page).to have_css('.comment', count: 1) - expect(page).to_not have_content('This comment has been deleted') - expect(page).to_not have_content('SPAM') + expect(page).not_to have_content('This comment has been deleted') + expect(page).not_to have_content('SPAM') end scenario 'Can not hide own comment' do @@ -32,8 +32,8 @@ feature 'Moderate comments' do visit debate_path(comment.commentable) within("#comment_#{comment.id}") do - expect(page).to_not have_link('Hide') - expect(page).to_not have_link('Block author') + expect(page).not_to have_link('Hide') + expect(page).not_to have_link('Block author') end end @@ -57,29 +57,29 @@ feature 'Moderate comments' do check "comment_#{@comment.id}_check" end - expect(page).to_not have_css("comment_#{@comment.id}") + expect(page).not_to have_css("comment_#{@comment.id}") end scenario 'Hide the comment' do click_on "Hide comments" - expect(page).to_not have_css("comment_#{@comment.id}") + expect(page).not_to have_css("comment_#{@comment.id}") expect(@comment.reload).to be_hidden - expect(@comment.user).to_not be_hidden + expect(@comment.user).not_to be_hidden end scenario 'Block the user' do click_on "Block authors" - expect(page).to_not have_css("comment_#{@comment.id}") + expect(page).not_to have_css("comment_#{@comment.id}") expect(@comment.reload).to be_hidden expect(@comment.user).to be_hidden end scenario 'Ignore the comment' do click_on "Mark as viewed" - expect(page).to_not have_css("comment_#{@comment.id}") + expect(page).not_to have_css("comment_#{@comment.id}") expect(@comment.reload).to be_ignored_flag - expect(@comment.reload).to_not be_hidden - expect(@comment.user).to_not be_hidden + expect(@comment.reload).not_to be_hidden + expect(@comment.user).not_to be_hidden end end @@ -90,14 +90,12 @@ feature 'Moderate comments' do within('.js-check') { click_on 'All' } - all('input[type=checkbox]').each do |checkbox| - expect(checkbox).to be_checked - end + expect(all('input[type=checkbox]')).to all(be_checked) within('.js-check') { click_on 'None' } all('input[type=checkbox]').each do |checkbox| - expect(checkbox).to_not be_checked + expect(checkbox).not_to be_checked end end @@ -118,13 +116,13 @@ feature 'Moderate comments' do scenario "Current filter is properly highlighted" do visit moderation_comments_path - expect(page).to_not have_link('Pending') + expect(page).not_to have_link('Pending') expect(page).to have_link('All') expect(page).to have_link('Marked as viewed') visit moderation_comments_path(filter: 'all') within('.menu.simple') do - expect(page).to_not have_link('All') + expect(page).not_to have_link('All') expect(page).to have_link('Pending') expect(page).to have_link('Marked as viewed') end @@ -132,7 +130,7 @@ feature 'Moderate comments' do visit moderation_comments_path(filter: 'pending_flag_review') within('.menu.simple') do expect(page).to have_link('All') - expect(page).to_not have_link('Pending') + expect(page).not_to have_link('Pending') expect(page).to have_link('Marked as viewed') end @@ -140,7 +138,7 @@ feature 'Moderate comments' do within('.menu.simple') do expect(page).to have_link('All') expect(page).to have_link('Pending') - expect(page).to_not have_link('Marked as viewed') + expect(page).not_to have_link('Marked as viewed') end end @@ -153,44 +151,44 @@ feature 'Moderate comments' do visit moderation_comments_path(filter: 'all') expect(page).to have_content('Regular comment') expect(page).to have_content('Pending comment') - expect(page).to_not have_content('Hidden comment') + expect(page).not_to have_content('Hidden comment') expect(page).to have_content('Ignored comment') visit moderation_comments_path(filter: 'pending_flag_review') - expect(page).to_not have_content('Regular comment') + expect(page).not_to have_content('Regular comment') expect(page).to have_content('Pending comment') - expect(page).to_not have_content('Hidden comment') - expect(page).to_not have_content('Ignored comment') + expect(page).not_to have_content('Hidden comment') + expect(page).not_to have_content('Ignored comment') visit moderation_comments_path(filter: 'with_ignored_flag') - expect(page).to_not have_content('Regular comment') - expect(page).to_not have_content('Pending comment') - expect(page).to_not have_content('Hidden comment') + expect(page).not_to have_content('Regular comment') + expect(page).not_to have_content('Pending comment') + expect(page).not_to have_content('Hidden comment') expect(page).to have_content('Ignored comment') end scenario "sorting comments" do - create(:comment, body: "Flagged comment", created_at: Time.current - 1.day, flags_count: 5) - create(:comment, body: "Flagged newer comment", created_at: Time.current - 12.hours, flags_count: 3) - create(:comment, body: "Newer comment", created_at: Time.current) + flagged_comment = create(:comment, body: "Flagged comment", created_at: Time.current - 1.day, flags_count: 5) + flagged_new_comment = create(:comment, body: "Flagged new comment", created_at: Time.current - 12.hours, flags_count: 3) + newer_comment = create(:comment, body: "Newer comment", created_at: Time.current) visit moderation_comments_path(order: 'newest') - expect("Flagged newer comment").to appear_before("Flagged comment") + expect(flagged_new_comment.body).to appear_before(flagged_comment.body) visit moderation_comments_path(order: 'flags') - expect("Flagged comment").to appear_before("Flagged newer comment") + expect(flagged_comment.body).to appear_before(flagged_new_comment.body) visit moderation_comments_path(filter: 'all', order: 'newest') - expect("Newer comment").to appear_before("Flagged newer comment") - expect("Flagged newer comment").to appear_before("Flagged comment") + expect(newer_comment.body).to appear_before(flagged_new_comment.body) + expect(flagged_new_comment.body).to appear_before(flagged_comment.body) visit moderation_comments_path(filter: 'all', order: 'flags') - expect("Flagged comment").to appear_before("Flagged newer comment") - expect("Flagged newer comment").to appear_before("Newer comment") + expect(flagged_comment.body).to appear_before(flagged_new_comment.body) + expect(flagged_new_comment.body).to appear_before(newer_comment.body) end end end diff --git a/spec/features/moderation/debates_spec.rb b/spec/features/moderation/debates_spec.rb index 5a74dd976..b31d361b4 100644 --- a/spec/features/moderation/debates_spec.rb +++ b/spec/features/moderation/debates_spec.rb @@ -41,8 +41,8 @@ feature 'Moderate debates' do visit debate_path(debate) within("#debate_#{debate.id}") do - expect(page).to_not have_link('Hide') - expect(page).to_not have_link('Block author') + expect(page).not_to have_link('Hide') + expect(page).not_to have_link('Block author') end end @@ -66,29 +66,29 @@ feature 'Moderate debates' do check "debate_#{@debate.id}_check" end - expect(page).to_not have_css("debate_#{@debate.id}") + expect(page).not_to have_css("debate_#{@debate.id}") end scenario 'Hide the debate' do click_on "Hide debates" - expect(page).to_not have_css("debate_#{@debate.id}") + expect(page).not_to have_css("debate_#{@debate.id}") expect(@debate.reload).to be_hidden - expect(@debate.author).to_not be_hidden + expect(@debate.author).not_to be_hidden end scenario 'Block the author' do click_on "Block authors" - expect(page).to_not have_css("debate_#{@debate.id}") + expect(page).not_to have_css("debate_#{@debate.id}") expect(@debate.reload).to be_hidden expect(@debate.author).to be_hidden end scenario 'Ignore the debate' do click_on "Mark as viewed" - expect(page).to_not have_css("debate_#{@debate.id}") + expect(page).not_to have_css("debate_#{@debate.id}") expect(@debate.reload).to be_ignored_flag - expect(@debate.reload).to_not be_hidden - expect(@debate.author).to_not be_hidden + expect(@debate.reload).not_to be_hidden + expect(@debate.author).not_to be_hidden end end @@ -99,14 +99,12 @@ feature 'Moderate debates' do within('.js-check') { click_on 'All' } - all('input[type=checkbox]').each do |checkbox| - expect(checkbox).to be_checked - end + expect(all('input[type=checkbox]')).to all(be_checked) within('.js-check') { click_on 'None' } all('input[type=checkbox]').each do |checkbox| - expect(checkbox).to_not be_checked + expect(checkbox).not_to be_checked end end @@ -127,13 +125,13 @@ feature 'Moderate debates' do scenario "Current filter is properly highlighted" do visit moderation_debates_path - expect(page).to_not have_link('Pending') + expect(page).not_to have_link('Pending') expect(page).to have_link('All') expect(page).to have_link('Marked as viewed') visit moderation_debates_path(filter: 'all') within('.menu.simple') do - expect(page).to_not have_link('All') + expect(page).not_to have_link('All') expect(page).to have_link('Pending') expect(page).to have_link('Marked as viewed') end @@ -141,7 +139,7 @@ feature 'Moderate debates' do visit moderation_debates_path(filter: 'pending_flag_review') within('.menu.simple') do expect(page).to have_link('All') - expect(page).to_not have_link('Pending') + expect(page).not_to have_link('Pending') expect(page).to have_link('Marked as viewed') end @@ -149,7 +147,7 @@ feature 'Moderate debates' do within('.menu.simple') do expect(page).to have_link('All') expect(page).to have_link('Pending') - expect(page).to_not have_link('Marked as viewed') + expect(page).not_to have_link('Marked as viewed') end end @@ -162,44 +160,44 @@ feature 'Moderate debates' do visit moderation_debates_path(filter: 'all') expect(page).to have_content('Regular debate') expect(page).to have_content('Pending debate') - expect(page).to_not have_content('Hidden debate') + expect(page).not_to have_content('Hidden debate') expect(page).to have_content('Ignored debate') visit moderation_debates_path(filter: 'pending_flag_review') - expect(page).to_not have_content('Regular debate') + expect(page).not_to have_content('Regular debate') expect(page).to have_content('Pending debate') - expect(page).to_not have_content('Hidden debate') - expect(page).to_not have_content('Ignored debate') + expect(page).not_to have_content('Hidden debate') + expect(page).not_to have_content('Ignored debate') visit moderation_debates_path(filter: 'with_ignored_flag') - expect(page).to_not have_content('Regular debate') - expect(page).to_not have_content('Pending debate') - expect(page).to_not have_content('Hidden debate') + expect(page).not_to have_content('Regular debate') + expect(page).not_to have_content('Pending debate') + expect(page).not_to have_content('Hidden debate') expect(page).to have_content('Ignored debate') end scenario "sorting debates" do - create(:debate, title: "Flagged debate", created_at: Time.current - 1.day, flags_count: 5) - create(:debate, title: "Flagged newer debate", created_at: Time.current - 12.hours, flags_count: 3) - create(:debate, title: "Newer debate", created_at: Time.current) + flagged_debate = create(:debate, title: "Flagged debate", created_at: Time.current - 1.day, flags_count: 5) + flagged_new_debate = create(:debate, title: "Flagged new debate", created_at: Time.current - 12.hours, flags_count: 3) + newer_debate = create(:debate, title: "Newer debate", created_at: Time.current) visit moderation_debates_path(order: 'created_at') - expect("Flagged newer debate").to appear_before("Flagged debate") + expect(flagged_new_debate.title).to appear_before(flagged_debate.title) visit moderation_debates_path(order: 'flags') - expect("Flagged debate").to appear_before("Flagged newer debate") + expect(flagged_debate.title).to appear_before(flagged_new_debate.title) visit moderation_debates_path(filter: 'all', order: 'created_at') - expect("Newer debate").to appear_before("Flagged newer debate") - expect("Flagged newer debate").to appear_before("Flagged debate") + expect(newer_debate.title).to appear_before(flagged_new_debate.title) + expect(flagged_new_debate.title).to appear_before(flagged_debate.title) visit moderation_debates_path(filter: 'all', order: 'flags') - expect("Flagged debate").to appear_before("Flagged newer debate") - expect("Flagged newer debate").to appear_before("Newer debate") + expect(flagged_debate.title).to appear_before(flagged_new_debate.title) + expect(flagged_new_debate.title).to appear_before(newer_debate.title) end end end diff --git a/spec/features/moderation/proposals_spec.rb b/spec/features/moderation/proposals_spec.rb index ab8da4764..60ea01dbc 100644 --- a/spec/features/moderation/proposals_spec.rb +++ b/spec/features/moderation/proposals_spec.rb @@ -2,6 +2,16 @@ require 'rails_helper' feature 'Moderate proposals' do + scenario 'Disabled with a feature flag' do + Setting['feature.proposals'] = nil + moderator = create(:moderator) + login_as(moderator.user) + + expect{ visit moderation_proposals_path }.to raise_exception(FeatureFlags::FeatureDisabled) + + Setting['feature.proposals'] = true + end + scenario 'Hide', :js do citizen = create(:user) moderator = create(:moderator) @@ -31,8 +41,8 @@ feature 'Moderate proposals' do visit proposal_path(proposal) within("#proposal_#{proposal.id}") do - expect(page).to_not have_link('Hide') - expect(page).to_not have_link('Block author') + expect(page).not_to have_link('Hide') + expect(page).not_to have_link('Block author') end end @@ -56,29 +66,29 @@ feature 'Moderate proposals' do check "proposal_#{@proposal.id}_check" end - expect(page).to_not have_css("proposal_#{@proposal.id}") + expect(page).not_to have_css("proposal_#{@proposal.id}") end scenario 'Hide the proposal' do click_on "Hide proposals" - expect(page).to_not have_css("proposal_#{@proposal.id}") + expect(page).not_to have_css("proposal_#{@proposal.id}") expect(@proposal.reload).to be_hidden - expect(@proposal.author).to_not be_hidden + expect(@proposal.author).not_to be_hidden end scenario 'Block the author' do click_on "Block authors" - expect(page).to_not have_css("proposal_#{@proposal.id}") + expect(page).not_to have_css("proposal_#{@proposal.id}") expect(@proposal.reload).to be_hidden expect(@proposal.author).to be_hidden end scenario 'Ignore the proposal' do click_button "Mark as viewed" - expect(page).to_not have_css("proposal_#{@proposal.id}") + expect(page).not_to have_css("proposal_#{@proposal.id}") expect(@proposal.reload).to be_ignored_flag - expect(@proposal.reload).to_not be_hidden - expect(@proposal.author).to_not be_hidden + expect(@proposal.reload).not_to be_hidden + expect(@proposal.author).not_to be_hidden end end @@ -89,14 +99,12 @@ feature 'Moderate proposals' do within('.js-check') { click_on 'All' } - all('input[type=checkbox]').each do |checkbox| - expect(checkbox).to be_checked - end + expect(all('input[type=checkbox]')).to all(be_checked) within('.js-check') { click_on 'None' } all('input[type=checkbox]').each do |checkbox| - expect(checkbox).to_not be_checked + expect(checkbox).not_to be_checked end end @@ -117,13 +125,13 @@ feature 'Moderate proposals' do scenario "Current filter is properly highlighted" do visit moderation_proposals_path - expect(page).to_not have_link('Pending') + expect(page).not_to have_link('Pending') expect(page).to have_link('All') expect(page).to have_link('Mark as viewed') visit moderation_proposals_path(filter: 'all') within('.menu.simple') do - expect(page).to_not have_link('All') + expect(page).not_to have_link('All') expect(page).to have_link('Pending review') expect(page).to have_link('Mark as viewed') end @@ -131,7 +139,7 @@ feature 'Moderate proposals' do visit moderation_proposals_path(filter: 'pending_flag_review') within('.menu.simple') do expect(page).to have_link('All') - expect(page).to_not have_link('Pending') + expect(page).not_to have_link('Pending') expect(page).to have_link('Mark as viewed') end @@ -139,7 +147,7 @@ feature 'Moderate proposals' do within('.menu.simple') do expect(page).to have_link('All') expect(page).to have_link('Pending review') - expect(page).to_not have_link('Marked as viewed') + expect(page).not_to have_link('Marked as viewed') end end @@ -152,44 +160,44 @@ feature 'Moderate proposals' do visit moderation_proposals_path(filter: 'all') expect(page).to have_content('Regular proposal') expect(page).to have_content('Pending proposal') - expect(page).to_not have_content('Hidden proposal') + expect(page).not_to have_content('Hidden proposal') expect(page).to have_content('Ignored proposal') visit moderation_proposals_path(filter: 'pending_flag_review') - expect(page).to_not have_content('Regular proposal') + expect(page).not_to have_content('Regular proposal') expect(page).to have_content('Pending proposal') - expect(page).to_not have_content('Hidden proposal') - expect(page).to_not have_content('Ignored proposal') + expect(page).not_to have_content('Hidden proposal') + expect(page).not_to have_content('Ignored proposal') visit moderation_proposals_path(filter: 'with_ignored_flag') - expect(page).to_not have_content('Regular proposal') - expect(page).to_not have_content('Pending proposal') - expect(page).to_not have_content('Hidden proposal') + expect(page).not_to have_content('Regular proposal') + expect(page).not_to have_content('Pending proposal') + expect(page).not_to have_content('Hidden proposal') expect(page).to have_content('Ignored proposal') end scenario "sorting proposals" do - create(:proposal, title: "Flagged proposal", created_at: Time.current - 1.day, flags_count: 5) - create(:proposal, title: "Flagged newer proposal", created_at: Time.current - 12.hours, flags_count: 3) - create(:proposal, title: "Newer proposal", created_at: Time.current) + flagged_proposal = create(:proposal, title: "Flagged proposal", created_at: Time.current - 1.day, flags_count: 5) + flagged_new_proposal = create(:proposal, title: "Flagged new proposal", created_at: Time.current - 12.hours, flags_count: 3) + newer_proposal = create(:proposal, title: "Newer proposal", created_at: Time.current) visit moderation_proposals_path(order: 'created_at') - expect("Flagged newer proposal").to appear_before("Flagged proposal") + expect(flagged_new_proposal.title).to appear_before(flagged_proposal.title) visit moderation_proposals_path(order: 'flags') - expect("Flagged proposal").to appear_before("Flagged newer proposal") + expect(flagged_proposal.title).to appear_before(flagged_new_proposal.title) visit moderation_proposals_path(filter: 'all', order: 'created_at') - expect("Newer proposal").to appear_before("Flagged newer proposal") - expect("Flagged newer proposal").to appear_before("Flagged proposal") + expect(newer_proposal.title).to appear_before(flagged_new_proposal.title) + expect(flagged_new_proposal.title).to appear_before(flagged_proposal.title) visit moderation_proposals_path(filter: 'all', order: 'flags') - expect("Flagged proposal").to appear_before("Flagged newer proposal") - expect("Flagged newer proposal").to appear_before("Newer proposal") + expect(flagged_proposal.title).to appear_before(flagged_new_proposal.title) + expect(flagged_new_proposal.title).to appear_before(newer_proposal.title) end end end diff --git a/spec/features/moderation/users_spec.rb b/spec/features/moderation/users_spec.rb index e34b4383e..697b11d34 100644 --- a/spec/features/moderation/users_spec.rb +++ b/spec/features/moderation/users_spec.rb @@ -28,14 +28,14 @@ feature 'Moderate users' do click_link 'Hide author' end - expect(current_path).to eq(debates_path) - expect(page).to_not have_content(debate1.title) - expect(page).to_not have_content(debate2.title) + expect(page).to have_current_path(debates_path) + expect(page).not_to have_content(debate1.title) + expect(page).not_to have_content(debate2.title) expect(page).to have_content(debate3.title) visit debate_path(debate3) - expect(page).to_not have_content(comment3.body) + expect(page).not_to have_content(comment3.body) click_link("Sign out") @@ -47,7 +47,7 @@ feature 'Moderate users' do click_button 'Enter' expect(page).to have_content 'Invalid login or password' - expect(current_path).to eq(new_user_session_path) + expect(page).to have_current_path(new_user_session_path) end scenario 'Search and ban users' do diff --git a/spec/features/moderation_spec.rb b/spec/features/moderation_spec.rb index fedcb105d..785c15580 100644 --- a/spec/features/moderation_spec.rb +++ b/spec/features/moderation_spec.rb @@ -7,11 +7,11 @@ feature 'Moderation' do login_as(user) visit root_path - expect(page).to_not have_link("Moderation") + expect(page).not_to have_link("Moderation") visit moderation_root_path - expect(current_path).not_to eq(moderation_root_path) - expect(current_path).to eq(proposals_path) + expect(page).not_to have_current_path(moderation_root_path) + expect(page).to have_current_path(root_path) expect(page).to have_content "You do not have permission to access this page" end @@ -21,11 +21,11 @@ feature 'Moderation' do login_as(user) visit root_path - expect(page).to_not have_link("Moderation") + expect(page).not_to have_link("Moderation") visit moderation_root_path - expect(current_path).not_to eq(moderation_root_path) - expect(current_path).to eq(proposals_path) + expect(page).not_to have_current_path(moderation_root_path) + expect(page).to have_current_path(root_path) expect(page).to have_content "You do not have permission to access this page" end @@ -35,11 +35,11 @@ feature 'Moderation' do login_as(user) visit root_path - expect(page).to_not have_link("Moderation") + expect(page).not_to have_link("Moderation") visit moderation_root_path - expect(current_path).not_to eq(moderation_root_path) - expect(current_path).to eq(proposals_path) + expect(page).not_to have_current_path(moderation_root_path) + expect(page).to have_current_path(root_path) expect(page).to have_content "You do not have permission to access this page" end @@ -49,11 +49,11 @@ feature 'Moderation' do login_as(user) visit root_path - expect(page).to_not have_link("Moderation") + expect(page).not_to have_link("Moderation") visit moderation_root_path - expect(current_path).not_to eq(moderation_root_path) - expect(current_path).to eq(proposals_path) + expect(page).not_to have_current_path(moderation_root_path) + expect(page).to have_current_path(root_path) expect(page).to have_content "You do not have permission to access this page" end @@ -66,8 +66,8 @@ feature 'Moderation' do expect(page).to have_link("Moderation") click_on "Moderation" - expect(current_path).to eq(moderation_root_path) - expect(page).to_not have_content "You do not have permission to access this page" + expect(page).to have_current_path(moderation_root_path) + expect(page).not_to have_content "You do not have permission to access this page" end scenario 'Access as an administrator is authorized' do @@ -79,8 +79,8 @@ feature 'Moderation' do expect(page).to have_link("Moderation") click_on "Moderation" - expect(current_path).to eq(moderation_root_path) - expect(page).to_not have_content "You do not have permission to access this page" + expect(page).to have_current_path(moderation_root_path) + expect(page).not_to have_content "You do not have permission to access this page" end scenario "Moderation access links" do @@ -89,21 +89,31 @@ feature 'Moderation' do visit root_path expect(page).to have_link('Moderation') - expect(page).to_not have_link('Administration') - expect(page).to_not have_link('Valuation') + expect(page).not_to have_link('Administration') + expect(page).not_to have_link('Valuation') end - scenario 'Moderation dashboard' do - create(:moderator, user: user) - login_as(user) - visit root_path + context 'Moderation dashboard' do + background do + Setting['org_name'] = 'OrgName' + end - click_link 'Moderation' + after do + Setting['org_name'] = 'CONSUL' + end - expect(current_path).to eq(moderation_root_path) - expect(page).to have_css('#moderation_menu') - expect(page).to_not have_css('#admin_menu') - expect(page).to_not have_css('#valuation_menu') + scenario 'Contains correct elements' do + create(:moderator, user: user) + login_as(user) + visit root_path + + click_link 'Moderation' + + expect(page).to have_link('Go back to OrgName') + expect(page).to have_current_path(moderation_root_path) + expect(page).to have_css('#moderation_menu') + expect(page).not_to have_css('#admin_menu') + expect(page).not_to have_css('#valuation_menu') + end end - end diff --git a/spec/features/notifications_spec.rb b/spec/features/notifications_spec.rb index 7b044e18a..c413f3fd2 100644 --- a/spec/features/notifications_spec.rb +++ b/spec/features/notifications_spec.rb @@ -1,303 +1,12 @@ require 'rails_helper' feature "Notifications" do - let(:admin_user) { create :user } - let(:administrator) do - create(:administrator, user: admin_user) - admin_user - end - let(:author) { create :user } + let(:user) { create :user } - let(:debate) { create :debate, author: author } - let(:proposal) { create :proposal, author: author } - let(:process) { create :legislation_process, :in_debate_phase } - let(:legislation_question) { create(:legislation_question, process: process, author: administrator) } - let(:legislation_annotation) { create(:legislation_annotation, author: author) } - - scenario "User commented on my debate", :js do - login_as user - visit debate_path debate - - fill_in "comment-body-debate_#{debate.id}", with: "I commented on your debate" - click_button "Publish comment" - within "#comments" do - expect(page).to have_content "I commented on your debate" - end - - logout - login_as author - visit root_path - - find(".icon-notification").click - - expect(page).to have_css ".notification", count: 1 - - expect(page).to have_content "Someone commented on" - expect(page).to have_xpath "//a[@href='#{notification_path(Notification.last)}']" - end - - scenario "User commented on my legislation question", :js do - verified_user = create(:user, :level_two) - login_as verified_user - visit legislation_process_question_path legislation_question.process, legislation_question - - fill_in "comment-body-legislation_question_#{legislation_question.id}", with: "I answered your question" - click_button "Publish answer" - within "#comments" do - expect(page).to have_content "I answered your question" - end - - logout - login_as administrator - visit root_path - - find(".icon-notification").click - - expect(page).to have_css ".notification", count: 1 - - expect(page).to have_content "Someone commented on" - expect(page).to have_xpath "//a[@href='#{notification_path(Notification.last)}']" - end - - scenario "Multiple comments on my proposal", :js do - login_as user - visit proposal_path proposal - - fill_in "comment-body-proposal_#{proposal.id}", with: "I agree" - click_button "Publish comment" - within "#comments" do - expect(page).to have_content "I agree" - end - - logout - login_as create(:user) - visit proposal_path proposal - - fill_in "comment-body-proposal_#{proposal.id}", with: "I disagree" - click_button "Publish comment" - within "#comments" do - expect(page).to have_content "I disagree" - end - - logout - login_as author - visit root_path - - find(".icon-notification").click - - expect(page).to have_css ".notification", count: 1 - - expect(page).to have_content "There are 2 new comments on" - expect(page).to have_xpath "//a[@href='#{notification_path(Notification.last)}']" - end - - scenario "User replied to my comment", :js do - comment = create :comment, commentable: debate, user: author - login_as user - visit debate_path debate - - click_link "Reply" - within "#js-comment-form-comment_#{comment.id}" do - fill_in "comment-body-comment_#{comment.id}", with: "I replied to your comment" - click_button "Publish reply" - end - - within "#comment_#{comment.id}" do - expect(page).to have_content "I replied to your comment" - end - - logout - login_as author - visit root_path - - find(".icon-notification").click - - expect(page).to have_css ".notification", count: 1 - expect(page).to have_content "Someone replied to your comment on" - expect(page).to have_xpath "//a[@href='#{notification_path(Notification.last)}']" - end - - scenario "Multiple replies to my comment", :js do - comment = create :comment, commentable: debate, user: author - 3.times do |n| - login_as create(:user) - visit debate_path debate - - within("#comment_#{comment.id}_reply") { click_link "Reply" } - within "#js-comment-form-comment_#{comment.id}" do - fill_in "comment-body-comment_#{comment.id}", with: "Reply number #{n}" - click_button "Publish reply" - end - - within "#comment_#{comment.id}" do - expect(page).to have_content "Reply number #{n}" - end - logout - end - - login_as author - visit root_path - - find(".icon-notification").click - - expect(page).to have_css ".notification", count: 1 - expect(page).to have_content "There are 3 new replies to your comment on" - expect(page).to have_xpath "//a[@href='#{notification_path(Notification.last)}']" - end - - scenario "Author commented on his own debate", :js do - login_as author - visit debate_path debate - - fill_in "comment-body-debate_#{debate.id}", with: "I commented on my own debate" - click_button "Publish comment" - within "#comments" do - expect(page).to have_content "I commented on my own debate" - end - - find(".icon-no-notification").click - expect(page).to have_css ".notification", count: 0 - end - - scenario "Author replied to his own comment", :js do - comment = create :comment, commentable: debate, user: author - login_as author - visit debate_path debate - - click_link "Reply" - within "#js-comment-form-comment_#{comment.id}" do - fill_in "comment-body-comment_#{comment.id}", with: "I replied to my own comment" - click_button "Publish reply" - end - - within "#comment_#{comment.id}" do - expect(page).to have_content "I replied to my own comment" - end - - find(".icon-no-notification") - - visit notifications_path - expect(page).to have_css ".notification", count: 0 - end - - context "Proposal notification" do - - scenario "Voters should receive a notification", :js do - author = create(:user) - - user1 = create(:user) - user2 = create(:user) - user3 = create(:user) - - proposal = create(:proposal, author: author) - - create(:vote, voter: user1, votable: proposal, vote_flag: true) - create(:vote, voter: user2, votable: proposal, vote_flag: true) - - login_as(author) - visit root_path - - visit new_proposal_notification_path(proposal_id: proposal.id) - - fill_in 'proposal_notification_title', with: "Thank you for supporting my proposal" - fill_in 'proposal_notification_body', with: "Please share it with others so we can make it happen!" - click_button "Send message" - - expect(page).to have_content "Your message has been sent correctly." - - logout - login_as user1 - visit root_path - - find(".icon-notification").click - - notification_for_user1 = Notification.where(user: user1).first - expect(page).to have_css ".notification", count: 1 - expect(page).to have_content "There is one new notification on #{proposal.title}" - expect(page).to have_xpath "//a[@href='#{notification_path(notification_for_user1)}']" - - logout - login_as user2 - visit root_path - - find(".icon-notification").click - - notification_for_user2 = Notification.where(user: user2).first - expect(page).to have_css ".notification", count: 1 - expect(page).to have_content "There is one new notification on #{proposal.title}" - expect(page).to have_xpath "//a[@href='#{notification_path(notification_for_user2)}']" - - logout - login_as user3 - visit root_path - - find(".icon-no-notification").click - - expect(page).to have_css ".notification", count: 0 - end - - scenario "Followers should receive a notification", :js do - author = create(:user) - - user1 = create(:user) - user2 = create(:user) - user3 = create(:user) - - proposal = create(:proposal, author: author) - - create(:follow, :followed_proposal, user: user1, followable: proposal) - create(:follow, :followed_proposal, user: user2, followable: proposal) - - login_as author.reload - visit root_path - - visit new_proposal_notification_path(proposal_id: proposal.id) - - fill_in 'proposal_notification_title', with: "Thank you for supporting my proposal" - fill_in 'proposal_notification_body', with: "Please share it with others so we can make it happen!" - click_button "Send message" - - expect(page).to have_content "Your message has been sent correctly." - - logout - login_as user1.reload - visit root_path - - find(".icon-notification").click - - notification_for_user1 = Notification.where(user: user1).first - expect(page).to have_css ".notification", count: 1 - expect(page).to have_content "There is one new notification on #{proposal.title}" - expect(page).to have_xpath "//a[@href='#{notification_path(notification_for_user1)}']" - - logout - login_as user2.reload - visit root_path - - find(".icon-notification").click - - notification_for_user2 = Notification.where(user: user2).first - expect(page).to have_css ".notification", count: 1 - expect(page).to have_content "There is one new notification on #{proposal.title}" - expect(page).to have_xpath "//a[@href='#{notification_path(notification_for_user2)}']" - - logout - login_as user3.reload - visit root_path - - find(".icon-no-notification").click - - expect(page).to have_css ".notification", count: 0 - end - - pending "group notifications for the same proposal" - - end context "mark as read" do scenario "mark a single notification as read" do - user = create :user notification = create :notification, user: user login_as user @@ -312,7 +21,6 @@ feature "Notifications" do end scenario "mark all notifications as read" do - user = create :user 2.times { create :notification, user: user } login_as user @@ -322,7 +30,7 @@ feature "Notifications" do click_link "Mark all as read" expect(page).to have_css ".notification", count: 0 - expect(current_path).to eq(notifications_path) + expect(page).to have_current_path(notifications_path) end end diff --git a/spec/features/officing/results_spec.rb b/spec/features/officing/results_spec.rb index 835903ab9..91a194eec 100644 --- a/spec/features/officing/results_spec.rb +++ b/spec/features/officing/results_spec.rb @@ -7,8 +7,13 @@ feature 'Officing Results' do @officer_assignment = create(:poll_officer_assignment, :final, officer: @poll_officer) @poll = @officer_assignment.booth_assignment.poll @poll.update(ends_at: 1.day.ago) - @question_1 = create(:poll_question, poll: @poll, valid_answers: "Yes,No") - @question_2 = create(:poll_question, poll: @poll, valid_answers: "Today,Tomorrow") + @question_1 = create(:poll_question, poll: @poll) + create(:poll_question_answer, title: 'Yes', question: @question_1) + create(:poll_question_answer, title: 'No', question: @question_1) + @question_2 = create(:poll_question, poll: @poll) + create(:poll_question_answer, title: 'Today', question: @question_2) + create(:poll_question_answer, title: 'Tomorrow', question: @question_2) + login_as(@poll_officer.user) end @@ -29,9 +34,9 @@ feature 'Officing Results' do click_link 'Total recounts and results' end - expect(page).to_not have_content(not_allowed_poll_1.name) - expect(page).to_not have_content(not_allowed_poll_2.name) - expect(page).to_not have_content(not_allowed_poll_3.name) + expect(page).not_to have_content(not_allowed_poll_1.name) + expect(page).not_to have_content(not_allowed_poll_2.name) + expect(page).not_to have_content(not_allowed_poll_3.name) expect(page).to have_content(@poll.name) visit new_officing_poll_result_path(not_allowed_poll_1) @@ -50,12 +55,10 @@ feature 'Officing Results' do click_link 'Add results' end - expect(page).to_not have_content('Your results') + expect(page).not_to have_content('Your results') booth_name = @officer_assignment.booth_assignment.booth.name - date = I18n.l(@poll.starts_at.to_date, format: :long) select booth_name, from: 'officer_assignment_id' - select date, from: 'date' fill_in "questions[#{@question_1.id}][0]", with: '100' fill_in "questions[#{@question_1.id}][1]", with: '200' @@ -71,8 +74,8 @@ feature 'Officing Results' do expect(page).to have_content('Your results') - within("#results_#{@officer_assignment.booth_assignment_id}_#{@poll.starts_at.to_date.strftime('%Y%m%d')}") do - expect(page).to have_content(date) + within("#results_#{@officer_assignment.booth_assignment_id}_#{Date.current.strftime('%Y%m%d')}") do + expect(page).to have_content(I18n.l(Date.current, format: :long)) expect(page).to have_content(booth_name) end end @@ -81,9 +84,9 @@ feature 'Officing Results' do partial_result = create(:poll_partial_result, officer_assignment: @officer_assignment, booth_assignment: @officer_assignment.booth_assignment, - date: @poll.starts_at, + date: Date.current, question: @question_1, - answer: @question_1.valid_answers[0], + answer: @question_1.question_answers.first.title, author: @poll_officer.user, amount: 7777) @@ -94,9 +97,7 @@ feature 'Officing Results' do visit new_officing_poll_result_path(@poll) booth_name = partial_result.booth_assignment.booth.name - date = I18n.l(partial_result.date, format: :long) select booth_name, from: 'officer_assignment_id' - select date, from: 'date' fill_in "questions[#{@question_1.id}][0]", with: '5555' fill_in "questions[#{@question_1.id}][1]", with: '200' @@ -112,7 +113,7 @@ feature 'Officing Results' do click_link "See results" end - expect(page).to_not have_content('7777') + expect(page).not_to have_content('7777') within("#white_results") { expect(page).to have_content('6') } within("#null_results") { expect(page).to have_content('7') } within("#total_results") { expect(page).to have_content('8') } @@ -127,21 +128,13 @@ feature 'Officing Results' do date: @poll.ends_at, question: @question_1, amount: 33) - white_result = create(:poll_white_result, + poll_recount = create(:poll_recount, officer_assignment: @officer_assignment, booth_assignment: @officer_assignment.booth_assignment, date: @poll.ends_at, - amount: 21) - null_result = create(:poll_null_result, - officer_assignment: @officer_assignment, - booth_assignment: @officer_assignment.booth_assignment, - date: @poll.ends_at, - amount: 44) - total_result = create(:poll_total_result, - officer_assignment: @officer_assignment, - booth_assignment: @officer_assignment.booth_assignment, - date: @poll.ends_at, - amount: 66) + white_amount: 21, + null_amount: 44, + total_amount: 66) visit officing_poll_results_path(@poll, date: I18n.l(@poll.ends_at.to_date), @@ -151,13 +144,13 @@ feature 'Officing Results' do expect(page).to have_content(@officer_assignment.booth_assignment.booth.name) expect(page).to have_content(@question_1.title) - @question_1.valid_answers.each_with_index do |answer, i| - within("#question_#{@question_1.id}_#{i}_result") { expect(page).to have_content(answer) } + @question_1.question_answers.each_with_index do |answer, i| + within("#question_#{@question_1.id}_#{i}_result") { expect(page).to have_content(answer.title) } end expect(page).to have_content(@question_2.title) - @question_2.valid_answers.each_with_index do |answer, i| - within("#question_#{@question_2.id}_#{i}_result") { expect(page).to have_content(answer) } + @question_2.question_answers.each_with_index do |answer, i| + within("#question_#{@question_2.id}_#{i}_result") { expect(page).to have_content(answer.title) } end within('#white_results') { expect(page).to have_content('21') } diff --git a/spec/features/officing/voters_spec.rb b/spec/features/officing/voters_spec.rb index 0a23a6a27..135bebdc8 100644 --- a/spec/features/officing/voters_spec.rb +++ b/spec/features/officing/voters_spec.rb @@ -2,16 +2,19 @@ require 'rails_helper' feature 'Voters' do + let(:poll) { create(:poll, :current) } + let(:booth) { create(:poll_booth) } let(:officer) { create(:poll_officer) } background do login_as(officer.user) create(:geozone, :in_census) + create(:poll_shift, officer: officer, booth: booth, date: Date.current, task: :vote_collection) + booth_assignment = create(:poll_booth_assignment, poll: poll, booth: booth) + create(:poll_officer_assignment, officer: officer, booth_assignment: booth_assignment) end scenario "Can vote", :js do - poll = create(:poll_officer_assignment, officer: officer).booth_assignment.poll - visit new_officing_residence_path officing_verify_residence @@ -21,25 +24,28 @@ feature 'Voters' do click_button "Confirm vote" expect(page).to have_content "Vote introduced!" - expect(page).to_not have_button "Confirm vote" + expect(page).not_to have_button "Confirm vote" page.evaluate_script("window.location.reload()") expect(page).to have_content "Has already participated in this poll" - expect(page).to_not have_button "Confirm vote" + expect(page).not_to have_button "Confirm vote" + + expect(Poll::Voter.last.officer_id).to eq(officer.id) end scenario "Already voted", :js do - poll1 = create(:poll) - poll2 = create(:poll) + poll2 = create(:poll, :current) + booth_assignment = create(:poll_booth_assignment, poll: poll2, booth: booth) + create(:poll_officer_assignment, officer: officer, booth_assignment: booth_assignment) user = create(:user, :level_two) - voter = create(:poll_voter, poll: poll1, user: user) + voter = create(:poll_voter, poll: poll, user: user) visit new_officing_voter_path(id: voter.user.id) - within("#poll_#{poll1.id}") do + within("#poll_#{poll.id}") do expect(page).to have_content "Has already participated in this poll" - expect(page).to_not have_button "Confirm vote" + expect(page).not_to have_button "Confirm vote" end within("#poll_#{poll2.id}") do @@ -49,8 +55,7 @@ feature 'Voters' do scenario "Had already verified his residence, but is not level 2 yet", :js do user = create(:user, residence_verified_at: Time.current, document_type: "1", document_number: "12345678Z") - expect(user).to_not be_level_two_verified - poll = create(:poll_officer_assignment, officer: officer).booth_assignment.poll + expect(user).not_to be_level_two_verified visit new_officing_residence_path officing_verify_residence @@ -59,6 +64,37 @@ feature 'Voters' do expect(page).to have_content poll.name end - #Fix and use answerable_by(user) - xscenario "Display only answerable polls" + scenario "Display only current polls on which officer has a voting shift today, and user can answer", :js do + poll_current = create(:poll, :current) + second_booth = create(:poll_booth) + booth_assignment = create(:poll_booth_assignment, poll: poll_current, booth: second_booth) + create(:poll_officer_assignment, officer: officer, booth_assignment: booth_assignment) + create(:poll_shift, officer: officer, booth: second_booth, date: Date.current, task: :recount_scrutiny) + create(:poll_shift, officer: officer, booth: second_booth, date: Date.tomorrow, task: :vote_collection) + + poll_expired = create(:poll, :expired) + create(:poll_officer_assignment, officer: officer, booth_assignment: create(:poll_booth_assignment, poll: poll_expired, booth: booth)) + + poll_incoming = create(:poll, :incoming) + create(:poll_officer_assignment, officer: officer, booth_assignment: create(:poll_booth_assignment, poll: poll_incoming, booth: booth)) + + poll_geozone_restricted_in = create(:poll, :current, geozone_restricted: true, geozones: [Geozone.first]) + booth_assignment = create(:poll_booth_assignment, poll: poll_geozone_restricted_in, booth: booth) + create(:poll_officer_assignment, officer: officer, booth_assignment: booth_assignment) + + poll_geozone_restricted_out = create(:poll, :current, geozone_restricted: true, geozones: [create(:geozone, census_code: "02")]) + booth_assignment = create(:poll_booth_assignment, poll: poll_geozone_restricted_out, booth: booth) + create(:poll_officer_assignment, officer: officer, booth_assignment: booth_assignment) + + visit new_officing_residence_path + officing_verify_residence + + expect(page).to have_content "Polls" + expect(page).to have_content poll.name + expect(page).not_to have_content poll_current.name + expect(page).not_to have_content poll_expired.name + expect(page).not_to have_content poll_incoming.name + expect(page).to have_content poll_geozone_restricted_in.name + expect(page).not_to have_content poll_geozone_restricted_out.name + end end diff --git a/spec/features/officing_spec.rb b/spec/features/officing_spec.rb index d4cb416a1..f2d31c334 100644 --- a/spec/features/officing_spec.rb +++ b/spec/features/officing_spec.rb @@ -1,4 +1,5 @@ require 'rails_helper' +require 'sessions_helper' feature 'Poll Officing' do let(:user) { create(:user) } @@ -7,11 +8,11 @@ feature 'Poll Officing' do login_as(user) visit root_path - expect(page).to_not have_link("Polling officers") + expect(page).not_to have_link("Polling officers") visit officing_root_path - expect(current_path).not_to eq(officing_root_path) - expect(current_path).to eq(proposals_path) + expect(page).not_to have_current_path(officing_root_path) + expect(page).to have_current_path(root_path) expect(page).to have_content "You do not have permission to access this page" end @@ -20,11 +21,11 @@ feature 'Poll Officing' do login_as(user) visit root_path - expect(page).to_not have_link("Polling officers") + expect(page).not_to have_link("Polling officers") visit officing_root_path - expect(current_path).not_to eq(officing_root_path) - expect(current_path).to eq(proposals_path) + expect(page).not_to have_current_path(officing_root_path) + expect(page).to have_current_path(root_path) expect(page).to have_content "You do not have permission to access this page" end @@ -33,11 +34,11 @@ feature 'Poll Officing' do login_as(user) visit root_path - expect(page).to_not have_link("Polling officers") + expect(page).not_to have_link("Polling officers") visit officing_root_path - expect(current_path).not_to eq(officing_root_path) - expect(current_path).to eq(proposals_path) + expect(page).not_to have_current_path(officing_root_path) + expect(page).to have_current_path(root_path) expect(page).to have_content "You do not have permission to access this page" end @@ -46,14 +47,42 @@ feature 'Poll Officing' do login_as(user) visit root_path - expect(page).to_not have_link("Polling officers") + expect(page).not_to have_link("Polling officers") visit officing_root_path - expect(current_path).not_to eq(officing_root_path) - expect(current_path).to eq(proposals_path) + expect(page).not_to have_current_path(officing_root_path) + expect(page).to have_current_path(root_path) expect(page).to have_content "You do not have permission to access this page" end + scenario 'Access as an administrator is not authorized' do + create(:administrator, user: user) + create(:poll) + login_as(user) + visit root_path + + expect(page).not_to have_link("Polling officers") + visit officing_root_path + + expect(page).not_to have_current_path(officing_root_path) + expect(page).to have_current_path(root_path) + expect(page).to have_content "You do not have permission to access this page" + end + + scenario 'Access as an administrator with poll officer role is authorized' do + create(:administrator, user: user) + create(:poll_officer, user: user) + create(:poll) + login_as(user) + visit root_path + + expect(page).to have_link("Polling officers") + click_on "Polling officers" + + expect(page).to have_current_path(officing_root_path) + expect(page).not_to have_content "You do not have permission to access this page" + end + scenario 'Access as an poll officer is authorized' do create(:poll_officer, user: user) create(:poll) @@ -63,21 +92,8 @@ feature 'Poll Officing' do expect(page).to have_link("Polling officers") click_on "Polling officers" - expect(current_path).to eq(officing_root_path) - expect(page).to_not have_content "You do not have permission to access this page" - end - - scenario 'Access as an administrator is authorized' do - create(:administrator, user: user) - create(:poll) - login_as(user) - visit root_path - - expect(page).to have_link("Polling officers") - click_on "Polling officers" - - expect(current_path).to eq(officing_root_path) - expect(page).to_not have_content "You do not have permission to access this page" + expect(page).to have_current_path(officing_root_path) + expect(page).not_to have_content "You do not have permission to access this page" end scenario "Poll officer access links" do @@ -86,9 +102,9 @@ feature 'Poll Officing' do visit root_path expect(page).to have_link("Polling officers") - expect(page).to_not have_link('Valuation') - expect(page).to_not have_link('Administration') - expect(page).to_not have_link('Moderation') + expect(page).not_to have_link('Valuation') + expect(page).not_to have_link('Administration') + expect(page).not_to have_link('Moderation') end scenario 'Officing dashboard' do @@ -99,11 +115,71 @@ feature 'Poll Officing' do click_link 'Polling officers' - expect(current_path).to eq(officing_root_path) + expect(page).to have_current_path(officing_root_path) expect(page).to have_css('#officing_menu') - expect(page).to_not have_css('#valuation_menu') - expect(page).to_not have_css('#admin_menu') - expect(page).to_not have_css('#moderation_menu') + expect(page).not_to have_css('#valuation_menu') + expect(page).not_to have_css('#admin_menu') + expect(page).not_to have_css('#moderation_menu') end -end \ No newline at end of file + scenario 'Officing dashboard available for multiple sessions', :js do + poll = create(:poll) + booth = create(:poll_booth) + booth_assignment = create(:poll_booth_assignment, poll: poll, booth: booth) + + user1 = create(:user) + user2 = create(:user) + officer1 = create(:poll_officer, user: user1) + officer2 = create(:poll_officer, user: user2) + + create(:poll_shift, officer: officer1, booth: booth, date: Date.current, task: :vote_collection) + create(:poll_shift, officer: officer2, booth: booth, date: Date.current, task: :vote_collection) + + officer_assignment_1 = create(:poll_officer_assignment, booth_assignment: booth_assignment, officer: officer1) + officer_assignment_2 = create(:poll_officer_assignment, booth_assignment: booth_assignment, officer: officer2) + + in_browser(:one) do + login_as user1 + visit officing_root_path + end + + in_browser(:two) do + login_as user2 + visit officing_root_path + end + + in_browser(:one) do + page.should have_content("Here you can validate user documents and store voting results") + + visit new_officing_residence_path + select 'DNI', from: 'residence_document_type' + fill_in 'residence_document_number', with: "12345678Z" + fill_in 'residence_year_of_birth', with: '1980' + click_button 'Validate document' + expect(page).to have_content 'Document verified with Census' + click_button "Confirm vote" + expect(page).to have_content "Vote introduced!" + expect(Poll::Voter.where(document_number: '12345678Z', poll_id: poll, origin: 'booth', officer_id: officer1).count).to be(1) + + visit final_officing_polls_path + page.should have_content("Polls ready for final recounting") + end + + in_browser(:two) do + page.should have_content("Here you can validate user documents and store voting results") + + visit new_officing_residence_path + select 'DNI', from: 'residence_document_type' + fill_in 'residence_document_number', with: "12345678Y" + fill_in 'residence_year_of_birth', with: '1980' + click_button 'Validate document' + expect(page).to have_content 'Document verified with Census' + click_button "Confirm vote" + expect(page).to have_content "Vote introduced!" + expect(Poll::Voter.where(document_number: '12345678Y', poll_id: poll, origin: 'booth', officer_id: officer2).count).to be(1) + + visit final_officing_polls_path + page.should have_content("Polls ready for final recounting") + end + end +end diff --git a/spec/features/organizations_spec.rb b/spec/features/organizations_spec.rb index f968d6cac..e2183bf25 100644 --- a/spec/features/organizations_spec.rb +++ b/spec/features/organizations_spec.rb @@ -4,7 +4,7 @@ feature 'Organizations' do scenario 'Organizations can be created' do user = User.organizations.where(email: 'green@peace.com').first - expect(user).to_not be + expect(user).not_to be visit new_organization_registration_path @@ -20,7 +20,7 @@ feature 'Organizations' do user = User.organizations.where(email: 'green@peace.com').first expect(user).to be expect(user).to be_organization - expect(user.organization).to_not be_verified + expect(user.organization).not_to be_verified end scenario 'Create with invisible_captcha honeypot field' do @@ -39,7 +39,7 @@ feature 'Organizations' do expect(page.status_code).to eq(200) expect(page.html).to be_empty - expect(current_path).to eq(organization_registration_path) + expect(page).to have_current_path(organization_registration_path) end scenario 'Create organization too fast' do @@ -55,7 +55,7 @@ feature 'Organizations' do expect(page).to have_content 'Sorry, that was too quick! Please resubmit' - expect(current_path).to eq(new_organization_registration_path) + expect(page).to have_current_path(new_organization_registration_path) end scenario 'Errors on create' do @@ -76,6 +76,6 @@ feature 'Organizations' do visit new_user_session_path expect(page).to have_link "Sign up" - expect(page).to_not have_link "Sign up as an organization" + expect(page).not_to have_link "Sign up as an organization" end end diff --git a/spec/features/polls/answers_spec.rb b/spec/features/polls/answers_spec.rb new file mode 100644 index 000000000..8bb87c94e --- /dev/null +++ b/spec/features/polls/answers_spec.rb @@ -0,0 +1,79 @@ +require 'rails_helper' + +feature 'Answers' do + + let(:question) { create(:poll_question) } + let(:admin) { create(:administrator) } + + background do + login_as(admin.user) + end + + scenario "Index" do + answer1 = create(:poll_question_answer, question: question, given_order: 2) + answer2 = create(:poll_question_answer, question: question, given_order: 1) + + visit admin_question_path(question) + + expect(page).to have_css(".poll_question_answer", count: 2) + expect(page.body.index(answer1.title)).to be < page.body.index(answer2.title) + + within("#poll_question_answer_#{answer1.id}") do + expect(page).to have_content answer1.title + expect(page).to have_content answer1.description + end + end + + scenario "Create" do + visit admin_question_path(question) + + click_link "Add answer" + fill_in "poll_question_answer_title", with: "¿Would you like to reform Central Park?" + fill_in "poll_question_answer_description", with: "Adding more trees, creating a play area..." + click_button "Save" + + expect(page).to have_content "Answer created successfully" + expect(page).to have_css(".poll_question_answer", count: 1) + expect(page).to have_content "¿Would you like to reform Central Park?" + expect(page).to have_content "Adding more trees, creating a play area..." + end + + scenario 'Add video to answer' do + answer1 = create(:poll_question_answer, question: question) + answer2 = create(:poll_question_answer, question: question) + + visit admin_question_path(question) + + within("#poll_question_answer_#{answer1.id}") do + click_link "Video list" + end + + click_link "Add video" + + fill_in "poll_question_answer_video_title", with: "Awesome project video" + fill_in "poll_question_answer_video_url", with: "https://www.youtube.com/watch?v=123" + + click_button "Save" + + within("#poll_question_answer_video_#{answer1.videos.last.id}") do + expect(page).to have_content "Awesome project video" + expect(page).to have_content "https://www.youtube.com/watch?v=123" + end + end + + pending "Update" + pending "Destroy" + + context "Gallery" do + + it_behaves_like "nested imageable", + "poll_question_answer", + "new_admin_answer_image_path", + { "answer_id": "id" }, + nil, + "Save image", + "Image uploaded successfully", + true + end + +end diff --git a/spec/features/polls/polls_spec.rb b/spec/features/polls/polls_spec.rb index 047c71146..c2e8413cf 100644 --- a/spec/features/polls/polls_spec.rb +++ b/spec/features/polls/polls_spec.rb @@ -2,15 +2,23 @@ require 'rails_helper' feature 'Polls' do + context "Concerns" do + it_behaves_like 'notifiable in-app', Poll + end + context '#index' do scenario 'Polls can be listed' do polls = create_list(:poll, 3) + create(:image, imageable: polls[0]) + create(:image, imageable: polls[1]) + create(:image, imageable: polls[2]) visit polls_path polls.each do |poll| expect(page).to have_content(poll.name) + expect(page).to have_css("img[alt='#{poll.image.title}']") expect(page).to have_link("Participate in this poll") end end @@ -23,43 +31,69 @@ feature 'Polls' do visit polls_path expect(page).to have_content('Current poll') expect(page).to have_link('Participate in this poll') - expect(page).to_not have_content('Incoming poll') - expect(page).to_not have_content('Expired poll') + expect(page).not_to have_content('Incoming poll') + expect(page).not_to have_content('Expired poll') visit polls_path(filter: 'incoming') - expect(page).to_not have_content('Current poll') + expect(page).not_to have_content('Current poll') expect(page).to have_content('Incoming poll') expect(page).to have_link('More information') - expect(page).to_not have_content('Expired poll') + expect(page).not_to have_content('Expired poll') visit polls_path(filter: 'expired') - expect(page).to_not have_content('Current poll') - expect(page).to_not have_content('Incoming poll') + expect(page).not_to have_content('Current poll') + expect(page).not_to have_content('Incoming poll') expect(page).to have_content('Expired poll') expect(page).to have_link('Poll ended') end scenario "Current filter is properly highlighted" do visit polls_path - expect(page).to_not have_link('Open') + expect(page).not_to have_link('Open') expect(page).to have_link('Incoming') expect(page).to have_link('Expired') visit polls_path(filter: 'incoming') expect(page).to have_link('Open') - expect(page).to_not have_link('Incoming') + expect(page).not_to have_link('Incoming') expect(page).to have_link('Expired') visit polls_path(filter: 'expired') expect(page).to have_link('Open') expect(page).to have_link('Incoming') - expect(page).to_not have_link('Expired') + expect(page).not_to have_link('Expired') + end + + scenario "Poll title link to stats if enabled" do + poll = create(:poll, name: "Poll with stats", stats_enabled: true) + + visit polls_path + + expect(page).to have_link("Poll with stats", href: stats_poll_path(poll)) + end + + scenario "Poll title link to results if enabled" do + poll = create(:poll, name: "Poll with results", stats_enabled: true, results_enabled: true) + + visit polls_path + + expect(page).to have_link("Poll with results", href: results_poll_path(poll)) end end context 'Show' do let(:geozone) { create(:geozone) } - let(:poll) { create(:poll) } + let(:poll) { create(:poll, summary: "Summary", description: "Description") } + + scenario 'Show answers with videos' do + question = create(:poll_question, poll: poll) + answer = create(:poll_question_answer, question: question, title: 'Chewbacca') + video = create(:poll_answer_video, answer: answer, title: "Awesome project video", url: "https://www.youtube.com/watch?v=123") + + visit poll_path(poll) + + expect(page).to have_link("Awesome project video", href: "https://www.youtube.com/watch?v=123") + end scenario 'Lists questions from proposals as well as regular ones' do normal_question = create(:poll_question, poll: poll) @@ -67,27 +101,63 @@ feature 'Polls' do visit poll_path(poll) expect(page).to have_content(poll.name) + expect(page).to have_content(poll.summary) + expect(page).to have_content(poll.description) expect(page).to have_content(normal_question.title) expect(page).to have_content(proposal_question.title) end + scenario "Question answers appear in the given order" do + question = create(:poll_question, poll: poll) + answer1 = create(:poll_question_answer, title: 'First', question: question, given_order: 2) + answer2 = create(:poll_question_answer, title: 'Second', question: question, given_order: 1) + + visit poll_path(poll) + + within("div#poll_question_#{question.id}") do + expect(page.body.index(answer1.title)).to be < page.body.index(answer2.title) + end + end + + scenario "More info answers appear in the given order" do + question = create(:poll_question, poll: poll) + answer1 = create(:poll_question_answer, title: 'First', question: question, given_order: 2) + answer2 = create(:poll_question_answer, title: 'Second', question: question, given_order: 1) + + visit poll_path(poll) + + within('div.poll-more-info-answers') do + expect(page.body.index(answer1.title)).to be < page.body.index(answer2.title) + end + end + scenario 'Non-logged in users' do - create(:poll_question, poll: poll, valid_answers: 'Han Solo, Chewbacca') + question = create(:poll_question, poll: poll) + answer1 = create(:poll_question_answer, question: question, title: 'Han Solo') + answer2 = create(:poll_question_answer, question: question, title: 'Chewbacca') + visit poll_path(poll) expect(page).to have_content('Han Solo') expect(page).to have_content('Chewbacca') expect(page).to have_content('You must Sign in or Sign up to participate') - expect(page).to_not have_link('Han Solo') - expect(page).to_not have_link('Chewbacca') + expect(page).not_to have_link('Han Solo') + expect(page).not_to have_link('Chewbacca') end scenario 'Level 1 users' do + visit polls_path + expect(page).not_to have_selector('.already-answer') + poll.update(geozone_restricted: true) poll.geozones << geozone - create(:poll_question, poll: poll, valid_answers: 'Han Solo, Chewbacca') + + question = create(:poll_question, poll: poll) + answer1 = create(:poll_question_answer, question: question, title: 'Han Solo') + answer2 = create(:poll_question_answer, question: question, title: 'Chewbacca') + login_as(create(:user, geozone: geozone)) visit poll_path(poll) @@ -96,22 +166,26 @@ feature 'Polls' do expect(page).to have_content('Han Solo') expect(page).to have_content('Chewbacca') - expect(page).to_not have_link('Han Solo') - expect(page).to_not have_link('Chewbacca') + expect(page).not_to have_link('Han Solo') + expect(page).not_to have_link('Chewbacca') end scenario 'Level 2 users in an incoming poll' do incoming_poll = create(:poll, :incoming, geozone_restricted: true) incoming_poll.geozones << geozone - create(:poll_question, poll: incoming_poll, valid_answers: 'Rey, Finn') + + question = create(:poll_question, poll: incoming_poll) + answer1 = create(:poll_question_answer, question: question, title: 'Rey') + answer2 = create(:poll_question_answer, question: question, title: 'Finn') + login_as(create(:user, :level_two, geozone: geozone)) visit poll_path(incoming_poll) expect(page).to have_content('Rey') expect(page).to have_content('Finn') - expect(page).to_not have_link('Rey') - expect(page).to_not have_link('Finn') + expect(page).not_to have_link('Rey') + expect(page).not_to have_link('Finn') expect(page).to have_content('This poll has not yet started') end @@ -119,15 +193,19 @@ feature 'Polls' do scenario 'Level 2 users in an expired poll' do expired_poll = create(:poll, :expired, geozone_restricted: true) expired_poll.geozones << geozone - create(:poll_question, poll: expired_poll, valid_answers: 'Luke, Leia') + + question = create(:poll_question, poll: expired_poll) + answer1 = create(:poll_question_answer, question: question, title: 'Luke') + answer2 = create(:poll_question_answer, question: question, title: 'Leia') + login_as(create(:user, :level_two, geozone: geozone)) visit poll_path(expired_poll) expect(page).to have_content('Luke') expect(page).to have_content('Leia') - expect(page).to_not have_link('Luke') - expect(page).to_not have_link('Leia') + expect(page).not_to have_link('Luke') + expect(page).not_to have_link('Leia') expect(page).to have_content('This poll has finished') end @@ -135,21 +213,29 @@ feature 'Polls' do scenario 'Level 2 users in a poll with questions for a geozone which is not theirs' do poll.update(geozone_restricted: true) poll.geozones << create(:geozone) - create(:poll_question, poll: poll, valid_answers: 'Vader, Palpatine') + + question = create(:poll_question, poll: poll) + answer1 = create(:poll_question_answer, question: question, title: 'Vader') + answer2 = create(:poll_question_answer, question: question, title: 'Palpatine') + login_as(create(:user, :level_two)) visit poll_path(poll) expect(page).to have_content('Vader') expect(page).to have_content('Palpatine') - expect(page).to_not have_link('Vader') - expect(page).to_not have_link('Palpatine') + expect(page).not_to have_link('Vader') + expect(page).not_to have_link('Palpatine') end scenario 'Level 2 users reading a same-geozone poll' do poll.update(geozone_restricted: true) poll.geozones << geozone - create(:poll_question, poll: poll, valid_answers: 'Han Solo, Chewbacca') + + question = create(:poll_question, poll: poll) + answer1 = create(:poll_question_answer, question: question, title: 'Han Solo') + answer2 = create(:poll_question_answer, question: question, title: 'Chewbacca') + login_as(create(:user, :level_two, geozone: geozone)) visit poll_path(poll) @@ -158,7 +244,10 @@ feature 'Polls' do end scenario 'Level 2 users reading a all-geozones poll' do - create(:poll_question, poll: poll, valid_answers: 'Han Solo, Chewbacca') + question = create(:poll_question, poll: poll) + answer1 = create(:poll_question_answer, question: question, title: 'Han Solo') + answer2 = create(:poll_question_answer, question: question, title: 'Chewbacca') + login_as(create(:user, :level_two)) visit poll_path(poll) @@ -167,7 +256,9 @@ feature 'Polls' do end scenario 'Level 2 users who have already answered' do - question = create(:poll_question, poll: poll, valid_answers: 'Han Solo, Chewbacca') + question = create(:poll_question, poll: poll) + answer1 = create(:poll_question_answer, question: question, title: 'Han Solo') + answer2 = create(:poll_question_answer, question: question, title: 'Chewbacca') user = create(:user, :level_two) create(:poll_answer, question: question, author: user, answer: 'Chewbacca') @@ -175,23 +266,195 @@ feature 'Polls' do visit poll_path(poll) expect(page).to have_link('Han Solo') - expect(page).to_not have_link('Chewbacca') - expect(page).to have_content('Chewbacca') + expect(page).to have_link('Chewbacca') end scenario 'Level 2 users answering', :js do poll.update(geozone_restricted: true) poll.geozones << geozone - create(:poll_question, poll: poll, valid_answers: 'Han Solo, Chewbacca') + + question = create(:poll_question, poll: poll) + answer1 = create(:poll_question_answer, question: question, title: 'Han Solo') + answer2 = create(:poll_question_answer, question: question, title: 'Chewbacca') + user = create(:user, :level_two, geozone: geozone) + login_as user visit poll_path(poll) click_link 'Han Solo' - expect(page).to_not have_link('Han Solo') + expect(page).not_to have_link('Han Solo') expect(page).to have_link('Chewbacca') end + scenario 'Level 2 users changing answer', :js do + poll.update(geozone_restricted: true) + poll.geozones << geozone + + question = create(:poll_question, poll: poll) + answer1 = create(:poll_question_answer, question: question, title: 'Han Solo') + answer2 = create(:poll_question_answer, question: question, title: 'Chewbacca') + + user = create(:user, :level_two, geozone: geozone) + + login_as user + visit poll_path(poll) + + click_link 'Han Solo' + + expect(page).not_to have_link('Han Solo') + expect(page).to have_link('Chewbacca') + + click_link 'Chewbacca' + + expect(page).not_to have_link('Chewbacca') + expect(page).to have_link('Han Solo') + end + + scenario 'Level 2 votes, signs out, signs in, votes again', :js do + poll.update(geozone_restricted: true) + poll.geozones << geozone + + question = create(:poll_question, poll: poll) + answer1 = create(:poll_question_answer, question: question, title: 'Han Solo') + answer2 = create(:poll_question_answer, question: question, title: 'Chewbacca') + + user = create(:user, :level_two, geozone: geozone) + + login_as user + visit poll_path(poll) + click_link 'Han Solo' + + expect(page).not_to have_link('Han Solo') + expect(page).to have_link('Chewbacca') + + click_link "Sign out" + login_as user + visit poll_path(poll) + click_link 'Han Solo' + + expect(page).not_to have_link('Han Solo') + expect(page).to have_link('Chewbacca') + + click_link "Sign out" + login_as user + visit poll_path(poll) + click_link 'Chewbacca' + + expect(page).not_to have_link('Chewbacca') + expect(page).to have_link('Han Solo') + end + end + + context 'Booth & Website' do + + let(:poll) { create(:poll, summary: "Summary", description: "Description") } + let(:booth) { create(:poll_booth) } + let(:officer) { create(:poll_officer) } + + scenario 'Already voted on booth cannot vote on website', :js do + + create(:poll_shift, officer: officer, booth: booth, date: Date.current, task: :vote_collection) + booth_assignment = create(:poll_booth_assignment, poll: poll, booth: booth) + create(:poll_officer_assignment, officer: officer, booth_assignment: booth_assignment) + question = create(:poll_question, poll: poll) + create(:poll_question_answer, question: question, title: 'Han Solo') + create(:poll_question_answer, question: question, title: 'Chewbacca') + user = create(:user, :level_two, :in_census) + + login_as(officer.user) + visit new_officing_residence_path + officing_verify_residence + click_button "Confirm vote" + + expect(page).to have_content "Vote introduced!" + + visit new_officing_residence_path + click_link "Sign out" + login_as user + visit poll_path(poll) + + expect(page).to have_content "You have already participated in a physical booth. You can not participate again." + + within("#poll_question_#{question.id}_answers") do + expect(page).to have_content('Han Solo') + expect(page).to have_content('Chewbacca') + + expect(page).not_to have_link('Han Solo') + expect(page).not_to have_link('Chewbacca') + end + end + + end + + context "Results and stats" do + scenario "Show poll results and stats if enabled and poll expired" do + poll = create(:poll, :expired, results_enabled: true, stats_enabled: true) + user = create(:user) + + login_as user + visit poll_path(poll) + + expect(page).to have_content("Poll results") + expect(page).to have_content("Participation statistics") + + visit results_poll_path(poll) + expect(page).to have_content("Questions") + + visit stats_poll_path(poll) + expect(page).to have_content("Participation data") + end + + scenario "Don't show poll results and stats if not enabled" do + poll = create(:poll, :expired, results_enabled: false, stats_enabled: false) + user = create(:user) + + login_as user + visit poll_path(poll) + + expect(page).not_to have_content("Poll results") + expect(page).not_to have_content("Participation statistics") + + visit results_poll_path(poll) + expect(page).to have_content("You do not have permission to carry out the action 'results' on poll.") + + visit stats_poll_path(poll) + expect(page).to have_content("You do not have permission to carry out the action 'stats' on poll.") + end + + scenario "Don't show poll results and stats if is not expired" do + poll = create(:poll, :current, results_enabled: true, stats_enabled: true) + user = create(:user) + + login_as user + visit poll_path(poll) + + expect(page).not_to have_content("Poll results") + expect(page).not_to have_content("Participation statistics") + + visit results_poll_path(poll) + expect(page).to have_content("You do not have permission to carry out the action 'results' on poll.") + + visit stats_poll_path(poll) + expect(page).to have_content("You do not have permission to carry out the action 'stats' on poll.") + end + + scenario "Show poll results and stats if user is administrator" do + poll = create(:poll, :current, results_enabled: false, stats_enabled: false) + user = create(:administrator).user + + login_as user + visit poll_path(poll) + + expect(page).to have_content("Poll results") + expect(page).to have_content("Participation statistics") + + visit results_poll_path(poll) + expect(page).to have_content("Questions") + + visit stats_poll_path(poll) + expect(page).to have_content("Participation data") + end end end diff --git a/spec/features/polls/questions_spec.rb b/spec/features/polls/questions_spec.rb index 1563ca81a..9e7efeedc 100644 --- a/spec/features/polls/questions_spec.rb +++ b/spec/features/polls/questions_spec.rb @@ -11,121 +11,4 @@ feature 'Poll Questions' do expect(proposal_question.title).to appear_before(normal_question.title) end - - scenario 'shows the author visible name instead of a link to the author' do - poll = create(:poll) - question_with_author = create(:poll_question, poll: poll) - question_with_author_visible_name = create(:poll_question, poll: poll, author_visible_name: 'potato') - - visit question_path(question_with_author) - expect(page).to have_link(question_with_author.author.name) - - visit question_path(question_with_author_visible_name) - expect(page).to_not have_link(question_with_author_visible_name.author.name) - expect(page).to have_content(question_with_author_visible_name.author_visible_name) - end - - scenario '#show view has video_url present' do - poll = create(:poll) - normal_question = create(:poll_question, poll: poll, video_url: "https://puppyvideos.com") - - visit question_path(normal_question) - - expect(page).to have_link(normal_question.video_url) - end - - scenario '#show view has document present' do - poll = create(:poll) - normal_question = create(:poll_question, poll: poll) - document = create(:document, documentable: normal_question) - - visit question_path(normal_question) - - expect(page).to have_content(document.title) - end - - context 'Answering' do - let(:geozone) { create(:geozone) } - let(:poll) { create(:poll, geozone_restricted: true, geozone_ids: [geozone.id]) } - - scenario 'Non-logged in users' do - question = create(:poll_question, valid_answers: 'Han Solo, Chewbacca') - - visit question_path(question) - - expect(page).to have_content('You must Sign in or Sign up to participate') - end - - scenario 'Level 1 users' do - question = create(:poll_question, poll: poll, valid_answers: 'Han Solo, Chewbacca') - - login_as(create(:user, geozone: geozone)) - visit question_path(question) - - expect(page).to have_content('You must verify your account in order to answer') - end - - scenario 'Level 2 users in an poll question for a geozone which is not theirs' do - - other_poll = create(:poll, geozone_restricted: true, geozone_ids: [create(:geozone).id]) - question = create(:poll_question, poll: other_poll, valid_answers: 'Vader, Palpatine') - - login_as(create(:user, :level_two, geozone: geozone)) - visit question_path(question) - - expect(page).to have_content('This question is not available on your geozone') - end - - scenario 'Level 2 users who can answer' do - question = create(:poll_question, poll: poll, valid_answers: 'Han Solo, Chewbacca') - - login_as(create(:user, :level_two, geozone: geozone)) - visit question_path(question) - - expect(page).to have_link('Answer this question') - end - - scenario 'Level 2 users who have already answered' do - question = create(:poll_question, poll: poll, valid_answers: 'Han Solo, Chewbacca') - - user = create(:user, :level_two, geozone: geozone) - create(:poll_answer, question: question, author: user, answer: 'Chewbacca') - - login_as user - visit question_path(question) - - expect(page).to have_link('Answer this question') - end - - scenario 'Level 2 users answering', :js do - question = create(:poll_question, poll: poll, valid_answers: 'Han Solo, Chewbacca') - user = create(:user, :level_two, geozone: geozone) - - login_as user - visit question_path(question) - - expect(page).to have_link('Answer this question') - end - - scenario 'Records participation', :js do - question = create(:poll_question, poll: poll, valid_answers: 'Han Solo, Chewbacca') - user = create(:user, :level_two, geozone: geozone, gender: 'female', date_of_birth: 33.years.ago) - - login_as user - visit question_path(question) - - click_link 'Answer this question' - click_link 'Han Solo' - - expect(page).to_not have_link('Han Solo') - - voter = poll.voters.first - expect(voter.document_number).to eq(user.document_number) - expect(voter.geozone_id).to eq(user.geozone_id) - expect(voter.gender).to eq(user.gender) - expect(voter.age).to eq(33) - expect(voter.poll_id).to eq(poll.id) - end - - end end diff --git a/spec/features/polls/results_spec.rb b/spec/features/polls/results_spec.rb new file mode 100644 index 000000000..326344dd9 --- /dev/null +++ b/spec/features/polls/results_spec.rb @@ -0,0 +1,55 @@ +require 'rails_helper' + +feature 'Poll Results' do + scenario 'List each Poll question', :js do + user1 = create(:user, :level_two) + user2 = create(:user, :level_two) + user3 = create(:user, :level_two) + + poll = create(:poll, results_enabled: true) + question1 = create(:poll_question, poll: poll) + answer1 = create(:poll_question_answer, question: question1, title: 'Yes') + answer2 = create(:poll_question_answer, question: question1, title: 'No') + + question2 = create(:poll_question, poll: poll) + answer3 = create(:poll_question_answer, question: question2, title: 'Blue') + answer4 = create(:poll_question_answer, question: question2, title: 'Green') + answer5 = create(:poll_question_answer, question: question2, title: 'Yellow') + + login_as user1 + vote_for_poll_via_web(poll, question1, 'Yes') + vote_for_poll_via_web(poll, question2, 'Blue') + expect(Poll::Voter.count).to eq(1) + logout + + login_as user2 + vote_for_poll_via_web(poll, question1, 'Yes') + vote_for_poll_via_web(poll, question2, 'Green') + expect(Poll::Voter.count).to eq(2) + logout + + login_as user3 + vote_for_poll_via_web(poll, question1, 'No') + vote_for_poll_via_web(poll, question2, 'Yellow') + expect(Poll::Voter.count).to eq(3) + logout + + poll.update(ends_at: 1.day.ago) + + visit results_poll_path(poll) + + expect(page).to have_content(question1.title) + expect(page).to have_content(question2.title) + + within("#question_#{question1.id}_results_table") do + expect(find("#answer_#{answer1.id}_result")).to have_content("2 (66.0%)") + expect(find("#answer_#{answer2.id}_result")).to have_content("1 (33.0%)") + end + + within("#question_#{question2.id}_results_table") do + expect(find("#answer_#{answer3.id}_result")).to have_content("1 (33.0%)") + expect(find("#answer_#{answer4.id}_result")).to have_content("1 (33.0%)") + expect(find("#answer_#{answer5.id}_result")).to have_content("1 (33.0%)") + end + end +end diff --git a/spec/features/polls/voter_spec.rb b/spec/features/polls/voter_spec.rb new file mode 100644 index 000000000..25817bff6 --- /dev/null +++ b/spec/features/polls/voter_spec.rb @@ -0,0 +1,168 @@ +require 'rails_helper' + +feature "Voter" do + + context "Origin" do + + let(:poll) { create(:poll, :current) } + let(:question) { create(:poll_question, poll: poll) } + let(:booth) { create(:poll_booth) } + let(:officer) { create(:poll_officer) } + let!(:answer_yes) { create(:poll_question_answer, question: question, title: 'Yes') } + let!(:answer_no) { create(:poll_question_answer, question: question, title: 'No') } + + background do + create(:geozone, :in_census) + create(:poll_shift, officer: officer, booth: booth, date: Date.current, task: :vote_collection) + booth_assignment = create(:poll_booth_assignment, poll: poll, booth: booth) + create(:poll_officer_assignment, officer: officer, booth_assignment: booth_assignment) + end + + scenario "Voting via web - Standard", :js do + user = create(:user, :level_two) + + login_as user + visit poll_path(poll) + + within("#poll_question_#{question.id}_answers") do + click_link answer_yes.title + expect(page).not_to have_link(answer_yes.title) + end + + find(:css, ".js-token-message").should be_visible + token = find(:css, ".js-question-answer")[:href].gsub(/.+?(?=token)/, '').gsub('token=', '') + + expect(page).to have_content "You can write down this vote identifier, to check your vote on the final results: #{token}" + + expect(Poll::Voter.count).to eq(1) + expect(Poll::Voter.first.origin).to eq("web") + end + + scenario "Voting via web as unverified user", :js do + user = create(:user, :incomplete_verification) + + login_as user + visit poll_path(poll) + + within("#poll_question_#{question.id}_answers") do + expect(page).not_to have_link(answer_yes.title, href: "/questions/#{question.id}/answer?answer=#{answer_yes.title}&token=") + expect(page).not_to have_link(answer_no.title, href: "/questions/#{question.id}/answer?answer=#{answer_no.title}&token=") + end + + expect(page).to have_content("You must verify your account in order to answer") + expect(page).not_to have_content("You have already participated in this poll. If you vote again it will be overwritten") + end + + scenario "Voting in booth", :js do + user = create(:user, :in_census) + + login_through_form_as_officer(officer.user) + + visit new_officing_residence_path + officing_verify_residence + + expect(page).to have_content poll.name + + within("#poll_#{poll.id}") do + click_button("Confirm vote") + expect(page).not_to have_button("Confirm vote") + expect(page).to have_button('Wait, confirming vote...', disabled: true) + expect(page).to have_content "Vote introduced!" + end + + expect(Poll::Voter.count).to eq(1) + expect(Poll::Voter.first.origin).to eq("booth") + end + + context "Trying to vote the same poll in booth and web" do + + let!(:user) { create(:user, :in_census) } + + background do + end + + scenario "Trying to vote in web and then in booth", :js do + login_as user + vote_for_poll_via_web(poll, question, answer_yes.title) + expect(Poll::Voter.count).to eq(1) + + click_link "Sign out" + + login_through_form_as_officer(officer.user) + + visit new_officing_residence_path + officing_verify_residence + + expect(page).to have_content poll.name + expect(page).not_to have_button "Confirm vote" + expect(page).to have_content "Has already participated in this poll" + end + + scenario "Trying to vote in booth and then in web", :js do + login_through_form_as_officer(officer.user) + + vote_for_poll_via_booth + + visit root_path + click_link "Sign out" + + login_as user + visit poll_path(poll) + + expect(page).not_to have_link(answer_yes.title) + expect(page).to have_content "You have already participated in a physical booth. You can not participate again." + expect(Poll::Voter.count).to eq(1) + end + + scenario "Trying to vote in web again", :js do + login_as user + vote_for_poll_via_web(poll, question, answer_yes.title) + expect(Poll::Voter.count).to eq(1) + + visit poll_path(poll) + + expect(page).not_to have_selector('.js-token-message') + + expect(page).to have_content "You have already participated in this poll. If you vote again it will be overwritten." + within("#poll_question_#{question.id}_answers") do + expect(page).not_to have_link(answer_yes.title) + end + + click_link "Sign out" + + login_as user + visit poll_path(poll) + + within("#poll_question_#{question.id}_answers") do + expect(page).to have_link(answer_yes.title) + expect(page).to have_link(answer_no.title) + end + end + end + + scenario "Voting in poll and then verifiying account", :js do + user = create(:user) + + login_through_form_as_officer(officer.user) + vote_for_poll_via_booth + + visit root_path + click_link "Sign out" + + login_as user + visit account_path + click_link 'Verify my account' + + verify_residence + confirm_phone(user) + + visit poll_path(poll) + + expect(page).not_to have_link(answer_yes.title) + expect(page).to have_content "You have already participated in a physical booth. You can not participate again." + expect(Poll::Voter.count).to eq(1) + end + + end + +end diff --git a/spec/features/proposal_notifications_spec.rb b/spec/features/proposal_notifications_spec.rb index 4756a1903..647ad88c8 100644 --- a/spec/features/proposal_notifications_spec.rb +++ b/spec/features/proposal_notifications_spec.rb @@ -177,7 +177,7 @@ feature 'Proposal Notifications' do visit user_path(author) within("#proposal_#{proposal.id}") do - expect(page).to_not have_link "Send message" + expect(page).not_to have_link "Send message" end end @@ -189,12 +189,176 @@ feature 'Proposal Notifications' do login_as(user) visit new_proposal_notification_path(proposal_id: proposal.id) - expect(current_path).to eq(proposals_path) + expect(page).to have_current_path(root_path) expect(page).to have_content("You do not have permission to carry out the action") end end + context "In-app notifications from the proposal's author" do + + scenario "Voters should receive a notification", :js do + author = create(:user) + + user1 = create(:user) + user2 = create(:user) + user3 = create(:user) + + proposal = create(:proposal, author: author) + + create(:vote, voter: user1, votable: proposal, vote_flag: true) + create(:vote, voter: user2, votable: proposal, vote_flag: true) + + login_as(author) + visit root_path + + visit new_proposal_notification_path(proposal_id: proposal.id) + + fill_in 'proposal_notification_title', with: "Thank you for supporting my proposal" + fill_in 'proposal_notification_body', with: "Please share it with others so we can make it happen!" + click_button "Send message" + + expect(page).to have_content "Your message has been sent correctly." + + logout + login_as user1 + visit root_path + visit root_path + + find(".icon-notification").click + + notification_for_user1 = Notification.where(user: user1).first + expect(page).to have_css ".notification", count: 1 + expect(page).to have_content "There is one new notification on #{proposal.title}" + expect(page).to have_xpath "//a[@href='#{notification_path(notification_for_user1)}']" + + logout + login_as user2 + visit root_path + visit root_path + + find(".icon-notification").click + + notification_for_user2 = Notification.where(user: user2).first + expect(page).to have_css ".notification", count: 1 + expect(page).to have_content "There is one new notification on #{proposal.title}" + expect(page).to have_xpath "//a[@href='#{notification_path(notification_for_user2)}']" + + logout + login_as user3 + visit root_path + visit root_path + + find(".icon-no-notification").click + + expect(page).to have_css ".notification", count: 0 + end + + scenario "Followers should receive a notification", :js do + author = create(:user) + + user1 = create(:user) + user2 = create(:user) + user3 = create(:user) + + proposal = create(:proposal, author: author) + + create(:follow, :followed_proposal, user: user1, followable: proposal) + create(:follow, :followed_proposal, user: user2, followable: proposal) + + login_as author.reload + visit root_path + + visit new_proposal_notification_path(proposal_id: proposal.id) + + fill_in 'proposal_notification_title', with: "Thank you for supporting my proposal" + fill_in 'proposal_notification_body', with: "Please share it with others so we can make it happen!" + click_button "Send message" + + expect(page).to have_content "Your message has been sent correctly." + + logout + login_as user1.reload + visit root_path + + find(".icon-notification").click + + notification_for_user1 = Notification.where(user: user1).first + expect(page).to have_css ".notification", count: 1 + expect(page).to have_content "There is one new notification on #{proposal.title}" + expect(page).to have_xpath "//a[@href='#{notification_path(notification_for_user1)}']" + + logout + login_as user2.reload + visit root_path + + find(".icon-notification").click + + notification_for_user2 = Notification.where(user: user2).first + expect(page).to have_css ".notification", count: 1 + expect(page).to have_content "There is one new notification on #{proposal.title}" + expect(page).to have_xpath "//a[@href='#{notification_path(notification_for_user2)}']" + + logout + login_as user3.reload + visit root_path + + find(".icon-no-notification").click + + expect(page).to have_css ".notification", count: 0 + end + + scenario "Proposal hidden", :js do + author = create(:user) + user = create(:user) + + proposal = create(:proposal, author: author) + + create(:vote, voter: user, votable: proposal, vote_flag: true) + + login_as(author) + visit root_path + + visit new_proposal_notification_path(proposal_id: proposal.id) + + fill_in 'proposal_notification_title', with: "Thank you for supporting my proposal" + fill_in 'proposal_notification_body', with: "Please share it with others so we can make it happen!" + click_button "Send message" + + expect(page).to have_content "Your message has been sent correctly." + + proposal.hide + + logout + login_as user + visit root_path + visit root_path + + find(".icon-notification").click + + notification_for_user = Notification.where(user: user).first + expect(page).to have_css ".notification", count: 1 + expect(page).to have_content "This resource is not available anymore" + expect(page).not_to have_xpath "//a[@href='#{notification_path(notification_for_user)}']" + end + + scenario "Proposal retired by author", :js do + author = create(:user) + user = create(:user) + + proposal = create(:proposal, author: author) + + create(:vote, voter: user, votable: proposal, vote_flag: true) + + login_as(author) + visit root_path + + visit new_proposal_notification_path(proposal_id: proposal.id) + end + + pending "group notifications for the same proposal" + end + scenario "Error messages" do author = create(:user) proposal = create(:proposal, author: author) diff --git a/spec/features/proposals_spec.rb b/spec/features/proposals_spec.rb index d297a294b..c6b966304 100644 --- a/spec/features/proposals_spec.rb +++ b/spec/features/proposals_spec.rb @@ -3,7 +3,27 @@ require 'rails_helper' feature 'Proposals' do + scenario 'Disabled with a feature flag' do + Setting['feature.proposals'] = nil + expect{ visit proposals_path }.to raise_exception(FeatureFlags::FeatureDisabled) + Setting['feature.proposals'] = true + end + + context "Concerns" do + it_behaves_like 'notifiable in-app', Proposal + it_behaves_like 'relationable', Proposal + end + context 'Index' do + + before do + Setting['feature.allow_images'] = true + end + + after do + Setting['feature.allow_images'] = nil + end + scenario 'Lists featured and regular proposals' do featured_proposals = create_featured_proposals proposals = [create(:proposal), create(:proposal), create(:proposal)] @@ -38,13 +58,29 @@ feature 'Proposals' do within("ul.pagination") do expect(page).to have_content("1") - expect(page).to have_content("2") - expect(page).to_not have_content("3") + expect(page).to have_link('2', href: 'http://www.example.com/proposals?page=2') + expect(page).not_to have_content("3") click_link "Next", exact: false end expect(page).to have_selector('#proposals .proposal', count: 2) end + + scenario 'Index should show proposal descriptive image only when is defined' do + featured_proposals = create_featured_proposals + proposal = create(:proposal) + proposal_with_image = create(:proposal) + image = create(:image, imageable: proposal_with_image) + + visit proposals_path(proposal) + + within("#proposal_#{proposal.id}") do + expect(page).not_to have_css("div.with-image") + end + within("#proposal_#{proposal_with_image.id}") do + expect(page).to have_css("img[alt='#{proposal_with_image.image.title}']") + end + end end scenario 'Show' do @@ -76,7 +112,7 @@ feature 'Proposals' do right_path = proposal_path(proposal) visit right_path - expect(current_path).to eq(right_path) + expect(page).to have_current_path(right_path) end scenario 'When path does not match the friendly url' do @@ -86,8 +122,8 @@ feature 'Proposals' do old_path = "#{proposals_path}/#{proposal.id}-something-else" visit old_path - expect(current_path).to_not eq(old_path) - expect(current_path).to eq(right_path) + expect(page).not_to have_current_path(old_path) + expect(page).to have_current_path(right_path) end scenario 'Can access the community' do @@ -129,7 +165,7 @@ feature 'Proposals' do proposal = create(:proposal, video_url: nil) visit proposal_path(proposal) - expect(page).to_not have_selector("div[id='js-embedded-video']") + expect(page).not_to have_selector("div[id='js-embedded-video']") end end @@ -137,8 +173,8 @@ feature 'Proposals' do proposal = create(:proposal) visit proposal_path(proposal) - expect(page.html).to include "" - expect(page.html).to include "" + expect(page).to have_css "meta[name='twitter:title'][content=\"#{proposal.title}\"]", visible: false + expect(page).to have_css "meta[property='og:title'][content=\"#{proposal.title}\"]", visible: false end scenario 'Create' do @@ -222,7 +258,7 @@ feature 'Proposals' do expect(page.status_code).to eq(200) expect(page.html).to be_empty - expect(current_path).to eq(proposals_path) + expect(page).to have_current_path(proposals_path) end scenario 'Create proposal too fast' do @@ -244,7 +280,7 @@ feature 'Proposals' do expect(page).to have_content 'Sorry, that was too quick! Please resubmit' - expect(current_path).to eq(new_proposal_path) + expect(page).to have_current_path(new_proposal_path) end scenario 'Responsible name is stored for anonymous users' do @@ -275,7 +311,7 @@ feature 'Proposals' do login_as(author) visit new_proposal_path - expect(page).to_not have_selector('#proposal_responsible_name') + expect(page).not_to have_selector('#proposal_responsible_name') fill_in 'proposal_title', with: 'Help refugees' fill_in 'proposal_question', with: '¿Would you like to give assistance to war refugees?' @@ -323,8 +359,8 @@ feature 'Proposals' do expect(page).to have_content 'Testing an attack' expect(page.html).to include 'This is alert("an attack");
' - expect(page.html).to_not include '' - expect(page.html).to_not include '<p>This is' + expect(page.html).not_to include '' + expect(page.html).not_to include '<p>This is' end scenario 'Autolinking is applied to description' do @@ -371,13 +407,13 @@ feature 'Proposals' do expect(page).to have_content 'Testing auto link' expect(page).to have_link('http://example.org', href: 'http://example.org') expect(page).not_to have_link('click me') - expect(page.html).to_not include "" + expect(page.html).not_to include "" click_link 'Edit' - expect(current_path).to eq edit_proposal_path(Proposal.last) + expect(page).to have_current_path(edit_proposal_path(Proposal.last)) expect(page).not_to have_link('click me') - expect(page.html).to_not include "" + expect(page.html).not_to include "" end context 'Geozones' do @@ -448,7 +484,7 @@ feature 'Proposals' do within("#proposal_#{proposal.id}") do click_link 'Retire' end - expect(current_path).to eq(retire_form_proposal_path(proposal)) + expect(page).to have_current_path(retire_form_proposal_path(proposal)) select 'Duplicated', from: 'proposal_retired_reason' fill_in 'proposal_retired_explanation', with: 'There are three other better proposals with the same subject' @@ -472,7 +508,7 @@ feature 'Proposals' do click_button 'Retire proposal' - expect(page).to_not have_content 'Proposal retired' + expect(page).not_to have_content 'Proposal retired' expect(page).to have_content "can't be blank", count: 2 end @@ -486,7 +522,7 @@ feature 'Proposals' do expect(page).to have_selector('#proposals .proposal', count: 1) within('#proposals') do expect(page).to have_content not_retired.title - expect(page).to_not have_content retired.title + expect(page).not_to have_content retired.title end end @@ -497,19 +533,19 @@ feature 'Proposals' do visit proposals_path - expect(page).to_not have_content retired.title + expect(page).not_to have_content retired.title click_link 'Proposals retired by the author' expect(page).to have_content retired.title - expect(page).to_not have_content not_retired.title + expect(page).not_to have_content not_retired.title end scenario 'Retired proposals index interface elements' do visit proposals_path(retired: 'all') - expect(page).to_not have_content 'Advanced search' - expect(page).to_not have_content 'Categories' - expect(page).to_not have_content 'Districts' + expect(page).not_to have_content 'Advanced search' + expect(page).not_to have_content 'Categories' + expect(page).not_to have_content 'Districts' end scenario 'Retired proposals index has links to filter by retired_reason' do @@ -529,7 +565,7 @@ feature 'Proposals' do click_link 'Unfeasible' expect(page).to have_content unfeasible.title - expect(page).to_not have_content duplicated.title + expect(page).not_to have_content duplicated.title end end @@ -539,8 +575,8 @@ feature 'Proposals' do login_as(create(:user)) visit edit_proposal_path(proposal) - expect(current_path).not_to eq(edit_proposal_path(proposal)) - expect(current_path).to eq(proposals_path) + expect(page).not_to have_current_path(edit_proposal_path(proposal)) + expect(page).to have_current_path(root_path) expect(page).to have_content 'You do not have permission' end @@ -549,13 +585,13 @@ feature 'Proposals' do Setting["max_votes_for_proposal_edit"] = 10 11.times { create(:vote, votable: proposal) } - expect(proposal).to_not be_editable + expect(proposal).not_to be_editable login_as(proposal.author) visit edit_proposal_path(proposal) - expect(current_path).not_to eq(edit_proposal_path(proposal)) - expect(current_path).to eq(proposals_path) + expect(page).not_to have_current_path(edit_proposal_path(proposal)) + expect(page).to have_current_path(root_path) expect(page).to have_content 'You do not have permission' Setting["max_votes_for_proposal_edit"] = 1000 end @@ -565,7 +601,7 @@ feature 'Proposals' do login_as(proposal.author) visit edit_proposal_path(proposal) - expect(current_path).to eq(edit_proposal_path(proposal)) + expect(page).to have_current_path(edit_proposal_path(proposal)) fill_in 'proposal_title', with: "End child poverty" fill_in 'proposal_question', with: '¿Would you like to give assistance to war refugees?' @@ -598,30 +634,36 @@ feature 'Proposals' do scenario 'Default order is hot_score', :js do create_featured_proposals - create(:proposal, title: 'Best proposal').update_column(:hot_score, 10) - create(:proposal, title: 'Worst proposal').update_column(:hot_score, 2) - create(:proposal, title: 'Medium proposal').update_column(:hot_score, 5) + best_proposal = create(:proposal, title: 'Best proposal') + best_proposal.update_column(:hot_score, 10) + worst_proposal = create(:proposal, title: 'Worst proposal') + worst_proposal.update_column(:hot_score, 2) + medium_proposal = create(:proposal, title: 'Medium proposal') + medium_proposal.update_column(:hot_score, 5) visit proposals_path - expect('Best proposal').to appear_before('Medium proposal') - expect('Medium proposal').to appear_before('Worst proposal') + expect(best_proposal.title).to appear_before(medium_proposal.title) + expect(medium_proposal.title).to appear_before(worst_proposal.title) end scenario 'Proposals are ordered by confidence_score', :js do create_featured_proposals - create(:proposal, title: 'Best proposal').update_column(:confidence_score, 10) - create(:proposal, title: 'Worst proposal').update_column(:confidence_score, 2) - create(:proposal, title: 'Medium proposal').update_column(:confidence_score, 5) + best_proposal = create(:proposal, title: 'Best proposal') + best_proposal.update_column(:confidence_score, 10) + worst_proposal = create(:proposal, title: 'Worst proposal') + worst_proposal.update_column(:confidence_score, 2) + medium_proposal = create(:proposal, title: 'Medium proposal') + medium_proposal.update_column(:confidence_score, 5) visit proposals_path click_link 'highest rated' expect(page).to have_selector('a.active', text: 'highest rated') within '#proposals' do - expect('Best proposal').to appear_before('Medium proposal') - expect('Medium proposal').to appear_before('Worst proposal') + expect(best_proposal.title).to appear_before(medium_proposal.title) + expect(medium_proposal.title).to appear_before(worst_proposal.title) end expect(current_url).to include('order=confidence_score') @@ -631,22 +673,86 @@ feature 'Proposals' do scenario 'Proposals are ordered by newest', :js do create_featured_proposals - create(:proposal, title: 'Best proposal', created_at: Time.current) - create(:proposal, title: 'Medium proposal', created_at: Time.current - 1.hour) - create(:proposal, title: 'Worst proposal', created_at: Time.current - 1.day) + best_proposal = create(:proposal, title: 'Best proposal', created_at: Time.current) + medium_proposal = create(:proposal, title: 'Medium proposal', created_at: Time.current - 1.hour) + worst_proposal = create(:proposal, title: 'Worst proposal', created_at: Time.current - 1.day) visit proposals_path click_link 'newest' expect(page).to have_selector('a.active', text: 'newest') within '#proposals' do - expect('Best proposal').to appear_before('Medium proposal') - expect('Medium proposal').to appear_before('Worst proposal') + expect(best_proposal.title).to appear_before(medium_proposal.title) + expect(medium_proposal.title).to appear_before(worst_proposal.title) end expect(current_url).to include('order=created_at') expect(current_url).to include('page=1') end + + context 'Recommendations' do + + let!(:best_proposal) { create(:proposal, title: 'Best', cached_votes_up: 10, tag_list: "Sport") } + let!(:medium_proposal) { create(:proposal, title: 'Medium', cached_votes_up: 5, tag_list: "Sport") } + let!(:worst_proposal) { create(:proposal, title: 'Worst', cached_votes_up: 1, tag_list: "Sport") } + + before do + Setting['feature.user.recommendations'] = true + end + + after do + Setting['feature.user.recommendations'] = nil + end + + scenario 'Proposals can not ordered by recommendations when there is not an user logged', :js do + visit proposals_path + + expect(page).not_to have_selector('a', text: 'recommendations') + end + + scenario 'Should display text when there are not recommendeds results', :js do + user = create(:user) + proposal = create(:proposal, tag_list: "Distinct_to_sport") + create(:follow, followable: proposal, user: user) + login_as(user) + visit proposals_path + + click_link 'recommendations' + + expect(page).to have_content "There are not proposals related to your interests" + end + + scenario 'Should display text when user has not related interests', :js do + user = create(:user) + login_as(user) + visit proposals_path + + click_link 'recommendations' + + expect(page).to have_content "Follow proposals so we can give you recommendations" + end + + scenario 'Proposals are ordered by recommendations when there is an user logged', :js do + user = create(:user) + proposal = create(:proposal, tag_list: "Sport") + create(:follow, followable: proposal, user: user) + login_as(user) + + visit proposals_path + + click_link 'recommendations' + + expect(page).to have_selector('a.active', text: 'recommendations') + + within '#proposals-list' do + expect(best_proposal.title).to appear_before(medium_proposal.title) + expect(medium_proposal.title).to appear_before(worst_proposal.title) + end + + expect(current_url).to include('order=recommendations') + expect(current_url).to include('page=1') + end + end end feature 'Archived proposals' do @@ -656,7 +762,7 @@ feature 'Proposals' do archived_proposals = create_archived_proposals visit proposals_path - click_link 'Archived' + click_link 'archived' within("#proposals-list") do archived_proposals.each do |proposal| @@ -672,7 +778,7 @@ feature 'Proposals' do visit proposals_path within("#proposals-list") do - expect(page).to_not have_content archived_proposal.title + expect(page).not_to have_content archived_proposal.title end orders = %w{hot_score confidence_score created_at relevance} @@ -680,7 +786,7 @@ feature 'Proposals' do visit proposals_path(order: order) within("#proposals-list") do - expect(page).to_not have_content archived_proposal.title + expect(page).not_to have_content archived_proposal.title end end end @@ -715,21 +821,21 @@ feature 'Proposals' do within("#featured-proposals") do expect(page).to have_content(featured_proposal.title) - expect(page).to_not have_content(archived_proposal.title) + expect(page).not_to have_content(archived_proposal.title) end within("#proposals-list") do - expect(page).to_not have_content(featured_proposal.title) - expect(page).to_not have_content(archived_proposal.title) + expect(page).not_to have_content(featured_proposal.title) + expect(page).not_to have_content(archived_proposal.title) end - click_link "Archived" + click_link "archived" within("#featured-proposals") do expect(page).to have_content(featured_proposal.title) - expect(page).to_not have_content(archived_proposal.title) + expect(page).not_to have_content(archived_proposal.title) end within("#proposals-list") do - expect(page).to_not have_content(featured_proposal.title) + expect(page).not_to have_content(featured_proposal.title) expect(page).to have_content(archived_proposal.title) end end @@ -740,7 +846,7 @@ feature 'Proposals' do create(:proposal, :archived, title: "Some votes").update_column(:confidence_score, 25) visit proposals_path - click_link 'Archived' + click_link 'archived' within("#proposals-list") do expect(all(".proposal")[0].text).to match "Most voted" @@ -772,7 +878,7 @@ feature 'Proposals' do expect(page).to have_content(proposal1.title) expect(page).to have_content(proposal2.title) - expect(page).to_not have_content(proposal3.title) + expect(page).not_to have_content(proposal3.title) end end @@ -791,7 +897,7 @@ feature 'Proposals' do expect(page).to have_css('.proposal', count: 1) expect(page).to have_content(proposal1.title) - expect(page).to_not have_content(proposal2.title) + expect(page).not_to have_content(proposal2.title) end end @@ -827,7 +933,7 @@ feature 'Proposals' do expect(page).to have_content(proposal1.title) expect(page).to have_content(proposal2.title) - expect(page).to_not have_content(proposal3.title) + expect(page).not_to have_content(proposal3.title) end end @@ -852,7 +958,7 @@ feature 'Proposals' do within("#proposals") do expect(page).to have_content(proposal1.title) expect(page).to have_content(proposal2.title) - expect(page).to_not have_content(proposal3.title) + expect(page).not_to have_content(proposal3.title) end end @@ -875,7 +981,7 @@ feature 'Proposals' do within("#proposals") do expect(page).to have_content(proposal1.title) expect(page).to have_content(proposal2.title) - expect(page).to_not have_content(proposal3.title) + expect(page).not_to have_content(proposal3.title) end end @@ -898,7 +1004,7 @@ feature 'Proposals' do within("#proposals") do expect(page).to have_content(proposal1.title) expect(page).to have_content(proposal2.title) - expect(page).to_not have_content(proposal3.title) + expect(page).not_to have_content(proposal3.title) end end @@ -921,7 +1027,7 @@ feature 'Proposals' do within("#proposals") do expect(page).to have_content(proposal1.title) expect(page).to have_content(proposal2.title) - expect(page).to_not have_content(proposal3.title) + expect(page).not_to have_content(proposal3.title) end end @@ -944,7 +1050,7 @@ feature 'Proposals' do within("#proposals") do expect(page).to have_content(proposal1.title) expect(page).to have_content(proposal2.title) - expect(page).to_not have_content(proposal3.title) + expect(page).not_to have_content(proposal3.title) end end @@ -970,7 +1076,7 @@ feature 'Proposals' do within("#proposals") do expect(page).to have_content(proposal1.title) expect(page).to have_content(proposal2.title) - expect(page).to_not have_content(proposal3.title) + expect(page).not_to have_content(proposal3.title) end end @@ -990,7 +1096,7 @@ feature 'Proposals' do within("#proposals") do expect(page).to have_content(proposal1.title) expect(page).to have_content(proposal2.title) - expect(page).to_not have_content(proposal3.title) + expect(page).not_to have_content(proposal3.title) end end @@ -1010,7 +1116,7 @@ feature 'Proposals' do within("#proposals") do expect(page).to have_content(proposal1.title) expect(page).to have_content(proposal2.title) - expect(page).to_not have_content(proposal3.title) + expect(page).not_to have_content(proposal3.title) end end @@ -1030,7 +1136,7 @@ feature 'Proposals' do within("#proposals") do expect(page).to have_content(proposal1.title) expect(page).to have_content(proposal2.title) - expect(page).to_not have_content(proposal3.title) + expect(page).not_to have_content(proposal3.title) end end @@ -1054,7 +1160,7 @@ feature 'Proposals' do within("#proposals") do expect(page).to have_content(proposal1.title) expect(page).to have_content(proposal2.title) - expect(page).to_not have_content(proposal3.title) + expect(page).not_to have_content(proposal3.title) end end @@ -1178,10 +1284,36 @@ feature 'Proposals' do expect(all(".proposal")[0].text).to match "Show you got" expect(all(".proposal")[1].text).to match "Show you got" expect(all(".proposal")[2].text).to match "Show what you got" - expect(page).to_not have_content "Do not display" + expect(page).not_to have_content "Do not display" end end + scenario "Reorder by recommendations results maintaing search", :js do + Setting['feature.user.recommendations'] = true + user = create(:user) + login_as(user) + proposal1 = create(:proposal, title: "Show you got", cached_votes_up: 10, tag_list: "Sport") + proposal2 = create(:proposal, title: "Show what you got", cached_votes_up: 1, tag_list: "Sport") + proposal3 = create(:proposal, title: "Do not display with same tag", cached_votes_up: 100, tag_list: "Sport") + proposal4 = create(:proposal, title: "Do not display", cached_votes_up: 1) + proposal5 = create(:proposal, tag_list: "Sport") + create(:follow, followable: proposal5, user: user) + + visit proposals_path + fill_in "search", with: "Show you got" + click_button "Search" + click_link 'recommendations' + expect(page).to have_selector("a.active", text: "recommendations") + + within("#proposals") do + expect(all(".proposal")[0].text).to match "Show you got" + expect(all(".proposal")[1].text).to match "Show what you got" + expect(page).not_to have_content "Do not display with same tag" + expect(page).not_to have_content "Do not display" + end + Setting['feature.user.recommendations'] = nil + end + scenario 'After a search do not show featured proposals' do featured_proposals = create_featured_proposals proposal = create(:proposal, title: "Abcdefghi") @@ -1192,8 +1324,8 @@ feature 'Proposals' do click_button "Search" end - expect(page).to_not have_selector('#proposals .proposal-featured') - expect(page).to_not have_selector('#featured-proposals') + expect(page).not_to have_selector('#proposals .proposal-featured') + expect(page).not_to have_selector('#featured-proposals') end end @@ -1206,7 +1338,7 @@ feature 'Proposals' do expect(page).to have_content "This proposal has been flagged as inappropriate by several users." visit proposal_path(good_proposal) - expect(page).to_not have_content "This proposal has been flagged as inappropriate by several users." + expect(page).not_to have_content "This proposal has been flagged as inappropriate by several users." end scenario "Flagging", :js do @@ -1241,7 +1373,7 @@ feature 'Proposals' do expect(page).to have_css("#flag-expand-proposal-#{proposal.id}") end - expect(Flag.flagged?(user, proposal)).to_not be + expect(Flag.flagged?(user, proposal)).not_to be end scenario 'Flagging/Unflagging AJAX', :js do @@ -1269,22 +1401,22 @@ feature 'Proposals' do expect(page).to have_css("#flag-expand-proposal-#{proposal.id}") end - expect(Flag.flagged?(user, proposal)).to_not be + expect(Flag.flagged?(user, proposal)).not_to be end it_behaves_like "followable", "proposal", "proposal_path", { "id": "id" } - it_behaves_like "documentable", "proposal", "proposal_path", { "id": "id" } + it_behaves_like "imageable", "proposal", "proposal_path", { "id": "id" } - it_behaves_like "nested documentable", + it_behaves_like "nested imageable", "proposal", "new_proposal_path", { }, - "fill_new_valid_proposal", + "imageable_fill_new_valid_proposal", "Create proposal", "Proposal created successfully" - it_behaves_like "nested documentable", + it_behaves_like "nested imageable", "proposal", "edit_proposal_path", { "id": "id" }, @@ -1292,6 +1424,34 @@ feature 'Proposals' do "Save changes", "Proposal updated successfully" + it_behaves_like "documentable", "proposal", "proposal_path", { "id": "id" } + + it_behaves_like "nested documentable", + "user", + "proposal", + "new_proposal_path", + { }, + "documentable_fill_new_valid_proposal", + "Create proposal", + "Proposal created successfully" + + it_behaves_like "nested documentable", + "user", + "proposal", + "edit_proposal_path", + { "id": "id" }, + nil, + "Save changes", + "Proposal updated successfully" + + it_behaves_like "mappable", + "proposal", + "proposal", + "new_proposal_path", + "edit_proposal_path", + "proposal_path", + { } + scenario 'Erased author' do user = create(:user) proposal = create(:proposal, author: user) @@ -1335,7 +1495,7 @@ feature 'Proposals' do expect(page).to have_css('.proposal', count: 2) expect(page).to have_content(@proposal1.title) expect(page).to have_content(@proposal2.title) - expect(page).to_not have_content(@proposal3.title) + expect(page).not_to have_content(@proposal3.title) end end @@ -1350,7 +1510,7 @@ feature 'Proposals' do expect(page).to have_css('.proposal', count: 2) expect(page).to have_content(@proposal1.title) expect(page).to have_content(@proposal2.title) - expect(page).to_not have_content(@proposal3.title) + expect(page).not_to have_content(@proposal3.title) end end @@ -1365,7 +1525,7 @@ feature 'Proposals' do expect(page).to have_css('.proposal', count: 2) expect(page).to have_content(@proposal1.title) expect(page).to have_content(@proposal2.title) - expect(page).to_not have_content(@proposal3.title) + expect(page).not_to have_content(@proposal3.title) end end @@ -1390,7 +1550,7 @@ feature 'Proposals' do check "proposal_terms_of_service" within('div#js-suggest') do - expect(page).to have_content ("You are seeing 5 of 6 proposals containing the term 'search'") + expect(page).to have_content "You are seeing 5 of 6 proposals containing the term 'search'" end end @@ -1406,7 +1566,7 @@ feature 'Proposals' do check "proposal_terms_of_service" within('div#js-suggest') do - expect(page).to_not have_content ('You are seeing') + expect(page).not_to have_content 'You are seeing' end end end @@ -1468,14 +1628,17 @@ feature 'Proposals' do scenario "Orders proposals by votes" do create(:tag, :category, name: 'culture') - create(:proposal, title: 'Best', tag_list: 'culture').update_column(:confidence_score, 10) - create(:proposal, title: 'Worst', tag_list: 'culture').update_column(:confidence_score, 2) - create(:proposal, title: 'Medium', tag_list: 'culture').update_column(:confidence_score, 5) + best_proposal = create(:proposal, title: 'Best', tag_list: 'culture') + best_proposal.update_column(:confidence_score, 10) + worst_proposal = create(:proposal, title: 'Worst', tag_list: 'culture') + worst_proposal.update_column(:confidence_score, 2) + medium_proposal = create(:proposal, title: 'Medium', tag_list: 'culture') + medium_proposal.update_column(:confidence_score, 5) visit summary_proposals_path - expect('Best').to appear_before('Medium') - expect('Medium').to appear_before('Worst') + expect(best_proposal.title).to appear_before(medium_proposal.title) + expect(medium_proposal.title).to appear_before(worst_proposal.title) end scenario "Displays proposals from last week" do @@ -1491,7 +1654,7 @@ feature 'Proposals' do expect(page).to have_content(proposal1.title) expect(page).to have_content(proposal2.title) - expect(page).to_not have_content(proposal3.title) + expect(page).not_to have_content(proposal3.title) end end @@ -1508,7 +1671,7 @@ feature 'Successful proposals' do successful_proposals.each do |proposal| within("#proposal_#{proposal.id}_votes") do - expect(page).to_not have_css(".supports") + expect(page).not_to have_css(".supports") expect(page).to have_content "This proposal has reached the required supports" end end @@ -1520,7 +1683,7 @@ feature 'Successful proposals' do successful_proposals.each do |proposal| visit proposal_path(proposal) within("#proposal_#{proposal.id}_votes") do - expect(page).to_not have_css(".supports") + expect(page).not_to have_css(".supports") expect(page).to have_content "This proposal has reached the required supports" end end @@ -1533,7 +1696,7 @@ feature 'Successful proposals' do successful_proposals.each do |proposal| within("#proposal_#{proposal.id}_votes") do - expect(page).to_not have_link "Create question" + expect(page).not_to have_link "Create question" end end diff --git a/spec/features/registration_form_spec.rb b/spec/features/registration_form_spec.rb index 2d3d16a25..e6428dd60 100644 --- a/spec/features/registration_form_spec.rb +++ b/spec/features/registration_form_spec.rb @@ -6,7 +6,7 @@ feature 'Registration form' do user = create(:user) visit new_user_registration_path - expect(page).to_not have_content I18n.t("devise_views.users.registrations.new.username_is_not_available") + expect(page).not_to have_content I18n.t("devise_views.users.registrations.new.username_is_not_available") fill_in "user_username", with: user.username check 'user_terms_of_service' @@ -16,7 +16,7 @@ feature 'Registration form' do scenario 'username is available', :js do visit new_user_registration_path - expect(page).to_not have_content I18n.t("devise_views.users.registrations.new.username_is_available") + expect(page).not_to have_content I18n.t("devise_views.users.registrations.new.username_is_available") fill_in "user_username", with: "available username" check 'user_terms_of_service' @@ -57,7 +57,7 @@ feature 'Registration form' do expect(page.status_code).to eq(200) expect(page.html).to be_empty - expect(current_path).to eq(user_registration_path) + expect(page).to have_current_path(user_registration_path) end scenario 'Create organization too fast' do @@ -75,7 +75,7 @@ feature 'Registration form' do expect(page).to have_content 'Sorry, that was too quick! Please resubmit' - expect(current_path).to eq(new_user_registration_path) + expect(page).to have_current_path(new_user_registration_path) end end diff --git a/spec/features/sessions_spec.rb b/spec/features/sessions_spec.rb index 990a94d5f..c5b098a25 100644 --- a/spec/features/sessions_spec.rb +++ b/spec/features/sessions_spec.rb @@ -11,12 +11,12 @@ feature 'Sessions' do login_through_form_as(user) expect(page).to have_content('You have been signed in successfully') - expect(current_path).to eq(debate_path(debate)) + expect(page).to have_current_path(debate_path(debate)) click_link 'Sign out' expect(page).to have_content('You have been signed out successfully') - expect(current_path).to eq(debate_path(debate)) + expect(page).to have_current_path(debate_path(debate)) end end diff --git a/spec/features/site_customization/content_blocks_spec.rb b/spec/features/site_customization/content_blocks_spec.rb index 995982063..6e5de3a7c 100644 --- a/spec/features/site_customization/content_blocks_spec.rb +++ b/spec/features/site_customization/content_blocks_spec.rb @@ -8,12 +8,12 @@ feature "Custom content blocks" do visit "/?locale=en" expect(page).to have_content("content for top links") - expect(page).to_not have_content("contenido para top links") + expect(page).not_to have_content("contenido para top links") visit "/?locale=es" expect(page).to have_content("contenido para top links") - expect(page).to_not have_content("content for top links") + expect(page).not_to have_content("content for top links") end scenario "footer" do @@ -23,11 +23,11 @@ feature "Custom content blocks" do visit "/?locale=en" expect(page).to have_content("content for footer") - expect(page).to_not have_content("contenido para footer") + expect(page).not_to have_content("contenido para footer") visit "/?locale=es" expect(page).to have_content("contenido para footer") - expect(page).to_not have_content("content for footer") + expect(page).not_to have_content("content for footer") end end diff --git a/spec/features/site_customization/custom_pages_spec.rb b/spec/features/site_customization/custom_pages_spec.rb index 653f783cd..38c2536e1 100644 --- a/spec/features/site_customization/custom_pages_spec.rb +++ b/spec/features/site_customization/custom_pages_spec.rb @@ -69,7 +69,7 @@ feature "Custom Pages" do expect(page).to have_title("Custom page") expect(page).to have_selector("h1", text: "Custom page") expect(page).to have_content("Text for new custom page") - expect(page).to_not have_content("Print this info") + expect(page).not_to have_content("Print this info") end scenario "Listed in more information page" do @@ -95,7 +95,7 @@ feature "Custom Pages" do visit more_info_path - expect(page).to_not have_content("Another custom page") + expect(page).not_to have_content("Another custom page") visit custom_page.url @@ -114,7 +114,7 @@ feature "Custom Pages" do visit more_info_path - expect(page).to_not have_content("Ce texte est en français") + expect(page).not_to have_content("Ce texte est en français") visit custom_page.url diff --git a/spec/features/social_media_meta_tags_spec.rb b/spec/features/social_media_meta_tags_spec.rb new file mode 100644 index 000000000..302e010f7 --- /dev/null +++ b/spec/features/social_media_meta_tags_spec.rb @@ -0,0 +1,54 @@ +require 'rails_helper' + +feature 'Social media meta tags' do + + context 'Setting social media meta tags' do + + let(:meta_keywords) { 'citizen, participation, open government' } + let(:meta_title) { 'CONSUL TEST' } + let(:meta_description) { 'Citizen Participation and Open Government Application' } + let(:twitter_handle) { '@consul_test' } + let(:url) { 'http://consul.dev' } + let(:facebook_handle) { 'consultest' } + let(:org_name) { 'CONSUL TEST' } + + before do + Setting['meta_keywords'] = meta_keywords + Setting['meta_title'] = meta_title + Setting['meta_description'] = meta_description + Setting['twitter_handle'] = twitter_handle + Setting['url'] = url + Setting['facebook_handle'] = facebook_handle + Setting['org_name'] = org_name + end + + after do + Setting['meta_keywords'] = nil + Setting['meta_title'] = nil + Setting['meta_description'] = nil + Setting['twitter_handle'] = nil + Setting['url'] = 'http://example.com' + Setting['facebook_handle'] = nil + Setting['org_name'] = 'CONSUL' + end + + scenario 'Social media meta tags partial render settings content' do + + visit root_path + + expect(page).to have_css 'meta[name="keywords"][content="' + meta_keywords + '"]', visible: false + expect(page).to have_css 'meta[name="twitter:site"][content="' + twitter_handle + '"]', visible: false + expect(page).to have_css 'meta[name="twitter:title"][content="' + meta_title + '"]', visible: false + expect(page).to have_css 'meta[name="twitter:description"][content="' + meta_description + '"]', visible: false + expect(page).to have_css 'meta[name="twitter:image"][content="http://www.example.com/social_media_icon_twitter.png"]', visible: false + expect(page).to have_css 'meta[property="og:title"][content="' + meta_title + '"]', visible: false + expect(page).to have_css 'meta[property="article:publisher"][content="' + url + '"]', visible: false + expect(page).to have_css 'meta[property="article:author"][content="https://www.facebook.com/' + facebook_handle + '"]', visible: false + expect(page).to have_css 'meta[property="og:url"][content="http://www.example.com/"]', visible: false + expect(page).to have_css 'meta[property="og:image"][content="http://www.example.com/social_media_icon.png"]', visible: false + expect(page).to have_css 'meta[property="og:site_name"][content="' + org_name + '"]', visible: false + expect(page).to have_css 'meta[property="og:description"][content="' + meta_description + '"]', visible: false + end + end + +end diff --git a/spec/features/tags/budget_investments_spec.rb b/spec/features/tags/budget_investments_spec.rb index fe1eed0e1..f244583a6 100644 --- a/spec/features/tags/budget_investments_spec.rb +++ b/spec/features/tags/budget_investments_spec.rb @@ -6,19 +6,22 @@ feature 'Tags' do let(:budget) { create(:budget, name: "Big Budget") } let(:group) { create(:budget_group, name: "Health", budget: budget) } let!(:heading) { create(:budget_heading, name: "More hospitals", group: group) } + let!(:tag_medio_ambiente) { create(:tag, :category, name: 'Medio Ambiente') } + let!(:tag_economia) { create(:tag, :category, name: 'Economía') } + let(:admin) { create(:administrator).user } scenario 'Index' do - earth = create(:budget_investment, heading: heading, tag_list: 'Medio Ambiente') - money = create(:budget_investment, heading: heading, tag_list: 'Economía') + earth = create(:budget_investment, heading: heading, tag_list: tag_medio_ambiente.name) + money = create(:budget_investment, heading: heading, tag_list: tag_economia.name) visit budget_investments_path(budget, heading_id: heading.id) within "#budget_investment_#{earth.id}" do - expect(page).to have_content "Medio Ambiente" + expect(page).to have_content(tag_medio_ambiente.name) end within "#budget_investment_#{money.id}" do - expect(page).to have_content "Economía" + expect(page).to have_content(tag_economia.name) end end @@ -49,12 +52,12 @@ feature 'Tags' do end scenario 'Show' do - investment = create(:budget_investment, heading: heading, tag_list: 'Hacienda, Economía') + investment = create(:budget_investment, heading: heading, tag_list: "#{tag_medio_ambiente.name}, #{tag_economia.name}") visit budget_investment_path(budget, investment) - expect(page).to have_content "Economía" - expect(page).to have_content "Hacienda" + expect(page).to have_content(tag_medio_ambiente.name) + expect(page).to have_content(tag_economia.name) end scenario 'Create with custom tags' do @@ -62,41 +65,38 @@ feature 'Tags' do visit new_budget_investment_path(budget_id: budget.id) - select 'Health: More hospitals', from: 'budget_investment_heading_id' + select "#{group.name}: #{heading.name}", from: 'budget_investment_heading_id' fill_in 'budget_investment_title', with: 'Build a skyscraper' fill_in 'budget_investment_description', with: 'I want to live in a high tower over the clouds' check 'budget_investment_terms_of_service' - fill_in 'budget_investment_tag_list', with: 'Economía, Hacienda' + fill_in 'budget_investment_tag_list', with: "#{tag_medio_ambiente.name}, #{tag_economia.name}" click_button 'Create Investment' expect(page).to have_content 'Investment created successfully.' - expect(page).to have_content 'Economía' - expect(page).to have_content 'Hacienda' + expect(page).to have_content tag_economia.name + expect(page).to have_content tag_medio_ambiente.name end scenario 'Category with category tags', :js do login_as(author) - education = create(:tag, :category, name: 'Education') - health = create(:tag, :category, name: 'Health') - visit new_budget_investment_path(budget_id: budget.id) - select 'Health: More hospitals', from: 'budget_investment_heading_id' + select "#{group.name}: #{heading.name}", from: 'budget_investment_heading_id' fill_in 'budget_investment_title', with: 'Build a skyscraper' fill_in_ckeditor 'budget_investment_description', with: 'If I had a gym near my place I could go do Zumba' check 'budget_investment_terms_of_service' - find('.js-add-tag-link', text: 'Education').click + find('.js-add-tag-link', text: tag_economia.name).click click_button 'Create Investment' expect(page).to have_content 'Investment created successfully.' within "#tags_budget_investment_#{Budget::Investment.last.id}" do - expect(page).to have_content 'Education' - expect(page).to_not have_content 'Health' + expect(page).to have_content tag_economia.name + expect(page).not_to have_content tag_medio_ambiente.name end end @@ -105,7 +105,7 @@ feature 'Tags' do visit new_budget_investment_path(budget_id: budget.id) - select 'Health: More hospitals', from: 'budget_investment_heading_id' + select "#{group.name}: #{heading.name}", from: 'budget_investment_heading_id' fill_in 'budget_investment_title', with: 'Build a skyscraper' fill_in 'budget_investment_description', with: 'I want to live in a high tower over the clouds' check 'budget_investment_terms_of_service' @@ -123,7 +123,7 @@ feature 'Tags' do visit new_budget_investment_path(budget_id: budget.id) - select 'Health: More hospitals', from: 'budget_investment_heading_id' + select "#{group.name}: #{heading.name}", from: 'budget_investment_heading_id' fill_in 'budget_investment_title', with: 'Build a skyscraper' fill_in 'budget_investment_description', with: 'I want to live in a high tower over the clouds' check 'budget_investment_terms_of_service' @@ -136,20 +136,20 @@ feature 'Tags' do expect(page).to have_content 'user_id1' expect(page).to have_content 'a3' expect(page).to have_content 'scriptalert("hey");script' - expect(page.html).to_not include 'user_id=1, &a=3, ' + expect(page.html).not_to include 'user_id=1, &a=3, ' end context "Filter" do scenario "From index" do - investment1 = create(:budget_investment, heading: heading, tag_list: 'Education') + investment1 = create(:budget_investment, heading: heading, tag_list: tag_economia.name) investment2 = create(:budget_investment, heading: heading, tag_list: 'Health') visit budget_investments_path(budget, heading_id: heading.id) within "#budget_investment_#{investment1.id}" do - click_link "Education" + click_link tag_economia.name end within("#budget-investments") do @@ -159,12 +159,12 @@ feature 'Tags' do end scenario "From show" do - investment1 = create(:budget_investment, heading: heading, tag_list: 'Education') + investment1 = create(:budget_investment, heading: heading, tag_list: tag_economia.name) investment2 = create(:budget_investment, heading: heading, tag_list: 'Health') visit budget_investment_path(budget, investment1) - click_link "Education" + click_link tag_economia.name within("#budget-investments") do expect(page).to have_css('.budget-investment', count: 1) @@ -176,19 +176,22 @@ feature 'Tags' do context 'Tag cloud' do - let!(:investment1) { create(:budget_investment, heading: heading, tag_list: 'Medio Ambiente') } - let!(:investment2) { create(:budget_investment, heading: heading, tag_list: 'Medio Ambiente') } - let!(:investment3) { create(:budget_investment, heading: heading, tag_list: 'Economía') } + let(:new_tag) { "New Tag" } + let(:newer_tag) { "Newer" } + let!(:investment1) { create(:budget_investment, heading: heading, tag_list: new_tag) } + let!(:investment2) { create(:budget_investment, heading: heading, tag_list: new_tag) } + let!(:investment3) { create(:budget_investment, heading: heading, tag_list: newer_tag) } scenario 'Display user tags' do Budget::PHASES.each do |phase| budget.update(phase: phase) + login_as(admin) if budget.drafting? visit budget_investments_path(budget, heading_id: heading.id) within "#tag-cloud" do - expect(page).to have_content "Medio Ambiente" - expect(page).to have_content "Economía" + expect(page).to have_content(new_tag) + expect(page).to have_content(newer_tag) end end end @@ -203,17 +206,18 @@ feature 'Tags' do end end + login_as(admin) if budget.drafting? visit budget_path(budget) click_link group.name within "#tag-cloud" do - click_link "Medio Ambiente" + click_link new_tag end expect(page).to have_css ".budget-investment", count: 2 expect(page).to have_content investment1.title expect(page).to have_content investment2.title - expect(page).to_not have_content investment3.title + expect(page).not_to have_content investment3.title end end @@ -221,22 +225,20 @@ feature 'Tags' do context "Categories" do - let!(:tag1) { create(:tag, :category, name: 'Medio Ambiente') } - let!(:tag2) { create(:tag, :category, name: 'Economía') } - - let!(:investment1) { create(:budget_investment, heading: heading, tag_list: 'Medio Ambiente') } - let!(:investment2) { create(:budget_investment, heading: heading, tag_list: 'Medio Ambiente') } - let!(:investment3) { create(:budget_investment, heading: heading, tag_list: 'Economía') } + let!(:investment1) { create(:budget_investment, heading: heading, tag_list: tag_medio_ambiente.name) } + let!(:investment2) { create(:budget_investment, heading: heading, tag_list: tag_medio_ambiente.name) } + let!(:investment3) { create(:budget_investment, heading: heading, tag_list: tag_economia.name) } scenario 'Display category tags' do Budget::PHASES.each do |phase| budget.update(phase: phase) + login_as(admin) if budget.drafting? visit budget_investments_path(budget, heading_id: heading.id) within "#categories" do - expect(page).to have_content "Medio Ambiente" - expect(page).to have_content "Economía" + expect(page).to have_content(tag_medio_ambiente.name) + expect(page).to have_content(tag_economia.name) end end end @@ -251,17 +253,18 @@ feature 'Tags' do end end + login_as(admin) if budget.drafting? visit budget_path(budget) click_link group.name within "#categories" do - click_link "Medio Ambiente" + click_link tag_medio_ambiente.name end expect(page).to have_css ".budget-investment", count: 2 expect(page).to have_content investment1.title expect(page).to have_content investment2.title - expect(page).to_not have_content investment3.title + expect(page).not_to have_content investment3.title end end end @@ -276,7 +279,7 @@ feature 'Tags' do visit budget_investment_path(budget, investment) expect(page).to have_content 'Park' - expect(page).to_not have_content 'Education' + expect(page).not_to have_content 'Education' end scenario "Valuators do not see user tags" do @@ -284,15 +287,14 @@ feature 'Tags' do investment.set_tag_list_on(:valuation, 'Education') investment.save - admin = create(:administrator) - login_as(admin.user) + login_as(admin) visit admin_budget_budget_investment_path(budget, investment) click_link 'Edit classification' expect(page).to have_content 'Education' - expect(page).to_not have_content 'Park' + expect(page).not_to have_content 'Park' end end -end \ No newline at end of file +end diff --git a/spec/features/tags/debates_spec.rb b/spec/features/tags/debates_spec.rb index 6bfca4772..99578b3e1 100644 --- a/spec/features/tags/debates_spec.rb +++ b/spec/features/tags/debates_spec.rb @@ -48,8 +48,8 @@ feature 'Tags' do visit debates_path(tag: "123") - expect(page).to_not have_selector('#debates .debate-featured') - expect(page).to_not have_selector('#featured-debates') + expect(page).not_to have_selector('#debates .debate-featured') + expect(page).not_to have_selector('#featured-debates') end scenario 'Show' do @@ -115,7 +115,7 @@ feature 'Tags' do expect(page).to have_content 'user_id1' expect(page).to have_content 'a3' expect(page).to have_content 'scriptalert("hey");script' - expect(page.html).to_not include 'user_id=1, &a=3, ' + expect(page.html).not_to include 'user_id=1, &a=3, ' end scenario 'Update' do @@ -146,7 +146,7 @@ feature 'Tags' do click_button 'Save changes' expect(page).to have_content 'Debate updated successfully.' - expect(page).to_not have_content 'Economía' + expect(page).not_to have_content 'Economía' end context "Filter" do @@ -211,7 +211,7 @@ feature 'Tags' do expect(page).to have_css ".debate", count: 2 expect(page).to have_content debate1.title expect(page).to have_content debate2.title - expect(page).to_not have_content debate3.title + expect(page).not_to have_content debate3.title end end diff --git a/spec/features/tags/proposals_spec.rb b/spec/features/tags/proposals_spec.rb index d2a16b8f7..7c8a5c026 100644 --- a/spec/features/tags/proposals_spec.rb +++ b/spec/features/tags/proposals_spec.rb @@ -36,8 +36,8 @@ feature 'Tags' do visit proposals_path(tag: "123") - expect(page).to_not have_selector('#proposals .proposal-featured') - expect(page).to_not have_selector('#featured-proposals') + expect(page).not_to have_selector('#proposals .proposal-featured') + expect(page).not_to have_selector('#featured-proposals') end scenario 'Index shows 3 tags with no plus link' do @@ -114,7 +114,7 @@ feature 'Tags' do within "#tags_proposal_#{Proposal.last.id}" do expect(page).to have_content 'Education' - expect(page).to_not have_content 'Health' + expect(page).not_to have_content 'Health' end end @@ -160,7 +160,7 @@ feature 'Tags' do expect(page).to have_content 'user_id1' expect(page).to have_content 'a3' expect(page).to have_content 'scriptalert("hey");script' - expect(page.html).to_not include 'user_id=1, &a=3, ' + expect(page.html).not_to include 'user_id=1, &a=3, ' end scenario 'Update' do @@ -191,7 +191,7 @@ feature 'Tags' do click_button 'Save changes' expect(page).to have_content 'Proposal updated successfully.' - expect(page).to_not have_content 'Economía' + expect(page).not_to have_content 'Economía' end context "Filter" do @@ -257,7 +257,7 @@ feature 'Tags' do expect(page).to have_css ".proposal", count: 2 expect(page).to have_content proposal1.title expect(page).to have_content proposal2.title - expect(page).to_not have_content proposal3.title + expect(page).not_to have_content proposal3.title end end @@ -296,7 +296,7 @@ feature 'Tags' do expect(page).to have_css ".proposal", count: 2 expect(page).to have_content proposal1.title expect(page).to have_content proposal2.title - expect(page).to_not have_content proposal3.title + expect(page).not_to have_content proposal3.title end end end diff --git a/spec/features/tags_spec.rb b/spec/features/tags_spec.rb index 8497d5b63..4aeec69df 100644 --- a/spec/features/tags_spec.rb +++ b/spec/features/tags_spec.rb @@ -30,8 +30,8 @@ feature 'Tags' do expect(page).to have_css('.debate', count: 2) expect(page).to have_content(debate1.title) expect(page).to have_content(debate2.title) - expect(page).to_not have_content(debate3.title) - expect(page).to_not have_content(debate4.title) + expect(page).not_to have_content(debate3.title) + expect(page).not_to have_content(debate4.title) end visit debates_path(search: 'salud') @@ -40,8 +40,8 @@ feature 'Tags' do expect(page).to have_css('.debate', count: 2) expect(page).to have_content(debate1.title) expect(page).to have_content(debate2.title) - expect(page).to_not have_content(debate3.title) - expect(page).to_not have_content(debate4.title) + expect(page).not_to have_content(debate3.title) + expect(page).not_to have_content(debate4.title) end end @@ -118,7 +118,7 @@ feature 'Tags' do click_button 'Save changes' expect(page).to have_content 'Debate updated successfully.' - expect(page).to_not have_content 'Economía' + expect(page).not_to have_content 'Economía' end context 'Tag cloud' do @@ -159,7 +159,7 @@ feature 'Tags' do within "#tag-cloud" do expect(page).to have_css(".tag", count: 1) expect(page).to have_content "Corrupción" - expect(page).to_not have_content "Economía" + expect(page).not_to have_content "Economía" end end @@ -175,7 +175,7 @@ feature 'Tags' do within "#tag-cloud" do expect(page).to have_css(".tag", count: 1) expect(page).to have_content "Playa" - expect(page).to_not have_content "Agua" + expect(page).not_to have_content "Agua" end end @@ -193,7 +193,7 @@ feature 'Tags' do expect(page).to have_css ".proposal", count: 2 expect(page).to have_content proposal1.title expect(page).to have_content proposal2.title - expect(page).to_not have_content proposal3.title + expect(page).not_to have_content proposal3.title end end diff --git a/spec/features/topics_specs.rb b/spec/features/topics_specs.rb index 0ba674844..51342af02 100644 --- a/spec/features/topics_specs.rb +++ b/spec/features/topics_specs.rb @@ -2,15 +2,22 @@ require 'rails_helper' feature 'Topics' do + context "Concerns" do + it_behaves_like 'notifiable in-app', Topic + end + context 'New' do - scenario 'Should display disabled button to new topic page without user logged', :js do + scenario 'Create new topic link should redirect to sign up for anonymous users', :js do proposal = create(:proposal) community = proposal.community + logout visit community_path(community) + click_link "Create topic" - expect(page).to have_selector(".button.expanded.disabled") + expect(page).to have_content "Sign in with:" + expect(page).to have_current_path(new_user_session_path) end scenario 'Can access to new topic page with user logged', :js do @@ -34,8 +41,8 @@ feature 'Topics' do click_link "Create topic" - expect(page).to have_content "Topic Title" - expect(page).to have_content "Description" + expect(page).to have_content "Title" + expect(page).to have_content "Initial text" expect(page).to have_content "Recommendations to create a topic" expect(page).to have_content "Do not write the topic title or whole sentences in capital letters. On the internet that is considered shouting. And no one likes to be yelled at." expect(page).to have_content "Any topic or comment that implies an illegal action will be eliminated, also those that intend to sabotage the spaces of the subject, everything else is allowed." @@ -59,7 +66,7 @@ feature 'Topics' do click_button "Create topic" expect(page).to have_content "New topic title" - expect(current_path).to eq(community_path(community)) + expect(page).to have_current_path(community_path(community)) end scenario 'Can not create a new topic when user not logged', :js do @@ -88,7 +95,7 @@ feature 'Topics' do click_button "Edit topic" expect(page).to have_content "Edit topic title" - expect(current_path).to eq(community_path(community)) + expect(page).to have_current_path(community_path(community)) end scenario 'Can not edit a topic when user logged is not an author' do @@ -128,13 +135,13 @@ feature 'Topics' do user = create(:user) topic = create(:topic, community: community, author: user) login_as(user) - visit community_path(community) + visit community_topic_path(community, topic) - click_link "Destroy" + click_link "Destroy topic" expect(page).to have_content "Topic deleted successfully." expect(page).not_to have_content topic.title - expect(current_path).to eq(community_path(community)) + expect(page).to have_current_path(community_path(community)) end scenario 'Can not destroy a topic when user logged is not an author' do diff --git a/spec/features/tracks_spec.rb b/spec/features/tracks_spec.rb index d93f0591c..2e2e4ec2f 100644 --- a/spec/features/tracks_spec.rb +++ b/spec/features/tracks_spec.rb @@ -53,24 +53,7 @@ feature 'Tracking' do expect(page.html).to include "data-track-event-action=start_census" end - scenario 'Verification: success census' do - create(:geozone) - user = create(:user) - login_as(user) - - visit account_path - click_link 'Verify my account' - - verify_residence - - fill_in 'sms_phone', with: "611111111" - click_button 'Send' - - expect(page.html).to include "data-track-event-category=verification" - expect(page.html).to include "data-track-event-action=start_sms" - end - - scenario 'Verification: start sms' do + scenario 'Verification: success census & start sms' do create(:geozone) user = create(:user) login_as(user) diff --git a/spec/features/users_auth_spec.rb b/spec/features/users_auth_spec.rb index c082ba85a..931a9638e 100644 --- a/spec/features/users_auth_spec.rb +++ b/spec/features/users_auth_spec.rb @@ -87,7 +87,7 @@ feature 'Users' do fill_in 'user_password', with: 'symbiote' click_button 'Enter' - expect(page).to_not have_content 'You have been signed in successfully.' + expect(page).not_to have_content 'You have been signed in successfully.' expect(page).to have_content 'Invalid login or password.' fill_in 'user_login', with: 'venom@nyc.dev' @@ -145,7 +145,7 @@ feature 'Users' do click_link 'Sign up with Twitter' - expect(current_path).to eq(new_user_session_path) + expect(page).to have_current_path(new_user_session_path) expect(page).to have_content "To continue, please click on the confirmation link that we have sent you via email" confirm_email @@ -170,7 +170,7 @@ feature 'Users' do click_link 'Register' click_link 'Sign up with Twitter' - expect(current_path).to eq(finish_signup_path) + expect(page).to have_current_path(finish_signup_path) fill_in 'user_email', with: 'manueladelascarmenas@example.com' click_button 'Register' @@ -198,7 +198,7 @@ feature 'Users' do click_link 'Register' click_link 'Sign up with Twitter' - expect(current_path).to eq(finish_signup_path) + expect(page).to have_current_path(finish_signup_path) click_link 'Cancel login' visit '/' @@ -232,13 +232,13 @@ feature 'Users' do click_link 'Register' click_link 'Sign up with Twitter' - expect(current_path).to eq(finish_signup_path) + expect(page).to have_current_path(finish_signup_path) expect(page).to have_field('user_username', with: 'manuela') click_button 'Register' - expect(current_path).to eq(do_finish_signup_path) + expect(page).to have_current_path(do_finish_signup_path) fill_in 'user_username', with: 'manuela2' click_button 'Register' @@ -260,12 +260,12 @@ feature 'Users' do click_link 'Register' click_link 'Sign up with Twitter' - expect(current_path).to eq(finish_signup_path) + expect(page).to have_current_path(finish_signup_path) fill_in 'user_email', with: 'manuela@example.com' click_button 'Register' - expect(current_path).to eq(do_finish_signup_path) + expect(page).to have_current_path(do_finish_signup_path) fill_in 'user_email', with: 'somethingelse@example.com' click_button 'Register' @@ -295,7 +295,7 @@ feature 'Users' do click_link 'Register' click_link 'Sign up with Twitter' - expect(current_path).to eq(finish_signup_path) + expect(page).to have_current_path(finish_signup_path) expect(page).to have_field('user_email', with: 'manuelacarmena@example.com') fill_in 'user_email', with: 'somethingelse@example.com' @@ -377,7 +377,7 @@ feature 'Users' do login_as(admin.user) visit root_path - expect(page).to_not have_content "Your password is expired" + expect(page).not_to have_content "Your password is expired" end scenario 'Sign in, user with password expired' do @@ -386,7 +386,7 @@ feature 'Users' do login_as(user) visit root_path - expect(page).to_not have_content "Your password is expired" + expect(page).not_to have_content "Your password is expired" end scenario 'Admin with password expired trying to use same password' do diff --git a/spec/features/users_spec.rb b/spec/features/users_spec.rb index ae2bac6d1..14615379e 100644 --- a/spec/features/users_spec.rb +++ b/spec/features/users_spec.rb @@ -24,7 +24,7 @@ feature 'Users' do scenario 'shows only items where user has activity' do @user.proposals.destroy_all - expect(page).to_not have_content('0 Proposals') + expect(page).not_to have_content('0 Proposals') expect(page).to have_content('1 Debate') expect(page).to have_content('3 Investments') expect(page).to have_content('4 Comments') @@ -36,11 +36,11 @@ feature 'Users' do end @user.debates.each do |debate| - expect(page).to_not have_content(debate.title) + expect(page).not_to have_content(debate.title) end @user.comments.each do |comment| - expect(page).to_not have_content(comment.body) + expect(page).not_to have_content(comment.body) end end @@ -78,11 +78,11 @@ feature 'Users' do end @user.proposals.each do |proposal| - expect(page).to_not have_content(proposal.title) + expect(page).not_to have_content(proposal.title) end @user.comments.each do |comment| - expect(page).to_not have_content(comment.body) + expect(page).not_to have_content(comment.body) end click_link '4 Comments' @@ -92,11 +92,11 @@ feature 'Users' do end @user.proposals.each do |proposal| - expect(page).to_not have_content(proposal.title) + expect(page).not_to have_content(proposal.title) end @user.debates.each do |debate| - expect(page).to_not have_content(debate.title) + expect(page).not_to have_content(debate.title) end click_link '2 Proposals' @@ -106,11 +106,11 @@ feature 'Users' do end @user.comments.each do |comment| - expect(page).to_not have_content(comment.body) + expect(page).not_to have_content(comment.body) end @user.debates.each do |debate| - expect(page).to_not have_content(debate.title) + expect(page).not_to have_content(debate.title) end end @@ -125,7 +125,7 @@ feature 'Users' do visit user_path(@user) expect(page).to have_content(@user.username) - expect(page).to_not have_content('activity list private') + expect(page).not_to have_content('activity list private') end scenario 'user can hide public page' do @@ -149,7 +149,7 @@ feature 'Users' do click_button 'Save changes' visit user_path(@user) - expect(page).to_not have_content('activity list private') + expect(page).not_to have_content('activity list private') end scenario 'is always visible for admins' do @@ -163,7 +163,7 @@ feature 'Users' do login_as(create(:administrator).user) visit user_path(@user) - expect(page).to_not have_content('activity list private') + expect(page).not_to have_content('activity list private') end scenario 'is always visible for moderators' do @@ -177,7 +177,7 @@ feature 'Users' do login_as(create(:moderator).user) visit user_path(@user) - expect(page).to_not have_content('activity list private') + expect(page).not_to have_content('activity list private') end feature 'User email' do @@ -188,19 +188,19 @@ feature 'Users' do scenario 'is not shown if no user logged in' do visit user_path(@user) - expect(page).to_not have_content(@user.email) + expect(page).not_to have_content(@user.email) end scenario 'is not shown if logged in user is a regular user' do login_as(create(:user)) visit user_path(@user) - expect(page).to_not have_content(@user.email) + expect(page).not_to have_content(@user.email) end scenario 'is not shown if logged in user is moderator' do login_as(create(:moderator).user) visit user_path(@user) - expect(page).to_not have_content(@user.email) + expect(page).not_to have_content(@user.email) end scenario 'is shown if logged in user is admin' do @@ -259,6 +259,9 @@ feature 'Users' do end scenario 'User can display public page' do + proposal = create(:proposal, tag_list: "Sport") + create(:follow, :followed_proposal, followable: proposal, user: @user) + login_as(@user) visit account_path @@ -267,22 +270,29 @@ feature 'Users' do logout - visit user_path(@user) + visit user_path(@user, filter: 'follows', page: '1') + expect(page).to have_css('#public_interests') end scenario 'Is always visible for the owner' do + proposal = create(:proposal, tag_list: "Sport") + create(:follow, :followed_proposal, followable: proposal, user: @user) + login_as(@user) visit account_path uncheck 'account_public_interests' click_button 'Save changes' - visit user_path(@user) + visit user_path(@user, filter: 'follows', page: '1') expect(page).to have_css('#public_interests') end scenario 'Is always visible for admins' do + proposal = create(:proposal, tag_list: "Sport") + create(:follow, :followed_proposal, followable: proposal, user: @user) + login_as(@user) visit account_path @@ -292,11 +302,14 @@ feature 'Users' do logout login_as(create(:administrator).user) - visit user_path(@user) + visit user_path(@user, filter: 'follows', page: '1') expect(page).to have_css('#public_interests') end scenario 'Is always visible for moderators' do + proposal = create(:proposal, tag_list: "Sport") + create(:follow, :followed_proposal, followable: proposal, user: @user) + login_as(@user) visit account_path @@ -306,38 +319,29 @@ feature 'Users' do logout login_as(create(:moderator).user) - visit user_path(@user) + visit user_path(@user, filter: 'follows', page: '1') expect(page).to have_css('#public_interests') end scenario 'Should display generic interests title' do - @user.update(public_interests: true) - visit user_path(@user) + proposal = create(:proposal, tag_list: "Sport") + create(:follow, :followed_proposal, followable: proposal, user: @user) - expect(page).to have_content("List of interests (Tags of elements this user follows)") + @user.update(public_interests: true) + visit user_path(@user, filter: 'follows', page: '1') + + expect(page).to have_content("Tags of elements this user follows") end scenario 'Should display custom interests title when user is visiting own user page' do + proposal = create(:proposal, tag_list: "Sport") + create(:follow, :followed_proposal, followable: proposal, user: @user) + @user.update(public_interests: true) login_as(@user) - visit user_path(@user) + visit user_path(@user, filter: 'follows', page: '1') - expect(page).to have_content("List of interests (Tags of elements you follow)") - end - - scenario 'Should display generic empty interests list message when visited user has not interests defined' do - @user.update(public_interests: true) - visit user_path(@user) - - expect(page).to have_content("This user does not follow any elements yet.") - end - - scenario 'Should display custom empty interests list message when user has not interests defined and user is visiting own user page' do - @user.update(public_interests: true) - login_as(@user) - visit user_path(@user) - - expect(page).to have_content("You do not follow any elements yet.") + expect(page).to have_content("Tags of elements you follow") end end @@ -351,7 +355,7 @@ feature 'Users' do visit user_path(moderator) expect(page).to have_content("1 Comment") expect(page).to have_content(comment.body) - expect(page).to_not have_content(moderator_comment.body) + expect(page).not_to have_content(moderator_comment.body) end scenario 'comments posted as admin are not visible in user activity' do @@ -361,7 +365,7 @@ feature 'Users' do visit user_path(admin) expect(page).to have_content(comment.body) - expect(page).to_not have_content(admin_comment.body) + expect(page).not_to have_content(admin_comment.body) end scenario 'shows only comments from active features' do @@ -418,22 +422,22 @@ feature 'Users' do expect(page).to have_content('1 Following') end - scenario 'Display accordion proposal tab when user is following one proposal at least' do + scenario 'Display proposal tab when user is following one proposal at least' do proposal = create(:proposal) create(:follow, followable: proposal, user: @user) visit user_path(@user, filter: "follows") - expect(page).to have_link('Citizen proposals', href: "#") + expect(page).to have_link('Citizen proposals', href: "#citizen_proposals") end - scenario 'Not display accordion proposal tab when user is not following any proposal' do + scenario 'Not display proposal tab when user is not following any proposal' do visit user_path(@user, filter: "follows") - expect(page).not_to have_link('Citizen proposals', href: "#") + expect(page).not_to have_link('Citizen proposals', href: "#citizen_proposals") end - scenario 'Display proposal with action buttons inside accordion proposal tab when current user is proposal author', :js do + scenario 'Display proposals with link to proposal' do proposal = create(:proposal, author: @user) create(:follow, followable: proposal, user: @user) login_as @user @@ -442,35 +446,7 @@ feature 'Users' do click_link 'Citizen proposals' expect(page).to have_content proposal.title - expect(page).to have_link "Send notification" - expect(page).to have_link "Retire" end - - scenario 'Display proposal with action buttons inside accordion proposal tab when there is no logged user', :js do - proposal = create(:proposal, author: @user) - create(:follow, followable: proposal, user: @user) - - visit user_path(@user, filter: "follows") - click_link 'Citizen proposals' - - expect(page).to have_content proposal.title - expect(page).not_to have_link "Send notification" - expect(page).not_to have_link "Retire" - end - - scenario 'Display proposal without action buttons inside accordion proposal tab when current user is not proposal author', :js do - proposal = create(:proposal) - create(:follow, followable: proposal, user: @user) - login_as @user - - visit user_path(@user, filter: "follows") - click_link 'Citizen proposals' - - expect(page).to have_content proposal.title - expect(page).not_to have_link "Send notification" - expect(page).not_to have_link "Retire" - end - end describe 'Budget Investments' do @@ -484,35 +460,22 @@ feature 'Users' do expect(page).to have_content('1 Following') end - scenario 'Display accordion budget investment tab when user is following one budget investment at least' do + scenario 'Display budget investment tab when user is following one budget investment at least' do budget_investment = create(:budget_investment) create(:follow, followable: budget_investment, user: @user) - visit user_path(@user, filter: "follow") + visit user_path(@user, filter: "follows") - expect(page).to have_link('Investments', href: "#") + expect(page).to have_link('Investments', href: "#investments") end - scenario 'Not display accordion budget investment tab when user is not following any budget investment' do - visit user_path(@user, filter: "follow") + scenario 'Not display budget investment tab when user is not following any budget investment' do + visit user_path(@user, filter: "follows") - expect(page).not_to have_link('Investments', href: "#") + expect(page).not_to have_link('Investments', href: "#investments") end - scenario 'Display budget investment with action buttons inside accordion budget investment tab when current user is a verified user and author', :js do - user = create(:user, :level_two) - budget_investment = create(:budget_investment, author: user) - create(:follow, followable: budget_investment, user: user) - login_as user - - visit user_path(user, filter: "follows") - click_link 'Investments' - - expect(page).to have_link budget_investment.title - expect(page).to have_link "Delete" - end - - scenario 'Display budget investment with action buttons inside accordion budget investment tab when there is no logged user', :js do + scenario 'Display budget investment with link to budget investment' do user = create(:user, :level_two) budget_investment = create(:budget_investment, author: user) create(:follow, followable: budget_investment, user: user) @@ -521,22 +484,7 @@ feature 'Users' do click_link 'Investments' expect(page).to have_link budget_investment.title - expect(page).not_to have_link "Delete" end - - scenario 'Display budget investment without action buttons inside accordion budget investment tab when current user is not budget investment author', :js do - user = create(:user, :level_two) - budget_investment = create(:budget_investment) - create(:follow, followable: budget_investment, user: user) - login_as user - - visit user_path(user, filter: "follows") - click_link 'Investments' - - expect(page).to have_link budget_investment.title - expect(page).not_to have_link "Delete" - end - end end diff --git a/spec/features/valuation/budget_investments_spec.rb b/spec/features/valuation/budget_investments_spec.rb index 3f91d8925..7bd955e0e 100644 --- a/spec/features/valuation/budget_investments_spec.rb +++ b/spec/features/valuation/budget_investments_spec.rb @@ -30,7 +30,7 @@ feature 'Valuation budget investments' do visit valuation_budget_budget_investments_path(@budget) expect(page).to have_content(investment1.title) - expect(page).to_not have_content(investment2.title) + expect(page).not_to have_content(investment2.title) end scenario 'Index shows no budget investment to admins no valuators' do @@ -43,8 +43,8 @@ feature 'Valuation budget investments' do login_as create(:administrator).user visit valuation_budget_budget_investments_path(@budget) - expect(page).to_not have_content(investment1.title) - expect(page).to_not have_content(investment2.title) + expect(page).not_to have_content(investment1.title) + expect(page).not_to have_content(investment2.title) end scenario 'Index orders budget investments by votes' do @@ -83,12 +83,12 @@ feature 'Valuation budget investments' do click_link "District 9", exact: false expect(page).to have_link("Realocate visitors") - expect(page).to_not have_link("Destroy the city") + expect(page).not_to have_link("Destroy the city") click_link "Down to the river", exact: false expect(page).to have_link("Destroy the city") - expect(page).to_not have_link("Realocate visitors") + expect(page).not_to have_link("Realocate visitors") click_link "All headings", exact: false expect(page).to have_link("Realocate visitors") @@ -101,13 +101,13 @@ feature 'Valuation budget investments' do visit valuation_budget_budget_investments_path(@budget) - expect(page).to_not have_link(filters_links.values.first) + expect(page).not_to have_link(filters_links.values.first) filters_links.keys.drop(1).each { |filter| expect(page).to have_link(filters_links[filter]) } filters_links.each_pair do |current_filter, link| visit valuation_budget_budget_investments_path(@budget, filter: current_filter) - expect(page).to_not have_link(link) + expect(page).not_to have_link(link) (filters_links.keys - [current_filter]).each do |filter| expect(page).to have_link(filters_links[filter]) @@ -124,16 +124,16 @@ feature 'Valuation budget investments' do visit valuation_budget_budget_investments_path(@budget) expect(page).to have_content("Ongoing valuation") - expect(page).to_not have_content("Old idea") + expect(page).not_to have_content("Old idea") visit valuation_budget_budget_investments_path(@budget, filter: 'valuating') expect(page).to have_content("Ongoing valuation") - expect(page).to_not have_content("Old idea") + expect(page).not_to have_content("Old idea") visit valuation_budget_budget_investments_path(@budget, filter: 'valuation_finished') - expect(page).to_not have_content("Ongoing valuation") + expect(page).not_to have_content("Ongoing valuation") expect(page).to have_content("Old idea") end @@ -234,8 +234,8 @@ feature 'Valuation budget investments' do within('#price_first_year') { expect(page).to have_content('Undefined') } within('#duration') { expect(page).to have_content('Undefined') } within('#feasibility') { expect(page).to have_content('Undecided') } - expect(page).to_not have_content('Valuation finished') - expect(page).to_not have_content('Internal comments') + expect(page).not_to have_content('Valuation finished') + expect(page).not_to have_content('Internal comments') end scenario 'Edit dossier' do @@ -262,7 +262,7 @@ feature 'Valuation budget investments' do expect(page).to have_content('Very cheap idea') within('#duration') { expect(page).to have_content('19 months') } within('#feasibility') { expect(page).to have_content('Feasible') } - expect(page).to_not have_content('Valuation finished') + expect(page).not_to have_content('Valuation finished') expect(page).to have_content('Internal comments') expect(page).to have_content('Should be double checked by the urbanism area') end @@ -271,20 +271,20 @@ feature 'Valuation budget investments' do visit valuation_budget_budget_investment_path(@budget, @investment) click_link 'Edit dossier' - expect(find "#budget_investment_feasibility_undecided").to be_checked + expect(find("#budget_investment_feasibility_undecided")).to be_checked choose 'budget_investment_feasibility_feasible' click_button 'Save changes' visit edit_valuation_budget_budget_investment_path(@budget, @investment) - expect(find "#budget_investment_feasibility_undecided").to_not be_checked - expect(find "#budget_investment_feasibility_feasible").to be_checked + expect(find("#budget_investment_feasibility_undecided")).not_to be_checked + expect(find("#budget_investment_feasibility_feasible")).to be_checked choose 'budget_investment_feasibility_undecided' click_button 'Save changes' visit edit_valuation_budget_budget_investment_path(@budget, @investment) - expect(find "#budget_investment_feasibility_undecided").to be_checked + expect(find("#budget_investment_feasibility_undecided")).to be_checked end scenario 'Feasibility selection makes proper fields visible', :js do @@ -295,7 +295,7 @@ feature 'Valuation budget investments' do visit edit_valuation_budget_budget_investment_path(@budget, @investment) - expect(find "#budget_investment_feasibility_undecided").to be_checked + expect(find("#budget_investment_feasibility_undecided")).to be_checked undecided_fields.each do |field| expect(page).to have_content(field) @@ -304,7 +304,7 @@ feature 'Valuation budget investments' do choose 'budget_investment_feasibility_feasible' unfeasible_fields.each do |field| - expect(page).to_not have_content(field) + expect(page).not_to have_content(field) end (feasible_fields + any_feasibility_fields).each do |field| @@ -314,7 +314,7 @@ feature 'Valuation budget investments' do choose 'budget_investment_feasibility_unfeasible' feasible_fields.each do |field| - expect(page).to_not have_content(field) + expect(page).not_to have_content(field) end (unfeasible_fields + any_feasibility_fields).each do |field| @@ -325,9 +325,9 @@ feature 'Valuation budget investments' do visit edit_valuation_budget_budget_investment_path(@budget, @investment) - expect(find "#budget_investment_feasibility_unfeasible").to be_checked + expect(find("#budget_investment_feasibility_unfeasible")).to be_checked feasible_fields.each do |field| - expect(page).to_not have_content(field) + expect(page).not_to have_content(field) end (unfeasible_fields + any_feasibility_fields).each do |field| @@ -349,7 +349,7 @@ feature 'Valuation budget investments' do click_button 'Save changes' visit valuation_budget_budget_investments_path(@budget) - expect(page).to_not have_content @investment.title + expect(page).not_to have_content @investment.title click_link 'Valuation finished' expect(page).to have_content @investment.title diff --git a/spec/features/valuation/budgets_spec.rb b/spec/features/valuation/budgets_spec.rb index 303d6c087..ec3b780ab 100644 --- a/spec/features/valuation/budgets_spec.rb +++ b/spec/features/valuation/budgets_spec.rb @@ -35,7 +35,7 @@ feature 'Valuation budgets' do expect(page).to have_content(budget2.name) expect(page).to have_content(budget3.name) expect(page).to have_content(budget4.name) - expect(page).to_not have_content(budget5.name) + expect(page).not_to have_content(budget5.name) end end diff --git a/spec/features/valuation_spec.rb b/spec/features/valuation_spec.rb index 5b6cc961c..c004f0773 100644 --- a/spec/features/valuation_spec.rb +++ b/spec/features/valuation_spec.rb @@ -17,11 +17,11 @@ feature 'Valuation' do login_as(user) visit root_path - expect(page).to_not have_link("Valuation") + expect(page).not_to have_link("Valuation") visit valuation_root_path - expect(current_path).not_to eq(valuation_root_path) - expect(current_path).to eq(proposals_path) + expect(page).not_to have_current_path(valuation_root_path) + expect(page).to have_current_path(root_path) expect(page).to have_content "You do not have permission to access this page" end @@ -30,11 +30,11 @@ feature 'Valuation' do login_as(user) visit root_path - expect(page).to_not have_link("Valuation") + expect(page).not_to have_link("Valuation") visit valuation_root_path - expect(current_path).not_to eq(valuation_root_path) - expect(current_path).to eq(proposals_path) + expect(page).not_to have_current_path(valuation_root_path) + expect(page).to have_current_path(root_path) expect(page).to have_content "You do not have permission to access this page" end @@ -43,11 +43,11 @@ feature 'Valuation' do login_as(user) visit root_path - expect(page).to_not have_link("Valuation") + expect(page).not_to have_link("Valuation") visit valuation_root_path - expect(current_path).not_to eq(valuation_root_path) - expect(current_path).to eq(proposals_path) + expect(page).not_to have_current_path(valuation_root_path) + expect(page).to have_current_path(root_path) expect(page).to have_content "You do not have permission to access this page" end @@ -56,11 +56,11 @@ feature 'Valuation' do login_as(user) visit root_path - expect(page).to_not have_link("Valuation") + expect(page).not_to have_link("Valuation") visit valuation_root_path - expect(current_path).not_to eq(valuation_root_path) - expect(current_path).to eq(proposals_path) + expect(page).not_to have_current_path(valuation_root_path) + expect(page).to have_current_path(root_path) expect(page).to have_content "You do not have permission to access this page" end @@ -72,8 +72,8 @@ feature 'Valuation' do expect(page).to have_link("Valuation") click_on "Valuation" - expect(current_path).to eq(valuation_root_path) - expect(page).to_not have_content "You do not have permission to access this page" + expect(page).to have_current_path(valuation_root_path) + expect(page).not_to have_content "You do not have permission to access this page" end scenario 'Access as an administrator is authorized' do @@ -84,8 +84,8 @@ feature 'Valuation' do expect(page).to have_link("Valuation") click_on "Valuation" - expect(current_path).to eq(valuation_root_path) - expect(page).to_not have_content "You do not have permission to access this page" + expect(page).to have_current_path(valuation_root_path) + expect(page).not_to have_content "You do not have permission to access this page" end scenario "Valuation access links" do @@ -94,8 +94,8 @@ feature 'Valuation' do visit root_path expect(page).to have_link('Valuation') - expect(page).to_not have_link('Administration') - expect(page).to_not have_link('Moderation') + expect(page).not_to have_link('Administration') + expect(page).not_to have_link('Moderation') end scenario 'Valuation dashboard' do @@ -105,10 +105,10 @@ feature 'Valuation' do click_link 'Valuation' - expect(current_path).to eq(valuation_root_path) + expect(page).to have_current_path(valuation_root_path) expect(page).to have_css('#valuation_menu') - expect(page).to_not have_css('#admin_menu') - expect(page).to_not have_css('#moderation_menu') + expect(page).not_to have_css('#admin_menu') + expect(page).not_to have_css('#moderation_menu') end end diff --git a/spec/features/verification/email_spec.rb b/spec/features/verification/email_spec.rb index bf1ff9b37..d29a56a80 100644 --- a/spec/features/verification/email_spec.rb +++ b/spec/features/verification/email_spec.rb @@ -29,7 +29,7 @@ feature 'Verify email' do expect(page).to have_content "You are a verified user" - expect(page).to_not have_link "Verify my account" + expect(page).not_to have_link "Verify my account" expect(page).to have_content "Account verified" end diff --git a/spec/features/verification/letter_spec.rb b/spec/features/verification/letter_spec.rb index 6291557f0..463b22ebb 100644 --- a/spec/features/verification/letter_spec.rb +++ b/spec/features/verification/letter_spec.rb @@ -38,7 +38,7 @@ feature 'Verify Letter' do visit new_letter_path expect(page).to have_content 'You have not yet confirmed your residency' - expect(current_path).to eq(new_residence_path) + expect(page).to have_current_path(new_residence_path) end scenario "Deny access unless verified phone/email" do @@ -48,7 +48,7 @@ feature 'Verify Letter' do visit new_letter_path expect(page).to have_content 'You have not yet entered the confirmation code' - expect(current_path).to eq(new_sms_path) + expect(page).to have_current_path(new_sms_path) end context "Code verification" do @@ -67,7 +67,7 @@ feature 'Verify Letter' do click_button "Verify my account" expect(page).to have_content "Code correct. Your account is now verified" - expect(current_path).to eq(account_path) + expect(page).to have_current_path(account_path) end scenario "Valid verification of user failing to add trailing zeros" do @@ -84,7 +84,7 @@ feature 'Verify Letter' do click_button "Verify my account" expect(page).to have_content "Account verified" - expect(current_path).to eq(account_path) + expect(page).to have_current_path(account_path) end scenario "Valid verification user not logged in" do @@ -100,7 +100,7 @@ feature 'Verify Letter' do click_button "Verify my account" expect(page).to have_content "Code correct. Your account is now verified" - expect(current_path).to eq(account_path) + expect(page).to have_current_path(account_path) end scenario "Error messages on authentication" do @@ -138,7 +138,7 @@ feature 'Verify Letter' do end expect(page).to have_content "You have reached the maximum number of attempts. Please try again later." - expect(current_path).to eq(account_path) + expect(page).to have_current_path(account_path) end end diff --git a/spec/features/verification/level_three_verification_spec.rb b/spec/features/verification/level_three_verification_spec.rb index ff88f8477..1e339307c 100644 --- a/spec/features/verification/level_three_verification_spec.rb +++ b/spec/features/verification/level_three_verification_spec.rb @@ -29,7 +29,7 @@ feature 'Level three verification' do expect(page).to have_content "Code correct. Your account is now verified" - expect(page).to_not have_link "Verify my account" + expect(page).not_to have_link "Verify my account" expect(page).to have_content "Account verified" end @@ -60,7 +60,7 @@ feature 'Level three verification' do expect(page).to have_content "You are a verified user" - expect(page).to_not have_link "Verify my account" + expect(page).not_to have_link "Verify my account" expect(page).to have_content "Account verified" end diff --git a/spec/features/verification/residence_spec.rb b/spec/features/verification/residence_spec.rb index a94834523..ac2096fce 100644 --- a/spec/features/verification/residence_spec.rb +++ b/spec/features/verification/residence_spec.rb @@ -121,10 +121,10 @@ feature 'Residence' do click_button 'Verify residence' expect(page).to have_content "You have reached the maximum number of attempts. Please try again later." - expect(current_path).to eq(account_path) + expect(page).to have_current_path(account_path) visit new_residence_path expect(page).to have_content "You have reached the maximum number of attempts. Please try again later." - expect(current_path).to eq(account_path) + expect(page).to have_current_path(account_path) end end diff --git a/spec/features/verification/sms_spec.rb b/spec/features/verification/sms_spec.rb index f582079a6..9274a1eb4 100644 --- a/spec/features/verification/sms_spec.rb +++ b/spec/features/verification/sms_spec.rb @@ -54,7 +54,7 @@ feature 'SMS Verification' do visit new_sms_path expect(page).to have_content 'You have not yet confirmed your residency' - expect(current_path).to eq(new_residence_path) + expect(page).to have_current_path(new_residence_path) end scenario '5 tries allowed' do @@ -70,11 +70,11 @@ feature 'SMS Verification' do end expect(page).to have_content "You have reached the maximum number of attempts. Please try again later." - expect(current_path).to eq(account_path) + expect(page).to have_current_path(account_path) visit new_sms_path expect(page).to have_content "You have reached the maximum number of attempts. Please try again later." - expect(current_path).to eq(account_path) + expect(page).to have_current_path(account_path) end end diff --git a/spec/features/verification/verification_path_spec.rb b/spec/features/verification/verification_path_spec.rb index bc5d60317..b7abf4a56 100644 --- a/spec/features/verification/verification_path_spec.rb +++ b/spec/features/verification/verification_path_spec.rb @@ -9,7 +9,7 @@ feature 'Verification path' do login_as(user) visit verification_path - expect(current_path).to eq account_path + expect(page).to have_current_path(account_path) end scenario "User is verified" do @@ -18,7 +18,7 @@ feature 'Verification path' do login_as(user) visit verification_path - expect(current_path).to eq account_path + expect(page).to have_current_path(account_path) expect(page).to have_content 'Your account is already verified' end @@ -29,7 +29,7 @@ feature 'Verification path' do login_as(user) visit verification_path - expect(current_path).to eq edit_letter_path + expect(page).to have_current_path(edit_letter_path) end scenario "User is level two verified" do @@ -38,7 +38,7 @@ feature 'Verification path' do login_as(user) visit verification_path - expect(current_path).to eq new_letter_path + expect(page).to have_current_path(new_letter_path) end scenario "User received a verification sms" do @@ -47,7 +47,7 @@ feature 'Verification path' do login_as(user) visit verification_path - expect(current_path).to eq edit_sms_path + expect(page).to have_current_path(edit_sms_path) end scenario "User received verification email" do @@ -60,7 +60,7 @@ feature 'Verification path' do visit verified_user_path - expect(current_path).to eq verification_redirect + expect(page).to have_current_path(verification_redirect) end scenario "User has verified residence" do @@ -73,7 +73,7 @@ feature 'Verification path' do visit verified_user_path - expect(current_path).to eq verification_redirect + expect(page).to have_current_path(verification_redirect) end scenario "User has not started verification process" do @@ -82,7 +82,7 @@ feature 'Verification path' do login_as(user) visit verification_path - expect(current_path).to eq new_residence_path + expect(page).to have_current_path(new_residence_path) end scenario "A verified user can not access verification pages" do @@ -94,7 +94,7 @@ feature 'Verification path' do verification_paths.each do |step_path| visit step_path - expect(current_path).to eq account_path + expect(page).to have_current_path(account_path) expect(page).to have_content 'Your account is already verified' end end diff --git a/spec/features/verification/verified_user_spec.rb b/spec/features/verification/verified_user_spec.rb index 3b020fcb0..87be185e9 100644 --- a/spec/features/verification/verified_user_spec.rb +++ b/spec/features/verification/verified_user_spec.rb @@ -66,7 +66,7 @@ feature 'Verified users' do login_as(user) visit verified_user_path - expect(current_path).to eq new_sms_path + expect(page).to have_current_path(new_sms_path) end scenario "Select a verified email" do @@ -86,7 +86,7 @@ feature 'Verified users' do end expect(page).to have_content 'We have sent a confirmation email to your account: rock@example.com' - expect(current_path).to eq(account_path) + expect(page).to have_current_path(account_path) end scenario "Select a verified phone" do @@ -122,7 +122,7 @@ feature 'Verified users' do click_link "Use other phone" - expect(current_path).to eq(new_sms_path) + expect(page).to have_current_path(new_sms_path) end scenario "No verified information" do @@ -131,7 +131,7 @@ feature 'Verified users' do login_as(user) visit verified_user_path - expect(current_path).to eq(new_sms_path) + expect(page).to have_current_path(new_sms_path) end end diff --git a/spec/features/votes_spec.rb b/spec/features/votes_spec.rb index 093599368..c837deebf 100644 --- a/spec/features/votes_spec.rb +++ b/spec/features/votes_spec.rb @@ -24,36 +24,36 @@ feature 'Votes' do within("#debate_#{debate1.id}_votes") do within(".in-favor") do expect(page).to have_css("a.voted") - expect(page).to_not have_css("a.no-voted") + expect(page).not_to have_css("a.no-voted") end within(".against") do expect(page).to have_css("a.no-voted") - expect(page).to_not have_css("a.voted") + expect(page).not_to have_css("a.voted") end end within("#debate_#{debate2.id}_votes") do within(".in-favor") do - expect(page).to_not have_css("a.voted") - expect(page).to_not have_css("a.no-voted") + expect(page).not_to have_css("a.voted") + expect(page).not_to have_css("a.no-voted") end within(".against") do - expect(page).to_not have_css("a.no-voted") - expect(page).to_not have_css("a.voted") + expect(page).not_to have_css("a.no-voted") + expect(page).not_to have_css("a.voted") end end within("#debate_#{debate3.id}_votes") do within(".in-favor") do expect(page).to have_css("a.no-voted") - expect(page).to_not have_css("a.voted") + expect(page).not_to have_css("a.voted") end within(".against") do expect(page).to have_css("a.voted") - expect(page).to_not have_css("a.no-voted") + expect(page).not_to have_css("a.no-voted") end end end @@ -68,14 +68,14 @@ feature 'Votes' do within('.in-favor') do expect(page).to have_content "0%" - expect(page).to_not have_css("a.voted") - expect(page).to_not have_css("a.no-voted") + expect(page).not_to have_css("a.voted") + expect(page).not_to have_css("a.no-voted") end within('.against') do expect(page).to have_content "0%" - expect(page).to_not have_css("a.voted") - expect(page).to_not have_css("a.no-voted") + expect(page).not_to have_css("a.voted") + expect(page).not_to have_css("a.no-voted") end end @@ -104,7 +104,7 @@ feature 'Votes' do find('.in-favor a').click expect(page).to have_content "1 vote" find('.in-favor a').click - expect(page).to_not have_content "2 votes" + expect(page).not_to have_content "2 votes" within('.in-favor') do expect(page).to have_content "100%" @@ -173,7 +173,7 @@ feature 'Votes' do expect(page).to have_content "1 vote" end - expect(current_path).to eq(debates_path) + expect(page).to have_current_path(debates_path) end end end @@ -195,11 +195,11 @@ feature 'Votes' do end within("#proposal_#{proposal2.id}_votes") do - expect(page).to_not have_content "You have already supported this proposal. Share it!" + expect(page).not_to have_content "You have already supported this proposal. Share it!" end within("#proposal_#{proposal3.id}_votes") do - expect(page).to_not have_content "You have already supported this proposal. Share it!" + expect(page).not_to have_content "You have already supported this proposal. Share it!" end end end @@ -221,7 +221,7 @@ feature 'Votes' do find('.in-favor a').click expect(page).to have_content "1 support" - expect(page).to_not have_selector ".in-favor a" + expect(page).not_to have_selector ".in-favor a" end end @@ -257,7 +257,7 @@ feature 'Votes' do expect(page).to have_content "1 support" expect(page).to have_content "You have already supported this proposal. Share it!" end - expect(current_path).to eq(proposals_path) + expect(page).to have_current_path(proposals_path) end scenario 'Create in featured proposal in index', :js do @@ -268,7 +268,7 @@ feature 'Votes' do expect(page).to have_content "You have already supported this proposal. Share it!" end - expect(current_path).to eq(proposals_path) + expect(page).to have_current_path(proposals_path) end end end @@ -389,11 +389,11 @@ feature 'Votes' do end within("#spending_proposal_#{spending_proposal2.id}_votes") do - expect(page).to_not have_content "You have already supported this. Share it!" + expect(page).not_to have_content "You have already supported this. Share it!" end within("#spending_proposal_#{spending_proposal3.id}_votes") do - expect(page).to_not have_content "You have already supported this. Share it!" + expect(page).not_to have_content "You have already supported this. Share it!" end end end @@ -428,7 +428,7 @@ feature 'Votes' do find('.in-favor a').click expect(page).to have_content "1 support" - expect(page).to_not have_selector ".in-favor a" + expect(page).not_to have_selector ".in-favor a" end end diff --git a/spec/features/welcome_spec.rb b/spec/features/welcome_spec.rb index ce06befcc..ead244e06 100644 --- a/spec/features/welcome_spec.rb +++ b/spec/features/welcome_spec.rb @@ -7,7 +7,7 @@ feature "Welcome screen" do login_through_form_as(user) - expect(current_path).to eq(welcome_path) + expect(page).to have_current_path(welcome_path) end scenario 'a regular user does not see it when coing to /email' do @@ -25,7 +25,7 @@ feature "Welcome screen" do expect(page).to have_content("You are a verified user") - expect(current_path).to eq(account_path) + expect(page).to have_current_path(account_path) end scenario 'it is not shown more than once' do @@ -33,7 +33,7 @@ feature "Welcome screen" do login_through_form_as(user) - expect(current_path).to eq(proposals_path) + expect(page).to have_current_path(root_path) end scenario 'is not shown to organizations' do @@ -41,7 +41,7 @@ feature "Welcome screen" do login_through_form_as(organization.user) - expect(current_path).to eq(proposals_path) + expect(page).to have_current_path(root_path) end scenario 'it is not shown to level-2 users' do @@ -49,7 +49,7 @@ feature "Welcome screen" do login_through_form_as(user) - expect(current_path).to eq(proposals_path) + expect(page).to have_current_path(root_path) end scenario 'it is not shown to level-3 users' do @@ -57,7 +57,7 @@ feature "Welcome screen" do login_through_form_as(user) - expect(current_path).to eq(proposals_path) + expect(page).to have_current_path(root_path) end scenario 'is not shown to administrators' do @@ -65,7 +65,7 @@ feature "Welcome screen" do login_through_form_as(administrator.user) - expect(current_path).to eq(proposals_path) + expect(page).to have_current_path(root_path) end end diff --git a/spec/fixtures/files/clippy.gif b/spec/fixtures/files/clippy.gif new file mode 100644 index 000000000..c2c2278af Binary files /dev/null and b/spec/fixtures/files/clippy.gif differ diff --git a/spec/fixtures/files/clippy.jpeg b/spec/fixtures/files/clippy.jpeg new file mode 100644 index 000000000..1edb6659b Binary files /dev/null and b/spec/fixtures/files/clippy.jpeg differ diff --git a/spec/fixtures/files/clippy.jpg b/spec/fixtures/files/clippy.jpg new file mode 100644 index 000000000..1edb6659b Binary files /dev/null and b/spec/fixtures/files/clippy.jpg differ diff --git a/spec/fixtures/files/clippy.pdf b/spec/fixtures/files/clippy.pdf new file mode 100644 index 000000000..d63e922cf Binary files /dev/null and b/spec/fixtures/files/clippy.pdf differ diff --git a/spec/fixtures/files/clippy.png b/spec/fixtures/files/clippy.png new file mode 100644 index 000000000..44e09b4e3 Binary files /dev/null and b/spec/fixtures/files/clippy.png differ diff --git a/spec/fixtures/files/logo.pdf b/spec/fixtures/files/logo.pdf new file mode 100644 index 000000000..39d69cfe6 Binary files /dev/null and b/spec/fixtures/files/logo.pdf differ diff --git a/spec/fixtures/files/logo_header.gif b/spec/fixtures/files/logo_header.gif new file mode 100644 index 000000000..4bfddd410 Binary files /dev/null and b/spec/fixtures/files/logo_header.gif differ diff --git a/spec/fixtures/files/logo_header.jpg b/spec/fixtures/files/logo_header.jpg new file mode 100644 index 000000000..aeed9e524 Binary files /dev/null and b/spec/fixtures/files/logo_header.jpg differ diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index 61137912d..4dd775c73 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -3,19 +3,19 @@ require 'rails_helper' describe ApplicationHelper do describe "#author_of?" do - it "should be true if user is the author" do + it "is true if user is the author" do user = create(:user) proposal = create(:proposal, author: user) expect(author_of?(proposal, user)).to eq true end - it "should be false if user is not the author" do + it "is false if user is not the author" do user = create(:user) proposal = create(:proposal) expect(author_of?(proposal, user)).to eq false end - it "should be false if user or authorable is nil" do + it "is false if user or authorable is nil" do user = create(:user) proposal = create(:proposal) diff --git a/spec/helpers/comments_helper_spec.rb b/spec/helpers/comments_helper_spec.rb index b1caabe53..6888ff5d4 100644 --- a/spec/helpers/comments_helper_spec.rb +++ b/spec/helpers/comments_helper_spec.rb @@ -14,9 +14,9 @@ RSpec.describe CommentsHelper, type: :helper do describe '#user_level_class' do - def comment_double as_administrator: false, as_moderator: false, official: false - user = double official?: official, official_level: 'Y' - double as_administrator?: as_administrator, as_moderator?: as_moderator, user: user + def comment_double(as_administrator: false, as_moderator: false, official: false) + user = instance_double('User', official?: official, official_level: 'Y') + instance_double('Comment', as_administrator?: as_administrator, as_moderator?: as_moderator, user: user) end it 'returns is-admin for comment done as administrator' do @@ -47,14 +47,14 @@ RSpec.describe CommentsHelper, type: :helper do describe '#comment_author_class' do it 'returns is-author if author is the commenting user' do author_id = 42 - comment = double user_id: author_id + comment = instance_double('Comment', user_id: author_id) expect(helper.comment_author_class(comment, author_id)).to eq('is-author') end it 'returns an empty string if commenter is not the author' do author_id = 42 - comment = double user_id: author_id - 1 + comment = instance_double('Comment', user_id: author_id - 1) expect(helper.comment_author_class(comment, author_id)).to eq('') end diff --git a/spec/helpers/proposals_helper_spec.rb b/spec/helpers/proposals_helper_spec.rb index d71178d9d..87da34be3 100644 --- a/spec/helpers/proposals_helper_spec.rb +++ b/spec/helpers/proposals_helper_spec.rb @@ -3,43 +3,43 @@ require 'rails_helper' describe ProposalsHelper do describe "#progress_bar_percentage" do - it "should be 0 if no votes" do + it "is 0 if no votes" do proposal = create(:proposal) expect(progress_bar_percentage(proposal)).to eq 0 end - it "should be a between 1 and 100 if there are votes but less than needed" do + it "is between 1 and 100 if there are votes but less than needed" do proposal = create(:proposal, cached_votes_up: Proposal.votes_needed_for_success / 2) expect(progress_bar_percentage(proposal)).to eq 50 end - it "should be 100 if there are more votes than needed" do + it "is 100 if there are more votes than needed" do proposal = create(:proposal, cached_votes_up: Proposal.votes_needed_for_success * 2) expect(progress_bar_percentage(proposal)).to eq 100 end end describe "#supports_percentage" do - it "should be 0 if no votes" do + it "is 0 if no votes" do proposal = create(:proposal) expect(supports_percentage(proposal)).to eq "0%" end - it "should be a between 0.1 from 1 to 0.1% of needed votes" do + it "is between 0.1 from 1 to 0.1% of needed votes" do proposal = create(:proposal, cached_votes_up: 1) expect(supports_percentage(proposal)).to eq "0.1%" end - it "should be a between 1 and 100 if there are votes but less than needed" do + it "is between 1 and 100 if there are votes but less than needed" do proposal = create(:proposal, cached_votes_up: Proposal.votes_needed_for_success / 2) expect(supports_percentage(proposal)).to eq "50%" end - it "should be 100 if there are more votes than needed" do + it "is 100 if there are more votes than needed" do proposal = create(:proposal, cached_votes_up: Proposal.votes_needed_for_success * 2) expect(supports_percentage(proposal)).to eq "100%" end end -end \ No newline at end of file +end diff --git a/spec/helpers/settings_helper_spec.rb b/spec/helpers/settings_helper_spec.rb index 0aa9b8541..0db6fed10 100644 --- a/spec/helpers/settings_helper_spec.rb +++ b/spec/helpers/settings_helper_spec.rb @@ -21,10 +21,10 @@ RSpec.describe SettingsHelper, type: :helper do Setting["feature.f2"] = "" Setting["feature.f3"] = nil - expect(feature? "f1").to eq("active") - expect(feature? "f2").to eq(nil) - expect(feature? "f3").to eq(nil) - expect(feature? "f4").to eq(nil) + expect(feature?("f1")).to eq("active") + expect(feature?("f2")).to eq(nil) + expect(feature?("f3")).to eq(nil) + expect(feature?("f4")).to eq(nil) end end diff --git a/spec/helpers/text_helper_spec.rb b/spec/helpers/text_helper_spec.rb index cc9300b7f..2b9884b9a 100644 --- a/spec/helpers/text_helper_spec.rb +++ b/spec/helpers/text_helper_spec.rb @@ -3,12 +3,12 @@ require 'rails_helper' describe TextHelper do describe "#first_paragraph" do - it "should return the first paragraph of a text" do + it "returns the first paragraph of a text" do text = "\n\nThis is the first paragraph\n\nThis is the second paragraph\n" expect(first_paragraph(text)).to eq("This is the first paragraph") end - it "should return blank if the text is blank" do + it "returns blank if the text is blank" do expect(first_paragraph("")).to eq("") expect(first_paragraph(nil)).to eq("") end diff --git a/spec/helpers/users_helper_spec.rb b/spec/helpers/users_helper_spec.rb index 55ea8445b..544c65d82 100644 --- a/spec/helpers/users_helper_spec.rb +++ b/spec/helpers/users_helper_spec.rb @@ -3,7 +3,7 @@ require 'rails_helper' describe UsersHelper do describe '#humanize_document_type' do - it "should return a humanized document type" do + it "returns a humanized document type" do expect(humanize_document_type("1")).to eq "DNI" expect(humanize_document_type("2")).to eq "Passport" expect(humanize_document_type("3")).to eq "Residence card" @@ -11,44 +11,48 @@ describe UsersHelper do end describe '#deleted_commentable_text' do - it "should return the appropriate message for deleted debates" do + it "returns the appropriate message for deleted debates" do debate = create(:debate) comment = create(:comment, commentable: debate) debate.hide - expect(comment_commentable_title(comment)).to eq '
+ +