brickset_api 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.ruby-gemset +1 -0
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +4 -0
  6. data/Gemfile +6 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +145 -0
  9. data/Rakefile +6 -0
  10. data/bin/console +14 -0
  11. data/bin/setup +8 -0
  12. data/brickset.gemspec +30 -0
  13. data/lib/brickset.rb +55 -0
  14. data/lib/brickset/api/auth.rb +22 -0
  15. data/lib/brickset/api/collection/advanced.rb +34 -0
  16. data/lib/brickset/api/collection/minifig.rb +35 -0
  17. data/lib/brickset/api/collection/set.rb +117 -0
  18. data/lib/brickset/api/set.rb +157 -0
  19. data/lib/brickset/client.rb +56 -0
  20. data/lib/brickset/configuration.rb +9 -0
  21. data/lib/brickset/elements/additional_image.rb +13 -0
  22. data/lib/brickset/elements/collection_detail.rb +28 -0
  23. data/lib/brickset/elements/collection_total.rb +15 -0
  24. data/lib/brickset/elements/condition.rb +11 -0
  25. data/lib/brickset/elements/instruction.rb +12 -0
  26. data/lib/brickset/elements/minifig_collection.rb +15 -0
  27. data/lib/brickset/elements/review.rb +20 -0
  28. data/lib/brickset/elements/set.rb +67 -0
  29. data/lib/brickset/elements/subtheme.rb +15 -0
  30. data/lib/brickset/elements/theme.rb +15 -0
  31. data/lib/brickset/elements/user_note.rb +12 -0
  32. data/lib/brickset/elements/year.rb +13 -0
  33. data/lib/brickset/version.rb +3 -0
  34. data/spec/brickset/api/auth_spec.rb +84 -0
  35. data/spec/brickset/api/collection/advanced_spec.rb +59 -0
  36. data/spec/brickset/api/collection/minifig_spec.rb +95 -0
  37. data/spec/brickset/api/collection/set_spec.rb +350 -0
  38. data/spec/brickset/api/set_spec.rb +658 -0
  39. data/spec/brickset/client_spec.rb +155 -0
  40. data/spec/brickset/configuration_spec.rb +9 -0
  41. data/spec/brickset/elements/additional_image_spec.rb +26 -0
  42. data/spec/brickset/elements/collection_detail_spec.rb +40 -0
  43. data/spec/brickset/elements/collection_total_spec.rb +27 -0
  44. data/spec/brickset/elements/condition_spec.rb +23 -0
  45. data/spec/brickset/elements/instruction_spec.rb +24 -0
  46. data/spec/brickset/elements/minifig_collection_spec.rb +27 -0
  47. data/spec/brickset/elements/review_spec.rb +32 -0
  48. data/spec/brickset/elements/set_spec.rb +72 -0
  49. data/spec/brickset/elements/subtheme_spec.rb +27 -0
  50. data/spec/brickset/elements/theme_spec.rb +27 -0
  51. data/spec/brickset/elements/user_note_spec.rb +24 -0
  52. data/spec/brickset/elements/year_spec.rb +25 -0
  53. data/spec/brickset_spec.rb +59 -0
  54. data/spec/fixtures/api_key_invalid.xml +2 -0
  55. data/spec/fixtures/api_key_valid.xml +2 -0
  56. data/spec/fixtures/get_additional_images.xml +24 -0
  57. data/spec/fixtures/get_additional_images_no_result.xml +2 -0
  58. data/spec/fixtures/get_collection_detail.xml +23 -0
  59. data/spec/fixtures/get_collection_detail_conditions.xml +24 -0
  60. data/spec/fixtures/get_collection_detail_no_result.xml +2 -0
  61. data/spec/fixtures/get_collection_totals.xml +8 -0
  62. data/spec/fixtures/get_collection_totals_no_result.xml +8 -0
  63. data/spec/fixtures/get_instructions.xml +7 -0
  64. data/spec/fixtures/get_instructions_no_result.xml +2 -0
  65. data/spec/fixtures/get_minifig_collection.xml +31 -0
  66. data/spec/fixtures/get_minifig_collection_owned.xml +17 -0
  67. data/spec/fixtures/get_minifig_collection_wanted.xml +10 -0
  68. data/spec/fixtures/get_recently_updated_sets.xml +52 -0
  69. data/spec/fixtures/get_recently_updated_sets_invalid_key.xml +1 -0
  70. data/spec/fixtures/get_reviews.xml +28 -0
  71. data/spec/fixtures/get_reviews_no_result.xml +2 -0
  72. data/spec/fixtures/get_set.xml +52 -0
  73. data/spec/fixtures/get_set_no_result.xml +2 -0
  74. data/spec/fixtures/get_sets.xml +101 -0
  75. data/spec/fixtures/get_sets_no_result.xml +2 -0
  76. data/spec/fixtures/get_subthemes.xml +24 -0
  77. data/spec/fixtures/get_subthemes_for_user.xml +24 -0
  78. data/spec/fixtures/get_subthemes_for_user_no_result.xml +2 -0
  79. data/spec/fixtures/get_subthemes_for_user_owned.xml +24 -0
  80. data/spec/fixtures/get_subthemes_for_user_wanted.xml +31 -0
  81. data/spec/fixtures/get_subthemes_no_result.xml +2 -0
  82. data/spec/fixtures/get_themes.xml +17 -0
  83. data/spec/fixtures/get_themes_for_user.xml +17 -0
  84. data/spec/fixtures/get_themes_for_user_no_result.xml +2 -0
  85. data/spec/fixtures/get_themes_for_user_owned.xml +17 -0
  86. data/spec/fixtures/get_themes_for_user_wanted.xml +25 -0
  87. data/spec/fixtures/get_themes_no_result.xml +2 -0
  88. data/spec/fixtures/get_user_notes.xml +11 -0
  89. data/spec/fixtures/get_user_notes_no_result.xml +2 -0
  90. data/spec/fixtures/get_years.xml +18 -0
  91. data/spec/fixtures/get_years_for_user.xml +18 -0
  92. data/spec/fixtures/get_years_for_user_no_result.xml +2 -0
  93. data/spec/fixtures/get_years_for_user_owned.xml +13 -0
  94. data/spec/fixtures/get_years_for_user_wanted.xml +13 -0
  95. data/spec/fixtures/get_years_no_result.xml +2 -0
  96. data/spec/fixtures/login.xml +2 -0
  97. data/spec/fixtures/login_invalid_credentials.xml +2 -0
  98. data/spec/fixtures/login_invalid_key.xml +2 -0
  99. data/spec/fixtures/set_collection.xml +2 -0
  100. data/spec/fixtures/set_collection_invalid.xml +2 -0
  101. data/spec/fixtures/set_collection_owns.xml +2 -0
  102. data/spec/fixtures/set_collection_owns_invalid.xml +2 -0
  103. data/spec/fixtures/set_collection_qty_owned.xml +2 -0
  104. data/spec/fixtures/set_collection_qty_owned_invalid.xml +2 -0
  105. data/spec/fixtures/set_collection_user_notes.xml +2 -0
  106. data/spec/fixtures/set_collection_user_notes_invalid.xml +2 -0
  107. data/spec/fixtures/set_collection_wants.xml +2 -0
  108. data/spec/fixtures/set_collection_wants_invalid.xml +2 -0
  109. data/spec/fixtures/set_minifig_collection.xml +2 -0
  110. data/spec/fixtures/set_minifig_collection_invalid.xml +2 -0
  111. data/spec/fixtures/set_user_rating.xml +2 -0
  112. data/spec/fixtures/set_user_rating_invalid.xml +2 -0
  113. data/spec/fixtures/token_invalid.xml +2 -0
  114. data/spec/fixtures/token_valid.xml +2 -0
  115. data/spec/spec_helper.rb +43 -0
  116. metadata +355 -0
