闭社主体 forked from https://github.com/tootsuite/mastodon
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

424 lines
12 KiB

8 years ago
8 years ago
  1. require 'rails_helper'
  2. RSpec.describe Account, type: :model do
  3. subject { Fabricate(:account, username: 'alice') }
  4. context do
  5. let(:bob) { Fabricate(:account, username: 'bob') }
  6. describe '#follow!' do
  7. it 'creates a follow' do
  8. follow = subject.follow!(bob)
  9. expect(follow).to be_instance_of Follow
  10. expect(follow.account).to eq subject
  11. expect(follow.target_account).to eq bob
  12. end
  13. end
  14. describe '#unfollow!' do
  15. before do
  16. subject.follow!(bob)
  17. end
  18. it 'destroys a follow' do
  19. unfollow = subject.unfollow!(bob)
  20. expect(unfollow).to be_instance_of Follow
  21. expect(unfollow.account).to eq subject
  22. expect(unfollow.target_account).to eq bob
  23. expect(unfollow.destroyed?).to be true
  24. end
  25. end
  26. describe '#following?' do
  27. it 'returns true when the target is followed' do
  28. subject.follow!(bob)
  29. expect(subject.following?(bob)).to be true
  30. end
  31. it 'returns false if the target is not followed' do
  32. expect(subject.following?(bob)).to be false
  33. end
  34. end
  35. end
  36. describe '#local?' do
  37. it 'returns true when the account is local' do
  38. expect(subject.local?).to be true
  39. end
  40. it 'returns false when the account is on a different domain' do
  41. subject.domain = 'foreign.tld'
  42. expect(subject.local?).to be false
  43. end
  44. end
  45. describe 'Local domain user methods' do
  46. around do |example|
  47. before = Rails.configuration.x.local_domain
  48. example.run
  49. Rails.configuration.x.local_domain = before
  50. end
  51. describe '#to_webfinger_s' do
  52. it 'returns a webfinger string for the account' do
  53. Rails.configuration.x.local_domain = 'example.com'
  54. expect(subject.to_webfinger_s).to eq 'acct:alice@example.com'
  55. end
  56. end
  57. describe '#local_username_and_domain' do
  58. it 'returns the username and local domain for the account' do
  59. Rails.configuration.x.local_domain = 'example.com'
  60. expect(subject.local_username_and_domain).to eq 'alice@example.com'
  61. end
  62. end
  63. end
  64. describe '#acct' do
  65. it 'returns username for local users' do
  66. expect(subject.acct).to eql 'alice'
  67. end
  68. it 'returns username@domain for foreign users' do
  69. subject.domain = 'foreign.tld'
  70. expect(subject.acct).to eql 'alice@foreign.tld'
  71. end
  72. end
  73. describe '#subscribed?' do
  74. it 'returns false when no subscription expiration information is present' do
  75. expect(subject.subscribed?).to be false
  76. end
  77. it 'returns true when subscription expiration has been set' do
  78. subject.subscription_expires_at = 30.days.from_now
  79. expect(subject.subscribed?).to be true
  80. end
  81. end
  82. describe '#keypair' do
  83. it 'returns an RSA key pair' do
  84. expect(subject.keypair).to be_instance_of OpenSSL::PKey::RSA
  85. end
  86. end
  87. describe '#subscription' do
  88. it 'returns an OStatus subscription' do
  89. expect(subject.subscription('')).to be_instance_of OStatus2::Subscription
  90. end
  91. end
  92. describe '#object_type' do
  93. it 'is always a person' do
  94. expect(subject.object_type).to be :person
  95. end
  96. end
  97. describe '#ping!' do
  98. pending
  99. end
  100. describe '#favourited?' do
  101. let(:original_status) do
  102. author = Fabricate(:account, username: 'original')
  103. Fabricate(:status, account: author)
  104. end
  105. context 'when the status is a reblog of another status' do
  106. let(:original_reblog) do
  107. author = Fabricate(:account, username: 'original_reblogger')
  108. Fabricate(:status, reblog: original_status, account: author)
  109. end
  110. it 'is is true when this account has favourited it' do
  111. Fabricate(:favourite, status: original_reblog, account: subject)
  112. expect(subject.favourited?(original_status)).to eq true
  113. end
  114. it 'is false when this account has not favourited it' do
  115. expect(subject.favourited?(original_status)).to eq false
  116. end
  117. end
  118. context 'when the status is an original status' do
  119. it 'is is true when this account has favourited it' do
  120. Fabricate(:favourite, status: original_status, account: subject)
  121. expect(subject.favourited?(original_status)).to eq true
  122. end
  123. it 'is false when this account has not favourited it' do
  124. expect(subject.favourited?(original_status)).to eq false
  125. end
  126. end
  127. end
  128. describe '#reblogged?' do
  129. let(:original_status) do
  130. author = Fabricate(:account, username: 'original')
  131. Fabricate(:status, account: author)
  132. end
  133. context 'when the status is a reblog of another status'do
  134. let(:original_reblog) do
  135. author = Fabricate(:account, username: 'original_reblogger')
  136. Fabricate(:status, reblog: original_status, account: author)
  137. end
  138. it 'is true when this account has reblogged it' do
  139. Fabricate(:status, reblog: original_reblog, account: subject)
  140. expect(subject.reblogged?(original_reblog)).to eq true
  141. end
  142. it 'is false when this account has not reblogged it' do
  143. expect(subject.reblogged?(original_reblog)).to eq false
  144. end
  145. end
  146. context 'when the status is an original status' do
  147. it 'is true when this account has reblogged it' do
  148. Fabricate(:status, reblog: original_status, account: subject)
  149. expect(subject.reblogged?(original_status)).to eq true
  150. end
  151. it 'is false when this account has not reblogged it' do
  152. expect(subject.reblogged?(original_status)).to eq false
  153. end
  154. end
  155. end
  156. describe '.search_for' do
  157. before do
  158. @match = Fabricate(
  159. :account,
  160. display_name: "Display Name",
  161. username: "username",
  162. domain: "example.com"
  163. )
  164. _missing = Fabricate(
  165. :account,
  166. display_name: "Missing",
  167. username: "missing",
  168. domain: "missing.com"
  169. )
  170. end
  171. it 'finds accounts with matching display_name' do
  172. results = Account.search_for("display")
  173. expect(results).to eq [@match]
  174. end
  175. it 'finds accounts with matching username' do
  176. results = Account.search_for("username")
  177. expect(results).to eq [@match]
  178. end
  179. it 'finds accounts with matching domain' do
  180. results = Account.search_for("example")
  181. expect(results).to eq [@match]
  182. end
  183. it 'ranks multiple matches higher' do
  184. account = Fabricate(
  185. :account,
  186. username: "username",
  187. display_name: "username"
  188. )
  189. results = Account.search_for("username")
  190. expect(results).to eq [account, @match]
  191. end
  192. end
  193. describe '.advanced_search_for' do
  194. it 'ranks followed accounts higher' do
  195. account = Fabricate(:account)
  196. match = Fabricate(:account, username: "Matching")
  197. followed_match = Fabricate(:account, username: "Matcher")
  198. Fabricate(:follow, account: account, target_account: followed_match)
  199. results = Account.advanced_search_for("match", account)
  200. expect(results).to eq [followed_match, match]
  201. expect(results.first.rank).to be > results.last.rank
  202. end
  203. end
  204. describe '.find_local' do
  205. before do
  206. Fabricate(:account, username: 'Alice')
  207. end
  208. it 'returns Alice for alice' do
  209. expect(Account.find_local('alice')).to_not be_nil
  210. end
  211. it 'returns Alice for Alice' do
  212. expect(Account.find_local('Alice')).to_not be_nil
  213. end
  214. it 'does not return anything for a_ice' do
  215. expect(Account.find_local('a_ice')).to be_nil
  216. end
  217. it 'does not return anything for al%' do
  218. expect(Account.find_local('al%')).to be_nil
  219. end
  220. end
  221. describe '.find_remote' do
  222. before do
  223. Fabricate(:account, username: 'Alice', domain: 'mastodon.social')
  224. end
  225. it 'returns Alice for alice@mastodon.social' do
  226. expect(Account.find_remote('alice', 'mastodon.social')).to_not be_nil
  227. end
  228. it 'returns Alice for ALICE@MASTODON.SOCIAL' do
  229. expect(Account.find_remote('ALICE', 'MASTODON.SOCIAL')).to_not be_nil
  230. end
  231. it 'does not return anything for a_ice@mastodon.social' do
  232. expect(Account.find_remote('a_ice', 'mastodon.social')).to be_nil
  233. end
  234. it 'does not return anything for alice@m_stodon.social' do
  235. expect(Account.find_remote('alice', 'm_stodon.social')).to be_nil
  236. end
  237. it 'does not return anything for alice@m%' do
  238. expect(Account.find_remote('alice', 'm%')).to be_nil
  239. end
  240. end
  241. describe '.following_map' do
  242. it 'returns an hash' do
  243. expect(Account.following_map([], 1)).to be_a Hash
  244. end
  245. end
  246. describe '.followed_by_map' do
  247. it 'returns an hash' do
  248. expect(Account.followed_by_map([], 1)).to be_a Hash
  249. end
  250. end
  251. describe '.blocking_map' do
  252. it 'returns an hash' do
  253. expect(Account.blocking_map([], 1)).to be_a Hash
  254. end
  255. end
  256. describe '.requested_map' do
  257. it 'returns an hash' do
  258. expect(Account.requested_map([], 1)).to be_a Hash
  259. end
  260. end
  261. describe 'MENTION_RE' do
  262. subject { Account::MENTION_RE }
  263. it 'matches usernames in the middle of a sentence' do
  264. expect(subject.match('Hello to @alice from me')[1]).to eq 'alice'
  265. end
  266. it 'matches usernames in the beginning of status' do
  267. expect(subject.match('@alice Hey how are you?')[1]).to eq 'alice'
  268. end
  269. it 'matches full usernames' do
  270. expect(subject.match('@alice@example.com')[1]).to eq 'alice@example.com'
  271. end
  272. it 'matches full usernames with a dot at the end' do
  273. expect(subject.match('Hello @alice@example.com.')[1]).to eq 'alice@example.com'
  274. end
  275. it 'matches dot-prepended usernames' do
  276. expect(subject.match('.@alice I want everybody to see this')[1]).to eq 'alice'
  277. end
  278. it 'does not match e-mails' do
  279. expect(subject.match('Drop me an e-mail at alice@example.com')).to be_nil
  280. end
  281. it 'does not match URLs' do
  282. expect(subject.match('Check this out https://medium.com/@alice/some-article#.abcdef123')).to be_nil
  283. end
  284. end
  285. describe 'validations' do
  286. it 'has a valid fabricator' do
  287. account = Fabricate.build(:account)
  288. account.valid?
  289. expect(account).to be_valid
  290. end
  291. it 'is invalid without a username' do
  292. account = Fabricate.build(:account, username: nil)
  293. account.valid?
  294. expect(account).to model_have_error_on_field(:username)
  295. end
  296. it 'is invalid if the username already exists' do
  297. account_1 = Fabricate(:account, username: 'the_doctor')
  298. account_2 = Fabricate.build(:account, username: 'the_doctor')
  299. account_2.valid?
  300. expect(account_2).to model_have_error_on_field(:username)
  301. end
  302. context 'when is local' do
  303. it 'is invalid if the username doesn\'t only contains letters, numbers and underscores' do
  304. account = Fabricate.build(:account, username: 'the-doctor')
  305. account.valid?
  306. expect(account).to model_have_error_on_field(:username)
  307. end
  308. it 'is invalid if the username is longer then 30 characters' do
  309. account = Fabricate.build(:account, username: Faker::Lorem.characters(31))
  310. account.valid?
  311. expect(account).to model_have_error_on_field(:username)
  312. end
  313. end
  314. end
  315. describe 'scopes' do
  316. describe 'remote' do
  317. it 'returns an array of accounts who have a domain' do
  318. account_1 = Fabricate(:account, domain: nil)
  319. account_2 = Fabricate(:account, domain: 'example.com')
  320. expect(Account.remote).to match_array([account_2])
  321. end
  322. end
  323. describe 'local' do
  324. it 'returns an array of accounts who do not have a domain' do
  325. account_1 = Fabricate(:account, domain: nil)
  326. account_2 = Fabricate(:account, domain: 'example.com')
  327. expect(Account.local).to match_array([account_1])
  328. end
  329. end
  330. describe 'silenced' do
  331. it 'returns an array of accounts who are silenced' do
  332. account_1 = Fabricate(:account, silenced: true)
  333. account_2 = Fabricate(:account, silenced: false)
  334. expect(Account.silenced).to match_array([account_1])
  335. end
  336. end
  337. describe 'suspended' do
  338. it 'returns an array of accounts who are suspended' do
  339. account_1 = Fabricate(:account, suspended: true)
  340. account_2 = Fabricate(:account, suspended: false)
  341. expect(Account.suspended).to match_array([account_1])
  342. end
  343. end
  344. end
  345. end