Skip to content
This repository was archived by the owner on Oct 7, 2022. It is now read-only.

Commit baa8492

Browse files
author
Sebastian Wilgosz
committed
Relationship support for CTB objects
1 parent 8495a2f commit baa8492

10 files changed

+275
-9
lines changed

Gemfile.lock

+12
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,24 @@ PATH
22
remote: .
33
specs:
44
creatubbles (0.0.1)
5+
activesupport
56
oauth2 (>= 1.3.0)
67

78
GEM
89
remote: https://rubygems.org/
910
specs:
11+
activesupport (5.0.1)
12+
concurrent-ruby (~> 1.0, >= 1.0.2)
13+
i18n (~> 0.7)
14+
minitest (~> 5.1)
15+
tzinfo (~> 1.1)
16+
concurrent-ruby (1.0.4)
1017
diff-lcs (1.2.5)
1118
faraday (0.10.1)
1219
multipart-post (>= 1.2, < 3)
20+
i18n (0.8.0)
1321
jwt (1.5.6)
22+
minitest (5.10.1)
1423
multi_json (1.12.1)
1524
multi_xml (0.6.0)
1625
multipart-post (2.0.0)
@@ -35,6 +44,9 @@ GEM
3544
diff-lcs (>= 1.2.0, < 2.0)
3645
rspec-support (~> 3.5.0)
3746
rspec-support (3.5.0)
47+
thread_safe (0.3.5)
48+
tzinfo (1.2.2)
49+
thread_safe (~> 0.1)
3850

3951
PLATFORMS
4052
ruby

creatubbles.gemspec

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ spec = Gem::Specification.new do |s|
1414
s.license = 'MIT'
1515

1616
s.add_dependency('oauth2', '>= 1.3.0')
17+
s.add_dependency('activesupport')
1718

1819
s.files = `git ls-files`.split("\n")
1920
s.test_files = `git ls-files -- test/*`.split("\n")

lib/creatubbles/base_object.rb

+29
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
1+
require 'active_support/core_ext/module/attribute_accessors'
2+
13
class Creatubbles::BaseObject
24

5+
def self.inherited(subclass)
6+
subclass.mattr_reader :attributes, :relationships
7+
subclass.class_variable_set(:@@attributes, [])
8+
subclass.class_variable_set(:@@relationships, [])
9+
end
10+
311
def self.define_type_name(type_name)
412
@type_name = type_name
513
Creatubbles.register_type_object_class(type_name, self)
@@ -11,6 +19,8 @@ def self.type_name
1119

1220
def self.define_attributes(atts)
1321
atts.each do |att|
22+
raise "Duplicated attribute: #{attr}" if attributes.include?(att.to_sym)
23+
attributes << att.to_sym
1424
class_eval <<-EOM, __FILE__, __LINE__ + 1
1525
def #{att}
1626
@data['attributes']['#{att}']
@@ -19,6 +29,25 @@ def #{att}
1929
end
2030
end
2131

32+
def self.define_relationships(relations)
33+
relations.each do |k, v|
34+
raise "Duplicated relationship: #{k}" if relationships.include?(k.to_sym)
35+
relationships << k.to_sym
36+
class_eval <<-EOM, __FILE__, __LINE__ + 1
37+
def #{k}
38+
relationship = @data['relationships']['#{k}']
39+
return nil unless relationship.is_a?(Hash)
40+
case (relationship_data = relationship['data']).class.name
41+
when 'Hash'
42+
relationship_data['id']
43+
when 'Array'
44+
relationship_data.map { |relation| relation['id'] }
45+
end
46+
end
47+
EOM
48+
end
49+
end
50+
2251
def initialize(connection, data)
2352
@connection = connection
2453
@data = data

lib/creatubbles/creation.rb

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
require "creatubbles/base_object"
22

33
class Creatubbles::Creation < Creatubbles::BaseObject
4-
54
define_type_name 'creations'
65
define_attributes %w[
76
name
@@ -28,6 +27,8 @@ class Creatubbles::Creation < Creatubbles::BaseObject
2827
updated_at
2928
]
3029

30+
define_relationships %w[user creators]
31+
3132
def update_tags(tags)
3233
@connection.put("creations/#{id}", :body => { 'data' => { 'type' => 'creations', 'attributes': {'tags' => tags }}})
3334
end

lib/creatubbles/user.rb

+22-4
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,37 @@ class Creatubbles::User < Creatubbles::BaseObject
44

55
define_type_name 'users'
66
define_attributes %w[
7-
name
8-
email
7+
username
98
display_name
10-
creations_count
9+
list_name
10+
name
11+
role
12+
age
13+
gender
14+
country_code
15+
country_name
16+
avatar_url
17+
short_url
18+
added_bubbles_count
19+
activities_count
1120
bubbles_count
1221
comments_count
22+
creations_count
23+
creators_count
24+
galleries_count
25+
managers_count
1326
last_bubbled_at
1427
last_commented_at
15-
short_url
28+
signed_up_as_instructor
29+
what_do_you_teach
30+
interests
31+
home_schooling
1632
created_at
1733
updated_at
1834
]
1935