@@ -0,0 +1,12 @@
1
+ module Brickset
2
+ module Elements
3
+ class UserNote
4
+ include HappyMapper
5
+
6
+ tag 'userNotes'
7
+
8
+ element :set_id, Integer, tag: 'setID'
9
+ element :user_notes, String, tag: 'userNotes'
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ module Brickset
2
+ module Elements
3
+ class Year
4
+ include HappyMapper
5
+
6
+ tag 'years'
7
+
8
+ element :theme, String
9
+ element :year, String
10
+ element :set_count, Integer, tag: 'setCount'
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ module Brickset
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,84 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Brickset::Client do
4
+ let(:api_key) { Brickset.configuration.api_key }
5
+
6
+ describe '#login' do
7
+ let(:username) { 'darth-vader' }
8
+ let(:password) { 'i-am-your-father' }
9
+
10
+ context 'with valid credentials and API key' do
11
+ before { stub_post('/login').with(body: "username=#{username}&password=#{password}&apiKey=#{api_key}").to_return body: fixture('login.xml') }
12
+
13
+ it 'receives an user hash' do
14
+ expect(subject.login(username, password)).to eq 'abc123!@#'
15
+ end
16
+ end
17
+
18
+ context 'with invalid credentials' do
19
+ let(:password) { 'invalid' }
20
+
21
+ before { stub_post('/login').with(body: "username=#{username}&password=#{password}&apiKey=#{api_key}").to_return body: fixture('login_invalid_credentials.xml') }
22
+
23
+ it 'receives an error response' do
24
+ expect(subject.login(username, password)).to eq 'ERROR: invalid username and/or password'
25
+ end
26
+ end
27
+
28
+ context 'with an invalid API key' do
29
+ before do
30
+ allow(Brickset).to receive(:configuration).and_return double(api_key: 'invalid')
31
+ stub_post('/login').with(body: "username=#{username}&password=#{password}&apiKey=#{api_key}").to_return body: fixture('login_invalid_key.xml')
32
+ end
33
+
34
+ it 'receives an INVALIDKEY response' do
35
+ expect(subject.login(username, password)).to eq 'INVALIDKEY'
36
+ end
37
+ end
38
+ end
39
+
40
+ describe '#valid_api_key?' do
41
+ context 'with a valid API key' do
42
+ before { stub_post('/checkKey').with(body: "apiKey=#{api_key}").to_return body: fixture('api_key_valid.xml') }
43
+
44
+ it 'returns true' do
45
+ expect(subject.valid_api_key?).to eq true
46
+ end
47
+ end
48
+
49
+ context 'with an invalid API key' do
50
+ before do
51
+ allow(Brickset).to receive(:configuration).and_return double(api_key: 'invalid')
52
+ stub_post('/checkKey').with(body: "apiKey=#{api_key}").to_return body: fixture('api_key_invalid.xml')
53
+ end
54
+
55
+ it 'returns false' do
56
+ expect(subject.valid_api_key?).to eq false
57
+ end
58
+ end
59
+ end
60
+
61
+ describe '#valid_token?' do
62
+ subject { described_class.new(token: token) }
63
+
64
+ context 'with a valid token' do
65
+ let(:token) { 'valid' }
66
+
67
+ before { stub_post('/checkUserHash').with(body: "apiKey=#{api_key}&userHash=#{token}").to_return body: fixture('token_valid.xml') }
68
+
69
+ it 'returns true' do
70
+ expect(subject.valid_token?).to eq true
71
+ end
72
+ end
73
+
74
+ context 'with an invalid token' do
75
+ let(:token) { 'invalid' }
76
+
77
+ before { stub_post('/checkUserHash').with(body: "apiKey=#{api_key}&userHash=#{token}").to_return body: fixture('token_invalid.xml') }
78
+
79
+ it 'returns false' do
80
+ expect(subject.valid_token?).to eq false
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Brickset::Client, type: :model do
4
+ let(:api_key) { Brickset.configuration.api_key }
5
+ let(:token) { 'valid' }
6
+
7
+ subject { described_class.new(token: token) }
8
+
9
+ describe 'validations' do
10
+ it { is_expected.to validate_inclusion_of(:condition).in_array(%w(acquired now)).on :collection_detail_conditions }
11
+ end
12
+
13
+ describe 'getCollectionDetail' do
14
+ context 'with valid parameters' do
15
+ before { stub_post('/getCollectionDetail').with(body: "setID=26907&apiKey=#{api_key}&userHash=#{token}").to_return body: fixture('get_collection_detail.xml') }
16
+
17
+ it 'receives the collection detail' do
18
+ expect(subject.collection_detail(26907)).to be_a Brickset::Elements::CollectionDetail
19
+ end
20
+ end
21
+
22
+ context 'with an invalid parameter' do
23
+ before do
24
+ stub_post('/getCollectionDetail').with(body: "setID=non-existent&apiKey=#{api_key}&userHash=#{token}").to_return body: fixture('get_collection_detail_no_result.xml')
25
+ end
26
+
27
+ it 'does not receive any collection detail' do
28
+ expect(subject.collection_detail('non-existent')).to be_nil
29
+ end
30
+ end
31
+ end
32
+
33
+ describe 'getCollectionDetailConditions' do
34
+ context 'with a valid condition' do
35
+ before do
36
+ stub_post('/getCollectionDetailConditions').with(body: "which=acquired&apiKey=#{api_key}&userHash=#{token}").to_return body: fixture('get_collection_detail_conditions.xml')
37
+ end
38
+
39
+ it 'receives the collection detail conditions' do
40
+ expect(subject.collection_detail_conditions('acquired')).to match_array [
41
+ an_instance_of(Brickset::Elements::Condition),
42
+ an_instance_of(Brickset::Elements::Condition),
43
+ an_instance_of(Brickset::Elements::Condition),
44
+ an_instance_of(Brickset::Elements::Condition),
45
+ an_instance_of(Brickset::Elements::Condition),
46
+ an_instance_of(Brickset::Elements::Condition),
47
+ an_instance_of(Brickset::Elements::Condition)
48
+ ]
49
+ end
50
+ end
51
+
52
+ context 'with an invalid condition' do
53
+ it 'raises a ValidationError' do
54
+ expect { subject.collection_detail_conditions('invalid-condition') }.to raise_error Brickset::ValidationError, 'Condition is not included in the list'
55
+ end
56
+ end
57
+ end
58
+
59
+ end
@@ -0,0 +1,95 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Brickset::Client, type: :model do
4
+ let(:api_key) { Brickset.configuration.api_key }
5
+ let(:token) { 'valid' }
6
+
7
+ subject { described_class.new(token: token) }
8
+
9
+ context 'validations' do
10
+ it { is_expected.to validate_presence_of(:minifig_number).on :update_minifig_collection }
11
+ it { is_expected.to validate_presence_of(:number_owned).on :update_minifig_collection }
12
+ it { is_expected.to validate_presence_of(:wanted).on :update_minifig_collection }
13
+ it { is_expected.to validate_inclusion_of(:number_owned).in_range(0..999).on :update_minifig_collection }
14
+ it { is_expected.to validate_inclusion_of(:wanted).in_array([0, 1]).on :update_minifig_collection }
15
+ end
16
+
17
+ describe '#minifig_collection' do
18
+ context 'with valid parameters' do
19
+ context 'when using the query parameter' do
20
+ before { stub_post('/getMinifigCollection').with(body: "query=Star%20Wars&owned=&wanted=&apiKey=#{api_key}&userHash=#{token}").to_return body: fixture('get_minifig_collection.xml') }
21
+
22
+ it 'returns the minifig collections that match the search query' do
23
+ expect(subject.minifig_collection(query: 'Star Wars')).to match_array [
24
+ an_instance_of(Brickset::Elements::MinifigCollection),
25
+ an_instance_of(Brickset::Elements::MinifigCollection),
26
+ an_instance_of(Brickset::Elements::MinifigCollection),
27
+ an_instance_of(Brickset::Elements::MinifigCollection)
28
+ ]
29
+ end
30
+ end
31
+
32
+ context 'when using the owned parameter' do
33
+ before { stub_post('/getMinifigCollection').with(body: "query=&owned=1&wanted=&apiKey=#{api_key}&userHash=#{token}").to_return body: fixture('get_minifig_collection_owned.xml') }
34
+
35
+ it 'returns the owned minifig collections' do
36
+ expect(subject.minifig_collection(owned: '1')).to match_array [
37
+ an_instance_of(Brickset::Elements::MinifigCollection),
38
+ an_instance_of(Brickset::Elements::MinifigCollection)
39
+ ]
40
+ end
41
+ end
42
+ context 'when using the wanted parameter' do
43
+ before { stub_post('/getMinifigCollection').with(body: "query=&owned=&wanted=1&apiKey=#{api_key}&userHash=#{token}").to_return body: fixture('get_minifig_collection_wanted.xml') }
44
+
45
+ it 'returns the wanted minifig collections' do
46
+ expect(subject.minifig_collection(wanted: '1')).to match_array [
47
+ an_instance_of(Brickset::Elements::MinifigCollection)
48
+ ]
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ describe '#update_minifig_collection' do
55
+ let(:minifig_number) { '47205pb026' }
56
+ let(:number_owned) { 2 }
57
+ let(:wanted) { 1 }
58
+
59
+ let(:update_minifig_collection) { subject.update_minifig_collection(minifig_number: minifig_number, number_owned: number_owned, wanted: wanted) }
60
+
61
+ context 'when all required parameters are specified' do
62
+ before { stub_post('/setMinifigCollection').with(body: "minifigNumber=#{minifig_number}&qtyOwned=#{number_owned}&wanted=#{wanted}&apiKey=#{api_key}&userHash=#{token}").to_return body: body }
63
+
64
+ context 'when all parameters are valid' do
65
+ let(:body) { fixture('set_minifig_collection.xml') }
66
+
67
+ it 'updates the specified minifig collection' do
68
+ expect(update_minifig_collection).to eq true
69
+ end
70
+ end
71
+
72
+ context 'when a parameter is invalid' do
73
+ let(:body) { fixture('set_minifig_collection_invalid.xml') }
74
+
75
+ it 'does not update the specified minifig collection' do
76
+ expect(update_minifig_collection).to eq false
77
+ end
78
+
79
+ it 'sets the error on the client' do
80
+ update_minifig_collection
81
+ expect(subject.errors[:base]).to match_array [ 'ERROR: invalid userHash' ]
82
+ end
83
+ end
84
+ end
85
+
86
+ context 'when not all parameters are valid' do
87
+ let(:minifig_number) { nil }
88
+ let(:wanted) { true }
89
+
90
+ it 'raises a ValidationError' do
91
+ expect { update_minifig_collection }.to raise_error Brickset::ValidationError, "Minifig number can't be blank and Wanted is not included in the list"
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,350 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Brickset::Client, type: :model do
4
+ let(:api_key) { Brickset.configuration.api_key }
5
+ let(:token) { 'valid' }
6
+
7
+ subject { described_class.new(token: token) }
8
+
9
+ describe 'validations' do
10
+ it { is_expected.to validate_presence_of(:set_id).on :update_collection }
11
+ it { is_expected.to validate_presence_of(:number_owned).on :update_collection }
12
+ it { is_expected.to validate_presence_of(:wanted).on :update_collection }
13
+ it { is_expected.to validate_inclusion_of(:number_owned).in_range(0..999).on :update_collection }
14
+ it { is_expected.to validate_inclusion_of(:wanted).in_array([0, 1]).on :update_collection }
15
+
16
+ it { is_expected.to validate_presence_of(:set_id).on :update_collection_owned }
17
+ it { is_expected.to validate_presence_of(:owned).on :update_collection_owned }
18
+ it { is_expected.to validate_inclusion_of(:owned).in_array([0, 1]).on :update_collection_owned }
19
+
20
+ it { is_expected.to validate_presence_of(:set_id).on :update_collection_wanted }
21
+ it { is_expected.to validate_presence_of(:wanted).on :update_collection_wanted }
22
+ it { is_expected.to validate_inclusion_of(:wanted).in_array([0, 1]).on :update_collection_wanted }
23
+
24
+ it { is_expected.to validate_presence_of(:set_id).on :update_collection_number_owned }
25
+ it { is_expected.to validate_presence_of(:number_owned).on :update_collection_number_owned }
26
+ it { is_expected.to validate_inclusion_of(:number_owned).in_range(0..999).on :update_collection_number_owned }
27
+
28
+ it { is_expected.to validate_presence_of(:set_id).on :update_collection_user_notes }
29
+ it { is_expected.to validate_presence_of(:notes).on :update_collection_user_notes }
30
+ it { is_expected.to validate_length_of(:notes).is_at_most(200).on :update_collection_user_notes }
31
+
32
+ it { is_expected.to validate_presence_of(:set_id).on :update_user_rating }
33
+ it { is_expected.to validate_presence_of(:rating).on :update_user_rating }
34
+ it { is_expected.to validate_inclusion_of(:rating).in_range(0..5).on :update_user_rating }
35
+ end
36
+
37
+ describe '#collection_totals' do
38
+ let(:body) { fixture('get_collection_totals.xml') }
39
+
40
+ before { stub_post('/getCollectionTotals').with(body: "apiKey=#{api_key}&userHash=#{token}").to_return body: body }
41
+
42
+ context 'with valid parameters' do
43
+ it 'returns the collection totals' do
44
+ aggregate_failures do
45
+ expect(subject.collection_totals).to be_a Brickset::Elements::CollectionTotal
46
+ expect(subject.collection_totals.total_sets_owned).to eq 126
47
+ expect(subject.collection_totals.total_sets_wanted).to eq 85
48
+ expect(subject.collection_totals.total_minifigs_owned).to eq 156
49
+ expect(subject.collection_totals.total_minifigs_wanted).to eq 40
50
+ expect(subject.collection_totals.total_distinct_sets_owned).to eq 121
51
+ end
52
+ end
53
+ end
54
+
55
+ context 'with invalid parameters' do
56
+ let(:token) { 'invalid' }
57
+ let(:body) { fixture('get_collection_totals_no_result.xml') }
58
+
59
+ it 'returns a collection total with default values' do
60
+ aggregate_failures do
61
+ expect(subject.collection_totals).to be_a Brickset::Elements::CollectionTotal
62
+ expect(subject.collection_totals.total_sets_owned).to eq 0
63
+ expect(subject.collection_totals.total_sets_wanted).to eq 0
64
+ expect(subject.collection_totals.total_minifigs_owned).to eq 0
65
+ expect(subject.collection_totals.total_minifigs_wanted).to eq 0
66
+ expect(subject.collection_totals.total_distinct_sets_owned).to eq 0
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ describe '#update_collection' do
73
+ let(:set_id) { 26725 }
74
+ let(:number_owned) { 2 }
75
+ let(:wanted) { 1 }
76
+
77
+ let(:update_collection) { subject.update_collection(set_id: set_id, number_owned: number_owned, wanted: wanted) }
78
+
79
+ context 'when all required parameters are specified' do
80
+ before { stub_post('/setCollection').with(body: "setID=#{set_id}&qtyOwned=#{number_owned}&wanted=#{wanted}&apiKey=#{api_key}&userHash=#{token}").to_return body: body }
81
+
82
+ context 'when all parameters are valid' do
83
+ let(:body) { fixture('set_collection.xml') }
84
+
85
+ it 'updates the specified collection' do
86
+ expect(update_collection).to eq true
87
+ end
88
+ end
89
+
90
+ context 'when a parameter is invalid' do
91
+ let(:body) { fixture('set_collection_invalid.xml') }
92
+
93
+ it 'does not update the specified collection' do
94
+ expect(update_collection).to eq false
95
+ end
96
+
97
+ it 'sets the error on the client' do
98
+ update_collection
99
+ expect(subject.errors[:base]).to match_array [ 'ERROR: invalid userHash' ]
100
+ end
101
+ end
102
+ end
103
+
104
+ context 'when not all parameters are valid' do
105
+ let(:set_id) { nil }
106
+ let(:wanted) { true }
107
+
108
+ it 'raises a ValidationError' do
109
+ expect { update_collection }.to raise_error Brickset::ValidationError, "Set can't be blank and Wanted is not included in the list"
110
+ end
111
+ end
112
+ end
113
+
114
+ describe '#update_collection_owned' do
115
+ let(:set_id) { 26725 }
116
+ let(:owned) { 1 }
117
+
118
+ let(:update_collection_owned) { subject.update_collection_owned(set_id: set_id, owned: owned) }
119
+
120
+ context 'when all required parameters are specified' do
121
+ before { stub_post('/setCollection_owns').with(body: "setID=#{set_id}&owned=#{owned}&apiKey=#{api_key}&userHash=#{token}").to_return body: body }
122
+
123
+ context 'when all parameters are valid' do
124
+ let(:body) { fixture('set_collection_owns.xml') }
125
+
126
+ it 'updates the specified collection owned' do
127
+ expect(update_collection_owned).to eq true
128
+ end
129
+ end
130
+
131
+ context 'when a parameter is invalid' do
132
+ let(:body) { fixture('set_collection_owns_invalid.xml') }
133
+
134
+ it 'does not update the specified collection owned' do
135
+ expect(update_collection_owned).to eq false
136
+ end
137
+
138
+ it 'sets the error on the client' do
139
+ update_collection_owned
140
+ expect(subject.errors[:base]).to match_array [ 'ERROR: invalid userHash' ]
141
+ end
142
+ end
143
+ end
144
+
145
+ context 'when not all parameters are valid' do
146
+ let(:set_id) { nil }
147
+ let(:owned) { true }
148
+
149
+ it 'raises a ValidationError' do
150
+ expect { update_collection_owned }.to raise_error Brickset::ValidationError, "Set can't be blank and Owned is not included in the list"
151
+ end
152
+ end
153
+ end
154
+
155
+ describe '#update_collection_wanted' do
156
+ let(:set_id) { 26725 }
157
+ let(:wanted) { 1 }
158
+
159
+ let(:update_collection_wanted) { subject.update_collection_wanted(set_id: set_id, wanted: wanted) }
160
+
161
+ context 'when all required parameters are specified' do
162
+ before { stub_post('/setCollection_wants').with(body: "setID=#{set_id}&wanted=#{wanted}&apiKey=#{api_key}&userHash=#{token}").to_return body: body }
163
+
164
+ context 'when all parameters are valid' do
165
+ let(:body) { fixture('set_collection_wants.xml') }
166
+
167
+ it 'updates the specified collection wanted' do
168
+ expect(update_collection_wanted).to eq true
169
+ end
170
+ end
171
+
172
+ context 'when a parameter is invalid' do
173
+ let(:body) { fixture('set_collection_wants_invalid.xml') }
174
+
175
+ it 'does not update the specified collection wanted' do
176
+ expect(update_collection_wanted).to eq false
177
+ end
178
+
179
+ it 'sets the error on the client' do
180
+ update_collection_wanted
181
+ expect(subject.errors[:base]).to match_array [ 'ERROR: invalid userHash' ]
182
+ end
183
+ end
184
+ end
185
+
186
+ context 'when not all parameters are valid' do
187
+ let(:set_id) { nil }
188
+ let(:wanted) { true }
189
+
190
+ it 'raises a ValidationError' do
191
+ expect { update_collection_wanted }.to raise_error Brickset::ValidationError, "Set can't be blank and Wanted is not included in the list"
192
+ end
193
+ end
194
+ end
195
+
196
+ describe '#update_collection_number_owned' do
197
+ let(:set_id) { 26725 }
198
+ let(:number_owned) { 1 }
199
+
200
+ let(:update_collection_number_owned) { subject.update_collection_number_owned(set_id: set_id, number_owned: number_owned) }
201
+
202
+ context 'when all required parameters are specified' do
203
+ before { stub_post('/setCollection_qtyOwned').with(body: "setID=#{set_id}&qtyOwned=#{number_owned}&apiKey=#{api_key}&userHash=#{token}").to_return body: body }
204
+
205
+ context 'when all parameters are valid' do
206
+ let(:body) { fixture('set_collection_qty_owned.xml') }
207
+
208
+ it 'updates the specified collection number owned' do
209
+ expect(update_collection_number_owned).to eq true
210
+ end
211
+ end
212
+
213
+ context 'when a parameter is invalid' do
214
+ let(:body) { fixture('set_collection_qty_owned_invalid.xml') }
215
+
216
+ it 'does not update the specified collection number owned' do
217
+ expect(update_collection_number_owned).to eq false
218
+ end
219
+
220
+ it 'sets the error on the client' do
221
+ update_collection_number_owned
222
+ expect(subject.errors[:base]).to match_array [ 'ERROR: invalid userHash' ]
223
+ end
224
+ end
225
+ end
226
+
227
+ context 'when not all parameters are valid' do
228
+ let(:set_id) { nil }
229
+ let(:number_owned) { true }
230
+
231
+ it 'raises a ValidationError' do
232
+ expect { update_collection_number_owned }.to raise_error Brickset::ValidationError, "Set can't be blank and Number owned is not included in the list"
233
+ end
234
+ end
235
+ end
236
+
237
+ describe '#update_collection_user_notes' do
238
+ let(:set_id) { 26725 }
239
+ let(:notes) { "She's the fastest hunk of junk in the galaxy!" }
240
+
241
+ let(:update_collection_user_notes) { subject.update_collection_user_notes(set_id: set_id, notes: notes) }
242
+
243
+ context 'when all required parameters are specified' do
244
+ before { stub_post('/setCollection_userNotes').with(body: "setID=#{set_id}&notes=#{ERB::Util.url_encode(notes)}&apiKey=#{api_key}&userHash=#{token}").to_return body: body }
245
+
246
+ context 'when all parameters are valid' do
247
+ let(:body) { fixture('set_collection_user_notes.xml') }
248
+
249
+ it 'updates the specified collection user notes' do
250
+ expect(update_collection_user_notes).to eq true
251
+ end
252
+ end
253
+
254
+ context 'when a parameter is invalid' do
255
+ let(:body) { fixture('set_collection_user_notes_invalid.xml') }
256
+
257
+ it 'does not update the specified collection user notes' do
258
+ expect(update_collection_user_notes).to eq false
259
+ end
260
+
261
+ it 'sets the error on the client' do
262
+ update_collection_user_notes
263
+ expect(subject.errors[:base]).to match_array [ 'ERROR: invalid userHash' ]
264
+ end
265
+ end
266
+ end
267
+
268
+ context 'when not all parameters are valid' do
269
+ let(:set_id) { nil }
270
+ let(:notes) { 'Star Wars. ' * 20 }
271
+
272
+ it 'raises a ValidationError' do
273
+ expect { update_collection_user_notes }.to raise_error Brickset::ValidationError, "Set can't be blank and Notes is too long (maximum is 200 characters)"
274
+ end
275
+ end
276
+ end
277
+
278
+ describe '#update_user_rating' do
279
+ let(:set_id) { 26725 }
280
+ let(:rating) { 4 }
281
+
282
+ let(:update_user_rating) { subject.update_user_rating(set_id: set_id, rating: rating) }
283
+
284
+ context 'when all required parameters are specified' do
285
+ before { stub_post('/setUserRating').with(body: "setID=#{set_id}&rating=#{rating}&apiKey=#{api_key}&userHash=#{token}").to_return body: body }
286
+
287
+ context 'when all parameters are valid' do
288
+ let(:body) { fixture('set_user_rating.xml') }
289
+
290
+ it 'updates the specified user rating' do
291
+ expect(update_user_rating).to eq true
292
+ end
293
+ end
294
+
295
+ context 'when a parameter is invalid' do
296
+ let(:body) { fixture('set_user_rating_invalid.xml') }
297
+
298
+ it 'does not update the specified user rating' do
299
+ expect(update_user_rating).to eq false
300
+ end
301
+
302
+ it 'sets the error on the client' do
303
+ update_user_rating
304
+ expect(subject.errors[:base]).to match_array [ 'ERROR: invalid userHash' ]
305
+ end
306
+ end
307
+ end
308
+
309
+ context 'when not all parameters are valid' do
310
+ let(:set_id) { nil }
311
+ let(:rating) { 6 }
312
+
313
+ it 'raises a ValidationError' do
314
+ expect { update_user_rating }.to raise_error Brickset::ValidationError, "Set can't be blank and Rating is not included in the list"
315
+ end
316
+ end
317
+ end
318
+
319
+ describe '#user_notes' do
320
+ let(:body) { fixture('get_user_notes.xml') }
321
+
322
+ before { stub_post('/getUserNotes').with(body: "apiKey=#{api_key}&userHash=#{token}").to_return body: body }
323
+
324
+ context 'with valid parameters' do
325
+ it 'returns the users notes' do
326
+ aggregate_failures do
327
+ expect(subject.user_notes).to match_array [
328
+ an_instance_of(Brickset::Elements::UserNote),
329
+ an_instance_of(Brickset::Elements::UserNote)
330
+ ]
331
+ expect(subject.user_notes.count).to eq 2
332
+ expect(subject.user_notes.first.set_id).to eq 5860
333
+ expect(subject.user_notes.first.user_notes).to eq 'A long time ago in a galaxy far, far away...'
334
+ expect(subject.user_notes.last.set_id).to eq 26725
335
+ expect(subject.user_notes.last.user_notes).to eq 'The ship that made the Kessel Run in less than 12 parsecs.'
336
+ end
337
+ end
338
+ end
339
+
340
+ context 'with invalid parameters' do
341
+ let(:token) { 'invalid' }
342
+ let(:body) { fixture('get_user_notes_no_result.xml') }
343
+
344
+ it 'does not receive any user notes' do
345
+ expect(subject.user_notes).to match_array []
346
+ end
347
+ end
348
+ end
349
+
350
+ end