From a1b03f9f696183d5bee5d9355ceae48a806db130 Mon Sep 17 00:00:00 2001 From: nertc Date: Wed, 8 Jan 2025 14:22:21 +0400 Subject: [PATCH] Add social profile links --- .../images/social_link_icons/discord.svg | 3 + .../images/social_link_icons/facebook.svg | 3 + .../images/social_link_icons/github.svg | 3 + .../images/social_link_icons/gitlab.svg | 3 + .../images/social_link_icons/instagram.svg | 3 + app/assets/images/social_link_icons/line.svg | 3 + .../images/social_link_icons/linkedin.svg | 3 + .../images/social_link_icons/mastodon.svg | 3 + .../images/social_link_icons/medium.svg | 3 + app/assets/images/social_link_icons/other.svg | 3 + app/assets/images/social_link_icons/quora.svg | 3 + .../images/social_link_icons/reddit.svg | 4 ++ app/assets/images/social_link_icons/skype.svg | 3 + app/assets/images/social_link_icons/slack.svg | 3 + .../images/social_link_icons/snapchat.svg | 3 + .../social_link_icons/stackoverflow.svg | 4 ++ .../images/social_link_icons/strava.svg | 3 + .../images/social_link_icons/substack.svg | 3 + .../images/social_link_icons/telegram.svg | 3 + .../images/social_link_icons/threads.svg | 3 + .../images/social_link_icons/tiktok.svg | 3 + .../images/social_link_icons/twitch.svg | 4 ++ .../images/social_link_icons/twitter_x.svg | 3 + app/assets/images/social_link_icons/vimeo.svg | 3 + .../images/social_link_icons/whatsapp.svg | 3 + .../images/social_link_icons/youtube.svg | 3 + app/assets/javascripts/user.js | 27 ++++++++ app/controllers/profiles_controller.rb | 3 + app/models/social_link.rb | 67 +++++++++++++++++++ app/models/user.rb | 3 + app/views/profiles/edit.html.erb | 15 +++++ app/views/social_links/_show.html.erb | 8 +++ app/views/users/show.html.erb | 17 +++-- config/locales/en.yml | 9 +++ .../20250106113207_create_social_links.rb | 10 +++ db/structure.sql | 63 +++++++++++++++++ test/controllers/profiles_controller_test.rb | 9 +++ test/factories/social_link.rb | 6 ++ test/models/social_link_test.rb | 49 ++++++++++++++ 39 files changed, 361 insertions(+), 6 deletions(-) create mode 100644 app/assets/images/social_link_icons/discord.svg create mode 100644 app/assets/images/social_link_icons/facebook.svg create mode 100644 app/assets/images/social_link_icons/github.svg create mode 100644 app/assets/images/social_link_icons/gitlab.svg create mode 100644 app/assets/images/social_link_icons/instagram.svg create mode 100644 app/assets/images/social_link_icons/line.svg create mode 100644 app/assets/images/social_link_icons/linkedin.svg create mode 100644 app/assets/images/social_link_icons/mastodon.svg create mode 100644 app/assets/images/social_link_icons/medium.svg create mode 100644 app/assets/images/social_link_icons/other.svg create mode 100644 app/assets/images/social_link_icons/quora.svg create mode 100644 app/assets/images/social_link_icons/reddit.svg create mode 100644 app/assets/images/social_link_icons/skype.svg create mode 100644 app/assets/images/social_link_icons/slack.svg create mode 100644 app/assets/images/social_link_icons/snapchat.svg create mode 100644 app/assets/images/social_link_icons/stackoverflow.svg create mode 100644 app/assets/images/social_link_icons/strava.svg create mode 100644 app/assets/images/social_link_icons/substack.svg create mode 100644 app/assets/images/social_link_icons/telegram.svg create mode 100644 app/assets/images/social_link_icons/threads.svg create mode 100644 app/assets/images/social_link_icons/tiktok.svg create mode 100644 app/assets/images/social_link_icons/twitch.svg create mode 100644 app/assets/images/social_link_icons/twitter_x.svg create mode 100644 app/assets/images/social_link_icons/vimeo.svg create mode 100644 app/assets/images/social_link_icons/whatsapp.svg create mode 100644 app/assets/images/social_link_icons/youtube.svg create mode 100644 app/models/social_link.rb create mode 100644 app/views/social_links/_show.html.erb create mode 100644 db/migrate/20250106113207_create_social_links.rb create mode 100644 test/factories/social_link.rb create mode 100644 test/models/social_link_test.rb diff --git a/app/assets/images/social_link_icons/discord.svg b/app/assets/images/social_link_icons/discord.svg new file mode 100644 index 0000000000..5f5bdd6aa6 --- /dev/null +++ b/app/assets/images/social_link_icons/discord.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/app/assets/images/social_link_icons/facebook.svg b/app/assets/images/social_link_icons/facebook.svg new file mode 100644 index 0000000000..e9e7963544 --- /dev/null +++ b/app/assets/images/social_link_icons/facebook.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/app/assets/images/social_link_icons/github.svg b/app/assets/images/social_link_icons/github.svg new file mode 100644 index 0000000000..51b1a80019 --- /dev/null +++ b/app/assets/images/social_link_icons/github.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/app/assets/images/social_link_icons/gitlab.svg b/app/assets/images/social_link_icons/gitlab.svg new file mode 100644 index 0000000000..760ea7c6ca --- /dev/null +++ b/app/assets/images/social_link_icons/gitlab.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/app/assets/images/social_link_icons/instagram.svg b/app/assets/images/social_link_icons/instagram.svg new file mode 100644 index 0000000000..2724fbd5bd --- /dev/null +++ b/app/assets/images/social_link_icons/instagram.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/app/assets/images/social_link_icons/line.svg b/app/assets/images/social_link_icons/line.svg new file mode 100644 index 0000000000..3808c88e23 --- /dev/null +++ b/app/assets/images/social_link_icons/line.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/app/assets/images/social_link_icons/linkedin.svg b/app/assets/images/social_link_icons/linkedin.svg new file mode 100644 index 0000000000..59f2e4533f --- /dev/null +++ b/app/assets/images/social_link_icons/linkedin.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/app/assets/images/social_link_icons/mastodon.svg b/app/assets/images/social_link_icons/mastodon.svg new file mode 100644 index 0000000000..44a2730f37 --- /dev/null +++ b/app/assets/images/social_link_icons/mastodon.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/app/assets/images/social_link_icons/medium.svg b/app/assets/images/social_link_icons/medium.svg new file mode 100644 index 0000000000..b0c359ec84 --- /dev/null +++ b/app/assets/images/social_link_icons/medium.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/app/assets/images/social_link_icons/other.svg b/app/assets/images/social_link_icons/other.svg new file mode 100644 index 0000000000..b78b4c73d9 --- /dev/null +++ b/app/assets/images/social_link_icons/other.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/app/assets/images/social_link_icons/quora.svg b/app/assets/images/social_link_icons/quora.svg new file mode 100644 index 0000000000..e18e02e3f0 --- /dev/null +++ b/app/assets/images/social_link_icons/quora.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/app/assets/images/social_link_icons/reddit.svg b/app/assets/images/social_link_icons/reddit.svg new file mode 100644 index 0000000000..dba2cb3f4b --- /dev/null +++ b/app/assets/images/social_link_icons/reddit.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/app/assets/images/social_link_icons/skype.svg b/app/assets/images/social_link_icons/skype.svg new file mode 100644 index 0000000000..ff4833d9da --- /dev/null +++ b/app/assets/images/social_link_icons/skype.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/app/assets/images/social_link_icons/slack.svg b/app/assets/images/social_link_icons/slack.svg new file mode 100644 index 0000000000..4698314471 --- /dev/null +++ b/app/assets/images/social_link_icons/slack.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/app/assets/images/social_link_icons/snapchat.svg b/app/assets/images/social_link_icons/snapchat.svg new file mode 100644 index 0000000000..a19a51993d --- /dev/null +++ b/app/assets/images/social_link_icons/snapchat.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/app/assets/images/social_link_icons/stackoverflow.svg b/app/assets/images/social_link_icons/stackoverflow.svg new file mode 100644 index 0000000000..24aaca0ace --- /dev/null +++ b/app/assets/images/social_link_icons/stackoverflow.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/app/assets/images/social_link_icons/strava.svg b/app/assets/images/social_link_icons/strava.svg new file mode 100644 index 0000000000..8e8625c167 --- /dev/null +++ b/app/assets/images/social_link_icons/strava.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/app/assets/images/social_link_icons/substack.svg b/app/assets/images/social_link_icons/substack.svg new file mode 100644 index 0000000000..d0d6d6d3aa --- /dev/null +++ b/app/assets/images/social_link_icons/substack.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/app/assets/images/social_link_icons/telegram.svg b/app/assets/images/social_link_icons/telegram.svg new file mode 100644 index 0000000000..1b77dce2ad --- /dev/null +++ b/app/assets/images/social_link_icons/telegram.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/app/assets/images/social_link_icons/threads.svg b/app/assets/images/social_link_icons/threads.svg new file mode 100644 index 0000000000..99ec962892 --- /dev/null +++ b/app/assets/images/social_link_icons/threads.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/app/assets/images/social_link_icons/tiktok.svg b/app/assets/images/social_link_icons/tiktok.svg new file mode 100644 index 0000000000..18f99ae1e9 --- /dev/null +++ b/app/assets/images/social_link_icons/tiktok.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/app/assets/images/social_link_icons/twitch.svg b/app/assets/images/social_link_icons/twitch.svg new file mode 100644 index 0000000000..8e3ac6fbf2 --- /dev/null +++ b/app/assets/images/social_link_icons/twitch.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/app/assets/images/social_link_icons/twitter_x.svg b/app/assets/images/social_link_icons/twitter_x.svg new file mode 100644 index 0000000000..d51006674d --- /dev/null +++ b/app/assets/images/social_link_icons/twitter_x.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/app/assets/images/social_link_icons/vimeo.svg b/app/assets/images/social_link_icons/vimeo.svg new file mode 100644 index 0000000000..13c9fcf58b --- /dev/null +++ b/app/assets/images/social_link_icons/vimeo.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/app/assets/images/social_link_icons/whatsapp.svg b/app/assets/images/social_link_icons/whatsapp.svg new file mode 100644 index 0000000000..e24000ea43 --- /dev/null +++ b/app/assets/images/social_link_icons/whatsapp.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/app/assets/images/social_link_icons/youtube.svg b/app/assets/images/social_link_icons/youtube.svg new file mode 100644 index 0000000000..38b2704b08 --- /dev/null +++ b/app/assets/images/social_link_icons/youtube.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/app/assets/javascripts/user.js b/app/assets/javascripts/user.js index b94db8b557..2536b53722 100644 --- a/app/assets/javascripts/user.js +++ b/app/assets/javascripts/user.js @@ -225,4 +225,31 @@ $(document).ready(function () { $("#read_tou").on("click", function () { $("#continue").prop("disabled", !($(this).prop("checked") && $("#read_ct").prop("checked"))); }); + + $("#add-social-link").click(function (event) { + event.preventDefault(); + const newIndex = -(new Date().getTime()); + const socialLinkForm = $(` + + `); + + socialLinkForm.find("button").click(function () { + $(this).parent().remove(); + }); + + $("#social_links").append(socialLinkForm); + }); + + $(".social_link_destroy input[type='checkbox']").change(function () { + $(this).parent().parent().addClass("d-none"); + }); + + $(".social_link_destroy input[type='checkbox']:checked").each(function () { + $(this).parent().parent().addClass("d-none"); + }); }); diff --git a/app/controllers/profiles_controller.rb b/app/controllers/profiles_controller.rb index 4005176ce1..428b1e36f6 100644 --- a/app/controllers/profiles_controller.rb +++ b/app/controllers/profiles_controller.rb @@ -12,6 +12,9 @@ class ProfilesController < ApplicationController def edit; end def update + social_links_params = params.require(:user).permit(:social_links_attributes => [:id, :url, :_destroy]) + current_user.assign_attributes(social_links_params) + if params[:user][:description] != current_user.description current_user.description = params[:user][:description] current_user.description_format = "markdown" diff --git a/app/models/social_link.rb b/app/models/social_link.rb new file mode 100644 index 0000000000..3c95258b88 --- /dev/null +++ b/app/models/social_link.rb @@ -0,0 +1,67 @@ +# == Schema Information +# +# Table name: social_links +# +# id :bigint(8) not null, primary key +# user_id :bigint(8) not null +# url :string not null +# created_at :datetime not null +# updated_at :datetime not null +# +# Indexes +# +# index_social_links_on_user_id (user_id) +# +# Foreign Keys +# +# fk_rails_... (user_id => users.id) +# + +class SocialLink < ApplicationRecord + belongs_to :user + + validates :url, :format => { :with => %r{\Ahttps?://}, :message => I18n.t("profiles.edit.social_links.http_parse_error") } + + URL_PATTERNS = { + :discord => %r{discord\.com/users/(\d+)}, + :facebook => %r{facebook\.com/([a-zA-Z0-9.]+)}, + :github => %r{github\.com/([a-zA-Z0-9_-]+)}, + :gitlab => %r{gitlab\.com/([a-zA-Z0-9_-]+)}, + :instagram => %r{instagram\.com/([a-zA-Z0-9._]+)}, + :linkedin => %r{linkedin\.com/in/([a-zA-Z0-9_-]+)}, + :line => %r{line\.me/ti/p/([a-zA-Z0-9_-]+)}, + :mastodon => %r{mastodon\.social/@([a-zA-Z0-9_]+)}, + :medium => %r{medium\.com/@([a-zA-Z0-9_]+)}, + :quora => %r{quora\.com/profile/([a-zA-Z0-9_-]+)}, + :reddit => %r{reddit\.com/user/([a-zA-Z0-9_-]+)}, + :skype => %r{join\.skype\.com/invite/([a-zA-Z0-9_-]+)}, + :slack => %r{join\.slack\.com/shareDM/([a-zA-Z0-9_~-]+)}, + :snapchat => %r{snapchat\.com/add/([a-zA-Z0-9_-]+)}, + :stackoverflow => %r{stackoverflow\.com/users/(\d+/[a-zA-Z0-9_-]+)}, + :strava => %r{strava\.com/athletes/([a-zA-Z0-9_-]+)}, + :substack => %r{substack\.com/@([a-zA-Z0-9_-]+)}, + :telegram => %r{t\.me/([a-zA-Z0-9_]+)}, + :threads => %r{threads\.net/@([a-zA-Z0-9_]+)}, + :tiktok => %r{tiktok\.com/@([a-zA-Z0-9_]+)}, + :twitch => %r{twitch\.tv/([a-zA-Z0-9_]+)}, + :twitter_x => %r{(?:twitter|x)\.com/([a-zA-Z0-9_]+)}, + :vimeo => %r{vimeo.com/([a-zA-Z0-9_]+)}, + :whatsapp => %r{wa\.me/(\d+)}, + :youtube => %r{youtube\.com/@([a-zA-Z0-9_-]+)} + }.freeze + + NO_USERNAME_PLATFORMS = %w[discord line skype slack].freeze + + def parsed + URL_PATTERNS.each do |platform, pattern| + names = url.match(pattern) + if names + return { + :platform => platform.to_s, + :name => NO_USERNAME_PLATFORMS.include?(platform.to_s) ? platform.to_s.capitalize : names[1] + } + end + end + { :platform => nil, :name => url } + end +end diff --git a/app/models/user.rb b/app/models/user.rb index 917faca218..01ff711c91 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -87,6 +87,9 @@ class User < ApplicationRecord has_many :reports + has_many :social_links + accepts_nested_attributes_for :social_links, :allow_destroy => true + scope :visible, -> { where(:status => %w[pending active confirmed]) } scope :active, -> { where(:status => %w[active confirmed]) } scope :identifiable, -> { where(:data_public => true) } diff --git a/app/views/profiles/edit.html.erb b/app/views/profiles/edit.html.erb index ac76b4d2d5..7349e618ab 100644 --- a/app/views/profiles/edit.html.erb +++ b/app/views/profiles/edit.html.erb @@ -40,6 +40,21 @@ +
+ <%= t ".social_links.legend" %> + + + +
+
<%= t ".home location" -%>

