Further generalize pages and site Twitter handle (#3177)

* Further generalize pages and site Twitter handle

* Add footer mod change

* Remove giveaways dead code
This commit is contained in:
Ben Halpern 2019-06-16 00:59:11 -04:00 committed by GitHub
parent d5869a3b99
commit 456931f208
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
44 changed files with 127 additions and 720 deletions

View file

@ -12,6 +12,7 @@ variable :APP_DOMAIN, :String, default: "localhost:3000"
variable :APP_PROTOCOL, :String, default: "http://"
variable :COMMUNITY_NAME, :String, default: "DEV(local)"
variable :MAIN_SOCIAL_IMAGE, :String, default: "https://thepracticaldev.s3.amazonaws.com/i/6hqmcjaxbgbon8ydw93z.png"
variable :SITE_TWITTER_HANDLE, :String, default: "tbd"
# Logo
variable :LOGO_SVG, :String, default: ""

View file

@ -1,7 +1,7 @@
function initializeFooterMod() {
var footerContainer = document.getElementById("footer-container");
if (
footerContainer && document.getElementById('page-content').className.indexOf('stories-show') > -1
footerContainer && document.getElementById('page-content').className.indexOf('stories-show') > -1 && !document.getElementById('IS_CENTERED_PAGE')
) {
document
.getElementById('footer-container')

View file

@ -4,29 +4,6 @@ class GiveawaysController < ApplicationController
@errors = []
end
def edit
@user = current_user
@errors = []
end
# POST /giveaways
# POST /giveaways.json
# def create
# @user = User.new(giveaway_params)
#
# respond_to do |format|
# if @user.save
# format.html { redirect_to @user, notice: 'Giveaway was successfully created.' }
# format.json { render :show, status: :created, location: @user }
# else
# format.html { render :new }
# format.json { render json: @user.errors, status: :unprocessable_entity }
# end
# end
# end
# PATCH/PUT /giveaways/1
# PATCH/PUT /giveaways/1.json
def update
prevent_request_if_requested_twice
@user = current_user

View file

@ -34,7 +34,7 @@ class Internal::PagesController < Internal::ApplicationController
private
def page_params
allowed_params = %i[title slug body_markdown body_html description template]
allowed_params = %i[title slug body_markdown body_html description template is_top_level_path]
params.require(:page).permit(allowed_params)
end
end

View file

@ -3,7 +3,7 @@ class StoriesController < ApplicationController
before_action :set_cache_control_headers, only: %i[index search show]
def index
return handle_user_or_organization_or_podcast_index if params[:username]
return handle_user_or_organization_or_podcast_or_page_index if params[:username]
return handle_tag_index if params[:tag]
handle_base_index
@ -63,13 +63,16 @@ class StoriesController < ApplicationController
not_found
end
def handle_user_or_organization_or_podcast_index
def handle_user_or_organization_or_podcast_or_page_index
@podcast = Podcast.find_by(slug: params[:username].downcase)
@organization = Organization.find_by(slug: params[:username].downcase)
@page = Page.find_by(slug: params[:username].downcase, is_top_level_path: true)
if @podcast
handle_podcast_index
elsif @organization
handle_organization_index
elsif @page
handle_page_display
else
handle_user_index
end
@ -98,6 +101,12 @@ class StoriesController < ApplicationController
render template: "articles/tag_index"
end
def handle_page_display
@story_show = true
set_surrogate_key_header "show-page-#{params[:username]}"
render template: "pages/show"
end
def handle_base_index
@home_page = true
@page = (params[:page] || 1).to_i

View file

@ -8,7 +8,11 @@ module ApplicationHelper
end
def view_class
"#{controller_name} #{controller_name}-#{controller.action_name}"
if @story_show #custom due to edge cases
"stories stories-show"
else
"#{controller_name} #{controller_name}-#{controller.action_name}"
end
end
def core_pages?

View file

@ -132,6 +132,6 @@ class Organization < ApplicationRecord
handle_asynchronously :bust_cache
def unique_slug_including_users_and_podcasts
errors.add(:slug, "is taken.") if User.find_by(username: slug) || Podcast.find_by(slug: slug)
errors.add(:slug, "is taken.") if User.find_by(username: slug) || Podcast.find_by(slug: slug) || Page.find_by(slug: slug)
end
end

View file

@ -4,6 +4,7 @@ class Page < ApplicationRecord
validates :slug, presence: true, format: /\A[0-9a-z\-_]*\z/
validates :template, inclusion: { in: %w[contained full_within_layout full_page] }
validate :body_present
validate :unique_slug_including_users_and_orgs, if: :slug_changed?
before_save :evaluate_markdown
after_save :bust_cache
@ -11,6 +12,10 @@ class Page < ApplicationRecord
mount_uploader :social_image, ProfileImageUploader
def path
is_top_level_path ? "/#{slug}" : "/page/#{slug}"
end
private
def evaluate_markdown
@ -30,6 +35,10 @@ class Page < ApplicationRecord
errors.add(:body_markdown, "must exist if body_html doesn't exist.") if body_markdown.blank? && body_html.blank?
end
def unique_slug_including_users_and_orgs
errors.add(:slug, "is taken.") if User.find_by(username: slug) || Organization.find_by(slug: slug) || Podcast.find_by(slug: slug)
end
def bust_cache
CacheBuster.new.bust "/page/#{slug}"
CacheBuster.new.bust "/page/#{slug}?i=i"

View file

@ -22,7 +22,7 @@ class Podcast < ApplicationRecord
private
def unique_slug_including_users_and_orgs
errors.add(:slug, "is taken.") if User.find_by(username: slug) || Organization.find_by(slug: slug)
errors.add(:slug, "is taken.") if User.find_by(username: slug) || Organization.find_by(slug: slug) || Page.find_by(slug: slug)
end
def bust_cache

View file

@ -378,7 +378,7 @@ class User < ApplicationRecord
end
def unique_including_orgs_and_podcasts
errors.add(:username, "is taken.") if Organization.find_by(slug: username) || Podcast.find_by(slug: username)
errors.add(:username, "is taken.") if Organization.find_by(slug: username) || Podcast.find_by(slug: username) || Page.find_by(slug: username)
end
def subscribe_to_mailchimp_newsletter_without_delay

View file

@ -43,11 +43,11 @@
<h4>key links</h4>
</header>
<div class="widget-body">
<a href="https://twitter.com/thepracticaldev" target="_blank" rel="noopener"><img src="<%= asset_path("twitter-logo.svg") %>" alt="Twitter logo" class="social-icon" /></a>
<a href="https://github.com/thepracticaldev" target="_blank" rel="noopener"><img src="<%= asset_path("github-logo.svg") %>" alt="GitHub logo" class="social-icon" /></a>
<a href="https://instagram.com/thepracticaldev" target="_blank" rel="noopener"><img src="<%= asset_path("instagram-logo.svg") %>" alt="Instagram logo" class="social-icon" /></a>
<a href="https://facebook.com/thepracticaldev" target="_blank" rel="noopener"><img src="<%= asset_path("facebook-logo.svg") %>" alt="Facebook logo" class="social-icon" /></a>
<a href="https://twitch.tv/thepracticaldev" target="_blank" rel="noopener"><img src="<%= asset_path("twitch-logo.svg") %>" alt="Twitch logo" class="social-icon" /></a>
<a href="https://twitter.com/<%= ApplicationConfig["SITE_TWITTER_HANDLE"] %>" target="_blank" rel="noopener"><img src="<%= asset_path("twitter-logo.svg") %>" alt="Twitter logo" class="social-icon" /></a>
<a href="https://github.com/<%= ApplicationConfig["SITE_TWITTER_HANDLE"] %>" target="_blank" rel="noopener"><img src="<%= asset_path("github-logo.svg") %>" alt="GitHub logo" class="social-icon" /></a>
<a href="https://instagram.com/<%= ApplicationConfig["SITE_TWITTER_HANDLE"] %>" target="_blank" rel="noopener"><img src="<%= asset_path("instagram-logo.svg") %>" alt="Instagram logo" class="social-icon" /></a>
<a href="https://facebook.com/<%= ApplicationConfig["SITE_TWITTER_HANDLE"] %>" target="_blank" rel="noopener"><img src="<%= asset_path("facebook-logo.svg") %>" alt="Facebook logo" class="social-icon" /></a>
<a href="https://twitch.tv/<%= ApplicationConfig["SITE_TWITTER_HANDLE"] %>" target="_blank" rel="noopener"><img src="<%= asset_path("twitch-logo.svg") %>" alt="Twitch logo" class="social-icon" /></a>
</div>
<div class="side-footer">
<a href="/about">About</a>

View file

@ -16,7 +16,7 @@
<meta property="og:description" content="Where programmers share ideas and help each other grow." />
<meta property="og:site_name" content="<%= community_qualified_name %>" />
<meta name="twitter:site" content="@ThePracticalDev">
<meta name="twitter:site" content="@<%= ApplicationConfig["SITE_TWITTER_HANDLE"] %>">
<meta name="twitter:title" content="<%= title_with_timeframe(page_title: community_qualified_name, timeframe: params[:timeframe]) %>">
<meta name="twitter:description" content="Where programmers share ideas, experiences, and help each other grow.">
<meta name="twitter:image:src" content="<%= ApplicationConfig["MAIN_SOCIAL_IMAGE"] %>">

View file

@ -5,12 +5,12 @@
<a href="/dashboard">Dashboard</a> 👉 Manage Your Post
</div>
<h2>Tools:</h2>
<p><strong>Suggest a Tweet:</strong> Help get your post in front of more developers by suggesting a tweet that <a href="https://twitter.com/thepracticaldev">@ThePracticalDev</a> editors can use.
<p><strong>Suggest a Tweet:</strong> Help get your post in front of more developers by suggesting a tweet that <a href="https://twitter.com/<%= ApplicationConfig["SITE_TWITTER_HANDLE"] %>">@<%= ApplicationConfig["SITE_TWITTER_HANDLE"] %></a> editors can use.
<p><strong>Experience Level of Post:</strong> The best target dev experience level— a <em>gentle</em> indicator to help show the post to the people who will benefit the most.
<h2>Tips:</h2>
<ol>
<li>
Make your own tweet about the post, describing personally why you wrote it or why people might find it useful. <a href="https://twitter.com/thepracticaldev">@ThePracticalDev</a> may retweet you.
Make your own tweet about the post, describing personally why you wrote it or why people might find it useful. <a href="https://twitter.com/<%= ApplicationConfig["SITE_TWITTER_HANDLE"] %>">@<%= ApplicationConfig["SITE_TWITTER_HANDLE"] %></a> may retweet you.
</li>
<li>
Share to link aggregators such as <a href="https://www.reddit.com/">Reddit</a>. Try to choose the most topic-specific subreddits, such as <a href="https://www.reddit.com/r/javascript">/r/javascript</a> instead of <a href="https://www.reddit.com/r/programming">/r/programming</a>. <em>Warning: jerks and trolls may be lurking.</em>

View file

@ -10,7 +10,7 @@
<meta property="og:description" content="Where programmers share ideas and help each other grow." />
<meta property="og:site_name" content="The DEV Community" />
<meta name="twitter:site" content="@ThePracticalDev">
<meta name="twitter:site" content="@<%= ApplicationConfig["SITE_TWITTER_HANDLE"] %>">
<meta name="twitter:title" content="DEV => Search Results">
<meta name="twitter:description" content="Where programmers share ideas, experiences, and help each other grow.">
<meta name="twitter:image:src" content="<%= ApplicationConfig["MAIN_SOCIAL_IMAGE"] %>">

View file

@ -49,7 +49,7 @@
<meta property="og:title" content="<%= @article.title %>" />
<meta property="og:description" content="<%= @article.description || "An article from the community" %>" />
<meta property="og:site_name" content="<%= community_qualified_name %>" />
<meta name="twitter:site" content="@ThePracticalDev">
<meta name="twitter:site" content="@<%= ApplicationConfig["SITE_TWITTER_HANDLE"] %>">
<meta name="twitter:creator" content="@<%= @user.twitter_username %>">
<meta name="twitter:title" content="<%= @article.title %>">
<meta name="twitter:description" content="<%= @article.description || "An article from the community" %>">

View file

@ -13,7 +13,7 @@
<meta property="og:description" content="<%= @tag.capitalize %> content on dev.to" />
<meta property="og:site_name" content="The DEV Community" />
<meta name="twitter:site" content="@ThePracticalDev">
<meta name="twitter:site" content="@<%= ApplicationConfig["SITE_TWITTER_HANDLE"] %>">
<meta name="twitter:creator" content="@<%= @tag.capitalize %>">
<meta name="twitter:title" content="<%= title_with_timeframe(page_title: @tag.capitalize, timeframe: params[:timeframe]) %>">
<meta name="twitter:description" content="<%= @tag.capitalize %> content on dev.to">

View file

@ -22,7 +22,7 @@
<meta name="twitter:description" content="Where programmers share ideas, experiences, and help each other grow.">
<meta name="twitter:image:src" content="https://thepracticaldev.s3.amazonaws.com/i/sa3xjflbtvt9zw0xpan5.png">
<% end %>
<meta name="twitter:site" content="@ThePracticalDev">
<meta name="twitter:site" content="@<%= ApplicationConfig["SITE_TWITTER_HANDLE"] %>">
<meta name="twitter:card" content="summary_large_image">
<% end %>

View file

@ -12,7 +12,7 @@
<meta property="og:title" content="Discussion of <%= @commentable.title %>" />
<meta property="og:description" content="<%= @commentable.description || "A DEV Comment" %>" />
<meta property="og:site_name" content="The DEV Community" />
<meta name="twitter:site" content="@ThePracticalDev">
<meta name="twitter:site" content="@<%= ApplicationConfig["SITE_TWITTER_HANDLE"] %>">
<meta name="twitter:creator" content="@<%= @user.twitter_username %>">
<meta name="twitter:title" content="<%= @commentable.title %>">
<meta name="twitter:description" content="<%= @commentable.description || "A DEV Comment" %>">

View file

@ -10,7 +10,7 @@
<meta property="og:description" content="Talks and workshops designed to help community members level up." />
<meta property="og:site_name" content="The Practical Dev" />
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@ThePracticalDev">
<meta name="twitter:site" content="@<%= ApplicationConfig["SITE_TWITTER_HANDLE"] %>">
<meta name="twitter:title" content="dev.to | Events">
<meta property="og:description" content="Talks and workshops designed to help community members level up." />
<meta name="twitter:image:src" content="https://thepracticaldev.s3.amazonaws.com/i/bhavxzyx2e7bdsyvysve.jpg">

View file

@ -16,7 +16,7 @@
<meta property="og:site_name" content="The Practical Dev" />
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@ThePracticalDev">
<meta name="twitter:site" content="@<%= ApplicationConfig["SITE_TWITTER_HANDLE"] %>">
<meta name="twitter:title" content="<%= truncate(strip_tags(@event.title), length: 70) %>">
<meta property="og:description" content="<%= truncate(strip_tags(@event.description_html), length: 140) %>" />
<% if @event.cover_image.present? %>

View file

@ -1,405 +0,0 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>
<script src="//d79i1fxsrar4t.cloudfront.net/jquery.liveaddress/3.4/jquery.liveaddress.min.js"></script>
<script>
var liveaddress = jQuery.LiveAddress({
key: "<%= ApplicationConfig["SMARTY_STREETS_WEB_KEY"] %>",
target: "US|International",
addresses: [{
address1: '#user_shipping_address',
address2: '#user_shipping_address_line_2',
locality: '#user_shipping_city',
administrative_area: '#user_shipping_state',
postal_code: '#user_shipping_postal_code',
country: '#user_shipping_country'
}]
});
liveaddress.on("OriginalInputSelected", function (event, data, previousHandler) {
$('#user_shipping_validated').attr('checked', false);
previousHandler(event, data);
});
liveaddress.on("AddressWasValid", function (event, data, previousHandler) {
$('#user_shipping_validated').attr('checked', true);
previousHandler(event, data);
});
</script>
<%= form_for(@user, url: "/giveaways/freestickers") do |f| %>
<% if @errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@errors.size, "issue") %> prohibited your form from being submitted:</h2>
<ul>
<% @errors.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<h2>Shipping Information</h2>
<% if @user.email.blank? %>
<div class="field">
<%= f.label :email, "Email" %><br>
<%= f.text_field :email %>
</div>
<% end %>
<div class="field">
<%= f.label :shipping_name, "Name (for shipping)" %><br>
<%= f.text_field :shipping_name %>
</div>
<div class="field">
<%= f.label :shipping_company, "Company (for shipping if applicable)" %><br>
<%= f.text_field :shipping_company %>
</div>
<div class="field">
<%= f.label :shipping_address, "Address" %><br>
<%= f.text_field :shipping_address %>
</div>
<div class="field">
<%= f.label :shipping_address_line_2, "Address Line 2" %><br>
<%= f.text_field :shipping_address_line_2 %>
</div>
<div class="field">
<%= f.label :shipping_city, "City" %><br>
<%= f.text_field :shipping_city %>
</div>
<div class="field">
<%= f.label :shipping_state, "State/Province" %><br>
<%= f.text_field :shipping_state %>
</div>
<div class="field">
<%= f.label :shipping_country, "Country" %><br>
<%= f.select :shipping_country,
options_for_select(
[["United States", "US"],
["-----", ""],
%w[Afghanistan AF],
["Åland Islands", "AX"],
%w[Albania AL],
%w[Algeria DZ],
["American Samoa", "AS"],
%w[Andorra AD],
%w[Angola AO],
%w[Anguilla AI],
%w[Antarctica AQ],
["Antigua and Barbuda", "AG"],
%w[Argentina AR],
%w[Armenia AM],
%w[Aruba AW],
%w[Australia AU],
%w[Austria AT],
%w[Azerbaijan AZ],
%w[Bahamas BS],
%w[Bahrain BH],
%w[Bangladesh BD],
%w[Barbados BB],
%w[Belarus BY],
%w[Belgium BE],
%w[Belize BZ],
%w[Benin BJ],
%w[Bermuda BM],
%w[Bhutan BT],
%w[Bolivia BO],
%w[Bonaire BQ],
["Bosnia and Herzegovina", "BA"],
%w[Botswana BW],
["Bouvet Island", "BV"],
%w[Brazil BR],
["BIO Territory", "IO"],
["Brunei Darussalam", "BN"],
%w[Bulgaria BG],
["Burkina Faso", "BF"],
%w[Burundi BI],
%w[Cambodia KH],
%w[Cameroon CM],
%w[Canada CA],
["Cape Verde", "CV"],
["Cayman Islands", "KY"],
["Central African Republic", "CF"],
%w[Chad TD],
%w[Chile CL],
%w[China CN],
["Christmas Island", "CX"],
["Cocos (Keeling) Islands", "CC"],
%w[Colombia CO],
%w[Comoros KM],
%w[Congo CG],
%w[Congo CD],
["Cook Islands", "CK"],
["Costa Rica", "CR"],
["Côte d'Ivoire", "CI"],
%w[Croatia HR],
%w[Cuba CU],
%w[Curaçao CW],
%w[Cyprus CY],
["Czech Republic", "CZ"],
%w[Denmark DK],
%w[Djibouti DJ],
%w[Dominica DM],
["Dominican Republic", "DO"],
%w[Ecuador EC],
%w[Egypt EG],
["El Salvador", "SV"],
["Equatorial Guinea", "GQ"],
%w[Eritrea ER],
%w[Estonia EE],
%w[Ethiopia ET],
["Falkland Islands", "FK"],
["Faroe Islands", "FO"],
%w[Fiji FJ],
%w[Finland FI],
%w[France FR],
["French Guiana", "GF"],
["French Polynesia", "PF"],
["French S Territories", "TF"],
%w[Gabon GA],
%w[Gambia GM],
%w[Georgia GE],
%w[Germany DE],
%w[Ghana GH],
%w[Gibraltar GI],
%w[Greece GR],
%w[Greenland GL],
%w[Grenada GD],
%w[Guadeloupe GP],
%w[Guam GU],
%w[Guatemala GT],
%w[Guernsey GG],
%w[Guinea GN],
["Guinea-Bissau", "GW"],
%w[Guyana GY],
%w[Haiti HT],
["Heard McDonald Islands", "HM"],
["Holy See", "VA"],
%w[Honduras HN],
["Hong Kong", "HK"],
%w[Hungary HU],
%w[Iceland IS],
%w[India IN],
%w[Indonesia ID],
%w[Iran IR],
%w[Iraq IQ],
%w[Ireland IE],
["Isle of Man", "IM"],
%w[Israel IL],
%w[Italy IT],
%w[Jamaica JM],
%w[Japan JP],
%w[Jersey JE],
%w[Jordan JO],
%w[Kazakhstan KZ],
%w[Kenya KE],
%w[Kiribati KI],
["Korea, People's Republic", "KP"],
["Korea, Republic of", "KR"],
%w[Kuwait KW],
%w[Kyrgyzstan KG],
%w[Lao LA],
%w[Latvia LV],
%w[Lebanon LB],
%w[Lesotho LS],
%w[Liberia LR],
%w[Libya LY],
%w[Liechtenstein LI],
%w[Lithuania LT],
%w[Luxembourg LU],
%w[Macao MO],
%w[Macedonia MK],
%w[Madagascar MG],
%w[Malawi MW],
%w[Malaysia MY],
%w[Maldives MV],
%w[Mali ML],
%w[Malta MT],
["Marshall Islands", "MH"],
%w[Martinique MQ],
%w[Mauritania MR],
%w[Mauritius MU],
%w[Mayotte YT],
%w[Mexico MX],
%w[Micronesia FM],
["Moldova, Republic of", "MD"],
%w[Monaco MC],
%w[Mongolia MN],
%w[Montenegro ME],
%w[Montserrat MS],
%w[Morocco MA],
%w[Mozambique MZ],
%w[Myanmar MM],
%w[Namibia NA],
%w[Nauru NR],
%w[Nepal NP],
%w[Netherlands NL],
["New Caledonia", "NC"],
["New Zealand", "NZ"],
%w[Nicaragua NI],
%w[Niger NE],
%w[Nigeria NG],
%w[Niue NU],
["Norfolk Island", "NF"],
["Northern Mariana Islands", "MP"],
%w[Norway NO],
%w[Oman OM],
%w[Pakistan PK],
%w[Palau PW],
["Palestinian Territory", "PS"],
%w[Panama PA],
["Papua New Guinea", "PG"],
%w[Paraguay PY],
%w[Peru PE],
%w[Philippines PH],
%w[Pitcairn PN],
%w[Poland PL],
%w[Portugal PT],
["Puerto Rico", "PR"],
%w[Qatar QA],
%w[Réunion RE],
%w[Romania RO],
["Russian Federation", "RU"],
%w[Rwanda RW],
["Saint Barthélemy", "BL"],
["Saint Helena", "SH"],
["Saint Kitts and Nevis", "KN"],
["Saint Lucia", "LC"],
["Saint Martin (French part)", "MF"],
["Saint Pierre and Miquelon", "PM"],
["Saint Vincent, Grenadines", "VC"],
%w[Samoa WS],
["San Marino", "SM"],
["Sao Tome and Principe", "ST"],
["Saudi Arabia", "SA"],
%w[Senegal SN],
%w[Serbia RS],
%w[Seychelles SC],
["Sierra Leone", "SL"],
%w[Singapore SG],
["Sint Maarten (Dutch part)", "SX"],
%w[Slovakia SK],
%w[Slovenia SI],
["Solomon Islands", "SB"],
%w[Somalia SO],
["South Africa", "ZA"],
["South Georgia", "GS"],
["South Sudan", "SS"],
%w[Spain ES],
["Sri Lanka", "LK"],
%w[Sudan SD],
%w[Suriname SR],
["Svalbard and Jan Mayen", "SJ"],
%w[Swaziland SZ],
%w[Sweden SE],
%w[Switzerland CH],
["Syrian Arab Republic", "SY"],
["Taiwan, Province of China", "TW"],
%w[Tajikistan TJ],
%w[Tanzania TZ],
%w[Thailand TH],
["Timor-Leste", "TL"],
%w[Togo TG],
%w[Tokelau TK],
%w[Tonga TO],
["Trinidad and Tobago", "TT"],
%w[Tunisia TN],
%w[Turkey TR],
%w[Turkmenistan TM],
["Turks and Caicos Isl", "TC"],
%w[Tuvalu TV],
%w[Uganda UG],
%w[Ukraine UA],
["United Arab Emirates", "AE"],
["United Kingdom", "GB"],
["United States", "US"],
["United States Minor", "UM"],
%w[Uruguay UY],
%w[Uzbekistan UZ],
%w[Vanuatu VU],
%w[Venezuela VE],
["Viet Nam", "VN"],
["Virgin Islands, British", "VG"],
["Virgin Islands, U.S.", "VI"],
["Wallis and Futuna", "WF"],
["Western Sahara", "EH"],
%w[Yemen YE],
%w[Zambia ZM],
%w[Zimbabwe ZW]],
@user.shipping_country,
) %>
</div>
<div class="field">
<%= f.label :shipping_postal_code, "Zip Number/Postal Code" %><br>
<%= f.text_field :shipping_postal_code %>
</div>
<div style="display: none">
<%= f.label :shipping_validated, "validate" %>
<%= f.check_box :shipping_validated %>
</div>
<h2>T-shirt size</h2>
<div class="field">
<%= f.label :shirt_gender, "Style" %><br>
<%= f.select :shirt_gender,
options_for_select(
[%w[Unisex unisex],
["Women's", "womens"]],
@user.shirt_gender,
) %>
</div>
<div class="field">
<%= f.label :shirt_size, "Size" %><br>
<%= f.select :shirt_size,
options_for_select(
[%w[Small s],
%w[Medium m],
%w[Large l],
["Extra Large", "xl"],
%w[2XL 2xl],
%w[3XL 3xl]],
@user.shirt_size,
) %>
</div>
<h2>A bit about you</h2>
<h3>(This is sort of our "I'm not a robot" test)</h3>
<div class="field">
<%= f.label :top_languages, "Favorite programming languages" %><br>
<%= f.text_field :top_languages %>
</div>
<div class="field">
<%= f.label :specialty, "Specialty (web development, sysadmin, etc.)" %><br>
<%= f.text_field :specialty %>
</div>
<div class="field">
<%= f.label :experience_level, "Programming Experience Level" %><br>
<%= f.select :experience_level,
options_for_select(
[["0 (Complete Newbie)", "0"],
%w[1 1],
%w[2 2],
["3 (Junior Developer)", "3"],
%w[4 4],
%w[5 5],
%w[6 6],
["7 (Experienced Developer)", "7"],
%w[8 8],
%w[9 9],
["10 (Senior Developer)", "10"]],
@user.experience_level,
) %>
</div>
<div class="field">
<%= f.label :tabs_or_spaces, "Tabs or spaces" %><br>
<%= f.select :tabs_or_spaces,
options_for_select(
[%w[Tabs tabs],
%w[Spaces spaces]],
@user.tabs_or_spaces,
) %>
</div>
<div class="actions">
<%= f.submit "Submit" %>
</div>
<p style="font-size:0.7em;line-height:1.3em">
All dev.to users who submit this form will receive a "welcome package" -- there is no element of chance or skill in this promotion. Additionally, there is no purchase necessary, and this offer is void if/where prohibited. Please note that there is a limit of 1 per person, and all entrants will go through a spam filtration procedure. Contact yo@dev.to with any questions, or to inquire about an alternative means of entry for this promotion.
</p>
<% end %>

View file

@ -1,47 +0,0 @@
<h1>Editing Giveaway</h1>
<div class="giveaway-header" style="background-image:url(https://res.cloudinary.com/practicaldev/image/upload/c_scale,f_auto,fl_progressive,q_80,w_1000/v1487774090/stickers_e0antp.png)">
</div>
<div class="giveaway-container">
<% if !current_user %>
<center>
<p>* * *</p>
<h2>Please sign in</h2>
<br />
<a href="/users/auth/twitter?callback_url=<%= ApplicationConfig["APP_PROTOCOL"] %><%= ApplicationConfig["APP_DOMAIN"] %>/users/auth/twitter/callback" class="sign-up-link" data-no-instant><span class="sign-up-text"><img src="<%= asset_url("nerd-emoji.png") %>" alt="nerd emoji" /> Sign in with Twitter</span></a>
<p>or</p>
<a href="/users/auth/github" class="sign-up-link" data-no-instant><span class="sign-up-text github-text"><img src="<%= asset_url("nerd-emoji.png") %>" alt="nerd emoji" /> Sign in with Github</span></a>
</center>
<% elsif current_user.onboarding_package_requested == false %>
<center>
<p>* * *</p>
<p>
It seems you've never requested stickers. </br>
Rest assured, we will have events and giveaways in the future for you look forward to.
</p>
<p>
❤️<br />
Ben & Jess
</p>
</center>
<% elsif current_user.onboarding_package_requested_again == false %>
<%= render "form" %>
<% else %>
<center>
<p>* * *</p>
<h2>
Thank you for the support.
</h2>
<p>
Your stickers should arrive soon.
</p>
<p>
❤️<br />
Ben & Jess
</p>
</center>
<% end %>
</div>

View file

@ -11,7 +11,7 @@
<meta property="og:description" content="Every developer gets free stickers!" />
<meta property="og:site_name" content="The Practical Dev" />
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@ThePracticalDev">
<meta name="twitter:site" content="@<%= ApplicationConfig["SITE_TWITTER_HANDLE"] %>">
<meta name="twitter:title" content="FREE STICKERS - dev.to">
<meta name="twitter:description" content="Every developer gets free stickers!">
<meta property="og:image" content="https://res.cloudinary.com/practicaldev/image/upload/c_scale,f_auto,fl_progressive,q_80,w_1000/v1487774090/stickers_e0antp.png" />

View file

@ -133,7 +133,7 @@
{ author: @<%= article.user.twitter_username %> } #DEVCommunity
<% end %></textarea>
<button class="btn btn-info" style="font-size:1em;">🦅 Tweet to @ThePracticalDev</button>
<button class="btn btn-info" style="font-size:1em;">🦅 Tweet to @<%= ApplicationConfig["SITE_TWITTER_HANDLE"] %></button>
<% end %>
<% if (article.decorate.cached_tag_list_array & Tag.bufferized_tags).any? %>
<%= form_tag "/internal/buffer_updates" do %>

View file

@ -19,6 +19,10 @@
<br/>
<%= form.text_field :description %>
<hr/>
<%= form.label :is_top_level_path %> (Determines if it is accessible by <code>/page-slug</code> vs <code>/page/page-slug</code>) Be careful! ⚠️
<br/>
<%= form.check_box :is_top_level_path %>
<hr/>
<%= form.submit %>
<hr/>

View file

@ -12,7 +12,7 @@
<meta property="og:site_name" content="The Practical Dev" />
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@ThePracticalDev">
<meta name="twitter:site" content="@<%= ApplicationConfig["SITE_TWITTER_HANDLE"] %>">
<meta name="twitter:title" content="Notifications - dev.to">
<meta name="twitter:description" content="Notifications inbox for dev.to">
<% end %>

View file

@ -13,7 +13,7 @@
<meta property="og:site_name" content="<%= ApplicationConfig["COMMUNITY_NAME"] %>" />
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@ThePracticalDev">
<meta name="twitter:site" content="@<%= ApplicationConfig["SITE_TWITTER_HANDLE"] %>">
<meta name="twitter:title" content="About <%= ApplicationConfig["COMMUNITY_NAME"] %>">
<meta name="twitter:description" content="<%= ApplicationConfig["COMMUNITY_NAME"] %> is great!">
<meta name="twitter:image:src" content="http://i.imgur.com/B4JNl1w.png">

View file

@ -10,7 +10,7 @@
<meta property="og:title" content="<%= ApplicationConfig["COMMUNITY_NAME"] %> API" />
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@ThePracticalDev">
<meta name="twitter:site" content="@<%= ApplicationConfig["SITE_TWITTER_HANDLE"] %>">
<meta name="twitter:title" content="<%= ApplicationConfig["COMMUNITY_NAME"] %> API">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.16.0/themes/prism-tomorrow.css" integrity="sha256-0dkohC9ZEupqWbq0hS5cVR4QQXJ+mp6N2oJyuks6gt0=" crossorigin="anonymous" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.16.0/prism.min.js"

View file

@ -13,7 +13,7 @@
<meta property="og:site_name" content="The Practical Dev" />
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@ThePracticalDev">
<meta name="twitter:site" content="@<%= ApplicationConfig["SITE_TWITTER_HANDLE"] %>">
<meta name="twitter:title" content="Add the DEV Badge to your personal site">
<meta name="twitter:description" content="Show visitors that you are an active member of our wonderful community. Put the badge on your personal website or use it as you see fit.">
<meta name="twitter:image:src" content="https://thepracticaldev.s3.amazonaws.com/i/kjn1gduswyrrisc1basc.png">

View file

@ -10,7 +10,7 @@
<meta property="og:title" content="About The Practical Dev Bounty System" />
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@ThePracticalDev">
<meta name="twitter:site" content="@<%= ApplicationConfig["SITE_TWITTER_HANDLE"] %>">
<meta name="twitter:title" content="The Practical Dev Bounty System">
<% end %>

View file

@ -10,7 +10,7 @@
<!-- <meta property="og:description" content="The Practical Dev is great!" /> -->
<meta property="og:site_name" content="The Practical Dev" />
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@ThePracticalDev">
<meta name="twitter:site" content="@<%= ApplicationConfig["SITE_TWITTER_HANDLE"] %>">
<meta name="twitter:title" content="The Practical Dev Code of Conduct">
<!-- <meta name="twitter:description" content="The Practical Dev is great!"> -->
<!-- <meta name="twitter:image:src" content="http://i.imgur.com/B4JNl1w.png"> -->

View file

@ -1,69 +0,0 @@
<% title "Community Moderation Guide for dev.to()" %>
<%= content_for :page_meta do %>
<link rel="canonical" href="https://dev.to/community-moderation" />
<meta name="description" content="Community Moderation Guide for dev.to()">
<meta name="keywords" content="software development,engineering,rails,javascript,ruby">
<meta property="og:type" content="article" />
<meta property="og:url" content="https://dev.to/community-moderation" />
<meta property="og:title" content="Community Moderation Guide for dev.to()" />
<meta property="og:image" content="<%= ApplicationConfig["MAIN_SOCIAL_IMAGE"] %>" />
<meta property="og:description" content="Things to know!" />
<meta property="og:site_name" content="The Practical Dev" />
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@ThePracticalDev">
<meta name="twitter:title" content="Community Moderation Guide for dev.to()">
<meta name="twitter:description" content="Things to know!">
<meta name="twitter:image:src" content="<%= ApplicationConfig["MAIN_SOCIAL_IMAGE"] %>">
<% end %>
<style>
img {
border: solid #444444;
}
</style>
<header>
<div class="blank-space"></div>
</header>
<div class="container article">
<div class="title">
<h1>
Community Moderation
</h1>
</div>
<div class="body">
<p>The DEV Community Moderator program gives trusted users the ability to help promote valuable posts and push down articles that we deem spammy, overly promotional, or unhelpful. It also provides moderators the ability to quickly flag harassment, as well as a few other neat things.</p>
<p>Neat things include:</p>
<ul>
<li>Quick emoji ratings to down-rank content</li>
<li>Suggest a tweet for a post</li>
<li>Rate the experience level of a post</li>
<li>A mod dashboard!</li>
</ul>
<p><strong>To become a community or <a href="/tag-moderation">tag moderator</a>, please email yo@dev.to!</strong></p>
<p>To access these features for an article, append "/mod" to the URL of any article or click "Moderate Post" located underneath the title of each post beside the read time.</p>
<img alt="mod-button-on-articles" src="<%= cloudinary("https://thepracticaldev.s3.amazonaws.com/i/ex81b5zgpfb7tof9ljr5.png") %>" />
<h3>Using our quick emoji rating to down-rank content</h3>
<p>Clicking on the 'thumbsdown' or 'vomit' button will activate them. Here's what each emoji does: </p>
<ol>
<li>Thumbsdown(👎): a quick way to "push content down" so that its less likely to be seen on the site (i.e. articles that only have a teaser paragraph and send the reader to an external link for the rest). </li>
<li>Vomit(🤢): a quick way to flag content that violates the <a href="https://dev.to/code-of-conduct">Code of Conduct</a> or <a href="https://dev.to/terms">Terms</a> so the DEV core team is notified and can take action.</li>
</ol>
<img alt="emoji-on-article-mod-page" src="<%= cloudinary("https://thepracticaldev.s3.amazonaws.com/i/snt5p004ck8b3xfhftkt.png") %>" />
<p>To down-rank comments, append /mod to the comment permalink or click 'moderate' from the ellipses on the comment.</p>
<img alt="comment-dropdown" src="<%= cloudinary("https://thepracticaldev.s3.amazonaws.com/i/ms02ntw0frn8j2rs214l.png") %>">
<h3>Suggesting a tweet for a post</h3>
<p>If you think a post is particularly good, help us craft a tweet to give it a shout out through one of our Twitter accounts. The tweet suggestion is not guaranteed to be used, but will be reviewed by a team member.</p>
<img alt="tweet-form" src="<%= cloudinary("https://thepracticaldev.s3.amazonaws.com/i/j58pg0ci23urj0jqh5oe.png") %>">
<h3>Rating the experience level of a post</h3>
<p>Using the 1-10 scale (1: beginner; 10: most advanced), rate what you believe a post's experience level to be. While this is somewhat subjective, just use your best judgement taking into account any bias you may have based on your own knowledge of the topic. This will help us bring more relevant posts to each individual's feed depending on their experience level.</p>
<img alt="experience-level-buttons" src="<%= cloudinary("https://thepracticaldev.s3.amazonaws.com/i/o7hz1ii15n9ywubgxwd9.png") %>">
<h3>Mod Dashboard</h3>
<p>To do the above two things (suggest-a-tweet & rate experience levels) in bulk, visit: <a href="/mod">dev.to/mod</a>!</p>
</div>
<br>
</div>

View file

@ -13,7 +13,7 @@
<meta property="og:site_name" content="The Practical Dev" />
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@ThePracticalDev">
<meta name="twitter:site" content="@<%= ApplicationConfig["SITE_TWITTER_HANDLE"] %>">
<meta name="twitter:title" content="Contact The Practical Dev">
<meta name="twitter:description" content="The Practical Dev is great!">
<meta name="twitter:image:src" content="http://i.imgur.com/B4JNl1w.png">
@ -33,7 +33,7 @@
Email: <a href="mailto:yo@dev.to">yo@dev.to</a> 😁
</p>
<p>
Twitter: <a href="http://twitter.com/thepracticaldev">@thepracticaldev</a> 👻
Twitter: <a href="http://twitter.com/<%= ApplicationConfig["SITE_TWITTER_HANDLE"] %>">@<%= ApplicationConfig["SITE_TWITTER_HANDLE"] %></a> 👻
</p>
<p>
Report a vulnerability: <a href="https://dev.to/security">dev.to/security</a> 🐛

View file

@ -1,7 +1,6 @@
<% title @page.title %>
<%= content_for :page_meta do %>
<link rel="canonical" href="https://dev.to<%= request.path %>" />
<link rel="canonical" href="https://dev.to<%= @page.path %>" />
<meta name="description" content="<%= @page.title %> — <%= community_qualified_name %>">
<meta name="keywords" content="software development,engineering,rails,javascript,ruby">
@ -36,3 +35,4 @@
<% else %>
<%= @page.processed_html.html_safe %>
<% end %>
<div id="IS_CENTERED_PAGE"></div>

View file

@ -1,80 +0,0 @@
<% title "Tag Moderation Guide for dev.to()" %>
<%= content_for :page_meta do %>
<link rel="canonical" href="https://dev.to/tag-moderation" />
<meta name="description" content="Tag Moderation Guide for dev.to()">
<meta name="keywords" content="software development,engineering,rails,javascript,ruby">
<meta property="og:type" content="article" />
<meta property="og:url" content="https://dev.to/tag-moderation" />
<meta property="og:title" content="Tag Moderation Guide for dev.to()" />
<meta property="og:image" content="<%= ApplicationConfig["MAIN_SOCIAL_IMAGE"] %>" />
<meta property="og:description" content="Things to know!" />
<meta property="og:site_name" content="The Practical Dev" />
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@ThePracticalDev">
<meta name="twitter:title" content="Tag Moderation Guide for dev.to()">
<meta name="twitter:description" content="Things to know!">
<meta name="twitter:image:src" content="<%= ApplicationConfig["MAIN_SOCIAL_IMAGE"] %>">
<% end %>
<style>
img {
border: solid #444444;
}
</style>
<header>
<div class="blank-space"></div>
</header>
<div class="container article">
<div class="title">
<h1>
Tag Moderation Guide
</h1>
</div>
<div class="body">
<p>The DEV Tag Moderator program gives trusted users the abiliy to help moderate content that appear under the tags they are moderating. You can see who the moderators of each tag are by visiting the tag page. (i.e. <a href="/t/ruby">ruby tag page</a>). Tag moderators have the ability to:</p>
<ul>
<li>Remove tags you are moderating from certain posts</li>
<li>Update the tag sidebar (i.e. add a description, submission guideline, etc).</li>
<li>Update the tags pretty name and colors.</li>
<li>Bulk suggest tweets and update experience levels for tags you moderate.</li>
</ul>
<p>In addition, tag moderators are also considered community moderators and have additional privileges listed <a href="/community-moderation">here</a>.<strong> If you're interested in becoming a community or tag moderator, please email yo@dev.to!</strong></p>
<h3>How to remove tags from a post</h3>
<p>If you are the moderator of a tag, you have the ability to remove that tag from posts that should not contain it. This action helps us keep content categorized appropriately so that people can confidently follow tags, knowing that they'll see the subjects they're interested in.</p>
<ol>
<li>Visit the article in question.</li>
<li>Append /mod to the end of the article URL (i.e. https://dev.to/ben/devto-is-now-open-source-5n1/mod)</li>
<li>You'll see the below form. Update the appropriate fields. Please include the reason for removing your tag from this post.
<strong>The author will receive a notification that the tag has been removed</strong>, along with your reason for removing it.
</li>
<li>
<strong>Note: once you remove the tag, the author will not be able to add it back.</strong> Only remove tags when you are confident they are not appropriate, and please do not remove tags simply because you did not like the post.
</li>
<li>Click remove!</li>
</ol>
<img alt="tag-removal-form" src="<%= cloudinary("https://thepracticaldev.s3.amazonaws.com/i/u67xiw2uon9g5mhbbeff.png") %>">
<h3>How to Update the Tag Sidebar</h3>
<ol>
<li>Visit: https://dev.to/t/{tag name}/edit (i.e. https://dev.to/t/discuss/edit)</li>
<li>Update form. See below for a reference for each field. All field accept markdown
<em>except</em> the pretty name and summary
</li>
<li>Click Save!</li>
</ol>
<img alt="tag-edit-form" src="<%= cloudinary("https://thepracticaldev.s3.amazonaws.com/i/my9u83otmqzep38lo3ib.png") %>">
<br>
<img alt="example-tag-page" src="<%= cloudinary("https://thepracticaldev.s3.amazonaws.com/i/cc8vz48djnhty6c31jog.png") %>">
<h3>Bulk Suggest Tweets & Update Experience Level</h3>
<p>Visit https://dev.to/mod?tag={your_tag_name} to make bulk suggestions for article tweets and experience levels. To learn more about these features and what they do, visit the <a href="/community-moderation">community moderation</a> page. </p>
<h4>Examples of supported tags:</h4>
<ul>
<li><a href="https://dev.to/t/shecoded">#shecoded</a></li>
<li><a href="https://dev.to/t/weeklyui">#weeklyui</a></li>
<li><a href="https://dev.to/t/meta">#meta</a></li>
</ul>
</div>
</div>

View file

@ -226,7 +226,6 @@ Rails.application.routes.draw do
get "/privacy" => "pages#privacy"
get "/terms" => "pages#terms"
get "/contact" => "pages#contact"
get "/merch" => "pages#merch"
get "/rlygenerator" => "pages#generator"
get "/orlygenerator" => "pages#generator"
get "/rlyslack" => "pages#generator"
@ -254,12 +253,7 @@ Rails.application.routes.draw do
post "comments/preview" => "comments#preview"
get "/stories/warm_comments/:username/:slug" => "stories#warm_comments"
get "/freestickers" => "giveaways#new"
get "/freestickers/edit" => "giveaways#edit"
get "/scholarship", to: redirect("/p/scholarships")
get "/scholarships", to: redirect("/p/scholarships")
get "/shop", to: redirect("https://shop.dev.to/")
get "/tag-moderation" => "pages#tag_moderation"
get "/community-moderation" => "pages#community_moderation"
get "/mod" => "moderations#index"
post "/fallback_activity_recorder" => "ga_events#create"

View file

@ -0,0 +1,6 @@
class AddIsTopLevelPathToPages < ActiveRecord::Migration[5.2]
def change
add_column :pages, :is_top_level_path, :boolean, default: false
add_index :pages, :slug, unique: true
end
end

View file

@ -12,9 +12,8 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2019_06_14_093041) do
ActiveRecord::Schema.define(version: 2019_06_16_024727) do
# These are extensions that must be enabled in order to support this database
enable_extension "pg_stat_statements"
enable_extension "plpgsql"
create_table "ahoy_messages", id: :serial, force: :cascade do |t|
@ -626,12 +625,14 @@ ActiveRecord::Schema.define(version: 2019_06_14_093041) do
t.string "description"
t.string "group"
t.integer "group_order_number"
t.boolean "is_top_level_path", default: false
t.text "processed_html"
t.string "slug"
t.string "social_image"
t.string "template"
t.string "title"
t.datetime "updated_at", null: false
t.index ["slug"], name: "index_pages_on_slug", unique: true
end
create_table "podcast_episodes", id: :serial, force: :cascade do |t|
@ -893,6 +894,7 @@ ActiveRecord::Schema.define(version: 2019_06_14_093041) do
t.text "base_cover_letter"
t.string "behance_url"
t.string "bg_color_hex"
t.text "cached_chat_channel_memberships"
t.boolean "checked_code_of_conduct", default: false
t.integer "comments_count", default: 0, null: false
t.string "config_font", default: "default"
@ -1015,6 +1017,7 @@ ActiveRecord::Schema.define(version: 2019_06_14_093041) do
t.string "stackoverflow_url"
t.string "stripe_id_code"
t.text "summary"
t.text "summary_html"
t.string "tabs_or_spaces"
t.string "text_color_hex"
t.string "text_only_name"

View file

@ -94,6 +94,13 @@ RSpec.describe Organization, type: :model do
expect(organization).not_to be_valid
expect(organization.errors[:slug].to_s.include?("taken")).to be true
end
it "takes page slug into account" do
create(:page, slug: "needed_info_for_site")
organization = build(:organization, slug: "needed_info_for_site")
expect(organization).not_to be_valid
expect(organization.errors[:slug].to_s.include?("taken")).to be true
end
end
describe "#url" do

View file

@ -23,4 +23,27 @@ RSpec.describe Page, type: :model do
expect(page).not_to be_valid
end
end
describe "#validations" do
it "takes organization slug into account" do
create(:organization, slug: "benandfriends")
page = build(:page, slug: "benandfriends")
expect(page).not_to be_valid
expect(page.errors[:slug].to_s.include?("taken")).to be true
end
it "takes podcast slug into account" do
create(:podcast, slug: "benmeetsworld")
page = build(:page, slug: "benmeetsworld")
expect(page).not_to be_valid
expect(page.errors[:slug].to_s.include?("taken")).to be true
end
it "takes user username into account" do
create(:user, username: "bennybenben")
page = build(:page, slug: "bennybenben")
expect(page).not_to be_valid
expect(page.errors[:slug].to_s.include?("taken")).to be true
end
end
end

View file

@ -46,6 +46,13 @@ RSpec.describe Podcast, type: :model do
expect(user_podcast.errors[:slug]).to be_present
end
it "is invalid when a page with a slug equal to the podcast slug exists" do
create(:page, slug: "superpage")
user_podcast = build(:podcast, slug: "superpage")
expect(user_podcast).not_to be_valid
expect(user_podcast.errors[:slug]).to be_present
end
it "is invalid when an org with a slug equal to the podcast slug exists" do
create(:organization, slug: "superorganization")
user_podcast = build(:podcast, slug: "superorganization")

View file

@ -57,6 +57,13 @@ RSpec.describe User, type: :model do
expect(user).not_to be_valid
expect(user.errors[:username].to_s.include?("taken")).to be true
end
it "takes page slug into account" do
create(:page, slug: "page_yo")
user = build(:user, username: "page_yo")
expect(user).not_to be_valid
expect(user.errors[:username].to_s.include?("taken")).to be true
end
end
# the followings are failing

View file

@ -2,10 +2,19 @@ require "rails_helper"
RSpec.describe "Pages", type: :request do
describe "GET /:slug" do
it "has proper headline" do
it "has proper headline for non-top-level" do
page = create(:page, title: "Edna O'Brien96")
get "/page/#{page.slug}"
expect(response.body).to include(CGI.escapeHTML(page.title))
expect(response.body).to include("/page/#{page.slug}")
end
it "has proper headline for top-level" do
page = create(:page, title: "Edna O'Brien96", is_top_level_path: true)
get "/#{page.slug}"
expect(response.body).to include(CGI.escapeHTML(page.title))
expect(response.body).not_to include("/page/#{page.slug}")
expect(response.body).to include("stories-show")
end
end

View file

@ -1,52 +0,0 @@
require "rails_helper"
RSpec.describe "Freestickers giveaway (wind-down)", type: :system do
let(:user) { create(:user, onboarding_package_requested: true) }
let(:success_message) { "Your stickers should arrive soon" }
let(:error_messages) do
[
"You need a shipping name",
"You need a shipping address",
"You need a shipping city",
"You need a shipping country",
"You need to include your favorite languages. It's a spam filter.",
]
end
def fill_form
fill_in "Name (for shipping)", with: user.name
fill_in "Company (for shipping if applicable)", with: "what"
fill_in "Address", with: "is"
fill_in "Address Line 2", with: "this"
fill_in "City", with: "New York"
fill_in "State/Province", with: "NY"
select "Canada", from: "Country"
fill_in "Zip Number/Postal Code", with: "10036"
fill_in "Favorite programming languages", with: "JavaScript"
fill_in "Specialty (web development, sysadmin, etc.)", with: "Software Developer"
end
before { sign_in(user) }
it "user fills out giveaway form correctly" do
visit "freestickers/edit"
fill_form
click_button("Submit")
expect(page).to have_text(success_message)
end
it "user fills out giveaway form incorrectly" do
visit "freestickers/edit"
# if we don't select '-----', the form will take 'US' because it is listed first
select "-----", from: "Country"
click_button("Submit")
expect(page).to have_css "div#error_explanation"
error_messages.all? { |error| expect(page).to have_text(error) }
end
it "user already filled out the re-request giveaway form" do
user.onboarding_package_requested_again = true
visit "freestickers/edit"
expect(page).to have_text(success_message)
end
end