nexus_mods 0.1.1 → 0.3.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 (35) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -0
  3. data/lib/nexus_mods/api/api_limits.rb +64 -0
  4. data/lib/nexus_mods/api/category.rb +54 -0
  5. data/lib/nexus_mods/api/game.rb +106 -0
  6. data/lib/nexus_mods/api/mod.rb +141 -0
  7. data/lib/nexus_mods/api/mod_file.rb +116 -0
  8. data/lib/nexus_mods/api/user.rb +55 -0
  9. data/lib/nexus_mods/api_client.rb +182 -0
  10. data/lib/nexus_mods/cacheable_api.rb +52 -0
  11. data/lib/nexus_mods/cacheable_with_expiry.rb +70 -0
  12. data/lib/nexus_mods/core_extensions/cacheable/cache_adapters/persistent_json_adapter.rb +62 -0
  13. data/lib/nexus_mods/core_extensions/cacheable/method_generator.rb +62 -0
  14. data/lib/nexus_mods/file_cache.rb +71 -0
  15. data/lib/nexus_mods/version.rb +1 -1
  16. data/lib/nexus_mods.rb +32 -86
  17. data/spec/nexus_mods_test/factories/games.rb +135 -0
  18. data/spec/nexus_mods_test/factories/mod_files.rb +113 -0
  19. data/spec/nexus_mods_test/factories/mods.rb +144 -0
  20. data/spec/nexus_mods_test/helpers.rb +39 -14
  21. data/spec/nexus_mods_test/scenarios/nexus_mods/{api_limits_spec.rb → api/api_limits_spec.rb} +10 -3
  22. data/spec/nexus_mods_test/scenarios/nexus_mods/api/game_spec.rb +93 -0
  23. data/spec/nexus_mods_test/scenarios/nexus_mods/api/mod_file_spec.rb +73 -0
  24. data/spec/nexus_mods_test/scenarios/nexus_mods/api/mod_spec.rb +62 -0
  25. data/spec/nexus_mods_test/scenarios/nexus_mods_caching_spec.rb +88 -0
  26. metadata +37 -13
  27. data/lib/nexus_mods/api_limits.rb +0 -44
  28. data/lib/nexus_mods/category.rb +0 -37
  29. data/lib/nexus_mods/game.rb +0 -78
  30. data/lib/nexus_mods/mod.rb +0 -106
  31. data/lib/nexus_mods/mod_file.rb +0 -86
  32. data/lib/nexus_mods/user.rb +0 -37
  33. data/spec/nexus_mods_test/scenarios/nexus_mods/game_spec.rb +0 -180
  34. data/spec/nexus_mods_test/scenarios/nexus_mods/mod_file_spec.rb +0 -140
  35. data/spec/nexus_mods_test/scenarios/nexus_mods/mod_spec.rb +0 -185
data/lib/nexus_mods.rb CHANGED
@@ -1,14 +1,13 @@
1
- require 'addressable/uri'
2
1
  require 'json'
3
2
  require 'time'
4
3
  require 'tmpdir'
5
- require 'faraday'
6
- require 'nexus_mods/api_limits'
7
- require 'nexus_mods/category'
8
- require 'nexus_mods/game'
9
- require 'nexus_mods/user'
10
- require 'nexus_mods/mod'
11
- require 'nexus_mods/mod_file'
4
+ require 'nexus_mods/api_client'
5
+ require 'nexus_mods/api/api_limits'
6
+ require 'nexus_mods/api/category'
7
+ require 'nexus_mods/api/game'
8
+ require 'nexus_mods/api/user'
9
+ require 'nexus_mods/api/mod'
10
+ require 'nexus_mods/api/mod_file'
12
11
 
13
12
  # Ruby API to access NexusMods REST API
14
13
  class NexusMods
@@ -40,27 +39,36 @@ class NexusMods
40
39
  # * *game_domain_name* (String): Game domain name to query by default [default: 'skyrimspecialedition']
41
40
  # * *mod_id* (Integer): Mod to query by default [default: 1]
42
41
  # * *file_id* (Integer): File to query by default [default: 1]