36+
define_relationships %w[school custom_style]
37+
2038
def creators
2139
res = @connection.get("users/#{id}/creators")
2240
Creatubbles.instantiate_objects_from_response(res, @connection)

spec/creatubbles/creation_spec.rb

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
require 'helper'
2+
3+
describe Creatubbles::Creation do
4+
let(:client) { Creatubbles::Client.new }
5+
6+
let(:connection) do
7+
token = { access_token: "sample", token_type: "bearer", created_at: 1479918313 }
8+
OAuth2::AccessToken.from_hash(client, token)
9+
end
10+
11+
subject { Creatubbles::Creation.new(connection, creation_json['data']) }
12+
13+
describe '.type_name' do
14+
it "should return proper type" do
15+
expect(Creatubbles::Creation.type_name).to eq 'creations'
16+
end
17+
end
18+
19+
describe 'attributes' do
20+
it 'attributes list should be accessible from class and from object' do
21+
subject.attributes == Creatubbles::Creation.attributes
22+
end
23+
24+
Creatubbles::Creation.attributes.each do |attr|
25+
it 'should return proper attributes' do
26+
expect(subject).to respond_to(attr)
27+
expect(subject.send(attr)).to eq(creation_json['data']['attributes'][attr.to_s])
28+
end
29+
end
30+
end
31+
32+
describe 'relationships' do
33+
it 'should include user id' do
34+
expect(subject.user).to eq 'xUt6Feou'
35+
end
36+
37+
it 'should include creator_ids' do
38+
expect(subject.creators).to eq ['xUt6Feou']
39+
end
40+
end
41+
end

spec/creatubbles/user_spec.rb

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
require 'helper'
2+
3+
describe Creatubbles::User do
4+
let(:client) { Creatubbles::Client.new }
5+
6+
let(:connection) do
7+
token = { access_token: "sample", token_type: "bearer", created_at: 1479918313 }
8+
OAuth2::AccessToken.from_hash(client, token)
9+
end
10+
11+
subject { Creatubbles::User.new(connection, creation_json['data']) }
12+
13+
describe '.type_name' do
14+
it "should return proper type" do
15+
expect(Creatubbles::User.type_name).to eq 'users'
16+
end
17+
end
18+
19+
describe 'attributes' do
20+
it 'attributes list should be accessible from class and from object' do
21+
subject.attributes == Creatubbles::User.attributes
22+
end
23+
24+
Creatubbles::User.attributes.each do |attr|
25+
it 'should return proper attributes' do
26+
expect(subject).to respond_to(attr)
27+
expect(subject.send(attr)).to eq(creation_json['data']['attributes'][attr.to_s])
28+
end
29+
end
30+
end
31+
32+
describe 'relationships' do
33+
it 'should include user id' do
34+
expect(subject.school).to be_nil
35+
end
36+
37+
it 'should include creator_ids' do
38+
expect(subject.custom_style).to be_nil
39+
end
40+
end
41+
end

spec/helper.rb

+2-4
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,7 @@
1010
config.expect_with :rspec do |c|
1111
c.syntax = :expect
1212
end
13-
end
14-
1513

16-
RSpec.configure do |conf|
17-
include CreationJson
14+
config.include CreationJson
15+
config.include UserJson
1816
end

