From 77d4c4d8dc00491b99aa15dfd78eb22a47ffe663 Mon Sep 17 00:00:00 2001 From: Guo Xiang Tan Date: Thu, 31 Aug 2017 12:06:56 +0800 Subject: [PATCH] Fix all the errors to get our tests green on Rails 5.1. --- Gemfile.lock | 4 +- .../google_branding/logo_calendar_48px.png | Bin 0 -> 1609 bytes app/controllers/about_controller.rb | 4 +- app/controllers/admin/admin_controller.rb | 6 +- app/controllers/admin/api_controller.rb | 2 +- app/controllers/admin/backups_controller.rb | 24 +- app/controllers/admin/badges_controller.rb | 2 +- .../admin/color_schemes_controller.rb | 2 +- .../admin/diagnostics_controller.rb | 2 +- app/controllers/admin/email_controller.rb | 2 +- .../admin/embeddable_hosts_controller.rb | 2 +- app/controllers/admin/embedding_controller.rb | 2 +- app/controllers/admin/flags_controller.rb | 6 +- app/controllers/admin/groups_controller.rb | 4 +- .../admin/impersonate_controller.rb | 2 +- .../admin/permalinks_controller.rb | 2 +- .../admin/screened_ip_addresses_controller.rb | 2 +- .../admin/site_settings_controller.rb | 2 +- app/controllers/admin/themes_controller.rb | 8 +- app/controllers/admin/users_controller.rb | 40 +- app/controllers/admin/web_hooks_controller.rb | 2 +- app/controllers/application_controller.rb | 32 +- app/controllers/badges_controller.rb | 2 +- app/controllers/categories_controller.rb | 13 +- .../category_hashtags_controller.rb | 2 +- app/controllers/clicks_controller.rb | 4 +- .../composer_messages_controller.rb | 2 +- app/controllers/directory_items_controller.rb | 2 +- app/controllers/draft_controller.rb | 4 +- app/controllers/email_controller.rb | 4 +- app/controllers/embed_controller.rb | 9 +- app/controllers/exceptions_controller.rb | 2 +- app/controllers/export_csv_controller.rb | 4 +- app/controllers/extra_locales_controller.rb | 4 +- .../finish_installation_controller.rb | 4 +- app/controllers/forums_controller.rb | 6 +- app/controllers/groups_controller.rb | 4 +- app/controllers/highlight_js_controller.rb | 4 +- app/controllers/inline_onebox_controller.rb | 4 +- app/controllers/invites_controller.rb | 20 +- app/controllers/list_controller.rb | 6 +- app/controllers/metadata_controller.rb | 2 +- app/controllers/notifications_controller.rb | 2 +- app/controllers/onebox_controller.rb | 6 +- app/controllers/permalinks_controller.rb | 2 +- app/controllers/post_actions_controller.rb | 6 +- app/controllers/posts_controller.rb | 27 +- app/controllers/queued_posts_controller.rb | 2 +- app/controllers/robots_txt_controller.rb | 2 +- app/controllers/safe_mode_controller.rb | 2 +- app/controllers/search_controller.rb | 10 +- app/controllers/session_controller.rb | 19 +- app/controllers/site_controller.rb | 4 +- app/controllers/static_controller.rb | 8 +- app/controllers/steps_controller.rb | 6 +- app/controllers/stylesheets_controller.rb | 4 +- app/controllers/tag_groups_controller.rb | 6 +- app/controllers/tags_controller.rb | 12 +- app/controllers/topics_controller.rb | 55 +- app/controllers/uploads_controller.rb | 6 +- app/controllers/user_api_keys_controller.rb | 6 +- app/controllers/user_avatars_controller.rb | 2 +- .../users/omniauth_callbacks_controller.rb | 6 +- app/controllers/users_controller.rb | 47 +- app/controllers/users_email_controller.rb | 8 +- app/controllers/webhooks_controller.rb | 12 +- app/controllers/wizard_controller.rb | 8 +- app/models/api_key.rb | 2 +- app/models/category.rb | 11 +- app/models/category_featured_topic.rb | 2 +- app/models/category_featured_user.rb | 3 +- app/models/concerns/trashable.rb | 2 +- app/models/emoji_set_site_setting.rb | 2 +- app/models/group.rb | 10 +- app/models/notification.rb | 5 +- app/models/post.rb | 2 +- app/models/post_action.rb | 1 - app/models/post_mover.rb | 4 +- app/models/post_timing.rb | 9 +- app/models/theme.rb | 4 +- app/models/theme_field.rb | 10 +- app/models/topic.rb | 9 +- app/models/topic_converter.rb | 2 +- app/models/topic_link.rb | 22 +- app/models/topic_timer.rb | 7 +- app/models/topic_tracking_state.rb | 10 +- app/models/user.rb | 18 +- app/models/user_badge.rb | 12 +- app/models/user_option.rb | 2 +- app/services/color_scheme_revisor.rb | 7 +- app/services/post_owner_changer.rb | 6 +- app/services/search_indexer.rb | 10 +- app/services/spam_rule/auto_block.rb | 2 +- app/views/robots_txt/no_index.erb | 4 +- bin/docker/README.md | 0 bin/rails | 2 +- config/application.rb | 5 - config/initializers/005-site_settings.rb | 2 +- config/initializers/099-anon-cache.rb | 2 +- config/initializers/100-logster.rb | 5 - config/initializers/100-quiet_logger.rb | 10 +- ...0225050318_add_schema_migration_details.rb | 2 +- .../20120311163914_create_forum_threads.rb | 2 +- db/migrate/20120311164326_create_posts.rb | 2 +- db/migrate/20120311170118_create_users.rb | 2 +- db/migrate/20120311201341_create_forums.rb | 2 +- db/migrate/20120311210245_create_sites.rb | 2 +- .../20120416201606_add_reply_to_to_posts.rb | 2 +- ...120420183447_add_views_to_forum_threads.rb | 2 +- ...140906_add_posts_count_to_forum_threads.rb | 2 +- db/migrate/20120423142820_fix_post_indices.rb | 2 +- .../20120423151548_remove_last_post_id.rb | 2 +- ...425145456_add_display_username_to_users.rb | 2 +- ...120427150624_add_user_id_index_to_posts.rb | 2 +- db/migrate/20120427151452_cooked_migration.rb | 2 +- .../20120427154330_create_vestal_versions.rb | 2 +- .../20120427172031_add_version_to_posts.rb | 2 +- ...2183240_add_created_by_to_forum_threads.rb | 2 +- ..._add_last_post_user_id_to_forum_threads.rb | 2 +- .../20120503205521_add_site_id_to_users.rb | 2 +- .../20120507144132_create_expressions.rb | 2 +- .../20120507144222_create_expression_types.rb | 2 +- ...20120514144549_add_reply_count_to_posts.rb | 2 +- ...0514173920_add_flag_to_expression_types.rb | 2 +- ...934_add_description_to_expression_types.rb | 2 +- .../20120517200130_add_quoteless_to_post.rb | 2 +- .../20120518200115_create_read_posts.rb | 2 +- .../20120519182212_create_last_read_posts.rb | 2 +- db/migrate/20120523180723_create_views.rb | 2 +- ...0523184307_add_replies_to_forum_threads.rb | 2 +- ...523201329_add_featured_to_forum_threads.rb | 2 +- ...525194845_add_avg_time_to_forum_threads.rb | 2 +- db/migrate/20120529175956_create_uploads.rb | 2 +- db/migrate/20120529202707_create_stars.rb | 2 +- ...20120530150726_create_forum_thread_user.rb | 2 +- db/migrate/20120530160745_migrate_posted.rb | 2 +- ...120530200724_add_index_to_forum_threads.rb | 2 +- ...0120530212912_create_forum_thread_links.rb | 2 +- ...0120614190726_add_tags_to_forum_threads.rb | 2 +- ...20120614202024_add_quote_count_to_posts.rb | 2 +- db/migrate/20120615180517_create_bookmarks.rb | 2 +- ...20120618152946_add_reply_below_to_posts.rb | 2 +- .../20120618212349_create_post_timings.rb | 2 +- .../20120618214856_create_message_bus.rb | 2 +- db/migrate/20120619150807_fix_post_timings.rb | 2 +- db/migrate/20120619153349_drop_read_posts.rb | 2 +- ...0619172714_add_post_number_to_bookmarks.rb | 2 +- ...d_seen_post_count_to_forum_thread_users.rb | 2 +- ...1190310_add_deleted_at_to_forum_threads.rb | 2 +- .../20120622200242_create_notifications.rb | 2 +- ...45714_add_seen_notification_id_to_users.rb | 2 +- .../20120625162318_add_deleted_at_to_posts.rb | 2 +- ...dd_highest_post_number_to_forum_threads.rb | 2 +- ...25195326_add_image_url_to_forum_threads.rb | 2 +- ...0120629143908_rename_expression_type_id.rb | 2 +- .../20120629150253_denormalize_expressions.rb | 2 +- ...629151243_make_expressions_less_generic.rb | 2 +- .../20120629182637_create_incoming_links.rb | 2 +- db/migrate/20120702211427_create_replies.rb | 2 +- ...34_add_reflection_to_forum_thread_links.rb | 2 +- ...201312_add_incoming_link_count_to_posts.rb | 2 +- ...dd_incoming_link_count_to_forum_threads.rb | 2 +- ...20703210004_add_bookmark_count_to_posts.rb | 2 +- .../20120704160659_add_avg_time_to_posts.rb | 2 +- .../20120704201743_add_view_count_to_posts.rb | 2 +- .../20120705181724_add_user_to_versions.rb | 2 +- ...20708210305_add_last_posted_at_to_users.rb | 2 +- .../20120712150500_create_categories.rb | 2 +- ...151934_add_category_id_to_forum_threads.rb | 2 +- ...201324_create_category_featured_threads.rb | 2 +- .../20120716020835_create_site_settings.rb | 2 +- .../20120716173544_add_stats_to_categories.rb | 2 +- .../20120718044955_create_user_open_ids.rb | 2 +- ...mail_hashed_password_name_salt_to_users.rb | 2 +- ...20720013733_add_username_lower_to_users.rb | 2 +- .../20120720044246_add_auth_token_to_users.rb | 2 +- ...120720162422_add_forum_id_to_categories.rb | 2 +- ...23051512_add_not_nulls_to_user_open_ids.rb | 2 +- ...0120724234502_add_last_seen_at_to_users.rb | 2 +- .../20120724234711_add_website_to_users.rb | 2 +- ...0120725183347_add_excerpt_to_categories.rb | 2 +- ...726201830_add_invisible_to_forum_thread.rb | 2 +- ...0120726235129_add_user_id_to_categories.rb | 2 +- ...27005556_remove_excerpt_from_categories.rb | 2 +- db/migrate/20120727150428_rename_invisible.rb | 2 +- ...7213543_add_thread_counts_to_categories.rb | 2 +- ...0802151210_add_icon_to_expression_types.rb | 2 +- .../20120803191426_add_admin_flag_to_users.rb | 2 +- ..._password_new_salt_email_token_to_users.rb | 2 +- ...617_remove_new_password_stuff_from_user.rb | 2 +- db/migrate/20120807223020_create_actions.rb | 2 +- db/migrate/20120809020415_remove_site_id.rb | 2 +- db/migrate/20120809030647_remove_forum_id.rb | 2 +- ...0120809053414_correct_indexing_on_posts.rb | 2 +- .../20120809154750_remove_index_for_now.rb | 2 +- .../20120809174649_create_post_actions.rb | 2 +- ...20120809175110_create_post_action_types.rb | 2 +- ...01855_migrate_bookmarks_to_post_actions.rb | 2 +- ...10064839_rename_actions_to_user_actions.rb | 2 +- .../20120812235417_retire_expressions.rb | 2 +- ...name_expression_columns_in_forum_thread.rb | 2 +- ...2912_rename_expression_columns_in_posts.rb | 2 +- ...3201426_create_forum_thread_link_clicks.rb | 2 +- ..._add_unique_index_to_forum_thread_links.rb | 2 +- .../20120815180106_add_post_type_to_posts.rb | 2 +- ..._moderator_posts_count_to_forum_threads.rb | 2 +- ...6_add_unique_constraint_to_user_actions.rb | 2 +- .../20120816205537_add_forum_thread_states.rb | 2 +- ...538_add_starred_at_to_forum_thread_user.rb | 2 +- .../20120820191804_add_search_indices.rb | 2 +- ...21191616_add_bumped_at_to_forum_threads.rb | 2 +- .../20120823205956_add_slug_to_categories.rb | 2 +- ...24171908_create_category_featured_users.rb | 2 +- .../20120828204209_create_onebox_renders.rb | 2 +- ...120828204624_create_post_onebox_renders.rb | 2 +- ...830182736_add_preview_to_onebox_renders.rb | 2 +- ...4_remove_description_from_site_settings.rb | 2 +- .../20120918152319_rename_views_to_reads.rb | 2 +- ...0918205931_add_sub_tag_to_forum_threads.rb | 2 +- ...152846_add_has_best_of_to_forum_threads.rb | 2 +- .../20120921055428_add_twitter_user_info.rb | 2 +- .../20120921155050_create_archetypes.rb | 2 +- ...21162512_add_meta_data_to_forum_threads.rb | 2 +- ...20120921163606_create_archetype_options.rb | 2 +- .../20120924182000_add_hstore_extension.rb | 2 +- .../20120924182031_add_vote_count_to_posts.rb | 2 +- ...0_remove_english_from_post_action_types.rb | 2 +- ...90802_add_sequence_to_post_action_types.rb | 2 +- .../20120928170023_add_sort_order_to_posts.rb | 2 +- ...20121009161116_add_email_stuff_to_users.rb | 2 +- .../20121011155904_create_email_logs.rb | 2 +- .../20121017162924_convert_archetypes.rb | 2 +- ...121018103721_rename_forum_thread_tables.rb | 2 +- ...121018133039_create_topic_allowed_users.rb | 2 +- .../20121018182709_fix_notification_data.rb | 2 +- ...121106015500_drop_avatar_url_from_users.rb | 2 +- ...516_add_post_action_id_to_notifications.rb | 2 +- .../20121109164630_create_trust_levels.rb | 2 +- .../20121113200844_bio_markdown_support.rb | 2 +- ...121113200845_create_facebook_user_infos.rb | 2 +- .../20121115172544_rename_sticky_to_pinned.rb | 2 +- ...6212424_add_more_email_settings_to_user.rb | 2 +- ...21119190529_add_email_settings_to_users.rb | 2 +- ...0121119200843_add_email_direct_to_users.rb | 2 +- db/migrate/20121121202035_create_invites.rb | 2 +- .../20121121205215_create_topic_invites.rb | 2 +- ...121122033316_add_muted_at_to_topic_user.rb | 2 +- ...0121123054127_make_post_number_distinct.rb | 2 +- .../20121123063630_create_user_visits.rb | 2 +- .../20121129160035_create_email_tokens.rb | 2 +- ...129184948_remove_email_token_from_users.rb | 2 +- db/migrate/20121130010400_create_drafts.rb | 2 +- ...0191818_add_link_post_id_to_topic_links.rb | 2 +- ...1202225421_add_visited_at_to_topic_user.rb | 2 +- ...21203181719_rename_seen_notificaiton_id.rb | 2 +- db/migrate/20121204183855_fix_link_post_id.rb | 4 +- ...747_add_another_featured_user_to_topics.rb | 2 +- .../20121205162143_add_approved_to_users.rb | 2 +- ...000741_add_notifications_to_topic_users.rb | 2 +- ...121211233131_create_site_customizations.rb | 2 +- ...ide_default_style_to_site_customization.rb | 2 +- ...21218205642_add_topics_entered_to_users.rb | 2 +- ...21224072204_add_last_editor_id_to_posts.rb | 2 +- .../20121224095139_create_draft_sequence.rb | 2 +- .../20121224100650_add_sequence_to_drafts.rb | 2 +- ...0121228192219_add_deleted_at_to_invites.rb | 2 +- ...07165207_add_digest_after_days_to_users.rb | 2 +- ...08195847_add_previous_visit_at_to_users.rb | 2 +- ...12140_merge_mute_options_on_topic_users.rb | 2 +- ...7_correct_default_on_notification_level.rb | 2 +- ...03_oops_unwatch_a_boat_of_watched_stuff.rb | 2 +- ...130116151829_remove_sub_tag_from_topics.rb | 2 +- db/migrate/20130120222728_fix_search.rb | 2 +- ...30121231352_add_tracking_to_topic_users.rb | 2 +- ...122051134_add_auto_track_topics_to_user.rb | 2 +- ...ter_seconds_and_banning_and_dob_to_user.rb | 2 +- ...070909_auto_track_all_topics_replied_to.rb | 2 +- .../20130125002652_add_hidden_to_posts.rb | 2 +- ...0130125030305_add_fields_to_post_action.rb | 2 +- ...0125031122_correct_index_on_post_action.rb | 2 +- .../20130127213646_remove_trust_levels.rb | 2 +- ...20130128182013_trust_level_default_null.rb | 2 +- .../20130129010625_remove_pm_reflections.rb | 2 +- .../20130129163244_add_time_read_to_users.rb | 2 +- ...0130129174845_add_days_visited_to_users.rb | 2 +- .../20130130154611_remove_index_from_views.rb | 2 +- ...1055710_add_custom_flag_count_to_topics.rb | 2 +- ...dd_column_summaries_to_posts_and_topics.rb | 2 +- ...023409_add_position_to_post_action_type.rb | 2 +- ...0203204338_add_last_version_at_to_posts.rb | 2 +- .../20130204000159_add_ip_address_to_users.rb | 2 +- .../20130205021905_alter_facebook_user_id.rb | 2 +- ...0130207200019_add_user_deleted_to_posts.rb | 2 +- ...move_reply_below_post_number_from_posts.rb | 2 +- ...213021450_remove_topic_response_actions.rb | 2 +- ...add_new_topic_duration_minutes_to_users.rb | 2 +- ...221215017_add_description_to_categories.rb | 2 +- .../20130226015336_add_github_user_info.rb | 2 +- ...80148_add_cleared_pinned_to_topic_users.rb | 2 +- ...20130311181327_remove_extra_spam_record.rb | 2 +- ...s_in_new_tab_an_disable_quoting_to_user.rb | 2 +- ...3434_add_foreground_color_to_categories.rb | 2 +- .../20130315180637_enable_trigram_support.rb | 2 +- ...0319122248_add_reply_to_user_id_to_post.rb | 2 +- ...00_add_user_indexes_to_posts_and_topics.rb | 2 +- .../20130320024345_add_moderator_to_user.rb | 2 +- .../20130321154905_remove_oneboxes_from_db.rb | 2 +- ...0130322183614_add_percent_rank_to_posts.rb | 2 +- .../20130326210101_add_hotness_to_category.rb | 2 +- ...0327185852_update_site_settings_for_hot.rb | 2 +- .../20130328162943_create_hot_topics.rb | 2 +- .../20130328182433_add_score_to_topics.rb | 2 +- ...20130402210723_add_values_to_hot_topics.rb | 2 +- .../20130404143437_create_site_contents.rb | 2 +- db/migrate/20130404232558_add_user_extras.rb | 2 +- .../20130411205132_create_admin_logs.rb | 2 +- .../20130412015502_correct_counts_on_posts.rb | 2 +- ...20130412020156_correct_counts_on_topics.rb | 2 +- db/migrate/20130416004607_create_groups.rb | 2 +- db/migrate/20130416004933_group_users.rb | 2 +- .../20130416170855_add_subtype_to_topics.rb | 2 +- ...6_increase_data_length_on_notifications.rb | 2 +- ...626_add_related_post_id_to_post_actions.rb | 2 +- .../20130424015746_add_slug_to_topics.rb | 2 +- ...424055025_add_user_id_to_incoming_links.rb | 2 +- ...426044914_allow_nulls_in_incoming_links.rb | 2 +- ...ng_ip_current_user_id_to_incoming_links.rb | 2 +- ...8194335_add_unstarred_at_to_topic_users.rb | 2 +- ...130429000101_add_security_to_categories.rb | 2 +- ...20130430052751_add_topic_allowed_groups.rb | 2 +- ...20130501105651_fix_topic_allowed_groups.rb | 2 +- .../20130506020935_add_automatic_to_groups.rb | 2 +- ...30506185042_add_auto_close_at_to_topics.rb | 2 +- ...20130508040235_add_user_count_to_groups.rb | 2 +- ...130509040248_update_sequence_for_groups.rb | 2 +- ...0130509041351_add_unique_name_to_groups.rb | 2 +- ...93551_add_auto_close_days_to_categories.rb | 2 +- .../20130521210140_create_cas_user_infos.rb | 2 +- .../20130522193615_rename_search_tables.rb | 2 +- .../20130527152648_add_like_score_to_posts.rb | 2 +- ...47_add_rank_to_category_featured_topics.rb | 2 +- ...6_add_staff_took_action_to_post_actions.rb | 2 +- .../20130603192412_add_blocked_to_users.rb | 2 +- ...601_add_auto_close_started_at_to_topics.rb | 2 +- ...30610201033_add_reply_key_to_email_logs.rb | 2 +- ...612200846_create_post_upload_join_table.rb | 2 +- .../20130613211700_drop_posts_uploads.rb | 2 +- .../20130613212230_create_post_uploads.rb | 2 +- ..._add_dynamic_favicon_preference_to_user.rb | 2 +- ...0615073305_remove_topic_id_from_uploads.rb | 2 +- .../20130615075557_add_sha_to_uploads.rb | 2 +- .../20130616082327_create_optimized_images.rb | 2 +- ...130617014127_rename_sha_and_ext_columns.rb | 2 +- .../20130617180009_rename_sha_column.rb | 2 +- ...0130617181804_add_post_id_to_email_logs.rb | 2 +- ...0130619063902_add_defer_to_post_actions.rb | 2 +- ...130621042855_change_supress_to_suppress.rb | 2 +- ...20130622110348_add_url_index_to_uploads.rb | 2 +- ..._change_ip_to_inet_in_topic_link_clicks.rb | 2 +- ...130625022454_change_ip_to_inet_in_views.rb | 2 +- .../20130625170842_remove_access_password.rb | 2 +- .../20130625201113_add_title_to_users.rb | 2 +- ...130709184941_add_deleted_by_id_to_posts.rb | 2 +- .../20130710201248_add_nuked_user_to_posts.rb | 2 +- ..._add_permission_type_to_category_groups.rb | 2 +- .../20130712163509_add_missing_id_columns.rb | 2 +- db/migrate/20130723212758_rename_admin_log.rb | 2 +- .../20130724201552_create_blocked_emails.rb | 2 +- ...0725213613_add_more_to_staff_action_log.rb | 2 +- ...30728172550_add_url_to_optimized_images.rb | 2 +- ...3035_add_report_index_to_incoming_links.rb | 2 +- ..._add_last_match_index_to_blocked_emails.rb | 2 +- ...0130809160751_fix_seen_notification_ids.rb | 2 +- ...add_filter_indexes_to_staff_action_logs.rb | 2 +- .../20130809211409_add_avatar_to_users.rb | 2 +- .../20130813204212_create_screened_urls.rb | 2 +- ...ename_blocked_emails_to_screened_emails.rb | 2 +- ...20130816024250_create_oauth2_user_infos.rb | 2 +- ..._add_value_columns_to_staff_action_logs.rb | 2 +- ..._add_subject_index_to_staff_action_logs.rb | 2 +- ...3513_add_ip_address_to_screening_tables.rb | 2 +- ...faults_on_email_digest_columns_of_users.rb | 2 +- ...20130826011521_create_plugin_store_rows.rb | 2 +- ...0130828192526_fix_optimized_images_urls.rb | 2 +- ...30903154323_allow_null_user_id_on_posts.rb | 2 +- ...0904181208_allow_null_user_id_on_topics.rb | 2 +- .../20130906081326_rename_system_username.rb | 2 +- .../20130906171631_add_index_to_uploads.rb | 2 +- ...30910040235_index_topics_for_front_page.rb | 2 +- ...ename_staff_action_logs_to_user_history.rb | 2 +- .../20130911182437_create_user_stats.rb | 2 +- db/migrate/20130912185218_acting_user_null.rb | 2 +- ...10454_add_mobile_to_site_customizations.rb | 2 +- ...17174738_add_topic_id_to_user_histories.rb | 2 +- ...0131001060630_add_email_always_to_users.rb | 2 +- ..._add_user_id_parent_type_index_on_views.rb | 2 +- ...131003061137_move_columns_to_user_stats.rb | 2 +- ...3951_backfill_post_upload_reverse_index.rb | 2 +- .../20131015131652_create_post_details.rb | 2 +- ...1017014509_add_post_count_to_categories.rb | 2 +- ...20131017030605_add_latest_to_categories.rb | 2 +- ...1017205954_create_screened_ip_addresses.rb | 2 +- ...131018050738_add_position_to_categories.rb | 2 +- ...131022045114_add_uncategorized_category.rb | 2 +- db/migrate/20131022151218_create_api_keys.rb | 2 +- ...09_add_parent_category_id_to_categories.rb | 2 +- .../20131105101051_add_origin_to_uploads.rb | 2 +- ...131107154900_rename_banned_to_suspended.rb | 2 +- ...4185225_add_participant_count_to_topics.rb | 2 +- ...20131115165105_add_edit_reason_to_posts.rb | 2 +- ...0131118173159_rename_best_of_to_summary.rb | 2 +- ...131120055018_move_emoji_to_new_location.rb | 2 +- ...2064921_increase_twitter_user_id_length.rb | 2 +- ...6200009_rename_auto_close_days_to_hours.rb | 2 +- .../20131209091702_create_post_revisions.rb | 2 +- .../20131209091742_create_topic_revisions.rb | 2 +- .../20131210163702_add_word_count_to_posts.rb | 2 +- .../20131210181901_migrate_word_counts.rb | 2 +- .../20131210234530_rename_version_column.rb | 2 +- ..._post_count_stats_columns_to_categories.rb | 2 +- ...57_make_position_nullable_in_categories.rb | 2 +- .../20131217174004_create_topic_embeds.rb | 2 +- ...20131219203905_add_cook_method_to_posts.rb | 2 +- .../20131223171005_create_top_topics.rb | 2 +- ...20131227164338_add_scores_to_top_topics.rb | 2 +- ...229221725_add_watch_new_topics_to_users.rb | 2 +- ..._last_emailed_post_number_to_topic_user.rb | 2 +- .../20140101235747_add_category_users.rb | 2 +- ...0140102104229_add_alias_level_to_groups.rb | 2 +- ..._default_from_external_links_in_new_tab.rb | 2 +- ...220141_remove_enable_wide_category_list.rb | 2 +- ...40109205940_rename_favorites_to_starred.rb | 2 +- db/migrate/20140116170655_drop_hot_topics.rb | 2 +- .../20140120155706_add_lounge_category.rb | 2 +- ...121204628_add_invalidated_at_to_invites.rb | 2 +- .../20140122043508_add_meta_category.rb | 2 +- ...124202427_add_posts_read_to_user_visits.rb | 2 +- .../20140129164541_remove_category_hotness.rb | 2 +- .../20140206044818_add_locale_to_user.rb | 2 +- ...lts_to_category_posts_and_topics_fields.rb | 2 +- ...06215029_add_mailing_list_mode_to_users.rb | 2 +- ...210194146_add_primary_group_id_to_users.rb | 2 +- .../20140211230222_move_cas_settings.rb | 2 +- ...34523_add_targets_topic_to_post_actions.rb | 2 +- ...0140214151255_add_skipped_to_email_logs.rb | 2 +- .../20140220160510_rename_site_settings.rb | 2 +- ...140220163213_rename_delete_user_max_age.rb | 2 +- ...24232712_add_profile_background_to_user.rb | 2 +- ...140224232913_add_single_sign_on_records.rb | 2 +- ...04930_add_custom_email_in_to_categories.rb | 2 +- .../20140227201005_add_staff_category.rb | 2 +- ...ernal_username_to_single_sign_on_record.rb | 2 +- ..._external_name_to_single_sign_on_record.rb | 2 +- ...205743_add_admin_only_to_user_histories.rb | 2 +- ...40303185354_add_new_since_to_user_stats.rb | 2 +- .../20140304200606_create_badge_types.rb | 2 +- db/migrate/20140304201403_create_badges.rb | 2 +- .../20140305100909_create_user_badges.rb | 2 +- ..._move_topic_revisions_to_post_revisions.rb | 2 +- .../20140318150412_add_excerpt_to_topics.rb | 2 +- ...318203559_add_created_at_index_to_posts.rb | 2 +- ...facebook_user_infos_username_can_be_nil.rb | 2 +- ...140402201432_make_content_sha1_nullable.rb | 2 +- ...20140404143501_add_title_to_topic_links.rb | 2 +- ...407055830_add_pinned_globally_to_topics.rb | 2 +- ...140407202158_site_setting_comma_to_pipe.rb | 2 +- .../20140408061512_add_wiki_to_posts.rb | 2 +- ...1_add_default_value_to_top_topic_scores.rb | 2 +- .../20140415054717_allow_longer_usernames.rb | 2 +- .../20140416202746_create_color_schemes.rb | 2 +- ...140416202801_create_color_scheme_colors.rb | 2 +- ...7_remove_color_hexcode_from_badge_types.rb | 2 +- .../20140421235646_add_user_custom_fields.rb | 2 +- .../20140422195623_add_visibile_to_groups.rb | 2 +- .../20140425125742_add_custom_fields.rb | 2 +- .../20140425135354_add_topic_custom_fields.rb | 2 +- .../20140425172618_add_titleable_to_badges.rb | 2 +- ...51_add_registration_ip_address_to_users.rb | 2 +- ...ncrement_reserved_trust_level_badge_ids.rb | 2 +- ..._add_last_redirected_to_top_at_to_users.rb | 2 +- ...20140506200235_remove_seed_color_scheme.rb | 2 +- ...remove_opacity_from_color_scheme_colors.rb | 2 +- .../20140508053815_add_invited_groups.rb | 2 +- ...111_init_fixed_category_positions_value.rb | 2 +- ...0520062826_add_multiple_award_to_badges.rb | 2 +- ...emove_has_custom_avatar_from_user_stats.rb | 2 +- ...20140521192142_create_google_user_infos.rb | 2 +- ...20115_google_openid_default_has_changed.rb | 2 +- db/migrate/20140522003151_add_user_avatars.rb | 2 +- ...ove_uploaded_avatar_template_from_users.rb | 2 +- ...9_change_category_uniquness_contstraint.rb | 2 +- ...6201939_add_disable_jump_reply_to_users.rb | 2 +- .../20140527163207_create_user_profiles.rb | 2 +- ..._system_savatar_version_to_user_avatars.rb | 2 +- .../20140528015354_add_baked_at_to_posts.rb | 2 +- ...08_remove_use_uploaded_avatar_from_user.rb | 2 +- ...remove_system_avatars_from_user_avatars.rb | 2 +- ...0140530043913_add_baked_version_to_post.rb | 2 +- ...45431_disable_external_auths_by_default.rb | 2 +- ...0607035234_add_website_to_user_profiles.rb | 2 +- ...140610012414_add_post_id_to_user_badges.rb | 2 +- .../20140610012833_add_icon_to_badges.rb | 2 +- ...0140610034314_move_bio_to_user_profiles.rb | 2 +- ...ove_profile_background_to_user_profiles.rb | 2 +- ...53829_add_notification_id_to_user_badge.rb | 2 +- .../20140617080955_rename_registered_users.rb | 2 +- ...193351_add_post_id_index_on_topic_links.rb | 2 +- .../20140618001820_dont_auto_muto_topics.rb | 2 +- ...dd_dismissed_banner_key_to_user_profile.rb | 2 +- .../20140620184031_add_hidden_at_to_posts.rb | 2 +- ...0140623195618_fix_categories_constraint.rb | 2 +- .../20140624044600_add_raw_data_to_search.rb | 2 +- ...20140627193814_add_images_to_categories.rb | 2 +- .../20140703022838_add_fields_to_badges.rb | 2 +- .../20140705081453_index_user_badges.rb | 2 +- .../20140707071913_add_self_edits_to_posts.rb | 2 +- ...0005023_add_badge_posts_and_topics_view.rb | 2 +- ...40710224658_add_is_quote_to_topic_links.rb | 2 +- ...140711063215_add_read_faq_to_user_stats.rb | 2 +- ...140711143146_remove_not_null_from_email.rb | 2 +- ...1193923_remove_email_in_address_setting.rb | 2 +- ...233329_badges_only_on_public_categories.rb | 2 +- .../20140714060646_add_enabled_to_badges.rb | 2 +- ...0140715013018_correct_post_number_index.rb | 2 +- ...0140715051412_add_auto_revoke_to_badges.rb | 2 +- db/migrate/20140715055242_add_quoted_posts.rb | 2 +- ...20_update_users_case_insensitive_emails.rb | 2 +- ...0715190552_remove_uncategorized_parents.rb | 2 +- .../20140716063802_add_badge_groupings.rb | 2 +- ..._description_optional_in_badge_grouping.rb | 2 +- ...140718041445_set_default_badge_grouping.rb | 2 +- .../20140721063820_add_trigger_to_badges.rb | 2 +- ...reed_at_and_agreed_by_id_to_post_action.rb | 2 +- ...307_rename_defer_columns_on_post_action.rb | 2 +- ...20140723011456_add_show_posts_to_badges.rb | 2 +- ...725050636_remove_invalid_incoming_links.rb | 2 +- ...5172830_remove_message_from_post_action.rb | 2 +- ...030954_add_edit_history_public_to_users.rb | 2 +- ...20140728120708_fix_index_on_post_action.rb | 2 +- ..._add_first_post_created_at_to_user_stat.rb | 2 +- ..._add_post_and_topic_counts_to_user_stat.rb | 2 +- ...ve_unique_constraint_from_invites_index.rb | 2 +- ...d_at_and_disagreed_by_id_to_post_action.rb | 2 +- ...0140731011328_add_reply_quoted_to_posts.rb | 2 +- .../20140801052028_fix_incoming_links.rb | 2 +- ...01170444_create_post_timings_user_index.rb | 2 +- ...40804010803_incoming_link_normalization.rb | 2 +- ...030041_remove_url_from_incoming_referer.rb | 2 +- ...60439_drop_topic_id_from_incoming_links.rb | 2 +- .../20140804072504_views_to_topic_views.rb | 2 +- ...613_normalize_topic_view_data_and_index.rb | 2 +- ..._add_bio_cooked_version_to_user_profile.rb | 2 +- db/migrate/20140806003116_fixup_badge_ids.rb | 2 +- ...7033123_add_index_on_last_seen_to_users.rb | 2 +- ...0140808051823_create_topic_search_index.rb | 2 +- ...40809224243_add_user_badge_unique_index.rb | 2 +- ...0_rename_defered_columns_on_post_action.rb | 2 +- .../20140813175357_add_default_to_active.rb | 2 +- ...0140815183851_fix_index_on_post_actions.rb | 2 +- ...0815191556_fix_post_actions_index_again.rb | 2 +- ...0815215618_add_name_lower_to_categories.rb | 2 +- ...nal_avatar_url_to_single_sign_on_record.rb | 2 +- .../20140818023700_index_email_tokens.rb | 2 +- ...826234625_rename_settings_pop3s_to_pop3.rb | 2 +- .../20140827044811_remove_nullable_dates.rb | 2 +- .../20140828172407_create_permalinks.rb | 2 +- ...00231_make_url_col_bigger_in_permalinks.rb | 2 +- ..._orphaned_by_removing_category_or_group.rb | 2 +- ...0140904055702_correct_post_action_index.rb | 2 +- .../20140904160015_add_via_email_to_posts.rb | 2 +- ...40904215629_rename_trust_level_settings.rb | 2 +- ...0140905055251_rename_trust_level_badges.rb | 2 +- db/migrate/20140905171733_create_warnings.rb | 2 +- ...08165716_migrate_warning_topic_subtypes.rb | 2 +- .../20140908191429_trim_profile_length.rb | 2 +- .../20140910130155_create_topic_user_index.rb | 2 +- ...49_private_messages_have_no_category_id.rb | 2 +- ...913192733_add_trust_level_locked_column.rb | 2 +- ...40923042349_add_retain_hours_to_uploads.rb | 2 +- .../20140924192418_rename_content_type.rb | 2 +- .../20140925173220_create_user_fields.rb | 2 +- ...40929181930_add_editable_to_user_fields.rb | 2 +- .../20140929204155_migrate_tos_setting.rb | 2 +- ...001101041_add_post_id_to_user_histories.rb | 2 +- ...02181613_add_description_to_user_fields.rb | 2 +- ...add_badge_granted_title_to_user_profile.rb | 2 +- ...008152953_add_exernal_url_to_permalinks.rb | 2 +- ...1228_add_required_signup_to_user_fields.rb | 2 +- ...ast_post_and_auto_close_hours_to_topics.rb | 2 +- ..._close_based_on_last_post_to_categories.rb | 2 +- ...41014032859_add_hidden_to_post_revision.rb | 2 +- db/migrate/20141014191645_fix_tos_name.rb | 2 +- .../20141015060145_add_raw_email_to_posts.rb | 2 +- ...d_expansion_background_to_user_profiles.rb | 2 +- ...41020153415_add_public_version_to_posts.rb | 2 +- ...20141020154935_rename_expansion_to_card.rb | 2 +- .../20141020164816_add_image_to_badges.rb | 2 +- ...0174120_add_card_image_to_user_profiles.rb | 2 +- .../20141030222425_rename_seen_post_count.rb | 2 +- ...150304_add_footer_to_site_customization.rb | 2 +- .../20141118011735_correct_username_search.rb | 2 +- ...41120035016_add_allowed_ips_to_api_keys.rb | 2 +- .../20141120043401_add_hidden_to_api_keys.rb | 2 +- db/migrate/20141211114517_fix_emoji_path.rb | 2 +- ...216112341_resolve_duplicate_group_names.rb | 2 +- ...default_styles_from_site_customizations.rb | 2 +- .../20141222224220_fix_emoji_path_take2.rb | 2 +- ...20141222230707_amend_site_customization.rb | 2 +- .../20141223145058_create_csv_export_logs.rb | 2 +- ..._rename_csv_export_logs_to_user_exports.rb | 2 +- .../20150102113309_clean_up_user_history.rb | 2 +- db/migrate/20150106215342_remove_stars.rb | 2 +- ..._add_liked_and_bookmarked_to_topic_user.rb | 2 +- .../20150108202057_create_bookmark_actions.rb | 2 +- ...8211557_index_topic_custom_field_values.rb | 2 +- db/migrate/20150108221703_group_managers.rb | 2 +- ...172258_add_new_site_customization_types.rb | 2 +- ...migrate_site_text_to_site_customization.rb | 2 +- ...114093325_add_top_to_site_customization.rb | 2 +- ...0150115172310_rename_user_export_column.rb | 2 +- ...92813_add_posts_index_including_deleted.rb | 2 +- ...45128_add_automatic_membership_to_group.rb | 2 +- ...4520_add_show_on_profile_to_user_fields.rb | 2 +- ...20150203041207_add_application_requests.rb | 2 +- ...150205032808_reset_application_requests.rb | 2 +- ...72051_add_custom_type_to_user_histories.rb | 2 +- ...150206004143_flush_application_requests.rb | 2 +- ...13174159_create_digest_unsubscribe_keys.rb | 2 +- .../20150224004420_add_pinned_indexes.rb | 2 +- ...27043622_add_long_description_to_badges.rb | 2 +- ...150301224250_create_suggested_for_index.rb | 2 +- ...add_all_time_and_op_likes_to_top_topics.rb | 2 +- .../20150318143915_create_directory_items.rb | 2 +- ..._allow_private_messages_to_user_profile.rb | 2 +- ...llow_private_messages_from_user_profile.rb | 2 +- db/migrate/20150323234856_add_muted_users.rb | 2 +- ...50324184222_add_more_to_directory_items.rb | 2 +- .../20150325183400_fix_group_user_count.rb | 2 +- .../20150325190959_create_queued_posts.rb | 2 +- ...50410002033_add_primary_group_to_groups.rb | 2 +- .../20150410002551_add_title_to_groups.rb | 2 +- ...5850_increase_url_length_on_topic_embed.rb | 2 +- ...0714_add_queued_post_id_to_user_actions.rb | 2 +- ...5_add_link_post_id_index_on_topic_links.rb | 2 +- .../20150505044154_add_stylesheet_cache.rb | 2 +- ...0150513094042_add_index_on_post_actions.rb | 2 +- ...14023016_add_unread_notifications_index.rb | 2 +- ...150514043155_add_user_actions_all_index.rb | 2 +- .../20150525151759_set_default_s3_region.rb | 2 +- .../20150609163211_migrate_embeddable_host.rb | 2 +- ...7080349_add_index_on_post_notifications.rb | 2 +- ...dd_index_target_post_id_on_user_actions.rb | 2 +- ...20150617234511_add_staff_index_to_users.rb | 2 +- ...201926_add_topic_template_to_categories.rb | 2 +- ...0150706215111_add_mobile_to_user_visits.rb | 2 +- ...163251_add_reports_index_to_user_visits.rb | 2 +- ...50709021818_add_like_count_to_post_menu.rb | 2 +- ...0150713203955_enlarge_users_email_field.rb | 2 +- ...4165259_add_index_to_post_custom_fields.rb | 2 +- .../20150724182342_add_action_code_to_post.rb | 2 +- ...0150727193414_create_user_field_options.rb | 2 +- ...150727210019_add_pinned_until_to_topics.rb | 2 +- ...50727210748_add_quarterly_to_top_topics.rb | 2 +- ...8004647_correct_custom_fields_migration.rb | 2 +- ...50728210202_migrate_old_moderator_posts.rb | 2 +- ...20150729150523_migrate_auto_close_posts.rb | 2 +- ...50730154830_add_position_to_user_fields.rb | 2 +- .../20150731225331_migrate_old_moved_posts.rb | 2 +- db/migrate/20150802233112_add_post_stats.rb | 2 +- ...add_embedded_css_to_site_customizations.rb | 2 +- .../20150818190757_create_embeddable_hosts.rb | 2 +- .../20150822141540_fix_migrated_hosts.rb | 2 +- ..._add_suppress_from_homepage_to_category.rb | 2 +- ...1192313_add_grant_trust_level_to_groups.rb | 2 +- ...0150914021445_create_user_profile_views.rb | 2 +- ...0150914034541_add_views_to_user_profile.rb | 2 +- ...71017_add_category_id_to_user_histories.rb | 2 +- ...d_user_id_group_id_index_to_group_users.rb | 2 +- ...20150924022040_add_fancy_title_to_topic.rb | 2 +- ...0925000915_exclude_whispers_from_badges.rb | 2 +- ...3233815_add_lower_title_index_on_topics.rb | 2 +- .../20151105181635_add_staged_to_user.rb | 2 +- ..._fix_incorrect_topic_creator_after_move.rb | 2 +- ...20151107042241_add_owner_to_group_users.rb | 2 +- .../20151109124147_drop_group_managers.rb | 2 +- ...1113205046_create_translation_overrides.rb | 2 +- ...add_automatically_unpin_topics_to_users.rb | 2 +- ...1124172631_add_is_support_to_categories.rb | 2 +- .../20151124192339_rename_ninja_edit.rb | 2 +- db/migrate/20151125194322_remove_site_text.rb | 2 +- ..._rename_is_support_to_contains_messages.rb | 2 +- ...ed_head_and_body_to_site_customizations.rb | 2 +- ...and_footer_baked_to_site_customizations.rb | 2 +- .../20151201035631_add_group_mentions.rb | 2 +- ...1201161726_add_incoming_email_to_groups.rb | 2 +- ...2_add_notification_level_to_group_users.rb | 2 +- ...2200_add_unique_index_to_category_users.rb | 2 +- ...151219045559_add_has_messages_to_groups.rb | 2 +- ...chived_messages_group_archived_messages.rb | 2 +- ...160108051129_fix_incorrect_user_history.rb | 2 +- ...archive_system_messages_with_no_replies.rb | 2 +- ...2_remove_users_from_topic_allowed_users.rb | 2 +- ...818_remove_contains_message_on_category.rb | 2 +- ...dd_contains_messages_back_to_categories.rb | 2 +- .../20160113160742_create_incoming_emails.rb | 2 +- ...160118174335_rebake_html_customizations.rb | 2 +- ...20160118233631_backfill_incoming_emails.rb | 2 +- ...ge_default_notification_level_on_groups.rb | 2 +- ...grate_uncategorized_description_setting.rb | 2 +- db/migrate/20160201181320_fix_email_logs.rb | 2 +- .../20160206210202_remove_invalid_websites.rb | 2 +- ...28_add_unread_pm_index_to_notifications.rb | 2 +- ...60224033122_create_instagram_user_infos.rb | 2 +- db/migrate/20160225050317_add_user_options.rb | 2 +- ...225050318_allow_defaults_on_users_table.rb | 2 +- ...9_move_tracking_options_to_user_options.rb | 2 +- ..._email_previous_replies_to_user_options.rb | 2 +- ...6_add_email_in_reply_to_to_user_options.rb | 2 +- ...63432_rebuild_directory_item_with_index.rb | 2 +- ..._notification_frequency_to_user_options.rb | 2 +- ...gest_after_days_to_digest_after_minutes.rb | 2 +- ...0303183607_clear_common_passwords_cache.rb | 2 +- ...add_rejection_message_to_incoming_email.rb | 2 +- ...0307190919_create_email_change_requests.rb | 2 +- ...08193142_rename_confirm_translation_key.rb | 2 +- ...9073132_add_mailing_list_mode_frequency.rb | 2 +- ...20160317174357_create_given_daily_likes.rb | 2 +- ..._include_tl0_in_digests_to_user_options.rb | 2 +- .../20160326001747_add_user_first_visit.rb | 2 +- .../20160329101122_remove_wiki_color.rb | 2 +- .../20160405172827_create_user_firsts.rb | 2 +- .../20160407160756_remove_user_firsts.rb | 2 +- .../20160407180149_create_onceoff_logs.rb | 2 +- ...59_add_show_on_user_card_to_user_fields.rb | 2 +- ...dd_compiled_js_to_translation_overrides.rb | 2 +- ...60418065403_add_bounce_key_to_email_log.rb | 2 +- ...dd_is_auto_generated_to_incoming_emails.rb | 2 +- ...60425141954_fix_incoming_emails_indices.rb | 2 +- ...27202222_add_support_for_bounced_emails.rb | 2 +- db/migrate/20160503205953_create_tags.rb | 2 +- ...0160514100852_remove_invalid_topic_user.rb | 2 +- ...22627_shorten_topic_custom_fields_index.rb | 2 +- ...355_correct_mailing_list_mode_frequency.rb | 2 +- .../20160527191614_create_category_tags.rb | 2 +- .../20160530003739_create_scheduler_stats.rb | 2 +- ...0530203810_add_message_id_to_email_logs.rb | 2 +- .../20160602164008_create_tag_groups.rb | 2 +- ...160606204319_create_category_tag_groups.rb | 2 +- .../20160607213656_add_tag_group_options.rb | 2 +- ...203508_remove_tag_count_from_tag_groups.rb | 2 +- ...615024524_rename_digest_unsbscribe_keys.rb | 2 +- ...5447_rename_num_flags_to_block_new_user.rb | 2 +- ..._use_https_name_change_in_site_settings.rb | 2 +- ...compiler_version_to_site_customizations.rb | 2 +- ...160716112354_remove_edit_history_public.rb | 2 +- ...9002225_add_deleted_post_index_to_posts.rb | 2 +- ...1221_add_auth_token_created_at_to_users.rb | 2 +- ...0725015749_rename_auth_token_created_at.rb | 2 +- .../20160727233044_create_developers_table.rb | 2 +- .../20160815002002_add_user_api_keys.rb | 2 +- .../20160815210156_add_flair_url_to_groups.rb | 2 +- ...0816052836_user_api_client_id_is_unique.rb | 2 +- ...6063534_add_revoked_at_to_user_api_keys.rb | 2 +- ..._add_path_whitelist_to_embeddable_hosts.rb | 2 +- ...0160826195018_add_flair_color_to_groups.rb | 2 +- ...60905082217_create_web_hook_event_types.rb | 2 +- db/migrate/20160905082248_create_web_hooks.rb | 2 +- .../20160905084502_create_web_hook_events.rb | 2 +- ...in_table_web_hooks_web_hook_event_types.rb | 2 +- ...1958_create_join_table_web_hooks_groups.rb | 2 +- ..._create_join_table_web_hooks_categories.rb | 2 +- ...6200439_add_via_wizard_to_color_schemes.rb | 2 +- ...9003141_add_avatar_url_to_facebook_info.rb | 2 +- ...054014_add_fields_to_facebook_user_info.rb | 2 +- ...20160920165833_add_moderator_to_invites.rb | 2 +- ...30_add_notification_level_when_replying.rb | 2 +- ...le_sign_on_increase_external_avatar_url.rb | 2 +- ...61013012136_add_scopes_to_user_api_keys.rb | 2 +- ...61014171034_add_directory_items_indexes.rb | 2 +- ...8_fix_category_logo_and_background_urls.rb | 2 +- .../20161029181306_add_image_url_to_posts.rb | 2 +- ...031183811_add_sort_fields_to_categories.rb | 2 +- ...20161102024700_add_post_uploads_indexes.rb | 2 +- ...8_add_uploaded_avatar_id_index_to_users.rb | 2 +- ...20161102024838_add_user_avatars_indexes.rb | 2 +- ...0161102024900_add_user_profiles_indexes.rb | 2 +- .../20161102024920_add_categories_indexes.rb | 2 +- ...020918_add_scores_indexes_to_top_topics.rb | 2 +- ...202011139_add_whisper_support_to_topics.rb | 2 +- ...0161202034856_add_uploads_to_categories.rb | 2 +- .../20161205001727_add_topic_columns_back.rb | 2 +- .../20161205065743_add_bio_to_groups.rb | 2 +- .../20161207030057_add_public_to_groups.rb | 2 +- .../20161208064834_create_group_histories.rb | 2 +- ...add_allow_membership_requests_to_groups.rb | 2 +- .../20161213073938_add_full_name_to_groups.rb | 2 +- ...1215201907_migrate_featured_link_fields.rb | 2 +- ...01352_add_all_topics_wiki_to_categories.rb | 2 +- .../20170124181409_add_user_auth_tokens.rb | 2 +- .../20170201085745_create_custom_emojis.rb | 2 +- .../20170213180857_add_user_auth_token_log.rb | 2 +- ...15151505_add_seen_at_to_user_auth_token.rb | 2 +- ...add_show_subcategory_list_to_categories.rb | 2 +- ...73036_make_user_auth_token_index_unique.rb | 2 +- ...11458_add_featured_topics_to_categories.rb | 2 +- ...01215150_add_default_view_to_categories.rb | 2 +- ...303070706_add_index_to_topic_view_items.rb | 2 +- ...7181800_add_path_to_user_auth_token_log.rb | 2 +- ...dd_subcategory_list_style_to_categories.rb | 2 +- db/migrate/20170313192741_add_themes.rb | 2 +- ...70322065911_create_topic_status_updates.rb | 2 +- ...322155537_add_theme_to_stylesheet_cache.rb | 2 +- ...05_add_default_top_period_to_categories.rb | 2 +- ...to_close_columns_to_topic_status_update.rb | 2 +- ...170324144456_amend_css_columns_in_theme.rb | 2 +- .../20170328163918_break_up_themes_table.rb | 2 +- ...22_add_compiler_version_to_theme_fields.rb | 2 +- ...41605_add_index_to_topic_status_updates.rb | 2 +- ...add_category_id_to_topic_status_updates.rb | 2 +- db/migrate/20170407154510_rename_theme_id.rb | 2 +- .../20170410170923_add_theme_remote_fields.rb | 2 +- db/migrate/20170413043152_rename_warnings.rb | 2 +- ...0417164715_add_theme_id_to_color_scheme.rb | 2 +- ...0170419193714_add_error_to_theme_fields.rb | 2 +- ...add_default_notification_level_to_group.rb | 2 +- ...25083011_add_deleted_at_to_topic_embeds.rb | 2 +- ...0425172415_add_error_to_scheduler_stats.rb | 2 +- ...501191912_add_upload_id_to_theme_fields.rb | 2 +- ...st_daily_updates_users_to_daily_summary.rb | 2 +- ..._add_css_class_name_to_embeddable_hosts.rb | 2 +- ...emove_convert_pasted_image_site_setting.rb | 2 +- ...vert_pasted_images_quality_site_setting.rb | 2 +- ...me_topic_status_updates_to_topic_timers.rb | 2 +- ...512153318_add_theme_key_to_user_options.rb | 2 +- ...85227_create_topic_status_updates_again.rb | 2 +- ...52725_add_theme_key_seq_to_user_options.rb | 2 +- ...5203721_add_public_type_to_topic_timers.rb | 2 +- ...70524182846_add_unread_tracking_columns.rb | 2 +- ...0526125321_drop_unread_tracking_columns.rb | 2 +- ...735_fix_group_allow_membership_requests.rb | 2 +- ...0_remove_auto_close_columns_from_topics.rb | 2 +- ...0609115401_add_extension_to_topic_links.rb | 2 +- .../20170628152322_create_watched_words.rb | 2 +- ...0630083540_add_custom_message_to_invite.rb | 2 +- ...20170703115216_add_extension_to_uploads.rb | 2 +- ...03144855_add_visibility_level_to_groups.rb | 2 +- ...170704142141_add_visible_back_to_groups.rb | 2 +- .../20170713164357_create_search_logs.rb | 2 +- .../20170717084947_create_user_emails.rb | 2 +- ...fault_email_mailing_list_mode_frequency.rb | 2 +- .../20170728012754_split_public_in_groups.rb | 2 +- ...0170728054115_remove_public_from_groups.rb | 2 +- ...d_membership_request_template_to_groups.rb | 2 +- ...170803123704_add_version_to_search_data.rb | 2 +- .../20170818191909_split_alias_levels.rb | 2 +- .../20170823173427_create_tag_search_data.rb | 2 +- .../20170824172615_add_slug_index_on_topic.rb | 2 +- ...170831180419_remove_whisper_topic_links.rb | 2 +- lib/auth/default_current_user_provider.rb | 1 + lib/cache.rb | 2 +- lib/comment_migration.rb | 2 +- lib/cooked_post_processor.rb | 2 +- lib/freedom_patches/fast_pluck.rb | 2 +- lib/freedom_patches/pool_drainer.rb | 2 +- lib/new_post_manager.rb | 2 +- lib/plugin/instance.rb | 4 +- lib/post_destroyer.rb | 6 +- lib/search.rb | 13 +- lib/sql_builder.rb | 2 +- lib/tasks/db.rake | 18 +- lib/topic_creator.rb | 4 +- lib/topic_query.rb | 9 +- plugins/discourse-narrative-bot/plugin.rb | 2 +- .../integration/discobot_certificate_spec.rb | 7 +- .../integration/discobot_welcome_post_spec.rb | 7 +- plugins/discourse-presence/plugin.rb | 2 +- .../spec/presence_controller_spec.rb | 40 +- ...0501152228_rename_total_votes_to_voters.rb | 2 +- .../20151016163051_merge_polls_votes.rb | 2 +- ...0321164925_close_polls_in_closed_topics.rb | 2 +- plugins/poll/plugin.rb | 2 +- .../spec/controllers/polls_controller_spec.rb | 111 ++- .../spec/controllers/posts_controller_spec.rb | 125 ++- .../spec/integration/poll_endpoints_spec.rb | 32 +- public/javascripts/ace/mode-ejs.js | 2 +- public/javascripts/ace/mode-haml.js | 2 +- public/javascripts/ace/mode-html_ruby.js | 2 +- public/javascripts/ace/mode-ruby.js | 2 +- public/javascripts/ace/snippets/ruby.js | 2 +- spec/components/cache_spec.rb | 4 +- spec/components/column_dropper_spec.rb | 4 +- spec/components/cooked_post_processor_spec.rb | 7 +- .../schema_migration_details_spec.rb | 2 +- spec/components/sql_builder_spec.rb | 8 +- spec/components/stylesheet/compiler_spec.rb | 8 +- spec/components/topic_query_spec.rb | 13 +- spec/controllers/about_controller_spec.rb | 9 +- .../admin/admin_controller_spec.rb | 6 +- spec/controllers/admin/api_controller_spec.rb | 16 +- .../admin/backups_controller_spec.rb | 40 +- .../admin/badges_controller_spec.rb | 85 +- .../admin/color_schemes_controller_spec.rb | 30 +- .../admin/dashboard_controller_spec.rb | 26 +- .../admin/email_controller_spec.rb | 35 +- .../admin/emojis_controller_spec.rb | 2 +- .../admin/groups_controller_spec.rb | 35 +- .../admin/impersonate_controller_spec.rb | 16 +- .../admin/permalinks_controller_spec.rb | 6 +- .../admin/plugins_controller_spec.rb | 2 +- .../admin/reports_controller_spec.rb | 12 +- .../admin/screened_emails_controller_spec.rb | 2 +- .../screened_ip_addresses_controller_spec.rb | 8 +- .../admin/screened_urls_controller_spec.rb | 2 +- .../admin/site_settings_controller_spec.rb | 29 +- .../admin/site_texts_controller_spec.rb | 25 +- .../staff_action_logs_controller_spec.rb | 4 +- .../admin/themes_controller_spec.rb | 62 +- .../admin/user_fields_controller_spec.rb | 76 +- .../admin/users_controller_spec.rb | 200 +++-- .../admin/versions_controller_spec.rb | 2 +- .../admin/web_hooks_controller_spec.rb | 51 +- spec/controllers/badges_controller_spec.rb | 6 +- .../controllers/categories_controller_spec.rb | 179 ++-- .../category_hashtags_controller_spec.rb | 15 +- spec/controllers/clicks_controller_spec.rb | 30 +- .../composer_messages_controller_spec.rb | 6 +- .../directory_items_controller_spec.rb | 11 +- spec/controllers/draft_controller_spec.rb | 4 +- spec/controllers/email_controller_spec.rb | 67 +- .../controllers/export_csv_controller_spec.rb | 22 +- .../extra_locales_controller_spec.rb | 22 +- .../finish_installation_controller_spec.rb | 32 +- spec/controllers/groups_controller_spec.rb | 22 +- .../inline_onebox_controller_spec.rb | 8 +- spec/controllers/invites_controller_spec.rb | 130 ++- spec/controllers/list_controller_spec.rb | 101 +-- .../notifications_controller_spec.rb | 20 +- spec/controllers/onebox_controller_spec.rb | 26 +- .../controllers/permalinks_controller_spec.rb | 10 +- .../post_action_users_controller_spec.rb | 33 +- .../post_actions_controller_spec.rb | 128 +-- spec/controllers/posts_controller_spec.rb | 453 +++++----- .../queued_posts_controller_spec.rb | 26 +- spec/controllers/search_controller_spec.rb | 110 ++- spec/controllers/session_controller_spec.rb | 209 +++-- .../similar_topics_controller_spec.rb | 8 +- spec/controllers/site_controller_spec.rb | 6 +- spec/controllers/steps_controller_spec.rb | 28 +- .../stylesheets_controller_spec.rb | 24 +- spec/controllers/tags_controller_spec.rb | 91 +- ...oller_spec.rb => topic_controller_spec.rb} | 151 +++- spec/controllers/topics_controller_spec.rb | 573 +++++++++---- spec/controllers/uploads_controller_spec.rb | 73 +- .../user_actions_controller_spec.rb | 27 +- .../user_api_keys_controller_spec.rb | 72 +- .../user_avatars_controller_spec.rb | 39 +- .../user_badges_controller_spec.rb | 58 +- spec/controllers/users_controller_spec.rb | 802 ++++++++++++------ spec/controllers/webhooks_controller_spec.rb | 78 +- spec/controllers/wizard_controller_spec.rb | 12 +- .../invite_only_registration_spec.rb | 17 +- spec/integration/topic_auto_close_spec.rb | 4 - spec/jobs/jobs_spec.rb | 1 - spec/models/category_spec.rb | 4 +- spec/models/invite_spec.rb | 4 +- spec/models/notification_spec.rb | 1 - spec/models/post_action_spec.rb | 2 +- spec/models/theme_field_spec.rb | 5 +- spec/models/topic_link_spec.rb | 4 +- spec/models/topic_timer_spec.rb | 5 - spec/models/user_spec.rb | 4 + spec/multisite/site_settings_spec.rb | 2 + spec/rails_helper.rb | 1 + spec/requests/admin/admin_controller_spec.rb | 2 +- spec/requests/admin/emojis_controller_spec.rb | 19 +- spec/requests/admin/groups_controller_spec.rb | 20 +- .../embed_controller_spec.rb | 93 +- spec/requests/groups_controller_spec.rb | 170 ++-- spec/requests/list_controller_spec.rb | 29 + spec/requests/post_actions_controller_spec.rb | 148 ++++ spec/requests/posts_controller_spec.rb | 202 +++++ .../robots_txt_controller_spec.rb | 17 +- .../static_controller_spec.rb | 119 +-- spec/requests/tags_controller_spec.rb | 2 +- spec/requests/topics_controller_spec.rb | 21 +- spec/requests/users_controller_spec.rb | 38 +- .../users_email_controller_spec.rb | 73 +- spec/services/user_anonymizer_spec.rb | 4 +- spec/support/integration_helpers.rb | 26 +- 989 files changed, 5114 insertions(+), 3117 deletions(-) create mode 100644 app/assets/images/favicons/google_branding/logo_calendar_48px.png mode change 100644 => 100755 bin/docker/README.md rename spec/controllers/{application_controller_spec.rb => topic_controller_spec.rb} (67%) rename spec/{controllers => requests}/embed_controller_spec.rb (52%) create mode 100644 spec/requests/list_controller_spec.rb create mode 100644 spec/requests/post_actions_controller_spec.rb create mode 100644 spec/requests/posts_controller_spec.rb rename spec/{controllers => requests}/robots_txt_controller_spec.rb (53%) rename spec/{controllers => requests}/static_controller_spec.rb (59%) rename spec/{controllers => requests}/users_email_controller_spec.rb (61%) diff --git a/Gemfile.lock b/Gemfile.lock index c717e440f2e..0040eb3e634 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -76,7 +76,7 @@ GEM crass (1.0.2) debug_inspector (0.0.3) diff-lcs (1.3) - discourse-qunit-rails (0.0.9) + discourse-qunit-rails (0.0.11) railties discourse_fastimage (2.1.0) discourse_image_optim (0.24.5) @@ -298,7 +298,7 @@ GEM rspec-mocks (3.6.0) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.6.0) - rspec-rails (3.6.0) + rspec-rails (3.6.1) actionpack (>= 3.0) activesupport (>= 3.0) railties (>= 3.0) diff --git a/app/assets/images/favicons/google_branding/logo_calendar_48px.png b/app/assets/images/favicons/google_branding/logo_calendar_48px.png new file mode 100644 index 0000000000000000000000000000000000000000..bb50bb966d48fcacb0d74aaef5a718e2dc0c74e5 GIT binary patch literal 1609 zcmV-P2DbT$P)q$gGRCwC#SW9dhMHv2PcVj0`+Bm6m zKuH{{l!m4k8>vVLDWoVuf&hmi5GRygI20}s71ss{4!|K?=z#-GBv7Fd2P(mZLtF}! zQbgQC3q{I9eF#-aB|CBa-W_IUAD*>mUv3)- zYY_qv4u_8t5^2#olG6qR_=E^NkqX4)ap>#oV|}SqYF+(gt&x!t= z3W26+AW4#KjGMo>5^$PGH>p;ute0h(jiaij8~Y_;u5GTx%z@0O+T=-i2}bzl_y>Pa zXY;kWVp)q;Yxw@64R=$&$ABHiG>+|15Ojs5Y_vz2`Qp^*ye9zye&U~dm8D$1_F%%L zP3rc(@jc*X^EK~!yA^mO7CQRnsnN8n6X){PiH8Z^*I+>-7D2EzN24YJo7w8FWznFV zHU!w32vk*gsM7b+gj>WB`J*Tgq<6ib@gFDBeh94ZhV+BPHg4X!uQ2-5n;GBhj}9U@ zI8EkAok_BMjUSxs4xq;#A1udv+T@9jvjN3{kkXxIW0q3PfHL^^!p=$y--vBuK zqXx?>m}!NI`So$+SNimMAQQ^EMV9lIHF7ySXhBdFQ>owFXdwi-U~)8}OP?jv*w_bq z>_>s~;Hh&{CuLcED;QoE>BI6F@rg`vS&uqR!Xqx*T8j7vH67~AR104blfgcd7Ir7K z-pYBvPQYOY8b(hZlNxFk44)F`-YH>6l(eAMG$bq^1Of_9AhtgNm3+?F6|p}(?a>~A zdB*69$&i=A>^?CdF%ycD`!{3_PXAD=&(ROT)_mIHalMZnFxREqA?pBxeH@OQH6V9@ z(i4Tsc8)95jlD6pfUMrtVD?;z{iYipIUvJZ&vn4~Aqnp0WH@(OvkveS95&~3;8e|6 z4kNBOK;Yxci}RtL&6O4C*wd>I!@3@<3d8_FfnftYZC6$__?sQu{$gPZ4uRouSvv}jL6WKpr#Bcd2bCgBmqXEdk+IZ zfzviNBs0eaKsHC6GE8S}19K*g42^NWZ8b4!DZdE`JpW-n>8OcF4=i0LA+oHS$n2{j zn0i8n!$T5GjL9(jiVS0edT3m@h&gg1o3As#;9hz^`~Ftaw+WF6&L49Li86G<>|zPt zeOZA4Qlw2kquAm(CAaVshHH03(&il2A;mZxe4;J;K(i(!xRvjO6Q7sh2&wB6q`0F* zHnw%}7yi1scfxP0C30aa+VEg);GsEGE?zEYkQ(qzRdjurjCR@dEIu4j%ikc|i%12$}~xD@SZO`=QbKlzwaSd<4*9aE1QeN==d7ZZLlPlA5XV)A76r~9) z@TYXDa)ew#dVU+#FsRjXmI!p_(kGA2L%X$GyZ!&#zXA*Zb1>cqg9*op00000NkvXX Hu0mjf(TMQ# literal 0 HcmV?d00001 diff --git a/app/controllers/about_controller.rb b/app/controllers/about_controller.rb index 40608cc50d4..0ca88b6945f 100644 --- a/app/controllers/about_controller.rb +++ b/app/controllers/about_controller.rb @@ -1,8 +1,8 @@ require_dependency 'rate_limiter' class AboutController < ApplicationController - skip_before_filter :check_xhr, only: [:index] - before_filter :ensure_logged_in, only: [:live_post_counts] + skip_before_action :check_xhr, only: [:index] + before_action :ensure_logged_in, only: [:live_post_counts] def index return redirect_to path('/login') if SiteSetting.login_required? && current_user.nil? diff --git a/app/controllers/admin/admin_controller.rb b/app/controllers/admin/admin_controller.rb index 30785689e1d..1b786ac0dec 100644 --- a/app/controllers/admin/admin_controller.rb +++ b/app/controllers/admin/admin_controller.rb @@ -1,10 +1,10 @@ class Admin::AdminController < ApplicationController - before_filter :ensure_logged_in - before_filter :ensure_staff + before_action :ensure_logged_in + before_action :ensure_staff def index - render nothing: true + render body: nil end end diff --git a/app/controllers/admin/api_controller.rb b/app/controllers/admin/api_controller.rb index 9fd25eecfbb..0c39edc98b2 100644 --- a/app/controllers/admin/api_controller.rb +++ b/app/controllers/admin/api_controller.rb @@ -17,7 +17,7 @@ class Admin::ApiController < Admin::AdminController raise Discourse::NotFound if api_key.blank? api_key.destroy - render nothing: true + render body: nil end def create_master_key diff --git a/app/controllers/admin/backups_controller.rb b/app/controllers/admin/backups_controller.rb index d0922f88638..76732d061e3 100644 --- a/app/controllers/admin/backups_controller.rb +++ b/app/controllers/admin/backups_controller.rb @@ -3,7 +3,7 @@ require "email_backup_token" class Admin::BackupsController < Admin::AdminController - skip_before_filter :check_xhr, only: [:index, :show, :logs, :check_backup_chunk, :upload_backup_chunk] + skip_before_action :check_xhr, only: [:index, :show, :logs, :check_backup_chunk, :upload_backup_chunk] def index respond_to do |format| @@ -50,9 +50,9 @@ class Admin::BackupsController < Admin::AdminController token = EmailBackupToken.set(current_user.id) download_url = "#{url_for(controller: 'backups', action: 'show')}?token=#{token}" Jobs.enqueue(:download_backup_email, to_address: current_user.email, backup_file_path: download_url) - render nothing: true + render body: nil else - render nothing: true, status: 404 + render body: nil, status: 404 end end @@ -70,7 +70,7 @@ class Admin::BackupsController < Admin::AdminController if @error render layout: 'no_ember', status: 422 else - render nothing: true, status: 404 + render body: nil, status: 404 end end end @@ -79,9 +79,9 @@ class Admin::BackupsController < Admin::AdminController if backup = Backup[params.fetch(:id)] StaffActionLogger.new(current_user).log_backup_destroy(backup) backup.remove - render nothing: true + render body: nil else - render nothing: true, status: 404 + render body: nil, status: 404 end end @@ -125,7 +125,7 @@ class Admin::BackupsController < Admin::AdminController StaffActionLogger.new(current_user).log_change_readonly_mode(enable) - render nothing: true + render body: nil end def check_backup_chunk @@ -139,16 +139,16 @@ class Admin::BackupsController < Admin::AdminController # check chunk upload status status = HandleChunkUpload.check_chunk(chunk, current_chunk_size: current_chunk_size) - render nothing: true, status: status + render body: nil, status: status end def upload_backup_chunk filename = params.fetch(:resumableFilename) total_size = params.fetch(:resumableTotalSize).to_i - return render status: 415, text: I18n.t("backup.backup_file_should_be_tar_gz") unless /\.(tar\.gz|t?gz)$/i =~ filename - return render status: 415, text: I18n.t("backup.not_enough_space_on_disk") unless has_enough_space_on_disk?(total_size) - return render status: 415, text: I18n.t("backup.invalid_filename") unless !!(/^[a-zA-Z0-9\._\-]+$/ =~ filename) + return render status: 415, plain: I18n.t("backup.backup_file_should_be_tar_gz") unless /\.(tar\.gz|t?gz)$/i =~ filename + return render status: 415, plain: I18n.t("backup.not_enough_space_on_disk") unless has_enough_space_on_disk?(total_size) + return render status: 415, plain: I18n.t("backup.invalid_filename") unless !!(/^[a-zA-Z0-9\._\-]+$/ =~ filename) file = params.fetch(:file) identifier = params.fetch(:resumableIdentifier) @@ -168,7 +168,7 @@ class Admin::BackupsController < Admin::AdminController Jobs.enqueue_in(5.seconds, :backup_chunks_merger, filename: filename, identifier: identifier, chunks: chunk_number) end - render nothing: true + render body: nil end private diff --git a/app/controllers/admin/badges_controller.rb b/app/controllers/admin/badges_controller.rb index 6fcdc7e7df4..e84a7dc65fe 100644 --- a/app/controllers/admin/badges_controller.rb +++ b/app/controllers/admin/badges_controller.rb @@ -84,7 +84,7 @@ class Admin::BadgesController < Admin::AdminController def destroy find_badge.destroy - render nothing: true + render body: nil end private diff --git a/app/controllers/admin/color_schemes_controller.rb b/app/controllers/admin/color_schemes_controller.rb index a070f2324d4..a5caf3de621 100644 --- a/app/controllers/admin/color_schemes_controller.rb +++ b/app/controllers/admin/color_schemes_controller.rb @@ -1,6 +1,6 @@ class Admin::ColorSchemesController < Admin::AdminController - before_filter :fetch_color_scheme, only: [:update, :destroy] + before_action :fetch_color_scheme, only: [:update, :destroy] def index render_serialized(ColorScheme.base_color_schemes + ColorScheme.order('id ASC').all.to_a, ColorSchemeSerializer) diff --git a/app/controllers/admin/diagnostics_controller.rb b/app/controllers/admin/diagnostics_controller.rb index 8411e854845..d10c559b4cd 100644 --- a/app/controllers/admin/diagnostics_controller.rb +++ b/app/controllers/admin/diagnostics_controller.rb @@ -2,7 +2,7 @@ require_dependency 'memory_diagnostics' class Admin::DiagnosticsController < Admin::AdminController layout false - skip_before_filter :check_xhr + skip_before_action :check_xhr def dump_statement_cache statements = Post.exec_sql("select * from pg_prepared_statements").to_a diff --git a/app/controllers/admin/email_controller.rb b/app/controllers/admin/email_controller.rb index a5030d06dd8..e4e59c19f9b 100644 --- a/app/controllers/admin/email_controller.rb +++ b/app/controllers/admin/email_controller.rb @@ -11,7 +11,7 @@ class Admin::EmailController < Admin::AdminController params.require(:email_address) begin Jobs::TestEmail.new.execute(to_address: params[:email_address]) - render nothing: true + render body: nil rescue => e render json: { errors: [e.message] }, status: 422 end diff --git a/app/controllers/admin/embeddable_hosts_controller.rb b/app/controllers/admin/embeddable_hosts_controller.rb index 60d24a310c9..f43ff955050 100644 --- a/app/controllers/admin/embeddable_hosts_controller.rb +++ b/app/controllers/admin/embeddable_hosts_controller.rb @@ -1,6 +1,6 @@ class Admin::EmbeddableHostsController < Admin::AdminController - before_filter :ensure_logged_in, :ensure_staff + before_action :ensure_logged_in, :ensure_staff def create save_host(EmbeddableHost.new) diff --git a/app/controllers/admin/embedding_controller.rb b/app/controllers/admin/embedding_controller.rb index 4c5f8548b59..ada7c668b9c 100644 --- a/app/controllers/admin/embedding_controller.rb +++ b/app/controllers/admin/embedding_controller.rb @@ -2,7 +2,7 @@ require_dependency 'embedding' class Admin::EmbeddingController < Admin::AdminController - before_filter :ensure_logged_in, :ensure_staff, :fetch_embedding + before_action :ensure_logged_in, :ensure_staff, :fetch_embedding def show render_serialized(@embedding, EmbeddingSerializer, root: 'embedding', rest_serializer: true) diff --git a/app/controllers/admin/flags_controller.rb b/app/controllers/admin/flags_controller.rb index f986ecd43e7..da4e0425337 100644 --- a/app/controllers/admin/flags_controller.rb +++ b/app/controllers/admin/flags_controller.rb @@ -38,7 +38,7 @@ class Admin::FlagsController < Admin::AdminController PostAction.hide_post!(post, post_action_type) end - render nothing: true + render body: nil end def disagree @@ -49,7 +49,7 @@ class Admin::FlagsController < Admin::AdminController post.unhide! - render nothing: true + render body: nil end def defer @@ -60,7 +60,7 @@ class Admin::FlagsController < Admin::AdminController PostDestroyer.new(current_user, post).destroy if params[:delete_post] - render nothing: true + render body: nil end end diff --git a/app/controllers/admin/groups_controller.rb b/app/controllers/admin/groups_controller.rb index 5f481d3a2fa..8a6a7a72394 100644 --- a/app/controllers/admin/groups_controller.rb +++ b/app/controllers/admin/groups_controller.rb @@ -14,11 +14,11 @@ class Admin::GroupsController < Admin::AdminController end def show - render nothing: true + render body: nil end def bulk - render nothing: true + render body: nil end def bulk_perform diff --git a/app/controllers/admin/impersonate_controller.rb b/app/controllers/admin/impersonate_controller.rb index f57692d923b..1e109521b9b 100644 --- a/app/controllers/admin/impersonate_controller.rb +++ b/app/controllers/admin/impersonate_controller.rb @@ -14,7 +14,7 @@ class Admin::ImpersonateController < Admin::AdminController # Log on as the user log_on_user(user) - render nothing: true + render body: nil end end diff --git a/app/controllers/admin/permalinks_controller.rb b/app/controllers/admin/permalinks_controller.rb index 875110e87a6..b00978f5259 100644 --- a/app/controllers/admin/permalinks_controller.rb +++ b/app/controllers/admin/permalinks_controller.rb @@ -1,6 +1,6 @@ class Admin::PermalinksController < Admin::AdminController - before_filter :fetch_permalink, only: [:destroy] + before_action :fetch_permalink, only: [:destroy] def index url = params[:filter] diff --git a/app/controllers/admin/screened_ip_addresses_controller.rb b/app/controllers/admin/screened_ip_addresses_controller.rb index 1f4bc315657..775f115195f 100644 --- a/app/controllers/admin/screened_ip_addresses_controller.rb +++ b/app/controllers/admin/screened_ip_addresses_controller.rb @@ -2,7 +2,7 @@ require_dependency 'ip_addr' class Admin::ScreenedIpAddressesController < Admin::AdminController - before_filter :fetch_screened_ip_address, only: [:update, :destroy] + before_action :fetch_screened_ip_address, only: [:update, :destroy] def index filter = params[:filter] diff --git a/app/controllers/admin/site_settings_controller.rb b/app/controllers/admin/site_settings_controller.rb index ed64aa2d4bb..4075f45545b 100644 --- a/app/controllers/admin/site_settings_controller.rb +++ b/app/controllers/admin/site_settings_controller.rb @@ -14,7 +14,7 @@ class Admin::SiteSettingsController < Admin::AdminController value.strip! if value.is_a?(String) raise_access_hidden_setting(id) SiteSetting.set_and_log(id, value, current_user) - render nothing: true + render body: nil end private diff --git a/app/controllers/admin/themes_controller.rb b/app/controllers/admin/themes_controller.rb index 4b8a8c58359..eb36ea4ade6 100644 --- a/app/controllers/admin/themes_controller.rb +++ b/app/controllers/admin/themes_controller.rb @@ -2,7 +2,7 @@ require_dependency 'upload_creator' class Admin::ThemesController < Admin::AdminController - skip_before_filter :check_xhr, only: [:show, :preview] + skip_before_action :check_xhr, only: [:show, :preview] def preview @theme = Theme.find(params[:id]) @@ -179,9 +179,10 @@ class Admin::ThemesController < Admin::AdminController def update_default_theme if theme_params.key?(:default) is_default = theme_params[:default] - if @theme.key == SiteSetting.default_theme_key && !is_default + + if @theme.key == SiteSetting.default_theme_key && is_default == "false" Theme.clear_default! - elsif is_default + elsif is_default == "true" @theme.set_default! end end @@ -192,6 +193,7 @@ class Admin::ThemesController < Admin::AdminController begin # deep munge is a train wreck, work around it for now params[:theme][:child_theme_ids] ||= [] if params[:theme].key?(:child_theme_ids) + params.require(:theme).permit( :name, :color_scheme_id, diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index f2f9eca6589..d2533deb2f0 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -4,7 +4,7 @@ require_dependency 'admin_confirmation' class Admin::UsersController < Admin::AdminController - before_filter :fetch_user, only: [:suspend, + before_action :fetch_user, only: [:suspend, :unsuspend, :refresh_browsers, :log_out, @@ -48,7 +48,7 @@ class Admin::UsersController < Admin::AdminController @user = User.find_by(id: params[:user_id]) @user.delete_all_posts!(guardian) # staff action logs will have an entry for each post - render nothing: true + render body: nil end def suspend @@ -59,7 +59,7 @@ class Admin::UsersController < Admin::AdminController @user.revoke_api_key StaffActionLogger.new(current_user).log_user_suspend(@user, params[:reason]) @user.logged_out - render nothing: true + render body: nil end def unsuspend @@ -68,7 +68,7 @@ class Admin::UsersController < Admin::AdminController @user.suspended_at = nil @user.save! StaffActionLogger.new(current_user).log_user_unsuspend(@user) - render nothing: true + render body: nil end def log_out @@ -83,14 +83,14 @@ class Admin::UsersController < Admin::AdminController def refresh_browsers refresh_browser @user - render nothing: true + render body: nil end def revoke_admin guardian.ensure_can_revoke_admin!(@user) @user.revoke_admin! StaffActionLogger.new(current_user).log_revoke_admin(@user) - render nothing: true + render body: nil end def generate_api_key @@ -100,7 +100,7 @@ class Admin::UsersController < Admin::AdminController def revoke_api_key @user.revoke_api_key - render nothing: true + render body: nil end def grant_admin @@ -112,7 +112,7 @@ class Admin::UsersController < Admin::AdminController guardian.ensure_can_revoke_moderation!(@user) @user.revoke_moderation! StaffActionLogger.new(current_user).log_revoke_moderation(@user) - render nothing: true + render body: nil end def grant_moderation @@ -129,7 +129,7 @@ class Admin::UsersController < Admin::AdminController group.add(@user) GroupActionLogger.new(current_user, group).log_add_user_to_group(@user) - render nothing: true + render body: nil end def remove_group @@ -139,7 +139,7 @@ class Admin::UsersController < Admin::AdminController group.remove(@user) GroupActionLogger.new(current_user, group).log_remove_user_from_group(@user) - render nothing: true + render body: nil end def primary_group @@ -158,7 +158,7 @@ class Admin::UsersController < Admin::AdminController @user.save! - render nothing: true + render body: nil end def trust_level @@ -204,20 +204,20 @@ class Admin::UsersController < Admin::AdminController end end - render nothing: true + render body: nil end def approve guardian.ensure_can_approve!(@user) @user.approve(current_user) - render nothing: true + render body: nil end def approve_bulk User.where(id: params[:users]).each do |u| u.approve(current_user) if guardian.can_approve?(u) end - render nothing: true + render body: nil end def activate @@ -234,19 +234,19 @@ class Admin::UsersController < Admin::AdminController @user.deactivate StaffActionLogger.new(current_user).log_user_deactivate(@user, I18n.t('user.deactivated_by_staff')) refresh_browser @user - render nothing: true + render body: nil end def block guardian.ensure_can_block_user! @user UserBlocker.block(@user, current_user, keep_posts: true) - render nothing: true + render body: nil end def unblock guardian.ensure_can_unblock_user! @user UserBlocker.unblock(@user, current_user) - render nothing: true + render body: nil end def reject_bulk @@ -267,7 +267,9 @@ class Admin::UsersController < Admin::AdminController user = User.find_by(id: params[:id].to_i) guardian.ensure_can_delete_user!(user) begin - options = params.slice(:delete_posts, :block_email, :block_urls, :block_ip, :context, :delete_as_spammer) + options = params.slice(:block_email, :block_urls, :block_ip, :context, :delete_as_spammer) + options[:delete_posts] = ActiveModel::Type::Boolean.new.cast(params[:delete_posts]) + if UserDestroyer.new(current_user).destroy(user, options) render json: { deleted: true } else @@ -298,7 +300,7 @@ class Admin::UsersController < Admin::AdminController end def sync_sso - return render nothing: true, status: 404 unless SiteSetting.enable_sso + return render body: nil, status: 404 unless SiteSetting.enable_sso sso = DiscourseSingleSignOn.parse("sso=#{params[:sso]}&sig=#{params[:sig]}") diff --git a/app/controllers/admin/web_hooks_controller.rb b/app/controllers/admin/web_hooks_controller.rb index c3b2cfe9ef0..92ec8019c3d 100644 --- a/app/controllers/admin/web_hooks_controller.rb +++ b/app/controllers/admin/web_hooks_controller.rb @@ -1,5 +1,5 @@ class Admin::WebHooksController < Admin::AdminController - before_filter :fetch_web_hook, only: %i(show update destroy list_events bulk_events ping) + before_action :fetch_web_hook, only: %i(show update destroy list_events bulk_events ping) def index limit = 50 diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index c1b66293e38..dbaa21b76c3 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -37,19 +37,19 @@ class ApplicationController < ActionController::Base end before_action :check_readonly_mode - before_filter :handle_theme - before_filter :set_current_user_for_logs - before_filter :clear_notifications - before_filter :set_locale - before_filter :set_mobile_view - before_filter :block_if_readonly_mode - before_filter :authorize_mini_profiler - before_filter :preload_json - before_filter :redirect_to_login_if_required - before_filter :check_xhr - after_filter :add_readonly_header - after_filter :perform_refresh_session - after_filter :dont_cache_page + before_action :handle_theme + before_action :set_current_user_for_logs + before_action :clear_notifications + before_action :set_locale + before_action :set_mobile_view + before_action :block_if_readonly_mode + before_action :authorize_mini_profiler + before_action :preload_json + before_action :redirect_to_login_if_required + before_action :check_xhr + after_action :add_readonly_header + after_action :perform_refresh_session + after_action :dont_cache_page layout :set_layout @@ -128,8 +128,8 @@ class ApplicationController < ActionController::Base class PluginDisabled < StandardError; end # Handles requests for giant IDs that throw pg exceptions - rescue_from RangeError do |e| - if e.message =~ /ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Integer/ + rescue_from ActiveModel::RangeError do |e| + if e.message =~ /ActiveModel::Type::Integer/ rescue_discourse_actions(:not_found, 404) else raise e @@ -169,7 +169,7 @@ class ApplicationController < ActionController::Base # If a controller requires a plugin, it will raise an exception if that plugin is # disabled. This allows plugins to be disabled programatically. def self.requires_plugin(plugin_name) - before_filter do + before_action do raise PluginDisabled.new if Discourse.disabled_plugin_names.include?(plugin_name) end end diff --git a/app/controllers/badges_controller.rb b/app/controllers/badges_controller.rb index 27a2d909ccc..5d1466ebb7d 100644 --- a/app/controllers/badges_controller.rb +++ b/app/controllers/badges_controller.rb @@ -1,5 +1,5 @@ class BadgesController < ApplicationController - skip_before_filter :check_xhr, only: [:index, :show] + skip_before_action :check_xhr, only: [:index, :show] def index raise Discourse::NotFound unless SiteSetting.enable_badges diff --git a/app/controllers/categories_controller.rb b/app/controllers/categories_controller.rb index 51e8e088528..d9ec6da97d2 100644 --- a/app/controllers/categories_controller.rb +++ b/app/controllers/categories_controller.rb @@ -2,10 +2,10 @@ require_dependency 'category_serializer' class CategoriesController < ApplicationController - before_filter :ensure_logged_in, except: [:index, :categories_and_latest, :show, :redirect, :find_by_slug] - before_filter :fetch_category, only: [:show, :update, :destroy] - before_filter :initialize_staff_action_logger, only: [:create, :update, :destroy] - skip_before_filter :check_xhr, only: [:index, :categories_and_latest, :redirect] + before_action :ensure_logged_in, except: [:index, :categories_and_latest, :show, :redirect, :find_by_slug] + before_action :fetch_category, only: [:show, :update, :destroy] + before_action :initialize_staff_action_logger, only: [:create, :update, :destroy] + skip_before_action :check_xhr, only: [:index, :categories_and_latest, :redirect] def redirect redirect_to path("/c/#{params[:path]}") @@ -107,8 +107,9 @@ class CategoriesController < ApplicationController by_category.each do |cat, pos| cat.position = pos - cat.save if cat.position_changed? + cat.save! if cat.will_save_change_to_position? end + render json: success_json end @@ -154,7 +155,7 @@ class CategoriesController < ApplicationController old_permissions = cat.permissions_params - if result = cat.update_attributes(category_params) + if result = cat.update(category_params) Scheduler::Defer.later "Log staff action change category settings" do @staff_action_logger.log_category_settings_change(@category, category_params, old_permissions) end diff --git a/app/controllers/category_hashtags_controller.rb b/app/controllers/category_hashtags_controller.rb index e779391f374..e0b6f768d7b 100644 --- a/app/controllers/category_hashtags_controller.rb +++ b/app/controllers/category_hashtags_controller.rb @@ -1,5 +1,5 @@ class CategoryHashtagsController < ApplicationController - before_filter :ensure_logged_in + before_action :ensure_logged_in def check category_slugs = params[:category_slugs] diff --git a/app/controllers/clicks_controller.rb b/app/controllers/clicks_controller.rb index 23b1684f2b5..8678966ae57 100644 --- a/app/controllers/clicks_controller.rb +++ b/app/controllers/clicks_controller.rb @@ -1,6 +1,6 @@ class ClicksController < ApplicationController - skip_before_filter :check_xhr, :preload_json + skip_before_action :check_xhr, :preload_json def track raise Discourse::NotFound unless params[:url] @@ -15,7 +15,7 @@ class ClicksController < ApplicationController # Sometimes we want to record a link without a 302. Since XHR has to load the redirected # URL we want it to not return a 302 in those cases. if params[:redirect] == 'false' || @redirect_url.blank? - render nothing: true + render body: nil else redirect_to(@redirect_url) end diff --git a/app/controllers/composer_messages_controller.rb b/app/controllers/composer_messages_controller.rb index 62f86b05835..60bc8a75ba5 100644 --- a/app/controllers/composer_messages_controller.rb +++ b/app/controllers/composer_messages_controller.rb @@ -2,7 +2,7 @@ require_dependency 'composer_messages_finder' class ComposerMessagesController < ApplicationController - before_filter :ensure_logged_in + before_action :ensure_logged_in def index finder = ComposerMessagesFinder.new(current_user, params.slice(:composer_action, :topic_id, :post_id)) diff --git a/app/controllers/directory_items_controller.rb b/app/controllers/directory_items_controller.rb index c4c61c5dfcc..bcaa9372de5 100644 --- a/app/controllers/directory_items_controller.rb +++ b/app/controllers/directory_items_controller.rb @@ -47,7 +47,7 @@ class DirectoryItemsController < ApplicationController result_count = result.count result = result.limit(PAGE_SIZE).offset(PAGE_SIZE * page).to_a - more_params = params.slice(:period, :order, :asc) + more_params = params.slice(:period, :order, :asc).permit! more_params[:page] = page + 1 # Put yourself at the top of the first page diff --git a/app/controllers/draft_controller.rb b/app/controllers/draft_controller.rb index 4e7a0437479..5734a0326a4 100644 --- a/app/controllers/draft_controller.rb +++ b/app/controllers/draft_controller.rb @@ -1,7 +1,7 @@ class DraftController < ApplicationController - before_filter :ensure_logged_in + before_action :ensure_logged_in # TODO really do we need to skip this? - skip_before_filter :check_xhr, :preload_json + skip_before_action :check_xhr, :preload_json def show seq = params[:sequence] || DraftSequence.current(current_user, params[:draft_key]) diff --git a/app/controllers/email_controller.rb b/app/controllers/email_controller.rb index 771e6e1b37a..600e6ceb3a8 100644 --- a/app/controllers/email_controller.rb +++ b/app/controllers/email_controller.rb @@ -1,8 +1,8 @@ class EmailController < ApplicationController - skip_before_filter :check_xhr, :preload_json, :redirect_to_login_if_required + skip_before_action :check_xhr, :preload_json, :redirect_to_login_if_required layout 'no_ember' - before_filter :ensure_logged_in, only: :preferences_redirect + before_action :ensure_logged_in, only: :preferences_redirect def preferences_redirect redirect_to(email_preferences_path(current_user.username_lower)) diff --git a/app/controllers/embed_controller.rb b/app/controllers/embed_controller.rb index d7da707d98d..fff17a578a1 100644 --- a/app/controllers/embed_controller.rb +++ b/app/controllers/embed_controller.rb @@ -1,9 +1,9 @@ class EmbedController < ApplicationController - skip_before_filter :check_xhr, :preload_json, :verify_authenticity_token + skip_before_action :check_xhr, :preload_json, :verify_authenticity_token - before_filter :ensure_embeddable, except: [ :info ] - before_filter :get_embeddable_css_class, except: [ :info ] - before_filter :ensure_api_request, only: [ :info ] + before_action :ensure_embeddable, except: [ :info ] + before_action :get_embeddable_css_class, except: [ :info ] + before_action :ensure_api_request, only: [ :info ] layout 'embed' @@ -46,7 +46,6 @@ class EmbedController < ApplicationController @reply_count = @topic_view.topic.posts_count - 1 @reply_count = 0 if @reply_count < 0 end - elsif embed_url.present? Jobs.enqueue(:retrieve_topic, user_id: current_user.try(:id), diff --git a/app/controllers/exceptions_controller.rb b/app/controllers/exceptions_controller.rb index 929509479a0..33cbad301b1 100644 --- a/app/controllers/exceptions_controller.rb +++ b/app/controllers/exceptions_controller.rb @@ -1,5 +1,5 @@ class ExceptionsController < ApplicationController - skip_before_filter :check_xhr, :preload_json + skip_before_action :check_xhr, :preload_json before_action :hide_google def not_found diff --git a/app/controllers/export_csv_controller.rb b/app/controllers/export_csv_controller.rb index 8f407b92fa3..0053837c008 100644 --- a/app/controllers/export_csv_controller.rb +++ b/app/controllers/export_csv_controller.rb @@ -1,6 +1,6 @@ class ExportCsvController < ApplicationController - skip_before_filter :preload_json, :check_xhr, only: [:show] + skip_before_action :preload_json, :check_xhr, only: [:show] def export_entity guardian.ensure_can_export_entity!(export_params[:entity]) @@ -20,7 +20,7 @@ class ExportCsvController < ApplicationController if export_csv_path && current_user.present? && export_initiated_by_user_id == current_user.id send_file export_csv_path else - render nothing: true, status: 404 + render body: nil, status: 404 end end diff --git a/app/controllers/extra_locales_controller.rb b/app/controllers/extra_locales_controller.rb index a3055b2addd..bc8cf8c4758 100644 --- a/app/controllers/extra_locales_controller.rb +++ b/app/controllers/extra_locales_controller.rb @@ -1,7 +1,7 @@ class ExtraLocalesController < ApplicationController layout :false - skip_before_filter :check_xhr, :preload_json + skip_before_action :check_xhr, :preload_json def show bundle = params[:bundle] @@ -32,6 +32,6 @@ class ExtraLocalesController < ApplicationController JS end - render text: js, content_type: "application/javascript" + render plain: js, content_type: "application/javascript" end end diff --git a/app/controllers/finish_installation_controller.rb b/app/controllers/finish_installation_controller.rb index 4e73594d8a5..848aa127f81 100644 --- a/app/controllers/finish_installation_controller.rb +++ b/app/controllers/finish_installation_controller.rb @@ -1,8 +1,8 @@ class FinishInstallationController < ApplicationController - skip_before_filter :check_xhr, :preload_json, :redirect_to_login_if_required + skip_before_action :check_xhr, :preload_json, :redirect_to_login_if_required layout 'finish_installation' - before_filter :ensure_no_admins, except: ['confirm_email', 'resend_email'] + before_action :ensure_no_admins, except: ['confirm_email', 'resend_email'] def index end diff --git a/app/controllers/forums_controller.rb b/app/controllers/forums_controller.rb index 879fb27da78..00b19366287 100644 --- a/app/controllers/forums_controller.rb +++ b/app/controllers/forums_controller.rb @@ -1,8 +1,8 @@ class ForumsController < ApplicationController - skip_before_filter :preload_json, :check_xhr - skip_before_filter :authorize_mini_profiler, only: [:status] - skip_before_filter :redirect_to_login_if_required, only: [:status] + skip_before_action :preload_json, :check_xhr + skip_before_action :authorize_mini_profiler, only: [:status] + skip_before_action :redirect_to_login_if_required, only: [:status] def status if $shutdown diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index 136c037d9d9..7691f99cab2 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -1,6 +1,6 @@ class GroupsController < ApplicationController - before_filter :ensure_logged_in, only: [ + before_action :ensure_logged_in, only: [ :set_notifications, :mentionable, :messageable, @@ -11,7 +11,7 @@ class GroupsController < ApplicationController :search ] - skip_before_filter :preload_json, :check_xhr, only: [:posts_feed, :mentions_feed] + skip_before_action :preload_json, :check_xhr, only: [:posts_feed, :mentions_feed] def index unless SiteSetting.enable_group_directory? diff --git a/app/controllers/highlight_js_controller.rb b/app/controllers/highlight_js_controller.rb index 19a83c4a766..31ba189e3bc 100644 --- a/app/controllers/highlight_js_controller.rb +++ b/app/controllers/highlight_js_controller.rb @@ -1,5 +1,5 @@ class HighlightJsController < ApplicationController - skip_before_filter :preload_json, :redirect_to_login_if_required, :check_xhr, :verify_authenticity_token, only: [:show] + skip_before_action :preload_json, :redirect_to_login_if_required, :check_xhr, :verify_authenticity_token, only: [:show] def show @@ -22,7 +22,7 @@ class HighlightJsController < ApplicationController response.headers["Content-Length"] = highlight_js.bytesize.to_s immutable_for 1.year - render text: highlight_js, disposition: nil, content_type: 'application/javascript' + render plain: highlight_js, disposition: nil, content_type: 'application/javascript' end end end diff --git a/app/controllers/inline_onebox_controller.rb b/app/controllers/inline_onebox_controller.rb index 67afcf01b24..c7f4e30f75c 100644 --- a/app/controllers/inline_onebox_controller.rb +++ b/app/controllers/inline_onebox_controller.rb @@ -1,10 +1,10 @@ require_dependency 'inline_oneboxer' class InlineOneboxController < ApplicationController - before_filter :ensure_logged_in + before_action :ensure_logged_in def show - oneboxes = InlineOneboxer.new(params[:urls]).process + oneboxes = InlineOneboxer.new(params[:urls] || []).process render json: { "inline-oneboxes" => oneboxes } end end diff --git a/app/controllers/invites_controller.rb b/app/controllers/invites_controller.rb index a892c50cfc4..152e23392f2 100644 --- a/app/controllers/invites_controller.rb +++ b/app/controllers/invites_controller.rb @@ -2,13 +2,13 @@ require_dependency 'rate_limiter' class InvitesController < ApplicationController - skip_before_filter :check_xhr, except: [:perform_accept_invitation] - skip_before_filter :preload_json, except: [:show] - skip_before_filter :redirect_to_login_if_required + skip_before_action :check_xhr, except: [:perform_accept_invitation] + skip_before_action :preload_json, except: [:show] + skip_before_action :redirect_to_login_if_required - before_filter :ensure_logged_in, only: [:destroy, :create, :create_invite_link, :rescind_all_invites, :resend_invite, :resend_all_invites, :upload_csv] - before_filter :ensure_new_registrations_allowed, only: [:show, :perform_accept_invitation] - before_filter :ensure_not_logged_in, only: [:show, :perform_accept_invitation] + before_action :ensure_logged_in, only: [:destroy, :create, :create_invite_link, :rescind_all_invites, :resend_invite, :resend_all_invites, :upload_csv] + before_action :ensure_new_registrations_allowed, only: [:show, :perform_accept_invitation] + before_action :ensure_not_logged_in, only: [:show, :perform_accept_invitation] def show expires_now @@ -122,14 +122,14 @@ class InvitesController < ApplicationController raise Discourse::InvalidParameters.new(:email) if invite.blank? invite.trash!(current_user) - render nothing: true + render body: nil end def rescind_all_invites guardian.ensure_can_rescind_all_invites!(current_user) Invite.rescind_all_invites_from(current_user) - render nothing: true + render body: nil end def resend_invite @@ -139,7 +139,7 @@ class InvitesController < ApplicationController invite = Invite.find_by(invited_by_id: current_user.id, email: params[:email]) raise Discourse::InvalidParameters.new(:email) if invite.blank? invite.resend_invite - render nothing: true + render body: nil rescue RateLimiter::LimitExceeded render_json_error(I18n.t("rate_limiter.slow_down")) @@ -149,7 +149,7 @@ class InvitesController < ApplicationController guardian.ensure_can_resend_all_invites!(current_user) Invite.resend_all_invites_from(current_user.id) - render nothing: true + render body: nil end def upload_csv diff --git a/app/controllers/list_controller.rb b/app/controllers/list_controller.rb index 65635e54293..1a77a589e40 100644 --- a/app/controllers/list_controller.rb +++ b/app/controllers/list_controller.rb @@ -3,9 +3,9 @@ require_dependency 'topic_list_responder' class ListController < ApplicationController include TopicListResponder - skip_before_filter :check_xhr + skip_before_action :check_xhr - before_filter :set_category, only: [ + before_action :set_category, only: [ :category_default, # filtered topics lists Discourse.filters.map { |f| :"category_#{f}" }, @@ -24,7 +24,7 @@ class ListController < ApplicationController :category_feed, ].flatten - before_filter :ensure_logged_in, except: [ + before_action :ensure_logged_in, except: [ :topics_by, # anonymous filters Discourse.anonymous_filters, diff --git a/app/controllers/metadata_controller.rb b/app/controllers/metadata_controller.rb index c297ed18bd7..5785c331762 100644 --- a/app/controllers/metadata_controller.rb +++ b/app/controllers/metadata_controller.rb @@ -1,6 +1,6 @@ class MetadataController < ApplicationController layout false - skip_before_filter :preload_json, :check_xhr, :redirect_to_login_if_required + skip_before_action :preload_json, :check_xhr, :redirect_to_login_if_required def manifest render json: default_manifest.to_json diff --git a/app/controllers/notifications_controller.rb b/app/controllers/notifications_controller.rb index 7f6b95ca535..bedfb6b515f 100644 --- a/app/controllers/notifications_controller.rb +++ b/app/controllers/notifications_controller.rb @@ -2,7 +2,7 @@ require_dependency 'notification_serializer' class NotificationsController < ApplicationController - before_filter :ensure_logged_in + before_action :ensure_logged_in def index user = diff --git a/app/controllers/onebox_controller.rb b/app/controllers/onebox_controller.rb index a8700a59cf1..f3f1fed3b5d 100644 --- a/app/controllers/onebox_controller.rb +++ b/app/controllers/onebox_controller.rb @@ -1,7 +1,7 @@ require_dependency 'oneboxer' class OneboxController < ApplicationController - before_filter :ensure_logged_in + before_action :ensure_logged_in def show params.require(:user_id) @@ -13,7 +13,7 @@ class OneboxController < ApplicationController end # only 1 outgoing preview per user - return render(nothing: true, status: 429) if Oneboxer.is_previewing?(params[:user_id]) + return render(body: nil, status: 429) if Oneboxer.is_previewing?(params[:user_id]) Oneboxer.preview_onebox!(params[:user_id]) @@ -25,7 +25,7 @@ class OneboxController < ApplicationController } if preview.blank? - render nothing: true, status: 404 + render body: nil, status: 404 else render plain: preview end diff --git a/app/controllers/permalinks_controller.rb b/app/controllers/permalinks_controller.rb index 05deaf0d6a7..e88af68f5b0 100644 --- a/app/controllers/permalinks_controller.rb +++ b/app/controllers/permalinks_controller.rb @@ -1,5 +1,5 @@ class PermalinksController < ApplicationController - skip_before_filter :check_xhr, :preload_json + skip_before_action :check_xhr, :preload_json def show url = request.fullpath diff --git a/app/controllers/post_actions_controller.rb b/app/controllers/post_actions_controller.rb index 7bcad95126a..2bf6027ba26 100644 --- a/app/controllers/post_actions_controller.rb +++ b/app/controllers/post_actions_controller.rb @@ -1,9 +1,9 @@ require_dependency 'discourse' class PostActionsController < ApplicationController - before_filter :ensure_logged_in - before_filter :fetch_post_from_params - before_filter :fetch_post_action_type_id_from_params + before_action :ensure_logged_in + before_action :fetch_post_from_params + before_action :fetch_post_action_type_id_from_params def create raise Discourse::NotFound if @post.blank? diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 0549a1cc233..17796b23238 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -8,9 +8,9 @@ require_dependency 'new_post_result_serializer' class PostsController < ApplicationController # Need to be logged in for all actions here - before_filter :ensure_logged_in, except: [:show, :replies, :by_number, :short_link, :reply_history, :revisions, :latest_revision, :expand_embed, :markdown_id, :markdown_num, :cooked, :latest, :user_posts_feed] + before_action :ensure_logged_in, except: [:show, :replies, :by_number, :short_link, :reply_history, :revisions, :latest_revision, :expand_embed, :markdown_id, :markdown_num, :cooked, :latest, :user_posts_feed] - skip_before_filter :preload_json, :check_xhr, only: [:markdown_id, :markdown_num, :short_link, :latest, :user_posts_feed] + skip_before_action :preload_json, :check_xhr, only: [:markdown_id, :markdown_num, :short_link, :latest, :user_posts_feed] def markdown_id markdown Post.find(params[:id].to_i) @@ -239,7 +239,7 @@ class PostsController < ApplicationController destroyer = PostDestroyer.new(current_user, post, context: params[:context]) destroyer.destroy - render nothing: true + render body: nil end def expand_embed @@ -272,7 +272,7 @@ class PostsController < ApplicationController posts.each { |p| PostDestroyer.new(current_user, p).destroy } end - render nothing: true + render body: nil end def merge_posts @@ -280,7 +280,7 @@ class PostsController < ApplicationController posts = Post.where(id: params[:post_ids]).order(:id) raise Discourse::InvalidParameters.new(:post_ids) if posts.pluck(:id) == params[:post_ids] PostMerger.new(current_user, posts).merge - render nothing: true + render body: nil end # Direct replies to this post @@ -312,7 +312,7 @@ class PostsController < ApplicationController post.public_version -= 1 post.save - render nothing: true + render body: nil end def show_revision @@ -325,7 +325,7 @@ class PostsController < ApplicationController post.public_version += 1 post.save - render nothing: true + render body: nil end def revert @@ -365,6 +365,7 @@ class PostsController < ApplicationController post_serializer = PostSerializer.new(post, scope: guardian, root: false) post_serializer.draft_sequence = DraftSequence.current(current_user, topic.draft_key) + link_counts = TopicLink.counts_for(guardian, topic, [post]) post_serializer.single_post_link_counts = link_counts[post.id] if link_counts.present? @@ -401,7 +402,7 @@ class PostsController < ApplicationController post.revise(current_user, wiki: params[:wiki]) - render nothing: true + render body: nil end def post_type @@ -410,7 +411,7 @@ class PostsController < ApplicationController post = find_post_from_params post.revise(current_user, post_type: params[:post_type].to_i) - render nothing: true + render body: nil end def rebake @@ -419,7 +420,7 @@ class PostsController < ApplicationController post = find_post_from_params post.rebake!(invalidate_oneboxes: true) - render nothing: true + render body: nil end def unhide @@ -429,7 +430,7 @@ class PostsController < ApplicationController post.unhide! - render nothing: true + render body: nil end def flagged_posts @@ -624,11 +625,13 @@ class PostsController < ApplicationController result[:target_group_names] = groups.join(",") end - result + result.permit! + result.to_h end def signature_for(args) "post##" << Digest::SHA1.hexdigest(args + .to_h .to_a .concat([["user", current_user.id]]) .sort { |x, y| x[0] <=> y[0] }.join do |x, y| diff --git a/app/controllers/queued_posts_controller.rb b/app/controllers/queued_posts_controller.rb index 55a086f5c6c..52792338c57 100644 --- a/app/controllers/queued_posts_controller.rb +++ b/app/controllers/queued_posts_controller.rb @@ -2,7 +2,7 @@ require_dependency 'queued_post_serializer' class QueuedPostsController < ApplicationController - before_filter :ensure_staff + before_action :ensure_staff def index state = QueuedPost.states[(params[:state] || 'new').to_sym] diff --git a/app/controllers/robots_txt_controller.rb b/app/controllers/robots_txt_controller.rb index 0919c254bd3..4a8600774cc 100644 --- a/app/controllers/robots_txt_controller.rb +++ b/app/controllers/robots_txt_controller.rb @@ -1,6 +1,6 @@ class RobotsTxtController < ApplicationController layout false - skip_before_filter :preload_json, :check_xhr, :redirect_to_login_if_required + skip_before_action :preload_json, :check_xhr, :redirect_to_login_if_required def index path = SiteSetting.allow_index_in_robots_txt ? :index : :no_index diff --git a/app/controllers/safe_mode_controller.rb b/app/controllers/safe_mode_controller.rb index e52161cff20..864d8408f7c 100644 --- a/app/controllers/safe_mode_controller.rb +++ b/app/controllers/safe_mode_controller.rb @@ -1,6 +1,6 @@ class SafeModeController < ApplicationController layout 'no_ember' - skip_before_filter :preload_json, :check_xhr + skip_before_action :preload_json, :check_xhr def index end diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index a07df59f57b..6972bc2dd3f 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -2,7 +2,7 @@ require_dependency 'search' class SearchController < ApplicationController - skip_before_filter :check_xhr, only: :show + skip_before_action :check_xhr, only: :show def self.valid_context_types %w{user topic category private_messages} @@ -77,14 +77,14 @@ class SearchController < ApplicationController params.require(:search_result_id) if params[:search_result_type] == 'topic' - where = { id: params[:search_log_id] } + attributes = { id: params[:search_log_id] } if current_user.present? - where[:user_id] = current_user.id + attributes[:user_id] = current_user.id else - where[:ip_address] = request.remote_ip + attributes[:ip_address] = request.remote_ip end - SearchLog.where(where).update_all( + SearchLog.where(attributes).update_all( clicked_topic_id: params[:search_result_id] ) end diff --git a/app/controllers/session_controller.rb b/app/controllers/session_controller.rb index dfa417f880e..1060c6e0348 100644 --- a/app/controllers/session_controller.rb +++ b/app/controllers/session_controller.rb @@ -4,12 +4,12 @@ require_dependency 'single_sign_on' class SessionController < ApplicationController class LocalLoginNotAllowed < StandardError; end rescue_from LocalLoginNotAllowed do - render nothing: true, status: 500 + render body: nil, status: 500 end - before_filter :check_local_login_allowed, only: %i(create forgot_password) - skip_before_filter :redirect_to_login_if_required - skip_before_filter :preload_json, :check_xhr, only: ['sso', 'sso_login', 'become', 'sso_provider', 'destroy'] + before_action :check_local_login_allowed, only: %i(create forgot_password) + skip_before_action :redirect_to_login_if_required + skip_before_action :preload_json, :check_xhr, only: ['sso', 'sso_login', 'become', 'sso_provider', 'destroy'] ACTIVATE_USER_KEY = "activate_user" @@ -36,7 +36,7 @@ class SessionController < ApplicationController end redirect_to sso.to_url else - render nothing: true, status: 404 + render body: nil, status: 404 end end @@ -67,7 +67,7 @@ class SessionController < ApplicationController redirect_to path('/login') end else - render nothing: true, status: 404 + render body: nil, status: 404 end end @@ -261,7 +261,7 @@ class SessionController < ApplicationController if current_user.present? render_serialized(current_user, CurrentUserSerializer) else - render nothing: true, status: 404 + render body: nil, status: 404 end end @@ -269,7 +269,7 @@ class SessionController < ApplicationController reset_session log_off_user if request.xhr? - render nothing: true + render body: nil else redirect_to (params[:return_url] || path("/")) end @@ -331,8 +331,9 @@ class SessionController < ApplicationController if payload = session.delete(:sso_payload) sso_provider(payload) + else + render_serialized(user, UserSerializer) end - render_serialized(user, UserSerializer) end def render_sso_error(status:, text:) diff --git a/app/controllers/site_controller.rb b/app/controllers/site_controller.rb index 587c9c79345..00ed49e502a 100644 --- a/app/controllers/site_controller.rb +++ b/app/controllers/site_controller.rb @@ -2,8 +2,8 @@ require_dependency 'site_serializer' class SiteController < ApplicationController layout false - skip_before_filter :preload_json, :check_xhr - skip_before_filter :redirect_to_login_if_required, only: ['basic_info', 'statistics'] + skip_before_action :preload_json, :check_xhr + skip_before_action :redirect_to_login_if_required, only: ['basic_info', 'statistics'] def site render json: Site.json_for(guardian) diff --git a/app/controllers/static_controller.rb b/app/controllers/static_controller.rb index b524b0dd8e7..cc04e232778 100644 --- a/app/controllers/static_controller.rb +++ b/app/controllers/static_controller.rb @@ -3,8 +3,8 @@ require_dependency 'file_helper' class StaticController < ApplicationController - skip_before_filter :check_xhr, :redirect_to_login_if_required - skip_before_filter :verify_authenticity_token, only: [:brotli_asset, :cdn_asset, :enter, :favicon] + skip_before_action :check_xhr, :redirect_to_login_if_required + skip_before_action :verify_authenticity_token, only: [:brotli_asset, :cdn_asset, :enter, :favicon] PAGES_WITH_EMAIL_PARAM = ['login', 'password_reset', 'signup'] @@ -121,13 +121,13 @@ class StaticController < ApplicationController if data.bytesize == 0 @@default_favicon ||= File.read(Rails.root + "public/images/default-favicon.png") response.headers["Content-Length"] = @@default_favicon.bytesize.to_s - render text: @@default_favicon, content_type: "image/png" + render plain: @@default_favicon, content_type: "image/png" else immutable_for 1.year response.headers["Expires"] = 1.year.from_now.httpdate response.headers["Content-Length"] = data.bytesize.to_s response.headers["Last-Modified"] = Time.new('2000-01-01').httpdate - render text: data, content_type: "image/png" + render plain: data, content_type: "image/png" end end diff --git a/app/controllers/steps_controller.rb b/app/controllers/steps_controller.rb index c80bdffd2f9..ebfd4b530d4 100644 --- a/app/controllers/steps_controller.rb +++ b/app/controllers/steps_controller.rb @@ -4,9 +4,9 @@ require_dependency 'wizard/step_updater' class StepsController < ApplicationController - before_filter :ensure_wizard_enabled - before_filter :ensure_logged_in - before_filter :ensure_admin + before_action :ensure_wizard_enabled + before_action :ensure_logged_in + before_action :ensure_admin def update wizard = Wizard::Builder.new(current_user).build diff --git a/app/controllers/stylesheets_controller.rb b/app/controllers/stylesheets_controller.rb index d174f28faa6..32b1f8be8e4 100644 --- a/app/controllers/stylesheets_controller.rb +++ b/app/controllers/stylesheets_controller.rb @@ -1,5 +1,5 @@ class StylesheetsController < ApplicationController - skip_before_filter :preload_json, :redirect_to_login_if_required, :check_xhr, :verify_authenticity_token, only: [:show, :show_source_map] + skip_before_action :preload_json, :redirect_to_login_if_required, :check_xhr, :verify_authenticity_token, only: [:show, :show_source_map] def show_source_map show_resource(source_map: true) @@ -56,7 +56,7 @@ class StylesheetsController < ApplicationController end if cache_time && stylesheet_time && stylesheet_time <= cache_time - return render nothing: true, status: 304 + return render body: nil, status: 304 end unless File.exist?(location) diff --git a/app/controllers/tag_groups_controller.rb b/app/controllers/tag_groups_controller.rb index d29d3ba8d7b..b55120954e1 100644 --- a/app/controllers/tag_groups_controller.rb +++ b/app/controllers/tag_groups_controller.rb @@ -1,7 +1,7 @@ class TagGroupsController < ApplicationController - skip_before_filter :check_xhr, only: [:index, :show] - before_filter :ensure_logged_in, except: [:index, :show] - before_filter :fetch_tag_group, only: [:show, :update, :destroy] + skip_before_action :check_xhr, only: [:index, :show] + before_action :ensure_logged_in, except: [:index, :show] + before_action :fetch_tag_group, only: [:show, :update, :destroy] def index tag_groups = TagGroup.order('name ASC').includes(:parent_tag).preload(:tags).all diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb index e65e8494254..75ce09efa7f 100644 --- a/app/controllers/tags_controller.rb +++ b/app/controllers/tags_controller.rb @@ -5,10 +5,10 @@ require_dependency 'topic_query' class TagsController < ::ApplicationController include TopicListResponder - before_filter :ensure_tags_enabled + before_action :ensure_tags_enabled - skip_before_filter :check_xhr, only: [:tag_feed, :show, :index] - before_filter :ensure_logged_in, except: [ + skip_before_action :check_xhr, only: [:tag_feed, :show, :index] + before_action :ensure_logged_in, except: [ :index, :show, :tag_feed, @@ -16,7 +16,7 @@ class TagsController < ::ApplicationController :check_hashtag, Discourse.anonymous_filters.map { |f| :"show_#{f}" } ].flatten - before_filter :set_category_from_params, except: [:index, :update, :destroy, :tag_feed, :search, :notifications, :update_notifications] + before_action :set_category_from_params, except: [:index, :update, :destroy, :tag_feed, :search, :notifications, :update_notifications] def index categories = Category.where("id in (select category_id from category_tags)") @@ -139,9 +139,9 @@ class TagsController < ::ApplicationController json_response = { results: tags } - if Tag.where(name: params[:q]).exists? && !tags.find { |h| h[:id] == t } + if Tag.where(name: params[:q]).exists? && !tags.find { |h| h[:id] == params[:q] } # filter_allowed_tags determined that the tag entered is not allowed - json_response[:forbidden] = t + json_response[:forbidden] = params[:q] end render json: json_response diff --git a/app/controllers/topics_controller.rb b/app/controllers/topics_controller.rb index 15bcbb23362..7a915c9870e 100644 --- a/app/controllers/topics_controller.rb +++ b/app/controllers/topics_controller.rb @@ -6,7 +6,7 @@ require_dependency 'discourse_event' require_dependency 'rate_limiter' class TopicsController < ApplicationController - before_filter :ensure_logged_in, only: [:timings, + before_action :ensure_logged_in, only: [:timings, :destroy_timings, :update, :star, @@ -32,9 +32,9 @@ class TopicsController < ApplicationController :convert_topic, :bookmark] - before_filter :consider_user_for_promotion, only: :show + before_action :consider_user_for_promotion, only: :show - skip_before_filter :check_xhr, only: [:show, :unsubscribe, :feed] + skip_before_action :check_xhr, only: [:show, :unsubscribe, :feed] def id_for_slug topic = Topic.find_by(slug: params[:slug].downcase) @@ -218,7 +218,7 @@ class TopicsController < ApplicationController def destroy_timings PostTiming.destroy_for(current_user.id, [params[:topic_id].to_i]) - render nothing: true + render body: nil end def update @@ -234,6 +234,7 @@ class TopicsController < ApplicationController changes.delete(:category_id) if topic.category_id.to_i == changes[:category_id].to_i success = true + if changes.length > 0 first_post = topic.ordered_posts.first success = PostRevisor.new(first_post, topic).revise!(current_user, changes, validate_post: false) @@ -332,7 +333,7 @@ class TopicsController < ApplicationController topic.make_banner!(current_user) - render nothing: true + render body: nil end def remove_banner @@ -341,7 +342,7 @@ class TopicsController < ApplicationController topic.remove_banner!(current_user) - render nothing: true + render body: nil end def remove_bookmarks @@ -354,7 +355,7 @@ class TopicsController < ApplicationController PostAction.remove_act(current_user, pa.post, PostActionType.types[:bookmark]) end - render nothing: true + render body: nil end def archive_message @@ -396,7 +397,7 @@ class TopicsController < ApplicationController name = Group.find_by(id: group_id).try(:name) render_json_dump(group_name: name) else - render nothing: true + render body: nil end end @@ -408,7 +409,7 @@ class TopicsController < ApplicationController PostAction.act(current_user, first_post, PostActionType.types[:bookmark]) - render nothing: true + render body: nil end def destroy @@ -418,7 +419,7 @@ class TopicsController < ApplicationController first_post = topic.ordered_posts.first PostDestroyer.new(current_user, first_post, context: params[:context]).destroy - render nothing: true + render body: nil end def recover @@ -428,11 +429,11 @@ class TopicsController < ApplicationController first_post = topic.posts.with_deleted.order(:post_number).first PostDestroyer.new(current_user, first_post).recover - render nothing: true + render body: nil end def excerpt - render nothing: true + render body: nil end def remove_allowed_user @@ -573,26 +574,25 @@ class TopicsController < ApplicationController topic = Topic.find_by(id: params[:topic_id].to_i) guardian.ensure_can_see!(topic) topic.clear_pin_for(current_user) - render nothing: true + render body: nil end def re_pin topic = Topic.find_by(id: params[:topic_id].to_i) guardian.ensure_can_see!(topic) topic.re_pin_for(current_user) - render nothing: true + render body: nil end def timings PostTiming.process_timings( current_user, - params[:topic_id].to_i, - params[:topic_time].to_i, - (params[:timings] || {}).map { |post_number, t| [post_number.to_i, t.to_i] }, + topic_params[:topic_id].to_i, + topic_params[:topic_time].to_i, + (topic_params[:timings].to_h || {}).map { |post_number, t| [post_number.to_i, t.to_i] }, mobile: view_context.mobile_view? ) - - render nothing: true + render body: nil end def feed @@ -613,7 +613,10 @@ class TopicsController < ApplicationController raise ActionController::ParameterMissing.new(:topic_ids) end - operation = params.require(:operation).symbolize_keys + operation = params.require(:operation) + operation.permit! + operation = operation.to_h.symbolize_keys + raise ActionController::ParameterMissing.new(:operation_type) if operation[:type].blank? operator = TopicsBulkAction.new(current_user, topic_ids, operation, group: operation[:group]) changed_topic_ids = operator.perform! @@ -622,7 +625,7 @@ class TopicsController < ApplicationController def reset_new current_user.user_stat.update_column(:new_since, Time.now) - render nothing: true + render body: nil end def convert_topic @@ -643,12 +646,20 @@ class TopicsController < ApplicationController private + def topic_params + params.permit( + :topic_id, + :topic_time, + timings: {} + ) + end + def toggle_mute @topic = Topic.find_by(id: params[:topic_id].to_i) guardian.ensure_can_see!(@topic) @topic.toggle_mute(current_user) - render nothing: true + render body: nil end def consider_user_for_promotion diff --git a/app/controllers/uploads_controller.rb b/app/controllers/uploads_controller.rb index da6fd016306..2869beaf123 100644 --- a/app/controllers/uploads_controller.rb +++ b/app/controllers/uploads_controller.rb @@ -2,12 +2,12 @@ require "mini_mime" require_dependency 'upload_creator' class UploadsController < ApplicationController - before_filter :ensure_logged_in, except: [:show] - skip_before_filter :preload_json, :check_xhr, :redirect_to_login_if_required, only: [:show] + before_action :ensure_logged_in, except: [:show] + skip_before_action :preload_json, :check_xhr, :redirect_to_login_if_required, only: [:show] def create # 50 characters ought to be enough for the upload type - type = params.require(:type).parameterize("_")[0..50] + type = params.require(:type).parameterize(separator: "_")[0..50] if type == "avatar" && (SiteSetting.sso_overrides_avatar || !SiteSetting.allow_uploaded_avatars) return render json: failed_json, status: 422 diff --git a/app/controllers/user_api_keys_controller.rb b/app/controllers/user_api_keys_controller.rb index 6fff6655c82..c6d41d2cc30 100644 --- a/app/controllers/user_api_keys_controller.rb +++ b/app/controllers/user_api_keys_controller.rb @@ -2,9 +2,9 @@ class UserApiKeysController < ApplicationController layout 'no_ember' - skip_before_filter :redirect_to_login_if_required, only: [:new] - skip_before_filter :check_xhr, :preload_json - before_filter :ensure_logged_in, only: [:create, :revoke, :undo_revoke] + skip_before_action :redirect_to_login_if_required, only: [:new] + skip_before_action :check_xhr, :preload_json + before_action :ensure_logged_in, only: [:create, :revoke, :undo_revoke] AUTH_API_VERSION ||= 2 diff --git a/app/controllers/user_avatars_controller.rb b/app/controllers/user_avatars_controller.rb index 119266fd357..ee0c08bffc6 100644 --- a/app/controllers/user_avatars_controller.rb +++ b/app/controllers/user_avatars_controller.rb @@ -2,7 +2,7 @@ require_dependency 'letter_avatar' class UserAvatarsController < ApplicationController - skip_before_filter :preload_json, :redirect_to_login_if_required, :check_xhr, :verify_authenticity_token, only: [:show, :show_letter, :show_proxy_letter] + skip_before_action :preload_json, :redirect_to_login_if_required, :check_xhr, :verify_authenticity_token, only: [:show, :show_letter, :show_proxy_letter] def refresh_gravatar user = User.find_by(username_lower: params[:username].downcase) diff --git a/app/controllers/users/omniauth_callbacks_controller.rb b/app/controllers/users/omniauth_callbacks_controller.rb index e9f23ca7173..69270438c2c 100644 --- a/app/controllers/users/omniauth_callbacks_controller.rb +++ b/app/controllers/users/omniauth_callbacks_controller.rb @@ -14,7 +14,7 @@ class Users::OmniauthCallbacksController < ApplicationController Auth::InstagramAuthenticator.new ] - skip_before_filter :redirect_to_login_if_required + skip_before_action :redirect_to_login_if_required layout false @@ -23,11 +23,11 @@ class Users::OmniauthCallbacksController < ApplicationController end # need to be able to call this - skip_before_filter :check_xhr + skip_before_action :check_xhr # this is the only spot where we allow CSRF, our openid / oauth redirect # will not have a CSRF token, however the payload is all validated so its safe - skip_before_filter :verify_authenticity_token, only: :complete + skip_before_action :verify_authenticity_token, only: :complete def complete auth = request.env["omniauth.auth"] diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 6a703c6aae4..f3453c04c83 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -7,19 +7,19 @@ require_dependency 'admin_confirmation' class UsersController < ApplicationController - skip_before_filter :authorize_mini_profiler, only: [:avatar] - skip_before_filter :check_xhr, only: [:show, :password_reset, :update, :account_created, :activate_account, :perform_account_activation, :user_preferences_redirect, :avatar, :my_redirect, :toggle_anon, :admin_login, :confirm_admin] + skip_before_action :authorize_mini_profiler, only: [:avatar] + skip_before_action :check_xhr, only: [:show, :password_reset, :update, :account_created, :activate_account, :perform_account_activation, :user_preferences_redirect, :avatar, :my_redirect, :toggle_anon, :admin_login, :confirm_admin] - before_filter :ensure_logged_in, only: [:username, :update, :user_preferences_redirect, :upload_user_image, + before_action :ensure_logged_in, only: [:username, :update, :user_preferences_redirect, :upload_user_image, :pick_avatar, :destroy_user_image, :destroy, :check_emails, :topic_tracking_state] - before_filter :respond_to_suspicious_request, only: [:create] + before_action :respond_to_suspicious_request, only: [:create] # we need to allow account creation with bad CSRF tokens, if people are caching, the CSRF token on the # page is going to be empty, this means that server will see an invalid CSRF and blow the session # once that happens you can't log in with social - skip_before_filter :verify_authenticity_token, only: [:create] - skip_before_filter :redirect_to_login_if_required, only: [:check_username, + skip_before_action :verify_authenticity_token, only: [:create] + skip_before_action :redirect_to_login_if_required, only: [:check_username, :create, :get_honeypot_value, :account_created, @@ -89,7 +89,7 @@ class UsersController < ApplicationController user.user_profile.update_column(:card_image_badge_id, nil) end - render nothing: true + render body: nil end def user_preferences_redirect @@ -99,9 +99,10 @@ class UsersController < ApplicationController def update user = fetch_user_from_params guardian.ensure_can_edit!(user) + attributes = user_params.merge!(custom_fields: params[:custom_fields]) if params[:user_fields].present? - params[:custom_fields] = {} unless params[:custom_fields].present? + attributes[:custom_fields] = {} unless params[:custom_fields].present? fields = UserField.all fields = fields.where(editable: true) unless current_user.staff? @@ -111,13 +112,13 @@ class UsersController < ApplicationController val = val[0...UserField.max_length] if val return render_json_error(I18n.t("login.missing_user_field")) if val.blank? && f.required? - params[:custom_fields]["user_field_#{f.id}"] = val + attributes[:custom_fields]["user_field_#{f.id}"] = val end end json_result(user, serializer: UserSerializer, additional_errors: [:user_profile]) do |u| updater = UserUpdater.new(current_user, user) - updater.update(params) + updater.update(attributes.permit!) end end @@ -177,11 +178,11 @@ class UsersController < ApplicationController user.save! end - render nothing: true + render body: nil end def preferences - render nothing: true + render body: nil end def my_redirect @@ -345,7 +346,7 @@ class UsersController < ApplicationController authentication = UserAuthenticator.new(user, session) if !authentication.has_authenticator? && !SiteSetting.enable_local_logins - return render nothing: true, status: 500 + return render body: nil, status: 500 end authentication.start @@ -660,7 +661,7 @@ class UsersController < ApplicationController else @email_token = @user.email_tokens.unconfirmed.active.first enqueue_activation_email - render nothing: true + render body: nil end end @@ -848,10 +849,20 @@ class UsersController < ApplicationController end def user_params - result = params.permit(:name, :email, :password, :username, :date_of_birth) - .merge(ip_address: request.remote_ip, - registration_ip_address: request.remote_ip, - locale: user_locale) + result = params.permit( + :name, + :email, + :password, + :username, + :date_of_birth, + :muted_usernames, + :theme_key, + :locale + ).reverse_merge( + ip_address: request.remote_ip, + registration_ip_address: request.remote_ip, + locale: user_locale + ) if !UsernameCheckerService.is_developer?(result['email']) && is_api? && diff --git a/app/controllers/users_email_controller.rb b/app/controllers/users_email_controller.rb index 474e370c781..6e1e2a1f0c7 100644 --- a/app/controllers/users_email_controller.rb +++ b/app/controllers/users_email_controller.rb @@ -4,10 +4,10 @@ require_dependency 'email_updater' class UsersEmailController < ApplicationController - before_filter :ensure_logged_in, only: [:index, :update] + before_action :ensure_logged_in, only: [:index, :update] - skip_before_filter :check_xhr, only: [:confirm] - skip_before_filter :redirect_to_login_if_required, only: [:confirm] + skip_before_action :check_xhr, only: [:confirm] + skip_before_action :redirect_to_login_if_required, only: [:confirm] def index end @@ -26,7 +26,7 @@ class UsersEmailController < ApplicationController return render_json_error(updater.errors.full_messages) end - render nothing: true + render body: nil rescue RateLimiter::LimitExceeded render_json_error(I18n.t("rate_limiter.slow_down")) end diff --git a/app/controllers/webhooks_controller.rb b/app/controllers/webhooks_controller.rb index 07da9d0f2f1..1c56b33dd1f 100644 --- a/app/controllers/webhooks_controller.rb +++ b/app/controllers/webhooks_controller.rb @@ -54,7 +54,7 @@ class WebhooksController < ActionController::Base end end - render nothing: true, status: 200 + render body: nil, status: 200 end def mailjet @@ -71,7 +71,7 @@ class WebhooksController < ActionController::Base end end - render nothing: true, status: 200 + render body: nil, status: 200 end def mandrill @@ -88,7 +88,7 @@ class WebhooksController < ActionController::Base end end - render nothing: true, status: 200 + render body: nil, status: 200 end def sparkpost @@ -114,17 +114,17 @@ class WebhooksController < ActionController::Base end end - render nothing: true, status: 200 + render body: nil, status: 200 end private def mailgun_failure - render nothing: true, status: 406 + render body: nil, status: 406 end def mailgun_success - render nothing: true, status: 200 + render body: nil, status: 200 end def mailgun_verify(timestamp, token, signature) diff --git a/app/controllers/wizard_controller.rb b/app/controllers/wizard_controller.rb index 88edb7af8d4..3c52ee68f31 100644 --- a/app/controllers/wizard_controller.rb +++ b/app/controllers/wizard_controller.rb @@ -2,11 +2,11 @@ require_dependency 'wizard' require_dependency 'wizard/builder' class WizardController < ApplicationController - before_filter :ensure_wizard_enabled, only: [:index] - before_filter :ensure_logged_in, except: [:qunit] - before_filter :ensure_admin, except: [:qunit] + before_action :ensure_wizard_enabled, only: [:index] + before_action :ensure_logged_in, except: [:qunit] + before_action :ensure_admin, except: [:qunit] - skip_before_filter :check_xhr, :preload_json + skip_before_action :check_xhr, :preload_json layout false diff --git a/app/models/api_key.rb b/app/models/api_key.rb index a617902d41f..b3a8a68bf02 100644 --- a/app/models/api_key.rb +++ b/app/models/api_key.rb @@ -1,6 +1,6 @@ class ApiKey < ActiveRecord::Base belongs_to :user - belongs_to :created_by, class_name: User + belongs_to :created_by, class_name: 'User' validates :user_id, uniqueness: true validates_presence_of :key diff --git a/app/models/category.rb b/app/models/category.rb index 3721e2bc9f3..1b9032b8d49 100644 --- a/app/models/category.rb +++ b/app/models/category.rb @@ -32,7 +32,7 @@ class Category < ActiveRecord::Base has_and_belongs_to_many :web_hooks validates :user_id, presence: true - validates :name, if: Proc.new { |c| c.new_record? || c.name_changed? }, + validates :name, if: Proc.new { |c| c.new_record? || c.will_save_change_to_name? }, presence: true, uniqueness: { scope: :parent_category_id, case_sensitive: false }, length: { in: 1..50 } @@ -60,8 +60,8 @@ class Category < ActiveRecord::Base after_create :delete_category_permalink - after_update :rename_category_definition, if: :name_changed? - after_update :create_category_permalink, if: :slug_changed? + after_update :rename_category_definition, if: :saved_change_to_name? + after_update :create_category_permalink, if: :saved_change_to_slug? belongs_to :parent_category, class_name: 'Category' has_many :subcategories, class_name: 'Category', foreign_key: 'parent_category_id' @@ -75,6 +75,7 @@ class Category < ActiveRecord::Base scope :secured, -> (guardian = nil) { ids = guardian.secure_category_ids if guardian + if ids.present? where("NOT categories.read_restricted OR categories.id IN (:cats)", cats: ids).references(:categories) else @@ -456,7 +457,7 @@ SQL # If the name changes, try and update the category definition topic too if it's # an exact match def rename_category_definition - old_name = changed_attributes["name"] + old_name = saved_changes.transform_values(&:first)["name"] return unless topic.present? if topic.title == I18n.t("category.topic_prefix", category: old_name) topic.update_attribute(:title, I18n.t("category.topic_prefix", category: name)) @@ -464,7 +465,7 @@ SQL end def create_category_permalink - old_slug = changed_attributes["slug"] + old_slug = saved_changes.transform_values(&:first)["slug"] if self.parent_category url = "c/#{self.parent_category.slug}/#{old_slug}" else diff --git a/app/models/category_featured_topic.rb b/app/models/category_featured_topic.rb index a5170643743..4b1f92628de 100644 --- a/app/models/category_featured_topic.rb +++ b/app/models/category_featured_topic.rb @@ -40,7 +40,7 @@ class CategoryFeaturedTopic < ActiveRecord::Base return if results == existing CategoryFeaturedTopic.transaction do - CategoryFeaturedTopic.delete_all(category_id: c.id) + CategoryFeaturedTopic.where(category_id: c.id).delete_all if results results.each_with_index do |topic_id, idx| begin diff --git a/app/models/category_featured_user.rb b/app/models/category_featured_user.rb index 73ac6b1516f..638af792135 100644 --- a/app/models/category_featured_user.rb +++ b/app/models/category_featured_user.rb @@ -36,7 +36,8 @@ class CategoryFeaturedUser < ActiveRecord::Base return if current == user_ids transaction do - CategoryFeaturedUser.delete_all category_id: category_id + CategoryFeaturedUser.where(category_id: category_id).delete_all + user_ids.each do |user_id| create(category_id: category_id, user_id: user_id) end diff --git a/app/models/concerns/trashable.rb b/app/models/concerns/trashable.rb index b758df0027e..ffd753a8054 100644 --- a/app/models/concerns/trashable.rb +++ b/app/models/concerns/trashable.rb @@ -16,7 +16,7 @@ module Trashable # scope = self.all - scope.where_values.delete(with_deleted_scope_sql) + scope.where_clause.send(:predicates).delete(with_deleted_scope_sql) scope end diff --git a/app/models/emoji_set_site_setting.rb b/app/models/emoji_set_site_setting.rb index 759b64e9b62..952bd37a0dc 100644 --- a/app/models/emoji_set_site_setting.rb +++ b/app/models/emoji_set_site_setting.rb @@ -7,7 +7,7 @@ class EmojiSetSiteSetting < EnumSiteSetting if site_setting.name.to_s == "emoji_set" && site_setting.value_changed? Emoji.clear_cache - previous_value = site_setting.value_was || SiteSetting.defaults[:emoji_set] + previous_value = site_setting.attribute_in_database(:value) || SiteSetting.defaults[:emoji_set] before = "/images/emoji/#{previous_value}/" after = "/images/emoji/#{site_setting.value}/" diff --git a/app/models/group.rb b/app/models/group.rb index 91b361f5b27..491d9d3daa8 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -30,7 +30,7 @@ class Group < ActiveRecord::Base after_save :update_title after_save :enqueue_update_mentions_job, - if: Proc.new { |g| g.name_was && g.name_changed? } + if: Proc.new { |g| g.name_before_last_save && g.saved_change_to_name? } after_save :expire_cache after_destroy :expire_cache @@ -552,7 +552,7 @@ class Group < ActiveRecord::Base def update_title return if new_record? && !self.title.present? - if self.title_changed? + if self.saved_change_to_title? sql = <<-SQL.squish UPDATE users SET title = :title @@ -561,14 +561,14 @@ class Group < ActiveRecord::Base AND id IN (SELECT user_id FROM group_users WHERE group_id = :id) SQL - self.class.exec_sql(sql, title: title, title_was: title_was, id: id) + self.class.exec_sql(sql, title: title, title_was: title_before_last_save, id: id) end end def update_primary_group return if new_record? && !self.primary_group? - if self.primary_group_changed? + if self.saved_change_to_primary_group? sql = <<~SQL UPDATE users /*set*/ @@ -613,7 +613,7 @@ class Group < ActiveRecord::Base def enqueue_update_mentions_job Jobs.enqueue(:update_group_mentions, - previous_name: self.name_was, + previous_name: self.name_before_last_save, group_id: self.id ) end diff --git a/app/models/notification.rb b/app/models/notification.rb index e238bd1f6ea..1096afc0c85 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -15,10 +15,7 @@ class Notification < ActiveRecord::Base attr_accessor :skip_send_email after_commit :send_email, on: :create - # This is super weird because the tests fail if we don't specify `on: :destroy` - # TODO: Revert back to default in Rails 5 - after_commit :refresh_notification_count, on: :destroy - after_commit :refresh_notification_count, on: [:create, :update] + after_commit :refresh_notification_count, on: [:create, :update, :destroy] def self.ensure_consistency! Notification.exec_sql <<-SQL diff --git a/app/models/post.rb b/app/models/post.rb index 0ddedf7f17e..9d067962601 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -563,7 +563,7 @@ class Post < ActiveRecord::Base before_save do self.last_editor_id ||= user_id - if !new_record? && raw_changed? + if !new_record? && will_save_change_to_raw? self.cooked = cook(raw, topic_id: topic_id) end diff --git a/app/models/post_action.rb b/app/models/post_action.rb index 8c2006c1df6..2ee784f7af0 100644 --- a/app/models/post_action.rb +++ b/app/models/post_action.rb @@ -258,7 +258,6 @@ SQL end def self.act(user, post, post_action_type_id, opts = {}) - limit_action!(user, post, post_action_type_id) related_post_id = create_message_for_post_action(user, post, post_action_type_id, opts) diff --git a/app/models/post_mover.rb b/app/models/post_mover.rb index 96f8f70588c..a2b5540a576 100644 --- a/app/models/post_mover.rb +++ b/app/models/post_mover.rb @@ -79,7 +79,9 @@ class PostMover PostReply.where("reply_id IN (:post_ids) OR post_id IN (:post_ids)", post_ids: post_ids).each do |post_reply| if post_reply.post && post_reply.reply && post_reply.reply.topic_id != post_reply.post.topic_id - PostReply.delete_all(reply_id: post_reply.reply.id, post_id: post_reply.post.id) + PostReply + .where(reply_id: post_reply.reply.id, post_id: post_reply.post.id) + .delete_all end end end diff --git a/app/models/post_timing.rb b/app/models/post_timing.rb index c006d29508e..0e29207dc4d 100644 --- a/app/models/post_timing.rb +++ b/app/models/post_timing.rb @@ -61,8 +61,13 @@ class PostTiming < ActiveRecord::Base def self.destroy_for(user_id, topic_ids) PostTiming.transaction do - PostTiming.delete_all(['user_id = ? and topic_id in (?)', user_id, topic_ids]) - TopicUser.delete_all(['user_id = ? and topic_id in (?)', user_id, topic_ids]) + PostTiming + .where('user_id = ? and topic_id in (?)', user_id, topic_ids) + .delete_all + + TopicUser + .where('user_id = ? and topic_id in (?)', user_id, topic_ids) + .delete_all end end diff --git a/app/models/theme.rb b/app/models/theme.rb index b9bf76c53d6..793c0988883 100644 --- a/app/models/theme.rb +++ b/app/models/theme.rb @@ -28,13 +28,13 @@ class Theme < ActiveRecord::Base changed_fields.each(&:save!) changed_fields.clear - Theme.expire_site_cache! if user_selectable_changed? || name_changed? + Theme.expire_site_cache! if saved_change_to_user_selectable? || saved_change_to_name? @dependant_themes = nil @included_themes = nil remove_from_cache! - notify_scheme_change if color_scheme_id_changed? + notify_scheme_change if saved_change_to_color_scheme_id? end after_destroy do diff --git a/app/models/theme_field.rb b/app/models/theme_field.rb index fdf384660ad..4178ce45d40 100644 --- a/app/models/theme_field.rb +++ b/app/models/theme_field.rb @@ -93,11 +93,13 @@ COMPILED def ensure_baked! if ThemeField.html_fields.include?(self.name) if !self.value_baked || compiler_version != COMPILER_VERSION - self.value_baked, self.error = process_html(self.value) self.compiler_version = COMPILER_VERSION - if self.value_baked_changed? || compiler_version.changed? || self.error_changed? + if self.will_save_change_to_value_baked? || + self.will_save_change_to_compiler_version? || + self.will_save_change_to_error? + self.update_columns(value_baked: value_baked, compiler_version: compiler_version, error: error) @@ -119,7 +121,7 @@ COMPILED self.error = e.message end - if error_changed? + if will_save_change_to_error? update_columns(error: self.error) end @@ -131,7 +133,7 @@ COMPILED end before_save do - if value_changed? && !value_baked_changed? + if will_save_change_to_value? && !will_save_change_to_value_baked? self.value_baked = nil end end diff --git a/app/models/topic.rb b/app/models/topic.rb index 12ee2ea2ae7..8dcd8d9a5ce 100644 --- a/app/models/topic.rb +++ b/app/models/topic.rb @@ -83,7 +83,8 @@ class Topic < ActiveRecord::Base validates :featured_link, allow_nil: true, format: URI::regexp(%w(http https)) validate if: :featured_link do - errors.add(:featured_link, :invalid_category) unless !featured_link_changed? || Guardian.new.can_edit_featured_link?(category_id) + errors.add(:featured_link, :invalid_category) unless !featured_link_changed? || + Guardian.new.can_edit_featured_link?(category_id) end before_validation do @@ -101,8 +102,8 @@ class Topic < ActiveRecord::Base has_many :group_archived_messages, dependent: :destroy has_many :user_archived_messages, dependent: :destroy - has_many :allowed_group_users, through: :allowed_groups, source: :users has_many :allowed_groups, through: :topic_allowed_groups, source: :group + has_many :allowed_group_users, through: :allowed_groups, source: :users has_many :allowed_users, through: :topic_allowed_users, source: :user has_many :queued_posts @@ -125,7 +126,7 @@ class Topic < ActiveRecord::Base has_many :topic_timers, dependent: :destroy has_one :user_warning - has_one :first_post, -> { where post_number: 1 }, class_name: Post + has_one :first_post, -> { where post_number: 1 }, class_name: 'Post' has_one :topic_search_data has_one :topic_embed, dependent: :destroy @@ -196,7 +197,7 @@ class Topic < ActiveRecord::Base after_save do banner = "banner".freeze - if archetype_was == banner || archetype == banner + if archetype_before_last_save == banner || archetype == banner ApplicationController.banner_json_cache.clear end diff --git a/app/models/topic_converter.rb b/app/models/topic_converter.rb index 3ec37b314a5..f46eaba6ce9 100644 --- a/app/models/topic_converter.rb +++ b/app/models/topic_converter.rb @@ -71,7 +71,7 @@ class TopicConverter def watch_topic(topic) @topic.notifier.watch_topic!(topic.user_id) - @topic.topic_allowed_users(true).each do |tau| + @topic.reload.topic_allowed_users.each do |tau| next if tau.user_id < 0 || tau.user_id == topic.user_id topic.notifier.watch!(tau.user_id) end diff --git a/app/models/topic_link.rb b/app/models/topic_link.rb index 633aca2fe7a..274c78437a0 100644 --- a/app/models/topic_link.rb +++ b/app/models/topic_link.rb @@ -214,17 +214,29 @@ SQL # Remove links that aren't there anymore if added_urls.present? - TopicLink.delete_all ["(url not in (:urls)) AND (post_id = :post_id AND NOT reflection)", urls: added_urls, post_id: post.id] + TopicLink.where( + "(url not in (:urls)) AND (post_id = :post_id AND NOT reflection)", + urls: added_urls, post_id: post.id + ).delete_all reflected_ids.compact! if reflected_ids.present? - TopicLink.delete_all ["(id not in (:reflected_ids)) AND (link_post_id = :post_id AND reflection)", - reflected_ids: reflected_ids, post_id: post.id] + TopicLink.where( + "(id not in (:reflected_ids)) AND (link_post_id = :post_id AND reflection)", + reflected_ids: reflected_ids, post_id: post.id + ).delete_all else - TopicLink.delete_all ["link_post_id = :post_id AND reflection", post_id: post.id] + TopicLink + .where("link_post_id = :post_id AND reflection", post_id: post.id) + .delete_all end else - TopicLink.delete_all ["(post_id = :post_id AND NOT reflection) OR (link_post_id = :post_id AND reflection)", post_id: post.id] + TopicLink + .where( + "(post_id = :post_id AND NOT reflection) OR (link_post_id = :post_id AND reflection)", + post_id: post.id + ) + .delete_all end end end diff --git a/app/models/topic_timer.rb b/app/models/topic_timer.rb index 85e7d7769b8..39f882dbafa 100644 --- a/app/models/topic_timer.rb +++ b/app/models/topic_timer.rb @@ -19,13 +19,16 @@ class TopicTimer < ActiveRecord::Base self.created_at ||= Time.zone.now if execute_at self.public_type = self.public_type? - if (execute_at_changed? && !execute_at_was.nil?) || user_id_changed? + if (will_save_change_to_execute_at? && + !attribute_in_database(:execute_at).nil?) || + will_save_change_to_user_id? + self.send("cancel_auto_#{self.class.types[status_type]}_job") end end after_save do - if (execute_at_changed? || user_id_changed?) + if (saved_change_to_execute_at? || saved_change_to_user_id?) now = Time.zone.now time = execute_at < now ? now : execute_at diff --git a/app/models/topic_tracking_state.rb b/app/models/topic_tracking_state.rb index 3c104f4fdb7..a7d48758ba3 100644 --- a/app/models/topic_tracking_state.rb +++ b/app/models/topic_tracking_state.rb @@ -155,7 +155,7 @@ class TopicTrackingState always: User::NewTopicDuration::ALWAYS, default_duration: SiteSetting.default_other_new_topic_duration_minutes, min_date: Time.at(SiteSetting.min_new_topics_time).to_datetime - ).where_values[0] + ).where_clause.send(:predicates)[0] end def self.report(user, topic_id = nil) @@ -185,14 +185,18 @@ class TopicTrackingState if opts && opts[:skip_unread] "1=0" else - TopicQuery.unread_filter(Topic, -999, staff: opts && opts[:staff]).where_values.join(" AND ").sub("-999", ":user_id") + TopicQuery + .unread_filter(Topic, -999, staff: opts && opts[:staff]) + .where_clause.send(:predicates) + .join(" AND ") + .gsub("-999", ":user_id") end new = if opts && opts[:skip_new] "1=0" else - TopicQuery.new_filter(Topic, "xxx").where_values.join(" AND ").gsub!("'xxx'", treat_as_new_topic_clause) + TopicQuery.new_filter(Topic, "xxx").where_clause.send(:predicates).join(" AND ").gsub!("'xxx'", treat_as_new_topic_clause) end select = (opts && opts[:select]) || " diff --git a/app/models/user.rb b/app/models/user.rb index a84a02b0c61..804bee2399f 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -72,15 +72,15 @@ class User < ActiveRecord::Base belongs_to :uploaded_avatar, class_name: 'Upload' - has_many :acting_group_histories, dependent: :destroy, foreign_key: :acting_user_id, class_name: GroupHistory - has_many :targeted_group_histories, dependent: :destroy, foreign_key: :target_user_id, class_name: GroupHistory + has_many :acting_group_histories, dependent: :destroy, foreign_key: :acting_user_id, class_name: 'GroupHistory' + has_many :targeted_group_histories, dependent: :destroy, foreign_key: :target_user_id, class_name: 'GroupHistory' delegate :last_sent_email_address, to: :email_logs validates_presence_of :username - validate :username_validator, if: :username_changed? + validate :username_validator, if: :will_save_change_to_username? validate :password_validator - validates :name, user_full_name: true, if: :name_changed?, length: { maximum: 255 } + validates :name, user_full_name: true, if: :will_save_change_to_name?, length: { maximum: 255 } validates :ip_address, allowed_ip_address: { on: :create, message: :signup_not_allowed } validates :primary_email, presence: true validates_associated :primary_email, message: -> (_, user_email) { user_email[:value]&.errors[:email]&.first } @@ -110,8 +110,8 @@ class User < ActiveRecord::Base before_destroy do # These tables don't have primary keys, so destroying them with activerecord is tricky: - PostTiming.delete_all(user_id: self.id) - TopicViewItem.delete_all(user_id: self.id) + PostTiming.where(user_id: self.id).delete_all + TopicViewItem.where(user_id: self.id).delete_all end # Skip validating email, for example from a particular auth provider plugin @@ -819,7 +819,7 @@ class User < ActiveRecord::Base end # mark all the user's quoted posts as "needing a rebake" - Post.rebake_all_quoted_posts(self.id) if self.uploaded_avatar_id_changed? + Post.rebake_all_quoted_posts(self.id) if self.will_save_change_to_uploaded_avatar_id? end def first_post_created_at @@ -950,7 +950,7 @@ class User < ActiveRecord::Base end def expire_old_email_tokens - if password_hash_changed? && !id_changed? + if saved_change_to_password_hash? && !saved_change_to_id? email_tokens.where('not expired').update_all(expired: true) end end @@ -1023,7 +1023,7 @@ class User < ActiveRecord::Base username_format_validator || begin lower = username.downcase existing = User.find_by(username_lower: lower) - if username_changed? && existing && existing.id != self.id + if will_save_change_to_username? && existing && existing.id != self.id errors.add(:username, I18n.t(:'user.username.unique')) end end diff --git a/app/models/user_badge.rb b/app/models/user_badge.rb index f7b8b55569c..53979ec9cf8 100644 --- a/app/models/user_badge.rb +++ b/app/models/user_badge.rb @@ -5,7 +5,11 @@ class UserBadge < ActiveRecord::Base belongs_to :notification, dependent: :destroy belongs_to :post - validates :badge_id, presence: true, uniqueness: { scope: :user_id }, if: 'badge.single_grant?' + validates :badge_id, + presence: true, + uniqueness: { scope: :user_id }, + if: :single_grant_badge? + validates :user_id, presence: true validates :granted_at, presence: true validates :granted_by, presence: true @@ -19,6 +23,12 @@ class UserBadge < ActiveRecord::Base Badge.decrement_counter 'grant_count', self.badge_id DiscourseEvent.trigger(:user_badge_removed, self.badge_id, self.user_id) end + + private + + def single_grant_badge? + self.badge.single_grant? + end end # == Schema Information diff --git a/app/models/user_option.rb b/app/models/user_option.rb index ee46d5b77e1..cf8d1359971 100644 --- a/app/models/user_option.rb +++ b/app/models/user_option.rb @@ -60,7 +60,7 @@ class UserOption < ActiveRecord::Base end def update_tracked_topics - return unless auto_track_topics_after_msecs_changed? + return unless saved_change_to_auto_track_topics_after_msecs? TrackedTopicsUpdater.new(id, auto_track_topics_after_msecs).call end diff --git a/app/services/color_scheme_revisor.rb b/app/services/color_scheme_revisor.rb index 1fec2875f50..0057dedfa5e 100644 --- a/app/services/color_scheme_revisor.rb +++ b/app/services/color_scheme_revisor.rb @@ -27,7 +27,12 @@ class ColorSchemeRevisor @color_scheme.clear_colors_cache end - @color_scheme.save if has_colors || @color_scheme.name_changed? || @color_scheme.base_scheme_id_changed? + if has_colors || + @color_scheme.saved_change_to_name? || + @color_scheme.saved_change_to_base_scheme_id? + + @color_scheme.save + end end @color_scheme end diff --git a/app/services/post_owner_changer.rb b/app/services/post_owner_changer.rb index 797cc3938d5..f419289faa0 100644 --- a/app/services/post_owner_changer.rb +++ b/app/services/post_owner_changer.rb @@ -26,7 +26,11 @@ class PostOwnerChanger end @topic.update_statistics - @new_owner.user_stat.update(first_post_created_at: @new_owner.posts(true).order('created_at ASC').first.try(:created_at)) + + @new_owner.user_stat.update( + first_post_created_at: @new_owner.reload.posts.order('created_at ASC').first&.created_at + ) + @topic.save! end end diff --git a/app/services/search_indexer.rb b/app/services/search_indexer.rb index b147e890838..2fe7255c76a 100644 --- a/app/services/search_indexer.rb +++ b/app/services/search_indexer.rb @@ -91,7 +91,7 @@ class SearchIndexer def self.index(obj, force: false) return if @disabled - if obj.class == Post && (obj.cooked_changed? || force) + if obj.class == Post && (obj.saved_change_to_cooked? || force) if obj.topic category_name = obj.topic.category.name if obj.topic.category SearchIndexer.update_posts_index(obj.id, obj.cooked, obj.topic.title, category_name) @@ -101,11 +101,11 @@ class SearchIndexer end end - if obj.class == User && (obj.username_changed? || obj.name_changed? || force) + if obj.class == User && (obj.saved_change_to_username? || obj.saved_change_to_name? || force) SearchIndexer.update_users_index(obj.id, obj.username_lower || '', obj.name ? obj.name.downcase : '') end - if obj.class == Topic && (obj.title_changed? || force) + if obj.class == Topic && (obj.saved_change_to_title? || force) if obj.posts post = obj.posts.find_by(post_number: 1) if post @@ -116,11 +116,11 @@ class SearchIndexer end end - if obj.class == Category && (obj.name_changed? || force) + if obj.class == Category && (obj.saved_change_to_name? || force) SearchIndexer.update_categories_index(obj.id, obj.name) end - if obj.class == Tag && (obj.name_changed? || force) + if obj.class == Tag && (obj.saved_change_to_name? || force) SearchIndexer.update_tags_index(obj.id, obj.name) end end diff --git a/app/services/spam_rule/auto_block.rb b/app/services/spam_rule/auto_block.rb index 03bb1bf67c3..bf855bea87e 100644 --- a/app/services/spam_rule/auto_block.rb +++ b/app/services/spam_rule/auto_block.rb @@ -45,7 +45,7 @@ class SpamRule::AutoBlock def num_users_who_flagged_spam_against_user post_ids = Post.where('user_id = ? and spam_count > 0', @user.id).pluck(:id) return 0 if post_ids.empty? - PostAction.spam_flags.where(post_id: post_ids).uniq.pluck(:user_id).size + PostAction.spam_flags.where(post_id: post_ids).pluck(:user_id).uniq.size end def num_tl3_flags_against_user diff --git a/app/views/robots_txt/no_index.erb b/app/views/robots_txt/no_index.erb index 867036ff28a..09e665facdf 100644 --- a/app/views/robots_txt/no_index.erb +++ b/app/views/robots_txt/no_index.erb @@ -1,6 +1,4 @@ # See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file # -User-Agent: * +User-agent: * Disallow: / - - diff --git a/bin/docker/README.md b/bin/docker/README.md old mode 100644 new mode 100755 diff --git a/bin/rails b/bin/rails index 728cd85aa58..07396602377 100755 --- a/bin/rails +++ b/bin/rails @@ -1,4 +1,4 @@ #!/usr/bin/env ruby -APP_PATH = File.expand_path('../../config/application', __FILE__) +APP_PATH = File.expand_path('../config/application', __dir__) require_relative '../config/boot' require 'rails/commands' diff --git a/config/application.rb b/config/application.rb index 95bb82db9f9..e9185f5306b 100644 --- a/config/application.rb +++ b/config/application.rb @@ -134,14 +134,9 @@ module Discourse # Version of your assets, change this if you want to expire all your assets config.assets.version = '1.2.4' - # We need to be able to spin threads - config.active_record.thread_safe! - # see: http://stackoverflow.com/questions/11894180/how-does-one-correctly-add-custom-sql-dml-in-migrations/11894420#11894420 config.active_record.schema_format = :sql - config.active_record.raise_in_transactional_callbacks = true - # per https://www.owasp.org/index.php/Password_Storage_Cheat_Sheet config.pbkdf2_iterations = 64000 config.pbkdf2_algorithm = "sha256" diff --git a/config/initializers/005-site_settings.rb b/config/initializers/005-site_settings.rb index f53f1684648..5be765f6c9e 100644 --- a/config/initializers/005-site_settings.rb +++ b/config/initializers/005-site_settings.rb @@ -24,7 +24,7 @@ reload_settings = lambda { reload_settings.call if !Rails.configuration.cache_classes - ActionDispatch::Reloader.to_prepare do + ActiveSupport::Reloader.to_prepare do reload_settings.call end end diff --git a/config/initializers/099-anon-cache.rb b/config/initializers/099-anon-cache.rb index e0a90c71f17..1b8165511e9 100644 --- a/config/initializers/099-anon-cache.rb +++ b/config/initializers/099-anon-cache.rb @@ -9,5 +9,5 @@ enabled = if !ENV['DISCOURSE_DISABLE_ANON_CACHE'] && enabled # in an ideal world this is position 0, but mobile detection uses ... session and request and params - Rails.configuration.middleware.insert_after ActionDispatch::ParamsParser, Middleware::AnonymousCache + Rails.configuration.middleware.insert_after ActionDispatch::Flash, Middleware::AnonymousCache end diff --git a/config/initializers/100-logster.rb b/config/initializers/100-logster.rb index c7277684c69..c2b96e10c8e 100644 --- a/config/initializers/100-logster.rb +++ b/config/initializers/100-logster.rb @@ -8,11 +8,6 @@ if Rails.env.production? /^ActionController::UnknownFormat/, /^ActionController::UnknownHttpMethod/, /^AbstractController::ActionNotFound/, - - # alihack is really annoying, nothing really we can do about this - # (795: unexpected token at 'alihack<%eval request("alihack.com")%> '): - /^ActionDispatch::ParamsParser::ParseError/, - # ignore any empty JS errors that contain blanks or zeros for line and column fields # # Line: diff --git a/config/initializers/100-quiet_logger.rb b/config/initializers/100-quiet_logger.rb index 908b0c2cfdd..e4106607c27 100644 --- a/config/initializers/100-quiet_logger.rb +++ b/config/initializers/100-quiet_logger.rb @@ -2,9 +2,8 @@ Rails.application.config.assets.configure do |env| env.logger = Logger.new('/dev/null') end -Rails::Rack::Logger.class_eval do - def call_with_quiet_assets(env) - +module DiscourseRackQuietAssetsLogger + def call(env) override = false if (env['PATH_INFO'].index("/assets/") == 0) || (env['PATH_INFO'].index("mini-profiler-resources") == 0) @@ -14,11 +13,12 @@ Rails::Rack::Logger.class_eval do end end - call_without_quiet_assets(env).tap do + super(env).tap do if override Rails.logger.override_level = nil end end end - alias_method_chain :call, :quiet_assets end + +Rails::Rack::Logger.prepend DiscourseRackQuietAssetsLogger diff --git a/db/migrate/20000225050318_add_schema_migration_details.rb b/db/migrate/20000225050318_add_schema_migration_details.rb index dbf4959b173..927b7d1e046 100644 --- a/db/migrate/20000225050318_add_schema_migration_details.rb +++ b/db/migrate/20000225050318_add_schema_migration_details.rb @@ -1,4 +1,4 @@ -class AddSchemaMigrationDetails < ActiveRecord::Migration +class AddSchemaMigrationDetails < ActiveRecord::Migration[4.2] def up # schema_migrations table is way too thin, does not give info about # duration of migration or the date it happened, this migration together with the diff --git a/db/migrate/20120311163914_create_forum_threads.rb b/db/migrate/20120311163914_create_forum_threads.rb index bf379f7367c..a0f4f2c5978 100644 --- a/db/migrate/20120311163914_create_forum_threads.rb +++ b/db/migrate/20120311163914_create_forum_threads.rb @@ -1,4 +1,4 @@ -class CreateForumThreads < ActiveRecord::Migration +class CreateForumThreads < ActiveRecord::Migration[4.2] def change create_table :forum_threads do |t| t.integer :forum_id, null: false diff --git a/db/migrate/20120311164326_create_posts.rb b/db/migrate/20120311164326_create_posts.rb index 5408bb79acf..f67d93f29d1 100644 --- a/db/migrate/20120311164326_create_posts.rb +++ b/db/migrate/20120311164326_create_posts.rb @@ -1,4 +1,4 @@ -class CreatePosts < ActiveRecord::Migration +class CreatePosts < ActiveRecord::Migration[4.2] def change create_table :posts do |t| t.integer :user_id, null: false diff --git a/db/migrate/20120311170118_create_users.rb b/db/migrate/20120311170118_create_users.rb index e2131e679f7..9a1ae7a448f 100644 --- a/db/migrate/20120311170118_create_users.rb +++ b/db/migrate/20120311170118_create_users.rb @@ -1,4 +1,4 @@ -class CreateUsers < ActiveRecord::Migration +class CreateUsers < ActiveRecord::Migration[4.2] def change create_table :users do |t| t.string :username, limit: 20, null: false diff --git a/db/migrate/20120311201341_create_forums.rb b/db/migrate/20120311201341_create_forums.rb index a1a76480c32..ef88af4c105 100644 --- a/db/migrate/20120311201341_create_forums.rb +++ b/db/migrate/20120311201341_create_forums.rb @@ -1,4 +1,4 @@ -class CreateForums < ActiveRecord::Migration +class CreateForums < ActiveRecord::Migration[4.2] def change create_table :forums do |t| t.integer :site_id, null: false diff --git a/db/migrate/20120311210245_create_sites.rb b/db/migrate/20120311210245_create_sites.rb index b16d2b6ddf3..70e8f2c4e60 100644 --- a/db/migrate/20120311210245_create_sites.rb +++ b/db/migrate/20120311210245_create_sites.rb @@ -1,4 +1,4 @@ -class CreateSites < ActiveRecord::Migration +class CreateSites < ActiveRecord::Migration[4.2] def change create_table :sites do |t| t.string :title, limit: 100, null: false diff --git a/db/migrate/20120416201606_add_reply_to_to_posts.rb b/db/migrate/20120416201606_add_reply_to_to_posts.rb index 0bdabad4052..0656d315370 100644 --- a/db/migrate/20120416201606_add_reply_to_to_posts.rb +++ b/db/migrate/20120416201606_add_reply_to_to_posts.rb @@ -1,4 +1,4 @@ -class AddReplyToToPosts < ActiveRecord::Migration +class AddReplyToToPosts < ActiveRecord::Migration[4.2] def change add_column :posts, :reply_to_post_number, :integer, null: true add_index :posts, :reply_to_post_number diff --git a/db/migrate/20120420183447_add_views_to_forum_threads.rb b/db/migrate/20120420183447_add_views_to_forum_threads.rb index 2309cad5938..50757876085 100644 --- a/db/migrate/20120420183447_add_views_to_forum_threads.rb +++ b/db/migrate/20120420183447_add_views_to_forum_threads.rb @@ -1,4 +1,4 @@ -class AddViewsToForumThreads < ActiveRecord::Migration +class AddViewsToForumThreads < ActiveRecord::Migration[4.2] def change add_column :forum_threads, :views, :integer, default: 0, null: false end diff --git a/db/migrate/20120423140906_add_posts_count_to_forum_threads.rb b/db/migrate/20120423140906_add_posts_count_to_forum_threads.rb index 6f319e75010..832f66a3076 100644 --- a/db/migrate/20120423140906_add_posts_count_to_forum_threads.rb +++ b/db/migrate/20120423140906_add_posts_count_to_forum_threads.rb @@ -1,4 +1,4 @@ -class AddPostsCountToForumThreads < ActiveRecord::Migration +class AddPostsCountToForumThreads < ActiveRecord::Migration[4.2] def change add_column :forum_threads, :posts_count, :integer, default: 0, null: false diff --git a/db/migrate/20120423142820_fix_post_indices.rb b/db/migrate/20120423142820_fix_post_indices.rb index 571db8f8ecc..0e99e03e161 100644 --- a/db/migrate/20120423142820_fix_post_indices.rb +++ b/db/migrate/20120423142820_fix_post_indices.rb @@ -1,4 +1,4 @@ -class FixPostIndices < ActiveRecord::Migration +class FixPostIndices < ActiveRecord::Migration[4.2] def up remove_index :posts, [:forum_thread_id, :created_at] add_index :posts, [:forum_thread_id, :post_number] diff --git a/db/migrate/20120423151548_remove_last_post_id.rb b/db/migrate/20120423151548_remove_last_post_id.rb index f9ec56229c0..fd3f1b292b6 100644 --- a/db/migrate/20120423151548_remove_last_post_id.rb +++ b/db/migrate/20120423151548_remove_last_post_id.rb @@ -1,4 +1,4 @@ -class RemoveLastPostId < ActiveRecord::Migration +class RemoveLastPostId < ActiveRecord::Migration[4.2] def up remove_column :forum_threads, :last_post_id end diff --git a/db/migrate/20120425145456_add_display_username_to_users.rb b/db/migrate/20120425145456_add_display_username_to_users.rb index 9ef10657bd4..43df8bdf6a6 100644 --- a/db/migrate/20120425145456_add_display_username_to_users.rb +++ b/db/migrate/20120425145456_add_display_username_to_users.rb @@ -1,4 +1,4 @@ -class AddDisplayUsernameToUsers < ActiveRecord::Migration +class AddDisplayUsernameToUsers < ActiveRecord::Migration[4.2] def up add_column :users, :display_username, :string execute "UPDATE users SET display_username = username" diff --git a/db/migrate/20120427150624_add_user_id_index_to_posts.rb b/db/migrate/20120427150624_add_user_id_index_to_posts.rb index 78f8ac68f6d..8da0ee50fe3 100644 --- a/db/migrate/20120427150624_add_user_id_index_to_posts.rb +++ b/db/migrate/20120427150624_add_user_id_index_to_posts.rb @@ -1,4 +1,4 @@ -class AddUserIdIndexToPosts < ActiveRecord::Migration +class AddUserIdIndexToPosts < ActiveRecord::Migration[4.2] def change add_index :posts, :user_id end diff --git a/db/migrate/20120427151452_cooked_migration.rb b/db/migrate/20120427151452_cooked_migration.rb index d027fe8ff21..9b8ca2d8e86 100644 --- a/db/migrate/20120427151452_cooked_migration.rb +++ b/db/migrate/20120427151452_cooked_migration.rb @@ -1,4 +1,4 @@ -class CookedMigration < ActiveRecord::Migration +class CookedMigration < ActiveRecord::Migration[4.2] def change rename_column :posts, :content, :raw rename_column :posts, :formatted_content, :cooked diff --git a/db/migrate/20120427154330_create_vestal_versions.rb b/db/migrate/20120427154330_create_vestal_versions.rb index 4249254f930..730c275c1f1 100644 --- a/db/migrate/20120427154330_create_vestal_versions.rb +++ b/db/migrate/20120427154330_create_vestal_versions.rb @@ -1,4 +1,4 @@ -class CreateVestalVersions < ActiveRecord::Migration +class CreateVestalVersions < ActiveRecord::Migration[4.2] def self.up create_table :versions do |t| t.belongs_to :versioned, polymorphic: true diff --git a/db/migrate/20120427172031_add_version_to_posts.rb b/db/migrate/20120427172031_add_version_to_posts.rb index 408dc293c42..6ff53461a42 100644 --- a/db/migrate/20120427172031_add_version_to_posts.rb +++ b/db/migrate/20120427172031_add_version_to_posts.rb @@ -1,4 +1,4 @@ -class AddVersionToPosts < ActiveRecord::Migration +class AddVersionToPosts < ActiveRecord::Migration[4.2] def change add_column :posts, :cached_version, :integer, null: false, default: 1 end diff --git a/db/migrate/20120502183240_add_created_by_to_forum_threads.rb b/db/migrate/20120502183240_add_created_by_to_forum_threads.rb index b9dd947e91f..0eca6e0908f 100644 --- a/db/migrate/20120502183240_add_created_by_to_forum_threads.rb +++ b/db/migrate/20120502183240_add_created_by_to_forum_threads.rb @@ -1,4 +1,4 @@ -class AddCreatedByToForumThreads < ActiveRecord::Migration +class AddCreatedByToForumThreads < ActiveRecord::Migration[4.2] def up add_column :forum_threads, :user_id, :integer diff --git a/db/migrate/20120502192121_add_last_post_user_id_to_forum_threads.rb b/db/migrate/20120502192121_add_last_post_user_id_to_forum_threads.rb index 28e3371745c..aafa179b823 100644 --- a/db/migrate/20120502192121_add_last_post_user_id_to_forum_threads.rb +++ b/db/migrate/20120502192121_add_last_post_user_id_to_forum_threads.rb @@ -1,4 +1,4 @@ -class AddLastPostUserIdToForumThreads < ActiveRecord::Migration +class AddLastPostUserIdToForumThreads < ActiveRecord::Migration[4.2] def up add_column :forum_threads, :last_post_user_id, :integer diff --git a/db/migrate/20120503205521_add_site_id_to_users.rb b/db/migrate/20120503205521_add_site_id_to_users.rb index 9b1121eee7b..2057bc809a1 100644 --- a/db/migrate/20120503205521_add_site_id_to_users.rb +++ b/db/migrate/20120503205521_add_site_id_to_users.rb @@ -1,4 +1,4 @@ -class AddSiteIdToUsers < ActiveRecord::Migration +class AddSiteIdToUsers < ActiveRecord::Migration[4.2] def change add_column :users, :site_id, :integer add_column :users, :bio, :text diff --git a/db/migrate/20120507144132_create_expressions.rb b/db/migrate/20120507144132_create_expressions.rb index 7dde3ad29d2..5daf04026fb 100644 --- a/db/migrate/20120507144132_create_expressions.rb +++ b/db/migrate/20120507144132_create_expressions.rb @@ -1,4 +1,4 @@ -class CreateExpressions < ActiveRecord::Migration +class CreateExpressions < ActiveRecord::Migration[4.2] def change create_table :expressions, id: false, force: true do |t| t.integer :parent_id, null: false diff --git a/db/migrate/20120507144222_create_expression_types.rb b/db/migrate/20120507144222_create_expression_types.rb index 68efefb4b8c..a536a0da51f 100644 --- a/db/migrate/20120507144222_create_expression_types.rb +++ b/db/migrate/20120507144222_create_expression_types.rb @@ -1,4 +1,4 @@ -class CreateExpressionTypes < ActiveRecord::Migration +class CreateExpressionTypes < ActiveRecord::Migration[4.2] def change create_table :expression_types do |t| t.integer :site_id, null: false diff --git a/db/migrate/20120514144549_add_reply_count_to_posts.rb b/db/migrate/20120514144549_add_reply_count_to_posts.rb index 31c7cf9e1a9..4be691b2340 100644 --- a/db/migrate/20120514144549_add_reply_count_to_posts.rb +++ b/db/migrate/20120514144549_add_reply_count_to_posts.rb @@ -1,4 +1,4 @@ -class AddReplyCountToPosts < ActiveRecord::Migration +class AddReplyCountToPosts < ActiveRecord::Migration[4.2] def up add_column :posts, :reply_count, :integer, null: false, default: 0 diff --git a/db/migrate/20120514173920_add_flag_to_expression_types.rb b/db/migrate/20120514173920_add_flag_to_expression_types.rb index 4251f61d24a..b5f15bf458f 100644 --- a/db/migrate/20120514173920_add_flag_to_expression_types.rb +++ b/db/migrate/20120514173920_add_flag_to_expression_types.rb @@ -1,4 +1,4 @@ -class AddFlagToExpressionTypes < ActiveRecord::Migration +class AddFlagToExpressionTypes < ActiveRecord::Migration[4.2] def change add_column :expression_types, :flag, :boolean, default: false end diff --git a/db/migrate/20120514204934_add_description_to_expression_types.rb b/db/migrate/20120514204934_add_description_to_expression_types.rb index fcb697ab9ba..8e4cc982716 100644 --- a/db/migrate/20120514204934_add_description_to_expression_types.rb +++ b/db/migrate/20120514204934_add_description_to_expression_types.rb @@ -1,4 +1,4 @@ -class AddDescriptionToExpressionTypes < ActiveRecord::Migration +class AddDescriptionToExpressionTypes < ActiveRecord::Migration[4.2] def change add_column :expression_types, :description, :text, null: true end diff --git a/db/migrate/20120517200130_add_quoteless_to_post.rb b/db/migrate/20120517200130_add_quoteless_to_post.rb index 5b3ba541fd5..116f67eabac 100644 --- a/db/migrate/20120517200130_add_quoteless_to_post.rb +++ b/db/migrate/20120517200130_add_quoteless_to_post.rb @@ -1,4 +1,4 @@ -class AddQuotelessToPost < ActiveRecord::Migration +class AddQuotelessToPost < ActiveRecord::Migration[4.2] def change add_column :posts, :quoteless, :boolean, default: false end diff --git a/db/migrate/20120518200115_create_read_posts.rb b/db/migrate/20120518200115_create_read_posts.rb index dde7280896d..d1cc7b99ff9 100644 --- a/db/migrate/20120518200115_create_read_posts.rb +++ b/db/migrate/20120518200115_create_read_posts.rb @@ -1,4 +1,4 @@ -class CreateReadPosts < ActiveRecord::Migration +class CreateReadPosts < ActiveRecord::Migration[4.2] def up create_table :read_posts, id: false do |t| t.integer :forum_thread_id, null: false diff --git a/db/migrate/20120519182212_create_last_read_posts.rb b/db/migrate/20120519182212_create_last_read_posts.rb index 6bbb21fc2e3..7c90498a5b3 100644 --- a/db/migrate/20120519182212_create_last_read_posts.rb +++ b/db/migrate/20120519182212_create_last_read_posts.rb @@ -1,4 +1,4 @@ -class CreateLastReadPosts < ActiveRecord::Migration +class CreateLastReadPosts < ActiveRecord::Migration[4.2] def change create_table :last_read_posts do |t| t.integer :user_id, null: false diff --git a/db/migrate/20120523180723_create_views.rb b/db/migrate/20120523180723_create_views.rb index 68638ef5063..aa201b3dd31 100644 --- a/db/migrate/20120523180723_create_views.rb +++ b/db/migrate/20120523180723_create_views.rb @@ -1,4 +1,4 @@ -class CreateViews < ActiveRecord::Migration +class CreateViews < ActiveRecord::Migration[4.2] def change create_table :views, id: false do |t| t.integer :parent_id, null: false diff --git a/db/migrate/20120523184307_add_replies_to_forum_threads.rb b/db/migrate/20120523184307_add_replies_to_forum_threads.rb index a8648b7e3e3..fd5870417c0 100644 --- a/db/migrate/20120523184307_add_replies_to_forum_threads.rb +++ b/db/migrate/20120523184307_add_replies_to_forum_threads.rb @@ -1,4 +1,4 @@ -class AddRepliesToForumThreads < ActiveRecord::Migration +class AddRepliesToForumThreads < ActiveRecord::Migration[4.2] def change add_column :forum_threads, :reply_count, :integer, default: 0, null: false diff --git a/db/migrate/20120523201329_add_featured_to_forum_threads.rb b/db/migrate/20120523201329_add_featured_to_forum_threads.rb index d9568d795aa..ef47cb07e49 100644 --- a/db/migrate/20120523201329_add_featured_to_forum_threads.rb +++ b/db/migrate/20120523201329_add_featured_to_forum_threads.rb @@ -1,4 +1,4 @@ -class AddFeaturedToForumThreads < ActiveRecord::Migration +class AddFeaturedToForumThreads < ActiveRecord::Migration[4.2] def up add_column :forum_threads, :featured_user1_id, :integer, null: true add_column :forum_threads, :featured_user2_id, :integer, null: true diff --git a/db/migrate/20120525194845_add_avg_time_to_forum_threads.rb b/db/migrate/20120525194845_add_avg_time_to_forum_threads.rb index aa364962f39..08f3bc7f371 100644 --- a/db/migrate/20120525194845_add_avg_time_to_forum_threads.rb +++ b/db/migrate/20120525194845_add_avg_time_to_forum_threads.rb @@ -1,4 +1,4 @@ -class AddAvgTimeToForumThreads < ActiveRecord::Migration +class AddAvgTimeToForumThreads < ActiveRecord::Migration[4.2] def up add_column :forum_threads, :avg_time, :integer diff --git a/db/migrate/20120529175956_create_uploads.rb b/db/migrate/20120529175956_create_uploads.rb index 2a5ddc36a0e..9d6c355dd03 100644 --- a/db/migrate/20120529175956_create_uploads.rb +++ b/db/migrate/20120529175956_create_uploads.rb @@ -1,4 +1,4 @@ -class CreateUploads < ActiveRecord::Migration +class CreateUploads < ActiveRecord::Migration[4.2] def change create_table :uploads do |t| t.integer :user_id, null: false diff --git a/db/migrate/20120529202707_create_stars.rb b/db/migrate/20120529202707_create_stars.rb index 8c5133c326e..75e75888379 100644 --- a/db/migrate/20120529202707_create_stars.rb +++ b/db/migrate/20120529202707_create_stars.rb @@ -1,4 +1,4 @@ -class CreateStars < ActiveRecord::Migration +class CreateStars < ActiveRecord::Migration[4.2] def change create_table :stars, id: false do |t| t.integer :parent_id, null: false diff --git a/db/migrate/20120530150726_create_forum_thread_user.rb b/db/migrate/20120530150726_create_forum_thread_user.rb index e74e053641d..272e96d5647 100644 --- a/db/migrate/20120530150726_create_forum_thread_user.rb +++ b/db/migrate/20120530150726_create_forum_thread_user.rb @@ -1,4 +1,4 @@ -class CreateForumThreadUser < ActiveRecord::Migration +class CreateForumThreadUser < ActiveRecord::Migration[4.2] def up create_table :forum_thread_users, id: false do |t| t.integer :user_id, null: false diff --git a/db/migrate/20120530160745_migrate_posted.rb b/db/migrate/20120530160745_migrate_posted.rb index e72528b465d..599c8810e4a 100644 --- a/db/migrate/20120530160745_migrate_posted.rb +++ b/db/migrate/20120530160745_migrate_posted.rb @@ -1,4 +1,4 @@ -class MigratePosted < ActiveRecord::Migration +class MigratePosted < ActiveRecord::Migration[4.2] def up end diff --git a/db/migrate/20120530200724_add_index_to_forum_threads.rb b/db/migrate/20120530200724_add_index_to_forum_threads.rb index cfe14bff143..35045d19517 100644 --- a/db/migrate/20120530200724_add_index_to_forum_threads.rb +++ b/db/migrate/20120530200724_add_index_to_forum_threads.rb @@ -1,4 +1,4 @@ -class AddIndexToForumThreads < ActiveRecord::Migration +class AddIndexToForumThreads < ActiveRecord::Migration[4.2] def change add_index :forum_threads, :last_posted_at end diff --git a/db/migrate/20120530212912_create_forum_thread_links.rb b/db/migrate/20120530212912_create_forum_thread_links.rb index 7e137206fa2..f43cbf9f2d0 100644 --- a/db/migrate/20120530212912_create_forum_thread_links.rb +++ b/db/migrate/20120530212912_create_forum_thread_links.rb @@ -1,4 +1,4 @@ -class CreateForumThreadLinks < ActiveRecord::Migration +class CreateForumThreadLinks < ActiveRecord::Migration[4.2] def change create_table :forum_thread_links do |t| t.integer :forum_thread_id, null: false diff --git a/db/migrate/20120614190726_add_tags_to_forum_threads.rb b/db/migrate/20120614190726_add_tags_to_forum_threads.rb index c65eaf3c32c..042f32b92ac 100644 --- a/db/migrate/20120614190726_add_tags_to_forum_threads.rb +++ b/db/migrate/20120614190726_add_tags_to_forum_threads.rb @@ -1,4 +1,4 @@ -class AddTagsToForumThreads < ActiveRecord::Migration +class AddTagsToForumThreads < ActiveRecord::Migration[4.2] def change add_column :forum_threads, :tag, :string, null: true, limit: 25 end diff --git a/db/migrate/20120614202024_add_quote_count_to_posts.rb b/db/migrate/20120614202024_add_quote_count_to_posts.rb index 46994edb69c..373e800789f 100644 --- a/db/migrate/20120614202024_add_quote_count_to_posts.rb +++ b/db/migrate/20120614202024_add_quote_count_to_posts.rb @@ -1,4 +1,4 @@ -class AddQuoteCountToPosts < ActiveRecord::Migration +class AddQuoteCountToPosts < ActiveRecord::Migration[4.2] def up add_column :posts, :quote_count, :integer, default: 0, null: false execute "UPDATE posts SET quote_count = 1 WHERE quoteless = 'f'" diff --git a/db/migrate/20120615180517_create_bookmarks.rb b/db/migrate/20120615180517_create_bookmarks.rb index a1c9c28d007..b8b1f66e4ba 100644 --- a/db/migrate/20120615180517_create_bookmarks.rb +++ b/db/migrate/20120615180517_create_bookmarks.rb @@ -1,4 +1,4 @@ -class CreateBookmarks < ActiveRecord::Migration +class CreateBookmarks < ActiveRecord::Migration[4.2] def change create_table :bookmarks do |t| t.integer :user_id diff --git a/db/migrate/20120618152946_add_reply_below_to_posts.rb b/db/migrate/20120618152946_add_reply_below_to_posts.rb index 99c23a87d98..33fcc006836 100644 --- a/db/migrate/20120618152946_add_reply_below_to_posts.rb +++ b/db/migrate/20120618152946_add_reply_below_to_posts.rb @@ -1,4 +1,4 @@ -class AddReplyBelowToPosts < ActiveRecord::Migration +class AddReplyBelowToPosts < ActiveRecord::Migration[4.2] def change add_column :posts, :reply_below_post_number, :integer, null: true end diff --git a/db/migrate/20120618212349_create_post_timings.rb b/db/migrate/20120618212349_create_post_timings.rb index b795ca902c3..4cfbf9d4aed 100644 --- a/db/migrate/20120618212349_create_post_timings.rb +++ b/db/migrate/20120618212349_create_post_timings.rb @@ -1,4 +1,4 @@ -class CreatePostTimings < ActiveRecord::Migration +class CreatePostTimings < ActiveRecord::Migration[4.2] def change create_table :post_timings do |t| t.integer :thread_id, null: false diff --git a/db/migrate/20120618214856_create_message_bus.rb b/db/migrate/20120618214856_create_message_bus.rb index f2d81c6d20d..a81441d5ad5 100644 --- a/db/migrate/20120618214856_create_message_bus.rb +++ b/db/migrate/20120618214856_create_message_bus.rb @@ -1,4 +1,4 @@ -class CreateMessageBus < ActiveRecord::Migration +class CreateMessageBus < ActiveRecord::Migration[4.2] def change create_table :message_bus do |t| t.string :name diff --git a/db/migrate/20120619150807_fix_post_timings.rb b/db/migrate/20120619150807_fix_post_timings.rb index 1d06d8f6d89..4e6fd051ebf 100644 --- a/db/migrate/20120619150807_fix_post_timings.rb +++ b/db/migrate/20120619150807_fix_post_timings.rb @@ -1,4 +1,4 @@ -class FixPostTimings < ActiveRecord::Migration +class FixPostTimings < ActiveRecord::Migration[4.2] def up remove_index :post_timings, [:thread_id, :post_number] remove_index :post_timings, [:thread_id, :post_number, :user_id] diff --git a/db/migrate/20120619153349_drop_read_posts.rb b/db/migrate/20120619153349_drop_read_posts.rb index f23dc488e93..89b74727513 100644 --- a/db/migrate/20120619153349_drop_read_posts.rb +++ b/db/migrate/20120619153349_drop_read_posts.rb @@ -1,4 +1,4 @@ -class DropReadPosts < ActiveRecord::Migration +class DropReadPosts < ActiveRecord::Migration[4.2] def up drop_table :read_posts end diff --git a/db/migrate/20120619172714_add_post_number_to_bookmarks.rb b/db/migrate/20120619172714_add_post_number_to_bookmarks.rb index 3d997ed2bc3..7a21dda8ad5 100644 --- a/db/migrate/20120619172714_add_post_number_to_bookmarks.rb +++ b/db/migrate/20120619172714_add_post_number_to_bookmarks.rb @@ -1,4 +1,4 @@ -class AddPostNumberToBookmarks < ActiveRecord::Migration +class AddPostNumberToBookmarks < ActiveRecord::Migration[4.2] def change drop_table :bookmarks diff --git a/db/migrate/20120621155351_add_seen_post_count_to_forum_thread_users.rb b/db/migrate/20120621155351_add_seen_post_count_to_forum_thread_users.rb index eff20e632e2..20199118cba 100644 --- a/db/migrate/20120621155351_add_seen_post_count_to_forum_thread_users.rb +++ b/db/migrate/20120621155351_add_seen_post_count_to_forum_thread_users.rb @@ -1,4 +1,4 @@ -class AddSeenPostCountToForumThreadUsers < ActiveRecord::Migration +class AddSeenPostCountToForumThreadUsers < ActiveRecord::Migration[4.2] def change remove_column :post_timings, :id remove_column :forum_thread_users, :created_at diff --git a/db/migrate/20120621190310_add_deleted_at_to_forum_threads.rb b/db/migrate/20120621190310_add_deleted_at_to_forum_threads.rb index 2aeb019f5ae..0d4b9c063b3 100644 --- a/db/migrate/20120621190310_add_deleted_at_to_forum_threads.rb +++ b/db/migrate/20120621190310_add_deleted_at_to_forum_threads.rb @@ -1,4 +1,4 @@ -class AddDeletedAtToForumThreads < ActiveRecord::Migration +class AddDeletedAtToForumThreads < ActiveRecord::Migration[4.2] def change add_column :forum_threads, :deleted_at, :datetime end diff --git a/db/migrate/20120622200242_create_notifications.rb b/db/migrate/20120622200242_create_notifications.rb index 51813b931ac..116b111974b 100644 --- a/db/migrate/20120622200242_create_notifications.rb +++ b/db/migrate/20120622200242_create_notifications.rb @@ -1,4 +1,4 @@ -class CreateNotifications < ActiveRecord::Migration +class CreateNotifications < ActiveRecord::Migration[4.2] def change create_table :notifications do |t| t.integer :notification_type, null: false diff --git a/db/migrate/20120625145714_add_seen_notification_id_to_users.rb b/db/migrate/20120625145714_add_seen_notification_id_to_users.rb index 920f136d3ec..c14c7f40c9a 100644 --- a/db/migrate/20120625145714_add_seen_notification_id_to_users.rb +++ b/db/migrate/20120625145714_add_seen_notification_id_to_users.rb @@ -1,4 +1,4 @@ -class AddSeenNotificationIdToUsers < ActiveRecord::Migration +class AddSeenNotificationIdToUsers < ActiveRecord::Migration[4.2] def change execute "TRUNCATE TABLE notifications" diff --git a/db/migrate/20120625162318_add_deleted_at_to_posts.rb b/db/migrate/20120625162318_add_deleted_at_to_posts.rb index ff9b313f5f3..55efd8b5bb4 100644 --- a/db/migrate/20120625162318_add_deleted_at_to_posts.rb +++ b/db/migrate/20120625162318_add_deleted_at_to_posts.rb @@ -1,4 +1,4 @@ -class AddDeletedAtToPosts < ActiveRecord::Migration +class AddDeletedAtToPosts < ActiveRecord::Migration[4.2] def change add_column :posts, :deleted_at, :datetime end diff --git a/db/migrate/20120625174544_add_highest_post_number_to_forum_threads.rb b/db/migrate/20120625174544_add_highest_post_number_to_forum_threads.rb index 33ffb5478e4..3a9cf51ed54 100644 --- a/db/migrate/20120625174544_add_highest_post_number_to_forum_threads.rb +++ b/db/migrate/20120625174544_add_highest_post_number_to_forum_threads.rb @@ -1,4 +1,4 @@ -class AddHighestPostNumberToForumThreads < ActiveRecord::Migration +class AddHighestPostNumberToForumThreads < ActiveRecord::Migration[4.2] def change add_column :forum_threads, :highest_post_number, :integer, default: 0, null: false diff --git a/db/migrate/20120625195326_add_image_url_to_forum_threads.rb b/db/migrate/20120625195326_add_image_url_to_forum_threads.rb index 4b37240bcd0..5f9cdfa4cad 100644 --- a/db/migrate/20120625195326_add_image_url_to_forum_threads.rb +++ b/db/migrate/20120625195326_add_image_url_to_forum_threads.rb @@ -1,4 +1,4 @@ -class AddImageUrlToForumThreads < ActiveRecord::Migration +class AddImageUrlToForumThreads < ActiveRecord::Migration[4.2] def change add_column :forum_threads, :image_url, :string end diff --git a/db/migrate/20120629143908_rename_expression_type_id.rb b/db/migrate/20120629143908_rename_expression_type_id.rb index eb19b14a20d..ccb7f6f4e74 100644 --- a/db/migrate/20120629143908_rename_expression_type_id.rb +++ b/db/migrate/20120629143908_rename_expression_type_id.rb @@ -1,4 +1,4 @@ -class RenameExpressionTypeId < ActiveRecord::Migration +class RenameExpressionTypeId < ActiveRecord::Migration[4.2] def up add_column :expression_types, :expression_index, :integer diff --git a/db/migrate/20120629150253_denormalize_expressions.rb b/db/migrate/20120629150253_denormalize_expressions.rb index 8a386648852..9c0ae638400 100644 --- a/db/migrate/20120629150253_denormalize_expressions.rb +++ b/db/migrate/20120629150253_denormalize_expressions.rb @@ -1,4 +1,4 @@ -class DenormalizeExpressions < ActiveRecord::Migration +class DenormalizeExpressions < ActiveRecord::Migration[4.2] def change # Denormalizing this makes our queries so, so, so much nicer diff --git a/db/migrate/20120629151243_make_expressions_less_generic.rb b/db/migrate/20120629151243_make_expressions_less_generic.rb index ffe9e6ee79f..a442abe5748 100644 --- a/db/migrate/20120629151243_make_expressions_less_generic.rb +++ b/db/migrate/20120629151243_make_expressions_less_generic.rb @@ -1,4 +1,4 @@ -class MakeExpressionsLessGeneric < ActiveRecord::Migration +class MakeExpressionsLessGeneric < ActiveRecord::Migration[4.2] def up rename_column :expressions, :parent_id, :post_id rename_column :expressions, :expression_type_id, :expression_index diff --git a/db/migrate/20120629182637_create_incoming_links.rb b/db/migrate/20120629182637_create_incoming_links.rb index 319ede0bff5..ffa324c0a9d 100644 --- a/db/migrate/20120629182637_create_incoming_links.rb +++ b/db/migrate/20120629182637_create_incoming_links.rb @@ -1,4 +1,4 @@ -class CreateIncomingLinks < ActiveRecord::Migration +class CreateIncomingLinks < ActiveRecord::Migration[4.2] def change create_table :incoming_links do |t| t.integer :site_id, null: false diff --git a/db/migrate/20120702211427_create_replies.rb b/db/migrate/20120702211427_create_replies.rb index bc65dd9f9df..fccfd383cde 100644 --- a/db/migrate/20120702211427_create_replies.rb +++ b/db/migrate/20120702211427_create_replies.rb @@ -1,4 +1,4 @@ -class CreateReplies < ActiveRecord::Migration +class CreateReplies < ActiveRecord::Migration[4.2] def change create_table :post_replies, id: false do |t| t.references :post diff --git a/db/migrate/20120703184734_add_reflection_to_forum_thread_links.rb b/db/migrate/20120703184734_add_reflection_to_forum_thread_links.rb index af6b99cb88e..aa41ca99056 100644 --- a/db/migrate/20120703184734_add_reflection_to_forum_thread_links.rb +++ b/db/migrate/20120703184734_add_reflection_to_forum_thread_links.rb @@ -1,4 +1,4 @@ -class AddReflectionToForumThreadLinks < ActiveRecord::Migration +class AddReflectionToForumThreadLinks < ActiveRecord::Migration[4.2] def change add_column :forum_thread_links, :reflection, :boolean, default: false change_column :forum_thread_links, :post_id, :integer, null: true diff --git a/db/migrate/20120703201312_add_incoming_link_count_to_posts.rb b/db/migrate/20120703201312_add_incoming_link_count_to_posts.rb index 16c4e37eaad..ca1641a5d41 100644 --- a/db/migrate/20120703201312_add_incoming_link_count_to_posts.rb +++ b/db/migrate/20120703201312_add_incoming_link_count_to_posts.rb @@ -1,4 +1,4 @@ -class AddIncomingLinkCountToPosts < ActiveRecord::Migration +class AddIncomingLinkCountToPosts < ActiveRecord::Migration[4.2] def change add_column :posts, :incoming_link_count, :integer, default: 0, null: false end diff --git a/db/migrate/20120703203623_add_incoming_link_count_to_forum_threads.rb b/db/migrate/20120703203623_add_incoming_link_count_to_forum_threads.rb index 15eb799751d..18684044edb 100644 --- a/db/migrate/20120703203623_add_incoming_link_count_to_forum_threads.rb +++ b/db/migrate/20120703203623_add_incoming_link_count_to_forum_threads.rb @@ -1,4 +1,4 @@ -class AddIncomingLinkCountToForumThreads < ActiveRecord::Migration +class AddIncomingLinkCountToForumThreads < ActiveRecord::Migration[4.2] def change add_column :forum_threads, :incoming_link_count, :integer, default: 0, null: false end diff --git a/db/migrate/20120703210004_add_bookmark_count_to_posts.rb b/db/migrate/20120703210004_add_bookmark_count_to_posts.rb index c9e5cf9b3cb..ddb1a98a02b 100644 --- a/db/migrate/20120703210004_add_bookmark_count_to_posts.rb +++ b/db/migrate/20120703210004_add_bookmark_count_to_posts.rb @@ -1,4 +1,4 @@ -class AddBookmarkCountToPosts < ActiveRecord::Migration +class AddBookmarkCountToPosts < ActiveRecord::Migration[4.2] def change add_column :posts, :bookmark_count, :integer, default: 0, null: false add_column :forum_threads, :bookmark_count, :integer, default: 0, null: false diff --git a/db/migrate/20120704160659_add_avg_time_to_posts.rb b/db/migrate/20120704160659_add_avg_time_to_posts.rb index 33fbd39f149..2aa76da9c58 100644 --- a/db/migrate/20120704160659_add_avg_time_to_posts.rb +++ b/db/migrate/20120704160659_add_avg_time_to_posts.rb @@ -1,4 +1,4 @@ -class AddAvgTimeToPosts < ActiveRecord::Migration +class AddAvgTimeToPosts < ActiveRecord::Migration[4.2] def change add_column :posts, :avg_time, :integer, null: true add_column :posts, :score, :float, null: true diff --git a/db/migrate/20120704201743_add_view_count_to_posts.rb b/db/migrate/20120704201743_add_view_count_to_posts.rb index 9ea94e0be45..286b9b97458 100644 --- a/db/migrate/20120704201743_add_view_count_to_posts.rb +++ b/db/migrate/20120704201743_add_view_count_to_posts.rb @@ -1,4 +1,4 @@ -class AddViewCountToPosts < ActiveRecord::Migration +class AddViewCountToPosts < ActiveRecord::Migration[4.2] def change add_column :posts, :views, :integer, default: 0, null: false diff --git a/db/migrate/20120705181724_add_user_to_versions.rb b/db/migrate/20120705181724_add_user_to_versions.rb index cdafd3472f0..0e68b887d6e 100644 --- a/db/migrate/20120705181724_add_user_to_versions.rb +++ b/db/migrate/20120705181724_add_user_to_versions.rb @@ -1,4 +1,4 @@ -class AddUserToVersions < ActiveRecord::Migration +class AddUserToVersions < ActiveRecord::Migration[4.2] def change execute "UPDATE versions SET user_type = 'User', user_id = posts.user_id FROM posts diff --git a/db/migrate/20120708210305_add_last_posted_at_to_users.rb b/db/migrate/20120708210305_add_last_posted_at_to_users.rb index b41d355698b..e0df759ebd7 100644 --- a/db/migrate/20120708210305_add_last_posted_at_to_users.rb +++ b/db/migrate/20120708210305_add_last_posted_at_to_users.rb @@ -1,4 +1,4 @@ -class AddLastPostedAtToUsers < ActiveRecord::Migration +class AddLastPostedAtToUsers < ActiveRecord::Migration[4.2] def change add_column :users, :last_posted_at, :datetime, null: true add_index :users, :last_posted_at diff --git a/db/migrate/20120712150500_create_categories.rb b/db/migrate/20120712150500_create_categories.rb index 6479e0596bd..90adb73d10d 100644 --- a/db/migrate/20120712150500_create_categories.rb +++ b/db/migrate/20120712150500_create_categories.rb @@ -1,4 +1,4 @@ -class CreateCategories < ActiveRecord::Migration +class CreateCategories < ActiveRecord::Migration[4.2] def up create_table :categories do |t| t.string :name, limit: 50, null: false diff --git a/db/migrate/20120712151934_add_category_id_to_forum_threads.rb b/db/migrate/20120712151934_add_category_id_to_forum_threads.rb index c918ebbdfa5..d90799dc4fb 100644 --- a/db/migrate/20120712151934_add_category_id_to_forum_threads.rb +++ b/db/migrate/20120712151934_add_category_id_to_forum_threads.rb @@ -1,4 +1,4 @@ -class AddCategoryIdToForumThreads < ActiveRecord::Migration +class AddCategoryIdToForumThreads < ActiveRecord::Migration[4.2] def up add_column :forum_threads, :category_id, :integer diff --git a/db/migrate/20120713201324_create_category_featured_threads.rb b/db/migrate/20120713201324_create_category_featured_threads.rb index 46752f44abe..897992ce64a 100644 --- a/db/migrate/20120713201324_create_category_featured_threads.rb +++ b/db/migrate/20120713201324_create_category_featured_threads.rb @@ -1,4 +1,4 @@ -class CreateCategoryFeaturedThreads < ActiveRecord::Migration +class CreateCategoryFeaturedThreads < ActiveRecord::Migration[4.2] def change create_table :category_featured_threads, id: false do |t| t.references :category, null: false diff --git a/db/migrate/20120716020835_create_site_settings.rb b/db/migrate/20120716020835_create_site_settings.rb index a5cdd44459e..f554de545a1 100644 --- a/db/migrate/20120716020835_create_site_settings.rb +++ b/db/migrate/20120716020835_create_site_settings.rb @@ -1,4 +1,4 @@ -class CreateSiteSettings < ActiveRecord::Migration +class CreateSiteSettings < ActiveRecord::Migration[4.2] def change create_table :site_settings do |t| t.string :name, null: false diff --git a/db/migrate/20120716173544_add_stats_to_categories.rb b/db/migrate/20120716173544_add_stats_to_categories.rb index e9cea0050a0..d904089921e 100644 --- a/db/migrate/20120716173544_add_stats_to_categories.rb +++ b/db/migrate/20120716173544_add_stats_to_categories.rb @@ -1,4 +1,4 @@ -class AddStatsToCategories < ActiveRecord::Migration +class AddStatsToCategories < ActiveRecord::Migration[4.2] def change add_column :categories, :posts_year, :integer add_column :categories, :posts_month, :integer diff --git a/db/migrate/20120718044955_create_user_open_ids.rb b/db/migrate/20120718044955_create_user_open_ids.rb index 95b87c5aae1..626c27897c1 100644 --- a/db/migrate/20120718044955_create_user_open_ids.rb +++ b/db/migrate/20120718044955_create_user_open_ids.rb @@ -1,4 +1,4 @@ -class CreateUserOpenIds < ActiveRecord::Migration +class CreateUserOpenIds < ActiveRecord::Migration[4.2] def change create_table :user_open_ids do |t| t.integer :user_id diff --git a/db/migrate/20120719004636_add_email_hashed_password_name_salt_to_users.rb b/db/migrate/20120719004636_add_email_hashed_password_name_salt_to_users.rb index 4bd5e9b733b..a4169738e72 100644 --- a/db/migrate/20120719004636_add_email_hashed_password_name_salt_to_users.rb +++ b/db/migrate/20120719004636_add_email_hashed_password_name_salt_to_users.rb @@ -1,4 +1,4 @@ -class AddEmailHashedPasswordNameSaltToUsers < ActiveRecord::Migration +class AddEmailHashedPasswordNameSaltToUsers < ActiveRecord::Migration[4.2] def up add_column :users, :email, :string, limit: 256 diff --git a/db/migrate/20120720013733_add_username_lower_to_users.rb b/db/migrate/20120720013733_add_username_lower_to_users.rb index 38602aa2aa7..0a6a89e741a 100644 --- a/db/migrate/20120720013733_add_username_lower_to_users.rb +++ b/db/migrate/20120720013733_add_username_lower_to_users.rb @@ -1,4 +1,4 @@ -class AddUsernameLowerToUsers < ActiveRecord::Migration +class AddUsernameLowerToUsers < ActiveRecord::Migration[4.2] def up add_column :users, :username_lower, :string, limit: 20 execute "update users set username_lower = lower(username)" diff --git a/db/migrate/20120720044246_add_auth_token_to_users.rb b/db/migrate/20120720044246_add_auth_token_to_users.rb index 3d6ec19efaf..d489e99b074 100644 --- a/db/migrate/20120720044246_add_auth_token_to_users.rb +++ b/db/migrate/20120720044246_add_auth_token_to_users.rb @@ -1,4 +1,4 @@ -class AddAuthTokenToUsers < ActiveRecord::Migration +class AddAuthTokenToUsers < ActiveRecord::Migration[4.2] def change add_column :users, :auth_token, :string, limit: 32 add_index :users, [:auth_token] diff --git a/db/migrate/20120720162422_add_forum_id_to_categories.rb b/db/migrate/20120720162422_add_forum_id_to_categories.rb index 39b734c73f7..8b253d15496 100644 --- a/db/migrate/20120720162422_add_forum_id_to_categories.rb +++ b/db/migrate/20120720162422_add_forum_id_to_categories.rb @@ -1,4 +1,4 @@ -class AddForumIdToCategories < ActiveRecord::Migration +class AddForumIdToCategories < ActiveRecord::Migration[4.2] def up add_column :categories, :forum_id, :integer execute "UPDATE categories SET forum_id = (SELECT MIN(id) FROM forums)" diff --git a/db/migrate/20120723051512_add_not_nulls_to_user_open_ids.rb b/db/migrate/20120723051512_add_not_nulls_to_user_open_ids.rb index 44572b23d5f..44666072a7e 100644 --- a/db/migrate/20120723051512_add_not_nulls_to_user_open_ids.rb +++ b/db/migrate/20120723051512_add_not_nulls_to_user_open_ids.rb @@ -1,4 +1,4 @@ -class AddNotNullsToUserOpenIds < ActiveRecord::Migration +class AddNotNullsToUserOpenIds < ActiveRecord::Migration[4.2] def change change_column :user_open_ids, :user_id, :integer, null: false change_column :user_open_ids, :email, :string, null: false diff --git a/db/migrate/20120724234502_add_last_seen_at_to_users.rb b/db/migrate/20120724234502_add_last_seen_at_to_users.rb index 7281d99bfb8..c957404fa8f 100644 --- a/db/migrate/20120724234502_add_last_seen_at_to_users.rb +++ b/db/migrate/20120724234502_add_last_seen_at_to_users.rb @@ -1,4 +1,4 @@ -class AddLastSeenAtToUsers < ActiveRecord::Migration +class AddLastSeenAtToUsers < ActiveRecord::Migration[4.2] def change add_column :users, :last_seen_at, :datetime end diff --git a/db/migrate/20120724234711_add_website_to_users.rb b/db/migrate/20120724234711_add_website_to_users.rb index 8687ceca6aa..96b5ba64d2d 100644 --- a/db/migrate/20120724234711_add_website_to_users.rb +++ b/db/migrate/20120724234711_add_website_to_users.rb @@ -1,4 +1,4 @@ -class AddWebsiteToUsers < ActiveRecord::Migration +class AddWebsiteToUsers < ActiveRecord::Migration[4.2] def change add_column :users, :website, :string end diff --git a/db/migrate/20120725183347_add_excerpt_to_categories.rb b/db/migrate/20120725183347_add_excerpt_to_categories.rb index ecbdca1790f..3171ec2a814 100644 --- a/db/migrate/20120725183347_add_excerpt_to_categories.rb +++ b/db/migrate/20120725183347_add_excerpt_to_categories.rb @@ -1,4 +1,4 @@ -class AddExcerptToCategories < ActiveRecord::Migration +class AddExcerptToCategories < ActiveRecord::Migration[4.2] def change add_column :categories, :excerpt, :string, limit: 250 end diff --git a/db/migrate/20120726201830_add_invisible_to_forum_thread.rb b/db/migrate/20120726201830_add_invisible_to_forum_thread.rb index 1c79c9a4674..404350ed86b 100644 --- a/db/migrate/20120726201830_add_invisible_to_forum_thread.rb +++ b/db/migrate/20120726201830_add_invisible_to_forum_thread.rb @@ -1,4 +1,4 @@ -class AddInvisibleToForumThread < ActiveRecord::Migration +class AddInvisibleToForumThread < ActiveRecord::Migration[4.2] def up add_column :forum_threads, :invisible, :boolean, default: false, null: false change_column :categories, :excerpt, :text, null: true diff --git a/db/migrate/20120726235129_add_user_id_to_categories.rb b/db/migrate/20120726235129_add_user_id_to_categories.rb index 26f2ff32b09..376781c4fd1 100644 --- a/db/migrate/20120726235129_add_user_id_to_categories.rb +++ b/db/migrate/20120726235129_add_user_id_to_categories.rb @@ -1,4 +1,4 @@ -class AddUserIdToCategories < ActiveRecord::Migration +class AddUserIdToCategories < ActiveRecord::Migration[4.2] def change add_column :categories, :user_id, :integer execute "UPDATE categories SET user_id = 1186" diff --git a/db/migrate/20120727005556_remove_excerpt_from_categories.rb b/db/migrate/20120727005556_remove_excerpt_from_categories.rb index aef33cbf933..8699dab5d59 100644 --- a/db/migrate/20120727005556_remove_excerpt_from_categories.rb +++ b/db/migrate/20120727005556_remove_excerpt_from_categories.rb @@ -1,4 +1,4 @@ -class RemoveExcerptFromCategories < ActiveRecord::Migration +class RemoveExcerptFromCategories < ActiveRecord::Migration[4.2] def up remove_column :categories, :excerpt end diff --git a/db/migrate/20120727150428_rename_invisible.rb b/db/migrate/20120727150428_rename_invisible.rb index 04dc3aab1cf..4829a1f5f28 100644 --- a/db/migrate/20120727150428_rename_invisible.rb +++ b/db/migrate/20120727150428_rename_invisible.rb @@ -1,4 +1,4 @@ -class RenameInvisible < ActiveRecord::Migration +class RenameInvisible < ActiveRecord::Migration[4.2] def change add_column :forum_threads, :visible, :boolean, default: true, null: false diff --git a/db/migrate/20120727213543_add_thread_counts_to_categories.rb b/db/migrate/20120727213543_add_thread_counts_to_categories.rb index 36add724c18..cd922b175f9 100644 --- a/db/migrate/20120727213543_add_thread_counts_to_categories.rb +++ b/db/migrate/20120727213543_add_thread_counts_to_categories.rb @@ -1,4 +1,4 @@ -class AddThreadCountsToCategories < ActiveRecord::Migration +class AddThreadCountsToCategories < ActiveRecord::Migration[4.2] def change add_column :categories, :threads_year, :integer add_column :categories, :threads_month, :integer diff --git a/db/migrate/20120802151210_add_icon_to_expression_types.rb b/db/migrate/20120802151210_add_icon_to_expression_types.rb index 289ae28b8aa..ab833036fb5 100644 --- a/db/migrate/20120802151210_add_icon_to_expression_types.rb +++ b/db/migrate/20120802151210_add_icon_to_expression_types.rb @@ -1,4 +1,4 @@ -class AddIconToExpressionTypes < ActiveRecord::Migration +class AddIconToExpressionTypes < ActiveRecord::Migration[4.2] def change add_column :expression_types, :icon, :string, limit: 20 diff --git a/db/migrate/20120803191426_add_admin_flag_to_users.rb b/db/migrate/20120803191426_add_admin_flag_to_users.rb index 9d7abddfec0..f60b405ee30 100644 --- a/db/migrate/20120803191426_add_admin_flag_to_users.rb +++ b/db/migrate/20120803191426_add_admin_flag_to_users.rb @@ -1,4 +1,4 @@ -class AddAdminFlagToUsers < ActiveRecord::Migration +class AddAdminFlagToUsers < ActiveRecord::Migration[4.2] def change add_column :users, :admin, :boolean, default: false, null: false add_column :users, :moderator, :boolean, default: false, null: false diff --git a/db/migrate/20120806030641_add_new_password_new_salt_email_token_to_users.rb b/db/migrate/20120806030641_add_new_password_new_salt_email_token_to_users.rb index dfac912b714..7277b4eb450 100644 --- a/db/migrate/20120806030641_add_new_password_new_salt_email_token_to_users.rb +++ b/db/migrate/20120806030641_add_new_password_new_salt_email_token_to_users.rb @@ -1,4 +1,4 @@ -class AddNewPasswordNewSaltEmailTokenToUsers < ActiveRecord::Migration +class AddNewPasswordNewSaltEmailTokenToUsers < ActiveRecord::Migration[4.2] def change add_column :users, :new_salt, :string, limit: 32 add_column :users, :new_password_hash, :string, limit: 64 diff --git a/db/migrate/20120806062617_remove_new_password_stuff_from_user.rb b/db/migrate/20120806062617_remove_new_password_stuff_from_user.rb index 9d8df3e7e44..c1a3069a256 100644 --- a/db/migrate/20120806062617_remove_new_password_stuff_from_user.rb +++ b/db/migrate/20120806062617_remove_new_password_stuff_from_user.rb @@ -1,4 +1,4 @@ -class RemoveNewPasswordStuffFromUser < ActiveRecord::Migration +class RemoveNewPasswordStuffFromUser < ActiveRecord::Migration[4.2] def change remove_column :users, :new_password_hash remove_column :users, :new_salt diff --git a/db/migrate/20120807223020_create_actions.rb b/db/migrate/20120807223020_create_actions.rb index a720e4e8b78..c84336dc22e 100644 --- a/db/migrate/20120807223020_create_actions.rb +++ b/db/migrate/20120807223020_create_actions.rb @@ -1,4 +1,4 @@ -class CreateActions < ActiveRecord::Migration +class CreateActions < ActiveRecord::Migration[4.2] def change create_table :actions do |t| diff --git a/db/migrate/20120809020415_remove_site_id.rb b/db/migrate/20120809020415_remove_site_id.rb index c9904d4a705..24a8019824f 100644 --- a/db/migrate/20120809020415_remove_site_id.rb +++ b/db/migrate/20120809020415_remove_site_id.rb @@ -1,4 +1,4 @@ -class RemoveSiteId < ActiveRecord::Migration +class RemoveSiteId < ActiveRecord::Migration[4.2] def up drop_table 'sites' remove_index 'incoming_links', name: "incoming_index" diff --git a/db/migrate/20120809030647_remove_forum_id.rb b/db/migrate/20120809030647_remove_forum_id.rb index 412f9e3cc70..f489fc52e5a 100644 --- a/db/migrate/20120809030647_remove_forum_id.rb +++ b/db/migrate/20120809030647_remove_forum_id.rb @@ -1,4 +1,4 @@ -class RemoveForumId < ActiveRecord::Migration +class RemoveForumId < ActiveRecord::Migration[4.2] def up remove_column 'forum_threads', 'forum_id' remove_column 'categories', 'forum_id' diff --git a/db/migrate/20120809053414_correct_indexing_on_posts.rb b/db/migrate/20120809053414_correct_indexing_on_posts.rb index 13ff4507d66..ce29c25a5a6 100644 --- a/db/migrate/20120809053414_correct_indexing_on_posts.rb +++ b/db/migrate/20120809053414_correct_indexing_on_posts.rb @@ -1,4 +1,4 @@ -class CorrectIndexingOnPosts < ActiveRecord::Migration +class CorrectIndexingOnPosts < ActiveRecord::Migration[4.2] def up execute "update posts pp set post_number = c.real_number diff --git a/db/migrate/20120809154750_remove_index_for_now.rb b/db/migrate/20120809154750_remove_index_for_now.rb index ea20ceb152e..dabc1728506 100644 --- a/db/migrate/20120809154750_remove_index_for_now.rb +++ b/db/migrate/20120809154750_remove_index_for_now.rb @@ -1,4 +1,4 @@ -class RemoveIndexForNow < ActiveRecord::Migration +class RemoveIndexForNow < ActiveRecord::Migration[4.2] def up remove_index "posts", ["forum_thread_id", "post_number"] add_index "posts", ["forum_thread_id", "post_number"], unique: false diff --git a/db/migrate/20120809174649_create_post_actions.rb b/db/migrate/20120809174649_create_post_actions.rb index 7a15a29fcff..f9d2d8af87d 100644 --- a/db/migrate/20120809174649_create_post_actions.rb +++ b/db/migrate/20120809174649_create_post_actions.rb @@ -1,4 +1,4 @@ -class CreatePostActions < ActiveRecord::Migration +class CreatePostActions < ActiveRecord::Migration[4.2] def up create_table :post_actions do |t| t.integer :post_id, null: false diff --git a/db/migrate/20120809175110_create_post_action_types.rb b/db/migrate/20120809175110_create_post_action_types.rb index 410547b6de8..1759817ea3e 100644 --- a/db/migrate/20120809175110_create_post_action_types.rb +++ b/db/migrate/20120809175110_create_post_action_types.rb @@ -1,4 +1,4 @@ -class CreatePostActionTypes < ActiveRecord::Migration +class CreatePostActionTypes < ActiveRecord::Migration[4.2] def change create_table(:post_action_types, id: false) do |t| t.integer :id, options: "PRIMARY KEY", null: false diff --git a/db/migrate/20120809201855_migrate_bookmarks_to_post_actions.rb b/db/migrate/20120809201855_migrate_bookmarks_to_post_actions.rb index 89db3302139..5b6705e8662 100644 --- a/db/migrate/20120809201855_migrate_bookmarks_to_post_actions.rb +++ b/db/migrate/20120809201855_migrate_bookmarks_to_post_actions.rb @@ -1,4 +1,4 @@ -class MigrateBookmarksToPostActions < ActiveRecord::Migration +class MigrateBookmarksToPostActions < ActiveRecord::Migration[4.2] def up drop_table "bookmarks" end diff --git a/db/migrate/20120810064839_rename_actions_to_user_actions.rb b/db/migrate/20120810064839_rename_actions_to_user_actions.rb index f7a245fdbe1..6be0a2b8b3c 100644 --- a/db/migrate/20120810064839_rename_actions_to_user_actions.rb +++ b/db/migrate/20120810064839_rename_actions_to_user_actions.rb @@ -1,4 +1,4 @@ -class RenameActionsToUserActions < ActiveRecord::Migration +class RenameActionsToUserActions < ActiveRecord::Migration[4.2] def change rename_table 'actions', 'user_actions' end diff --git a/db/migrate/20120812235417_retire_expressions.rb b/db/migrate/20120812235417_retire_expressions.rb index 696d9a39f89..3f565558c18 100644 --- a/db/migrate/20120812235417_retire_expressions.rb +++ b/db/migrate/20120812235417_retire_expressions.rb @@ -1,4 +1,4 @@ -class RetireExpressions < ActiveRecord::Migration +class RetireExpressions < ActiveRecord::Migration[4.2] def up execute 'insert into post_actions (post_action_type_id, user_id, post_id, created_at, updated_at) select diff --git a/db/migrate/20120813004347_rename_expression_columns_in_forum_thread.rb b/db/migrate/20120813004347_rename_expression_columns_in_forum_thread.rb index 77efca9ea8f..4483800e4f6 100644 --- a/db/migrate/20120813004347_rename_expression_columns_in_forum_thread.rb +++ b/db/migrate/20120813004347_rename_expression_columns_in_forum_thread.rb @@ -1,4 +1,4 @@ -class RenameExpressionColumnsInForumThread < ActiveRecord::Migration +class RenameExpressionColumnsInForumThread < ActiveRecord::Migration[4.2] def change rename_column 'forum_threads', 'expression1_count', 'off_topic_count' rename_column 'forum_threads', 'expression2_count', 'offensive_count' diff --git a/db/migrate/20120813042912_rename_expression_columns_in_posts.rb b/db/migrate/20120813042912_rename_expression_columns_in_posts.rb index c57a2507041..8b22ec5a279 100644 --- a/db/migrate/20120813042912_rename_expression_columns_in_posts.rb +++ b/db/migrate/20120813042912_rename_expression_columns_in_posts.rb @@ -1,4 +1,4 @@ -class RenameExpressionColumnsInPosts < ActiveRecord::Migration +class RenameExpressionColumnsInPosts < ActiveRecord::Migration[4.2] def change rename_column 'posts', 'expression1_count', 'off_topic_count' rename_column 'posts', 'expression2_count', 'offensive_count' diff --git a/db/migrate/20120813201426_create_forum_thread_link_clicks.rb b/db/migrate/20120813201426_create_forum_thread_link_clicks.rb index c216f836ace..65e67011b7e 100644 --- a/db/migrate/20120813201426_create_forum_thread_link_clicks.rb +++ b/db/migrate/20120813201426_create_forum_thread_link_clicks.rb @@ -1,4 +1,4 @@ -class CreateForumThreadLinkClicks < ActiveRecord::Migration +class CreateForumThreadLinkClicks < ActiveRecord::Migration[4.2] def change create_table :forum_thread_link_clicks do |t| t.references :forum_thread_link, null: false diff --git a/db/migrate/20120815004411_add_unique_index_to_forum_thread_links.rb b/db/migrate/20120815004411_add_unique_index_to_forum_thread_links.rb index e94bcc9337b..7ddf6d405b9 100644 --- a/db/migrate/20120815004411_add_unique_index_to_forum_thread_links.rb +++ b/db/migrate/20120815004411_add_unique_index_to_forum_thread_links.rb @@ -1,4 +1,4 @@ -class AddUniqueIndexToForumThreadLinks < ActiveRecord::Migration +class AddUniqueIndexToForumThreadLinks < ActiveRecord::Migration[4.2] def change execute "DELETE FROM forum_thread_links USING forum_thread_links ftl2 diff --git a/db/migrate/20120815180106_add_post_type_to_posts.rb b/db/migrate/20120815180106_add_post_type_to_posts.rb index 768da19725d..4f3b00c168d 100644 --- a/db/migrate/20120815180106_add_post_type_to_posts.rb +++ b/db/migrate/20120815180106_add_post_type_to_posts.rb @@ -1,4 +1,4 @@ -class AddPostTypeToPosts < ActiveRecord::Migration +class AddPostTypeToPosts < ActiveRecord::Migration[4.2] def change add_column :posts, :post_type, :integer, default: 1, null: false end diff --git a/db/migrate/20120815204733_add_moderator_posts_count_to_forum_threads.rb b/db/migrate/20120815204733_add_moderator_posts_count_to_forum_threads.rb index 0f3ff34966e..49717c4fd92 100644 --- a/db/migrate/20120815204733_add_moderator_posts_count_to_forum_threads.rb +++ b/db/migrate/20120815204733_add_moderator_posts_count_to_forum_threads.rb @@ -1,4 +1,4 @@ -class AddModeratorPostsCountToForumThreads < ActiveRecord::Migration +class AddModeratorPostsCountToForumThreads < ActiveRecord::Migration[4.2] def change add_column :forum_threads, :moderator_posts_count, :integer, default: 0, null: false diff --git a/db/migrate/20120816050526_add_unique_constraint_to_user_actions.rb b/db/migrate/20120816050526_add_unique_constraint_to_user_actions.rb index 6d79402d346..43bbe102d11 100644 --- a/db/migrate/20120816050526_add_unique_constraint_to_user_actions.rb +++ b/db/migrate/20120816050526_add_unique_constraint_to_user_actions.rb @@ -1,4 +1,4 @@ -class AddUniqueConstraintToUserActions < ActiveRecord::Migration +class AddUniqueConstraintToUserActions < ActiveRecord::Migration[4.2] def change add_index :user_actions, ['action_type', 'user_id', 'target_forum_thread_id', 'target_post_id', 'acting_user_id'], name: "idx_unique_rows", unique: true end diff --git a/db/migrate/20120816205537_add_forum_thread_states.rb b/db/migrate/20120816205537_add_forum_thread_states.rb index 95a6e8b6a89..5a80831a14e 100644 --- a/db/migrate/20120816205537_add_forum_thread_states.rb +++ b/db/migrate/20120816205537_add_forum_thread_states.rb @@ -1,4 +1,4 @@ -class AddForumThreadStates < ActiveRecord::Migration +class AddForumThreadStates < ActiveRecord::Migration[4.2] def change add_column :forum_threads, :closed, :boolean, default: false, null: false add_column :forum_threads, :sticky, :boolean, default: false, null: false diff --git a/db/migrate/20120816205538_add_starred_at_to_forum_thread_user.rb b/db/migrate/20120816205538_add_starred_at_to_forum_thread_user.rb index 6cbe575a342..2fc02d4287b 100644 --- a/db/migrate/20120816205538_add_starred_at_to_forum_thread_user.rb +++ b/db/migrate/20120816205538_add_starred_at_to_forum_thread_user.rb @@ -1,4 +1,4 @@ -class AddStarredAtToForumThreadUser < ActiveRecord::Migration +class AddStarredAtToForumThreadUser < ActiveRecord::Migration[4.2] def up add_column :forum_thread_users, :starred_at, :datetime User.exec_sql 'update forum_thread_users f set starred_at = COALESCE(created_at, ?) diff --git a/db/migrate/20120820191804_add_search_indices.rb b/db/migrate/20120820191804_add_search_indices.rb index e073be6c16d..11f8c307485 100644 --- a/db/migrate/20120820191804_add_search_indices.rb +++ b/db/migrate/20120820191804_add_search_indices.rb @@ -1,4 +1,4 @@ -class AddSearchIndices < ActiveRecord::Migration +class AddSearchIndices < ActiveRecord::Migration[4.2] def up execute "CREATE INDEX idx_search_user ON users USING GIN(to_tsvector('english', username))" execute "CREATE INDEX idx_search_thread ON forum_threads USING GIN(to_tsvector('english', title))" diff --git a/db/migrate/20120821191616_add_bumped_at_to_forum_threads.rb b/db/migrate/20120821191616_add_bumped_at_to_forum_threads.rb index 9420f79a8d3..96217a0ad84 100644 --- a/db/migrate/20120821191616_add_bumped_at_to_forum_threads.rb +++ b/db/migrate/20120821191616_add_bumped_at_to_forum_threads.rb @@ -1,4 +1,4 @@ -class AddBumpedAtToForumThreads < ActiveRecord::Migration +class AddBumpedAtToForumThreads < ActiveRecord::Migration[4.2] def change add_column :forum_threads, :bumped_at, :datetime execute "UPDATE forum_threads SET bumped_at = last_posted_at" diff --git a/db/migrate/20120823205956_add_slug_to_categories.rb b/db/migrate/20120823205956_add_slug_to_categories.rb index 50641848253..76cdab26a71 100644 --- a/db/migrate/20120823205956_add_slug_to_categories.rb +++ b/db/migrate/20120823205956_add_slug_to_categories.rb @@ -1,4 +1,4 @@ -class AddSlugToCategories < ActiveRecord::Migration +class AddSlugToCategories < ActiveRecord::Migration[4.2] def change add_column :categories, :slug, :string execute "UPDATE categories SET slug = REPLACE(LOWER(name), ' ', '-')" diff --git a/db/migrate/20120824171908_create_category_featured_users.rb b/db/migrate/20120824171908_create_category_featured_users.rb index db72c45b5cd..c97fcf195f4 100644 --- a/db/migrate/20120824171908_create_category_featured_users.rb +++ b/db/migrate/20120824171908_create_category_featured_users.rb @@ -1,4 +1,4 @@ -class CreateCategoryFeaturedUsers < ActiveRecord::Migration +class CreateCategoryFeaturedUsers < ActiveRecord::Migration[4.2] def change create_table :category_featured_users do |t| t.references :category diff --git a/db/migrate/20120828204209_create_onebox_renders.rb b/db/migrate/20120828204209_create_onebox_renders.rb index c28657b7ca5..297be79b76f 100644 --- a/db/migrate/20120828204209_create_onebox_renders.rb +++ b/db/migrate/20120828204209_create_onebox_renders.rb @@ -1,4 +1,4 @@ -class CreateOneboxRenders < ActiveRecord::Migration +class CreateOneboxRenders < ActiveRecord::Migration[4.2] def change create_table :onebox_renders do |t| t.string :url, null: false diff --git a/db/migrate/20120828204624_create_post_onebox_renders.rb b/db/migrate/20120828204624_create_post_onebox_renders.rb index 4a991a14f9c..fae17c5052e 100644 --- a/db/migrate/20120828204624_create_post_onebox_renders.rb +++ b/db/migrate/20120828204624_create_post_onebox_renders.rb @@ -1,4 +1,4 @@ -class CreatePostOneboxRenders < ActiveRecord::Migration +class CreatePostOneboxRenders < ActiveRecord::Migration[4.2] def change create_table :post_onebox_renders, id: false do |t| t.references :post, null: false diff --git a/db/migrate/20120830182736_add_preview_to_onebox_renders.rb b/db/migrate/20120830182736_add_preview_to_onebox_renders.rb index 79edede11af..e41805580e2 100644 --- a/db/migrate/20120830182736_add_preview_to_onebox_renders.rb +++ b/db/migrate/20120830182736_add_preview_to_onebox_renders.rb @@ -1,4 +1,4 @@ -class AddPreviewToOneboxRenders < ActiveRecord::Migration +class AddPreviewToOneboxRenders < ActiveRecord::Migration[4.2] def change add_column :onebox_renders, :preview, :text, null: true diff --git a/db/migrate/20120910171504_remove_description_from_site_settings.rb b/db/migrate/20120910171504_remove_description_from_site_settings.rb index a0718456c2d..f353e117c11 100644 --- a/db/migrate/20120910171504_remove_description_from_site_settings.rb +++ b/db/migrate/20120910171504_remove_description_from_site_settings.rb @@ -1,4 +1,4 @@ -class RemoveDescriptionFromSiteSettings < ActiveRecord::Migration +class RemoveDescriptionFromSiteSettings < ActiveRecord::Migration[4.2] def up remove_column :site_settings, :description end diff --git a/db/migrate/20120918152319_rename_views_to_reads.rb b/db/migrate/20120918152319_rename_views_to_reads.rb index 4a35838010f..8f65f1c6468 100644 --- a/db/migrate/20120918152319_rename_views_to_reads.rb +++ b/db/migrate/20120918152319_rename_views_to_reads.rb @@ -1,4 +1,4 @@ -class RenameViewsToReads < ActiveRecord::Migration +class RenameViewsToReads < ActiveRecord::Migration[4.2] def up rename_column :posts, :views, :reads end diff --git a/db/migrate/20120918205931_add_sub_tag_to_forum_threads.rb b/db/migrate/20120918205931_add_sub_tag_to_forum_threads.rb index 4765da2e969..bcd4f98b6c5 100644 --- a/db/migrate/20120918205931_add_sub_tag_to_forum_threads.rb +++ b/db/migrate/20120918205931_add_sub_tag_to_forum_threads.rb @@ -1,4 +1,4 @@ -class AddSubTagToForumThreads < ActiveRecord::Migration +class AddSubTagToForumThreads < ActiveRecord::Migration[4.2] def change add_column :forum_threads, :sub_tag, :string add_index :forum_threads, [:category_id, :sub_tag, :bumped_at] diff --git a/db/migrate/20120919152846_add_has_best_of_to_forum_threads.rb b/db/migrate/20120919152846_add_has_best_of_to_forum_threads.rb index d6fd5599fdd..ae0b8bbb29d 100644 --- a/db/migrate/20120919152846_add_has_best_of_to_forum_threads.rb +++ b/db/migrate/20120919152846_add_has_best_of_to_forum_threads.rb @@ -1,4 +1,4 @@ -class AddHasBestOfToForumThreads < ActiveRecord::Migration +class AddHasBestOfToForumThreads < ActiveRecord::Migration[4.2] def change add_column :forum_threads, :has_best_of, :boolean, default: false, null: false diff --git a/db/migrate/20120921055428_add_twitter_user_info.rb b/db/migrate/20120921055428_add_twitter_user_info.rb index 8830ef0175d..48b8c34ad6e 100644 --- a/db/migrate/20120921055428_add_twitter_user_info.rb +++ b/db/migrate/20120921055428_add_twitter_user_info.rb @@ -1,4 +1,4 @@ -class AddTwitterUserInfo < ActiveRecord::Migration +class AddTwitterUserInfo < ActiveRecord::Migration[4.2] def change create_table :twitter_user_infos do |t| t.integer :user_id, null: false diff --git a/db/migrate/20120921155050_create_archetypes.rb b/db/migrate/20120921155050_create_archetypes.rb index 59bca0e28e9..6e9ae48981e 100644 --- a/db/migrate/20120921155050_create_archetypes.rb +++ b/db/migrate/20120921155050_create_archetypes.rb @@ -1,4 +1,4 @@ -class CreateArchetypes < ActiveRecord::Migration +class CreateArchetypes < ActiveRecord::Migration[4.2] def up create_table :archetypes do |t| t.string :name_key, null: false diff --git a/db/migrate/20120921162512_add_meta_data_to_forum_threads.rb b/db/migrate/20120921162512_add_meta_data_to_forum_threads.rb index 7543fe98767..e4377a7744c 100644 --- a/db/migrate/20120921162512_add_meta_data_to_forum_threads.rb +++ b/db/migrate/20120921162512_add_meta_data_to_forum_threads.rb @@ -1,4 +1,4 @@ -class AddMetaDataToForumThreads < ActiveRecord::Migration +class AddMetaDataToForumThreads < ActiveRecord::Migration[4.2] def change execute "CREATE EXTENSION IF NOT EXISTS hstore" add_column :forum_threads, :meta_data, :hstore diff --git a/db/migrate/20120921163606_create_archetype_options.rb b/db/migrate/20120921163606_create_archetype_options.rb index 9ddc71fc071..f772013d90a 100644 --- a/db/migrate/20120921163606_create_archetype_options.rb +++ b/db/migrate/20120921163606_create_archetype_options.rb @@ -1,4 +1,4 @@ -class CreateArchetypeOptions < ActiveRecord::Migration +class CreateArchetypeOptions < ActiveRecord::Migration[4.2] def change create_table :archetype_options do |t| t.references :archetype, null: false diff --git a/db/migrate/20120924182000_add_hstore_extension.rb b/db/migrate/20120924182000_add_hstore_extension.rb index f3f8d8acba9..f8145e7e7f3 100644 --- a/db/migrate/20120924182000_add_hstore_extension.rb +++ b/db/migrate/20120924182000_add_hstore_extension.rb @@ -1,4 +1,4 @@ -class AddHstoreExtension < ActiveRecord::Migration +class AddHstoreExtension < ActiveRecord::Migration[4.2] def self.up execute "CREATE EXTENSION IF NOT EXISTS hstore" end diff --git a/db/migrate/20120924182031_add_vote_count_to_posts.rb b/db/migrate/20120924182031_add_vote_count_to_posts.rb index c65852ae77c..1b0e7395700 100644 --- a/db/migrate/20120924182031_add_vote_count_to_posts.rb +++ b/db/migrate/20120924182031_add_vote_count_to_posts.rb @@ -1,4 +1,4 @@ -class AddVoteCountToPosts < ActiveRecord::Migration +class AddVoteCountToPosts < ActiveRecord::Migration[4.2] def change add_column :forum_threads, :vote_count, :integer, default: 0, null: false add_column :posts, :vote_count, :integer, default: 0, null: false diff --git a/db/migrate/20120925171620_remove_english_from_post_action_types.rb b/db/migrate/20120925171620_remove_english_from_post_action_types.rb index 25eb104afb5..b3d2840a22d 100644 --- a/db/migrate/20120925171620_remove_english_from_post_action_types.rb +++ b/db/migrate/20120925171620_remove_english_from_post_action_types.rb @@ -1,4 +1,4 @@ -class RemoveEnglishFromPostActionTypes < ActiveRecord::Migration +class RemoveEnglishFromPostActionTypes < ActiveRecord::Migration[4.2] def up rename_column :post_action_types, :name, :name_key execute "UPDATE post_action_types SET name_key = regexp_replace(lower(name_key), '[^a-z]', '_')" diff --git a/db/migrate/20120925190802_add_sequence_to_post_action_types.rb b/db/migrate/20120925190802_add_sequence_to_post_action_types.rb index d6d14b9589a..b82c69f252c 100644 --- a/db/migrate/20120925190802_add_sequence_to_post_action_types.rb +++ b/db/migrate/20120925190802_add_sequence_to_post_action_types.rb @@ -1,4 +1,4 @@ -class AddSequenceToPostActionTypes < ActiveRecord::Migration +class AddSequenceToPostActionTypes < ActiveRecord::Migration[4.2] def change remove_column :post_action_types, :id add_column :post_action_types, :id, :primary_key diff --git a/db/migrate/20120928170023_add_sort_order_to_posts.rb b/db/migrate/20120928170023_add_sort_order_to_posts.rb index de98ed3b75a..6a0bf192ad2 100644 --- a/db/migrate/20120928170023_add_sort_order_to_posts.rb +++ b/db/migrate/20120928170023_add_sort_order_to_posts.rb @@ -1,4 +1,4 @@ -class AddSortOrderToPosts < ActiveRecord::Migration +class AddSortOrderToPosts < ActiveRecord::Migration[4.2] def change add_column :posts, :sort_order, :integer remove_index :posts, :user_id diff --git a/db/migrate/20121009161116_add_email_stuff_to_users.rb b/db/migrate/20121009161116_add_email_stuff_to_users.rb index af0210eef16..839a10bee6b 100644 --- a/db/migrate/20121009161116_add_email_stuff_to_users.rb +++ b/db/migrate/20121009161116_add_email_stuff_to_users.rb @@ -1,4 +1,4 @@ -class AddEmailStuffToUsers < ActiveRecord::Migration +class AddEmailStuffToUsers < ActiveRecord::Migration[4.2] def change add_column :users, :last_emailed_at, :datetime, null: true add_column :users, :email_digests, :boolean, null: false, default: true diff --git a/db/migrate/20121011155904_create_email_logs.rb b/db/migrate/20121011155904_create_email_logs.rb index a4b0c49e4eb..f6a5af197c2 100644 --- a/db/migrate/20121011155904_create_email_logs.rb +++ b/db/migrate/20121011155904_create_email_logs.rb @@ -1,4 +1,4 @@ -class CreateEmailLogs < ActiveRecord::Migration +class CreateEmailLogs < ActiveRecord::Migration[4.2] def change create_table :email_logs do |t| t.string :to_address, null: false diff --git a/db/migrate/20121017162924_convert_archetypes.rb b/db/migrate/20121017162924_convert_archetypes.rb index ba4559da9d8..b6513f9fbc2 100644 --- a/db/migrate/20121017162924_convert_archetypes.rb +++ b/db/migrate/20121017162924_convert_archetypes.rb @@ -1,4 +1,4 @@ -class ConvertArchetypes < ActiveRecord::Migration +class ConvertArchetypes < ActiveRecord::Migration[4.2] def up add_column :forum_threads, :archetype, :string, default: 'regular', null: false execute "UPDATE forum_threads SET archetype = a.name_key FROM archetypes AS a WHERE a.id = forum_threads.archetype_id" diff --git a/db/migrate/20121018103721_rename_forum_thread_tables.rb b/db/migrate/20121018103721_rename_forum_thread_tables.rb index 84980494dae..e8a3e4160d1 100644 --- a/db/migrate/20121018103721_rename_forum_thread_tables.rb +++ b/db/migrate/20121018103721_rename_forum_thread_tables.rb @@ -1,4 +1,4 @@ -class RenameForumThreadTables < ActiveRecord::Migration +class RenameForumThreadTables < ActiveRecord::Migration[4.2] def change rename_table 'forum_threads', 'topics' rename_table 'forum_thread_link_clicks', 'topic_link_clicks' diff --git a/db/migrate/20121018133039_create_topic_allowed_users.rb b/db/migrate/20121018133039_create_topic_allowed_users.rb index b3d4324fcb7..8975ae622f2 100644 --- a/db/migrate/20121018133039_create_topic_allowed_users.rb +++ b/db/migrate/20121018133039_create_topic_allowed_users.rb @@ -1,4 +1,4 @@ -class CreateTopicAllowedUsers < ActiveRecord::Migration +class CreateTopicAllowedUsers < ActiveRecord::Migration[4.2] def change create_table :topic_allowed_users do |t| t.integer :user_id, null: false diff --git a/db/migrate/20121018182709_fix_notification_data.rb b/db/migrate/20121018182709_fix_notification_data.rb index 5d261a464f5..cbfeb28fd24 100644 --- a/db/migrate/20121018182709_fix_notification_data.rb +++ b/db/migrate/20121018182709_fix_notification_data.rb @@ -1,4 +1,4 @@ -class FixNotificationData < ActiveRecord::Migration +class FixNotificationData < ActiveRecord::Migration[4.2] def up execute "UPDATE notifications SET data = replace(data, 'thread_title', 'topic_title')" end diff --git a/db/migrate/20121106015500_drop_avatar_url_from_users.rb b/db/migrate/20121106015500_drop_avatar_url_from_users.rb index a9cc69114d3..9d6662322bd 100644 --- a/db/migrate/20121106015500_drop_avatar_url_from_users.rb +++ b/db/migrate/20121106015500_drop_avatar_url_from_users.rb @@ -4,7 +4,7 @@ # for local urls we need to upload an image and have a pointer to the upload, then use the upload id in the user table # for gravatar we already have the email and can hash it -class DropAvatarUrlFromUsers < ActiveRecord::Migration +class DropAvatarUrlFromUsers < ActiveRecord::Migration[4.2] def up remove_column :users, :avatar_url end diff --git a/db/migrate/20121108193516_add_post_action_id_to_notifications.rb b/db/migrate/20121108193516_add_post_action_id_to_notifications.rb index beeae1131cc..01e1f7e7b1c 100644 --- a/db/migrate/20121108193516_add_post_action_id_to_notifications.rb +++ b/db/migrate/20121108193516_add_post_action_id_to_notifications.rb @@ -1,4 +1,4 @@ -class AddPostActionIdToNotifications < ActiveRecord::Migration +class AddPostActionIdToNotifications < ActiveRecord::Migration[4.2] def change add_column :notifications, :post_action_id, :integer, null: true add_index :notifications, :post_action_id diff --git a/db/migrate/20121109164630_create_trust_levels.rb b/db/migrate/20121109164630_create_trust_levels.rb index 6c3983e8925..8b5fe68192d 100644 --- a/db/migrate/20121109164630_create_trust_levels.rb +++ b/db/migrate/20121109164630_create_trust_levels.rb @@ -1,4 +1,4 @@ -class CreateTrustLevels < ActiveRecord::Migration +class CreateTrustLevels < ActiveRecord::Migration[4.2] def change create_table :trust_levels do |t| t.string :name_key, null: false diff --git a/db/migrate/20121113200844_bio_markdown_support.rb b/db/migrate/20121113200844_bio_markdown_support.rb index 54ad72f71c3..1737b65449d 100644 --- a/db/migrate/20121113200844_bio_markdown_support.rb +++ b/db/migrate/20121113200844_bio_markdown_support.rb @@ -1,4 +1,4 @@ -class BioMarkdownSupport < ActiveRecord::Migration +class BioMarkdownSupport < ActiveRecord::Migration[4.2] def up rename_column :users, :bio, :bio_raw add_column :users, :bio_cooked, :text, null: true diff --git a/db/migrate/20121113200845_create_facebook_user_infos.rb b/db/migrate/20121113200845_create_facebook_user_infos.rb index 1ef46b480b6..9640031c92d 100644 --- a/db/migrate/20121113200845_create_facebook_user_infos.rb +++ b/db/migrate/20121113200845_create_facebook_user_infos.rb @@ -1,4 +1,4 @@ -class CreateFacebookUserInfos < ActiveRecord::Migration +class CreateFacebookUserInfos < ActiveRecord::Migration[4.2] def change create_table :facebook_user_infos do |t| t.integer :user_id, null: false diff --git a/db/migrate/20121115172544_rename_sticky_to_pinned.rb b/db/migrate/20121115172544_rename_sticky_to_pinned.rb index 6feb2a720c4..915bd3cb4e1 100644 --- a/db/migrate/20121115172544_rename_sticky_to_pinned.rb +++ b/db/migrate/20121115172544_rename_sticky_to_pinned.rb @@ -1,4 +1,4 @@ -class RenameStickyToPinned < ActiveRecord::Migration +class RenameStickyToPinned < ActiveRecord::Migration[4.2] def up rename_column :topics, :sticky, :pinned end diff --git a/db/migrate/20121116212424_add_more_email_settings_to_user.rb b/db/migrate/20121116212424_add_more_email_settings_to_user.rb index 6a7ac29519b..6d6e7282d17 100644 --- a/db/migrate/20121116212424_add_more_email_settings_to_user.rb +++ b/db/migrate/20121116212424_add_more_email_settings_to_user.rb @@ -1,4 +1,4 @@ -class AddMoreEmailSettingsToUser < ActiveRecord::Migration +class AddMoreEmailSettingsToUser < ActiveRecord::Migration[4.2] def change add_column :users, :email_private_messages, :boolean, default: true add_column :users, :email_mentions, :boolean, default: true diff --git a/db/migrate/20121119190529_add_email_settings_to_users.rb b/db/migrate/20121119190529_add_email_settings_to_users.rb index b6e7e8a656e..8eea445eb03 100644 --- a/db/migrate/20121119190529_add_email_settings_to_users.rb +++ b/db/migrate/20121119190529_add_email_settings_to_users.rb @@ -1,4 +1,4 @@ -class AddEmailSettingsToUsers < ActiveRecord::Migration +class AddEmailSettingsToUsers < ActiveRecord::Migration[4.2] def change add_column :users, :email_replied, :boolean, default: true add_column :users, :email_quoted, :boolean, default: true diff --git a/db/migrate/20121119200843_add_email_direct_to_users.rb b/db/migrate/20121119200843_add_email_direct_to_users.rb index 0091e6e3480..c3e9cc97012 100644 --- a/db/migrate/20121119200843_add_email_direct_to_users.rb +++ b/db/migrate/20121119200843_add_email_direct_to_users.rb @@ -1,4 +1,4 @@ -class AddEmailDirectToUsers < ActiveRecord::Migration +class AddEmailDirectToUsers < ActiveRecord::Migration[4.2] def change add_column :users, :email_direct, :boolean, default: true, null: false remove_column :users, :email_mentions diff --git a/db/migrate/20121121202035_create_invites.rb b/db/migrate/20121121202035_create_invites.rb index 71ef5c2f1a6..3da6834354f 100644 --- a/db/migrate/20121121202035_create_invites.rb +++ b/db/migrate/20121121202035_create_invites.rb @@ -1,4 +1,4 @@ -class CreateInvites < ActiveRecord::Migration +class CreateInvites < ActiveRecord::Migration[4.2] def change create_table :invites do |t| t.string :invite_key, null: false, limit: 32 diff --git a/db/migrate/20121121205215_create_topic_invites.rb b/db/migrate/20121121205215_create_topic_invites.rb index 45fb2d59510..30071dc1268 100644 --- a/db/migrate/20121121205215_create_topic_invites.rb +++ b/db/migrate/20121121205215_create_topic_invites.rb @@ -1,4 +1,4 @@ -class CreateTopicInvites < ActiveRecord::Migration +class CreateTopicInvites < ActiveRecord::Migration[4.2] def change create_table :topic_invites do |t| t.references :topic, null: false diff --git a/db/migrate/20121122033316_add_muted_at_to_topic_user.rb b/db/migrate/20121122033316_add_muted_at_to_topic_user.rb index 9ecd7d07abe..3b8119fffbd 100644 --- a/db/migrate/20121122033316_add_muted_at_to_topic_user.rb +++ b/db/migrate/20121122033316_add_muted_at_to_topic_user.rb @@ -1,4 +1,4 @@ -class AddMutedAtToTopicUser < ActiveRecord::Migration +class AddMutedAtToTopicUser < ActiveRecord::Migration[4.2] def change add_column :topic_users, :muted_at, :datetime change_column :topic_users, :last_read_post_number, :integer, null: true diff --git a/db/migrate/20121123054127_make_post_number_distinct.rb b/db/migrate/20121123054127_make_post_number_distinct.rb index fc8959cc838..695ac7392c0 100644 --- a/db/migrate/20121123054127_make_post_number_distinct.rb +++ b/db/migrate/20121123054127_make_post_number_distinct.rb @@ -1,4 +1,4 @@ -class MakePostNumberDistinct < ActiveRecord::Migration +class MakePostNumberDistinct < ActiveRecord::Migration[4.2] def up Topic.exec_sql('update posts p diff --git a/db/migrate/20121123063630_create_user_visits.rb b/db/migrate/20121123063630_create_user_visits.rb index e68d6dd50f5..6a130d16822 100644 --- a/db/migrate/20121123063630_create_user_visits.rb +++ b/db/migrate/20121123063630_create_user_visits.rb @@ -1,4 +1,4 @@ -class CreateUserVisits < ActiveRecord::Migration +class CreateUserVisits < ActiveRecord::Migration[4.2] def change create_table :user_visits do |t| t.integer :user_id, null: false diff --git a/db/migrate/20121129160035_create_email_tokens.rb b/db/migrate/20121129160035_create_email_tokens.rb index c4ade0f0cc2..e4011c7a328 100644 --- a/db/migrate/20121129160035_create_email_tokens.rb +++ b/db/migrate/20121129160035_create_email_tokens.rb @@ -1,4 +1,4 @@ -class CreateEmailTokens < ActiveRecord::Migration +class CreateEmailTokens < ActiveRecord::Migration[4.2] def change create_table :email_tokens do |t| t.references :user, null: false diff --git a/db/migrate/20121129184948_remove_email_token_from_users.rb b/db/migrate/20121129184948_remove_email_token_from_users.rb index f605820daab..4cace300c95 100644 --- a/db/migrate/20121129184948_remove_email_token_from_users.rb +++ b/db/migrate/20121129184948_remove_email_token_from_users.rb @@ -1,4 +1,4 @@ -class RemoveEmailTokenFromUsers < ActiveRecord::Migration +class RemoveEmailTokenFromUsers < ActiveRecord::Migration[4.2] def up execute "INSERT INTO email_tokens (user_id, email, token, created_at, updated_at) SELECT id, email, email_token, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP diff --git a/db/migrate/20121130010400_create_drafts.rb b/db/migrate/20121130010400_create_drafts.rb index dba5708226a..1be48658a7c 100644 --- a/db/migrate/20121130010400_create_drafts.rb +++ b/db/migrate/20121130010400_create_drafts.rb @@ -1,4 +1,4 @@ -class CreateDrafts < ActiveRecord::Migration +class CreateDrafts < ActiveRecord::Migration[4.2] def change create_table :drafts do |t| t.integer :user_id, null: false diff --git a/db/migrate/20121130191818_add_link_post_id_to_topic_links.rb b/db/migrate/20121130191818_add_link_post_id_to_topic_links.rb index f8347dc2b7b..d6b1ccf27c0 100644 --- a/db/migrate/20121130191818_add_link_post_id_to_topic_links.rb +++ b/db/migrate/20121130191818_add_link_post_id_to_topic_links.rb @@ -1,4 +1,4 @@ -class AddLinkPostIdToTopicLinks < ActiveRecord::Migration +class AddLinkPostIdToTopicLinks < ActiveRecord::Migration[4.2] def change add_column :topic_links, :link_post_id, :integer end diff --git a/db/migrate/20121202225421_add_visited_at_to_topic_user.rb b/db/migrate/20121202225421_add_visited_at_to_topic_user.rb index 4525698b2ca..ea27d4a3103 100644 --- a/db/migrate/20121202225421_add_visited_at_to_topic_user.rb +++ b/db/migrate/20121202225421_add_visited_at_to_topic_user.rb @@ -1,4 +1,4 @@ -class AddVisitedAtToTopicUser < ActiveRecord::Migration +class AddVisitedAtToTopicUser < ActiveRecord::Migration[4.2] def change add_column :topic_users, :last_visited_at, :datetime add_column :topic_users, :first_visited_at, :datetime diff --git a/db/migrate/20121203181719_rename_seen_notificaiton_id.rb b/db/migrate/20121203181719_rename_seen_notificaiton_id.rb index 017f1991216..9f6996aa7b5 100644 --- a/db/migrate/20121203181719_rename_seen_notificaiton_id.rb +++ b/db/migrate/20121203181719_rename_seen_notificaiton_id.rb @@ -1,4 +1,4 @@ -class RenameSeenNotificaitonId < ActiveRecord::Migration +class RenameSeenNotificaitonId < ActiveRecord::Migration[4.2] def up rename_column :users, :seen_notificaiton_id, :seen_notification_id end diff --git a/db/migrate/20121204183855_fix_link_post_id.rb b/db/migrate/20121204183855_fix_link_post_id.rb index 4b03b963275..47491880989 100644 --- a/db/migrate/20121204183855_fix_link_post_id.rb +++ b/db/migrate/20121204183855_fix_link_post_id.rb @@ -1,4 +1,4 @@ -class FixLinkPostId < ActiveRecord::Migration +class FixLinkPostId < ActiveRecord::Migration[4.2] def up to_remove = [] @@ -18,7 +18,7 @@ class FixLinkPostId < ActiveRecord::Migration end - TopicLink.delete_all ["id in (?)", to_remove] + TopicLink.where("id in (?)", to_remove).delete_all end def down diff --git a/db/migrate/20121204193747_add_another_featured_user_to_topics.rb b/db/migrate/20121204193747_add_another_featured_user_to_topics.rb index 7e639e75d4e..bda56c09c1f 100644 --- a/db/migrate/20121204193747_add_another_featured_user_to_topics.rb +++ b/db/migrate/20121204193747_add_another_featured_user_to_topics.rb @@ -1,4 +1,4 @@ -class AddAnotherFeaturedUserToTopics < ActiveRecord::Migration +class AddAnotherFeaturedUserToTopics < ActiveRecord::Migration[4.2] def change add_column :topics, :featured_user4_id, :integer, null: true end diff --git a/db/migrate/20121205162143_add_approved_to_users.rb b/db/migrate/20121205162143_add_approved_to_users.rb index fdb474e30eb..8202b725fa9 100644 --- a/db/migrate/20121205162143_add_approved_to_users.rb +++ b/db/migrate/20121205162143_add_approved_to_users.rb @@ -1,4 +1,4 @@ -class AddApprovedToUsers < ActiveRecord::Migration +class AddApprovedToUsers < ActiveRecord::Migration[4.2] def change add_column :users, :approved, :boolean, null: false, default: false add_column :users, :approved_by_id, :integer, null: true diff --git a/db/migrate/20121207000741_add_notifications_to_topic_users.rb b/db/migrate/20121207000741_add_notifications_to_topic_users.rb index 37eb8129c67..ae31470d985 100644 --- a/db/migrate/20121207000741_add_notifications_to_topic_users.rb +++ b/db/migrate/20121207000741_add_notifications_to_topic_users.rb @@ -1,4 +1,4 @@ -class AddNotificationsToTopicUsers < ActiveRecord::Migration +class AddNotificationsToTopicUsers < ActiveRecord::Migration[4.2] def change add_column :topic_users, :notifications, :integer, default: 2 add_column :topic_users, :notifications_changed_at, :datetime diff --git a/db/migrate/20121211233131_create_site_customizations.rb b/db/migrate/20121211233131_create_site_customizations.rb index dd39279f4f7..206f041c600 100644 --- a/db/migrate/20121211233131_create_site_customizations.rb +++ b/db/migrate/20121211233131_create_site_customizations.rb @@ -1,4 +1,4 @@ -class CreateSiteCustomizations < ActiveRecord::Migration +class CreateSiteCustomizations < ActiveRecord::Migration[4.2] def change create_table :site_customizations do |t| t.string :name, null: false diff --git a/db/migrate/20121216230719_add_override_default_style_to_site_customization.rb b/db/migrate/20121216230719_add_override_default_style_to_site_customization.rb index 786df0f1cce..f4b21257a91 100644 --- a/db/migrate/20121216230719_add_override_default_style_to_site_customization.rb +++ b/db/migrate/20121216230719_add_override_default_style_to_site_customization.rb @@ -1,4 +1,4 @@ -class AddOverrideDefaultStyleToSiteCustomization < ActiveRecord::Migration +class AddOverrideDefaultStyleToSiteCustomization < ActiveRecord::Migration[4.2] def change add_column :site_customizations, :override_default_style, :boolean, default: false, null: false add_column :site_customizations, :stylesheet_baked, :text, default: '', null: false diff --git a/db/migrate/20121218205642_add_topics_entered_to_users.rb b/db/migrate/20121218205642_add_topics_entered_to_users.rb index 38cf2a158db..464ffabf62e 100644 --- a/db/migrate/20121218205642_add_topics_entered_to_users.rb +++ b/db/migrate/20121218205642_add_topics_entered_to_users.rb @@ -1,4 +1,4 @@ -class AddTopicsEnteredToUsers < ActiveRecord::Migration +class AddTopicsEnteredToUsers < ActiveRecord::Migration[4.2] def change add_column :users, :topics_entered, :integer, default: 0, null: false add_column :users, :posts_read_count, :integer, default: 0, null: false diff --git a/db/migrate/20121224072204_add_last_editor_id_to_posts.rb b/db/migrate/20121224072204_add_last_editor_id_to_posts.rb index 0c74f2992b4..9651bae6789 100644 --- a/db/migrate/20121224072204_add_last_editor_id_to_posts.rb +++ b/db/migrate/20121224072204_add_last_editor_id_to_posts.rb @@ -1,4 +1,4 @@ -class AddLastEditorIdToPosts < ActiveRecord::Migration +class AddLastEditorIdToPosts < ActiveRecord::Migration[4.2] def change add_column :posts, :last_editor_id, :integer end diff --git a/db/migrate/20121224095139_create_draft_sequence.rb b/db/migrate/20121224095139_create_draft_sequence.rb index a93d444a0bd..239a7a3851c 100644 --- a/db/migrate/20121224095139_create_draft_sequence.rb +++ b/db/migrate/20121224095139_create_draft_sequence.rb @@ -1,4 +1,4 @@ -class CreateDraftSequence < ActiveRecord::Migration +class CreateDraftSequence < ActiveRecord::Migration[4.2] def change create_table :draft_sequences do |t| t.integer :user_id, null: false diff --git a/db/migrate/20121224100650_add_sequence_to_drafts.rb b/db/migrate/20121224100650_add_sequence_to_drafts.rb index 7edde6492d5..555174f2618 100644 --- a/db/migrate/20121224100650_add_sequence_to_drafts.rb +++ b/db/migrate/20121224100650_add_sequence_to_drafts.rb @@ -1,4 +1,4 @@ -class AddSequenceToDrafts < ActiveRecord::Migration +class AddSequenceToDrafts < ActiveRecord::Migration[4.2] def change add_column :drafts, :sequence, :integer, null: false, default: 0 end diff --git a/db/migrate/20121228192219_add_deleted_at_to_invites.rb b/db/migrate/20121228192219_add_deleted_at_to_invites.rb index f95e811ad16..46ba45daf99 100644 --- a/db/migrate/20121228192219_add_deleted_at_to_invites.rb +++ b/db/migrate/20121228192219_add_deleted_at_to_invites.rb @@ -1,4 +1,4 @@ -class AddDeletedAtToInvites < ActiveRecord::Migration +class AddDeletedAtToInvites < ActiveRecord::Migration[4.2] def change add_column :invites, :deleted_at, :datetime end diff --git a/db/migrate/20130107165207_add_digest_after_days_to_users.rb b/db/migrate/20130107165207_add_digest_after_days_to_users.rb index 7964f2c71ae..fa4e01b6a6c 100644 --- a/db/migrate/20130107165207_add_digest_after_days_to_users.rb +++ b/db/migrate/20130107165207_add_digest_after_days_to_users.rb @@ -1,4 +1,4 @@ -class AddDigestAfterDaysToUsers < ActiveRecord::Migration +class AddDigestAfterDaysToUsers < ActiveRecord::Migration[4.2] def change add_column :users, :digest_after_days, :integer, default: 7, null: false end diff --git a/db/migrate/20130108195847_add_previous_visit_at_to_users.rb b/db/migrate/20130108195847_add_previous_visit_at_to_users.rb index d56d116bab7..b8cd19ba34b 100644 --- a/db/migrate/20130108195847_add_previous_visit_at_to_users.rb +++ b/db/migrate/20130108195847_add_previous_visit_at_to_users.rb @@ -1,4 +1,4 @@ -class AddPreviousVisitAtToUsers < ActiveRecord::Migration +class AddPreviousVisitAtToUsers < ActiveRecord::Migration[4.2] def change add_column :users, :previous_visit_at, :timestamp end diff --git a/db/migrate/20130115012140_merge_mute_options_on_topic_users.rb b/db/migrate/20130115012140_merge_mute_options_on_topic_users.rb index a3b80104aed..0fc471fcfe7 100644 --- a/db/migrate/20130115012140_merge_mute_options_on_topic_users.rb +++ b/db/migrate/20130115012140_merge_mute_options_on_topic_users.rb @@ -1,4 +1,4 @@ -class MergeMuteOptionsOnTopicUsers < ActiveRecord::Migration +class MergeMuteOptionsOnTopicUsers < ActiveRecord::Migration[4.2] def change execute "update topic_users set notifications = 0 where notifications = 3" execute "update topic_users set notifications = 1 where notifications = 2" diff --git a/db/migrate/20130115021937_correct_default_on_notification_level.rb b/db/migrate/20130115021937_correct_default_on_notification_level.rb index 93947c64629..dda56432a9e 100644 --- a/db/migrate/20130115021937_correct_default_on_notification_level.rb +++ b/db/migrate/20130115021937_correct_default_on_notification_level.rb @@ -1,4 +1,4 @@ -class CorrectDefaultOnNotificationLevel < ActiveRecord::Migration +class CorrectDefaultOnNotificationLevel < ActiveRecord::Migration[4.2] def change change_column :topic_users, :notification_level, :integer, default: 1, null: false end diff --git a/db/migrate/20130115043603_oops_unwatch_a_boat_of_watched_stuff.rb b/db/migrate/20130115043603_oops_unwatch_a_boat_of_watched_stuff.rb index e2078fee0f2..ebf1f48b13c 100644 --- a/db/migrate/20130115043603_oops_unwatch_a_boat_of_watched_stuff.rb +++ b/db/migrate/20130115043603_oops_unwatch_a_boat_of_watched_stuff.rb @@ -1,4 +1,4 @@ -class OopsUnwatchABoatOfWatchedStuff < ActiveRecord::Migration +class OopsUnwatchABoatOfWatchedStuff < ActiveRecord::Migration[4.2] def change execute 'update topic_users set notification_level = 1 where notifications_reason_id is null and notification_level = 2' end diff --git a/db/migrate/20130116151829_remove_sub_tag_from_topics.rb b/db/migrate/20130116151829_remove_sub_tag_from_topics.rb index 2ff253b2232..1c6e189b14b 100644 --- a/db/migrate/20130116151829_remove_sub_tag_from_topics.rb +++ b/db/migrate/20130116151829_remove_sub_tag_from_topics.rb @@ -1,4 +1,4 @@ -class RemoveSubTagFromTopics < ActiveRecord::Migration +class RemoveSubTagFromTopics < ActiveRecord::Migration[4.2] def up remove_column :topics, :sub_tag end diff --git a/db/migrate/20130120222728_fix_search.rb b/db/migrate/20130120222728_fix_search.rb index ee44ea1ae80..4d5dfcd4f18 100644 --- a/db/migrate/20130120222728_fix_search.rb +++ b/db/migrate/20130120222728_fix_search.rb @@ -1,4 +1,4 @@ -class FixSearch < ActiveRecord::Migration +class FixSearch < ActiveRecord::Migration[4.2] def up execute 'drop index idx_search_thread' execute 'drop index idx_search_user' diff --git a/db/migrate/20130121231352_add_tracking_to_topic_users.rb b/db/migrate/20130121231352_add_tracking_to_topic_users.rb index b52c0d98214..b0882cde820 100644 --- a/db/migrate/20130121231352_add_tracking_to_topic_users.rb +++ b/db/migrate/20130121231352_add_tracking_to_topic_users.rb @@ -1,4 +1,4 @@ -class AddTrackingToTopicUsers < ActiveRecord::Migration +class AddTrackingToTopicUsers < ActiveRecord::Migration[4.2] def up execute 'update topic_users set notification_level = 3 where notification_level = 2' end diff --git a/db/migrate/20130122051134_add_auto_track_topics_to_user.rb b/db/migrate/20130122051134_add_auto_track_topics_to_user.rb index a995ba0731e..9339f7e25f6 100644 --- a/db/migrate/20130122051134_add_auto_track_topics_to_user.rb +++ b/db/migrate/20130122051134_add_auto_track_topics_to_user.rb @@ -1,4 +1,4 @@ -class AddAutoTrackTopicsToUser < ActiveRecord::Migration +class AddAutoTrackTopicsToUser < ActiveRecord::Migration[4.2] def change add_column :users, :auto_track_topics, :boolean, null: false, default: false end diff --git a/db/migrate/20130122232825_add_auto_track_after_seconds_and_banning_and_dob_to_user.rb b/db/migrate/20130122232825_add_auto_track_after_seconds_and_banning_and_dob_to_user.rb index 34ee5edbced..f654cb6fec0 100644 --- a/db/migrate/20130122232825_add_auto_track_after_seconds_and_banning_and_dob_to_user.rb +++ b/db/migrate/20130122232825_add_auto_track_after_seconds_and_banning_and_dob_to_user.rb @@ -1,4 +1,4 @@ -class AddAutoTrackAfterSecondsAndBanningAndDobToUser < ActiveRecord::Migration +class AddAutoTrackAfterSecondsAndBanningAndDobToUser < ActiveRecord::Migration[4.2] def change add_column :users, :banned_at, :datetime add_column :users, :banned_till, :datetime diff --git a/db/migrate/20130123070909_auto_track_all_topics_replied_to.rb b/db/migrate/20130123070909_auto_track_all_topics_replied_to.rb index 0989ff343d0..334566680c8 100644 --- a/db/migrate/20130123070909_auto_track_all_topics_replied_to.rb +++ b/db/migrate/20130123070909_auto_track_all_topics_replied_to.rb @@ -1,4 +1,4 @@ -class AutoTrackAllTopicsRepliedTo < ActiveRecord::Migration +class AutoTrackAllTopicsRepliedTo < ActiveRecord::Migration[4.2] def up execute 'update topic_users set notification_level = 2, notifications_reason_id = 4 from posts p diff --git a/db/migrate/20130125002652_add_hidden_to_posts.rb b/db/migrate/20130125002652_add_hidden_to_posts.rb index ad787fbacc7..b98ee5aefde 100644 --- a/db/migrate/20130125002652_add_hidden_to_posts.rb +++ b/db/migrate/20130125002652_add_hidden_to_posts.rb @@ -1,4 +1,4 @@ -class AddHiddenToPosts < ActiveRecord::Migration +class AddHiddenToPosts < ActiveRecord::Migration[4.2] def change add_column :posts, :hidden, :boolean, null: false, default: false add_column :posts, :hidden_reason_id, :integer diff --git a/db/migrate/20130125030305_add_fields_to_post_action.rb b/db/migrate/20130125030305_add_fields_to_post_action.rb index 6e140794408..09fef75bdb1 100644 --- a/db/migrate/20130125030305_add_fields_to_post_action.rb +++ b/db/migrate/20130125030305_add_fields_to_post_action.rb @@ -1,4 +1,4 @@ -class AddFieldsToPostAction < ActiveRecord::Migration +class AddFieldsToPostAction < ActiveRecord::Migration[4.2] def change add_column :post_actions, :deleted_by, :integer add_column :post_actions, :message, :text diff --git a/db/migrate/20130125031122_correct_index_on_post_action.rb b/db/migrate/20130125031122_correct_index_on_post_action.rb index 6d3d71716c4..d16d54c1456 100644 --- a/db/migrate/20130125031122_correct_index_on_post_action.rb +++ b/db/migrate/20130125031122_correct_index_on_post_action.rb @@ -1,4 +1,4 @@ -class CorrectIndexOnPostAction < ActiveRecord::Migration +class CorrectIndexOnPostAction < ActiveRecord::Migration[4.2] def change remove_index "post_actions", name: "idx_unique_actions" add_index "post_actions", ["user_id", "post_action_type_id", "post_id", "deleted_at"], name: "idx_unique_actions", unique: true diff --git a/db/migrate/20130127213646_remove_trust_levels.rb b/db/migrate/20130127213646_remove_trust_levels.rb index 53f9c738feb..9ba29eafd5f 100644 --- a/db/migrate/20130127213646_remove_trust_levels.rb +++ b/db/migrate/20130127213646_remove_trust_levels.rb @@ -1,4 +1,4 @@ -class RemoveTrustLevels < ActiveRecord::Migration +class RemoveTrustLevels < ActiveRecord::Migration[4.2] def up drop_table :trust_levels change_column_default :users, :trust_level_id, TrustLevel[0] diff --git a/db/migrate/20130128182013_trust_level_default_null.rb b/db/migrate/20130128182013_trust_level_default_null.rb index 3031ade9160..d6409650eb5 100644 --- a/db/migrate/20130128182013_trust_level_default_null.rb +++ b/db/migrate/20130128182013_trust_level_default_null.rb @@ -1,4 +1,4 @@ -class TrustLevelDefaultNull < ActiveRecord::Migration +class TrustLevelDefaultNull < ActiveRecord::Migration[4.2] def up change_column_default :users, :trust_level, nil end diff --git a/db/migrate/20130129010625_remove_pm_reflections.rb b/db/migrate/20130129010625_remove_pm_reflections.rb index bf82c73b37a..eb3f73e661a 100644 --- a/db/migrate/20130129010625_remove_pm_reflections.rb +++ b/db/migrate/20130129010625_remove_pm_reflections.rb @@ -1,4 +1,4 @@ -class RemovePmReflections < ActiveRecord::Migration +class RemovePmReflections < ActiveRecord::Migration[4.2] def up execute 'delete from topic_links where link_topic_id in (select id from topics where archetype = \'private_message\') ' end diff --git a/db/migrate/20130129163244_add_time_read_to_users.rb b/db/migrate/20130129163244_add_time_read_to_users.rb index bd5c3cf8a0d..3b714744d75 100644 --- a/db/migrate/20130129163244_add_time_read_to_users.rb +++ b/db/migrate/20130129163244_add_time_read_to_users.rb @@ -1,4 +1,4 @@ -class AddTimeReadToUsers < ActiveRecord::Migration +class AddTimeReadToUsers < ActiveRecord::Migration[4.2] def change add_column :users, :time_read, :integer, default: 0, null: false diff --git a/db/migrate/20130129174845_add_days_visited_to_users.rb b/db/migrate/20130129174845_add_days_visited_to_users.rb index eff920af0d8..b5b5dc76c82 100644 --- a/db/migrate/20130129174845_add_days_visited_to_users.rb +++ b/db/migrate/20130129174845_add_days_visited_to_users.rb @@ -1,4 +1,4 @@ -class AddDaysVisitedToUsers < ActiveRecord::Migration +class AddDaysVisitedToUsers < ActiveRecord::Migration[4.2] def change add_column :users, :days_visited, :integer, null: false, default: 0 diff --git a/db/migrate/20130130154611_remove_index_from_views.rb b/db/migrate/20130130154611_remove_index_from_views.rb index a6662c81619..449dbef48c4 100644 --- a/db/migrate/20130130154611_remove_index_from_views.rb +++ b/db/migrate/20130130154611_remove_index_from_views.rb @@ -1,4 +1,4 @@ -class RemoveIndexFromViews < ActiveRecord::Migration +class RemoveIndexFromViews < ActiveRecord::Migration[4.2] def up remove_index "views", name: "unique_views" change_column :views, :viewed_at, :date diff --git a/db/migrate/20130131055710_add_custom_flag_count_to_topics.rb b/db/migrate/20130131055710_add_custom_flag_count_to_topics.rb index 8574ad22126..d99df1d52dd 100644 --- a/db/migrate/20130131055710_add_custom_flag_count_to_topics.rb +++ b/db/migrate/20130131055710_add_custom_flag_count_to_topics.rb @@ -1,4 +1,4 @@ -class AddCustomFlagCountToTopics < ActiveRecord::Migration +class AddCustomFlagCountToTopics < ActiveRecord::Migration[4.2] def change add_column :topics, :custom_flag_count, :integer, null: false, default: 0 add_column :posts, :custom_flag_count, :integer, null: false, default: 0 diff --git a/db/migrate/20130201000828_add_column_summaries_to_posts_and_topics.rb b/db/migrate/20130201000828_add_column_summaries_to_posts_and_topics.rb index 5c86c11a43c..0a085816056 100644 --- a/db/migrate/20130201000828_add_column_summaries_to_posts_and_topics.rb +++ b/db/migrate/20130201000828_add_column_summaries_to_posts_and_topics.rb @@ -1,4 +1,4 @@ -class AddColumnSummariesToPostsAndTopics < ActiveRecord::Migration +class AddColumnSummariesToPostsAndTopics < ActiveRecord::Migration[4.2] def change add_column :posts, :spam_count, :integer, default: 0, null: false add_column :topics, :spam_count, :integer, default: 0, null: false diff --git a/db/migrate/20130201023409_add_position_to_post_action_type.rb b/db/migrate/20130201023409_add_position_to_post_action_type.rb index 80bf29fb1da..bc9c974f837 100644 --- a/db/migrate/20130201023409_add_position_to_post_action_type.rb +++ b/db/migrate/20130201023409_add_position_to_post_action_type.rb @@ -1,4 +1,4 @@ -class AddPositionToPostActionType < ActiveRecord::Migration +class AddPositionToPostActionType < ActiveRecord::Migration[4.2] def change add_column :post_action_types, :position, :integer, default: 0, null: false end diff --git a/db/migrate/20130203204338_add_last_version_at_to_posts.rb b/db/migrate/20130203204338_add_last_version_at_to_posts.rb index 5ce0f7257b0..44eef360dd2 100644 --- a/db/migrate/20130203204338_add_last_version_at_to_posts.rb +++ b/db/migrate/20130203204338_add_last_version_at_to_posts.rb @@ -1,4 +1,4 @@ -class AddLastVersionAtToPosts < ActiveRecord::Migration +class AddLastVersionAtToPosts < ActiveRecord::Migration[4.2] def change add_column :posts, :last_version_at, :timestamp execute "UPDATE posts SET last_version_at = COALESCE((SELECT max(created_at) diff --git a/db/migrate/20130204000159_add_ip_address_to_users.rb b/db/migrate/20130204000159_add_ip_address_to_users.rb index 7537b3d7844..6c5910ec91b 100644 --- a/db/migrate/20130204000159_add_ip_address_to_users.rb +++ b/db/migrate/20130204000159_add_ip_address_to_users.rb @@ -1,4 +1,4 @@ -class AddIpAddressToUsers < ActiveRecord::Migration +class AddIpAddressToUsers < ActiveRecord::Migration[4.2] def up execute 'alter table users add column ip_address inet' end diff --git a/db/migrate/20130205021905_alter_facebook_user_id.rb b/db/migrate/20130205021905_alter_facebook_user_id.rb index 8517a9799ed..56011785dc4 100644 --- a/db/migrate/20130205021905_alter_facebook_user_id.rb +++ b/db/migrate/20130205021905_alter_facebook_user_id.rb @@ -1,4 +1,4 @@ -class AlterFacebookUserId < ActiveRecord::Migration +class AlterFacebookUserId < ActiveRecord::Migration[4.2] def up change_column :facebook_user_infos, :facebook_user_id, :integer, limit: 8, null: false end diff --git a/db/migrate/20130207200019_add_user_deleted_to_posts.rb b/db/migrate/20130207200019_add_user_deleted_to_posts.rb index 04e45a1a0b2..ed6274c82c4 100644 --- a/db/migrate/20130207200019_add_user_deleted_to_posts.rb +++ b/db/migrate/20130207200019_add_user_deleted_to_posts.rb @@ -1,4 +1,4 @@ -class AddUserDeletedToPosts < ActiveRecord::Migration +class AddUserDeletedToPosts < ActiveRecord::Migration[4.2] def change add_column :posts, :user_deleted, :boolean, null: false, default: false end diff --git a/db/migrate/20130208220635_remove_reply_below_post_number_from_posts.rb b/db/migrate/20130208220635_remove_reply_below_post_number_from_posts.rb index 85336bce305..3e58b83fffc 100644 --- a/db/migrate/20130208220635_remove_reply_below_post_number_from_posts.rb +++ b/db/migrate/20130208220635_remove_reply_below_post_number_from_posts.rb @@ -1,4 +1,4 @@ -class RemoveReplyBelowPostNumberFromPosts < ActiveRecord::Migration +class RemoveReplyBelowPostNumberFromPosts < ActiveRecord::Migration[4.2] def change remove_column :posts, :reply_below_post_number end diff --git a/db/migrate/20130213021450_remove_topic_response_actions.rb b/db/migrate/20130213021450_remove_topic_response_actions.rb index f993a9049e8..076f3f557d2 100644 --- a/db/migrate/20130213021450_remove_topic_response_actions.rb +++ b/db/migrate/20130213021450_remove_topic_response_actions.rb @@ -1,4 +1,4 @@ -class RemoveTopicResponseActions < ActiveRecord::Migration +class RemoveTopicResponseActions < ActiveRecord::Migration[4.2] def up # 2 notes: # migrations should never use the object model to run sql, otherwise they are a time bomb diff --git a/db/migrate/20130213203300_add_new_topic_duration_minutes_to_users.rb b/db/migrate/20130213203300_add_new_topic_duration_minutes_to_users.rb index 51685cd59a1..8d5516f1e25 100644 --- a/db/migrate/20130213203300_add_new_topic_duration_minutes_to_users.rb +++ b/db/migrate/20130213203300_add_new_topic_duration_minutes_to_users.rb @@ -1,4 +1,4 @@ -class AddNewTopicDurationMinutesToUsers < ActiveRecord::Migration +class AddNewTopicDurationMinutesToUsers < ActiveRecord::Migration[4.2] def change # note, no constants allowed here, -1 means since last visit # -2 means always diff --git a/db/migrate/20130221215017_add_description_to_categories.rb b/db/migrate/20130221215017_add_description_to_categories.rb index 15645c19437..aa225680146 100644 --- a/db/migrate/20130221215017_add_description_to_categories.rb +++ b/db/migrate/20130221215017_add_description_to_categories.rb @@ -1,4 +1,4 @@ -class AddDescriptionToCategories < ActiveRecord::Migration +class AddDescriptionToCategories < ActiveRecord::Migration[4.2] def up add_column :categories, :description, :text, null: true diff --git a/db/migrate/20130226015336_add_github_user_info.rb b/db/migrate/20130226015336_add_github_user_info.rb index 6d575d1c034..775a763e963 100644 --- a/db/migrate/20130226015336_add_github_user_info.rb +++ b/db/migrate/20130226015336_add_github_user_info.rb @@ -1,4 +1,4 @@ -class AddGithubUserInfo < ActiveRecord::Migration +class AddGithubUserInfo < ActiveRecord::Migration[4.2] def change create_table :github_user_infos do |t| t.integer :user_id, null: false diff --git a/db/migrate/20130306180148_add_cleared_pinned_to_topic_users.rb b/db/migrate/20130306180148_add_cleared_pinned_to_topic_users.rb index 9cc4af5d914..1182b90191f 100644 --- a/db/migrate/20130306180148_add_cleared_pinned_to_topic_users.rb +++ b/db/migrate/20130306180148_add_cleared_pinned_to_topic_users.rb @@ -1,4 +1,4 @@ -class AddClearedPinnedToTopicUsers < ActiveRecord::Migration +class AddClearedPinnedToTopicUsers < ActiveRecord::Migration[4.2] def change add_column :topic_users, :cleared_pinned_at, :datetime, null: true diff --git a/db/migrate/20130311181327_remove_extra_spam_record.rb b/db/migrate/20130311181327_remove_extra_spam_record.rb index 7b326476444..ceee3c5d058 100644 --- a/db/migrate/20130311181327_remove_extra_spam_record.rb +++ b/db/migrate/20130311181327_remove_extra_spam_record.rb @@ -1,4 +1,4 @@ -class RemoveExtraSpamRecord < ActiveRecord::Migration +class RemoveExtraSpamRecord < ActiveRecord::Migration[4.2] def up execute "UPDATE post_actions SET post_action_type_id = 7 where post_action_type_id = 8" execute "DELETE FROM post_action_types WHERE id = 8" diff --git a/db/migrate/20130313004922_add_external_links_in_new_tab_an_disable_quoting_to_user.rb b/db/migrate/20130313004922_add_external_links_in_new_tab_an_disable_quoting_to_user.rb index fe83a95a290..8c96e4cbbab 100644 --- a/db/migrate/20130313004922_add_external_links_in_new_tab_an_disable_quoting_to_user.rb +++ b/db/migrate/20130313004922_add_external_links_in_new_tab_an_disable_quoting_to_user.rb @@ -1,4 +1,4 @@ -class AddExternalLinksInNewTabAnDisableQuotingToUser < ActiveRecord::Migration +class AddExternalLinksInNewTabAnDisableQuotingToUser < ActiveRecord::Migration[4.2] def change add_column :users, :external_links_in_new_tab, :boolean, default: false, null: false add_column :users, :enable_quoting, :boolean, default: true, null: false diff --git a/db/migrate/20130314093434_add_foreground_color_to_categories.rb b/db/migrate/20130314093434_add_foreground_color_to_categories.rb index f60663b85cb..9a149136ff4 100644 --- a/db/migrate/20130314093434_add_foreground_color_to_categories.rb +++ b/db/migrate/20130314093434_add_foreground_color_to_categories.rb @@ -1,4 +1,4 @@ -class AddForegroundColorToCategories < ActiveRecord::Migration +class AddForegroundColorToCategories < ActiveRecord::Migration[4.2] def change add_column :categories, :text_color, :string, limit: 6, null: false, default: 'FFFFFF' end diff --git a/db/migrate/20130315180637_enable_trigram_support.rb b/db/migrate/20130315180637_enable_trigram_support.rb index 602133d8504..1b82f45aaec 100644 --- a/db/migrate/20130315180637_enable_trigram_support.rb +++ b/db/migrate/20130315180637_enable_trigram_support.rb @@ -1,4 +1,4 @@ -class EnableTrigramSupport < ActiveRecord::Migration +class EnableTrigramSupport < ActiveRecord::Migration[4.2] def up execute "CREATE EXTENSION IF NOT EXISTS pg_trgm" end diff --git a/db/migrate/20130319122248_add_reply_to_user_id_to_post.rb b/db/migrate/20130319122248_add_reply_to_user_id_to_post.rb index 1eb09763de7..7da8abad4f6 100644 --- a/db/migrate/20130319122248_add_reply_to_user_id_to_post.rb +++ b/db/migrate/20130319122248_add_reply_to_user_id_to_post.rb @@ -1,4 +1,4 @@ -class AddReplyToUserIdToPost < ActiveRecord::Migration +class AddReplyToUserIdToPost < ActiveRecord::Migration[4.2] def up # caching this column makes the topic page WAY faster add_column :posts, :reply_to_user_id, :integer diff --git a/db/migrate/20130320012100_add_user_indexes_to_posts_and_topics.rb b/db/migrate/20130320012100_add_user_indexes_to_posts_and_topics.rb index 89bdb3aee4b..cdd421f34b2 100644 --- a/db/migrate/20130320012100_add_user_indexes_to_posts_and_topics.rb +++ b/db/migrate/20130320012100_add_user_indexes_to_posts_and_topics.rb @@ -1,4 +1,4 @@ -class AddUserIndexesToPostsAndTopics < ActiveRecord::Migration +class AddUserIndexesToPostsAndTopics < ActiveRecord::Migration[4.2] def up execute "CREATE INDEX idx_posts_user_id_deleted_at ON posts(user_id) WHERE deleted_at IS NULL" diff --git a/db/migrate/20130320024345_add_moderator_to_user.rb b/db/migrate/20130320024345_add_moderator_to_user.rb index 62d466af736..e8943b7dcaf 100644 --- a/db/migrate/20130320024345_add_moderator_to_user.rb +++ b/db/migrate/20130320024345_add_moderator_to_user.rb @@ -1,4 +1,4 @@ -class AddModeratorToUser < ActiveRecord::Migration +class AddModeratorToUser < ActiveRecord::Migration[4.2] def up add_column :users, :moderator, :boolean, default: false execute "UPDATE users SET trust_level = 1, moderator = 't' where trust_level = 5" diff --git a/db/migrate/20130321154905_remove_oneboxes_from_db.rb b/db/migrate/20130321154905_remove_oneboxes_from_db.rb index 8cf4c1cfef6..75c25d064a7 100644 --- a/db/migrate/20130321154905_remove_oneboxes_from_db.rb +++ b/db/migrate/20130321154905_remove_oneboxes_from_db.rb @@ -1,4 +1,4 @@ -class RemoveOneboxesFromDb < ActiveRecord::Migration +class RemoveOneboxesFromDb < ActiveRecord::Migration[4.2] def up drop_table :post_onebox_renders drop_table :onebox_renders diff --git a/db/migrate/20130322183614_add_percent_rank_to_posts.rb b/db/migrate/20130322183614_add_percent_rank_to_posts.rb index 25554a94e05..e3d54a70319 100644 --- a/db/migrate/20130322183614_add_percent_rank_to_posts.rb +++ b/db/migrate/20130322183614_add_percent_rank_to_posts.rb @@ -1,4 +1,4 @@ -class AddPercentRankToPosts < ActiveRecord::Migration +class AddPercentRankToPosts < ActiveRecord::Migration[4.2] def change add_column :posts, :percent_rank, :float, default: 1.0 diff --git a/db/migrate/20130326210101_add_hotness_to_category.rb b/db/migrate/20130326210101_add_hotness_to_category.rb index 19412d7cb51..3dca552afc8 100644 --- a/db/migrate/20130326210101_add_hotness_to_category.rb +++ b/db/migrate/20130326210101_add_hotness_to_category.rb @@ -1,4 +1,4 @@ -class AddHotnessToCategory < ActiveRecord::Migration +class AddHotnessToCategory < ActiveRecord::Migration[4.2] def change add_column :categories, :hotness, :float, default: 5.0, null: false end diff --git a/db/migrate/20130327185852_update_site_settings_for_hot.rb b/db/migrate/20130327185852_update_site_settings_for_hot.rb index 1040a2ccc7f..46b3c06a573 100644 --- a/db/migrate/20130327185852_update_site_settings_for_hot.rb +++ b/db/migrate/20130327185852_update_site_settings_for_hot.rb @@ -1,4 +1,4 @@ -class UpdateSiteSettingsForHot < ActiveRecord::Migration +class UpdateSiteSettingsForHot < ActiveRecord::Migration[4.2] def up execute "UPDATE site_settings SET value = REPLACE(value, 'popular|', 'latest|hot|') where name = 'top_menu'" end diff --git a/db/migrate/20130328162943_create_hot_topics.rb b/db/migrate/20130328162943_create_hot_topics.rb index 21b5f8a2d93..018c13fc721 100644 --- a/db/migrate/20130328162943_create_hot_topics.rb +++ b/db/migrate/20130328162943_create_hot_topics.rb @@ -1,4 +1,4 @@ -class CreateHotTopics < ActiveRecord::Migration +class CreateHotTopics < ActiveRecord::Migration[4.2] def change create_table :hot_topics, force: true do |t| t.integer :topic_id, null: false diff --git a/db/migrate/20130328182433_add_score_to_topics.rb b/db/migrate/20130328182433_add_score_to_topics.rb index 2c0a2612edc..44fb14904dc 100644 --- a/db/migrate/20130328182433_add_score_to_topics.rb +++ b/db/migrate/20130328182433_add_score_to_topics.rb @@ -1,4 +1,4 @@ -class AddScoreToTopics < ActiveRecord::Migration +class AddScoreToTopics < ActiveRecord::Migration[4.2] def change add_column :topics, :score, :float add_column :topics, :percent_rank, :float, null: false, default: 1.0 diff --git a/db/migrate/20130402210723_add_values_to_hot_topics.rb b/db/migrate/20130402210723_add_values_to_hot_topics.rb index dab4598a6c6..989b91d77db 100644 --- a/db/migrate/20130402210723_add_values_to_hot_topics.rb +++ b/db/migrate/20130402210723_add_values_to_hot_topics.rb @@ -1,4 +1,4 @@ -class AddValuesToHotTopics < ActiveRecord::Migration +class AddValuesToHotTopics < ActiveRecord::Migration[4.2] def change add_column :hot_topics, :random_bias, :float add_column :hot_topics, :random_multiplier, :float diff --git a/db/migrate/20130404143437_create_site_contents.rb b/db/migrate/20130404143437_create_site_contents.rb index f4241a6a464..f35acd90216 100644 --- a/db/migrate/20130404143437_create_site_contents.rb +++ b/db/migrate/20130404143437_create_site_contents.rb @@ -1,4 +1,4 @@ -class CreateSiteContents < ActiveRecord::Migration +class CreateSiteContents < ActiveRecord::Migration[4.2] def change create_table :site_contents, force: true, id: false do |t| t.string :content_type, null: false diff --git a/db/migrate/20130404232558_add_user_extras.rb b/db/migrate/20130404232558_add_user_extras.rb index 70c75482e56..2f2b5ec6c3f 100644 --- a/db/migrate/20130404232558_add_user_extras.rb +++ b/db/migrate/20130404232558_add_user_extras.rb @@ -1,4 +1,4 @@ -class AddUserExtras < ActiveRecord::Migration +class AddUserExtras < ActiveRecord::Migration[4.2] def up # NOTE: our user table is getting bloated, we probably want to split it for performance diff --git a/db/migrate/20130411205132_create_admin_logs.rb b/db/migrate/20130411205132_create_admin_logs.rb index f79b27f06a3..0dc74ac8fd8 100644 --- a/db/migrate/20130411205132_create_admin_logs.rb +++ b/db/migrate/20130411205132_create_admin_logs.rb @@ -1,4 +1,4 @@ -class CreateAdminLogs < ActiveRecord::Migration +class CreateAdminLogs < ActiveRecord::Migration[4.2] def up create_table :admin_logs, force: true do |t| t.integer :action, null: false diff --git a/db/migrate/20130412015502_correct_counts_on_posts.rb b/db/migrate/20130412015502_correct_counts_on_posts.rb index 4711c14f36f..abc798964a3 100644 --- a/db/migrate/20130412015502_correct_counts_on_posts.rb +++ b/db/migrate/20130412015502_correct_counts_on_posts.rb @@ -1,4 +1,4 @@ -class CorrectCountsOnPosts < ActiveRecord::Migration +class CorrectCountsOnPosts < ActiveRecord::Migration[4.2] def change rename_column :posts, :custom_flag_count, :notify_moderators_count add_column :posts, :notify_user_count, :integer, default: 0, null: false diff --git a/db/migrate/20130412020156_correct_counts_on_topics.rb b/db/migrate/20130412020156_correct_counts_on_topics.rb index bae4bf86f71..67ac99527e6 100644 --- a/db/migrate/20130412020156_correct_counts_on_topics.rb +++ b/db/migrate/20130412020156_correct_counts_on_topics.rb @@ -1,4 +1,4 @@ -class CorrectCountsOnTopics < ActiveRecord::Migration +class CorrectCountsOnTopics < ActiveRecord::Migration[4.2] def change rename_column :topics, :custom_flag_count, :notify_moderators_count add_column :topics, :notify_user_count, :integer, default: 0, null: false diff --git a/db/migrate/20130416004607_create_groups.rb b/db/migrate/20130416004607_create_groups.rb index 30969acad14..5fb442d00ab 100644 --- a/db/migrate/20130416004607_create_groups.rb +++ b/db/migrate/20130416004607_create_groups.rb @@ -1,4 +1,4 @@ -class CreateGroups < ActiveRecord::Migration +class CreateGroups < ActiveRecord::Migration[4.2] def change create_table :groups, force: true do |t| t.string :name, null: false diff --git a/db/migrate/20130416004933_group_users.rb b/db/migrate/20130416004933_group_users.rb index 3dfa140dc49..238ddd19519 100644 --- a/db/migrate/20130416004933_group_users.rb +++ b/db/migrate/20130416004933_group_users.rb @@ -1,4 +1,4 @@ -class GroupUsers < ActiveRecord::Migration +class GroupUsers < ActiveRecord::Migration[4.2] def change create_table :group_users, force: true do |t| t.integer :group_id, null: false diff --git a/db/migrate/20130416170855_add_subtype_to_topics.rb b/db/migrate/20130416170855_add_subtype_to_topics.rb index 93aa0c32284..a148cf76b3b 100644 --- a/db/migrate/20130416170855_add_subtype_to_topics.rb +++ b/db/migrate/20130416170855_add_subtype_to_topics.rb @@ -1,4 +1,4 @@ -class AddSubtypeToTopics < ActiveRecord::Migration +class AddSubtypeToTopics < ActiveRecord::Migration[4.2] def up add_column :topics, :subtype, :string execute "update topics set subtype = 'user_to_user' where archetype = 'private_message'" diff --git a/db/migrate/20130419195746_increase_data_length_on_notifications.rb b/db/migrate/20130419195746_increase_data_length_on_notifications.rb index 796b83c7e48..ac3234fe0cd 100644 --- a/db/migrate/20130419195746_increase_data_length_on_notifications.rb +++ b/db/migrate/20130419195746_increase_data_length_on_notifications.rb @@ -1,4 +1,4 @@ -class IncreaseDataLengthOnNotifications < ActiveRecord::Migration +class IncreaseDataLengthOnNotifications < ActiveRecord::Migration[4.2] def up execute "ALTER TABLE notifications ALTER COLUMN data TYPE VARCHAR(1000)" end diff --git a/db/migrate/20130422050626_add_related_post_id_to_post_actions.rb b/db/migrate/20130422050626_add_related_post_id_to_post_actions.rb index 7f3bbcf16c1..23a89836d57 100644 --- a/db/migrate/20130422050626_add_related_post_id_to_post_actions.rb +++ b/db/migrate/20130422050626_add_related_post_id_to_post_actions.rb @@ -1,4 +1,4 @@ -class AddRelatedPostIdToPostActions < ActiveRecord::Migration +class AddRelatedPostIdToPostActions < ActiveRecord::Migration[4.2] def change add_column :post_actions, :related_post_id, :integer end diff --git a/db/migrate/20130424015746_add_slug_to_topics.rb b/db/migrate/20130424015746_add_slug_to_topics.rb index 729cbfd07e1..cd3458e590e 100644 --- a/db/migrate/20130424015746_add_slug_to_topics.rb +++ b/db/migrate/20130424015746_add_slug_to_topics.rb @@ -1,4 +1,4 @@ -class AddSlugToTopics < ActiveRecord::Migration +class AddSlugToTopics < ActiveRecord::Migration[4.2] def change add_column :topics, :slug, :string end diff --git a/db/migrate/20130424055025_add_user_id_to_incoming_links.rb b/db/migrate/20130424055025_add_user_id_to_incoming_links.rb index 623e5af9158..36a428c87dd 100644 --- a/db/migrate/20130424055025_add_user_id_to_incoming_links.rb +++ b/db/migrate/20130424055025_add_user_id_to_incoming_links.rb @@ -1,4 +1,4 @@ -class AddUserIdToIncomingLinks < ActiveRecord::Migration +class AddUserIdToIncomingLinks < ActiveRecord::Migration[4.2] def change add_column :incoming_links, :user_id, :integer end diff --git a/db/migrate/20130426044914_allow_nulls_in_incoming_links.rb b/db/migrate/20130426044914_allow_nulls_in_incoming_links.rb index d4b92156a08..92827f5cd18 100644 --- a/db/migrate/20130426044914_allow_nulls_in_incoming_links.rb +++ b/db/migrate/20130426044914_allow_nulls_in_incoming_links.rb @@ -1,4 +1,4 @@ -class AllowNullsInIncomingLinks < ActiveRecord::Migration +class AllowNullsInIncomingLinks < ActiveRecord::Migration[4.2] def change change_column :incoming_links, :referer, :string, limit: 1000, null: true change_column :incoming_links, :domain, :string, limit: 100, null: true diff --git a/db/migrate/20130426052257_add_incoming_ip_current_user_id_to_incoming_links.rb b/db/migrate/20130426052257_add_incoming_ip_current_user_id_to_incoming_links.rb index bfc8eb830a0..b89f599dbf9 100644 --- a/db/migrate/20130426052257_add_incoming_ip_current_user_id_to_incoming_links.rb +++ b/db/migrate/20130426052257_add_incoming_ip_current_user_id_to_incoming_links.rb @@ -1,4 +1,4 @@ -class AddIncomingIpCurrentUserIdToIncomingLinks < ActiveRecord::Migration +class AddIncomingIpCurrentUserIdToIncomingLinks < ActiveRecord::Migration[4.2] def change add_column :incoming_links, :ip_address, :inet add_column :incoming_links, :current_user_id, :int diff --git a/db/migrate/20130428194335_add_unstarred_at_to_topic_users.rb b/db/migrate/20130428194335_add_unstarred_at_to_topic_users.rb index 1f74eca660e..279ff2fd6ac 100644 --- a/db/migrate/20130428194335_add_unstarred_at_to_topic_users.rb +++ b/db/migrate/20130428194335_add_unstarred_at_to_topic_users.rb @@ -1,4 +1,4 @@ -class AddUnstarredAtToTopicUsers < ActiveRecord::Migration +class AddUnstarredAtToTopicUsers < ActiveRecord::Migration[4.2] def change add_column :topic_users, :unstarred_at, :datetime end diff --git a/db/migrate/20130429000101_add_security_to_categories.rb b/db/migrate/20130429000101_add_security_to_categories.rb index 5881bf07ad8..dc6bbef6684 100644 --- a/db/migrate/20130429000101_add_security_to_categories.rb +++ b/db/migrate/20130429000101_add_security_to_categories.rb @@ -1,4 +1,4 @@ -class AddSecurityToCategories < ActiveRecord::Migration +class AddSecurityToCategories < ActiveRecord::Migration[4.2] def change add_column :categories, :secure, :boolean, default: false, null: false diff --git a/db/migrate/20130430052751_add_topic_allowed_groups.rb b/db/migrate/20130430052751_add_topic_allowed_groups.rb index 57bb23fbb21..a83f8645711 100644 --- a/db/migrate/20130430052751_add_topic_allowed_groups.rb +++ b/db/migrate/20130430052751_add_topic_allowed_groups.rb @@ -1,4 +1,4 @@ -class AddTopicAllowedGroups < ActiveRecord::Migration +class AddTopicAllowedGroups < ActiveRecord::Migration[4.2] def change create_table :topic_allowed_groups, force: true do |t| # oops diff --git a/db/migrate/20130501105651_fix_topic_allowed_groups.rb b/db/migrate/20130501105651_fix_topic_allowed_groups.rb index cf12cedff9d..02e3ec3afc5 100644 --- a/db/migrate/20130501105651_fix_topic_allowed_groups.rb +++ b/db/migrate/20130501105651_fix_topic_allowed_groups.rb @@ -1,4 +1,4 @@ -class FixTopicAllowedGroups < ActiveRecord::Migration +class FixTopicAllowedGroups < ActiveRecord::Migration[4.2] def change # big oops remove_column :topic_allowed_groups, :integer diff --git a/db/migrate/20130506020935_add_automatic_to_groups.rb b/db/migrate/20130506020935_add_automatic_to_groups.rb index e62081c7b15..e04bac57aaa 100644 --- a/db/migrate/20130506020935_add_automatic_to_groups.rb +++ b/db/migrate/20130506020935_add_automatic_to_groups.rb @@ -1,4 +1,4 @@ -class AddAutomaticToGroups < ActiveRecord::Migration +class AddAutomaticToGroups < ActiveRecord::Migration[4.2] def up add_column :groups, :automatic, :boolean, default: false, null: false diff --git a/db/migrate/20130506185042_add_auto_close_at_to_topics.rb b/db/migrate/20130506185042_add_auto_close_at_to_topics.rb index c4f9987f58c..297608e8e7e 100644 --- a/db/migrate/20130506185042_add_auto_close_at_to_topics.rb +++ b/db/migrate/20130506185042_add_auto_close_at_to_topics.rb @@ -1,4 +1,4 @@ -class AddAutoCloseAtToTopics < ActiveRecord::Migration +class AddAutoCloseAtToTopics < ActiveRecord::Migration[4.2] def change add_column :topics, :auto_close_at, :datetime add_column :topics, :auto_close_user_id, :integer diff --git a/db/migrate/20130508040235_add_user_count_to_groups.rb b/db/migrate/20130508040235_add_user_count_to_groups.rb index cae58bc21e3..7ab95b79bc7 100644 --- a/db/migrate/20130508040235_add_user_count_to_groups.rb +++ b/db/migrate/20130508040235_add_user_count_to_groups.rb @@ -1,4 +1,4 @@ -class AddUserCountToGroups < ActiveRecord::Migration +class AddUserCountToGroups < ActiveRecord::Migration[4.2] def change add_column :groups, :user_count, :integer, null: false, default: 0 end diff --git a/db/migrate/20130509040248_update_sequence_for_groups.rb b/db/migrate/20130509040248_update_sequence_for_groups.rb index 0c0c70b6823..7bf85eea4c7 100644 --- a/db/migrate/20130509040248_update_sequence_for_groups.rb +++ b/db/migrate/20130509040248_update_sequence_for_groups.rb @@ -1,4 +1,4 @@ -class UpdateSequenceForGroups < ActiveRecord::Migration +class UpdateSequenceForGroups < ActiveRecord::Migration[4.2] def up # even if you alter a sequence you still need to set the seq execute < 0") if result[0] && result[0]["count"].to_i > (0) diff --git a/db/migrate/20130625201113_add_title_to_users.rb b/db/migrate/20130625201113_add_title_to_users.rb index 8b921702a64..cb63d4fa5b9 100644 --- a/db/migrate/20130625201113_add_title_to_users.rb +++ b/db/migrate/20130625201113_add_title_to_users.rb @@ -1,4 +1,4 @@ -class AddTitleToUsers < ActiveRecord::Migration +class AddTitleToUsers < ActiveRecord::Migration[4.2] def change add_column :users, :title, :string end diff --git a/db/migrate/20130709184941_add_deleted_by_id_to_posts.rb b/db/migrate/20130709184941_add_deleted_by_id_to_posts.rb index 7f725b19854..d322f05dd76 100644 --- a/db/migrate/20130709184941_add_deleted_by_id_to_posts.rb +++ b/db/migrate/20130709184941_add_deleted_by_id_to_posts.rb @@ -1,4 +1,4 @@ -class AddDeletedByIdToPosts < ActiveRecord::Migration +class AddDeletedByIdToPosts < ActiveRecord::Migration[4.2] def change add_column :posts, :deleted_by_id, :integer, null: true add_column :topics, :deleted_by_id, :integer, null: true diff --git a/db/migrate/20130710201248_add_nuked_user_to_posts.rb b/db/migrate/20130710201248_add_nuked_user_to_posts.rb index 6c72dd26844..14e9aad0efd 100644 --- a/db/migrate/20130710201248_add_nuked_user_to_posts.rb +++ b/db/migrate/20130710201248_add_nuked_user_to_posts.rb @@ -1,4 +1,4 @@ -class AddNukedUserToPosts < ActiveRecord::Migration +class AddNukedUserToPosts < ActiveRecord::Migration[4.2] def change add_column :posts, :nuked_user, :boolean, default: false end diff --git a/db/migrate/20130712041133_add_permission_type_to_category_groups.rb b/db/migrate/20130712041133_add_permission_type_to_category_groups.rb index ae227562e3c..4ddab5fe075 100644 --- a/db/migrate/20130712041133_add_permission_type_to_category_groups.rb +++ b/db/migrate/20130712041133_add_permission_type_to_category_groups.rb @@ -1,4 +1,4 @@ -class AddPermissionTypeToCategoryGroups < ActiveRecord::Migration +class AddPermissionTypeToCategoryGroups < ActiveRecord::Migration[4.2] def change # 1 is full permissions add_column :category_groups, :permission_type, :integer, default: 1 diff --git a/db/migrate/20130712163509_add_missing_id_columns.rb b/db/migrate/20130712163509_add_missing_id_columns.rb index 97987e0bc51..a81cadc696e 100644 --- a/db/migrate/20130712163509_add_missing_id_columns.rb +++ b/db/migrate/20130712163509_add_missing_id_columns.rb @@ -1,4 +1,4 @@ -class AddMissingIdColumns < ActiveRecord::Migration +class AddMissingIdColumns < ActiveRecord::Migration[4.2] def up add_column :category_featured_topics, :id, :primary_key add_column :topic_users, :id, :primary_key diff --git a/db/migrate/20130723212758_rename_admin_log.rb b/db/migrate/20130723212758_rename_admin_log.rb index 5e33a253256..e7f2e5471b2 100644 --- a/db/migrate/20130723212758_rename_admin_log.rb +++ b/db/migrate/20130723212758_rename_admin_log.rb @@ -1,4 +1,4 @@ -class RenameAdminLog < ActiveRecord::Migration +class RenameAdminLog < ActiveRecord::Migration[4.2] def up rename_table :admin_logs, :staff_action_logs rename_column :staff_action_logs, :admin_id, :staff_user_id diff --git a/db/migrate/20130724201552_create_blocked_emails.rb b/db/migrate/20130724201552_create_blocked_emails.rb index 557c1363899..e3e7b35600e 100644 --- a/db/migrate/20130724201552_create_blocked_emails.rb +++ b/db/migrate/20130724201552_create_blocked_emails.rb @@ -1,4 +1,4 @@ -class CreateBlockedEmails < ActiveRecord::Migration +class CreateBlockedEmails < ActiveRecord::Migration[4.2] def change create_table :blocked_emails do |t| t.string :email, null: false diff --git a/db/migrate/20130725213613_add_more_to_staff_action_log.rb b/db/migrate/20130725213613_add_more_to_staff_action_log.rb index c2385f6afca..dbefeedcf7d 100644 --- a/db/migrate/20130725213613_add_more_to_staff_action_log.rb +++ b/db/migrate/20130725213613_add_more_to_staff_action_log.rb @@ -1,4 +1,4 @@ -class AddMoreToStaffActionLog < ActiveRecord::Migration +class AddMoreToStaffActionLog < ActiveRecord::Migration[4.2] def change add_column :staff_action_logs, :context, :string add_column :staff_action_logs, :ip_address, :string diff --git a/db/migrate/20130728172550_add_url_to_optimized_images.rb b/db/migrate/20130728172550_add_url_to_optimized_images.rb index f22892014e5..cf881a2002d 100644 --- a/db/migrate/20130728172550_add_url_to_optimized_images.rb +++ b/db/migrate/20130728172550_add_url_to_optimized_images.rb @@ -1,4 +1,4 @@ -class AddUrlToOptimizedImages < ActiveRecord::Migration +class AddUrlToOptimizedImages < ActiveRecord::Migration[4.2] def up # add a nullable url column add_column :optimized_images, :url, :string diff --git a/db/migrate/20130731163035_add_report_index_to_incoming_links.rb b/db/migrate/20130731163035_add_report_index_to_incoming_links.rb index 7d02541696b..c470979e0fc 100644 --- a/db/migrate/20130731163035_add_report_index_to_incoming_links.rb +++ b/db/migrate/20130731163035_add_report_index_to_incoming_links.rb @@ -1,4 +1,4 @@ -class AddReportIndexToIncomingLinks < ActiveRecord::Migration +class AddReportIndexToIncomingLinks < ActiveRecord::Migration[4.2] def change add_index :incoming_links, [:created_at, :user_id] add_index :incoming_links, [:created_at, :domain] diff --git a/db/migrate/20130807202516_add_last_match_index_to_blocked_emails.rb b/db/migrate/20130807202516_add_last_match_index_to_blocked_emails.rb index 4a49304ee4d..ad3828c7a22 100644 --- a/db/migrate/20130807202516_add_last_match_index_to_blocked_emails.rb +++ b/db/migrate/20130807202516_add_last_match_index_to_blocked_emails.rb @@ -1,4 +1,4 @@ -class AddLastMatchIndexToBlockedEmails < ActiveRecord::Migration +class AddLastMatchIndexToBlockedEmails < ActiveRecord::Migration[4.2] def change add_index :blocked_emails, :last_match_at end diff --git a/db/migrate/20130809160751_fix_seen_notification_ids.rb b/db/migrate/20130809160751_fix_seen_notification_ids.rb index 9a83d826051..fce5ae11658 100644 --- a/db/migrate/20130809160751_fix_seen_notification_ids.rb +++ b/db/migrate/20130809160751_fix_seen_notification_ids.rb @@ -1,4 +1,4 @@ -class FixSeenNotificationIds < ActiveRecord::Migration +class FixSeenNotificationIds < ActiveRecord::Migration[4.2] def up # There was an error where `seen_notification_id` was being updated incorrectly. diff --git a/db/migrate/20130809204732_add_filter_indexes_to_staff_action_logs.rb b/db/migrate/20130809204732_add_filter_indexes_to_staff_action_logs.rb index 24aa1ad1f8a..db5a1b47d8c 100644 --- a/db/migrate/20130809204732_add_filter_indexes_to_staff_action_logs.rb +++ b/db/migrate/20130809204732_add_filter_indexes_to_staff_action_logs.rb @@ -1,4 +1,4 @@ -class AddFilterIndexesToStaffActionLogs < ActiveRecord::Migration +class AddFilterIndexesToStaffActionLogs < ActiveRecord::Migration[4.2] def change add_index :staff_action_logs, [:action, :id] add_index :staff_action_logs, [:staff_user_id, :id] diff --git a/db/migrate/20130809211409_add_avatar_to_users.rb b/db/migrate/20130809211409_add_avatar_to_users.rb index 4d570aeee7d..c891fbdecc3 100644 --- a/db/migrate/20130809211409_add_avatar_to_users.rb +++ b/db/migrate/20130809211409_add_avatar_to_users.rb @@ -1,4 +1,4 @@ -class AddAvatarToUsers < ActiveRecord::Migration +class AddAvatarToUsers < ActiveRecord::Migration[4.2] def change add_column :users, :use_uploaded_avatar, :boolean, default: false add_column :users, :uploaded_avatar_template, :string diff --git a/db/migrate/20130813204212_create_screened_urls.rb b/db/migrate/20130813204212_create_screened_urls.rb index d5e6e3ba892..e9887141aad 100644 --- a/db/migrate/20130813204212_create_screened_urls.rb +++ b/db/migrate/20130813204212_create_screened_urls.rb @@ -1,4 +1,4 @@ -class CreateScreenedUrls < ActiveRecord::Migration +class CreateScreenedUrls < ActiveRecord::Migration[4.2] def change create_table :screened_urls do |t| t.string :url, null: false diff --git a/db/migrate/20130813224817_rename_blocked_emails_to_screened_emails.rb b/db/migrate/20130813224817_rename_blocked_emails_to_screened_emails.rb index 5f593e445ad..6518c622b69 100644 --- a/db/migrate/20130813224817_rename_blocked_emails_to_screened_emails.rb +++ b/db/migrate/20130813224817_rename_blocked_emails_to_screened_emails.rb @@ -1,4 +1,4 @@ -class RenameBlockedEmailsToScreenedEmails < ActiveRecord::Migration +class RenameBlockedEmailsToScreenedEmails < ActiveRecord::Migration[4.2] def change rename_table :blocked_emails, :screened_emails end diff --git a/db/migrate/20130816024250_create_oauth2_user_infos.rb b/db/migrate/20130816024250_create_oauth2_user_infos.rb index d70ab81cc91..d29ec19b194 100644 --- a/db/migrate/20130816024250_create_oauth2_user_infos.rb +++ b/db/migrate/20130816024250_create_oauth2_user_infos.rb @@ -1,4 +1,4 @@ -class CreateOauth2UserInfos < ActiveRecord::Migration +class CreateOauth2UserInfos < ActiveRecord::Migration[4.2] def change create_table :oauth2_user_infos do |t| t.integer :user_id, null: false diff --git a/db/migrate/20130819192358_add_value_columns_to_staff_action_logs.rb b/db/migrate/20130819192358_add_value_columns_to_staff_action_logs.rb index 5ea550ece92..4251b122f8d 100644 --- a/db/migrate/20130819192358_add_value_columns_to_staff_action_logs.rb +++ b/db/migrate/20130819192358_add_value_columns_to_staff_action_logs.rb @@ -1,4 +1,4 @@ -class AddValueColumnsToStaffActionLogs < ActiveRecord::Migration +class AddValueColumnsToStaffActionLogs < ActiveRecord::Migration[4.2] def change add_column :staff_action_logs, :subject, :text add_column :staff_action_logs, :previous_value, :text diff --git a/db/migrate/20130820174431_add_subject_index_to_staff_action_logs.rb b/db/migrate/20130820174431_add_subject_index_to_staff_action_logs.rb index 24471d4c03a..47459b3bfc5 100644 --- a/db/migrate/20130820174431_add_subject_index_to_staff_action_logs.rb +++ b/db/migrate/20130820174431_add_subject_index_to_staff_action_logs.rb @@ -1,4 +1,4 @@ -class AddSubjectIndexToStaffActionLogs < ActiveRecord::Migration +class AddSubjectIndexToStaffActionLogs < ActiveRecord::Migration[4.2] def change add_index :staff_action_logs, [:subject, :id] end diff --git a/db/migrate/20130822213513_add_ip_address_to_screening_tables.rb b/db/migrate/20130822213513_add_ip_address_to_screening_tables.rb index 73eb383248d..b5a5490e73a 100644 --- a/db/migrate/20130822213513_add_ip_address_to_screening_tables.rb +++ b/db/migrate/20130822213513_add_ip_address_to_screening_tables.rb @@ -1,4 +1,4 @@ -class AddIpAddressToScreeningTables < ActiveRecord::Migration +class AddIpAddressToScreeningTables < ActiveRecord::Migration[4.2] def change add_column :screened_emails, :ip_address, :inet add_column :screened_urls, :ip_address, :inet diff --git a/db/migrate/20130823201420_drop_defaults_on_email_digest_columns_of_users.rb b/db/migrate/20130823201420_drop_defaults_on_email_digest_columns_of_users.rb index 45b3f326762..0f113875753 100644 --- a/db/migrate/20130823201420_drop_defaults_on_email_digest_columns_of_users.rb +++ b/db/migrate/20130823201420_drop_defaults_on_email_digest_columns_of_users.rb @@ -1,4 +1,4 @@ -class DropDefaultsOnEmailDigestColumnsOfUsers < ActiveRecord::Migration +class DropDefaultsOnEmailDigestColumnsOfUsers < ActiveRecord::Migration[4.2] def up change_column_default :users, :email_digests, nil change_column :users, :digest_after_days, :integer, default: nil, null: true diff --git a/db/migrate/20130826011521_create_plugin_store_rows.rb b/db/migrate/20130826011521_create_plugin_store_rows.rb index acf0e2c38dd..c26e09e0b02 100644 --- a/db/migrate/20130826011521_create_plugin_store_rows.rb +++ b/db/migrate/20130826011521_create_plugin_store_rows.rb @@ -1,4 +1,4 @@ -class CreatePluginStoreRows < ActiveRecord::Migration +class CreatePluginStoreRows < ActiveRecord::Migration[4.2] def change create_table :plugin_store_rows do |table| table.string :plugin_name, null: false diff --git a/db/migrate/20130828192526_fix_optimized_images_urls.rb b/db/migrate/20130828192526_fix_optimized_images_urls.rb index c605b7b74ed..31eb7d61cb4 100644 --- a/db/migrate/20130828192526_fix_optimized_images_urls.rb +++ b/db/migrate/20130828192526_fix_optimized_images_urls.rb @@ -1,4 +1,4 @@ -class FixOptimizedImagesUrls < ActiveRecord::Migration +class FixOptimizedImagesUrls < ActiveRecord::Migration[4.2] def up # `AddUrlToOptimizedImages` was wrongly computing the URLs. This fixes it! execute "UPDATE optimized_images diff --git a/db/migrate/20130903154323_allow_null_user_id_on_posts.rb b/db/migrate/20130903154323_allow_null_user_id_on_posts.rb index 8a9141268d5..8afa0a9d1e4 100644 --- a/db/migrate/20130903154323_allow_null_user_id_on_posts.rb +++ b/db/migrate/20130903154323_allow_null_user_id_on_posts.rb @@ -1,4 +1,4 @@ -class AllowNullUserIdOnPosts < ActiveRecord::Migration +class AllowNullUserIdOnPosts < ActiveRecord::Migration[4.2] def up change_column :posts, :user_id, :integer, null: true execute "UPDATE posts SET user_id = NULL WHERE nuked_user = true" diff --git a/db/migrate/20130904181208_allow_null_user_id_on_topics.rb b/db/migrate/20130904181208_allow_null_user_id_on_topics.rb index 48e9b157d5d..1cf399f4b37 100644 --- a/db/migrate/20130904181208_allow_null_user_id_on_topics.rb +++ b/db/migrate/20130904181208_allow_null_user_id_on_topics.rb @@ -1,4 +1,4 @@ -class AllowNullUserIdOnTopics < ActiveRecord::Migration +class AllowNullUserIdOnTopics < ActiveRecord::Migration[4.2] def up change_column :topics, :user_id, :integer, null: true end diff --git a/db/migrate/20130906081326_rename_system_username.rb b/db/migrate/20130906081326_rename_system_username.rb index 38550ddc482..13e3dcc9127 100644 --- a/db/migrate/20130906081326_rename_system_username.rb +++ b/db/migrate/20130906081326_rename_system_username.rb @@ -1,4 +1,4 @@ -class RenameSystemUsername < ActiveRecord::Migration +class RenameSystemUsername < ActiveRecord::Migration[4.2] def up execute "update site_settings set name = 'site_contact_username' where name = 'system_username'" end diff --git a/db/migrate/20130906171631_add_index_to_uploads.rb b/db/migrate/20130906171631_add_index_to_uploads.rb index 38e91b75b76..f52a61e8b4a 100644 --- a/db/migrate/20130906171631_add_index_to_uploads.rb +++ b/db/migrate/20130906171631_add_index_to_uploads.rb @@ -1,4 +1,4 @@ -class AddIndexToUploads < ActiveRecord::Migration +class AddIndexToUploads < ActiveRecord::Migration[4.2] def change add_index :uploads, [:id, :url] end diff --git a/db/migrate/20130910040235_index_topics_for_front_page.rb b/db/migrate/20130910040235_index_topics_for_front_page.rb index 33dd7de6787..7b495958dea 100644 --- a/db/migrate/20130910040235_index_topics_for_front_page.rb +++ b/db/migrate/20130910040235_index_topics_for_front_page.rb @@ -1,4 +1,4 @@ -class IndexTopicsForFrontPage < ActiveRecord::Migration +class IndexTopicsForFrontPage < ActiveRecord::Migration[4.2] def change add_index :topics, [:deleted_at, :visible, :archetype, :id] # covering index for join diff --git a/db/migrate/20130910220317_rename_staff_action_logs_to_user_history.rb b/db/migrate/20130910220317_rename_staff_action_logs_to_user_history.rb index e5163dd1eaa..b11fb90b29e 100644 --- a/db/migrate/20130910220317_rename_staff_action_logs_to_user_history.rb +++ b/db/migrate/20130910220317_rename_staff_action_logs_to_user_history.rb @@ -1,4 +1,4 @@ -class RenameStaffActionLogsToUserHistory < ActiveRecord::Migration +class RenameStaffActionLogsToUserHistory < ActiveRecord::Migration[4.2] def up remove_index :staff_action_logs, [:staff_user_id, :id] rename_table :staff_action_logs, :user_histories diff --git a/db/migrate/20130911182437_create_user_stats.rb b/db/migrate/20130911182437_create_user_stats.rb index ff3f78ab185..b7936b37104 100644 --- a/db/migrate/20130911182437_create_user_stats.rb +++ b/db/migrate/20130911182437_create_user_stats.rb @@ -1,4 +1,4 @@ -class CreateUserStats < ActiveRecord::Migration +class CreateUserStats < ActiveRecord::Migration[4.2] def up create_table :user_stats, id: false do |t| t.references :user, null: false diff --git a/db/migrate/20130912185218_acting_user_null.rb b/db/migrate/20130912185218_acting_user_null.rb index d03eabe527f..e6a8b92aa77 100644 --- a/db/migrate/20130912185218_acting_user_null.rb +++ b/db/migrate/20130912185218_acting_user_null.rb @@ -1,4 +1,4 @@ -class ActingUserNull < ActiveRecord::Migration +class ActingUserNull < ActiveRecord::Migration[4.2] def up change_column :user_histories, :acting_user_id, :integer, null: true end diff --git a/db/migrate/20130913210454_add_mobile_to_site_customizations.rb b/db/migrate/20130913210454_add_mobile_to_site_customizations.rb index 681788ce6e1..f66162dc299 100644 --- a/db/migrate/20130913210454_add_mobile_to_site_customizations.rb +++ b/db/migrate/20130913210454_add_mobile_to_site_customizations.rb @@ -1,4 +1,4 @@ -class AddMobileToSiteCustomizations < ActiveRecord::Migration +class AddMobileToSiteCustomizations < ActiveRecord::Migration[4.2] def change add_column :site_customizations, :mobile_stylesheet, :text add_column :site_customizations, :mobile_header, :text diff --git a/db/migrate/20130917174738_add_topic_id_to_user_histories.rb b/db/migrate/20130917174738_add_topic_id_to_user_histories.rb index 2b0c17946d9..0347a3edc08 100644 --- a/db/migrate/20130917174738_add_topic_id_to_user_histories.rb +++ b/db/migrate/20130917174738_add_topic_id_to_user_histories.rb @@ -1,4 +1,4 @@ -class AddTopicIdToUserHistories < ActiveRecord::Migration +class AddTopicIdToUserHistories < ActiveRecord::Migration[4.2] def change add_column :user_histories, :topic_id, :integer end diff --git a/db/migrate/20131001060630_add_email_always_to_users.rb b/db/migrate/20131001060630_add_email_always_to_users.rb index c5773574ed2..f8ef7f31a3a 100644 --- a/db/migrate/20131001060630_add_email_always_to_users.rb +++ b/db/migrate/20131001060630_add_email_always_to_users.rb @@ -1,4 +1,4 @@ -class AddEmailAlwaysToUsers < ActiveRecord::Migration +class AddEmailAlwaysToUsers < ActiveRecord::Migration[4.2] def change add_column :users, :email_always, :bool, default: false, null: false end diff --git a/db/migrate/20131002070347_add_user_id_parent_type_index_on_views.rb b/db/migrate/20131002070347_add_user_id_parent_type_index_on_views.rb index 3055c712a84..f20ecc4545c 100644 --- a/db/migrate/20131002070347_add_user_id_parent_type_index_on_views.rb +++ b/db/migrate/20131002070347_add_user_id_parent_type_index_on_views.rb @@ -1,4 +1,4 @@ -class AddUserIdParentTypeIndexOnViews < ActiveRecord::Migration +class AddUserIdParentTypeIndexOnViews < ActiveRecord::Migration[4.2] def change add_index :views, [:user_id, :parent_type, :parent_id] end diff --git a/db/migrate/20131003061137_move_columns_to_user_stats.rb b/db/migrate/20131003061137_move_columns_to_user_stats.rb index b5346a9452e..4212b56bca7 100644 --- a/db/migrate/20131003061137_move_columns_to_user_stats.rb +++ b/db/migrate/20131003061137_move_columns_to_user_stats.rb @@ -1,4 +1,4 @@ -class MoveColumnsToUserStats < ActiveRecord::Migration +class MoveColumnsToUserStats < ActiveRecord::Migration[4.2] def up add_column :user_stats, :topics_entered, :integer, default: 0, null: false add_column :user_stats, :time_read, :integer, default: 0, null: false diff --git a/db/migrate/20131014203951_backfill_post_upload_reverse_index.rb b/db/migrate/20131014203951_backfill_post_upload_reverse_index.rb index d4d121bf81b..d288ef1ec2d 100644 --- a/db/migrate/20131014203951_backfill_post_upload_reverse_index.rb +++ b/db/migrate/20131014203951_backfill_post_upload_reverse_index.rb @@ -1,4 +1,4 @@ -class BackfillPostUploadReverseIndex < ActiveRecord::Migration +class BackfillPostUploadReverseIndex < ActiveRecord::Migration[4.2] def up # clean the reverse index diff --git a/db/migrate/20131015131652_create_post_details.rb b/db/migrate/20131015131652_create_post_details.rb index ab912848257..20b780b9f73 100644 --- a/db/migrate/20131015131652_create_post_details.rb +++ b/db/migrate/20131015131652_create_post_details.rb @@ -1,4 +1,4 @@ -class CreatePostDetails < ActiveRecord::Migration +class CreatePostDetails < ActiveRecord::Migration[4.2] def change create_table :post_details do |t| t.belongs_to :post diff --git a/db/migrate/20131017014509_add_post_count_to_categories.rb b/db/migrate/20131017014509_add_post_count_to_categories.rb index 809eb65e89e..c1db909d769 100644 --- a/db/migrate/20131017014509_add_post_count_to_categories.rb +++ b/db/migrate/20131017014509_add_post_count_to_categories.rb @@ -1,4 +1,4 @@ -class AddPostCountToCategories < ActiveRecord::Migration +class AddPostCountToCategories < ActiveRecord::Migration[4.2] def up add_column :categories, :post_count, :integer, null: false, default: 0 execute <]*)assets\/emoji\/', '\\1plugins\/emoji\/images\/' , 'g') where cooked like '%emoji%'") end diff --git a/db/migrate/20131122064921_increase_twitter_user_id_length.rb b/db/migrate/20131122064921_increase_twitter_user_id_length.rb index 65cb13ce3e1..ab1ee73c0ad 100644 --- a/db/migrate/20131122064921_increase_twitter_user_id_length.rb +++ b/db/migrate/20131122064921_increase_twitter_user_id_length.rb @@ -1,4 +1,4 @@ -class IncreaseTwitterUserIdLength < ActiveRecord::Migration +class IncreaseTwitterUserIdLength < ActiveRecord::Migration[4.2] def change change_column :twitter_user_infos, :twitter_user_id, :bigint end diff --git a/db/migrate/20131206200009_rename_auto_close_days_to_hours.rb b/db/migrate/20131206200009_rename_auto_close_days_to_hours.rb index 6a1f550e84c..f37240a3716 100644 --- a/db/migrate/20131206200009_rename_auto_close_days_to_hours.rb +++ b/db/migrate/20131206200009_rename_auto_close_days_to_hours.rb @@ -1,4 +1,4 @@ -class RenameAutoCloseDaysToHours < ActiveRecord::Migration +class RenameAutoCloseDaysToHours < ActiveRecord::Migration[4.2] def up rename_column :categories, :auto_close_days, :auto_close_hours execute "update categories set auto_close_hours = auto_close_hours * 24" diff --git a/db/migrate/20131209091702_create_post_revisions.rb b/db/migrate/20131209091702_create_post_revisions.rb index f9d613361ba..0cc684cf859 100644 --- a/db/migrate/20131209091702_create_post_revisions.rb +++ b/db/migrate/20131209091702_create_post_revisions.rb @@ -1,4 +1,4 @@ -class CreatePostRevisions < ActiveRecord::Migration +class CreatePostRevisions < ActiveRecord::Migration[4.2] def up create_table :post_revisions do |t| t.belongs_to :user diff --git a/db/migrate/20131209091742_create_topic_revisions.rb b/db/migrate/20131209091742_create_topic_revisions.rb index 94d89bc6dde..ecbb4e2c37e 100644 --- a/db/migrate/20131209091742_create_topic_revisions.rb +++ b/db/migrate/20131209091742_create_topic_revisions.rb @@ -1,4 +1,4 @@ -class CreateTopicRevisions < ActiveRecord::Migration +class CreateTopicRevisions < ActiveRecord::Migration[4.2] def up create_table :topic_revisions do |t| t.belongs_to :user diff --git a/db/migrate/20131210163702_add_word_count_to_posts.rb b/db/migrate/20131210163702_add_word_count_to_posts.rb index f0436ef8306..6f008f8604a 100644 --- a/db/migrate/20131210163702_add_word_count_to_posts.rb +++ b/db/migrate/20131210163702_add_word_count_to_posts.rb @@ -1,4 +1,4 @@ -class AddWordCountToPosts < ActiveRecord::Migration +class AddWordCountToPosts < ActiveRecord::Migration[4.2] def up add_column :posts, :word_count, :integer add_column :topics, :word_count, :integer diff --git a/db/migrate/20131210181901_migrate_word_counts.rb b/db/migrate/20131210181901_migrate_word_counts.rb index e783725bb80..1731e2cefd6 100644 --- a/db/migrate/20131210181901_migrate_word_counts.rb +++ b/db/migrate/20131210181901_migrate_word_counts.rb @@ -1,4 +1,4 @@ -class MigrateWordCounts < ActiveRecord::Migration +class MigrateWordCounts < ActiveRecord::Migration[4.2] disable_ddl_transaction! def up diff --git a/db/migrate/20131210234530_rename_version_column.rb b/db/migrate/20131210234530_rename_version_column.rb index 04f811e7dc7..f6271fc83f6 100644 --- a/db/migrate/20131210234530_rename_version_column.rb +++ b/db/migrate/20131210234530_rename_version_column.rb @@ -1,4 +1,4 @@ -class RenameVersionColumn < ActiveRecord::Migration +class RenameVersionColumn < ActiveRecord::Migration[4.2] def change add_column :posts, :version, :integer, default: 1, null: false diff --git a/db/migrate/20131212225511_add_post_count_stats_columns_to_categories.rb b/db/migrate/20131212225511_add_post_count_stats_columns_to_categories.rb index 4c42074a2dd..73466e65e08 100644 --- a/db/migrate/20131212225511_add_post_count_stats_columns_to_categories.rb +++ b/db/migrate/20131212225511_add_post_count_stats_columns_to_categories.rb @@ -1,4 +1,4 @@ -class AddPostCountStatsColumnsToCategories < ActiveRecord::Migration +class AddPostCountStatsColumnsToCategories < ActiveRecord::Migration[4.2] def change change_table :categories do |t| t.integer :posts_year diff --git a/db/migrate/20131216164557_make_position_nullable_in_categories.rb b/db/migrate/20131216164557_make_position_nullable_in_categories.rb index 9b7dc619ac3..d47d852f0b8 100644 --- a/db/migrate/20131216164557_make_position_nullable_in_categories.rb +++ b/db/migrate/20131216164557_make_position_nullable_in_categories.rb @@ -1,4 +1,4 @@ -class MakePositionNullableInCategories < ActiveRecord::Migration +class MakePositionNullableInCategories < ActiveRecord::Migration[4.2] def up change_column :categories, :position, :integer, null: true end diff --git a/db/migrate/20131217174004_create_topic_embeds.rb b/db/migrate/20131217174004_create_topic_embeds.rb index 81de1d93957..53be7fff287 100644 --- a/db/migrate/20131217174004_create_topic_embeds.rb +++ b/db/migrate/20131217174004_create_topic_embeds.rb @@ -1,4 +1,4 @@ -class CreateTopicEmbeds < ActiveRecord::Migration +class CreateTopicEmbeds < ActiveRecord::Migration[4.2] def change create_table :topic_embeds, force: true do |t| t.integer :topic_id, null: false diff --git a/db/migrate/20131219203905_add_cook_method_to_posts.rb b/db/migrate/20131219203905_add_cook_method_to_posts.rb index 5549082059c..987349d345c 100644 --- a/db/migrate/20131219203905_add_cook_method_to_posts.rb +++ b/db/migrate/20131219203905_add_cook_method_to_posts.rb @@ -1,4 +1,4 @@ -class AddCookMethodToPosts < ActiveRecord::Migration +class AddCookMethodToPosts < ActiveRecord::Migration[4.2] def change add_column :posts, :cook_method, :integer, default: 1, null: false end diff --git a/db/migrate/20131223171005_create_top_topics.rb b/db/migrate/20131223171005_create_top_topics.rb index 974928c96d8..af3be254834 100644 --- a/db/migrate/20131223171005_create_top_topics.rb +++ b/db/migrate/20131223171005_create_top_topics.rb @@ -1,4 +1,4 @@ -class CreateTopTopics < ActiveRecord::Migration +class CreateTopTopics < ActiveRecord::Migration[4.2] PERIODS = [:yearly, :monthly, :weekly, :daily] SORT_ORDERS = [:posts, :views, :likes] diff --git a/db/migrate/20131227164338_add_scores_to_top_topics.rb b/db/migrate/20131227164338_add_scores_to_top_topics.rb index e9bf28fb3c8..4245057c828 100644 --- a/db/migrate/20131227164338_add_scores_to_top_topics.rb +++ b/db/migrate/20131227164338_add_scores_to_top_topics.rb @@ -1,4 +1,4 @@ -class AddScoresToTopTopics < ActiveRecord::Migration +class AddScoresToTopTopics < ActiveRecord::Migration[4.2] def change [:daily, :weekly, :monthly, :yearly].each do |period| add_column :top_topics, "#{period}_score".to_sym, :float diff --git a/db/migrate/20131229221725_add_watch_new_topics_to_users.rb b/db/migrate/20131229221725_add_watch_new_topics_to_users.rb index 4d18f69453a..9c3105ad8bc 100644 --- a/db/migrate/20131229221725_add_watch_new_topics_to_users.rb +++ b/db/migrate/20131229221725_add_watch_new_topics_to_users.rb @@ -1,4 +1,4 @@ -class AddWatchNewTopicsToUsers < ActiveRecord::Migration +class AddWatchNewTopicsToUsers < ActiveRecord::Migration[4.2] def change add_column :users, :watch_new_topics, :boolean, default: false, null: false end diff --git a/db/migrate/20131230010239_add_last_emailed_post_number_to_topic_user.rb b/db/migrate/20131230010239_add_last_emailed_post_number_to_topic_user.rb index 8d2e2d2a96f..b49bf2b4c22 100644 --- a/db/migrate/20131230010239_add_last_emailed_post_number_to_topic_user.rb +++ b/db/migrate/20131230010239_add_last_emailed_post_number_to_topic_user.rb @@ -1,4 +1,4 @@ -class AddLastEmailedPostNumberToTopicUser < ActiveRecord::Migration +class AddLastEmailedPostNumberToTopicUser < ActiveRecord::Migration[4.2] def change add_column :topic_users, :last_emailed_post_number, :integer end diff --git a/db/migrate/20140101235747_add_category_users.rb b/db/migrate/20140101235747_add_category_users.rb index 57841fe7fdd..11fc4bfffe4 100644 --- a/db/migrate/20140101235747_add_category_users.rb +++ b/db/migrate/20140101235747_add_category_users.rb @@ -1,4 +1,4 @@ -class AddCategoryUsers < ActiveRecord::Migration +class AddCategoryUsers < ActiveRecord::Migration[4.2] def change create_table :category_users do |t| t.column :category_id, :integer, null: false diff --git a/db/migrate/20140102104229_add_alias_level_to_groups.rb b/db/migrate/20140102104229_add_alias_level_to_groups.rb index 9cee03f581f..64106fdf69d 100644 --- a/db/migrate/20140102104229_add_alias_level_to_groups.rb +++ b/db/migrate/20140102104229_add_alias_level_to_groups.rb @@ -1,4 +1,4 @@ -class AddAliasLevelToGroups < ActiveRecord::Migration +class AddAliasLevelToGroups < ActiveRecord::Migration[4.2] def change add_column :groups, :alias_level, :integer, default: 0 end diff --git a/db/migrate/20140102194802_remove_default_from_external_links_in_new_tab.rb b/db/migrate/20140102194802_remove_default_from_external_links_in_new_tab.rb index b18afe4c757..af05478d6f2 100644 --- a/db/migrate/20140102194802_remove_default_from_external_links_in_new_tab.rb +++ b/db/migrate/20140102194802_remove_default_from_external_links_in_new_tab.rb @@ -1,4 +1,4 @@ -class RemoveDefaultFromExternalLinksInNewTab < ActiveRecord::Migration +class RemoveDefaultFromExternalLinksInNewTab < ActiveRecord::Migration[4.2] def up change_column_default :users, :external_links_in_new_tab, nil end diff --git a/db/migrate/20140107220141_remove_enable_wide_category_list.rb b/db/migrate/20140107220141_remove_enable_wide_category_list.rb index 80850969f5c..0d5f52112f8 100644 --- a/db/migrate/20140107220141_remove_enable_wide_category_list.rb +++ b/db/migrate/20140107220141_remove_enable_wide_category_list.rb @@ -1,4 +1,4 @@ -class RemoveEnableWideCategoryList < ActiveRecord::Migration +class RemoveEnableWideCategoryList < ActiveRecord::Migration[4.2] def up execute "DELETE FROM site_settings WHERE name = 'enable_wide_category_list'" end diff --git a/db/migrate/20140109205940_rename_favorites_to_starred.rb b/db/migrate/20140109205940_rename_favorites_to_starred.rb index ec59b71e7a9..bdfc6b505fe 100644 --- a/db/migrate/20140109205940_rename_favorites_to_starred.rb +++ b/db/migrate/20140109205940_rename_favorites_to_starred.rb @@ -1,4 +1,4 @@ -class RenameFavoritesToStarred < ActiveRecord::Migration +class RenameFavoritesToStarred < ActiveRecord::Migration[4.2] def up execute "UPDATE site_settings SET name = 'max_stars_per_day' where name = 'max_favorites_per_day'" execute "UPDATE site_settings SET value = REPLACE(value, '|favorited', '|starred') where name = 'top_menu'" diff --git a/db/migrate/20140116170655_drop_hot_topics.rb b/db/migrate/20140116170655_drop_hot_topics.rb index 8042ee06fe7..77caed34697 100644 --- a/db/migrate/20140116170655_drop_hot_topics.rb +++ b/db/migrate/20140116170655_drop_hot_topics.rb @@ -1,4 +1,4 @@ -class DropHotTopics < ActiveRecord::Migration +class DropHotTopics < ActiveRecord::Migration[4.2] def change drop_table :hot_topics end diff --git a/db/migrate/20140120155706_add_lounge_category.rb b/db/migrate/20140120155706_add_lounge_category.rb index b43b8b97e10..0dac6e7b291 100644 --- a/db/migrate/20140120155706_add_lounge_category.rb +++ b/db/migrate/20140120155706_add_lounge_category.rb @@ -1,4 +1,4 @@ -class AddLoungeCategory < ActiveRecord::Migration +class AddLoungeCategory < ActiveRecord::Migration[4.2] def up return if Rails.env.test? diff --git a/db/migrate/20140121204628_add_invalidated_at_to_invites.rb b/db/migrate/20140121204628_add_invalidated_at_to_invites.rb index 7ce133dea58..2c7508d6e10 100644 --- a/db/migrate/20140121204628_add_invalidated_at_to_invites.rb +++ b/db/migrate/20140121204628_add_invalidated_at_to_invites.rb @@ -1,4 +1,4 @@ -class AddInvalidatedAtToInvites < ActiveRecord::Migration +class AddInvalidatedAtToInvites < ActiveRecord::Migration[4.2] def change add_column :invites, :invalidated_at, :datetime end diff --git a/db/migrate/20140122043508_add_meta_category.rb b/db/migrate/20140122043508_add_meta_category.rb index 1e17de6f463..2b42b81643a 100644 --- a/db/migrate/20140122043508_add_meta_category.rb +++ b/db/migrate/20140122043508_add_meta_category.rb @@ -1,4 +1,4 @@ -class AddMetaCategory < ActiveRecord::Migration +class AddMetaCategory < ActiveRecord::Migration[4.2] def up return if Rails.env.test? diff --git a/db/migrate/20140124202427_add_posts_read_to_user_visits.rb b/db/migrate/20140124202427_add_posts_read_to_user_visits.rb index 5315f07ba7b..aa8492d3975 100644 --- a/db/migrate/20140124202427_add_posts_read_to_user_visits.rb +++ b/db/migrate/20140124202427_add_posts_read_to_user_visits.rb @@ -1,4 +1,4 @@ -class AddPostsReadToUserVisits < ActiveRecord::Migration +class AddPostsReadToUserVisits < ActiveRecord::Migration[4.2] def up add_column :user_visits, :posts_read, :integer, default: 0 diff --git a/db/migrate/20140129164541_remove_category_hotness.rb b/db/migrate/20140129164541_remove_category_hotness.rb index 9eaaed14928..af127eaacb2 100644 --- a/db/migrate/20140129164541_remove_category_hotness.rb +++ b/db/migrate/20140129164541_remove_category_hotness.rb @@ -1,4 +1,4 @@ -class RemoveCategoryHotness < ActiveRecord::Migration +class RemoveCategoryHotness < ActiveRecord::Migration[4.2] def change remove_column :categories, :hotness end diff --git a/db/migrate/20140206044818_add_locale_to_user.rb b/db/migrate/20140206044818_add_locale_to_user.rb index c0f2431b3ef..8771039c50a 100644 --- a/db/migrate/20140206044818_add_locale_to_user.rb +++ b/db/migrate/20140206044818_add_locale_to_user.rb @@ -1,4 +1,4 @@ -class AddLocaleToUser < ActiveRecord::Migration +class AddLocaleToUser < ActiveRecord::Migration[4.2] def change add_column :users, :locale, :string, limit: 10 end diff --git a/db/migrate/20140206195001_add_defaults_to_category_posts_and_topics_fields.rb b/db/migrate/20140206195001_add_defaults_to_category_posts_and_topics_fields.rb index 28426a572b6..e5c7ddbdd30 100644 --- a/db/migrate/20140206195001_add_defaults_to_category_posts_and_topics_fields.rb +++ b/db/migrate/20140206195001_add_defaults_to_category_posts_and_topics_fields.rb @@ -1,4 +1,4 @@ -class AddDefaultsToCategoryPostsAndTopicsFields < ActiveRecord::Migration +class AddDefaultsToCategoryPostsAndTopicsFields < ActiveRecord::Migration[4.2] def change change_column_default :categories, :posts_week, 0 change_column_default :categories, :posts_month, 0 diff --git a/db/migrate/20140206215029_add_mailing_list_mode_to_users.rb b/db/migrate/20140206215029_add_mailing_list_mode_to_users.rb index c4de0991fda..d9a0c0d9404 100644 --- a/db/migrate/20140206215029_add_mailing_list_mode_to_users.rb +++ b/db/migrate/20140206215029_add_mailing_list_mode_to_users.rb @@ -1,4 +1,4 @@ -class AddMailingListModeToUsers < ActiveRecord::Migration +class AddMailingListModeToUsers < ActiveRecord::Migration[4.2] def change rename_column :users, :watch_new_topics, :mailing_list_mode end diff --git a/db/migrate/20140210194146_add_primary_group_id_to_users.rb b/db/migrate/20140210194146_add_primary_group_id_to_users.rb index 84d328ff2c5..71562daba9f 100644 --- a/db/migrate/20140210194146_add_primary_group_id_to_users.rb +++ b/db/migrate/20140210194146_add_primary_group_id_to_users.rb @@ -1,4 +1,4 @@ -class AddPrimaryGroupIdToUsers < ActiveRecord::Migration +class AddPrimaryGroupIdToUsers < ActiveRecord::Migration[4.2] def change add_column :users, :primary_group_id, :integer, null: true end diff --git a/db/migrate/20140211230222_move_cas_settings.rb b/db/migrate/20140211230222_move_cas_settings.rb index b832385a3b9..d2775e2f305 100644 --- a/db/migrate/20140211230222_move_cas_settings.rb +++ b/db/migrate/20140211230222_move_cas_settings.rb @@ -1,4 +1,4 @@ -class MoveCasSettings < ActiveRecord::Migration +class MoveCasSettings < ActiveRecord::Migration[4.2] def change #As part of removing the build in CAS authentication we should #convert the data over to be used by the plugin. diff --git a/db/migrate/20140211234523_add_targets_topic_to_post_actions.rb b/db/migrate/20140211234523_add_targets_topic_to_post_actions.rb index 38355175b4d..5da97fe9840 100644 --- a/db/migrate/20140211234523_add_targets_topic_to_post_actions.rb +++ b/db/migrate/20140211234523_add_targets_topic_to_post_actions.rb @@ -1,4 +1,4 @@ -class AddTargetsTopicToPostActions < ActiveRecord::Migration +class AddTargetsTopicToPostActions < ActiveRecord::Migration[4.2] def change add_column :post_actions, :targets_topic, :boolean, default: false end diff --git a/db/migrate/20140214151255_add_skipped_to_email_logs.rb b/db/migrate/20140214151255_add_skipped_to_email_logs.rb index e6615453650..f24b2fc09fb 100644 --- a/db/migrate/20140214151255_add_skipped_to_email_logs.rb +++ b/db/migrate/20140214151255_add_skipped_to_email_logs.rb @@ -1,4 +1,4 @@ -class AddSkippedToEmailLogs < ActiveRecord::Migration +class AddSkippedToEmailLogs < ActiveRecord::Migration[4.2] def change add_column :email_logs, :skipped, :boolean, default: :false add_column :email_logs, :skipped_reason, :string diff --git a/db/migrate/20140220160510_rename_site_settings.rb b/db/migrate/20140220160510_rename_site_settings.rb index 1a3395c865b..78da03786e2 100644 --- a/db/migrate/20140220160510_rename_site_settings.rb +++ b/db/migrate/20140220160510_rename_site_settings.rb @@ -1,4 +1,4 @@ -class RenameSiteSettings < ActiveRecord::Migration +class RenameSiteSettings < ActiveRecord::Migration[4.2] def up execute "UPDATE site_settings SET name = 'allow_restore' WHERE name = 'allow_import'" diff --git a/db/migrate/20140220163213_rename_delete_user_max_age.rb b/db/migrate/20140220163213_rename_delete_user_max_age.rb index 79a9616af5c..5906f36f796 100644 --- a/db/migrate/20140220163213_rename_delete_user_max_age.rb +++ b/db/migrate/20140220163213_rename_delete_user_max_age.rb @@ -1,4 +1,4 @@ -class RenameDeleteUserMaxAge < ActiveRecord::Migration +class RenameDeleteUserMaxAge < ActiveRecord::Migration[4.2] def change execute "UPDATE site_settings SET name = 'delete_user_max_post_age' WHERE name = 'delete_user_max_age'" end diff --git a/db/migrate/20140224232712_add_profile_background_to_user.rb b/db/migrate/20140224232712_add_profile_background_to_user.rb index 83c0e231495..ad6f4366f82 100644 --- a/db/migrate/20140224232712_add_profile_background_to_user.rb +++ b/db/migrate/20140224232712_add_profile_background_to_user.rb @@ -1,4 +1,4 @@ -class AddProfileBackgroundToUser < ActiveRecord::Migration +class AddProfileBackgroundToUser < ActiveRecord::Migration[4.2] def change add_column :users, :profile_background, :string, limit: 255 end diff --git a/db/migrate/20140224232913_add_single_sign_on_records.rb b/db/migrate/20140224232913_add_single_sign_on_records.rb index c0321c617cc..994a5cfceee 100644 --- a/db/migrate/20140224232913_add_single_sign_on_records.rb +++ b/db/migrate/20140224232913_add_single_sign_on_records.rb @@ -1,4 +1,4 @@ -class AddSingleSignOnRecords < ActiveRecord::Migration +class AddSingleSignOnRecords < ActiveRecord::Migration[4.2] def change create_table :single_sign_on_records do |t| t.integer :user_id, null: false diff --git a/db/migrate/20140227104930_add_custom_email_in_to_categories.rb b/db/migrate/20140227104930_add_custom_email_in_to_categories.rb index fa31829cafe..007c54e165a 100644 --- a/db/migrate/20140227104930_add_custom_email_in_to_categories.rb +++ b/db/migrate/20140227104930_add_custom_email_in_to_categories.rb @@ -1,4 +1,4 @@ -class AddCustomEmailInToCategories < ActiveRecord::Migration +class AddCustomEmailInToCategories < ActiveRecord::Migration[4.2] def up add_column :categories, :email_in, :string, null: true add_column :categories, :email_in_allow_strangers, :boolean, default: false diff --git a/db/migrate/20140227201005_add_staff_category.rb b/db/migrate/20140227201005_add_staff_category.rb index c8b7075b303..67a84806016 100644 --- a/db/migrate/20140227201005_add_staff_category.rb +++ b/db/migrate/20140227201005_add_staff_category.rb @@ -1,4 +1,4 @@ -class AddStaffCategory < ActiveRecord::Migration +class AddStaffCategory < ActiveRecord::Migration[4.2] def up return if Rails.env.test? diff --git a/db/migrate/20140228005443_add_external_username_to_single_sign_on_record.rb b/db/migrate/20140228005443_add_external_username_to_single_sign_on_record.rb index 61a1a1bb723..b450c55260a 100644 --- a/db/migrate/20140228005443_add_external_username_to_single_sign_on_record.rb +++ b/db/migrate/20140228005443_add_external_username_to_single_sign_on_record.rb @@ -1,4 +1,4 @@ -class AddExternalUsernameToSingleSignOnRecord < ActiveRecord::Migration +class AddExternalUsernameToSingleSignOnRecord < ActiveRecord::Migration[4.2] def change add_column :single_sign_on_records, :external_username, :string end diff --git a/db/migrate/20140228173431_add_external_email_and_external_name_to_single_sign_on_record.rb b/db/migrate/20140228173431_add_external_email_and_external_name_to_single_sign_on_record.rb index a56a611d899..720a1b5e4e3 100644 --- a/db/migrate/20140228173431_add_external_email_and_external_name_to_single_sign_on_record.rb +++ b/db/migrate/20140228173431_add_external_email_and_external_name_to_single_sign_on_record.rb @@ -1,4 +1,4 @@ -class AddExternalEmailAndExternalNameToSingleSignOnRecord < ActiveRecord::Migration +class AddExternalEmailAndExternalNameToSingleSignOnRecord < ActiveRecord::Migration[4.2] def change add_column :single_sign_on_records, :external_email, :string add_column :single_sign_on_records, :external_name, :string diff --git a/db/migrate/20140228205743_add_admin_only_to_user_histories.rb b/db/migrate/20140228205743_add_admin_only_to_user_histories.rb index 7e55ab6a07c..1a9e3a7d0bf 100644 --- a/db/migrate/20140228205743_add_admin_only_to_user_histories.rb +++ b/db/migrate/20140228205743_add_admin_only_to_user_histories.rb @@ -1,4 +1,4 @@ -class AddAdminOnlyToUserHistories < ActiveRecord::Migration +class AddAdminOnlyToUserHistories < ActiveRecord::Migration[4.2] def up add_column :user_histories, :admin_only, :boolean, default: false execute "UPDATE user_histories SET admin_only = true WHERE action = #{UserHistory.actions[:change_site_setting]}" diff --git a/db/migrate/20140303185354_add_new_since_to_user_stats.rb b/db/migrate/20140303185354_add_new_since_to_user_stats.rb index f0e1a071cdc..c510ea61731 100644 --- a/db/migrate/20140303185354_add_new_since_to_user_stats.rb +++ b/db/migrate/20140303185354_add_new_since_to_user_stats.rb @@ -1,4 +1,4 @@ -class AddNewSinceToUserStats < ActiveRecord::Migration +class AddNewSinceToUserStats < ActiveRecord::Migration[4.2] def change add_column :user_stats, :new_since, :datetime execute "UPDATE user_stats AS us diff --git a/db/migrate/20140304200606_create_badge_types.rb b/db/migrate/20140304200606_create_badge_types.rb index 1ddffbfe715..4c3d460dce1 100644 --- a/db/migrate/20140304200606_create_badge_types.rb +++ b/db/migrate/20140304200606_create_badge_types.rb @@ -1,4 +1,4 @@ -class CreateBadgeTypes < ActiveRecord::Migration +class CreateBadgeTypes < ActiveRecord::Migration[4.2] def change create_table :badge_types do |t| t.string :name, null: false diff --git a/db/migrate/20140304201403_create_badges.rb b/db/migrate/20140304201403_create_badges.rb index 89550ea9d26..040468e042e 100644 --- a/db/migrate/20140304201403_create_badges.rb +++ b/db/migrate/20140304201403_create_badges.rb @@ -1,4 +1,4 @@ -class CreateBadges < ActiveRecord::Migration +class CreateBadges < ActiveRecord::Migration[4.2] def change create_table :badges do |t| t.string :name, null: false diff --git a/db/migrate/20140305100909_create_user_badges.rb b/db/migrate/20140305100909_create_user_badges.rb index 52afead5adf..bb26815e72e 100644 --- a/db/migrate/20140305100909_create_user_badges.rb +++ b/db/migrate/20140305100909_create_user_badges.rb @@ -1,4 +1,4 @@ -class CreateUserBadges < ActiveRecord::Migration +class CreateUserBadges < ActiveRecord::Migration[4.2] def change create_table :user_badges do |t| t.integer :badge_id, null: false diff --git a/db/migrate/20140306223522_move_topic_revisions_to_post_revisions.rb b/db/migrate/20140306223522_move_topic_revisions_to_post_revisions.rb index 2f5cd70b08c..3f810cb4526 100644 --- a/db/migrate/20140306223522_move_topic_revisions_to_post_revisions.rb +++ b/db/migrate/20140306223522_move_topic_revisions_to_post_revisions.rb @@ -1,4 +1,4 @@ -class MoveTopicRevisionsToPostRevisions < ActiveRecord::Migration +class MoveTopicRevisionsToPostRevisions < ActiveRecord::Migration[4.2] def up execute < 1 diff --git a/db/migrate/20140522003151_add_user_avatars.rb b/db/migrate/20140522003151_add_user_avatars.rb index 025a233be1e..5b4cccbf4c2 100644 --- a/db/migrate/20140522003151_add_user_avatars.rb +++ b/db/migrate/20140522003151_add_user_avatars.rb @@ -1,4 +1,4 @@ -class AddUserAvatars < ActiveRecord::Migration +class AddUserAvatars < ActiveRecord::Migration[4.2] def up create_table :user_avatars do |t| t.integer :user_id, null: false diff --git a/db/migrate/20140525233953_remove_uploaded_avatar_template_from_users.rb b/db/migrate/20140525233953_remove_uploaded_avatar_template_from_users.rb index 138dcb992f9..8e06b8507a0 100644 --- a/db/migrate/20140525233953_remove_uploaded_avatar_template_from_users.rb +++ b/db/migrate/20140525233953_remove_uploaded_avatar_template_from_users.rb @@ -1,4 +1,4 @@ -class RemoveUploadedAvatarTemplateFromUsers < ActiveRecord::Migration +class RemoveUploadedAvatarTemplateFromUsers < ActiveRecord::Migration[4.2] def change remove_column :users, :uploaded_avatar_template end diff --git a/db/migrate/20140526185749_change_category_uniquness_contstraint.rb b/db/migrate/20140526185749_change_category_uniquness_contstraint.rb index 65788268c8c..1c605402372 100644 --- a/db/migrate/20140526185749_change_category_uniquness_contstraint.rb +++ b/db/migrate/20140526185749_change_category_uniquness_contstraint.rb @@ -1,4 +1,4 @@ -class ChangeCategoryUniqunessContstraint < ActiveRecord::Migration +class ChangeCategoryUniqunessContstraint < ActiveRecord::Migration[4.2] def change remove_index :categories, name: 'index_categories_on_name' add_index :categories, [:parent_category_id, :name], unique: true diff --git a/db/migrate/20140526201939_add_disable_jump_reply_to_users.rb b/db/migrate/20140526201939_add_disable_jump_reply_to_users.rb index 84c6c8c0ddd..e0567340351 100644 --- a/db/migrate/20140526201939_add_disable_jump_reply_to_users.rb +++ b/db/migrate/20140526201939_add_disable_jump_reply_to_users.rb @@ -1,4 +1,4 @@ -class AddDisableJumpReplyToUsers < ActiveRecord::Migration +class AddDisableJumpReplyToUsers < ActiveRecord::Migration[4.2] def change add_column :users, :disable_jump_reply, :boolean, default: false, null: false end diff --git a/db/migrate/20140527163207_create_user_profiles.rb b/db/migrate/20140527163207_create_user_profiles.rb index 34d8fa87cd6..ce1bd614600 100644 --- a/db/migrate/20140527163207_create_user_profiles.rb +++ b/db/migrate/20140527163207_create_user_profiles.rb @@ -1,4 +1,4 @@ -class CreateUserProfiles < ActiveRecord::Migration +class CreateUserProfiles < ActiveRecord::Migration[4.2] def up create_table :user_profiles, id: false do |t| t.references :user diff --git a/db/migrate/20140527233225_add_system_savatar_version_to_user_avatars.rb b/db/migrate/20140527233225_add_system_savatar_version_to_user_avatars.rb index 9fe87c9a80b..2992db210a2 100644 --- a/db/migrate/20140527233225_add_system_savatar_version_to_user_avatars.rb +++ b/db/migrate/20140527233225_add_system_savatar_version_to_user_avatars.rb @@ -1,4 +1,4 @@ -class AddSystemSavatarVersionToUserAvatars < ActiveRecord::Migration +class AddSystemSavatarVersionToUserAvatars < ActiveRecord::Migration[4.2] def change add_column :user_avatars, :system_avatar_version, :integer, default: 0 end diff --git a/db/migrate/20140528015354_add_baked_at_to_posts.rb b/db/migrate/20140528015354_add_baked_at_to_posts.rb index bd97a56f104..6d6e9541860 100644 --- a/db/migrate/20140528015354_add_baked_at_to_posts.rb +++ b/db/migrate/20140528015354_add_baked_at_to_posts.rb @@ -1,4 +1,4 @@ -class AddBakedAtToPosts < ActiveRecord::Migration +class AddBakedAtToPosts < ActiveRecord::Migration[4.2] def change add_column :posts, :baked_at, :datetime end diff --git a/db/migrate/20140529045508_remove_use_uploaded_avatar_from_user.rb b/db/migrate/20140529045508_remove_use_uploaded_avatar_from_user.rb index 21bb9956e3b..018b84d701d 100644 --- a/db/migrate/20140529045508_remove_use_uploaded_avatar_from_user.rb +++ b/db/migrate/20140529045508_remove_use_uploaded_avatar_from_user.rb @@ -1,4 +1,4 @@ -class RemoveUseUploadedAvatarFromUser < ActiveRecord::Migration +class RemoveUseUploadedAvatarFromUser < ActiveRecord::Migration[4.2] def change remove_column :users, :use_uploaded_avatar end diff --git a/db/migrate/20140530002535_remove_system_avatars_from_user_avatars.rb b/db/migrate/20140530002535_remove_system_avatars_from_user_avatars.rb index 82e90e71530..8711d90dcff 100644 --- a/db/migrate/20140530002535_remove_system_avatars_from_user_avatars.rb +++ b/db/migrate/20140530002535_remove_system_avatars_from_user_avatars.rb @@ -1,6 +1,6 @@ # This takes all the system avatars out of the upload system, saving us a huge # amount of space on backups -class RemoveSystemAvatarsFromUserAvatars < ActiveRecord::Migration +class RemoveSystemAvatarsFromUserAvatars < ActiveRecord::Migration[4.2] def up execute "UPDATE users SET uploaded_avatar_id = NULL WHERE uploaded_avatar_id IN ( SELECT system_upload_id FROM user_avatars diff --git a/db/migrate/20140530043913_add_baked_version_to_post.rb b/db/migrate/20140530043913_add_baked_version_to_post.rb index dd1cbd75d99..55824b283ab 100644 --- a/db/migrate/20140530043913_add_baked_version_to_post.rb +++ b/db/migrate/20140530043913_add_baked_version_to_post.rb @@ -1,4 +1,4 @@ -class AddBakedVersionToPost < ActiveRecord::Migration +class AddBakedVersionToPost < ActiveRecord::Migration[4.2] def change add_column :posts, :baked_version, :integer end diff --git a/db/migrate/20140604145431_disable_external_auths_by_default.rb b/db/migrate/20140604145431_disable_external_auths_by_default.rb index 8a5e780a3cd..8f47ba505ec 100644 --- a/db/migrate/20140604145431_disable_external_auths_by_default.rb +++ b/db/migrate/20140604145431_disable_external_auths_by_default.rb @@ -1,4 +1,4 @@ -class DisableExternalAuthsByDefault < ActiveRecord::Migration +class DisableExternalAuthsByDefault < ActiveRecord::Migration[4.2] def enable_setting_if_default(name) result = User.exec_sql("SELECT count(*) count FROM site_settings WHERE name = '#{name}'") diff --git a/db/migrate/20140607035234_add_website_to_user_profiles.rb b/db/migrate/20140607035234_add_website_to_user_profiles.rb index 4194dcf1393..4fcecb74017 100644 --- a/db/migrate/20140607035234_add_website_to_user_profiles.rb +++ b/db/migrate/20140607035234_add_website_to_user_profiles.rb @@ -1,4 +1,4 @@ -class AddWebsiteToUserProfiles < ActiveRecord::Migration +class AddWebsiteToUserProfiles < ActiveRecord::Migration[4.2] def up add_column :user_profiles, :website, :string diff --git a/db/migrate/20140610012414_add_post_id_to_user_badges.rb b/db/migrate/20140610012414_add_post_id_to_user_badges.rb index 26ecd890c71..ec15a9ae338 100644 --- a/db/migrate/20140610012414_add_post_id_to_user_badges.rb +++ b/db/migrate/20140610012414_add_post_id_to_user_badges.rb @@ -1,4 +1,4 @@ -class AddPostIdToUserBadges < ActiveRecord::Migration +class AddPostIdToUserBadges < ActiveRecord::Migration[4.2] def change add_column :user_badges, :post_id, :integer end diff --git a/db/migrate/20140610012833_add_icon_to_badges.rb b/db/migrate/20140610012833_add_icon_to_badges.rb index 7610385079d..81f08ad1691 100644 --- a/db/migrate/20140610012833_add_icon_to_badges.rb +++ b/db/migrate/20140610012833_add_icon_to_badges.rb @@ -1,4 +1,4 @@ -class AddIconToBadges < ActiveRecord::Migration +class AddIconToBadges < ActiveRecord::Migration[4.2] def change add_column :badges, :icon, :string, default: "fa-certificate" end diff --git a/db/migrate/20140610034314_move_bio_to_user_profiles.rb b/db/migrate/20140610034314_move_bio_to_user_profiles.rb index d1042c552ab..4d832da743c 100644 --- a/db/migrate/20140610034314_move_bio_to_user_profiles.rb +++ b/db/migrate/20140610034314_move_bio_to_user_profiles.rb @@ -1,4 +1,4 @@ -class MoveBioToUserProfiles < ActiveRecord::Migration +class MoveBioToUserProfiles < ActiveRecord::Migration[4.2] def up add_column :user_profiles, :bio_raw, :text add_column :user_profiles, :bio_cooked, :text diff --git a/db/migrate/20140612010718_move_profile_background_to_user_profiles.rb b/db/migrate/20140612010718_move_profile_background_to_user_profiles.rb index d654ab19a29..b5c9a12cb27 100644 --- a/db/migrate/20140612010718_move_profile_background_to_user_profiles.rb +++ b/db/migrate/20140612010718_move_profile_background_to_user_profiles.rb @@ -1,4 +1,4 @@ -class MoveProfileBackgroundToUserProfiles < ActiveRecord::Migration +class MoveProfileBackgroundToUserProfiles < ActiveRecord::Migration[4.2] def up add_column :user_profiles, :profile_background, :string, limit: 255 diff --git a/db/migrate/20140617053829_add_notification_id_to_user_badge.rb b/db/migrate/20140617053829_add_notification_id_to_user_badge.rb index e066ac3cf02..1cdd62c80fa 100644 --- a/db/migrate/20140617053829_add_notification_id_to_user_badge.rb +++ b/db/migrate/20140617053829_add_notification_id_to_user_badge.rb @@ -1,4 +1,4 @@ -class AddNotificationIdToUserBadge < ActiveRecord::Migration +class AddNotificationIdToUserBadge < ActiveRecord::Migration[4.2] def change add_column :user_badges, :notification_id, :integer end diff --git a/db/migrate/20140617080955_rename_registered_users.rb b/db/migrate/20140617080955_rename_registered_users.rb index ec7e35b9e80..b036c8e5652 100644 --- a/db/migrate/20140617080955_rename_registered_users.rb +++ b/db/migrate/20140617080955_rename_registered_users.rb @@ -1,4 +1,4 @@ -class RenameRegisteredUsers < ActiveRecord::Migration +class RenameRegisteredUsers < ActiveRecord::Migration[4.2] def change execute "update groups set name = 'trust_level_0' where name = 'registered_users' and id = 10" end diff --git a/db/migrate/20140617193351_add_post_id_index_on_topic_links.rb b/db/migrate/20140617193351_add_post_id_index_on_topic_links.rb index aae44fbc1d0..dcdc5bd9e1f 100644 --- a/db/migrate/20140617193351_add_post_id_index_on_topic_links.rb +++ b/db/migrate/20140617193351_add_post_id_index_on_topic_links.rb @@ -1,4 +1,4 @@ -class AddPostIdIndexOnTopicLinks < ActiveRecord::Migration +class AddPostIdIndexOnTopicLinks < ActiveRecord::Migration[4.2] def up add_index :topic_links, :post_id end diff --git a/db/migrate/20140618001820_dont_auto_muto_topics.rb b/db/migrate/20140618001820_dont_auto_muto_topics.rb index f91070a3911..23edeb32222 100644 --- a/db/migrate/20140618001820_dont_auto_muto_topics.rb +++ b/db/migrate/20140618001820_dont_auto_muto_topics.rb @@ -1,4 +1,4 @@ -class DontAutoMutoTopics < ActiveRecord::Migration +class DontAutoMutoTopics < ActiveRecord::Migration[4.2] def change # muting all new topics was a mistake, revert it execute 'DELETE FROM topic_users WHERE notification_level = 0 and notifications_reason_id =7 AND first_visited_at IS NULL' diff --git a/db/migrate/20140618163511_add_dismissed_banner_key_to_user_profile.rb b/db/migrate/20140618163511_add_dismissed_banner_key_to_user_profile.rb index f84c1f9a928..1e0e390ec20 100644 --- a/db/migrate/20140618163511_add_dismissed_banner_key_to_user_profile.rb +++ b/db/migrate/20140618163511_add_dismissed_banner_key_to_user_profile.rb @@ -1,4 +1,4 @@ -class AddDismissedBannerKeyToUserProfile < ActiveRecord::Migration +class AddDismissedBannerKeyToUserProfile < ActiveRecord::Migration[4.2] def change add_column :user_profiles, :dismissed_banner_key, :integer, nullable: true end diff --git a/db/migrate/20140620184031_add_hidden_at_to_posts.rb b/db/migrate/20140620184031_add_hidden_at_to_posts.rb index e22041be19b..60138d9d0c1 100644 --- a/db/migrate/20140620184031_add_hidden_at_to_posts.rb +++ b/db/migrate/20140620184031_add_hidden_at_to_posts.rb @@ -1,4 +1,4 @@ -class AddHiddenAtToPosts < ActiveRecord::Migration +class AddHiddenAtToPosts < ActiveRecord::Migration[4.2] def change add_column :posts, :hidden_at, :timestamp end diff --git a/db/migrate/20140623195618_fix_categories_constraint.rb b/db/migrate/20140623195618_fix_categories_constraint.rb index 5c6daa0cc56..5e1423032fa 100644 --- a/db/migrate/20140623195618_fix_categories_constraint.rb +++ b/db/migrate/20140623195618_fix_categories_constraint.rb @@ -1,4 +1,4 @@ -class FixCategoriesConstraint < ActiveRecord::Migration +class FixCategoriesConstraint < ActiveRecord::Migration[4.2] def change remove_index :categories, name: 'index_categories_on_parent_category_id_and_name' diff --git a/db/migrate/20140624044600_add_raw_data_to_search.rb b/db/migrate/20140624044600_add_raw_data_to_search.rb index 51fe1c4e8ef..6e69bfcf3e2 100644 --- a/db/migrate/20140624044600_add_raw_data_to_search.rb +++ b/db/migrate/20140624044600_add_raw_data_to_search.rb @@ -1,4 +1,4 @@ -class AddRawDataToSearch < ActiveRecord::Migration +class AddRawDataToSearch < ActiveRecord::Migration[4.2] def change add_column :post_search_data, :raw_data, :text add_column :user_search_data, :raw_data, :text diff --git a/db/migrate/20140627193814_add_images_to_categories.rb b/db/migrate/20140627193814_add_images_to_categories.rb index 58e4cce7319..5317a70f113 100644 --- a/db/migrate/20140627193814_add_images_to_categories.rb +++ b/db/migrate/20140627193814_add_images_to_categories.rb @@ -1,4 +1,4 @@ -class AddImagesToCategories < ActiveRecord::Migration +class AddImagesToCategories < ActiveRecord::Migration[4.2] def change add_column :categories, :logo_url, :string add_column :categories, :background_url, :string diff --git a/db/migrate/20140703022838_add_fields_to_badges.rb b/db/migrate/20140703022838_add_fields_to_badges.rb index 69cfd32ec26..1597bc62410 100644 --- a/db/migrate/20140703022838_add_fields_to_badges.rb +++ b/db/migrate/20140703022838_add_fields_to_badges.rb @@ -1,4 +1,4 @@ -class AddFieldsToBadges < ActiveRecord::Migration +class AddFieldsToBadges < ActiveRecord::Migration[4.2] def change add_column :badges, :listable, :boolean, default: true add_column :badges, :target_posts, :boolean, default: false diff --git a/db/migrate/20140705081453_index_user_badges.rb b/db/migrate/20140705081453_index_user_badges.rb index 332fc17188d..6133b2b46f2 100644 --- a/db/migrate/20140705081453_index_user_badges.rb +++ b/db/migrate/20140705081453_index_user_badges.rb @@ -1,4 +1,4 @@ -class IndexUserBadges < ActiveRecord::Migration +class IndexUserBadges < ActiveRecord::Migration[4.2] def change execute 'DELETE FROM user_badges USING user_badges ub2 WHERE user_badges.badge_id = ub2.badge_id AND diff --git a/db/migrate/20140707071913_add_self_edits_to_posts.rb b/db/migrate/20140707071913_add_self_edits_to_posts.rb index cd0727b409c..aa93dd502ec 100644 --- a/db/migrate/20140707071913_add_self_edits_to_posts.rb +++ b/db/migrate/20140707071913_add_self_edits_to_posts.rb @@ -1,4 +1,4 @@ -class AddSelfEditsToPosts < ActiveRecord::Migration +class AddSelfEditsToPosts < ActiveRecord::Migration[4.2] def up add_column :posts, :self_edits, :integer, null: false, default: 0 execute " diff --git a/db/migrate/20140710005023_add_badge_posts_and_topics_view.rb b/db/migrate/20140710005023_add_badge_posts_and_topics_view.rb index 5f1cae360ef..3b9c43df94a 100644 --- a/db/migrate/20140710005023_add_badge_posts_and_topics_view.rb +++ b/db/migrate/20140710005023_add_badge_posts_and_topics_view.rb @@ -1,4 +1,4 @@ -class AddBadgePostsAndTopicsView < ActiveRecord::Migration +class AddBadgePostsAndTopicsView < ActiveRecord::Migration[4.2] def up add_column :categories, :allow_badges, :boolean, default: true, null: false diff --git a/db/migrate/20140710224658_add_is_quote_to_topic_links.rb b/db/migrate/20140710224658_add_is_quote_to_topic_links.rb index 0abe4d3c8e1..f816f8a6ffb 100644 --- a/db/migrate/20140710224658_add_is_quote_to_topic_links.rb +++ b/db/migrate/20140710224658_add_is_quote_to_topic_links.rb @@ -1,4 +1,4 @@ -class AddIsQuoteToTopicLinks < ActiveRecord::Migration +class AddIsQuoteToTopicLinks < ActiveRecord::Migration[4.2] def up add_column :topic_links, :quote, :boolean, default: false, null: false diff --git a/db/migrate/20140711063215_add_read_faq_to_user_stats.rb b/db/migrate/20140711063215_add_read_faq_to_user_stats.rb index 90b6ce6efd6..2441605d4fd 100644 --- a/db/migrate/20140711063215_add_read_faq_to_user_stats.rb +++ b/db/migrate/20140711063215_add_read_faq_to_user_stats.rb @@ -1,4 +1,4 @@ -class AddReadFaqToUserStats < ActiveRecord::Migration +class AddReadFaqToUserStats < ActiveRecord::Migration[4.2] def change add_column :user_stats, :read_faq, :datetime end diff --git a/db/migrate/20140711143146_remove_not_null_from_email.rb b/db/migrate/20140711143146_remove_not_null_from_email.rb index 9cde9b01bce..a6e63168baa 100644 --- a/db/migrate/20140711143146_remove_not_null_from_email.rb +++ b/db/migrate/20140711143146_remove_not_null_from_email.rb @@ -1,4 +1,4 @@ -class RemoveNotNullFromEmail < ActiveRecord::Migration +class RemoveNotNullFromEmail < ActiveRecord::Migration[4.2] def up execute "ALTER TABLE invites ALTER COLUMN email DROP NOT NULL" end diff --git a/db/migrate/20140711193923_remove_email_in_address_setting.rb b/db/migrate/20140711193923_remove_email_in_address_setting.rb index f81efdb7a60..a82dbe4dd08 100644 --- a/db/migrate/20140711193923_remove_email_in_address_setting.rb +++ b/db/migrate/20140711193923_remove_email_in_address_setting.rb @@ -1,4 +1,4 @@ -class RemoveEmailInAddressSetting < ActiveRecord::Migration +class RemoveEmailInAddressSetting < ActiveRecord::Migration[4.2] def up uncat_id = ActiveRecord::Base.exec_sql("SELECT value FROM site_settings WHERE name = 'uncategorized_category_id'").first cat_id_r = ActiveRecord::Base.exec_sql("SELECT value FROM site_settings WHERE name = 'email_in_category'").first diff --git a/db/migrate/20140711233329_badges_only_on_public_categories.rb b/db/migrate/20140711233329_badges_only_on_public_categories.rb index e1c5659a31e..320201849d6 100644 --- a/db/migrate/20140711233329_badges_only_on_public_categories.rb +++ b/db/migrate/20140711233329_badges_only_on_public_categories.rb @@ -1,4 +1,4 @@ -class BadgesOnlyOnPublicCategories < ActiveRecord::Migration +class BadgesOnlyOnPublicCategories < ActiveRecord::Migration[4.2] def up execute "DROP VIEW badge_posts" diff --git a/db/migrate/20140714060646_add_enabled_to_badges.rb b/db/migrate/20140714060646_add_enabled_to_badges.rb index c381511a0b0..e62aac8651d 100644 --- a/db/migrate/20140714060646_add_enabled_to_badges.rb +++ b/db/migrate/20140714060646_add_enabled_to_badges.rb @@ -1,4 +1,4 @@ -class AddEnabledToBadges < ActiveRecord::Migration +class AddEnabledToBadges < ActiveRecord::Migration[4.2] def change add_column :badges, :enabled, :boolean, default: true, null: false end diff --git a/db/migrate/20140715013018_correct_post_number_index.rb b/db/migrate/20140715013018_correct_post_number_index.rb index 5aeb03f7a77..f554e01dea8 100644 --- a/db/migrate/20140715013018_correct_post_number_index.rb +++ b/db/migrate/20140715013018_correct_post_number_index.rb @@ -1,4 +1,4 @@ -class CorrectPostNumberIndex < ActiveRecord::Migration +class CorrectPostNumberIndex < ActiveRecord::Migration[4.2] def change begin diff --git a/db/migrate/20140715051412_add_auto_revoke_to_badges.rb b/db/migrate/20140715051412_add_auto_revoke_to_badges.rb index a86127f4e02..b7e4a741756 100644 --- a/db/migrate/20140715051412_add_auto_revoke_to_badges.rb +++ b/db/migrate/20140715051412_add_auto_revoke_to_badges.rb @@ -1,4 +1,4 @@ -class AddAutoRevokeToBadges < ActiveRecord::Migration +class AddAutoRevokeToBadges < ActiveRecord::Migration[4.2] def change add_column :badges, :auto_revoke, :boolean, default: true, null: false end diff --git a/db/migrate/20140715055242_add_quoted_posts.rb b/db/migrate/20140715055242_add_quoted_posts.rb index 6dd573e031e..7c29156facf 100644 --- a/db/migrate/20140715055242_add_quoted_posts.rb +++ b/db/migrate/20140715055242_add_quoted_posts.rb @@ -1,4 +1,4 @@ -class AddQuotedPosts < ActiveRecord::Migration +class AddQuotedPosts < ActiveRecord::Migration[4.2] def change create_table :quoted_posts do |t| t.integer :post_id, null: false diff --git a/db/migrate/20140715160720_update_users_case_insensitive_emails.rb b/db/migrate/20140715160720_update_users_case_insensitive_emails.rb index 13c1aebefad..ea0c876c784 100644 --- a/db/migrate/20140715160720_update_users_case_insensitive_emails.rb +++ b/db/migrate/20140715160720_update_users_case_insensitive_emails.rb @@ -1,4 +1,4 @@ -class UpdateUsersCaseInsensitiveEmails < ActiveRecord::Migration +class UpdateUsersCaseInsensitiveEmails < ActiveRecord::Migration[4.2] def up execute "DROP INDEX index_users_on_email" diff --git a/db/migrate/20140715190552_remove_uncategorized_parents.rb b/db/migrate/20140715190552_remove_uncategorized_parents.rb index ebfc334277f..f29ae00a7a9 100644 --- a/db/migrate/20140715190552_remove_uncategorized_parents.rb +++ b/db/migrate/20140715190552_remove_uncategorized_parents.rb @@ -1,4 +1,4 @@ -class RemoveUncategorizedParents < ActiveRecord::Migration +class RemoveUncategorizedParents < ActiveRecord::Migration[4.2] def up uncat = execute("SELECT value FROM site_settings WHERE name = 'uncategorized_category_id'") if uncat && uncat[0] && uncat[0]['value'] diff --git a/db/migrate/20140716063802_add_badge_groupings.rb b/db/migrate/20140716063802_add_badge_groupings.rb index 8ea63ed7797..806d615e421 100644 --- a/db/migrate/20140716063802_add_badge_groupings.rb +++ b/db/migrate/20140716063802_add_badge_groupings.rb @@ -1,4 +1,4 @@ -class AddBadgeGroupings < ActiveRecord::Migration +class AddBadgeGroupings < ActiveRecord::Migration[4.2] def change create_table :badge_groupings do |t| t.string :name, null: false diff --git a/db/migrate/20140717024528_description_optional_in_badge_grouping.rb b/db/migrate/20140717024528_description_optional_in_badge_grouping.rb index d5be6dc5d7f..323a5597127 100644 --- a/db/migrate/20140717024528_description_optional_in_badge_grouping.rb +++ b/db/migrate/20140717024528_description_optional_in_badge_grouping.rb @@ -1,4 +1,4 @@ -class DescriptionOptionalInBadgeGrouping < ActiveRecord::Migration +class DescriptionOptionalInBadgeGrouping < ActiveRecord::Migration[4.2] def change change_column :badge_groupings, :description, :text, null: true end diff --git a/db/migrate/20140718041445_set_default_badge_grouping.rb b/db/migrate/20140718041445_set_default_badge_grouping.rb index 8b1b3591c9a..9615a9996f1 100644 --- a/db/migrate/20140718041445_set_default_badge_grouping.rb +++ b/db/migrate/20140718041445_set_default_badge_grouping.rb @@ -1,4 +1,4 @@ -class SetDefaultBadgeGrouping < ActiveRecord::Migration +class SetDefaultBadgeGrouping < ActiveRecord::Migration[4.2] def change execute 'UPDATE badges SET badge_grouping_id = 5 WHERE badge_grouping_id IS NULL' change_column :badges, :badge_grouping_id, :integer, null: false, default: 5 diff --git a/db/migrate/20140721063820_add_trigger_to_badges.rb b/db/migrate/20140721063820_add_trigger_to_badges.rb index 743b2a8357e..eec45e3f583 100644 --- a/db/migrate/20140721063820_add_trigger_to_badges.rb +++ b/db/migrate/20140721063820_add_trigger_to_badges.rb @@ -1,4 +1,4 @@ -class AddTriggerToBadges < ActiveRecord::Migration +class AddTriggerToBadges < ActiveRecord::Migration[4.2] def change add_column :badges, :trigger, :integer end diff --git a/db/migrate/20140721161249_add_agreed_at_and_agreed_by_id_to_post_action.rb b/db/migrate/20140721161249_add_agreed_at_and_agreed_by_id_to_post_action.rb index c676a0faf5c..549751b6cc1 100644 --- a/db/migrate/20140721161249_add_agreed_at_and_agreed_by_id_to_post_action.rb +++ b/db/migrate/20140721161249_add_agreed_at_and_agreed_by_id_to_post_action.rb @@ -1,4 +1,4 @@ -class AddAgreedAtAndAgreedByIdToPostAction < ActiveRecord::Migration +class AddAgreedAtAndAgreedByIdToPostAction < ActiveRecord::Migration[4.2] def change add_column :post_actions, :agreed_at, :datetime add_column :post_actions, :agreed_by_id, :integer diff --git a/db/migrate/20140721162307_rename_defer_columns_on_post_action.rb b/db/migrate/20140721162307_rename_defer_columns_on_post_action.rb index 7a02bc139a7..99ecbfa792f 100644 --- a/db/migrate/20140721162307_rename_defer_columns_on_post_action.rb +++ b/db/migrate/20140721162307_rename_defer_columns_on_post_action.rb @@ -1,4 +1,4 @@ -class RenameDeferColumnsOnPostAction < ActiveRecord::Migration +class RenameDeferColumnsOnPostAction < ActiveRecord::Migration[4.2] def up rename_column :post_actions, :defer_by, :defered_by_id diff --git a/db/migrate/20140723011456_add_show_posts_to_badges.rb b/db/migrate/20140723011456_add_show_posts_to_badges.rb index d830861af76..3b4190d41ee 100644 --- a/db/migrate/20140723011456_add_show_posts_to_badges.rb +++ b/db/migrate/20140723011456_add_show_posts_to_badges.rb @@ -1,4 +1,4 @@ -class AddShowPostsToBadges < ActiveRecord::Migration +class AddShowPostsToBadges < ActiveRecord::Migration[4.2] def change # show posts to users on badge show page add_column :badges, :show_posts, :boolean, null: false, default: false diff --git a/db/migrate/20140725050636_remove_invalid_incoming_links.rb b/db/migrate/20140725050636_remove_invalid_incoming_links.rb index ae6833ef326..56eecad2a6b 100644 --- a/db/migrate/20140725050636_remove_invalid_incoming_links.rb +++ b/db/migrate/20140725050636_remove_invalid_incoming_links.rb @@ -1,4 +1,4 @@ -class RemoveInvalidIncomingLinks < ActiveRecord::Migration +class RemoveInvalidIncomingLinks < ActiveRecord::Migration[4.2] def change execute "DELETE FROM incoming_links WHERE url ILIKE '%avatar%.png'" end diff --git a/db/migrate/20140725172830_remove_message_from_post_action.rb b/db/migrate/20140725172830_remove_message_from_post_action.rb index 778d99a7f88..8521705a708 100644 --- a/db/migrate/20140725172830_remove_message_from_post_action.rb +++ b/db/migrate/20140725172830_remove_message_from_post_action.rb @@ -1,4 +1,4 @@ -class RemoveMessageFromPostAction < ActiveRecord::Migration +class RemoveMessageFromPostAction < ActiveRecord::Migration[4.2] def up remove_column :post_actions, :message end diff --git a/db/migrate/20140727030954_add_edit_history_public_to_users.rb b/db/migrate/20140727030954_add_edit_history_public_to_users.rb index 61d571aeb79..e738497d37c 100644 --- a/db/migrate/20140727030954_add_edit_history_public_to_users.rb +++ b/db/migrate/20140727030954_add_edit_history_public_to_users.rb @@ -1,4 +1,4 @@ -class AddEditHistoryPublicToUsers < ActiveRecord::Migration +class AddEditHistoryPublicToUsers < ActiveRecord::Migration[4.2] def change add_column :users, :edit_history_public, :boolean, default: false, null: false end diff --git a/db/migrate/20140728120708_fix_index_on_post_action.rb b/db/migrate/20140728120708_fix_index_on_post_action.rb index 23be8acecdd..5752e45e2c8 100644 --- a/db/migrate/20140728120708_fix_index_on_post_action.rb +++ b/db/migrate/20140728120708_fix_index_on_post_action.rb @@ -1,4 +1,4 @@ -class FixIndexOnPostAction < ActiveRecord::Migration +class FixIndexOnPostAction < ActiveRecord::Migration[4.2] def change remove_index "post_actions", name: "idx_unique_actions" add_index "post_actions", ["user_id", "post_action_type_id", "post_id", "deleted_at", "targets_topic"], name: "idx_unique_actions", unique: true diff --git a/db/migrate/20140728144308_add_first_post_created_at_to_user_stat.rb b/db/migrate/20140728144308_add_first_post_created_at_to_user_stat.rb index 34dfca71cb5..c163c9a63be 100644 --- a/db/migrate/20140728144308_add_first_post_created_at_to_user_stat.rb +++ b/db/migrate/20140728144308_add_first_post_created_at_to_user_stat.rb @@ -1,4 +1,4 @@ -class AddFirstPostCreatedAtToUserStat < ActiveRecord::Migration +class AddFirstPostCreatedAtToUserStat < ActiveRecord::Migration[4.2] def up add_column :user_stats, :first_post_created_at, :datetime diff --git a/db/migrate/20140728152804_add_post_and_topic_counts_to_user_stat.rb b/db/migrate/20140728152804_add_post_and_topic_counts_to_user_stat.rb index 3152191d16b..055ad3cb0b2 100644 --- a/db/migrate/20140728152804_add_post_and_topic_counts_to_user_stat.rb +++ b/db/migrate/20140728152804_add_post_and_topic_counts_to_user_stat.rb @@ -1,4 +1,4 @@ -class AddPostAndTopicCountsToUserStat < ActiveRecord::Migration +class AddPostAndTopicCountsToUserStat < ActiveRecord::Migration[4.2] def up add_column :user_stats, :post_count, :integer, default: 0, null: false add_column :user_stats, :topic_count, :integer, default: 0, null: false diff --git a/db/migrate/20140729092525_remove_unique_constraint_from_invites_index.rb b/db/migrate/20140729092525_remove_unique_constraint_from_invites_index.rb index 6ec759f65cc..f250648c05a 100644 --- a/db/migrate/20140729092525_remove_unique_constraint_from_invites_index.rb +++ b/db/migrate/20140729092525_remove_unique_constraint_from_invites_index.rb @@ -1,4 +1,4 @@ -class RemoveUniqueConstraintFromInvitesIndex < ActiveRecord::Migration +class RemoveUniqueConstraintFromInvitesIndex < ActiveRecord::Migration[4.2] def up remove_index :invites, [:email, :invited_by_id] add_index :invites, [:email, :invited_by_id], unique: false diff --git a/db/migrate/20140730203029_add_disagreed_at_and_disagreed_by_id_to_post_action.rb b/db/migrate/20140730203029_add_disagreed_at_and_disagreed_by_id_to_post_action.rb index 4b9aefa8921..5a458424dd3 100644 --- a/db/migrate/20140730203029_add_disagreed_at_and_disagreed_by_id_to_post_action.rb +++ b/db/migrate/20140730203029_add_disagreed_at_and_disagreed_by_id_to_post_action.rb @@ -1,4 +1,4 @@ -class AddDisagreedAtAndDisagreedByIdToPostAction < ActiveRecord::Migration +class AddDisagreedAtAndDisagreedByIdToPostAction < ActiveRecord::Migration[4.2] def up add_column :post_actions, :disagreed_at, :datetime add_column :post_actions, :disagreed_by_id, :integer diff --git a/db/migrate/20140731011328_add_reply_quoted_to_posts.rb b/db/migrate/20140731011328_add_reply_quoted_to_posts.rb index 8dc7a8d4461..d21ad72a559 100644 --- a/db/migrate/20140731011328_add_reply_quoted_to_posts.rb +++ b/db/migrate/20140731011328_add_reply_quoted_to_posts.rb @@ -1,4 +1,4 @@ -class AddReplyQuotedToPosts < ActiveRecord::Migration +class AddReplyQuotedToPosts < ActiveRecord::Migration[4.2] def up add_column :posts, :reply_quoted, :boolean, null: false, default: false execute "UPDATE posts p diff --git a/db/migrate/20140801052028_fix_incoming_links.rb b/db/migrate/20140801052028_fix_incoming_links.rb index c00ac021a26..d2b8f85c07f 100644 --- a/db/migrate/20140801052028_fix_incoming_links.rb +++ b/db/migrate/20140801052028_fix_incoming_links.rb @@ -1,4 +1,4 @@ -class FixIncomingLinks < ActiveRecord::Migration +class FixIncomingLinks < ActiveRecord::Migration[4.2] def up execute "DROP INDEX incoming_index" add_column :incoming_links, :post_id, :integer diff --git a/db/migrate/20140801170444_create_post_timings_user_index.rb b/db/migrate/20140801170444_create_post_timings_user_index.rb index c33b84f862b..dde6da3b513 100644 --- a/db/migrate/20140801170444_create_post_timings_user_index.rb +++ b/db/migrate/20140801170444_create_post_timings_user_index.rb @@ -1,4 +1,4 @@ -class CreatePostTimingsUserIndex < ActiveRecord::Migration +class CreatePostTimingsUserIndex < ActiveRecord::Migration[4.2] def change add_index :post_timings, :user_id end diff --git a/db/migrate/20140804010803_incoming_link_normalization.rb b/db/migrate/20140804010803_incoming_link_normalization.rb index 171451dff51..4d8c04c09d7 100644 --- a/db/migrate/20140804010803_incoming_link_normalization.rb +++ b/db/migrate/20140804010803_incoming_link_normalization.rb @@ -1,4 +1,4 @@ -class IncomingLinkNormalization < ActiveRecord::Migration +class IncomingLinkNormalization < ActiveRecord::Migration[4.2] def up remove_column :incoming_links, :post_number remove_column :incoming_links, :domain diff --git a/db/migrate/20140804030041_remove_url_from_incoming_referer.rb b/db/migrate/20140804030041_remove_url_from_incoming_referer.rb index 33061941324..75abede78eb 100644 --- a/db/migrate/20140804030041_remove_url_from_incoming_referer.rb +++ b/db/migrate/20140804030041_remove_url_from_incoming_referer.rb @@ -1,4 +1,4 @@ -class RemoveUrlFromIncomingReferer < ActiveRecord::Migration +class RemoveUrlFromIncomingReferer < ActiveRecord::Migration[4.2] def up remove_column :incoming_referers, :url end diff --git a/db/migrate/20140804060439_drop_topic_id_from_incoming_links.rb b/db/migrate/20140804060439_drop_topic_id_from_incoming_links.rb index 305e93ea188..15fdc10ddb9 100644 --- a/db/migrate/20140804060439_drop_topic_id_from_incoming_links.rb +++ b/db/migrate/20140804060439_drop_topic_id_from_incoming_links.rb @@ -1,4 +1,4 @@ -class DropTopicIdFromIncomingLinks < ActiveRecord::Migration +class DropTopicIdFromIncomingLinks < ActiveRecord::Migration[4.2] def change remove_column :incoming_links, :topic_id end diff --git a/db/migrate/20140804072504_views_to_topic_views.rb b/db/migrate/20140804072504_views_to_topic_views.rb index 16e78bc9416..d88620afba0 100644 --- a/db/migrate/20140804072504_views_to_topic_views.rb +++ b/db/migrate/20140804072504_views_to_topic_views.rb @@ -1,4 +1,4 @@ -class ViewsToTopicViews < ActiveRecord::Migration +class ViewsToTopicViews < ActiveRecord::Migration[4.2] def change remove_column :views, :parent_type rename_column :views, :parent_id, :topic_id diff --git a/db/migrate/20140804075613_normalize_topic_view_data_and_index.rb b/db/migrate/20140804075613_normalize_topic_view_data_and_index.rb index 67b9d784b5b..eedb52fb388 100644 --- a/db/migrate/20140804075613_normalize_topic_view_data_and_index.rb +++ b/db/migrate/20140804075613_normalize_topic_view_data_and_index.rb @@ -1,4 +1,4 @@ -class NormalizeTopicViewDataAndIndex < ActiveRecord::Migration +class NormalizeTopicViewDataAndIndex < ActiveRecord::Migration[4.2] def change remove_index :topic_views, [:topic_id] remove_index :topic_views, [:user_id, :topic_id] diff --git a/db/migrate/20140805061612_add_bio_cooked_version_to_user_profile.rb b/db/migrate/20140805061612_add_bio_cooked_version_to_user_profile.rb index 200e3f4198e..56d72bc1f07 100644 --- a/db/migrate/20140805061612_add_bio_cooked_version_to_user_profile.rb +++ b/db/migrate/20140805061612_add_bio_cooked_version_to_user_profile.rb @@ -1,4 +1,4 @@ -class AddBioCookedVersionToUserProfile < ActiveRecord::Migration +class AddBioCookedVersionToUserProfile < ActiveRecord::Migration[4.2] def change add_column :user_profiles, :bio_cooked_version, :integer add_index :user_profiles, [:bio_cooked_version] diff --git a/db/migrate/20140806003116_fixup_badge_ids.rb b/db/migrate/20140806003116_fixup_badge_ids.rb index 61dc0a4caa7..f64e7c42215 100644 --- a/db/migrate/20140806003116_fixup_badge_ids.rb +++ b/db/migrate/20140806003116_fixup_badge_ids.rb @@ -1,4 +1,4 @@ -class FixupBadgeIds < ActiveRecord::Migration +class FixupBadgeIds < ActiveRecord::Migration[4.2] def change # badge ids were below 100, for user badges, this really messed stuff up # to resolve this add a "system" flag which we can use to figure out what diff --git a/db/migrate/20140807033123_add_index_on_last_seen_to_users.rb b/db/migrate/20140807033123_add_index_on_last_seen_to_users.rb index dc7eecc8857..2b7e5231998 100644 --- a/db/migrate/20140807033123_add_index_on_last_seen_to_users.rb +++ b/db/migrate/20140807033123_add_index_on_last_seen_to_users.rb @@ -1,4 +1,4 @@ -class AddIndexOnLastSeenToUsers < ActiveRecord::Migration +class AddIndexOnLastSeenToUsers < ActiveRecord::Migration[4.2] def change add_index :users, [:last_seen_at] end diff --git a/db/migrate/20140808051823_create_topic_search_index.rb b/db/migrate/20140808051823_create_topic_search_index.rb index 1a154e6a082..6edfc1e5feb 100644 --- a/db/migrate/20140808051823_create_topic_search_index.rb +++ b/db/migrate/20140808051823_create_topic_search_index.rb @@ -1,4 +1,4 @@ -class CreateTopicSearchIndex < ActiveRecord::Migration +class CreateTopicSearchIndex < ActiveRecord::Migration[4.2] def up # used for similarity search create_table :topic_search_data, id: false do |t| diff --git a/db/migrate/20140809224243_add_user_badge_unique_index.rb b/db/migrate/20140809224243_add_user_badge_unique_index.rb index aefb27af477..83f8be6dafa 100644 --- a/db/migrate/20140809224243_add_user_badge_unique_index.rb +++ b/db/migrate/20140809224243_add_user_badge_unique_index.rb @@ -1,4 +1,4 @@ -class AddUserBadgeUniqueIndex < ActiveRecord::Migration +class AddUserBadgeUniqueIndex < ActiveRecord::Migration[4.2] def up # used to keep badges distinct add_column :user_badges, :seq, :integer, default: 0, null: false diff --git a/db/migrate/20140811094300_rename_defered_columns_on_post_action.rb b/db/migrate/20140811094300_rename_defered_columns_on_post_action.rb index ad4f7c50a2b..635562c432d 100644 --- a/db/migrate/20140811094300_rename_defered_columns_on_post_action.rb +++ b/db/migrate/20140811094300_rename_defered_columns_on_post_action.rb @@ -1,4 +1,4 @@ -class RenameDeferedColumnsOnPostAction < ActiveRecord::Migration +class RenameDeferedColumnsOnPostAction < ActiveRecord::Migration[4.2] def change rename_column :post_actions, :defered_by_id, :deferred_by_id rename_column :post_actions, :defered_at, :deferred_at diff --git a/db/migrate/20140813175357_add_default_to_active.rb b/db/migrate/20140813175357_add_default_to_active.rb index 5d5000fe32a..dcf60f63d2a 100644 --- a/db/migrate/20140813175357_add_default_to_active.rb +++ b/db/migrate/20140813175357_add_default_to_active.rb @@ -1,4 +1,4 @@ -class AddDefaultToActive < ActiveRecord::Migration +class AddDefaultToActive < ActiveRecord::Migration[4.2] def change change_column :users, :active, :boolean, default: false, null: false end diff --git a/db/migrate/20140815183851_fix_index_on_post_actions.rb b/db/migrate/20140815183851_fix_index_on_post_actions.rb index ed403da399e..e899a702b68 100644 --- a/db/migrate/20140815183851_fix_index_on_post_actions.rb +++ b/db/migrate/20140815183851_fix_index_on_post_actions.rb @@ -1,4 +1,4 @@ -class FixIndexOnPostActions < ActiveRecord::Migration +class FixIndexOnPostActions < ActiveRecord::Migration[4.2] def change execute 'UPDATE post_actions SET targets_topic = false WHERE targets_topic IS NULL' change_column :post_actions, :targets_topic, :boolean, default: false, null: false diff --git a/db/migrate/20140815191556_fix_post_actions_index_again.rb b/db/migrate/20140815191556_fix_post_actions_index_again.rb index 1979cbb8a93..93310192a46 100644 --- a/db/migrate/20140815191556_fix_post_actions_index_again.rb +++ b/db/migrate/20140815191556_fix_post_actions_index_again.rb @@ -1,4 +1,4 @@ -class FixPostActionsIndexAgain < ActiveRecord::Migration +class FixPostActionsIndexAgain < ActiveRecord::Migration[4.2] def change remove_index "post_actions", name: "idx_unique_actions" add_index "post_actions", diff --git a/db/migrate/20140815215618_add_name_lower_to_categories.rb b/db/migrate/20140815215618_add_name_lower_to_categories.rb index 20f6ef8c374..6672608ebbf 100644 --- a/db/migrate/20140815215618_add_name_lower_to_categories.rb +++ b/db/migrate/20140815215618_add_name_lower_to_categories.rb @@ -1,4 +1,4 @@ -class AddNameLowerToCategories < ActiveRecord::Migration +class AddNameLowerToCategories < ActiveRecord::Migration[4.2] def up add_column :categories, :name_lower, :string, limit: 50 diff --git a/db/migrate/20140817011612_add_external_avatar_url_to_single_sign_on_record.rb b/db/migrate/20140817011612_add_external_avatar_url_to_single_sign_on_record.rb index 6069d8771e6..cc664ae52a7 100644 --- a/db/migrate/20140817011612_add_external_avatar_url_to_single_sign_on_record.rb +++ b/db/migrate/20140817011612_add_external_avatar_url_to_single_sign_on_record.rb @@ -1,4 +1,4 @@ -class AddExternalAvatarUrlToSingleSignOnRecord < ActiveRecord::Migration +class AddExternalAvatarUrlToSingleSignOnRecord < ActiveRecord::Migration[4.2] def change add_column :single_sign_on_records, :external_avatar_url, :string end diff --git a/db/migrate/20140818023700_index_email_tokens.rb b/db/migrate/20140818023700_index_email_tokens.rb index 8f855f679e2..fe7a041e122 100644 --- a/db/migrate/20140818023700_index_email_tokens.rb +++ b/db/migrate/20140818023700_index_email_tokens.rb @@ -1,4 +1,4 @@ -class IndexEmailTokens < ActiveRecord::Migration +class IndexEmailTokens < ActiveRecord::Migration[4.2] def change add_index :email_tokens, [:user_id] end diff --git a/db/migrate/20140826234625_rename_settings_pop3s_to_pop3.rb b/db/migrate/20140826234625_rename_settings_pop3s_to_pop3.rb index 0672e5168fd..1d8b1c6b004 100644 --- a/db/migrate/20140826234625_rename_settings_pop3s_to_pop3.rb +++ b/db/migrate/20140826234625_rename_settings_pop3s_to_pop3.rb @@ -1,4 +1,4 @@ -class RenameSettingsPop3sToPop3 < ActiveRecord::Migration +class RenameSettingsPop3sToPop3 < ActiveRecord::Migration[4.2] def up execute "UPDATE site_settings SET name = replace(name, 'pop3s', 'pop3') WHERE name ILIKE 'pop3%'" end diff --git a/db/migrate/20140827044811_remove_nullable_dates.rb b/db/migrate/20140827044811_remove_nullable_dates.rb index 3f8f2211be5..2baf9745a66 100644 --- a/db/migrate/20140827044811_remove_nullable_dates.rb +++ b/db/migrate/20140827044811_remove_nullable_dates.rb @@ -1,4 +1,4 @@ -class RemoveNullableDates < ActiveRecord::Migration +class RemoveNullableDates < ActiveRecord::Migration[4.2] def up # must drop so we can muck with the column diff --git a/db/migrate/20140828172407_create_permalinks.rb b/db/migrate/20140828172407_create_permalinks.rb index cc2e1a687f5..564907b4878 100644 --- a/db/migrate/20140828172407_create_permalinks.rb +++ b/db/migrate/20140828172407_create_permalinks.rb @@ -1,4 +1,4 @@ -class CreatePermalinks < ActiveRecord::Migration +class CreatePermalinks < ActiveRecord::Migration[4.2] def change create_table :permalinks do |t| t.string :url, null: false diff --git a/db/migrate/20140828200231_make_url_col_bigger_in_permalinks.rb b/db/migrate/20140828200231_make_url_col_bigger_in_permalinks.rb index f2767d1a2a8..653510c8c46 100644 --- a/db/migrate/20140828200231_make_url_col_bigger_in_permalinks.rb +++ b/db/migrate/20140828200231_make_url_col_bigger_in_permalinks.rb @@ -1,4 +1,4 @@ -class MakeUrlColBiggerInPermalinks < ActiveRecord::Migration +class MakeUrlColBiggerInPermalinks < ActiveRecord::Migration[4.2] def up remove_index :permalinks, :url change_column :permalinks, :url, :string, limit: 1000, null: false diff --git a/db/migrate/20140831191346_remove_category_groups_orphaned_by_removing_category_or_group.rb b/db/migrate/20140831191346_remove_category_groups_orphaned_by_removing_category_or_group.rb index 2e19870c2bc..fd30ea531a1 100644 --- a/db/migrate/20140831191346_remove_category_groups_orphaned_by_removing_category_or_group.rb +++ b/db/migrate/20140831191346_remove_category_groups_orphaned_by_removing_category_or_group.rb @@ -1,4 +1,4 @@ -class RemoveCategoryGroupsOrphanedByRemovingCategoryOrGroup < ActiveRecord::Migration +class RemoveCategoryGroupsOrphanedByRemovingCategoryOrGroup < ActiveRecord::Migration[4.2] def up execute "DELETE FROM category_groups WHERE group_id NOT IN ( diff --git a/db/migrate/20140904055702_correct_post_action_index.rb b/db/migrate/20140904055702_correct_post_action_index.rb index a582d19f8e6..f98e1258852 100644 --- a/db/migrate/20140904055702_correct_post_action_index.rb +++ b/db/migrate/20140904055702_correct_post_action_index.rb @@ -1,4 +1,4 @@ -class CorrectPostActionIndex < ActiveRecord::Migration +class CorrectPostActionIndex < ActiveRecord::Migration[4.2] def up diff --git a/db/migrate/20140904160015_add_via_email_to_posts.rb b/db/migrate/20140904160015_add_via_email_to_posts.rb index 2b3425b0689..bf3cb33e090 100644 --- a/db/migrate/20140904160015_add_via_email_to_posts.rb +++ b/db/migrate/20140904160015_add_via_email_to_posts.rb @@ -1,4 +1,4 @@ -class AddViaEmailToPosts < ActiveRecord::Migration +class AddViaEmailToPosts < ActiveRecord::Migration[4.2] def change add_column :posts, :via_email, :boolean, default: false, null: false end diff --git a/db/migrate/20140904215629_rename_trust_level_settings.rb b/db/migrate/20140904215629_rename_trust_level_settings.rb index 317fb6ae004..f19af1a5b54 100644 --- a/db/migrate/20140904215629_rename_trust_level_settings.rb +++ b/db/migrate/20140904215629_rename_trust_level_settings.rb @@ -1,4 +1,4 @@ -class RenameTrustLevelSettings < ActiveRecord::Migration +class RenameTrustLevelSettings < ActiveRecord::Migration[4.2] def up execute "UPDATE site_settings SET name = regexp_replace(name, '^basic_', 'tl1_')" diff --git a/db/migrate/20140905055251_rename_trust_level_badges.rb b/db/migrate/20140905055251_rename_trust_level_badges.rb index 40b34e0dd05..db6e341f2e8 100644 --- a/db/migrate/20140905055251_rename_trust_level_badges.rb +++ b/db/migrate/20140905055251_rename_trust_level_badges.rb @@ -1,4 +1,4 @@ -class RenameTrustLevelBadges < ActiveRecord::Migration +class RenameTrustLevelBadges < ActiveRecord::Migration[4.2] def rename(id, old, new) execute "UPDATE badges SET name = '#{new}' WHERE name = '#{old}' AND id = #{id}" diff --git a/db/migrate/20140905171733_create_warnings.rb b/db/migrate/20140905171733_create_warnings.rb index c3da0e5c538..7c0ae9931c4 100644 --- a/db/migrate/20140905171733_create_warnings.rb +++ b/db/migrate/20140905171733_create_warnings.rb @@ -1,4 +1,4 @@ -class CreateWarnings < ActiveRecord::Migration +class CreateWarnings < ActiveRecord::Migration[4.2] def change create_table :warnings do |t| t.references :topic, null: false diff --git a/db/migrate/20140908165716_migrate_warning_topic_subtypes.rb b/db/migrate/20140908165716_migrate_warning_topic_subtypes.rb index 30b477a809d..cddb771ffd0 100644 --- a/db/migrate/20140908165716_migrate_warning_topic_subtypes.rb +++ b/db/migrate/20140908165716_migrate_warning_topic_subtypes.rb @@ -1,4 +1,4 @@ -class MigrateWarningTopicSubtypes < ActiveRecord::Migration +class MigrateWarningTopicSubtypes < ActiveRecord::Migration[4.2] def change execute "UPDATE topics AS t SET subtype = 'moderator_warning' diff --git a/db/migrate/20140908191429_trim_profile_length.rb b/db/migrate/20140908191429_trim_profile_length.rb index 4651bcae2e5..739e1ea7bda 100644 --- a/db/migrate/20140908191429_trim_profile_length.rb +++ b/db/migrate/20140908191429_trim_profile_length.rb @@ -1,4 +1,4 @@ -class TrimProfileLength < ActiveRecord::Migration +class TrimProfileLength < ActiveRecord::Migration[4.2] def change # In case any profiles exceed 3000 chars execute "UPDATE user_profiles SET bio_raw=LEFT(bio_raw, 3000)" diff --git a/db/migrate/20140910130155_create_topic_user_index.rb b/db/migrate/20140910130155_create_topic_user_index.rb index 0f02e645348..8f3eaecddd9 100644 --- a/db/migrate/20140910130155_create_topic_user_index.rb +++ b/db/migrate/20140910130155_create_topic_user_index.rb @@ -1,4 +1,4 @@ -class CreateTopicUserIndex < ActiveRecord::Migration +class CreateTopicUserIndex < ActiveRecord::Migration[4.2] def change # seems to be the most effective for joining into topics add_index :topic_users, [:user_id, :topic_id], unique: true diff --git a/db/migrate/20140911065449_private_messages_have_no_category_id.rb b/db/migrate/20140911065449_private_messages_have_no_category_id.rb index c02ea84e5ae..32b058a4d08 100644 --- a/db/migrate/20140911065449_private_messages_have_no_category_id.rb +++ b/db/migrate/20140911065449_private_messages_have_no_category_id.rb @@ -1,4 +1,4 @@ -class PrivateMessagesHaveNoCategoryId < ActiveRecord::Migration +class PrivateMessagesHaveNoCategoryId < ActiveRecord::Migration[4.2] def up execute "UPDATE topics SET category_id = NULL WHERE category_id IS NOT NULL AND archetype = \'private_message\'" execute "ALTER TABLE topics ADD CONSTRAINT pm_has_no_category CHECK (category_id IS NULL OR archetype <> 'private_message')" diff --git a/db/migrate/20140913192733_add_trust_level_locked_column.rb b/db/migrate/20140913192733_add_trust_level_locked_column.rb index c086f4a2fde..71b34b0086d 100644 --- a/db/migrate/20140913192733_add_trust_level_locked_column.rb +++ b/db/migrate/20140913192733_add_trust_level_locked_column.rb @@ -1,4 +1,4 @@ -class AddTrustLevelLockedColumn < ActiveRecord::Migration +class AddTrustLevelLockedColumn < ActiveRecord::Migration[4.2] def change add_column :users, :trust_level_locked, :boolean, default: false, null: false diff --git a/db/migrate/20140923042349_add_retain_hours_to_uploads.rb b/db/migrate/20140923042349_add_retain_hours_to_uploads.rb index 38aea048f8a..513f686d579 100644 --- a/db/migrate/20140923042349_add_retain_hours_to_uploads.rb +++ b/db/migrate/20140923042349_add_retain_hours_to_uploads.rb @@ -1,4 +1,4 @@ -class AddRetainHoursToUploads < ActiveRecord::Migration +class AddRetainHoursToUploads < ActiveRecord::Migration[4.2] def change add_column :uploads, :retain_hours, :integer end diff --git a/db/migrate/20140924192418_rename_content_type.rb b/db/migrate/20140924192418_rename_content_type.rb index 31620962030..0f428aa02a5 100644 --- a/db/migrate/20140924192418_rename_content_type.rb +++ b/db/migrate/20140924192418_rename_content_type.rb @@ -1,4 +1,4 @@ -class RenameContentType < ActiveRecord::Migration +class RenameContentType < ActiveRecord::Migration[4.2] def change rename_column :site_contents, :content_type, :text_type rename_column :site_contents, :content, :value diff --git a/db/migrate/20140925173220_create_user_fields.rb b/db/migrate/20140925173220_create_user_fields.rb index 5aad6efb8e5..03ae8dec139 100644 --- a/db/migrate/20140925173220_create_user_fields.rb +++ b/db/migrate/20140925173220_create_user_fields.rb @@ -1,4 +1,4 @@ -class CreateUserFields < ActiveRecord::Migration +class CreateUserFields < ActiveRecord::Migration[4.2] def change create_table :user_fields do |t| t.string :name, null: false diff --git a/db/migrate/20140929181930_add_editable_to_user_fields.rb b/db/migrate/20140929181930_add_editable_to_user_fields.rb index bfb4ee47462..f3399901d93 100644 --- a/db/migrate/20140929181930_add_editable_to_user_fields.rb +++ b/db/migrate/20140929181930_add_editable_to_user_fields.rb @@ -1,4 +1,4 @@ -class AddEditableToUserFields < ActiveRecord::Migration +class AddEditableToUserFields < ActiveRecord::Migration[4.2] def change add_column :user_fields, :editable, :boolean, default: false, null: false end diff --git a/db/migrate/20140929204155_migrate_tos_setting.rb b/db/migrate/20140929204155_migrate_tos_setting.rb index 6ecac45bb81..6f2e91a534a 100644 --- a/db/migrate/20140929204155_migrate_tos_setting.rb +++ b/db/migrate/20140929204155_migrate_tos_setting.rb @@ -1,4 +1,4 @@ -class MigrateTosSetting < ActiveRecord::Migration +class MigrateTosSetting < ActiveRecord::Migration[4.2] def up res = execute("SELECT * FROM site_settings WHERE name = 'tos_accept_required' AND value = 't'") if res.present? && res.cmd_tuples > 0 diff --git a/db/migrate/20141001101041_add_post_id_to_user_histories.rb b/db/migrate/20141001101041_add_post_id_to_user_histories.rb index 049ad95a753..cd70b1308b4 100644 --- a/db/migrate/20141001101041_add_post_id_to_user_histories.rb +++ b/db/migrate/20141001101041_add_post_id_to_user_histories.rb @@ -1,4 +1,4 @@ -class AddPostIdToUserHistories < ActiveRecord::Migration +class AddPostIdToUserHistories < ActiveRecord::Migration[4.2] def change add_column :user_histories, :post_id, :integer end diff --git a/db/migrate/20141002181613_add_description_to_user_fields.rb b/db/migrate/20141002181613_add_description_to_user_fields.rb index 5bebb80bdec..1495975c47a 100644 --- a/db/migrate/20141002181613_add_description_to_user_fields.rb +++ b/db/migrate/20141002181613_add_description_to_user_fields.rb @@ -1,4 +1,4 @@ -class AddDescriptionToUserFields < ActiveRecord::Migration +class AddDescriptionToUserFields < ActiveRecord::Migration[4.2] def change add_column :user_fields, :description, :string, null: true execute "UPDATE user_fields SET description=name" diff --git a/db/migrate/20141007224814_add_badge_granted_title_to_user_profile.rb b/db/migrate/20141007224814_add_badge_granted_title_to_user_profile.rb index 008590121ad..73576c7b3bc 100644 --- a/db/migrate/20141007224814_add_badge_granted_title_to_user_profile.rb +++ b/db/migrate/20141007224814_add_badge_granted_title_to_user_profile.rb @@ -1,4 +1,4 @@ -class AddBadgeGrantedTitleToUserProfile < ActiveRecord::Migration +class AddBadgeGrantedTitleToUserProfile < ActiveRecord::Migration[4.2] def up add_column :user_profiles, :badge_granted_title, :boolean, default: false diff --git a/db/migrate/20141008152953_add_exernal_url_to_permalinks.rb b/db/migrate/20141008152953_add_exernal_url_to_permalinks.rb index f0ec6783737..a4fbedc514c 100644 --- a/db/migrate/20141008152953_add_exernal_url_to_permalinks.rb +++ b/db/migrate/20141008152953_add_exernal_url_to_permalinks.rb @@ -1,4 +1,4 @@ -class AddExernalUrlToPermalinks < ActiveRecord::Migration +class AddExernalUrlToPermalinks < ActiveRecord::Migration[4.2] def change add_column :permalinks, :external_url, :string, limit: 1000 end diff --git a/db/migrate/20141008181228_add_required_signup_to_user_fields.rb b/db/migrate/20141008181228_add_required_signup_to_user_fields.rb index d95286054e1..a160f51b707 100644 --- a/db/migrate/20141008181228_add_required_signup_to_user_fields.rb +++ b/db/migrate/20141008181228_add_required_signup_to_user_fields.rb @@ -1,4 +1,4 @@ -class AddRequiredSignupToUserFields < ActiveRecord::Migration +class AddRequiredSignupToUserFields < ActiveRecord::Migration[4.2] def change add_column :user_fields, :required, :boolean, default: true, null: false end diff --git a/db/migrate/20141008192525_add_auto_close_based_on_last_post_and_auto_close_hours_to_topics.rb b/db/migrate/20141008192525_add_auto_close_based_on_last_post_and_auto_close_hours_to_topics.rb index 71e8712316e..ecf5837f383 100644 --- a/db/migrate/20141008192525_add_auto_close_based_on_last_post_and_auto_close_hours_to_topics.rb +++ b/db/migrate/20141008192525_add_auto_close_based_on_last_post_and_auto_close_hours_to_topics.rb @@ -1,4 +1,4 @@ -class AddAutoCloseBasedOnLastPostAndAutoCloseHoursToTopics < ActiveRecord::Migration +class AddAutoCloseBasedOnLastPostAndAutoCloseHoursToTopics < ActiveRecord::Migration[4.2] def change add_column :topics, :auto_close_based_on_last_post, :boolean, default: false add_column :topics, :auto_close_hours, :float diff --git a/db/migrate/20141008192526_add_auto_close_based_on_last_post_to_categories.rb b/db/migrate/20141008192526_add_auto_close_based_on_last_post_to_categories.rb index 3af300abc03..bc80b617475 100644 --- a/db/migrate/20141008192526_add_auto_close_based_on_last_post_to_categories.rb +++ b/db/migrate/20141008192526_add_auto_close_based_on_last_post_to_categories.rb @@ -1,4 +1,4 @@ -class AddAutoCloseBasedOnLastPostToCategories < ActiveRecord::Migration +class AddAutoCloseBasedOnLastPostToCategories < ActiveRecord::Migration[4.2] def change add_column :categories, :auto_close_based_on_last_post, :boolean, default: false end diff --git a/db/migrate/20141014032859_add_hidden_to_post_revision.rb b/db/migrate/20141014032859_add_hidden_to_post_revision.rb index 93423e2190a..de1c2f4ba9f 100644 --- a/db/migrate/20141014032859_add_hidden_to_post_revision.rb +++ b/db/migrate/20141014032859_add_hidden_to_post_revision.rb @@ -1,4 +1,4 @@ -class AddHiddenToPostRevision < ActiveRecord::Migration +class AddHiddenToPostRevision < ActiveRecord::Migration[4.2] def change add_column :post_revisions, :hidden, :boolean, null: false, default: false end diff --git a/db/migrate/20141014191645_fix_tos_name.rb b/db/migrate/20141014191645_fix_tos_name.rb index 56059dd95f9..42daa0a1508 100644 --- a/db/migrate/20141014191645_fix_tos_name.rb +++ b/db/migrate/20141014191645_fix_tos_name.rb @@ -1,4 +1,4 @@ -class FixTosName < ActiveRecord::Migration +class FixTosName < ActiveRecord::Migration[4.2] def up I18n.overrides_disabled do execute ActiveRecord::Base.sql_fragment('UPDATE user_fields SET name = ? WHERE name = ?', I18n.t('terms_of_service.title'), I18n.t("terms_of_service.signup_form_message")) diff --git a/db/migrate/20141015060145_add_raw_email_to_posts.rb b/db/migrate/20141015060145_add_raw_email_to_posts.rb index 2c3b89b6d64..44f703e6665 100644 --- a/db/migrate/20141015060145_add_raw_email_to_posts.rb +++ b/db/migrate/20141015060145_add_raw_email_to_posts.rb @@ -1,4 +1,4 @@ -class AddRawEmailToPosts < ActiveRecord::Migration +class AddRawEmailToPosts < ActiveRecord::Migration[4.2] def change add_column :posts, :raw_email, :text end diff --git a/db/migrate/20141016183307_add_expansion_background_to_user_profiles.rb b/db/migrate/20141016183307_add_expansion_background_to_user_profiles.rb index af0c536bf46..97b85cccd91 100644 --- a/db/migrate/20141016183307_add_expansion_background_to_user_profiles.rb +++ b/db/migrate/20141016183307_add_expansion_background_to_user_profiles.rb @@ -1,4 +1,4 @@ -class AddExpansionBackgroundToUserProfiles < ActiveRecord::Migration +class AddExpansionBackgroundToUserProfiles < ActiveRecord::Migration[4.2] def change add_column :user_profiles, :expansion_background, :string, limit: 255 end diff --git a/db/migrate/20141020153415_add_public_version_to_posts.rb b/db/migrate/20141020153415_add_public_version_to_posts.rb index 52cb65f41ac..aa7f2368b39 100644 --- a/db/migrate/20141020153415_add_public_version_to_posts.rb +++ b/db/migrate/20141020153415_add_public_version_to_posts.rb @@ -1,4 +1,4 @@ -class AddPublicVersionToPosts < ActiveRecord::Migration +class AddPublicVersionToPosts < ActiveRecord::Migration[4.2] def up add_column :posts, :public_version, :integer, null: false, default: 1 diff --git a/db/migrate/20141020154935_rename_expansion_to_card.rb b/db/migrate/20141020154935_rename_expansion_to_card.rb index 9dbde2f8218..bb8b0e6a254 100644 --- a/db/migrate/20141020154935_rename_expansion_to_card.rb +++ b/db/migrate/20141020154935_rename_expansion_to_card.rb @@ -1,4 +1,4 @@ -class RenameExpansionToCard < ActiveRecord::Migration +class RenameExpansionToCard < ActiveRecord::Migration[4.2] def change rename_column :user_profiles, :expansion_background, :card_background end diff --git a/db/migrate/20141020164816_add_image_to_badges.rb b/db/migrate/20141020164816_add_image_to_badges.rb index 2d8e8c5a2b2..4d6101ecc21 100644 --- a/db/migrate/20141020164816_add_image_to_badges.rb +++ b/db/migrate/20141020164816_add_image_to_badges.rb @@ -1,4 +1,4 @@ -class AddImageToBadges < ActiveRecord::Migration +class AddImageToBadges < ActiveRecord::Migration[4.2] def change add_column :badges, :image, :string, limit: 255 end diff --git a/db/migrate/20141020174120_add_card_image_to_user_profiles.rb b/db/migrate/20141020174120_add_card_image_to_user_profiles.rb index a875ce0a56f..c94074bc810 100644 --- a/db/migrate/20141020174120_add_card_image_to_user_profiles.rb +++ b/db/migrate/20141020174120_add_card_image_to_user_profiles.rb @@ -1,4 +1,4 @@ -class AddCardImageToUserProfiles < ActiveRecord::Migration +class AddCardImageToUserProfiles < ActiveRecord::Migration[4.2] def change add_column :user_profiles, :card_image_badge_id, :integer end diff --git a/db/migrate/20141030222425_rename_seen_post_count.rb b/db/migrate/20141030222425_rename_seen_post_count.rb index dac8d14467c..8401d8d67a5 100644 --- a/db/migrate/20141030222425_rename_seen_post_count.rb +++ b/db/migrate/20141030222425_rename_seen_post_count.rb @@ -1,4 +1,4 @@ -class RenameSeenPostCount < ActiveRecord::Migration +class RenameSeenPostCount < ActiveRecord::Migration[4.2] def change rename_column :topic_users, :seen_post_count, :highest_seen_post_number end diff --git a/db/migrate/20141110150304_add_footer_to_site_customization.rb b/db/migrate/20141110150304_add_footer_to_site_customization.rb index c6819230996..c1266a1c705 100644 --- a/db/migrate/20141110150304_add_footer_to_site_customization.rb +++ b/db/migrate/20141110150304_add_footer_to_site_customization.rb @@ -1,4 +1,4 @@ -class AddFooterToSiteCustomization < ActiveRecord::Migration +class AddFooterToSiteCustomization < ActiveRecord::Migration[4.2] def change add_column :site_customizations, :footer, :text add_column :site_customizations, :mobile_footer, :text diff --git a/db/migrate/20141118011735_correct_username_search.rb b/db/migrate/20141118011735_correct_username_search.rb index fad33f0f116..996b87e79bf 100644 --- a/db/migrate/20141118011735_correct_username_search.rb +++ b/db/migrate/20141118011735_correct_username_search.rb @@ -1,4 +1,4 @@ -class CorrectUsernameSearch < ActiveRecord::Migration +class CorrectUsernameSearch < ActiveRecord::Migration[4.2] def up execute "update user_search_data set search_data = TO_TSVECTOR('simple', username_lower || ' ' || lower(name)) diff --git a/db/migrate/20141120035016_add_allowed_ips_to_api_keys.rb b/db/migrate/20141120035016_add_allowed_ips_to_api_keys.rb index 846c8891957..275e040367b 100644 --- a/db/migrate/20141120035016_add_allowed_ips_to_api_keys.rb +++ b/db/migrate/20141120035016_add_allowed_ips_to_api_keys.rb @@ -1,4 +1,4 @@ -class AddAllowedIpsToApiKeys < ActiveRecord::Migration +class AddAllowedIpsToApiKeys < ActiveRecord::Migration[4.2] def change change_table :api_keys do |t| t.inet :allowed_ips, array: true diff --git a/db/migrate/20141120043401_add_hidden_to_api_keys.rb b/db/migrate/20141120043401_add_hidden_to_api_keys.rb index 565baa05040..c64acf921ff 100644 --- a/db/migrate/20141120043401_add_hidden_to_api_keys.rb +++ b/db/migrate/20141120043401_add_hidden_to_api_keys.rb @@ -1,4 +1,4 @@ -class AddHiddenToApiKeys < ActiveRecord::Migration +class AddHiddenToApiKeys < ActiveRecord::Migration[4.2] def change change_table :api_keys do |t| t.boolean :hidden, null: false, default: false diff --git a/db/migrate/20141211114517_fix_emoji_path.rb b/db/migrate/20141211114517_fix_emoji_path.rb index 03c5cd9bdd4..8b202671f9d 100644 --- a/db/migrate/20141211114517_fix_emoji_path.rb +++ b/db/migrate/20141211114517_fix_emoji_path.rb @@ -1,4 +1,4 @@ -class FixEmojiPath < ActiveRecord::Migration +class FixEmojiPath < ActiveRecord::Migration[4.2] BASE_URL = '/plugins/emoji/images/' def up diff --git a/db/migrate/20141216112341_resolve_duplicate_group_names.rb b/db/migrate/20141216112341_resolve_duplicate_group_names.rb index dc8fa1fdb02..c13b1f7b808 100644 --- a/db/migrate/20141216112341_resolve_duplicate_group_names.rb +++ b/db/migrate/20141216112341_resolve_duplicate_group_names.rb @@ -1,4 +1,4 @@ -class ResolveDuplicateGroupNames < ActiveRecord::Migration +class ResolveDuplicateGroupNames < ActiveRecord::Migration[4.2] def up results = Group.exec_sql 'SELECT id FROM groups diff --git a/db/migrate/20141222051622_remove_override_default_styles_from_site_customizations.rb b/db/migrate/20141222051622_remove_override_default_styles_from_site_customizations.rb index c70f570f863..14c7c099105 100644 --- a/db/migrate/20141222051622_remove_override_default_styles_from_site_customizations.rb +++ b/db/migrate/20141222051622_remove_override_default_styles_from_site_customizations.rb @@ -1,4 +1,4 @@ -class RemoveOverrideDefaultStylesFromSiteCustomizations < ActiveRecord::Migration +class RemoveOverrideDefaultStylesFromSiteCustomizations < ActiveRecord::Migration[4.2] def change remove_column :site_customizations, :override_default_style end diff --git a/db/migrate/20141222224220_fix_emoji_path_take2.rb b/db/migrate/20141222224220_fix_emoji_path_take2.rb index e0b167d065d..b7842f1b53c 100644 --- a/db/migrate/20141222224220_fix_emoji_path_take2.rb +++ b/db/migrate/20141222224220_fix_emoji_path_take2.rb @@ -1,4 +1,4 @@ -class FixEmojiPathTake2 < ActiveRecord::Migration +class FixEmojiPathTake2 < ActiveRecord::Migration[4.2] OLD_URL = '/plugins/emoji/images/' NEW_URL = '/images/emoji/' diff --git a/db/migrate/20141222230707_amend_site_customization.rb b/db/migrate/20141222230707_amend_site_customization.rb index 70b3067f6f1..36006f41117 100644 --- a/db/migrate/20141222230707_amend_site_customization.rb +++ b/db/migrate/20141222230707_amend_site_customization.rb @@ -1,4 +1,4 @@ -class AmendSiteCustomization < ActiveRecord::Migration +class AmendSiteCustomization < ActiveRecord::Migration[4.2] def change remove_column :site_customizations, :position end diff --git a/db/migrate/20141223145058_create_csv_export_logs.rb b/db/migrate/20141223145058_create_csv_export_logs.rb index 870ba4d2125..afb698f49e6 100644 --- a/db/migrate/20141223145058_create_csv_export_logs.rb +++ b/db/migrate/20141223145058_create_csv_export_logs.rb @@ -1,4 +1,4 @@ -class CreateCsvExportLogs < ActiveRecord::Migration +class CreateCsvExportLogs < ActiveRecord::Migration[4.2] def change create_table :csv_export_logs do |t| t.string :export_type, null: false diff --git a/db/migrate/20141228151019_rename_csv_export_logs_to_user_exports.rb b/db/migrate/20141228151019_rename_csv_export_logs_to_user_exports.rb index 12d15bb5e1b..e7364392f13 100644 --- a/db/migrate/20141228151019_rename_csv_export_logs_to_user_exports.rb +++ b/db/migrate/20141228151019_rename_csv_export_logs_to_user_exports.rb @@ -1,4 +1,4 @@ -class RenameCsvExportLogsToUserExports < ActiveRecord::Migration +class RenameCsvExportLogsToUserExports < ActiveRecord::Migration[4.2] def change rename_table :csv_export_logs, :user_exports end diff --git a/db/migrate/20150102113309_clean_up_user_history.rb b/db/migrate/20150102113309_clean_up_user_history.rb index 8ddbe9be05c..7e341e67100 100644 --- a/db/migrate/20150102113309_clean_up_user_history.rb +++ b/db/migrate/20150102113309_clean_up_user_history.rb @@ -1,4 +1,4 @@ -class CleanUpUserHistory < ActiveRecord::Migration +class CleanUpUserHistory < ActiveRecord::Migration[4.2] def up # 'checked_for_custom_avatar' is not used anymore # was removed in https://github.com/discourse/discourse/commit/6c1c8be79433f87bef9d768da7b8fa4ec9bb18d7 diff --git a/db/migrate/20150106215342_remove_stars.rb b/db/migrate/20150106215342_remove_stars.rb index 7e5f6e44d9e..3cdf9ddbd99 100644 --- a/db/migrate/20150106215342_remove_stars.rb +++ b/db/migrate/20150106215342_remove_stars.rb @@ -1,4 +1,4 @@ -class RemoveStars < ActiveRecord::Migration +class RemoveStars < ActiveRecord::Migration[4.2] def up r = execute < 'private_message'" diff --git a/db/migrate/20150306050437_add_all_time_and_op_likes_to_top_topics.rb b/db/migrate/20150306050437_add_all_time_and_op_likes_to_top_topics.rb index 36bc6de65a3..cfd31ba158d 100644 --- a/db/migrate/20150306050437_add_all_time_and_op_likes_to_top_topics.rb +++ b/db/migrate/20150306050437_add_all_time_and_op_likes_to_top_topics.rb @@ -1,4 +1,4 @@ -class AddAllTimeAndOpLikesToTopTopics < ActiveRecord::Migration +class AddAllTimeAndOpLikesToTopTopics < ActiveRecord::Migration[4.2] def change add_column :top_topics, :all_score, :float, default: 0 [:daily, :weekly, :monthly, :yearly].each do |period| diff --git a/db/migrate/20150318143915_create_directory_items.rb b/db/migrate/20150318143915_create_directory_items.rb index b541cedc4dd..9ca67c75063 100644 --- a/db/migrate/20150318143915_create_directory_items.rb +++ b/db/migrate/20150318143915_create_directory_items.rb @@ -1,4 +1,4 @@ -class CreateDirectoryItems < ActiveRecord::Migration +class CreateDirectoryItems < ActiveRecord::Migration[4.2] def change create_table :directory_items, force: true do |t| t.integer :period_type, null: false diff --git a/db/migrate/20150323034933_add_allow_private_messages_to_user_profile.rb b/db/migrate/20150323034933_add_allow_private_messages_to_user_profile.rb index f80bc1b11c7..cbf27cf0386 100644 --- a/db/migrate/20150323034933_add_allow_private_messages_to_user_profile.rb +++ b/db/migrate/20150323034933_add_allow_private_messages_to_user_profile.rb @@ -1,4 +1,4 @@ -class AddAllowPrivateMessagesToUserProfile < ActiveRecord::Migration +class AddAllowPrivateMessagesToUserProfile < ActiveRecord::Migration[4.2] def change add_column :user_profiles, :allow_private_messages, :boolean, default: true, null: false end diff --git a/db/migrate/20150323062322_remove_allow_private_messages_from_user_profile.rb b/db/migrate/20150323062322_remove_allow_private_messages_from_user_profile.rb index ea120aa584f..0a3781a78d5 100644 --- a/db/migrate/20150323062322_remove_allow_private_messages_from_user_profile.rb +++ b/db/migrate/20150323062322_remove_allow_private_messages_from_user_profile.rb @@ -1,4 +1,4 @@ -class RemoveAllowPrivateMessagesFromUserProfile < ActiveRecord::Migration +class RemoveAllowPrivateMessagesFromUserProfile < ActiveRecord::Migration[4.2] def change remove_column :user_profiles, :allow_private_messages end diff --git a/db/migrate/20150323234856_add_muted_users.rb b/db/migrate/20150323234856_add_muted_users.rb index acdb020c7f1..9b4edb5d379 100644 --- a/db/migrate/20150323234856_add_muted_users.rb +++ b/db/migrate/20150323234856_add_muted_users.rb @@ -1,4 +1,4 @@ -class AddMutedUsers < ActiveRecord::Migration +class AddMutedUsers < ActiveRecord::Migration[4.2] def change create_table :muted_users, force: true do |t| t.integer :user_id, null: false diff --git a/db/migrate/20150324184222_add_more_to_directory_items.rb b/db/migrate/20150324184222_add_more_to_directory_items.rb index efc7e9477fd..28eac2dced5 100644 --- a/db/migrate/20150324184222_add_more_to_directory_items.rb +++ b/db/migrate/20150324184222_add_more_to_directory_items.rb @@ -1,4 +1,4 @@ -class AddMoreToDirectoryItems < ActiveRecord::Migration +class AddMoreToDirectoryItems < ActiveRecord::Migration[4.2] def change add_column :directory_items, :days_visited, :integer, null: false, default: 0 add_column :directory_items, :posts_read, :integer, null: false, default: 0 diff --git a/db/migrate/20150325183400_fix_group_user_count.rb b/db/migrate/20150325183400_fix_group_user_count.rb index 96988a6287e..4cffb5eea57 100644 --- a/db/migrate/20150325183400_fix_group_user_count.rb +++ b/db/migrate/20150325183400_fix_group_user_count.rb @@ -1,4 +1,4 @@ -class FixGroupUserCount < ActiveRecord::Migration +class FixGroupUserCount < ActiveRecord::Migration[4.2] def change execute "UPDATE groups g SET user_count = (SELECT COUNT(user_id) FROM group_users gu WHERE gu.group_id = g.id)" end diff --git a/db/migrate/20150325190959_create_queued_posts.rb b/db/migrate/20150325190959_create_queued_posts.rb index c511e8fcd22..b2bf9e1eef4 100644 --- a/db/migrate/20150325190959_create_queued_posts.rb +++ b/db/migrate/20150325190959_create_queued_posts.rb @@ -1,4 +1,4 @@ -class CreateQueuedPosts < ActiveRecord::Migration +class CreateQueuedPosts < ActiveRecord::Migration[4.2] def change create_table :queued_posts, force: true do |t| t.string :queue, null: false diff --git a/db/migrate/20150410002033_add_primary_group_to_groups.rb b/db/migrate/20150410002033_add_primary_group_to_groups.rb index 23e4e87138e..ddd303e182c 100644 --- a/db/migrate/20150410002033_add_primary_group_to_groups.rb +++ b/db/migrate/20150410002033_add_primary_group_to_groups.rb @@ -1,4 +1,4 @@ -class AddPrimaryGroupToGroups < ActiveRecord::Migration +class AddPrimaryGroupToGroups < ActiveRecord::Migration[4.2] def change add_column :groups, :primary_group, :boolean, default: false, null: false end diff --git a/db/migrate/20150410002551_add_title_to_groups.rb b/db/migrate/20150410002551_add_title_to_groups.rb index eb90e98efa5..ccc234e6656 100644 --- a/db/migrate/20150410002551_add_title_to_groups.rb +++ b/db/migrate/20150410002551_add_title_to_groups.rb @@ -1,4 +1,4 @@ -class AddTitleToGroups < ActiveRecord::Migration +class AddTitleToGroups < ActiveRecord::Migration[4.2] def change add_column :groups, :title, :string end diff --git a/db/migrate/20150421085850_increase_url_length_on_topic_embed.rb b/db/migrate/20150421085850_increase_url_length_on_topic_embed.rb index 3f0ea315be2..6166070be10 100644 --- a/db/migrate/20150421085850_increase_url_length_on_topic_embed.rb +++ b/db/migrate/20150421085850_increase_url_length_on_topic_embed.rb @@ -1,4 +1,4 @@ -class IncreaseUrlLengthOnTopicEmbed < ActiveRecord::Migration +class IncreaseUrlLengthOnTopicEmbed < ActiveRecord::Migration[4.2] def up remove_index :topic_embeds, :embed_url change_column :topic_embeds, :embed_url, :string, limit: 1000, null: false diff --git a/db/migrate/20150421190714_add_queued_post_id_to_user_actions.rb b/db/migrate/20150421190714_add_queued_post_id_to_user_actions.rb index d6987afc253..f658d1f0ea6 100644 --- a/db/migrate/20150421190714_add_queued_post_id_to_user_actions.rb +++ b/db/migrate/20150421190714_add_queued_post_id_to_user_actions.rb @@ -1,4 +1,4 @@ -class AddQueuedPostIdToUserActions < ActiveRecord::Migration +class AddQueuedPostIdToUserActions < ActiveRecord::Migration[4.2] def change add_column :user_actions, :queued_post_id, :integer, null: true end diff --git a/db/migrate/20150422160235_add_link_post_id_index_on_topic_links.rb b/db/migrate/20150422160235_add_link_post_id_index_on_topic_links.rb index 0ccb6562798..24442c3625e 100644 --- a/db/migrate/20150422160235_add_link_post_id_index_on_topic_links.rb +++ b/db/migrate/20150422160235_add_link_post_id_index_on_topic_links.rb @@ -1,4 +1,4 @@ -class AddLinkPostIdIndexOnTopicLinks < ActiveRecord::Migration +class AddLinkPostIdIndexOnTopicLinks < ActiveRecord::Migration[4.2] def change add_index :topic_links, [:link_post_id, :reflection] end diff --git a/db/migrate/20150505044154_add_stylesheet_cache.rb b/db/migrate/20150505044154_add_stylesheet_cache.rb index d2034743f41..98634c543ff 100644 --- a/db/migrate/20150505044154_add_stylesheet_cache.rb +++ b/db/migrate/20150505044154_add_stylesheet_cache.rb @@ -1,4 +1,4 @@ -class AddStylesheetCache < ActiveRecord::Migration +class AddStylesheetCache < ActiveRecord::Migration[4.2] def change create_table :stylesheet_cache do |t| t.string :target, null: false diff --git a/db/migrate/20150513094042_add_index_on_post_actions.rb b/db/migrate/20150513094042_add_index_on_post_actions.rb index e79c0ce9bed..54502aa7fc7 100644 --- a/db/migrate/20150513094042_add_index_on_post_actions.rb +++ b/db/migrate/20150513094042_add_index_on_post_actions.rb @@ -1,4 +1,4 @@ -class AddIndexOnPostActions < ActiveRecord::Migration +class AddIndexOnPostActions < ActiveRecord::Migration[4.2] def change add_index :post_actions, [:user_id, :post_action_type_id], where: 'deleted_at IS NULL' end diff --git a/db/migrate/20150514023016_add_unread_notifications_index.rb b/db/migrate/20150514023016_add_unread_notifications_index.rb index e4a7694c189..fabd25fca63 100644 --- a/db/migrate/20150514023016_add_unread_notifications_index.rb +++ b/db/migrate/20150514023016_add_unread_notifications_index.rb @@ -1,4 +1,4 @@ -class AddUnreadNotificationsIndex < ActiveRecord::Migration +class AddUnreadNotificationsIndex < ActiveRecord::Migration[4.2] def change add_index :notifications, [:user_id, :notification_type], where: 'not read', name: 'idx_notifications_speedup_unread_count' end diff --git a/db/migrate/20150514043155_add_user_actions_all_index.rb b/db/migrate/20150514043155_add_user_actions_all_index.rb index 5d2a9d54c0f..74feeccb32d 100644 --- a/db/migrate/20150514043155_add_user_actions_all_index.rb +++ b/db/migrate/20150514043155_add_user_actions_all_index.rb @@ -1,4 +1,4 @@ -class AddUserActionsAllIndex < ActiveRecord::Migration +class AddUserActionsAllIndex < ActiveRecord::Migration[4.2] def change add_index :user_actions, [:user_id, :created_at, :action_type], name: 'idx_user_actions_speed_up_user_all' end diff --git a/db/migrate/20150525151759_set_default_s3_region.rb b/db/migrate/20150525151759_set_default_s3_region.rb index de3d0b7b2c5..58ecb95fcfc 100644 --- a/db/migrate/20150525151759_set_default_s3_region.rb +++ b/db/migrate/20150525151759_set_default_s3_region.rb @@ -1,4 +1,4 @@ -class SetDefaultS3Region < ActiveRecord::Migration +class SetDefaultS3Region < ActiveRecord::Migration[4.2] def up execute <<-SQL UPDATE site_settings diff --git a/db/migrate/20150609163211_migrate_embeddable_host.rb b/db/migrate/20150609163211_migrate_embeddable_host.rb index d3d351a32ba..de40f7290cf 100644 --- a/db/migrate/20150609163211_migrate_embeddable_host.rb +++ b/db/migrate/20150609163211_migrate_embeddable_host.rb @@ -1,4 +1,4 @@ -class MigrateEmbeddableHost < ActiveRecord::Migration +class MigrateEmbeddableHost < ActiveRecord::Migration[4.2] def change execute "UPDATE site_settings SET name = 'embeddable_hosts', data_type = 9 WHERE name = 'embeddable_host'" end diff --git a/db/migrate/20150617080349_add_index_on_post_notifications.rb b/db/migrate/20150617080349_add_index_on_post_notifications.rb index a8cbccfdc8f..a2f65f6a36a 100644 --- a/db/migrate/20150617080349_add_index_on_post_notifications.rb +++ b/db/migrate/20150617080349_add_index_on_post_notifications.rb @@ -1,4 +1,4 @@ -class AddIndexOnPostNotifications < ActiveRecord::Migration +class AddIndexOnPostNotifications < ActiveRecord::Migration[4.2] def change add_index :notifications, [:user_id, :topic_id, :post_number] end diff --git a/db/migrate/20150617233018_add_index_target_post_id_on_user_actions.rb b/db/migrate/20150617233018_add_index_target_post_id_on_user_actions.rb index 973bda76f04..ec4b5ea0162 100644 --- a/db/migrate/20150617233018_add_index_target_post_id_on_user_actions.rb +++ b/db/migrate/20150617233018_add_index_target_post_id_on_user_actions.rb @@ -1,4 +1,4 @@ -class AddIndexTargetPostIdOnUserActions < ActiveRecord::Migration +class AddIndexTargetPostIdOnUserActions < ActiveRecord::Migration[4.2] def change add_index :user_actions, [:target_post_id] end diff --git a/db/migrate/20150617234511_add_staff_index_to_users.rb b/db/migrate/20150617234511_add_staff_index_to_users.rb index f060b9b1693..5b4ddf85689 100644 --- a/db/migrate/20150617234511_add_staff_index_to_users.rb +++ b/db/migrate/20150617234511_add_staff_index_to_users.rb @@ -1,4 +1,4 @@ -class AddStaffIndexToUsers < ActiveRecord::Migration +class AddStaffIndexToUsers < ActiveRecord::Migration[4.2] def change add_index :users, [:id], name: 'idx_users_admin', where: 'admin' add_index :users, [:id], name: 'idx_users_moderator', where: 'moderator' diff --git a/db/migrate/20150702201926_add_topic_template_to_categories.rb b/db/migrate/20150702201926_add_topic_template_to_categories.rb index 719851cdbc2..b1e66e53409 100644 --- a/db/migrate/20150702201926_add_topic_template_to_categories.rb +++ b/db/migrate/20150702201926_add_topic_template_to_categories.rb @@ -1,4 +1,4 @@ -class AddTopicTemplateToCategories < ActiveRecord::Migration +class AddTopicTemplateToCategories < ActiveRecord::Migration[4.2] def change add_column :categories, :topic_template, :text, null: true end diff --git a/db/migrate/20150706215111_add_mobile_to_user_visits.rb b/db/migrate/20150706215111_add_mobile_to_user_visits.rb index f794e1a8ffe..1e371b9413e 100644 --- a/db/migrate/20150706215111_add_mobile_to_user_visits.rb +++ b/db/migrate/20150706215111_add_mobile_to_user_visits.rb @@ -1,4 +1,4 @@ -class AddMobileToUserVisits < ActiveRecord::Migration +class AddMobileToUserVisits < ActiveRecord::Migration[4.2] def change add_column :user_visits, :mobile, :boolean, default: false end diff --git a/db/migrate/20150707163251_add_reports_index_to_user_visits.rb b/db/migrate/20150707163251_add_reports_index_to_user_visits.rb index 299bcb250e5..c0d56dfe19a 100644 --- a/db/migrate/20150707163251_add_reports_index_to_user_visits.rb +++ b/db/migrate/20150707163251_add_reports_index_to_user_visits.rb @@ -1,4 +1,4 @@ -class AddReportsIndexToUserVisits < ActiveRecord::Migration +class AddReportsIndexToUserVisits < ActiveRecord::Migration[4.2] def up add_index :user_visits, [:visited_at, :mobile] end diff --git a/db/migrate/20150709021818_add_like_count_to_post_menu.rb b/db/migrate/20150709021818_add_like_count_to_post_menu.rb index a12a166f417..901a7c35a00 100644 --- a/db/migrate/20150709021818_add_like_count_to_post_menu.rb +++ b/db/migrate/20150709021818_add_like_count_to_post_menu.rb @@ -1,4 +1,4 @@ -class AddLikeCountToPostMenu < ActiveRecord::Migration +class AddLikeCountToPostMenu < ActiveRecord::Migration[4.2] def up execute < 5 were off by one diff --git a/db/migrate/20160110053003_archive_system_messages_with_no_replies.rb b/db/migrate/20160110053003_archive_system_messages_with_no_replies.rb index da9b1d71c31..e639a2b2764 100644 --- a/db/migrate/20160110053003_archive_system_messages_with_no_replies.rb +++ b/db/migrate/20160110053003_archive_system_messages_with_no_replies.rb @@ -1,4 +1,4 @@ -class ArchiveSystemMessagesWithNoReplies < ActiveRecord::Migration +class ArchiveSystemMessagesWithNoReplies < ActiveRecord::Migration[4.2] def up # backdate archival of system messages send on behalf of site_contact_user execute < 0 PostUpload.exec_sql("INSERT INTO post_uploads (post_id, upload_id) VALUES #{values}") end diff --git a/lib/freedom_patches/fast_pluck.rb b/lib/freedom_patches/fast_pluck.rb index 9eacba972ff..6034cf7a521 100644 --- a/lib/freedom_patches/fast_pluck.rb +++ b/lib/freedom_patches/fast_pluck.rb @@ -64,7 +64,7 @@ class ActiveRecord::Relation columns_hash.key?(cn) ? arel_table[cn] : cn } - conn.select_raw(relation, nil, relation.arel.bind_values + bind_values) do |result, _| + conn.select_raw(relation, nil, relation.bound_attributes) do |result, _| result.type_map = SqlBuilder.pg_type_map result.nfields == 1 ? result.column_values(0) : result.values end diff --git a/lib/freedom_patches/pool_drainer.rb b/lib/freedom_patches/pool_drainer.rb index bf1eb1e89c0..0e0350d6353 100644 --- a/lib/freedom_patches/pool_drainer.rb +++ b/lib/freedom_patches/pool_drainer.rb @@ -11,7 +11,7 @@ if Rails.version >= "4.2.0" end def lease - synchronize do + @lock.synchronize do unless in_use? @last_use = Time.now super diff --git a/lib/new_post_manager.rb b/lib/new_post_manager.rb index 8777f1b8ff7..34919c01cb8 100644 --- a/lib/new_post_manager.rb +++ b/lib/new_post_manager.rb @@ -92,7 +92,7 @@ class NewPostManager validator.validate(post) if post.errors[:raw].present? result = NewPostResult.new(:created_post, false) - result.errors[:base] = post.errors[:raw] + result.errors[:base] << post.errors[:raw] return result end diff --git a/lib/plugin/instance.rb b/lib/plugin/instance.rb index beb285b49c7..3eb44c76bd1 100644 --- a/lib/plugin/instance.rb +++ b/lib/plugin/instance.rb @@ -501,8 +501,8 @@ JS end def reloadable_patch(plugin = self) - if Rails.env.development? && defined?(ActionDispatch::Reloader) - ActionDispatch::Reloader.to_prepare do + if Rails.env.development? && defined?(ActiveSupport::Reloader) + ActiveSupport::Reloader.to_prepare do # reload the patch yield plugin end diff --git a/lib/post_destroyer.rb b/lib/post_destroyer.rb index 3f7cdbffab1..61595ab8f6e 100644 --- a/lib/post_destroyer.rb +++ b/lib/post_destroyer.rb @@ -202,13 +202,15 @@ class PostDestroyer post_ids = PostReply.where(reply_id: @post.id).pluck(:post_id) if post_ids.present? - PostReply.delete_all reply_id: @post.id + PostReply.where(reply_id: @post.id).delete_all Post.where(id: post_ids).each { |p| p.update_column :reply_count, p.replies.count } end end def remove_associated_notifications - Notification.delete_all topic_id: @post.topic_id, post_number: @post.post_number + Notification + .where(topic_id: @post.topic_id, post_number: @post.post_number) + .delete_all end def update_associated_category_latest_topic diff --git a/lib/search.rb b/lib/search.rb index 4baf419fd3b..91a8d45e431 100644 --- a/lib/search.rb +++ b/lib/search.rb @@ -318,7 +318,7 @@ class Search .joins("INNER JOIN post_timings ON post_timings.topic_id = posts.topic_id AND post_timings.post_number = posts.post_number - AND post_timings.user_id = #{Post.sanitize(@guardian.user.id)} + AND post_timings.user_id = #{ActiveRecord::Base.connection.quote(@guardian.user.id)} ") end end @@ -329,7 +329,7 @@ class Search .joins("LEFT JOIN post_timings ON post_timings.topic_id = posts.topic_id AND post_timings.post_number = posts.post_number - AND post_timings.user_id = #{Post.sanitize(@guardian.user.id)} + AND post_timings.user_id = #{ActiveRecord::Base.connection.quote(@guardian.user.id)} ") .where("post_timings.user_id IS NULL") end @@ -776,13 +776,18 @@ class Search config: 'simple', term: term).values[0][0] - ts_config = Post.sanitize(ts_config) if ts_config + ts_config = ActiveRecord::Base.connection.quote(ts_config) if ts_config all_terms = data.scan(/'([^']+)'\:\d+/).flatten all_terms.map! do |t| t.split(/[\)\(&']/)[0] end.compact! - query = Post.sanitize(all_terms.map { |t| "'#{PG::Connection.escape_string(t)}':*" }.join(" #{joiner} ")) + query = ActiveRecord::Base.connection.quote( + all_terms + .map { |t| "'#{PG::Connection.escape_string(t)}':*" } + .join(" #{joiner} ") + ) + "TO_TSQUERY(#{ts_config || default_ts_config}, #{query})" end diff --git a/lib/sql_builder.rb b/lib/sql_builder.rb index 35598c57232..3498cbe6175 100644 --- a/lib/sql_builder.rb +++ b/lib/sql_builder.rb @@ -77,7 +77,7 @@ class SqlBuilder def decode(string, tuple = nil, field = nil) if Rails.version >= "4.2.0" @caster ||= ActiveRecord::Type::DateTime.new - @caster.type_cast_from_database(string) + @caster.cast(string) else ActiveRecord::ConnectionAdapters::Column.string_to_time string end diff --git a/lib/tasks/db.rake b/lib/tasks/db.rake index a765c3899f7..e6d5040a2a6 100644 --- a/lib/tasks/db.rake +++ b/lib/tasks/db.rake @@ -3,27 +3,33 @@ task 'set_locale' do I18n.locale = (SiteSetting.default_locale || :en) rescue :en end +task 'db:environment:set', [:multisite] => [:load_config] do |_, args| + if Rails.env.test? && !args[:multisite] + system("MULTISITE=multisite rails db:environment:set['true'] RAILS_ENV=test") + end +end + task 'db:create', [:multisite] => [:load_config] do |_, args| if Rails.env.test? && !args[:multisite] - system("MULTISITE=multisite rake db:create['true']") + system("MULTISITE=multisite rails db:create['true']") end end task 'db:drop', [:multisite] => [:load_config] do |_, args| if Rails.env.test? && !args[:multisite] - system("MULTISITE=multisite rake db:drop['true']") + system("MULTISITE=multisite rails db:drop['true']") end end -# we need to run seed_fu every time we run rake db:migrate +# we need to run seed_fu every time we run rails db:migrate task 'db:migrate', [:multisite] => ['environment', 'set_locale'] do |_, args| SeedFu.seed Jobs::Onceoff.enqueue_all if Rails.env.test? && !args[:multisite] - system("rake db:schema:dump") - system("MULTISITE=multisite rake db:schema:load") - system("RAILS_DB=discourse_test_multisite rake db:migrate['multisite']") + system("rails db:schema:dump") + system("MULTISITE=multisite rails db:schema:load") + system("RAILS_DB=discourse_test_multisite rails db:migrate['multisite']") end end diff --git a/lib/topic_creator.rb b/lib/topic_creator.rb index 19b656d5fb9..5347f464b6b 100644 --- a/lib/topic_creator.rb +++ b/lib/topic_creator.rb @@ -72,12 +72,12 @@ class TopicCreator topic.notifier.watch_topic!(topic.user_id) end - topic.topic_allowed_users(true).each do |tau| + topic.reload.topic_allowed_users.each do |tau| next if tau.user_id == -1 || tau.user_id == topic.user_id topic.notifier.watch!(tau.user_id) end - topic.topic_allowed_groups(true).each do |tag| + topic.reload.topic_allowed_groups.each do |tag| tag.group.group_users.each do |gu| next if gu.user_id == -1 || gu.user_id == topic.user_id diff --git a/lib/topic_query.rb b/lib/topic_query.rb index 2e4066fc5c9..14aaaa8bbc7 100644 --- a/lib/topic_query.rb +++ b/lib/topic_query.rb @@ -266,9 +266,7 @@ class TopicQuery def list_category_topic_ids(category) query = default_results(category: category.id) - pinned_ids = query.where('pinned_at IS NOT NULL AND category_id = ?', category.id) - .limit(nil) - .order('pinned_at DESC').pluck(:id) + pinned_ids = query.where('pinned_at IS NOT NULL AND category_id = ?', category.id).limit(nil).order('pinned_at DESC').pluck(:id) non_pinned_ids = query.where('pinned_at IS NULL OR category_id <> ?', category.id).pluck(:id) (pinned_ids + non_pinned_ids) end @@ -311,7 +309,7 @@ class TopicQuery if page == 0 (pinned_topics + unpinned_topics)[0...limit] if limit else - offset = (page * per_page) - pinned_topics.count + offset = (page * per_page) - pinned_topics.length offset = 0 unless offset > 0 unpinned_topics.offset(offset).to_a end @@ -559,7 +557,7 @@ class TopicQuery end elsif @options[:no_tags] # the following will do: ("topics"."id" NOT IN (SELECT DISTINCT "topic_tags"."topic_id" FROM "topic_tags")) - result = result.where.not(id: TopicTag.select(:topic_id).uniq) + result = result.where.not(id: TopicTag.distinct.pluck(:topic_id)) end end @@ -576,7 +574,6 @@ class TopicQuery end result = result.limit(options[:per_page]) unless options[:limit] == false - result = result.visible if options[:visible] result = result.where.not(topics: { id: options[:except_topic_ids] }).references(:topics) if options[:except_topic_ids] diff --git a/plugins/discourse-narrative-bot/plugin.rb b/plugins/discourse-narrative-bot/plugin.rb index 79aba1b6ede..27b67194872 100644 --- a/plugins/discourse-narrative-bot/plugin.rb +++ b/plugins/discourse-narrative-bot/plugin.rb @@ -75,7 +75,7 @@ after_initialize do class CertificatesController < ::ApplicationController layout :false - skip_before_filter :check_xhr + skip_before_action :check_xhr def generate raise Discourse::InvalidParameters.new('user_id must be present') unless params[:user_id]&.present? diff --git a/plugins/discourse-narrative-bot/spec/integration/discobot_certificate_spec.rb b/plugins/discourse-narrative-bot/spec/integration/discobot_certificate_spec.rb index 394be887e68..cf81fce7034 100644 --- a/plugins/discourse-narrative-bot/spec/integration/discobot_certificate_spec.rb +++ b/plugins/discourse-narrative-bot/spec/integration/discobot_certificate_spec.rb @@ -15,7 +15,7 @@ describe "Discobot Certificate" do stub_request(:get, "http://test.localhost//images/d-logo-sketch-small.png") .to_return(status: 200) - xhr :get, '/discobot/certificate.svg', params + get '/discobot/certificate.svg', params: params expect(response.status).to eq(200) end @@ -28,7 +28,7 @@ describe "Discobot Certificate" do } params.each do |key, _| - expect { xhr :get, '/discobot/certificate.svg', params.except(key) } + expect { get '/discobot/certificate.svg', params: params.except(key) } .to raise_error(Discourse::InvalidParameters) end end @@ -37,11 +37,12 @@ describe "Discobot Certificate" do describe 'when date is invalid' do it 'should raise the right error' do expect do - xhr :get, '/discobot/certificate.svg', + get '/discobot/certificate.svg', params: { name: user.name, date: "", avatar_url: 'https://somesite.com/someavatar', user_id: user.id + } end.to raise_error(ArgumentError, 'invalid date') end end diff --git a/plugins/discourse-narrative-bot/spec/integration/discobot_welcome_post_spec.rb b/plugins/discourse-narrative-bot/spec/integration/discobot_welcome_post_spec.rb index ae21103119a..9ada964d7ab 100644 --- a/plugins/discourse-narrative-bot/spec/integration/discobot_welcome_post_spec.rb +++ b/plugins/discourse-narrative-bot/spec/integration/discobot_welcome_post_spec.rb @@ -8,10 +8,6 @@ describe "Discobot welcome post" do SiteSetting.discourse_narrative_bot_enabled = true end - after do - Jobs::NarrativeInit.jobs.clear - end - context 'when discourse_narrative_bot_welcome_post_delay is 0' do it 'should not delay the welcome post' do user @@ -38,10 +34,11 @@ describe "Discobot welcome post" do invite expect do - xhr :put, "/invites/show/#{invite.invite_key}", + put "/invites/show/#{invite.invite_key}.json", params: { username: 'somename', name: 'testing', password: 'asodaasdaosdhq' + } end.to change { User.count }.by(1) expect(Jobs::NarrativeInit.jobs.first["args"].first["user_id"]).to eq(User.last.id) diff --git a/plugins/discourse-presence/plugin.rb b/plugins/discourse-presence/plugin.rb index 7c59e0e343e..7d7a57ac8f7 100644 --- a/plugins/discourse-presence/plugin.rb +++ b/plugins/discourse-presence/plugin.rb @@ -97,7 +97,7 @@ after_initialize do class Presence::PresencesController < ::ApplicationController requires_plugin PLUGIN_NAME - before_filter :ensure_logged_in + before_action :ensure_logged_in def publish data = params.permit(:response_needed, diff --git a/plugins/discourse-presence/spec/presence_controller_spec.rb b/plugins/discourse-presence/spec/presence_controller_spec.rb index e61531beedc..28d62753b30 100644 --- a/plugins/discourse-presence/spec/presence_controller_spec.rb +++ b/plugins/discourse-presence/spec/presence_controller_spec.rb @@ -38,7 +38,11 @@ describe ::Presence::PresencesController, type: :request do it "uses guardian to secure endpoint" do # Private message private_post = Fabricate(:private_message_post) - post '/presence/publish.json', current: { action: 'edit', post_id: private_post.id } + + post '/presence/publish.json', params: { + current: { action: 'edit', post_id: private_post.id } + } + expect(response.code.to_i).to eq(403) # Secure category @@ -46,13 +50,18 @@ describe ::Presence::PresencesController, type: :request do category = Fabricate(:private_category, group: group) private_topic = Fabricate(:topic, category: category) - post '/presence/publish.json', current: { action: 'edit', topic_id: private_topic.id } + post '/presence/publish.json', params: { + current: { action: 'edit', topic_id: private_topic.id } + } + expect(response.code.to_i).to eq(403) end it "returns a response when requested" do messages = MessageBus.track_publish do - post '/presence/publish.json', current: { compose_state: 'open', action: 'edit', post_id: post1.id }, response_needed: true + post '/presence/publish.json', params: { + current: { compose_state: 'open', action: 'edit', post_id: post1.id }, response_needed: true + } end expect(messages.count).to eq (1) @@ -66,7 +75,9 @@ describe ::Presence::PresencesController, type: :request do it "doesn't return a response when not requested" do messages = MessageBus.track_publish do - post '/presence/publish.json', current: { compose_state: 'open', action: 'edit', post_id: post1.id } + post '/presence/publish.json', params: { + current: { compose_state: 'open', action: 'edit', post_id: post1.id } + } end expect(messages.count).to eq (1) @@ -77,21 +88,34 @@ describe ::Presence::PresencesController, type: :request do it "doesn't send duplicate messagebus messages" do messages = MessageBus.track_publish do - post '/presence/publish.json', current: { compose_state: 'open', action: 'edit', post_id: post1.id } + post '/presence/publish.json', params: { + current: { compose_state: 'open', action: 'edit', post_id: post1.id } + } end + expect(messages.count).to eq (1) messages = MessageBus.track_publish do - post '/presence/publish.json', current: { compose_state: 'open', action: 'edit', post_id: post1.id } + post '/presence/publish.json', params: { + current: { compose_state: 'open', action: 'edit', post_id: post1.id } + } end + expect(messages.count).to eq (0) end it "clears 'previous' state when supplied" do messages = MessageBus.track_publish do - post '/presence/publish.json', current: { compose_state: 'open', action: 'edit', post_id: post1.id } - post '/presence/publish.json', current: { compose_state: 'open', action: 'edit', post_id: post2.id }, previous: { compose_state: 'open', action: 'edit', post_id: post1.id } + post '/presence/publish.json', params: { + current: { compose_state: 'open', action: 'edit', post_id: post1.id } + } + + post '/presence/publish.json', params: { + current: { compose_state: 'open', action: 'edit', post_id: post2.id }, + previous: { compose_state: 'open', action: 'edit', post_id: post1.id } + } end + expect(messages.count).to eq (3) end diff --git a/plugins/poll/db/migrate/20150501152228_rename_total_votes_to_voters.rb b/plugins/poll/db/migrate/20150501152228_rename_total_votes_to_voters.rb index 902c84dedcb..f548ebdf891 100644 --- a/plugins/poll/db/migrate/20150501152228_rename_total_votes_to_voters.rb +++ b/plugins/poll/db/migrate/20150501152228_rename_total_votes_to_voters.rb @@ -1,4 +1,4 @@ -class RenameTotalVotesToVoters < ActiveRecord::Migration +class RenameTotalVotesToVoters < ActiveRecord::Migration[4.2] def up PostCustomField.where(name: "polls").find_each do |pcf| diff --git a/plugins/poll/db/migrate/20151016163051_merge_polls_votes.rb b/plugins/poll/db/migrate/20151016163051_merge_polls_votes.rb index 33bd122bdf9..dfa47c51d9e 100644 --- a/plugins/poll/db/migrate/20151016163051_merge_polls_votes.rb +++ b/plugins/poll/db/migrate/20151016163051_merge_polls_votes.rb @@ -1,4 +1,4 @@ -class MergePollsVotes < ActiveRecord::Migration +class MergePollsVotes < ActiveRecord::Migration[4.2] def up PostCustomField.where(name: "polls").order(:post_id).pluck(:post_id).each do |post_id| diff --git a/plugins/poll/db/migrate/20160321164925_close_polls_in_closed_topics.rb b/plugins/poll/db/migrate/20160321164925_close_polls_in_closed_topics.rb index 978a41c890c..6ef50e82fcd 100644 --- a/plugins/poll/db/migrate/20160321164925_close_polls_in_closed_topics.rb +++ b/plugins/poll/db/migrate/20160321164925_close_polls_in_closed_topics.rb @@ -1,4 +1,4 @@ -class ClosePollsInClosedTopics < ActiveRecord::Migration +class ClosePollsInClosedTopics < ActiveRecord::Migration[4.2] def up PostCustomField.joins(post: :topic) diff --git a/plugins/poll/plugin.rb b/plugins/poll/plugin.rb index cd426235365..84eb24adf63 100644 --- a/plugins/poll/plugin.rb +++ b/plugins/poll/plugin.rb @@ -181,7 +181,7 @@ after_initialize do class DiscoursePoll::PollsController < ::ApplicationController requires_plugin PLUGIN_NAME - before_filter :ensure_logged_in, except: [:voters] + before_action :ensure_logged_in, except: [:voters] def vote post_id = params.require(:post_id) diff --git a/plugins/poll/spec/controllers/polls_controller_spec.rb b/plugins/poll/spec/controllers/polls_controller_spec.rb index d2d671b0e28..c9f353862e9 100644 --- a/plugins/poll/spec/controllers/polls_controller_spec.rb +++ b/plugins/poll/spec/controllers/polls_controller_spec.rb @@ -14,7 +14,9 @@ describe ::DiscoursePoll::PollsController do it "works" do MessageBus.expects(:publish) - xhr :put, :vote, post_id: poll.id, poll_name: "poll", options: ["5c24fc1df56d764b550ceae1b9319125"] + put :vote, params: { + post_id: poll.id, poll_name: "poll", options: ["5c24fc1df56d764b550ceae1b9319125"] + }, format: :json expect(response).to be_success json = ::JSON.parse(response.body) @@ -24,7 +26,9 @@ describe ::DiscoursePoll::PollsController do end it "requires at least 1 valid option" do - xhr :put, :vote, post_id: poll.id, poll_name: "poll", options: ["A", "B"] + put :vote, params: { + post_id: poll.id, poll_name: "poll", options: ["A", "B"] + }, format: :json expect(response).not_to be_success json = ::JSON.parse(response.body) @@ -32,10 +36,16 @@ describe ::DiscoursePoll::PollsController do end it "supports vote changes" do - xhr :put, :vote, post_id: poll.id, poll_name: "poll", options: ["5c24fc1df56d764b550ceae1b9319125"] + put :vote, params: { + post_id: poll.id, poll_name: "poll", options: ["5c24fc1df56d764b550ceae1b9319125"] + }, format: :json + expect(response).to be_success - xhr :put, :vote, post_id: poll.id, poll_name: "poll", options: ["e89dec30bbd9bf50fabf6a05b4324edf"] + put :vote, params: { + post_id: poll.id, poll_name: "poll", options: ["e89dec30bbd9bf50fabf6a05b4324edf"] + }, format: :json + expect(response).to be_success json = ::JSON.parse(response.body) expect(json["poll"]["voters"]).to eq(1) @@ -45,13 +55,19 @@ describe ::DiscoursePoll::PollsController do it "works even if topic is closed" do topic.update_attribute(:closed, true) - xhr :put, :vote, post_id: poll.id, poll_name: "poll", options: ["5c24fc1df56d764b550ceae1b9319125"] + put :vote, params: { + post_id: poll.id, poll_name: "poll", options: ["5c24fc1df56d764b550ceae1b9319125"] + }, format: :json + expect(response).to be_success end it "ensures topic is not archived" do topic.update_attribute(:archived, true) - xhr :put, :vote, post_id: poll.id, poll_name: "poll", options: ["A"] + put :vote, params: { + post_id: poll.id, poll_name: "poll", options: ["A"] + }, format: :json + expect(response).not_to be_success json = ::JSON.parse(response.body) expect(json["errors"][0]).to eq(I18n.t("poll.topic_must_be_open_to_vote")) @@ -59,21 +75,30 @@ describe ::DiscoursePoll::PollsController do it "ensures post is not trashed" do poll.trash! - xhr :put, :vote, post_id: poll.id, poll_name: "poll", options: ["A"] + put :vote, params: { + post_id: poll.id, poll_name: "poll", options: ["A"] + }, format: :json + expect(response).not_to be_success json = ::JSON.parse(response.body) expect(json["errors"][0]).to eq(I18n.t("poll.post_is_deleted")) end it "ensures polls are associated with the post" do - xhr :put, :vote, post_id: Fabricate(:post).id, poll_name: "foobar", options: ["A"] + put :vote, params: { + post_id: Fabricate(:post).id, poll_name: "foobar", options: ["A"] + }, format: :json + expect(response).not_to be_success json = ::JSON.parse(response.body) expect(json["errors"][0]).to eq(I18n.t("poll.no_polls_associated_with_this_post")) end it "checks the name of the poll" do - xhr :put, :vote, post_id: poll.id, poll_name: "foobar", options: ["A"] + put :vote, params: { + post_id: poll.id, poll_name: "foobar", options: ["A"] + }, format: :json + expect(response).not_to be_success json = ::JSON.parse(response.body) expect(json["errors"][0]).to eq(I18n.t("poll.no_poll_with_this_name", name: "foobar")) @@ -81,7 +106,11 @@ describe ::DiscoursePoll::PollsController do it "ensures poll is open" do closed_poll = create_post(raw: "[poll status=closed]\n- A\n- B\n[/poll]") - xhr :put, :vote, post_id: closed_poll.id, poll_name: "poll", options: ["5c24fc1df56d764b550ceae1b9319125"] + + put :vote, params: { + post_id: closed_poll.id, poll_name: "poll", options: ["5c24fc1df56d764b550ceae1b9319125"] + }, format: :json + expect(response).not_to be_success json = ::JSON.parse(response.body) expect(json["errors"][0]).to eq(I18n.t("poll.poll_must_be_open_to_vote")) @@ -91,7 +120,10 @@ describe ::DiscoursePoll::PollsController do default_poll = poll.custom_fields["polls"]["poll"] add_anonymous_votes(poll, default_poll, 17, "5c24fc1df56d764b550ceae1b9319125" => 11, "e89dec30bbd9bf50fabf6a05b4324edf" => 6) - xhr :put, :vote, post_id: poll.id, poll_name: "poll", options: ["5c24fc1df56d764b550ceae1b9319125"] + put :vote, params: { + post_id: poll.id, poll_name: "poll", options: ["5c24fc1df56d764b550ceae1b9319125"] + }, format: :json + expect(response).to be_success json = ::JSON.parse(response.body) @@ -105,7 +137,9 @@ describe ::DiscoursePoll::PollsController do body = { post_id: public_poll.id, poll_name: "poll" } message = MessageBus.track_publish do - xhr :put, :vote, body.merge(options: ["5c24fc1df56d764b550ceae1b9319125"]) + put :vote, + params: body.merge(options: ["5c24fc1df56d764b550ceae1b9319125"]), + format: :json end.first expect(response).to be_success @@ -119,7 +153,10 @@ describe ::DiscoursePoll::PollsController do expect(message.data[:post_id].to_i).to eq(public_poll.id) expect(message.data[:user][:id].to_i).to eq(user.id) - xhr :put, :vote, body.merge(options: ["e89dec30bbd9bf50fabf6a05b4324edf"]) + put :vote, + params: body.merge(options: ["e89dec30bbd9bf50fabf6a05b4324edf"]), + format: :json + expect(response).to be_success json = ::JSON.parse(response.body) @@ -132,7 +169,10 @@ describe ::DiscoursePoll::PollsController do another_user = Fabricate(:user) log_in_user(another_user) - xhr :put, :vote, body.merge(options: ["e89dec30bbd9bf50fabf6a05b4324edf", "5c24fc1df56d764b550ceae1b9319125"]) + put :vote, + params: body.merge(options: ["e89dec30bbd9bf50fabf6a05b4324edf", "5c24fc1df56d764b550ceae1b9319125"]), + format: :json + expect(response).to be_success json = ::JSON.parse(response.body) @@ -149,7 +189,10 @@ describe ::DiscoursePoll::PollsController do it "works for OP" do MessageBus.expects(:publish) - xhr :put, :toggle_status, post_id: poll.id, poll_name: "poll", status: "closed" + put :toggle_status, params: { + post_id: poll.id, poll_name: "poll", status: "closed" + }, format: :json + expect(response).to be_success json = ::JSON.parse(response.body) expect(json["poll"]["status"]).to eq("closed") @@ -159,7 +202,10 @@ describe ::DiscoursePoll::PollsController do log_in(:moderator) MessageBus.expects(:publish) - xhr :put, :toggle_status, post_id: poll.id, poll_name: "poll", status: "closed" + put :toggle_status, params: { + post_id: poll.id, poll_name: "poll", status: "closed" + }, format: :json + expect(response).to be_success json = ::JSON.parse(response.body) expect(json["poll"]["status"]).to eq("closed") @@ -167,7 +213,11 @@ describe ::DiscoursePoll::PollsController do it "ensures post is not trashed" do poll.trash! - xhr :put, :toggle_status, post_id: poll.id, poll_name: "poll", status: "closed" + + put :toggle_status, params: { + post_id: poll.id, poll_name: "poll", status: "closed" + }, format: :json + expect(response).not_to be_success json = ::JSON.parse(response.body) expect(json["errors"][0]).to eq(I18n.t("poll.post_is_deleted")) @@ -183,18 +233,37 @@ describe ::DiscoursePoll::PollsController do second = "e89dec30bbd9bf50fabf6a05b4324edf" user1 = log_in - xhr :put, :vote, post_id: multi_poll.id, poll_name: "poll", options: [first] + + put :vote, params: { + post_id: multi_poll.id, poll_name: "poll", options: [first] + }, format: :json + + expect(response).to be_success user2 = log_in - xhr :put, :vote, post_id: multi_poll.id, poll_name: "poll", options: [first] + + put :vote, params: { + post_id: multi_poll.id, poll_name: "poll", options: [first] + }, format: :json + + expect(response).to be_success user3 = log_in - xhr :put, :vote, + + put :vote, params: { post_id: multi_poll.id, poll_name: "poll", options: [first, second] + }, format: :json + + expect(response).to be_success + + get :voters, params: { + poll_name: 'poll', post_id: multi_poll.id, voter_limit: 2 + }, format: :json + + expect(response).to be_success - xhr :get, :voters, poll_name: 'poll', post_id: multi_poll.id, voter_limit: 2 json = JSON.parse(response.body) # no user3 cause voter_limit is 2 diff --git a/plugins/poll/spec/controllers/posts_controller_spec.rb b/plugins/poll/spec/controllers/posts_controller_spec.rb index dd0219f3845..7a3e39a77cd 100644 --- a/plugins/poll/spec/controllers/posts_controller_spec.rb +++ b/plugins/poll/spec/controllers/posts_controller_spec.rb @@ -12,7 +12,10 @@ describe PostsController do describe "polls" do it "works" do - xhr :post, :create, title: title, raw: "[poll]\n- A\n- B\n[/poll]" + post :create, params: { + title: title, raw: "[poll]\n- A\n- B\n[/poll]" + }, format: :json + expect(response).to be_success json = ::JSON.parse(response.body) expect(json["cooked"]).to match("data-poll-") @@ -20,8 +23,12 @@ describe PostsController do end it "works on any post" do - post = Fabricate(:post) - xhr :post, :create, topic_id: post.topic.id, raw: "[poll]\n- A\n- B\n[/poll]" + post_1 = Fabricate(:post) + + post :create, params: { + topic_id: post_1.topic.id, raw: "[poll]\n- A\n- B\n[/poll]" + }, format: :json + expect(response).to be_success json = ::JSON.parse(response.body) expect(json["cooked"]).to match("data-poll-") @@ -29,14 +36,20 @@ describe PostsController do end it "should have different options" do - xhr :post, :create, title: title, raw: "[poll]\n- A\n- A\n[/poll]" + post :create, params: { + title: title, raw: "[poll]\n- A\n- A\n[/poll]" + }, format: :json + expect(response).not_to be_success json = ::JSON.parse(response.body) expect(json["errors"][0]).to eq(I18n.t("poll.default_poll_must_have_different_options")) end it "should have at least 2 options" do - xhr :post, :create, title: title, raw: "[poll]\n- A\n[/poll]" + post :create, params: { + title: title, raw: "[poll]\n- A\n[/poll]" + }, format: :json + expect(response).not_to be_success json = ::JSON.parse(response.body) expect(json["errors"][0]).to eq(I18n.t("poll.default_poll_must_have_at_least_2_options")) @@ -47,7 +60,9 @@ describe PostsController do (SiteSetting.poll_maximum_options + 1).times { |n| raw << "\n- #{n}" } raw << "\n[/poll]" - xhr :post, :create, title: title, raw: raw + post :create, params: { + title: title, raw: raw + }, format: :json expect(response).not_to be_success json = ::JSON.parse(response.body) @@ -55,14 +70,20 @@ describe PostsController do end it "should have valid parameters" do - xhr :post, :create, title: title, raw: "[poll type=multiple min=5]\n- A\n- B\n[/poll]" + post :create, params: { + title: title, raw: "[poll type=multiple min=5]\n- A\n- B\n[/poll]" + }, format: :json + expect(response).not_to be_success json = ::JSON.parse(response.body) expect(json["errors"][0]).to eq(I18n.t("poll.default_poll_with_multiple_choices_has_invalid_parameters")) end it "prevents self-xss" do - xhr :post, :create, title: title, raw: "[poll name=]\n- A\n- B\n[/poll]" + post :create, params: { + title: title, raw: "[poll name=]\n- A\n- B\n[/poll]" + }, format: :json + expect(response).to be_success json = ::JSON.parse(response.body) expect(json["cooked"]).to match("data-poll-") @@ -71,7 +92,10 @@ describe PostsController do end it "also works whe there is a link starting with '[poll'" do - xhr :post, :create, title: title, raw: "[Polls are awesome](/foobar)\n[poll]\n- A\n- B\n[/poll]" + post :create, params: { + title: title, raw: "[Polls are awesome](/foobar)\n[poll]\n- A\n- B\n[/poll]" + }, format: :json + expect(response).to be_success json = ::JSON.parse(response.body) expect(json["cooked"]).to match("data-poll-") @@ -79,7 +103,10 @@ describe PostsController do end it "prevents pollception" do - xhr :post, :create, title: title, raw: "[poll name=1]\n- A\n[poll name=2]\n- B\n- C\n[/poll]\n- D\n[/poll]" + post :create, params: { + title: title, raw: "[poll name=1]\n- A\n[poll name=2]\n- B\n- C\n[/poll]\n- D\n[/poll]" + }, format: :json + expect(response).to be_success json = ::JSON.parse(response.body) expect(json["cooked"]).to match("data-poll-") @@ -93,13 +120,19 @@ describe PostsController do let(:post_id) do freeze_time(4.minutes.ago) do - xhr :post, :create, title: title, raw: "[poll]\n- A\n- B\n[/poll]" + post :create, params: { + title: title, raw: "[poll]\n- A\n- B\n[/poll]" + }, format: :json + ::JSON.parse(response.body)["id"] end end it "can be changed" do - xhr :put, :update, id: post_id, post: { raw: "[poll]\n- A\n- B\n- C\n[/poll]" } + put :update, params: { + id: post_id, post: { raw: "[poll]\n- A\n- B\n- C\n[/poll]" } + }, format: :json + expect(response).to be_success json = ::JSON.parse(response.body) expect(json["post"]["polls"]["poll"]["options"][2]["html"]).to eq("C") @@ -107,7 +140,11 @@ describe PostsController do it "resets the votes" do DiscoursePoll::Poll.vote(post_id, "poll", ["5c24fc1df56d764b550ceae1b9319125"], user) - xhr :put, :update, id: post_id, post: { raw: "[poll]\n- A\n- B\n- C\n[/poll]" } + + put :update, params: { + id: post_id, post: { raw: "[poll]\n- A\n- B\n- C\n[/poll]" } + }, format: :json + expect(response).to be_success json = ::JSON.parse(response.body) expect(json["post"]["polls_votes"]).to_not be @@ -123,7 +160,10 @@ describe PostsController do let(:post_id) do freeze_time(6.minutes.ago) do - xhr :post, :create, title: title, raw: poll + post :create, params: { + title: title, raw: poll + }, format: :json + ::JSON.parse(response.body)["id"] end end @@ -137,7 +177,10 @@ describe PostsController do describe "with no vote" do it "OP can change the options" do - xhr :put, :update, id: post_id, post: { raw: new_option } + put :update, params: { + id: post_id, post: { raw: new_option } + }, format: :json + expect(response).to be_success json = ::JSON.parse(response.body) expect(json["post"]["polls"]["poll"]["options"][1]["html"]).to eq("C") @@ -145,14 +188,18 @@ describe PostsController do it "staff can change the options" do log_in_user(Fabricate(:moderator)) - xhr :put, :update, id: post_id, post: { raw: new_option } + + put :update, params: { + id: post_id, post: { raw: new_option } + }, format: :json + expect(response).to be_success json = ::JSON.parse(response.body) expect(json["post"]["polls"]["poll"]["options"][1]["html"]).to eq("C") end it "support changes on the post" do - xhr :put, :update, id: post_id, post: { raw: updated } + put :update, params: { id: post_id, post: { raw: updated } }, format: :json expect(response).to be_success json = ::JSON.parse(response.body) expect(json["post"]["cooked"]).to match("before") @@ -167,7 +214,10 @@ describe PostsController do end it "OP cannot change the options" do - xhr :put, :update, id: post_id, post: { raw: new_option } + put :update, params: { + id: post_id, post: { raw: new_option } + }, format: :json + expect(response).not_to be_success json = ::JSON.parse(response.body) expect(json["errors"][0]).to eq(I18n.t( @@ -178,7 +228,11 @@ describe PostsController do it "staff can change the options and votes are merged" do log_in_user(Fabricate(:moderator)) - xhr :put, :update, id: post_id, post: { raw: new_option } + + put :update, params: { + id: post_id, post: { raw: new_option } + }, format: :json + expect(response).to be_success json = ::JSON.parse(response.body) expect(json["post"]["polls"]["poll"]["options"][1]["html"]).to eq("C") @@ -193,7 +247,11 @@ describe PostsController do add_anonymous_votes(post, default_poll, 7, "5c24fc1df56d764b550ceae1b9319125" => 7) log_in_user(Fabricate(:moderator)) - xhr :put, :update, id: post_id, post: { raw: new_option } + + put :update, params: { + id: post_id, post: { raw: new_option } + }, format: :json + expect(response).to be_success json = ::JSON.parse(response.body) @@ -204,7 +262,7 @@ describe PostsController do end it "support changes on the post" do - xhr :put, :update, id: post_id, post: { raw: updated } + put :update, params: { id: post_id, post: { raw: updated } }, format: :json expect(response).to be_success json = ::JSON.parse(response.body) expect(json["post"]["cooked"]).to match("before") @@ -221,14 +279,20 @@ describe PostsController do describe "named polls" do it "should have different options" do - xhr :post, :create, title: title, raw: "[poll name=""foo""]\n- A\n- A\n[/poll]" + post :create, params: { + title: title, raw: "[poll name=""foo""]\n- A\n- A\n[/poll]" + }, format: :json + expect(response).not_to be_success json = ::JSON.parse(response.body) expect(json["errors"][0]).to eq(I18n.t("poll.named_poll_must_have_different_options", name: "foo")) end it "should have at least 2 options" do - xhr :post, :create, title: title, raw: "[poll name='foo']\n- A\n[/poll]" + post :create, params: { + title: title, raw: "[poll name='foo']\n- A\n[/poll]" + }, format: :json + expect(response).not_to be_success json = ::JSON.parse(response.body) expect(json["errors"][0]).to eq(I18n.t("poll.named_poll_must_have_at_least_2_options", name: "foo")) @@ -239,7 +303,10 @@ describe PostsController do describe "multiple polls" do it "works" do - xhr :post, :create, title: title, raw: "[poll]\n- A\n- B\n[/poll]\n[poll name=foo]\n- A\n- B\n[/poll]" + post :create, params: { + title: title, raw: "[poll]\n- A\n- B\n[/poll]\n[poll name=foo]\n- A\n- B\n[/poll]" + }, format: :json + expect(response).to be_success json = ::JSON.parse(response.body) expect(json["cooked"]).to match("data-poll-") @@ -248,14 +315,20 @@ describe PostsController do end it "should have a name" do - xhr :post, :create, title: title, raw: "[poll]\n- A\n- B\n[/poll]\n[poll]\n- A\n- B\n[/poll]" + post :create, params: { + title: title, raw: "[poll]\n- A\n- B\n[/poll]\n[poll]\n- A\n- B\n[/poll]" + }, format: :json + expect(response).not_to be_success json = ::JSON.parse(response.body) expect(json["errors"][0]).to eq(I18n.t("poll.multiple_polls_without_name")) end it "should have unique name" do - xhr :post, :create, title: title, raw: "[poll name=foo]\n- A\n- B\n[/poll]\n[poll name=foo]\n- A\n- B\n[/poll]" + post :create, params: { + title: title, raw: "[poll name=foo]\n- A\n- B\n[/poll]\n[poll name=foo]\n- A\n- B\n[/poll]" + }, format: :json + expect(response).not_to be_success json = ::JSON.parse(response.body) expect(json["errors"][0]).to eq(I18n.t("poll.multiple_polls_with_same_name", name: "foo")) diff --git a/plugins/poll/spec/integration/poll_endpoints_spec.rb b/plugins/poll/spec/integration/poll_endpoints_spec.rb index 67e247e4f21..e4c8005a442 100644 --- a/plugins/poll/spec/integration/poll_endpoints_spec.rb +++ b/plugins/poll/spec/integration/poll_endpoints_spec.rb @@ -13,8 +13,10 @@ describe "DiscoursePoll endpoints" do user ) - get "/polls/voters.json", post_id: post.id, - poll_name: DiscoursePoll::DEFAULT_POLL_NAME + get "/polls/voters.json", params: { + post_id: post.id, + poll_name: DiscoursePoll::DEFAULT_POLL_NAME + } expect(response.status).to eq(200) @@ -34,9 +36,11 @@ describe "DiscoursePoll endpoints" do user ) - get "/polls/voters.json", post_id: post.id, - poll_name: DiscoursePoll::DEFAULT_POLL_NAME, - option_id: 'e89dec30bbd9bf50fabf6a05b4324edf' + get "/polls/voters.json", params: { + post_id: post.id, + poll_name: DiscoursePoll::DEFAULT_POLL_NAME, + option_id: 'e89dec30bbd9bf50fabf6a05b4324edf' + } expect(response.status).to eq(200) @@ -53,7 +57,7 @@ describe "DiscoursePoll endpoints" do describe 'when post_id is blank' do it 'should raise the right error' do - expect { get "/polls/voters.json", poll_name: DiscoursePoll::DEFAULT_POLL_NAME } + expect { get "/polls/voters.json", params: { poll_name: DiscoursePoll::DEFAULT_POLL_NAME } } .to raise_error(ActionController::ParameterMissing) end end @@ -61,15 +65,17 @@ describe "DiscoursePoll endpoints" do describe 'when post_id is not valid' do it 'should raise the right error' do expect do - get "/polls/voters.json", post_id: -1, - poll_name: DiscoursePoll::DEFAULT_POLL_NAME + get "/polls/voters.json", params: { + post_id: -1, + poll_name: DiscoursePoll::DEFAULT_POLL_NAME + } end.to raise_error(Discourse::InvalidParameters, 'post_id is invalid') end end describe 'when poll_name is blank' do it 'should raise the right error' do - expect { get "/polls/voters.json", post_id: post.id } + expect { get "/polls/voters.json", params: { post_id: post.id } } .to raise_error(ActionController::ParameterMissing) end end @@ -77,7 +83,7 @@ describe "DiscoursePoll endpoints" do describe 'when poll_name is not valid' do it 'should raise the right error' do expect do - get "/polls/voters.json", post_id: post.id, poll_name: 'wrongpoll' + get "/polls/voters.json", params: { post_id: post.id, poll_name: 'wrongpoll' } end.to raise_error(Discourse::InvalidParameters, 'poll_name is invalid') end end @@ -95,8 +101,10 @@ describe "DiscoursePoll endpoints" do user ) - get "/polls/voters.json", post_id: post.id, - poll_name: DiscoursePoll::DEFAULT_POLL_NAME + get "/polls/voters.json", params: { + post_id: post.id, + poll_name: DiscoursePoll::DEFAULT_POLL_NAME + } expect(response.status).to eq(200) diff --git a/public/javascripts/ace/mode-ejs.js b/public/javascripts/ace/mode-ejs.js index e46c1bc2ea3..790ba049d29 100644 --- a/public/javascripts/ace/mode-ejs.js +++ b/public/javascripts/ace/mode-ejs.js @@ -1 +1 @@ -ace.define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=t.supportType="animation-fill-mode|alignment-adjust|alignment-baseline|animation-delay|animation-direction|animation-duration|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|animation|appearance|azimuth|backface-visibility|background-attachment|background-break|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|background|baseline-shift|binding|bleed|bookmark-label|bookmark-level|bookmark-state|bookmark-target|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|border|bottom|box-align|box-decoration-break|box-direction|box-flex-group|box-flex|box-lines|box-ordinal-group|box-orient|box-pack|box-shadow|box-sizing|break-after|break-before|break-inside|caption-side|clear|clip|color-profile|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|crop|cue-after|cue-before|cue|cursor|direction|display|dominant-baseline|drop-initial-after-adjust|drop-initial-after-align|drop-initial-before-adjust|drop-initial-before-align|drop-initial-size|drop-initial-value|elevation|empty-cells|fit|fit-position|float-offset|float|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|font|grid-columns|grid-rows|hanging-punctuation|height|hyphenate-after|hyphenate-before|hyphenate-character|hyphenate-lines|hyphenate-resource|hyphens|icon|image-orientation|image-rendering|image-resolution|inline-box-align|left|letter-spacing|line-height|line-stacking-ruby|line-stacking-shift|line-stacking-strategy|line-stacking|list-style-image|list-style-position|list-style-type|list-style|margin-bottom|margin-left|margin-right|margin-top|margin|mark-after|mark-before|mark|marks|marquee-direction|marquee-play-count|marquee-speed|marquee-style|max-height|max-width|min-height|min-width|move-to|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|orphans|outline-color|outline-offset|outline-style|outline-width|outline|overflow-style|overflow-x|overflow-y|overflow|padding-bottom|padding-left|padding-right|padding-top|padding|page-break-after|page-break-before|page-break-inside|page-policy|page|pause-after|pause-before|pause|perspective-origin|perspective|phonemes|pitch-range|pitch|play-during|pointer-events|position|presentation-level|punctuation-trim|quotes|rendering-intent|resize|rest-after|rest-before|rest|richness|right|rotation-point|rotation|ruby-align|ruby-overhang|ruby-position|ruby-span|size|speak-header|speak-numeral|speak-punctuation|speak|speech-rate|stress|string-set|table-layout|target-name|target-new|target-position|target|text-align-last|text-align|text-decoration|text-emphasis|text-height|text-indent|text-justify|text-outline|text-shadow|text-transform|text-wrap|top|transform-origin|transform-style|transform|transition-delay|transition-duration|transition-property|transition-timing-function|transition|unicode-bidi|vertical-align|visibility|voice-balance|voice-duration|voice-family|voice-pitch-range|voice-pitch|voice-rate|voice-stress|voice-volume|volume|white-space-collapse|white-space|widows|width|word-break|word-spacing|word-wrap|z-index",u=t.supportFunction="rgb|rgba|url|attr|counter|counters",a=t.supportConstant="absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero",f=t.supportConstantColor="aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow",l=t.supportConstantFonts="arial|century|comic|courier|cursive|fantasy|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace",c=t.numRe="\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))",h=t.pseudoElements="(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b",p=t.pseudoClasses="(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b",d=function(){var e=this.createKeywordMapper({"support.function":u,"support.constant":a,"support.type":o,"support.constant.color":f,"support.constant.fonts":l},"text",!0);this.$rules={start:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"@.*?{",push:"media"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],media:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"\\}",next:"pop"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],comment:[{token:"comment",regex:"\\*\\/",next:"pop"},{defaultToken:"comment"}],ruleset:[{token:"paren.rparen",regex:"\\}",next:"pop"},{token:"comment",regex:"\\/\\*",push:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:["constant.numeric","keyword"],regex:"("+c+")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vm|vw|%)"},{token:"constant.numeric",regex:c},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:h},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:p},{token:["support.function","string","support.function"],regex:"(url\\()(.*)(\\))"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"},{caseInsensitive:!0}]},this.normalizeRules()};r.inherits(d,s),t.CssHighlightRules=d}),ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},s.getTagRule(),{defaultToken:"comment.doc",caseInsensitive:!0}]}};r.inherits(s,i),s.getTagRule=function(e){return{token:"comment.doc.tag.storage.type",regex:"\\b(?:TODO|FIXME|XXX|HACK)\\b"}},s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(e){var t=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),n="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",r="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*\\b",s="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[{token:"comment",regex:"\\/\\/",next:"line_comment"},i.getStartRule("doc-start"),{token:"comment",regex:/\/\*/,next:"comment"},{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0[xX][0-9a-fA-F]+\b/},{token:"constant.numeric",regex:/[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+r+")(\\.)(prototype)(\\.)("+r+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+r+")(\\.)("+r+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+r+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+r+")(\\.)("+r+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+r+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+r+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"(?:"+n+")\\b",next:"start"},{token:["punctuation.operator","support.function"],regex:/(\.)(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:["punctuation.operator","support.function.dom"],regex:/(\.)(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName|ClassName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:["punctuation.operator","support.constant"],regex:/(\.)(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:t,regex:r},{token:"keyword.operator",regex:/--|\+\+|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|[!$%&*+\-~\/^]=?/,next:"start"},{token:"punctuation.operator",regex:/[?:,;.]/,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"comment",regex:/^#!.*$/}],start:[i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment_regex_allowed"},{token:"comment",regex:"\\/\\/",next:"line_comment_regex_allowed"},{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.charclass.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:r},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],comment_regex_allowed:[i.getTagRule(),{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment",caseInsensitive:!0}],comment:[i.getTagRule(),{token:"comment",regex:"\\*\\/",next:"no_regex"},{defaultToken:"comment",caseInsensitive:!0}],line_comment_regex_allowed:[i.getTagRule(),{token:"comment",regex:"$|^",next:"start"},{defaultToken:"comment",caseInsensitive:!0}],line_comment:[i.getTagRule(),{token:"comment",regex:"$|^",next:"no_regex"},{defaultToken:"comment",caseInsensitive:!0}],qqstring:[{token:"constant.language.escape",regex:s},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:s},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},(!e||!e.noES6)&&this.$rules.no_regex.unshift({regex:"[{}]",onMatch:function(e,t,n){this.next=e=="{"?this.nextState:"";if(e=="{"&&n.length)return n.unshift("start",t),"paren";if(e=="}"&&n.length){n.shift(),this.next=n.shift();if(this.next.indexOf("string")!=-1)return"paren.quasi.end"}return e=="{"?"paren.lparen":"paren.rparen"},nextState:"start"},{token:"string.quasi.start",regex:/`/,push:[{token:"constant.language.escape",regex:s},{token:"paren.quasi.start",regex:/\${/,push:"start"},{token:"string.quasi.end",regex:/`/,next:"pop"},{defaultToken:"string.quasi"}]}),this.embedRules(i,"doc-",[i.getEndRule("no_regex")]),this.normalizeRules()};r.inherits(o,s),t.JavaScriptHighlightRules=o}),ace.define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(e){var t="[_:a-zA-Z\u00c0-\uffff][-_:.a-zA-Z0-9\u00c0-\uffff]*";this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.xml-decl.xml","keyword.xml-decl.xml"],regex:"(<\\?)(xml)(?=[\\s])",next:"xml_decl",caseInsensitive:!0},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)("+t+")",next:"processing_instruction"},{token:"comment.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"",next:"start"}],processing_instruction:[{token:"punctuation.instruction.xml",regex:"\\?>",next:"start"},{defaultToken:"instruction.xml"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)("+t+")",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.xml",regex:"-->",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:"(?:"+t+":)?"+t+""},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===s&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(i.prototype),r.inherits(s,i),t.XmlHighlightRules=s}),ace.define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./css_highlight_rules").CssHighlightRules,o=e("./javascript_highlight_rules").JavaScriptHighlightRules,u=e("./xml_highlight_rules").XmlHighlightRules,a=i.createMap({a:"anchor",button:"form",form:"form",img:"image",input:"form",label:"form",option:"form",script:"script",select:"form",textarea:"form",style:"style",table:"table",tbody:"table",td:"table",tfoot:"table",th:"table",tr:"table"}),f=function(){u.call(this),this.addRules({attributes:[{include:"tag_whitespace"},{token:"entity.other.attribute-name.xml",regex:"[-_a-zA-Z0-9:.]+"},{token:"keyword.operator.attribute-equals.xml",regex:"=",push:[{include:"tag_whitespace"},{token:"string.unquoted.attribute-value.html",regex:"[^<>='\"`\\s]+",next:"pop"},{token:"empty",regex:"",next:"pop"}]},{include:"attribute_value"}],tag:[{token:function(e,t){var n=a[t];return["meta.tag.punctuation."+(e=="<"?"":"end-")+"tag-open.xml","meta.tag"+(n?"."+n:"")+".tag-name.xml"]},regex:"(",next:"start"}]}),this.embedTagRules(s,"css-","style"),this.embedTagRules(o,"js-","script"),this.constructor===f&&this.normalizeRules()};r.inherits(f,u),t.HtmlHighlightRules=f}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.index,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(e,t,n,r){var i=e.end.row-e.start.row;return{text:n+t+r,selection:[0,e.start.column+1,i,e.end.column+(i?0:1)]}},p=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return h(a,l,"{","}");if(p.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(p.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(p.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var d=u.substring(s.column,s.column+1);if(d=="}"){var v=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(v!==null&&p.isAutoInsertedClosing(s,u,i))return p.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var m="";p.isMaybeInsertedClosing(s,u)&&(m=o.stringRepeat("}",f.maybeInsertedBrackets),p.clearMaybeInsertedClosing());var d=u.substring(s.column,s.column+1);if(d==="}"){var g=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!g)return null;var y=this.$getIndent(r.getLine(g.row))}else{if(!m){p.clearMaybeInsertedClosing();return}var y=this.$getIndent(u)}var b=y+r.getTabString();return{text:"\n"+b+"\n"+y+m,selection:[1,b.length,1,b.length]}}p.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return h(s,o,"(",")");if(p.isSaneInsertion(n,r))return p.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&p.isAutoInsertedClosing(u,a,i))return p.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return h(s,o,"[","]");if(p.isSaneInsertion(n,r))return p.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&p.isAutoInsertedClosing(u,a,i))return p.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return h(o,u,s,s);if(!u){var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column),p=f.substring(a.column,a.column+1),d=r.getTokenAt(a.row,a.column),v=r.getTokenAt(a.row,a.column+1);if(l=="\\"&&d&&/escape/.test(d.type))return null;var m=d&&/string/.test(d.type),g=!v||/string/.test(v.type),y;if(p==s)y=m!==g;else{if(m&&!g)return null;if(m&&g)return null;var b=r.$mode.tokenRe;b.lastIndex=0;var w=b.test(l);b.lastIndex=0;var E=b.test(l);if(w||E)return null;if(p&&!/[\s;,.})\]\\]/.test(p))return null;y=!0}return{text:y?s+s:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};p.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},p.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},p.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},p.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},p.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},p.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},p.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},p.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(p,i),t.CstyleBehaviour=p}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);if(this.singleLineBlockCommentRe.test(r)&&!this.startRegionRe.test(r)&&!this.tripleStarBlockCommentRe.test(r))return"";var i=this._getFoldWidgetBase(e,t,n);return!i&&this.startRegionRe.test(r)?"start":i},this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n);if(this.startRegionRe.test(i))return this.getCommentRegionBlock(e,i,n);var s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++tf)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)},this.getCommentRegionBlock=function(e,t,n){var r=t.search(/\s*$/),s=e.getLength(),o=n,u=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,a=1;while(++no)return new i(o,r,l,t.length)}}.call(o.prototype)}),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./javascript_highlight_rules").JavaScriptHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../range").Range,a=e("../worker/worker_client").WorkerClient,f=e("./behaviour/cstyle").CstyleBehaviour,l=e("./folding/cstyle").FoldMode,c=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new f,this.foldingRules=new l};r.inherits(c,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"||e=="no_regex"){var u=t.match(/^.*(?:\bcase\b.*\:|[\{\(\[])\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start"||o=="no_regex")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new a(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("annotate",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/javascript"}.call(c.prototype),t.Mode=c}),ace.define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("./cstyle").CstyleBehaviour,o=e("../../token_iterator").TokenIterator,u=function(){this.inherit(s),this.add("colon","insertion",function(e,t,n,r,i){if(i===":"){var s=n.getCursorPosition(),u=new o(r,s.row,s.column),a=u.getCurrentToken();a&&a.value.match(/\s+/)&&(a=u.stepBackward());if(a&&a.type==="support.type"){var f=r.doc.getLine(s.row),l=f.substring(s.column,s.column+1);if(l===":")return{text:"",selection:[1,1]};if(!f.substring(s.column).match(/^\s*;/))return{text:":;",selection:[1,1]}}}}),this.add("colon","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s===":"){var u=n.getCursorPosition(),a=new o(r,u.row,u.column),f=a.getCurrentToken();f&&f.value.match(/\s+/)&&(f=a.stepBackward());if(f&&f.type==="support.type"){var l=r.doc.getLine(i.start.row),c=l.substring(i.end.column,i.end.column+1);if(c===";")return i.end.column++,i}}}),this.add("semicolon","insertion",function(e,t,n,r,i){if(i===";"){var s=n.getCursorPosition(),o=r.doc.getLine(s.row),u=o.substring(s.column,s.column+1);if(u===";")return{text:"",selection:[1,1]}}})};r.inherits(u,s),t.CssBehaviour=u}),ace.define("ace/mode/css",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/css","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./css_highlight_rules").CssHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../worker/worker_client").WorkerClient,a=e("./behaviour/css").CssBehaviour,f=e("./folding/cstyle").FoldMode,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new a,this.foldingRules=new f};r.inherits(l,i),function(){this.foldingRules="cStyle",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e).tokens;if(i.length&&i[i.length-1].type=="comment")return r;var s=t.match(/^.*\{\s*$/);return s&&(r+=n),r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new u(["ace"],"ace/mode/css_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("annotate",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/css"}.call(l.prototype),t.Mode=l}),ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";function u(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),a=function(){this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){var o=i,a=r.doc.getTextRange(n.getSelectionRange());if(a!==""&&a!=="'"&&a!='"'&&n.getWrapBehavioursEnabled())return{text:o+a+o,selection:!1};var f=n.getCursorPosition(),l=r.doc.getLine(f.row),c=l.substring(f.column,f.column+1),h=new s(r,f.row,f.column),p=h.getCurrentToken();if(c==o&&(u(p,"attribute-value")||u(p,"string")))return{text:"",selection:[1,1]};p||(p=h.stepBackward());if(!p)return;while(u(p,"tag-whitespace")||u(p,"whitespace"))p=h.stepBackward();var d=!c||c.match(/\s/);if(u(p,"attribute-equals")&&(d||c==">")||u(p,"decl-attribute-equals")&&(d||c=="?"))return{text:o+o,selection:[1,1]}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}}),this.add("autoclosing","insertion",function(e,t,n,r,i){if(i==">"){var o=n.getCursorPosition(),a=new s(r,o.row,o.column),f=a.getCurrentToken()||a.stepBackward();if(!f||!(u(f,"tag-name")||u(f,"tag-whitespace")||u(f,"attribute-name")||u(f,"attribute-equals")||u(f,"attribute-value")))return;if(u(f,"reference.attribute-value"))return;if(u(f,"attribute-value")){var l=f.value.charAt(0);if(l=='"'||l=="'"){var c=f.value.charAt(f.value.length-1),h=a.getCurrentTokenColumn()+f.value.length;if(h>o.column||h==o.column&&l!=c)return}}while(!u(f,"tag-name"))f=a.stepBackward();var p=a.getCurrentTokenRow(),d=a.getCurrentTokenColumn();if(u(a.stepBackward(),"end-tag-open"))return;var v=f.value;p==o.row&&(v=v.substring(0,o.column-d));if(this.voidElements.hasOwnProperty(v.toLowerCase()))return;return{text:">",selection:[1,1]}}}),this.add("autoindent","insertion",function(e,t,n,r,i){if(i=="\n"){var o=n.getCursorPosition(),u=r.getLine(o.row),a=new s(r,o.row,o.column),f=a.getCurrentToken();if(f&&f.type.indexOf("tag-close")!==-1){if(f.value=="/>")return;while(f&&f.type.indexOf("tag-name")===-1)f=a.stepBackward();if(!f)return;var l=f.value,c=a.getCurrentTokenRow();f=a.stepBackward();if(!f||f.type.indexOf("end-tag")!==-1)return;if(this.voidElements&&!this.voidElements[l]){var h=r.getTokenAt(o.row,o.column+1),u=r.getLine(c),p=this.$getIndent(u),d=p+r.getTabString();return h&&h.value==="-1}var r=e("../../lib/oop"),i=e("../../lib/lang"),s=e("../../range").Range,o=e("./fold_mode").FoldMode,u=e("../../token_iterator").TokenIterator,a=t.FoldMode=function(e,t){o.call(this),this.voidElements=e||{},this.optionalEndTags=r.mixin({},this.voidElements),t&&r.mixin(this.optionalEndTags,t)};r.inherits(a,o);var f=function(){this.tagName="",this.closing=!1,this.selfClosing=!1,this.start={row:0,column:0},this.end={row:0,column:0}};(function(){this.getFoldWidget=function(e,t,n){var r=this._getFirstTagInLine(e,n);return r?r.closing||!r.tagName&&r.selfClosing?t=="markbeginend"?"end":"":!r.tagName||r.selfClosing||this.voidElements.hasOwnProperty(r.tagName.toLowerCase())?"":this._findEndTagInLine(e,n,r.tagName,r.end.column)?"":"start":""},this._getFirstTagInLine=function(e,t){var n=e.getTokens(t),r=new f;for(var i=0;i";break}}return r}if(l(s,"tag-close"))return r.selfClosing=s.value=="/>",r;r.start.column+=s.value.length}return null},this._findEndTagInLine=function(e,t,n,r){var i=e.getTokens(t),s=0;for(var o=0;o",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length,e.stepForward(),n;while(t=e.stepForward());return null},this._readTagBackward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do{if(l(t,"tag-open"))return n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn(),e.stepBackward(),n;l(t,"tag-name")?n.tagName=t.value:l(t,"tag-close")&&(n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length)}while(t=e.stepBackward());return null},this._pop=function(e,t){while(e.length){var n=e[e.length-1];if(!t||n.tagName==t.tagName)return e.pop();if(this.optionalEndTags.hasOwnProperty(n.tagName)){e.pop();continue}return null}},this.getFoldWidgetRange=function(e,t,n){var r=this._getFirstTagInLine(e,n);if(!r)return null;var i=r.closing||r.selfClosing,o=[],a;if(!i){var f=new u(e,n,r.start.column),l={row:n,column:r.start.column+r.tagName.length+2};r.start.row==r.end.row&&(l.column=r.end.column);while(a=this._readTagForward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(a.closing){this._pop(o,a);if(o.length==0)return s.fromPoints(l,a.start)}else o.push(a)}}else{var f=new u(e,n,r.end.column),c={row:n,column:r.start.column};while(a=this._readTagBackward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(!a.closing){this._pop(o,a);if(o.length==0)return a.start.column+=a.tagName.length+2,a.start.row==a.end.row&&a.start.column-1}function l(e,t){var n=new r(e,t.row,t.column),i=n.getCurrentToken();while(i&&!f(i,"tag-name"))i=n.stepBackward();if(i)return i.value}var r=e("../token_iterator").TokenIterator,i=["accesskey","class","contenteditable","contextmenu","dir","draggable","dropzone","hidden","id","inert","itemid","itemprop","itemref","itemscope","itemtype","lang","spellcheck","style","tabindex","title","translate"],s=["onabort","onblur","oncancel","oncanplay","oncanplaythrough","onchange","onclick","onclose","oncontextmenu","oncuechange","ondblclick","ondrag","ondragend","ondragenter","ondragleave","ondragover","ondragstart","ondrop","ondurationchange","onemptied","onended","onerror","onfocus","oninput","oninvalid","onkeydown","onkeypress","onkeyup","onload","onloadeddata","onloadedmetadata","onloadstart","onmousedown","onmousemove","onmouseout","onmouseover","onmouseup","onmousewheel","onpause","onplay","onplaying","onprogress","onratechange","onreset","onscroll","onseeked","onseeking","onselect","onshow","onstalled","onsubmit","onsuspend","ontimeupdate","onvolumechange","onwaiting"],o=i.concat(s),u={html:["manifest"],head:[],title:[],base:["href","target"],link:["href","hreflang","rel","media","type","sizes"],meta:["http-equiv","name","content","charset"],style:["type","media","scoped"],script:["charset","type","src","defer","async"],noscript:["href"],body:["onafterprint","onbeforeprint","onbeforeunload","onhashchange","onmessage","onoffline","onpopstate","onredo","onresize","onstorage","onundo","onunload"],section:[],nav:[],article:["pubdate"],aside:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],header:[],footer:[],address:[],main:[],p:[],hr:[],pre:[],blockquote:["cite"],ol:["start","reversed"],ul:[],li:["value"],dl:[],dt:[],dd:[],figure:[],figcaption:[],div:[],a:["href","target","ping","rel","media","hreflang","type"],em:[],strong:[],small:[],s:[],cite:[],q:["cite"],dfn:[],abbr:[],data:[],time:["datetime"],code:[],"var":[],samp:[],kbd:[],sub:[],sup:[],i:[],b:[],u:[],mark:[],ruby:[],rt:[],rp:[],bdi:[],bdo:[],span:[],br:[],wbr:[],ins:["cite","datetime"],del:["cite","datetime"],img:["alt","src","height","width","usemap","ismap"],iframe:["name","src","height","width","sandbox","seamless"],embed:["src","height","width","type"],object:["param","data","type","height","width","usemap","name","form","classid"],param:["name","value"],video:["src","autobuffer","autoplay","loop","controls","width","height","poster"],audio:["src","autobuffer","autoplay","loop","controls"],source:["src","type","media"],track:["kind","src","srclang","label","default"],canvas:["width","height"],map:["name"],area:["shape","coords","href","hreflang","alt","target","media","rel","ping","type"],svg:[],math:[],table:["summary"],caption:[],colgroup:["span"],col:["span"],tbody:[],thead:[],tfoot:[],tr:[],td:["headers","rowspan","colspan"],th:["headers","rowspan","colspan","scope"],form:["accept-charset","action","autocomplete","enctype","method","name","novalidate","target"],fieldset:["disabled","form","name"],legend:[],label:["form","for"],input:["type","accept","alt","autocomplete","checked","disabled","form","formaction","formenctype","formmethod","formnovalidate","formtarget","height","list","max","maxlength","min","multiple","pattern","placeholder","readonly","required","size","src","step","width","files","value"],button:["autofocus","disabled","form","formaction","formenctype","formmethod","formnovalidate","formtarget","name","value","type"],select:["autofocus","disabled","form","multiple","name","size"],datalist:[],optgroup:["disabled","label"],option:["disabled","selected","label","value"],textarea:["autofocus","disabled","form","maxlength","name","placeholder","readonly","required","rows","cols","wrap"],keygen:["autofocus","challenge","disabled","form","keytype","name"],output:["for","form","name"],progress:["value","max"],meter:["value","min","max","low","high","optimum"],details:["open"],summary:[],command:["type","label","icon","disabled","checked","radiogroup","command"],menu:["type","label"],dialog:["open"]},a=Object.keys(u),c=function(){};(function(){this.getCompletions=function(e,t,n,r){var i=t.getTokenAt(n.row,n.column);return i?f(i,"tag-name")||f(i,"tag-open")||f(i,"end-tag-open")?this.getTagCompletions(e,t,n,r):f(i,"tag-whitespace")||f(i,"attribute-name")?this.getAttributeCompetions(e,t,n,r):[]:[]},this.getTagCompletions=function(e,t,n,r){return a.map(function(e){return{value:e,meta:"tag",score:Number.MAX_VALUE}})},this.getAttributeCompetions=function(e,t,n,r){var i=l(t,n);if(!i)return[];var s=o;return i in u&&(s=s.concat(u[i])),s.map(function(e){return{caption:e,snippet:e+'="$0"',meta:"attribute",score:Number.MAX_VALUE}})}}).call(c.prototype),t.HtmlCompletions=c}),ace.define("ace/mode/html",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/javascript","ace/mode/css","ace/mode/html_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/html","ace/mode/html_completions","ace/worker/worker_client"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text").Mode,o=e("./javascript").Mode,u=e("./css").Mode,a=e("./html_highlight_rules").HtmlHighlightRules,f=e("./behaviour/xml").XmlBehaviour,l=e("./folding/html").FoldMode,c=e("./html_completions").HtmlCompletions,h=e("../worker/worker_client").WorkerClient,p=["area","base","br","col","embed","hr","img","input","keygen","link","meta","menuitem","param","source","track","wbr"],d=["li","dt","dd","p","rt","rp","optgroup","option","colgroup","td","th"],v=function(e){this.fragmentContext=e&&e.fragmentContext,this.HighlightRules=a,this.$behaviour=new f,this.$completer=new c,this.createModeDelegates({"js-":o,"css-":u}),this.foldingRules=new l(this.voidElements,i.arrayToMap(d))};r.inherits(v,s),function(){this.blockComment={start:""},this.voidElements=i.arrayToMap(p),this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.getCompletions=function(e,t,n,r){return this.$completer.getCompletions(e,t,n,r)},this.createWorker=function(e){if(this.constructor!=v)return;var t=new h(["ace"],"ace/mode/html_worker","Worker");return t.attachToDocument(e.getDocument()),this.fragmentContext&&t.call("setOptions",[{context:this.fragmentContext}]),t.on("error",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/html"}.call(v.prototype),t.Mode=v}),ace.define("ace/mode/ruby_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=t.constantOtherSymbol={token:"constant.other.symbol.ruby",regex:"[:](?:[A-Za-z_]|[@$](?=[a-zA-Z0-9_]))[a-zA-Z0-9_]*[!=?]?"},o=t.qString={token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},u=t.qqString={token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},a=t.tString={token:"string",regex:"[`](?:(?:\\\\.)|(?:[^'\\\\]))*?[`]"},f=t.constantNumericHex={token:"constant.numeric",regex:"0[xX][0-9a-fA-F](?:[0-9a-fA-F]|_(?=[0-9a-fA-F]))*\\b"},l=t.constantNumericFloat={token:"constant.numeric",regex:"[+-]?\\d(?:\\d|_(?=\\d))*(?:(?:\\.\\d(?:\\d|_(?=\\d))*)?(?:[eE][+-]?\\d+)?)?\\b"},c=function(){var e="abort|Array|assert|assert_equal|assert_not_equal|assert_same|assert_not_same|assert_nil|assert_not_nil|assert_match|assert_no_match|assert_in_delta|assert_throws|assert_raise|assert_nothing_raised|assert_instance_of|assert_kind_of|assert_respond_to|assert_operator|assert_send|assert_difference|assert_no_difference|assert_recognizes|assert_generates|assert_response|assert_redirected_to|assert_template|assert_select|assert_select_email|assert_select_rjs|assert_select_encoded|css_select|at_exit|attr|attr_writer|attr_reader|attr_accessor|attr_accessible|autoload|binding|block_given?|callcc|caller|catch|chomp|chomp!|chop|chop!|defined?|delete_via_redirect|eval|exec|exit|exit!|fail|Float|flunk|follow_redirect!|fork|form_for|form_tag|format|gets|global_variables|gsub|gsub!|get_via_redirect|host!|https?|https!|include|Integer|lambda|link_to|link_to_unless_current|link_to_function|link_to_remote|load|local_variables|loop|open|open_session|p|print|printf|proc|putc|puts|post_via_redirect|put_via_redirect|raise|rand|raw|readline|readlines|redirect?|request_via_redirect|require|scan|select|set_trace_func|sleep|split|sprintf|srand|String|stylesheet_link_tag|syscall|system|sub|sub!|test|throw|trace_var|trap|untrace_var|atan2|cos|exp|frexp|ldexp|log|log10|sin|sqrt|tan|render|javascript_include_tag|csrf_meta_tag|label_tag|text_field_tag|submit_tag|check_box_tag|content_tag|radio_button_tag|text_area_tag|password_field_tag|hidden_field_tag|fields_for|select_tag|options_for_select|options_from_collection_for_select|collection_select|time_zone_select|select_date|select_time|select_datetime|date_select|time_select|datetime_select|select_year|select_month|select_day|select_hour|select_minute|select_second|file_field_tag|file_field|respond_to|skip_before_filter|around_filter|after_filter|verify|protect_from_forgery|rescue_from|helper_method|redirect_to|before_filter|send_data|send_file|validates_presence_of|validates_uniqueness_of|validates_length_of|validates_format_of|validates_acceptance_of|validates_associated|validates_exclusion_of|validates_inclusion_of|validates_numericality_of|validates_with|validates_each|authenticate_or_request_with_http_basic|authenticate_or_request_with_http_digest|filter_parameter_logging|match|get|post|resources|redirect|scope|assert_routing|translate|localize|extract_locale_from_tld|caches_page|expire_page|caches_action|expire_action|cache|expire_fragment|expire_cache_for|observe|cache_sweeper|has_many|has_one|belongs_to|has_and_belongs_to_many",t="alias|and|BEGIN|begin|break|case|class|def|defined|do|else|elsif|END|end|ensure|__FILE__|finally|for|gem|if|in|__LINE__|module|next|not|or|private|protected|public|redo|rescue|retry|return|super|then|undef|unless|until|when|while|yield",n="true|TRUE|false|FALSE|nil|NIL|ARGF|ARGV|DATA|ENV|RUBY_PLATFORM|RUBY_RELEASE_DATE|RUBY_VERSION|STDERR|STDIN|STDOUT|TOPLEVEL_BINDING",r="$DEBUG|$defout|$FILENAME|$LOAD_PATH|$SAFE|$stdin|$stdout|$stderr|$VERBOSE|$!|root_url|flash|session|cookies|params|request|response|logger|self",i=this.$keywords=this.createKeywordMapper({keyword:t,"constant.language":n,"variable.language":r,"support.function":e,"invalid.deprecated":"debugger"},"identifier");this.$rules={start:[{token:"comment",regex:"#.*$"},{token:"comment",regex:"^=begin(?:$|\\s.*$)",next:"comment"},{token:"string.regexp",regex:"[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/]\\w*\\s*(?=[).,;]|$)"},[{regex:"[{}]",onMatch:function(e,t,n){this.next=e=="{"?this.nextState:"";if(e=="{"&&n.length)return n.unshift("start",t),"paren.lparen";if(e=="}"&&n.length){n.shift(),this.next=n.shift();if(this.next.indexOf("string")!=-1)return"paren.end"}return e=="{"?"paren.lparen":"paren.rparen"},nextState:"start"},{token:"string.start",regex:/"/,push:[{token:"constant.language.escape",regex:/\\(?:[nsrtvfbae'"\\]|c.|C-.|M-.(?:\\C-.)?|[0-7]{3}|x[\da-fA-F]{2}|u[\da-fA-F]{4})/},{token:"paren.start",regex:/\#{/,push:"start"},{token:"string.end",regex:/"/,next:"pop"},{defaultToken:"string"}]},{token:"string.start",regex:/`/,push:[{token:"constant.language.escape",regex:/\\(?:[nsrtvfbae'"\\]|c.|C-.|M-.(?:\\C-.)?|[0-7]{3}|x[\da-fA-F]{2}|u[\da-fA-F]{4})/},{token:"paren.start",regex:/\#{/,push:"start"},{token:"string.end",regex:/`/,next:"pop"},{defaultToken:"string"}]},{token:"string.start",regex:/'/,push:[{token:"constant.language.escape",regex:/\\['\\]/},{token:"string.end",regex:/'/,next:"pop"},{defaultToken:"string"}]}],{token:"text",regex:"::"},{token:"variable.instance",regex:"@{1,2}[a-zA-Z_\\d]+"},{token:"support.class",regex:"[A-Z][a-zA-Z_\\d]+"},s,f,l,{token:"constant.language.boolean",regex:"(?:true|false)\\b"},{token:i,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"punctuation.separator.key-value",regex:"=>"},{stateName:"heredoc",onMatch:function(e,t,n){var r=e[2]=="-"?"indentedHeredoc":"heredoc",i=e.split(this.splitRegex);return n.push(r,i[3]),[{type:"constant",value:i[1]},{type:"string",value:i[2]},{type:"support.class",value:i[3]},{type:"string",value:i[4]}]},regex:"(<<-?)(['\"`]?)([\\w]+)(['\"`]?)",rules:{heredoc:[{onMatch:function(e,t,n){return e===n[1]?(n.shift(),n.shift(),this.next=n[0]||"start","support.class"):(this.next="","string")},regex:".*$",next:"start"}],indentedHeredoc:[{token:"string",regex:"^ +"},{onMatch:function(e,t,n){return e===n[1]?(n.shift(),n.shift(),this.next=n[0]||"start","support.class"):(this.next="","string")},regex:".*$",next:"start"}]}},{regex:"$",token:"empty",next:function(e,t){return t[0]==="heredoc"||t[0]==="indentedHeredoc"?t[0]:e}},{token:"string.character",regex:"\\B\\?."},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:"^=end(?:$|\\s.*$)",next:"start"},{token:"comment",regex:".+"}]},this.normalizeRules()};r.inherits(c,i),t.RubyHighlightRules=c}),ace.define("ace/mode/folding/coffee",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=e("../../range").Range,o=t.FoldMode=function(){};r.inherits(o,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=this.indentationBlock(e,n);if(r)return r;var i=/\S/,o=e.getLine(n),u=o.search(i);if(u==-1||o[u]!="#")return;var a=o.length,f=e.getLength(),l=n,c=n;while(++nl){var p=e.getLine(c).length;return new s(l,a,c,p)}},this.getFoldWidget=function(e,t,n){var r=e.getLine(n),i=r.search(/\S/),s=e.getLine(n+1),o=e.getLine(n-1),u=o.search(/\S/),a=s.search(/\S/);if(i==-1)return e.foldWidgets[n-1]=u!=-1&&u|\\?>|}})");for(var n in this.$rules)this.$rules[n].unshift({token:"markup.list.meta.tag",regex:e+"(?![>}])[-=]?",push:"ejs-start"});this.embedRules(s,"ejs-"),this.$rules["ejs-start"].unshift({token:"markup.list.meta.tag",regex:"-?"+t,next:"pop"},{token:"comment",regex:"//.*?"+t,next:"pop"}),this.$rules["ejs-no_regex"].unshift({token:"markup.list.meta.tag",regex:"-?"+t,next:"pop"},{token:"comment",regex:"//.*?"+t,next:"pop"}),this.normalizeRules()};r.inherits(o,i),t.EjsHighlightRules=o;var r=e("../lib/oop"),u=e("./html").Mode,a=e("./javascript").Mode,f=e("./css").Mode,l=e("./ruby").Mode,c=function(){u.call(this),this.HighlightRules=o,this.createModeDelegates({"js-":a,"css-":f,"ejs-":a})};r.inherits(c,u),function(){this.$id="ace/mode/ejs"}.call(c.prototype),t.Mode=c}) \ No newline at end of file +ace.define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=t.supportType="animation-fill-mode|alignment-adjust|alignment-baseline|animation-delay|animation-direction|animation-duration|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|animation|appearance|azimuth|backface-visibility|background-attachment|background-break|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|background|baseline-shift|binding|bleed|bookmark-label|bookmark-level|bookmark-state|bookmark-target|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|border|bottom|box-align|box-decoration-break|box-direction|box-flex-group|box-flex|box-lines|box-ordinal-group|box-orient|box-pack|box-shadow|box-sizing|break-after|break-before|break-inside|caption-side|clear|clip|color-profile|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|crop|cue-after|cue-before|cue|cursor|direction|display|dominant-baseline|drop-initial-after-adjust|drop-initial-after-align|drop-initial-before-adjust|drop-initial-before-align|drop-initial-size|drop-initial-value|elevation|empty-cells|fit|fit-position|float-offset|float|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|font|grid-columns|grid-rows|hanging-punctuation|height|hyphenate-after|hyphenate-before|hyphenate-character|hyphenate-lines|hyphenate-resource|hyphens|icon|image-orientation|image-rendering|image-resolution|inline-box-align|left|letter-spacing|line-height|line-stacking-ruby|line-stacking-shift|line-stacking-strategy|line-stacking|list-style-image|list-style-position|list-style-type|list-style|margin-bottom|margin-left|margin-right|margin-top|margin|mark-after|mark-before|mark|marks|marquee-direction|marquee-play-count|marquee-speed|marquee-style|max-height|max-width|min-height|min-width|move-to|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|orphans|outline-color|outline-offset|outline-style|outline-width|outline|overflow-style|overflow-x|overflow-y|overflow|padding-bottom|padding-left|padding-right|padding-top|padding|page-break-after|page-break-before|page-break-inside|page-policy|page|pause-after|pause-before|pause|perspective-origin|perspective|phonemes|pitch-range|pitch|play-during|pointer-events|position|presentation-level|punctuation-trim|quotes|rendering-intent|resize|rest-after|rest-before|rest|richness|right|rotation-point|rotation|ruby-align|ruby-overhang|ruby-position|ruby-span|size|speak-header|speak-numeral|speak-punctuation|speak|speech-rate|stress|string-set|table-layout|target-name|target-new|target-position|target|text-align-last|text-align|text-decoration|text-emphasis|text-height|text-indent|text-justify|text-outline|text-shadow|text-transform|text-wrap|top|transform-origin|transform-style|transform|transition-delay|transition-duration|transition-property|transition-timing-function|transition|unicode-bidi|vertical-align|visibility|voice-balance|voice-duration|voice-family|voice-pitch-range|voice-pitch|voice-rate|voice-stress|voice-volume|volume|white-space-collapse|white-space|widows|width|word-break|word-spacing|word-wrap|z-index",u=t.supportFunction="rgb|rgba|url|attr|counter|counters",a=t.supportConstant="absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero",f=t.supportConstantColor="aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow",l=t.supportConstantFonts="arial|century|comic|courier|cursive|fantasy|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace",c=t.numRe="\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))",h=t.pseudoElements="(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b",p=t.pseudoClasses="(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b",d=function(){var e=this.createKeywordMapper({"support.function":u,"support.constant":a,"support.type":o,"support.constant.color":f,"support.constant.fonts":l},"text",!0);this.$rules={start:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"@.*?{",push:"media"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],media:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"\\}",next:"pop"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],comment:[{token:"comment",regex:"\\*\\/",next:"pop"},{defaultToken:"comment"}],ruleset:[{token:"paren.rparen",regex:"\\}",next:"pop"},{token:"comment",regex:"\\/\\*",push:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:["constant.numeric","keyword"],regex:"("+c+")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vm|vw|%)"},{token:"constant.numeric",regex:c},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:h},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:p},{token:["support.function","string","support.function"],regex:"(url\\()(.*)(\\))"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"},{caseInsensitive:!0}]},this.normalizeRules()};r.inherits(d,s),t.CssHighlightRules=d}),ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},s.getTagRule(),{defaultToken:"comment.doc",caseInsensitive:!0}]}};r.inherits(s,i),s.getTagRule=function(e){return{token:"comment.doc.tag.storage.type",regex:"\\b(?:TODO|FIXME|XXX|HACK)\\b"}},s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(e){var t=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),n="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",r="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*\\b",s="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[{token:"comment",regex:"\\/\\/",next:"line_comment"},i.getStartRule("doc-start"),{token:"comment",regex:/\/\*/,next:"comment"},{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0[xX][0-9a-fA-F]+\b/},{token:"constant.numeric",regex:/[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+r+")(\\.)(prototype)(\\.)("+r+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+r+")(\\.)("+r+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+r+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+r+")(\\.)("+r+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+r+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+r+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"(?:"+n+")\\b",next:"start"},{token:["punctuation.operator","support.function"],regex:/(\.)(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:["punctuation.operator","support.function.dom"],regex:/(\.)(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName|ClassName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:["punctuation.operator","support.constant"],regex:/(\.)(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:t,regex:r},{token:"keyword.operator",regex:/--|\+\+|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|[!$%&*+\-~\/^]=?/,next:"start"},{token:"punctuation.operator",regex:/[?:,;.]/,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"comment",regex:/^#!.*$/}],start:[i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment_regex_allowed"},{token:"comment",regex:"\\/\\/",next:"line_comment_regex_allowed"},{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.charclass.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:r},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],comment_regex_allowed:[i.getTagRule(),{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment",caseInsensitive:!0}],comment:[i.getTagRule(),{token:"comment",regex:"\\*\\/",next:"no_regex"},{defaultToken:"comment",caseInsensitive:!0}],line_comment_regex_allowed:[i.getTagRule(),{token:"comment",regex:"$|^",next:"start"},{defaultToken:"comment",caseInsensitive:!0}],line_comment:[i.getTagRule(),{token:"comment",regex:"$|^",next:"no_regex"},{defaultToken:"comment",caseInsensitive:!0}],qqstring:[{token:"constant.language.escape",regex:s},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:s},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},(!e||!e.noES6)&&this.$rules.no_regex.unshift({regex:"[{}]",onMatch:function(e,t,n){this.next=e=="{"?this.nextState:"";if(e=="{"&&n.length)return n.unshift("start",t),"paren";if(e=="}"&&n.length){n.shift(),this.next=n.shift();if(this.next.indexOf("string")!=-1)return"paren.quasi.end"}return e=="{"?"paren.lparen":"paren.rparen"},nextState:"start"},{token:"string.quasi.start",regex:/`/,push:[{token:"constant.language.escape",regex:s},{token:"paren.quasi.start",regex:/\${/,push:"start"},{token:"string.quasi.end",regex:/`/,next:"pop"},{defaultToken:"string.quasi"}]}),this.embedRules(i,"doc-",[i.getEndRule("no_regex")]),this.normalizeRules()};r.inherits(o,s),t.JavaScriptHighlightRules=o}),ace.define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(e){var t="[_:a-zA-Z\u00c0-\uffff][-_:.a-zA-Z0-9\u00c0-\uffff]*";this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.xml-decl.xml","keyword.xml-decl.xml"],regex:"(<\\?)(xml)(?=[\\s])",next:"xml_decl",caseInsensitive:!0},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)("+t+")",next:"processing_instruction"},{token:"comment.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"",next:"start"}],processing_instruction:[{token:"punctuation.instruction.xml",regex:"\\?>",next:"start"},{defaultToken:"instruction.xml"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)("+t+")",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.xml",regex:"-->",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:"(?:"+t+":)?"+t+""},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===s&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(i.prototype),r.inherits(s,i),t.XmlHighlightRules=s}),ace.define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./css_highlight_rules").CssHighlightRules,o=e("./javascript_highlight_rules").JavaScriptHighlightRules,u=e("./xml_highlight_rules").XmlHighlightRules,a=i.createMap({a:"anchor",button:"form",form:"form",img:"image",input:"form",label:"form",option:"form",script:"script",select:"form",textarea:"form",style:"style",table:"table",tbody:"table",td:"table",tfoot:"table",th:"table",tr:"table"}),f=function(){u.call(this),this.addRules({attributes:[{include:"tag_whitespace"},{token:"entity.other.attribute-name.xml",regex:"[-_a-zA-Z0-9:.]+"},{token:"keyword.operator.attribute-equals.xml",regex:"=",push:[{include:"tag_whitespace"},{token:"string.unquoted.attribute-value.html",regex:"[^<>='\"`\\s]+",next:"pop"},{token:"empty",regex:"",next:"pop"}]},{include:"attribute_value"}],tag:[{token:function(e,t){var n=a[t];return["meta.tag.punctuation."+(e=="<"?"":"end-")+"tag-open.xml","meta.tag"+(n?"."+n:"")+".tag-name.xml"]},regex:"(",next:"start"}]}),this.embedTagRules(s,"css-","style"),this.embedTagRules(o,"js-","script"),this.constructor===f&&this.normalizeRules()};r.inherits(f,u),t.HtmlHighlightRules=f}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.index,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(e,t,n,r){var i=e.end.row-e.start.row;return{text:n+t+r,selection:[0,e.start.column+1,i,e.end.column+(i?0:1)]}},p=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return h(a,l,"{","}");if(p.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(p.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(p.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var d=u.substring(s.column,s.column+1);if(d=="}"){var v=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(v!==null&&p.isAutoInsertedClosing(s,u,i))return p.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var m="";p.isMaybeInsertedClosing(s,u)&&(m=o.stringRepeat("}",f.maybeInsertedBrackets),p.clearMaybeInsertedClosing());var d=u.substring(s.column,s.column+1);if(d==="}"){var g=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!g)return null;var y=this.$getIndent(r.getLine(g.row))}else{if(!m){p.clearMaybeInsertedClosing();return}var y=this.$getIndent(u)}var b=y+r.getTabString();return{text:"\n"+b+"\n"+y+m,selection:[1,b.length,1,b.length]}}p.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return h(s,o,"(",")");if(p.isSaneInsertion(n,r))return p.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&p.isAutoInsertedClosing(u,a,i))return p.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return h(s,o,"[","]");if(p.isSaneInsertion(n,r))return p.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&p.isAutoInsertedClosing(u,a,i))return p.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return h(o,u,s,s);if(!u){var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column),p=f.substring(a.column,a.column+1),d=r.getTokenAt(a.row,a.column),v=r.getTokenAt(a.row,a.column+1);if(l=="\\"&&d&&/escape/.test(d.type))return null;var m=d&&/string/.test(d.type),g=!v||/string/.test(v.type),y;if(p==s)y=m!==g;else{if(m&&!g)return null;if(m&&g)return null;var b=r.$mode.tokenRe;b.lastIndex=0;var w=b.test(l);b.lastIndex=0;var E=b.test(l);if(w||E)return null;if(p&&!/[\s;,.})\]\\]/.test(p))return null;y=!0}return{text:y?s+s:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};p.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},p.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},p.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},p.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},p.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},p.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},p.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},p.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(p,i),t.CstyleBehaviour=p}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);if(this.singleLineBlockCommentRe.test(r)&&!this.startRegionRe.test(r)&&!this.tripleStarBlockCommentRe.test(r))return"";var i=this._getFoldWidgetBase(e,t,n);return!i&&this.startRegionRe.test(r)?"start":i},this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n);if(this.startRegionRe.test(i))return this.getCommentRegionBlock(e,i,n);var s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++tf)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)},this.getCommentRegionBlock=function(e,t,n){var r=t.search(/\s*$/),s=e.getLength(),o=n,u=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,a=1;while(++no)return new i(o,r,l,t.length)}}.call(o.prototype)}),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./javascript_highlight_rules").JavaScriptHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../range").Range,a=e("../worker/worker_client").WorkerClient,f=e("./behaviour/cstyle").CstyleBehaviour,l=e("./folding/cstyle").FoldMode,c=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new f,this.foldingRules=new l};r.inherits(c,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"||e=="no_regex"){var u=t.match(/^.*(?:\bcase\b.*\:|[\{\(\[])\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start"||o=="no_regex")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new a(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("annotate",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/javascript"}.call(c.prototype),t.Mode=c}),ace.define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("./cstyle").CstyleBehaviour,o=e("../../token_iterator").TokenIterator,u=function(){this.inherit(s),this.add("colon","insertion",function(e,t,n,r,i){if(i===":"){var s=n.getCursorPosition(),u=new o(r,s.row,s.column),a=u.getCurrentToken();a&&a.value.match(/\s+/)&&(a=u.stepBackward());if(a&&a.type==="support.type"){var f=r.doc.getLine(s.row),l=f.substring(s.column,s.column+1);if(l===":")return{text:"",selection:[1,1]};if(!f.substring(s.column).match(/^\s*;/))return{text:":;",selection:[1,1]}}}}),this.add("colon","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s===":"){var u=n.getCursorPosition(),a=new o(r,u.row,u.column),f=a.getCurrentToken();f&&f.value.match(/\s+/)&&(f=a.stepBackward());if(f&&f.type==="support.type"){var l=r.doc.getLine(i.start.row),c=l.substring(i.end.column,i.end.column+1);if(c===";")return i.end.column++,i}}}),this.add("semicolon","insertion",function(e,t,n,r,i){if(i===";"){var s=n.getCursorPosition(),o=r.doc.getLine(s.row),u=o.substring(s.column,s.column+1);if(u===";")return{text:"",selection:[1,1]}}})};r.inherits(u,s),t.CssBehaviour=u}),ace.define("ace/mode/css",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/css","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./css_highlight_rules").CssHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../worker/worker_client").WorkerClient,a=e("./behaviour/css").CssBehaviour,f=e("./folding/cstyle").FoldMode,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new a,this.foldingRules=new f};r.inherits(l,i),function(){this.foldingRules="cStyle",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e).tokens;if(i.length&&i[i.length-1].type=="comment")return r;var s=t.match(/^.*\{\s*$/);return s&&(r+=n),r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new u(["ace"],"ace/mode/css_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("annotate",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/css"}.call(l.prototype),t.Mode=l}),ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";function u(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),a=function(){this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){var o=i,a=r.doc.getTextRange(n.getSelectionRange());if(a!==""&&a!=="'"&&a!='"'&&n.getWrapBehavioursEnabled())return{text:o+a+o,selection:!1};var f=n.getCursorPosition(),l=r.doc.getLine(f.row),c=l.substring(f.column,f.column+1),h=new s(r,f.row,f.column),p=h.getCurrentToken();if(c==o&&(u(p,"attribute-value")||u(p,"string")))return{text:"",selection:[1,1]};p||(p=h.stepBackward());if(!p)return;while(u(p,"tag-whitespace")||u(p,"whitespace"))p=h.stepBackward();var d=!c||c.match(/\s/);if(u(p,"attribute-equals")&&(d||c==">")||u(p,"decl-attribute-equals")&&(d||c=="?"))return{text:o+o,selection:[1,1]}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}}),this.add("autoclosing","insertion",function(e,t,n,r,i){if(i==">"){var o=n.getCursorPosition(),a=new s(r,o.row,o.column),f=a.getCurrentToken()||a.stepBackward();if(!f||!(u(f,"tag-name")||u(f,"tag-whitespace")||u(f,"attribute-name")||u(f,"attribute-equals")||u(f,"attribute-value")))return;if(u(f,"reference.attribute-value"))return;if(u(f,"attribute-value")){var l=f.value.charAt(0);if(l=='"'||l=="'"){var c=f.value.charAt(f.value.length-1),h=a.getCurrentTokenColumn()+f.value.length;if(h>o.column||h==o.column&&l!=c)return}}while(!u(f,"tag-name"))f=a.stepBackward();var p=a.getCurrentTokenRow(),d=a.getCurrentTokenColumn();if(u(a.stepBackward(),"end-tag-open"))return;var v=f.value;p==o.row&&(v=v.substring(0,o.column-d));if(this.voidElements.hasOwnProperty(v.toLowerCase()))return;return{text:">",selection:[1,1]}}}),this.add("autoindent","insertion",function(e,t,n,r,i){if(i=="\n"){var o=n.getCursorPosition(),u=r.getLine(o.row),a=new s(r,o.row,o.column),f=a.getCurrentToken();if(f&&f.type.indexOf("tag-close")!==-1){if(f.value=="/>")return;while(f&&f.type.indexOf("tag-name")===-1)f=a.stepBackward();if(!f)return;var l=f.value,c=a.getCurrentTokenRow();f=a.stepBackward();if(!f||f.type.indexOf("end-tag")!==-1)return;if(this.voidElements&&!this.voidElements[l]){var h=r.getTokenAt(o.row,o.column+1),u=r.getLine(c),p=this.$getIndent(u),d=p+r.getTabString();return h&&h.value==="-1}var r=e("../../lib/oop"),i=e("../../lib/lang"),s=e("../../range").Range,o=e("./fold_mode").FoldMode,u=e("../../token_iterator").TokenIterator,a=t.FoldMode=function(e,t){o.call(this),this.voidElements=e||{},this.optionalEndTags=r.mixin({},this.voidElements),t&&r.mixin(this.optionalEndTags,t)};r.inherits(a,o);var f=function(){this.tagName="",this.closing=!1,this.selfClosing=!1,this.start={row:0,column:0},this.end={row:0,column:0}};(function(){this.getFoldWidget=function(e,t,n){var r=this._getFirstTagInLine(e,n);return r?r.closing||!r.tagName&&r.selfClosing?t=="markbeginend"?"end":"":!r.tagName||r.selfClosing||this.voidElements.hasOwnProperty(r.tagName.toLowerCase())?"":this._findEndTagInLine(e,n,r.tagName,r.end.column)?"":"start":""},this._getFirstTagInLine=function(e,t){var n=e.getTokens(t),r=new f;for(var i=0;i";break}}return r}if(l(s,"tag-close"))return r.selfClosing=s.value=="/>",r;r.start.column+=s.value.length}return null},this._findEndTagInLine=function(e,t,n,r){var i=e.getTokens(t),s=0;for(var o=0;o",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length,e.stepForward(),n;while(t=e.stepForward());return null},this._readTagBackward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do{if(l(t,"tag-open"))return n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn(),e.stepBackward(),n;l(t,"tag-name")?n.tagName=t.value:l(t,"tag-close")&&(n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length)}while(t=e.stepBackward());return null},this._pop=function(e,t){while(e.length){var n=e[e.length-1];if(!t||n.tagName==t.tagName)return e.pop();if(this.optionalEndTags.hasOwnProperty(n.tagName)){e.pop();continue}return null}},this.getFoldWidgetRange=function(e,t,n){var r=this._getFirstTagInLine(e,n);if(!r)return null;var i=r.closing||r.selfClosing,o=[],a;if(!i){var f=new u(e,n,r.start.column),l={row:n,column:r.start.column+r.tagName.length+2};r.start.row==r.end.row&&(l.column=r.end.column);while(a=this._readTagForward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(a.closing){this._pop(o,a);if(o.length==0)return s.fromPoints(l,a.start)}else o.push(a)}}else{var f=new u(e,n,r.end.column),c={row:n,column:r.start.column};while(a=this._readTagBackward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(!a.closing){this._pop(o,a);if(o.length==0)return a.start.column+=a.tagName.length+2,a.start.row==a.end.row&&a.start.column-1}function l(e,t){var n=new r(e,t.row,t.column),i=n.getCurrentToken();while(i&&!f(i,"tag-name"))i=n.stepBackward();if(i)return i.value}var r=e("../token_iterator").TokenIterator,i=["accesskey","class","contenteditable","contextmenu","dir","draggable","dropzone","hidden","id","inert","itemid","itemprop","itemref","itemscope","itemtype","lang","spellcheck","style","tabindex","title","translate"],s=["onabort","onblur","oncancel","oncanplay","oncanplaythrough","onchange","onclick","onclose","oncontextmenu","oncuechange","ondblclick","ondrag","ondragend","ondragenter","ondragleave","ondragover","ondragstart","ondrop","ondurationchange","onemptied","onended","onerror","onfocus","oninput","oninvalid","onkeydown","onkeypress","onkeyup","onload","onloadeddata","onloadedmetadata","onloadstart","onmousedown","onmousemove","onmouseout","onmouseover","onmouseup","onmousewheel","onpause","onplay","onplaying","onprogress","onratechange","onreset","onscroll","onseeked","onseeking","onselect","onshow","onstalled","onsubmit","onsuspend","ontimeupdate","onvolumechange","onwaiting"],o=i.concat(s),u={html:["manifest"],head:[],title:[],base:["href","target"],link:["href","hreflang","rel","media","type","sizes"],meta:["http-equiv","name","content","charset"],style:["type","media","scoped"],script:["charset","type","src","defer","async"],noscript:["href"],body:["onafterprint","onbeforeprint","onbeforeunload","onhashchange","onmessage","onoffline","onpopstate","onredo","onresize","onstorage","onundo","onunload"],section:[],nav:[],article:["pubdate"],aside:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],header:[],footer:[],address:[],main:[],p:[],hr:[],pre:[],blockquote:["cite"],ol:["start","reversed"],ul:[],li:["value"],dl:[],dt:[],dd:[],figure:[],figcaption:[],div:[],a:["href","target","ping","rel","media","hreflang","type"],em:[],strong:[],small:[],s:[],cite:[],q:["cite"],dfn:[],abbr:[],data:[],time:["datetime"],code:[],"var":[],samp:[],kbd:[],sub:[],sup:[],i:[],b:[],u:[],mark:[],ruby:[],rt:[],rp:[],bdi:[],bdo:[],span:[],br:[],wbr:[],ins:["cite","datetime"],del:["cite","datetime"],img:["alt","src","height","width","usemap","ismap"],iframe:["name","src","height","width","sandbox","seamless"],embed:["src","height","width","type"],object:["param","data","type","height","width","usemap","name","form","classid"],param:["name","value"],video:["src","autobuffer","autoplay","loop","controls","width","height","poster"],audio:["src","autobuffer","autoplay","loop","controls"],source:["src","type","media"],track:["kind","src","srclang","label","default"],canvas:["width","height"],map:["name"],area:["shape","coords","href","hreflang","alt","target","media","rel","ping","type"],svg:[],math:[],table:["summary"],caption:[],colgroup:["span"],col:["span"],tbody:[],thead:[],tfoot:[],tr:[],td:["headers","rowspan","colspan"],th:["headers","rowspan","colspan","scope"],form:["accept-charset","action","autocomplete","enctype","method","name","novalidate","target"],fieldset:["disabled","form","name"],legend:[],label:["form","for"],input:["type","accept","alt","autocomplete","checked","disabled","form","formaction","formenctype","formmethod","formnovalidate","formtarget","height","list","max","maxlength","min","multiple","pattern","placeholder","readonly","required","size","src","step","width","files","value"],button:["autofocus","disabled","form","formaction","formenctype","formmethod","formnovalidate","formtarget","name","value","type"],select:["autofocus","disabled","form","multiple","name","size"],datalist:[],optgroup:["disabled","label"],option:["disabled","selected","label","value"],textarea:["autofocus","disabled","form","maxlength","name","placeholder","readonly","required","rows","cols","wrap"],keygen:["autofocus","challenge","disabled","form","keytype","name"],output:["for","form","name"],progress:["value","max"],meter:["value","min","max","low","high","optimum"],details:["open"],summary:[],command:["type","label","icon","disabled","checked","radiogroup","command"],menu:["type","label"],dialog:["open"]},a=Object.keys(u),c=function(){};(function(){this.getCompletions=function(e,t,n,r){var i=t.getTokenAt(n.row,n.column);return i?f(i,"tag-name")||f(i,"tag-open")||f(i,"end-tag-open")?this.getTagCompletions(e,t,n,r):f(i,"tag-whitespace")||f(i,"attribute-name")?this.getAttributeCompetions(e,t,n,r):[]:[]},this.getTagCompletions=function(e,t,n,r){return a.map(function(e){return{value:e,meta:"tag",score:Number.MAX_VALUE}})},this.getAttributeCompetions=function(e,t,n,r){var i=l(t,n);if(!i)return[];var s=o;return i in u&&(s=s.concat(u[i])),s.map(function(e){return{caption:e,snippet:e+'="$0"',meta:"attribute",score:Number.MAX_VALUE}})}}).call(c.prototype),t.HtmlCompletions=c}),ace.define("ace/mode/html",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/javascript","ace/mode/css","ace/mode/html_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/html","ace/mode/html_completions","ace/worker/worker_client"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text").Mode,o=e("./javascript").Mode,u=e("./css").Mode,a=e("./html_highlight_rules").HtmlHighlightRules,f=e("./behaviour/xml").XmlBehaviour,l=e("./folding/html").FoldMode,c=e("./html_completions").HtmlCompletions,h=e("../worker/worker_client").WorkerClient,p=["area","base","br","col","embed","hr","img","input","keygen","link","meta","menuitem","param","source","track","wbr"],d=["li","dt","dd","p","rt","rp","optgroup","option","colgroup","td","th"],v=function(e){this.fragmentContext=e&&e.fragmentContext,this.HighlightRules=a,this.$behaviour=new f,this.$completer=new c,this.createModeDelegates({"js-":o,"css-":u}),this.foldingRules=new l(this.voidElements,i.arrayToMap(d))};r.inherits(v,s),function(){this.blockComment={start:""},this.voidElements=i.arrayToMap(p),this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.getCompletions=function(e,t,n,r){return this.$completer.getCompletions(e,t,n,r)},this.createWorker=function(e){if(this.constructor!=v)return;var t=new h(["ace"],"ace/mode/html_worker","Worker");return t.attachToDocument(e.getDocument()),this.fragmentContext&&t.call("setOptions",[{context:this.fragmentContext}]),t.on("error",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/html"}.call(v.prototype),t.Mode=v}),ace.define("ace/mode/ruby_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=t.constantOtherSymbol={token:"constant.other.symbol.ruby",regex:"[:](?:[A-Za-z_]|[@$](?=[a-zA-Z0-9_]))[a-zA-Z0-9_]*[!=?]?"},o=t.qString={token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},u=t.qqString={token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},a=t.tString={token:"string",regex:"[`](?:(?:\\\\.)|(?:[^'\\\\]))*?[`]"},f=t.constantNumericHex={token:"constant.numeric",regex:"0[xX][0-9a-fA-F](?:[0-9a-fA-F]|_(?=[0-9a-fA-F]))*\\b"},l=t.constantNumericFloat={token:"constant.numeric",regex:"[+-]?\\d(?:\\d|_(?=\\d))*(?:(?:\\.\\d(?:\\d|_(?=\\d))*)?(?:[eE][+-]?\\d+)?)?\\b"},c=function(){var e="abort|Array|assert|assert_equal|assert_not_equal|assert_same|assert_not_same|assert_nil|assert_not_nil|assert_match|assert_no_match|assert_in_delta|assert_throws|assert_raise|assert_nothing_raised|assert_instance_of|assert_kind_of|assert_respond_to|assert_operator|assert_send|assert_difference|assert_no_difference|assert_recognizes|assert_generates|assert_response|assert_redirected_to|assert_template|assert_select|assert_select_email|assert_select_rjs|assert_select_encoded|css_select|at_exit|attr|attr_writer|attr_reader|attr_accessor|attr_accessible|autoload|binding|block_given?|callcc|caller|catch|chomp|chomp!|chop|chop!|defined?|delete_via_redirect|eval|exec|exit|exit!|fail|Float|flunk|follow_redirect!|fork|form_for|form_tag|format|gets|global_variables|gsub|gsub!|get_via_redirect|host!|https?|https!|include|Integer|lambda|link_to|link_to_unless_current|link_to_function|link_to_remote|load|local_variables|loop|open|open_session|p|print|printf|proc|putc|puts|post_via_redirect|put_via_redirect|raise|rand|raw|readline|readlines|redirect?|request_via_redirect|require|scan|select|set_trace_func|sleep|split|sprintf|srand|String|stylesheet_link_tag|syscall|system|sub|sub!|test|throw|trace_var|trap|untrace_var|atan2|cos|exp|frexp|ldexp|log|log10|sin|sqrt|tan|render|javascript_include_tag|csrf_meta_tag|label_tag|text_field_tag|submit_tag|check_box_tag|content_tag|radio_button_tag|text_area_tag|password_field_tag|hidden_field_tag|fields_for|select_tag|options_for_select|options_from_collection_for_select|collection_select|time_zone_select|select_date|select_time|select_datetime|date_select|time_select|datetime_select|select_year|select_month|select_day|select_hour|select_minute|select_second|file_field_tag|file_field|respond_to|skip_before_action|around_filter|after_filter|verify|protect_from_forgery|rescue_from|helper_method|redirect_to|before_action|send_data|send_file|validates_presence_of|validates_uniqueness_of|validates_length_of|validates_format_of|validates_acceptance_of|validates_associated|validates_exclusion_of|validates_inclusion_of|validates_numericality_of|validates_with|validates_each|authenticate_or_request_with_http_basic|authenticate_or_request_with_http_digest|filter_parameter_logging|match|get|post|resources|redirect|scope|assert_routing|translate|localize|extract_locale_from_tld|caches_page|expire_page|caches_action|expire_action|cache|expire_fragment|expire_cache_for|observe|cache_sweeper|has_many|has_one|belongs_to|has_and_belongs_to_many",t="alias|and|BEGIN|begin|break|case|class|def|defined|do|else|elsif|END|end|ensure|__FILE__|finally|for|gem|if|in|__LINE__|module|next|not|or|private|protected|public|redo|rescue|retry|return|super|then|undef|unless|until|when|while|yield",n="true|TRUE|false|FALSE|nil|NIL|ARGF|ARGV|DATA|ENV|RUBY_PLATFORM|RUBY_RELEASE_DATE|RUBY_VERSION|STDERR|STDIN|STDOUT|TOPLEVEL_BINDING",r="$DEBUG|$defout|$FILENAME|$LOAD_PATH|$SAFE|$stdin|$stdout|$stderr|$VERBOSE|$!|root_url|flash|session|cookies|params|request|response|logger|self",i=this.$keywords=this.createKeywordMapper({keyword:t,"constant.language":n,"variable.language":r,"support.function":e,"invalid.deprecated":"debugger"},"identifier");this.$rules={start:[{token:"comment",regex:"#.*$"},{token:"comment",regex:"^=begin(?:$|\\s.*$)",next:"comment"},{token:"string.regexp",regex:"[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/]\\w*\\s*(?=[).,;]|$)"},[{regex:"[{}]",onMatch:function(e,t,n){this.next=e=="{"?this.nextState:"";if(e=="{"&&n.length)return n.unshift("start",t),"paren.lparen";if(e=="}"&&n.length){n.shift(),this.next=n.shift();if(this.next.indexOf("string")!=-1)return"paren.end"}return e=="{"?"paren.lparen":"paren.rparen"},nextState:"start"},{token:"string.start",regex:/"/,push:[{token:"constant.language.escape",regex:/\\(?:[nsrtvfbae'"\\]|c.|C-.|M-.(?:\\C-.)?|[0-7]{3}|x[\da-fA-F]{2}|u[\da-fA-F]{4})/},{token:"paren.start",regex:/\#{/,push:"start"},{token:"string.end",regex:/"/,next:"pop"},{defaultToken:"string"}]},{token:"string.start",regex:/`/,push:[{token:"constant.language.escape",regex:/\\(?:[nsrtvfbae'"\\]|c.|C-.|M-.(?:\\C-.)?|[0-7]{3}|x[\da-fA-F]{2}|u[\da-fA-F]{4})/},{token:"paren.start",regex:/\#{/,push:"start"},{token:"string.end",regex:/`/,next:"pop"},{defaultToken:"string"}]},{token:"string.start",regex:/'/,push:[{token:"constant.language.escape",regex:/\\['\\]/},{token:"string.end",regex:/'/,next:"pop"},{defaultToken:"string"}]}],{token:"text",regex:"::"},{token:"variable.instance",regex:"@{1,2}[a-zA-Z_\\d]+"},{token:"support.class",regex:"[A-Z][a-zA-Z_\\d]+"},s,f,l,{token:"constant.language.boolean",regex:"(?:true|false)\\b"},{token:i,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"punctuation.separator.key-value",regex:"=>"},{stateName:"heredoc",onMatch:function(e,t,n){var r=e[2]=="-"?"indentedHeredoc":"heredoc",i=e.split(this.splitRegex);return n.push(r,i[3]),[{type:"constant",value:i[1]},{type:"string",value:i[2]},{type:"support.class",value:i[3]},{type:"string",value:i[4]}]},regex:"(<<-?)(['\"`]?)([\\w]+)(['\"`]?)",rules:{heredoc:[{onMatch:function(e,t,n){return e===n[1]?(n.shift(),n.shift(),this.next=n[0]||"start","support.class"):(this.next="","string")},regex:".*$",next:"start"}],indentedHeredoc:[{token:"string",regex:"^ +"},{onMatch:function(e,t,n){return e===n[1]?(n.shift(),n.shift(),this.next=n[0]||"start","support.class"):(this.next="","string")},regex:".*$",next:"start"}]}},{regex:"$",token:"empty",next:function(e,t){return t[0]==="heredoc"||t[0]==="indentedHeredoc"?t[0]:e}},{token:"string.character",regex:"\\B\\?."},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:"^=end(?:$|\\s.*$)",next:"start"},{token:"comment",regex:".+"}]},this.normalizeRules()};r.inherits(c,i),t.RubyHighlightRules=c}),ace.define("ace/mode/folding/coffee",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=e("../../range").Range,o=t.FoldMode=function(){};r.inherits(o,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=this.indentationBlock(e,n);if(r)return r;var i=/\S/,o=e.getLine(n),u=o.search(i);if(u==-1||o[u]!="#")return;var a=o.length,f=e.getLength(),l=n,c=n;while(++nl){var p=e.getLine(c).length;return new s(l,a,c,p)}},this.getFoldWidget=function(e,t,n){var r=e.getLine(n),i=r.search(/\S/),s=e.getLine(n+1),o=e.getLine(n-1),u=o.search(/\S/),a=s.search(/\S/);if(i==-1)return e.foldWidgets[n-1]=u!=-1&&u|\\?>|}})");for(var n in this.$rules)this.$rules[n].unshift({token:"markup.list.meta.tag",regex:e+"(?![>}])[-=]?",push:"ejs-start"});this.embedRules(s,"ejs-"),this.$rules["ejs-start"].unshift({token:"markup.list.meta.tag",regex:"-?"+t,next:"pop"},{token:"comment",regex:"//.*?"+t,next:"pop"}),this.$rules["ejs-no_regex"].unshift({token:"markup.list.meta.tag",regex:"-?"+t,next:"pop"},{token:"comment",regex:"//.*?"+t,next:"pop"}),this.normalizeRules()};r.inherits(o,i),t.EjsHighlightRules=o;var r=e("../lib/oop"),u=e("./html").Mode,a=e("./javascript").Mode,f=e("./css").Mode,l=e("./ruby").Mode,c=function(){u.call(this),this.HighlightRules=o,this.createModeDelegates({"js-":a,"css-":f,"ejs-":a})};r.inherits(c,u),function(){this.$id="ace/mode/ejs"}.call(c.prototype),t.Mode=c}) \ No newline at end of file diff --git a/public/javascripts/ace/mode-haml.js b/public/javascripts/ace/mode-haml.js index 1952632df07..225b778fd67 100644 --- a/public/javascripts/ace/mode-haml.js +++ b/public/javascripts/ace/mode-haml.js @@ -1 +1 @@ -ace.define("ace/mode/ruby_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=t.constantOtherSymbol={token:"constant.other.symbol.ruby",regex:"[:](?:[A-Za-z_]|[@$](?=[a-zA-Z0-9_]))[a-zA-Z0-9_]*[!=?]?"},o=t.qString={token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},u=t.qqString={token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},a=t.tString={token:"string",regex:"[`](?:(?:\\\\.)|(?:[^'\\\\]))*?[`]"},f=t.constantNumericHex={token:"constant.numeric",regex:"0[xX][0-9a-fA-F](?:[0-9a-fA-F]|_(?=[0-9a-fA-F]))*\\b"},l=t.constantNumericFloat={token:"constant.numeric",regex:"[+-]?\\d(?:\\d|_(?=\\d))*(?:(?:\\.\\d(?:\\d|_(?=\\d))*)?(?:[eE][+-]?\\d+)?)?\\b"},c=function(){var e="abort|Array|assert|assert_equal|assert_not_equal|assert_same|assert_not_same|assert_nil|assert_not_nil|assert_match|assert_no_match|assert_in_delta|assert_throws|assert_raise|assert_nothing_raised|assert_instance_of|assert_kind_of|assert_respond_to|assert_operator|assert_send|assert_difference|assert_no_difference|assert_recognizes|assert_generates|assert_response|assert_redirected_to|assert_template|assert_select|assert_select_email|assert_select_rjs|assert_select_encoded|css_select|at_exit|attr|attr_writer|attr_reader|attr_accessor|attr_accessible|autoload|binding|block_given?|callcc|caller|catch|chomp|chomp!|chop|chop!|defined?|delete_via_redirect|eval|exec|exit|exit!|fail|Float|flunk|follow_redirect!|fork|form_for|form_tag|format|gets|global_variables|gsub|gsub!|get_via_redirect|host!|https?|https!|include|Integer|lambda|link_to|link_to_unless_current|link_to_function|link_to_remote|load|local_variables|loop|open|open_session|p|print|printf|proc|putc|puts|post_via_redirect|put_via_redirect|raise|rand|raw|readline|readlines|redirect?|request_via_redirect|require|scan|select|set_trace_func|sleep|split|sprintf|srand|String|stylesheet_link_tag|syscall|system|sub|sub!|test|throw|trace_var|trap|untrace_var|atan2|cos|exp|frexp|ldexp|log|log10|sin|sqrt|tan|render|javascript_include_tag|csrf_meta_tag|label_tag|text_field_tag|submit_tag|check_box_tag|content_tag|radio_button_tag|text_area_tag|password_field_tag|hidden_field_tag|fields_for|select_tag|options_for_select|options_from_collection_for_select|collection_select|time_zone_select|select_date|select_time|select_datetime|date_select|time_select|datetime_select|select_year|select_month|select_day|select_hour|select_minute|select_second|file_field_tag|file_field|respond_to|skip_before_filter|around_filter|after_filter|verify|protect_from_forgery|rescue_from|helper_method|redirect_to|before_filter|send_data|send_file|validates_presence_of|validates_uniqueness_of|validates_length_of|validates_format_of|validates_acceptance_of|validates_associated|validates_exclusion_of|validates_inclusion_of|validates_numericality_of|validates_with|validates_each|authenticate_or_request_with_http_basic|authenticate_or_request_with_http_digest|filter_parameter_logging|match|get|post|resources|redirect|scope|assert_routing|translate|localize|extract_locale_from_tld|caches_page|expire_page|caches_action|expire_action|cache|expire_fragment|expire_cache_for|observe|cache_sweeper|has_many|has_one|belongs_to|has_and_belongs_to_many",t="alias|and|BEGIN|begin|break|case|class|def|defined|do|else|elsif|END|end|ensure|__FILE__|finally|for|gem|if|in|__LINE__|module|next|not|or|private|protected|public|redo|rescue|retry|return|super|then|undef|unless|until|when|while|yield",n="true|TRUE|false|FALSE|nil|NIL|ARGF|ARGV|DATA|ENV|RUBY_PLATFORM|RUBY_RELEASE_DATE|RUBY_VERSION|STDERR|STDIN|STDOUT|TOPLEVEL_BINDING",r="$DEBUG|$defout|$FILENAME|$LOAD_PATH|$SAFE|$stdin|$stdout|$stderr|$VERBOSE|$!|root_url|flash|session|cookies|params|request|response|logger|self",i=this.$keywords=this.createKeywordMapper({keyword:t,"constant.language":n,"variable.language":r,"support.function":e,"invalid.deprecated":"debugger"},"identifier");this.$rules={start:[{token:"comment",regex:"#.*$"},{token:"comment",regex:"^=begin(?:$|\\s.*$)",next:"comment"},{token:"string.regexp",regex:"[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/]\\w*\\s*(?=[).,;]|$)"},[{regex:"[{}]",onMatch:function(e,t,n){this.next=e=="{"?this.nextState:"";if(e=="{"&&n.length)return n.unshift("start",t),"paren.lparen";if(e=="}"&&n.length){n.shift(),this.next=n.shift();if(this.next.indexOf("string")!=-1)return"paren.end"}return e=="{"?"paren.lparen":"paren.rparen"},nextState:"start"},{token:"string.start",regex:/"/,push:[{token:"constant.language.escape",regex:/\\(?:[nsrtvfbae'"\\]|c.|C-.|M-.(?:\\C-.)?|[0-7]{3}|x[\da-fA-F]{2}|u[\da-fA-F]{4})/},{token:"paren.start",regex:/\#{/,push:"start"},{token:"string.end",regex:/"/,next:"pop"},{defaultToken:"string"}]},{token:"string.start",regex:/`/,push:[{token:"constant.language.escape",regex:/\\(?:[nsrtvfbae'"\\]|c.|C-.|M-.(?:\\C-.)?|[0-7]{3}|x[\da-fA-F]{2}|u[\da-fA-F]{4})/},{token:"paren.start",regex:/\#{/,push:"start"},{token:"string.end",regex:/`/,next:"pop"},{defaultToken:"string"}]},{token:"string.start",regex:/'/,push:[{token:"constant.language.escape",regex:/\\['\\]/},{token:"string.end",regex:/'/,next:"pop"},{defaultToken:"string"}]}],{token:"text",regex:"::"},{token:"variable.instance",regex:"@{1,2}[a-zA-Z_\\d]+"},{token:"support.class",regex:"[A-Z][a-zA-Z_\\d]+"},s,f,l,{token:"constant.language.boolean",regex:"(?:true|false)\\b"},{token:i,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"punctuation.separator.key-value",regex:"=>"},{stateName:"heredoc",onMatch:function(e,t,n){var r=e[2]=="-"?"indentedHeredoc":"heredoc",i=e.split(this.splitRegex);return n.push(r,i[3]),[{type:"constant",value:i[1]},{type:"string",value:i[2]},{type:"support.class",value:i[3]},{type:"string",value:i[4]}]},regex:"(<<-?)(['\"`]?)([\\w]+)(['\"`]?)",rules:{heredoc:[{onMatch:function(e,t,n){return e===n[1]?(n.shift(),n.shift(),this.next=n[0]||"start","support.class"):(this.next="","string")},regex:".*$",next:"start"}],indentedHeredoc:[{token:"string",regex:"^ +"},{onMatch:function(e,t,n){return e===n[1]?(n.shift(),n.shift(),this.next=n[0]||"start","support.class"):(this.next="","string")},regex:".*$",next:"start"}]}},{regex:"$",token:"empty",next:function(e,t){return t[0]==="heredoc"||t[0]==="indentedHeredoc"?t[0]:e}},{token:"string.character",regex:"\\B\\?."},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:"^=end(?:$|\\s.*$)",next:"start"},{token:"comment",regex:".+"}]},this.normalizeRules()};r.inherits(c,i),t.RubyHighlightRules=c}),ace.define("ace/mode/haml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules","ace/mode/ruby_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=e("./ruby_highlight_rules"),o=s.RubyHighlightRules,u=function(){this.$rules={start:[{token:"punctuation.section.comment",regex:/^\s*\/.*/},{token:"punctuation.section.comment",regex:/^\s*#.*/},{token:"string.quoted.double",regex:"==.+?=="},{token:"keyword.other.doctype",regex:"^!!!\\s*(?:[a-zA-Z0-9-_]+)?"},s.qString,s.qqString,s.tString,{token:["entity.name.tag.haml"],regex:/^\s*%[\w:]+/,next:"tag_single"},{token:["meta.escape.haml"],regex:"^\\s*\\\\."},s.constantNumericHex,s.constantNumericFloat,s.constantOtherSymbol,{token:"text",regex:"=|-|~",next:"embedded_ruby"}],tag_single:[{token:"entity.other.attribute-name.class.haml",regex:"\\.[\\w-]+"},{token:"entity.other.attribute-name.id.haml",regex:"#[\\w-]+"},{token:"punctuation.section",regex:"\\{",next:"section"},s.constantOtherSymbol,{token:"text",regex:/\s/,next:"start"},{token:"empty",regex:"$|(?!\\.|#|\\{|\\[|=|-|~|\\/)",next:"start"}],section:[s.constantOtherSymbol,s.qString,s.qqString,s.tString,s.constantNumericHex,s.constantNumericFloat,{token:"punctuation.section",regex:"\\}",next:"start"}],embedded_ruby:[s.constantNumericHex,s.constantNumericFloat,{token:"support.class",regex:"[A-Z][a-zA-Z_\\d]+"},{token:(new o).getKeywords(),regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:["keyword","text","text"],regex:"(?:do|\\{)(?: \\|[^|]+\\|)?$",next:"start"},{token:["text"],regex:"^$",next:"start"},{token:["text"],regex:"^(?!.*\\|\\s*$)",next:"start"}]}};r.inherits(u,i),t.HamlHighlightRules=u}),ace.define("ace/mode/folding/coffee",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=e("../../range").Range,o=t.FoldMode=function(){};r.inherits(o,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=this.indentationBlock(e,n);if(r)return r;var i=/\S/,o=e.getLine(n),u=o.search(i);if(u==-1||o[u]!="#")return;var a=o.length,f=e.getLength(),l=n,c=n;while(++nl){var p=e.getLine(c).length;return new s(l,a,c,p)}},this.getFoldWidget=function(e,t,n){var r=e.getLine(n),i=r.search(/\S/),s=e.getLine(n+1),o=e.getLine(n-1),u=o.search(/\S/),a=s.search(/\S/);if(i==-1)return e.foldWidgets[n-1]=u!=-1&&u"},{stateName:"heredoc",onMatch:function(e,t,n){var r=e[2]=="-"?"indentedHeredoc":"heredoc",i=e.split(this.splitRegex);return n.push(r,i[3]),[{type:"constant",value:i[1]},{type:"string",value:i[2]},{type:"support.class",value:i[3]},{type:"string",value:i[4]}]},regex:"(<<-?)(['\"`]?)([\\w]+)(['\"`]?)",rules:{heredoc:[{onMatch:function(e,t,n){return e===n[1]?(n.shift(),n.shift(),this.next=n[0]||"start","support.class"):(this.next="","string")},regex:".*$",next:"start"}],indentedHeredoc:[{token:"string",regex:"^ +"},{onMatch:function(e,t,n){return e===n[1]?(n.shift(),n.shift(),this.next=n[0]||"start","support.class"):(this.next="","string")},regex:".*$",next:"start"}]}},{regex:"$",token:"empty",next:function(e,t){return t[0]==="heredoc"||t[0]==="indentedHeredoc"?t[0]:e}},{token:"string.character",regex:"\\B\\?."},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:"^=end(?:$|\\s.*$)",next:"start"},{token:"comment",regex:".+"}]},this.normalizeRules()};r.inherits(c,i),t.RubyHighlightRules=c}),ace.define("ace/mode/haml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules","ace/mode/ruby_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=e("./ruby_highlight_rules"),o=s.RubyHighlightRules,u=function(){this.$rules={start:[{token:"punctuation.section.comment",regex:/^\s*\/.*/},{token:"punctuation.section.comment",regex:/^\s*#.*/},{token:"string.quoted.double",regex:"==.+?=="},{token:"keyword.other.doctype",regex:"^!!!\\s*(?:[a-zA-Z0-9-_]+)?"},s.qString,s.qqString,s.tString,{token:["entity.name.tag.haml"],regex:/^\s*%[\w:]+/,next:"tag_single"},{token:["meta.escape.haml"],regex:"^\\s*\\\\."},s.constantNumericHex,s.constantNumericFloat,s.constantOtherSymbol,{token:"text",regex:"=|-|~",next:"embedded_ruby"}],tag_single:[{token:"entity.other.attribute-name.class.haml",regex:"\\.[\\w-]+"},{token:"entity.other.attribute-name.id.haml",regex:"#[\\w-]+"},{token:"punctuation.section",regex:"\\{",next:"section"},s.constantOtherSymbol,{token:"text",regex:/\s/,next:"start"},{token:"empty",regex:"$|(?!\\.|#|\\{|\\[|=|-|~|\\/)",next:"start"}],section:[s.constantOtherSymbol,s.qString,s.qqString,s.tString,s.constantNumericHex,s.constantNumericFloat,{token:"punctuation.section",regex:"\\}",next:"start"}],embedded_ruby:[s.constantNumericHex,s.constantNumericFloat,{token:"support.class",regex:"[A-Z][a-zA-Z_\\d]+"},{token:(new o).getKeywords(),regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:["keyword","text","text"],regex:"(?:do|\\{)(?: \\|[^|]+\\|)?$",next:"start"},{token:["text"],regex:"^$",next:"start"},{token:["text"],regex:"^(?!.*\\|\\s*$)",next:"start"}]}};r.inherits(u,i),t.HamlHighlightRules=u}),ace.define("ace/mode/folding/coffee",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=e("../../range").Range,o=t.FoldMode=function(){};r.inherits(o,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=this.indentationBlock(e,n);if(r)return r;var i=/\S/,o=e.getLine(n),u=o.search(i);if(u==-1||o[u]!="#")return;var a=o.length,f=e.getLength(),l=n,c=n;while(++nl){var p=e.getLine(c).length;return new s(l,a,c,p)}},this.getFoldWidget=function(e,t,n){var r=e.getLine(n),i=r.search(/\S/),s=e.getLine(n+1),o=e.getLine(n-1),u=o.search(/\S/),a=s.search(/\S/);if(i==-1)return e.foldWidgets[n-1]=u!=-1&&u=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|[!$%&*+\-~\/^]=?/,next:"start"},{token:"punctuation.operator",regex:/[?:,;.]/,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"comment",regex:/^#!.*$/}],start:[i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment_regex_allowed"},{token:"comment",regex:"\\/\\/",next:"line_comment_regex_allowed"},{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.charclass.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:r},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],comment_regex_allowed:[i.getTagRule(),{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment",caseInsensitive:!0}],comment:[i.getTagRule(),{token:"comment",regex:"\\*\\/",next:"no_regex"},{defaultToken:"comment",caseInsensitive:!0}],line_comment_regex_allowed:[i.getTagRule(),{token:"comment",regex:"$|^",next:"start"},{defaultToken:"comment",caseInsensitive:!0}],line_comment:[i.getTagRule(),{token:"comment",regex:"$|^",next:"no_regex"},{defaultToken:"comment",caseInsensitive:!0}],qqstring:[{token:"constant.language.escape",regex:s},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:s},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},(!e||!e.noES6)&&this.$rules.no_regex.unshift({regex:"[{}]",onMatch:function(e,t,n){this.next=e=="{"?this.nextState:"";if(e=="{"&&n.length)return n.unshift("start",t),"paren";if(e=="}"&&n.length){n.shift(),this.next=n.shift();if(this.next.indexOf("string")!=-1)return"paren.quasi.end"}return e=="{"?"paren.lparen":"paren.rparen"},nextState:"start"},{token:"string.quasi.start",regex:/`/,push:[{token:"constant.language.escape",regex:s},{token:"paren.quasi.start",regex:/\${/,push:"start"},{token:"string.quasi.end",regex:/`/,next:"pop"},{defaultToken:"string.quasi"}]}),this.embedRules(i,"doc-",[i.getEndRule("no_regex")]),this.normalizeRules()};r.inherits(o,s),t.JavaScriptHighlightRules=o}),ace.define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(e){var t="[_:a-zA-Z\u00c0-\uffff][-_:.a-zA-Z0-9\u00c0-\uffff]*";this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.xml-decl.xml","keyword.xml-decl.xml"],regex:"(<\\?)(xml)(?=[\\s])",next:"xml_decl",caseInsensitive:!0},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)("+t+")",next:"processing_instruction"},{token:"comment.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"",next:"start"}],processing_instruction:[{token:"punctuation.instruction.xml",regex:"\\?>",next:"start"},{defaultToken:"instruction.xml"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)("+t+")",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.xml",regex:"-->",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:"(?:"+t+":)?"+t+""},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===s&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(i.prototype),r.inherits(s,i),t.XmlHighlightRules=s}),ace.define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./css_highlight_rules").CssHighlightRules,o=e("./javascript_highlight_rules").JavaScriptHighlightRules,u=e("./xml_highlight_rules").XmlHighlightRules,a=i.createMap({a:"anchor",button:"form",form:"form",img:"image",input:"form",label:"form",option:"form",script:"script",select:"form",textarea:"form",style:"style",table:"table",tbody:"table",td:"table",tfoot:"table",th:"table",tr:"table"}),f=function(){u.call(this),this.addRules({attributes:[{include:"tag_whitespace"},{token:"entity.other.attribute-name.xml",regex:"[-_a-zA-Z0-9:.]+"},{token:"keyword.operator.attribute-equals.xml",regex:"=",push:[{include:"tag_whitespace"},{token:"string.unquoted.attribute-value.html",regex:"[^<>='\"`\\s]+",next:"pop"},{token:"empty",regex:"",next:"pop"}]},{include:"attribute_value"}],tag:[{token:function(e,t){var n=a[t];return["meta.tag.punctuation."+(e=="<"?"":"end-")+"tag-open.xml","meta.tag"+(n?"."+n:"")+".tag-name.xml"]},regex:"(",next:"start"}]}),this.embedTagRules(s,"css-","style"),this.embedTagRules(o,"js-","script"),this.constructor===f&&this.normalizeRules()};r.inherits(f,u),t.HtmlHighlightRules=f}),ace.define("ace/mode/ruby_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=t.constantOtherSymbol={token:"constant.other.symbol.ruby",regex:"[:](?:[A-Za-z_]|[@$](?=[a-zA-Z0-9_]))[a-zA-Z0-9_]*[!=?]?"},o=t.qString={token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},u=t.qqString={token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},a=t.tString={token:"string",regex:"[`](?:(?:\\\\.)|(?:[^'\\\\]))*?[`]"},f=t.constantNumericHex={token:"constant.numeric",regex:"0[xX][0-9a-fA-F](?:[0-9a-fA-F]|_(?=[0-9a-fA-F]))*\\b"},l=t.constantNumericFloat={token:"constant.numeric",regex:"[+-]?\\d(?:\\d|_(?=\\d))*(?:(?:\\.\\d(?:\\d|_(?=\\d))*)?(?:[eE][+-]?\\d+)?)?\\b"},c=function(){var e="abort|Array|assert|assert_equal|assert_not_equal|assert_same|assert_not_same|assert_nil|assert_not_nil|assert_match|assert_no_match|assert_in_delta|assert_throws|assert_raise|assert_nothing_raised|assert_instance_of|assert_kind_of|assert_respond_to|assert_operator|assert_send|assert_difference|assert_no_difference|assert_recognizes|assert_generates|assert_response|assert_redirected_to|assert_template|assert_select|assert_select_email|assert_select_rjs|assert_select_encoded|css_select|at_exit|attr|attr_writer|attr_reader|attr_accessor|attr_accessible|autoload|binding|block_given?|callcc|caller|catch|chomp|chomp!|chop|chop!|defined?|delete_via_redirect|eval|exec|exit|exit!|fail|Float|flunk|follow_redirect!|fork|form_for|form_tag|format|gets|global_variables|gsub|gsub!|get_via_redirect|host!|https?|https!|include|Integer|lambda|link_to|link_to_unless_current|link_to_function|link_to_remote|load|local_variables|loop|open|open_session|p|print|printf|proc|putc|puts|post_via_redirect|put_via_redirect|raise|rand|raw|readline|readlines|redirect?|request_via_redirect|require|scan|select|set_trace_func|sleep|split|sprintf|srand|String|stylesheet_link_tag|syscall|system|sub|sub!|test|throw|trace_var|trap|untrace_var|atan2|cos|exp|frexp|ldexp|log|log10|sin|sqrt|tan|render|javascript_include_tag|csrf_meta_tag|label_tag|text_field_tag|submit_tag|check_box_tag|content_tag|radio_button_tag|text_area_tag|password_field_tag|hidden_field_tag|fields_for|select_tag|options_for_select|options_from_collection_for_select|collection_select|time_zone_select|select_date|select_time|select_datetime|date_select|time_select|datetime_select|select_year|select_month|select_day|select_hour|select_minute|select_second|file_field_tag|file_field|respond_to|skip_before_filter|around_filter|after_filter|verify|protect_from_forgery|rescue_from|helper_method|redirect_to|before_filter|send_data|send_file|validates_presence_of|validates_uniqueness_of|validates_length_of|validates_format_of|validates_acceptance_of|validates_associated|validates_exclusion_of|validates_inclusion_of|validates_numericality_of|validates_with|validates_each|authenticate_or_request_with_http_basic|authenticate_or_request_with_http_digest|filter_parameter_logging|match|get|post|resources|redirect|scope|assert_routing|translate|localize|extract_locale_from_tld|caches_page|expire_page|caches_action|expire_action|cache|expire_fragment|expire_cache_for|observe|cache_sweeper|has_many|has_one|belongs_to|has_and_belongs_to_many",t="alias|and|BEGIN|begin|break|case|class|def|defined|do|else|elsif|END|end|ensure|__FILE__|finally|for|gem|if|in|__LINE__|module|next|not|or|private|protected|public|redo|rescue|retry|return|super|then|undef|unless|until|when|while|yield",n="true|TRUE|false|FALSE|nil|NIL|ARGF|ARGV|DATA|ENV|RUBY_PLATFORM|RUBY_RELEASE_DATE|RUBY_VERSION|STDERR|STDIN|STDOUT|TOPLEVEL_BINDING",r="$DEBUG|$defout|$FILENAME|$LOAD_PATH|$SAFE|$stdin|$stdout|$stderr|$VERBOSE|$!|root_url|flash|session|cookies|params|request|response|logger|self",i=this.$keywords=this.createKeywordMapper({keyword:t,"constant.language":n,"variable.language":r,"support.function":e,"invalid.deprecated":"debugger"},"identifier");this.$rules={start:[{token:"comment",regex:"#.*$"},{token:"comment",regex:"^=begin(?:$|\\s.*$)",next:"comment"},{token:"string.regexp",regex:"[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/]\\w*\\s*(?=[).,;]|$)"},[{regex:"[{}]",onMatch:function(e,t,n){this.next=e=="{"?this.nextState:"";if(e=="{"&&n.length)return n.unshift("start",t),"paren.lparen";if(e=="}"&&n.length){n.shift(),this.next=n.shift();if(this.next.indexOf("string")!=-1)return"paren.end"}return e=="{"?"paren.lparen":"paren.rparen"},nextState:"start"},{token:"string.start",regex:/"/,push:[{token:"constant.language.escape",regex:/\\(?:[nsrtvfbae'"\\]|c.|C-.|M-.(?:\\C-.)?|[0-7]{3}|x[\da-fA-F]{2}|u[\da-fA-F]{4})/},{token:"paren.start",regex:/\#{/,push:"start"},{token:"string.end",regex:/"/,next:"pop"},{defaultToken:"string"}]},{token:"string.start",regex:/`/,push:[{token:"constant.language.escape",regex:/\\(?:[nsrtvfbae'"\\]|c.|C-.|M-.(?:\\C-.)?|[0-7]{3}|x[\da-fA-F]{2}|u[\da-fA-F]{4})/},{token:"paren.start",regex:/\#{/,push:"start"},{token:"string.end",regex:/`/,next:"pop"},{defaultToken:"string"}]},{token:"string.start",regex:/'/,push:[{token:"constant.language.escape",regex:/\\['\\]/},{token:"string.end",regex:/'/,next:"pop"},{defaultToken:"string"}]}],{token:"text",regex:"::"},{token:"variable.instance",regex:"@{1,2}[a-zA-Z_\\d]+"},{token:"support.class",regex:"[A-Z][a-zA-Z_\\d]+"},s,f,l,{token:"constant.language.boolean",regex:"(?:true|false)\\b"},{token:i,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"punctuation.separator.key-value",regex:"=>"},{stateName:"heredoc",onMatch:function(e,t,n){var r=e[2]=="-"?"indentedHeredoc":"heredoc",i=e.split(this.splitRegex);return n.push(r,i[3]),[{type:"constant",value:i[1]},{type:"string",value:i[2]},{type:"support.class",value:i[3]},{type:"string",value:i[4]}]},regex:"(<<-?)(['\"`]?)([\\w]+)(['\"`]?)",rules:{heredoc:[{onMatch:function(e,t,n){return e===n[1]?(n.shift(),n.shift(),this.next=n[0]||"start","support.class"):(this.next="","string")},regex:".*$",next:"start"}],indentedHeredoc:[{token:"string",regex:"^ +"},{onMatch:function(e,t,n){return e===n[1]?(n.shift(),n.shift(),this.next=n[0]||"start","support.class"):(this.next="","string")},regex:".*$",next:"start"}]}},{regex:"$",token:"empty",next:function(e,t){return t[0]==="heredoc"||t[0]==="indentedHeredoc"?t[0]:e}},{token:"string.character",regex:"\\B\\?."},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:"^=end(?:$|\\s.*$)",next:"start"},{token:"comment",regex:".+"}]},this.normalizeRules()};r.inherits(c,i),t.RubyHighlightRules=c}),ace.define("ace/mode/html_ruby_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/html_highlight_rules","ace/mode/ruby_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./html_highlight_rules").HtmlHighlightRules,s=e("./ruby_highlight_rules").RubyHighlightRules,o=function(){i.call(this);var e=[{regex:"<%%|%%>",token:"constant.language.escape"},{token:"comment.start.erb",regex:"<%#",push:[{token:"comment.end.erb",regex:"%>",next:"pop",defaultToken:"comment"}]},{token:"support.ruby_tag",regex:"<%+(?!>)[-=]?",push:"ruby-start"}],t=[{token:"support.ruby_tag",regex:"%>",next:"pop"},{token:"comment",regex:"#(?:[^%]|%[^>])*"}];for(var n in this.$rules)this.$rules[n].unshift.apply(this.$rules[n],e);this.embedRules(s,"ruby-",t,["start"]),this.normalizeRules()};r.inherits(o,i),t.HtmlRubyHighlightRules=o}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.index,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(e,t,n,r){var i=e.end.row-e.start.row;return{text:n+t+r,selection:[0,e.start.column+1,i,e.end.column+(i?0:1)]}},p=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return h(a,l,"{","}");if(p.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(p.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(p.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var d=u.substring(s.column,s.column+1);if(d=="}"){var v=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(v!==null&&p.isAutoInsertedClosing(s,u,i))return p.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var m="";p.isMaybeInsertedClosing(s,u)&&(m=o.stringRepeat("}",f.maybeInsertedBrackets),p.clearMaybeInsertedClosing());var d=u.substring(s.column,s.column+1);if(d==="}"){var g=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!g)return null;var y=this.$getIndent(r.getLine(g.row))}else{if(!m){p.clearMaybeInsertedClosing();return}var y=this.$getIndent(u)}var b=y+r.getTabString();return{text:"\n"+b+"\n"+y+m,selection:[1,b.length,1,b.length]}}p.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return h(s,o,"(",")");if(p.isSaneInsertion(n,r))return p.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&p.isAutoInsertedClosing(u,a,i))return p.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return h(s,o,"[","]");if(p.isSaneInsertion(n,r))return p.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&p.isAutoInsertedClosing(u,a,i))return p.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return h(o,u,s,s);if(!u){var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column),p=f.substring(a.column,a.column+1),d=r.getTokenAt(a.row,a.column),v=r.getTokenAt(a.row,a.column+1);if(l=="\\"&&d&&/escape/.test(d.type))return null;var m=d&&/string/.test(d.type),g=!v||/string/.test(v.type),y;if(p==s)y=m!==g;else{if(m&&!g)return null;if(m&&g)return null;var b=r.$mode.tokenRe;b.lastIndex=0;var w=b.test(l);b.lastIndex=0;var E=b.test(l);if(w||E)return null;if(p&&!/[\s;,.})\]\\]/.test(p))return null;y=!0}return{text:y?s+s:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};p.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},p.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},p.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},p.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},p.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},p.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},p.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},p.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(p,i),t.CstyleBehaviour=p}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);if(this.singleLineBlockCommentRe.test(r)&&!this.startRegionRe.test(r)&&!this.tripleStarBlockCommentRe.test(r))return"";var i=this._getFoldWidgetBase(e,t,n);return!i&&this.startRegionRe.test(r)?"start":i},this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n);if(this.startRegionRe.test(i))return this.getCommentRegionBlock(e,i,n);var s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++tf)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)},this.getCommentRegionBlock=function(e,t,n){var r=t.search(/\s*$/),s=e.getLength(),o=n,u=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,a=1;while(++no)return new i(o,r,l,t.length)}}.call(o.prototype)}),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./javascript_highlight_rules").JavaScriptHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../range").Range,a=e("../worker/worker_client").WorkerClient,f=e("./behaviour/cstyle").CstyleBehaviour,l=e("./folding/cstyle").FoldMode,c=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new f,this.foldingRules=new l};r.inherits(c,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"||e=="no_regex"){var u=t.match(/^.*(?:\bcase\b.*\:|[\{\(\[])\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start"||o=="no_regex")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new a(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("annotate",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/javascript"}.call(c.prototype),t.Mode=c}),ace.define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("./cstyle").CstyleBehaviour,o=e("../../token_iterator").TokenIterator,u=function(){this.inherit(s),this.add("colon","insertion",function(e,t,n,r,i){if(i===":"){var s=n.getCursorPosition(),u=new o(r,s.row,s.column),a=u.getCurrentToken();a&&a.value.match(/\s+/)&&(a=u.stepBackward());if(a&&a.type==="support.type"){var f=r.doc.getLine(s.row),l=f.substring(s.column,s.column+1);if(l===":")return{text:"",selection:[1,1]};if(!f.substring(s.column).match(/^\s*;/))return{text:":;",selection:[1,1]}}}}),this.add("colon","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s===":"){var u=n.getCursorPosition(),a=new o(r,u.row,u.column),f=a.getCurrentToken();f&&f.value.match(/\s+/)&&(f=a.stepBackward());if(f&&f.type==="support.type"){var l=r.doc.getLine(i.start.row),c=l.substring(i.end.column,i.end.column+1);if(c===";")return i.end.column++,i}}}),this.add("semicolon","insertion",function(e,t,n,r,i){if(i===";"){var s=n.getCursorPosition(),o=r.doc.getLine(s.row),u=o.substring(s.column,s.column+1);if(u===";")return{text:"",selection:[1,1]}}})};r.inherits(u,s),t.CssBehaviour=u}),ace.define("ace/mode/css",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/css","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./css_highlight_rules").CssHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../worker/worker_client").WorkerClient,a=e("./behaviour/css").CssBehaviour,f=e("./folding/cstyle").FoldMode,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new a,this.foldingRules=new f};r.inherits(l,i),function(){this.foldingRules="cStyle",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e).tokens;if(i.length&&i[i.length-1].type=="comment")return r;var s=t.match(/^.*\{\s*$/);return s&&(r+=n),r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new u(["ace"],"ace/mode/css_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("annotate",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/css"}.call(l.prototype),t.Mode=l}),ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";function u(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),a=function(){this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){var o=i,a=r.doc.getTextRange(n.getSelectionRange());if(a!==""&&a!=="'"&&a!='"'&&n.getWrapBehavioursEnabled())return{text:o+a+o,selection:!1};var f=n.getCursorPosition(),l=r.doc.getLine(f.row),c=l.substring(f.column,f.column+1),h=new s(r,f.row,f.column),p=h.getCurrentToken();if(c==o&&(u(p,"attribute-value")||u(p,"string")))return{text:"",selection:[1,1]};p||(p=h.stepBackward());if(!p)return;while(u(p,"tag-whitespace")||u(p,"whitespace"))p=h.stepBackward();var d=!c||c.match(/\s/);if(u(p,"attribute-equals")&&(d||c==">")||u(p,"decl-attribute-equals")&&(d||c=="?"))return{text:o+o,selection:[1,1]}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}}),this.add("autoclosing","insertion",function(e,t,n,r,i){if(i==">"){var o=n.getCursorPosition(),a=new s(r,o.row,o.column),f=a.getCurrentToken()||a.stepBackward();if(!f||!(u(f,"tag-name")||u(f,"tag-whitespace")||u(f,"attribute-name")||u(f,"attribute-equals")||u(f,"attribute-value")))return;if(u(f,"reference.attribute-value"))return;if(u(f,"attribute-value")){var l=f.value.charAt(0);if(l=='"'||l=="'"){var c=f.value.charAt(f.value.length-1),h=a.getCurrentTokenColumn()+f.value.length;if(h>o.column||h==o.column&&l!=c)return}}while(!u(f,"tag-name"))f=a.stepBackward();var p=a.getCurrentTokenRow(),d=a.getCurrentTokenColumn();if(u(a.stepBackward(),"end-tag-open"))return;var v=f.value;p==o.row&&(v=v.substring(0,o.column-d));if(this.voidElements.hasOwnProperty(v.toLowerCase()))return;return{text:">",selection:[1,1]}}}),this.add("autoindent","insertion",function(e,t,n,r,i){if(i=="\n"){var o=n.getCursorPosition(),u=r.getLine(o.row),a=new s(r,o.row,o.column),f=a.getCurrentToken();if(f&&f.type.indexOf("tag-close")!==-1){if(f.value=="/>")return;while(f&&f.type.indexOf("tag-name")===-1)f=a.stepBackward();if(!f)return;var l=f.value,c=a.getCurrentTokenRow();f=a.stepBackward();if(!f||f.type.indexOf("end-tag")!==-1)return;if(this.voidElements&&!this.voidElements[l]){var h=r.getTokenAt(o.row,o.column+1),u=r.getLine(c),p=this.$getIndent(u),d=p+r.getTabString();return h&&h.value==="-1}var r=e("../../lib/oop"),i=e("../../lib/lang"),s=e("../../range").Range,o=e("./fold_mode").FoldMode,u=e("../../token_iterator").TokenIterator,a=t.FoldMode=function(e,t){o.call(this),this.voidElements=e||{},this.optionalEndTags=r.mixin({},this.voidElements),t&&r.mixin(this.optionalEndTags,t)};r.inherits(a,o);var f=function(){this.tagName="",this.closing=!1,this.selfClosing=!1,this.start={row:0,column:0},this.end={row:0,column:0}};(function(){this.getFoldWidget=function(e,t,n){var r=this._getFirstTagInLine(e,n);return r?r.closing||!r.tagName&&r.selfClosing?t=="markbeginend"?"end":"":!r.tagName||r.selfClosing||this.voidElements.hasOwnProperty(r.tagName.toLowerCase())?"":this._findEndTagInLine(e,n,r.tagName,r.end.column)?"":"start":""},this._getFirstTagInLine=function(e,t){var n=e.getTokens(t),r=new f;for(var i=0;i";break}}return r}if(l(s,"tag-close"))return r.selfClosing=s.value=="/>",r;r.start.column+=s.value.length}return null},this._findEndTagInLine=function(e,t,n,r){var i=e.getTokens(t),s=0;for(var o=0;o",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length,e.stepForward(),n;while(t=e.stepForward());return null},this._readTagBackward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do{if(l(t,"tag-open"))return n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn(),e.stepBackward(),n;l(t,"tag-name")?n.tagName=t.value:l(t,"tag-close")&&(n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length)}while(t=e.stepBackward());return null},this._pop=function(e,t){while(e.length){var n=e[e.length-1];if(!t||n.tagName==t.tagName)return e.pop();if(this.optionalEndTags.hasOwnProperty(n.tagName)){e.pop();continue}return null}},this.getFoldWidgetRange=function(e,t,n){var r=this._getFirstTagInLine(e,n);if(!r)return null;var i=r.closing||r.selfClosing,o=[],a;if(!i){var f=new u(e,n,r.start.column),l={row:n,column:r.start.column+r.tagName.length+2};r.start.row==r.end.row&&(l.column=r.end.column);while(a=this._readTagForward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(a.closing){this._pop(o,a);if(o.length==0)return s.fromPoints(l,a.start)}else o.push(a)}}else{var f=new u(e,n,r.end.column),c={row:n,column:r.start.column};while(a=this._readTagBackward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(!a.closing){this._pop(o,a);if(o.length==0)return a.start.column+=a.tagName.length+2,a.start.row==a.end.row&&a.start.column-1}function l(e,t){var n=new r(e,t.row,t.column),i=n.getCurrentToken();while(i&&!f(i,"tag-name"))i=n.stepBackward();if(i)return i.value}var r=e("../token_iterator").TokenIterator,i=["accesskey","class","contenteditable","contextmenu","dir","draggable","dropzone","hidden","id","inert","itemid","itemprop","itemref","itemscope","itemtype","lang","spellcheck","style","tabindex","title","translate"],s=["onabort","onblur","oncancel","oncanplay","oncanplaythrough","onchange","onclick","onclose","oncontextmenu","oncuechange","ondblclick","ondrag","ondragend","ondragenter","ondragleave","ondragover","ondragstart","ondrop","ondurationchange","onemptied","onended","onerror","onfocus","oninput","oninvalid","onkeydown","onkeypress","onkeyup","onload","onloadeddata","onloadedmetadata","onloadstart","onmousedown","onmousemove","onmouseout","onmouseover","onmouseup","onmousewheel","onpause","onplay","onplaying","onprogress","onratechange","onreset","onscroll","onseeked","onseeking","onselect","onshow","onstalled","onsubmit","onsuspend","ontimeupdate","onvolumechange","onwaiting"],o=i.concat(s),u={html:["manifest"],head:[],title:[],base:["href","target"],link:["href","hreflang","rel","media","type","sizes"],meta:["http-equiv","name","content","charset"],style:["type","media","scoped"],script:["charset","type","src","defer","async"],noscript:["href"],body:["onafterprint","onbeforeprint","onbeforeunload","onhashchange","onmessage","onoffline","onpopstate","onredo","onresize","onstorage","onundo","onunload"],section:[],nav:[],article:["pubdate"],aside:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],header:[],footer:[],address:[],main:[],p:[],hr:[],pre:[],blockquote:["cite"],ol:["start","reversed"],ul:[],li:["value"],dl:[],dt:[],dd:[],figure:[],figcaption:[],div:[],a:["href","target","ping","rel","media","hreflang","type"],em:[],strong:[],small:[],s:[],cite:[],q:["cite"],dfn:[],abbr:[],data:[],time:["datetime"],code:[],"var":[],samp:[],kbd:[],sub:[],sup:[],i:[],b:[],u:[],mark:[],ruby:[],rt:[],rp:[],bdi:[],bdo:[],span:[],br:[],wbr:[],ins:["cite","datetime"],del:["cite","datetime"],img:["alt","src","height","width","usemap","ismap"],iframe:["name","src","height","width","sandbox","seamless"],embed:["src","height","width","type"],object:["param","data","type","height","width","usemap","name","form","classid"],param:["name","value"],video:["src","autobuffer","autoplay","loop","controls","width","height","poster"],audio:["src","autobuffer","autoplay","loop","controls"],source:["src","type","media"],track:["kind","src","srclang","label","default"],canvas:["width","height"],map:["name"],area:["shape","coords","href","hreflang","alt","target","media","rel","ping","type"],svg:[],math:[],table:["summary"],caption:[],colgroup:["span"],col:["span"],tbody:[],thead:[],tfoot:[],tr:[],td:["headers","rowspan","colspan"],th:["headers","rowspan","colspan","scope"],form:["accept-charset","action","autocomplete","enctype","method","name","novalidate","target"],fieldset:["disabled","form","name"],legend:[],label:["form","for"],input:["type","accept","alt","autocomplete","checked","disabled","form","formaction","formenctype","formmethod","formnovalidate","formtarget","height","list","max","maxlength","min","multiple","pattern","placeholder","readonly","required","size","src","step","width","files","value"],button:["autofocus","disabled","form","formaction","formenctype","formmethod","formnovalidate","formtarget","name","value","type"],select:["autofocus","disabled","form","multiple","name","size"],datalist:[],optgroup:["disabled","label"],option:["disabled","selected","label","value"],textarea:["autofocus","disabled","form","maxlength","name","placeholder","readonly","required","rows","cols","wrap"],keygen:["autofocus","challenge","disabled","form","keytype","name"],output:["for","form","name"],progress:["value","max"],meter:["value","min","max","low","high","optimum"],details:["open"],summary:[],command:["type","label","icon","disabled","checked","radiogroup","command"],menu:["type","label"],dialog:["open"]},a=Object.keys(u),c=function(){};(function(){this.getCompletions=function(e,t,n,r){var i=t.getTokenAt(n.row,n.column);return i?f(i,"tag-name")||f(i,"tag-open")||f(i,"end-tag-open")?this.getTagCompletions(e,t,n,r):f(i,"tag-whitespace")||f(i,"attribute-name")?this.getAttributeCompetions(e,t,n,r):[]:[]},this.getTagCompletions=function(e,t,n,r){return a.map(function(e){return{value:e,meta:"tag",score:Number.MAX_VALUE}})},this.getAttributeCompetions=function(e,t,n,r){var i=l(t,n);if(!i)return[];var s=o;return i in u&&(s=s.concat(u[i])),s.map(function(e){return{caption:e,snippet:e+'="$0"',meta:"attribute",score:Number.MAX_VALUE}})}}).call(c.prototype),t.HtmlCompletions=c}),ace.define("ace/mode/html",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/javascript","ace/mode/css","ace/mode/html_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/html","ace/mode/html_completions","ace/worker/worker_client"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text").Mode,o=e("./javascript").Mode,u=e("./css").Mode,a=e("./html_highlight_rules").HtmlHighlightRules,f=e("./behaviour/xml").XmlBehaviour,l=e("./folding/html").FoldMode,c=e("./html_completions").HtmlCompletions,h=e("../worker/worker_client").WorkerClient,p=["area","base","br","col","embed","hr","img","input","keygen","link","meta","menuitem","param","source","track","wbr"],d=["li","dt","dd","p","rt","rp","optgroup","option","colgroup","td","th"],v=function(e){this.fragmentContext=e&&e.fragmentContext,this.HighlightRules=a,this.$behaviour=new f,this.$completer=new c,this.createModeDelegates({"js-":o,"css-":u}),this.foldingRules=new l(this.voidElements,i.arrayToMap(d))};r.inherits(v,s),function(){this.blockComment={start:""},this.voidElements=i.arrayToMap(p),this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.getCompletions=function(e,t,n,r){return this.$completer.getCompletions(e,t,n,r)},this.createWorker=function(e){if(this.constructor!=v)return;var t=new h(["ace"],"ace/mode/html_worker","Worker");return t.attachToDocument(e.getDocument()),this.fragmentContext&&t.call("setOptions",[{context:this.fragmentContext}]),t.on("error",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/html"}.call(v.prototype),t.Mode=v}),ace.define("ace/mode/folding/coffee",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=e("../../range").Range,o=t.FoldMode=function(){};r.inherits(o,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=this.indentationBlock(e,n);if(r)return r;var i=/\S/,o=e.getLine(n),u=o.search(i);if(u==-1||o[u]!="#")return;var a=o.length,f=e.getLength(),l=n,c=n;while(++nl){var p=e.getLine(c).length;return new s(l,a,c,p)}},this.getFoldWidget=function(e,t,n){var r=e.getLine(n),i=r.search(/\S/),s=e.getLine(n+1),o=e.getLine(n-1),u=o.search(/\S/),a=s.search(/\S/);if(i==-1)return e.foldWidgets[n-1]=u!=-1&&u=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|[!$%&*+\-~\/^]=?/,next:"start"},{token:"punctuation.operator",regex:/[?:,;.]/,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"comment",regex:/^#!.*$/}],start:[i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment_regex_allowed"},{token:"comment",regex:"\\/\\/",next:"line_comment_regex_allowed"},{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.charclass.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:r},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],comment_regex_allowed:[i.getTagRule(),{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment",caseInsensitive:!0}],comment:[i.getTagRule(),{token:"comment",regex:"\\*\\/",next:"no_regex"},{defaultToken:"comment",caseInsensitive:!0}],line_comment_regex_allowed:[i.getTagRule(),{token:"comment",regex:"$|^",next:"start"},{defaultToken:"comment",caseInsensitive:!0}],line_comment:[i.getTagRule(),{token:"comment",regex:"$|^",next:"no_regex"},{defaultToken:"comment",caseInsensitive:!0}],qqstring:[{token:"constant.language.escape",regex:s},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:s},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},(!e||!e.noES6)&&this.$rules.no_regex.unshift({regex:"[{}]",onMatch:function(e,t,n){this.next=e=="{"?this.nextState:"";if(e=="{"&&n.length)return n.unshift("start",t),"paren";if(e=="}"&&n.length){n.shift(),this.next=n.shift();if(this.next.indexOf("string")!=-1)return"paren.quasi.end"}return e=="{"?"paren.lparen":"paren.rparen"},nextState:"start"},{token:"string.quasi.start",regex:/`/,push:[{token:"constant.language.escape",regex:s},{token:"paren.quasi.start",regex:/\${/,push:"start"},{token:"string.quasi.end",regex:/`/,next:"pop"},{defaultToken:"string.quasi"}]}),this.embedRules(i,"doc-",[i.getEndRule("no_regex")]),this.normalizeRules()};r.inherits(o,s),t.JavaScriptHighlightRules=o}),ace.define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(e){var t="[_:a-zA-Z\u00c0-\uffff][-_:.a-zA-Z0-9\u00c0-\uffff]*";this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.xml-decl.xml","keyword.xml-decl.xml"],regex:"(<\\?)(xml)(?=[\\s])",next:"xml_decl",caseInsensitive:!0},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)("+t+")",next:"processing_instruction"},{token:"comment.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"",next:"start"}],processing_instruction:[{token:"punctuation.instruction.xml",regex:"\\?>",next:"start"},{defaultToken:"instruction.xml"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)("+t+")",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.xml",regex:"-->",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:"(?:"+t+":)?"+t+""},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===s&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(i.prototype),r.inherits(s,i),t.XmlHighlightRules=s}),ace.define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./css_highlight_rules").CssHighlightRules,o=e("./javascript_highlight_rules").JavaScriptHighlightRules,u=e("./xml_highlight_rules").XmlHighlightRules,a=i.createMap({a:"anchor",button:"form",form:"form",img:"image",input:"form",label:"form",option:"form",script:"script",select:"form",textarea:"form",style:"style",table:"table",tbody:"table",td:"table",tfoot:"table",th:"table",tr:"table"}),f=function(){u.call(this),this.addRules({attributes:[{include:"tag_whitespace"},{token:"entity.other.attribute-name.xml",regex:"[-_a-zA-Z0-9:.]+"},{token:"keyword.operator.attribute-equals.xml",regex:"=",push:[{include:"tag_whitespace"},{token:"string.unquoted.attribute-value.html",regex:"[^<>='\"`\\s]+",next:"pop"},{token:"empty",regex:"",next:"pop"}]},{include:"attribute_value"}],tag:[{token:function(e,t){var n=a[t];return["meta.tag.punctuation."+(e=="<"?"":"end-")+"tag-open.xml","meta.tag"+(n?"."+n:"")+".tag-name.xml"]},regex:"(",next:"start"}]}),this.embedTagRules(s,"css-","style"),this.embedTagRules(o,"js-","script"),this.constructor===f&&this.normalizeRules()};r.inherits(f,u),t.HtmlHighlightRules=f}),ace.define("ace/mode/ruby_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=t.constantOtherSymbol={token:"constant.other.symbol.ruby",regex:"[:](?:[A-Za-z_]|[@$](?=[a-zA-Z0-9_]))[a-zA-Z0-9_]*[!=?]?"},o=t.qString={token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},u=t.qqString={token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},a=t.tString={token:"string",regex:"[`](?:(?:\\\\.)|(?:[^'\\\\]))*?[`]"},f=t.constantNumericHex={token:"constant.numeric",regex:"0[xX][0-9a-fA-F](?:[0-9a-fA-F]|_(?=[0-9a-fA-F]))*\\b"},l=t.constantNumericFloat={token:"constant.numeric",regex:"[+-]?\\d(?:\\d|_(?=\\d))*(?:(?:\\.\\d(?:\\d|_(?=\\d))*)?(?:[eE][+-]?\\d+)?)?\\b"},c=function(){var e="abort|Array|assert|assert_equal|assert_not_equal|assert_same|assert_not_same|assert_nil|assert_not_nil|assert_match|assert_no_match|assert_in_delta|assert_throws|assert_raise|assert_nothing_raised|assert_instance_of|assert_kind_of|assert_respond_to|assert_operator|assert_send|assert_difference|assert_no_difference|assert_recognizes|assert_generates|assert_response|assert_redirected_to|assert_template|assert_select|assert_select_email|assert_select_rjs|assert_select_encoded|css_select|at_exit|attr|attr_writer|attr_reader|attr_accessor|attr_accessible|autoload|binding|block_given?|callcc|caller|catch|chomp|chomp!|chop|chop!|defined?|delete_via_redirect|eval|exec|exit|exit!|fail|Float|flunk|follow_redirect!|fork|form_for|form_tag|format|gets|global_variables|gsub|gsub!|get_via_redirect|host!|https?|https!|include|Integer|lambda|link_to|link_to_unless_current|link_to_function|link_to_remote|load|local_variables|loop|open|open_session|p|print|printf|proc|putc|puts|post_via_redirect|put_via_redirect|raise|rand|raw|readline|readlines|redirect?|request_via_redirect|require|scan|select|set_trace_func|sleep|split|sprintf|srand|String|stylesheet_link_tag|syscall|system|sub|sub!|test|throw|trace_var|trap|untrace_var|atan2|cos|exp|frexp|ldexp|log|log10|sin|sqrt|tan|render|javascript_include_tag|csrf_meta_tag|label_tag|text_field_tag|submit_tag|check_box_tag|content_tag|radio_button_tag|text_area_tag|password_field_tag|hidden_field_tag|fields_for|select_tag|options_for_select|options_from_collection_for_select|collection_select|time_zone_select|select_date|select_time|select_datetime|date_select|time_select|datetime_select|select_year|select_month|select_day|select_hour|select_minute|select_second|file_field_tag|file_field|respond_to|skip_before_action|around_filter|after_filter|verify|protect_from_forgery|rescue_from|helper_method|redirect_to|before_action|send_data|send_file|validates_presence_of|validates_uniqueness_of|validates_length_of|validates_format_of|validates_acceptance_of|validates_associated|validates_exclusion_of|validates_inclusion_of|validates_numericality_of|validates_with|validates_each|authenticate_or_request_with_http_basic|authenticate_or_request_with_http_digest|filter_parameter_logging|match|get|post|resources|redirect|scope|assert_routing|translate|localize|extract_locale_from_tld|caches_page|expire_page|caches_action|expire_action|cache|expire_fragment|expire_cache_for|observe|cache_sweeper|has_many|has_one|belongs_to|has_and_belongs_to_many",t="alias|and|BEGIN|begin|break|case|class|def|defined|do|else|elsif|END|end|ensure|__FILE__|finally|for|gem|if|in|__LINE__|module|next|not|or|private|protected|public|redo|rescue|retry|return|super|then|undef|unless|until|when|while|yield",n="true|TRUE|false|FALSE|nil|NIL|ARGF|ARGV|DATA|ENV|RUBY_PLATFORM|RUBY_RELEASE_DATE|RUBY_VERSION|STDERR|STDIN|STDOUT|TOPLEVEL_BINDING",r="$DEBUG|$defout|$FILENAME|$LOAD_PATH|$SAFE|$stdin|$stdout|$stderr|$VERBOSE|$!|root_url|flash|session|cookies|params|request|response|logger|self",i=this.$keywords=this.createKeywordMapper({keyword:t,"constant.language":n,"variable.language":r,"support.function":e,"invalid.deprecated":"debugger"},"identifier");this.$rules={start:[{token:"comment",regex:"#.*$"},{token:"comment",regex:"^=begin(?:$|\\s.*$)",next:"comment"},{token:"string.regexp",regex:"[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/]\\w*\\s*(?=[).,;]|$)"},[{regex:"[{}]",onMatch:function(e,t,n){this.next=e=="{"?this.nextState:"";if(e=="{"&&n.length)return n.unshift("start",t),"paren.lparen";if(e=="}"&&n.length){n.shift(),this.next=n.shift();if(this.next.indexOf("string")!=-1)return"paren.end"}return e=="{"?"paren.lparen":"paren.rparen"},nextState:"start"},{token:"string.start",regex:/"/,push:[{token:"constant.language.escape",regex:/\\(?:[nsrtvfbae'"\\]|c.|C-.|M-.(?:\\C-.)?|[0-7]{3}|x[\da-fA-F]{2}|u[\da-fA-F]{4})/},{token:"paren.start",regex:/\#{/,push:"start"},{token:"string.end",regex:/"/,next:"pop"},{defaultToken:"string"}]},{token:"string.start",regex:/`/,push:[{token:"constant.language.escape",regex:/\\(?:[nsrtvfbae'"\\]|c.|C-.|M-.(?:\\C-.)?|[0-7]{3}|x[\da-fA-F]{2}|u[\da-fA-F]{4})/},{token:"paren.start",regex:/\#{/,push:"start"},{token:"string.end",regex:/`/,next:"pop"},{defaultToken:"string"}]},{token:"string.start",regex:/'/,push:[{token:"constant.language.escape",regex:/\\['\\]/},{token:"string.end",regex:/'/,next:"pop"},{defaultToken:"string"}]}],{token:"text",regex:"::"},{token:"variable.instance",regex:"@{1,2}[a-zA-Z_\\d]+"},{token:"support.class",regex:"[A-Z][a-zA-Z_\\d]+"},s,f,l,{token:"constant.language.boolean",regex:"(?:true|false)\\b"},{token:i,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"punctuation.separator.key-value",regex:"=>"},{stateName:"heredoc",onMatch:function(e,t,n){var r=e[2]=="-"?"indentedHeredoc":"heredoc",i=e.split(this.splitRegex);return n.push(r,i[3]),[{type:"constant",value:i[1]},{type:"string",value:i[2]},{type:"support.class",value:i[3]},{type:"string",value:i[4]}]},regex:"(<<-?)(['\"`]?)([\\w]+)(['\"`]?)",rules:{heredoc:[{onMatch:function(e,t,n){return e===n[1]?(n.shift(),n.shift(),this.next=n[0]||"start","support.class"):(this.next="","string")},regex:".*$",next:"start"}],indentedHeredoc:[{token:"string",regex:"^ +"},{onMatch:function(e,t,n){return e===n[1]?(n.shift(),n.shift(),this.next=n[0]||"start","support.class"):(this.next="","string")},regex:".*$",next:"start"}]}},{regex:"$",token:"empty",next:function(e,t){return t[0]==="heredoc"||t[0]==="indentedHeredoc"?t[0]:e}},{token:"string.character",regex:"\\B\\?."},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:"^=end(?:$|\\s.*$)",next:"start"},{token:"comment",regex:".+"}]},this.normalizeRules()};r.inherits(c,i),t.RubyHighlightRules=c}),ace.define("ace/mode/html_ruby_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/html_highlight_rules","ace/mode/ruby_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./html_highlight_rules").HtmlHighlightRules,s=e("./ruby_highlight_rules").RubyHighlightRules,o=function(){i.call(this);var e=[{regex:"<%%|%%>",token:"constant.language.escape"},{token:"comment.start.erb",regex:"<%#",push:[{token:"comment.end.erb",regex:"%>",next:"pop",defaultToken:"comment"}]},{token:"support.ruby_tag",regex:"<%+(?!>)[-=]?",push:"ruby-start"}],t=[{token:"support.ruby_tag",regex:"%>",next:"pop"},{token:"comment",regex:"#(?:[^%]|%[^>])*"}];for(var n in this.$rules)this.$rules[n].unshift.apply(this.$rules[n],e);this.embedRules(s,"ruby-",t,["start"]),this.normalizeRules()};r.inherits(o,i),t.HtmlRubyHighlightRules=o}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.index,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(e,t,n,r){var i=e.end.row-e.start.row;return{text:n+t+r,selection:[0,e.start.column+1,i,e.end.column+(i?0:1)]}},p=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return h(a,l,"{","}");if(p.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(p.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(p.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var d=u.substring(s.column,s.column+1);if(d=="}"){var v=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(v!==null&&p.isAutoInsertedClosing(s,u,i))return p.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var m="";p.isMaybeInsertedClosing(s,u)&&(m=o.stringRepeat("}",f.maybeInsertedBrackets),p.clearMaybeInsertedClosing());var d=u.substring(s.column,s.column+1);if(d==="}"){var g=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!g)return null;var y=this.$getIndent(r.getLine(g.row))}else{if(!m){p.clearMaybeInsertedClosing();return}var y=this.$getIndent(u)}var b=y+r.getTabString();return{text:"\n"+b+"\n"+y+m,selection:[1,b.length,1,b.length]}}p.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return h(s,o,"(",")");if(p.isSaneInsertion(n,r))return p.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&p.isAutoInsertedClosing(u,a,i))return p.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return h(s,o,"[","]");if(p.isSaneInsertion(n,r))return p.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&p.isAutoInsertedClosing(u,a,i))return p.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return h(o,u,s,s);if(!u){var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column),p=f.substring(a.column,a.column+1),d=r.getTokenAt(a.row,a.column),v=r.getTokenAt(a.row,a.column+1);if(l=="\\"&&d&&/escape/.test(d.type))return null;var m=d&&/string/.test(d.type),g=!v||/string/.test(v.type),y;if(p==s)y=m!==g;else{if(m&&!g)return null;if(m&&g)return null;var b=r.$mode.tokenRe;b.lastIndex=0;var w=b.test(l);b.lastIndex=0;var E=b.test(l);if(w||E)return null;if(p&&!/[\s;,.})\]\\]/.test(p))return null;y=!0}return{text:y?s+s:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};p.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},p.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},p.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},p.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},p.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},p.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},p.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},p.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(p,i),t.CstyleBehaviour=p}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);if(this.singleLineBlockCommentRe.test(r)&&!this.startRegionRe.test(r)&&!this.tripleStarBlockCommentRe.test(r))return"";var i=this._getFoldWidgetBase(e,t,n);return!i&&this.startRegionRe.test(r)?"start":i},this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n);if(this.startRegionRe.test(i))return this.getCommentRegionBlock(e,i,n);var s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++tf)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)},this.getCommentRegionBlock=function(e,t,n){var r=t.search(/\s*$/),s=e.getLength(),o=n,u=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,a=1;while(++no)return new i(o,r,l,t.length)}}.call(o.prototype)}),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./javascript_highlight_rules").JavaScriptHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../range").Range,a=e("../worker/worker_client").WorkerClient,f=e("./behaviour/cstyle").CstyleBehaviour,l=e("./folding/cstyle").FoldMode,c=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new f,this.foldingRules=new l};r.inherits(c,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"||e=="no_regex"){var u=t.match(/^.*(?:\bcase\b.*\:|[\{\(\[])\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start"||o=="no_regex")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new a(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("annotate",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/javascript"}.call(c.prototype),t.Mode=c}),ace.define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("./cstyle").CstyleBehaviour,o=e("../../token_iterator").TokenIterator,u=function(){this.inherit(s),this.add("colon","insertion",function(e,t,n,r,i){if(i===":"){var s=n.getCursorPosition(),u=new o(r,s.row,s.column),a=u.getCurrentToken();a&&a.value.match(/\s+/)&&(a=u.stepBackward());if(a&&a.type==="support.type"){var f=r.doc.getLine(s.row),l=f.substring(s.column,s.column+1);if(l===":")return{text:"",selection:[1,1]};if(!f.substring(s.column).match(/^\s*;/))return{text:":;",selection:[1,1]}}}}),this.add("colon","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s===":"){var u=n.getCursorPosition(),a=new o(r,u.row,u.column),f=a.getCurrentToken();f&&f.value.match(/\s+/)&&(f=a.stepBackward());if(f&&f.type==="support.type"){var l=r.doc.getLine(i.start.row),c=l.substring(i.end.column,i.end.column+1);if(c===";")return i.end.column++,i}}}),this.add("semicolon","insertion",function(e,t,n,r,i){if(i===";"){var s=n.getCursorPosition(),o=r.doc.getLine(s.row),u=o.substring(s.column,s.column+1);if(u===";")return{text:"",selection:[1,1]}}})};r.inherits(u,s),t.CssBehaviour=u}),ace.define("ace/mode/css",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/css","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./css_highlight_rules").CssHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../worker/worker_client").WorkerClient,a=e("./behaviour/css").CssBehaviour,f=e("./folding/cstyle").FoldMode,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new a,this.foldingRules=new f};r.inherits(l,i),function(){this.foldingRules="cStyle",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e).tokens;if(i.length&&i[i.length-1].type=="comment")return r;var s=t.match(/^.*\{\s*$/);return s&&(r+=n),r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new u(["ace"],"ace/mode/css_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("annotate",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/css"}.call(l.prototype),t.Mode=l}),ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";function u(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),a=function(){this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){var o=i,a=r.doc.getTextRange(n.getSelectionRange());if(a!==""&&a!=="'"&&a!='"'&&n.getWrapBehavioursEnabled())return{text:o+a+o,selection:!1};var f=n.getCursorPosition(),l=r.doc.getLine(f.row),c=l.substring(f.column,f.column+1),h=new s(r,f.row,f.column),p=h.getCurrentToken();if(c==o&&(u(p,"attribute-value")||u(p,"string")))return{text:"",selection:[1,1]};p||(p=h.stepBackward());if(!p)return;while(u(p,"tag-whitespace")||u(p,"whitespace"))p=h.stepBackward();var d=!c||c.match(/\s/);if(u(p,"attribute-equals")&&(d||c==">")||u(p,"decl-attribute-equals")&&(d||c=="?"))return{text:o+o,selection:[1,1]}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}}),this.add("autoclosing","insertion",function(e,t,n,r,i){if(i==">"){var o=n.getCursorPosition(),a=new s(r,o.row,o.column),f=a.getCurrentToken()||a.stepBackward();if(!f||!(u(f,"tag-name")||u(f,"tag-whitespace")||u(f,"attribute-name")||u(f,"attribute-equals")||u(f,"attribute-value")))return;if(u(f,"reference.attribute-value"))return;if(u(f,"attribute-value")){var l=f.value.charAt(0);if(l=='"'||l=="'"){var c=f.value.charAt(f.value.length-1),h=a.getCurrentTokenColumn()+f.value.length;if(h>o.column||h==o.column&&l!=c)return}}while(!u(f,"tag-name"))f=a.stepBackward();var p=a.getCurrentTokenRow(),d=a.getCurrentTokenColumn();if(u(a.stepBackward(),"end-tag-open"))return;var v=f.value;p==o.row&&(v=v.substring(0,o.column-d));if(this.voidElements.hasOwnProperty(v.toLowerCase()))return;return{text:">",selection:[1,1]}}}),this.add("autoindent","insertion",function(e,t,n,r,i){if(i=="\n"){var o=n.getCursorPosition(),u=r.getLine(o.row),a=new s(r,o.row,o.column),f=a.getCurrentToken();if(f&&f.type.indexOf("tag-close")!==-1){if(f.value=="/>")return;while(f&&f.type.indexOf("tag-name")===-1)f=a.stepBackward();if(!f)return;var l=f.value,c=a.getCurrentTokenRow();f=a.stepBackward();if(!f||f.type.indexOf("end-tag")!==-1)return;if(this.voidElements&&!this.voidElements[l]){var h=r.getTokenAt(o.row,o.column+1),u=r.getLine(c),p=this.$getIndent(u),d=p+r.getTabString();return h&&h.value==="-1}var r=e("../../lib/oop"),i=e("../../lib/lang"),s=e("../../range").Range,o=e("./fold_mode").FoldMode,u=e("../../token_iterator").TokenIterator,a=t.FoldMode=function(e,t){o.call(this),this.voidElements=e||{},this.optionalEndTags=r.mixin({},this.voidElements),t&&r.mixin(this.optionalEndTags,t)};r.inherits(a,o);var f=function(){this.tagName="",this.closing=!1,this.selfClosing=!1,this.start={row:0,column:0},this.end={row:0,column:0}};(function(){this.getFoldWidget=function(e,t,n){var r=this._getFirstTagInLine(e,n);return r?r.closing||!r.tagName&&r.selfClosing?t=="markbeginend"?"end":"":!r.tagName||r.selfClosing||this.voidElements.hasOwnProperty(r.tagName.toLowerCase())?"":this._findEndTagInLine(e,n,r.tagName,r.end.column)?"":"start":""},this._getFirstTagInLine=function(e,t){var n=e.getTokens(t),r=new f;for(var i=0;i";break}}return r}if(l(s,"tag-close"))return r.selfClosing=s.value=="/>",r;r.start.column+=s.value.length}return null},this._findEndTagInLine=function(e,t,n,r){var i=e.getTokens(t),s=0;for(var o=0;o",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length,e.stepForward(),n;while(t=e.stepForward());return null},this._readTagBackward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do{if(l(t,"tag-open"))return n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn(),e.stepBackward(),n;l(t,"tag-name")?n.tagName=t.value:l(t,"tag-close")&&(n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length)}while(t=e.stepBackward());return null},this._pop=function(e,t){while(e.length){var n=e[e.length-1];if(!t||n.tagName==t.tagName)return e.pop();if(this.optionalEndTags.hasOwnProperty(n.tagName)){e.pop();continue}return null}},this.getFoldWidgetRange=function(e,t,n){var r=this._getFirstTagInLine(e,n);if(!r)return null;var i=r.closing||r.selfClosing,o=[],a;if(!i){var f=new u(e,n,r.start.column),l={row:n,column:r.start.column+r.tagName.length+2};r.start.row==r.end.row&&(l.column=r.end.column);while(a=this._readTagForward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(a.closing){this._pop(o,a);if(o.length==0)return s.fromPoints(l,a.start)}else o.push(a)}}else{var f=new u(e,n,r.end.column),c={row:n,column:r.start.column};while(a=this._readTagBackward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(!a.closing){this._pop(o,a);if(o.length==0)return a.start.column+=a.tagName.length+2,a.start.row==a.end.row&&a.start.column-1}function l(e,t){var n=new r(e,t.row,t.column),i=n.getCurrentToken();while(i&&!f(i,"tag-name"))i=n.stepBackward();if(i)return i.value}var r=e("../token_iterator").TokenIterator,i=["accesskey","class","contenteditable","contextmenu","dir","draggable","dropzone","hidden","id","inert","itemid","itemprop","itemref","itemscope","itemtype","lang","spellcheck","style","tabindex","title","translate"],s=["onabort","onblur","oncancel","oncanplay","oncanplaythrough","onchange","onclick","onclose","oncontextmenu","oncuechange","ondblclick","ondrag","ondragend","ondragenter","ondragleave","ondragover","ondragstart","ondrop","ondurationchange","onemptied","onended","onerror","onfocus","oninput","oninvalid","onkeydown","onkeypress","onkeyup","onload","onloadeddata","onloadedmetadata","onloadstart","onmousedown","onmousemove","onmouseout","onmouseover","onmouseup","onmousewheel","onpause","onplay","onplaying","onprogress","onratechange","onreset","onscroll","onseeked","onseeking","onselect","onshow","onstalled","onsubmit","onsuspend","ontimeupdate","onvolumechange","onwaiting"],o=i.concat(s),u={html:["manifest"],head:[],title:[],base:["href","target"],link:["href","hreflang","rel","media","type","sizes"],meta:["http-equiv","name","content","charset"],style:["type","media","scoped"],script:["charset","type","src","defer","async"],noscript:["href"],body:["onafterprint","onbeforeprint","onbeforeunload","onhashchange","onmessage","onoffline","onpopstate","onredo","onresize","onstorage","onundo","onunload"],section:[],nav:[],article:["pubdate"],aside:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],header:[],footer:[],address:[],main:[],p:[],hr:[],pre:[],blockquote:["cite"],ol:["start","reversed"],ul:[],li:["value"],dl:[],dt:[],dd:[],figure:[],figcaption:[],div:[],a:["href","target","ping","rel","media","hreflang","type"],em:[],strong:[],small:[],s:[],cite:[],q:["cite"],dfn:[],abbr:[],data:[],time:["datetime"],code:[],"var":[],samp:[],kbd:[],sub:[],sup:[],i:[],b:[],u:[],mark:[],ruby:[],rt:[],rp:[],bdi:[],bdo:[],span:[],br:[],wbr:[],ins:["cite","datetime"],del:["cite","datetime"],img:["alt","src","height","width","usemap","ismap"],iframe:["name","src","height","width","sandbox","seamless"],embed:["src","height","width","type"],object:["param","data","type","height","width","usemap","name","form","classid"],param:["name","value"],video:["src","autobuffer","autoplay","loop","controls","width","height","poster"],audio:["src","autobuffer","autoplay","loop","controls"],source:["src","type","media"],track:["kind","src","srclang","label","default"],canvas:["width","height"],map:["name"],area:["shape","coords","href","hreflang","alt","target","media","rel","ping","type"],svg:[],math:[],table:["summary"],caption:[],colgroup:["span"],col:["span"],tbody:[],thead:[],tfoot:[],tr:[],td:["headers","rowspan","colspan"],th:["headers","rowspan","colspan","scope"],form:["accept-charset","action","autocomplete","enctype","method","name","novalidate","target"],fieldset:["disabled","form","name"],legend:[],label:["form","for"],input:["type","accept","alt","autocomplete","checked","disabled","form","formaction","formenctype","formmethod","formnovalidate","formtarget","height","list","max","maxlength","min","multiple","pattern","placeholder","readonly","required","size","src","step","width","files","value"],button:["autofocus","disabled","form","formaction","formenctype","formmethod","formnovalidate","formtarget","name","value","type"],select:["autofocus","disabled","form","multiple","name","size"],datalist:[],optgroup:["disabled","label"],option:["disabled","selected","label","value"],textarea:["autofocus","disabled","form","maxlength","name","placeholder","readonly","required","rows","cols","wrap"],keygen:["autofocus","challenge","disabled","form","keytype","name"],output:["for","form","name"],progress:["value","max"],meter:["value","min","max","low","high","optimum"],details:["open"],summary:[],command:["type","label","icon","disabled","checked","radiogroup","command"],menu:["type","label"],dialog:["open"]},a=Object.keys(u),c=function(){};(function(){this.getCompletions=function(e,t,n,r){var i=t.getTokenAt(n.row,n.column);return i?f(i,"tag-name")||f(i,"tag-open")||f(i,"end-tag-open")?this.getTagCompletions(e,t,n,r):f(i,"tag-whitespace")||f(i,"attribute-name")?this.getAttributeCompetions(e,t,n,r):[]:[]},this.getTagCompletions=function(e,t,n,r){return a.map(function(e){return{value:e,meta:"tag",score:Number.MAX_VALUE}})},this.getAttributeCompetions=function(e,t,n,r){var i=l(t,n);if(!i)return[];var s=o;return i in u&&(s=s.concat(u[i])),s.map(function(e){return{caption:e,snippet:e+'="$0"',meta:"attribute",score:Number.MAX_VALUE}})}}).call(c.prototype),t.HtmlCompletions=c}),ace.define("ace/mode/html",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/javascript","ace/mode/css","ace/mode/html_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/html","ace/mode/html_completions","ace/worker/worker_client"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text").Mode,o=e("./javascript").Mode,u=e("./css").Mode,a=e("./html_highlight_rules").HtmlHighlightRules,f=e("./behaviour/xml").XmlBehaviour,l=e("./folding/html").FoldMode,c=e("./html_completions").HtmlCompletions,h=e("../worker/worker_client").WorkerClient,p=["area","base","br","col","embed","hr","img","input","keygen","link","meta","menuitem","param","source","track","wbr"],d=["li","dt","dd","p","rt","rp","optgroup","option","colgroup","td","th"],v=function(e){this.fragmentContext=e&&e.fragmentContext,this.HighlightRules=a,this.$behaviour=new f,this.$completer=new c,this.createModeDelegates({"js-":o,"css-":u}),this.foldingRules=new l(this.voidElements,i.arrayToMap(d))};r.inherits(v,s),function(){this.blockComment={start:""},this.voidElements=i.arrayToMap(p),this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.getCompletions=function(e,t,n,r){return this.$completer.getCompletions(e,t,n,r)},this.createWorker=function(e){if(this.constructor!=v)return;var t=new h(["ace"],"ace/mode/html_worker","Worker");return t.attachToDocument(e.getDocument()),this.fragmentContext&&t.call("setOptions",[{context:this.fragmentContext}]),t.on("error",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/html"}.call(v.prototype),t.Mode=v}),ace.define("ace/mode/folding/coffee",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=e("../../range").Range,o=t.FoldMode=function(){};r.inherits(o,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=this.indentationBlock(e,n);if(r)return r;var i=/\S/,o=e.getLine(n),u=o.search(i);if(u==-1||o[u]!="#")return;var a=o.length,f=e.getLength(),l=n,c=n;while(++nl){var p=e.getLine(c).length;return new s(l,a,c,p)}},this.getFoldWidget=function(e,t,n){var r=e.getLine(n),i=r.search(/\S/),s=e.getLine(n+1),o=e.getLine(n-1),u=o.search(/\S/),a=s.search(/\S/);if(i==-1)return e.foldWidgets[n-1]=u!=-1&&u"},{stateName:"heredoc",onMatch:function(e,t,n){var r=e[2]=="-"?"indentedHeredoc":"heredoc",i=e.split(this.splitRegex);return n.push(r,i[3]),[{type:"constant",value:i[1]},{type:"string",value:i[2]},{type:"support.class",value:i[3]},{type:"string",value:i[4]}]},regex:"(<<-?)(['\"`]?)([\\w]+)(['\"`]?)",rules:{heredoc:[{onMatch:function(e,t,n){return e===n[1]?(n.shift(),n.shift(),this.next=n[0]||"start","support.class"):(this.next="","string")},regex:".*$",next:"start"}],indentedHeredoc:[{token:"string",regex:"^ +"},{onMatch:function(e,t,n){return e===n[1]?(n.shift(),n.shift(),this.next=n[0]||"start","support.class"):(this.next="","string")},regex:".*$",next:"start"}]}},{regex:"$",token:"empty",next:function(e,t){return t[0]==="heredoc"||t[0]==="indentedHeredoc"?t[0]:e}},{token:"string.character",regex:"\\B\\?."},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:"^=end(?:$|\\s.*$)",next:"start"},{token:"comment",regex:".+"}]},this.normalizeRules()};r.inherits(c,i),t.RubyHighlightRules=c}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.index,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(e,t,n,r){var i=e.end.row-e.start.row;return{text:n+t+r,selection:[0,e.start.column+1,i,e.end.column+(i?0:1)]}},p=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return h(a,l,"{","}");if(p.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(p.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(p.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var d=u.substring(s.column,s.column+1);if(d=="}"){var v=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(v!==null&&p.isAutoInsertedClosing(s,u,i))return p.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var m="";p.isMaybeInsertedClosing(s,u)&&(m=o.stringRepeat("}",f.maybeInsertedBrackets),p.clearMaybeInsertedClosing());var d=u.substring(s.column,s.column+1);if(d==="}"){var g=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!g)return null;var y=this.$getIndent(r.getLine(g.row))}else{if(!m){p.clearMaybeInsertedClosing();return}var y=this.$getIndent(u)}var b=y+r.getTabString();return{text:"\n"+b+"\n"+y+m,selection:[1,b.length,1,b.length]}}p.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return h(s,o,"(",")");if(p.isSaneInsertion(n,r))return p.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&p.isAutoInsertedClosing(u,a,i))return p.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return h(s,o,"[","]");if(p.isSaneInsertion(n,r))return p.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&p.isAutoInsertedClosing(u,a,i))return p.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return h(o,u,s,s);if(!u){var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column),p=f.substring(a.column,a.column+1),d=r.getTokenAt(a.row,a.column),v=r.getTokenAt(a.row,a.column+1);if(l=="\\"&&d&&/escape/.test(d.type))return null;var m=d&&/string/.test(d.type),g=!v||/string/.test(v.type),y;if(p==s)y=m!==g;else{if(m&&!g)return null;if(m&&g)return null;var b=r.$mode.tokenRe;b.lastIndex=0;var w=b.test(l);b.lastIndex=0;var E=b.test(l);if(w||E)return null;if(p&&!/[\s;,.})\]\\]/.test(p))return null;y=!0}return{text:y?s+s:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};p.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},p.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},p.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},p.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},p.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},p.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},p.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},p.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(p,i),t.CstyleBehaviour=p}),ace.define("ace/mode/folding/coffee",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=e("../../range").Range,o=t.FoldMode=function(){};r.inherits(o,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=this.indentationBlock(e,n);if(r)return r;var i=/\S/,o=e.getLine(n),u=o.search(i);if(u==-1||o[u]!="#")return;var a=o.length,f=e.getLength(),l=n,c=n;while(++nl){var p=e.getLine(c).length;return new s(l,a,c,p)}},this.getFoldWidget=function(e,t,n){var r=e.getLine(n),i=r.search(/\S/),s=e.getLine(n+1),o=e.getLine(n-1),u=o.search(/\S/),a=s.search(/\S/);if(i==-1)return e.foldWidgets[n-1]=u!=-1&&u"},{stateName:"heredoc",onMatch:function(e,t,n){var r=e[2]=="-"?"indentedHeredoc":"heredoc",i=e.split(this.splitRegex);return n.push(r,i[3]),[{type:"constant",value:i[1]},{type:"string",value:i[2]},{type:"support.class",value:i[3]},{type:"string",value:i[4]}]},regex:"(<<-?)(['\"`]?)([\\w]+)(['\"`]?)",rules:{heredoc:[{onMatch:function(e,t,n){return e===n[1]?(n.shift(),n.shift(),this.next=n[0]||"start","support.class"):(this.next="","string")},regex:".*$",next:"start"}],indentedHeredoc:[{token:"string",regex:"^ +"},{onMatch:function(e,t,n){return e===n[1]?(n.shift(),n.shift(),this.next=n[0]||"start","support.class"):(this.next="","string")},regex:".*$",next:"start"}]}},{regex:"$",token:"empty",next:function(e,t){return t[0]==="heredoc"||t[0]==="indentedHeredoc"?t[0]:e}},{token:"string.character",regex:"\\B\\?."},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:"^=end(?:$|\\s.*$)",next:"start"},{token:"comment",regex:".+"}]},this.normalizeRules()};r.inherits(c,i),t.RubyHighlightRules=c}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.index,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(e,t,n,r){var i=e.end.row-e.start.row;return{text:n+t+r,selection:[0,e.start.column+1,i,e.end.column+(i?0:1)]}},p=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return h(a,l,"{","}");if(p.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(p.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(p.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var d=u.substring(s.column,s.column+1);if(d=="}"){var v=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(v!==null&&p.isAutoInsertedClosing(s,u,i))return p.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var m="";p.isMaybeInsertedClosing(s,u)&&(m=o.stringRepeat("}",f.maybeInsertedBrackets),p.clearMaybeInsertedClosing());var d=u.substring(s.column,s.column+1);if(d==="}"){var g=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!g)return null;var y=this.$getIndent(r.getLine(g.row))}else{if(!m){p.clearMaybeInsertedClosing();return}var y=this.$getIndent(u)}var b=y+r.getTabString();return{text:"\n"+b+"\n"+y+m,selection:[1,b.length,1,b.length]}}p.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return h(s,o,"(",")");if(p.isSaneInsertion(n,r))return p.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&p.isAutoInsertedClosing(u,a,i))return p.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return h(s,o,"[","]");if(p.isSaneInsertion(n,r))return p.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&p.isAutoInsertedClosing(u,a,i))return p.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return h(o,u,s,s);if(!u){var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column),p=f.substring(a.column,a.column+1),d=r.getTokenAt(a.row,a.column),v=r.getTokenAt(a.row,a.column+1);if(l=="\\"&&d&&/escape/.test(d.type))return null;var m=d&&/string/.test(d.type),g=!v||/string/.test(v.type),y;if(p==s)y=m!==g;else{if(m&&!g)return null;if(m&&g)return null;var b=r.$mode.tokenRe;b.lastIndex=0;var w=b.test(l);b.lastIndex=0;var E=b.test(l);if(w||E)return null;if(p&&!/[\s;,.})\]\\]/.test(p))return null;y=!0}return{text:y?s+s:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};p.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},p.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},p.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},p.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},p.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},p.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},p.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},p.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(p,i),t.CstyleBehaviour=p}),ace.define("ace/mode/folding/coffee",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=e("../../range").Range,o=t.FoldMode=function(){};r.inherits(o,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=this.indentationBlock(e,n);if(r)return r;var i=/\S/,o=e.getLine(n),u=o.search(i);if(u==-1||o[u]!="#")return;var a=o.length,f=e.getLength(),l=n,c=n;while(++nl){var p=e.getLine(c).length;return new s(l,a,c,p)}},this.getFoldWidget=function(e,t,n){var r=e.getLine(n),i=r.search(/\S/),s=e.getLine(n+1),o=e.getLine(n-1),u=o.search(/\S/),a=s.search(/\S/);if(i==-1)return e.foldWidgets[n-1]=u!=-1&&u(other)\n ${1}\n end\n# extend Forwardable\nsnippet Forw-\n extend Forwardable\n# def self\nsnippet defs\n def self.${1:class_method_name}\n ${2}\n end\n# def method_missing\nsnippet defmm\n def method_missing(meth, *args, &blk)\n ${1}\n end\nsnippet defd\n def_delegator :${1:@del_obj}, :${2:del_meth}, :${3:new_name}\nsnippet defds\n def_delegators :${1:@del_obj}, :${2:del_methods}\nsnippet am\n alias_method :${1:new_name}, :${2:old_name}\nsnippet app\n if __FILE__ == $PROGRAM_NAME\n ${1}\n end\n# usage_if()\nsnippet usai\n if ARGV.${1}\n abort "Usage: #{$PROGRAM_NAME} ${2:ARGS_GO_HERE}"${3}\n end\n# usage_unless()\nsnippet usau\n unless ARGV.${1}\n abort "Usage: #{$PROGRAM_NAME} ${2:ARGS_GO_HERE}"${3}\n end\nsnippet array\n Array.new(${1:10}) { |${2:i}| ${3} }\nsnippet hash\n Hash.new { |${1:hash}, ${2:key}| $1[$2] = ${3} }\nsnippet file File.foreach() { |line| .. }\n File.foreach(${1:"path/to/file"}) { |${2:line}| ${3} }\nsnippet file File.read()\n File.read(${1:"path/to/file"})${2}\nsnippet Dir Dir.global() { |file| .. }\n Dir.glob(${1:"dir/glob/*"}) { |${2:file}| ${3} }\nsnippet Dir Dir[".."]\n Dir[${1:"glob/**/*.rb"}]${2}\nsnippet dir\n Filename.dirname(__FILE__)\nsnippet deli\n delete_if { |${1:e}| ${2} }\nsnippet fil\n fill(${1:range}) { |${2:i}| ${3} }\n# flatten_once()\nsnippet flao\n inject(Array.new) { |${1:arr}, ${2:a}| $1.push(*$2)}${3}\nsnippet zip\n zip(${1:enums}) { |${2:row}| ${3} }\n# downto(0) { |n| .. }\nsnippet dow\n downto(${1:0}) { |${2:n}| ${3} }\nsnippet ste\n step(${1:2}) { |${2:n}| ${3} }\nsnippet tim\n times { |${1:n}| ${2} }\nsnippet upt\n upto(${1:1.0/0.0}) { |${2:n}| ${3} }\nsnippet loo\n loop { ${1} }\nsnippet ea\n each { |${1:e}| ${2} }\nsnippet ead\n each do |${1:e}|\n ${2}\n end\nsnippet eab\n each_byte { |${1:byte}| ${2} }\nsnippet eac- each_char { |chr| .. }\n each_char { |${1:chr}| ${2} }\nsnippet eac- each_cons(..) { |group| .. }\n each_cons(${1:2}) { |${2:group}| ${3} }\nsnippet eai\n each_index { |${1:i}| ${2} }\nsnippet eaid\n each_index do |${1:i}|\n ${2}\n end\nsnippet eak\n each_key { |${1:key}| ${2} }\nsnippet eakd\n each_key do |${1:key}|\n ${2}\n end\nsnippet eal\n each_line { |${1:line}| ${2} }\nsnippet eald\n each_line do |${1:line}|\n ${2}\n end\nsnippet eap\n each_pair { |${1:name}, ${2:val}| ${3} }\nsnippet eapd\n each_pair do |${1:name}, ${2:val}|\n ${3}\n end\nsnippet eas-\n each_slice(${1:2}) { |${2:group}| ${3} }\nsnippet easd-\n each_slice(${1:2}) do |${2:group}|\n ${3}\n end\nsnippet eav\n each_value { |${1:val}| ${2} }\nsnippet eavd\n each_value do |${1:val}|\n ${2}\n end\nsnippet eawi\n each_with_index { |${1:e}, ${2:i}| ${3} }\nsnippet eawid\n each_with_index do |${1:e},${2:i}|\n ${3}\n end\nsnippet reve\n reverse_each { |${1:e}| ${2} }\nsnippet reved\n reverse_each do |${1:e}|\n ${2}\n end\nsnippet inj\n inject(${1:init}) { |${2:mem}, ${3:var}| ${4} }\nsnippet injd\n inject(${1:init}) do |${2:mem}, ${3:var}|\n ${4}\n end\nsnippet map\n map { |${1:e}| ${2} }\nsnippet mapd\n map do |${1:e}|\n ${2}\n end\nsnippet mapwi-\n enum_with_index.map { |${1:e}, ${2:i}| ${3} }\nsnippet sor\n sort { |a, b| ${1} }\nsnippet sorb\n sort_by { |${1:e}| ${2} }\nsnippet ran\n sort_by { rand }\nsnippet all\n all? { |${1:e}| ${2} }\nsnippet any\n any? { |${1:e}| ${2} }\nsnippet cl\n classify { |${1:e}| ${2} }\nsnippet col\n collect { |${1:e}| ${2} }\nsnippet cold\n collect do |${1:e}|\n ${2}\n end\nsnippet det\n detect { |${1:e}| ${2} }\nsnippet detd\n detect do |${1:e}|\n ${2}\n end\nsnippet fet\n fetch(${1:name}) { |${2:key}| ${3} }\nsnippet fin\n find { |${1:e}| ${2} }\nsnippet find\n find do |${1:e}|\n ${2}\n end\nsnippet fina\n find_all { |${1:e}| ${2} }\nsnippet finad\n find_all do |${1:e}|\n ${2}\n end\nsnippet gre\n grep(${1:/pattern/}) { |${2:match}| ${3} }\nsnippet sub\n ${1:g}sub(${2:/pattern/}) { |${3:match}| ${4} }\nsnippet sca\n scan(${1:/pattern/}) { |${2:match}| ${3} }\nsnippet scad\n scan(${1:/pattern/}) do |${2:match}|\n ${3}\n end\nsnippet max\n max { |a, b| ${1} }\nsnippet min\n min { |a, b| ${1} }\nsnippet par\n partition { |${1:e}| ${2} }\nsnippet pard\n partition do |${1:e}|\n ${2}\n end\nsnippet rej\n reject { |${1:e}| ${2} }\nsnippet rejd\n reject do |${1:e}|\n ${2}\n end\nsnippet sel\n select { |${1:e}| ${2} }\nsnippet seld\n select do |${1:e}|\n ${2}\n end\nsnippet lam\n lambda { |${1:args}| ${2} }\nsnippet doo\n do\n ${1}\n end\nsnippet dov\n do |${1:variable}|\n ${2}\n end\nsnippet :\n :${1:key} => ${2:"value"}${3}\nsnippet ope\n open(${1:"path/or/url/or/pipe"}, "${2:w}") { |${3:io}| ${4} }\n# path_from_here()\nsnippet fpath\n File.join(File.dirname(__FILE__), *%2[${1:rel path here}])${2}\n# unix_filter {}\nsnippet unif\n ARGF.each_line${1} do |${2:line}|\n ${3}\n end\n# option_parse {}\nsnippet optp\n require "optparse"\n\n options = {${1:default => "args"}}\n\n ARGV.options do |opts|\n opts.banner = "Usage: #{File.basename($PROGRAM_NAME)}\nsnippet opt\n opts.on( "-${1:o}", "--${2:long-option-name}", ${3:String},\n "${4:Option description.}") do |${5:opt}|\n ${6}\n end\nsnippet tc\n require "test/unit"\n\n require "${1:library_file_name}"\n\n class Test${2:$1} < Test::Unit::TestCase\n def test_${3:case_name}\n ${4}\n end\n end\nsnippet ts\n require "test/unit"\n\n require "tc_${1:test_case_file}"\n require "tc_${2:test_case_file}"${3}\nsnippet as\n assert ${1:test}, "${2:Failure message.}"${3}\nsnippet ase\n assert_equal ${1:expected}, ${2:actual}${3}\nsnippet asne\n assert_not_equal ${1:unexpected}, ${2:actual}${3}\nsnippet asid\n assert_in_delta ${1:expected_float}, ${2:actual_float}, ${3:2 ** -20}${4}\nsnippet asio\n assert_instance_of ${1:ExpectedClass}, ${2:actual_instance}${3}\nsnippet asko\n assert_kind_of ${1:ExpectedKind}, ${2:actual_instance}${3}\nsnippet asn\n assert_nil ${1:instance}${2}\nsnippet asnn\n assert_not_nil ${1:instance}${2}\nsnippet asm\n assert_match /${1:expected_pattern}/, ${2:actual_string}${3}\nsnippet asnm\n assert_no_match /${1:unexpected_pattern}/, ${2:actual_string}${3}\nsnippet aso\n assert_operator ${1:left}, :${2:operator}, ${3:right}${4}\nsnippet asr\n assert_raise ${1:Exception} { ${2} }\nsnippet asrd\n assert_raise ${1:Exception} do\n ${2}\n end\nsnippet asnr\n assert_nothing_raised ${1:Exception} { ${2} }\nsnippet asnrd\n assert_nothing_raised ${1:Exception} do\n ${2}\n end\nsnippet asrt\n assert_respond_to ${1:object}, :${2:method}${3}\nsnippet ass assert_same(..)\n assert_same ${1:expected}, ${2:actual}${3}\nsnippet ass assert_send(..)\n assert_send [${1:object}, :${2:message}, ${3:args}]${4}\nsnippet asns\n assert_not_same ${1:unexpected}, ${2:actual}${3}\nsnippet ast\n assert_throws :${1:expected} { ${2} }\nsnippet astd\n assert_throws :${1:expected} do\n ${2}\n end\nsnippet asnt\n assert_nothing_thrown { ${1} }\nsnippet asntd\n assert_nothing_thrown do\n ${1}\n end\nsnippet fl\n flunk "${1:Failure message.}"${2}\n# Benchmark.bmbm do .. end\nsnippet bm-\n TESTS = ${1:10_000}\n Benchmark.bmbm do |results|\n ${2}\n end\nsnippet rep\n results.report("${1:name}:") { TESTS.times { ${2} }}\n# Marshal.dump(.., file)\nsnippet Md\n File.open(${1:"path/to/file.dump"}, "wb") { |${2:file}| Marshal.dump(${3:obj}, $2) }${4}\n# Mashal.load(obj)\nsnippet Ml\n File.open(${1:"path/to/file.dump"}, "rb") { |${2:file}| Marshal.load($2) }${3}\n# deep_copy(..)\nsnippet deec\n Marshal.load(Marshal.dump(${1:obj_to_copy}))${2}\nsnippet Pn-\n PStore.new(${1:"file_name.pstore"})${2}\nsnippet tra\n transaction(${1:true}) { ${2} }\n# xmlread(..)\nsnippet xml-\n REXML::Document.new(File.read(${1:"path/to/file"}))${2}\n# xpath(..) { .. }\nsnippet xpa\n elements.each(${1:"//Xpath"}) do |${2:node}|\n ${3}\n end\n# class_from_name()\nsnippet clafn\n split("::").inject(Object) { |par, const| par.const_get(const) }\n# singleton_class()\nsnippet sinc\n class << self; self end\nsnippet nam\n namespace :${1:`Filename()`} do\n ${2}\n end\nsnippet tas\n desc "${1:Task description}"\n task :${2:task_name => [:dependent, :tasks]} do\n ${3}\n end\n# block\nsnippet b\n { |${1:var}| ${2} }\nsnippet begin\n begin\n raise \'A test exception.\'\n rescue Exception => e\n puts e.message\n puts e.backtrace.inspect\n else\n # other exception\n ensure\n # always executed\n end\n\n#debugging\nsnippet debug\n require \'ruby-debug\'; debugger; true;\nsnippet pry\n require \'pry\'; binding.pry\n\n#############################################\n# Rails snippets - for pure Ruby, see above #\n#############################################\nsnippet art\n assert_redirected_to ${1::action => "${2:index}"}\nsnippet artnp\n assert_redirected_to ${1:parent}_${2:child}_path(${3:@$1}, ${4:@$2})\nsnippet artnpp\n assert_redirected_to ${1:parent}_${2:child}_path(${3:@$1})\nsnippet artp\n assert_redirected_to ${1:model}_path(${2:@$1})\nsnippet artpp\n assert_redirected_to ${1:model}s_path\nsnippet asd\n assert_difference "${1:Model}.${2:count}", $1 do\n ${3}\n end\nsnippet asnd\n assert_no_difference "${1:Model}.${2:count}" do\n ${3}\n end\nsnippet asre\n assert_response :${1:success}, @response.body${2}\nsnippet asrj\n assert_rjs :${1:replace}, "${2:dom id}"\nsnippet ass assert_select(..)\n assert_select \'${1:path}\', :${2:text} => \'${3:inner_html\' ${4:do}\nsnippet bf\n before_filter :${1:method}\nsnippet bt\n belongs_to :${1:association}\nsnippet crw\n cattr_accessor :${1:attr_names}\nsnippet defcreate\n def create\n @${1:model_class_name} = ${2:ModelClassName}.new(params[:$1])\n\n respond_to do |wants|\n if @$1.save\n flash[:notice] = \'$2 was successfully created.\'\n wants.html { redirect_to(@$1) }\n wants.xml { render :xml => @$1, :status => :created, :location => @$1 }\n else\n wants.html { render :action => "new" }\n wants.xml { render :xml => @$1.errors, :status => :unprocessable_entity }\n end\n end\n end${3}\nsnippet defdestroy\n def destroy\n @${1:model_class_name} = ${2:ModelClassName}.find(params[:id])\n @$1.destroy\n\n respond_to do |wants|\n wants.html { redirect_to($1s_url) }\n wants.xml { head :ok }\n end\n end${3}\nsnippet defedit\n def edit\n @${1:model_class_name} = ${2:ModelClassName}.find(params[:id])\n end\nsnippet defindex\n def index\n @${1:model_class_name} = ${2:ModelClassName}.all\n\n respond_to do |wants|\n wants.html # index.html.erb\n wants.xml { render :xml => @$1s }\n end\n end${3}\nsnippet defnew\n def new\n @${1:model_class_name} = ${2:ModelClassName}.new\n\n respond_to do |wants|\n wants.html # new.html.erb\n wants.xml { render :xml => @$1 }\n end\n end${3}\nsnippet defshow\n def show\n @${1:model_class_name} = ${2:ModelClassName}.find(params[:id])\n\n respond_to do |wants|\n wants.html # show.html.erb\n wants.xml { render :xml => @$1 }\n end\n end${3}\nsnippet defupdate\n def update\n @${1:model_class_name} = ${2:ModelClassName}.find(params[:id])\n\n respond_to do |wants|\n if @$1.update_attributes(params[:$1])\n flash[:notice] = \'$2 was successfully updated.\'\n wants.html { redirect_to(@$1) }\n wants.xml { head :ok }\n else\n wants.html { render :action => "edit" }\n wants.xml { render :xml => @$1.errors, :status => :unprocessable_entity }\n end\n end\n end${3}\nsnippet flash\n flash[:${1:notice}] = "${2}"\nsnippet habtm\n has_and_belongs_to_many :${1:object}, :join_table => "${2:table_name}", :foreign_key => "${3}_id"${4}\nsnippet hm\n has_many :${1:object}\nsnippet hmd\n has_many :${1:other}s, :class_name => "${2:$1}", :foreign_key => "${3:$1}_id", :dependent => :destroy${4}\nsnippet hmt\n has_many :${1:object}, :through => :${2:object}\nsnippet ho\n has_one :${1:object}\nsnippet i18\n I18n.t(\'${1:type.key}\')${2}\nsnippet ist\n <%= image_submit_tag("${1:agree.png}", :id => "${2:id}"${3} %>\nsnippet log\n Rails.logger.${1:debug} ${2}\nsnippet log2\n RAILS_DEFAULT_LOGGER.${1:debug} ${2}\nsnippet logd\n logger.debug { "${1:message}" }${2}\nsnippet loge\n logger.error { "${1:message}" }${2}\nsnippet logf\n logger.fatal { "${1:message}" }${2}\nsnippet logi\n logger.info { "${1:message}" }${2}\nsnippet logw\n logger.warn { "${1:message}" }${2}\nsnippet mapc\n ${1:map}.${2:connect} \'${3:controller/:action/:id}\'\nsnippet mapca\n ${1:map}.catch_all "*${2:anything}", :controller => "${3:default}", :action => "${4:error}"${5}\nsnippet mapr\n ${1:map}.resource :${2:resource}\nsnippet maprs\n ${1:map}.resources :${2:resource}\nsnippet mapwo\n ${1:map}.with_options :${2:controller} => \'${3:thing}\' do |$3|\n ${4}\n end\nsnippet mbs\n before_save :${1:method}\nsnippet mcht\n change_table :${1:table_name} do |t|\n ${2}\n end\nsnippet mp\n map(&:${1:id})\nsnippet mrw\n mattr_accessor :${1:attr_names}\nsnippet oa\n order("${1:field}")\nsnippet od\n order("${1:field} DESC")\nsnippet pa\n params[:${1:id}]${2}\nsnippet ra\n render :action => "${1:action}"\nsnippet ral\n render :action => "${1:action}", :layout => "${2:layoutname}"\nsnippet rest\n respond_to do |wants|\n wants.${1:html} { ${2} }\n end\nsnippet rf\n render :file => "${1:filepath}"\nsnippet rfu\n render :file => "${1:filepath}", :use_full_path => ${2:false}\nsnippet ri\n render :inline => "${1:<%= \'hello\' %>}"\nsnippet ril\n render :inline => "${1:<%= \'hello\' %>}", :locals => { ${2::name} => "${3:value}"${4} }\nsnippet rit\n render :inline => "${1:<%= \'hello\' %>}", :type => ${2::rxml}\nsnippet rjson\n render :json => ${1:text to render}\nsnippet rl\n render :layout => "${1:layoutname}"\nsnippet rn\n render :nothing => ${1:true}\nsnippet rns\n render :nothing => ${1:true}, :status => ${2:401}\nsnippet rp\n render :partial => "${1:item}"\nsnippet rpc\n render :partial => "${1:item}", :collection => ${2:@$1s}\nsnippet rpl\n render :partial => "${1:item}", :locals => { :${2:$1} => ${3:@$1}\nsnippet rpo\n render :partial => "${1:item}", :object => ${2:@$1}\nsnippet rps\n render :partial => "${1:item}", :status => ${2:500}\nsnippet rt\n render :text => "${1:text to render}"\nsnippet rtl\n render :text => "${1:text to render}", :layout => "${2:layoutname}"\nsnippet rtlt\n render :text => "${1:text to render}", :layout => ${2:true}\nsnippet rts\n render :text => "${1:text to render}", :status => ${2:401}\nsnippet ru\n render :update do |${1:page}|\n $1.${2}\n end\nsnippet rxml\n render :xml => ${1:text to render}\nsnippet sc\n scope :${1:name}, :where(:@${2:field} => ${3:value})\nsnippet sl\n scope :${1:name}, lambda do |${2:value}|\n where("${3:field = ?}", ${4:bind var})\n end\nsnippet sha1\n Digest::SHA1.hexdigest(${1:string})\nsnippet sweeper\n class ${1:ModelClassName}Sweeper < ActionController::Caching::Sweeper\n observe $1\n\n def after_save(${2:model_class_name})\n expire_cache($2)\n end\n\n def after_destroy($2)\n expire_cache($2)\n end\n\n def expire_cache($2)\n expire_page\n end\n end\nsnippet tcb\n t.boolean :${1:title}\n ${2}\nsnippet tcbi\n t.binary :${1:title}, :limit => ${2:2}.megabytes\n ${3}\nsnippet tcd\n t.decimal :${1:title}, :precision => ${2:10}, :scale => ${3:2}\n ${4}\nsnippet tcda\n t.date :${1:title}\n ${2}\nsnippet tcdt\n t.datetime :${1:title}\n ${2}\nsnippet tcf\n t.float :${1:title}\n ${2}\nsnippet tch\n t.change :${1:name}, :${2:string}, :${3:limit} => ${4:80}\n ${5}\nsnippet tci\n t.integer :${1:title}\n ${2}\nsnippet tcl\n t.integer :lock_version, :null => false, :default => 0\n ${1}\nsnippet tcr\n t.references :${1:taggable}, :polymorphic => { :default => \'${2:Photo}\' }\n ${3}\nsnippet tcs\n t.string :${1:title}\n ${2}\nsnippet tct\n t.text :${1:title}\n ${2}\nsnippet tcti\n t.time :${1:title}\n ${2}\nsnippet tcts\n t.timestamp :${1:title}\n ${2}\nsnippet tctss\n t.timestamps\n ${1}\nsnippet va\n validates_associated :${1:attribute}\nsnippet vao\n validates_acceptance_of :${1:terms}\nsnippet vc\n validates_confirmation_of :${1:attribute}\nsnippet ve\n validates_exclusion_of :${1:attribute}, :in => ${2:%w( mov avi )}\nsnippet vf\n validates_format_of :${1:attribute}, :with => /${2:regex}/\nsnippet vi\n validates_inclusion_of :${1:attribute}, :in => %w(${2: mov avi })\nsnippet vl\n validates_length_of :${1:attribute}, :within => ${2:3}..${3:20}\nsnippet vn\n validates_numericality_of :${1:attribute}\nsnippet vpo\n validates_presence_of :${1:attribute}\nsnippet vu\n validates_uniqueness_of :${1:attribute}\nsnippet wants\n wants.${1:js|xml|html} { ${2} }\nsnippet wc\n where(${1:"conditions"}${2:, bind_var})\nsnippet wh\n where(${1:field} => ${2:value})\nsnippet xdelete\n xhr :delete, :${1:destroy}, :id => ${2:1}${3}\nsnippet xget\n xhr :get, :${1:show}, :id => ${2:1}${3}\nsnippet xpost\n xhr :post, :${1:create}, :${2:object} => { ${3} }\nsnippet xput\n xhr :put, :${1:update}, :id => ${2:1}, :${3:object} => { ${4} }${5}\nsnippet test\n test "should ${1:do something}" do\n ${2}\n end\n#migrations\nsnippet mac\n add_column :${1:table_name}, :${2:column_name}, :${3:data_type}\nsnippet mrc\n remove_column :${1:table_name}, :${2:column_name}\nsnippet mrnc\n rename_column :${1:table_name}, :${2:old_column_name}, :${3:new_column_name}\nsnippet mcc\n change_column :${1:table}, :${2:column}, :${3:type}\nsnippet mccc\n t.column :${1:title}, :${2:string}\nsnippet mct\n create_table :${1:table_name} do |t|\n t.column :${2:name}, :${3:type}\n end\nsnippet migration\n class ${1:class_name} < ActiveRecord::Migration\n def self.up\n ${2}\n end\n\n def self.down\n end\n end\n\nsnippet trc\n t.remove :${1:column}\nsnippet tre\n t.rename :${1:old_column_name}, :${2:new_column_name}\n ${3}\nsnippet tref\n t.references :${1:model}\n\n#rspec\nsnippet it\n it "${1:spec_name}" do\n ${2}\n end\nsnippet itp\n it "${1:spec_name}"\n ${2}\nsnippet desc\n describe ${1:class_name} do\n ${2}\n end\nsnippet cont\n context "${1:message}" do\n ${2}\n end\nsnippet bef\n before :${1:each} do\n ${2}\n end\nsnippet aft\n after :${1:each} do\n ${2}\n end\n',t.scope="ruby"}) \ No newline at end of file +ace.define("ace/snippets/ruby",["require","exports","module"],function(e,t,n){"use strict";t.snippetText='########################################\n# Ruby snippets - for Rails, see below #\n########################################\n\n# encoding for Ruby 1.9\nsnippet enc\n # encoding: utf-8\n\n# #!/usr/bin/env ruby\nsnippet #!\n #!/usr/bin/env ruby\n # encoding: utf-8\n\n# New Block\nsnippet =b\n =begin rdoc\n ${1}\n =end\nsnippet y\n :yields: ${1:arguments}\nsnippet rb\n #!/usr/bin/env ruby -wKU\nsnippet beg\n begin\n ${3}\n rescue ${1:Exception} => ${2:e}\n end\n\nsnippet req require\n require "${1}"${2}\nsnippet #\n # =>\nsnippet end\n __END__\nsnippet case\n case ${1:object}\n when ${2:condition}\n ${3}\n end\nsnippet when\n when ${1:condition}\n ${2}\nsnippet def\n def ${1:method_name}\n ${2}\n end\nsnippet deft\n def test_${1:case_name}\n ${2}\n end\nsnippet if\n if ${1:condition}\n ${2}\n end\nsnippet ife\n if ${1:condition}\n ${2}\n else\n ${3}\n end\nsnippet elsif\n elsif ${1:condition}\n ${2}\nsnippet unless\n unless ${1:condition}\n ${2}\n end\nsnippet while\n while ${1:condition}\n ${2}\n end\nsnippet for\n for ${1:e} in ${2:c}\n ${3}\n end\nsnippet until\n until ${1:condition}\n ${2}\n end\nsnippet cla class .. end\n class ${1:`substitute(Filename(), \'\\(_\\|^\\)\\(.\\)\', \'\\u\\2\', \'g\')`}\n ${2}\n end\nsnippet cla class .. initialize .. end\n class ${1:`substitute(Filename(), \'\\(_\\|^\\)\\(.\\)\', \'\\u\\2\', \'g\')`}\n def initialize(${2:args})\n ${3}\n end\n end\nsnippet cla class .. < ParentClass .. initialize .. end\n class ${1:`substitute(Filename(), \'\\(_\\|^\\)\\(.\\)\', \'\\u\\2\', \'g\')`} < ${2:ParentClass}\n def initialize(${3:args})\n ${4}\n end\n end\nsnippet cla ClassName = Struct .. do .. end\n ${1:`substitute(Filename(), \'\\(_\\|^\\)\\(.\\)\', \'\\u\\2\', \'g\')`} = Struct.new(:${2:attr_names}) do\n def ${3:method_name}\n ${4}\n end\n end\nsnippet cla class BlankSlate .. initialize .. end\n class ${1:BlankSlate}\n instance_methods.each { |meth| undef_method(meth) unless meth =~ /\\A__/ }\n end\nsnippet cla class << self .. end\n class << ${1:self}\n ${2}\n end\n# class .. < DelegateClass .. initialize .. end\nsnippet cla-\n class ${1:`substitute(Filename(), \'\\(_\\|^\\)\\(.\\)\', \'\\u\\2\', \'g\')`} < DelegateClass(${2:ParentClass})\n def initialize(${3:args})\n super(${4:del_obj})\n\n ${5}\n end\n end\nsnippet mod module .. end\n module ${1:`substitute(Filename(), \'\\(_\\|^\\)\\(.\\)\', \'\\u\\2\', \'g\')`}\n ${2}\n end\nsnippet mod module .. module_function .. end\n module ${1:`substitute(Filename(), \'\\(_\\|^\\)\\(.\\)\', \'\\u\\2\', \'g\')`}\n module_function\n\n ${2}\n end\nsnippet mod module .. ClassMethods .. end\n module ${1:`substitute(Filename(), \'\\(_\\|^\\)\\(.\\)\', \'\\u\\2\', \'g\')`}\n module ClassMethods\n ${2}\n end\n\n module InstanceMethods\n\n end\n\n def self.included(receiver)\n receiver.extend ClassMethods\n receiver.send :include, InstanceMethods\n end\n end\n# attr_reader\nsnippet r\n attr_reader :${1:attr_names}\n# attr_writer\nsnippet w\n attr_writer :${1:attr_names}\n# attr_accessor\nsnippet rw\n attr_accessor :${1:attr_names}\nsnippet atp\n attr_protected :${1:attr_names}\nsnippet ata\n attr_accessible :${1:attr_names}\n# include Enumerable\nsnippet Enum\n include Enumerable\n\n def each(&block)\n ${1}\n end\n# include Comparable\nsnippet Comp\n include Comparable\n\n def <=>(other)\n ${1}\n end\n# extend Forwardable\nsnippet Forw-\n extend Forwardable\n# def self\nsnippet defs\n def self.${1:class_method_name}\n ${2}\n end\n# def method_missing\nsnippet defmm\n def method_missing(meth, *args, &blk)\n ${1}\n end\nsnippet defd\n def_delegator :${1:@del_obj}, :${2:del_meth}, :${3:new_name}\nsnippet defds\n def_delegators :${1:@del_obj}, :${2:del_methods}\nsnippet am\n alias_method :${1:new_name}, :${2:old_name}\nsnippet app\n if __FILE__ == $PROGRAM_NAME\n ${1}\n end\n# usage_if()\nsnippet usai\n if ARGV.${1}\n abort "Usage: #{$PROGRAM_NAME} ${2:ARGS_GO_HERE}"${3}\n end\n# usage_unless()\nsnippet usau\n unless ARGV.${1}\n abort "Usage: #{$PROGRAM_NAME} ${2:ARGS_GO_HERE}"${3}\n end\nsnippet array\n Array.new(${1:10}) { |${2:i}| ${3} }\nsnippet hash\n Hash.new { |${1:hash}, ${2:key}| $1[$2] = ${3} }\nsnippet file File.foreach() { |line| .. }\n File.foreach(${1:"path/to/file"}) { |${2:line}| ${3} }\nsnippet file File.read()\n File.read(${1:"path/to/file"})${2}\nsnippet Dir Dir.global() { |file| .. }\n Dir.glob(${1:"dir/glob/*"}) { |${2:file}| ${3} }\nsnippet Dir Dir[".."]\n Dir[${1:"glob/**/*.rb"}]${2}\nsnippet dir\n Filename.dirname(__FILE__)\nsnippet deli\n delete_if { |${1:e}| ${2} }\nsnippet fil\n fill(${1:range}) { |${2:i}| ${3} }\n# flatten_once()\nsnippet flao\n inject(Array.new) { |${1:arr}, ${2:a}| $1.push(*$2)}${3}\nsnippet zip\n zip(${1:enums}) { |${2:row}| ${3} }\n# downto(0) { |n| .. }\nsnippet dow\n downto(${1:0}) { |${2:n}| ${3} }\nsnippet ste\n step(${1:2}) { |${2:n}| ${3} }\nsnippet tim\n times { |${1:n}| ${2} }\nsnippet upt\n upto(${1:1.0/0.0}) { |${2:n}| ${3} }\nsnippet loo\n loop { ${1} }\nsnippet ea\n each { |${1:e}| ${2} }\nsnippet ead\n each do |${1:e}|\n ${2}\n end\nsnippet eab\n each_byte { |${1:byte}| ${2} }\nsnippet eac- each_char { |chr| .. }\n each_char { |${1:chr}| ${2} }\nsnippet eac- each_cons(..) { |group| .. }\n each_cons(${1:2}) { |${2:group}| ${3} }\nsnippet eai\n each_index { |${1:i}| ${2} }\nsnippet eaid\n each_index do |${1:i}|\n ${2}\n end\nsnippet eak\n each_key { |${1:key}| ${2} }\nsnippet eakd\n each_key do |${1:key}|\n ${2}\n end\nsnippet eal\n each_line { |${1:line}| ${2} }\nsnippet eald\n each_line do |${1:line}|\n ${2}\n end\nsnippet eap\n each_pair { |${1:name}, ${2:val}| ${3} }\nsnippet eapd\n each_pair do |${1:name}, ${2:val}|\n ${3}\n end\nsnippet eas-\n each_slice(${1:2}) { |${2:group}| ${3} }\nsnippet easd-\n each_slice(${1:2}) do |${2:group}|\n ${3}\n end\nsnippet eav\n each_value { |${1:val}| ${2} }\nsnippet eavd\n each_value do |${1:val}|\n ${2}\n end\nsnippet eawi\n each_with_index { |${1:e}, ${2:i}| ${3} }\nsnippet eawid\n each_with_index do |${1:e},${2:i}|\n ${3}\n end\nsnippet reve\n reverse_each { |${1:e}| ${2} }\nsnippet reved\n reverse_each do |${1:e}|\n ${2}\n end\nsnippet inj\n inject(${1:init}) { |${2:mem}, ${3:var}| ${4} }\nsnippet injd\n inject(${1:init}) do |${2:mem}, ${3:var}|\n ${4}\n end\nsnippet map\n map { |${1:e}| ${2} }\nsnippet mapd\n map do |${1:e}|\n ${2}\n end\nsnippet mapwi-\n enum_with_index.map { |${1:e}, ${2:i}| ${3} }\nsnippet sor\n sort { |a, b| ${1} }\nsnippet sorb\n sort_by { |${1:e}| ${2} }\nsnippet ran\n sort_by { rand }\nsnippet all\n all? { |${1:e}| ${2} }\nsnippet any\n any? { |${1:e}| ${2} }\nsnippet cl\n classify { |${1:e}| ${2} }\nsnippet col\n collect { |${1:e}| ${2} }\nsnippet cold\n collect do |${1:e}|\n ${2}\n end\nsnippet det\n detect { |${1:e}| ${2} }\nsnippet detd\n detect do |${1:e}|\n ${2}\n end\nsnippet fet\n fetch(${1:name}) { |${2:key}| ${3} }\nsnippet fin\n find { |${1:e}| ${2} }\nsnippet find\n find do |${1:e}|\n ${2}\n end\nsnippet fina\n find_all { |${1:e}| ${2} }\nsnippet finad\n find_all do |${1:e}|\n ${2}\n end\nsnippet gre\n grep(${1:/pattern/}) { |${2:match}| ${3} }\nsnippet sub\n ${1:g}sub(${2:/pattern/}) { |${3:match}| ${4} }\nsnippet sca\n scan(${1:/pattern/}) { |${2:match}| ${3} }\nsnippet scad\n scan(${1:/pattern/}) do |${2:match}|\n ${3}\n end\nsnippet max\n max { |a, b| ${1} }\nsnippet min\n min { |a, b| ${1} }\nsnippet par\n partition { |${1:e}| ${2} }\nsnippet pard\n partition do |${1:e}|\n ${2}\n end\nsnippet rej\n reject { |${1:e}| ${2} }\nsnippet rejd\n reject do |${1:e}|\n ${2}\n end\nsnippet sel\n select { |${1:e}| ${2} }\nsnippet seld\n select do |${1:e}|\n ${2}\n end\nsnippet lam\n lambda { |${1:args}| ${2} }\nsnippet doo\n do\n ${1}\n end\nsnippet dov\n do |${1:variable}|\n ${2}\n end\nsnippet :\n :${1:key} => ${2:"value"}${3}\nsnippet ope\n open(${1:"path/or/url/or/pipe"}, "${2:w}") { |${3:io}| ${4} }\n# path_from_here()\nsnippet fpath\n File.join(File.dirname(__FILE__), *%2[${1:rel path here}])${2}\n# unix_filter {}\nsnippet unif\n ARGF.each_line${1} do |${2:line}|\n ${3}\n end\n# option_parse {}\nsnippet optp\n require "optparse"\n\n options = {${1:default => "args"}}\n\n ARGV.options do |opts|\n opts.banner = "Usage: #{File.basename($PROGRAM_NAME)}\nsnippet opt\n opts.on( "-${1:o}", "--${2:long-option-name}", ${3:String},\n "${4:Option description.}") do |${5:opt}|\n ${6}\n end\nsnippet tc\n require "test/unit"\n\n require "${1:library_file_name}"\n\n class Test${2:$1} < Test::Unit::TestCase\n def test_${3:case_name}\n ${4}\n end\n end\nsnippet ts\n require "test/unit"\n\n require "tc_${1:test_case_file}"\n require "tc_${2:test_case_file}"${3}\nsnippet as\n assert ${1:test}, "${2:Failure message.}"${3}\nsnippet ase\n assert_equal ${1:expected}, ${2:actual}${3}\nsnippet asne\n assert_not_equal ${1:unexpected}, ${2:actual}${3}\nsnippet asid\n assert_in_delta ${1:expected_float}, ${2:actual_float}, ${3:2 ** -20}${4}\nsnippet asio\n assert_instance_of ${1:ExpectedClass}, ${2:actual_instance}${3}\nsnippet asko\n assert_kind_of ${1:ExpectedKind}, ${2:actual_instance}${3}\nsnippet asn\n assert_nil ${1:instance}${2}\nsnippet asnn\n assert_not_nil ${1:instance}${2}\nsnippet asm\n assert_match /${1:expected_pattern}/, ${2:actual_string}${3}\nsnippet asnm\n assert_no_match /${1:unexpected_pattern}/, ${2:actual_string}${3}\nsnippet aso\n assert_operator ${1:left}, :${2:operator}, ${3:right}${4}\nsnippet asr\n assert_raise ${1:Exception} { ${2} }\nsnippet asrd\n assert_raise ${1:Exception} do\n ${2}\n end\nsnippet asnr\n assert_nothing_raised ${1:Exception} { ${2} }\nsnippet asnrd\n assert_nothing_raised ${1:Exception} do\n ${2}\n end\nsnippet asrt\n assert_respond_to ${1:object}, :${2:method}${3}\nsnippet ass assert_same(..)\n assert_same ${1:expected}, ${2:actual}${3}\nsnippet ass assert_send(..)\n assert_send [${1:object}, :${2:message}, ${3:args}]${4}\nsnippet asns\n assert_not_same ${1:unexpected}, ${2:actual}${3}\nsnippet ast\n assert_throws :${1:expected} { ${2} }\nsnippet astd\n assert_throws :${1:expected} do\n ${2}\n end\nsnippet asnt\n assert_nothing_thrown { ${1} }\nsnippet asntd\n assert_nothing_thrown do\n ${1}\n end\nsnippet fl\n flunk "${1:Failure message.}"${2}\n# Benchmark.bmbm do .. end\nsnippet bm-\n TESTS = ${1:10_000}\n Benchmark.bmbm do |results|\n ${2}\n end\nsnippet rep\n results.report("${1:name}:") { TESTS.times { ${2} }}\n# Marshal.dump(.., file)\nsnippet Md\n File.open(${1:"path/to/file.dump"}, "wb") { |${2:file}| Marshal.dump(${3:obj}, $2) }${4}\n# Mashal.load(obj)\nsnippet Ml\n File.open(${1:"path/to/file.dump"}, "rb") { |${2:file}| Marshal.load($2) }${3}\n# deep_copy(..)\nsnippet deec\n Marshal.load(Marshal.dump(${1:obj_to_copy}))${2}\nsnippet Pn-\n PStore.new(${1:"file_name.pstore"})${2}\nsnippet tra\n transaction(${1:true}) { ${2} }\n# xmlread(..)\nsnippet xml-\n REXML::Document.new(File.read(${1:"path/to/file"}))${2}\n# xpath(..) { .. }\nsnippet xpa\n elements.each(${1:"//Xpath"}) do |${2:node}|\n ${3}\n end\n# class_from_name()\nsnippet clafn\n split("::").inject(Object) { |par, const| par.const_get(const) }\n# singleton_class()\nsnippet sinc\n class << self; self end\nsnippet nam\n namespace :${1:`Filename()`} do\n ${2}\n end\nsnippet tas\n desc "${1:Task description}"\n task :${2:task_name => [:dependent, :tasks]} do\n ${3}\n end\n# block\nsnippet b\n { |${1:var}| ${2} }\nsnippet begin\n begin\n raise \'A test exception.\'\n rescue Exception => e\n puts e.message\n puts e.backtrace.inspect\n else\n # other exception\n ensure\n # always executed\n end\n\n#debugging\nsnippet debug\n require \'ruby-debug\'; debugger; true;\nsnippet pry\n require \'pry\'; binding.pry\n\n#############################################\n# Rails snippets - for pure Ruby, see above #\n#############################################\nsnippet art\n assert_redirected_to ${1::action => "${2:index}"}\nsnippet artnp\n assert_redirected_to ${1:parent}_${2:child}_path(${3:@$1}, ${4:@$2})\nsnippet artnpp\n assert_redirected_to ${1:parent}_${2:child}_path(${3:@$1})\nsnippet artp\n assert_redirected_to ${1:model}_path(${2:@$1})\nsnippet artpp\n assert_redirected_to ${1:model}s_path\nsnippet asd\n assert_difference "${1:Model}.${2:count}", $1 do\n ${3}\n end\nsnippet asnd\n assert_no_difference "${1:Model}.${2:count}" do\n ${3}\n end\nsnippet asre\n assert_response :${1:success}, @response.body${2}\nsnippet asrj\n assert_rjs :${1:replace}, "${2:dom id}"\nsnippet ass assert_select(..)\n assert_select \'${1:path}\', :${2:text} => \'${3:inner_html\' ${4:do}\nsnippet bf\n before_action :${1:method}\nsnippet bt\n belongs_to :${1:association}\nsnippet crw\n cattr_accessor :${1:attr_names}\nsnippet defcreate\n def create\n @${1:model_class_name} = ${2:ModelClassName}.new(params[:$1])\n\n respond_to do |wants|\n if @$1.save\n flash[:notice] = \'$2 was successfully created.\'\n wants.html { redirect_to(@$1) }\n wants.xml { render :xml => @$1, :status => :created, :location => @$1 }\n else\n wants.html { render :action => "new" }\n wants.xml { render :xml => @$1.errors, :status => :unprocessable_entity }\n end\n end\n end${3}\nsnippet defdestroy\n def destroy\n @${1:model_class_name} = ${2:ModelClassName}.find(params[:id])\n @$1.destroy\n\n respond_to do |wants|\n wants.html { redirect_to($1s_url) }\n wants.xml { head :ok }\n end\n end${3}\nsnippet defedit\n def edit\n @${1:model_class_name} = ${2:ModelClassName}.find(params[:id])\n end\nsnippet defindex\n def index\n @${1:model_class_name} = ${2:ModelClassName}.all\n\n respond_to do |wants|\n wants.html # index.html.erb\n wants.xml { render :xml => @$1s }\n end\n end${3}\nsnippet defnew\n def new\n @${1:model_class_name} = ${2:ModelClassName}.new\n\n respond_to do |wants|\n wants.html # new.html.erb\n wants.xml { render :xml => @$1 }\n end\n end${3}\nsnippet defshow\n def show\n @${1:model_class_name} = ${2:ModelClassName}.find(params[:id])\n\n respond_to do |wants|\n wants.html # show.html.erb\n wants.xml { render :xml => @$1 }\n end\n end${3}\nsnippet defupdate\n def update\n @${1:model_class_name} = ${2:ModelClassName}.find(params[:id])\n\n respond_to do |wants|\n if @$1.update_attributes(params[:$1])\n flash[:notice] = \'$2 was successfully updated.\'\n wants.html { redirect_to(@$1) }\n wants.xml { head :ok }\n else\n wants.html { render :action => "edit" }\n wants.xml { render :xml => @$1.errors, :status => :unprocessable_entity }\n end\n end\n end${3}\nsnippet flash\n flash[:${1:notice}] = "${2}"\nsnippet habtm\n has_and_belongs_to_many :${1:object}, :join_table => "${2:table_name}", :foreign_key => "${3}_id"${4}\nsnippet hm\n has_many :${1:object}\nsnippet hmd\n has_many :${1:other}s, :class_name => "${2:$1}", :foreign_key => "${3:$1}_id", :dependent => :destroy${4}\nsnippet hmt\n has_many :${1:object}, :through => :${2:object}\nsnippet ho\n has_one :${1:object}\nsnippet i18\n I18n.t(\'${1:type.key}\')${2}\nsnippet ist\n <%= image_submit_tag("${1:agree.png}", :id => "${2:id}"${3} %>\nsnippet log\n Rails.logger.${1:debug} ${2}\nsnippet log2\n RAILS_DEFAULT_LOGGER.${1:debug} ${2}\nsnippet logd\n logger.debug { "${1:message}" }${2}\nsnippet loge\n logger.error { "${1:message}" }${2}\nsnippet logf\n logger.fatal { "${1:message}" }${2}\nsnippet logi\n logger.info { "${1:message}" }${2}\nsnippet logw\n logger.warn { "${1:message}" }${2}\nsnippet mapc\n ${1:map}.${2:connect} \'${3:controller/:action/:id}\'\nsnippet mapca\n ${1:map}.catch_all "*${2:anything}", :controller => "${3:default}", :action => "${4:error}"${5}\nsnippet mapr\n ${1:map}.resource :${2:resource}\nsnippet maprs\n ${1:map}.resources :${2:resource}\nsnippet mapwo\n ${1:map}.with_options :${2:controller} => \'${3:thing}\' do |$3|\n ${4}\n end\nsnippet mbs\n before_save :${1:method}\nsnippet mcht\n change_table :${1:table_name} do |t|\n ${2}\n end\nsnippet mp\n map(&:${1:id})\nsnippet mrw\n mattr_accessor :${1:attr_names}\nsnippet oa\n order("${1:field}")\nsnippet od\n order("${1:field} DESC")\nsnippet pa\n params[:${1:id}]${2}\nsnippet ra\n render :action => "${1:action}"\nsnippet ral\n render :action => "${1:action}", :layout => "${2:layoutname}"\nsnippet rest\n respond_to do |wants|\n wants.${1:html} { ${2} }\n end\nsnippet rf\n render :file => "${1:filepath}"\nsnippet rfu\n render :file => "${1:filepath}", :use_full_path => ${2:false}\nsnippet ri\n render :inline => "${1:<%= \'hello\' %>}"\nsnippet ril\n render :inline => "${1:<%= \'hello\' %>}", :locals => { ${2::name} => "${3:value}"${4} }\nsnippet rit\n render :inline => "${1:<%= \'hello\' %>}", :type => ${2::rxml}\nsnippet rjson\n render :json => ${1:text to render}\nsnippet rl\n render :layout => "${1:layoutname}"\nsnippet rn\n render :nothing => ${1:true}\nsnippet rns\n render :nothing => ${1:true}, :status => ${2:401}\nsnippet rp\n render :partial => "${1:item}"\nsnippet rpc\n render :partial => "${1:item}", :collection => ${2:@$1s}\nsnippet rpl\n render :partial => "${1:item}", :locals => { :${2:$1} => ${3:@$1}\nsnippet rpo\n render :partial => "${1:item}", :object => ${2:@$1}\nsnippet rps\n render :partial => "${1:item}", :status => ${2:500}\nsnippet rt\n render :text => "${1:text to render}"\nsnippet rtl\n render :text => "${1:text to render}", :layout => "${2:layoutname}"\nsnippet rtlt\n render :text => "${1:text to render}", :layout => ${2:true}\nsnippet rts\n render :text => "${1:text to render}", :status => ${2:401}\nsnippet ru\n render :update do |${1:page}|\n $1.${2}\n end\nsnippet rxml\n render :xml => ${1:text to render}\nsnippet sc\n scope :${1:name}, :where(:@${2:field} => ${3:value})\nsnippet sl\n scope :${1:name}, lambda do |${2:value}|\n where("${3:field = ?}", ${4:bind var})\n end\nsnippet sha1\n Digest::SHA1.hexdigest(${1:string})\nsnippet sweeper\n class ${1:ModelClassName}Sweeper < ActionController::Caching::Sweeper\n observe $1\n\n def after_save(${2:model_class_name})\n expire_cache($2)\n end\n\n def after_destroy($2)\n expire_cache($2)\n end\n\n def expire_cache($2)\n expire_page\n end\n end\nsnippet tcb\n t.boolean :${1:title}\n ${2}\nsnippet tcbi\n t.binary :${1:title}, :limit => ${2:2}.megabytes\n ${3}\nsnippet tcd\n t.decimal :${1:title}, :precision => ${2:10}, :scale => ${3:2}\n ${4}\nsnippet tcda\n t.date :${1:title}\n ${2}\nsnippet tcdt\n t.datetime :${1:title}\n ${2}\nsnippet tcf\n t.float :${1:title}\n ${2}\nsnippet tch\n t.change :${1:name}, :${2:string}, :${3:limit} => ${4:80}\n ${5}\nsnippet tci\n t.integer :${1:title}\n ${2}\nsnippet tcl\n t.integer :lock_version, :null => false, :default => 0\n ${1}\nsnippet tcr\n t.references :${1:taggable}, :polymorphic => { :default => \'${2:Photo}\' }\n ${3}\nsnippet tcs\n t.string :${1:title}\n ${2}\nsnippet tct\n t.text :${1:title}\n ${2}\nsnippet tcti\n t.time :${1:title}\n ${2}\nsnippet tcts\n t.timestamp :${1:title}\n ${2}\nsnippet tctss\n t.timestamps\n ${1}\nsnippet va\n validates_associated :${1:attribute}\nsnippet vao\n validates_acceptance_of :${1:terms}\nsnippet vc\n validates_confirmation_of :${1:attribute}\nsnippet ve\n validates_exclusion_of :${1:attribute}, :in => ${2:%w( mov avi )}\nsnippet vf\n validates_format_of :${1:attribute}, :with => /${2:regex}/\nsnippet vi\n validates_inclusion_of :${1:attribute}, :in => %w(${2: mov avi })\nsnippet vl\n validates_length_of :${1:attribute}, :within => ${2:3}..${3:20}\nsnippet vn\n validates_numericality_of :${1:attribute}\nsnippet vpo\n validates_presence_of :${1:attribute}\nsnippet vu\n validates_uniqueness_of :${1:attribute}\nsnippet wants\n wants.${1:js|xml|html} { ${2} }\nsnippet wc\n where(${1:"conditions"}${2:, bind_var})\nsnippet wh\n where(${1:field} => ${2:value})\nsnippet xdelete\n xhr :delete, :${1:destroy}, :id => ${2:1}${3}\nsnippet xget\n xhr :get, :${1:show}, :id => ${2:1}${3}\nsnippet xpost\n xhr :post, :${1:create}, :${2:object} => { ${3} }\nsnippet xput\n xhr :put, :${1:update}, :id => ${2:1}, :${3:object} => { ${4} }${5}\nsnippet test\n test "should ${1:do something}" do\n ${2}\n end\n#migrations\nsnippet mac\n add_column :${1:table_name}, :${2:column_name}, :${3:data_type}\nsnippet mrc\n remove_column :${1:table_name}, :${2:column_name}\nsnippet mrnc\n rename_column :${1:table_name}, :${2:old_column_name}, :${3:new_column_name}\nsnippet mcc\n change_column :${1:table}, :${2:column}, :${3:type}\nsnippet mccc\n t.column :${1:title}, :${2:string}\nsnippet mct\n create_table :${1:table_name} do |t|\n t.column :${2:name}, :${3:type}\n end\nsnippet migration\n class ${1:class_name} < ActiveRecord::Migration[4.2]\n def self.up\n ${2}\n end\n\n def self.down\n end\n end\n\nsnippet trc\n t.remove :${1:column}\nsnippet tre\n t.rename :${1:old_column_name}, :${2:new_column_name}\n ${3}\nsnippet tref\n t.references :${1:model}\n\n#rspec\nsnippet it\n it "${1:spec_name}" do\n ${2}\n end\nsnippet itp\n it "${1:spec_name}"\n ${2}\nsnippet desc\n describe ${1:class_name} do\n ${2}\n end\nsnippet cont\n context "${1:message}" do\n ${2}\n end\nsnippet bef\n before :${1:each} do\n ${2}\n end\nsnippet aft\n after :${1:each} do\n ${2}\n end\n',t.scope="ruby"}) \ No newline at end of file diff --git a/spec/components/cache_spec.rb b/spec/components/cache_spec.rb index 23d9983f075..1f531f62f61 100644 --- a/spec/components/cache_spec.rb +++ b/spec/components/cache_spec.rb @@ -41,7 +41,7 @@ describe Cache do cache.delete("key") cache.delete("bla") - key = cache.namespaced_key("key") + key = cache.normalize_key("key") cache.fetch("key", expires_in: 1.minute) do "bob" @@ -52,7 +52,7 @@ describe Cache do # we always expire withing a day cache.fetch("bla") { "hi" } - key = cache.namespaced_key("bla") + key = cache.normalize_key("bla") expect($redis.ttl(key)).to be_within(2.seconds).of(1.day) end diff --git a/spec/components/column_dropper_spec.rb b/spec/components/column_dropper_spec.rb index 12e01fb9fd7..3fd75815905 100644 --- a/spec/components/column_dropper_spec.rb +++ b/spec/components/column_dropper_spec.rb @@ -111,7 +111,7 @@ RSpec.describe ColumnDropper do expect( ActiveRecord::Base.exec_sql("SELECT * FROM #{table_name};").values - ).to include(["2", "something@email.com"]) + ).to include([2, "something@email.com"]) end it 'should prevent insertions to the readonly column' do @@ -134,7 +134,7 @@ RSpec.describe ColumnDropper do expect( ActiveRecord::Base.exec_sql("SELECT * FROM #{table_name} WHERE topic_id = 2;").values - ).to include(["2", nil]) + ).to include([2, nil]) end end end diff --git a/spec/components/cooked_post_processor_spec.rb b/spec/components/cooked_post_processor_spec.rb index 5bdef69864e..e56f364cc66 100644 --- a/spec/components/cooked_post_processor_spec.rb +++ b/spec/components/cooked_post_processor_spec.rb @@ -75,8 +75,13 @@ describe CookedPostProcessor do end it "cleans the reverse index up for the current post" do - PostUpload.expects(:delete_all).with(post_id: post.id) cpp.keep_reverse_index_up_to_date + + post_uploads_ids = post.post_uploads.pluck(:id) + + cpp.keep_reverse_index_up_to_date + + expect(post.reload.post_uploads.pluck(:id)).to_not eq(post_uploads_ids) end end diff --git a/spec/components/freedom_patches/schema_migration_details_spec.rb b/spec/components/freedom_patches/schema_migration_details_spec.rb index 8f04dbc06b9..b4f378c0698 100644 --- a/spec/components/freedom_patches/schema_migration_details_spec.rb +++ b/spec/components/freedom_patches/schema_migration_details_spec.rb @@ -7,7 +7,7 @@ describe FreedomPatches::SchemaMigrationDetails do class SchemaMigrationDetail < ActiveRecord::Base end - class TestMigration < ActiveRecord::Migration + class TestMigration < ActiveRecord::Migration[4.2] def up sleep 0.001 end diff --git a/spec/components/sql_builder_spec.rb b/spec/components/sql_builder_spec.rb index 5fbad00228c..4ccdde49a25 100644 --- a/spec/components/sql_builder_spec.rb +++ b/spec/components/sql_builder_spec.rb @@ -48,12 +48,12 @@ describe SqlBuilder do end it "should allow for 1 param exec" do - expect(@builder.exec(a: 1, b: 2).values[0][0]).to eq('1') + expect(@builder.exec(a: 1, b: 2).values[0][0]).to eq(1) end it "should allow for a single where" do @builder.where(":a = 1") - expect(@builder.exec(a: 1, b: 2).values[0][0]).to eq('1') + expect(@builder.exec(a: 1, b: 2).values[0][0]).to eq(1) end it "should allow where chaining" do @@ -64,11 +64,11 @@ describe SqlBuilder do it "should allow order by" do expect(@builder.order_by("A desc").limit(1) - .exec(a: 1, b: 2).values[0][0]).to eq("2") + .exec(a: 1, b: 2).values[0][0]).to eq(2) end it "should allow offset" do expect(@builder.order_by("A desc").offset(1) - .exec(a: 1, b: 2).values[0][0]).to eq("1") + .exec(a: 1, b: 2).values[0][0]).to eq(1) end end diff --git a/spec/components/stylesheet/compiler_spec.rb b/spec/components/stylesheet/compiler_spec.rb index 47420c18a1d..0c9bf8bc127 100644 --- a/spec/components/stylesheet/compiler_spec.rb +++ b/spec/components/stylesheet/compiler_spec.rb @@ -14,16 +14,16 @@ describe Stylesheet::Compiler do end it "supports asset-url" do - css, _map = Stylesheet::Compiler.compile(".body{background-image: asset-url('foo.png');}", "test.scss") + css, _map = Stylesheet::Compiler.compile(".body{background-image: asset-url('/images/favicons/github.png');}", "test.scss") - expect(css).to include("url('/foo.png')") + expect(css).to include("url('/images/favicons/github.png')") expect(css).not_to include('asset-url') end it "supports image-url" do - css, _map = Stylesheet::Compiler.compile(".body{background-image: image-url('foo.png');}", "test.scss") + css, _map = Stylesheet::Compiler.compile(".body{background-image: image-url('/favicons/github.png');}", "test.scss") - expect(css).to include("url('/images/foo.png')") + expect(css).to include("url('/favicons/github.png')") expect(css).not_to include('image-url') end end diff --git a/spec/components/topic_query_spec.rb b/spec/components/topic_query_spec.rb index b7d38eb0364..add11d20666 100644 --- a/spec/components/topic_query_spec.rb +++ b/spec/components/topic_query_spec.rb @@ -82,12 +82,15 @@ describe TopicQuery do topic_query = TopicQuery.new(user) results = topic_query.send(:default_results) - expect(topic_query.prioritize_pinned_topics(results, per_page: per_page, - page: 0)).to eq(topics[0...per_page]) - - expect(topic_query.prioritize_pinned_topics(results, per_page: per_page, - page: 1)).to eq(topics[per_page...num_topics]) + expect(topic_query.prioritize_pinned_topics(results, + per_page: per_page, + page: 0) + ).to eq(topics[0...per_page]) + expect(topic_query.prioritize_pinned_topics(results, + per_page: per_page, + page: 1) + ).to eq(topics[per_page...num_topics]) end end diff --git a/spec/controllers/about_controller_spec.rb b/spec/controllers/about_controller_spec.rb index 4589fda3510..647e50c4976 100644 --- a/spec/controllers/about_controller_spec.rb +++ b/spec/controllers/about_controller_spec.rb @@ -6,20 +6,23 @@ describe AboutController do it "should display the about page for anonymous user when login_required is false" do SiteSetting.login_required = false - xhr :get, :index + get :index + expect(response).to be_success end it 'should redirect to login page for anonymous user when login_required is true' do SiteSetting.login_required = true - xhr :get, :index + get :index + expect(response).to redirect_to '/login' end it "should display the about page for logged in user when login_required is true" do SiteSetting.login_required = true log_in - xhr :get, :index + get :index + expect(response).to be_success end end diff --git a/spec/controllers/admin/admin_controller_spec.rb b/spec/controllers/admin/admin_controller_spec.rb index 8cf851b51a2..54db42f3f96 100644 --- a/spec/controllers/admin/admin_controller_spec.rb +++ b/spec/controllers/admin/admin_controller_spec.rb @@ -5,12 +5,14 @@ describe Admin::AdminController do context 'index' do it 'needs you to be logged in' do - expect { xhr :get, :index }.to raise_error(Discourse::NotLoggedIn) + expect do + get :index, format: :json + end.to raise_error(Discourse::NotLoggedIn) end it "raises an error if you aren't an admin" do user = log_in - xhr :get, :index + get :index, format: :json expect(response).to be_forbidden end diff --git a/spec/controllers/admin/api_controller_spec.rb b/spec/controllers/admin/api_controller_spec.rb index 2805a2d4b1d..af72b0529ad 100644 --- a/spec/controllers/admin/api_controller_spec.rb +++ b/spec/controllers/admin/api_controller_spec.rb @@ -10,7 +10,7 @@ describe Admin::ApiController do context '.index' do it "succeeds" do - xhr :get, :index + get :index, format: :json expect(response).to be_success end end @@ -19,14 +19,14 @@ describe Admin::ApiController do let(:api_key) { Fabricate(:api_key) } it "returns 404 when there is no key" do - xhr :put, :regenerate_key, id: 1234 + put :regenerate_key, params: { id: 1234 }, format: :json expect(response).not_to be_success expect(response.status).to eq(404) end it "delegates to the api key's `regenerate!` method" do ApiKey.any_instance.expects(:regenerate!) - xhr :put, :regenerate_key, id: api_key.id + put :regenerate_key, params: { id: api_key.id }, format: :json end end @@ -34,22 +34,22 @@ describe Admin::ApiController do let(:api_key) { Fabricate(:api_key) } it "returns 404 when there is no key" do - xhr :delete, :revoke_key, id: 1234 + delete :revoke_key, params: { id: 1234 }, format: :json expect(response).not_to be_success expect(response.status).to eq(404) end it "delegates to the api key's `regenerate!` method" do ApiKey.any_instance.expects(:destroy) - xhr :delete, :revoke_key, id: api_key.id + delete :revoke_key, params: { id: api_key.id }, format: :json end end context '.create_master_key' do it "creates a record" do - expect { - xhr :post, :create_master_key - }.to change(ApiKey, :count).by(1) + expect do + post :create_master_key, format: :json + end.to change(ApiKey, :count).by(1) end end diff --git a/spec/controllers/admin/backups_controller_spec.rb b/spec/controllers/admin/backups_controller_spec.rb index 14014d5c721..fd841d548bb 100644 --- a/spec/controllers/admin/backups_controller_spec.rb +++ b/spec/controllers/admin/backups_controller_spec.rb @@ -26,7 +26,7 @@ describe Admin::BackupsController do BackupRestore.expects(:logs).returns([]) subject.expects(:store_preloaded).with("logs", "[]") - xhr :get, :index, format: :html + get :index, format: :html, xhr: true expect(response).to be_success end @@ -38,7 +38,7 @@ describe Admin::BackupsController do it "returns a list of all the backups" do Backup.expects(:all).returns([Backup.new("backup1"), Backup.new("backup2")]) - xhr :get, :index, format: :json + get :index, format: :json, xhr: true expect(response).to be_success @@ -56,7 +56,7 @@ describe Admin::BackupsController do it "returns the current backups status" do BackupRestore.expects(:operations_status) - xhr :get, :status + get :status, format: :json expect(response).to be_success end @@ -68,7 +68,9 @@ describe Admin::BackupsController do it "starts a backup" do BackupRestore.expects(:backup!).with(@admin.id, publish_to_message_bus: true, with_uploads: false, client_id: "foo") - xhr :post, :create, with_uploads: false, client_id: "foo" + post :create, params: { + with_uploads: false, client_id: "foo" + }, format: :json expect(response).to be_success end @@ -87,7 +89,7 @@ describe Admin::BackupsController do StaffActionLogger.any_instance.expects(:log_backup_download).once - get :show, id: backup_filename, token: token + get :show, params: { id: backup_filename, token: token }, format: :json expect(response.headers['Content-Length']).to eq("5") expect(response.headers['Content-Disposition']).to match(/attachment; filename/) @@ -104,7 +106,7 @@ describe Admin::BackupsController do Backup.create_from_filename(backup_filename) - get :show, id: backup_filename, token: "bad_value" + get :show, params: { id: backup_filename, token: "bad_value" }, xhr: true expect(response.status).to eq(422) ensure @@ -116,7 +118,7 @@ describe Admin::BackupsController do token = EmailBackupToken.set(@admin.id) Backup.expects(:[]).returns(nil) - get :show, id: backup_filename, token: token + get :show, params: { id: backup_filename, token: token }, format: :json EmailBackupToken.del(@admin.id) @@ -133,13 +135,13 @@ describe Admin::BackupsController do Backup.expects(:[]).with(backup_filename).returns(b) Jobs.expects(:enqueue).with(:download_backup_email, has_entries(to_address: @admin.email)) - xhr :put, :email, id: backup_filename + put :email, params: { id: backup_filename }, format: :json expect(response).to be_success end it "returns 404 when the backup does not exist" do - xhr :put, :email, id: backup_filename + put :email, params: { id: backup_filename }, format: :json expect(response).to be_not_found end @@ -156,7 +158,7 @@ describe Admin::BackupsController do StaffActionLogger.any_instance.expects(:log_backup_destroy).with(b).once - xhr :delete, :destroy, id: backup_filename + delete :destroy, params: { id: backup_filename }, format: :json expect(response).to be_success end @@ -164,7 +166,7 @@ describe Admin::BackupsController do it "doesn't remove the backup if not found" do Backup.expects(:[]).with(backup_filename).returns(nil) b.expects(:remove).never - xhr :delete, :destroy, id: backup_filename + delete :destroy, params: { id: backup_filename }, format: :json expect(response).not_to be_success end @@ -179,7 +181,7 @@ describe Admin::BackupsController do BackupRestore.expects(:logs).returns([]) subject.expects(:store_preloaded).with("logs", "[]") - xhr :get, :logs, format: :html + get :logs, format: :html, xhr: true expect(response).to be_success end @@ -191,7 +193,7 @@ describe Admin::BackupsController do expect(SiteSetting.disable_emails).to eq(false) BackupRestore.expects(:restore!).with(@admin.id, filename: backup_filename, publish_to_message_bus: true, client_id: "foo") - xhr :post, :restore, id: backup_filename, client_id: "foo" + post :restore, params: { id: backup_filename, client_id: "foo" }, format: :json expect(SiteSetting.disable_emails).to eq(true) expect(response).to be_success @@ -204,7 +206,7 @@ describe Admin::BackupsController do it "enables readonly mode" do Discourse.expects(:enable_readonly_mode) - expect { xhr :put, :readonly, enable: true } + expect { put :readonly, params: { enable: true }, format: :json } .to change { UserHistory.count }.by(1) expect(response).to be_success @@ -218,7 +220,7 @@ describe Admin::BackupsController do it "disables readonly mode" do Discourse.expects(:disable_readonly_mode) - expect { xhr :put, :readonly, enable: false } + expect { put :readonly, params: { enable: false }, format: :json } .to change { UserHistory.count }.by(1) expect(response).to be_success @@ -236,7 +238,10 @@ describe Admin::BackupsController do it "should raise an error" do ['灰色.tar.gz', '; echo \'haha\'.tar.gz'].each do |invalid_filename| described_class.any_instance.expects(:has_enough_space_on_disk?).returns(true) - xhr :post, :upload_backup_chunk, resumableFilename: invalid_filename, resumableTotalSize: 1 + + post :upload_backup_chunk, params: { + resumableFilename: invalid_filename, resumableTotalSize: 1 + } expect(response.status).to eq(415) expect(response.body).to eq(I18n.t('backup.invalid_filename')) @@ -251,7 +256,7 @@ describe Admin::BackupsController do filename = 'test_Site-0123456789.tar.gz' - xhr :post, :upload_backup_chunk, + post :upload_backup_chunk, params: { resumableFilename: filename, resumableTotalSize: 1, resumableIdentifier: 'test', @@ -259,6 +264,7 @@ describe Admin::BackupsController do resumableChunkSize: '1', resumableCurrentChunkSize: '1', file: fixture_file_upload(Tempfile.new) + }, format: :json expect(response.status).to eq(200) expect(response.body).to eq("") diff --git a/spec/controllers/admin/badges_controller_spec.rb b/spec/controllers/admin/badges_controller_spec.rb index dad6e6b5702..3fea129cf69 100644 --- a/spec/controllers/admin/badges_controller_spec.rb +++ b/spec/controllers/admin/badges_controller_spec.rb @@ -8,7 +8,7 @@ describe Admin::BadgesController do context 'index' do it 'returns badge index' do - xhr :get, :index + get :index, format: :json expect(response).to be_success end end @@ -16,13 +16,21 @@ describe Admin::BadgesController do context 'preview' do it 'allows preview enable_badge_sql is enabled' do SiteSetting.enable_badge_sql = true - result = xhr :get, :preview, sql: 'select id as user_id, created_at granted_at from users' - expect(JSON.parse(result.body)["grant_count"]).to be > 0 + + get :preview, params: { + sql: 'select id as user_id, created_at granted_at from users' + }, format: :json + + expect(JSON.parse(response.body)["grant_count"]).to be > 0 end it 'does not allow anything if enable_badge_sql is disabled' do SiteSetting.enable_badge_sql = false - result = xhr :get, :preview, sql: 'select id as user_id, created_at granted_at from users' - expect(result.status).to eq(403) + + get :preview, params: { + sql: 'select id as user_id, created_at granted_at from users' + }, format: :json + + expect(response.status).to eq(403) end end @@ -31,9 +39,13 @@ describe Admin::BadgesController do it 'can create badges correctly' do SiteSetting.enable_badge_sql = true - result = xhr :post, :create, name: 'test', query: 'select 1 as user_id, null as granted_at', badge_type_id: 1 - json = JSON.parse(result.body) - expect(result.status).to eq(200) + + post :create, params: { + name: 'test', query: 'select 1 as user_id, null as granted_at', badge_type_id: 1 + }, format: :json + + json = JSON.parse(response.body) + expect(response.status).to eq(200) expect(json["badge"]["name"]).to eq('test') expect(json["badge"]["query"]).to eq('select 1 as user_id, null as granted_at') end @@ -51,37 +63,33 @@ describe Admin::BadgesController do names = groupings.map { |g| g.name } ids = groupings.map { |g| g.id.to_s } - xhr :post, :save_badge_groupings, ids: ids, names: names + post :save_badge_groupings, params: { ids: ids, names: names }, format: :json groupings2 = BadgeGrouping.all.order(:position).to_a expect(groupings2.map { |g| g.name }).to eq(names) expect((groupings.map(&:id) - groupings2.map { |g| g.id }).compact).to be_blank - expect(::JSON.parse(response.body)["badge_groupings"].length).to eq(groupings2.length) end end context '.badge_types' do - it 'returns success' do - xhr :get, :badge_types - expect(response).to be_success - end - it 'returns JSON' do - xhr :get, :badge_types + get :badge_types, format: :json + + expect(response).to be_success expect(::JSON.parse(response.body)["badge_types"]).to be_present end end context '.destroy' do it 'returns success' do - xhr :delete, :destroy, id: badge.id + delete :destroy, params: { id: badge.id }, format: :json expect(response).to be_success end it 'deletes the badge' do - xhr :delete, :destroy, id: badge.id + delete :destroy, params: { id: badge.id }, format: :json expect(Badge.where(id: badge.id).count).to eq(0) end end @@ -92,9 +100,10 @@ describe Admin::BadgesController do editor_badge = Badge.find(Badge::Editor) editor_badge_name = editor_badge.name - xhr :put, :update, - id: editor_badge.id, - name: "123456" + put :update, params: { + id: editor_badge.id, + name: "123456" + }, format: :json expect(response).to be_success editor_badge.reload @@ -107,14 +116,15 @@ describe Admin::BadgesController do SiteSetting.enable_badge_sql = false - xhr :put, :update, - id: badge.id, - name: "123456", - query: "select id user_id, created_at granted_at from users", - badge_type_id: badge.badge_type_id, - allow_title: false, - multiple_grant: false, - enabled: true + put :update, params: { + id: badge.id, + name: "123456", + query: "select id user_id, created_at granted_at from users", + badge_type_id: badge.badge_type_id, + allow_title: false, + multiple_grant: false, + enabled: true + }, format: :json expect(response).to be_success badge.reload @@ -126,14 +136,15 @@ describe Admin::BadgesController do SiteSetting.enable_badge_sql = true sql = "select id user_id, created_at granted_at from users" - xhr :put, :update, - id: badge.id, - name: "123456", - query: sql, - badge_type_id: badge.badge_type_id, - allow_title: false, - multiple_grant: false, - enabled: true + put :update, params: { + id: badge.id, + name: "123456", + query: sql, + badge_type_id: badge.badge_type_id, + allow_title: false, + multiple_grant: false, + enabled: true + }, format: :json expect(response).to be_success badge.reload diff --git a/spec/controllers/admin/color_schemes_controller_spec.rb b/spec/controllers/admin/color_schemes_controller_spec.rb index 7bc1941e8b8..6b11e219fb8 100644 --- a/spec/controllers/admin/color_schemes_controller_spec.rb +++ b/spec/controllers/admin/color_schemes_controller_spec.rb @@ -17,33 +17,29 @@ describe Admin::ColorSchemesController do } } describe "index" do - it "returns success" do - xhr :get, :index - expect(response).to be_success - end - it "returns JSON" do Fabricate(:color_scheme) - xhr :get, :index + get :index, format: :json + + expect(response).to be_success expect(::JSON.parse(response.body)).to be_present end end describe "create" do - it "returns success" do - xhr :post, :create, valid_params - expect(response).to be_success - end - it "returns JSON" do - xhr :post, :create, valid_params + post :create, params: valid_params, format: :json + + expect(response).to be_success expect(::JSON.parse(response.body)['id']).to be_present end it "returns failure with invalid params" do params = valid_params params[:color_scheme][:colors][0][:hex] = 'cool color please' - xhr :post, :create, valid_params + + post :create, params: valid_params, format: :json + expect(response).not_to be_success expect(::JSON.parse(response.body)['errors']).to be_present end @@ -54,13 +50,13 @@ describe Admin::ColorSchemesController do it "returns success" do ColorSchemeRevisor.expects(:revise).returns(existing) - xhr :put, :update, valid_params.merge(id: existing.id) + put :update, params: valid_params.merge(id: existing.id), format: :json expect(response).to be_success end it "returns JSON" do ColorSchemeRevisor.expects(:revise).returns(existing) - xhr :put, :update, valid_params.merge(id: existing.id) + put :update, params: valid_params.merge(id: existing.id), format: :json expect(::JSON.parse(response.body)['id']).to be_present end @@ -69,7 +65,7 @@ describe Admin::ColorSchemesController do params = valid_params.merge(id: color_scheme.id) params[:color_scheme][:colors][0][:name] = color_scheme.colors.first.name params[:color_scheme][:colors][0][:hex] = 'cool color please' - xhr :put, :update, params + put :update, params: params, format: :json expect(response).not_to be_success expect(::JSON.parse(response.body)['errors']).to be_present end @@ -80,7 +76,7 @@ describe Admin::ColorSchemesController do it "returns success" do expect { - xhr :delete, :destroy, id: existing.id + delete :destroy, params: { id: existing.id }, format: :json }.to change { ColorScheme.count }.by(-1) expect(response).to be_success end diff --git a/spec/controllers/admin/dashboard_controller_spec.rb b/spec/controllers/admin/dashboard_controller_spec.rb index 6d862eecc1c..c190f72b7ea 100644 --- a/spec/controllers/admin/dashboard_controller_spec.rb +++ b/spec/controllers/admin/dashboard_controller_spec.rb @@ -15,20 +15,16 @@ describe Admin::DashboardController do let!(:admin) { log_in(:admin) } context '.index' do - it 'should be successful' do - xhr :get, :index - expect(response).to be_successful - end - context 'version checking is enabled' do before do SiteSetting.version_checks = true end it 'returns discourse version info' do - xhr :get, :index - json = JSON.parse(response.body) - expect(json['version_check']).to be_present + get :index, format: :json + + expect(response).to be_success + expect(JSON.parse(response.body)['version_check']).to be_present end end @@ -38,7 +34,7 @@ describe Admin::DashboardController do end it 'does not return discourse version info' do - xhr :get, :index + get :index, format: :json json = JSON.parse(response.body) expect(json['version_check']).not_to be_present end @@ -46,19 +42,15 @@ describe Admin::DashboardController do end context '.problems' do - it 'should be successful' do - AdminDashboardData.stubs(:fetch_problems).returns([]) - xhr :get, :problems - expect(response).to be_successful - end - context 'when there are no problems' do before do AdminDashboardData.stubs(:fetch_problems).returns([]) end it 'returns an empty array' do - xhr :get, :problems + get :problems, format: :json + + expect(response).to be_success json = JSON.parse(response.body) expect(json['problems'].size).to eq(0) end @@ -70,7 +62,7 @@ describe Admin::DashboardController do end it 'returns an array of strings' do - xhr :get, :problems + get :problems, format: :json json = JSON.parse(response.body) expect(json['problems'].size).to eq(2) expect(json['problems'][0]).to be_a(String) diff --git a/spec/controllers/admin/email_controller_spec.rb b/spec/controllers/admin/email_controller_spec.rb index aa78de722f5..e778f8b7d95 100644 --- a/spec/controllers/admin/email_controller_spec.rb +++ b/spec/controllers/admin/email_controller_spec.rb @@ -10,10 +10,14 @@ describe Admin::EmailController do context '.index' do before do - subject.expects(:action_mailer_settings).returns(username: 'username', - password: 'secret') + subject + .expects(:action_mailer_settings) + .returns( + username: 'username', + password: 'secret' + ) - xhr :get, :index + get :index, format: :json end it 'does not include the password in the response' do @@ -27,7 +31,7 @@ describe Admin::EmailController do context '.sent' do before do - xhr :get, :sent + get :sent, format: :json end subject { response } @@ -36,7 +40,7 @@ describe Admin::EmailController do context '.skipped' do before do - xhr :get, :skipped + get :skipped, format: :json end subject { response } @@ -45,7 +49,9 @@ describe Admin::EmailController do context '.test' do it 'raises an error without the email parameter' do - expect { xhr :post, :test }.to raise_error(ActionController::ParameterMissing) + expect do + post :test, format: :json + end.to raise_error(ActionController::ParameterMissing) end context 'with an email address' do @@ -53,18 +59,23 @@ describe Admin::EmailController do job_mock = mock Jobs::TestEmail.expects(:new).returns(job_mock) job_mock.expects(:execute).with(to_address: 'eviltrout@test.domain') - xhr :post, :test, email_address: 'eviltrout@test.domain' + post :test, params: { email_address: 'eviltrout@test.domain' }, format: :json end end end context '.preview_digest' do it 'raises an error without the last_seen_at parameter' do - expect { xhr :get, :preview_digest }.to raise_error(ActionController::ParameterMissing) + expect do + get :preview_digest, format: :json + end.to raise_error(ActionController::ParameterMissing) end it "previews the digest" do - xhr :get, :preview_digest, last_seen_at: 1.week.ago, username: user.username + get :preview_digest, params: { + last_seen_at: 1.week.ago, username: user.username + }, format: :json + expect(response).to be_success end end @@ -76,7 +87,7 @@ describe Admin::EmailController do end it 'should enqueue the right job' do - expect { xhr :post, :handle_mail, email: email('cc') } + expect { post :handle_mail, params: { email: email('cc') }, format: :json } .to change { Jobs::ProcessEmail.jobs.count }.by(1) end end @@ -84,7 +95,7 @@ describe Admin::EmailController do context '.rejected' do it 'should provide a string for a blank error' do Fabricate(:incoming_email, error: "") - xhr :get, :rejected + get :rejected, format: :json rejected = JSON.parse(response.body) expect(rejected.first['error']).to eq(I18n.t("emails.incoming.unrecognized_error")) end @@ -93,7 +104,7 @@ describe Admin::EmailController do context '.incoming' do it 'should provide a string for a blank error' do incoming_email = Fabricate(:incoming_email, error: "") - xhr :get, :incoming, id: incoming_email.id + get :incoming, params: { id: incoming_email.id }, format: :json incoming = JSON.parse(response.body) expect(incoming['error']).to eq(I18n.t("emails.incoming.unrecognized_error")) end diff --git a/spec/controllers/admin/emojis_controller_spec.rb b/spec/controllers/admin/emojis_controller_spec.rb index 5b769ab90ad..1b494f05718 100644 --- a/spec/controllers/admin/emojis_controller_spec.rb +++ b/spec/controllers/admin/emojis_controller_spec.rb @@ -22,7 +22,7 @@ describe Admin::EmojisController do context ".index" do it "returns a list of custom emojis" do Emoji.expects(:custom).returns([custom_emoji]) - xhr :get, :index + get :index, format: :json expect(response).to be_success json = ::JSON.parse(response.body) expect(json[0]["name"]).to eq(custom_emoji.name) diff --git a/spec/controllers/admin/groups_controller_spec.rb b/spec/controllers/admin/groups_controller_spec.rb index 7f02fe769e9..e8ecd77c0ac 100644 --- a/spec/controllers/admin/groups_controller_spec.rb +++ b/spec/controllers/admin/groups_controller_spec.rb @@ -18,7 +18,9 @@ describe Admin::GroupsController do user = Fabricate(:user, trust_level: 2) user2 = Fabricate(:user, trust_level: 4) - xhr :put, :bulk_perform, group_id: group.id, users: [user.username.upcase, user2.email, 'doesnt_exist'] + put :bulk_perform, params: { + group_id: group.id, users: [user.username.upcase, user2.email, 'doesnt_exist'] + }, format: :json expect(response).to be_success @@ -44,10 +46,13 @@ describe Admin::GroupsController do group.add_owner(user) expect do - xhr :put, :update, id: group.id, group: { - visibility_level: Group.visibility_levels[:owners], - allow_membership_requests: "true" - } + put :update, params: { + id: group.id, + group: { + visibility_level: Group.visibility_levels[:owners], + allow_membership_requests: "true" + } + }, format: :json end.to change { GroupHistory.count }.by(2) @@ -60,7 +65,7 @@ describe Admin::GroupsController do end it "ignore name change on automatic group" do - xhr :put, :update, id: 1, group: { name: "WAT" } + put :update, params: { id: 1, group: { name: "WAT" } }, format: :json expect(response).to be_success group = Group.find(1) @@ -70,14 +75,22 @@ describe Admin::GroupsController do it "doesn't launch the 'automatic group membership' job when it's not retroactive" do Jobs.expects(:enqueue).never group = Fabricate(:group) - xhr :put, :update, id: group.id, group: { automatic_membership_retroactive: "false" } + + put :update, params: { + id: group.id, group: { automatic_membership_retroactive: "false" } + }, format: :json + expect(response).to be_success end it "launches the 'automatic group membership' job when it's retroactive" do group = Fabricate(:group) Jobs.expects(:enqueue).with(:automatic_group_membership, group_id: group.id) - xhr :put, :update, id: group.id, group: { automatic_membership_retroactive: "true" } + + put :update, params: { + id: group.id, group: { automatic_membership_retroactive: "true" } + }, format: :json + expect(response).to be_success end @@ -87,14 +100,14 @@ describe Admin::GroupsController do it "returns a 422 if the group is automatic" do group = Fabricate(:group, automatic: true) - xhr :delete, :destroy, id: group.id + delete :destroy, params: { id: group.id }, format: :json expect(response.status).to eq(422) expect(Group.where(id: group.id).count).to eq(1) end it "is able to destroy a non-automatic group" do group = Fabricate(:group) - xhr :delete, :destroy, id: group.id + delete :destroy, params: { id: group.id }, format: :json expect(response.status).to eq(200) expect(Group.where(id: group.id).count).to eq(0) end @@ -106,7 +119,7 @@ describe Admin::GroupsController do it "is able to refresh automatic groups" do Group.expects(:refresh_automatic_groups!).returns(true) - xhr :post, :refresh_automatic_groups + post :refresh_automatic_groups, format: :json expect(response.status).to eq(200) end diff --git a/spec/controllers/admin/impersonate_controller_spec.rb b/spec/controllers/admin/impersonate_controller_spec.rb index 54eb1ee1f6a..866e6898b5e 100644 --- a/spec/controllers/admin/impersonate_controller_spec.rb +++ b/spec/controllers/admin/impersonate_controller_spec.rb @@ -12,7 +12,7 @@ describe Admin::ImpersonateController do context 'index' do it 'returns success' do - xhr :get, :index + get :index, format: :json expect(response).to be_success end end @@ -20,17 +20,17 @@ describe Admin::ImpersonateController do context 'create' do it 'requires a username_or_email parameter' do - expect { xhr :put, :create }.to raise_error(ActionController::ParameterMissing) + expect { put :create, format: :json }.to raise_error(ActionController::ParameterMissing) end it 'returns 404 when that user does not exist' do - xhr :post, :create, username_or_email: 'hedonismbot' + post :create, params: { username_or_email: 'hedonismbot' }, format: :json expect(response.status).to eq(404) end it "raises an invalid access error if the user can't be impersonated" do Guardian.any_instance.expects(:can_impersonate?).with(user).returns(false) - xhr :post, :create, username_or_email: user.email + post :create, params: { username_or_email: user.email }, format: :json expect(response).to be_forbidden end @@ -38,21 +38,21 @@ describe Admin::ImpersonateController do it "logs the impersonation" do StaffActionLogger.any_instance.expects(:log_impersonate) - xhr :post, :create, username_or_email: user.username + post :create, params: { username_or_email: user.username }, format: :json end it "changes the current user session id" do - xhr :post, :create, username_or_email: user.username + post :create, params: { username_or_email: user.username }, format: :json expect(session[:current_user_id]).to eq(user.id) end it "returns success" do - xhr :post, :create, username_or_email: user.email + post :create, params: { username_or_email: user.email }, format: :json expect(response).to be_success end it "also works with an email address" do - xhr :post, :create, username_or_email: user.email + post :create, params: { username_or_email: user.email }, format: :json expect(session[:current_user_id]).to eq(user.id) end diff --git a/spec/controllers/admin/permalinks_controller_spec.rb b/spec/controllers/admin/permalinks_controller_spec.rb index fe5652597d2..1075150ab16 100644 --- a/spec/controllers/admin/permalinks_controller_spec.rb +++ b/spec/controllers/admin/permalinks_controller_spec.rb @@ -15,7 +15,7 @@ describe Admin::PermalinksController do Fabricate(:permalink, url: "/discuss/topic/45") Fabricate(:permalink, url: "/discuss/topic/76") - xhr :get, :index, filter: "topic" + get :index, params: { filter: "topic" }, format: :json expect(response).to be_success result = JSON.parse(response.body) @@ -28,7 +28,7 @@ describe Admin::PermalinksController do Fabricate(:permalink, external_url: "http://www.discourse.org") Fabricate(:permalink, external_url: "http://try.discourse.org") - xhr :get, :index, filter: "discourse" + get :index, params: { filter: "discourse" }, format: :json expect(response).to be_success result = JSON.parse(response.body) @@ -41,7 +41,7 @@ describe Admin::PermalinksController do Fabricate(:permalink, url: "/discuss/topic/45", external_url: "http://discourse.org") Fabricate(:permalink, url: "/discuss/topic/76", external_url: "http://try.discourse.org") - xhr :get, :index, filter: "discourse" + get :index, params: { filter: "discourse" }, format: :json expect(response).to be_success result = JSON.parse(response.body) diff --git a/spec/controllers/admin/plugins_controller_spec.rb b/spec/controllers/admin/plugins_controller_spec.rb index 42a385e3c93..9df2c2737e1 100644 --- a/spec/controllers/admin/plugins_controller_spec.rb +++ b/spec/controllers/admin/plugins_controller_spec.rb @@ -10,7 +10,7 @@ describe Admin::PluginsController do let!(:admin) { log_in(:admin) } it 'should return JSON' do - xhr :get, :index + get :index, format: :json expect(response).to be_success expect(::JSON.parse(response.body).has_key?('plugins')).to eq(true) end diff --git a/spec/controllers/admin/reports_controller_spec.rb b/spec/controllers/admin/reports_controller_spec.rb index 7c34ee0e25f..740df64afb0 100644 --- a/spec/controllers/admin/reports_controller_spec.rb +++ b/spec/controllers/admin/reports_controller_spec.rb @@ -16,11 +16,11 @@ describe Admin::ReportsController do it "never calls Report.find" do Report.expects(:find).never - xhr :get, :show, type: invalid_id + get :show, params: { type: invalid_id }, format: :json end it "returns 404" do - xhr :get, :show, type: invalid_id + get :show, params: { type: invalid_id }, format: :json expect(response.status).to eq(404) end end @@ -30,7 +30,7 @@ describe Admin::ReportsController do context 'missing report' do before do Report.expects(:find).with('active', instance_of(Hash)).returns(nil) - xhr :get, :show, type: 'active' + get :show, params: { type: 'active' }, format: :json end it "renders the report as JSON" do @@ -41,7 +41,7 @@ describe Admin::ReportsController do context 'a report is found' do before do Report.expects(:find).with('active', instance_of(Hash)).returns(Report.new('active')) - xhr :get, :show, type: 'active' + get :show, params: { type: 'active' }, format: :json end it "renders the report as JSON" do @@ -65,7 +65,7 @@ describe Admin::ReportsController do topic other_topic - xhr :get, :show, type: 'topics', category_id: category.id + get :show, params: { type: 'topics', category_id: category.id }, format: :json expect(response).to be_success @@ -85,7 +85,7 @@ describe Admin::ReportsController do other_user group.add(user) - xhr :get, :show, type: 'signups', group_id: group.id + get :show, params: { type: 'signups', group_id: group.id }, format: :json expect(response).to be_success diff --git a/spec/controllers/admin/screened_emails_controller_spec.rb b/spec/controllers/admin/screened_emails_controller_spec.rb index 07adde47542..fb4486a9b48 100644 --- a/spec/controllers/admin/screened_emails_controller_spec.rb +++ b/spec/controllers/admin/screened_emails_controller_spec.rb @@ -9,7 +9,7 @@ describe Admin::ScreenedEmailsController do context '.index' do before do - xhr :get, :index + get :index, format: :json end subject { response } diff --git a/spec/controllers/admin/screened_ip_addresses_controller_spec.rb b/spec/controllers/admin/screened_ip_addresses_controller_spec.rb index 201a2fad5ef..664fc85cdb2 100644 --- a/spec/controllers/admin/screened_ip_addresses_controller_spec.rb +++ b/spec/controllers/admin/screened_ip_addresses_controller_spec.rb @@ -16,13 +16,13 @@ describe Admin::ScreenedIpAddressesController do Fabricate(:screened_ip_address, ip_address: "1.2.3.6") Fabricate(:screened_ip_address, ip_address: "4.5.6.7") - xhr :get, :index, filter: "1.2.*" + get :index, params: { filter: "1.2.*" }, format: :json expect(response).to be_success result = JSON.parse(response.body) expect(result.length).to eq(3) - xhr :get, :index, filter: "4.5.6.7" + get :index, params: { filter: "4.5.6.7" }, format: :json expect(response).to be_success result = JSON.parse(response.body) @@ -44,7 +44,7 @@ describe Admin::ScreenedIpAddressesController do StaffActionLogger.any_instance.expects(:log_roll_up) SiteSetting.min_ban_entries_for_roll_up = 3 - xhr :post, :roll_up + post :roll_up, format: :json expect(response).to be_success subnet = ScreenedIpAddress.where(ip_address: "1.2.3.0/24").first @@ -64,7 +64,7 @@ describe Admin::ScreenedIpAddressesController do StaffActionLogger.any_instance.expects(:log_roll_up) SiteSetting.min_ban_entries_for_roll_up = 5 - xhr :post, :roll_up + post :roll_up, format: :json expect(response).to be_success subnet = ScreenedIpAddress.where(ip_address: "1.2.0.0/16").first diff --git a/spec/controllers/admin/screened_urls_controller_spec.rb b/spec/controllers/admin/screened_urls_controller_spec.rb index 3bd763d2bb9..86d7fce0b72 100644 --- a/spec/controllers/admin/screened_urls_controller_spec.rb +++ b/spec/controllers/admin/screened_urls_controller_spec.rb @@ -9,7 +9,7 @@ describe Admin::ScreenedUrlsController do context '.index' do before do - xhr :get, :index + get :index, format: :json end subject { response } diff --git a/spec/controllers/admin/site_settings_controller_spec.rb b/spec/controllers/admin/site_settings_controller_spec.rb index 6193572987e..874f3756026 100644 --- a/spec/controllers/admin/site_settings_controller_spec.rb +++ b/spec/controllers/admin/site_settings_controller_spec.rb @@ -13,12 +13,12 @@ describe Admin::SiteSettingsController do context 'index' do it 'returns success' do - xhr :get, :index + get :index, format: :json expect(response).to be_success end it 'returns JSON' do - xhr :get, :index + get :index, format: :json expect(::JSON.parse(response.body)).to be_present end end @@ -31,34 +31,47 @@ describe Admin::SiteSettingsController do end it 'sets the value when the param is present' do - xhr :put, :update, id: 'test_setting', test_setting: 'hello' + put :update, params: { + id: 'test_setting', test_setting: 'hello' + }, format: :json expect(SiteSetting.test_setting).to eq('hello') end it 'allows value to be a blank string' do - xhr :put, :update, id: 'test_setting', test_setting: '' + put :update, params: { + id: 'test_setting', test_setting: '' + }, format: :json + expect(SiteSetting.test_setting).to eq('') end it 'logs the change' do SiteSetting.test_setting = 'previous' StaffActionLogger.any_instance.expects(:log_site_setting_change).with('test_setting', 'previous', 'hello') - xhr :put, :update, id: 'test_setting', test_setting: 'hello' + + put :update, params: { + id: 'test_setting', test_setting: 'hello' + }, format: :json + expect(SiteSetting.test_setting).to eq('hello') end it 'does not allow changing of hidden settings' do SiteSetting.setting(:hidden_setting, "hidden", hidden: true) SiteSetting.refresh! - result = xhr :put, :update, id: 'hidden_setting', hidden_setting: 'not allowed' + + put :update, params: { + id: 'hidden_setting', hidden_setting: 'not allowed' + }, format: :json + expect(SiteSetting.hidden_setting).to eq("hidden") - expect(result.status).to eq(422) + expect(response.status).to eq(422) end it 'fails when a setting does not exist' do expect { - xhr :put, :update, id: 'provider', provider: 'gotcha' + put :update, params: { id: 'provider', provider: 'gotcha' }, format: :json }.to raise_error(ArgumentError) end end diff --git a/spec/controllers/admin/site_texts_controller_spec.rb b/spec/controllers/admin/site_texts_controller_spec.rb index bcbef94ba55..b0a5191ff7d 100644 --- a/spec/controllers/admin/site_texts_controller_spec.rb +++ b/spec/controllers/admin/site_texts_controller_spec.rb @@ -13,7 +13,7 @@ describe Admin::SiteTextsController do context '.index' do it 'returns json' do - xhr :get, :index, q: 'title' + get :index, params: { q: 'title' }, format: :json expect(response).to be_success expect(::JSON.parse(response.body)).to be_present end @@ -21,7 +21,7 @@ describe Admin::SiteTextsController do context '.show' do it 'returns a site text for a key that exists' do - xhr :get, :show, id: 'title' + get :show, params: { id: 'title' }, format: :json expect(response).to be_success json = ::JSON.parse(response.body) @@ -35,7 +35,7 @@ describe Admin::SiteTextsController do end it 'returns not found for missing keys' do - xhr :get, :show, id: 'made_up_no_key_exists' + get :show, params: { id: 'made_up_no_key_exists' }, format: :json expect(response).not_to be_success end end @@ -52,7 +52,9 @@ describe Admin::SiteTextsController do end it 'returns the right error message' do - xhr :put, :update, id: 'some_key', site_text: { value: 'hello %{key}' } + put :update, params: { + id: 'some_key', site_text: { value: 'hello %{key}' } + }, format: :json expect(response.status).to eq(422) @@ -68,7 +70,7 @@ describe Admin::SiteTextsController do it 'updates and reverts the key' do orig_title = I18n.t(:title) - xhr :put, :update, id: 'title', site_text: { value: 'hello' } + put :update, params: { id: 'title', site_text: { value: 'hello' } }, format: :json expect(response).to be_success json = ::JSON.parse(response.body) @@ -81,7 +83,7 @@ describe Admin::SiteTextsController do expect(site_text['value']).to eq('hello') # Revert - xhr :put, :revert, id: 'title' + put :revert, params: { id: 'title' }, format: :json expect(response).to be_success json = ::JSON.parse(response.body) @@ -95,14 +97,19 @@ describe Admin::SiteTextsController do end it 'returns not found for missing keys' do - xhr :put, :update, id: 'made_up_no_key_exists', site_text: { value: 'hello' } + put :update, params: { + id: 'made_up_no_key_exists', site_text: { value: 'hello' } + }, format: :json + expect(response).not_to be_success end it 'logs the change' do original_title = I18n.t(:title) - xhr :put, :update, id: 'title', site_text: { value: 'yay' } + put :update, params: { + id: 'title', site_text: { value: 'yay' } + }, format: :json log = UserHistory.last @@ -110,7 +117,7 @@ describe Admin::SiteTextsController do expect(log.new_value).to eq('yay') expect(log.action).to eq(UserHistory.actions[:change_site_text]) - xhr :put, :revert, id: 'title' + put :revert, params: { id: 'title' }, format: :json log = UserHistory.last diff --git a/spec/controllers/admin/staff_action_logs_controller_spec.rb b/spec/controllers/admin/staff_action_logs_controller_spec.rb index 45d6f14eee9..d1e302bd1f7 100644 --- a/spec/controllers/admin/staff_action_logs_controller_spec.rb +++ b/spec/controllers/admin/staff_action_logs_controller_spec.rb @@ -14,7 +14,7 @@ describe Admin::StaffActionLogsController do topic = Fabricate(:topic) _record = StaffActionLogger.new(Discourse.system_user).log_topic_deletion(topic) - xhr :get, :index, action_id: UserHistory.actions[:delete_topic] + get :index, params: { action_id: UserHistory.actions[:delete_topic] }, format: :json json = JSON.parse(response.body) expect(response).to be_success @@ -40,7 +40,7 @@ describe Admin::StaffActionLogsController do record = StaffActionLogger.new(Discourse.system_user) .log_theme_change(original_json, theme) - xhr :get, :diff, id: record.id + get :diff, params: { id: record.id }, format: :json expect(response).to be_success parsed = JSON.parse(response.body) diff --git a/spec/controllers/admin/themes_controller_spec.rb b/spec/controllers/admin/themes_controller_spec.rb index f8f661ce9b6..16947e17566 100644 --- a/spec/controllers/admin/themes_controller_spec.rb +++ b/spec/controllers/admin/themes_controller_spec.rb @@ -15,14 +15,15 @@ describe Admin::ThemesController do render_views let(:upload) do - ActionDispatch::Http::UploadedFile.new(filename: 'test.woff2', - tempfile: file_from_fixtures("fake.woff2", "woff2")) + Rack::Test::UploadedFile.new(file_from_fixtures("fake.woff2", "woff2")) end it 'can create a theme upload' do - xhr :post, :upload_asset, file: upload + post :upload_asset, params: { file: upload }, format: :json expect(response.status).to eq(201) - upload = Upload.find_by(original_filename: "test.woff2") + + upload = Upload.find_by(original_filename: "fake.woff2") + expect(upload.id).not_to be_nil expect(JSON.parse(response.body)["upload_id"]).to eq(upload.id) end @@ -30,12 +31,11 @@ describe Admin::ThemesController do context '.import' do let(:theme_file) do - ActionDispatch::Http::UploadedFile.new(filename: 'sam-s-simple-theme.dcstyle.json', - tempfile: file_from_fixtures("sam-s-simple-theme.dcstyle.json", "json")) + Rack::Test::UploadedFile.new(file_from_fixtures("sam-s-simple-theme.dcstyle.json", "json")) end it 'imports a theme' do - xhr :post, :import, theme: theme_file + post :import, params: { theme: theme_file }, format: :json expect(response).to be_success json = ::JSON.parse(response.body) @@ -68,7 +68,7 @@ describe Admin::ThemesController do # this will get serialized as well ColorScheme.create_from_base(name: "test", colors: []) - xhr :get, :index + get :index, format: :json expect(response).to be_success @@ -83,7 +83,13 @@ describe Admin::ThemesController do context ' .create' do it 'creates a theme' do - xhr :post, :create, theme: { name: 'my test name', theme_fields: [name: 'scss', target: 'common', value: 'body{color: red;}'] } + post :create, params: { + theme: { + name: 'my test name', + theme_fields: [name: 'scss', target: 'common', value: 'body{color: red;}'] + } + }, format: :json + expect(response).to be_success json = ::JSON.parse(response.body) @@ -96,14 +102,22 @@ describe Admin::ThemesController do context ' .update' do it 'can change default theme' do theme = Theme.create(name: 'my name', user_id: -1) - xhr :put, :update, id: theme.id, theme: { default: true } + + put :update, params: { + id: theme.id, theme: { default: true } + }, format: :json + expect(SiteSetting.default_theme_key).to eq(theme.key) end it 'can unset default theme' do theme = Theme.create(name: 'my name', user_id: -1) SiteSetting.default_theme_key = theme.key - xhr :put, :update, id: theme.id, theme: { default: false } + + put :update, params: { + id: theme.id, theme: { default: false } + }, format: :json + expect(SiteSetting.default_theme_key).to be_blank end @@ -116,16 +130,19 @@ describe Admin::ThemesController do upload = Fabricate(:upload) - xhr :put, :update, id: theme.id, - theme: { - child_theme_ids: [child_theme.id], - name: 'my test name', - theme_fields: [ - { name: 'scss', target: 'common', value: '' }, - { name: 'scss', target: 'desktop', value: 'body{color: blue;}' }, - { name: 'bob', target: 'common', value: '', type_id: 2, upload_id: upload.id }, - ] - } + put :update, params: { + id: theme.id, + theme: { + child_theme_ids: [child_theme.id], + name: 'my test name', + theme_fields: [ + { name: 'scss', target: 'common', value: '' }, + { name: 'scss', target: 'desktop', value: 'body{color: blue;}' }, + { name: 'bob', target: 'common', value: '', type_id: 2, upload_id: upload.id }, + ] + } + }, format: :json + expect(response).to be_success json = ::JSON.parse(response.body) @@ -135,11 +152,8 @@ describe Admin::ThemesController do expect(fields[0]["value"]).to eq('') expect(fields[0]["upload_id"]).to eq(upload.id) expect(fields[1]["value"]).to eq('body{color: blue;}') - expect(fields.length).to eq(2) - expect(json["theme"]["child_themes"].length).to eq(1) - expect(UserHistory.where(action: UserHistory.actions[:change_theme]).count).to eq(1) end end diff --git a/spec/controllers/admin/user_fields_controller_spec.rb b/spec/controllers/admin/user_fields_controller_spec.rb index cc5d06be13c..de46a1cf0ce 100644 --- a/spec/controllers/admin/user_fields_controller_spec.rb +++ b/spec/controllers/admin/user_fields_controller_spec.rb @@ -12,19 +12,27 @@ describe Admin::UserFieldsController do context '.create' do it "creates a user field" do expect { - xhr :post, :create, user_field: { name: 'hello', description: 'hello desc', field_type: 'text' } + post :create, params: { + user_field: { name: 'hello', description: 'hello desc', field_type: 'text' } + }, format: :json + expect(response).to be_success }.to change(UserField, :count).by(1) end it "creates a user field with options" do - expect { - xhr :post, :create, user_field: { name: 'hello', - description: 'hello desc', - field_type: 'dropdown', - options: ['a', 'b', 'c'] } + expect do + post :create, params: { + user_field: { + name: 'hello', + description: 'hello desc', + field_type: 'dropdown', + options: ['a', 'b', 'c'] + } + }, format: :json + expect(response).to be_success - }.to change(UserField, :count).by(1) + end.to change(UserField, :count).by(1) expect(UserFieldOption.count).to eq(3) end @@ -34,7 +42,7 @@ describe Admin::UserFieldsController do let!(:user_field) { Fabricate(:user_field) } it "returns a list of user fields" do - xhr :get, :index + get :index, format: :json expect(response).to be_success json = ::JSON.parse(response.body) expect(json['user_fields']).to be_present @@ -46,7 +54,7 @@ describe Admin::UserFieldsController do it "deletes the user field" do expect { - xhr :delete, :destroy, id: user_field.id + delete :destroy, params: { id: user_field.id }, format: :json expect(response).to be_success }.to change(UserField, :count).by(-1) end @@ -56,7 +64,11 @@ describe Admin::UserFieldsController do let!(:user_field) { Fabricate(:user_field) } it "updates the user field" do - xhr :put, :update, id: user_field.id, user_field: { name: 'fraggle', field_type: 'confirm', description: 'muppet' } + put :update, params: { + id: user_field.id, + user_field: { name: 'fraggle', field_type: 'confirm', description: 'muppet' } + }, format: :json + expect(response).to be_success user_field.reload expect(user_field.name).to eq('fraggle') @@ -64,10 +76,16 @@ describe Admin::UserFieldsController do end it "updates the user field options" do - xhr :put, :update, id: user_field.id, user_field: { name: 'fraggle', - field_type: 'dropdown', - description: 'muppet', - options: ['hello', 'hello', 'world'] } + put :update, params: { + id: user_field.id, + user_field: { + name: 'fraggle', + field_type: 'dropdown', + description: 'muppet', + options: ['hello', 'hello', 'world'] + } + }, format: :json + expect(response).to be_success user_field.reload expect(user_field.name).to eq('fraggle') @@ -76,19 +94,31 @@ describe Admin::UserFieldsController do end it "keeps options when updating the user field" do - xhr :put, :update, id: user_field.id, user_field: { name: 'fraggle', - field_type: 'dropdown', - description: 'muppet', - options: ['hello', 'hello', 'world'], - position: 1 } + put :update, params: { + id: user_field.id, + user_field: { + name: 'fraggle', + field_type: 'dropdown', + description: 'muppet', + options: ['hello', 'hello', 'world'], + position: 1 + } + }, format: :json + expect(response).to be_success user_field.reload expect(user_field.user_field_options.size).to eq(2) - xhr :put, :update, id: user_field.id, user_field: { name: 'fraggle', - field_type: 'dropdown', - description: 'muppet', - position: 2 } + put :update, params: { + id: user_field.id, + user_field: { + name: 'fraggle', + field_type: 'dropdown', + description: 'muppet', + position: 2 + } + }, format: :json + expect(response).to be_success user_field.reload expect(user_field.user_field_options.size).to eq(2) diff --git a/spec/controllers/admin/users_controller_spec.rb b/spec/controllers/admin/users_controller_spec.rb index c8d1ecbc84a..ad209931c3a 100644 --- a/spec/controllers/admin/users_controller_spec.rb +++ b/spec/controllers/admin/users_controller_spec.rb @@ -14,19 +14,19 @@ describe Admin::UsersController do context '.index' do it 'returns success' do - xhr :get, :index + get :index, format: :json expect(response).to be_success end it 'returns JSON' do - xhr :get, :index + get :index, format: :json expect(::JSON.parse(response.body)).to be_present end context 'when showing emails' do it "returns email for all the users" do - xhr :get, :index, show_emails: "true" + get :index, params: { show_emails: "true" }, format: :json data = ::JSON.parse(response.body) data.each do |user| expect(user["email"]).to be_present @@ -36,7 +36,7 @@ describe Admin::UsersController do it "logs only 1 enty" do expect(UserHistory.where(action: UserHistory.actions[:check_email], acting_user_id: @user.id).count).to eq(0) - xhr :get, :index, show_emails: "true" + get :index, params: { show_emails: "true" }, format: :json expect(UserHistory.where(action: UserHistory.actions[:check_email], acting_user_id: @user.id).count).to eq(1) end @@ -47,14 +47,14 @@ describe Admin::UsersController do describe '.show' do context 'an existing user' do it 'returns success' do - xhr :get, :show, id: @user.id + get :show, params: { id: @user.id }, format: :json expect(response).to be_success end end context 'an existing user' do it 'returns success' do - xhr :get, :show, id: 0 + get :show, params: { id: 0 }, format: :json expect(response).not_to be_success end end @@ -66,19 +66,19 @@ describe Admin::UsersController do it "does nothing without uesrs" do User.any_instance.expects(:approve).never - xhr :put, :approve_bulk + put :approve_bulk, format: :json end it "won't approve the user when not allowed" do Guardian.any_instance.expects(:can_approve?).with(evil_trout).returns(false) User.any_instance.expects(:approve).never - xhr :put, :approve_bulk, users: [evil_trout.id] + put :approve_bulk, params: { users: [evil_trout.id] }, format: :json end it "approves the user when permitted" do Guardian.any_instance.expects(:can_approve?).with(evil_trout).returns(true) User.any_instance.expects(:approve).once - xhr :put, :approve_bulk, users: [evil_trout.id] + put :approve_bulk, params: { users: [evil_trout.id] }, format: :json end end @@ -88,7 +88,7 @@ describe Admin::UsersController do it 'calls generate_api_key' do User.any_instance.expects(:generate_api_key).with(@user) - xhr :post, :generate_api_key, user_id: evil_trout.id + post :generate_api_key, params: { user_id: evil_trout.id }, format: :json end end @@ -98,7 +98,7 @@ describe Admin::UsersController do it 'calls revoke_api_key' do User.any_instance.expects(:revoke_api_key) - xhr :delete, :revoke_api_key, user_id: evil_trout.id + delete :revoke_api_key, params: { user_id: evil_trout.id }, format: :json end end @@ -109,13 +109,13 @@ describe Admin::UsersController do it "raises an error when the user doesn't have permission" do Guardian.any_instance.expects(:can_approve?).with(evil_trout).returns(false) - xhr :put, :approve, user_id: evil_trout.id + put :approve, params: { user_id: evil_trout.id }, format: :json expect(response).to be_forbidden end it 'calls approve' do User.any_instance.expects(:approve).with(@user) - xhr :put, :approve, user_id: evil_trout.id + put :approve, params: { user_id: evil_trout.id }, format: :json end end @@ -126,7 +126,7 @@ describe Admin::UsersController do it "also revoke any api keys" do User.any_instance.expects(:revoke_api_key) - xhr :put, :suspend, user_id: evil_trout.id + put :suspend, params: { user_id: evil_trout.id }, format: :json end end @@ -138,12 +138,12 @@ describe Admin::UsersController do it 'raises an error unless the user can revoke access' do Guardian.any_instance.expects(:can_revoke_admin?).with(@another_admin).returns(false) - xhr :put, :revoke_admin, user_id: @another_admin.id + put :revoke_admin, params: { user_id: @another_admin.id }, format: :json expect(response).to be_forbidden end it 'updates the admin flag' do - xhr :put, :revoke_admin, user_id: @another_admin.id + put :revoke_admin, params: { user_id: @another_admin.id }, format: :json @another_admin.reload expect(@another_admin).not_to be_admin end @@ -160,18 +160,18 @@ describe Admin::UsersController do it "raises an error when the user doesn't have permission" do Guardian.any_instance.expects(:can_grant_admin?).with(@another_user).returns(false) - xhr :put, :grant_admin, user_id: @another_user.id + put :grant_admin, params: { user_id: @another_user.id }, format: :json expect(response).to be_forbidden end it "returns a 404 if the username doesn't exist" do - xhr :put, :grant_admin, user_id: 123123 + put :grant_admin, params: { user_id: 123123 }, format: :json expect(response).to be_forbidden end it 'updates the admin flag' do expect(AdminConfirmation.exists_for?(@another_user.id)).to eq(false) - xhr :put, :grant_admin, user_id: @another_user.id + put :grant_admin, params: { user_id: @another_user.id }, format: :json expect(AdminConfirmation.exists_for?(@another_user.id)).to eq(true) end end @@ -181,7 +181,9 @@ describe Admin::UsersController do let(:group) { Fabricate(:group) } it 'adds the user to the group' do - xhr :post, :add_group, group_id: group.id, user_id: user.id + post :add_group, params: { + group_id: group.id, user_id: user.id + }, format: :json expect(response).to be_success expect(GroupUser.where(user_id: user.id, group_id: group.id).exists?).to eq(true) @@ -193,7 +195,10 @@ describe Admin::UsersController do expect(group_history.target_user).to eq(user) # Doing it again doesn't raise an error - xhr :post, :add_group, group_id: group.id, user_id: user.id + post :add_group, params: { + group_id: group.id, user_id: user.id + }, format: :json + expect(response).to be_success end end @@ -207,31 +212,47 @@ describe Admin::UsersController do it "raises an error when the user doesn't have permission" do Guardian.any_instance.expects(:can_change_primary_group?).with(@another_user).returns(false) - xhr :put, :primary_group, user_id: @another_user.id + put :primary_group, params: { + user_id: @another_user.id + }, format: :json + expect(response).to be_forbidden end it "returns a 404 if the user doesn't exist" do - xhr :put, :primary_group, user_id: 123123 + put :primary_group, params: { + user_id: 123123 + }, format: :json + expect(response).to be_forbidden end it "changes the user's primary group" do group.add(@another_user) - xhr :put, :primary_group, user_id: @another_user.id, primary_group_id: group.id + put :primary_group, params: { + user_id: @another_user.id, primary_group_id: group.id + }, format: :json + @another_user.reload expect(@another_user.primary_group_id).to eq(group.id) end it "doesn't change primary group if they aren't a member of the group" do - xhr :put, :primary_group, user_id: @another_user.id, primary_group_id: group.id + put :primary_group, params: { + user_id: @another_user.id, primary_group_id: group.id + }, format: :json + @another_user.reload expect(@another_user.primary_group_id).to be_nil end it "remove user's primary group" do group.add(@another_user) - xhr :put, :primary_group, user_id: @another_user.id, primary_group_id: "" + + put :primary_group, params: { + user_id: @another_user.id, primary_group_id: "" + }, format: :json + @another_user.reload expect(@another_user.primary_group_id).to be(nil) end @@ -244,18 +265,28 @@ describe Admin::UsersController do it "raises an error when the user doesn't have permission" do Guardian.any_instance.expects(:can_change_trust_level?).with(@another_user).returns(false) - xhr :put, :trust_level, user_id: @another_user.id + put :trust_level, params: { + user_id: @another_user.id + }, format: :json + expect(response).not_to be_success end it "returns a 404 if the username doesn't exist" do - xhr :put, :trust_level, user_id: 123123 + put :trust_level, params: { + user_id: 123123 + }, format: :json + expect(response).not_to be_success end it "upgrades the user's trust level" do StaffActionLogger.any_instance.expects(:log_trust_level_change).with(@another_user, @another_user.trust_level, 2).once - xhr :put, :trust_level, user_id: @another_user.id, level: 2 + + put :trust_level, params: { + user_id: @another_user.id, level: 2 + }, format: :json + @another_user.reload expect(@another_user.trust_level).to eq(2) expect(response).to be_success @@ -268,7 +299,11 @@ describe Admin::UsersController do stat.time_read = SiteSetting.tl1_requires_time_spent_mins * 60 stat.save! @another_user.update_attributes(trust_level: TrustLevel[1]) - xhr :put, :trust_level, user_id: @another_user.id, level: TrustLevel[0] + + put :trust_level, params: { + user_id: @another_user.id, level: TrustLevel[0] + }, format: :json + expect(response).to be_success @another_user.reload expect(@another_user.trust_level_locked).to eq(true) @@ -282,12 +317,18 @@ describe Admin::UsersController do it 'raises an error unless the user can revoke access' do Guardian.any_instance.expects(:can_revoke_moderation?).with(@moderator).returns(false) - xhr :put, :revoke_moderation, user_id: @moderator.id + put :revoke_moderation, params: { + user_id: @moderator.id + }, format: :json + expect(response).to be_forbidden end it 'updates the moderator flag' do - xhr :put, :revoke_moderation, user_id: @moderator.id + put :revoke_moderation, params: { + user_id: @moderator.id + }, format: :json + @moderator.reload expect(@moderator.moderator).not_to eq(true) end @@ -300,17 +341,17 @@ describe Admin::UsersController do it "raises an error when the user doesn't have permission" do Guardian.any_instance.expects(:can_grant_moderation?).with(@another_user).returns(false) - xhr :put, :grant_moderation, user_id: @another_user.id + put :grant_moderation, params: { user_id: @another_user.id }, format: :json expect(response).to be_forbidden end it "returns a 404 if the username doesn't exist" do - xhr :put, :grant_moderation, user_id: 123123 + put :grant_moderation, params: { user_id: 123123 }, format: :json expect(response).to be_forbidden end it 'updates the moderator flag' do - xhr :put, :grant_moderation, user_id: @another_user.id + put :grant_moderation, params: { user_id: @another_user.id }, format: :json @another_user.reload expect(@another_user.moderator).to eq(true) end @@ -322,19 +363,26 @@ describe Admin::UsersController do it 'does nothing without users' do UserDestroyer.any_instance.expects(:destroy).never - xhr :delete, :reject_bulk + delete :reject_bulk, format: :json end it "won't delete users if not allowed" do Guardian.any_instance.stubs(:can_delete_user?).returns(false) UserDestroyer.any_instance.expects(:destroy).never - xhr :delete, :reject_bulk, users: [reject_me.id] + + delete :reject_bulk, params: { + users: [reject_me.id] + }, format: :json end it "reports successes" do Guardian.any_instance.stubs(:can_delete_user?).returns(true) UserDestroyer.any_instance.stubs(:destroy).returns(true) - xhr :delete, :reject_bulk, users: [reject_me.id, reject_me_too.id] + + delete :reject_bulk, params: { + users: [reject_me.id, reject_me_too.id] + }, format: :json + expect(response).to be_success json = ::JSON.parse(response.body) expect(json['success'].to_i).to eq(2) @@ -349,7 +397,11 @@ describe Admin::UsersController do it 'can handle some successes and some failures' do UserDestroyer.any_instance.stubs(:destroy).with(reject_me, anything).returns(false) UserDestroyer.any_instance.stubs(:destroy).with(reject_me_too, anything).returns(true) - xhr :delete, :reject_bulk, users: [reject_me.id, reject_me_too.id] + + delete :reject_bulk, params: { + users: [reject_me.id, reject_me_too.id] + }, format: :json + expect(response).to be_success json = ::JSON.parse(response.body) expect(json['success'].to_i).to eq(1) @@ -358,7 +410,11 @@ describe Admin::UsersController do it 'reports failure due to a user still having posts' do UserDestroyer.any_instance.expects(:destroy).with(reject_me, anything).raises(UserDestroyer::PostsExistError) - xhr :delete, :reject_bulk, users: [reject_me.id] + + delete :reject_bulk, params: { + users: [reject_me.id] + }, format: :json + expect(response).to be_success json = ::JSON.parse(response.body) expect(json['success'].to_i).to eq(0) @@ -374,12 +430,12 @@ describe Admin::UsersController do it "raises an error when the user doesn't have permission" do Guardian.any_instance.expects(:can_delete_user?).with(@delete_me).returns(false) - xhr :delete, :destroy, id: @delete_me.id + delete :destroy, params: { id: @delete_me.id }, format: :json expect(response).to be_forbidden end it "returns a 403 if the user doesn't exist" do - xhr :delete, :destroy, id: 123123 + delete :destroy, params: { id: 123123 }, format: :json expect(response).to be_forbidden end @@ -394,13 +450,13 @@ describe Admin::UsersController do end it "returns an error" do - xhr :delete, :destroy, id: @delete_me.id + delete :destroy, params: { id: @delete_me.id }, format: :json expect(response).to be_forbidden end it "doesn't return an error if delete_posts == true" do UserDestroyer.any_instance.expects(:destroy).with(@user, has_entry('delete_posts' => true)).returns(true) - xhr :delete, :destroy, id: @delete_me.id, delete_posts: true + delete :destroy, params: { id: @delete_me.id, delete_posts: true }, format: :json expect(response).to be_success end @@ -408,7 +464,7 @@ describe Admin::UsersController do it "deletes the user record" do UserDestroyer.any_instance.expects(:destroy).returns(true) - xhr :delete, :destroy, id: @delete_me.id + delete :destroy, params: { id: @delete_me.id }, format: :json end end @@ -418,7 +474,7 @@ describe Admin::UsersController do end it "returns success" do - xhr :put, :activate, user_id: @reg_user.id + put :activate, params: { user_id: @reg_user.id }, format: :json expect(response).to be_success json = ::JSON.parse(response.body) expect(json['success']).to eq("OK") @@ -430,7 +486,7 @@ describe Admin::UsersController do @reg_user.reload expect(@reg_user.email_confirmed?).to eq(false) - xhr :put, :activate, user_id: @reg_user.id + put :activate, params: { user_id: @reg_user.id }, format: :json expect(response).to be_success @reg_user.reload @@ -444,14 +500,14 @@ describe Admin::UsersController do end it "returns success" do - xhr :put, :log_out, user_id: @reg_user.id + put :log_out, params: { user_id: @reg_user.id }, format: :json expect(response).to be_success json = ::JSON.parse(response.body) expect(json['success']).to eq("OK") end it "returns 404 when user_id does not exist" do - xhr :put, :log_out, user_id: 123123 + put :log_out, params: { user_id: 123123 }, format: :json expect(response).not_to be_success end end @@ -464,18 +520,18 @@ describe Admin::UsersController do it "raises an error when the user doesn't have permission" do Guardian.any_instance.expects(:can_block_user?).with(@reg_user).returns(false) UserBlocker.expects(:block).never - xhr :put, :block, user_id: @reg_user.id + put :block, params: { user_id: @reg_user.id }, format: :json expect(response).to be_forbidden end it "returns a 403 if the user doesn't exist" do - xhr :put, :block, user_id: 123123 + put :block, params: { user_id: 123123 }, format: :json expect(response).to be_forbidden end it "punishes the user for spamming" do UserBlocker.expects(:block).with(@reg_user, @user, anything) - xhr :put, :block, user_id: @reg_user.id + put :block, params: { user_id: @reg_user.id }, format: :json end end @@ -486,18 +542,18 @@ describe Admin::UsersController do it "raises an error when the user doesn't have permission" do Guardian.any_instance.expects(:can_unblock_user?).with(@reg_user).returns(false) - xhr :put, :unblock, user_id: @reg_user.id + put :unblock, params: { user_id: @reg_user.id }, format: :json expect(response).to be_forbidden end it "returns a 403 if the user doesn't exist" do - xhr :put, :unblock, user_id: 123123 + put :unblock, params: { user_id: 123123 }, format: :json expect(response).to be_forbidden end it "punishes the user for spamming" do UserBlocker.expects(:unblock).with(@reg_user, @user, anything) - xhr :put, :unblock, user_id: @reg_user.id + put :unblock, params: { user_id: @reg_user.id }, format: :json end end @@ -505,7 +561,7 @@ describe Admin::UsersController do it "uses ipinfo.io webservice to retrieve the info" do Excon.expects(:get).with("https://ipinfo.io/123.123.123.123/json", read_timeout: 10, connect_timeout: 10) - xhr :get, :ip_info, ip: "123.123.123.123" + get :ip_info, params: { ip: "123.123.123.123" }, format: :json end end @@ -518,7 +574,9 @@ describe Admin::UsersController do UserDestroyer.any_instance.expects(:destroy).twice - xhr :delete, :delete_other_accounts_with_same_ip, ip: "42.42.42.42", exclude: -1, order: "trust_level DESC" + delete :delete_other_accounts_with_same_ip, params: { + ip: "42.42.42.42", exclude: -1, order: "trust_level DESC" + }, format: :json end end @@ -526,14 +584,22 @@ describe Admin::UsersController do context ".invite_admin" do it "doesn't work when not via API" do controller.stubs(:is_api?).returns(false) - xhr :post, :invite_admin, name: 'Bill', username: 'bill22', email: 'bill@bill.com' + + post :invite_admin, params: { + name: 'Bill', username: 'bill22', email: 'bill@bill.com' + }, format: :json + expect(response).not_to be_success end it 'should invite admin' do controller.stubs(:is_api?).returns(true) Jobs.expects(:enqueue).with(:critical_user_email, anything).returns(true) - xhr :post, :invite_admin, name: 'Bill', username: 'bill22', email: 'bill@bill.com' + + post :invite_admin, params: { + name: 'Bill', username: 'bill22', email: 'bill@bill.com' + }, format: :json + expect(response).to be_success u = User.find_by_email('bill@bill.com') @@ -545,7 +611,11 @@ describe Admin::UsersController do it "doesn't send the email with send_email falsy" do controller.stubs(:is_api?).returns(true) Jobs.expects(:enqueue).with(:user_email, anything).never - xhr :post, :invite_admin, name: 'Bill', username: 'bill22', email: 'bill@bill.com', send_email: '0' + + post :invite_admin, params: { + name: 'Bill', username: 'bill22', email: 'bill@bill.com', send_email: '0' + }, format: :json + expect(response).to be_success json = ::JSON.parse(response.body) expect(json["password_url"]).to be_present @@ -556,11 +626,11 @@ describe Admin::UsersController do it "also clears the user's primary group" do g = Fabricate(:group) u = Fabricate(:user, primary_group: g) - xhr :delete, :remove_group, group_id: g.id, user_id: u.id + delete :remove_group, params: { group_id: g.id, user_id: u.id }, format: :json + expect(u.reload.primary_group).to be_nil end end - end context '#sync_sso' do @@ -592,7 +662,7 @@ describe Admin::UsersController do sso.username = "Hokli$$!!" sso.email = "bob2@bob.com" - xhr :post, :sync_sso, Rack::Utils.parse_query(sso.payload) + post :sync_sso, params: Rack::Utils.parse_query(sso.payload), format: :json expect(response).to be_success user.reload @@ -606,7 +676,7 @@ describe Admin::UsersController do sso.username = "dr_claw" sso.email = "dr@claw.com" sso.external_id = "2" - xhr :post, :sync_sso, Rack::Utils.parse_query(sso.payload) + post :sync_sso, params: Rack::Utils.parse_query(sso.payload), format: :json expect(response).to be_success user = User.find_by_email('dr@claw.com') @@ -619,7 +689,7 @@ describe Admin::UsersController do sso.name = "" sso.external_id = "1" - xhr :post, :sync_sso, Rack::Utils.parse_query(sso.payload) + post :sync_sso, params: Rack::Utils.parse_query(sso.payload), format: :json expect(response.status).to eq(403) expect(JSON.parse(response.body)["message"]).to include("Primary email can't be blank") end diff --git a/spec/controllers/admin/versions_controller_spec.rb b/spec/controllers/admin/versions_controller_spec.rb index 0353062d470..62c8cea39df 100644 --- a/spec/controllers/admin/versions_controller_spec.rb +++ b/spec/controllers/admin/versions_controller_spec.rb @@ -20,7 +20,7 @@ describe Admin::VersionsController do end describe 'show' do - subject { xhr :get, :show } + subject { get :show, format: :json } it { is_expected.to be_success } it 'should return the currently available version' do diff --git a/spec/controllers/admin/web_hooks_controller_spec.rb b/spec/controllers/admin/web_hooks_controller_spec.rb index bcd05a32f5d..6b793dd0deb 100644 --- a/spec/controllers/admin/web_hooks_controller_spec.rb +++ b/spec/controllers/admin/web_hooks_controller_spec.rb @@ -14,17 +14,20 @@ describe Admin::WebHooksController do describe '#create' do it 'creates a webhook' do - xhr :post, :create, web_hook: { - payload_url: 'https://meta.discourse.org/', - content_type: 1, - secret: "a_secret_for_webhooks", - wildcard_web_hook: false, - active: true, - verify_certificate: true, - web_hook_event_type_ids: [1], - group_ids: [], - category_ids: [] - } + post :create, params: { + web_hook: { + payload_url: 'https://meta.discourse.org/', + content_type: 1, + secret: "a_secret_for_webhooks", + wildcard_web_hook: false, + active: true, + verify_certificate: true, + web_hook_event_type_ids: [1], + group_ids: [], + category_ids: [] + } + }, format: :json + expect(response).to be_success json = ::JSON.parse(response.body) @@ -32,16 +35,19 @@ describe Admin::WebHooksController do end it 'returns error when field is not filled correctly' do - xhr :post, :create, web_hook: { - content_type: 1, - secret: "a_secret_for_webhooks", - wildcard_web_hook: false, - active: true, - verify_certificate: true, - web_hook_event_type_ids: [1], - group_ids: [], - category_ids: [] - } + post :create, params: { + web_hook: { + content_type: 1, + secret: "a_secret_for_webhooks", + wildcard_web_hook: false, + active: true, + verify_certificate: true, + web_hook_event_type_ids: [1], + group_ids: [], + category_ids: [] + } + }, format: :json + expect(response.status).to eq 422 response_body = JSON.parse(response.body) @@ -53,7 +59,8 @@ describe Admin::WebHooksController do it 'enqueues the ping event' do Jobs.expects(:enqueue) .with(:emit_web_hook_event, web_hook_id: web_hook.id, event_type: 'ping', event_name: 'ping') - xhr :post, :ping, id: web_hook.id + + post :ping, params: { id: web_hook.id }, format: :json expect(response).to be_success end diff --git a/spec/controllers/badges_controller_spec.rb b/spec/controllers/badges_controller_spec.rb index a59cc812081..de894666c6b 100644 --- a/spec/controllers/badges_controller_spec.rb +++ b/spec/controllers/badges_controller_spec.rb @@ -20,7 +20,7 @@ describe BadgesController do context 'show' do it "should return a badge" do - get :show, id: badge.id, format: :json + get :show, params: { id: badge.id }, format: :json expect(response.status).to eq(200) parsed = JSON.parse(response.body) expect(parsed["badge"]).to be_present @@ -30,12 +30,12 @@ describe BadgesController do log_in_user(user) user_badge = BadgeGranter.grant(badge, user) expect(user_badge.notification.read).to eq(false) - get :show, id: badge.id, format: :json + get :show, params: { id: badge.id } expect(user_badge.notification.reload.read).to eq(true) end it 'renders rss feed of a badge' do - get :show, id: badge.id, format: :rss + get :show, params: { id: badge.id }, format: :rss expect(response.status).to eq(200) expect(response.content_type).to eq('application/rss+xml') end diff --git a/spec/controllers/categories_controller_spec.rb b/spec/controllers/categories_controller_spec.rb index b60f8d3441b..30eeaef636f 100644 --- a/spec/controllers/categories_controller_spec.rb +++ b/spec/controllers/categories_controller_spec.rb @@ -4,7 +4,7 @@ describe CategoriesController do describe "create" do it "requires the user to be logged in" do - expect { xhr :post, :create }.to raise_error(Discourse::NotLoggedIn) + expect { post :create, format: :json }.to raise_error(Discourse::NotLoggedIn) end describe "logged in" do @@ -14,26 +14,38 @@ describe CategoriesController do it "raises an exception when they don't have permission to create it" do Guardian.any_instance.expects(:can_create?).with(Category, nil).returns(false) - xhr :post, :create, name: 'hello', color: 'ff0', text_color: 'fff' + post :create, params: { + name: 'hello', color: 'ff0', text_color: 'fff' + }, format: :json + expect(response).to be_forbidden end it "raises an exception when the name is missing" do - expect { xhr :post, :create, color: "ff0", text_color: "fff" }.to raise_error(ActionController::ParameterMissing) + expect do + post :create, params: { color: "ff0", text_color: "fff" }, format: :json + end.to raise_error(ActionController::ParameterMissing) end it "raises an exception when the color is missing" do - expect { xhr :post, :create, name: "hello", text_color: "fff" }.to raise_error(ActionController::ParameterMissing) + expect do + post :create, params: { name: "hello", text_color: "fff" }, format: :json + end.to raise_error(ActionController::ParameterMissing) end it "raises an exception when the text color is missing" do - expect { xhr :post, :create, name: "hello", color: "ff0" }.to raise_error(ActionController::ParameterMissing) + expect do + post :create, params: { name: "hello", color: "ff0" }, format: :json + end.to raise_error(ActionController::ParameterMissing) end describe "failure" do before do @category = Fabricate(:category, user: @user) - xhr :post, :create, name: @category.name, color: "ff0", text_color: "fff" + + post :create, params: { + name: @category.name, color: "ff0", text_color: "fff" + }, format: :json end it { is_expected.not_to respond_with(:success) } @@ -48,12 +60,17 @@ describe CategoriesController do readonly = CategoryGroup.permission_types[:readonly] create_post = CategoryGroup.permission_types[:create_post] - xhr :post, :create, name: "hello", color: "ff0", text_color: "fff", slug: "hello-cat", - auto_close_hours: 72, - permissions: { - "everyone" => readonly, - "staff" => create_post - } + post :create, params: { + name: "hello", + color: "ff0", + text_color: "fff", + slug: "hello-cat", + auto_close_hours: 72, + permissions: { + "everyone" => readonly, + "staff" => create_post + } + }, format: :json expect(response.status).to eq(200) category = Category.find_by(name: "hello") @@ -73,7 +90,8 @@ describe CategoriesController do describe "destroy" do it "requires the user to be logged in" do - expect { xhr :delete, :destroy, id: "category" }.to raise_error(Discourse::NotLoggedIn) + expect { delete :destroy, params: { id: "category" }, format: :json } + .to raise_error(Discourse::NotLoggedIn) end describe "logged in" do @@ -84,13 +102,16 @@ describe CategoriesController do it "raises an exception if they don't have permission to delete it" do Guardian.any_instance.expects(:can_delete_category?).returns(false) - xhr :delete, :destroy, id: @category.slug + delete :destroy, params: { id: @category.slug }, format: :json expect(response).to be_forbidden end it "deletes the record" do Guardian.any_instance.expects(:can_delete_category?).returns(true) - expect { xhr :delete, :destroy, id: @category.slug }.to change(Category, :count).by(-1) + expect do + delete :destroy, params: { id: @category.slug }, format: :json + end.to change(Category, :count).by(-1) + expect(UserHistory.count).to eq(1) end end @@ -119,24 +140,25 @@ describe CategoriesController do payload[c3.id] = 6 payload[c4.id] = 5 - xhr :post, :reorder, mapping: MultiJson.dump(payload) + post :reorder, params: { mapping: MultiJson.dump(payload) }, format: :json SiteSetting.fixed_category_positions = true list = CategoryList.new(Guardian.new(admin)) + expect(list.categories).to eq([ - Category.find(SiteSetting.uncategorized_category_id), - c1, - c4, - c2, - c3 - ]) + Category.find(SiteSetting.uncategorized_category_id), + c1, + c4, + c2, + c3 + ]) end end describe "update" do it "requires the user to be logged in" do - expect { xhr :put, :update, id: 'category' }.to raise_error(Discourse::NotLoggedIn) + expect { put :update, params: { id: 'category' }, format: :json }.to raise_error(Discourse::NotLoggedIn) end describe "logged in" do @@ -149,26 +171,54 @@ describe CategoriesController do it "raises an exception if they don't have permission to edit it" do Guardian.any_instance.expects(:can_edit?).returns(false) - xhr :put, :update, id: @category.slug, name: 'hello', color: 'ff0', text_color: 'fff' + put :update, params: { + id: @category.slug, + name: 'hello', + color: 'ff0', + text_color: 'fff' + }, format: :json + expect(response).to be_forbidden end it "requires a name" do - expect { xhr :put, :update, id: @category.slug, color: 'fff', text_color: '0ff' }.to raise_error(ActionController::ParameterMissing) + expect do + put :update, params: { + id: @category.slug, + color: 'fff', + text_color: '0ff', + }, format: :json + end.to raise_error(ActionController::ParameterMissing) end it "requires a color" do - expect { xhr :put, :update, id: @category.slug, name: 'asdf', text_color: '0ff' }.to raise_error(ActionController::ParameterMissing) + expect do + put :update, params: { + id: @category.slug, + name: 'asdf', + text_color: '0ff', + }, format: :json + end.to raise_error(ActionController::ParameterMissing) end it "requires a text color" do - expect { xhr :put, :update, id: @category.slug, name: 'asdf', color: 'fff' }.to raise_error(ActionController::ParameterMissing) + expect do + put :update, + params: { id: @category.slug, name: 'asdf', color: 'fff' }, + format: :json + end.to raise_error(ActionController::ParameterMissing) end describe "failure" do before do @other_category = Fabricate(:category, name: "Other", user: @user) - xhr :put, :update, id: @category.id, name: @other_category.name, color: "ff0", text_color: "fff" + + put :update, params: { + id: @category.id, + name: @other_category.name, + color: "ff0", + text_color: "fff", + }, format: :json end it "returns errors on a duplicate category name" do @@ -182,7 +232,14 @@ describe CategoriesController do it "returns 422 if email_in address is already in use for other category" do @other_category = Fabricate(:category, name: "Other", email_in: "mail@examle.com") - xhr :put, :update, id: @category.id, name: "Email", email_in: "mail@examle.com", color: "ff0", text_color: "fff" + + put :update, params: { + id: @category.id, + name: "Email", + email_in: "mail@examle.com", + color: "ff0", + text_color: "fff", + }, format: :json expect(response).not_to be_success expect(response.code.to_i).to eq(422) @@ -194,15 +251,21 @@ describe CategoriesController do readonly = CategoryGroup.permission_types[:readonly] create_post = CategoryGroup.permission_types[:create_post] - xhr :put, :update, id: @category.id, name: "hello", color: "ff0", text_color: "fff", slug: "hello-category", - auto_close_hours: 72, - permissions: { - "everyone" => readonly, - "staff" => create_post - }, - custom_fields: { - "dancing" => "frogs" - } + put :update, params: { + id: @category.id, + name: "hello", + color: "ff0", + text_color: "fff", + slug: "hello-category", + auto_close_hours: 72, + permissions: { + "everyone" => readonly, + "staff" => create_post + }, + custom_fields: { + "dancing" => "frogs" + }, + }, format: :json expect(response.status).to eq(200) @category.reload @@ -219,12 +282,16 @@ describe CategoriesController do it 'logs the changes correctly' do @category.update!(permissions: { "admins" => CategoryGroup.permission_types[:create_post] }) - xhr :put , :update, id: @category.id, name: 'new name', - color: @category.color, text_color: @category.text_color, - slug: @category.slug, - permissions: { + put :update, params: { + id: @category.id, + name: 'new name', + color: @category.color, + text_color: @category.text_color, + slug: @category.slug, + permissions: { "everyone" => CategoryGroup.permission_types[:create_post] - } + }, + }, format: :json expect(UserHistory.count).to eq(5) # 2 + 3 (bootstrap mode) end @@ -235,7 +302,9 @@ describe CategoriesController do describe 'update_slug' do it 'requires the user to be logged in' do - expect { xhr :put, :update_slug, category_id: 'category' }.to raise_error(Discourse::NotLoggedIn) + expect do + put :update_slug, params: { category_id: 'category' }, format: :json + end.to raise_error(Discourse::NotLoggedIn) end describe 'logged in' do @@ -247,32 +316,44 @@ describe CategoriesController do end it 'rejects blank' do - xhr :put, :update_slug, category_id: @category.id, slug: nil + put :update_slug, params: { category_id: @category.id, slug: nil }, format: :json expect(response.status).to eq(422) end it 'accepts valid custom slug' do - xhr :put, :update_slug, category_id: @category.id, slug: 'valid-slug' + put :update_slug, + params: { category_id: @category.id, slug: 'valid-slug' }, + format: :json + expect(response).to be_success expect(@category.reload.slug).to eq('valid-slug') end it 'accepts not well formed custom slug' do - xhr :put, :update_slug, category_id: @category.id, slug: ' valid slug' + put :update_slug, + params: { category_id: @category.id, slug: ' valid slug' }, + format: :json + expect(response).to be_success expect(@category.reload.slug).to eq('valid-slug') end it 'accepts and sanitize custom slug when the slug generation method is not english' do SiteSetting.slug_generation_method = 'none' - xhr :put, :update_slug, category_id: @category.id, slug: ' another !_ slug @' + put :update_slug, + params: { category_id: @category.id, slug: ' another !_ slug @' }, + format: :json + expect(response).to be_success expect(@category.reload.slug).to eq('another-slug') SiteSetting.slug_generation_method = 'ascii' end it 'rejects invalid custom slug' do - xhr :put, :update_slug, category_id: @category.id, slug: ' ' + put :update_slug, + params: { category_id: @category.id, slug: ' ' }, + format: :json + expect(response.status).to eq(422) end end diff --git a/spec/controllers/category_hashtags_controller_spec.rb b/spec/controllers/category_hashtags_controller_spec.rb index 43d8b3b4fd8..56d9b50565a 100644 --- a/spec/controllers/category_hashtags_controller_spec.rb +++ b/spec/controllers/category_hashtags_controller_spec.rb @@ -9,7 +9,8 @@ describe CategoryHashtagsController do it 'only returns the categories that are valid' do category = Fabricate(:category) - xhr :get, :check, category_slugs: [category.slug, 'none'] + + get :check, params: { category_slugs: [category.slug, 'none'] }, format: :json expect(JSON.parse(response.body)).to eq( "valid" => [{ "slug" => category.hashtag_slug, "url" => category.url_with_id }] @@ -19,7 +20,8 @@ describe CategoryHashtagsController do it 'does not return restricted categories for a normal user' do group = Fabricate(:group) private_category = Fabricate(:private_category, group: group) - xhr :get, :check, category_slugs: [private_category.slug] + + get :check, params: { category_slugs: [private_category.slug] }, format: :json expect(JSON.parse(response.body)).to eq("valid" => []) end @@ -29,7 +31,10 @@ describe CategoryHashtagsController do group = Fabricate(:group) group.add(admin) private_category = Fabricate(:private_category, group: group) - xhr :get, :check, category_slugs: [private_category.slug] + + get :check, + params: { category_slugs: [private_category.slug] }, + format: :json expect(JSON.parse(response.body)).to eq( "valid" => [{ "slug" => private_category.hashtag_slug, "url" => private_category.url_with_id }] @@ -39,7 +44,9 @@ describe CategoryHashtagsController do describe "not logged in" do it 'raises an exception' do - expect { xhr :get, :check, category_slugs: [] }.to raise_error(Discourse::NotLoggedIn) + expect do + get :check, params: { category_slugs: [] }, format: :json + end.to raise_error(Discourse::NotLoggedIn) end end end diff --git a/spec/controllers/clicks_controller_spec.rb b/spec/controllers/clicks_controller_spec.rb index 3beaf783ef6..0c342c851cb 100644 --- a/spec/controllers/clicks_controller_spec.rb +++ b/spec/controllers/clicks_controller_spec.rb @@ -6,12 +6,12 @@ describe ClicksController do context 'missing params' do it 'raises a 404 without the url param' do - xhr :get, :track, post_id: 123 + get :track, params: { post_id: 123 }, format: :json expect(response).to be_not_found end it "redirects to the url even without the topic_id or post_id params" do - xhr :get, :track, url: 'http://google.com' + get :track, params: { url: 'http://google.com' }, format: :json expect(response).not_to be_redirect end end @@ -19,12 +19,18 @@ describe ClicksController do context 'correct params' do let(:url) { "http://discourse.org" } - before { request.stubs(:remote_ip).returns('192.168.0.1') } + before do + request.headers.merge!('REMOTE_ADDR' => '192.168.0.1') + end context "with a made up url" do it "doesn't redirect" do TopicLinkClick.expects(:create_from).returns(nil) - xhr :get, :track, url: 'http://discourse.org', post_id: 123 + + get :track, + params: { url: 'http://discourse.org', post_id: 123 }, + format: :json + expect(response).not_to be_redirect end end @@ -32,7 +38,11 @@ describe ClicksController do context "with a query string" do it "redirects" do TopicLinkClick.expects(:create_from).with(has_entries('url' => 'http://discourse.org/?hello=123')).returns(url) - xhr :get, :track, url: 'http://discourse.org/?hello=123', post_id: 123 + + get :track, params: { + url: 'http://discourse.org/?hello=123', post_id: 123, format: :json + } + expect(response).to redirect_to(url) end end @@ -40,13 +50,17 @@ describe ClicksController do context 'with a post_id' do it 'redirects' do TopicLinkClick.expects(:create_from).with('url' => url, 'post_id' => '123', 'ip' => '192.168.0.1').returns(url) - xhr :get, :track, url: url, post_id: 123 + get :track, params: { url: url, post_id: 123, format: :json } expect(response).to redirect_to(url) end it "doesn't redirect with the redirect=false param" do TopicLinkClick.expects(:create_from).with('url' => url, 'post_id' => '123', 'ip' => '192.168.0.1', 'redirect' => 'false').returns(url) - xhr :get, :track, url: url, post_id: 123, redirect: 'false' + + get :track, params: { + url: url, post_id: 123, redirect: 'false', format: :json + } + expect(response).not_to be_redirect end @@ -55,7 +69,7 @@ describe ClicksController do context 'with a topic_id' do it 'redirects' do TopicLinkClick.expects(:create_from).with('url' => url, 'topic_id' => '789', 'ip' => '192.168.0.1').returns(url) - xhr :get, :track, url: url, topic_id: 789 + get :track, params: { url: url, topic_id: 789, format: :json } expect(response).to redirect_to(url) end end diff --git a/spec/controllers/composer_messages_controller_spec.rb b/spec/controllers/composer_messages_controller_spec.rb index 6552767a2ac..5f22deda8e2 100644 --- a/spec/controllers/composer_messages_controller_spec.rb +++ b/spec/controllers/composer_messages_controller_spec.rb @@ -5,7 +5,7 @@ describe ComposerMessagesController do context '.index' do it 'requires you to be logged in' do - expect { xhr :get, :index }.to raise_error(Discourse::NotLoggedIn) + expect { get :index, format: :json }.to raise_error(Discourse::NotLoggedIn) end context 'when logged in' do @@ -13,7 +13,7 @@ describe ComposerMessagesController do let(:args) { { 'topic_id' => '123', 'post_id' => '333', 'composer_action' => 'reply' } } it 'redirects to your user preferences' do - xhr :get, :index + get :index, format: :json expect(response).to be_success end @@ -21,7 +21,7 @@ describe ComposerMessagesController do finder = mock ComposerMessagesFinder.expects(:new).with(instance_of(User), has_entries(args)).returns(finder) finder.expects(:find) - xhr :get, :index, args + get :index, params: args, format: :json end end end diff --git a/spec/controllers/directory_items_controller_spec.rb b/spec/controllers/directory_items_controller_spec.rb index 7f9612b1c43..6e91bf69d81 100644 --- a/spec/controllers/directory_items_controller_spec.rb +++ b/spec/controllers/directory_items_controller_spec.rb @@ -3,11 +3,11 @@ require 'rails_helper' describe DirectoryItemsController do it "requires a `period` param" do - expect { xhr :get, :index }.to raise_error(ActionController::ParameterMissing) + expect { get :index, format: :json }.to raise_error(ActionController::ParameterMissing) end it "requires a proper `period` param" do - xhr :get, :index, period: 'eviltrout' + get :index, params: { period: 'eviltrout' }, format: :json expect(response).not_to be_success end @@ -17,9 +17,8 @@ describe DirectoryItemsController do let!(:user) { log_in } it "succeeds" do - xhr :get, :index, period: 'all' + get :index, params: { period: 'all' }, format: :json expect(response).to be_success - json = ::JSON.parse(response.body) end end @@ -32,7 +31,7 @@ describe DirectoryItemsController do end it "succeeds with a valid value" do - xhr :get, :index, period: 'all' + get :index, params: { period: 'all' }, format: :json expect(response).to be_success json = ::JSON.parse(response.body) @@ -45,7 +44,7 @@ describe DirectoryItemsController do it "fails when the directory is disabled" do SiteSetting.enable_user_directory = false - xhr :get, :index, period: 'all' + get :index, params: { period: 'all' }, format: :json expect(response).not_to be_success end end diff --git a/spec/controllers/draft_controller_spec.rb b/spec/controllers/draft_controller_spec.rb index 1153e7529ca..fd8912caa7c 100644 --- a/spec/controllers/draft_controller_spec.rb +++ b/spec/controllers/draft_controller_spec.rb @@ -8,14 +8,14 @@ describe DraftController do it 'saves a draft on update' do user = log_in - post :update, draft_key: 'xyz', data: 'my data', sequence: 0 + post :update, params: { draft_key: 'xyz', data: 'my data', sequence: 0 }, format: :json expect(Draft.get(user, 'xyz', 0)).to eq('my data') end it 'destroys drafts when required' do user = log_in Draft.set(user, 'xxx', 0, 'hi') - delete :destroy, draft_key: 'xxx', sequence: 0 + delete :destroy, params: { draft_key: 'xxx', sequence: 0 }, format: :json expect(Draft.get(user, 'xxx', 0)).to eq(nil) end diff --git a/spec/controllers/email_controller_spec.rb b/spec/controllers/email_controller_spec.rb index ef0882336b9..4a1a03994f7 100644 --- a/spec/controllers/email_controller_spec.rb +++ b/spec/controllers/email_controller_spec.rb @@ -5,14 +5,14 @@ describe EmailController do context '.preferences_redirect' do it 'requires you to be logged in' do - expect { get :preferences_redirect }.to raise_error(Discourse::NotLoggedIn) + expect { get :preferences_redirect, format: :json }.to raise_error(Discourse::NotLoggedIn) end context 'when logged in' do let!(:user) { log_in } it 'redirects to your user preferences' do - get :preferences_redirect + get :preferences_redirect, format: :json expect(response).to redirect_to("/u/#{user.username}/preferences") end end @@ -21,7 +21,7 @@ describe EmailController do context '.perform unsubscribe' do it 'raises not found on invalid key' do - post :perform_unsubscribe, key: "123" + post :perform_unsubscribe, params: { key: "123" }, format: :json expect(response.status).to eq(404) end @@ -34,7 +34,10 @@ describe EmailController do email_direct: true, email_private_messages: true) - post :perform_unsubscribe, key: key, unsubscribe_all: "1" + post :perform_unsubscribe, + params: { key: key, unsubscribe_all: "1" }, + format: :json + expect(response.status).to eq(302) user.user_option.reload @@ -52,7 +55,10 @@ describe EmailController do user.user_option.update_columns(mailing_list_mode: true) - post :perform_unsubscribe, key: key, disable_mailing_list: "1" + post :perform_unsubscribe, + params: { key: key, disable_mailing_list: "1" }, + format: :json + expect(response.status).to eq(302) user.user_option.reload @@ -66,7 +72,10 @@ describe EmailController do user.user_option.update_columns(email_digests: true) - post :perform_unsubscribe, key: key, disable_digest_emails: "1" + post :perform_unsubscribe, + params: { key: key, disable_digest_emails: "1" }, + format: :json + expect(response.status).to eq(302) user.user_option.reload @@ -79,7 +88,11 @@ describe EmailController do key = UnsubscribeKey.create_key_for(p.user, p) TopicUser.change(p.user_id, p.topic_id, notification_level: TopicUser.notification_levels[:watching]) - post :perform_unsubscribe, key: key, unwatch_topic: "1" + + post :perform_unsubscribe, + params: { key: key, unwatch_topic: "1" }, + format: :json + expect(response.status).to eq(302) expect(TopicUser.get(p.topic, p.user).notification_level).to eq(TopicUser.notification_levels[:tracking]) @@ -90,7 +103,11 @@ describe EmailController do key = UnsubscribeKey.create_key_for(p.user, p) TopicUser.change(p.user_id, p.topic_id, notification_level: TopicUser.notification_levels[:watching]) - post :perform_unsubscribe, key: key, mute_topic: "1" + + post :perform_unsubscribe, + params: { key: key, mute_topic: "1" }, + format: :json + expect(response.status).to eq(302) expect(TopicUser.get(p.topic, p.user).notification_level).to eq(TopicUser.notification_levels[:muted]) @@ -104,7 +121,10 @@ describe EmailController do category_id: p.topic.category_id, notification_level: CategoryUser.notification_levels[:watching]) - post :perform_unsubscribe, key: key, unwatch_category: "1" + post :perform_unsubscribe, + params: { key: key, unwatch_category: "1" }, + format: :json + expect(response.status).to eq(302) expect(CategoryUser.find_by(id: cu.id)).to eq(nil) @@ -118,7 +138,10 @@ describe EmailController do category_id: p.topic.category_id, notification_level: CategoryUser.notification_levels[:watching_first_post]) - post :perform_unsubscribe, key: key, unwatch_category: "1" + post :perform_unsubscribe, + params: { key: key, unwatch_category: "1" }, + format: :json + expect(response.status).to eq(302) expect(CategoryUser.find_by(id: cu.id)).to eq(nil) @@ -134,14 +157,14 @@ describe EmailController do user = Fabricate(:user) key = UnsubscribeKey.create_key_for(user, "digest") - get :unsubscribe, key: key + get :unsubscribe, params: { key: key } expect(response.body).to include(I18n.t("unsubscribe.log_out")) expect(response.body).to include(I18n.t("unsubscribe.different_user_description")) end it 'displays not found if key is not found' do - get :unsubscribe, key: SecureRandom.hex + get :unsubscribe, params: { key: SecureRandom.hex } expect(response.body).to include(CGI.escapeHTML(I18n.t("unsubscribe.not_found_description"))) end @@ -152,18 +175,18 @@ describe EmailController do user.user_option.update_columns(mailing_list_mode: true) - get :unsubscribe, key: key + get :unsubscribe, params: { key: key } expect(response.body).to include(I18n.t("unsubscribe.mailing_list_mode")) SiteSetting.disable_mailing_list_mode = true - get :unsubscribe, key: key + get :unsubscribe, params: { key: key } expect(response.body).not_to include(I18n.t("unsubscribe.mailing_list_mode")) user.user_option.update_columns(mailing_list_mode: false) SiteSetting.disable_mailing_list_mode = false - get :unsubscribe, key: key + get :unsubscribe, params: { key: key } expect(response.body).not_to include(I18n.t("unsubscribe.mailing_list_mode")) end @@ -175,7 +198,7 @@ describe EmailController do key = UnsubscribeKey.create_key_for(user, "digest") # because we are type digest we will always show digest and it will be selected - get :unsubscribe, key: key + get :unsubscribe, params: { key: key } expect(response.body).to include(I18n.t("unsubscribe.disable_digest_emails")) source = Nokogiri::HTML::fragment(response.body) @@ -183,13 +206,13 @@ describe EmailController do SiteSetting.disable_digest_emails = true - get :unsubscribe, key: key + get :unsubscribe, params: { key: key } expect(response.body).not_to include(I18n.t("unsubscribe.disable_digest_emails")) SiteSetting.disable_digest_emails = false key = UnsubscribeKey.create_key_for(user, "not_digest") - get :unsubscribe, key: key + get :unsubscribe, params: { key: key } expect(response.body).to include(I18n.t("unsubscribe.disable_digest_emails")) end @@ -201,12 +224,12 @@ describe EmailController do notification_level: CategoryUser.notification_levels[:watching]) key = UnsubscribeKey.create_key_for(user, post) - get :unsubscribe, key: key + get :unsubscribe, params: { key: key } expect(response.body).to include("unwatch_category") cu.destroy! - get :unsubscribe, key: key + get :unsubscribe, params: { key: key } expect(response.body).not_to include("unwatch_category") end @@ -219,12 +242,12 @@ describe EmailController do notification_level: CategoryUser.notification_levels[:watching_first_post]) key = UnsubscribeKey.create_key_for(user, post) - get :unsubscribe, key: key + get :unsubscribe, params: { key: key } expect(response.body).to include("unwatch_category") cu.destroy! - get :unsubscribe, key: key + get :unsubscribe, params: { key: key } expect(response.body).not_to include("unwatch_category") end diff --git a/spec/controllers/export_csv_controller_spec.rb b/spec/controllers/export_csv_controller_spec.rb index bf4b5a0fa6a..53d5be2ea14 100644 --- a/spec/controllers/export_csv_controller_spec.rb +++ b/spec/controllers/export_csv_controller_spec.rb @@ -6,7 +6,7 @@ describe ExportCsvController do context "while not logged in" do describe ".download" do it "returns 404 when the unauthorized user tries to export csv file" do - get :show, id: export_filename + get :show, params: { id: export_filename } expect(response.status).to eq(404) end end @@ -18,19 +18,19 @@ describe ExportCsvController do describe ".export_entity" do it "enqueues export job" do Jobs.expects(:enqueue).with(:export_csv_file, has_entries(entity: "user_archive", user_id: @user.id)) - xhr :post, :export_entity, entity: "user_archive" + post :export_entity, params: { entity: "user_archive" }, format: :json expect(response).to be_success end it "should not enqueue export job if rate limit is reached" do Jobs::ExportCsvFile.any_instance.expects(:execute).never UserExport.create(file_name: "user-archive-codinghorror-150116-003249", user_id: @user.id) - xhr :post, :export_entity, entity: "user_archive" + post :export_entity, params: { entity: "user_archive" }, format: :json expect(response).not_to be_success end it "returns 404 when normal user tries to export admin entity" do - xhr :post, :export_entity, entity: "staff_action" + post :export_entity, params: { entity: "staff_action" }, format: :json expect(response).not_to be_success end end @@ -43,18 +43,18 @@ describe ExportCsvController do export = UserExport.new() UserExport.expects(:get_download_path).with(file_name).returns(export) subject.expects(:send_file).with(export) - get :show, id: file_name + get :show, params: { id: file_name } expect(response).to be_success end it "returns 404 when the user tries to export another user's csv file" do - get :show, id: export_filename + get :show, params: { id: export_filename } expect(response).to be_not_found end it "returns 404 when the export file does not exist" do UserExport.expects(:get_download_path).returns(nil) - get :show, id: export_filename + get :show, params: { id: export_filename } expect(response).to be_not_found end end @@ -66,14 +66,14 @@ describe ExportCsvController do describe ".export_entity" do it "enqueues export job" do Jobs.expects(:enqueue).with(:export_csv_file, has_entries(entity: "staff_action", user_id: @admin.id)) - xhr :post, :export_entity, entity: "staff_action" + post :export_entity, params: { entity: "staff_action" }, format: :json expect(response).to be_success end it "should not rate limit export for staff" do Jobs.expects(:enqueue).with(:export_csv_file, has_entries(entity: "staff_action", user_id: @admin.id)) UserExport.create(file_name: "screened-email-150116-010145", user_id: @admin.id) - xhr :post, :export_entity, entity: "staff_action" + post :export_entity, params: { entity: "staff_action" }, format: :json expect(response).to be_success end end @@ -86,13 +86,13 @@ describe ExportCsvController do export = UserExport.new() UserExport.expects(:get_download_path).with(file_name).returns(export) subject.expects(:send_file).with(export) - get :show, id: file_name + get :show, params: { id: file_name } expect(response).to be_success end it "returns 404 when the export file does not exist" do UserExport.expects(:get_download_path).returns(nil) - get :show, id: export_filename + get :show, params: { id: export_filename } expect(response).to be_not_found end end diff --git a/spec/controllers/extra_locales_controller_spec.rb b/spec/controllers/extra_locales_controller_spec.rb index 38d128965cd..8ec2784ead2 100644 --- a/spec/controllers/extra_locales_controller_spec.rb +++ b/spec/controllers/extra_locales_controller_spec.rb @@ -5,13 +5,13 @@ describe ExtraLocalesController do context 'show' do it "needs a valid bundle" do - get :show, bundle: 'made-up-bundle' + get :show, params: { bundle: 'made-up-bundle' } expect(response).to_not be_success expect(response.body).to be_blank end it "won't work with a weird parameter" do - get :show, bundle: '-invalid..character!!' + get :show, params: { bundle: '-invalid..character!!' } expect(response).to_not be_success end @@ -22,16 +22,16 @@ describe ExtraLocalesController do JsLocaleHelper.expects(:plugin_translations) .with(I18n.locale.to_s) .returns("admin_js" => { - "admin" => { - "site_settings" => { - "categories" => { - "github_badges" => "Github Badges" - } - } - } - }).at_least_once + "admin" => { + "site_settings" => { + "categories" => { + "github_badges" => "Github Badges" + } + } + } + }).at_least_once - get :show, bundle: "admin" + get :show, params: { bundle: "admin" } expect(response).to be_success expect(response.body.include?("github_badges")).to eq(true) diff --git a/spec/controllers/finish_installation_controller_spec.rb b/spec/controllers/finish_installation_controller_spec.rb index 2e519aedbd1..ea222c9bc21 100644 --- a/spec/controllers/finish_installation_controller_spec.rb +++ b/spec/controllers/finish_installation_controller_spec.rb @@ -50,19 +50,34 @@ describe FinishInstallationController do end it "raises an error when the email is not in the allowed list" do - expect { - post :register, email: 'notrobin@example.com', username: 'eviltrout', password: 'disismypasswordokay' - }.to raise_error(Discourse::InvalidParameters) + expect do + post :register, params: { + email: 'notrobin@example.com', + username: 'eviltrout', + password: 'disismypasswordokay' + }, format: :json + end.to raise_error(Discourse::InvalidParameters) end it "doesn't redirect when fields are wrong" do - post :register, email: 'robin@example.com', username: '', password: 'disismypasswordokay' + post :register, params: { + email: 'robin@example.com', + username: '', + password: 'disismypasswordokay' + } + expect(response).not_to be_redirect end it "registers the admin when the email is in the list" do Jobs.expects(:enqueue).with(:critical_user_email, has_entries(type: :signup)) - post :register, email: 'robin@example.com', username: 'eviltrout', password: 'disismypasswordokay' + + post :register, params: { + email: 'robin@example.com', + username: 'eviltrout', + password: 'disismypasswordokay' + }, format: :json + expect(response).to be_redirect expect(User.where(username: 'eviltrout').exists?).to eq(true) end @@ -87,7 +102,12 @@ describe FinishInstallationController do before do SiteSetting.has_login_hint = true GlobalSetting.stubs(:developer_emails).returns("robin@example.com") - post :register, email: 'robin@example.com', username: 'eviltrout', password: 'disismypasswordokay' + + post :register, params: { + email: 'robin@example.com', + username: 'eviltrout', + password: 'disismypasswordokay' + } end it "resends the email" do diff --git a/spec/controllers/groups_controller_spec.rb b/spec/controllers/groups_controller_spec.rb index 7488dff66da..f73cbcc00f4 100644 --- a/spec/controllers/groups_controller_spec.rb +++ b/spec/controllers/groups_controller_spec.rb @@ -6,20 +6,20 @@ describe GroupsController do describe 'show' do it "ensures the group can be seen" do Guardian.any_instance.expects(:can_see?).with(group).returns(false) - xhr :get, :show, id: group.name + get :show, params: { id: group.name }, format: :json expect(response).not_to be_success end it "responds with JSON" do Guardian.any_instance.expects(:can_see?).with(group).returns(true) - xhr :get, :show, id: group.name + get :show, params: { id: group.name }, format: :json expect(response).to be_success expect(::JSON.parse(response.body)['basic_group']['id']).to eq(group.id) end it "works even with an upper case group name" do Guardian.any_instance.expects(:can_see?).with(group).returns(true) - xhr :get, :show, id: group.name.upcase + get :show, params: { id: group.name.upcase }, format: :json expect(response).to be_success expect(::JSON.parse(response.body)['basic_group']['id']).to eq(group.id) end @@ -28,14 +28,14 @@ describe GroupsController do describe "posts" do it "ensures the group can be seen" do Guardian.any_instance.expects(:can_see?).with(group).returns(false) - xhr :get, :posts, group_id: group.name + get :posts, params: { group_id: group.name }, format: :json expect(response).not_to be_success end it "calls `posts_for` and responds with JSON" do Guardian.any_instance.expects(:can_see?).with(group).returns(true) Group.any_instance.expects(:posts_for).returns(Group.none) - xhr :get, :posts, group_id: group.name + get :posts, params: { group_id: group.name }, format: :json expect(response).to be_success end end @@ -43,13 +43,13 @@ describe GroupsController do describe "members" do it "ensures the group can be seen" do Guardian.any_instance.expects(:can_see?).with(group).returns(false) - xhr :get, :members, group_id: group.name + get :members, params: { group_id: group.name }, format: :json expect(response).not_to be_success end it "calls `posts_for` and responds with JSON" do Guardian.any_instance.expects(:can_see?).with(group).returns(true) - xhr :get, :posts, group_id: group.name + get :posts, params: { group_id: group.name }, format: :json expect(response).to be_success end @@ -57,12 +57,12 @@ describe GroupsController do 5.times { group.add(Fabricate(:user)) } usernames = group.users.map { |m| m.username }.sort - xhr :get, :members, group_id: group.name, limit: 3 + get :members, params: { group_id: group.name, limit: 3 }, format: :json expect(response).to be_success members = JSON.parse(response.body)["members"] expect(members.map { |m| m['username'] }).to eq(usernames[0..2]) - xhr :get, :members, group_id: group.name, limit: 3, offset: 3 + get :members, params: { group_id: group.name, limit: 3, offset: 3 }, format: :json expect(response).to be_success members = JSON.parse(response.body)["members"] expect(members.map { |m| m['username'] }).to eq(usernames[3..4]) @@ -71,7 +71,7 @@ describe GroupsController do describe '.posts_feed' do it 'renders RSS' do - get :posts_feed, group_id: group.name, format: :rss + get :posts_feed, params: { group_id: group.name }, format: :rss expect(response).to be_success expect(response.content_type).to eq('application/rss+xml') end @@ -79,7 +79,7 @@ describe GroupsController do describe '.mentions_feed' do it 'renders RSS' do - get :mentions_feed, group_id: group.name, format: :rss + get :mentions_feed, params: { group_id: group.name }, format: :rss expect(response).to be_success expect(response.content_type).to eq('application/rss+xml') end diff --git a/spec/controllers/inline_onebox_controller_spec.rb b/spec/controllers/inline_onebox_controller_spec.rb index d9a18a4ab85..72ee3762e8a 100644 --- a/spec/controllers/inline_onebox_controller_spec.rb +++ b/spec/controllers/inline_onebox_controller_spec.rb @@ -3,14 +3,16 @@ require 'rails_helper' describe InlineOneboxController do it "requires the user to be logged in" do - expect { xhr :get, :show, urls: [] }.to raise_error(Discourse::NotLoggedIn) + expect do + get :show, params: { urls: [] }, format: :json + end.to raise_error(Discourse::NotLoggedIn) end context "logged in" do let!(:user) { log_in(:user) } it "returns empty JSON for empty input" do - xhr :get, :show, urls: [] + get :show, params: { urls: [] }, format: :json expect(response).to be_success json = JSON.parse(response.body) expect(json['inline-oneboxes']).to eq([]) @@ -20,7 +22,7 @@ describe InlineOneboxController do let(:topic) { Fabricate(:topic) } it "returns information for a valid link" do - xhr :get, :show, urls: [ topic.url ] + get :show, params: { urls: [ topic.url ] }, format: :json expect(response).to be_success json = JSON.parse(response.body) onebox = json['inline-oneboxes'][0] diff --git a/spec/controllers/invites_controller_spec.rb b/spec/controllers/invites_controller_spec.rb index f17f86bb8cd..0dd1b20158f 100644 --- a/spec/controllers/invites_controller_spec.rb +++ b/spec/controllers/invites_controller_spec.rb @@ -3,26 +3,40 @@ require 'rails_helper' describe InvitesController do context '.show' do + render_views + it "shows error if invite not found" do - get :show, id: 'nopeNOPEnope' - expect(response).to render_template(layout: 'no_ember') - expect(flash[:error]).to be_present + get :show, params: { id: 'nopeNOPEnope' } + + expect(response).to be_success + + body = response.body + + expect(body).to_not have_tag(:script, with: { src: '/assets/application.js' }) + expect(CGI.unescapeHTML(body)).to include(I18n.t('invite.not_found')) end it "renders the accept invite page if invite exists" do i = Fabricate(:invite) - get :show, id: i.invite_key - expect(response).to render_template(layout: 'application') - expect(flash[:error]).to be_nil + get :show, params: { id: i.invite_key } + + expect(response).to be_success + + body = response.body + + expect(body).to have_tag(:script, with: { src: '/assets/application.js' }) + expect(CGI.unescapeHTML(body)).to_not include(I18n.t('invite.not_found')) end end context '.destroy' do it 'requires you to be logged in' do - expect { - delete :destroy, email: 'jake@adventuretime.ooo' - }.to raise_error(Discourse::NotLoggedIn) + expect do + delete :destroy, + params: { email: 'jake@adventuretime.ooo' }, + format: :json + end.to raise_error(Discourse::NotLoggedIn) end context 'while logged in' do @@ -31,20 +45,24 @@ describe InvitesController do let(:another_invite) { Fabricate(:invite, email: 'anotheremail@address.com') } it 'raises an error when the email is missing' do - expect { delete :destroy }.to raise_error(ActionController::ParameterMissing) + expect { delete :destroy, format: :json }.to raise_error(ActionController::ParameterMissing) end it "raises an error when the email cannot be found" do - expect { delete :destroy, email: 'finn@adventuretime.ooo' }.to raise_error(Discourse::InvalidParameters) + expect do + delete :destroy, params: { email: 'finn@adventuretime.ooo' }, format: :json + end.to raise_error(Discourse::InvalidParameters) end it 'raises an error when the invite is not yours' do - expect { delete :destroy, email: another_invite.email }.to raise_error(Discourse::InvalidParameters) + expect do + delete :destroy, params: { email: another_invite.email }, format: :json + end.to raise_error(Discourse::InvalidParameters) end it "destroys the invite" do Invite.any_instance.expects(:trash!).with(user) - delete :destroy, email: invite.email + delete :destroy, params: { email: invite.email }, format: :json end end @@ -54,7 +72,7 @@ describe InvitesController do context '#create' do it 'requires you to be logged in' do expect do - post :create, email: 'jake@adventuretime.ooo' + post :create, params: { email: 'jake@adventuretime.ooo' }, format: :json end.to raise_error(Discourse::NotLoggedIn) end @@ -63,7 +81,7 @@ describe InvitesController do it "fails if you can't invite to the forum" do log_in - post :create, email: email + post :create, params: { email: email }, format: :json expect(response).not_to be_success end @@ -71,7 +89,7 @@ describe InvitesController do user = log_in(:trust_level_4) invite = Invite.invite_by_email("invite@example.com", user) invite.reload - post :create, email: invite.email + post :create, params: { email: invite.email }, format: :json expect(response).not_to be_success json = JSON.parse(response.body) expect(json["failed"]).to be_present @@ -80,7 +98,7 @@ describe InvitesController do it "allows admins to invite to groups" do group = Fabricate(:group) log_in(:admin) - post :create, email: email, group_names: group.name + post :create, params: { email: email, group_names: group.name }, format: :json expect(response).to be_success expect(Invite.find_by(email: email).invited_groups.count).to eq(1) end @@ -91,7 +109,7 @@ describe InvitesController do user.update!(trust_level: TrustLevel[2]) group.add_owner(user) - post :create, email: email, group_names: group.name + post :create, params: { email: email, group_names: group.name }, format: :json expect(response).to be_success expect(Invite.find_by(email: email).invited_groups.count).to eq(1) @@ -101,13 +119,13 @@ describe InvitesController do user = log_in(:admin) invite = Invite.invite_by_email("invite@example.com", user) invite.reload - post :create, email: invite.email + post :create, params: { email: invite.email }, format: :json expect(response).to be_success end it "responds with error message in case of validation failure" do log_in(:admin) - post :create, email: "test@mailinator.com" + post :create, params: { email: "test@mailinator.com" }, format: :json expect(response).not_to be_success json = JSON.parse(response.body) expect(json["errors"]).to be_present @@ -119,7 +137,9 @@ describe InvitesController do context '.create_invite_link' do it 'requires you to be logged in' do expect { - post :create_invite_link, email: 'jake@adventuretime.ooo' + post :create_invite_link, params: { + email: 'jake@adventuretime.ooo' + }, format: :json }.to raise_error(Discourse::NotLoggedIn) end @@ -128,7 +148,7 @@ describe InvitesController do it "fails if you can't invite to the forum" do log_in - post :create_invite_link, email: email + post :create_invite_link, params: { email: email }, format: :json expect(response).not_to be_success end @@ -136,14 +156,22 @@ describe InvitesController do user = log_in(:trust_level_4) invite = Invite.invite_by_email("invite@example.com", user) invite.reload - post :create_invite_link, email: invite.email + + post :create_invite_link, params: { + email: invite.email + }, format: :json + expect(response).not_to be_success end it "allows admins to invite to groups" do group = Fabricate(:group) log_in(:admin) - post :create_invite_link, email: email, group_names: group.name + + post :create_invite_link, params: { + email: email, group_names: group.name + }, format: :json + expect(response).to be_success expect(Invite.find_by(email: email).invited_groups.count).to eq(1) end @@ -152,7 +180,11 @@ describe InvitesController do Fabricate(:group, name: "security") Fabricate(:group, name: "support") log_in(:admin) - post :create_invite_link, email: email, group_names: "security,support" + + post :create_invite_link, params: { + email: email, group_names: "security,support" + }, format: :json + expect(response).to be_success expect(Invite.find_by(email: email).invited_groups.count).to eq(2) end @@ -163,7 +195,7 @@ describe InvitesController do context 'with an invalid invite id' do before do - xhr :put, :perform_accept_invitation, id: "doesn't exist", format: :json + put :perform_accept_invitation, params: { id: "doesn't exist" }, format: :json end it "redirects to the root" do @@ -183,7 +215,7 @@ describe InvitesController do let(:invite) { topic.invite_by_email(topic.user, "iceking@adventuretime.ooo") } let(:deleted_invite) { invite.destroy; invite } before do - xhr :put, :perform_accept_invitation, id: deleted_invite.invite_key, format: :json + put :perform_accept_invitation, params: { id: deleted_invite.invite_key }, format: :json end it "redirects to the root" do @@ -204,14 +236,14 @@ describe InvitesController do it 'redeems the invite' do Invite.any_instance.expects(:redeem) - xhr :put, :perform_accept_invitation, id: invite.invite_key, format: :json + put :perform_accept_invitation, params: { id: invite.invite_key }, format: :json end context 'when redeem returns a user' do let(:user) { Fabricate(:coding_horror) } context 'success' do - subject { xhr :put, :perform_accept_invitation, id: invite.invite_key, format: :json } + subject { put :perform_accept_invitation, params: { id: invite.invite_key }, format: :json } before do Invite.any_instance.expects(:redeem).returns(user) @@ -236,7 +268,7 @@ describe InvitesController do end context 'failure' do - subject { xhr :put, :perform_accept_invitation, id: invite.invite_key, format: :json } + subject { put :perform_accept_invitation, params: { id: invite.invite_key }, format: :json } it "doesn't log in the user if there's a validation error" do user.errors.add(:password, :common) @@ -260,32 +292,32 @@ describe InvitesController do user.send_welcome_message = true user.expects(:enqueue_welcome_message).with('welcome_invite') Jobs.expects(:enqueue).with(:invite_password_instructions_email, has_entries(username: user.username)) - xhr :put, :perform_accept_invitation, id: invite.invite_key, format: :json + put :perform_accept_invitation, params: { id: invite.invite_key }, format: :json end it "sends password reset email if password is not set" do user.expects(:enqueue_welcome_message).with('welcome_invite').never Jobs.expects(:enqueue).with(:invite_password_instructions_email, has_entries(username: user.username)) - xhr :put, :perform_accept_invitation, id: invite.invite_key, format: :json + put :perform_accept_invitation, params: { id: invite.invite_key }, format: :json end it "does not send password reset email if sso is enabled" do SiteSetting.enable_sso = true Jobs.expects(:enqueue).with(:invite_password_instructions_email, has_key(:username)).never - xhr :put, :perform_accept_invitation, id: invite.invite_key, format: :json + put :perform_accept_invitation, params: { id: invite.invite_key }, format: :json end it "does not send password reset email if local login is disabled" do SiteSetting.enable_local_logins = false Jobs.expects(:enqueue).with(:invite_password_instructions_email, has_key(:username)).never - xhr :put, :perform_accept_invitation, id: invite.invite_key, format: :json + put :perform_accept_invitation, params: { id: invite.invite_key }, format: :json end it 'sends an activation email if password is set' do user.password_hash = 'qaw3ni3h2wyr63lakw7pea1nrtr44pls' Jobs.expects(:enqueue).with(:invite_password_instructions_email, has_key(:username)).never Jobs.expects(:enqueue).with(:critical_user_email, has_entries(type: :signup, user_id: user.id)) - xhr :put, :perform_accept_invitation, id: invite.invite_key, format: :json + put :perform_accept_invitation, params: { id: invite.invite_key }, format: :json end end end @@ -298,7 +330,7 @@ describe InvitesController do it "doesn't redeem the invite" do Invite.any_instance.stubs(:redeem).never - put :perform_accept_invitation, id: invite.invite_key + put :perform_accept_invitation, params: { id: invite.invite_key }, format: :json end end @@ -309,7 +341,7 @@ describe InvitesController do it "doesn't redeem the invite" do Invite.any_instance.stubs(:redeem).never - put :perform_accept_invitation, id: invite.invite_key + put :perform_accept_invitation, params: { id: invite.invite_key }, format: :json end end end @@ -318,7 +350,7 @@ describe InvitesController do it 'requires you to be logged in' do expect { - delete :resend_invite, email: 'first_name@example.com' + delete :resend_invite, params: { email: 'first_name@example.com' }, format: :json }.to raise_error(Discourse::NotLoggedIn) end @@ -328,20 +360,24 @@ describe InvitesController do let(:another_invite) { Fabricate(:invite, email: 'last_name@example.com') } it 'raises an error when the email is missing' do - expect { post :resend_invite }.to raise_error(ActionController::ParameterMissing) + expect { post :resend_invite, format: :json }.to raise_error(ActionController::ParameterMissing) end it "raises an error when the email cannot be found" do - expect { post :resend_invite, email: 'first_name@example.com' }.to raise_error(Discourse::InvalidParameters) + expect do + post :resend_invite, params: { email: 'first_name@example.com' }, format: :json + end.to raise_error(Discourse::InvalidParameters) end it 'raises an error when the invite is not yours' do - expect { post :resend_invite, email: another_invite.email }.to raise_error(Discourse::InvalidParameters) + expect do + post :resend_invite, params: { email: another_invite.email }, format: :json + end.to raise_error(Discourse::InvalidParameters) end it "resends the invite" do Invite.any_instance.expects(:resend_invite) - post :resend_invite, email: invite.email + post :resend_invite, params: { email: invite.email }, format: :json end end @@ -351,26 +387,28 @@ describe InvitesController do context '.upload_csv' do it 'requires you to be logged in' do expect { - xhr :post, :upload_csv + post :upload_csv, format: :json }.to raise_error(Discourse::NotLoggedIn) end context 'while logged in' do let(:csv_file) { File.new("#{Rails.root}/spec/fixtures/csv/discourse.csv") } + let(:file) do - ActionDispatch::Http::UploadedFile.new(filename: 'discourse.csv', tempfile: csv_file) + Rack::Test::UploadedFile.new(File.open(csv_file)) end + let(:filename) { 'discourse.csv' } it "fails if you can't bulk invite to the forum" do log_in - xhr :post, :upload_csv, file: file, name: filename + post :upload_csv, params: { file: file, name: filename }, format: :json expect(response).not_to be_success end it "allows admin to bulk invite" do log_in(:admin) - xhr :post, :upload_csv, file: file, name: filename + post :upload_csv, params: { file: file, name: filename }, format: :json expect(response).to be_success end end diff --git a/spec/controllers/list_controller_spec.rb b/spec/controllers/list_controller_spec.rb index 2117193f4bf..3de5a762b21 100644 --- a/spec/controllers/list_controller_spec.rb +++ b/spec/controllers/list_controller_spec.rb @@ -11,23 +11,11 @@ describe ListController do SiteSetting.top_menu = 'latest,-video|new|unread|categories|category/beer' end - describe 'titles for crawler layout' do - it 'has no title for the default URL' do - xhr :get, Discourse.anonymous_filters[0], _escaped_fragment_: 'true' - expect(assigns(:title)).to be_blank - end - - it 'has a title for non-default URLs' do - xhr :get, Discourse.anonymous_filters[1], _escaped_fragment_: 'true' - expect(assigns(:title)).to be_present - end - end - describe 'indexes' do (Discourse.anonymous_filters - [:categories]).each do |filter| context "#{filter}" do - before { xhr :get, filter } + before { get filter } it { is_expected.to respond_with(:success) } end end @@ -35,14 +23,14 @@ describe ListController do it 'allows users to filter on a set of topic ids' do p = create_post - xhr :get, :latest, format: :json, topic_ids: "#{p.topic_id}" + get :latest, format: :json, params: { topic_ids: "#{p.topic_id}" } expect(response).to be_success parsed = JSON.parse(response.body) expect(parsed["topic_list"]["topics"].length).to eq(1) end it "doesn't throw an error with a negative page" do - xhr :get, :top, page: -1024 + get :top, params: { page: -1024 } expect(response).to be_success end end @@ -105,7 +93,7 @@ describe ListController do context 'without access to see the category' do before do Guardian.any_instance.expects(:can_see?).with(category).returns(false) - xhr :get, :category_latest, category: category.slug + get :category_latest, params: { category: category.slug } end it { is_expected.not_to respond_with(:success) } @@ -113,7 +101,7 @@ describe ListController do context 'with access to see the category' do before do - xhr :get, :category_latest, category: category.slug + get :category_latest, params: { category: category.slug } end it { is_expected.to respond_with(:success) } @@ -121,7 +109,9 @@ describe ListController do context 'with a link that includes an id' do before do - xhr :get, :category_latest, category: "#{category.id}-#{category.slug}" + get :category_latest, params: { + category: "#{category.id}-#{category.slug}" + } end it { is_expected.to respond_with(:success) } @@ -132,7 +122,11 @@ describe ListController do context "with valid slug" do before do - xhr :get, :category_latest, parent_category: category.slug, category: child_category.slug, id: child_category.id + get :category_latest, params: { + parent_category: category.slug, + category: child_category.slug, + id: child_category.id + } end it { is_expected.to redirect_to(child_category.url) } @@ -140,7 +134,11 @@ describe ListController do context "with invalid slug" do before do - xhr :get, :category_latest, parent_category: 'random slug', category: 'random slug', id: child_category.id + get :category_latest, params: { + parent_category: 'random slug', + category: 'random slug', + id: child_category.id + } end it { is_expected.to redirect_to(child_category.url) } @@ -151,14 +149,17 @@ describe ListController do # One category has another category's id at the beginning of its name let!(:other_category) { Fabricate(:category, name: "#{category.id} name") } - before do - xhr :get, :category_latest, category: other_category.slug - end - - it { is_expected.to respond_with(:success) } - it 'uses the correct category' do - expect(assigns(:category)).to eq(other_category) + get :category_latest, + params: { category: other_category.slug }, + format: :json + + expect(response).to be_success + + body = JSON.parse(response.body) + + expect(body["topic_list"]["topics"].first["category_id"]) + .to eq(other_category.id) end end @@ -167,7 +168,9 @@ describe ListController do context 'when parent and child are requested' do before do - xhr :get, :category_latest, parent_category: category.slug, category: sub_category.slug + get :category_latest, params: { + parent_category: category.slug, category: sub_category.slug + } end it { is_expected.to respond_with(:success) } @@ -175,7 +178,9 @@ describe ListController do context 'when child is requested with the wrong parent' do before do - xhr :get, :category_latest, parent_category: 'not_the_right_slug', category: sub_category.slug + get :category_latest, params: { + parent_category: 'not_the_right_slug', category: sub_category.slug + } end it { is_expected.not_to respond_with(:success) } @@ -184,7 +189,7 @@ describe ListController do describe 'feed' do it 'renders RSS' do - get :category_feed, category: category.slug, format: :rss + get :category_feed, params: { category: category.slug }, format: :rss expect(response).to be_success expect(response.content_type).to eq('application/rss+xml') end @@ -194,28 +199,28 @@ describe ListController do it "has a top default view" do category.update_attributes!(default_view: 'top', default_top_period: 'monthly') described_class.expects(:best_period_with_topics_for).with(anything, category.id, :monthly).returns(:monthly) - xhr :get, :category_default, category: category.slug + get :category_default, params: { category: category.slug } expect(response).to be_success end it "has a default view of nil" do category.update_attributes!(default_view: nil) described_class.expects(:best_period_for).never - xhr :get, :category_default, category: category.slug + get :category_default, params: { category: category.slug } expect(response).to be_success end it "has a default view of ''" do category.update_attributes!(default_view: '') described_class.expects(:best_period_for).never - xhr :get, :category_default, category: category.slug + get :category_default, params: { category: category.slug } expect(response).to be_success end it "has a default view of latest" do category.update_attributes!(default_view: 'latest') described_class.expects(:best_period_for).never - xhr :get, :category_default, category: category.slug + get :category_default, params: { category: category.slug } expect(response).to be_success end end @@ -224,13 +229,13 @@ describe ListController do render_views it 'for category default view' do - get :category_default, category: category.slug + get :category_default, params: { category: category.slug } expect(response).to be_success expect(css_select("link[rel=canonical]").length).to eq(1) end it 'for category latest view' do - get :category_latest, category: category.slug + get :category_latest, params: { category: category.slug } expect(response).to be_success expect(css_select("link[rel=canonical]").length).to eq(1) end @@ -242,7 +247,7 @@ describe ListController do let!(:user) { log_in } it "should respond with a list" do - xhr :get, :topics_by, username: @user.username + get :topics_by, params: { username: @user.username } expect(response).to be_success end end @@ -252,13 +257,13 @@ describe ListController do it "raises an error when can_see_private_messages? is false " do Guardian.any_instance.expects(:can_see_private_messages?).returns(false) - xhr :get, :private_messages, username: @user.username + get :private_messages, params: { username: @user.username } expect(response).to be_forbidden end it "succeeds when can_see_private_messages? is false " do Guardian.any_instance.expects(:can_see_private_messages?).returns(true) - xhr :get, :private_messages, username: @user.username + get :private_messages, params: { username: @user.username } expect(response).to be_success end end @@ -268,13 +273,13 @@ describe ListController do it "raises an error when can_see_private_messages? is false " do Guardian.any_instance.expects(:can_see_private_messages?).returns(false) - xhr :get, :private_messages_sent, username: @user.username + get :private_messages_sent, params: { username: @user.username } expect(response).to be_forbidden end it "succeeds when can_see_private_messages? is false " do Guardian.any_instance.expects(:can_see_private_messages?).returns(true) - xhr :get, :private_messages_sent, username: @user.username + get :private_messages_sent, params: { username: @user.username } expect(response).to be_success end end @@ -284,26 +289,26 @@ describe ListController do it "raises an error when can_see_private_messages? is false " do Guardian.any_instance.expects(:can_see_private_messages?).returns(false) - xhr :get, :private_messages_unread, username: @user.username + get :private_messages_unread, params: { username: @user.username } expect(response).to be_forbidden end it "succeeds when can_see_private_messages? is false " do Guardian.any_instance.expects(:can_see_private_messages?).returns(true) - xhr :get, :private_messages_unread, username: @user.username + get :private_messages_unread, params: { username: @user.username } expect(response).to be_success end end context 'read' do it 'raises an error when not logged in' do - expect { xhr :get, :read }.to raise_error(Discourse::NotLoggedIn) + expect { get :read }.to raise_error(Discourse::NotLoggedIn) end context 'when logged in' do before do log_in_user(@user) - xhr :get, :read + get :read end it { is_expected.to respond_with(:success) } @@ -378,7 +383,7 @@ describe ListController do end it "does not suppress" do - get SiteSetting.homepage, category: category_one.id, format: :json + get SiteSetting.homepage, params: { category: category_one.id }, format: :json expect(response).to be_success topic_titles = JSON.parse(response.body)["topic_list"]["topics"].map { |t| t["title"] } @@ -395,11 +400,11 @@ describe ListController do expect(response.body).to match(/plugin\.js/) expect(response.body).to match(/plugin-third-party\.js/) - get :latest, safe_mode: "no_plugins" + get :latest, params: { safe_mode: "no_plugins" } expect(response.body).not_to match(/plugin\.js/) expect(response.body).not_to match(/plugin-third-party\.js/) - get :latest, safe_mode: "only_official" + get :latest, params: { safe_mode: "only_official" } expect(response.body).to match(/plugin\.js/) expect(response.body).not_to match(/plugin-third-party\.js/) diff --git a/spec/controllers/notifications_controller_spec.rb b/spec/controllers/notifications_controller_spec.rb index f521898bf07..b5d4b1acbcd 100644 --- a/spec/controllers/notifications_controller_spec.rb +++ b/spec/controllers/notifications_controller_spec.rb @@ -7,12 +7,12 @@ describe NotificationsController do describe '#index' do it 'should succeed for recent' do - xhr :get, :index, recent: true + get :index, params: { recent: true } expect(response).to be_success end it 'should succeed for history' do - xhr :get, :index + get :index expect(response).to be_success end @@ -20,7 +20,7 @@ describe NotificationsController do notification = Fabricate(:notification, user: user) expect(user.reload.unread_notifications).to eq(1) expect(user.reload.total_unread_notifications).to eq(1) - xhr :get, :index, recent: true + get :index, params: { recent: true }, format: :json expect(user.reload.unread_notifications).to eq(0) expect(user.reload.total_unread_notifications).to eq(1) end @@ -29,14 +29,14 @@ describe NotificationsController do notification = Fabricate(:notification, user: user) expect(user.reload.unread_notifications).to eq(1) expect(user.reload.total_unread_notifications).to eq(1) - xhr :get, :index, recent: true, silent: true + get :index, params: { recent: true, silent: true } expect(user.reload.unread_notifications).to eq(1) expect(user.reload.total_unread_notifications).to eq(1) end context 'when username params is not valid' do it 'should raise the right error' do - xhr :get, :index, username: 'somedude' + get :index, params: { username: 'somedude' }, format: :json expect(response).to_not be_success expect(response.status).to eq(404) @@ -45,14 +45,14 @@ describe NotificationsController do end it 'should succeed' do - xhr :put, :mark_read + put :mark_read, format: :json expect(response).to be_success end it "can update a single notification" do notification = Fabricate(:notification, user: user) notification2 = Fabricate(:notification, user: user) - xhr :put, :mark_read, id: notification.id + put :mark_read, params: { id: notification.id }, format: :json expect(response).to be_success notification.reload @@ -66,7 +66,7 @@ describe NotificationsController do notification = Fabricate(:notification, user: user) expect(user.reload.unread_notifications).to eq(1) expect(user.reload.total_unread_notifications).to eq(1) - xhr :put, :mark_read + put :mark_read, format: :json user.reload expect(user.reload.unread_notifications).to eq(0) expect(user.reload.total_unread_notifications).to eq(0) @@ -75,7 +75,9 @@ describe NotificationsController do context 'when not logged in' do it 'should raise an error' do - expect { xhr :get, :index, recent: true }.to raise_error(Discourse::NotLoggedIn) + expect do + get :index, params: { recent: true }, format: :json + end.to raise_error(Discourse::NotLoggedIn) end end diff --git a/spec/controllers/onebox_controller_spec.rb b/spec/controllers/onebox_controller_spec.rb index dcb9354ee80..403a6279fe8 100644 --- a/spec/controllers/onebox_controller_spec.rb +++ b/spec/controllers/onebox_controller_spec.rb @@ -5,7 +5,9 @@ describe OneboxController do let(:url) { "http://google.com" } it "requires the user to be logged in" do - expect { xhr :get, :show, url: url }.to raise_error(Discourse::NotLoggedIn) + expect do + get :show, params: { url: url }, format: :json + end.to raise_error(Discourse::NotLoggedIn) end describe "logged in" do @@ -14,7 +16,7 @@ describe OneboxController do it 'invalidates the cache if refresh is passed' do Oneboxer.expects(:preview).with(url, invalidate_oneboxes: true) - xhr :get, :show, url: url, refresh: 'true', user_id: @user.id + get :show, params: { url: url, refresh: 'true', user_id: @user.id }, format: :json end describe "cached onebox" do @@ -24,14 +26,11 @@ describe OneboxController do before do Oneboxer.expects(:cached_preview).with(url).returns(body) Oneboxer.expects(:preview).never - xhr :get, :show, url: url, user_id: @user.id - end - - it "returns success" do - expect(response).to be_success + get :show, params: { url: url, user_id: @user.id }, format: :json end it "returns the cached onebox response in the body" do + expect(response).to be_success expect(response.body).to eq(body) end @@ -41,7 +40,7 @@ describe OneboxController do it "returns 429" do Oneboxer.expects(:is_previewing?).returns(true) - xhr :get, :show, url: url, user_id: @user.id + get :show, params: { url: url, user_id: @user.id }, format: :json expect(response.status).to eq(429) end @@ -53,14 +52,11 @@ describe OneboxController do before do Oneboxer.expects(:preview).with(url, invalidate_oneboxes: false).returns(body) - xhr :get, :show, url: url, user_id: @user.id - end - - it 'returns success' do - expect(response).to be_success + get :show, params: { url: url, user_id: @user.id }, format: :json end it 'returns the onebox response in the body' do + expect(response).to be_success expect(response.body).to eq(body) end @@ -70,13 +66,13 @@ describe OneboxController do it "returns 404 if the onebox is nil" do Oneboxer.expects(:preview).with(url, invalidate_oneboxes: false).returns(nil) - xhr :get, :show, url: url, user_id: @user.id + get :show, params: { url: url, user_id: @user.id }, format: :json expect(response.response_code).to eq(404) end it "returns 404 if the onebox is an empty string" do Oneboxer.expects(:preview).with(url, invalidate_oneboxes: false).returns(" \t ") - xhr :get, :show, url: url, user_id: @user.id + get :show, params: { url: url, user_id: @user.id }, format: :json expect(response.response_code).to eq(404) end diff --git a/spec/controllers/permalinks_controller_spec.rb b/spec/controllers/permalinks_controller_spec.rb index d88f7c7d671..595571f9bdb 100644 --- a/spec/controllers/permalinks_controller_spec.rb +++ b/spec/controllers/permalinks_controller_spec.rb @@ -5,7 +5,7 @@ describe PermalinksController do it "should redirect to a permalink's target_url with status 301" do permalink = Fabricate(:permalink) Permalink.any_instance.stubs(:target_url).returns('/t/the-topic-slug/42') - get :show, url: permalink.url + get :show, params: { url: permalink.url } expect(response).to redirect_to('/t/the-topic-slug/42') expect(response.status).to eq(301) end @@ -15,7 +15,7 @@ describe PermalinksController do Discourse.stubs(:base_uri).returns("/forum") permalink = Fabricate(:permalink) Permalink.any_instance.stubs(:target_url).returns('/forum/t/the-topic-slug/42') - get :show, url: permalink.url + get :show, params: { url: permalink.url } expect(response).to redirect_to('/forum/t/the-topic-slug/42') expect(response.status).to eq(301) end @@ -25,20 +25,20 @@ describe PermalinksController do permalink = Fabricate(:permalink, url: '/topic/bla', external_url: '/topic/100') - get :show, url: permalink.url, test: "hello" + get :show, params: { url: permalink.url, test: "hello" } expect(response).to redirect_to('/topic/100') expect(response.status).to eq(301) SiteSetting.permalink_normalizations = "/(.*)\\?.*/\\1X" - get :show, url: permalink.url, test: "hello" + get :show, params: { url: permalink.url, test: "hello" } expect(response.status).to eq(404) end it 'return 404 if permalink record does not exist' do - get :show, url: '/not/a/valid/url' + get :show, params: { url: '/not/a/valid/url' } expect(response.status).to eq(404) end end diff --git a/spec/controllers/post_action_users_controller_spec.rb b/spec/controllers/post_action_users_controller_spec.rb index 121df7a1324..702194b896a 100644 --- a/spec/controllers/post_action_users_controller_spec.rb +++ b/spec/controllers/post_action_users_controller_spec.rb @@ -11,7 +11,7 @@ describe PostActionUsersController do PostAction.act(post.user, post, notify_mod, message: 'well something is wrong here!') PostAction.act(Fabricate(:user), post, notify_mod, message: 'well something is not wrong here!') - xhr :get, :index, id: post.id, post_action_type_id: notify_mod + get :index, params: { id: post.id, post_action_type_id: notify_mod }, format: :json expect(response.status).to eq(200) json = JSON.parse(response.body) users = json["post_action_users"] @@ -22,30 +22,43 @@ describe PostActionUsersController do end it 'raises an error without an id' do - expect { - xhr :get, :index, post_action_type_id: PostActionType.types[:like] - }.to raise_error(ActionController::ParameterMissing) + expect do + get :index, + params: { post_action_type_id: PostActionType.types[:like] }, + format: :json + end.to raise_error(ActionController::ParameterMissing) end it 'raises an error without a post action type' do - expect { - xhr :get, :index, id: post.id - }.to raise_error(ActionController::ParameterMissing) + expect do + get :index, params: { id: post.id }, format: :json + end.to raise_error(ActionController::ParameterMissing) end it "fails when the user doesn't have permission to see the post" do Guardian.any_instance.expects(:can_see?).with(post).returns(false) - xhr :get, :index, id: post.id, post_action_type_id: PostActionType.types[:like] + + get :index, params: { + id: post.id, post_action_type_id: PostActionType.types[:like] + }, format: :json + expect(response).to be_forbidden end it 'raises an error when anon tries to look at an invalid action' do - xhr :get, :index, id: Fabricate(:post).id, post_action_type_id: PostActionType.types[:notify_moderators] + get :index, params: { + id: Fabricate(:post).id, + post_action_type_id: PostActionType.types[:notify_moderators] + }, format: :json + expect(response).to be_forbidden end it 'succeeds' do - xhr :get, :index, id: post.id, post_action_type_id: PostActionType.types[:like] + get :index, params: { + id: post.id, post_action_type_id: PostActionType.types[:like] + } + expect(response).to be_success end end diff --git a/spec/controllers/post_actions_controller_spec.rb b/spec/controllers/post_actions_controller_spec.rb index a4b335f2042..5a68642acee 100644 --- a/spec/controllers/post_actions_controller_spec.rb +++ b/spec/controllers/post_actions_controller_spec.rb @@ -4,7 +4,9 @@ describe PostActionsController do describe 'create' do it 'requires you to be logged in' do - expect { xhr :post, :create }.to raise_error(Discourse::NotLoggedIn) + expect do + post :create, format: :json + end.to raise_error(Discourse::NotLoggedIn) end context 'logged in as user' do @@ -16,80 +18,14 @@ describe PostActionsController do end it 'fails when the user does not have permission to see the post' do - xhr :post, :create, id: private_message.id, post_action_type_id: PostActionType.types[:bookmark] + post :create, params: { + id: private_message.id, + post_action_type_id: PostActionType.types[:bookmark] + }, format: :json + expect(response).to be_forbidden end end - - describe 'logged in as moderator' do - before do - @user = log_in(:moderator) - @post = Fabricate(:post, user: Fabricate(:coding_horror)) - end - - it 'raises an error when the id is missing' do - expect { xhr :post, :create, post_action_type_id: PostActionType.types[:like] }.to raise_error(ActionController::ParameterMissing) - end - - it 'fails when the id is invalid' do - xhr :post, :create, post_action_type_id: PostActionType.types[:like], id: -1 - expect(response.status).to eq(404) - end - - it 'raises an error when the post_action_type_id index is missing' do - expect { xhr :post, :create, id: @post.id }.to raise_error(ActionController::ParameterMissing) - end - - it "fails when the user doesn't have permission to see the post" do - @post = Fabricate(:private_message_post, user: Fabricate(:user)) - xhr :post, :create, id: @post.id, post_action_type_id: PostActionType.types[:like] - expect(response).to be_forbidden - end - - it 'allows us to create an post action on a post' do - PostAction.expects(:act).once.with(@user, @post, PostActionType.types[:like], {}) - xhr :post, :create, id: @post.id, post_action_type_id: PostActionType.types[:like] - end - - it "passes a list of taken actions through" do - PostAction.create(post_id: @post.id, user_id: @user.id, post_action_type_id: PostActionType.types[:inappropriate]) - - Guardian.any_instance.expects(:post_can_act?).with(@post, :off_topic, - has_entry(opts: has_entry(taken_actions: has_key(PostActionType.types[:inappropriate]))) - ) - - xhr :post, :create, id: @post.id, post_action_type_id: PostActionType.types[:off_topic] - end - - it 'passes the message through' do - PostAction.expects(:act).once.with(@user, @post, PostActionType.types[:like], message: 'action message goes here') - xhr :post, :create, id: @post.id, post_action_type_id: PostActionType.types[:like], message: 'action message goes here' - end - - it 'passes the message through as warning' do - PostAction.expects(:act).once.with(@user, @post, PostActionType.types[:like], message: 'action message goes here', is_warning: true) - xhr :post, :create, id: @post.id, post_action_type_id: PostActionType.types[:like], message: 'action message goes here', is_warning: true - end - - it "doesn't create message as a warning if the user isn't staff" do - Guardian.any_instance.stubs(:is_staff?).returns(false) - PostAction.expects(:act).once.with(@user, @post, PostActionType.types[:like], message: 'action message goes here') - xhr :post, :create, id: @post.id, post_action_type_id: PostActionType.types[:like], message: 'action message goes here', is_warning: true - end - - it 'passes take_action through' do - PostAction.expects(:act).once.with(@user, @post, PostActionType.types[:like], take_action: true) - xhr :post, :create, id: @post.id, post_action_type_id: PostActionType.types[:like], take_action: 'true' - end - - it "doesn't pass take_action through if the user isn't staff" do - Guardian.any_instance.stubs(:is_staff?).returns(false) - PostAction.expects(:act).once.with(@user, @post, PostActionType.types[:like], {}) - xhr :post, :create, id: @post.id, post_action_type_id: PostActionType.types[:like], take_action: 'true' - end - - end - end context 'destroy' do @@ -97,18 +33,22 @@ describe PostActionsController do let(:post) { Fabricate(:post, user: Fabricate(:coding_horror)) } it 'requires you to be logged in' do - expect { xhr :delete, :destroy, id: post.id }.to raise_error(Discourse::NotLoggedIn) + expect do + delete :destroy, params: { id: post.id }, format: :json + end.to raise_error(Discourse::NotLoggedIn) end context 'logged in' do let!(:user) { log_in } it 'raises an error when the post_action_type_id is missing' do - expect { xhr :delete, :destroy, id: post.id }.to raise_error(ActionController::ParameterMissing) + expect do + delete :destroy, params: { id: post.id }, format: :json + end.to raise_error(ActionController::ParameterMissing) end it "returns 404 when the post action type doesn't exist for that user" do - xhr :delete, :destroy, id: post.id, post_action_type_id: 1 + delete :destroy, params: { id: post.id, post_action_type_id: 1 }, format: :json expect(response.code).to eq('404') end @@ -116,18 +56,25 @@ describe PostActionsController do let!(:post_action) { PostAction.create(user_id: user.id, post_id: post.id, post_action_type_id: 1) } it 'returns success' do - xhr :delete, :destroy, id: post.id, post_action_type_id: 1 + delete :destroy, params: { id: post.id, post_action_type_id: 1 }, format: :json expect(response).to be_success end it 'deletes the action' do - xhr :delete, :destroy, id: post.id, post_action_type_id: 1 + delete :destroy, params: { + id: post.id, post_action_type_id: 1 + }, format: :json + expect(PostAction.exists?(user_id: user.id, post_id: post.id, post_action_type_id: 1, deleted_at: nil)).to eq(false) end it 'ensures it can be deleted' do Guardian.any_instance.expects(:can_delete?).with(post_action).returns(false) - xhr :delete, :destroy, id: post.id, post_action_type_id: 1 + + delete :destroy, params: { + id: post.id, post_action_type_id: 1 + }, format: :json + expect(response).to be_forbidden end end @@ -142,7 +89,9 @@ describe PostActionsController do context "not logged in" do it "should not allow them to clear flags" do - expect { xhr :post, :defer_flags }.to raise_error(Discourse::NotLoggedIn) + expect do + post :defer_flags, format: :json + end.to raise_error(Discourse::NotLoggedIn) end end @@ -150,12 +99,18 @@ describe PostActionsController do let!(:user) { log_in(:moderator) } it "raises an error without a post_action_type_id" do - expect { xhr :post, :defer_flags, id: flagged_post.id }.to raise_error(ActionController::ParameterMissing) + expect do + post :defer_flags, params: { id: flagged_post.id }, format: :json + end.to raise_error(ActionController::ParameterMissing) end it "raises an error when the user doesn't have access" do Guardian.any_instance.expects(:can_defer_flags?).returns(false) - xhr :post, :defer_flags, id: flagged_post.id, post_action_type_id: PostActionType.types[:spam] + + post :defer_flags, params: { + id: flagged_post.id, post_action_type_id: PostActionType.types[:spam] + }, format: :json + expect(response).to be_forbidden end @@ -166,13 +121,20 @@ describe PostActionsController do end it "delegates to defer_flags" do - xhr :post, :defer_flags, id: flagged_post.id, post_action_type_id: PostActionType.types[:spam] + post :defer_flags, params: { + id: flagged_post.id, post_action_type_id: PostActionType.types[:spam] + }, format: :json + expect(response).to be_success end it "works with a deleted post" do flagged_post.trash!(user) - xhr :post, :defer_flags, id: flagged_post.id, post_action_type_id: PostActionType.types[:spam] + + post :defer_flags, params: { + id: flagged_post.id, post_action_type_id: PostActionType.types[:spam] + }, format: :json + expect(response).to be_success end diff --git a/spec/controllers/posts_controller_spec.rb b/spec/controllers/posts_controller_spec.rb index e2c4300146a..5a1850792ef 100644 --- a/spec/controllers/posts_controller_spec.rb +++ b/spec/controllers/posts_controller_spec.rb @@ -6,12 +6,12 @@ shared_examples 'finding and showing post' do it 'ensures the user can see the post' do Guardian.any_instance.expects(:can_see?).with(post).returns(false) - xhr :get, action, params + get action, params: params, format: :json expect(response).to be_forbidden end it 'succeeds' do - xhr :get, action, params + get action, params: params, format: :json expect(response).to be_success end @@ -21,25 +21,25 @@ shared_examples 'finding and showing post' do end it "can't find deleted posts as an anonymous user" do - xhr :get, action, params + get action, params: params, format: :json expect(response.status).to eq(404) end it "can't find deleted posts as a regular user" do log_in(:user) - xhr :get, action, params + get action, params: params, format: :json expect(response.status).to eq(404) end it "can find posts as a moderator" do log_in(:moderator) - xhr :get, action, params + get action, params: params, format: :json expect(response).to be_success end it "can find posts as a admin" do log_in(:admin) - xhr :get, action, params + get action, params: params, format: :json expect(response).to be_success end end @@ -47,7 +47,11 @@ end shared_examples 'action requires login' do |method, action, params| it 'raises an exception when not logged in' do - expect { xhr method, action, params }.to raise_error(Discourse::NotLoggedIn) + expect do + options = { format: :json } + options.merge!(params: params) if params + self.public_send(method, action, options) + end.to raise_error(Discourse::NotLoggedIn) end end @@ -67,7 +71,7 @@ describe PostsController do end it 'returns public posts with topic for json' do - xhr :get, :latest, id: "latest_posts", format: :json + get :latest, params: { id: "latest_posts" }, format: :json expect(response).to be_success json = ::JSON.parse(response.body) post_ids = json['latest_posts'].map { |p| p['id'] } @@ -75,14 +79,6 @@ describe PostsController do expect(post_ids).to_not include private_post.id expect(post_ids).to_not include topicless_post.id end - - it 'returns public posts with topic for rss' do - xhr :get, :latest, id: "latest_posts", format: :rss - expect(response).to be_success - expect(assigns(:posts)).to include post - expect(assigns(:posts)).to_not include private_post - expect(assigns(:posts)).to_not include topicless_post - end end context 'private posts' do @@ -91,38 +87,13 @@ describe PostsController do end it 'returns private posts for json' do - xhr :get, :latest, id: "private_posts", format: :json + get :latest, params: { id: "private_posts" }, format: :json expect(response).to be_success json = ::JSON.parse(response.body) post_ids = json['private_posts'].map { |p| p['id'] } expect(post_ids).to include private_post.id expect(post_ids).to_not include post.id end - - it 'returns private posts for rss' do - xhr :get, :latest, id: "private_posts", format: :rss - expect(response).to be_success - expect(assigns(:posts)).to include private_post - expect(assigns(:posts)).to_not include post - end - end - end - - describe 'user_posts_feed' do - let(:user) { log_in } - let!(:public_topic) { Fabricate(:topic) } - let!(:post) { Fabricate(:post, user: user, topic: public_topic) } - let!(:private_topic) { Fabricate(:topic, archetype: Archetype.private_message, category: nil) } - let!(:private_post) { Fabricate(:post, user: user, topic: private_topic) } - let!(:topicless_post) { Fabricate(:post, user: user, raw: '

Car 54, where are you?

') } - - it 'returns public posts with topic for rss' do - topicless_post.update topic_id: -100 - xhr :get, :user_posts_feed, username: user.username, format: :rss - expect(response).to be_success - expect(assigns(:posts)).to include post - expect(assigns(:posts)).to_not include private_post - expect(assigns(:posts)).to_not include topicless_post end end @@ -133,7 +104,7 @@ describe PostsController do end it 'returns the cooked conent' do - xhr :get, :cooked, id: 1234 + get :cooked, params: { id: 1234 }, format: :json expect(response).to be_success json = ::JSON.parse(response.body) expect(json).to be_present @@ -151,7 +122,7 @@ describe PostsController do it "raises an error if the user doesn't have permission to view raw email" do Guardian.any_instance.expects(:can_view_raw_email?).returns(false) - xhr :get, :raw_email, id: post.id + get :raw_email, params: { id: post.id }, format: :json expect(response).to be_forbidden end @@ -159,7 +130,7 @@ describe PostsController do it "can view raw email" do Guardian.any_instance.expects(:can_view_raw_email?).returns(true) - xhr :get, :raw_email, id: post.id + get :raw_email, params: { id: post.id }, format: :json expect(response).to be_success json = ::JSON.parse(response.body) @@ -179,7 +150,7 @@ describe PostsController do it 'gets all the expected fields' do # non fabricated test new_post = create_post - xhr :get, :show, id: new_post.id + get :show, params: { id: new_post.id }, format: :json parsed = JSON.parse(response.body) expect(parsed["topic_slug"]).to eq(new_post.topic.slug) expect(parsed["moderator"]).to eq(false) @@ -203,7 +174,7 @@ describe PostsController do it 'asks post for reply history' do Post.any_instance.expects(:reply_history) - xhr :get, :reply_history, id: post.id + get :reply_history, params: { id: post.id }, format: :json end end @@ -215,7 +186,7 @@ describe PostsController do it 'asks post for replies' do p1 = Fabricate(:post) - xhr :get, :replies, post_id: p1.id + get :replies, params: { post_id: p1.id }, format: :json expect(response.status).to eq(200) end end @@ -232,7 +203,7 @@ describe PostsController do Guardian.any_instance.stubs(:can_delete_post?).with(post).returns(false) Post.any_instance.stubs(:edit_time_limit_expired?).returns(true) - xhr :delete, :destroy, id: post.id + delete :destroy, params: { id: post.id }, format: :json expect(response.status).to eq(422) expect(JSON.parse(response.body)['errors']).to include(I18n.t('too_late_to_edit')) @@ -240,7 +211,7 @@ describe PostsController do it "raises an error when the user doesn't have permission to see the post" do Guardian.any_instance.expects(:can_delete?).with(post).returns(false) - xhr :delete, :destroy, id: post.id + delete :destroy, params: { id: post.id }, format: :json expect(response).to be_forbidden end @@ -248,7 +219,7 @@ describe PostsController do destroyer = mock PostDestroyer.expects(:new).returns(destroyer) destroyer.expects(:destroy) - xhr :delete, :destroy, id: post.id + delete :destroy, params: { id: post.id }, format: :json end end @@ -264,7 +235,7 @@ describe PostsController do it "raises an error when the user doesn't have permission to see the post" do Guardian.any_instance.expects(:can_recover_post?).with(post).returns(false) - xhr :put, :recover, post_id: post.id + put :recover, params: { post_id: post.id }, format: :json expect(response).to be_forbidden end @@ -273,7 +244,7 @@ describe PostsController do post = create_post(topic_id: topic_id) PostDestroyer.new(user, post).destroy - xhr :put, :recover, post_id: post.id + put :recover, params: { post_id: post.id }, format: :json post.reload expect(post.deleted_at).to eq(nil) end @@ -291,27 +262,31 @@ describe PostsController do let!(:post2) { Fabricate(:post, topic_id: post1.topic_id, user: poster, post_number: 3, reply_to_post_number: post1.post_number) } it "raises invalid parameters no post_ids" do - expect { xhr :delete, :destroy_many }.to raise_error(ActionController::ParameterMissing) + expect do + delete :destroy_many, format: :json + end.to raise_error(ActionController::ParameterMissing) end it "raises invalid parameters with missing ids" do - expect { xhr :delete, :destroy_many, post_ids: [12345] }.to raise_error(Discourse::InvalidParameters) + expect do + delete :destroy_many, params: { post_ids: [12345] }, format: :json + end.to raise_error(Discourse::InvalidParameters) end it "raises an error when the user doesn't have permission to delete the posts" do Guardian.any_instance.expects(:can_delete?).with(instance_of(Post)).returns(false) - xhr :delete, :destroy_many, post_ids: [post1.id, post2.id] + delete :destroy_many, params: { post_ids: [post1.id, post2.id] }, format: :json expect(response).to be_forbidden end it "deletes the post" do PostDestroyer.any_instance.expects(:destroy).twice - xhr :delete, :destroy_many, post_ids: [post1.id, post2.id] + delete :destroy_many, params: { post_ids: [post1.id, post2.id] }, format: :json end it "updates the highest read data for the forum" do Topic.expects(:reset_highest).twice - xhr :delete, :destroy_many, post_ids: [post1.id, post2.id] + delete :destroy_many, params: { post_ids: [post1.id, post2.id] }, format: :json end describe "can delete replies" do @@ -322,7 +297,9 @@ describe PostsController do it "deletes the post and the reply to it" do PostDestroyer.any_instance.expects(:destroy).twice - xhr :delete, :destroy_many, post_ids: [post1.id], reply_post_ids: [post1.id] + delete :destroy_many, + params: { post_ids: [post1.id], reply_post_ids: [post1.id] }, + format: :json end end @@ -352,7 +329,7 @@ describe PostsController do Guardian.any_instance.stubs(:can_edit?).with(post).returns(false) Post.any_instance.stubs(:edit_time_limit_expired?).returns(true) - xhr :put, :update, update_params + put :update, params: update_params, format: :json expect(response.status).to eq(422) expect(JSON.parse(response.body)['errors']).to include(I18n.t('too_late_to_edit')) @@ -360,37 +337,38 @@ describe PostsController do it 'passes the image sizes through' do Post.any_instance.expects(:image_sizes=) - xhr :put, :update, update_params + put :update, params: update_params, format: :json end it 'passes the edit reason through' do Post.any_instance.expects(:edit_reason=) - xhr :put, :update, update_params + put :update, params: update_params, format: :json end it "raises an error when the post parameter is missing" do update_params.delete(:post) expect { - xhr :put, :update, update_params + put :update, params: update_params, format: :json }.to raise_error(ActionController::ParameterMissing) end it "raises an error when the user doesn't have permission to see the post" do Guardian.any_instance.expects(:can_edit?).with(post).at_least_once.returns(false) - xhr :put, :update, update_params + put :update, params: update_params, format: :json expect(response).to be_forbidden end it "calls revise with valid parameters" do PostRevisor.any_instance.expects(:revise!).with(post.user, { raw: 'edited body' , edit_reason: 'typo' }, anything) - xhr :put, :update, update_params + put :update, params: update_params, format: :json end it "extracts links from the new body" do param = update_params param[:post][:raw] = 'I just visited this https://google.com so many cool links' - xhr :put, :update, param + put :update, params: param, format: :json + expect(response).to be_success expect(TopicLink.count).to eq(1) end @@ -399,7 +377,7 @@ describe PostsController do first_post = post.topic.ordered_posts.first PostDestroyer.new(moderator, first_post).destroy - xhr :put, :update, update_params + put :update, params: update_params, format: :json expect(response).not_to be_success end end @@ -411,7 +389,7 @@ describe PostsController do first_post = post.topic.ordered_posts.first PostDestroyer.new(moderator, first_post).destroy - xhr :put, :update, update_params + put :update, params: update_params, format: :json expect(response).to be_success post.reload @@ -432,12 +410,18 @@ describe PostsController do it "raises an error if the user doesn't have permission to see the post" do post - xhr :put, :bookmark, post_id: private_message.id, bookmarked: 'true' + + put :bookmark, + params: { post_id: private_message.id, bookmarked: 'true' }, + format: :json + expect(response).to be_forbidden end it 'creates a bookmark' do - xhr :put, :bookmark, post_id: post.id, bookmarked: 'true' + put :bookmark, + params: { post_id: post.id, bookmarked: 'true' }, + format: :json post_action = PostAction.find_by(user: user, post: post) @@ -449,14 +433,16 @@ describe PostsController do let(:admin) { Fabricate(:admin) } it "returns the right response when post is not bookmarked" do - xhr :put, :bookmark, post_id: Fabricate(:post, user: user).id + put :bookmark, + params: { post_id: Fabricate(:post, user: user).id }, + format: :json expect(response.status).to eq(404) end it 'should be able to remove a bookmark' do post_action - xhr :put, :bookmark, post_id: post.id + put :bookmark, params: { post_id: post.id }, format: :json expect(PostAction.find_by(id: post_action.id)).to eq(nil) end @@ -471,7 +457,7 @@ describe PostsController do expect(Guardian.new(user).can_see_post?(post.reload)).to eq(false) - xhr :put, :bookmark, post_id: post.id + put :bookmark, params: { post_id: post.id }, format: :json expect(PostAction.find_by(id: post_action.id)).to eq(nil) end @@ -482,7 +468,7 @@ describe PostsController do post = post_action.post post.trash! - xhr :put, :bookmark, post_id: post.id + put :bookmark, params: { post_id: post.id }, format: :json expect(PostAction.find_by(id: post_action.id)).to eq(nil) end @@ -504,7 +490,9 @@ describe PostsController do it "raises an error if the user doesn't have permission to wiki the post" do Guardian.any_instance.expects(:can_wiki?).with(post).returns(false) - xhr :put, :wiki, post_id: post.id, wiki: 'true' + put :wiki, + params: { post_id: post.id, wiki: 'true' }, + format: :json expect(response).to be_forbidden end @@ -514,22 +502,31 @@ describe PostsController do another_user = Fabricate(:user) another_post = Fabricate(:post, user: another_user) - expect { xhr :put, :wiki, post_id: another_post.id, wiki: 'true' } - .to change { another_post.reload.version }.by(1) + expect do + put :wiki, + params: { post_id: another_post.id, wiki: 'true' }, + format: :json + end.to change { another_post.reload.version }.by(1) - expect { xhr :put, :wiki, post_id: another_post.id, wiki: 'false' } - .to change { another_post.reload.version }.by(-1) + expect do + put :wiki, + params: { post_id: another_post.id, wiki: 'false' }, + format: :json + end.to change { another_post.reload.version }.by(-1) _another_admin = log_in(:admin) - expect { xhr :put, :wiki, post_id: another_post.id, wiki: 'true' } - .to change { another_post.reload.version }.by(1) + expect do + put :wiki, + params: { post_id: another_post.id, wiki: 'true' }, + format: :json + end.to change { another_post.reload.version }.by(1) end it "can wiki a post" do Guardian.any_instance.expects(:can_wiki?).with(post).returns(true) - xhr :put, :wiki, post_id: post.id, wiki: 'true' + put :wiki, params: { post_id: post.id, wiki: 'true' }, format: :json post.reload expect(post.wiki).to eq(true) @@ -539,7 +536,7 @@ describe PostsController do wikied_post = Fabricate(:post, user: user, wiki: true) Guardian.any_instance.expects(:can_wiki?).with(wikied_post).returns(true) - xhr :put, :wiki, post_id: wikied_post.id, wiki: 'false' + put :wiki, params: { post_id: wikied_post.id, wiki: 'false' }, format: :json wikied_post.reload expect(wikied_post.wiki).to eq(false) @@ -560,7 +557,7 @@ describe PostsController do it "raises an error if the user doesn't have permission to change the post type" do Guardian.any_instance.expects(:can_change_post_type?).returns(false) - xhr :put, :post_type, post_id: post.id, post_type: 2 + put :post_type, params: { post_id: post.id, post_type: 2 }, format: :json expect(response).to be_forbidden end @@ -568,7 +565,7 @@ describe PostsController do it "can change the post type" do Guardian.any_instance.expects(:can_change_post_type?).returns(true) - xhr :put, :post_type, post_id: post.id, post_type: 2 + put :post_type, params: { post_id: post.id, post_type: 2 }, format: :json post.reload expect(post.post_type).to eq(2) @@ -589,7 +586,7 @@ describe PostsController do it "raises an error if the user doesn't have permission to rebake the post" do Guardian.any_instance.expects(:can_rebake?).returns(false) - xhr :put, :rebake, post_id: post.id + put :rebake, params: { post_id: post.id }, format: :json expect(response).to be_forbidden end @@ -597,7 +594,7 @@ describe PostsController do it "can rebake the post" do Guardian.any_instance.expects(:can_rebake?).returns(true) - xhr :put, :rebake, post_id: post.id + put :rebake, params: { post_id: post.id }, format: :json expect(response).to be_success end @@ -622,54 +619,70 @@ describe PostsController do user = Fabricate(:user) master_key = ApiKey.create_master_key.key - xhr :post, :create, api_username: user.username, api_key: master_key, raw: raw, title: title, wpid: 1 + post :create, params: { + api_username: user.username, + api_key: master_key, + raw: raw, + title: title, + wpid: 1 + }, format: :json + expect(response).to be_success original = response.body - xhr :post, :create, api_username: user.username_lower, api_key: master_key, raw: raw, title: title, wpid: 2 - expect(response).to be_success + post :create, params: { + api_username: user.username_lower, + api_key: master_key, + raw: raw, + title: title, + wpid: 2 + }, format: :json + expect(response).to be_success expect(response.body).to eq(original) end it 'allows to create posts in import_mode' do NotificationEmailer.enable - post = Fabricate(:post) + post_1 = Fabricate(:post) user = Fabricate(:user) master_key = ApiKey.create_master_key.key - xhr :post, :create, + post :create, params: { api_username: user.username, api_key: master_key, raw: 'this is test reply 1', - topic_id: post.topic.id, + topic_id: post_1.topic.id, reply_to_post_number: 1 + }, format: :json expect(response).to be_success - expect(post.topic.user.notifications.count).to eq(1) - post.topic.user.notifications.destroy_all + expect(post_1.topic.user.notifications.count).to eq(1) + post_1.topic.user.notifications.destroy_all - xhr :post, :create, + post :create, params: { api_username: user.username, api_key: master_key, raw: 'this is test reply 2', - topic_id: post.topic.id, + topic_id: post_1.topic.id, reply_to_post_number: 1, import_mode: true + }, format: :json expect(response).to be_success - expect(post.topic.user.notifications.count).to eq(0) + expect(post_1.topic.user.notifications.count).to eq(0) - xhr :post, :create, + post :create, params: { api_username: user.username, api_key: master_key, raw: 'this is test reply 3', - topic_id: post.topic.id, + topic_id: post_1.topic.id, reply_to_post_number: 1, import_mode: false + } expect(response).to be_success - expect(post.topic.user.notifications.count).to eq(1) + expect(post_1.topic.user.notifications.count).to eq(1) end end @@ -686,7 +699,10 @@ describe PostsController do end it 'queues the post if min_first_post_typing_time is not met' do - xhr :post, :create, raw: 'this is the test content', title: 'this is the test title for the topic' + post :create, params: { + raw: 'this is the test content', + title: 'this is the test title for the topic' + }, format: :json expect(response).to be_success parsed = ::JSON.parse(response.body) @@ -708,9 +724,11 @@ describe PostsController do it "doesn't enqueue replies when the topic is closed" do topic = Fabricate(:closed_topic) - xhr :post, :create, raw: 'this is the test content', - title: 'this is the test title for the topic', - topic_id: topic.id + post :create, params: { + raw: 'this is the test content', + title: 'this is the test title for the topic', + topic_id: topic.id + }, format: :json expect(response).not_to be_success parsed = ::JSON.parse(response.body) @@ -719,8 +737,11 @@ describe PostsController do it "doesn't enqueue replies when the post is too long" do SiteSetting.max_post_length = 10 - xhr :post, :create, raw: 'this is the test content', - title: 'this is the test title for the topic' + + post :create, params: { + raw: 'this is the test content', + title: 'this is the test title for the topic' + }, format: :json expect(response).not_to be_success parsed = ::JSON.parse(response.body) @@ -731,7 +752,10 @@ describe PostsController do it 'blocks correctly based on auto_block_first_post_regex' do SiteSetting.auto_block_first_post_regex = "I love candy|i eat s[1-5]" - xhr :post, :create, raw: 'this is the test content', title: 'when I eat s3 sometimes when not looking' + post :create, params: { + raw: 'this is the test content', + title: 'when I eat s3 sometimes when not looking' + }, format: :json expect(response).to be_success parsed = ::JSON.parse(response.body) @@ -742,37 +766,30 @@ describe PostsController do expect(user.blocked).to eq(true) end - it 'creates the post' do - xhr :post, :create, raw: 'this is the test content', title: 'this is the test title for the topic' - - expect(response).to be_success - parsed = ::JSON.parse(response.body) - - # Deprecated structure - expect(parsed['post']).to be_blank - expect(parsed['cooked']).to be_present - end - it "can send a message to a group" do group = Group.create(name: 'test_group', messageable_level: Group::ALIAS_LEVELS[:nobody]) user1 = Fabricate(:user) group.add(user1) - xhr :post, :create, raw: 'I can haz a test', - title: 'I loves my test', - target_usernames: group.name, - archetype: Archetype.private_message + post :create, params: { + raw: 'I can haz a test', + title: 'I loves my test', + target_usernames: group.name, + archetype: Archetype.private_message + }, format: :json expect(response).not_to be_success # allow pm to this group group.update_columns(messageable_level: Group::ALIAS_LEVELS[:everyone]) - xhr :post, :create, raw: 'I can haz a test', - title: 'I loves my test', - target_usernames: group.name, - archetype: Archetype.private_message + post :create, params: { + raw: 'I can haz a test', + title: 'I loves my test', + target_usernames: group.name, + archetype: Archetype.private_message + }, format: :json expect(response).to be_success @@ -784,9 +801,11 @@ describe PostsController do end it "returns the nested post with a param" do - xhr :post, :create, raw: 'this is the test content', - title: 'this is the test title for the topic', - nested_post: true + post :create, params: { + raw: 'this is the test content', + title: 'this is the test title for the topic', + nested_post: true + }, format: :json expect(response).to be_success parsed = ::JSON.parse(response.body) @@ -798,10 +817,10 @@ describe PostsController do raw = "this is a test post 123 #{SecureRandom.hash}" title = "this is a title #{SecureRandom.hash}" - xhr :post, :create, raw: raw, title: title, wpid: 1 + post :create, params: { raw: raw, title: title, wpid: 1 }, format: :json expect(response).to be_success - xhr :post, :create, raw: raw, title: title, wpid: 2 + post :create, params: { raw: raw, title: title, wpid: 2 }, format: :json expect(response).not_to be_success end @@ -816,7 +835,7 @@ describe PostsController do end it "does not succeed" do - xhr :post, :create, raw: 'test' + post :create, params: { raw: 'test' }, format: :json User.any_instance.expects(:flag_linked_posts_as_spam).never expect(response).not_to be_success end @@ -824,86 +843,9 @@ describe PostsController do it "it triggers flag_linked_posts_as_spam when the post creator returns spam" do PostCreator.any_instance.expects(:spam?).returns(true) User.any_instance.expects(:flag_linked_posts_as_spam) - xhr :post, :create, raw: 'test' + post :create, params: { raw: 'test' }, format: :json end - end - - context "parameters" do - - before do - # Just for performance, no reason to actually perform for these - # tests. - NewPostManager.stubs(:perform).returns(NewPostResult) - end - - it "passes raw through" do - xhr :post, :create, raw: 'hello' - expect(assigns(:manager_params)['raw']).to eq('hello') - end - - it "passes title through" do - xhr :post, :create, raw: 'hello', title: 'new topic title' - expect(assigns(:manager_params)['title']).to eq('new topic title') - end - - it "passes topic_id through" do - xhr :post, :create, raw: 'hello', topic_id: 1234 - expect(assigns(:manager_params)['topic_id']).to eq('1234') - end - - it "passes archetype through" do - xhr :post, :create, raw: 'hello', archetype: 'private_message' - expect(assigns(:manager_params)['archetype']).to eq('private_message') - end - - it "passes category through" do - xhr :post, :create, raw: 'hello', category: 1 - expect(assigns(:manager_params)['category']).to eq('1') - end - - it "passes target_usernames through" do - xhr :post, :create, raw: 'hello', target_usernames: 'evil,trout' - expect(assigns(:manager_params)['target_usernames']).to eq('evil,trout') - end - - it "passes reply_to_post_number through" do - xhr :post, :create, raw: 'hello', reply_to_post_number: 6789, topic_id: 1234 - expect(assigns(:manager_params)['reply_to_post_number']).to eq('6789') - end - - it "passes image_sizes through" do - xhr :post, :create, raw: 'hello', image_sizes: { width: '100', height: '200' } - expect(assigns(:manager_params)['image_sizes']['width']).to eq('100') - expect(assigns(:manager_params)['image_sizes']['height']).to eq('200') - end - - it "passes meta_data through" do - xhr :post, :create, raw: 'hello', meta_data: { xyz: 'abc' } - expect(assigns(:manager_params)['meta_data']['xyz']).to eq('abc') - end - - context "is_warning" do - it "doesn't pass `is_warning` through if you're not staff" do - xhr :post, :create, raw: 'hello', archetype: 'private_message', is_warning: 'true' - expect(assigns(:manager_params)['is_warning']).to eq(false) - end - - it "passes `is_warning` through if you're staff" do - log_in(:moderator) - xhr :post, :create, raw: 'hello', archetype: 'private_message', is_warning: 'true' - expect(assigns(:manager_params)['is_warning']).to eq(true) - end - - it "passes `is_warning` as false through if you're staff" do - xhr :post, :create, raw: 'hello', archetype: 'private_message', is_warning: 'false' - expect(assigns(:manager_params)['is_warning']).to eq(false) - end - - end - - end - end end @@ -914,7 +856,9 @@ describe PostsController do it "throws an exception when revision is < 2" do expect { - xhr :get, :revisions, post_id: post_revision.post_id, revision: 1 + get :revisions, params: { + post_id: post_revision.post_id, revision: 1 + }, format: :json }.to raise_error(Discourse::InvalidParameters) end @@ -923,19 +867,26 @@ describe PostsController do before { SiteSetting.edit_history_visible_to_public = false } it "ensures anonymous cannot see the revisions" do - xhr :get, :revisions, post_id: post_revision.post_id, revision: post_revision.number + get :revisions, params: { + post_id: post_revision.post_id, revision: post_revision.number + }, format: :json + expect(response).to be_forbidden end it "ensures regular user cannot see the revisions" do log_in(:user) - xhr :get, :revisions, post_id: post_revision.post_id, revision: post_revision.number + get :revisions, params: { + post_id: post_revision.post_id, revision: post_revision.number + }, format: :json expect(response).to be_forbidden end it "ensures staff can see the revisions" do log_in(:admin) - xhr :get, :revisions, post_id: post_revision.post_id, revision: post_revision.number + get :revisions, params: { + post_id: post_revision.post_id, revision: post_revision.number + }, format: :json expect(response).to be_success end @@ -943,13 +894,17 @@ describe PostsController do user = log_in(:active_user) post = Fabricate(:post, user: user, version: 3) pr = Fabricate(:post_revision, user: user, post: post) - xhr :get, :revisions, post_id: pr.post_id, revision: pr.number + get :revisions, params: { + post_id: pr.post_id, revision: pr.number + }, format: :json expect(response).to be_success end it "ensures trust level 4 can see the revisions" do log_in(:trust_level_4) - xhr :get, :revisions, post_id: post_revision.post_id, revision: post_revision.number + get :revisions, params: { + post_id: post_revision.post_id, revision: post_revision.number + }, format: :json expect(response).to be_success end @@ -960,7 +915,9 @@ describe PostsController do before { SiteSetting.edit_history_visible_to_public = true } it "ensures anyone can see the revisions" do - xhr :get, :revisions, post_id: post_revision.post_id, revision: post_revision.number + get :revisions, params: { + post_id: post_revision.post_id, revision: post_revision.number + }, format: :json expect(response).to be_success end @@ -974,7 +931,9 @@ describe PostsController do before { deleted_post.trash!(admin) } it "also work on deleted post" do - xhr :get, :revisions, post_id: deleted_post_revision.post_id, revision: deleted_post_revision.number + get :revisions, params: { + post_id: deleted_post_revision.post_id, revision: deleted_post_revision.number + }, format: :json expect(response).to be_success end end @@ -988,7 +947,9 @@ describe PostsController do before { deleted_topic.trash!(admin) } it "also work on deleted topic" do - xhr :get, :revisions, post_id: post_revision.post_id, revision: post_revision.number + get :revisions, params: { + post_id: post_revision.post_id, revision: post_revision.number + } expect(response).to be_success end end @@ -1015,7 +976,7 @@ describe PostsController do let(:logged_in_as) { log_in } it "does not work" do - xhr :put, :revert, revert_params + put :revert, params: revert_params, format: :json expect(response).to_not be_success end end @@ -1025,36 +986,44 @@ describe PostsController do it "throws an exception when revision is < 2" do expect { - xhr :put, :revert, post_id: post.id, revision: 1 + put :revert, params: { post_id: post.id, revision: 1 }, format: :json }.to raise_error(Discourse::InvalidParameters) end it "fails when post_revision record is not found" do - xhr :put, :revert, post_id: post.id, revision: post_revision.number + 1 + put :revert, params: { + post_id: post.id, revision: post_revision.number + 1 + }, format: :json expect(response).to_not be_success end it "fails when post record is not found" do - xhr :put, :revert, post_id: post.id + 1, revision: post_revision.number + put :revert, params: { + post_id: post.id + 1, revision: post_revision.number + }, format: :json expect(response).to_not be_success end it "fails when revision is blank" do - xhr :put, :revert, post_id: post.id, revision: blank_post_revision.number + put :revert, params: { + post_id: post.id, revision: blank_post_revision.number + }, format: :json expect(response.status).to eq(422) expect(JSON.parse(response.body)['errors']).to include(I18n.t('revert_version_same')) end it "fails when revised version is same as current version" do - xhr :put, :revert, post_id: post.id, revision: same_post_revision.number + put :revert, params: { + post_id: post.id, revision: same_post_revision.number + }, format: :json expect(response.status).to eq(422) expect(JSON.parse(response.body)['errors']).to include(I18n.t('revert_version_same')) end it "works!" do - xhr :put, :revert, revert_params + put :revert, params: revert_params, format: :json expect(response).to be_success end @@ -1062,7 +1031,7 @@ describe PostsController do first_post = post.topic.ordered_posts.first PostDestroyer.new(moderator, first_post).destroy - xhr :put, :revert, revert_params + put :revert, params: revert_params, format: :json expect(response).to be_success end end @@ -1073,14 +1042,14 @@ describe PostsController do it "raises an error when you can't see the post" do Guardian.any_instance.expects(:can_see?).with(post).returns(false) - xhr :get, :expand_embed, id: post.id + get :expand_embed, params: { id: post.id }, format: :json expect(response).not_to be_success end it "retrieves the body when you can see the post" do Guardian.any_instance.expects(:can_see?).with(post).returns(true) TopicEmbed.expects(:expanded_for).with(post).returns("full content") - xhr :get, :expand_embed, id: post.id + get :expand_embed, params: { id: post.id }, format: :json expect(response).to be_success expect(::JSON.parse(response.body)['cooked']).to eq("full content") end @@ -1095,13 +1064,13 @@ describe PostsController do it "raises an error if the user doesn't have permission to see the flagged posts" do Guardian.any_instance.expects(:can_see_flagged_posts?).returns(false) - xhr :get, :flagged_posts, username: "system" + get :flagged_posts, params: { username: "system" }, format: :json expect(response).to be_forbidden end it "can see the flagged posts when authorized" do Guardian.any_instance.expects(:can_see_flagged_posts?).returns(true) - xhr :get, :flagged_posts, username: "system" + get :flagged_posts, params: { username: "system" }, format: :json expect(response).to be_success end @@ -1122,7 +1091,7 @@ describe PostsController do PostAction.clear_flags!(post_disagreed, admin) Guardian.any_instance.expects(:can_see_flagged_posts?).returns(true) - xhr :get, :flagged_posts, username: user.username + get :flagged_posts, params: { username: user.username }, format: :json expect(response).to be_success expect(JSON.parse(response.body).length).to eq(2) @@ -1141,13 +1110,13 @@ describe PostsController do it "raises an error if the user doesn't have permission to see the deleted posts" do Guardian.any_instance.expects(:can_see_deleted_posts?).returns(false) - xhr :get, :deleted_posts, username: "system" + get :deleted_posts, params: { username: "system" }, format: :json expect(response).to be_forbidden end it "can see the deleted posts when authorized" do Guardian.any_instance.expects(:can_see_deleted_posts?).returns(true) - xhr :get, :deleted_posts, username: "system" + get :deleted_posts, params: { username: "system" }, format: :json expect(response).to be_success end @@ -1164,7 +1133,7 @@ describe PostsController do PostDestroyer.new(admin, secured_post).destroy log_in(:moderator) - xhr :get, :deleted_posts, username: user.username + get :deleted_posts, params: { username: user.username }, format: :json expect(response).to be_success data = JSON.parse(response.body) @@ -1180,7 +1149,7 @@ describe PostsController do PostDestroyer.new(admin, pm_post).destroy log_in(:moderator) - xhr :get, :deleted_posts, username: user.username + get :deleted_posts, params: { username: user.username }, format: :json expect(response).to be_success data = JSON.parse(response.body) @@ -1199,7 +1168,7 @@ describe PostsController do PostDestroyer.new(admin, post_deleted_by_admin).destroy Guardian.any_instance.expects(:can_see_deleted_posts?).returns(true) - xhr :get, :deleted_posts, username: user.username + get :deleted_posts, params: { username: user.username }, format: :json expect(response).to be_success data = JSON.parse(response.body) @@ -1216,7 +1185,7 @@ describe PostsController do describe "by ID" do it "can be viewed by anonymous" do post = Fabricate(:post, raw: "123456789") - xhr :get, :markdown_id, id: post.id + get :markdown_id, params: { id: post.id }, format: :json expect(response).to be_success expect(response.body).to eq("123456789") end @@ -1227,7 +1196,7 @@ describe PostsController do topic = Fabricate(:topic) post = Fabricate(:post, topic: topic, post_number: 1, raw: "123456789") post.save - xhr :get, :markdown_num, topic_id: topic.id, post_number: 1 + get :markdown_num, params: { topic_id: topic.id, post_number: 1 }, format: :json expect(response).to be_success expect(response.body).to eq("123456789") end @@ -1239,13 +1208,13 @@ describe PostsController do let(:post) { Fabricate(:post, topic: topic) } it "redirects to the topic" do - xhr :get, :short_link, post_id: post.id + get :short_link, params: { post_id: post.id }, format: :json expect(response).to be_redirect end it "returns a 403 when access is denied" do Guardian.any_instance.stubs(:can_see?).returns(false) - xhr :get, :short_link, post_id: post.id + get :short_link, params: { post_id: post.id }, format: :json expect(response).to be_forbidden end end diff --git a/spec/controllers/queued_posts_controller_spec.rb b/spec/controllers/queued_posts_controller_spec.rb index 590e988a010..81713052487 100644 --- a/spec/controllers/queued_posts_controller_spec.rb +++ b/spec/controllers/queued_posts_controller_spec.rb @@ -5,7 +5,7 @@ require_dependency 'queued_post' describe QueuedPostsController do context 'without authentication' do it 'fails' do - xhr :get, :index + get :index, format: :json expect(response).not_to be_success end end @@ -13,7 +13,7 @@ describe QueuedPostsController do context 'as a regular user' do let!(:user) { log_in(:user) } it 'fails' do - xhr :get, :index + get :index, format: :json expect(response).not_to be_success end end @@ -22,7 +22,7 @@ describe QueuedPostsController do let!(:user) { log_in(:moderator) } it 'returns the queued posts' do - xhr :get, :index + get :index, format: :json expect(response).to be_success end end @@ -34,7 +34,10 @@ describe QueuedPostsController do context 'approved' do it 'updates the post to approved' do - xhr :put, :update, id: qp.id, queued_post: { state: 'approved' } + put :update, params: { + id: qp.id, queued_post: { state: 'approved' } + }, format: :json + expect(response).to be_success qp.reload @@ -45,7 +48,10 @@ describe QueuedPostsController do context 'rejected' do it 'updates the post to rejected' do - xhr :put, :update, id: qp.id, queued_post: { state: 'rejected' } + put :update, params: { + id: qp.id, queued_post: { state: 'rejected' } + }, format: :json + expect(response).to be_success qp.reload @@ -67,7 +73,10 @@ describe QueuedPostsController do let(:queued_topic) { Fabricate(:queued_topic) } before do - xhr :put, :update, id: queued_topic.id, queued_post: changes + put :update, params: { + id: queued_topic.id, queued_post: changes + }, format: :json + expect(response).to be_success end @@ -92,7 +101,10 @@ describe QueuedPostsController do let(:queued_reply) { Fabricate(:queued_post) } before do - xhr :put, :update, id: queued_reply.id, queued_post: changes + put :update, params: { + id: queued_reply.id, queued_post: changes + }, format: :json + expect(response).to be_success end diff --git a/spec/controllers/search_controller_spec.rb b/spec/controllers/search_controller_spec.rb index 4aa3eddb495..1cc46050392 100644 --- a/spec/controllers/search_controller_spec.rb +++ b/spec/controllers/search_controller_spec.rb @@ -9,7 +9,10 @@ describe SearchController do it "can search correctly" do my_post = Fabricate(:post, raw: 'this is my really awesome post') - xhr :get, :query, term: 'awesome', include_blurb: true + + get :query, params: { + term: 'awesome', include_blurb: true + }, format: :json expect(response).to be_success data = JSON.parse(response.body) @@ -21,7 +24,10 @@ describe SearchController do it 'performs the query with a type filter' do user = Fabricate(:user) my_post = Fabricate(:post, raw: "#{user.username} is a cool person") - xhr :get, :query, term: user.username, type_filter: 'topic' + + get :query, params: { + term: user.username, type_filter: 'topic' + }, format: :json expect(response).to be_success data = JSON.parse(response.body) @@ -29,7 +35,10 @@ describe SearchController do expect(data['posts'][0]['id']).to eq(my_post.id) expect(data['users']).to be_blank - xhr :get, :query, term: user.username, type_filter: 'user' + get :query, params: { + term: user.username, type_filter: 'user' + }, format: :json + expect(response).to be_success data = JSON.parse(response.body) @@ -43,13 +52,11 @@ describe SearchController do post = Fabricate(:post) - xhr( - :get, - :query, + get :query, params: { term: post.topic_id, type_filter: 'topic', search_for_id: true - ) + }, format: :json expect(response).to be_success data = JSON.parse(response.body) @@ -61,13 +68,11 @@ describe SearchController do user = Fabricate(:user) my_post = Fabricate(:post, raw: "#{user.username} is a cool person") - xhr( - :get, - :query, + get :query, params: { term: my_post.topic_id, type_filter: 'topic', search_for_id: true - ) + }, format: :json expect(response).to be_success data = JSON.parse(response.body) @@ -80,7 +85,7 @@ describe SearchController do context "#query" do it "logs the search term" do SiteSetting.log_search_queries = true - xhr :get, :query, term: 'wookie' + get :query, params: { term: 'wookie' }, format: :json expect(response).to be_success expect(SearchLog.where(term: 'wookie')).to be_present @@ -96,7 +101,7 @@ describe SearchController do it "doesn't log when disabled" do SiteSetting.log_search_queries = false - xhr :get, :query, term: 'wookie' + get :query, params: { term: 'wookie' }, format: :json expect(response).to be_success expect(SearchLog.where(term: 'wookie')).to be_blank end @@ -105,14 +110,14 @@ describe SearchController do context "#show" do it "logs the search term" do SiteSetting.log_search_queries = true - xhr :get, :show, q: 'bantha' + get :show, params: { q: 'bantha' }, format: :json expect(response).to be_success expect(SearchLog.where(term: 'bantha')).to be_present end it "doesn't log when disabled" do SiteSetting.log_search_queries = false - xhr :get, :show, q: 'bantha' + get :show, params: { q: 'bantha' }, format: :json expect(response).to be_success expect(SearchLog.where(term: 'bantha')).to be_blank end @@ -120,27 +125,38 @@ describe SearchController do context "search context" do it "raises an error with an invalid context type" do - expect { - xhr :get, :query, term: 'test', search_context: { type: 'security', id: 'hole' } - }.to raise_error(Discourse::InvalidParameters) + expect do + get :query, params: { + term: 'test', search_context: { type: 'security', id: 'hole' } + }, format: :json + end.to raise_error(Discourse::InvalidParameters) end it "raises an error with a missing id" do - expect { - xhr :get, :query, term: 'test', search_context: { type: 'user' } - }.to raise_error(Discourse::InvalidParameters) + expect do + get :query, + params: { term: 'test', search_context: { type: 'user' } }, + format: :json + end.to raise_error(Discourse::InvalidParameters) end context "with a user" do let(:user) { Fabricate(:user) } + it "raises an error if the user can't see the context" do Guardian.any_instance.expects(:can_see?).with(user).returns(false) - xhr :get, :query, term: 'test', search_context: { type: 'user', id: user.username } + get :query, params: { + term: 'test', search_context: { type: 'user', id: user.username } + }, format: :json + expect(response).not_to be_success end it 'performs the query with a search context' do - xhr :get, :query, term: 'test', search_context: { type: 'user', id: user.username } + get :query, params: { + term: 'test', search_context: { type: 'user', id: user.username } + }, format: :json + expect(response).to be_success end end @@ -149,9 +165,9 @@ describe SearchController do context "#click" do it "doesn't work wthout the necessary parameters" do - expect(-> { - xhr :post, :click - }).to raise_error(ActionController::ParameterMissing) + expect do + post :click, format: :json + end.to raise_error(ActionController::ParameterMissing) end it "doesn't record the click for a different user" do @@ -164,11 +180,13 @@ describe SearchController do ip_address: '127.0.0.1' ) - xhr :post, :click, search_log_id: search_log_id, - search_result_id: 12345, - search_result_type: 'topic' - expect(response).to be_success + post :click, params: { + search_log_id: search_log_id, + search_result_id: 12345, + search_result_type: 'topic' + } + expect(response).to be_success expect(SearchLog.find(search_log_id).clicked_topic_id).to be_blank end @@ -182,16 +200,18 @@ describe SearchController do ip_address: '127.0.0.1' ) - xhr :post, :click, search_log_id: search_log_id, - search_result_id: 12345, - search_result_type: 'topic' - expect(response).to be_success + post :click, params: { + search_log_id: search_log_id, + search_result_id: 12345, + search_result_type: 'topic' + }, format: :json + expect(response).to be_success expect(SearchLog.find(search_log_id).clicked_topic_id).to eq(12345) end it "records the click for an anonymous user" do - request.stubs(:remote_ip).returns('192.168.0.1') + request.remote_addr = '192.168.0.1'; _, search_log_id = SearchLog.log( term: 'kitty', @@ -199,11 +219,13 @@ describe SearchController do ip_address: '192.168.0.1' ) - xhr :post, :click, search_log_id: search_log_id, - search_result_id: 22222, - search_result_type: 'topic' - expect(response).to be_success + post :click, params: { + search_log_id: search_log_id, + search_result_id: 22222, + search_result_type: 'topic' + }, format: :json + expect(response).to be_success expect(SearchLog.find(search_log_id).clicked_topic_id).to eq(22222) end @@ -216,11 +238,13 @@ describe SearchController do ip_address: '192.168.0.1' ) - xhr :post, :click, search_log_id: search_log_id, - search_result_id: 22222, - search_result_type: 'topic' - expect(response).to be_success + post :click, params: { + search_log_id: search_log_id, + search_result_id: 22222, + search_result_type: 'topic' + } + expect(response).to be_success expect(SearchLog.find(search_log_id).clicked_topic_id).to be_blank end end diff --git a/spec/controllers/session_controller_spec.rb b/spec/controllers/session_controller_spec.rb index 44ebb652de5..e04681b2f3c 100644 --- a/spec/controllers/session_controller_spec.rb +++ b/spec/controllers/session_controller_spec.rb @@ -13,14 +13,14 @@ describe SessionController do it "does not work when not in development mode" do Rails.env.stubs(:development?).returns(false) - get :become, session_id: user.username + get :become, params: { session_id: user.username }, format: :json expect(response).not_to be_redirect expect(session[:current_user_id]).to be_blank end it "works in developmenet mode" do Rails.env.stubs(:development?).returns(true) - get :become, session_id: user.username + get :become, params: { session_id: user.username }, format: :json expect(response).to be_redirect expect(session[:current_user_id]).to eq(user.id) end @@ -64,7 +64,7 @@ describe SessionController do sso.external_id = 'abc' sso.username = 'sam' - get :sso_login, Rack::Utils.parse_query(sso.payload) + get :sso_login, params: Rack::Utils.parse_query(sso.payload) expect(response).to redirect_to('/') logged_on_user = Discourse.current_user_provider.new(request.env).current_user @@ -87,7 +87,7 @@ describe SessionController do ActionDispatch::Request.any_instance.stubs(:remote_ip).returns(screened_ip.ip_address) sso = sso_for_ip_specs - get :sso_login, Rack::Utils.parse_query(sso.payload) + get :sso_login, params: Rack::Utils.parse_query(sso.payload) logged_on_user = Discourse.current_user_provider.new(request.env).current_user expect(logged_on_user).to eq(nil) @@ -101,7 +101,7 @@ describe SessionController do screened_ip = Fabricate(:screened_ip_address) ActionDispatch::Request.any_instance.stubs(:remote_ip).returns(screened_ip.ip_address) - get :sso_login, Rack::Utils.parse_query(sso.payload) + get :sso_login, params: Rack::Utils.parse_query(sso.payload) logged_on_user = Discourse.current_user_provider.new(request.env).current_user expect(logged_on_user).to be_blank end @@ -114,7 +114,7 @@ describe SessionController do sso.username = 'sam' ScreenedEmail.block('bob@bob.com') - get :sso_login, Rack::Utils.parse_query(sso.payload) + get :sso_login, params: Rack::Utils.parse_query(sso.payload) logged_on_user = Discourse.current_user_provider.new(request.env).current_user expect(logged_on_user).to eq(nil) @@ -130,7 +130,7 @@ describe SessionController do sso.custom_fields["shop_name"] = "Sam" sso.admin = true - get :sso_login, Rack::Utils.parse_query(sso.payload) + get :sso_login, params: Rack::Utils.parse_query(sso.payload) logged_on_user = Discourse.current_user_provider.new(request.env).current_user expect(logged_on_user.admin).to eq(true) @@ -143,7 +143,7 @@ describe SessionController do sso.name = 'Sam Saffron' sso.username = 'sam' - get :sso_login, Rack::Utils.parse_query(sso.payload) + get :sso_login, params: Rack::Utils.parse_query(sso.payload) expect(response).to redirect_to('/b/') end @@ -156,7 +156,7 @@ describe SessionController do sso.name = 'Sam Saffron' sso.username = 'sam' - get :sso_login, Rack::Utils.parse_query(sso.payload) + get :sso_login, params: Rack::Utils.parse_query(sso.payload) expect(response).to redirect_to('https://gusundtrout.com') end @@ -167,7 +167,7 @@ describe SessionController do sso.name = 'Sam Saffron' sso.username = 'sam' - get :sso_login, Rack::Utils.parse_query(sso.payload) + get :sso_login, params: Rack::Utils.parse_query(sso.payload) expect(response).to redirect_to('/') end @@ -178,7 +178,7 @@ describe SessionController do sso.name = 'Sam Saffron' sso.username = 'sam' - get :sso_login, Rack::Utils.parse_query(sso.payload) + get :sso_login, params: Rack::Utils.parse_query(sso.payload) expect(response).to redirect_to('/') end @@ -192,7 +192,7 @@ describe SessionController do sso.custom_fields["shop_name"] = "Sam" events = DiscourseEvent.track_events do - get :sso_login, Rack::Utils.parse_query(sso.payload) + get :sso_login, params: Rack::Utils.parse_query(sso.payload) end expect(events.map { |event| event[:event_name] }).to include( @@ -229,7 +229,7 @@ describe SessionController do sso.username = 'sam' sso.require_activation = true - get :sso_login, Rack::Utils.parse_query(sso.payload) + get :sso_login, params: Rack::Utils.parse_query(sso.payload) logged_on_user = Discourse.current_user_provider.new(request.env).current_user expect(logged_on_user).to eq(nil) @@ -244,7 +244,7 @@ describe SessionController do sso.username = 'sam' sso.require_activation = true - get :sso_login, Rack::Utils.parse_query(sso.payload) + get :sso_login, params: Rack::Utils.parse_query(sso.payload) end end @@ -259,7 +259,7 @@ describe SessionController do user.create_single_sign_on_record(external_id: '997', last_payload: '') user.stubs(:active?).returns(true) - get :sso_login, Rack::Utils.parse_query(sso.payload) + get :sso_login, params: Rack::Utils.parse_query(sso.payload) logged_on_user = Discourse.current_user_provider.new(request.env).current_user expect(user.id).to eq(logged_on_user.id) @@ -275,7 +275,7 @@ describe SessionController do user = Fabricate(:user) user.create_single_sign_on_record(external_id: '997', last_payload: '') - get :sso_login, Rack::Utils.parse_query(sso.payload) + get :sso_login, params: Rack::Utils.parse_query(sso.payload) user.single_sign_on_record.reload expect(user.single_sign_on_record.last_payload).to eq(sso.unsigned_payload) @@ -286,7 +286,7 @@ describe SessionController do expect(user.id).to eq(logged_on_user.id) # nonce is bad now - get :sso_login, Rack::Utils.parse_query(sso.payload) + get :sso_login, params: Rack::Utils.parse_query(sso.payload) expect(response.code).to eq('419') end @@ -307,12 +307,15 @@ describe SessionController do end it "successfully logs in and redirects user to return_sso_url when the user is not logged in" do - get :sso_provider, Rack::Utils.parse_query(@sso.payload) + get :sso_provider, params: Rack::Utils.parse_query(@sso.payload) expect(response).to redirect_to("/login") - xhr :post, :create, login: @user.username, password: "frogs", format: :json + post :create, + params: { login: @user.username, password: "frogs" }, + format: :json, + xhr: true - location = cookies[:sso_destination_url] + location = response.cookies["sso_destination_url"] # javascript code will handle redirection of user to return_sso_url expect(location).to match(/^http:\/\/somewhere.over.rainbow\/sso/) @@ -330,7 +333,7 @@ describe SessionController do it "successfully redirects user to return_sso_url when the user is logged in" do log_in_user(@user) - get :sso_provider, Rack::Utils.parse_query(@sso.payload) + get :sso_provider, params: Rack::Utils.parse_query(@sso.payload) location = response.header["Location"] expect(location).to match(/^http:\/\/somewhere.over.rainbow\/sso/) @@ -371,7 +374,7 @@ describe SessionController do end it 'stores the external attributes' do - get :sso_login, Rack::Utils.parse_query(@sso.payload) + get :sso_login, params: Rack::Utils.parse_query(@sso.payload) @user.single_sign_on_record.reload expect(@user.single_sign_on_record.external_username).to eq(@sso.username) expect(@user.single_sign_on_record.external_email).to eq(@sso.email) @@ -379,7 +382,7 @@ describe SessionController do end it 'overrides attributes' do - get :sso_login, Rack::Utils.parse_query(@sso.payload) + get :sso_login, params: Rack::Utils.parse_query(@sso.payload) logged_on_user = Discourse.current_user_provider.new(request.env).current_user expect(logged_on_user.username).to eq(@suggested_username) @@ -392,7 +395,7 @@ describe SessionController do @sso.name = @user.name @sso.email = @user.email - get :sso_login, Rack::Utils.parse_query(@sso.payload) + get :sso_login, params: Rack::Utils.parse_query(@sso.payload) logged_on_user = Discourse.current_user_provider.new(request.env).current_user expect(logged_on_user.username).to eq(@user.username) @@ -420,12 +423,15 @@ describe SessionController do end it "successfully logs in and redirects user to return_sso_url when the user is not logged in" do - get :sso_provider, Rack::Utils.parse_query(@sso.payload) + get :sso_provider, params: Rack::Utils.parse_query(@sso.payload) expect(response).to redirect_to("/login") - xhr :post, :create, login: @user.username, password: "frogs", format: :json + post :create, + params: { login: @user.username, password: "frogs" }, + format: :json, + xhr: true - location = cookies[:sso_destination_url] + location = response.cookies["sso_destination_url"] # javascript code will handle redirection of user to return_sso_url expect(location).to match(/^http:\/\/somewhere.over.rainbow\/sso/) @@ -443,7 +449,7 @@ describe SessionController do it "successfully redirects user to return_sso_url when the user is logged in" do log_in_user(@user) - get :sso_provider, Rack::Utils.parse_query(@sso.payload) + get :sso_provider, params: Rack::Utils.parse_query(@sso.payload) location = response.header["Location"] expect(location).to match(/^http:\/\/somewhere.over.rainbow\/sso/) @@ -467,7 +473,10 @@ describe SessionController do context 'local login is disabled' do before do SiteSetting.enable_local_logins = false - xhr :post, :create, login: user.username, password: 'myawesomepassword' + + post :create, params: { + login: user.username, password: 'myawesomepassword' + }, format: :json end it_behaves_like "failed to continue local login" end @@ -475,7 +484,10 @@ describe SessionController do context 'SSO is enabled' do before do SiteSetting.enable_sso = true - xhr :post, :create, login: user.username, password: 'myawesomepassword' + + post :create, params: { + login: user.username, password: 'myawesomepassword' + }, format: :json end it_behaves_like "failed to continue local login" end @@ -487,12 +499,17 @@ describe SessionController do end it "raises an error when the login isn't present" do - expect { xhr :post, :create }.to raise_error(ActionController::ParameterMissing) + expect do + post :create, format: :json + end.to raise_error(ActionController::ParameterMissing) end describe 'invalid password' do it "should return an error with an invalid password" do - xhr :post, :create, login: user.username, password: 'sssss' + post :create, params: { + login: user.username, password: 'sssss' + }, format: :json + expect(::JSON.parse(response.body)['error']).to be_present end end @@ -500,7 +517,10 @@ describe SessionController do describe 'invalid password' do it "should return an error with an invalid password if too long" do User.any_instance.expects(:confirm_password?).never - xhr :post, :create, login: user.username, password: ('s' * (User.max_password_length + 1)) + post :create, params: { + login: user.username, password: ('s' * (User.max_password_length + 1)) + }, format: :json + expect(::JSON.parse(response.body)['error']).to be_present end end @@ -511,7 +531,9 @@ describe SessionController do user.suspended_at = Time.now user.save! StaffActionLogger.new(user).log_user_suspend(user, "banned") - xhr :post, :create, login: user.username, password: 'myawesomepassword' + post :create, params: { + login: user.username, password: 'myawesomepassword' + }, format: :json error = ::JSON.parse(response.body)['error'] expect(error).to be_present @@ -523,7 +545,11 @@ describe SessionController do describe 'deactivated user' do it 'should return an error' do User.any_instance.stubs(:active).returns(false) - xhr :post, :create, login: user.username, password: 'myawesomepassword' + + post :create, params: { + login: user.username, password: 'myawesomepassword' + }, format: :json + expect(JSON.parse(response.body)['error']).to eq(I18n.t('login.not_activated')) end end @@ -531,7 +557,9 @@ describe SessionController do describe 'success by username' do it 'logs in correctly' do events = DiscourseEvent.track_events do - xhr :post, :create, login: user.username, password: 'myawesomepassword' + post :create, params: { + login: user.username, password: 'myawesomepassword' + }, format: :json end expect(events.map { |event| event[:event_name] }).to include( @@ -550,7 +578,10 @@ describe SessionController do before do screened_ip = Fabricate(:screened_ip_address) ActionDispatch::Request.any_instance.stubs(:remote_ip).returns(screened_ip.ip_address) - xhr :post, :create, login: "@" + user.username, password: 'myawesomepassword' + post :create, params: { + login: "@" + user.username, password: 'myawesomepassword' + }, format: :json + user.reload end @@ -561,7 +592,10 @@ describe SessionController do describe 'strips leading @ symbol' do before do - xhr :post, :create, login: "@" + user.username, password: 'myawesomepassword' + post :create, params: { + login: "@" + user.username, password: 'myawesomepassword' + }, format: :json + user.reload end @@ -572,7 +606,9 @@ describe SessionController do describe 'also allow login by email' do before do - xhr :post, :create, login: user.email, password: 'myawesomepassword' + post :create, params: { + login: user.email, password: 'myawesomepassword' + }, format: :json end it 'sets a session id' do @@ -585,12 +621,18 @@ describe SessionController do let(:email) { " #{user.email} " } it "strips spaces from the username" do - xhr :post, :create, login: username, password: 'myawesomepassword' + post :create, params: { + login: username, password: 'myawesomepassword' + }, format: :json + expect(::JSON.parse(response.body)['error']).not_to be_present end it "strips spaces from the email" do - xhr :post, :create, login: email, password: 'myawesomepassword' + post :create, params: { + login: email, password: 'myawesomepassword' + }, format: :json + expect(::JSON.parse(response.body)['error']).not_to be_present end end @@ -602,7 +644,9 @@ describe SessionController do context 'with an unapproved user' do before do - xhr :post, :create, login: user.email, password: 'myawesomepassword' + post :create, params: { + login: user.email, password: 'myawesomepassword' + }, format: :json end it "doesn't log in the user" do @@ -619,7 +663,10 @@ describe SessionController do context "with an unapproved user who is an admin" do before do User.any_instance.stubs(:admin?).returns(true) - xhr :post, :create, login: user.email, password: 'myawesomepassword' + + post :create, params: { + login: user.email, password: 'myawesomepassword' + }, format: :json end it 'sets a session id' do @@ -638,14 +685,22 @@ describe SessionController do it 'is successful for admin at the ip address' do User.any_instance.stubs(:admin?).returns(true) ActionDispatch::Request.any_instance.stubs(:remote_ip).returns(permitted_ip_address) - xhr :post, :create, login: user.username, password: 'myawesomepassword' + + post :create, params: { + login: user.username, password: 'myawesomepassword' + }, format: :json + expect(session[:current_user_id]).to eq(user.id) end it 'returns an error for admin not at the ip address' do User.any_instance.stubs(:admin?).returns(true) ActionDispatch::Request.any_instance.stubs(:remote_ip).returns("111.234.23.12") - xhr :post, :create, login: user.username, password: 'myawesomepassword' + + post :create, params: { + login: user.username, password: 'myawesomepassword' + }, format: :json + expect(JSON.parse(response.body)['error']).to be_present expect(session[:current_user_id]).not_to eq(user.id) end @@ -653,7 +708,11 @@ describe SessionController do it 'is successful for non-admin not at the ip address' do User.any_instance.stubs(:admin?).returns(false) ActionDispatch::Request.any_instance.stubs(:remote_ip).returns("111.234.23.12") - xhr :post, :create, login: user.username, password: 'myawesomepassword' + + post :create, params: { + login: user.username, password: 'myawesomepassword' + }, format: :json + expect(session[:current_user_id]).to eq(user.id) end end @@ -661,7 +720,9 @@ describe SessionController do context 'when email has not been confirmed' do def post_login - xhr :post, :create, login: user.email, password: 'myawesomepassword' + post :create, params: { + login: user.email, password: 'myawesomepassword' + }, format: :json end it "doesn't log in the user" do @@ -695,10 +756,17 @@ describe SessionController do RateLimiter.clear_all! 2.times do - xhr :post, :create, login: user.username, password: 'myawesomepassword' + post :create, params: { + login: user.username, password: 'myawesomepassword' + }, format: :json + expect(response).to be_success end - xhr :post, :create, login: user.username, password: 'myawesomepassword' + + post :create, params: { + login: user.username, password: 'myawesomepassword' + }, format: :json + expect(response).not_to be_success json = JSON.parse(response.body) expect(json["error_type"]).to eq("rate_limit") @@ -709,7 +777,7 @@ describe SessionController do describe '.destroy' do before do @user = log_in - xhr :delete, :destroy, id: @user.username + delete :destroy, params: { id: @user.username }, format: :json end it 'removes the session variable' do @@ -717,24 +785,28 @@ describe SessionController do end it 'removes the auth token cookie' do - expect(cookies[:_t]).to be_blank + expect(response.cookies["_t"]).to be_blank end end describe '.forgot_password' do it 'raises an error without a username parameter' do - expect { xhr :post, :forgot_password }.to raise_error(ActionController::ParameterMissing) + expect do + post :forgot_password, format: :json + end.to raise_error(ActionController::ParameterMissing) end context 'for a non existant username' do it "doesn't generate a new token for a made up username" do - expect { xhr :post, :forgot_password, login: 'made_up' }.not_to change(EmailToken, :count) + expect do + post :forgot_password, params: { login: 'made_up' }, format: :json + end.not_to change(EmailToken, :count) end it "doesn't enqueue an email" do Jobs.expects(:enqueue).with(:user_mail, anything).never - xhr :post, :forgot_password, login: 'made_up' + post :forgot_password, params: { login: 'made_up' }, format: :json end end @@ -744,7 +816,7 @@ describe SessionController do context 'local login is disabled' do before do SiteSetting.enable_local_logins = false - xhr :post, :forgot_password, login: user.username + post :forgot_password, params: { login: user.username }, format: :json end it_behaves_like "failed to continue local login" end @@ -752,18 +824,23 @@ describe SessionController do context 'SSO is enabled' do before do SiteSetting.enable_sso = true - xhr :post, :create, login: user.username, password: 'myawesomepassword' + + post :create, params: { + login: user.username, password: 'myawesomepassword' + }, format: :json end it_behaves_like "failed to continue local login" end it "generates a new token for a made up username" do - expect { xhr :post, :forgot_password, login: user.username }.to change(EmailToken, :count) + expect do + post :forgot_password, params: { login: user.username }, format: :json + end.to change(EmailToken, :count) end it "enqueues an email" do Jobs.expects(:enqueue).with(:critical_user_email, has_entries(type: :forgot_password, user_id: user.id)) - xhr :post, :forgot_password, login: user.username + post :forgot_password, params: { login: user.username }, format: :json end end @@ -771,12 +848,14 @@ describe SessionController do let(:system) { Discourse.system_user } it 'generates no token for system username' do - expect { xhr :post, :forgot_password, login: system.username }.not_to change(EmailToken, :count) + expect do + post :forgot_password, params: { login: system.username }, format: :json + end.not_to change(EmailToken, :count) end it 'enqueues no email' do Jobs.expects(:enqueue).never - xhr :post, :forgot_password, login: system.username + post :forgot_password, params: { login: system.username }, format: :json end end @@ -784,12 +863,14 @@ describe SessionController do let!(:staged) { Fabricate(:staged) } it 'generates no token for staged username' do - expect { xhr :post, :forgot_password, login: staged.username }.not_to change(EmailToken, :count) + expect do + post :forgot_password, params: { login: staged.username }, format: :json + end.not_to change(EmailToken, :count) end it 'enqueues no email' do Jobs.expects(:enqueue).never - xhr :post, :forgot_password, login: staged.username + post :forgot_password, params: { login: staged.username }, format: :json end end end @@ -797,7 +878,7 @@ describe SessionController do describe '.current' do context "when not logged in" do it "retuns 404" do - xhr :get, :current + get :current, format: :json expect(response).not_to be_success end end @@ -806,7 +887,7 @@ describe SessionController do let!(:user) { log_in } it "returns the JSON for the user" do - xhr :get, :current + get :current, format: :json expect(response).to be_success json = ::JSON.parse(response.body) expect(json['current_user']).to be_present diff --git a/spec/controllers/similar_topics_controller_spec.rb b/spec/controllers/similar_topics_controller_spec.rb index e14432ecced..f7dad39562b 100644 --- a/spec/controllers/similar_topics_controller_spec.rb +++ b/spec/controllers/similar_topics_controller_spec.rb @@ -7,13 +7,15 @@ describe SimilarTopicsController do let(:raw) { 'this body is long enough to search for' } it "requires a title" do - expect { xhr :get, :index, raw: raw }.to raise_error(ActionController::ParameterMissing) + expect do + get :index, params: { raw: raw }, format: :json + end.to raise_error(ActionController::ParameterMissing) end it "returns no results if the title length is below the minimum" do Topic.expects(:similar_to).never SiteSetting.min_title_similar_length = 100 - xhr :get, :index, title: title, raw: raw + get :index, params: { title: title, raw: raw }, format: :json json = ::JSON.parse(response.body) expect(json["similar_topics"].size).to eq(0) end @@ -25,7 +27,7 @@ describe SimilarTopicsController do end after do - xhr :get, :index, title: title, raw: raw + get :index, params: { title: title, raw: raw }, format: :json end describe "With enough topics" do diff --git a/spec/controllers/site_controller_spec.rb b/spec/controllers/site_controller_spec.rb index e46f280a259..c36a79589c6 100644 --- a/spec/controllers/site_controller_spec.rb +++ b/spec/controllers/site_controller_spec.rb @@ -13,7 +13,7 @@ describe SiteController do SiteSetting.apple_touch_icon_url = "https://boom.com/apple/logo.png" SiteSetting.mobile_logo_url = "https://a.a/a.png" - xhr :get, :basic_info + get :basic_info, format: :json json = JSON.parse(response.body) expect(json["title"]).to eq("Hammer Time") @@ -31,7 +31,7 @@ describe SiteController do SiteSetting.login_required = true SiteSetting.share_anonymized_statistics = true - xhr :get, :statistics + get :statistics, format: :json json = JSON.parse(response.body) expect(response).to be_success @@ -54,7 +54,7 @@ describe SiteController do it 'is not visible if site setting share_anonymized_statistics is disabled' do SiteSetting.share_anonymized_statistics = false - xhr :get, :statistics + get :statistics, format: :json expect(response).to redirect_to '/' end end diff --git a/spec/controllers/steps_controller_spec.rb b/spec/controllers/steps_controller_spec.rb index 7380852467c..50a31a28d2a 100644 --- a/spec/controllers/steps_controller_spec.rb +++ b/spec/controllers/steps_controller_spec.rb @@ -7,14 +7,20 @@ describe StepsController do end it 'needs you to be logged in' do - expect { - xhr :put, :update, id: 'made-up-id', fields: { forum_title: "updated title" } - }.to raise_error(Discourse::NotLoggedIn) + expect do + put :update, params: { + id: 'made-up-id', fields: { forum_title: "updated title" } + }, format: :json + end.to raise_error(Discourse::NotLoggedIn) end it "raises an error if you aren't an admin" do log_in(:moderator) - xhr :put, :update, id: 'made-up-id', fields: { forum_title: "updated title" } + + put :update, params: { + id: 'made-up-id', fields: { forum_title: "updated title" } + }, format: :json + expect(response).to be_forbidden end @@ -25,18 +31,26 @@ describe StepsController do it "raises an error if the wizard is disabled" do SiteSetting.wizard_enabled = false - xhr :put, :update, id: 'contact', fields: { contact_email: "eviltrout@example.com" } + put :update, params: { + id: 'contact', fields: { contact_email: "eviltrout@example.com" } + }, format: :json expect(response).to be_forbidden end it "updates properly if you are staff" do - xhr :put, :update, id: 'contact', fields: { contact_email: "eviltrout@example.com" } + put :update, params: { + id: 'contact', fields: { contact_email: "eviltrout@example.com" } + }, format: :json + expect(response).to be_success expect(SiteSetting.contact_email).to eq("eviltrout@example.com") end it "returns errors if the field has them" do - xhr :put, :update, id: 'contact', fields: { contact_email: "not-an-email" } + put :update, params: { + id: 'contact', fields: { contact_email: "not-an-email" } + }, format: :json + expect(response).to_not be_success end end diff --git a/spec/controllers/stylesheets_controller_spec.rb b/spec/controllers/stylesheets_controller_spec.rb index 6ebf29f7f25..a68ccc62bed 100644 --- a/spec/controllers/stylesheets_controller_spec.rb +++ b/spec/controllers/stylesheets_controller_spec.rb @@ -11,7 +11,7 @@ describe StylesheetsController do digest = StylesheetCache.first.digest StylesheetCache.destroy_all - get :show, name: "desktop_rtl_#{digest}" + get :show, params: { name: "desktop_rtl_#{digest}" }, format: :json expect(response).to be_success cached = StylesheetCache.first @@ -21,7 +21,7 @@ describe StylesheetsController do # tmp folder destruction and cached `rm #{Stylesheet::Manager.cache_fullpath}/*` - get :show, name: "desktop_rtl_#{digest}" + get :show, params: { name: "desktop_rtl_#{digest}" }, format: :json expect(response).to be_success # there is an edge case which is ... disk and db cache is nuked, very unlikely to happen @@ -37,10 +37,16 @@ describe StylesheetsController do `rm #{Stylesheet::Manager.cache_fullpath}/*` - get :show, name: builder.stylesheet_filename.sub(".css", "") + get :show, params: { + name: builder.stylesheet_filename.sub(".css", "") + }, format: :json + expect(response).to be_success - get :show, name: builder.stylesheet_filename_no_digest.sub(".css", "") + get :show, params: { + name: builder.stylesheet_filename_no_digest.sub(".css", "") + }, format: :json + expect(response).to be_success builder = Stylesheet::Manager.new(:desktop_theme, theme.key) @@ -48,10 +54,16 @@ describe StylesheetsController do `rm #{Stylesheet::Manager.cache_fullpath}/*` - get :show, name: builder.stylesheet_filename.sub(".css", "") + get :show, params: { + name: builder.stylesheet_filename.sub(".css", "") + }, format: :json + expect(response).to be_success - get :show, name: builder.stylesheet_filename_no_digest.sub(".css", "") + get :show, params: { + name: builder.stylesheet_filename_no_digest.sub(".css", "") + }, format: :json + expect(response).to be_success end diff --git a/spec/controllers/tags_controller_spec.rb b/spec/controllers/tags_controller_spec.rb index 02690123c0b..f0e296345de 100644 --- a/spec/controllers/tags_controller_spec.rb +++ b/spec/controllers/tags_controller_spec.rb @@ -14,7 +14,7 @@ describe TagsController do context 'tagging disabled' do it "returns 404" do - xhr :get, :show_latest, tag_id: tag.name + get :show_latest, params: { tag_id: tag.name }, format: :json expect(response.status).to eq(404) end end @@ -25,47 +25,80 @@ describe TagsController do end it "can filter by tag" do - xhr :get, :show_latest, tag_id: tag.name + get :show_latest, params: { tag_id: tag.name }, format: :json expect(response).to be_success end it "can filter by two tags" do single_tag_topic; multi_tag_topic; all_tag_topic - xhr :get, :show_latest, tag_id: tag.name, additional_tag_ids: other_tag.name + + get :show_latest, params: { + tag_id: tag.name, additional_tag_ids: other_tag.name + }, format: :json + expect(response).to be_success - expect(assigns(:list).topics).to include all_tag_topic - expect(assigns(:list).topics).to include multi_tag_topic - expect(assigns(:list).topics).to_not include single_tag_topic + + topic_ids = JSON.parse(response.body)["topic_list"]["topics"] + .map { |topic| topic["id"] } + + expect(topic_ids).to include(all_tag_topic.id) + expect(topic_ids).to include(multi_tag_topic.id) + expect(topic_ids).to_not include(single_tag_topic.id) end it "can filter by multiple tags" do single_tag_topic; multi_tag_topic; all_tag_topic - xhr :get, :show_latest, tag_id: tag.name, additional_tag_ids: "#{other_tag.name}/#{third_tag.name}" + + get :show_latest, params: { + tag_id: tag.name, additional_tag_ids: "#{other_tag.name}/#{third_tag.name}" + }, format: :json + expect(response).to be_success - expect(assigns(:list).topics).to include all_tag_topic - expect(assigns(:list).topics).to_not include multi_tag_topic - expect(assigns(:list).topics).to_not include single_tag_topic + + topic_ids = JSON.parse(response.body)["topic_list"]["topics"] + .map { |topic| topic["id"] } + + expect(topic_ids).to include(all_tag_topic.id) + expect(topic_ids).to_not include(multi_tag_topic.id) + expect(topic_ids).to_not include(single_tag_topic.id) end it "does not find any tags when a tag which doesn't exist is passed" do single_tag_topic - xhr :get, :show_latest, tag_id: tag.name, additional_tag_ids: "notatag" + + get :show_latest, params: { + tag_id: tag.name, additional_tag_ids: "notatag" + }, format: :json + expect(response).to be_success - expect(assigns(:list).topics).to_not include single_tag_topic + + topic_ids = JSON.parse(response.body)["topic_list"]["topics"] + .map { |topic| topic["id"] } + + expect(topic_ids).to_not include(single_tag_topic.id) end it "can filter by category and tag" do - xhr :get, :show_latest, tag_id: tag.name, category: category.slug + get :show_latest, params: { + tag_id: tag.name, category: category.slug + }, format: :json + expect(response).to be_success end it "can filter by category, sub-category, and tag" do - xhr :get, :show_latest, tag_id: tag.name, category: subcategory.slug, parent_category: category.slug + get :show_latest, params: { + tag_id: tag.name, category: subcategory.slug, parent_category: category.slug + }, format: :json + expect(response).to be_success end it "can filter by category, no sub-category, and tag" do - xhr :get, :show_latest, tag_id: tag.name, category: 'none', parent_category: category.slug + get :show_latest, params: { + tag_id: tag.name, category: 'none', parent_category: category.slug + }, format: :json + expect(response).to be_success end @@ -77,14 +110,24 @@ describe TagsController do slug: subcategory.slug ) t = Fabricate(:topic, category_id: subcategory2.id, tags: [other_tag]) - xhr :get, :show_latest, tag_id: other_tag.name, category: subcategory2.slug, parent_category: category2.slug + get :show_latest, params: { + tag_id: other_tag.name, category: subcategory2.slug, parent_category: category2.slug + }, format: :json + expect(response).to be_success - expect(assigns(:list).topics).to include(t) + + topic_ids = JSON.parse(response.body)["topic_list"]["topics"] + .map { |topic| topic["id"] } + + expect(topic_ids).to include(t.id) end it "can filter by bookmarked" do log_in(:user) - xhr :get, :show_bookmarks, tag_id: tag.name + get :show_bookmarks, params: { + tag_id: tag.name + }, format: :json + expect(response).to be_success end end @@ -93,7 +136,7 @@ describe TagsController do describe 'search' do context 'tagging disabled' do it "returns 404" do - xhr :get, :search, q: 'stuff' + get :search, params: { q: 'stuff' }, format: :json expect(response.status).to eq(404) end end @@ -106,7 +149,7 @@ describe TagsController do it "can return some tags" do tag_names = ['stuff', 'stinky', 'stumped'] tag_names.each { |name| Fabricate(:tag, name: name) } - xhr :get, :search, q: 'stu' + get :search, params: { q: 'stu' }, format: :json expect(response).to be_success json = ::JSON.parse(response.body) expect(json["results"].map { |j| j["id"] }.sort).to eq(['stuff', 'stumped']) @@ -115,7 +158,7 @@ describe TagsController do it "can say if given tag is not allowed" do yup, nope = Fabricate(:tag, name: 'yup'), Fabricate(:tag, name: 'nope') category = Fabricate(:category, tags: [yup]) - xhr :get, :search, q: 'nope', categoryId: category.id + get :search, params: { q: 'nope', categoryId: category.id }, format: :json expect(response).to be_success json = ::JSON.parse(response.body) expect(json["results"].map { |j| j["id"] }.sort).to eq([]) @@ -125,7 +168,7 @@ describe TagsController do it "can return tags that are in secured categories but are allowed to be used" do c = Fabricate(:private_category, group: Fabricate(:group)) Fabricate(:topic, category: c, tags: [Fabricate(:tag, name: "cooltag")]) - xhr :get, :search, q: "cool" + get :search, params: { q: "cool" }, format: :json expect(response).to be_success json = ::JSON.parse(response.body) expect(json["results"].map { |j| j["id"] }).to eq(['cooltag']) @@ -135,12 +178,12 @@ describe TagsController do tag_names = ['房地产', 'тема-в-разработке'] tag_names.each { |name| Fabricate(:tag, name: name) } - xhr :get, :search, q: '房' + get :search, params: { q: '房' }, format: :json expect(response).to be_success json = ::JSON.parse(response.body) expect(json["results"].map { |j| j["id"] }).to eq(['房地产']) - xhr :get, :search, q: 'тема' + get :search, params: { q: 'тема' }, format: :json expect(response).to be_success json = ::JSON.parse(response.body) expect(json["results"].map { |j| j["id"] }).to eq(['тема-в-разработке']) diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/topic_controller_spec.rb similarity index 67% rename from spec/controllers/application_controller_spec.rb rename to spec/controllers/topic_controller_spec.rb index fdae7c579cd..6be013eb884 100644 --- a/spec/controllers/application_controller_spec.rb +++ b/spec/controllers/topic_controller_spec.rb @@ -30,12 +30,12 @@ describe TopicsController do user = log_in user.user_option.update_columns(theme_key: theme.key) - get :show, id: 666 + get :show, params: { id: 666 } expect(controller.theme_key).to eq(theme.key) theme.update_columns(user_selectable: false) - get :show, id: 666 + get :show, params: { id: 666 } expect(controller.theme_key).not_to eq(theme.key) end @@ -45,7 +45,7 @@ describe TopicsController do cookies['theme_key'] = "#{theme2.key},#{user.user_option.theme_key_seq}" - get :show, id: 666 + get :show, params: { id: 666 } expect(controller.theme_key).to eq(theme2.key) end @@ -55,20 +55,23 @@ describe TopicsController do user.user_option.update_columns(theme_key: theme.key) cookies['theme_key'] = "#{theme2.key},#{user.user_option.theme_key_seq - 1}" - get :show, id: 666 + get :show, params: { id: 666 } expect(controller.theme_key).to eq(theme.key) end end it "doesn't store an incoming link when there's no referer" do expect { - get :show, id: topic.id + get :show, params: { id: topic.id }, format: :json }.not_to change(IncomingLink, :count) end it "doesn't raise an error on a very long link" do set_referer("http://#{'a' * 2000}.com") - expect { get :show, id: topic.id }.not_to raise_error + + expect do + get :show, params: { id: topic.id }, format: :json + end.not_to raise_error end describe "has_escaped_fragment?" do @@ -78,9 +81,17 @@ describe TopicsController do it "uses the application layout even with an escaped fragment param" do SiteSetting.enable_escaped_fragments = false - get :show, 'topic_id' => topic.id, 'slug' => topic.slug, '_escaped_fragment_' => 'true' - expect(response).to render_template(layout: 'application') - assert_select "meta[name=fragment]", false, "it doesn't have the meta tag" + + get :show, params: { + 'topic_id' => topic.id, + 'slug' => topic.slug, + '_escaped_fragment_' => 'true' + } + + body = response.body + + expect(body).to have_tag(:script, with: { src: '/assets/application.js' }) + expect(body).to_not have_tag(:meta, with: { name: 'fragment' }) end end @@ -91,15 +102,25 @@ describe TopicsController do end it "uses the application layout when there's no param" do - get :show, topic_id: topic.id, slug: topic.slug - expect(response).to render_template(layout: 'application') - assert_select "meta[name=fragment]", true, "it has the meta tag" + get :show, params: { topic_id: topic.id, slug: topic.slug } + + body = response.body + + expect(body).to have_tag(:script, with: { src: '/assets/application.js' }) + expect(body).to have_tag(:meta, with: { name: 'fragment' }) end it "uses the crawler layout when there's an _escaped_fragment_ param" do - get :show, topic_id: topic.id, slug: topic.slug, _escaped_fragment_: 'true' - expect(response).to render_template(layout: 'crawler') - assert_select "meta[name=fragment]", false, "it doesn't have the meta tag" + get :show, params: { + topic_id: topic.id, + slug: topic.slug, + _escaped_fragment_: 'true' + } + + body = response.body + + expect(body).to have_tag(:body, with: { class: 'crawler' }) + expect(body).to_not have_tag(:meta, with: { name: 'fragment' }) end end end @@ -109,18 +130,24 @@ describe TopicsController do context "when not a crawler" do it "renders with the application layout" do - get :show, topic_id: topic.id, slug: topic.slug - expect(response).to render_template(layout: 'application') - assert_select "meta[name=fragment]", true, "it has the meta tag" + get :show, params: { topic_id: topic.id, slug: topic.slug } + + body = response.body + + expect(body).to have_tag(:script, with: { src: '/assets/application.js' }) + expect(body).to have_tag(:meta, with: { name: 'fragment' }) end end context "when a crawler" do it "renders with the crawler layout" do request.env["HTTP_USER_AGENT"] = "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" - get :show, topic_id: topic.id, slug: topic.slug - expect(response).to render_template(layout: 'crawler') - assert_select "meta[name=fragment]", false, "it doesn't have the meta tag" + get :show, params: { topic_id: topic.id, slug: topic.slug } + + body = response.body + + expect(body).to have_tag(:body, with: { class: 'crawler' }) + expect(body).to_not have_tag(:meta, with: { name: 'fragment' }) end end @@ -131,15 +158,21 @@ describe TopicsController do context "when the SiteSetting is enabled" do it "uses the application layout when there's no param" do - get :show, topic_id: topic.id, slug: topic.slug - expect(response).to render_template(layout: 'application') - assert_select "meta[name=fragment]", true, "it has the meta tag" + get :show, params: { topic_id: topic.id, slug: topic.slug } + + body = response.body + + expect(body).to have_tag(:script, src: '/assets/application.js') + expect(body).to have_tag(:meta, with: { name: 'fragment' }) end it "uses the crawler layout when there's an print param" do - get :show, topic_id: topic.id, slug: topic.slug, print: 'true' - expect(response).to render_template(layout: 'crawler') - assert_select "meta[name=fragment]", false, "it doesn't have the meta tag" + get :show, params: { topic_id: topic.id, slug: topic.slug, print: 'true' } + + body = response.body + + expect(body).to have_tag(:body, class: 'crawler') + expect(body).to_not have_tag(:meta, with: { name: 'fragment' }) end end end @@ -151,7 +184,7 @@ describe TopicsController do request.cookies['cn'] = "2828,100,#{notification.id}" - get :show, topic_id: 100 + get :show, params: { topic_id: 100, format: :json } expect(response.cookies['cn']).to eq nil @@ -166,7 +199,7 @@ describe TopicsController do request.headers['Discourse-Clear-Notifications'] = "2828,100,#{notification.id}" - get :show, topic_id: 100 + get :show, params: { topic_id: 100, format: :json } notification.reload expect(notification.read).to eq true @@ -184,7 +217,7 @@ describe TopicsController do context "with an anonymous user" do it "uses the default locale" do - get :show, topic_id: topic.id + get :show, params: { topic_id: topic.id, format: :json } expect(I18n.locale).to eq(:en) end @@ -195,7 +228,7 @@ describe TopicsController do user = Fabricate(:user, locale: :fr) log_in_user(user) - get :show, topic_id: topic.id + get :show, params: { topic_id: topic.id, format: :json } expect(I18n.locale).to eq(:en) end @@ -214,7 +247,7 @@ describe TopicsController do context "with an anonymous user" do it "uses the locale from the headers" do - get :show, topic_id: topic.id + get :show, params: { topic_id: topic.id, format: :json } expect(I18n.locale).to eq(:fr) end @@ -225,7 +258,7 @@ describe TopicsController do user = Fabricate(:user, locale: :fr) log_in_user(user) - get :show, topic_id: topic.id + get :show, params: { topic_id: topic.id, format: :json } expect(I18n.locale).to eq(:fr) end @@ -239,7 +272,7 @@ describe TopicsController do SiteSetting.default_locale = "en" set_accept_language("zh-CN") - get :show, topic_id: topic.id + get :show, params: { topic_id: topic.id, format: :json } expect(I18n.locale).to eq(:zh_CN) end @@ -251,7 +284,7 @@ describe TopicsController do SiteSetting.default_locale = 'en' set_accept_language('') - get :show, topic_id: topic.id + get :show, params: { topic_id: topic.id, format: :json } expect(I18n.locale).to eq(:en) end @@ -261,13 +294,13 @@ describe TopicsController do describe "read only header" do it "returns no read only header by default" do - get :show, topic_id: topic.id + get :show, params: { topic_id: topic.id, format: :json } expect(response.headers['Discourse-Readonly']).to eq(nil) end it "returns a readonly header if the site is read only" do Discourse.received_readonly! - get :show, topic_id: topic.id + get :show, params: { topic_id: topic.id, format: :json } expect(response.headers['Discourse-Readonly']).to eq('true') end end @@ -298,31 +331,65 @@ describe 'api' do # choosing an arbitrarily easy to mock trusted activity it 'allows users with api key to bookmark posts' do PostAction.expects(:act).with(user, post, PostActionType.types[:bookmark]).once - put :bookmark, bookmarked: "true", post_id: post.id, api_key: api_key.key, format: :json + + put :bookmark, params: { + bookmarked: "true", + post_id: post.id, + api_key: api_key.key + }, format: :json + expect(response).to be_success end it 'raises an error with a user key that does not match an optionally specified username' do PostAction.expects(:act).with(user, post, PostActionType.types[:bookmark]).never - put :bookmark, bookmarked: "true", post_id: post.id, api_key: api_key.key, api_username: 'made_up', format: :json + + put :bookmark, params: { + bookmarked: "true", + post_id: post.id, + api_key: api_key.key, + api_username: 'made_up' + }, format: :json + expect(response).not_to be_success end it 'allows users with a master api key to bookmark posts' do PostAction.expects(:act).with(user, post, PostActionType.types[:bookmark]).once - put :bookmark, bookmarked: "true", post_id: post.id, api_key: master_key.key, api_username: user.username, format: :json + + put :bookmark, params: { + bookmarked: "true", + post_id: post.id, + api_key: master_key.key, + api_username: user.username + }, format: :json + expect(response).to be_success end it 'disallows phonies to bookmark posts' do PostAction.expects(:act).with(user, post, PostActionType.types[:bookmark]).never - put :bookmark, bookmarked: "true", post_id: post.id, api_key: SecureRandom.hex(32), api_username: user.username, format: :json + + put :bookmark, params: { + bookmarked: "true", + post_id: post.id, + api_key: SecureRandom.hex(32), + api_username: user.username + }, format: :json + expect(response.code.to_i).to eq(403) end it 'disallows blank api' do PostAction.expects(:act).with(user, post, PostActionType.types[:bookmark]).never - put :bookmark, bookmarked: "true", post_id: post.id, api_key: "", api_username: user.username, format: :json + + put :bookmark, params: { + bookmarked: "true", + post_id: post.id, + api_key: "", + api_username: user.username + }, format: :json + expect(response.code.to_i).to eq(403) end end diff --git a/spec/controllers/topics_controller_spec.rb b/spec/controllers/topics_controller_spec.rb index 300ea2024c2..a29cd6955e0 100644 --- a/spec/controllers/topics_controller_spec.rb +++ b/spec/controllers/topics_controller_spec.rb @@ -6,15 +6,19 @@ def topics_controller_show_gen_perm_tests(expected, ctx) if sym == :nonexist params = "topic_id: nonexist_topic_id" end - ctx.instance_eval(" -it 'returns #{status} for #{sym}' do - begin - xhr :get, :show, #{params} - expect(response.status).to eq(#{status}) - rescue Discourse::NotLoggedIn - expect(302).to eq(#{status}) - end -end") + + method = <<~TEXT + it 'returns #{status} for #{sym}' do + begin + get :show, params: { #{params} } + expect(response.status).to eq(#{status}) + rescue Discourse::NotLoggedIn + expect(302).to eq(#{status}) + end + end + TEXT + + ctx.instance_eval(method) end end @@ -29,7 +33,8 @@ describe TopicsController do it "returns the JSON in the format our wordpress plugin needs" do SiteSetting.external_system_avatars_enabled = false - xhr :get, :wordpress, topic_id: topic.id, best: 3 + get :wordpress, params: { topic_id: topic.id, best: 3 }, format: :json + expect(response).to be_success json = ::JSON.parse(response.body) expect(json).to be_present @@ -60,7 +65,13 @@ describe TopicsController do context 'move_posts' do it 'needs you to be logged in' do - expect { xhr :post, :move_posts, topic_id: 111, title: 'blah', post_ids: [1, 2, 3] }.to raise_error(Discourse::NotLoggedIn) + expect do + post :move_posts, params: { + topic_id: 111, + title: 'blah', + post_ids: [1, 2, 3] + }, format: :json + end.to raise_error(Discourse::NotLoggedIn) end describe 'moving to a new topic' do @@ -69,12 +80,20 @@ describe TopicsController do let(:topic) { p1.topic } it "raises an error without postIds" do - expect { xhr :post, :move_posts, topic_id: topic.id, title: 'blah' }.to raise_error(ActionController::ParameterMissing) + expect do + post :move_posts, params: { + topic_id: topic.id, title: 'blah' + }, format: :json + end.to raise_error(ActionController::ParameterMissing) end it "raises an error when the user doesn't have permission to move the posts" do Guardian.any_instance.expects(:can_move_posts?).returns(false) - xhr :post, :move_posts, topic_id: topic.id, title: 'blah', post_ids: [1, 2, 3] + + post :move_posts, params: { + topic_id: topic.id, title: 'blah', post_ids: [1, 2, 3] + }, format: :json + expect(response).to be_forbidden end @@ -86,11 +105,12 @@ describe TopicsController do p2 expect do - xhr :post, :move_posts, + post :move_posts, params: { topic_id: topic.id, title: 'Logan is a good movie', post_ids: [p2.id], category_id: 123 + }, format: :json end.to change { Topic.count }.by(1) expect(response).to be_success @@ -108,11 +128,12 @@ describe TopicsController do expect(topic.reload.deleted_at).to_not be_nil expect do - xhr :post, :move_posts, + post :move_posts, params: { topic_id: topic.id, title: 'Logan is a good movie', post_ids: [p2.id], category_id: 123 + }, format: :json end.to change { Topic.count }.by(1) expect(response).to be_success @@ -130,7 +151,10 @@ describe TopicsController do before do Topic.any_instance.expects(:move_posts).with(user, [p2.id], title: 'blah').returns(nil) - xhr :post, :move_posts, topic_id: topic.id, title: 'blah', post_ids: [p2.id] + + post :move_posts, params: { + topic_id: topic.id, title: 'blah', post_ids: [p2.id] + }, format: :json end it "returns JSON with a false success" do @@ -156,7 +180,13 @@ describe TopicsController do it "moves the child posts too" do Topic.any_instance.expects(:move_posts).with(user, [p1.id, p2.id], title: 'blah').returns(topic) - xhr :post, :move_posts, topic_id: topic.id, title: 'blah', post_ids: [p1.id], reply_post_ids: [p1.id] + + post :move_posts, params: { + topic_id: topic.id, + title: 'blah', + post_ids: [p1.id], + reply_post_ids: [p1.id] + }, format: :json end end @@ -173,7 +203,12 @@ describe TopicsController do before do Topic.any_instance.expects(:move_posts).with(user, [p2.id], destination_topic_id: dest_topic.id).returns(topic) - xhr :post, :move_posts, topic_id: topic.id, post_ids: [p2.id], destination_topic_id: dest_topic.id + + post :move_posts, params: { + topic_id: topic.id, + post_ids: [p2.id], + destination_topic_id: dest_topic.id + }, format: :json end it "returns success" do @@ -189,7 +224,12 @@ describe TopicsController do before do Topic.any_instance.expects(:move_posts).with(user, [p2.id], destination_topic_id: dest_topic.id).returns(nil) - xhr :post, :move_posts, topic_id: topic.id, destination_topic_id: dest_topic.id, post_ids: [p2.id] + + post :move_posts, params: { + topic_id: topic.id, + destination_topic_id: dest_topic.id, + post_ids: [p2.id] + }, format: :json end it "returns JSON with a false success" do @@ -204,7 +244,11 @@ describe TopicsController do context "merge_topic" do it 'needs you to be logged in' do - expect { xhr :post, :merge_topic, topic_id: 111, destination_topic_id: 345 }.to raise_error(Discourse::NotLoggedIn) + expect do + post :merge_topic, params: { + topic_id: 111, destination_topic_id: 345 + }, format: :json + end.to raise_error(Discourse::NotLoggedIn) end describe 'moving to a new topic' do @@ -213,12 +257,18 @@ describe TopicsController do let(:topic) { p1.topic } it "raises an error without destination_topic_id" do - expect { xhr :post, :merge_topic, topic_id: topic.id }.to raise_error(ActionController::ParameterMissing) + expect do + post :merge_topic, params: { topic_id: topic.id }, format: :json + end.to raise_error(ActionController::ParameterMissing) end it "raises an error when the user doesn't have permission to merge" do Guardian.any_instance.expects(:can_move_posts?).returns(false) - xhr :post, :merge_topic, topic_id: 111, destination_topic_id: 345 + + post :merge_topic, + params: { topic_id: 111, destination_topic_id: 345 }, + format: :json + expect(response).to be_forbidden end @@ -229,7 +279,10 @@ describe TopicsController do before do Topic.any_instance.expects(:move_posts).with(user, [p1.id], destination_topic_id: dest_topic.id).returns(topic) - xhr :post, :merge_topic, topic_id: topic.id, destination_topic_id: dest_topic.id + + post :merge_topic, params: { + topic_id: topic.id, destination_topic_id: dest_topic.id + }, format: :json end it "returns success" do @@ -246,13 +299,22 @@ describe TopicsController do context 'change_post_owners' do it 'needs you to be logged in' do - expect { xhr :post, :change_post_owners, topic_id: 111, username: 'user_a', post_ids: [1, 2, 3] }.to raise_error(Discourse::NotLoggedIn) + expect do + post :change_post_owners, params: { + topic_id: 111, + username: 'user_a', + post_ids: [1, 2, 3] + }, format: :json + end.to raise_error(Discourse::NotLoggedIn) end describe 'forbidden to moderators' do let!(:moderator) { log_in(:moderator) } it 'correctly denies' do - xhr :post, :change_post_owners, topic_id: 111, username: 'user_a', post_ids: [1, 2, 3] + post :change_post_owners, params: { + topic_id: 111, username: 'user_a', post_ids: [1, 2, 3] + }, format: :json + expect(response).to be_forbidden end end @@ -261,7 +323,10 @@ describe TopicsController do let!(:trust_level_4) { log_in(:trust_level_4) } it 'correctly denies' do - xhr :post, :change_post_owners, topic_id: 111, username: 'user_a', post_ids: [1, 2, 3] + post :change_post_owners, params: { + topic_id: 111, username: 'user_a', post_ids: [1, 2, 3] + }, format: :json + expect(response).to be_forbidden end end @@ -274,22 +339,40 @@ describe TopicsController do let(:p2) { Fabricate(:post, topic_id: topic.id) } it "raises an error with a parameter missing" do - expect { xhr :post, :change_post_owners, topic_id: 111, post_ids: [1, 2, 3] }.to raise_error(ActionController::ParameterMissing) - expect { xhr :post, :change_post_owners, topic_id: 111, username: 'user_a' }.to raise_error(ActionController::ParameterMissing) + expect do + post :change_post_owners, params: { + topic_id: 111, post_ids: [1, 2, 3] + }, format: :json + end.to raise_error(ActionController::ParameterMissing) + + expect do + post :change_post_owners, params: { + topic_id: 111, username: 'user_a' + }, format: :json + end.to raise_error(ActionController::ParameterMissing) end it "calls PostOwnerChanger" do PostOwnerChanger.any_instance.expects(:change_owner!).returns(true) - xhr :post, :change_post_owners, topic_id: topic.id, username: user_a.username_lower, post_ids: [p1.id] + post :change_post_owners, params: { + topic_id: topic.id, username: user_a.username_lower, post_ids: [p1.id] + }, format: :json + expect(response).to be_success end it "changes multiple posts" do - # an integration test - xhr :post, :change_post_owners, topic_id: topic.id, username: user_a.username_lower, post_ids: [p1.id, p2.id] - p1.reload; p2.reload - expect(p1.user).not_to eq(nil) - expect(p1.user).to eq(p2.user) + post :change_post_owners, params: { + topic_id: topic.id, username: user_a.username_lower, post_ids: [p1.id, p2.id] + }, format: :json + + expect(response).to be_success + + p1.reload + p2.reload + + expect(p1.user).to_not eq(nil) + expect(p1.reload.user).to eq(p2.reload.user) end it "works with deleted users" do @@ -302,7 +385,10 @@ describe TopicsController do UserDestroyer.new(editor).destroy(deleted_user, delete_posts: true, context: 'test', delete_as_spammer: true) - xhr :post, :change_post_owners, topic_id: t2.id, username: user_a.username_lower, post_ids: [p3.id] + post :change_post_owners, params: { + topic_id: t2.id, username: user_a.username_lower, post_ids: [p3.id] + }, format: :json + expect(response).to be_success t2.reload p3.reload @@ -316,7 +402,9 @@ describe TopicsController do let(:params) { { topic_id: 1, timestamp: Time.zone.now } } it 'needs you to be logged in' do - expect { xhr :put, :change_timestamps, params }.to raise_error(Discourse::NotLoggedIn) + expect do + put :change_timestamps, params: params, format: :json + end.to raise_error(Discourse::NotLoggedIn) end [:moderator, :trust_level_4].each do |user| @@ -324,7 +412,7 @@ describe TopicsController do let!(user) { log_in(user) } it 'correctly denies' do - xhr :put, :change_timestamps, params + put :change_timestamps, params: params, format: :json expect(response).to be_forbidden end end @@ -339,11 +427,16 @@ describe TopicsController do let!(:p2) { Fabricate(:post, topic_id: topic.id, created_at: old_timestamp + 1.day) } it 'raises an error with a missing parameter' do - expect { xhr :put, :change_timestamps, topic_id: 1 }.to raise_error(ActionController::ParameterMissing) + expect do + put :change_timestamps, params: { topic_id: 1 }, format: :json + end.to raise_error(ActionController::ParameterMissing) end it 'should update the timestamps of selected posts' do - xhr :put, :change_timestamps, topic_id: topic.id, timestamp: new_timestamp.to_f + put :change_timestamps, params: { + topic_id: topic.id, timestamp: new_timestamp.to_f + }, format: :json + expect(topic.reload.created_at).to be_within_one_second_of(new_timestamp) expect(p1.reload.created_at).to be_within_one_second_of(new_timestamp) expect(p2.reload.created_at).to be_within_one_second_of(old_timestamp) @@ -353,7 +446,9 @@ describe TopicsController do context 'clear_pin' do it 'needs you to be logged in' do - expect { xhr :put, :clear_pin, topic_id: 1 }.to raise_error(Discourse::NotLoggedIn) + expect do + put :clear_pin, params: { topic_id: 1 }, format: :json + end.to raise_error(Discourse::NotLoggedIn) end context 'when logged in' do @@ -362,18 +457,18 @@ describe TopicsController do it "fails when the user can't see the topic" do Guardian.any_instance.expects(:can_see?).with(topic).returns(false) - xhr :put, :clear_pin, topic_id: topic.id + put :clear_pin, params: { topic_id: topic.id }, format: :json expect(response).not_to be_success end describe 'when the user can see the topic' do it "calls clear_pin_for if the user can see the topic" do Topic.any_instance.expects(:clear_pin_for).with(user).once - xhr :put, :clear_pin, topic_id: topic.id + put :clear_pin, params: { topic_id: topic.id }, format: :json end it "succeeds" do - xhr :put, :clear_pin, topic_id: topic.id + put :clear_pin, params: { topic_id: topic.id }, format: :json expect(response).to be_success end end @@ -384,7 +479,11 @@ describe TopicsController do context 'status' do it 'needs you to be logged in' do - expect { xhr :put, :status, topic_id: 1, status: 'visible', enabled: true }.to raise_error(Discourse::NotLoggedIn) + expect do + put :status, params: { + topic_id: 1, status: 'visible', enabled: true + }, format: :json + end.to raise_error(Discourse::NotLoggedIn) end describe 'when logged in' do @@ -395,20 +494,36 @@ describe TopicsController do it "raises an exception if you can't change it" do Guardian.any_instance.expects(:can_moderate?).with(@topic).returns(false) - xhr :put, :status, topic_id: @topic.id, status: 'visible', enabled: 'true' + + put :status, params: { + topic_id: @topic.id, status: 'visible', enabled: 'true' + }, format: :json + expect(response).to be_forbidden end it 'requires the status parameter' do - expect { xhr :put, :status, topic_id: @topic.id, enabled: true }.to raise_error(ActionController::ParameterMissing) + expect do + put :status, params: { + topic_id: @topic.id, enabled: true + }, format: :json + end.to raise_error(ActionController::ParameterMissing) end it 'requires the enabled parameter' do - expect { xhr :put, :status, topic_id: @topic.id, status: 'visible' }.to raise_error(ActionController::ParameterMissing) + expect do + put :status, params: { + topic_id: @topic.id, status: 'visible' + }, format: :json + end.to raise_error(ActionController::ParameterMissing) end it 'raises an error with a status not in the whitelist' do - expect { xhr :put, :status, topic_id: @topic.id, status: 'title', enabled: 'true' }.to raise_error(Discourse::InvalidParameters) + expect do + put :status, params: { + topic_id: @topic.id, status: 'title', enabled: 'true' + }, format: :json + end.to raise_error(Discourse::InvalidParameters) end it 'should update the status of the topic correctly' do @@ -416,7 +531,9 @@ describe TopicsController do Fabricate(:topic_timer, status_type: TopicTimer.types[:open]) ]) - xhr :put, :status, topic_id: @topic.id, status: 'closed', enabled: 'false' + put :status, params: { + topic_id: @topic.id, status: 'closed', enabled: 'false' + }, format: :json expect(response).to be_success expect(@topic.reload.closed).to eq(false) @@ -434,7 +551,9 @@ describe TopicsController do context 'delete_timings' do it 'needs you to be logged in' do - expect { xhr :delete, :destroy_timings, topic_id: 1 }.to raise_error(Discourse::NotLoggedIn) + expect do + delete :destroy_timings, params: { topic_id: 1 }, format: :json + end.to raise_error(Discourse::NotLoggedIn) end context 'when logged in' do @@ -446,7 +565,7 @@ describe TopicsController do it 'deletes the forum topic user record' do PostTiming.expects(:destroy_for).with(@user.id, [@topic.id]) - xhr :delete, :destroy_timings, topic_id: @topic.id + delete :destroy_timings, params: { topic_id: @topic.id }, format: :json end end @@ -456,25 +575,23 @@ describe TopicsController do describe 'mute/unmute' do it 'needs you to be logged in' do - expect { xhr :put, :mute, topic_id: 99 }.to raise_error(Discourse::NotLoggedIn) + expect do + put :mute, params: { topic_id: 99 }, format: :json + end.to raise_error(Discourse::NotLoggedIn) end it 'needs you to be logged in' do - expect { xhr :put, :unmute, topic_id: 99 }.to raise_error(Discourse::NotLoggedIn) + expect do + put :unmute, params: { topic_id: 99 }, format: :json + end.to raise_error(Discourse::NotLoggedIn) end - - describe 'when logged in' do - before do - @topic = Fabricate(:topic, user: log_in) - end - - end - end describe 'recover' do it "won't allow us to recover a topic when we're not logged in" do - expect { xhr :put, :recover, topic_id: 1 }.to raise_error(Discourse::NotLoggedIn) + expect do + put :recover, params: { topic_id: 1 }, format: :json + end.to raise_error(Discourse::NotLoggedIn) end describe 'when logged in' do @@ -483,7 +600,7 @@ describe TopicsController do describe 'without access' do it "raises an exception when the user doesn't have permission to delete the topic" do Guardian.any_instance.expects(:can_recover_topic?).with(topic).returns(false) - xhr :put, :recover, topic_id: topic.id + put :recover, params: { topic_id: topic.id }, format: :json expect(response).to be_forbidden end end @@ -495,7 +612,7 @@ describe TopicsController do it 'succeeds' do PostDestroyer.any_instance.expects(:recover) - xhr :put, :recover, topic_id: topic.id + put :recover, params: { topic_id: topic.id }, format: :json expect(response).to be_success end end @@ -505,7 +622,9 @@ describe TopicsController do describe 'delete' do it "won't allow us to delete a topic when we're not logged in" do - expect { xhr :delete, :destroy, id: 1 }.to raise_error(Discourse::NotLoggedIn) + expect do + delete :destroy, params: { id: 1 }, format: :json + end.to raise_error(Discourse::NotLoggedIn) end describe 'when logged in' do @@ -514,7 +633,7 @@ describe TopicsController do describe 'without access' do it "raises an exception when the user doesn't have permission to delete the topic" do Guardian.any_instance.expects(:can_delete?).with(topic).returns(false) - xhr :delete, :destroy, id: topic.id + delete :destroy, params: { id: topic.id }, format: :json expect(response).to be_forbidden end end @@ -526,7 +645,7 @@ describe TopicsController do it 'succeeds' do PostDestroyer.any_instance.expects(:destroy) - xhr :delete, :destroy, id: topic.id + delete :destroy, params: { id: topic.id }, format: :json expect(response).to be_success end @@ -539,7 +658,7 @@ describe TopicsController do let(:topic) { Fabricate(:post).topic } it "returns JSON for the slug" do - xhr :get, :id_for_slug, slug: topic.slug + get :id_for_slug, params: { slug: topic.slug }, format: :json expect(response).to be_success json = ::JSON.parse(response.body) expect(json).to be_present @@ -550,7 +669,7 @@ describe TopicsController do it "returns invalid access if the user can't see the topic" do Guardian.any_instance.expects(:can_see?).with(topic).returns(false) - xhr :get, :id_for_slug, slug: topic.slug + get :id_for_slug, params: { slug: topic.slug }, format: :json expect(response).not_to be_success end end @@ -560,7 +679,8 @@ describe TopicsController do it 'correctly renders canoicals' do topic = Fabricate(:post).topic - get :show, topic_id: topic.id, slug: topic.slug + get :show, params: { topic_id: topic.id, slug: topic.slug } + expect(response).to be_success expect(css_select("link[rel=canonical]").length).to eq(1) expect(response.headers["Cache-Control"]).to eq("no-store, must-revalidate, no-cache, private") @@ -579,13 +699,13 @@ describe TopicsController do topic = Fabricate(:topic, visible: false) Fabricate(:post, topic: topic) - xhr :get, :show, topic_id: topic.id, slug: topic.slug + get :show, params: { topic_id: topic.id, slug: topic.slug }, format: :json expect(response).to be_success - xhr :get, :show, topic_id: topic.id, slug: "just-guessing" + get :show, params: { topic_id: topic.id, slug: "just-guessing" }, format: :json expect(response.code).to eq("301") - xhr :get, :show, id: topic.slug + get :show, params: { id: topic.slug }, format: :json expect(response.code).to eq("301") end end @@ -597,17 +717,17 @@ describe TopicsController do let!(:p2) { Fabricate(:post, user: topic.user) } it 'shows a topic correctly' do - xhr :get, :show, topic_id: topic.id, slug: topic.slug + get :show, params: { topic_id: topic.id, slug: topic.slug }, format: :json expect(response).to be_success end it 'return 404 for an invalid page' do - xhr :get, :show, topic_id: topic.id, slug: topic.slug, page: 2 + get :show, params: { topic_id: topic.id, slug: topic.slug, page: 2 }, format: :json expect(response.code).to eq("404") end it 'can find a topic given a slug in the id param' do - xhr :get, :show, id: topic.slug + get :show, params: { id: topic.slug } expect(response).to redirect_to(topic.relative_url) end @@ -615,38 +735,53 @@ describe TopicsController do another_topic = Fabricate(:post).topic topic.update_column(:slug, "#{another_topic.id}-reasons-discourse-is-awesome") - xhr :get, :show, id: "#{another_topic.id}-reasons-discourse-is-awesome" + get :show, params: { id: "#{another_topic.id}-reasons-discourse-is-awesome" } expect(response).to redirect_to(topic.relative_url) end it 'keeps the post_number parameter around when redirecting' do - xhr :get, :show, id: topic.slug, post_number: 42 + get :show, params: { id: topic.slug, post_number: 42 } expect(response).to redirect_to(topic.relative_url + "/42") end it 'keeps the page around when redirecting' do - xhr :get, :show, id: topic.slug, post_number: 42, page: 123 + get :show, params: { + id: topic.slug, post_number: 42, page: 123 + } + expect(response).to redirect_to(topic.relative_url + "/42?page=123") end it 'does not accept page params as an array' do - xhr :get, :show, id: topic.slug, post_number: 42, page: [2] + get :show, params: { + id: topic.slug, post_number: 42, page: [2] + } + expect(response).to redirect_to("#{topic.relative_url}/42?page=1") end it 'returns 404 when an invalid slug is given and no id' do - xhr :get, :show, id: 'nope-nope' + get :show, params: { + id: 'nope-nope' + }, format: :json + expect(response.status).to eq(404) end it 'returns a 404 when slug and topic id do not match a topic' do - xhr :get, :show, topic_id: 123123, slug: 'topic-that-is-made-up' + get :show, params: { + topic_id: 123123, slug: 'topic-that-is-made-up' + }, format: :json + expect(response.status).to eq(404) end it 'returns a 404 for an ID that is larger than postgres limits' do - xhr :get, :show, topic_id: 50142173232201640412, slug: 'topic-that-is-made-up' + get :show, params: { + topic_id: 5014217323220164041, slug: 'topic-that-is-made-up' + }, format: :json + expect(response.status).to eq(404) end @@ -657,7 +792,10 @@ describe TopicsController do end it 'returns a 404 when slug and topic id do not match a topic' do - xhr :get, :show, topic_id: 123123, slug: 'topic-that-is-made-up' + get :show, params: { + topic_id: 123123, slug: 'topic-that-is-made-up' + }, format: :json + expect(response.status).to eq(404) end end @@ -779,12 +917,19 @@ describe TopicsController do end it 'records a view' do - expect { xhr :get, :show, topic_id: topic.id, slug: topic.slug }.to change(TopicViewItem, :count).by(1) + expect do + get :show, params: { + topic_id: topic.id, slug: topic.slug + }, format: :json + end.to change(TopicViewItem, :count).by(1) end it 'records incoming links' do user = Fabricate(:user) - get :show, topic_id: topic.id, slug: topic.slug, u: user.username + + get :show, params: { + topic_id: topic.id, slug: topic.slug, u: user.username + } expect(IncomingLink.count).to eq(1) end @@ -793,23 +938,31 @@ describe TopicsController do it "doesn't renders the print view when disabled" do SiteSetting.max_prints_per_hour_per_user = 0 - get :show, topic_id: topic.id, slug: topic.slug, print: true + + get :show, params: { + topic_id: topic.id, slug: topic.slug, print: true + } + expect(response).to be_forbidden end it 'renders the print view when enabled' do SiteSetting.max_prints_per_hour_per_user = 10 - get :show, topic_id: topic.id, slug: topic.slug, print: true + + get :show, params: { + topic_id: topic.id, slug: topic.slug, print: true + } + expect(response).to be_successful end end it 'records redirects' do - @request.env['HTTP_REFERER'] = 'http://twitter.com' - get :show, id: topic.id + request.env['HTTP_REFERER'] = 'http://twitter.com' + get :show, params: { id: topic.id } - @request.env['HTTP_REFERER'] = nil - get :show, topic_id: topic.id, slug: topic.slug + request.env['HTTP_REFERER'] = nil + get :show, params: { topic_id: topic.id, slug: topic.slug } link = IncomingLink.first expect(link.referer).to eq('http://twitter.com') @@ -818,7 +971,7 @@ describe TopicsController do it 'tracks a visit for all html requests' do current_user = log_in(:coding_horror) TopicUser.expects(:track_visit!).with(topic.id, current_user.id) - get :show, topic_id: topic.id, slug: topic.slug + get :show, params: { topic_id: topic.id, slug: topic.slug } end context 'consider for a promotion' do @@ -832,7 +985,7 @@ describe TopicsController do it "reviews the user for a promotion if they're new" do user.update_column(:trust_level, TrustLevel[0]) Promotion.any_instance.expects(:review) - get :show, topic_id: topic.id, slug: topic.slug + get :show, params: { topic_id: topic.id, slug: topic.slug }, format: :json end end @@ -840,22 +993,34 @@ describe TopicsController do it 'grabs first page when no filter is provided' do TopicView.any_instance.expects(:filter_posts_in_range).with(0, 19) - xhr :get, :show, topic_id: topic.id, slug: topic.slug + + get :show, params: { + topic_id: topic.id, slug: topic.slug + }, format: :json end it 'grabs first page when first page is provided' do TopicView.any_instance.expects(:filter_posts_in_range).with(0, 19) - xhr :get, :show, topic_id: topic.id, slug: topic.slug, page: 1 + + get :show, params: { + topic_id: topic.id, slug: topic.slug, page: 1 + }, format: :json end it 'grabs correct range when a page number is provided' do TopicView.any_instance.expects(:filter_posts_in_range).with(20, 39) - xhr :get, :show, topic_id: topic.id, slug: topic.slug, page: 2 + + get :show, params: { + topic_id: topic.id, slug: topic.slug, page: 2 + }, format: :json end it 'delegates a post_number param to TopicView#filter_posts_near' do TopicView.any_instance.expects(:filter_posts_near).with(p2.post_number) - xhr :get, :show, topic_id: topic.id, slug: topic.slug, post_number: p2.post_number + + get :show, params: { + topic_id: topic.id, slug: topic.slug, post_number: p2.post_number + }, format: :json end end @@ -866,7 +1031,7 @@ describe TopicsController do before { log_in(:coding_horror) } it 'shows the topic' do - get :show, topic_id: topic.id, slug: topic.slug + get :show, params: { topic_id: topic.id, slug: topic.slug }, format: :json expect(response).to be_successful end end @@ -875,12 +1040,18 @@ describe TopicsController do let(:api_key) { topic.user.generate_api_key(topic.user) } it 'redirects to the login page' do - get :show, topic_id: topic.id, slug: topic.slug + get :show, params: { + topic_id: topic.id, slug: topic.slug + }, format: :json + expect(response).to redirect_to login_path end it 'shows the topic if valid api key is provided' do - get :show, topic_id: topic.id, slug: topic.slug, api_key: api_key.key + get :show, params: { + topic_id: topic.id, slug: topic.slug, api_key: api_key.key + }, format: :json + expect(response).to be_successful topic.reload # free test, only costs a reload @@ -888,7 +1059,10 @@ describe TopicsController do end it 'returns 403 for an invalid key' do - get :show, topic_id: topic.id, slug: topic.slug, api_key: "bad" + get :show, params: { + topic_id: topic.id, slug: topic.slug, api_key: "bad" + }, format: :json + expect(response.code.to_i).to be(403) end end @@ -899,7 +1073,7 @@ describe TopicsController do let(:topic) { Fabricate(:post).topic } it 'returns first posts of the topic' do - get :posts, topic_id: topic.id, format: :json + get :posts, params: { topic_id: topic.id }, format: :json expect(response).to be_success expect(response.content_type).to eq('application/json') end @@ -909,7 +1083,7 @@ describe TopicsController do let(:topic) { Fabricate(:post).topic } it 'renders rss of the topic' do - get :feed, topic_id: topic.id, slug: 'foo', format: :rss + get :feed, params: { topic_id: topic.id, slug: 'foo' }, format: :rss expect(response).to be_success expect(response.content_type).to eq('application/rss+xml') end @@ -917,7 +1091,9 @@ describe TopicsController do describe 'update' do it "won't allow us to update a topic when we're not logged in" do - expect { xhr :put, :update, topic_id: 1, slug: 'xyz' }.to raise_error(Discourse::NotLoggedIn) + expect do + put :update, params: { topic_id: 1, slug: 'xyz' }, format: :json + end.to raise_error(Discourse::NotLoggedIn) end describe 'when logged in' do @@ -929,7 +1105,11 @@ describe TopicsController do describe 'without permission' do it "raises an exception when the user doesn't have permission to update the topic" do Guardian.any_instance.expects(:can_edit?).with(@topic).returns(false) - xhr :put, :update, topic_id: @topic.id, slug: @topic.title + + put :update, params: { + topic_id: @topic.id, slug: @topic.title + }, format: :json + expect(response).to be_forbidden end end @@ -940,47 +1120,71 @@ describe TopicsController do end it 'succeeds' do - xhr :put, :update, topic_id: @topic.id, slug: @topic.title + put :update, params: { + topic_id: @topic.id, slug: @topic.title + }, format: :json + expect(response).to be_success expect(::JSON.parse(response.body)['basic_topic']).to be_present end it 'allows a change of title' do - xhr :put, :update, topic_id: @topic.id, slug: @topic.title, title: 'This is a new title for the topic' + put :update, params: { + topic_id: @topic.id, slug: @topic.title, title: 'This is a new title for the topic' + }, format: :json + @topic.reload expect(@topic.title).to eq('This is a new title for the topic') end it 'triggers a change of category' do Topic.any_instance.expects(:change_category_to_id).with(123).returns(true) - xhr :put, :update, topic_id: @topic.id, slug: @topic.title, category_id: 123 + put :update, params: { + topic_id: @topic.id, slug: @topic.title, category_id: 123 + }, format: :json + end it 'allows to change category to "uncategorized"' do Topic.any_instance.expects(:change_category_to_id).with(0).returns(true) - xhr :put, :update, topic_id: @topic.id, slug: @topic.title, category_id: "" + put :update, params: { + topic_id: @topic.id, slug: @topic.title, category_id: "" + }, format: :json + end it "returns errors with invalid titles" do - xhr :put, :update, topic_id: @topic.id, slug: @topic.title, title: 'asdf' + put :update, params: { + topic_id: @topic.id, slug: @topic.title, title: 'asdf' + }, format: :json + expect(response).not_to be_success end it "returns errors when the rate limit is exceeded" do EditRateLimiter.any_instance.expects(:performed!).raises(RateLimiter::LimitExceeded.new(60)) - xhr :put, :update, topic_id: @topic.id, slug: @topic.title, title: 'This is a new title for the topic' + put :update, params: { + topic_id: @topic.id, slug: @topic.title, title: 'This is a new title for the topic' + }, format: :json + expect(response).not_to be_success end it "returns errors with invalid categories" do Topic.any_instance.expects(:change_category_to_id).returns(false) - xhr :put, :update, topic_id: @topic.id, slug: @topic.title, category_id: -1 + put :update, params: { + topic_id: @topic.id, slug: @topic.title, category_id: -1 + }, format: :json + expect(response).not_to be_success end it "doesn't call the PostRevisor when there is no changes" do PostRevisor.any_instance.expects(:revise!).never - xhr :put, :update, topic_id: @topic.id, slug: @topic.title, title: @topic.title, category_id: @topic.category_id + put :update, params: { + topic_id: @topic.id, slug: @topic.title, title: @topic.title, category_id: @topic.category_id + }, format: :json + expect(response).to be_success end @@ -994,7 +1198,10 @@ describe TopicsController do context 'when there are no changes' do it 'does not call the PostRevisor' do PostRevisor.any_instance.expects(:revise!).never - xhr :put, :update, topic_id: @topic.id, slug: @topic.title, title: @topic.title, category_id: nil + put :update, params: { + topic_id: @topic.id, slug: @topic.title, title: @topic.title, category_id: nil + }, format: :json + expect(response).to be_success end end @@ -1007,7 +1214,11 @@ describe TopicsController do it "can add a category to an uncategorized topic" do Topic.any_instance.expects(:change_category_to_id).with(456).returns(true) - xhr :put, :update, topic_id: @topic.id, slug: @topic.title, category_id: 456 + + put :update, params: { + topic_id: @topic.id, slug: @topic.title, category_id: 456 + }, format: :json + expect(response).to be_success end end @@ -1032,13 +1243,18 @@ describe TopicsController do it "disallows inviting a group to a topic" do topic = Fabricate(:topic) - xhr :post, :invite_group, topic_id: topic.id, group: 'admins' + post :invite_group, params: { + topic_id: topic.id, group: 'admins' + }, format: :json + expect(response.status).to eq(422) end it "allows inviting a group to a PM" do topic = Fabricate(:private_message_topic) - xhr :post, :invite_group, topic_id: topic.id, group: 'admins' + post :invite_group, params: { + topic_id: topic.id, group: 'admins' + }, format: :json expect(response.status).to eq(200) expect(topic.allowed_groups.first.id).to eq(admins.id) @@ -1053,7 +1269,9 @@ describe TopicsController do topic = Fabricate(:topic) _admin = log_in(:admin) - xhr :post, :invite, topic_id: topic.id, email: 'hiro@from.heros', group_ids: "#{group.id}" + post :invite, params: { + topic_id: topic.id, email: 'hiro@from.heros', group_ids: "#{group.id}" + }, format: :json expect(response).to be_success @@ -1065,7 +1283,11 @@ describe TopicsController do end it "won't allow us to invite toa topic when we're not logged in" do - expect { xhr :post, :invite, topic_id: 1, email: 'jake@adventuretime.ooo' }.to raise_error(Discourse::NotLoggedIn) + expect do + post :invite, params: { + topic_id: 1, email: 'jake@adventuretime.ooo' + }, format: :json + end.to raise_error(Discourse::NotLoggedIn) end describe 'when logged in as group manager' do @@ -1076,7 +1298,10 @@ describe TopicsController do let(:recipient) { 'jake@adventuretime.ooo' } it "should attach group to the invite" do - xhr :post, :invite, topic_id: group_private_topic.id, user: recipient + post :invite, params: { + topic_id: group_private_topic.id, user: recipient + }, format: :json + expect(response).to be_success expect(Invite.find_by(email: recipient).groups).to eq([group]) end @@ -1088,12 +1313,17 @@ describe TopicsController do end it 'requires an email parameter' do - expect { xhr :post, :invite, topic_id: @topic.id }.to raise_error(ActionController::ParameterMissing) + expect do + post :invite, params: { topic_id: @topic.id }, format: :json + end.to raise_error(ActionController::ParameterMissing) end describe 'without permission' do it "raises an exception when the user doesn't have permission to invite to the topic" do - xhr :post, :invite, topic_id: @topic.id, user: 'jake@adventuretime.ooo' + post :invite, params: { + topic_id: @topic.id, user: 'jake@adventuretime.ooo' + }, format: :json + expect(response).to be_forbidden end end @@ -1105,14 +1335,20 @@ describe TopicsController do end it 'should work as expected' do - xhr :post, :invite, topic_id: @topic.id, user: 'jake@adventuretime.ooo' + post :invite, params: { + topic_id: @topic.id, user: 'jake@adventuretime.ooo' + }, format: :json + expect(response).to be_success expect(::JSON.parse(response.body)).to eq('success' => 'OK') expect(Invite.where(invited_by_id: admin.id).count).to eq(1) end it 'should fail on shoddy email' do - xhr :post, :invite, topic_id: @topic.id, user: 'i_am_not_an_email' + post :invite, params: { + topic_id: @topic.id, user: 'i_am_not_an_email' + }, format: :json + expect(response).not_to be_success expect(::JSON.parse(response.body)).to eq('failed' => 'FAILED') end @@ -1127,7 +1363,7 @@ describe TopicsController do it 'needs you to be a staff member' do log_in - xhr :put, :make_banner, topic_id: 99 + put :make_banner, params: { topic_id: 99 }, format: :json expect(response).to be_forbidden end @@ -1137,7 +1373,7 @@ describe TopicsController do topic = Fabricate(:topic, user: log_in(:admin)) Topic.any_instance.expects(:make_banner!) - xhr :put, :make_banner, topic_id: topic.id + put :make_banner, params: { topic_id: topic.id }, format: :json expect(response).to be_success end end @@ -1150,7 +1386,9 @@ describe TopicsController do user = Fabricate(:user) pm = create_post(user: user, archetype: 'private_message', target_usernames: [user.username, admin.username]) - xhr :put, :remove_allowed_user, topic_id: pm.topic_id, username: admin.username + put :remove_allowed_user, params: { + topic_id: pm.topic_id, username: admin.username + }, format: :json expect(response.status).to eq(200) expect(TopicAllowedUser.where(topic_id: pm.topic_id, user_id: admin.id).first).to eq(nil) @@ -1161,7 +1399,7 @@ describe TopicsController do it 'needs you to be a staff member' do log_in - xhr :put, :remove_banner, topic_id: 99 + put :remove_banner, params: { topic_id: 99 }, format: :json expect(response).to be_forbidden end @@ -1171,7 +1409,7 @@ describe TopicsController do topic = Fabricate(:topic, user: log_in(:admin)) Topic.any_instance.expects(:remove_banner!) - xhr :put, :remove_banner, topic_id: topic.id + put :remove_banner, params: { topic_id: topic.id }, format: :json expect(response).to be_success end @@ -1181,7 +1419,9 @@ describe TopicsController do describe "bulk" do it 'needs you to be logged in' do - expect { xhr :put, :bulk }.to raise_error(Discourse::NotLoggedIn) + expect do + put :bulk, format: :json + end.to raise_error(Discourse::NotLoggedIn) end describe "when logged in" do @@ -1190,20 +1430,29 @@ describe TopicsController do let(:topic_ids) { [1, 2, 3] } it "requires a list of topic_ids or filter" do - expect { xhr :put, :bulk, operation: operation }.to raise_error(ActionController::ParameterMissing) + expect do + put :bulk, params: { operation: operation }, format: :json + end.to raise_error(ActionController::ParameterMissing) end it "requires an operation param" do - expect { xhr :put, :bulk, topic_ids: topic_ids }.to raise_error(ActionController::ParameterMissing) + expect do + put :bulk, params: { topic_ids: topic_ids }, format: :json + end.to raise_error(ActionController::ParameterMissing) end it "requires a type field for the operation param" do - expect { xhr :put, :bulk, topic_ids: topic_ids, operation: {} }.to raise_error(ActionController::ParameterMissing) + expect do + put :bulk, params: { topic_ids: topic_ids, operation: {} }, format: :json + end.to raise_error(ActionController::ParameterMissing) end it "can find unread" do # mark all unread muted - xhr :put, :bulk, filter: 'unread', operation: { type: :change_notification_level, notification_level_id: 0 } + put :bulk, params: { + filter: 'unread', operation: { type: :change_notification_level, notification_level_id: 0 } + }, format: :json + expect(response.status).to eq(200) end @@ -1211,7 +1460,10 @@ describe TopicsController do topics_bulk_action = mock TopicsBulkAction.expects(:new).with(user, topic_ids, operation, group: nil).returns(topics_bulk_action) topics_bulk_action.expects(:perform!) - xhr :put, :bulk, topic_ids: topic_ids, operation: operation + + put :bulk, params: { + topic_ids: topic_ids, operation: operation + }, format: :json end end end @@ -1226,10 +1478,10 @@ describe TopicsController do PostAction.act(user, post2, bookmark) - xhr :put, :bookmark, topic_id: post.topic_id + put :bookmark, params: { topic_id: post.topic_id }, format: :json expect(PostAction.where(user_id: user.id, post_action_type: bookmark).count).to eq(2) - xhr :put, :remove_bookmarks, topic_id: post.topic_id + put :remove_bookmarks, params: { topic_id: post.topic_id }, format: :json expect(PostAction.where(user_id: user.id, post_action_type: bookmark).count).to eq(0) end @@ -1238,14 +1490,16 @@ describe TopicsController do user = Fabricate(:user) pm = create_post(user: user, archetype: 'private_message', target_usernames: [user.username]) - xhr :put, :bookmark, topic_id: pm.topic_id + put :bookmark, params: { topic_id: pm.topic_id }, format: :json expect(response).to be_forbidden end end describe 'reset_new' do it 'needs you to be logged in' do - expect { xhr :put, :reset_new }.to raise_error(Discourse::NotLoggedIn) + expect do + put :reset_new, format: :json + end.to raise_error(Discourse::NotLoggedIn) end let(:user) { log_in(:user) } @@ -1255,7 +1509,7 @@ describe TopicsController do user.user_stat.update_column(:new_since, old_date) - xhr :put, :reset_new + put :reset_new, format: :json user.reload expect(user.user_stat.new_since.to_date).not_to eq(old_date.to_date) end @@ -1264,7 +1518,7 @@ describe TopicsController do describe "feature_stats" do it "works" do - xhr :get, :feature_stats, category_id: 1 + get :feature_stats, params: { category_id: 1 }, format: :json expect(response).to be_success json = JSON.parse(response.body) @@ -1276,7 +1530,7 @@ describe TopicsController do it "allows unlisted banner topic" do Fabricate(:topic, category_id: 1, archetype: Archetype.banner, visible: false) - xhr :get, :feature_stats, category_id: 1 + get :feature_stats, params: { category_id: 1 }, format: :json json = JSON.parse(response.body) expect(json["banner_count"]).to eq(1) end @@ -1285,13 +1539,13 @@ describe TopicsController do describe "x-robots-tag" do it "is included for unlisted topics" do topic = Fabricate(:topic, visible: false) - get :show, topic_id: topic.id, slug: topic.slug + get :show, params: { topic_id: topic.id, slug: topic.slug }, format: :json expect(response.headers['X-Robots-Tag']).to eq('noindex') end it "is not included for normal topics" do topic = Fabricate(:topic, visible: true) - get :show, topic_id: topic.id, slug: topic.slug + get :show, params: { topic_id: topic.id, slug: topic.slug }, format: :json expect(response.headers['X-Robots-Tag']).to eq(nil) end @@ -1306,7 +1560,10 @@ describe TopicsController do random_post = Fabricate(:post) - xhr :get, :excerpts, topic_id: first_post.topic_id, post_ids: [first_post.id, second_post.id, random_post.id] + get :excerpts, params: { + topic_id: first_post.topic_id, + post_ids: [first_post.id, second_post.id, random_post.id] + }, format: :json json = JSON.parse(response.body) json.sort! { |a, b| a["post_id"] <=> b["post_id"] } @@ -1327,7 +1584,9 @@ describe TopicsController do context "convert_topic" do it 'needs you to be logged in' do - expect { xhr :put, :convert_topic, id: 111, type: "private" }.to raise_error(Discourse::NotLoggedIn) + expect do + put :convert_topic, params: { id: 111, type: "private" }, format: :json + end.to raise_error(Discourse::NotLoggedIn) end describe 'converting public topic to private message' do @@ -1336,7 +1595,10 @@ describe TopicsController do it "raises an error when the user doesn't have permission to convert topic" do log_in - xhr :put, :convert_topic, id: topic.id, type: "private" + put :convert_topic, params: { + id: topic.id, type: "private" + }, format: :json + expect(response).to be_forbidden end @@ -1344,7 +1606,10 @@ describe TopicsController do before do admin = log_in(:admin) Topic.any_instance.expects(:convert_to_private_message).with(admin).returns(topic) - xhr :put, :convert_topic, id: topic.id, type: "private" + + put :convert_topic, params: { + id: topic.id, type: "private" + }, format: :json end it "returns success" do @@ -1362,7 +1627,10 @@ describe TopicsController do it "raises an error when the user doesn't have permission to convert topic" do log_in - xhr :put, :convert_topic, id: topic.id, type: "public" + put :convert_topic, params: { + id: topic.id, type: "public" + }, format: :json + expect(response).to be_forbidden end @@ -1370,7 +1638,10 @@ describe TopicsController do before do admin = log_in(:admin) Topic.any_instance.expects(:convert_to_public_topic).with(admin).returns(topic) - xhr :put, :convert_topic, id: topic.id, type: "public" + + put :convert_topic, params: { + id: topic.id, type: "public" + }, format: :json end it "returns success" do diff --git a/spec/controllers/uploads_controller_spec.rb b/spec/controllers/uploads_controller_spec.rb index 2dc04a70b77..58819817aa4 100644 --- a/spec/controllers/uploads_controller_spec.rb +++ b/spec/controllers/uploads_controller_spec.rb @@ -5,7 +5,7 @@ describe UploadsController do context '.create' do it 'requires you to be logged in' do - expect { xhr :post, :create }.to raise_error(Discourse::NotLoggedIn) + expect { post :create, format: :json }.to raise_error(Discourse::NotLoggedIn) end context 'logged in' do @@ -13,32 +13,38 @@ describe UploadsController do before { @user = log_in :user } let(:logo) do - ActionDispatch::Http::UploadedFile.new(filename: 'logo.png', - tempfile: file_from_fixtures("logo.png")) + Rack::Test::UploadedFile.new(file_from_fixtures("logo.png")) end let(:fake_jpg) do - ActionDispatch::Http::UploadedFile.new(filename: 'fake.jpg', - tempfile: file_from_fixtures("fake.jpg")) + Rack::Test::UploadedFile.new(file_from_fixtures("fake.jpg")) end let(:text_file) do - ActionDispatch::Http::UploadedFile.new(filename: 'LICENSE.TXT', - tempfile: File.new("#{Rails.root}/LICENSE.txt")) + Rack::Test::UploadedFile.new(File.new("#{Rails.root}/LICENSE.txt")) end it 'expects a type' do - expect { xhr :post, :create, file: logo }.to raise_error(ActionController::ParameterMissing) + expect do + post :create, params: { format: :json, file: logo } + end.to raise_error(ActionController::ParameterMissing) end it 'parameterize the type' do - subject.expects(:create_upload).with(logo, nil, "super_long_type_with_charssuper_long_type_with_char", false, false) - xhr :post, :create, file: logo, type: "super \# long \//\\ type with \\. $%^&*( chars" * 5 + subject.expects(:create_upload).with( + anything, + nil, + "super_long_type_with_charssuper_long_type_with_char", + false, + false + ) + + post :create, params: { format: :json, file: logo, type: "super \# long \//\\ type with \\. $%^&*( chars" * 5 } end it 'can look up long urls' do upload = Fabricate(:upload) - xhr :post, :lookup_urls, short_urls: [upload.short_url] + post :lookup_urls, params: { short_urls: [upload.short_url], format: :json } result = JSON.parse(response.body) expect(result[0]["url"]).to eq(upload.url) end @@ -47,7 +53,7 @@ describe UploadsController do Jobs.expects(:enqueue).with(:create_avatar_thumbnails, anything) message = MessageBus.track_publish do - xhr :post, :create, file: logo, type: "avatar" + post :create, params: { file: logo, type: "avatar", format: :json } end.find { |m| m.channel == "/uploads/avatar" } expect(response.status).to eq 200 @@ -62,7 +68,7 @@ describe UploadsController do Jobs.expects(:enqueue).never message = MessageBus.track_publish do - xhr :post, :create, file: text_file, type: "composer" + post :create, params: { file: text_file, type: "composer", format: :json } end.find { |m| m.channel == "/uploads/composer" } expect(response.status).to eq 200 @@ -79,7 +85,12 @@ describe UploadsController do stub_request(:head, 'http://example.com/image.png') stub_request(:get, "http://example.com/image.png").to_return(body: File.read('spec/fixtures/images/logo.png')) - xhr :post, :create, url: 'http://example.com/image.png', type: "avatar", synchronous: true + post :create, params: { + url: 'http://example.com/image.png', + type: "avatar", + synchronous: true, + format: :json + } json = ::JSON.parse(response.body) @@ -93,7 +104,12 @@ describe UploadsController do Jobs.expects(:enqueue).with(:create_avatar_thumbnails, anything).never message = MessageBus.track_publish do - xhr :post, :create, file: logo, retain_hours: 100, type: "profile_background" + post :create, params: { + file: logo, + retain_hours: 100, + type: "profile_background", + format: :json + } end.first id = message.data["id"] @@ -104,7 +120,7 @@ describe UploadsController do Jobs.expects(:enqueue).never message = MessageBus.track_publish do - xhr :post, :create, type: "composer" + post :create, params: { type: "composer", format: :json } end.first expect(response.status).to eq 200 @@ -117,7 +133,7 @@ describe UploadsController do Jobs.expects(:enqueue).never message = MessageBus.track_publish do - xhr :post, :create, file: text_file, type: "avatar" + post :create, params: { file: text_file, type: "avatar", format: :json } end.first expect(response.status).to eq 200 @@ -126,13 +142,13 @@ describe UploadsController do it 'ensures allow_uploaded_avatars is enabled when uploading an avatar' do SiteSetting.allow_uploaded_avatars = false - xhr :post, :create, file: logo, type: "avatar" + post :create, params: { file: logo, type: "avatar", format: :json } expect(response).to_not be_success end it 'ensures sso_overrides_avatar is not enabled when uploading an avatar' do SiteSetting.sso_overrides_avatar = true - xhr :post, :create, file: logo, type: "avatar" + post :create, params: { file: logo, type: "avatar", format: :json } expect(response).to_not be_success end @@ -142,7 +158,12 @@ describe UploadsController do @user.update_columns(moderator: true) message = MessageBus.track_publish do - xhr :post, :create, file: text_file, type: "composer", for_private_message: "true" + post :create, params: { + file: text_file, + type: "composer", + for_private_message: "true", + format: :json + } end.first expect(response).to be_success @@ -153,7 +174,7 @@ describe UploadsController do Jobs.expects(:enqueue).with(:create_avatar_thumbnails, anything).never message = MessageBus.track_publish do - xhr :post, :create, file: fake_jpg, type: "composer" + post :create, params: { file: fake_jpg, type: "composer", format: :json } end.find { |m| m.channel == '/uploads/composer' } expect(response.status).to eq 200 @@ -176,14 +197,14 @@ describe UploadsController do Discourse.stubs(:store).returns(store) Upload.expects(:find_by).never - get :show, site: site, sha: sha, extension: "pdf" + get :show, params: { site: site, sha: sha, extension: "pdf" } expect(response.response_code).to eq(404) end it "returns 404 when the upload doesn't exist" do Upload.stubs(:find_by).returns(nil) - get :show, site: site, sha: sha, extension: "pdf" + get :show, params: { site: site, sha: sha, extension: "pdf" } expect(response.response_code).to eq(404) end @@ -194,7 +215,7 @@ describe UploadsController do controller.stubs(:render) controller.expects(:send_file) - get :show, site: site, sha: sha, extension: "zip" + get :show, params: { site: site, sha: sha, extension: "zip" } end it "handles file without extension" do @@ -203,7 +224,7 @@ describe UploadsController do controller.stubs(:render) controller.expects(:send_file) - get :show, site: site, sha: sha + get :show, params: { site: site, sha: sha, format: :json } expect(response).to be_success end @@ -214,7 +235,7 @@ describe UploadsController do it "returns 404 when an anonymous user tries to download a file" do Upload.expects(:find_by).never - get :show, site: site, sha: sha, extension: "pdf" + get :show, params: { site: site, sha: sha, extension: "pdf", format: :json } expect(response.response_code).to eq(404) end diff --git a/spec/controllers/user_actions_controller_spec.rb b/spec/controllers/user_actions_controller_spec.rb index 9e606101272..79cf2ac1084 100644 --- a/spec/controllers/user_actions_controller_spec.rb +++ b/spec/controllers/user_actions_controller_spec.rb @@ -5,14 +5,16 @@ describe UserActionsController do context 'index' do it 'fails if username is not specified' do - expect { xhr :get, :index }.to raise_error(ActionController::ParameterMissing) + expect do + get :index, format: :json + end.to raise_error(ActionController::ParameterMissing) end it 'renders list correctly' do UserActionCreator.enable post = Fabricate(:post) - xhr :get, :index, username: post.user.username + get :index, params: { username: post.user.username }, format: :json expect(response.status).to eq(200) parsed = JSON.parse(response.body) @@ -27,7 +29,11 @@ describe UserActionsController do it 'renders help text if provided for self' do logged_in = log_in - xhr :get, :index, filter: UserAction::LIKE, username: logged_in.username, no_results_help_key: "user_activity.no_bookmarks" + get :index, params: { + filter: UserAction::LIKE, + username: logged_in.username, + no_results_help_key: "user_activity.no_bookmarks" + }, format: :json expect(response.status).to eq(200) parsed = JSON.parse(response.body) @@ -38,7 +44,12 @@ describe UserActionsController do it 'renders help text for others' do user = Fabricate(:user) - xhr :get, :index, filter: UserAction::LIKE, username: user.username, no_results_help_key: "user_activity.no_bookmarks" + + get :index, params: { + filter: UserAction::LIKE, + username: user.username, + no_results_help_key: "user_activity.no_bookmarks" + }, format: :json expect(response.status).to eq(200) parsed = JSON.parse(response.body) @@ -50,7 +61,9 @@ describe UserActionsController do context "without access" do let(:user) { Fabricate(:user) } it "raises an exception" do - xhr :get, :index, username: user.username, filter: UserAction::PENDING + get :index, params: { + username: user.username, filter: UserAction::PENDING + }, format: :json expect(response).to_not be_success end @@ -62,7 +75,9 @@ describe UserActionsController do it 'finds queued posts' do queued_post = PostEnqueuer.new(user, 'default').enqueue(raw: 'this is the raw enqueued content') - xhr :get, :index, username: user.username, filter: UserAction::PENDING + get :index, params: { + username: user.username, filter: UserAction::PENDING + }, format: :json expect(response.status).to eq(200) parsed = JSON.parse(response.body) diff --git a/spec/controllers/user_api_keys_controller_spec.rb b/spec/controllers/user_api_keys_controller_spec.rb index 4f5a1cfa91a..64a43182a12 100644 --- a/spec/controllers/user_api_keys_controller_spec.rb +++ b/spec/controllers/user_api_keys_controller_spec.rb @@ -3,34 +3,34 @@ require 'rails_helper' describe UserApiKeysController do let :public_key do - <') end @@ -300,10 +330,11 @@ describe UsersController do user = Fabricate(:user) user_auth_token = UserAuthToken.generate!(user_id: user.id) token = user.email_tokens.create(email: user.email).token - get :password_reset, token: token + get :password_reset, params: { token: token } events = DiscourseEvent.track_events do - put :password_reset, token: token, password: 'hg9ow8yhg98o' + put :password_reset, + params: { token: token, password: 'hg9ow8yhg98o' } end expect(events.map { |event| event[:event_name] }).to include( @@ -311,7 +342,7 @@ describe UsersController do ) expect(response).to be_success - expect(assigns[:error]).to be_blank + expect(response.body).to include('{"is_developer":false}') user.reload @@ -323,9 +354,13 @@ describe UsersController do user = Fabricate(:user) token = user.email_tokens.create(email: user.email).token - get :password_reset, token: token - put :password_reset, token: token, password: 'hg9ow8yHG32O' - put :password_reset, token: token, password: 'test123987AsdfXYZ' + get :password_reset, params: { token: token } + + put :password_reset, + params: { token: token, password: 'hg9ow8yHG32O' } + + put :password_reset, + params: { token: token, password: 'test123987AsdfXYZ' } user.reload expect(user.confirm_password?('hg9ow8yHG32O')).to eq(true) @@ -339,7 +374,7 @@ describe UsersController do UserAuthToken.generate!(user_id: user.id) token = user.email_tokens.create(email: user.email).token - get :password_reset, token: token + get :password_reset, params: { token: token }, format: :json expect(response).not_to redirect_to(wizard_path) end @@ -348,8 +383,12 @@ describe UsersController do UserAuthToken.generate!(user_id: user.id) token = user.email_tokens.create(email: user.email).token - get :password_reset, token: token - put :password_reset, token: token, password: 'hg9ow8yhg98oadminlonger' + get :password_reset, params: { token: token } + + put :password_reset, params: { + token: token, password: 'hg9ow8yhg98oadminlonger' + } + expect(response).to redirect_to(wizard_path) end @@ -359,7 +398,7 @@ describe UsersController do email_token = user.email_tokens.create(email: user.email) - get :password_reset, token: email_token.token + get :password_reset, params: { token: email_token.token }, format: :json email_token.reload @@ -370,32 +409,48 @@ describe UsersController do context 'submit change' do let(:token) { EmailToken.generate_token } + before do EmailToken.expects(:confirm).with(token).returns(user) end it "fails when the password is blank" do - put :password_reset, token: token, password: '' - expect(assigns(:user).errors).to be_present + put :password_reset, params: { + token: token, password: '' + }, format: :json + + expect(response).to be_success + expect(JSON.parse(response.body)["errors"]).to be_present expect(session[:current_user_id]).to be_blank end it "fails when the password is too long" do - put :password_reset, token: token, password: ('x' * (User.max_password_length + 1)) - expect(assigns(:user).errors).to be_present + put :password_reset, params: { + token: token, password: ('x' * (User.max_password_length + 1)) + }, format: :json + + expect(response).to be_success + expect(JSON.parse(response.body)["errors"]).to be_present expect(session[:current_user_id]).to be_blank end it "logs in the user" do - put :password_reset, token: token, password: 'ksjafh928r' - expect(assigns(:user).errors).to be_blank + put :password_reset, params: { + token: token, password: 'ksjafh928r' + }, format: :json + + expect(response).to be_success + expect(JSON.parse(response.body)["errors"]).to be_blank expect(session[:current_user_id]).to be_present end it "doesn't log in the user when not approved" do SiteSetting.must_approve_users = true - put :password_reset, token: token, password: 'ksjafh928r' - expect(assigns(:user).errors).to be_blank + put :password_reset, params: { + token: token, password: 'ksjafh928r' + }, format: :json + + expect(JSON.parse(response.body)["errors"]).to be_blank expect(session[:current_user_id]).to be_blank end end @@ -406,14 +461,14 @@ describe UsersController do it "token doesn't match any records" do email_token = user.email_tokens.create(email: user.email) - get :confirm_email_token, token: SecureRandom.hex, format: :json + get :confirm_email_token, params: { token: SecureRandom.hex }, format: :json expect(response).to be_success expect(email_token.reload.confirmed).to eq(false) end it "token matches" do email_token = user.email_tokens.create(email: user.email) - get :confirm_email_token, token: email_token.token, format: :json + get :confirm_email_token, params: { token: email_token.token }, format: :json expect(response).to be_success expect(email_token.reload.confirmed).to eq(true) end @@ -426,14 +481,14 @@ describe UsersController do context 'enqueues mail' do it 'enqueues mail with admin email and sso enabled' do Jobs.expects(:enqueue).with(:critical_user_email, has_entries(type: :admin_login, user_id: admin.id)) - put :admin_login, email: admin.email + put :admin_login, params: { email: admin.email } end end context 'logs in admin' do it 'does not log in admin with invalid token' do SiteSetting.enable_sso = true - get :admin_login, token: "invalid" + get :admin_login, params: { token: "invalid" } expect(session[:current_user_id]).to be_blank end @@ -442,7 +497,7 @@ describe UsersController do SiteSetting.enable_sso = false token = admin.email_tokens.create(email: admin.email).token - get :admin_login, token: token + get :admin_login, params: { token: token } expect(response).to redirect_to('/') expect(session[:current_user_id]).to eq(admin.id) end @@ -451,7 +506,7 @@ describe UsersController do SiteSetting.enable_sso = true token = admin.email_tokens.create(email: admin.email).token - get :admin_login, token: token + get :admin_login, params: { token: token } expect(response).to redirect_to('/') expect(session[:current_user_id]).to eq(admin.id) end @@ -467,11 +522,11 @@ describe UsersController do user.trust_level = 1 user.save - post :toggle_anon + post :toggle_anon, format: :json expect(response).to be_success expect(session[:current_user_id]).to eq(AnonymousShadowCreator.get(user).id) - post :toggle_anon + post :toggle_anon, format: :json expect(response).to be_success expect(session[:current_user_id]).to eq(user.id) @@ -496,16 +551,17 @@ describe UsersController do end def post_user - xhr :post, :create, post_user_params + post :create, params: post_user_params, format: :json end context 'when email params is missing' do it 'should raise the right error' do expect do - xhr :post, :create, + post :create, params: { name: @user.name, username: @user.username, passsword: 'tesing12352343' + }, format: :json end.to raise_error(ActionController::ParameterMissing) end end @@ -569,7 +625,7 @@ describe UsersController do context "creating as active" do it "won't create the user as active" do - xhr :post, :create, post_user_params.merge(active: true) + post :create, params: post_user_params.merge(active: true), format: :json expect(JSON.parse(response.body)['active']).to be_falsey end @@ -578,7 +634,10 @@ describe UsersController do let(:api_key) { Fabricate(:api_key, user: user) } it "won't create the user as active with a regular key" do - xhr :post, :create, post_user_params.merge(active: true, api_key: api_key.key) + post :create, + params: post_user_params.merge(active: true, api_key: api_key.key), + format: :json + expect(JSON.parse(response.body)['active']).to be_falsey end end @@ -594,7 +653,10 @@ describe UsersController do Sidekiq::Client.expects(:enqueue).never - xhr :post, :create, post_user_params.merge(approved: true, active: true, api_key: api_key.key) + post :create, + params: post_user_params.merge(approved: true, active: true, api_key: api_key.key), + format: :json + json = JSON.parse(response.body) new_user = User.find(json["user_id"]) @@ -610,7 +672,10 @@ describe UsersController do it "won't create the developer as active" do UsernameCheckerService.expects(:is_developer?).returns(true) - xhr :post, :create, post_user_params.merge(active: true, api_key: api_key.key) + post :create, + params: post_user_params.merge(active: true, api_key: api_key.key), + format: :json + expect(JSON.parse(response.body)['active']).to be_falsy end end @@ -618,7 +683,10 @@ describe UsersController do context "creating as staged" do it "won't create the user as staged" do - xhr :post, :create, post_user_params.merge(staged: true) + post :create, + params: post_user_params.merge(staged: true), + format: :json + new_user = User.where(username: post_user_params[:username]).first expect(new_user.staged?).to eq(false) end @@ -628,7 +696,10 @@ describe UsersController do let(:api_key) { Fabricate(:api_key, user: user) } it "won't create the user as staged with a regular key" do - xhr :post, :create, post_user_params.merge(staged: true, api_key: api_key.key) + post :create, + params: post_user_params.merge(staged: true, api_key: api_key.key), + format: :json + new_user = User.where(username: post_user_params[:username]).first expect(new_user.staged?).to eq(false) end @@ -639,7 +710,9 @@ describe UsersController do let(:api_key) { Fabricate(:api_key, user: user) } it "creates the user as staged with a regular key" do - xhr :post, :create, post_user_params.merge(staged: true, api_key: api_key.key) + post :create, + params: post_user_params.merge(staged: true, api_key: api_key.key), + format: :json new_user = User.where(username: post_user_params[:username]).first expect(new_user.staged?).to eq(true) @@ -647,7 +720,9 @@ describe UsersController do it "won't create the developer as staged" do UsernameCheckerService.expects(:is_developer?).returns(true) - xhr :post, :create, post_user_params.merge(staged: true, api_key: api_key.key) + post :create, + params: post_user_params.merge(staged: true, api_key: api_key.key), + format: :json new_user = User.where(username: post_user_params[:username]).first expect(new_user.staged?).to eq(false) @@ -734,17 +809,17 @@ describe UsersController do shared_examples 'honeypot fails' do it 'should not create a new user' do expect { - xhr :post, :create, create_params + post :create, params: create_params, format: :json }.to_not change { User.count } end it 'should not send an email' do User.any_instance.expects(:enqueue_welcome_message).never - xhr :post, :create, create_params + post :create, params: create_params, format: :json end it 'should say it was successful' do - xhr :post, :create, create_params + post :create, params: create_params, format: :json json = JSON::parse(response.body) expect(json["success"]).to eq(true) @@ -785,11 +860,11 @@ describe UsersController do shared_examples 'failed signup' do it 'should not create a new User' do - expect { xhr :post, :create, create_params }.to_not change { User.count } + expect { post :create, params: create_params, format: :json }.to_not change { User.count } end it 'should report failed' do - xhr :post, :create, create_params + post :create, params: create_params, format: :json json = JSON::parse(response.body) expect(json["success"]).not_to eq(true) @@ -855,7 +930,7 @@ describe UsersController do } } it "should succeed without the optional field" do - xhr :post, :create, create_params + post :create, params: create_params, format: :json expect(response).to be_success inserted = User.find_by_email(@user.email) expect(inserted).to be_present @@ -867,7 +942,7 @@ describe UsersController do it "should succeed with the optional field" do create_params[:user_fields][optional_field.id.to_s] = 'value3' - xhr :post, :create, create_params.merge(create_params) + post :create, params: create_params.merge(create_params), format: :json expect(response).to be_success inserted = User.find_by_email(@user.email) expect(inserted).to be_present @@ -879,7 +954,7 @@ describe UsersController do it "trims excessively long fields" do create_params[:user_fields][optional_field.id.to_s] = ('x' * 3000) - xhr :post, :create, create_params.merge(create_params) + post :create, params: create_params.merge(create_params), format: :json expect(response).to be_success inserted = User.find_by_email(@user.email) @@ -901,7 +976,7 @@ describe UsersController do } } it "should succeed" do - xhr :post, :create, create_params + post :create, params: create_params, format: :json expect(response).to be_success inserted = User.find_by_email(@user.email) expect(inserted).to be_present @@ -915,7 +990,10 @@ describe UsersController do let!(:staged) { Fabricate(:staged, email: "staged@account.com") } it "succeeds" do - xhr :post, :create, email: staged.email, username: "zogstrip", password: "P4ssw0rd$$" + post :create, params: { + email: staged.email, username: "zogstrip", password: "P4ssw0rd$$" + }, format: :json + result = ::JSON.parse(response.body) expect(result["success"]).to eq(true) expect(User.find_by_email(staged.email).staged).to eq(false) @@ -926,7 +1004,9 @@ describe UsersController do context '#username' do it 'raises an error when not logged in' do - expect { xhr :put, :username, username: 'somename' }.to raise_error(Discourse::NotLoggedIn) + expect do + put :username, params: { username: 'somename' }, format: :json + end.to raise_error(Discourse::NotLoggedIn) end context 'while logged in' do @@ -940,19 +1020,28 @@ describe UsersController do end it 'raises an error without a new_username param' do - expect { xhr :put, :username, username: user.username }.to raise_error(ActionController::ParameterMissing) + expect do + put :username, params: { username: user.username }, format: :json + end.to raise_error(ActionController::ParameterMissing) + expect(user.reload.username).to eq(old_username) end it 'raises an error when you don\'t have permission to change the username' do Guardian.any_instance.expects(:can_edit_username?).with(user).returns(false) - xhr :put, :username, username: user.username, new_username: new_username + + put :username, params: { + username: user.username, new_username: new_username + }, format: :json + expect(response).to be_forbidden expect(user.reload.username).to eq(old_username) end it 'raises an error when change_username fails' do - xhr :put, :username, username: user.username, new_username: '@' + put :username, + params: { username: user.username, new_username: '@' }, + format: :json expect(response).to_not be_success @@ -966,7 +1055,10 @@ describe UsersController do end it 'should succeed in normal circumstances' do - xhr :put, :username, username: user.username, new_username: new_username + put :username, + params: { username: user.username, new_username: new_username }, + format: :json + expect(response).to be_success expect(user.reload.username).to eq(new_username) end @@ -979,7 +1071,9 @@ describe UsersController do raw: 'This is a test this is a test' ).create - xhr :put, :username, username: user.username, new_username: new_username + put :username, params: { + username: user.username, new_username: new_username + }, format: :json expect(response).to be_forbidden expect(user.reload.username).to eq(old_username) @@ -988,14 +1082,21 @@ describe UsersController do it 'should create a staff action log when a staff member changes the username' do acting_user = Fabricate(:admin) log_in_user(acting_user) - xhr :put, :username, username: user.username, new_username: new_username + + put :username, params: { + username: user.username, new_username: new_username + }, format: :json + expect(response).to be_success expect(UserHistory.where(action: UserHistory.actions[:change_username], target_user_id: user.id, acting_user_id: acting_user.id)).to be_present expect(user.reload.username).to eq(new_username) end it 'should return a JSON response with the updated username' do - xhr :put, :username, username: user.username, new_username: new_username + put :username, params: { + username: user.username, new_username: new_username + }, format: :json + expect(::JSON.parse(response.body)['username']).to eq(new_username) end @@ -1004,7 +1105,9 @@ describe UsersController do context '.check_username' do it 'raises an error without any parameters' do - expect { xhr :get, :check_username }.to raise_error(ActionController::ParameterMissing) + expect do + get :check_username, format: :json + end.to raise_error(ActionController::ParameterMissing) end shared_examples 'when username is unavailable' do @@ -1032,13 +1135,13 @@ describe UsersController do end it 'returns nothing when given an email param but no username' do - xhr :get, :check_username, email: 'dood@example.com' + get :check_username, params: { email: 'dood@example.com' }, format: :json expect(response).to be_success end context 'username is available' do before do - xhr :get, :check_username, username: 'BruceWayne' + get :check_username, params: { username: 'BruceWayne' }, format: :json end include_examples 'when username is available' end @@ -1046,7 +1149,7 @@ describe UsersController do context 'username is unavailable' do let!(:user) { Fabricate(:user) } before do - xhr :get, :check_username, username: user.username + get :check_username, params: { username: user.username }, format: :json end include_examples 'when username is unavailable' end @@ -1067,7 +1170,9 @@ describe UsersController do context 'has invalid characters' do before do - xhr :get, :check_username, username: 'bad username' + get :check_username, params: { + username: 'bad username' + }, format: :json end include_examples 'checking an invalid username' @@ -1078,7 +1183,9 @@ describe UsersController do context 'is too long' do before do - xhr :get, :check_username, username: generate_username(User.username_length.last + 1) + get :check_username, params: { + username: generate_username(User.username_length.last + 1) + }, format: :json end include_examples 'checking an invalid username' @@ -1092,7 +1199,10 @@ describe UsersController do let!(:user) { Fabricate(:user, username: 'hansolo') } before do log_in_user(user) - xhr :get, :check_username, username: 'HanSolo' + + get :check_username, params: { + username: 'HanSolo' + }, format: :json end include_examples 'when username is available' end @@ -1101,7 +1211,10 @@ describe UsersController do let!(:user) { Fabricate(:user, username: 'hansolo') } before do log_in - xhr :get, :check_username, username: 'HanSolo' + + get :check_username, params: { + username: 'HanSolo' + }, format: :json end include_examples 'when username is unavailable' end @@ -1110,7 +1223,10 @@ describe UsersController do let!(:user) { Fabricate(:user, username: 'hansolo') } before do log_in_user(Fabricate(:admin)) - xhr :get, :check_username, username: 'HanSolo', for_user_id: user.id + + get :check_username, params: { + username: 'HanSolo', for_user_id: user.id + }, format: :json end include_examples 'when username is available' end @@ -1120,8 +1236,7 @@ describe UsersController do describe '#invited' do it 'returns success' do user = Fabricate(:user) - - xhr :get, :invited, username: user.username + get :invited, params: { username: user.username }, format: :json expect(response).to be_success end @@ -1142,7 +1257,9 @@ describe UsersController do user: invitee ) - xhr :get, :invited, username: inviter.username, search: 'billybob' + get :invited, params: { + username: inviter.username, search: 'billybob' + }, format: :json invites = JSON.parse(response.body)['invites'] expect(invites.size).to eq(1) @@ -1164,7 +1281,9 @@ describe UsersController do user: Fabricate(:user, username: 'jimtom') ) - xhr :get, :invited, username: inviter.username, search: 'billybob' + get :invited, params: { + username: inviter.username, search: 'billybob' + }, format: :json invites = JSON.parse(response.body)['invites'] expect(invites.size).to eq(1) @@ -1177,7 +1296,9 @@ describe UsersController do inviter = Fabricate(:user) Fabricate(:invite, invited_by: inviter) - xhr :get, :invited, username: inviter.username, filter: 'pending' + get :invited, + params: { username: inviter.username, filter: 'pending' }, + format: :json invites = JSON.parse(response.body)['invites'] expect(invites).to be_empty @@ -1190,7 +1311,9 @@ describe UsersController do invitee = Fabricate(:user) invite = Fabricate(:invite, invited_by: inviter, user: invitee) - xhr :get, :invited, username: inviter.username + get :invited, + params: { username: inviter.username }, + format: :json invites = JSON.parse(response.body)['invites'] expect(invites.size).to eq(1) @@ -1211,7 +1334,9 @@ describe UsersController do with(inviter).returns(true) end - xhr :get, :invited, username: inviter.username, filter: 'pending' + get :invited, params: { + username: inviter.username, filter: 'pending' + }, format: :json invites = JSON.parse(response.body)['invites'] expect(invites.size).to eq(1) @@ -1230,7 +1355,9 @@ describe UsersController do with(inviter).returns(false) end - xhr :get, :invited, username: inviter.username, filter: 'pending' + get :invited, params: { + username: inviter.username, filter: 'pending' + }, format: :json json = JSON.parse(response.body)['invites'] expect(json).to be_empty @@ -1245,7 +1372,7 @@ describe UsersController do invitee = Fabricate(:user) invite = Fabricate(:invite, invited_by: inviter, user: invitee) - xhr :get, :invited, username: inviter.username + get :invited, params: { username: inviter.username }, format: :json invites = JSON.parse(response.body)['invites'] expect(invites.size).to eq(1) @@ -1259,7 +1386,7 @@ describe UsersController do context 'with guest' do it 'raises an error' do expect do - xhr :put, :update, username: 'guest' + put :update, params: { username: 'guest' }, format: :json end.to raise_error(Discourse::NotLoggedIn) end end @@ -1271,7 +1398,12 @@ describe UsersController do let!(:user_field) { Fabricate(:user_field, editable: false) } it "allows staff to edit the field" do - put :update, username: user.username, name: 'Jim Tom', user_fields: { user_field.id.to_s => 'happy' } + put :update, params: { + username: user.username, + name: 'Jim Tom', + user_fields: { user_field.id.to_s => 'happy' } + }, format: :json + expect(response).to be_success expect(user.user_fields[user_field.id.to_s]).to eq('happy') end @@ -1288,11 +1420,12 @@ describe UsersController do user2 = Fabricate(:user) user3 = Fabricate(:user) - put :update, - username: user.username, - name: 'Jim Tom', - custom_fields: { test: :it }, - muted_usernames: "#{user2.username},#{user3.username}" + put :update, params: { + username: user.username, + name: 'Jim Tom', + custom_fields: { test: :it }, + muted_usernames: "#{user2.username},#{user3.username}" + }, format: :json expect(response).to be_success @@ -1304,10 +1437,11 @@ describe UsersController do theme = Theme.create(name: "test", user_selectable: true, user_id: -1) - put :update, - username: user.username, - muted_usernames: "", - theme_key: theme.key + put :update, params: { + username: user.username, + muted_usernames: "", + theme_key: theme.key + }, format: :json user.reload @@ -1320,9 +1454,10 @@ describe UsersController do it "updates the user's locale" do I18n.stubs(:locale).returns('fr') - put :update, - username: user.username, - locale: :fa_IR + put :update, params: { + username: user.username, + locale: :fa_IR + }, format: :json expect(User.find_by(username: user.username).locale).to eq('fa_IR') end @@ -1335,19 +1470,28 @@ describe UsersController do let!(:optional_field) { Fabricate(:user_field, required: false) } it "should update the user field" do - put :update, username: user.username, name: 'Jim Tom', user_fields: { user_field.id.to_s => 'happy' } + put :update, params: { + username: user.username, name: 'Jim Tom', user_fields: { user_field.id.to_s => 'happy' } + }, format: :json + expect(response).to be_success expect(user.user_fields[user_field.id.to_s]).to eq 'happy' end it "cannot be updated to blank" do - put :update, username: user.username, name: 'Jim Tom', user_fields: { user_field.id.to_s => '' } + put :update, params: { + username: user.username, name: 'Jim Tom', user_fields: { user_field.id.to_s => '' } + }, format: :json + expect(response).not_to be_success expect(user.user_fields[user_field.id.to_s]).not_to eq('happy') end it "trims excessively large fields" do - put :update, username: user.username, name: 'Jim Tom', user_fields: { user_field.id.to_s => ('x' * 3000) } + put :update, params: { + username: user.username, name: 'Jim Tom', user_fields: { user_field.id.to_s => ('x' * 3000) } + }, format: :json + expect(user.user_fields[user_field.id.to_s].size).to eq(UserField.max_length) end end @@ -1356,7 +1500,10 @@ describe UsersController do let!(:user_field) { Fabricate(:user_field, editable: false) } it "does not update the user field" do - put :update, username: user.username, name: 'Jim Tom', user_fields: { user_field.id.to_s => 'happy' } + put :update, params: { + username: user.username, name: 'Jim Tom', user_fields: { user_field.id.to_s => 'happy' } + }, format: :json + expect(response).to be_success expect(user.user_fields[user_field.id.to_s]).to be_blank end @@ -1365,7 +1512,7 @@ describe UsersController do end it 'returns user JSON' do - put :update, username: user.username + put :update, params: { username: user.username }, format: :json json = JSON.parse(response.body) expect(json['user']['id']).to eq user.id @@ -1379,7 +1526,9 @@ describe UsersController do log_in_user(user) Guardian.any_instance.expects(:can_edit?).with(user).returns(false) - put :update, username: user.username, name: 'Jim Tom' + put :update, + params: { username: user.username, name: 'Jim Tom' }, + format: :json expect(response).to be_forbidden expect(user.reload.name).not_to eq 'Jim Tom' @@ -1395,15 +1544,24 @@ describe UsersController do it "sets the user's card image to the badge" do log_in_user user - xhr :put, :update_card_badge, user_badge_id: user_badge.id, username: user.username + put :update_card_badge, params: { + user_badge_id: user_badge.id, username: user.username + }, format: :json + expect(user.user_profile.reload.card_image_badge_id).to be_blank badge.update_attributes image: "wat.com/wat.jpg" - xhr :put, :update_card_badge, user_badge_id: user_badge.id, username: user.username + put :update_card_badge, params: { + user_badge_id: user_badge.id, username: user.username + }, format: :json + expect(user.user_profile.reload.card_image_badge_id).to eq(badge.id) # Can set to nothing - xhr :put, :update_card_badge, username: user.username + put :update_card_badge, params: { + username: user.username + }, format: :json + expect(user.user_profile.reload.card_image_badge_id).to be_blank end end @@ -1415,10 +1573,18 @@ describe UsersController do it "sets the user's title to the badge name if it is titleable" do log_in_user user - xhr :put, :badge_title, user_badge_id: user_badge.id, username: user.username + + put :badge_title, params: { + user_badge_id: user_badge.id, username: user.username + }, format: :json + expect(user.reload.title).not_to eq(badge.name) badge.update_attributes allow_title: true - xhr :put, :badge_title, user_badge_id: user_badge.id, username: user.username + + put :badge_title, params: { + user_badge_id: user_badge.id, username: user.username + }, format: :json + expect(user.reload.title).to eq(badge.name) expect(user.user_profile.badge_granted_title).to eq(true) @@ -1441,21 +1607,24 @@ describe UsersController do end it "searches when provided the term only" do - xhr :post, :search_users, term: user.name.split(" ").last + post :search_users, params: { term: user.name.split(" ").last }, format: :json expect(response).to be_success json = JSON.parse(response.body) expect(json["users"].map { |u| u["username"] }).to include(user.username) end it "searches when provided the topic only" do - xhr :post, :search_users, topic_id: topic.id + post :search_users, params: { topic_id: topic.id }, format: :json expect(response).to be_success json = JSON.parse(response.body) expect(json["users"].map { |u| u["username"] }).to include(user.username) end it "searches when provided the term and topic" do - xhr :post, :search_users, term: user.name.split(" ").last, topic_id: topic.id + post :search_users, params: { + term: user.name.split(" ").last, topic_id: topic.id + }, format: :json + expect(response).to be_success json = JSON.parse(response.body) expect(json["users"].map { |u| u["username"] }).to include(user.username) @@ -1473,7 +1642,10 @@ describe UsersController do private_topic = Fabricate(:topic, category: category) - xhr :post, :search_users, term: user.name.split(" ").last, topic_id: private_topic.id, topic_allowed_users: "true" + post :search_users, params: { + term: user.name.split(" ").last, topic_id: private_topic.id, topic_allowed_users: "true" + }, format: :json + expect(response).to be_success json = JSON.parse(response.body) expect(json["users"].map { |u| u["username"] }).to_not include(user.username) @@ -1486,7 +1658,7 @@ describe UsersController do end it "returns names" do - xhr :post, :search_users, term: user.name + post :search_users, params: { term: user.name }, format: :json json = JSON.parse(response.body) expect(json["users"].map { |u| u["name"] }).to include(user.name) end @@ -1498,7 +1670,7 @@ describe UsersController do end it "returns names" do - xhr :post, :search_users, term: user.name + post :search_users, params: { term: user.name }, format: :json json = JSON.parse(response.body) expect(json["users"].map { |u| u["name"] }).not_to include(user.name) end @@ -1516,7 +1688,10 @@ describe UsersController do email_token = active_user.email_tokens.create(email: active_user.email).token EmailToken.confirm(email_token) session[SessionController::ACTIVATE_USER_KEY] = active_user.id - xhr :post, :send_activation_email, username: active_user.username + + post :send_activation_email, params: { + username: active_user.username + }, format: :json expect(response.status).to eq(409) @@ -1534,7 +1709,10 @@ describe UsersController do unconfirmed_email_user.email_tokens.create(email: unconfirmed_email_user.email) session[SessionController::ACTIVATE_USER_KEY] = unconfirmed_email_user.id Jobs.expects(:enqueue).with(:critical_user_email, has_entries(type: :signup, to_address: unconfirmed_email_user.email)) - xhr :post, :send_activation_email, username: unconfirmed_email_user.username + + post :send_activation_email, params: { + username: unconfirmed_email_user.username + }, format: :json expect(response.status).to eq(200) @@ -1551,7 +1729,10 @@ describe UsersController do unconfirmed_email_user = Fabricate(:user, active: true) unconfirmed_email_user.email_tokens.create(email: unconfirmed_email_user.email) session[SessionController::ACTIVATE_USER_KEY] = unconfirmed_email_user.id - xhr :post, :send_activation_email, username: unconfirmed_email_user.username + post :send_activation_email, params: { + username: unconfirmed_email_user.username + }, format: :json + expect(response.status).to eq(403) end end @@ -1559,14 +1740,21 @@ describe UsersController do describe 'when user does not have a valid session' do it 'should not be valid' do user = Fabricate(:user) - xhr :post, :send_activation_email, username: user.username + post :send_activation_email, params: { + username: user.username + }, format: :json + expect(response.status).to eq(403) end it 'should allow staff regardless' do log_in :admin user = Fabricate(:user, active: false) - xhr :post, :send_activation_email, username: user.username + + post :send_activation_email, params: { + username: user.username + }, format: :json + expect(response.status).to eq(200) end end @@ -1575,7 +1763,10 @@ describe UsersController do it 'should send the activation email' do session[SessionController::ACTIVATE_USER_KEY] = user.id Jobs.expects(:enqueue).with(:critical_user_email, has_entries(type: :signup)) - xhr :post, :send_activation_email, username: user.username + + post :send_activation_email, params: { + username: user.username + }, format: :json expect(session[SessionController::ACTIVATE_USER_KEY]).to eq(nil) end @@ -1590,14 +1781,20 @@ describe UsersController do it 'should generate a new token' do expect { session[SessionController::ACTIVATE_USER_KEY] = user.id - xhr :post, :send_activation_email, username: user.username - }.to change { user.email_tokens(true).count }.by(1) + + post :send_activation_email, + params: { username: user.username }, + format: :json + }.to change { user.reload.email_tokens.count }.by(1) end it 'should send an email' do session[SessionController::ACTIVATE_USER_KEY] = user.id Jobs.expects(:enqueue).with(:critical_user_email, has_entries(type: :signup)) - xhr :post, :send_activation_email, username: user.username + + post :send_activation_email, + params: { username: user.username }, + format: :json expect(session[SessionController::ACTIVATE_USER_KEY]).to eq(nil) end @@ -1607,7 +1804,10 @@ describe UsersController do context 'when username does not exist' do it 'should not send an email' do Jobs.expects(:enqueue).never - xhr :post, :send_activation_email, username: 'nopenopenopenope' + + post :send_activation_email, + params: { username: 'nopenopenopenope' }, + format: :json end end end @@ -1616,7 +1816,9 @@ describe UsersController do it 'raises an error when not logged in' do expect { - xhr :put, :pick_avatar, username: 'asdf', avatar_id: 1, type: "custom" + put :pick_avatar, params: { + username: 'asdf', avatar_id: 1, type: "custom" + }, format: :json }.to raise_error(Discourse::NotLoggedIn) end @@ -1627,37 +1829,55 @@ describe UsersController do it "raises an error when you don't have permission to toggle the avatar" do another_user = Fabricate(:user) - xhr :put, :pick_avatar, username: another_user.username, upload_id: upload.id, type: "custom" + put :pick_avatar, params: { + username: another_user.username, upload_id: upload.id, type: "custom" + }, format: :json + expect(response).to be_forbidden end it "raises an error when sso_overrides_avatar is disabled" do SiteSetting.sso_overrides_avatar = true - xhr :put, :pick_avatar, username: user.username, upload_id: upload.id, type: "custom" + put :pick_avatar, params: { + username: user.username, upload_id: upload.id, type: "custom" + }, format: :json + expect(response).to_not be_success end it "raises an error when selecting the custom/uploaded avatar and allow_uploaded_avatars is disabled" do SiteSetting.allow_uploaded_avatars = false - xhr :put, :pick_avatar, username: user.username, upload_id: upload.id, type: "custom" + put :pick_avatar, params: { + username: user.username, upload_id: upload.id, type: "custom" + }, format: :json + expect(response).to_not be_success end it 'can successfully pick the system avatar' do - xhr :put, :pick_avatar, username: user.username + put :pick_avatar, params: { + username: user.username + }, format: :json + expect(response).to be_success expect(user.reload.uploaded_avatar_id).to eq(nil) end it 'can successfully pick a gravatar' do - xhr :put, :pick_avatar, username: user.username, upload_id: upload.id, type: "gravatar" + put :pick_avatar, params: { + username: user.username, upload_id: upload.id, type: "gravatar" + }, format: :json + expect(response).to be_success expect(user.reload.uploaded_avatar_id).to eq(upload.id) expect(user.user_avatar.reload.gravatar_upload_id).to eq(upload.id) end it 'can successfully pick a custom avatar' do - xhr :put, :pick_avatar, username: user.username, upload_id: upload.id, type: "custom" + put :pick_avatar, params: { + username: user.username, upload_id: upload.id, type: "custom" + }, format: :json + expect(response).to be_success expect(user.reload.uploaded_avatar_id).to eq(upload.id) expect(user.user_avatar.reload.custom_upload_id).to eq(upload.id) @@ -1670,7 +1890,11 @@ describe UsersController do describe '.destroy_user_image' do it 'raises an error when not logged in' do - expect { xhr :delete, :destroy_user_image, type: 'profile_background', username: 'asdf' }.to raise_error(Discourse::NotLoggedIn) + expect do + delete :destroy_user_image, + params: { type: 'profile_background', username: 'asdf' }, + format: :json + end.to raise_error(Discourse::NotLoggedIn) end context 'while logged in' do @@ -1679,20 +1903,33 @@ describe UsersController do it 'raises an error when you don\'t have permission to clear the profile background' do Guardian.any_instance.expects(:can_edit?).with(user).returns(false) - xhr :delete, :destroy_user_image, username: user.username, type: 'profile_background' + + delete :destroy_user_image, + params: { username: user.username, type: 'profile_background' }, + format: :json + expect(response).to be_forbidden end it "requires the `type` param" do - expect { xhr :delete, :destroy_user_image, username: user.username }.to raise_error(ActionController::ParameterMissing) + expect do + delete :destroy_user_image, params: { username: user.username }, format: :json + end.to raise_error(ActionController::ParameterMissing) end it "only allows certain `types`" do - expect { xhr :delete, :destroy_user_image, username: user.username, type: 'wat' }.to raise_error(Discourse::InvalidParameters) + expect do + delete :destroy_user_image, + params: { username: user.username, type: 'wat' }, + format: :json + end.to raise_error(Discourse::InvalidParameters) end it 'can clear the profile background' do - xhr :delete, :destroy_user_image, type: 'profile_background', username: user.username + delete :destroy_user_image, params: { + type: 'profile_background', username: user.username + }, format: :json + expect(user.reload.user_profile.profile_background).to eq("") expect(response).to be_success end @@ -1702,7 +1939,9 @@ describe UsersController do describe '.destroy' do it 'raises an error when not logged in' do - expect { xhr :delete, :destroy, username: 'nobody' }.to raise_error(Discourse::NotLoggedIn) + expect do + delete :destroy, params: { username: 'nobody' }, format: :json + end.to raise_error(Discourse::NotLoggedIn) end context 'while logged in' do @@ -1711,20 +1950,20 @@ describe UsersController do it 'raises an error when you cannot delete your account' do Guardian.any_instance.stubs(:can_delete_user?).returns(false) UserDestroyer.any_instance.expects(:destroy).never - xhr :delete, :destroy, username: user.username + delete :destroy, params: { username: user.username }, format: :json expect(response).to be_forbidden end it "raises an error when you try to delete someone else's account" do UserDestroyer.any_instance.expects(:destroy).never - xhr :delete, :destroy, username: Fabricate(:user).username + delete :destroy, params: { username: Fabricate(:user).username }, format: :json expect(response).to be_forbidden end it "deletes your account when you're allowed to" do Guardian.any_instance.stubs(:can_delete_user?).returns(true) UserDestroyer.any_instance.expects(:destroy).with(user, anything).returns(user) - xhr :delete, :destroy, username: user.username + delete :destroy, params: { username: user.username }, format: :json expect(response).to be_success end end @@ -1733,7 +1972,7 @@ describe UsersController do describe '.my_redirect' do it "redirects if the user is not logged in" do - get :my_redirect, path: "wat" + get :my_redirect, params: { path: "wat" }, format: :json expect(response).not_to be_success expect(response).to be_redirect end @@ -1742,17 +1981,17 @@ describe UsersController do let!(:user) { log_in } it "will not redirect to an invalid path" do - get :my_redirect, path: "wat/..password.txt" + get :my_redirect, params: { path: "wat/..password.txt" }, format: :json expect(response).not_to be_redirect end it "will redirect to an valid path" do - get :my_redirect, path: "preferences" + get :my_redirect, params: { path: "preferences" }, format: :json expect(response).to be_redirect end it "permits forward slashes" do - get :my_redirect, path: "activity/posts" + get :my_redirect, params: { path: "activity/posts" }, format: :json expect(response).to be_redirect end end @@ -1761,7 +2000,9 @@ describe UsersController do describe '.check_emails' do it 'raises an error when not logged in' do - expect { xhr :put, :check_emails, username: 'zogstrip' }.to raise_error(Discourse::NotLoggedIn) + expect do + put :check_emails, params: { username: 'zogstrip' }, format: :json + end.to raise_error(Discourse::NotLoggedIn) end context 'while logged in' do @@ -1769,13 +2010,21 @@ describe UsersController do it "raises an error when you aren't allowed to check emails" do Guardian.any_instance.expects(:can_check_emails?).returns(false) - xhr :put, :check_emails, username: Fabricate(:user).username + + put :check_emails, + params: { username: Fabricate(:user).username }, + format: :json + expect(response).to be_forbidden end it "returns both email and associated_accounts when you're allowed to see them" do Guardian.any_instance.expects(:can_check_emails?).returns(true) - xhr :put, :check_emails, username: Fabricate(:user).username + + put :check_emails, + params: { username: Fabricate(:user).username }, + format: :json + expect(response).to be_success json = JSON.parse(response.body) expect(json["email"]).to be_present @@ -1785,7 +2034,11 @@ describe UsersController do it "works on inactive users" do inactive_user = Fabricate(:user, active: false) Guardian.any_instance.expects(:can_check_emails?).returns(true) - xhr :put, :check_emails, username: inactive_user.username + + put :check_emails, params: { + username: inactive_user.username + }, format: :json + expect(response).to be_success json = JSON.parse(response.body) expect(json["email"]).to be_present @@ -1805,21 +2058,30 @@ describe UsersController do let(:private_topic) { Fabricate(:private_message_topic, user: allowed_user) } it "finds the user" do - xhr :get, :is_local_username, username: user.username + get :is_local_username, params: { + username: user.username + }, format: :json + expect(response).to be_success json = JSON.parse(response.body) expect(json["valid"][0]).to eq(user.username) end it "finds the group" do - xhr :get, :is_local_username, username: group.name + get :is_local_username, params: { + username: group.name + }, format: :json + expect(response).to be_success json = JSON.parse(response.body) expect(json["valid_groups"][0]).to eq(group.name) end it "supports multiples usernames" do - xhr :get, :is_local_username, usernames: [user.username, "system"] + get :is_local_username, params: { + usernames: [user.username, "system"] + }, format: :json + expect(response).to be_success json = JSON.parse(response.body) expect(json["valid"].size).to eq(2) @@ -1827,7 +2089,11 @@ describe UsersController do it "never includes staged accounts" do staged = Fabricate(:user, staged: true) - xhr :get, :is_local_username, usernames: [staged.username] + + get :is_local_username, params: { + usernames: [staged.username] + }, format: :json + expect(response).to be_success json = JSON.parse(response.body) expect(json["valid"].size).to eq(0) @@ -1835,7 +2101,11 @@ describe UsersController do it "returns user who cannot see topic" do Guardian.any_instance.expects(:can_see?).with(topic).returns(false) - xhr :get, :is_local_username, usernames: [user.username], topic_id: topic.id + + get :is_local_username, params: { + usernames: [user.username], topic_id: topic.id + }, format: :json + expect(response).to be_success json = JSON.parse(response.body) expect(json["cannot_see"].size).to eq(1) @@ -1843,7 +2113,11 @@ describe UsersController do it "never returns a user who can see the topic" do Guardian.any_instance.expects(:can_see?).with(topic).returns(true) - xhr :get, :is_local_username, usernames: [user.username], topic_id: topic.id + + get :is_local_username, params: { + usernames: [user.username], topic_id: topic.id + }, format: :json + expect(response).to be_success json = JSON.parse(response.body) expect(json["cannot_see"].size).to eq(0) @@ -1851,7 +2125,11 @@ describe UsersController do it "returns user who cannot see a private topic" do Guardian.any_instance.expects(:can_see?).with(private_topic).returns(false) - xhr :get, :is_local_username, usernames: [user.username], topic_id: private_topic.id + + get :is_local_username, params: { + usernames: [user.username], topic_id: private_topic.id + }, format: :json + expect(response).to be_success json = JSON.parse(response.body) expect(json["cannot_see"].size).to eq(1) @@ -1859,7 +2137,11 @@ describe UsersController do it "never returns a user who can see the topic" do Guardian.any_instance.expects(:can_see?).with(private_topic).returns(true) - xhr :get, :is_local_username, usernames: [allowed_user.username], topic_id: private_topic.id + + get :is_local_username, params: { + usernames: [allowed_user.username], topic_id: private_topic.id + }, format: :json + expect(response).to be_success json = JSON.parse(response.body) expect(json["cannot_see"].size).to eq(0) @@ -1873,7 +2155,7 @@ describe UsersController do context 'anon' do it "raises an error on anon for topic_tracking_state" do expect { - xhr :get, :topic_tracking_state, username: user.username, format: :json + get :topic_tracking_state, params: { username: user.username }, format: :json }.to raise_error(Discourse::NotLoggedIn) end end @@ -1883,7 +2165,7 @@ describe UsersController do log_in_user(user) topic = Fabricate(:topic) - xhr :get, :topic_tracking_state, username: user.username, format: :json + get :topic_tracking_state, params: { username: user.username }, format: :json states = JSON.parse(response.body) @@ -1898,7 +2180,7 @@ describe UsersController do user = Fabricate(:user) create_post(user: user) - xhr :get, :summary, username: user.username_lower + get :summary, params: { username: user.username_lower }, format: :json expect(response).to be_success json = JSON.parse(response.body) @@ -1910,12 +2192,12 @@ describe UsersController do describe ".confirm_admin" do it "fails without a valid token" do expect { - get :confirm_admin, token: 'invalid-token' + get :confirm_admin, params: { token: 'invalid-token' }, format: :json }.to raise_error(ActionController::UrlGenerationError) end it "fails with a missing token" do - get :confirm_admin, token: 'a0a0a0a0a0' + get :confirm_admin, params: { token: 'a0a0a0a0a0' }, format: :json expect(response).to_not be_success end @@ -1923,7 +2205,7 @@ describe UsersController do user = Fabricate(:user) ac = AdminConfirmation.new(user, Fabricate(:admin)) ac.create_confirmation - get :confirm_admin, token: ac.token + get :confirm_admin, params: { token: ac.token } expect(response).to be_success user.reload @@ -1936,7 +2218,7 @@ describe UsersController do ac = AdminConfirmation.new(user, admin) ac.create_confirmation - get :confirm_admin, token: ac.token + get :confirm_admin, params: { token: ac.token } expect(response).to be_success user.reload @@ -1949,7 +2231,7 @@ describe UsersController do ac = AdminConfirmation.new(user, Fabricate(:admin)) ac.create_confirmation - get :confirm_admin, token: ac.token + get :confirm_admin, params: { token: ac.token }, format: :json expect(response).to_not be_success user.reload @@ -1961,7 +2243,7 @@ describe UsersController do user = Fabricate(:user) ac = AdminConfirmation.new(user, Fabricate(:admin)) ac.create_confirmation - post :confirm_admin, token: ac.token + post :confirm_admin, params: { token: ac.token } expect(response).to be_success user.reload @@ -1977,21 +2259,33 @@ describe UsersController do it "raises an error with an invalid session value" do session[SessionController::ACTIVATE_USER_KEY] = 1234 - xhr :put, :update_activation_email, email: 'updatedemail@example.com' + + put :update_activation_email, params: { + email: 'updatedemail@example.com' + }, format: :json + expect(response).to_not be_success end it "raises an error for an active user" do user = Fabricate(:walter_white) session[SessionController::ACTIVATE_USER_KEY] = user.id - xhr :put, :update_activation_email, email: 'updatedemail@example.com' + + put :update_activation_email, params: { + email: 'updatedemail@example.com' + }, format: :json + expect(response).to_not be_success end it "raises an error when logged in" do moderator = log_in(:moderator) session[SessionController::ACTIVATE_USER_KEY] = moderator.id - xhr :put, :update_activation_email, email: 'updatedemail@example.com' + + put :update_activation_email, params: { + email: 'updatedemail@example.com' + }, format: :json + expect(response).to_not be_success end @@ -1999,7 +2293,11 @@ describe UsersController do active_user = Fabricate(:user) user = Fabricate(:inactive_user) session[SessionController::ACTIVATE_USER_KEY] = user.id - xhr :put, :update_activation_email, email: active_user.email + + put :update_activation_email, params: { + email: active_user.email + }, format: :json + expect(response).to_not be_success end @@ -2007,7 +2305,7 @@ describe UsersController do user = Fabricate(:inactive_user) SiteSetting.email_domains_blacklist = 'example.com' session[SessionController::ACTIVATE_USER_KEY] = user.id - xhr :put, :update_activation_email, email: 'test@example.com' + put :update_activation_email, params: { email: 'test@example.com' }, format: :json expect(response).to_not be_success end @@ -2016,7 +2314,10 @@ describe UsersController do token = user.email_tokens.first session[SessionController::ACTIVATE_USER_KEY] = user.id - xhr :put, :update_activation_email, email: 'updatedemail@example.com' + + put :update_activation_email, params: { + email: 'updatedemail@example.com' + }, format: :json expect(response).to be_success @@ -2031,41 +2332,55 @@ describe UsersController do context "with a username and password" do it "raises an error with an invalid username" do - xhr :put, :update_activation_email, username: 'eviltrout', - password: 'invalid-password', - email: 'updatedemail@example.com' + put :update_activation_email, params: { + username: 'eviltrout', + password: 'invalid-password', + email: 'updatedemail@example.com' + }, format: :json + expect(response).to_not be_success end it "raises an error with an invalid password" do - xhr :put, :update_activation_email, username: Fabricate(:inactive_user).username, - password: 'invalid-password', - email: 'updatedemail@example.com' + put :update_activation_email, params: { + username: Fabricate(:inactive_user).username, + password: 'invalid-password', + email: 'updatedemail@example.com' + }, format: :json + expect(response).to_not be_success end it "raises an error for an active user" do - xhr :put, :update_activation_email, username: Fabricate(:walter_white).username, - password: 'letscook', - email: 'updatedemail@example.com' + put :update_activation_email, params: { + username: Fabricate(:walter_white).username, + password: 'letscook', + email: 'updatedemail@example.com' + }, format: :json + expect(response).to_not be_success end it "raises an error when logged in" do log_in(:moderator) - xhr :put, :update_activation_email, username: Fabricate(:inactive_user).username, - password: 'qwerqwer123', - email: 'updatedemail@example.com' + put :update_activation_email, params: { + username: Fabricate(:inactive_user).username, + password: 'qwerqwer123', + email: 'updatedemail@example.com' + }, format: :json + expect(response).to_not be_success end it "raises an error when the new email is taken" do user = Fabricate(:user) - xhr :put, :update_activation_email, username: Fabricate(:inactive_user).username, - password: 'qwerqwer123', - email: user.email + put :update_activation_email, params: { + username: Fabricate(:inactive_user).username, + password: 'qwerqwer123', + email: user.email + }, format: :json expect(response).to_not be_success end @@ -2074,10 +2389,11 @@ describe UsersController do user = Fabricate(:inactive_user) token = user.email_tokens.first - xhr :put, :update_activation_email, + put :update_activation_email, params: { username: user.username, password: 'qwerqwer123', email: 'updatedemail@example.com' + }, format: :json expect(response).to be_success @@ -2089,53 +2405,5 @@ describe UsersController do expect(token.expired?).to eq(true) end end - end - - context "account_created" do - - it "returns a message when no session is present" do - get :account_created - created = assigns(:account_created) - expect(created).to be_present - expect(created[:message]).to eq(I18n.t('activation.missing_session')) - expect(created[:email]).to be_blank - expect(created[:username]).to be_blank - end - - it "redirects when the user is logged in" do - log_in(:user) - get :account_created - expect(response).to be_redirect - end - - context "when the user account is created" do - before do - session['user_created_message'] = "Donuts" - end - - it "returns the message when set in the session" do - get :account_created - created = assigns(:account_created) - expect(created).to be_present - expect(created[:message]).to eq('Donuts') - expect(created[:email]).to be_blank - expect(created[:username]).to be_blank - end - - it "includes user information when the session variable is present " do - user = Fabricate(:user, active: false) - session[SessionController::ACTIVATE_USER_KEY] = user.id - - get :account_created - created = assigns(:account_created) - expect(created).to be_present - expect(created[:message]).to eq('Donuts') - expect(created[:email]).to eq(user.email) - expect(created[:username]).to eq(user.username) - end - end - - end - end diff --git a/spec/controllers/webhooks_controller_spec.rb b/spec/controllers/webhooks_controller_spec.rb index 955f4c0a26d..b5b049ca8a4 100644 --- a/spec/controllers/webhooks_controller_spec.rb +++ b/spec/controllers/webhooks_controller_spec.rb @@ -16,11 +16,13 @@ describe WebhooksController do WebhooksController.any_instance.expects(:mailgun_verify).returns(true) - post :mailgun, "token" => "705a8ccd2ce932be8e98c221fe701c1b4a0afcb8bbd57726de", - "timestamp" => Time.now.to_i, - "event" => "dropped", - "recipient" => email, - "Message-Id" => "<12345@il.com>" + post :mailgun, params: { + "token" => "705a8ccd2ce932be8e98c221fe701c1b4a0afcb8bbd57726de", + "timestamp" => Time.now.to_i, + "event" => "dropped", + "recipient" => email, + "Message-Id" => "<12345@il.com>" + }, format: :json expect(response).to be_success @@ -37,14 +39,16 @@ describe WebhooksController do user = Fabricate(:user, email: email) email_log = Fabricate(:email_log, user: user, message_id: message_id, to_address: email) - post :sendgrid, "_json" => [ - { - "email" => email, - "smtp-id" => "<12345@il.com>", - "event" => "bounce", - "status" => "5.0.0" - } - ] + post :sendgrid, params: { + "_json" => [ + { + "email" => email, + "smtp-id" => "<12345@il.com>", + "event" => "bounce", + "status" => "5.0.0" + } + ] + }, format: :json expect(response).to be_success @@ -61,10 +65,12 @@ describe WebhooksController do user = Fabricate(:user, email: email) email_log = Fabricate(:email_log, user: user, message_id: message_id, to_address: email) - post :mailjet, "event" => "bounce", - "email" => email, - "hard_bounce" => true, - "CustomID" => message_id + post :mailjet, params: { + "event" => "bounce", + "email" => email, + "hard_bounce" => true, + "CustomID" => message_id + }, format: :json expect(response).to be_success @@ -81,15 +87,17 @@ describe WebhooksController do user = Fabricate(:user, email: email) email_log = Fabricate(:email_log, user: user, message_id: message_id, to_address: email) - post :mandrill, mandrill_events: [{ - "event" => "hard_bounce", - "msg" => { - "email" => email, - "metadata" => { - "message_id" => message_id + post :mandrill, params: { + mandrill_events: [{ + "event" => "hard_bounce", + "msg" => { + "email" => email, + "metadata" => { + "message_id" => message_id + } } - } - }] + }] + }, format: :json expect(response).to be_success @@ -106,17 +114,19 @@ describe WebhooksController do user = Fabricate(:user, email: email) email_log = Fabricate(:email_log, user: user, message_id: message_id, to_address: email) - post :sparkpost, "_json" => [{ - "msys" => { - "message_event" => { - "bounce_class" => 10, - "rcpt_to" => email, - "rcpt_meta" => { - "message_id" => message_id + post :sparkpost, params: { + "_json" => [{ + "msys" => { + "message_event" => { + "bounce_class" => 10, + "rcpt_to" => email, + "rcpt_meta" => { + "message_id" => message_id + } } } - } - }] + }] + }, format: :json expect(response).to be_success diff --git a/spec/controllers/wizard_controller_spec.rb b/spec/controllers/wizard_controller_spec.rb index 6621e34815c..a6d38fee2cd 100644 --- a/spec/controllers/wizard_controller_spec.rb +++ b/spec/controllers/wizard_controller_spec.rb @@ -10,31 +10,33 @@ describe WizardController do end it 'needs you to be logged in' do - expect { xhr :get, :index }.to raise_error(Discourse::NotLoggedIn) + expect do + get :index, format: :json + end.to raise_error(Discourse::NotLoggedIn) end it "raises an error if you aren't an admin" do log_in(:moderator) - xhr :get, :index + get :index, format: :json expect(response).to be_forbidden end it "raises an error if the wizard is disabled" do SiteSetting.wizard_enabled = false log_in(:admin) - xhr :get, :index + get :index, format: :json expect(response).to be_forbidden end it "renders the wizard if you are an admin" do log_in(:admin) - xhr :get, :index + get :index, format: :json expect(response).to be_success end it "returns JSON when the mime type is appropriate" do log_in(:admin) - xhr :get, :index, format: 'json' + get :index, format: 'json' expect(response).to be_success expect(::JSON.parse(response.body).has_key?('wizard')).to eq(true) end diff --git a/spec/integration/invite_only_registration_spec.rb b/spec/integration/invite_only_registration_spec.rb index 72575738df9..3151eebc1d3 100644 --- a/spec/integration/invite_only_registration_spec.rb +++ b/spec/integration/invite_only_registration_spec.rb @@ -12,25 +12,28 @@ describe 'invite only' do admin = Fabricate(:admin) api_key = Fabricate(:api_key, user: admin) - xhr :post, '/users', + post '/users.json', params: { name: 'bob', username: 'bob', password: 'strongpassword', email: 'bob@bob.com', api_key: api_key.key, api_username: admin.username + } user_id = JSON.parse(response.body)["user_id"] expect(user_id).to be > 0 # activate and approve - xhr :put, "/admin/users/#{user_id}/activate", - api_key: api_key.key, - api_username: admin.username + put "/admin/users/#{user_id}/activate.json", params: { + api_key: api_key.key, + api_username: admin.username + } - xhr :put, "/admin/users/#{user_id}/approve", - api_key: api_key.key, - api_username: admin.username + put "/admin/users/#{user_id}/approve.json", params: { + api_key: api_key.key, + api_username: admin.username + } u = User.find(user_id) expect(u.active).to eq(true) diff --git a/spec/integration/topic_auto_close_spec.rb b/spec/integration/topic_auto_close_spec.rb index ad4a091cd26..7dd24eef55d 100644 --- a/spec/integration/topic_auto_close_spec.rb +++ b/spec/integration/topic_auto_close_spec.rb @@ -5,10 +5,6 @@ require 'rails_helper' describe Topic do let(:job_klass) { Jobs::ToggleTopicClosed } - before do - job_klass.jobs.clear - end - context 'creating a topic without auto-close' do let(:topic) { Fabricate(:topic, category: category) } diff --git a/spec/jobs/jobs_spec.rb b/spec/jobs/jobs_spec.rb index 9f200eceb24..7ec26fd6049 100644 --- a/spec/jobs/jobs_spec.rb +++ b/spec/jobs/jobs_spec.rb @@ -82,7 +82,6 @@ describe Jobs do Sidekiq::Testing.disable! do scheduled_jobs = Sidekiq::ScheduledSet.new - scheduled_jobs.clear expect(scheduled_jobs.size).to eq(0) diff --git a/spec/models/category_spec.rb b/spec/models/category_spec.rb index 1090a6bb69b..e61de161b15 100644 --- a/spec/models/category_spec.rb +++ b/spec/models/category_spec.rb @@ -131,9 +131,9 @@ describe Category do group.add(user) category.set_permissions(group.id => :full) - category.save + category.save! category_2.set_permissions(group.id => :full) - category_2.save + category_2.save! expect(Category.secured).to match_array([uncategorized]) expect(Category.secured(Guardian.new(user))).to match_array([uncategorized, category, category_2]) diff --git a/spec/models/invite_spec.rb b/spec/models/invite_spec.rb index 13162f74f6e..b3abb0306b7 100644 --- a/spec/models/invite_spec.rb +++ b/spec/models/invite_spec.rb @@ -392,7 +392,7 @@ describe Invite do invites = Invite.find_pending_invites_from(inviter) - expect(invites.size).to eq(1) + expect(invites.length).to eq(1) expect(invites.first).to eq pending_invite end end @@ -416,7 +416,7 @@ describe Invite do invites = Invite.find_redeemed_invites_from(inviter) - expect(invites.size).to eq(1) + expect(invites.length).to eq(1) expect(invites.first).to eq redeemed_invite end end diff --git a/spec/models/notification_spec.rb b/spec/models/notification_spec.rb index b8ad1da108a..34af1be3431 100644 --- a/spec/models/notification_spec.rb +++ b/spec/models/notification_spec.rb @@ -127,7 +127,6 @@ describe Notification do end context 'destroy' do - let!(:notification) { Fabricate(:notification) } it 'updates the notification count on destroy' do diff --git a/spec/models/post_action_spec.rb b/spec/models/post_action_spec.rb index e4f74d5fad1..34514489b31 100644 --- a/spec/models/post_action_spec.rb +++ b/spec/models/post_action_spec.rb @@ -61,7 +61,7 @@ describe PostAction do topic = posts[0].topic # Moderators should be invited to the private topic, otherwise they're not permitted to see it - topic_user_ids = topic.topic_users(true).map { |x| x.user_id } + topic_user_ids = topic.reload.topic_users.map { |x| x.user_id } expect(topic_user_ids).to include(codinghorror.id) expect(topic_user_ids).to include(mod.id) diff --git a/spec/models/theme_field_spec.rb b/spec/models/theme_field_spec.rb index 00c88834d87..9952dfc2dd0 100644 --- a/spec/models/theme_field_spec.rb +++ b/spec/models/theme_field_spec.rb @@ -9,10 +9,11 @@ describe ThemeField do badJavaScript(; HTML + field = ThemeField.create!(theme_id: 1, target_id: 0, name: "header", value: html) expect(field.error).not_to eq(nil) - field.value = "" - field.save! + + field.update!(value: '') expect(field.error).to eq(nil) end diff --git a/spec/models/topic_link_spec.rb b/spec/models/topic_link_spec.rb index 64b5a694011..40fafa5a03c 100644 --- a/spec/models/topic_link_spec.rb +++ b/spec/models/topic_link_spec.rb @@ -131,7 +131,7 @@ http://b.com/#{'a' * 500} expect(topic.topic_links.first.url).to eq(url) linked_post.revise(post.user, raw: "no more linkies https://eviltrout.com") - expect(other_topic.topic_links.where(link_post_id: linked_post.id)).to be_blank + expect(other_topic.reload.topic_links.where(link_post_id: linked_post.id)).to be_blank end end @@ -323,7 +323,7 @@ http://b.com/#{'a' * 500} array = TopicLink.topic_map(Guardian.new, post.topic_id) expect(array.length).to eq(6) - expect(array[0]["clicks"]).to eq("1") + expect(array[0]["clicks"]).to eq(1) end it 'secures internal links correctly' do diff --git a/spec/models/topic_timer_spec.rb b/spec/models/topic_timer_spec.rb index d48760616e6..ef1e32e712a 100644 --- a/spec/models/topic_timer_spec.rb +++ b/spec/models/topic_timer_spec.rb @@ -5,10 +5,6 @@ RSpec.describe TopicTimer, type: :model do let(:topic) { Fabricate(:topic) } let(:admin) { Fabricate(:admin) } - before do - Jobs::ToggleTopicClosed.jobs.clear - end - context "validations" do describe '#status_type' do it 'should ensure that only one active public topic status update exists' do @@ -245,7 +241,6 @@ RSpec.describe TopicTimer, type: :model do describe '.ensure_consistency!' do before do SiteSetting.queue_jobs = true - Jobs::ToggleTopicClosed.jobs.clear end it 'should enqueue jobs that have been missed' do diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 20065603191..9599ba22f79 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -736,6 +736,10 @@ describe User do user.update_last_seen! end + after do + $redis.flushall + end + it "updates last_seen_at" do expect(user.last_seen_at).to be_within_one_second_of(date) end diff --git a/spec/multisite/site_settings_spec.rb b/spec/multisite/site_settings_spec.rb index 75ebfc92553..09a5b90bb5c 100644 --- a/spec/multisite/site_settings_spec.rb +++ b/spec/multisite/site_settings_spec.rb @@ -8,6 +8,7 @@ RSpec.describe 'Multisite SiteSettings' do SiteSetting.provider = SiteSettings::DbProvider.new(SiteSetting) conn.config_filename = "spec/fixtures/multisite/two_dbs.yml" conn.load_settings! + conn.remove_class_variable(:@@current_db) end after do @@ -21,6 +22,7 @@ RSpec.describe 'Multisite SiteSettings' do conn.remove_class_variable(class_variable) end + conn.set_current_db SiteSetting.provider = @original_provider end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 50f2d38a251..665ec0088e1 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -121,6 +121,7 @@ RSpec.configure do |config| SiteSetting.automatically_download_gravatars = false Discourse.clear_readonly! + Sidekiq::Worker.clear_all I18n.locale = :en end diff --git a/spec/requests/admin/admin_controller_spec.rb b/spec/requests/admin/admin_controller_spec.rb index 0d87a7e6e09..2d55f8747a6 100644 --- a/spec/requests/admin/admin_controller_spec.rb +++ b/spec/requests/admin/admin_controller_spec.rb @@ -3,7 +3,7 @@ require 'rails_helper' RSpec.describe Admin::AdminController do it "should return the right response if user isn't a staff" do expect do - get "/admin", api_key: 'asdiasiduga' + get "/admin", params: { api_key: 'asdiasiduga' } end.to raise_error(ActionController::RoutingError) end end diff --git a/spec/requests/admin/emojis_controller_spec.rb b/spec/requests/admin/emojis_controller_spec.rb index 352205c77cb..329778e50e7 100644 --- a/spec/requests/admin/emojis_controller_spec.rb +++ b/spec/requests/admin/emojis_controller_spec.rb @@ -12,10 +12,10 @@ RSpec.describe Admin::EmojisController do describe 'when upload is invalid' do it 'should publish the right error' do message = MessageBus.track_publish do - post("/admin/customize/emojis.json", + post "/admin/customize/emojis.json", params: { name: 'test', file: fixture_file_upload("#{Rails.root}/spec/fixtures/images/fake.jpg") - ) + } end.find { |m| m.channel == "/uploads/emoji" } expect(message.channel).to eq("/uploads/emoji") @@ -28,10 +28,10 @@ RSpec.describe Admin::EmojisController do CustomEmoji.create!(name: 'test', upload: upload) message = MessageBus.track_publish do - post("/admin/customize/emojis.json", + post "/admin/customize/emojis.json", params: { name: 'test', file: fixture_file_upload("#{Rails.root}/spec/fixtures/images/logo.png") - ) + } end.find { |m| m.channel == "/uploads/emoji" } expect(message.channel).to eq("/uploads/emoji") @@ -46,10 +46,10 @@ RSpec.describe Admin::EmojisController do Emoji.expects(:clear_cache) message = MessageBus.track_publish do - post("/admin/customize/emojis.json", + post "/admin/customize/emojis.json", params: { name: 'test', file: fixture_file_upload("#{Rails.root}/spec/fixtures/images/logo.png") - ) + } end.find { |m| m.channel == "/uploads/emoji" } custom_emoji = CustomEmoji.last @@ -68,9 +68,10 @@ RSpec.describe Admin::EmojisController do custom_emoji = CustomEmoji.create!(name: 'test', upload: upload) Emoji.clear_cache - expect { delete "/admin/customize/emojis/#{custom_emoji.name}.json", name: 'test' } - .to change { Upload.count }.by(-1) - .and change { CustomEmoji.count }.by(-1) + expect do + delete "/admin/customize/emojis/#{custom_emoji.name}.json", + params: { name: 'test' } + end.to change { Upload.count }.by(-1).and change { CustomEmoji.count }.by(-1) end end end diff --git a/spec/requests/admin/groups_controller_spec.rb b/spec/requests/admin/groups_controller_spec.rb index 93f5323a32c..7d6045b6085 100644 --- a/spec/requests/admin/groups_controller_spec.rb +++ b/spec/requests/admin/groups_controller_spec.rb @@ -11,12 +11,14 @@ RSpec.describe Admin::GroupsController do describe '#create' do it 'should work' do - post "/admin/groups.json", group: { - name: 'testing', - usernames: [admin.username, user.username].join(","), - owner_usernames: [user.username].join(","), - allow_membership_requests: true, - membership_request_template: 'Testing', + post "/admin/groups.json", params: { + group: { + name: 'testing', + usernames: [admin.username, user.username].join(","), + owner_usernames: [user.username].join(","), + allow_membership_requests: true, + membership_request_template: 'Testing', + } } expect(response).to be_success @@ -32,8 +34,10 @@ RSpec.describe Admin::GroupsController do describe '#add_owners' do it 'should work' do - put "/admin/groups/#{group.id}/owners.json", group: { - usernames: [user.username, admin.username].join(",") + put "/admin/groups/#{group.id}/owners.json", params: { + group: { + usernames: [user.username, admin.username].join(",") + } } expect(response).to be_success diff --git a/spec/controllers/embed_controller_spec.rb b/spec/requests/embed_controller_spec.rb similarity index 52% rename from spec/controllers/embed_controller_spec.rb rename to spec/requests/embed_controller_spec.rb index 69dfc83683e..d6ae02f8297 100644 --- a/spec/controllers/embed_controller_spec.rb +++ b/spec/requests/embed_controller_spec.rb @@ -7,34 +7,34 @@ describe EmbedController do let(:discourse_username) { "eviltrout" } it "is 404 without an embed_url" do - get :comments - expect(response).to render_template :embed_error + get '/embed/comments' + expect(response.body).to match(I18n.t('embed.error')) end it "raises an error with a missing host" do - get :comments, embed_url: embed_url - expect(response).to render_template :embed_error + get '/embed/comments', params: { embed_url: embed_url } + expect(response.body).to match(I18n.t('embed.error')) end context "by topic id" do + let(:headers) { { 'REFERER' => 'http://eviltrout.com/some-page' } } before do Fabricate(:embeddable_host) - controller.request.stubs(:referer).returns('http://eviltrout.com/some-page') end it "allows a topic to be embedded by id" do topic = Fabricate(:topic) - get :comments, topic_id: topic.id + get '/embed/comments', params: { topic_id: topic.id }, headers: headers expect(response).to be_success end end - context ".info" do + context "#info" do context "without api key" do it "fails" do - get :info, format: :json - expect(response).to render_template :embed_error + get '/embed/info.json' + expect(response.body).to match(I18n.t('embed.error')) end end @@ -46,7 +46,9 @@ describe EmbedController do let(:topic_embed) { Fabricate(:topic_embed, embed_url: embed_url) } it "returns information about the topic" do - get :info, format: :json, embed_url: topic_embed.embed_url, api_key: api_key.key, api_username: "system" + get '/embed/info.json', + params: { embed_url: topic_embed.embed_url, api_key: api_key.key, api_username: "system" } + json = JSON.parse(response.body) expect(json['topic_id']).to eq(topic_embed.topic.id) expect(json['post_id']).to eq(topic_embed.post.id) @@ -56,7 +58,9 @@ describe EmbedController do context "without invalid embed url" do it "returns error response" do - get :info, format: :json, embed_url: "http://nope.com", api_key: api_key.key, api_username: "system" + get '/embed/info.json', + params: { embed_url: "http://nope.com", api_key: api_key.key, api_username: "system" } + json = JSON.parse(response.body) expect(json["error_type"]).to eq("not_found") end @@ -68,14 +72,12 @@ describe EmbedController do let!(:embeddable_host) { Fabricate(:embeddable_host) } it "raises an error with no referer" do - get :comments, embed_url: embed_url - expect(response).to render_template :embed_error + get '/embed/comments', params: { embed_url: embed_url } + expect(response.body).to match(I18n.t('embed.error')) end context "success" do - before do - controller.request.stubs(:referer).returns(embed_url) - end + let(:headers) { { 'REFERER' => embed_url } } after do expect(response).to be_success @@ -87,18 +89,33 @@ describe EmbedController do retriever = mock TopicRetriever.expects(:new).returns(retriever) retriever.expects(:retrieve) - get :comments, embed_url: embed_url + get '/embed/comments', params: { embed_url: embed_url }, headers: headers + end + + it "displays the right view" do + topic_embed = Fabricate(:topic_embed, embed_url: embed_url) + + get '/embed/comments', params: { embed_url: embed_url }, headers: headers + + expect(response.body).to match(I18n.t('embed.start_discussion')) end it "creates a topic view when a topic_id is found" do - TopicEmbed.expects(:topic_id_for_embed).returns(123) - TopicView.expects(:new).with(123, nil, limit: 100, exclude_first: true, exclude_deleted_users: true, exclude_hidden: true) - get :comments, embed_url: embed_url + topic_embed = Fabricate(:topic_embed, embed_url: embed_url) + post = Fabricate(:post, topic: topic_embed.topic) + + get '/embed/comments', params: { embed_url: embed_url }, headers: headers + + expect(response.body).to match(I18n.t('embed.continue')) + expect(response.body).to match(post.cooked) end it "provides the topic retriever with the discourse username when provided" do TopicRetriever.expects(:new).with(embed_url, has_entry(author_username: discourse_username)) - get :comments, embed_url: embed_url, discourse_username: discourse_username + + get '/embed/comments', + params: { embed_url: embed_url, discourse_username: discourse_username }, + headers: headers end end @@ -113,33 +130,43 @@ describe EmbedController do context "success" do it "works with the first host" do - controller.request.stubs(:referer).returns("http://eviltrout.com/wat/1-2-3.html") - get :comments, embed_url: embed_url + get '/embed/comments', + params: { embed_url: embed_url }, + headers: { 'REFERER' => "http://eviltrout.com/wat/1-2-3.html" } + expect(response).to be_success end it "works with the second host" do - controller.request.stubs(:referer).returns("https://discourse.org/blog-entry-1") - get :comments, embed_url: embed_url + get '/embed/comments', + params: { embed_url: embed_url }, + headers: { 'REFERER' => "http://eviltrout.com/wat/1-2-3.html" } + expect(response).to be_success end it "works with a host with a path" do - controller.request.stubs(:referer).returns("https://example.com/some-other-path") - get :comments, embed_url: embed_url + get '/embed/comments', + params: { embed_url: embed_url }, + headers: { 'REFERER' => "https://example.com/some-other-path" } + expect(response).to be_success end it "contains custom class name" do - controller.request.stubs(:referer).returns("https://example.com/some-other-path") - get :comments, embed_url: embed_url - expect(assigns(:embeddable_css_class)).to eq(' class="example"') + get '/embed/comments', + params: { embed_url: embed_url }, + headers: { 'REFERER' => "https://example.com/some-other-path" } + + expect(response.body).to match('class="example"') end it "doesn't work with a made up host" do - controller.request.stubs(:referer).returns("http://codinghorror.com/invalid-url") - get :comments, embed_url: embed_url - expect(response).to render_template :embed_error + get '/embed/comments', + params: { embed_url: embed_url }, + headers: { 'REFERER' => "http://codinghorror.com/invalid-url" } + + expect(response.body).to match(I18n.t('embed.error')) end end end diff --git a/spec/requests/groups_controller_spec.rb b/spec/requests/groups_controller_spec.rb index 6975052beac..f808ed7578d 100644 --- a/spec/requests/groups_controller_spec.rb +++ b/spec/requests/groups_controller_spec.rb @@ -62,7 +62,7 @@ describe GroupsController do sign_in(user) group.update_attributes!(name: 'test') - get "/groups/test/mentionable.json", name: group.name + get "/groups/test/mentionable.json", params: { name: group.name } expect(response).to be_success @@ -71,7 +71,7 @@ describe GroupsController do group.update_attributes!(mentionable_level: Group::ALIAS_LEVELS[:everyone]) - get "/groups/test/mentionable.json", name: group.name + get "/groups/test/mentionable.json", params: { name: group.name } expect(response).to be_success response_body = JSON.parse(response.body) @@ -103,15 +103,17 @@ describe GroupsController do group.update!(allow_membership_requests: false) expect do - put "/groups/#{group.id}.json", group: { - flair_bg_color: 'FFF', - flair_color: 'BBB', - flair_url: 'fa-adjust', - bio_raw: 'testing', - full_name: 'awesome team', - public_admission: true, - public_exit: true, - allow_membership_requests: true + put "/groups/#{group.id}.json", params: { + group: { + flair_bg_color: 'FFF', + flair_color: 'BBB', + flair_url: 'fa-adjust', + bio_raw: 'testing', + full_name: 'awesome team', + public_admission: true, + public_exit: true, + allow_membership_requests: true + } } end.to change { GroupHistory.count }.by(8) @@ -138,7 +140,7 @@ describe GroupsController do end it 'should be able to update the group' do - put "/groups/#{group.id}.json", group: { flair_color: 'BBB' } + put "/groups/#{group.id}.json", params: { group: { flair_color: 'BBB' } } expect(response).to be_success expect(group.reload.flair_color).to eq('BBB') @@ -149,7 +151,7 @@ describe GroupsController do it 'should not be able to update the group' do sign_in(user) - put "/groups/#{group.id}.json", group: { name: 'testing' } + put "/groups/#{group.id}.json", params: { group: { name: 'testing' } } expect(response.status).to eq(403) end @@ -184,7 +186,9 @@ describe GroupsController do let(:group) { Fabricate(:group, users: [user1, user2, user3]) } it "should allow members to be sorted by" do - xhr :get, "/groups/#{group.name}/members", order: 'last_seen_at', desc: true + get "/groups/#{group.name}/members.json", params: { + order: 'last_seen_at', desc: true + } expect(response).to be_success @@ -192,7 +196,7 @@ describe GroupsController do expect(members.map { |m| m["id"] }).to eq([user1.id, user2.id, user3.id]) - xhr :get, "/groups/#{group.name}/members", order: 'last_seen_at' + get "/groups/#{group.name}/members.json", params: { order: 'last_seen_at' } expect(response).to be_success @@ -200,7 +204,9 @@ describe GroupsController do expect(members.map { |m| m["id"] }).to eq([user2.id, user1.id, user3.id]) - xhr :get, "/groups/#{group.name}/members", order: 'last_posted_at', desc: true + get "/groups/#{group.name}/members.json", params: { + order: 'last_posted_at', desc: true + } expect(response).to be_success @@ -210,7 +216,7 @@ describe GroupsController do end it "should not allow members to be sorted by columns that are not allowed" do - xhr :get, "/groups/#{group.name}/members", order: 'email' + get "/groups/#{group.name}/members.json", params: { order: 'email' } expect(response).to be_success @@ -225,10 +231,10 @@ describe GroupsController do context 'when user is not signed in' do it 'should be fobidden' do - xhr :put, "/groups/#{group.id}/members", usernames: "bob" + put "/groups/#{group.id}/members.json", params: { usernames: "bob" } expect(response).to be_forbidden - xhr :delete, "/groups/#{group.id}/members", username: "bob" + delete "/groups/#{group.id}/members.json", params: { username: "bob" } expect(response).to be_forbidden end @@ -239,10 +245,10 @@ describe GroupsController do public_exit: true ) - expect { xhr :put, "/groups/#{group.id}/members", usernames: "bob" } + expect { put "/groups/#{group.id}/members.json", params: { usernames: "bob" } } .to raise_error(Discourse::NotLoggedIn) - expect { xhr :delete, "/groups/#{group.id}/members", username: "bob" } + expect { delete "/groups/#{group.id}/members.json", params: { username: "bob" } } .to raise_error(Discourse::NotLoggedIn) end end @@ -254,10 +260,10 @@ describe GroupsController do end it "refuses membership changes to unauthorized users" do - xhr :put, "/groups/#{group.id}/members", usernames: "bob" + put "/groups/#{group.id}/members.json", params: { usernames: "bob" } expect(response).to be_forbidden - xhr :delete, "/groups/#{group.id}/members", username: "bob" + delete "/groups/#{group.id}/members.json", params: { username: "bob" } expect(response).to be_forbidden end end @@ -271,10 +277,10 @@ describe GroupsController do end it "cannot add members to automatic groups" do - xhr :put, "/groups/#{group.id}/members", usernames: "bob" + put "/groups/#{group.id}/members.json", params: { usernames: "bob" } expect(response).to be_forbidden - xhr :delete, "/groups/#{group.id}/members", username: "bob" + delete "/groups/#{group.id}/members.json", params: { username: "bob" } expect(response).to be_forbidden end end @@ -292,7 +298,7 @@ describe GroupsController do user2 = Fabricate(:user) expect do - xhr :put, "/groups/#{group.id}/members", usernames: user2.username + put "/groups/#{group.id}/members.json", params: { usernames: user2.username } end.to change { group.users.count }.by(1) expect(response).to be_success @@ -307,7 +313,7 @@ describe GroupsController do it "cannot add members to automatic groups" do group.update!(automatic: true) - xhr :put, "/groups/#{group.id}/members", usernames: "l77t" + put "/groups/#{group.id}/members.json", params: { usernames: "l77t" } expect(response.status).to eq(403) end @@ -316,35 +322,41 @@ describe GroupsController do let(:user2) { Fabricate(:user) } it "adds by username" do - expect { xhr :put, "/groups/#{group.id}/members", usernames: [user1.username, user2.username].join(",") } - .to change { group.users.count }.by(2) + expect do + put "/groups/#{group.id}/members.json", + params: { usernames: [user1.username, user2.username].join(",") } + end.to change { group.users.count }.by(2) expect(response).to be_success end it "adds by id" do - expect { xhr :put, "/groups/#{group.id}/members", user_ids: [user1.id, user2.id].join(",") } - .to change { group.users.count }.by(2) + expect do + put "/groups/#{group.id}/members.json", + params: { user_ids: [user1.id, user2.id].join(",") } + end.to change { group.users.count }.by(2) expect(response).to be_success end it "adds by email" do - expect { xhr :put, "/groups/#{group.id}/members", user_emails: [user1.email, user2.email].join(",") } - .to change { group.users.count }.by(2) + expect do + put "/groups/#{group.id}/members.json", + params: { user_emails: [user1.email, user2.email].join(",") } + end.to change { group.users.count }.by(2) expect(response).to be_success end end it "returns 422 if member already exists" do - xhr :put, "/groups/#{group.id}/members", usernames: user.username + put "/groups/#{group.id}/members.json", params: { usernames: user.username } expect(response.status).to eq(422) end it "returns 404 if member is not found" do - xhr :put, "/groups/#{group.id}/members", usernames: 'some donkey' + put "/groups/#{group.id}/members.json", params: { usernames: 'some donkey' } expect(response.status).to eq(404) end @@ -362,7 +374,8 @@ describe GroupsController do context 'admin' do it "can make incremental adds" do expect do - xhr :put, "/groups/#{group.id}/members", usernames: other_user.username + put "/groups/#{group.id}/members.json", + params: { usernames: other_user.username } end.to change { group.users.count }.by(1) expect(response).to be_success @@ -378,8 +391,10 @@ describe GroupsController do it 'should allow a user to join the group' do sign_in(other_user) - expect { xhr :put, "/groups/#{group.id}/members", usernames: other_user.username } - .to change { group.users.count }.by(1) + expect do + put "/groups/#{group.id}/members.json", + params: { usernames: other_user.username } + end.to change { group.users.count }.by(1) expect(response).to be_success end @@ -387,7 +402,8 @@ describe GroupsController do it 'should not allow an underprivilege user to add another user to a group' do sign_in(user) - xhr :put, "/groups/#{group.id}/members", usernames: other_user.username + put "/groups/#{group.id}/members.json", + params: { usernames: other_user.username } expect(response).to be_forbidden end @@ -398,26 +414,28 @@ describe GroupsController do it "cannot remove members from automatic groups" do group.update!(automatic: true) - xhr :delete, "/groups/#{group.id}/members", user_id: 42 + delete "/groups/#{group.id}/members.json", params: { user_id: 42 } expect(response.status).to eq(403) end it "raises an error if user to be removed is not found" do - xhr :delete, "/groups/#{group.id}/members", user_id: -10 + delete "/groups/#{group.id}/members.json", params: { user_id: -10 } expect(response.status).to eq(404) end context "is able to remove a member" do it "removes by id" do - expect { xhr :delete, "/groups/#{group.id}/members", user_id: user.id } - .to change { group.users.count }.by(-1) + expect do + delete "/groups/#{group.id}/members.json", params: { user_id: user.id } + end.to change { group.users.count }.by(-1) expect(response).to be_success end it "removes by username" do - expect { xhr :delete, "/groups/#{group.id}/members", username: user.username } - .to change { group.users.count }.by(-1) + expect do + delete "/groups/#{group.id}/members.json", params: { username: user.username } + end.to change { group.users.count }.by(-1) expect(response).to be_success end @@ -425,14 +443,16 @@ describe GroupsController do it "removes user.primary_group_id when user is removed from group" do user.update!(primary_group_id: group.id) - xhr :delete, "/groups/#{group.id}/members", user_id: user.id + delete "/groups/#{group.id}/members.json", params: { user_id: user.id } expect(user.reload.primary_group_id).to eq(nil) end it "removes by user_email" do - expect { xhr :delete, "/groups/#{group.id}/members", user_email: user.email } - .to change { group.users.count }.by(-1) + expect do + delete "/groups/#{group.id}/members.json", + params: { user_email: user.email } + end.to change { group.users.count }.by(-1) expect(response).to be_success end @@ -443,8 +463,10 @@ describe GroupsController do context "admin" do it "removes by username" do - expect { xhr :delete, "/groups/#{group.id}/members", username: other_user.username } - .to change { group.users.count }.by(-1) + expect do + delete "/groups/#{group.id}/members.json", + params: { username: other_user.username } + end.to change { group.users.count }.by(-1) expect(response).to be_success end @@ -453,8 +475,10 @@ describe GroupsController do it 'should allow a user to leave a group' do sign_in(other_user) - expect { xhr :delete, "/groups/#{group.id}/members", username: other_user.username } - .to change { group.users.count }.by(-1) + expect do + delete "/groups/#{group.id}/members.json", + params: { username: other_user.username } + end.to change { group.users.count }.by(-1) expect(response).to be_success end @@ -462,7 +486,8 @@ describe GroupsController do it 'should not allow a underprivilege user to leave a group for another user' do sign_in(user) - xhr :delete, "/groups/#{group.id}/members", username: other_user.username + delete "/groups/#{group.id}/members.json", + params: { username: other_user.username } expect(response).to be_forbidden end @@ -474,8 +499,9 @@ describe GroupsController do describe "group histories" do context 'when user is not signed in' do it 'should raise the right error' do - expect { xhr :get, "/groups/#{group.name}/logs" } - .to raise_error(Discourse::NotLoggedIn) + expect do + get "/groups/#{group.name}/logs.json" + end.to raise_error(Discourse::NotLoggedIn) end end @@ -485,7 +511,7 @@ describe GroupsController do end it 'should be forbidden' do - xhr :get, "/groups/#{group.name}/logs" + get "/groups/#{group.name}/logs.json" expect(response).to be_forbidden end @@ -506,11 +532,11 @@ describe GroupsController do end it 'should allow group owner to view history' do - xhr :get, "/groups/#{group.name}/logs" + get "/groups/#{group.name}/logs.json" expect(response).to be_success - result = JSON.parse(response.body)["logs"].first + result = JSON.parse(response.body)["logs"].last expect(result["action"]).to eq(GroupHistory.actions[1].to_s) expect(result["subject"]).to eq('public_exit') @@ -529,7 +555,7 @@ describe GroupsController do it 'should be able to view history' do GroupActionLogger.new(admin, group).log_remove_user_from_group(user) - xhr :get, "/groups/#{group.name}/logs" + get "/groups/#{group.name}/logs.json" expect(response).to be_success @@ -542,7 +568,9 @@ describe GroupsController do GroupActionLogger.new(admin, group).log_add_user_to_group(user) GroupActionLogger.new(admin, group).log_remove_user_from_group(user) - xhr :get, "/groups/#{group.name}/logs", filters: { "action" => "add_user_to_group" } + get "/groups/#{group.name}/logs.json", params: { + filters: { "action" => "add_user_to_group" } + } expect(response).to be_success @@ -560,7 +588,7 @@ describe GroupsController do it 'requires the user to log in' do expect do - xhr :post, "/groups/#{group.name}/request_membership" + post "/groups/#{group.name}/request_membership.json" end.to raise_error(Discourse::NotLoggedIn) end @@ -568,7 +596,7 @@ describe GroupsController do sign_in(user) expect do - xhr :post, "/groups/#{group.name}/request_membership" + post "/groups/#{group.name}/request_membership.json" end.to raise_error(ActionController::ParameterMissing) end @@ -579,8 +607,8 @@ describe GroupsController do sign_in(user) - xhr :post, "/groups/#{group.name}/request_membership", - reason: 'Please add me in' + post "/groups/#{group.name}/request_membership.json", + params: { reason: 'Please add me in' } expect(response).to be_success @@ -621,7 +649,9 @@ describe GroupsController do context 'as an anon user' do it "returns the right response" do - expect { xhr :get, '/groups/search' }.to raise_error(Discourse::NotLoggedIn) + expect do + get '/groups/search.json' + end.to raise_error(Discourse::NotLoggedIn) end end @@ -629,7 +659,7 @@ describe GroupsController do it "returns the right response" do sign_in(user) - xhr :get, '/groups/search' + get '/groups/search.json' expect(response).to be_success groups = JSON.parse(response.body) @@ -641,7 +671,7 @@ describe GroupsController do expect(groups.map { |group| group["id"] }).to contain_exactly(*expected_ids) ['GO', 'nerys'].each do |term| - xhr :get, "/groups/search?term=#{term}" + get "/groups/search.json?term=#{term}" expect(response).to be_success groups = JSON.parse(response.body) @@ -650,7 +680,7 @@ describe GroupsController do expect(groups.first['id']).to eq(group.id) end - xhr :get, "/groups/search?term=KingOfTheNorth" + get "/groups/search.json?term=KingOfTheNorth" expect(response).to be_success groups = JSON.parse(response.body) @@ -667,7 +697,7 @@ describe GroupsController do it "returns the right response" do sign_in(user) - xhr :get, "/groups/search?term=north" + get "/groups/search.json?term=north" expect(response).to be_success groups = JSON.parse(response.body) @@ -681,7 +711,7 @@ describe GroupsController do it "returns the right response" do sign_in(Fabricate(:admin)) - xhr :get, '/groups/search?ignore_automatic=true' + get '/groups/search.json?ignore_automatic=true' expect(response).to be_success groups = JSON.parse(response.body) diff --git a/spec/requests/list_controller_spec.rb b/spec/requests/list_controller_spec.rb new file mode 100644 index 00000000000..cec635654e6 --- /dev/null +++ b/spec/requests/list_controller_spec.rb @@ -0,0 +1,29 @@ +require 'rails_helper' + +RSpec.describe ListController do + let(:topic) { Fabricate(:topic) } + + describe 'titles for crawler layout' do + it 'has no title for the default URL' do + topic + filter = Discourse.anonymous_filters[0] + get "/#{filter}", params: { _escaped_fragment_: 'true' } + + expect(response.body).to include(I18n.t("rss_description.posts")) + + expect(response.body).to_not include( + I18n.t('js.filters.with_topics', filter: filter) + ) + end + + it 'has a title for non-default URLs' do + topic + filter = Discourse.anonymous_filters[1] + get "/#{filter}", params: { _escaped_fragment_: 'true' } + + expect(response.body).to include( + I18n.t('js.filters.with_topics', filter: filter) + ) + end + end +end diff --git a/spec/requests/post_actions_controller_spec.rb b/spec/requests/post_actions_controller_spec.rb new file mode 100644 index 00000000000..5ad8455334a --- /dev/null +++ b/spec/requests/post_actions_controller_spec.rb @@ -0,0 +1,148 @@ +require 'rails_helper' + +RSpec.describe PostActionsController do + describe '#create' do + describe 'as a moderator' do + let(:user) { Fabricate(:moderator) } + let(:post_1) { Fabricate(:post, user: Fabricate(:coding_horror)) } + + before do + sign_in(user) + end + + it 'raises an error when the id is missing' do + expect do + post "/post_actions.json", params: { + post_action_type_id: PostActionType.types[:like] + } + end.to raise_error(ActionController::ParameterMissing) + end + + it 'fails when the id is invalid' do + post "/post_actions.json", params: { + post_action_type_id: PostActionType.types[:like], id: -1 + } + + expect(response.status).to eq(404) + end + + it 'raises an error when the post_action_type_id index is missing' do + expect do + post "/post_actions.json", params: { id: post_1.id } + end.to raise_error(ActionController::ParameterMissing) + end + + it "fails when the user doesn't have permission to see the post" do + post_1 = Fabricate(:private_message_post, user: Fabricate(:user)) + + post "/post_actions.json", params: { + id: post_1.id, post_action_type_id: PostActionType.types[:like] + } + + expect(response).to be_forbidden + end + + it 'allows us to create an post action on a post' do + expect do + post "/post_actions.json", params: { + id: post_1.id, post_action_type_id: PostActionType.types[:like] + } + end.to change { PostAction.count }.by(1) + + post_action = PostAction.last + + expect(post_action.post_id).to eq(post_1.id) + expect(post_action.post_action_type_id).to eq(PostActionType.types[:like]) + end + + it "passes a list of taken actions through" do + PostAction.create( + post_id: post_1.id, + user_id: user.id, + post_action_type_id: PostActionType.types[:inappropriate] + ) + + post "/post_actions.json", params: { + id: post_1.id, post_action_type_id: PostActionType.types[:off_topic] + } + + expect(response).to_not be_success + end + + it 'passes the message through' do + message = 'action message goes here' + + post "/post_actions.json", params: { + id: post_1.id, + post_action_type_id: PostActionType.types[:notify_user], + message: message + } + + expect(PostAction.last.post_id).to eq(post_1.id) + expect(Post.last.raw).to include(message) + end + + it 'passes the message through as warning' do + message = 'action message goes here' + + post "/post_actions.json", params: { + id: post_1.id, + post_action_type_id: PostActionType.types[:notify_user], + message: message, + is_warning: true + } + + expect(PostAction.last.post_id).to eq(post_1.id) + + post = Post.last + + expect(post.raw).to include(message) + expect(post.topic.is_official_warning?).to eq(true) + end + + it "doesn't create message as a warning if the user isn't staff" do + sign_in(Fabricate(:user)) + + post "/post_actions.json", params: { + id: post_1.id, + post_action_type_id: PostActionType.types[:notify_user], + message: 'action message goes here', + is_warning: true + } + + expect(response.status).to eq(403) + end + + it 'passes take_action through' do + post "/post_actions.json", params: { + id: post_1.id, + post_action_type_id: PostActionType.types[:spam], + take_action: 'true' + } + + expect(response).to be_success + + post_action = PostAction.last + + expect(post_action.post_id).to eq(post_1.id) + expect(post_action.staff_took_action).to eq(true) + end + + it "doesn't pass take_action through if the user isn't staff" do + sign_in(Fabricate(:user)) + + post "/post_actions.json", params: { + id: post_1.id, + post_action_type_id: PostActionType.types[:like] + } + + expect(response).to be_success + + post_action = PostAction.last + + expect(post_action.post_id).to eq(post_1.id) + expect(post_action.staff_took_action).to eq(false) + end + end + end +end diff --git a/spec/requests/posts_controller_spec.rb b/spec/requests/posts_controller_spec.rb new file mode 100644 index 00000000000..62256403bf0 --- /dev/null +++ b/spec/requests/posts_controller_spec.rb @@ -0,0 +1,202 @@ +require 'rails_helper' + +RSpec.describe PostsController do + let(:user) { Fabricate(:user) } + let(:category) { Fabricate(:category) } + let(:topic) { Fabricate(:topic) } + let(:public_post) { Fabricate(:post, user: user, topic: topic) } + + let(:private_topic) do + Fabricate(:topic, archetype: Archetype.private_message, category: nil) + end + + let(:private_post) { Fabricate(:post, user: user, topic: private_topic) } + + describe '#create' do + before do + sign_in(user) + end + + it 'creates the post' do + post "/posts.json", params: { + raw: 'this is the test content', + title: 'this is the test title for the topic', + category: category.id, + meta_data: { xyz: 'abc' } + } + + expect(response).to be_success + + new_post = Post.last + topic = new_post.topic + + expect(new_post.user).to eq(user) + expect(new_post.raw).to eq('this is the test content') + expect(topic.title).to eq('This is the test title for the topic') + expect(topic.category).to eq(category) + expect(topic.meta_data).to eq("xyz" => 'abc') + end + + it 'can create a reply to a post' do + SiteSetting.queue_jobs = true + + topic = Fabricate(:private_message_post, user: user).topic + post_2 = Fabricate(:private_message_post, user: user, topic: topic) + + post "/posts.json", params: { + raw: 'this is the test content', + topic_id: topic.id, + reply_to_post_number: post_2.post_number, + image_sizes: { width: '100', height: '200' } + } + + expect(response).to be_success + + new_post = Post.last + topic = new_post.topic + + expect(new_post.user).to eq(user) + expect(new_post.raw).to eq('this is the test content') + expect(new_post.reply_to_post_number).to eq(post_2.post_number) + + job_args = Jobs::ProcessPost.jobs.first["args"].first + + expect(job_args["image_sizes"]).to eq("width" => '100', "height" => '200') + end + + it 'creates a private post' do + user_2 = Fabricate(:user) + user_3 = Fabricate(:user) + + post "/posts.json", params: { + raw: 'this is the test content', + archetype: 'private_message', + title: "this is some post", + target_usernames: "#{user_2.username},#{user_3.username}" + } + + expect(response).to be_success + + new_post = Post.last + new_topic = Topic.last + + expect(new_post.user).to eq(user) + expect(new_topic.private_message?).to eq(true) + expect(new_topic.allowed_users).to contain_exactly(user, user_2, user_3) + end + + describe 'warnings' do + let(:user_2) { Fabricate(:user) } + + context 'as a staff user' do + before do + sign_in(Fabricate(:admin)) + end + + it 'should be able to mark a topic as warning' do + post "/posts.json", params: { + raw: 'this is the test content', + archetype: 'private_message', + title: "this is some post", + target_usernames: user_2.username, + is_warning: true + } + + expect(response).to be_success + + new_topic = Topic.last + + expect(new_topic.title).to eq('This is some post') + expect(new_topic.is_official_warning?).to eq(true) + end + + it 'should be able to mark a topic as not a warning' do + post "/posts.json", params: { + raw: 'this is the test content', + archetype: 'private_message', + title: "this is some post", + target_usernames: user_2.username, + is_warning: false + } + + expect(response).to be_success + + new_topic = Topic.last + + expect(new_topic.title).to eq('This is some post') + expect(new_topic.is_official_warning?).to eq(false) + end + end + + context 'as a normal user' do + it 'should not be able to mark a topic as warning' do + post "/posts.json", params: { + raw: 'this is the test content', + archetype: 'private_message', + title: "this is some post", + target_usernames: user_2.username, + is_warning: true + } + + expect(response).to be_success + + new_topic = Topic.last + + expect(new_topic.title).to eq('This is some post') + expect(new_topic.is_official_warning?).to eq(false) + end + end + end + end + + describe '#user_posts_feed' do + it 'returns public posts rss feed' do + public_post + private_post + + get "/u/#{user.username}/activity.rss" + + expect(response).to be_success + + body = response.body + + expect(body).to_not include(private_post.url) + expect(body).to include(public_post.url) + end + end + + describe '#latest' do + context 'private posts' do + it 'returns private posts rss feed' do + sign_in(Fabricate(:admin)) + + public_post + private_post + get "/private-posts.rss" + + expect(response).to be_success + + body = response.body + + expect(body).to include(private_post.url) + expect(body).to_not include(public_post.url) + end + end + + context 'public posts' do + it 'returns public posts with topic rss feed' do + public_post + private_post + + get "/posts.rss" + + expect(response).to be_success + + body = response.body + + expect(body).to include(public_post.url) + expect(body).to_not include(private_post.url) + end + end + end +end diff --git a/spec/controllers/robots_txt_controller_spec.rb b/spec/requests/robots_txt_controller_spec.rb similarity index 53% rename from spec/controllers/robots_txt_controller_spec.rb rename to spec/requests/robots_txt_controller_spec.rb index 8ee44f9a47e..68d5912be41 100644 --- a/spec/controllers/robots_txt_controller_spec.rb +++ b/spec/requests/robots_txt_controller_spec.rb @@ -1,20 +1,19 @@ require 'rails_helper' -describe RobotsTxtController do - - context '.index' do - +RSpec.describe RobotsTxtController do + describe '#index' do it "returns index when indexing is allowed" do SiteSetting.allow_index_in_robots_txt = true - get :index - expect(response).to render_template :index + get '/robots.txt' + + expect(response.body).to include("Disallow: /u/") end it "returns noindex when indexing is disallowed" do SiteSetting.allow_index_in_robots_txt = false - get :index - expect(response).to render_template :no_index - end + get '/robots.txt' + expect(response.body).to_not include("Disallow: /u/") + end end end diff --git a/spec/controllers/static_controller_spec.rb b/spec/requests/static_controller_spec.rb similarity index 59% rename from spec/controllers/static_controller_spec.rb rename to spec/requests/static_controller_spec.rb index 1e1fbbd963d..f3343505d65 100644 --- a/spec/controllers/static_controller_spec.rb +++ b/spec/requests/static_controller_spec.rb @@ -2,14 +2,14 @@ require 'rails_helper' describe StaticController do - context 'brotli_asset' do + context '#brotli_asset' do it 'returns a non brotli encoded 404 if asset is missing' do - get :brotli_asset, path: 'missing.js' + get "/brotli_asset/missing.js" - expect(response.status).to eq(404) - expect(response.headers['Content-Encoding']).not_to eq('br') - expect(response.headers["Cache-Control"]).to match(/max-age=1/) + expect(response.status).to eq(404) + expect(response.headers['Content-Encoding']).not_to eq('br') + expect(response.headers["Cache-Control"]).to match(/max-age=1/) end it 'can handle fallback brotli assets' do @@ -23,7 +23,7 @@ describe StaticController do file_path = assets_path.join("test.js.br") File.write(file_path, 'fake brotli file') - get :brotli_asset, path: 'test.js' + get "/brotli_asset/test.js" expect(response.status).to eq(200) expect(response.headers["Cache-Control"]).to match(/public/) @@ -41,7 +41,7 @@ describe StaticController do file_path = assets_path.join("test.js.br") File.write(file_path, 'fake brotli file') - get :brotli_asset, path: 'test.js' + get "/brotli_asset/test.js" expect(response.status).to eq(200) expect(response.headers["Cache-Control"]).to match(/public/) @@ -51,7 +51,7 @@ describe StaticController do end end - context 'show' do + context '#show' do before do post = create_post SiteSetting.tos_topic_id = post.topic.id @@ -60,37 +60,38 @@ describe StaticController do end context "with a static file that's present" do + it "should return the right response" do + get "/faq" - before do - xhr :get, :show, id: 'faq' - end - - it 'renders the static file if present' do expect(response).to be_success - end - - it "renders the file" do - expect(response).to render_template('static/show') - expect(assigns(:page)).to eq('faq') + expect(response.body).to include(I18n.t('js.faq')) end end - [ ['tos', :tos_url], ['privacy', :privacy_policy_url] ].each do |id, setting_name| - context "#{id}" do - subject { xhr :get, :show, id: id } + [ + ['tos', :tos_url, I18n.t('terms_of_service.title')], + ['privacy', :privacy_policy_url, I18n.t('privacy')] + ].each do |id, setting_name, text| + context "#{id}" do context "when #{setting_name} site setting is NOT set" do it "renders the #{id} page" do - expect(subject).to render_template("static/show") - expect(assigns(:page)).to eq(id) + get "/#{id}" + + expect(response).to be_success + expect(response.body).to include(text) end end context "when #{setting_name} site setting is set" do - before { SiteSetting.public_send("#{setting_name}=", 'http://example.com/page') } + before do + SiteSetting.public_send("#{setting_name}=", 'http://example.com/page') + end it "redirects to the #{setting_name}" do - expect(subject).to redirect_to('http://example.com/page') + get "/#{id}" + + expect(response).to redirect_to('http://example.com/page') end end end @@ -98,21 +99,27 @@ describe StaticController do context "with a missing file" do it "should respond 404" do - xhr :get, :show, id: 'does-not-exist' - expect(response.response_code).to eq(404) + get "/static/does-not-exist" + expect(response.status).to eq(404) end end it 'should redirect to / when logged in and path is /login' do - log_in - xhr :get, :show, id: 'login' - expect(response).to redirect_to '/' + sign_in(Fabricate(:user)) + get "/login" + expect(response).to redirect_to('/') end it "should display the login template when login is required" do SiteSetting.login_required = true - xhr :get, :show, id: 'login' + + get "/login" + expect(response).to be_success + + expect(response.body).to include(PrettyText.cook(I18n.t( + 'login_required.welcome_message', title: SiteSetting.title + ))) end context "when login_required is enabled" do @@ -121,29 +128,31 @@ describe StaticController do end it 'faq page redirects to login page for anon' do - xhr :get, :show, id: 'faq' + get '/faq' expect(response).to redirect_to '/login' end it 'guidelines page redirects to login page for anon' do - xhr :get, :show, id: 'guidelines' + get '/guidelines' expect(response).to redirect_to '/login' end it 'faq page loads for logged in user' do - log_in - xhr :get, :show, id: 'faq' + sign_in(Fabricate(:user)) + + get '/faq' + expect(response).to be_success - expect(response).to render_template('static/show') - expect(assigns(:page)).to eq('faq') + expect(response.body).to include(I18n.t('js.faq')) end it 'guidelines page loads for logged in user' do - log_in - xhr :get, :show, id: 'guidelines' + sign_in(Fabricate(:user)) + + get '/guidelines' + expect(response).to be_success - expect(response).to render_template('static/show') - expect(assigns(:page)).to eq('faq') + expect(response.body).to include(I18n.t('guidelines')) end end end @@ -151,50 +160,50 @@ describe StaticController do describe '#enter' do context 'without a redirect path' do it 'redirects to the root url' do - xhr :post, :enter - expect(response).to redirect_to '/' + post "/login.json" + expect(response).to redirect_to('/') end end context 'with a redirect path' do it 'redirects to the redirect path' do - xhr :post, :enter, redirect: '/foo' - expect(response).to redirect_to '/foo' + post "/login.json", params: { redirect: '/foo' } + expect(response).to redirect_to('/foo') end end context 'with a full url' do it 'redirects to the correct path' do - xhr :post, :enter, redirect: "#{Discourse.base_url}/foo" - expect(response).to redirect_to '/foo' + post "/login.json", params: { redirect: "#{Discourse.base_url}/foo" } + expect(response).to redirect_to('/foo') end end context 'with a period to force a new host' do it 'redirects to the root path' do - xhr :post, :enter, redirect: ".org/foo" - expect(response).to redirect_to '/' + post "/login.json", params: { redirect: ".org/foo" } + expect(response).to redirect_to('/') end end context 'with a full url to someone else' do it 'redirects to the root path' do - xhr :post, :enter, redirect: "http://eviltrout.com/foo" - expect(response).to redirect_to '/' + post "/login.json", params: { redirect: "http://eviltrout.com/foo" } + expect(response).to redirect_to('/') end end context 'with an invalid URL' do it "redirects to the root" do - xhr :post, :enter, redirect: "javascript:alert('trout')" - expect(response).to redirect_to '/' + post "/login.json", params: { redirect: "javascript:alert('trout')" } + expect(response).to redirect_to('/') end end context 'when the redirect path is the login page' do it 'redirects to the root url' do - xhr :post, :enter, redirect: login_path - expect(response).to redirect_to '/' + post "/login.json", params: { redirect: login_path } + expect(response).to redirect_to('/') end end end diff --git a/spec/requests/tags_controller_spec.rb b/spec/requests/tags_controller_spec.rb index 7e9f721d153..568fa9858dd 100644 --- a/spec/requests/tags_controller_spec.rb +++ b/spec/requests/tags_controller_spec.rb @@ -9,7 +9,7 @@ describe TagsController do let(:tag) { Fabricate(:tag, name: 'test') } it "should return the right response" do - get "/tags/check.json", tag_values: [tag.name] + get "/tags/check.json", params: { tag_values: [tag.name] } expect(response).to be_success diff --git a/spec/requests/topics_controller_spec.rb b/spec/requests/topics_controller_spec.rb index d2e1990e3cc..cb5133a3e03 100644 --- a/spec/requests/topics_controller_spec.rb +++ b/spec/requests/topics_controller_spec.rb @@ -10,10 +10,11 @@ RSpec.describe TopicsController do it 'should record the timing' do sign_in(user) - post "/topics/timings.json", + post "/topics/timings.json", params: { topic_id: topic.id, topic_time: 5, timings: { post_1.post_number => 2 } + } expect(response).to be_success @@ -29,9 +30,10 @@ RSpec.describe TopicsController do context 'when a user is not logged in' do it 'should return the right response' do expect do - post "/t/#{topic.id}/timer.json", + post "/t/#{topic.id}/timer.json", params: { time: '24', status_type: TopicTimer.types[1] + } end.to raise_error(Discourse::NotLoggedIn) end end @@ -40,9 +42,10 @@ RSpec.describe TopicsController do it 'should return the right response' do sign_in(user) - post "/t/#{topic.id}/timer.json", + post "/t/#{topic.id}/timer.json", params: { time: '24', status_type: TopicTimer.types[1] + } expect(response.status).to eq(403) expect(JSON.parse(response.body)["error_type"]).to eq('invalid_access') @@ -59,9 +62,10 @@ RSpec.describe TopicsController do it 'should be able to create a topic status update' do time = 24 - post "/t/#{topic.id}/timer.json", + post "/t/#{topic.id}/timer.json", params: { time: 24, status_type: TopicTimer.types[1] + } expect(response).to be_success @@ -84,9 +88,10 @@ RSpec.describe TopicsController do it 'should be able to delete a topic status update' do Fabricate(:topic_timer, topic: topic) - post "/t/#{topic.id}/timer.json", + post "/t/#{topic.id}/timer.json", params: { time: nil, status_type: TopicTimer.types[1] + } expect(response).to be_success expect(topic.reload.public_topic_timer).to eq(nil) @@ -102,10 +107,11 @@ RSpec.describe TopicsController do it 'should be able to create the topic status update' do SiteSetting.queue_jobs = true - post "/t/#{topic.id}/timer.json", + post "/t/#{topic.id}/timer.json", params: { time: 24, status_type: TopicTimer.types[3], category_id: topic.category_id + } expect(response).to be_success @@ -128,9 +134,10 @@ RSpec.describe TopicsController do describe 'invalid status type' do it 'should raise the right error' do expect do - post "/t/#{topic.id}/timer.json", + post "/t/#{topic.id}/timer.json", params: { time: 10, status_type: 'something' + } end.to raise_error(Discourse::InvalidParameters) end end diff --git a/spec/requests/users_controller_spec.rb b/spec/requests/users_controller_spec.rb index 23bf76dbd0f..53d5eb5a367 100644 --- a/spec/requests/users_controller_spec.rb +++ b/spec/requests/users_controller_spec.rb @@ -32,7 +32,7 @@ RSpec.describe UsersController do end it "should be able to update a user" do - put "/u/#{user.username}.json", name: 'test.test' + put "/u/#{user.username}.json", params: { name: 'test.test' } expect(response).to be_success expect(user.reload.name).to eq('test.test') @@ -44,11 +44,45 @@ RSpec.describe UsersController do end it "should be able to update a user" do - put "/u/#{user.username}.json", name: 'testing123' + put "/u/#{user.username}.json", params: { name: 'testing123' } expect(response).to be_success expect(user.reload.name).to eq('testing123') end end end + + describe "#account_created" do + it "returns a message when no session is present" do + get "/u/account-created" + + expect(response).to be_success + + body = response.body + + expect(body).to match(I18n.t('activation.missing_session')) + end + + it "redirects when the user is logged in" do + sign_in(Fabricate(:user)) + get "/u/account-created" + + expect(response).to redirect_to("/") + end + + context "when the user account is created" do + include ApplicationHelper + + it "returns the message when set in the session" do + user = create_user + get "/u/account-created" + + expect(response).to be_success + + expect(response.body).to include( + "{\"message\":\"#{I18n.t("login.activate_email", email: user.email).gsub!("