2019-04-30 08:27:42 +08:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2022-07-28 10:27:38 +08:00
|
|
|
RSpec.describe Permalink do
|
2015-07-15 13:32:35 +08:00
|
|
|
describe "normalization" do
|
|
|
|
it "correctly normalizes" do
|
|
|
|
normalizer = Permalink::Normalizer.new("/(\\/hello.*)\\?.*/\\1|/(\\/bye.*)\\?.*/\\1")
|
|
|
|
|
|
|
|
expect(normalizer.normalize("/hello?a=1")).to eq("/hello")
|
|
|
|
expect(normalizer.normalize("/bye?test=1")).to eq("/bye")
|
|
|
|
expect(normalizer.normalize("/bla?a=1")).to eq("/bla?a=1")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-08-29 03:09:36 +08:00
|
|
|
describe "new record" do
|
|
|
|
it "strips blanks" do
|
2024-05-28 04:33:30 +08:00
|
|
|
permalink = described_class.create!(url: " my/old/url ")
|
2014-12-31 22:55:03 +08:00
|
|
|
expect(permalink.url).to eq("my/old/url")
|
2014-08-29 03:09:36 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
it "removes leading slash" do
|
2024-05-28 04:33:30 +08:00
|
|
|
permalink = described_class.create!(url: "/my/old/url")
|
2014-12-31 22:55:03 +08:00
|
|
|
expect(permalink.url).to eq("my/old/url")
|
2014-08-29 03:09:36 +08:00
|
|
|
end
|
2024-05-28 04:33:30 +08:00
|
|
|
|
|
|
|
it "checks for unique URL" do
|
|
|
|
permalink = described_class.create(url: "/my/old/url")
|
|
|
|
expect(permalink.errors[:url]).to be_empty
|
|
|
|
|
|
|
|
permalink = described_class.create(url: "/my/old/url")
|
|
|
|
expect(permalink.errors[:url]).to be_present
|
|
|
|
|
|
|
|
permalink = described_class.create(url: "my/old/url")
|
|
|
|
expect(permalink.errors[:url]).to be_present
|
|
|
|
end
|
|
|
|
|
2024-11-14 07:03:58 +08:00
|
|
|
it "validates association" do
|
|
|
|
permalink = described_class.create(url: "/my/old/url", permalink_type: "topic")
|
|
|
|
expect(permalink.errors[:topic_id]).to be_present
|
|
|
|
|
|
|
|
permalink = described_class.create(url: "/my/old/url", permalink_type: "post")
|
|
|
|
expect(permalink.errors[:post_id]).to be_present
|
|
|
|
|
|
|
|
permalink = described_class.create(url: "/my/old/url", permalink_type: "category")
|
|
|
|
expect(permalink.errors[:category_id]).to be_present
|
|
|
|
|
|
|
|
permalink = described_class.create(url: "/my/old/url", permalink_type: "user")
|
|
|
|
expect(permalink.errors[:user_id]).to be_present
|
|
|
|
|
|
|
|
permalink = described_class.create(url: "/my/old/url", permalink_type: "external_url")
|
|
|
|
expect(permalink.errors[:external_url]).to be_present
|
|
|
|
|
|
|
|
permalink = described_class.create(url: "/my/old/url", permalink_type: "tag")
|
|
|
|
expect(permalink.errors[:tag_id]).to be_present
|
|
|
|
end
|
|
|
|
|
|
|
|
it "clears associations when permalink_type changes" do
|
|
|
|
permalink = described_class.create!(url: " my/old/url ")
|
|
|
|
|
|
|
|
permalink.update!(permalink_type_value: 1, permalink_type: "topic")
|
|
|
|
expect(permalink.topic_id).to eq(1)
|
|
|
|
|
|
|
|
permalink.update!(permalink_type_value: 1, permalink_type: "post")
|
|
|
|
expect(permalink.topic_id).to be_nil
|
|
|
|
expect(permalink.post_id).to eq(1)
|
|
|
|
|
|
|
|
permalink.update!(permalink_type_value: 1, permalink_type: "category")
|
|
|
|
expect(permalink.post_id).to be_nil
|
|
|
|
expect(permalink.category_id).to eq(1)
|
|
|
|
|
|
|
|
permalink.update!(permalink_type_value: 1, permalink_type: "user")
|
|
|
|
expect(permalink.category_id).to be_nil
|
|
|
|
expect(permalink.user_id).to eq(1)
|
|
|
|
|
|
|
|
permalink.update!(
|
|
|
|
permalink_type_value: "https://discourse.org",
|
|
|
|
permalink_type: "external_url",
|
|
|
|
)
|
|
|
|
expect(permalink.user_id).to be_nil
|
|
|
|
expect(permalink.external_url).to eq("https://discourse.org")
|
|
|
|
|
|
|
|
tag = Fabricate(:tag, name: "art")
|
|
|
|
permalink.update!(permalink_type_value: "art", permalink_type: "tag")
|
|
|
|
expect(permalink.external_url).to be_nil
|
|
|
|
expect(permalink.tag_id).to eq(tag.id)
|
|
|
|
|
|
|
|
permalink.update!(permalink_type_value: 1, permalink_type: "topic")
|
|
|
|
expect(permalink.tag_id).to be_nil
|
|
|
|
expect(permalink.topic_id).to eq(1)
|
|
|
|
end
|
|
|
|
|
2024-05-28 04:33:30 +08:00
|
|
|
context "with special characters in URL" do
|
|
|
|
it "percent encodes any special character" do
|
|
|
|
permalink = described_class.create!(url: "/2022/10/03/привет-sam")
|
|
|
|
expect(permalink.url).to eq("2022/10/03/%D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82-sam")
|
|
|
|
end
|
|
|
|
|
|
|
|
it "checks for unique URL" do
|
|
|
|
permalink = described_class.create(url: "/2022/10/03/привет-sam")
|
|
|
|
expect(permalink.errors[:url]).to be_empty
|
|
|
|
|
|
|
|
permalink = described_class.create(url: "/2022/10/03/привет-sam")
|
|
|
|
expect(permalink.errors[:url]).to be_present
|
|
|
|
end
|
|
|
|
end
|
2014-08-29 03:09:36 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
describe "target_url" do
|
2023-06-21 22:00:19 +08:00
|
|
|
subject(:target_url) { permalink.target_url }
|
|
|
|
|
2014-08-29 03:09:36 +08:00
|
|
|
let(:permalink) { Fabricate.build(:permalink) }
|
|
|
|
let(:topic) { Fabricate(:topic) }
|
|
|
|
let(:post) { Fabricate(:post, topic: topic) }
|
|
|
|
let(:category) { Fabricate(:category) }
|
2020-05-25 17:48:54 +08:00
|
|
|
let(:tag) { Fabricate(:tag) }
|
2024-02-06 00:31:31 +08:00
|
|
|
let(:user) { Fabricate(:user) }
|
2014-08-29 03:09:36 +08:00
|
|
|
|
2024-05-28 03:30:19 +08:00
|
|
|
it "returns nil when nothing is set" do
|
2014-12-31 22:55:03 +08:00
|
|
|
expect(target_url).to eq(nil)
|
2014-08-29 03:09:36 +08:00
|
|
|
end
|
|
|
|
|
2024-05-28 03:30:19 +08:00
|
|
|
context "when `topic_id` is set" do
|
|
|
|
it "returns an absolute path" do
|
|
|
|
permalink.topic_id = topic.id
|
|
|
|
expect(target_url).to eq(topic.relative_url)
|
|
|
|
expect(target_url).not_to start_with("http")
|
|
|
|
end
|
2014-08-29 03:09:36 +08:00
|
|
|
|
2024-05-28 03:30:19 +08:00
|
|
|
it "returns nil when topic is not found" do
|
|
|
|
permalink.topic_id = 99_999
|
|
|
|
expect(target_url).to eq(nil)
|
|
|
|
end
|
2014-08-29 03:09:36 +08:00
|
|
|
end
|
|
|
|
|
2024-05-28 03:30:19 +08:00
|
|
|
context "when `post_id` is set" do
|
|
|
|
it "returns an absolute path" do
|
|
|
|
permalink.post_id = post.id
|
|
|
|
expect(target_url).to eq(post.relative_url)
|
|
|
|
expect(target_url).not_to start_with("http")
|
|
|
|
end
|
2014-08-29 03:09:36 +08:00
|
|
|
|
2024-05-28 03:30:19 +08:00
|
|
|
it "returns nil when post is not found" do
|
|
|
|
permalink.post_id = 99_999
|
|
|
|
expect(target_url).to eq(nil)
|
|
|
|
end
|
2014-08-29 03:09:36 +08:00
|
|
|
end
|
|
|
|
|
2024-05-28 03:30:19 +08:00
|
|
|
context "when `category_id` is set" do
|
|
|
|
it "returns an absolute path" do
|
|
|
|
permalink.category_id = category.id
|
|
|
|
expect(target_url).to eq(category.url)
|
|
|
|
expect(target_url).not_to start_with("http")
|
|
|
|
end
|
2014-08-29 03:09:36 +08:00
|
|
|
|
2024-05-28 03:30:19 +08:00
|
|
|
it "returns nil when category is not found" do
|
|
|
|
permalink.category_id = 99_999
|
|
|
|
expect(target_url).to eq(nil)
|
|
|
|
end
|
2014-08-29 03:09:36 +08:00
|
|
|
end
|
|
|
|
|
2024-05-28 03:30:19 +08:00
|
|
|
context "when `tag_id` is set" do
|
|
|
|
it "returns an absolute path" do
|
|
|
|
permalink.tag_id = tag.id
|
|
|
|
expect(target_url).to eq(tag.relative_url)
|
|
|
|
expect(target_url).not_to start_with("http")
|
|
|
|
end
|
2020-05-25 17:48:54 +08:00
|
|
|
|
2024-05-28 03:30:19 +08:00
|
|
|
it "returns nil when tag is not found" do
|
|
|
|
permalink.tag_id = 99_999
|
|
|
|
expect(target_url).to eq(nil)
|
|
|
|
end
|
2020-05-25 17:48:54 +08:00
|
|
|
end
|
|
|
|
|
2024-05-28 03:30:19 +08:00
|
|
|
context "when `user_id` is set" do
|
|
|
|
it "returns an absolute path" do
|
|
|
|
permalink.user_id = user.id
|
|
|
|
expect(target_url).to eq(user.relative_url)
|
|
|
|
expect(target_url).not_to start_with("http")
|
|
|
|
end
|
2020-05-25 17:48:54 +08:00
|
|
|
|
2024-05-28 03:30:19 +08:00
|
|
|
it "returns nil when user is not found" do
|
|
|
|
permalink.user_id = 99_999
|
|
|
|
expect(target_url).to eq(nil)
|
|
|
|
end
|
2014-08-29 03:09:36 +08:00
|
|
|
end
|
2024-02-06 00:31:31 +08:00
|
|
|
|
2024-05-28 03:30:19 +08:00
|
|
|
context "when `external_url` is set" do
|
|
|
|
it "returns a URL when an absolute URL is set" do
|
|
|
|
permalink.external_url = "https://example.com"
|
|
|
|
expect(target_url).to eq("https://example.com")
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns a protocol-relative URL when a PRURL is set" do
|
|
|
|
permalink.external_url = "//example.com"
|
|
|
|
expect(target_url).to eq("//example.com")
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns an absolute path when an absolute path is set" do
|
|
|
|
permalink.external_url = "/my/preferences"
|
|
|
|
expect(target_url).to eq("/my/preferences")
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns a relative path when a relative path is set" do
|
|
|
|
permalink.external_url = "foo/bar"
|
|
|
|
expect(target_url).to eq("foo/bar")
|
|
|
|
end
|
2024-02-06 00:31:31 +08:00
|
|
|
end
|
|
|
|
|
2024-05-28 03:31:51 +08:00
|
|
|
context "with subfolder" do
|
|
|
|
before { set_subfolder "/community" }
|
|
|
|
|
|
|
|
context "when `topic_id` is set" do
|
|
|
|
it "returns an absolute path" do
|
|
|
|
permalink.topic_id = topic.id
|
|
|
|
expect(target_url).to eq(topic.relative_url)
|
|
|
|
expect(target_url).to start_with("/community/")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "when `post_id` is set" do
|
|
|
|
it "returns an absolute path" do
|
|
|
|
permalink.post_id = post.id
|
|
|
|
expect(target_url).to eq(post.relative_url)
|
|
|
|
expect(target_url).to start_with("/community/")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "when `category_id` is set" do
|
|
|
|
it "returns an absolute path" do
|
|
|
|
permalink.category_id = category.id
|
|
|
|
expect(target_url).to eq(category.url)
|
|
|
|
expect(target_url).to start_with("/community/")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "when `tag_id` is set" do
|
|
|
|
it "returns an absolute path" do
|
|
|
|
permalink.tag_id = tag.id
|
|
|
|
expect(target_url).to eq(tag.relative_url)
|
|
|
|
expect(target_url).to start_with("/community/")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "when `user_id` is set" do
|
|
|
|
it "returns an absolute path" do
|
|
|
|
permalink.user_id = user.id
|
|
|
|
expect(target_url).to eq(user.relative_url)
|
|
|
|
expect(target_url).to start_with("/community/")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "when `external_url` is set" do
|
|
|
|
it "returns a URL when an absolute URL is set" do
|
|
|
|
permalink.external_url = "https://example.com"
|
|
|
|
expect(target_url).to eq("https://example.com")
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns a protocol-relative URL when a PRURL is set" do
|
|
|
|
permalink.external_url = "//example.com"
|
|
|
|
expect(target_url).to eq("//example.com")
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns an absolute path when an absolute path is set" do
|
|
|
|
permalink.external_url = "/my/preferences"
|
|
|
|
expect(target_url).to eq("/community/my/preferences")
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns a relative path when a relative path is set" do
|
|
|
|
permalink.external_url = "foo/bar"
|
|
|
|
expect(target_url).to eq("foo/bar")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2024-05-28 03:30:19 +08:00
|
|
|
it "returns the highest priority url when multiple attributes are set" do
|
|
|
|
permalink.external_url = "/my/preferences"
|
|
|
|
permalink.post = post
|
|
|
|
permalink.topic = topic
|
|
|
|
permalink.category = category
|
|
|
|
permalink.tag = tag
|
|
|
|
permalink.user = user
|
|
|
|
|
|
|
|
expect(permalink.target_url).to eq("/my/preferences")
|
|
|
|
|
|
|
|
permalink.external_url = nil
|
|
|
|
expect(permalink.target_url).to eq(post.relative_url)
|
|
|
|
|
|
|
|
permalink.post = nil
|
|
|
|
expect(permalink.target_url).to eq(topic.relative_url)
|
|
|
|
|
|
|
|
permalink.topic = nil
|
|
|
|
expect(permalink.target_url).to eq(category.relative_url)
|
|
|
|
|
|
|
|
permalink.category = nil
|
|
|
|
expect(permalink.target_url).to eq(tag.relative_url)
|
|
|
|
|
|
|
|
permalink.tag = nil
|
|
|
|
expect(permalink.target_url).to eq(user.relative_url)
|
|
|
|
|
|
|
|
permalink.user = nil
|
|
|
|
expect(permalink.target_url).to be_nil
|
2024-02-06 00:31:31 +08:00
|
|
|
end
|
2014-08-29 03:09:36 +08:00
|
|
|
end
|
|
|
|
end
|