spec/support/creation_json.rb

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
module CreationJson
2+
def creation_json
3+
{
4+
"data"=>{
5+
"id"=>"XIeQuGLw",
6+
"type"=>"creations",
7+
"attributes"=> creation_json_attributes,
8+
"relationships"=>{
9+
"user"=>{ "data"=>{ "id"=>"xUt6Feou", "type"=>"users" } },
10+
"creators"=>{
11+
"data"=>[
12+
{ "id"=>"xUt6Feou", "type"=>"users" }
13+
]
14+
},
15+
"partner_application"=>{ "data"=>nil }
16+
}
17+
},
18+
"included"=>[
19+
{
20+
"id"=>"xUt6Feou",
21+
"type"=>"users",
22+
"attributes"=> user_json_attributes,
23+
"relationships"=>{
24+
"school"=>{ "data"=>nil },
25+
"custom_style"=> { "data"=>{ "id"=>"3584", "type"=>"custom_styles"} }
26+
}
27+
}
28+
],
29+
"meta"=>{ "abilities"=>[], "user_bubbled_creations"=>[], "followed_users"=>[] }
30+
}
31+
end
32+
33+
def creation_json_attributes
34+
{
35+
'name' => 'A boat',
36+
"translated_names"=>[
37+
{ "code"=>"en", "name"=>"A boat", "original"=>true }
38+
],
39+
"image"=>{
40+
"links"=>{
41+
"original"=>"https://api.creatubbles.com/v2/creation/XIeQuGLw/original/boat.jpg",
42+
"full_view"=>"https://api.creatubbles.com/v2/creation/XIeQuGLw/full_view/boat.jpg",
43+
"gallery_mobile"=>"https://api.creatubbles.com/v2/creation/XIeQuGLw/gallery_mobile/boat.jpg",
44+
"list_view_retina"=>"https://api.creatubbles.com/v2/creation/XIeQuGLw/list_view_retina/boat.jpg",
45+
"share"=>"https://api.creatubbles.com/v2/creation/XIeQuGLw/share/boat.jpg",
46+
"list_view"=>"https://api.creatubbles.com/v2/creation/XIeQuGLw/list_view/boat.jpg",
47+
"matrix_view_retina"=>"https://api.creatubbles.com/v2/creation/XIeQuGLw/matrix_view_retina/boat.jpg",
48+
"matrix_view"=>"https://api.creatubbles.com/v2/creation/XIeQuGLw/matrix_view/boat.jpg",
49+
"explore_mobile"=>"https://api.creatubbles.com/v2/creation/XIeQuGLw/explore_mobile/boat.jpg"
50+
}
51+
},
52+
"image_status"=>3,
53+
"approved"=>true,
54+
"approval_status"=>"approved",
55+
"created_at_age"=>"at 14y",
56+
"created_at_age_per_creator"=>{"xUt6Feou"=>nil},
57+
"reflection_text"=> 'My reflection',
58+
"reflection_video_url"=>nil,
59+
"play_iframe_url"=>nil,
60+
"obj_file_url"=>nil,
61+
"bubbles_count"=>1,
62+
"comments_count"=>0,
63+
"views_count"=>5,
64+
"last_bubbled_at"=>"2017-01-25T14:07:54.202+01:00",
65+
"last_commented_at"=>nil,
66+
"last_submitted_at"=>nil,
67+
'short_url' => "https://ctbl.es/XIeQuGLw",
68+
"content_type"=>"video/quicktime",
69+
"tags" => [ 'School', 'Animals' ],
70+
"created_at"=>"2017-01-23T16:24:08.112+01:00",
71+
"updated_at"=>"2017-01-25T14:07:54.252+01:00"
72+
}
73+
end
74+
end

spec/support/user_json.rb

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
module UserJson
2+
def user_json
3+
{
4+
"data"=> {
5+
"id"=>"xUt6Feou",
6+
"type"=>"users",
7+
"attributes"=> user_json_attributes,
8+
"relationships"=>{
9+
"school"=>{ "data"=>nil },
10+
"custom_style"=>{ "data"=>{ "id"=>"525", "type"=>"custom_styles" } }
11+
}
12+
}
13+
}
14+
end
15+
16+
def user_json_attributes
17+
{
18+
"username"=>"teacher098260598",
19+
"display_name"=>"teacher098260598",
20+
"list_name"=>"teacher098260598 (@teacher098260598)",
21+
"name"=>"teacher098260598",
22+
"role"=>"instructor",
23+
"avatar_url"=>"https://d3fll5fltyv3n9.cloudfront.net/users/72057/creations/33535/matrix_view_retina/1485185089creation.jpg",
24+
"age"=>"",
25+
"gender"=>"unknown",
26+
"last_bubbled_at"=>"2017-01-23T19:04:24.045Z",
27+
"last_commented_at"=>nil,
28+
"activities_count"=>2,
29+
"comments_count"=>0,
30+
"followed_users_count"=>0,
31+
"creators_count"=>6,
32+
"galleries_count"=>0,
33+
"managers_count"=>0,
34+
"short_url"=>"https://staging.ctbl.es/teacher098260598",
35+
"what_do_you_teach"=>nil,
36+
"interests"=>nil,
37+
"country_code"=>"PL",
38+
"country_flag_url"=>"https://d2r48com4t2oyq.cloudfront.net/assets/country-4x3/pl-c4d5935a0981cf8a0ac04a9f873cc2f9e2f15a8cf8ba0682e6f56f1000db6556.svg",
39+
"created_at"=>"2017-01-23T12:44:50.021Z",
40+
"updated_at"=>"2017-01-25T13:08:01.177Z",
41+
"connected_users_count"=>5,
42+
"is_young_creator"=>false,
43+
"country_name"=>"Poland",
44+
"signed_up_as_instructor"=>true,
45+
"home_schooling"=>true,
46+
"bubbles_count"=>2,
47+
"added_bubbles_count"=>1,
48+
"creations_count"=>1
49+
}
50+
end
51+
end

0 commit comments

Comments
 (0)