actv 1.3.11 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/actv/article.rb +44 -53
- data/lib/actv/article_validator.rb +8 -0
- data/lib/actv/asset.rb +31 -27
- data/lib/actv/asset_factory.rb +15 -0
- data/lib/actv/asset_image.rb +0 -2
- data/lib/actv/asset_reference.rb +11 -0
- data/lib/actv/asset_validator.rb +31 -0
- data/lib/actv/author.rb +61 -0
- data/lib/actv/author_validator.rb +8 -0
- data/lib/actv/base.rb +12 -7
- data/lib/actv/client.rb +43 -28
- data/lib/actv/event.rb +9 -4
- data/lib/actv/event_validator.rb +8 -0
- data/lib/actv/version.rb +1 -1
- data/spec/actv/article_spec.rb +138 -28
- data/spec/actv/article_validator_spec.rb +23 -0
- data/spec/actv/asset_component_spec.rb +1 -2
- data/spec/actv/asset_factory_spec.rb +40 -0
- data/spec/actv/asset_reference_spec.rb +20 -0
- data/spec/actv/asset_spec.rb +51 -3
- data/spec/actv/asset_validator_spec.rb +8 -0
- data/spec/actv/author_spec.rb +80 -0
- data/spec/actv/author_validator_spec.rb +23 -0
- data/spec/actv/client_spec.rb +76 -5
- data/spec/actv/event_spec.rb +16 -8
- data/spec/actv/event_validator_spec.rb +23 -0
- data/spec/actv/evergreen_spec.rb +0 -10
- data/spec/fixtures/valid_article.json +181 -182
- data/spec/fixtures/valid_assets.json +394 -722
- data/spec/fixtures/valid_author.json +135 -0
- data/spec/fixtures/valid_event.json +178 -178
- data/spec/fixtures/valid_events.json +839 -0
- metadata +28 -3
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ACTV::Author do
|
4
|
+
before do
|
5
|
+
stub_request(:post, "http://api.amp.active.com/v2/assets.json").
|
6
|
+
to_return(body: fixture("valid_author.json"))
|
7
|
+
end
|
8
|
+
subject(:author) { ACTV.asset('author_id').first }
|
9
|
+
|
10
|
+
|
11
|
+
context 'when valid author asset is initialized' do
|
12
|
+
its(:footer) { should start_with '<div class="article-signature-block">' }
|
13
|
+
its(:bio) { should start_with 'Jacquie Cattanach is an avid runner and triathlete' }
|
14
|
+
its('photo.url') {should eq 'http://www.active.com/Assets/Running/Bios/jacquie-cattanach-bio.jpg'}
|
15
|
+
its(:name_from_footer) { should eq 'Jacquie Cattanach'}
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#valid?' do
|
19
|
+
let(:asset_categories) { [] }
|
20
|
+
let(:response) { { assetGuid: 1, assetCategories: asset_categories } }
|
21
|
+
subject(:valid?) { ACTV::Author.valid? response }
|
22
|
+
context 'when the category name is author' do
|
23
|
+
let(:asset_categories) { [ { category: { categoryName: "Author", categoryTaxonomy: "" } } ] }
|
24
|
+
it { should be_true }
|
25
|
+
end
|
26
|
+
context 'when the category taxonomy is author' do
|
27
|
+
let(:asset_categories) { [ { category: { categoryName: "", categoryTaxonomy: "Person/Author" } } ] }
|
28
|
+
it { should be_true }
|
29
|
+
end
|
30
|
+
context 'when there is no category taxonomy or name' do
|
31
|
+
it { should be_false }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '#image_url' do
|
36
|
+
context 'when photo url is a fully qualified url' do
|
37
|
+
it 'returns the photo url' do
|
38
|
+
expect(author.image_url).to eq 'http://www.active.com/Assets/Running/Bios/jacquie-cattanach-bio.jpg'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'when photo url starts with /' do
|
43
|
+
before do
|
44
|
+
allow(author.photo).to receive(:url).and_return '/hello'
|
45
|
+
end
|
46
|
+
it 'returns the url for the active.com domain' do
|
47
|
+
expect(author.image_url).to eq 'http://www.active.com/hello'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe '#name' do
|
53
|
+
context 'when the author is created from an article' do
|
54
|
+
let(:author_name) { "" }
|
55
|
+
let(:asset_descriptions) { [] }
|
56
|
+
let(:response) { { assetGuid: "777", assetDescriptions: asset_descriptions, authorName: author_name} }
|
57
|
+
let(:author_from_article) { ACTV::Author.build_from_article response }
|
58
|
+
context 'when author name exists in the author footer' do
|
59
|
+
let(:asset_descriptions) { [ { descriptionType: { descriptionTypeId: "3", descriptionTypeName: "authorFooter" }, description: "<span class='author-name'>Bob Marley</span>" } ] }
|
60
|
+
let(:author_name) { "Jimi Hendrix" }
|
61
|
+
|
62
|
+
it 'returns the author name from the article footer' do
|
63
|
+
expect(author_from_article.name).to eq "Bob Marley"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
context 'when author name exists only in the author name field' do
|
67
|
+
let(:author_name) { "Jimi Hendrix" }
|
68
|
+
it 'returns author name from the author name field' do
|
69
|
+
expect(author_from_article.name).to eq 'Jimi Hendrix'
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
context 'when the author is created from an author' do
|
74
|
+
it 'returns the author name from the author footer' do
|
75
|
+
expect(author.name).to eq "Jacquie Cattanach"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ACTV::AuthorValidator do
|
4
|
+
let(:asset_categories) { [] }
|
5
|
+
let(:response) { { assetGuid: 1, assetCategories: asset_categories } }
|
6
|
+
subject(:validator) { ACTV::AuthorValidator.new(response).valid? }
|
7
|
+
|
8
|
+
describe '#valid?' do
|
9
|
+
context 'when the response is valid' do
|
10
|
+
context 'because the category name is valid' do
|
11
|
+
let(:asset_categories) { [ { category: { categoryName: "Author", categoryTaxonomy: "" } } ] }
|
12
|
+
it { should be_true }
|
13
|
+
end
|
14
|
+
context 'because the category taxonomy is valid' do
|
15
|
+
let(:asset_categories) { [ { category: { categoryName: "", categoryTaxonomy: "Person/Author" } } ] }
|
16
|
+
it { should be_true }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
context 'when the response is not valid' do
|
20
|
+
it { should be_false }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/spec/actv/client_spec.rb
CHANGED
@@ -212,7 +212,7 @@ describe ACTV::Client do
|
|
212
212
|
context 'find event' do
|
213
213
|
before do
|
214
214
|
stub_request(:get, "http://api.amp.active.com/v2/assets/asset_id.json").
|
215
|
-
to_return(body: fixture("
|
215
|
+
to_return(body: fixture("valid_event.json"), headers: { content_type: "application/json; charset=utf-8" })
|
216
216
|
end
|
217
217
|
|
218
218
|
it 'makes a normal asset call' do
|
@@ -220,10 +220,10 @@ describe ACTV::Client do
|
|
220
220
|
end
|
221
221
|
end
|
222
222
|
|
223
|
-
context 'when
|
223
|
+
context 'when multiple event ids' do
|
224
224
|
before do
|
225
225
|
stub_request(:get, "http://api.amp.active.com/v2/assets/asset_ids.json").
|
226
|
-
to_return(body: fixture("
|
226
|
+
to_return(body: fixture("valid_events.json"), headers: { content_type: "application/json; charset=utf-8" })
|
227
227
|
end
|
228
228
|
|
229
229
|
it 'returns an Array of Events' do
|
@@ -237,7 +237,7 @@ describe ACTV::Client do
|
|
237
237
|
context 'when preview is true' do
|
238
238
|
before do
|
239
239
|
stub_request(:get, "http://api.amp.active.com/v2/assets/asset_id/preview.json").
|
240
|
-
to_return(body: fixture("
|
240
|
+
to_return(body: fixture("valid_event.json"), headers: { content_type: "application/json; charset=utf-8" })
|
241
241
|
end
|
242
242
|
|
243
243
|
it 'returns an event' do
|
@@ -248,7 +248,7 @@ describe ACTV::Client do
|
|
248
248
|
context 'when preview is false' do
|
249
249
|
before do
|
250
250
|
stub_request(:get, "http://api.amp.active.com/v2/assets/asset_id.json").
|
251
|
-
to_return(body: fixture("
|
251
|
+
to_return(body: fixture("valid_event.json"), headers: { content_type: "application/json; charset=utf-8" })
|
252
252
|
end
|
253
253
|
|
254
254
|
it 'returns an event' do
|
@@ -258,6 +258,77 @@ describe ACTV::Client do
|
|
258
258
|
end
|
259
259
|
end
|
260
260
|
|
261
|
+
describe '#asset' do
|
262
|
+
let(:configuration) do
|
263
|
+
{ consumer_key: "CK",
|
264
|
+
consumer_secret: "CS",
|
265
|
+
oauth_token: "OT",
|
266
|
+
oauth_token_secret: "OS"}
|
267
|
+
end
|
268
|
+
let(:fixture_asset) { "valid_asset.json" }
|
269
|
+
let(:request_type) { :post }
|
270
|
+
let(:endpoint) { "http://api.amp.active.com/v2/assets.json" }
|
271
|
+
let(:asset) { client.asset('asset_id').first }
|
272
|
+
let(:assets) { client.asset('author_guid,article_guid,event_guid') }
|
273
|
+
before do
|
274
|
+
stub_request(request_type, endpoint).
|
275
|
+
to_return(body: fixture(fixture_asset), headers: { content_type: "application/json; charset=utf-8" })
|
276
|
+
end
|
277
|
+
|
278
|
+
context 'when an asset guid with no category is passed' do
|
279
|
+
it 'returns an event' do
|
280
|
+
expect(asset).to be_an ACTV::Asset
|
281
|
+
end
|
282
|
+
end
|
283
|
+
context 'when an event guid is passed' do
|
284
|
+
let(:fixture_asset) { "valid_event.json" }
|
285
|
+
it 'returns an event' do
|
286
|
+
expect(asset).to be_an ACTV::Event
|
287
|
+
end
|
288
|
+
end
|
289
|
+
context 'when an article guid is passed' do
|
290
|
+
let(:fixture_asset) { "valid_article.json" }
|
291
|
+
it 'returns an article' do
|
292
|
+
expect(asset).to be_an ACTV::Article
|
293
|
+
end
|
294
|
+
end
|
295
|
+
context 'when an author guid is passed' do
|
296
|
+
let(:fixture_asset) { "valid_author.json" }
|
297
|
+
it 'returns an author' do
|
298
|
+
expect(asset).to be_an ACTV::Author
|
299
|
+
end
|
300
|
+
end
|
301
|
+
context 'when multiple asset guids are passed' do
|
302
|
+
let(:fixture_asset) { "valid_assets.json" }
|
303
|
+
it 'returns an author' do
|
304
|
+
expect(assets.first).to be_an ACTV::Author
|
305
|
+
end
|
306
|
+
it 'returns an article' do
|
307
|
+
expect(assets[1]).to be_an ACTV::Article
|
308
|
+
end
|
309
|
+
it 'returns an event' do
|
310
|
+
expect(assets.last).to be_an ACTV::Event
|
311
|
+
end
|
312
|
+
end
|
313
|
+
context 'when a preview key is provided' do
|
314
|
+
context 'when preview is true' do
|
315
|
+
let(:request_type) { :get }
|
316
|
+
let(:endpoint) { "http://api.amp.active.com/v2/assets/asset_id/preview.json" }
|
317
|
+
let(:asset) { client.asset('asset_id', preview: 'true').first }
|
318
|
+
it 'returns an asset' do
|
319
|
+
expect(asset).to be_an ACTV::Asset
|
320
|
+
end
|
321
|
+
end
|
322
|
+
context 'when preview is false' do
|
323
|
+
let(:endpoint) { "http://api.amp.active.com/v2/assets.json" }
|
324
|
+
let(:asset) { client.asset('asset_id', preview: 'false').first }
|
325
|
+
it 'returns an asset' do
|
326
|
+
expect(asset).to be_an ACTV::Asset
|
327
|
+
end
|
328
|
+
end
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
261
332
|
ACTV::Configurable::CONFIG_KEYS.each do |key|
|
262
333
|
it "has a default #{key.to_s.gsub('_', ' ')}" do
|
263
334
|
expect(client.send key).to eq ACTV::Default.options[key]
|
data/spec/actv/event_spec.rb
CHANGED
@@ -16,14 +16,22 @@ describe ACTV::Event do
|
|
16
16
|
format_date(date) << ' UTC'
|
17
17
|
end
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
19
|
+
describe '#self.valid?' do
|
20
|
+
let(:asset_categories) { [] }
|
21
|
+
let(:response) { { assetGuid: 1, assetCategories: asset_categories } }
|
22
|
+
subject(:valid?) { ACTV::Event.valid? response }
|
23
|
+
context 'when the category name is event' do
|
24
|
+
let(:asset_categories) { [ { category: { categoryName: "Event", categoryTaxonomy: "" } } ] }
|
25
|
+
it { should be_true }
|
26
|
+
end
|
27
|
+
context 'when the category taxonomy is event' do
|
28
|
+
let(:asset_categories) { [ { category: { categoryName: "", categoryTaxonomy: "Races/Event" } } ] }
|
29
|
+
it { should be_true }
|
30
|
+
end
|
31
|
+
context 'when there is no category taxonomy or name' do
|
32
|
+
it { should be_false }
|
33
|
+
end
|
34
|
+
end
|
27
35
|
|
28
36
|
describe '#online_registration_available?' do
|
29
37
|
context 'when online_registration_available is true' do
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ACTV::EventValidator do
|
4
|
+
let(:asset_categories) { [] }
|
5
|
+
let(:response) { { assetGuid: 1, assetCategories: asset_categories } }
|
6
|
+
subject(:validator) { ACTV::EventValidator.new(response).valid? }
|
7
|
+
|
8
|
+
describe '#valid?' do
|
9
|
+
context 'when the response is valid' do
|
10
|
+
context 'because the category name is valid' do
|
11
|
+
let(:asset_categories) { [ { category: { categoryName: "Event", categoryTaxonomy: "" } } ] }
|
12
|
+
it { should be_true }
|
13
|
+
end
|
14
|
+
context 'because the category taxonomy is valid' do
|
15
|
+
let(:asset_categories) { [ { category: { categoryName: "", categoryTaxonomy: "Races/Event" } } ] }
|
16
|
+
it { should be_true }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
context 'when the response is not valid' do
|
20
|
+
it { should be_false }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/spec/actv/evergreen_spec.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require "active_support/time"
|
3
|
-
require "pry"
|
4
3
|
|
5
4
|
describe ACTV::Evergreen do
|
6
5
|
before do
|
@@ -17,15 +16,6 @@ describe ACTV::Evergreen do
|
|
17
16
|
format_date(date) << ' UTC'
|
18
17
|
end
|
19
18
|
|
20
|
-
# describe "available methods" do
|
21
|
-
# subject { ACTV::Event.new(assetGuid: 1) }
|
22
|
-
# it { should respond_to :online_registration_available? }
|
23
|
-
# it { should respond_to :registration_not_yet_open? }
|
24
|
-
# it { should respond_to :registration_open? }
|
25
|
-
# it { should respond_to :registration_closed? }
|
26
|
-
# it { should respond_to :event_ended? }
|
27
|
-
# end
|
28
|
-
|
29
19
|
describe "evergreen?" do
|
30
20
|
its(:evergreen?) { should be_true }
|
31
21
|
end
|
@@ -1,187 +1,186 @@
|
|
1
1
|
{
|
2
|
-
|
3
|
-
"
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
2
|
+
"assetStatus": {
|
3
|
+
"assetStatusId": "2",
|
4
|
+
"assetStatusName": "VISIBLE",
|
5
|
+
"isSearchable": "true",
|
6
|
+
"isDeleted": "false",
|
7
|
+
"createdDate": "2012-05-09T22:37:09",
|
8
|
+
"modifiedDate": "2012-05-09T22:37:09"
|
9
|
+
},
|
10
|
+
"organization": { },
|
11
|
+
"place": {
|
12
|
+
"placeGuid": "91a9a869-e74e-4016-ba1e-2aafb17a9acc",
|
13
|
+
"placeName": "Article",
|
14
|
+
"placeDsc": "",
|
15
|
+
"placeUrlAdr": "",
|
16
|
+
"addressLine1Txt": "Article",
|
17
|
+
"addressLine2Txt": "",
|
18
|
+
"cityName": "Article",
|
19
|
+
"stateProvinceCode": "CA",
|
20
|
+
"localityName": "",
|
21
|
+
"postalCode": "00000",
|
22
|
+
"countryName": "USA",
|
23
|
+
"countryCode": "",
|
24
|
+
"latitude": "37.271875",
|
25
|
+
"longitude": "-119.270229",
|
26
|
+
"directionsTxt": "",
|
27
|
+
"geoPoint": {
|
28
|
+
"lat": "37.271875",
|
29
|
+
"lon": "-119.270229"
|
30
|
+
}
|
31
|
+
},
|
32
|
+
"evergreenAsset": { },
|
33
|
+
"dma": { },
|
34
|
+
"sourceSystem": {
|
35
|
+
"sourceSystemName": "Active.com Articles",
|
36
|
+
"legacyGuid": "CA4EA0B1-7377-470D-B20D-BF6BEA23F040"
|
37
|
+
},
|
38
|
+
"assetRootAsset": { },
|
39
|
+
"assetParentAsset": { },
|
40
|
+
"market": {
|
41
|
+
"marketId": "8",
|
42
|
+
"marketName": "endurance-running"
|
43
|
+
},
|
44
|
+
"assetGuid": "63e030f3-3df4-402c-9617-d37f6fb2c11a",
|
45
|
+
"assetName": "4 Tips on Running Your Best 10K",
|
46
|
+
"assetDsc": "",
|
47
|
+
"alternateName": "",
|
48
|
+
"timezone": "",
|
49
|
+
"timezoneAbb": "",
|
50
|
+
"timezoneName": "",
|
51
|
+
"currencyCd": "",
|
52
|
+
"localeCd": "",
|
53
|
+
"salesStartDate": null,
|
54
|
+
"salesEndDate": null,
|
55
|
+
"urlAdr": "http://www.active.com/running/Articles/4-Tips-on-Running-Your-Best-10k.htm",
|
56
|
+
"detailPageTemplateId": "",
|
57
|
+
"preferredUrlAdr": "",
|
58
|
+
"logoUrlAdr": "",
|
59
|
+
"activityStartDate": null,
|
60
|
+
"activityStartTime": "",
|
61
|
+
"activityEndDate": null,
|
62
|
+
"activityEndTime": "",
|
63
|
+
"donationUrlAdr": "",
|
64
|
+
"teamUrlAdr": "",
|
65
|
+
"homePageUrlAdr": "",
|
66
|
+
"registrationUrlAdr": "",
|
67
|
+
"regReqMinAge": "",
|
68
|
+
"regReqMaxAge": "",
|
69
|
+
"regReqGenderCd": "",
|
70
|
+
"resultsUrlAdr": "",
|
71
|
+
"isRecurring": "false",
|
72
|
+
"contactName": "",
|
73
|
+
"contactEmailAdr": "",
|
74
|
+
"contactPhone": "",
|
75
|
+
"contactTxt": "",
|
76
|
+
"showContact": "false",
|
77
|
+
"sorId": "",
|
78
|
+
"sorCreateDtm": null,
|
79
|
+
"sorCreateUserId": "",
|
80
|
+
"authorName": "Greg Tymon, M.Ed., C.S.C.S.",
|
81
|
+
"publishDate": "2012-07-01T12:12:00",
|
82
|
+
"createdDate": "2012-07-06T15:51:52",
|
83
|
+
"modifiedDate": "2012-07-09T20:56:06",
|
84
|
+
"activityRecurrences": [ ],
|
85
|
+
"assetQuantity": { },
|
86
|
+
"assetLegacyData": { },
|
87
|
+
"assetTags": [
|
88
|
+
{
|
89
|
+
"tag": {
|
90
|
+
"tagId": "3162",
|
91
|
+
"tagName": "Article",
|
92
|
+
"tagDescription": "articleType"
|
93
|
+
}
|
94
|
+
}
|
95
|
+
],
|
96
|
+
"assetPrices": [ ],
|
97
|
+
"assetDescriptions": [
|
98
|
+
{
|
99
|
+
"descriptionType": {
|
100
|
+
"descriptionTypeId": "4",
|
101
|
+
"descriptionTypeName": "summary"
|
102
|
+
},
|
103
|
+
"description": "Running can be endlessly challenging for any participant. There is always another mile or a faster time that you can work towards. Use these tips to push it a little harder on your next run."
|
10
104
|
},
|
11
|
-
|
12
|
-
|
13
|
-
"
|
14
|
-
"
|
15
|
-
|
16
|
-
|
17
|
-
"addressLine1Txt": "Article",
|
18
|
-
"addressLine2Txt": "",
|
19
|
-
"cityName": "Article",
|
20
|
-
"stateProvinceCode": "CA",
|
21
|
-
"localityName": "",
|
22
|
-
"postalCode": "00000",
|
23
|
-
"countryName": "USA",
|
24
|
-
"countryCode": "",
|
25
|
-
"latitude": "37.271875",
|
26
|
-
"longitude": "-119.270229",
|
27
|
-
"directionsTxt": "",
|
28
|
-
"geoPoint": {
|
29
|
-
"lat": "37.271875",
|
30
|
-
"lon": "-119.270229"
|
31
|
-
}
|
105
|
+
{
|
106
|
+
"descriptionType": {
|
107
|
+
"descriptionTypeId": "6",
|
108
|
+
"descriptionTypeName": "Standard"
|
109
|
+
},
|
110
|
+
"description": "<p> One of the great virtues of the sport of running is that it can be endlessly challenging for every participant. There is always a greater distance or a faster time just waiting for you to take it on. For beginners, just completing your first three-mile training run can be celebrated as a tremendous accomplishment. </p> <p> For seasoned runners, shaving time from a personal record is its own form of winning. As you age, your progress within age groups may account for new personal bests. And for every runner, it is the running itself that is its own reward.<br /> <br /> If you're relatively new to running, adding up mileage works physiological magic-increasing your stamina, your strength, and your speed. But if you've built a good base of about 25 to 30 miles a week or more and have been running in your comfort zone for a while, you will need to introduce some new training techniques and tweak your habits here and there to get faster. </p> <p> What you need is a well-rounded <a href=/Page23545.aspx title=Your 3-Part Training Plan>training program</a> that incorporates speed work, long runs, and adequate rest and recovery. Here is a quick guide for improving your 10K race time: </p> <h2>Adding Speed Work</h2> <p> The human body adapts very specifically to the demands placed upon it. If you run long and slow, your body will become very efficient at running long and slow. For example, if you run a total of 40 miles per week at a constant pace, you will train the energy...</p>"
|
32
111
|
},
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
"
|
37
|
-
|
112
|
+
{
|
113
|
+
"descriptionType": {
|
114
|
+
"descriptionTypeId": "8",
|
115
|
+
"descriptionTypeName": "articleSource"
|
116
|
+
},
|
117
|
+
"description": "<a href=http://www.americanrunning.org/><i>American Running Association</i></a>"
|
38
118
|
},
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
"
|
43
|
-
|
119
|
+
{
|
120
|
+
"descriptionType": {
|
121
|
+
"descriptionTypeId": "9",
|
122
|
+
"descriptionTypeName": "articleByline"
|
123
|
+
},
|
124
|
+
"description": "By Greg Tymon, M.Ed., C.S.C.S."
|
44
125
|
},
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
{
|
107
|
-
"descriptionType": {
|
108
|
-
"descriptionTypeId": "6",
|
109
|
-
"descriptionTypeName": "Standard"
|
110
|
-
},
|
111
|
-
"description": "<p> One of the great virtues of the sport of running is that it can be endlessly challenging for every participant. There is always a greater distance or a faster time just waiting for you to take it on. For beginners, just completing your first three-mile training run can be celebrated as a tremendous accomplishment. </p> <p> For seasoned runners, shaving time from a personal record is its own form of winning. As you age, your progress within age groups may account for new personal bests. And for every runner, it is the running itself that is its own reward.<br /> <br /> If you're relatively new to running, adding up mileage works physiological magic-increasing your stamina, your strength, and your speed. But if you've built a good base of about 25 to 30 miles a week or more and have been running in your comfort zone for a while, you will need to introduce some new training techniques and tweak your habits here and there to get faster. </p> <p> What you need is a well-rounded <a href=/Page23545.aspx title=Your 3-Part Training Plan>training program</a> that incorporates speed work, long runs, and adequate rest and recovery. Here is a quick guide for improving your 10K race time: </p> <h2>Adding Speed Work</h2> <p> The human body adapts very specifically to the demands placed upon it. If you run long and slow, your body will become very efficient at running long and slow. For example, if you run a total of 40 miles per week at a constant pace, you will train the energy...</p>"
|
112
|
-
},
|
113
|
-
{
|
114
|
-
"descriptionType": {
|
115
|
-
"descriptionTypeId": "8",
|
116
|
-
"descriptionTypeName": "articleSource"
|
117
|
-
},
|
118
|
-
"description": "<a href=http://www.americanrunning.org/><i>American Running Association</i></a>"
|
119
|
-
},
|
120
|
-
{
|
121
|
-
"descriptionType": {
|
122
|
-
"descriptionTypeId": "9",
|
123
|
-
"descriptionTypeName": "articleByline"
|
124
|
-
},
|
125
|
-
"description": "By Greg Tymon, M.Ed., C.S.C.S."
|
126
|
-
},
|
127
|
-
{
|
128
|
-
"descriptionType": {
|
129
|
-
"descriptionTypeId": "10",
|
130
|
-
"descriptionTypeName": "articleAuthorBio"
|
131
|
-
},
|
132
|
-
"description": "Author Bio"
|
133
|
-
},
|
134
|
-
{
|
135
|
-
"descriptionType": {
|
136
|
-
"descriptionTypeId": "28",
|
137
|
-
"descriptionTypeName": "authorFooter"
|
138
|
-
},
|
139
|
-
"description": "<div class=\"article-signature-block\"> <div class=\"signature-block-photo\"><img width=\"60\" height=\"60\" src=\"/Assets/Running/Experts/Jeff+Galloway_120.jpg\" /></div> <div class=\"author-info\"> <span class=\"author-link\"><a href=\"http://www.active.com/running/experts/jeffgalloway/\" title=\"Jeff Galloway\">Jeff's Bio</a></span> <span class=\"author-name\">Jeff Galloway</span><span class=\"author-title\"> Active.com Running Expert</span> </div> <div class=\"author-text\">Olympian Jeff Galloway has helped over a million runners through his running schools, training programs, beach and Tahoe retreats, books and training programs?which are fun and offer individualized coaching from Jeff. To subscribe to his free newsletter visit <a target=\"_blank\" href=\"http://www.JeffGalloway.com\">JeffGalloway.com</a> </div> </div>"
|
140
|
-
}
|
141
|
-
],
|
142
|
-
"assetChannels": [
|
143
|
-
{
|
144
|
-
"sequence": "1",
|
145
|
-
"channel": {
|
146
|
-
"channelId": "1020",
|
147
|
-
"channelName": "Running",
|
148
|
-
"channelDsc": "Running"
|
149
|
-
}
|
150
|
-
}
|
151
|
-
],
|
152
|
-
"assetMediaTypes": [ ],
|
153
|
-
"assetImages": [
|
154
|
-
{
|
155
|
-
"imageUrlAdr": "http://www.active.com/AssetFactory.aspx?did=50534",
|
156
|
-
"imageName": "image1",
|
157
|
-
"imageCaptionTxt": ""
|
158
|
-
},
|
159
|
-
{
|
160
|
-
"imageUrlAdr": "http://www.active.com/AssetFactory.aspx?did=50534",
|
161
|
-
"imageName": "authorImage",
|
162
|
-
"imageCaptionTxt": "Author"
|
163
|
-
}
|
164
|
-
],
|
165
|
-
"assetTopics": [
|
166
|
-
{
|
167
|
-
"sequence": "1",
|
168
|
-
"topic": {
|
169
|
-
"topicId": "27",
|
170
|
-
"topicName": "Running"
|
171
|
-
}
|
172
|
-
}
|
173
|
-
],
|
174
|
-
"assetCategories": [
|
175
|
-
{
|
176
|
-
"sequence": "1",
|
177
|
-
"category": {
|
178
|
-
"categoryId": "7",
|
179
|
-
"categoryName": "Articles"
|
180
|
-
}
|
181
|
-
}
|
182
|
-
],
|
183
|
-
"assetMetaInterests": [ ],
|
184
|
-
"assetComponents": [ ],
|
185
|
-
"assetServiceHostName": "int-asset-403"
|
186
|
-
|
187
|
-
}
|
126
|
+
{
|
127
|
+
"descriptionType": {
|
128
|
+
"descriptionTypeId": "10",
|
129
|
+
"descriptionTypeName": "articleAuthorBio"
|
130
|
+
},
|
131
|
+
"description": "Author Bio"
|
132
|
+
},
|
133
|
+
{
|
134
|
+
"descriptionType": {
|
135
|
+
"descriptionTypeId": "28",
|
136
|
+
"descriptionTypeName": "authorFooter"
|
137
|
+
},
|
138
|
+
"description": "<div class=\"article-signature-block\"> <div class=\"signature-block-photo\"><img width=\"60\" height=\"60\" src=\"/Assets/Running/Experts/Jeff+Galloway_120.jpg\" /></div> <div class=\"author-info\"> <span class=\"author-link\"><a href=\"http://www.active.com/running/experts/jeffgalloway/\" title=\"Jeff Galloway\">Jeff's Bio</a></span> <span class=\"author-name\">Jeff Galloway</span><span class=\"author-title\"> Active.com Running Expert</span> </div> <div class=\"author-text\">Olympian Jeff Galloway has helped over a million runners through his running schools, training programs, beach and Tahoe retreats, books and training programs?which are fun and offer individualized coaching from Jeff. To subscribe to his free newsletter visit <a target=\"_blank\" href=\"http://www.JeffGalloway.com\">JeffGalloway.com</a> </div> </div>"
|
139
|
+
}
|
140
|
+
],
|
141
|
+
"assetChannels": [
|
142
|
+
{
|
143
|
+
"sequence": "1",
|
144
|
+
"channel": {
|
145
|
+
"channelId": "1020",
|
146
|
+
"channelName": "Running",
|
147
|
+
"channelDsc": "Running"
|
148
|
+
}
|
149
|
+
}
|
150
|
+
],
|
151
|
+
"assetMediaTypes": [ ],
|
152
|
+
"assetImages": [
|
153
|
+
{
|
154
|
+
"imageUrlAdr": "http://www.active.com/AssetFactory.aspx?did=50534",
|
155
|
+
"imageName": "image1",
|
156
|
+
"imageCaptionTxt": ""
|
157
|
+
},
|
158
|
+
{
|
159
|
+
"imageUrlAdr": "http://www.active.com/AssetFactory.aspx?did=50534",
|
160
|
+
"imageName": "authorImage",
|
161
|
+
"imageCaptionTxt": "Author"
|
162
|
+
}
|
163
|
+
],
|
164
|
+
"assetTopics": [
|
165
|
+
{
|
166
|
+
"sequence": "1",
|
167
|
+
"topic": {
|
168
|
+
"topicId": "27",
|
169
|
+
"topicName": "Running"
|
170
|
+
}
|
171
|
+
}
|
172
|
+
],
|
173
|
+
"assetCategories": [
|
174
|
+
{
|
175
|
+
"sequence": "1",
|
176
|
+
"category": {
|
177
|
+
"categoryId": "7",
|
178
|
+
"categoryName": "Articles",
|
179
|
+
"categoryTaxonomy": "Creative Work/Articles"
|
180
|
+
}
|
181
|
+
}
|
182
|
+
],
|
183
|
+
"assetMetaInterests": [ ],
|
184
|
+
"assetComponents": [ ],
|
185
|
+
"assetServiceHostName": "int-asset-403"
|
186
|
+
}
|