42
+ # * *http_cache_file* (String): File used to store the HTTP cache, or nil for no cache [default: "#{Dir.tmpdir}/nexus_mods_http_cache.json"]
43
+ # * *api_cache_expiry* (Hash<Symbol,Integer>): Expiry times in seconds, per expiry key. Possible keys are:
44
+ # * *games*: Expiry associated to queries on games [default: 1 day]
45
+ # * *mod*: Expiry associated to queries on mod [default: 1 day]
46
+ # * *mod_files*: Expiry associated to queries on mod files [default: 1 day]
43
47
  # * *logger* (Logger): The logger to be used for log messages [default: Logger.new(STDOUT)]
44
48
  def initialize(
45
49
  api_key: nil,
46
50
  game_domain_name: 'skyrimspecialedition',
47
51
  mod_id: 1,
48
52
  file_id: 1,
53
+ http_cache_file: "#{Dir.tmpdir}/nexus_mods_http_cache.json",
54
+ api_cache_expiry: {},
49
55
  logger: Logger.new($stdout)
50
56
  )
51
- @api_key = api_key
52
57
  @game_domain_name = game_domain_name
53
58
  @mod_id = mod_id
54
59
  @file_id = file_id
55
60
  @logger = logger
56
61
  @premium = false
57
- # Initialize our HTTP client
58
- @http_client = Faraday.new do |builder|
59
- builder.adapter Faraday.default_adapter
60
- end
62
+ @api_client = ApiClient.new(
63
+ api_key:,
64
+ http_cache_file:,
65
+ api_cache_expiry:,
66
+ logger:
67
+ )
68
+
61
69
  # Check that the key is correct and know if the user is premium
62
70
  begin
63
- @premium = api('users/validate')['is_premium?']
71
+ @premium = @api_client.api('users/validate')['is_premium?']
64
72
  rescue LimitsExceededError
65
73
  raise
66
74
  rescue ApiError
@@ -74,8 +82,8 @@ class NexusMods
74
82
  # Result::
75
83
  # * ApiLimits: API calls limits
76
84
  def api_limits