<%= t ".no home location" %>

diff --git a/app/views/social_links/_show.html.erb b/app/views/social_links/_show.html.erb new file mode 100644 index 0000000000..6bfa5c5a20 --- /dev/null +++ b/app/views/social_links/_show.html.erb @@ -0,0 +1,8 @@ +<% social_links.each do |social_link| %> +

+ <%= image_tag "/assets/social_link_icons/#{social_link.parsed[:platform].nil? ? 'other' : social_link.parsed[:platform]}.svg", + :alt => social_link.parsed[:platform].nil? ? "other" : social_link.parsed[:platform], + :class => "me-2" %> + <%= link_to social_link.parsed[:name], social_link.url, :class => "text-body-secondary", :rel => "nofollow me" %> +

+<% end %> diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb index c168972aac..a205b0ee90 100644 --- a/app/views/users/show.html.erb +++ b/app/views/users/show.html.erb @@ -233,10 +233,15 @@ <% end %> -
<%= @user.description.to_html %>
- -<% if current_user and @user.id == current_user.id %> -
- <%= link_to t(".edit_profile"), edit_profile_path, :class => "btn btn-outline-primary" %> +
+
+ <%= render "social_links/show", + :social_links => @user.social_links %> + <% if current_user and @user.id == current_user.id %> +
+ <%= link_to t(".edit_profile"), edit_profile_path, :class => "btn btn-outline-primary" %> +
+ <% end %>
-<% end %> +
<%= @user.description.to_html %>
+
diff --git a/config/locales/en.yml b/config/locales/en.yml index 4f21742065..189dd5f25e 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1877,6 +1877,11 @@ en: show: "Show" delete: "Delete" undelete: "Undo delete" + social_links: + legend: Social Profile Links + remove: Remove + add: Add Social Link + http_parse_error: Url should start with http:// or https:// update: success: Profile updated. failure: Couldn't update profile. @@ -3256,6 +3261,10 @@ en: ninth: "9th" tenth: "10th" time: "Time" + profiles: + edit: + social_links: + remove: Remove query: node: Node way: Way diff --git a/db/migrate/20250106113207_create_social_links.rb b/db/migrate/20250106113207_create_social_links.rb new file mode 100644 index 0000000000..67aa525e51 --- /dev/null +++ b/db/migrate/20250106113207_create_social_links.rb @@ -0,0 +1,10 @@ +class CreateSocialLinks < ActiveRecord::Migration[7.2] + def change + create_table :social_links do |t| + t.references :user, :null => false, :foreign_key => true + t.string :url + + t.timestamps + end + end +end diff --git a/db/structure.sql b/db/structure.sql index 9679e0b925..2a2eaafab8 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -1358,6 +1358,38 @@ CREATE TABLE public.schema_migrations ( ); +-- +-- Name: social_links; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.social_links ( + id bigint NOT NULL, + user_id bigint NOT NULL, + url character varying, + created_at timestamp(6) without time zone NOT NULL, + updated_at timestamp(6) without time zone NOT NULL +); + + +-- +-- Name: social_links_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.social_links_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: social_links_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.social_links_id_seq OWNED BY public.social_links.id; + + -- -- Name: user_blocks; Type: TABLE; Schema: public; Owner: - -- @@ -1752,6 +1784,13 @@ ALTER TABLE ONLY public.redactions ALTER COLUMN id SET DEFAULT nextval('public.r ALTER TABLE ONLY public.reports ALTER COLUMN id SET DEFAULT nextval('public.reports_id_seq'::regclass); +-- +-- Name: social_links id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.social_links ALTER COLUMN id SET DEFAULT nextval('public.social_links_id_seq'::regclass); + + -- -- Name: user_blocks id; Type: DEFAULT; Schema: public; Owner: - -- @@ -2116,6 +2155,14 @@ ALTER TABLE ONLY public.schema_migrations ADD CONSTRAINT schema_migrations_pkey PRIMARY KEY (version); +-- +-- Name: social_links social_links_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.social_links + ADD CONSTRAINT social_links_pkey PRIMARY KEY (id); + + -- -- Name: user_blocks user_blocks_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- @@ -2607,6 +2654,13 @@ CREATE INDEX index_reports_on_issue_id ON public.reports USING btree (issue_id); CREATE INDEX index_reports_on_user_id ON public.reports USING btree (user_id); +-- +-- Name: index_social_links_on_user_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_social_links_on_user_id ON public.social_links USING btree (user_id); + + -- -- Name: index_user_blocks_on_creator_id_and_id; Type: INDEX; Schema: public; Owner: - -- @@ -3002,6 +3056,14 @@ ALTER TABLE ONLY public.user_mutes ADD CONSTRAINT fk_rails_591dad3359 FOREIGN KEY (owner_id) REFERENCES public.users(id); +-- +-- Name: social_links fk_rails_6034fd4f62; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.social_links + ADD CONSTRAINT fk_rails_6034fd4f62 FOREIGN KEY (user_id) REFERENCES public.users(id); + + -- -- Name: oauth_access_tokens fk_rails_732cb83ab7; Type: FK CONSTRAINT; Schema: public; Owner: - -- @@ -3397,6 +3459,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('23'), ('22'), ('21'), +('20250106113207'), ('20241023004427'), ('20241022141247'), ('20240913171951'), diff --git a/test/controllers/profiles_controller_test.rb b/test/controllers/profiles_controller_test.rb index f388349ab3..75443efa29 100644 --- a/test/controllers/profiles_controller_test.rb +++ b/test/controllers/profiles_controller_test.rb @@ -59,5 +59,14 @@ def test_update get edit_profile_path assert_select "form > fieldset > div > div.col-sm-10 > div > input[name=avatar_action][checked]", false assert_select "form > fieldset > div > div.col-sm-10 > div > div.form-check > input[name=avatar_action][checked]", false + + # Updating social links should work + put profile_path, :params => { :user => { :description => user.description, :social_links_attributes => [{ :url => "https://test.com/test" }] } } + assert_redirected_to user_path(user) + follow_redirect! + assert_response :success + assert_template :show + assert_select ".alert-success", /^Profile updated./ + assert_select "a", "https://test.com/test" end end diff --git a/test/factories/social_link.rb b/test/factories/social_link.rb new file mode 100644 index 0000000000..fb6f7f6e1b --- /dev/null +++ b/test/factories/social_link.rb @@ -0,0 +1,6 @@ +FactoryBot.define do + factory :social_link do + sequence(:url) { |n| "https://test.com/#{n}" } + user + end +end diff --git a/test/models/social_link_test.rb b/test/models/social_link_test.rb new file mode 100644 index 0000000000..0cf6064856 --- /dev/null +++ b/test/models/social_link_test.rb @@ -0,0 +1,49 @@ +require "test_helper" + +class SocialLinkTest < ActiveSupport::TestCase + def test_user_required + social_link = create(:social_link) + + assert_predicate social_link, :valid? + social_link.user = nil + assert_not_predicate social_link, :valid? + end + + def test_url_required + social_link = create(:social_link) + + assert_predicate social_link, :valid? + social_link.url = nil + assert_not_predicate social_link, :valid? + end + + def test_url_https_valid + social_link = create(:social_link) + + assert_predicate social_link, :valid? + social_link.url = "test" + assert_not_predicate social_link, :valid? + end + + def test_parsed_platform + social_link = create(:social_link, :url => "https://mastodon.social/@test") + + assert_equal "mastodon", social_link.parsed[:platform] + assert_equal "test", social_link.parsed[:name] + end + + def test_parsed_platform_custom_name + social_link = create(:social_link, :url => "https://discord.com/users/0") + + assert_equal "discord", social_link.parsed[:platform] + assert_equal "Discord", social_link.parsed[:name] + end + + def test_parsed_platform_other + url = "https://test.com/test" + social_link = create(:social_link, :url => url) + + assert_nil social_link.parsed[:platform] + assert_equal social_link.parsed[:name], url + end +end