social_plus-web_api 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,58 @@
1
+ require 'social_plus/web_api/profile'
2
+ require 'active_support/core_ext/string/inquiry'
3
+ require 'active_support/core_ext/hash/slice'
4
+
5
+ # :nodoc:
6
+ module SocialPlus
7
+ # :nodoc:
8
+ module WebApi
9
+ # A class which represents a user of Social Plus
10
+ class User
11
+ class << self
12
+ # Fetch information of a user using a given one time token
13
+ # @param [Client] api_client an API client
14
+ # @param [String] token the token returned from Social Plus login
15
+ # @return [User] User object
16
+ def authenticate(api_client, token)
17
+ result = api_client.execute('authenticated_user', token: token, add_profile: true)
18
+ result['providers'] = api_client.execute('providers_of_user', identifier: result['user']['identifier'])['providers']
19
+ new(result)
20
+ end
21
+ private :new
22
+ end
23
+
24
+ # rubocop: disable Metrics/AbcSize
25
+
26
+ # @param [hash] params User information obtained from Social Plus Web API
27
+ # @option params [Hash] "user" User
28
+ # @option params [Hash] "profile" User's profile
29
+ # @option params [Array] "email" User's email addresses
30
+ # @option params [Hash] "follow" User's counts of following/followed people
31
+ # @option params [Hash] "providers" Providers which the user has logged in
32
+ def initialize(params)
33
+ raise ArgumentError, %q|missing 'user'| unless params.key?('user')
34
+ user = params['user']
35
+ raise ArgumentError, %q|missing 'user/identifier'| unless user.key?('identifier')
36
+ @identifier = user['identifier']
37
+ last_logged_in_provider = user['last_logged_in_provider'] || ''
38
+ @last_logged_in_provider = last_logged_in_provider.inquiry.freeze
39
+ @profile = SocialPlus::WebApi::Profile.new(params.slice('profile', 'email')).freeze
40
+ @followers = params.key?('follow') && params['follow'].key?('followed_by') ? params['follow']['followed_by'] : 0
41
+ @providers = params['providers']
42
+ end
43
+
44
+ # rubocop: enable Metrics/AbcSize
45
+
46
+ # @return [String] The user's Social Plus ID
47
+ attr_reader :identifier
48
+ # @return [ActiveSupport::StringInquirer] The provider which the user has logged in most recently
49
+ attr_reader :last_logged_in_provider
50
+ # @return [Profile] The user's profile
51
+ attr_reader :profile
52
+ # @return [Integer] The number of user's followers(reaches)
53
+ attr_reader :followers
54
+ # @return [Array] The Providers which the user has logged in
55
+ attr_reader :providers
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,7 @@
1
+ # :nodoc:
2
+ module SocialPlus
3
+ # :nodoc:
4
+ module WebApi
5
+ VERSION = '1.0.0'
6
+ end
7
+ end
@@ -0,0 +1,4 @@
1
+ require 'rspec/core/rake_task'
2
+
3
+ RSpec::Core::RakeTask.new
4
+ task default: :spec
@@ -0,0 +1,6 @@
1
+ require 'rubocop/rake_task'
2
+
3
+ RuboCop::RakeTask.new do |t|
4
+ t.options << 'lib' << 'spec'
5
+ t.formatters = %w(simple)
6
+ end
@@ -0,0 +1,8 @@
1
+ require 'yard'
2
+ require 'yard/rake/yardoc_task'
3
+
4
+ YARD::Rake::YardocTask.new do |t|
5
+ t.files = %w(lib/**/*.rb)
6
+ t.options += %w(--markup markdown)
7
+ t.options += %w(--debug --verbose) if $trace
8
+ end
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'social_plus/web_api/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'social_plus-web_api'
8
+ spec.version = SocialPlus::WebApi::VERSION
9
+ spec.authors = %(OZAWA Sakuro)
10
+ spec.email = %(sakuro+rubygems.org@2238club.org)
11
+ spec.summary = %q{SocialPlus Web API client}
12
+ spec.description = %q{This gem provides fundamental access to Social Plus's Web API.}
13
+ spec.homepage = 'https://socialplus.jp'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = []
18
+ spec.test_files = spec.files.grep(%r{^spec/})
19
+ spec.require_paths = %w(lib)
20
+
21
+ spec.add_development_dependency 'bundler', '~> 1.7'
22
+ spec.add_development_dependency 'rake', '~> 10.0'
23
+ spec.add_development_dependency 'rspec', '~> 3.1'
24
+ spec.add_development_dependency 'webmock'
25
+
26
+ spec.add_development_dependency 'yard'
27
+ spec.add_development_dependency 'rubocop'
28
+ spec.add_dependency 'activesupport', '>= 3.0'
29
+
30
+ spec.required_ruby_version = '>= 2.1'
31
+ end
@@ -0,0 +1,152 @@
1
+ require 'social_plus/web_api/client'
2
+ require 'webmock/rspec'
3
+
4
+ describe SocialPlus::WebApi::Client do
5
+ describe '#initialize' do
6
+ let(:client) { SocialPlus::WebApi::Client.new(api_key) }
7
+ context 'with valid API key' do
8
+ # 40-digit hexadecimal
9
+ let(:api_key) { '100e1d1f03d1cbcbd35d1a07dcafa96b364c67d3' }
10
+ it { expect(client).to be_an_instance_of(SocialPlus::WebApi::Client) }
11
+ end
12
+
13
+ context 'with invalid API key' do
14
+ let(:api_key) { '100e1d1' }
15
+ it { expect { client }.to raise_error(ArgumentError) }
16
+ end
17
+ end
18
+
19
+ describe '#execute' do
20
+ shared_examples_for 'Web API' do
21
+ context 'with registered API key' do
22
+ let(:stub_status) { 200 }
23
+ let(:stub_body) {
24
+ {
25
+ 'status' => 'ok',
26
+ 'info' => {
27
+ 'account' => 'ff',
28
+ 'site_id' => 'demoapp'
29
+ }
30
+ }.to_json
31
+ }
32
+ it { expect(api_call).to eq('info' => { 'account' => 'ff', 'site_id' => 'demoapp' }) }
33
+ end
34
+
35
+ context 'with unregistered API key' do
36
+ let(:stub_status) { 400 }
37
+ let(:stub_body) {
38
+ {
39
+ 'status' => 'failed',
40
+ 'error' => {
41
+ 'code' => 1,
42
+ 'message' => 'Invalid API key or API key not found.'
43
+ }
44
+ }.to_json
45
+ }
46
+ it 'raises an ApiError' do
47
+ expect { api_call }.to raise_error {|error|
48
+ expect(error).to be_a(SocialPlus::WebApi::ApiError)
49
+ expect(error.message).to eq('Invalid API key or API key not found.')
50
+ expect(error.code).to eq(1)
51
+ }
52
+ end
53
+ end
54
+
55
+ context 'when a server error unrelated to the API occurs' do
56
+ let(:stub_status) { 503 }
57
+ let(:stub_body) { '' }
58
+ it 'raises an ApiError based on the HTTP response' do
59
+ expect { api_call }.to raise_error {|error|
60
+ expect(error).to be_a(SocialPlus::WebApi::ApiError)
61
+ expect(error.code).to eq(503)
62
+ }
63
+ end
64
+ end
65
+
66
+ context 'when a client error unrelated to the API occurs' do
67
+ let(:stub_status) { 402 }
68
+ let(:stub_body) { '' }
69
+ it 'raises an ApiError based on the HTTP response' do
70
+ expect { api_call }.to raise_error {|error|
71
+ expect(error).to be_a(SocialPlus::WebApi::ApiError)
72
+ expect(error.code).to eq(402)
73
+ }
74
+ end
75
+ end
76
+
77
+ context 'Invalid authentication token' do
78
+ let(:stub_status) { 404 }
79
+ let(:stub_body) {
80
+ {
81
+ 'status' => 'failed',
82
+ 'error' => {
83
+ 'code' => 4,
84
+ 'message' => 'Invalid authentication token or token not found'
85
+ }
86
+ }.to_json
87
+ }
88
+ it 'raises an InvalidToken' do
89
+ expect { api_call }.to raise_error {|error|
90
+ expect(error).to be_an_instance_of(SocialPlus::WebApi::InvalidToken)
91
+ expect(error.message).to eq('Invalid authentication token or token not found')
92
+ expect(error.code).to eq(4)
93
+ }
94
+ end
95
+ end
96
+
97
+ context 'when the response is neither an API response nor an HTTP error' do
98
+ let(:stub_status) { 301 }
99
+ let(:stub_body) { '' }
100
+ it 'raises an ApiError based on the HTTP response' do
101
+ expect { api_call }.to raise_error {|error|
102
+ expect(error).to be_a(SocialPlus::WebApi::ApiError)
103
+ expect(error.code).to eq(301)
104
+ }
105
+ end
106
+ end
107
+ end
108
+
109
+ let(:api_key) { '100e1d1f03d1cbcbd35d1a07dcafa96b364c67d3' }
110
+ let(:client) { SocialPlus::WebApi::Client.new(api_key) }
111
+
112
+ describe 'GET request' do
113
+ describe 'request headers' do
114
+ let(:request) { client.send(:create_get_request, 'appinfo', key: '100e1d1f03d1cbcbd35d1a07dcafa96b364c67d3') }
115
+ describe 'User-Agent' do
116
+ it { expect(request['User-Agent']).to eq('SocialPlus Web API gem/0.0.1') }
117
+ end
118
+ end
119
+
120
+ describe 'an API call' do
121
+ let(:api_call) { client.execute('appinfo', {}) }
122
+ before :each do
123
+ stub_request(:get, 'https://api.socialplus.jp/api/appinfo').with(query: { key: '100e1d1f03d1cbcbd35d1a07dcafa96b364c67d3' }).to_return(
124
+ status: stub_status, body: stub_body
125
+ )
126
+ end
127
+
128
+ it_behaves_like 'Web API'
129
+ end
130
+ end
131
+
132
+ describe 'POST request' do
133
+ describe 'request headers' do
134
+ let(:request) { client.send(:create_post_request, 'share', key: '100e1d1f03d1cbcbd35d1a07dcafa96b364c67d3') }
135
+ describe 'User-Agent' do
136
+ it { expect(request['User-Agent']).to eq('SocialPlus Web API gem/0.0.1') }
137
+ end
138
+ end
139
+
140
+ describe 'an API call' do
141
+ let(:api_call) { client.execute('share', via: :post) }
142
+ before :each do
143
+ stub_request(:post, 'https://api.socialplus.jp/api/share').with(body: 'key=100e1d1f03d1cbcbd35d1a07dcafa96b364c67d3').to_return(
144
+ status: stub_status, body: stub_body
145
+ )
146
+ end
147
+
148
+ it_behaves_like 'Web API'
149
+ end
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,418 @@
1
+ require 'social_plus/web_api/profile'
2
+ require 'support/macros/social_plus_macros'
3
+
4
+ describe SocialPlus::WebApi::Profile do
5
+ include SocialPlusMacros
6
+ let(:params) { social_plus_user_params }
7
+
8
+ describe '#initialize' do
9
+ let(:profile) { SocialPlus::WebApi::Profile.new(params) }
10
+
11
+ describe 'name stuff' do
12
+ # full(K) | last(K) | first(K) | full | last | first | user |
13
+ # #1 ******* | ******* | ******** | | | | |
14
+ it { expect(profile.full_name).to eq('山田 太郎') }
15
+ it { expect(profile.family_name).to eq('山田') }
16
+ it { expect(profile.given_name).to eq('太郎') }
17
+
18
+ # full(K) | last(K) | first(K) | full | last | first | user |
19
+ # #1 ******* | ******* | -------- | | | | |
20
+ context %q|with 'full_name_kanji', 'last_name_kanji'| do
21
+ before do
22
+ params['profile'].except!('first_name_kanji')
23
+ end
24
+ it { expect(profile.full_name).to eq('山田 太郎') }
25
+ it { expect(profile.family_name).to eq('山田') }
26
+ it { expect(profile.given_name).to eq('') }
27
+ end
28
+
29
+ # full(K) | last(K) | first(K) | full | last | first | user |
30
+ # #1 ******* | ------- | ******** | | | | |
31
+ context %q|with 'full_name_kanji', 'first_name_kanji'| do
32
+ before do
33
+ params['profile'].except!('last_name_kanji')
34
+ end
35
+ it { expect(profile.full_name).to eq('山田 太郎') }
36
+ it { expect(profile.family_name).to eq('') }
37
+ it { expect(profile.given_name).to eq('太郎') }
38
+ end
39
+
40
+ # full(K) | last(K) | first(K) | full | last | first | user |
41
+ # #1' | | | **** | **** | ***** | |
42
+ context %q|with 'full_name', 'last_name', 'first_name'| do
43
+ before do
44
+ params['profile'].except!('full_name_kanji', 'last_name_kanji', 'first_name_kanji')
45
+ end
46
+ it { expect(profile.full_name).to eq('YAMADA Taro') }
47
+ it { expect(profile.family_name).to eq('YAMADA') }
48
+ it { expect(profile.given_name).to eq('Taro') }
49
+ end
50
+
51
+ # full(K) | last(K) | first(K) | full | last | first | user |
52
+ # #1' | | | **** | **** | ----- | |
53
+ context %q|with 'full_name', 'last_name'| do
54
+ before do
55
+ params['profile'].except!('full_name_kanji', 'last_name_kanji', 'first_name_kanji')
56
+ params['profile'].except!('first_name')
57
+ end
58
+ it { expect(profile.full_name).to eq('YAMADA Taro') }
59
+ it { expect(profile.family_name).to eq('YAMADA') }
60
+ it { expect(profile.given_name).to eq('') }
61
+ end
62
+
63
+ # full(K) | last(K) | first(K) | full | last | first | user |
64
+ # #1' | | | **** | ---- | ***** | |
65
+ context %q|with 'full_name', 'first_name'| do
66
+ before do
67
+ params['profile'].except!('full_name_kanji', 'last_name_kanji', 'first_name_kanji')
68
+ params['profile'].except!('last_name')
69
+ end
70
+ it { expect(profile.full_name).to eq('YAMADA Taro') }
71
+ it { expect(profile.family_name).to eq('') }
72
+ it { expect(profile.given_name).to eq('Taro') }
73
+ end
74
+
75
+ # full(K) | last(K) | first(K) | full | last | first | user |
76
+ # #2 ------- | ******* | ******** | | | | |
77
+ context %q|with 'last_name_kanji', 'first_name_kanji'| do
78
+ before do
79
+ params['profile'].except!('full_name_kanji')
80
+ params['profile'].except!('full_name', 'last_name', 'first_name')
81
+ end
82
+ it { expect(profile.full_name).to eq('山田 太郎') }
83
+ it { expect(profile.family_name).to eq('山田') }
84
+ it { expect(profile.given_name).to eq('太郎') }
85
+ end
86
+
87
+ # full(K) | last(K) | first(K) | full | last | first | user |
88
+ # #2 ------- | ******* | -------- | | | | |
89
+ context %q|with 'last_name_kanji'| do
90
+ before do
91
+ params['profile'].except!('full_name_kanji', 'first_name_kanji')
92
+ params['profile'].except!('full_name', 'last_name', 'first_name')
93
+ end
94
+ it { expect(profile.full_name).to eq('山田') }
95
+ it { expect(profile.family_name).to eq('山田') }
96
+ it { expect(profile.given_name).to eq('') }
97
+ end
98
+
99
+ # full(K) | last(K) | first(K) | full | last | first | user |
100
+ # #2 ------- | ------- | ******** | | | | |
101
+ context %q|with 'first_name_kanji'| do
102
+ before do
103
+ params['profile'].except!('full_name_kanji', 'last_name_kanji')
104
+ params['profile'].except!('full_name', 'last_name', 'first_name')
105
+ end
106
+ it { expect(profile.full_name).to eq('太郎') }
107
+ it { expect(profile.family_name).to eq('') }
108
+ it { expect(profile.given_name).to eq('太郎') }
109
+ end
110
+
111
+ # full(K) | last(K) | first(K) | full | last | first | user |
112
+ # #2' | | | ---- | **** | ***** | |
113
+ context %q|with 'last_name', 'first_name'| do
114
+ before do
115
+ params['profile'].except!('full_name_kanji', 'last_name_kanji', 'first_name_kanji')
116
+ params['profile'].except!('full_name')
117
+ end
118
+ it { expect(profile.full_name).to eq('YAMADA Taro') }
119
+ it { expect(profile.family_name).to eq('YAMADA') }
120
+ it { expect(profile.given_name).to eq('Taro') }
121
+ end
122
+
123
+ # full(K) | last(K) | first(K) | full | last | first | user |
124
+ # #2' | | | ---- | **** | ----- | |
125
+ context %q|with 'last_name'| do
126
+ before do
127
+ params['profile'].except!('full_name_kanji', 'last_name_kanji', 'first_name_kanji')
128
+ params['profile'].except!('full_name', 'first_name')
129
+ end
130
+ it { expect(profile.full_name).to eq('YAMADA') }
131
+ it { expect(profile.family_name).to eq('YAMADA') }
132
+ it { expect(profile.given_name).to eq('') }
133
+ end
134
+
135
+ # full(K) | last(K) | first(K) | full | last | first | user |
136
+ # #2' | | | ---- | ---- | ***** | |
137
+ context %q|with 'first_name'| do
138
+ before do
139
+ params['profile'].except!('full_name_kanji', 'last_name_kanji', 'first_name_kanji')
140
+ params['profile'].except!('full_name', 'last_name')
141
+ end
142
+ it { expect(profile.full_name).to eq('Taro') }
143
+ it { expect(profile.family_name).to eq('') }
144
+ it { expect(profile.given_name).to eq('Taro') }
145
+ end
146
+
147
+ # full(K) | last(K) | first(K) | full | last | first | user |
148
+ # #3 ******* | ------- | -------- | | | | |
149
+ context %q|with 'full_name_kanji'| do
150
+ before do
151
+ params['profile'].except!('last_name_kanji', 'first_name_kanji')
152
+ params['profile'].except!('full_name', 'last_name', 'first_name')
153
+ end
154
+ it { expect(profile.full_name).to eq('山田 太郎') }
155
+ it { expect(profile.family_name).to eq('山田 太郎') }
156
+ it { expect(profile.given_name).to eq('') }
157
+ end
158
+
159
+ # full(K) | last(K) | first(K) | full | last | first | user |
160
+ # #3' | | | **** | ---- | ----- | |
161
+ context %q|with 'full_name'| do
162
+ before do
163
+ params['profile'].except!('full_name_kanji', 'last_name_kanji', 'first_name_kanji')
164
+ params['profile'].except!('last_name', 'first_name')
165
+ end
166
+ it { expect(profile.full_name).to eq('YAMADA Taro') }
167
+ it { expect(profile.family_name).to eq('YAMADA Taro') }
168
+ it { expect(profile.given_name).to eq('') }
169
+ end
170
+
171
+ # full(K) | last(K) | first(K) | full | last | first | user |
172
+ # #4 ------- | ------- | -------- | ---- | ---- | ----- | **** |
173
+ context %q|with only 'user_name'| do
174
+ before do
175
+ params['profile'].except!('full_name_kanji', 'last_name_kanji', 'first_name_kanji')
176
+ params['profile'].except!('full_name', 'last_name', 'first_name')
177
+ end
178
+ it { expect(profile.full_name).to eq('taro') }
179
+ it { expect(profile.family_name).to eq('') }
180
+ it { expect(profile.given_name).to eq('') }
181
+ end
182
+
183
+ # full(K) | last(K) | first(K) | full | last | first | user |
184
+ # #5 ------- | ------- | -------- | ---- | ---- | ----- | ---- |
185
+ context %q|with nothing| do
186
+ before do
187
+ params['profile'].except!('full_name_kanji', 'last_name_kanji', 'first_name_kanji')
188
+ params['profile'].except!('full_name', 'last_name', 'first_name')
189
+ params['profile'].except!('user_name')
190
+ end
191
+ it { expect(profile.full_name).to eq('') }
192
+ it { expect(profile.family_name).to eq('') }
193
+ it { expect(profile.given_name).to eq('') }
194
+ end
195
+ end
196
+
197
+ describe 'kana stuff' do
198
+ # full(K) | last(K) | first(K) |
199
+ # #1 ******* | ******* | ******** |
200
+ it { expect(profile.full_name_kana).to eq('ヤマダ タロウ') }
201
+ it { expect(profile.family_name_kana).to eq('ヤマダ') }
202
+ it { expect(profile.given_name_kana).to eq('タロウ') }
203
+
204
+ # full(K) | last(K) | first(K) |
205
+ # #1 ******* | ******* | -------- |
206
+ context %q|with 'full_name_kana', 'last_name_kana'| do
207
+ before do
208
+ params['profile'].except!('first_name_kana')
209
+ end
210
+ it { expect(profile.full_name_kana).to eq('ヤマダ タロウ') }
211
+ it { expect(profile.family_name_kana).to eq('ヤマダ') }
212
+ it { expect(profile.given_name_kana).to eq('') }
213
+ end
214
+
215
+ # full(K) | last(K) | first(K) |
216
+ # #1 ******* | ------- | ******** |
217
+ context %q|with 'full_name_kana', 'first_name_kana'| do
218
+ before do
219
+ params['profile'].except!('last_name_kana')
220
+ end
221
+ it { expect(profile.full_name_kana).to eq('ヤマダ タロウ') }
222
+ it { expect(profile.family_name_kana).to eq('') }
223
+ it { expect(profile.given_name_kana).to eq('タロウ') }
224
+ end
225
+
226
+ # full(K) | last(K) | first(K) |
227
+ # #2 ------- | ******* | ******** |
228
+ context %q|with 'last_name_kana', 'first_name_kana'| do
229
+ before do
230
+ params['profile'].except!('full_name_kana')
231
+ end
232
+ it { expect(profile.full_name_kana).to eq('ヤマダ タロウ') }
233
+ it { expect(profile.family_name_kana).to eq('ヤマダ') }
234
+ it { expect(profile.given_name_kana).to eq('タロウ') }
235
+ end
236
+
237
+ # full(K) | last(K) | first(K) |
238
+ # #2 ------- | ******* | -------- |
239
+ context %q|with 'last_name_kana'| do
240
+ before do
241
+ params['profile'].except!('full_name_kana', 'first_name_kana')
242
+ end
243
+ it { expect(profile.full_name_kana).to eq('ヤマダ') }
244
+ it { expect(profile.family_name_kana).to eq('ヤマダ') }
245
+ it { expect(profile.given_name_kana).to eq('') }
246
+ end
247
+
248
+ # full(K) | last(K) | first(K) |
249
+ # #2 ------- | ------- | ******** |
250
+ context %q|with 'first_name_kana'| do
251
+ before do
252
+ params['profile'].except!('full_name_kana', 'last_name_kana')
253
+ end
254
+ it { expect(profile.full_name_kana).to eq('タロウ') }
255
+ it { expect(profile.family_name_kana).to eq('') }
256
+ it { expect(profile.given_name_kana).to eq('タロウ') }
257
+ end
258
+
259
+ # full(K) | last(K) | first(K) |
260
+ # #3 ******* | ------- | -------- |
261
+ context %q|with 'full_name_kana'| do
262
+ before do
263
+ params['profile'].except!('last_name_kana', 'first_name_kana')
264
+ end
265
+ it { expect(profile.full_name_kana).to eq('ヤマダ タロウ') }
266
+ it { expect(profile.family_name_kana).to eq('ヤマダ タロウ') }
267
+ it { expect(profile.given_name_kana).to eq('') }
268
+ end
269
+
270
+ # full(K) | last(K) | first(K) | full | last | first | user |
271
+ # #5 ------- | ------- | -------- | ---- | ---- | ----- | ---- |
272
+ context %q|with nothing| do
273
+ before do
274
+ params['profile'].except!('full_name_kana', 'last_name_kana', 'first_name_kana')
275
+ end
276
+ it { expect(profile.full_name_kana).to eq('') }
277
+ it { expect(profile.family_name_kana).to eq('') }
278
+ it { expect(profile.given_name_kana).to eq('') }
279
+ end
280
+ end
281
+
282
+ describe '#zip_code' do
283
+ it { expect(profile.zip_code).to eq('112-0002') }
284
+ context %q|when 'postal_code' is missing| do
285
+ before do
286
+ params['profile'].except!('postal_code')
287
+ end
288
+ it { expect(profile.zip_code).to be_nil }
289
+ end
290
+ end
291
+
292
+ describe 'location stuff' do
293
+ it { expect(profile.prefecture).to eq(13) }
294
+ it { expect(profile.prefecture_name).to eq('東京都') }
295
+ it { expect(profile.city).to eq(13106) }
296
+ it { expect(profile.location).to eq('文京区1-2-1') }
297
+
298
+ context %q|'location_jis_id' is out of range| do
299
+ before do
300
+ params['profile']['location_jis_id'] = 50101
301
+ end
302
+ it { expect(profile.prefecture).to be_nil }
303
+ it { expect(profile.prefecture_name).to eq('') }
304
+ it { expect(profile.city).to be_nil }
305
+ it { expect(profile.location).to eq('東京都文京区1-2-1') }
306
+ end
307
+
308
+ context %q|'location_jis_id' is missing| do
309
+ before do
310
+ params['profile'].except!('location_jis_id')
311
+ end
312
+ it { expect(profile.prefecture).to be_nil }
313
+ it { expect(profile.prefecture_name).to eq('') }
314
+ it { expect(profile.city).to be_nil }
315
+ it { expect(profile.location).to eq('東京都文京区1-2-1') }
316
+ end
317
+
318
+ context %q|'location_jis_id' and 'location' are missing| do
319
+ before do
320
+ params['profile'].except!('location_jis_id', 'location')
321
+ end
322
+ it { expect(profile.prefecture).to be_nil }
323
+ it { expect(profile.prefecture_name).to eq('') }
324
+ it { expect(profile.city).to be_nil }
325
+ it { expect(profile.location).to eq('') }
326
+ end
327
+ end
328
+
329
+ describe 'birthday' do
330
+ it { expect(profile.birthday).to eq(Date.parse('1990-1-1')) }
331
+
332
+ context %q|when 'birthday' is missing| do
333
+ before do
334
+ params['profile'].except!('birthday')
335
+ end
336
+ it { expect(profile.birthday).to be_nil }
337
+ end
338
+
339
+ context %q|when 'birthday' is invalid| do
340
+ before do
341
+ params['profile']['birthday'] = '-1990-1-1'
342
+ end
343
+ it { expect(profile.birthday).to be_nil }
344
+ end
345
+ end
346
+
347
+ describe 'gender' do
348
+ it { expect(profile.gender).to eq(1) }
349
+
350
+ context %q|when 'gender' is missing| do
351
+ before do
352
+ params['profile'].except!('gender')
353
+ end
354
+ it { expect(profile.gender).to be_nil }
355
+ end
356
+
357
+ context %q|when 'gender' is invalid| do
358
+ before do
359
+ params['profile']['gender'] = 99
360
+ end
361
+ it { expect(profile.gender).to be_nil }
362
+ end
363
+ end
364
+
365
+ describe 'urls' do
366
+ it { expect(profile.urls).to eq([ URI('http://example.com') ]) }
367
+
368
+ context %q|when 'uri' is missing| do
369
+ before do
370
+ params['profile'].except!('uri')
371
+ end
372
+ it { expect(profile.urls).to eq([]) }
373
+ end
374
+
375
+ context %q|when 'uri' is empty| do
376
+ before do
377
+ params['profile']['uri'] = []
378
+ end
379
+ it { expect(profile.urls).to eq([]) }
380
+ end
381
+
382
+ context %q|when 'uri' is invalid| do
383
+ before do
384
+ params['profile']['uri'] = [ '-http://example.com' ]
385
+ end
386
+ it { expect(profile.urls).to eq([]) }
387
+ end
388
+ context %q|when scheme of 'uri' is invalid| do
389
+ before do
390
+ params['profile']['uri'] = [ 'ftp://example.com' ]
391
+ end
392
+ it { expect(profile.urls).to eq([]) }
393
+ end
394
+ end
395
+ describe 'email' do
396
+ it { expect(profile.emails).to eq(['taro-facebook@example.com', 'taro-twitter@example.com']) }
397
+
398
+ context %q|when 'email' is missing| do
399
+ before do
400
+ params.except!('email')
401
+ end
402
+ it { expect(profile.emails).to eq([]) }
403
+ end
404
+ context %q|when 'email' is empty| do
405
+ before do
406
+ params['email'] = []
407
+ end
408
+ it { expect(profile.emails).to eq([]) }
409
+ end
410
+ context %q|when 'email[0]/email' is missing| do
411
+ before do
412
+ params['email'][0]['email'] = nil
413
+ end
414
+ it { expect(profile.emails).to eq(['taro-twitter@example.com']) }
415
+ end
416
+ end
417
+ end
418
+ end