77
- api_limits_headers = http('users/validate').headers
78
- ApiLimits.new(
85
+ api_limits_headers = @api_client.http('users/validate').headers
86
+ Api::ApiLimits.new(
79
87
  daily_limit: Integer(api_limits_headers['x-rl-daily-limit']),
80
88
  daily_remaining: Integer(api_limits_headers['x-rl-daily-remaining']),
81
89
  daily_reset: Time.parse(api_limits_headers['x-rl-daily-reset']).utc,
@@ -90,7 +98,7 @@ class NexusMods
90
98
  # Result::
91
99
  # * Array<Game>: List of games
92
100
  def games
93
- api('games').map do |game_json|
101
+ @api_client.api('games').map do |game_json|
94
102
  # First create categories tree
95
103
  # Hash<Integer, [Category, Integer]>: Category and its parent category id, per category id
96
104
  categories = game_json['categories'].to_h do |category_json|
@@ -98,7 +106,7 @@ class NexusMods
98
106
  [
99
107
  category_id,
100
108
  [
101
- Category.new(
109
+ Api::Category.new(
102
110
  id: category_id,
103
111
  name: category_json['name']
104
112
  ),
@@ -110,7 +118,7 @@ class NexusMods
110
118
  # Ignore missing parent categories: this situation happens.
111
119
  category.parent_category = categories[parent_category_id]&.first if parent_category_id
112
120
  end
113
- Game.new(
121
+ Api::Game.new(
114
122
  id: game_json['id'],
115
123
  name: game_json['name'],
116
124
  forum_url: game_json['forum_url'],
@@ -137,8 +145,8 @@ class NexusMods
137
145
  # Result::
138
146
  # * Mod: Mod information
139
147
  def mod(game_domain_name: @game_domain_name, mod_id: @mod_id)
140
- mod_json = api "games/#{game_domain_name}/mods/#{mod_id}"
141
- Mod.new(
148
+ mod_json = @api_client.api "games/#{game_domain_name}/mods/#{mod_id}"
149
+ Api::Mod.new(
142
150
  uid: mod_json['uid'],
143
151
  mod_id: mod_json['mod_id'],
144
152
  game_id: mod_json['game_id'],
@@ -152,7 +160,7 @@ class NexusMods
152
160
  contains_adult_content: mod_json['contains_adult_content'],
153
161
  status: mod_json['status'],
154
162
  available: mod_json['available'],
155
- uploader: User.new(
163
+ uploader: Api::User.new(
156
164
  member_id: mod_json['user']['member_id'],
157
165
  member_group_id: mod_json['user']['member_group_id'],
158
166
  name: mod_json['user']['name'],
@@ -185,11 +193,11 @@ class NexusMods
185
193
  # Result::
186
194
  # * Array<ModFile>: List of mod's files
187
195
  def mod_files(game_domain_name: @game_domain_name, mod_id: @mod_id)
188
- api("games/#{game_domain_name}/mods/#{mod_id}/files")['files'].map do |file_json|
196
+ @api_client.api("games/#{game_domain_name}/mods/#{mod_id}/files")['files'].map do |file_json|
189
197
  category_id = FILE_CATEGORIES[file_json['category_id']]
190
198
  raise "Unknown file category: #{file_json['category_id']}" if category_id.nil?
191
199
 
192
- ModFile.new(
200
+ Api::ModFile.new(
193
201
  ids: file_json['id'],
194
202
  uid: file_json['uid'],
195
203
  id: file_json['file_id'],
@@ -210,66 +218,4 @@ class NexusMods
210
218
  end
211
219
  end
212
220
 
213
- private
214
-
215
- # Send an HTTP request to the API and get back the answer as a JSON
216
- #
217
- # Parameters::
218
- # * *path* (String): API path to contact (from v1/ and without .json)
219
- # * *verb* (Symbol): Verb to be used (:get, :post...) [default: :get]
220
- # Result::
221
- # * Object: The JSON response
222
- def api(path, verb: :get)
223
- res = http(path, verb:)
224
- json = JSON.parse(res.body)
225
- uri = api_uri(path)
226
- @logger.debug "[API call] - #{verb} #{uri} => #{res.status}\n#{
227
- JSON.
228
- pretty_generate(json).
229
- split("\n").
230
- map { |line| " #{line}" }.
231
- join("\n")
232
- }\n#{
233
- res.
234
- headers.
235
- map { |header, value| " #{header}: #{value}" }.
236
- join("\n")
237
- }"
238
- case res.status
239
- when 200
240
- # Happy
241
- when 429
242
- # Some limits of the API have been reached
243
- raise LimitsExceededError, "Exceeding limits of API calls: #{res.headers.select { |header, _value| header =~ /^x-rl-.+$/ }}"
244
- else
245
- raise ApiError, "API #{uri} returned error code #{res.status}" unless res.status == '200'
246
- end
247
- json
248
- end
249
-
250
- # Send an HTTP request to the API and get back the HTTP response
251
- #
252
- # Parameters::
253
- # * *path* (String): API path to contact (from v1/ and without .json)
254
- # * *verb* (Symbol): Verb to be used (:get, :post...) [default: :get]
255
- # Result::
256
- # * Faraday::Response: The HTTP response
257
- def http(path, verb: :get)
258
- @http_client.send(verb) do |req|
259
- req.url api_uri(path)
260
- req.headers['apikey'] = @api_key
261
- req.headers['User-Agent'] = "nexus_mods (#{RUBY_PLATFORM}) Ruby/#{RUBY_VERSION}"
262
- end
263
- end
264
-
265
- # Get the real URI to query for a given API path
266
- #
267
- # Parameters::
268
- # * *path* (String): API path to contact (from v1/ and without .json)
269
- # Result::
270
- # * String: The URI
271
- def api_uri(path)
272
- "https://api.nexusmods.com/v1/#{path}.json"
273
- end
274
-
275
221
  end
@@ -0,0 +1,135 @@
1
+ module NexusModsTest
2
+
3
+ module Factories
4
+
5
+ module Games
6
+
7
+ # Test game with id 100
8
+ def json_game100
9
+ {
10
+ 'id' => 100,
11
+ 'name' => 'Morrowind',
12
+ 'forum_url' => 'https://forums.nexusmods.com/index.php?/forum/111-morrowind/',
13
+ 'nexusmods_url' => 'http://www.nexusmods.com/morrowind',
14
+ 'genre' => 'RPG',
15
+ 'file_count' => 14_143,
16
+ 'downloads' => 20_414_985,
17
+ 'domain_name' => 'morrowind',
18
+ 'approved_date' => 1,
19
+ 'file_views' => 100_014_750,
20
+ 'authors' => 2062,
21
+ 'file_endorsements' => 719_262,
22
+ 'mods' => 6080,
23
+ 'categories' => [
24
+ {
25
+ 'category_id' => 1,
26
+ 'name' => 'Morrowind',
27
+ 'parent_category' => false
28
+ },
29
+ {
30
+ 'category_id' => 2,
31
+ 'name' => 'Buildings',
32
+ 'parent_category' => 1
33
+ }
34
+ ]
35
+ }
36
+ end
37
+
38
+ # Test game with id 101
39
+ def json_game101
40
+ {
41
+ 'id' => 101,
42
+ 'name' => 'Oblivion',
43
+ 'forum_url' => 'https://forums.nexusmods.com/index.php?/forum/131-oblivion/',
44
+ 'nexusmods_url' => 'http://www.nexusmods.com/oblivion',
45
+ 'genre' => 'RPG',
46
+ 'file_count' => 52_775,
47
+ 'downloads' => 187_758_634,
48
+ 'domain_name' => 'oblivion',
49
+ 'approved_date' => 1,
50
+ 'file_views' => 880_508_188,
51
+ 'authors' => 10_673,
52
+ 'file_endorsements' => 4_104_067,
53
+ 'mods' => 29_220,
54
+ 'categories' => [
55
+ {
56
+ 'category_id' => 20,
57
+ 'name' => 'Oblivion',
58
+ 'parent_category' => false
59
+ },
60
+ {
61
+ 'category_id' => 22,
62
+ 'name' => 'New structures - Buildings',
63
+ 'parent_category' => 20
64
+ }
65
+ ]
66
+ }
67
+ end
68
+
69
+ # Expect a game to be the test game of id 100
70
+ #
71
+ # Parameters::
72
+ # * *game* (NexusMods::Api::Game): Game to validate
73
+ def expect_game_to_be_game100(game)
74
+ expect(game.id).to eq 100
75
+ expect(game.name).to eq 'Morrowind'
76
+ expect(game.forum_url).to eq 'https://forums.nexusmods.com/index.php?/forum/111-morrowind/'
77
+ expect(game.nexusmods_url).to eq 'http://www.nexusmods.com/morrowind'
78
+ expect(game.genre).to eq 'RPG'
79
+ expect(game.files_count).to eq 14_143
80
+ expect(game.downloads_count).to eq 20_414_985
81
+ expect(game.domain_name).to eq 'morrowind'
82
+ expect(game.approved_date).to eq Time.parse('1970-01-01 00:00:01 +0000')
83
+ expect(game.files_views).to eq 100_014_750
84
+ expect(game.authors_count).to eq 2062
85
+ expect(game.files_endorsements).to eq 719_262
86
+ expect(game.mods_count).to eq 6080
87
+ game_categories = game.categories
88
+ expect(game_categories.size).to eq 2
89
+ expect(game_categories.first.id).to eq 1
90
+ expect(game_categories.first.name).to eq 'Morrowind'
91
+ expect(game_categories.first.parent_category).to be_nil
92
+ expect(game_categories[1].id).to eq 2
93
+ expect(game_categories[1].name).to eq 'Buildings'
94
+ expect(game_categories[1].parent_category).not_to be_nil
95
+ expect(game_categories[1].parent_category.id).to eq 1
96
+ expect(game_categories[1].parent_category.name).to eq 'Morrowind'
97
+ expect(game_categories[1].parent_category.parent_category).to be_nil
98
+ end
99
+
100
+ # Expect a game to be the test game of id 101
101
+ #
102
+ # Parameters::
103
+ # * *game* (NexusMods::Api::Game): Game to validate
104
+ def expect_game_to_be_game101(game)
105
+ expect(game.id).to eq 101
106
+ expect(game.name).to eq 'Oblivion'
107
+ expect(game.forum_url).to eq 'https://forums.nexusmods.com/index.php?/forum/131-oblivion/'
108
+ expect(game.nexusmods_url).to eq 'http://www.nexusmods.com/oblivion'
109
+ expect(game.genre).to eq 'RPG'
110
+ expect(game.files_count).to eq 52_775
111
+ expect(game.downloads_count).to eq 187_758_634
112
+ expect(game.domain_name).to eq 'oblivion'
113
+ expect(game.approved_date).to eq Time.parse('1970-01-01 00:00:01 +0000')
114
+ expect(game.files_views).to eq 880_508_188
115
+ expect(game.authors_count).to eq 10_673
116
+ expect(game.files_endorsements).to eq 4_104_067
117
+ expect(game.mods_count).to eq 29_220
118
+ game_categories = game.categories
119
+ expect(game_categories.size).to eq 2
120
+ expect(game_categories.first.id).to eq 20
121
+ expect(game_categories.first.name).to eq 'Oblivion'
122
+ expect(game_categories.first.parent_category).to be_nil
123
+ expect(game_categories[1].id).to eq 22
124
+ expect(game_categories[1].name).to eq 'New structures - Buildings'
125
+ expect(game_categories[1].parent_category).not_to be_nil
126
+ expect(game_categories[1].parent_category.id).to eq 20
127
+ expect(game_categories[1].parent_category.name).to eq 'Oblivion'
128
+ expect(game_categories[1].parent_category.parent_category).to be_nil
129
+ end
130
+
131
+ end
132
+
133
+ end
134
+
135
+ end
@@ -0,0 +1,113 @@
1
+ module NexusModsTest
2
+
3
+ module Factories
4
+
5
+ module ModFiles
6
+
7
+ # Test mod file with id 2472
8
+ def json_mod_file2472
9
+ {
10
+ 'id' => [
11
+ 2472,
12
+ 1704
13
+ ],
14
+ 'uid' => 7_318_624_274_856,
15
+ 'file_id' => 2472,
16
+ 'name' => 'ApachiiSkyHair_v_1_6_Full',
17
+ 'version' => '1.6.Full',
18
+ 'category_id' => 4,
19
+ 'category_name' => 'OLD_VERSION',
20
+ 'is_primary' => false,
21
+ 'file_name' => 'ApachiiSkyHair_v_1_6_Full-2014-1-6-Full.7z',
22
+ 'uploaded_timestamp' => 1_477_967_645,
23
+ 'uploaded_time' => '2016-11-01T02:34:05.000+00:00',
24
+ 'mod_version' => '1.6.Full',
25
+ 'external_virus_scan_url' => 'https://www.virustotal.com/file/3dcc96dce0b846ea643d626c48bd6ad08752da8232f3d29be644d36e1fd627cf/analysis/1477978674/',
26
+ 'description' => '[b][color=orange] NOT optimized meshes. Standalone. Adds 42 new hairstyles for females, 21 hair for males and 5 hairs for Female Khajiit- 2 hairs for Male Khajiit[/color][/b] ',
27
+ 'size' => 304_347,
28
+ 'size_kb' => 304_347,
29
+ 'size_in_bytes' => 309_251_227,
30
+ 'changelog_html' => nil,
31
+ 'content_preview_link' => 'https://file-metadata.nexusmods.com/file/nexus-files-meta/1704/2014/ApachiiSkyHair_v_1_6_Full-2014-1-6-Full.7z.json'
32
+ }
33
+ end
34
+
35
+ # Test mod file with id 2487
36
+ def json_mod_file2487
37
+ {
38
+ 'id' => [
39
+ 2487,
40
+ 1705
41
+ ],
42
+ 'uid' => 7_318_624_274_857,
43
+ 'file_id' => 2487,
44
+ 'name' => 'ApachiiSkyHairMale_v_1_2',
45
+ 'version' => '1.2',
46
+ 'category_id' => 4,
47
+ 'category_name' => 'OLD_VERSION',
48
+ 'is_primary' => false,
49
+ 'file_name' => 'ApachiiSkyHairMale_v_1_2-2014-1-2.7z',
50
+ 'uploaded_timestamp' => 1_477_968_373,
51
+ 'uploaded_time' => '2016-11-01T02:46:13.000+00:00',
52
+ 'mod_version' => '1.2',
53
+ 'external_virus_scan_url' => 'https://www.virustotal.com/file/3e86106233499ac43383c32ce4a2d8e162dc6e940b4d228f649a701b71ee5676/analysis/1477979366/',
54
+ 'description' => 'NOT optimezed meshes. Standalone 55 Male hairs - Not included in ApachiiSkyHair v_1_6_Full ',
55
+ 'size' => 204_347,
56
+ 'size_kb' => 204_347,
57
+ 'size_in_bytes' => 209_251_227,
58
+ 'changelog_html' => nil,
59
+ 'content_preview_link' => 'https://file-metadata.nexusmods.com/file/nexus-files-meta/1704/2014/ApachiiSkyHairMale_v_1_2-2014-1-2.7z.json'
60
+ }
61
+ end
62
+
63
+ # Expect a mod's file to be the example one with id 2472
64
+ #
65
+ # Parameters::
66
+ # * *mod_file* (NexusMods::Api::File): Mod file to validate
67
+ def expect_mod_file_to_be2472(mod_file)
68
+ expect(mod_file.ids).to eq [2472, 1704]
69
+ expect(mod_file.uid).to eq 7_318_624_274_856
70
+ expect(mod_file.id).to eq 2472
71
+ expect(mod_file.name).to eq 'ApachiiSkyHair_v_1_6_Full'
72
+ expect(mod_file.version).to eq '1.6.Full'
73
+ expect(mod_file.category_id).to eq :old
74
+ expect(mod_file.category_name).to eq 'OLD_VERSION'
75
+ expect(mod_file.is_primary).to be false
76
+ expect(mod_file.size).to eq 309_251_227
77
+ expect(mod_file.file_name).to eq 'ApachiiSkyHair_v_1_6_Full-2014-1-6-Full.7z'
78
+ expect(mod_file.uploaded_time).to eq Time.parse('2016-11-01T02:34:05.000+00:00')
79
+ expect(mod_file.mod_version).to eq '1.6.Full'
80
+ expect(mod_file.external_virus_scan_url).to eq 'https://www.virustotal.com/file/3dcc96dce0b846ea643d626c48bd6ad08752da8232f3d29be644d36e1fd627cf/analysis/1477978674/'
81
+ expect(mod_file.description).to eq '[b][color=orange] NOT optimized meshes. Standalone. Adds 42 new hairstyles for females, 21 hair for males and 5 hairs for Female Khajiit- 2 hairs for Male Khajiit[/color][/b] '
82
+ expect(mod_file.changelog_html).to be_nil
83
+ expect(mod_file.content_preview_url).to eq 'https://file-metadata.nexusmods.com/file/nexus-files-meta/1704/2014/ApachiiSkyHair_v_1_6_Full-2014-1-6-Full.7z.json'
84
+ end
85
+
86
+ # Expect a mod's file to be the example one with id 2487
87
+ #
88
+ # Parameters::
89
+ # * *mod_file* (NexusMods::Api::File): Mod file to validate
90
+ def expect_mod_file_to_be2487(mod_file)
91
+ expect(mod_file.ids).to eq [2487, 1705]
92
+ expect(mod_file.uid).to eq 7_318_624_274_857
93
+ expect(mod_file.id).to eq 2487
94
+ expect(mod_file.name).to eq 'ApachiiSkyHairMale_v_1_2'
95
+ expect(mod_file.version).to eq '1.2'
96
+ expect(mod_file.category_id).to eq :old
97
+ expect(mod_file.category_name).to eq 'OLD_VERSION'
98
+ expect(mod_file.is_primary).to be false
99
+ expect(mod_file.size).to eq 209_251_227
100
+ expect(mod_file.file_name).to eq 'ApachiiSkyHairMale_v_1_2-2014-1-2.7z'
101
+ expect(mod_file.uploaded_time).to eq Time.parse('2016-11-01T02:46:13.000+00:00')
102
+ expect(mod_file.mod_version).to eq '1.2'
103
+ expect(mod_file.external_virus_scan_url).to eq 'https://www.virustotal.com/file/3e86106233499ac43383c32ce4a2d8e162dc6e940b4d228f649a701b71ee5676/analysis/1477979366/'
104
+ expect(mod_file.description).to eq 'NOT optimezed meshes. Standalone 55 Male hairs - Not included in ApachiiSkyHair v_1_6_Full '
105
+ expect(mod_file.changelog_html).to be_nil
106
+ expect(mod_file.content_preview_url).to eq 'https://file-metadata.nexusmods.com/file/nexus-files-meta/1704/2014/ApachiiSkyHairMale_v_1_2-2014-1-2.7z.json'
107
+ end
108
+
109
+ end
110
+
111
+ end
112
+
113
+ end
@@ -0,0 +1,144 @@
1
+ module NexusModsTest
2
+
3
+ module Factories
4
+
5
+ module Mods
6
+
7
+ # Example of JSON object returned by the API for a mod information, having all possible fields
8
+ def json_complete_mod
9
+ {
10
+ 'name' => 'ApachiiSkyHair SSE',
11
+ 'summary' => 'New Female and Male Hairstyles for Humans, Elves and Orcs. Converted hair from Sims2 and Sims3.<br />Standalone version.',
12
+ 'description' => 'Mod description',
13
+ 'picture_url' => 'https://staticdelivery.nexusmods.com/mods/1704/images/10168-1-1392817986.jpg',
14
+ 'mod_downloads' => 13_634_545,
15
+ 'mod_unique_downloads' => 4_052_221,
16
+ 'uid' => 7_318_624_272_650,
17
+ 'mod_id' => 2014,
18
+ 'game_id' => 1704,
19
+ 'allow_rating' => true,
20
+ 'domain_name' => 'skyrimspecialedition',
21
+ 'category_id' => 26,
22
+ 'version' => '1.6.Full',
23
+ 'endorsement_count' => 298_845,
24
+ 'created_timestamp' => 1_477_972_056,
25
+ 'created_time' => '2016-11-01T03:47:36.000+00:00',
26
+ 'updated_timestamp' => 1_507_398_546,
27
+ 'updated_time' => '2017-10-07T17:49:06.000+00:00',
28
+ 'author' => 'Apachii',
29
+ 'uploaded_by' => 'apachii',
30
+ 'uploaded_users_profile_url' => 'http://www.nexusmods.com/games/users/283148',
31
+ 'contains_adult_content' => false,
32
+ 'status' => 'published',
33
+ 'available' => true,
34
+ 'user' => {
35
+ 'member_id' => 283_148,
36
+ 'member_group_id' => 27,
37
+ 'name' => 'apachii'
38
+ },
39
+ 'endorsement' => {
40
+ 'endorse_status' => 'Undecided',
41
+ 'timestamp' => nil,
42
+ 'version' => nil
43
+ }
44
+ }
45
+ end
46
+
47
+ # Example of JSON object returned by the API for a mod information, having minimum fields
48
+ def json_partial_mod
49
+ {
50
+ 'mod_downloads' => 13_634_545,
51
+ 'mod_unique_downloads' => 4_052_221,
52
+ 'uid' => 7_318_624_272_650,
53
+ 'mod_id' => 2014,
54
+ 'game_id' => 1704,
55
+ 'allow_rating' => true,
56
+ 'domain_name' => 'skyrimspecialedition',
57
+ 'category_id' => 26,
58
+ 'version' => '1.6.Full',
59
+ 'endorsement_count' => 298_845,
60
+ 'created_timestamp' => 1_477_972_056,
61
+ 'created_time' => '2016-11-01T03:47:36.000+00:00',
62
+ 'updated_timestamp' => 1_507_398_546,
63
+ 'updated_time' => '2017-10-07T17:49:06.000+00:00',
64
+ 'author' => 'Apachii',
65
+ 'uploaded_by' => 'apachii',
66
+ 'uploaded_users_profile_url' => 'http://www.nexusmods.com/games/users/283148',
67
+ 'contains_adult_content' => false,
68
+ 'status' => 'published',
69
+ 'available' => true,
70
+ 'user' => {
71
+ 'member_id' => 283_148,
72
+ 'member_group_id' => 27,
73
+ 'name' => 'apachii'
74
+ }
75
+ }
76
+ end
77
+
78
+ # Expect a mod to be the example complete one
79
+ #
80
+ # Parameters::
81
+ # * *mod* (NexusMods::Api::Mod): Mod to validate
82
+ def expect_mod_to_be_complete(mod)
83
+ expect(mod.name).to eq 'ApachiiSkyHair SSE'
84
+ expect(mod.summary).to eq 'New Female and Male Hairstyles for Humans, Elves and Orcs. Converted hair from Sims2 and Sims3.<br />Standalone version.'
85
+ expect(mod.description).to eq 'Mod description'
86
+ expect(mod.picture_url).to eq 'https://staticdelivery.nexusmods.com/mods/1704/images/10168-1-1392817986.jpg'
87
+ expect(mod.downloads_count).to eq 13_634_545
88
+ expect(mod.unique_downloads_count).to eq 4_052_221
89
+ expect(mod.uid).to eq 7_318_624_272_650
90
+ expect(mod.mod_id).to eq 2014
91
+ expect(mod.game_id).to eq 1704
92
+ expect(mod.allow_rating).to be true
93
+ expect(mod.domain_name).to eq 'skyrimspecialedition'
94
+ expect(mod.category_id).to eq 26
95
+ expect(mod.version).to eq '1.6.Full'
96
+ expect(mod.endorsements_count).to eq 298_845
97
+ expect(mod.created_time).to eq Time.parse('2016-11-01T03:47:36.000+00:00')
98
+ expect(mod.updated_time).to eq Time.parse('2017-10-07T17:49:06.000+00:00')
99
+ expect(mod.author).to eq 'Apachii'
100
+ expect(mod.contains_adult_content).to be false
101
+ expect(mod.status).to eq 'published'
102
+ expect(mod.available).to be true
103
+ expect(mod.uploader.member_id).to eq 283_148
104
+ expect(mod.uploader.member_group_id).to eq 27
105
+ expect(mod.uploader.name).to eq 'apachii'
106
+ expect(mod.uploader.profile_url).to eq 'http://www.nexusmods.com/games/users/283148'
107
+ end
108
+
109
+ # Expect a mod to be the example partial one
110
+ #
111
+ # Parameters::
112
+ # * *mod* (NexusMods::Api::Mod): Mod to validate
113
+ def expect_mod_to_be_partial(mod)
114
+ expect(mod.name).to be_nil
115
+ expect(mod.summary).to be_nil
116
+ expect(mod.description).to be_nil
117
+ expect(mod.picture_url).to be_nil
118
+ expect(mod.downloads_count).to eq 13_634_545
119
+ expect(mod.unique_downloads_count).to eq 4_052_221
120
+ expect(mod.uid).to eq 7_318_624_272_650
121
+ expect(mod.mod_id).to eq 2014
122
+ expect(mod.game_id).to eq 1704
123
+ expect(mod.allow_rating).to be true
124
+ expect(mod.domain_name).to eq 'skyrimspecialedition'
125
+ expect(mod.category_id).to eq 26
126
+ expect(mod.version).to eq '1.6.Full'
127
+ expect(mod.endorsements_count).to eq 298_845
128
+ expect(mod.created_time).to eq Time.parse('2016-11-01T03:47:36.000+00:00')
129
+ expect(mod.updated_time).to eq Time.parse('2017-10-07T17:49:06.000+00:00')
130
+ expect(mod.author).to eq 'Apachii'
131
+ expect(mod.contains_adult_content).to be false
132
+ expect(mod.status).to eq 'published'
133
+ expect(mod.available).to be true
134
+ expect(mod.uploader.member_id).to eq 283_148
135
+ expect(mod.uploader.member_group_id).to eq 27
136
+ expect(mod.uploader.name).to eq 'apachii'
137
+ expect(mod.uploader.profile_url).to eq 'http://www.nexusmods.com/games/users/283148'
138
+ end
139
+
140
+ end
141
+
142
+ end
143
+
144
+ end